tizen 2.3.1 release submit/tizen_2.3.1/20150915.081658 tizen_2.3.1_release
authorjk7744.park <jk7744.park@samsung.com>
Tue, 8 Sep 2015 13:32:37 +0000 (22:32 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Tue, 8 Sep 2015 13:32:37 +0000 (22:32 +0900)
751 files changed:
.gitignore [new file with mode: 0644]
.tarball-version [new file with mode: 0644]
ABOUT-NLS [deleted file]
ChangeLog [deleted file]
LICENSE
Makefile.am
PROTOCOL [new file with mode: 0644]
PulseAudioConfig.cmake.in [new file with mode: 0644]
PulseAudioConfigVersion.cmake.in [new file with mode: 0644]
README
autogen.sh [deleted file]
bootstrap.sh
build/orc.mak [deleted file]
compile [new file with mode: 0755]
config.rpath [changed mode: 0755->0644]
configure.ac
depcomp [new file with mode: 0755]
doxygen/.gitignore [new file with mode: 0644]
doxygen/doxygen.conf.in
git-version-gen
install-sh [new file with mode: 0755]
libpulse-browse.pc.in [deleted file]
libpulse-mainloop-glib.pc.in
libpulse-simple.pc.in
libpulse.pc.in
ltmain.sh [new file with mode: 0644]
m4/.gitignore [new file with mode: 0644]
m4/acx_lirc.m4 [deleted file]
m4/acx_pthread.m4 [deleted file]
m4/attributes.m4 [deleted file]
m4/ax_check_define.m4 [new file with mode: 0644]
m4/ax_check_flag.m4 [new file with mode: 0644]
m4/ax_define_dir.m4 [new file with mode: 0644]
m4/ax_pthread.m4 [new file with mode: 0644]
m4/ax_tls.m4 [new file with mode: 0644]
m4/check_define.m4 [deleted file]
m4/gettext.m4 [deleted file]
m4/iconv.m4 [deleted file]
m4/intltool.m4 [deleted file]
m4/lib-ld.m4 [deleted file]
m4/lib-link.m4 [deleted file]
m4/lib-prefix.m4 [deleted file]
m4/nls.m4 [deleted file]
m4/orc.m4
m4/po.m4 [deleted file]
m4/progtest.m4 [deleted file]
m4/tls.m4 [deleted file]
man/.gitignore [new file with mode: 0644]
man/Makefile.am
man/default.pa.5.xml.in
man/esdcompat.1.xml.in
man/pacat.1.xml.in
man/pacmd.1.xml.in
man/pactl.1.xml.in
man/pax11publish.1.xml.in
man/pulse-cli-syntax.5.xml.in [new file with mode: 0644]
man/pulse-client.conf.5.xml.in
man/pulse-daemon.conf.5.xml.in
man/pulseaudio.1.xml.in
man/start-pulseaudio-kde.1.xml.in [moved from man/pabrowse.1.xml.in with 66% similarity]
man/start-pulseaudio-x11.1.xml.in [new file with mode: 0644]
missing [new file with mode: 0755]
orc.mak [new file with mode: 0644]
packaging/pulseaudio.service [new file with mode: 0644]
packaging/pulseaudio.spec [changed mode: 0644->0755]
po/.gitignore [new file with mode: 0644]
po/ChangeLog [deleted file]
po/LINGUAS
po/Makefile.in.in
po/POTFILES.in
po/POTFILES.skip
po/as.po
po/bn_IN.po
po/ca.po
po/cs.po
po/de.po
po/de_CH.po
po/el.po
po/es.po
po/fi.po
po/fr.po
po/gu.po
po/he.po [new file with mode: 0644]
po/hi.po
po/hu.po
po/id.po [new file with mode: 0644]
po/it.po
po/ja.po
po/kn.po
po/ml.po
po/mr.po
po/nl.po
po/or.po
po/pa.po
po/pl.po
po/pt.po
po/pt_BR.po
po/ru.po [new file with mode: 0644]
po/sr.po
po/sr@latin.po
po/sv.po
po/ta.po
po/te.po
po/uk.po
po/zh_CN.po
po/zh_TW.po [new file with mode: 0644]
pulseaudio.manifest [new file with mode: 0755]
pulseaudio.sh.in
pulseaudio_shared.manifest [new file with mode: 0644]
pulsecore.pc.in [new file with mode: 0644]
shell-completion/pulseaudio-bash-completion.sh [new file with mode: 0644]
shell-completion/pulseaudio-zsh-completion.zsh [new file with mode: 0644]
src/.gitignore [new file with mode: 0644]
src/Makefile.am
src/daemon/.gitignore [new file with mode: 0644]
src/daemon/caps.c
src/daemon/caps.h
src/daemon/cmdline.c
src/daemon/cmdline.h
src/daemon/cpulimit.c
src/daemon/daemon-conf.c
src/daemon/daemon-conf.h
src/daemon/daemon.conf.in
src/daemon/default.pa.in
src/daemon/default.pa.win32 [deleted file]
src/daemon/dumpmodules.c
src/daemon/esdcompat.in
src/daemon/ltdl-bind-now.c
src/daemon/main.c
src/daemon/pulseaudio-system.conf
src/daemon/pulseaudio.desktop.in
src/daemon/server-lookup.c [new file with mode: 0644]
src/daemon/server-lookup.h [new file with mode: 0644]
src/daemon/start-pulseaudio-x11.in
src/daemon/system.pa.in
src/map-file
src/modules/alsa/alsa-mixer.c [changed mode: 0644->0755]
src/modules/alsa/alsa-mixer.h
src/modules/alsa/alsa-sink.c [changed mode: 0644->0755]
src/modules/alsa/alsa-sink.h
src/modules/alsa/alsa-source.c [changed mode: 0644->0755]
src/modules/alsa/alsa-ucm.c [new file with mode: 0755]
src/modules/alsa/alsa-ucm.h [new file with mode: 0644]
src/modules/alsa/alsa-util.c [changed mode: 0644->0755]
src/modules/alsa/alsa-util.h [changed mode: 0644->0755]
src/modules/alsa/mixer/paths/analog-input-aux.conf
src/modules/alsa/mixer/paths/analog-input-dock-mic.conf [new file with mode: 0644]
src/modules/alsa/mixer/paths/analog-input-fm.conf
src/modules/alsa/mixer/paths/analog-input-front-mic.conf [new file with mode: 0644]
src/modules/alsa/mixer/paths/analog-input-headphone-mic.conf [new file with mode: 0644]
src/modules/alsa/mixer/paths/analog-input-headset-mic.conf [new file with mode: 0644]
src/modules/alsa/mixer/paths/analog-input-internal-mic-always.conf [new file with mode: 0644]
src/modules/alsa/mixer/paths/analog-input-internal-mic.conf [new file with mode: 0644]
src/modules/alsa/mixer/paths/analog-input-linein.conf
src/modules/alsa/mixer/paths/analog-input-mic-line.conf
src/modules/alsa/mixer/paths/analog-input-mic.conf
src/modules/alsa/mixer/paths/analog-input-mic.conf.common
src/modules/alsa/mixer/paths/analog-input-rear-mic.conf [new file with mode: 0644]
src/modules/alsa/mixer/paths/analog-input-tvtuner.conf
src/modules/alsa/mixer/paths/analog-input-video.conf
src/modules/alsa/mixer/paths/analog-input.conf
src/modules/alsa/mixer/paths/analog-input.conf.common
src/modules/alsa/mixer/paths/analog-output-desktop-speaker.conf [moved from src/modules/alsa/mixer/paths/analog-output-lfe-on-mono.conf with 64% similarity]
src/modules/alsa/mixer/paths/analog-output-headphones-2.conf
src/modules/alsa/mixer/paths/analog-output-headphones.conf
src/modules/alsa/mixer/paths/analog-output-mono.conf
src/modules/alsa/mixer/paths/analog-output-speaker-always.conf [new file with mode: 0644]
src/modules/alsa/mixer/paths/analog-output-speaker.conf
src/modules/alsa/mixer/paths/analog-output.conf
src/modules/alsa/mixer/paths/analog-output.conf.common
src/modules/alsa/mixer/paths/hdmi-output-0.conf [new file with mode: 0644]
src/modules/alsa/mixer/paths/hdmi-output-1.conf [new file with mode: 0644]
src/modules/alsa/mixer/paths/hdmi-output-2.conf [new file with mode: 0644]
src/modules/alsa/mixer/paths/hdmi-output-3.conf [new file with mode: 0644]
src/modules/alsa/mixer/paths/iec958-stereo-output.conf [new file with mode: 0644]
src/modules/alsa/mixer/profile-sets/90-pulseaudio.rules
src/modules/alsa/mixer/profile-sets/default.conf
src/modules/alsa/mixer/profile-sets/extra-hdmi.conf [new file with mode: 0644]
src/modules/alsa/mixer/profile-sets/force-speaker-and-int-mic.conf [new file with mode: 0644]
src/modules/alsa/mixer/profile-sets/force-speaker.conf [new file with mode: 0644]
src/modules/alsa/mixer/profile-sets/kinect-audio.conf [new file with mode: 0644]
src/modules/alsa/mixer/profile-sets/maudio-fasttrack-pro.conf [new file with mode: 0644]
src/modules/alsa/mixer/profile-sets/native-instruments-audio8dj.conf
src/modules/alsa/mixer/profile-sets/native-instruments-korecontroller.conf [new file with mode: 0644]
src/modules/alsa/mixer/profile-sets/native-instruments-traktor-audio10.conf [new file with mode: 0644]
src/modules/alsa/mixer/profile-sets/native-instruments-traktor-audio6.conf [new file with mode: 0644]
src/modules/alsa/mixer/profile-sets/native-instruments-traktorkontrol-s4.conf [new file with mode: 0644]
src/modules/alsa/module-alsa-card-symdef.h [deleted file]
src/modules/alsa/module-alsa-card.c
src/modules/alsa/module-alsa-sink-symdef.h [deleted file]
src/modules/alsa/module-alsa-sink.c
src/modules/alsa/module-alsa-source-symdef.h [deleted file]
src/modules/alsa/module-alsa-source.c
src/modules/ascenario-ymu831.c [new file with mode: 0644]
src/modules/bluetooth/a2dp-codecs.h [changed mode: 0644->0755]
src/modules/bluetooth/bluetooth-util.c [deleted file]
src/modules/bluetooth/bluetooth-util.h
src/modules/bluetooth/bluez4-util.c [new file with mode: 0644]
src/modules/bluetooth/bluez4-util.h [new file with mode: 0644]
src/modules/bluetooth/bluez5-util.c [new file with mode: 0644]
src/modules/bluetooth/bluez5-util.h [new file with mode: 0644]
src/modules/bluetooth/hfaudioagent-null.c [new file with mode: 0644]
src/modules/bluetooth/hfaudioagent-ofono.c [new file with mode: 0644]
src/modules/bluetooth/hfaudioagent.h [new file with mode: 0644]
src/modules/bluetooth/ipc.c [deleted file]
src/modules/bluetooth/ipc.h [deleted file]
src/modules/bluetooth/module-bluetooth-discover.c [changed mode: 0644->0755]
src/modules/bluetooth/module-bluetooth-policy.c [new file with mode: 0644]
src/modules/bluetooth/module-bluetooth-proximity.c [deleted file]
src/modules/bluetooth/module-bluez4-device.c [moved from src/modules/bluetooth/module-bluetooth-device.c with 52% similarity]
src/modules/bluetooth/module-bluez4-discover.c [new file with mode: 0644]
src/modules/bluetooth/module-bluez5-device.c [new file with mode: 0644]
src/modules/bluetooth/module-bluez5-discover.c [new file with mode: 0644]
src/modules/bluetooth/proximity-helper.c [deleted file]
src/modules/bluetooth/sbc/sbc.c [deleted file]
src/modules/bluetooth/sbc/sbc.h [deleted file]
src/modules/bluetooth/sbc/sbc_math.h [deleted file]
src/modules/bluetooth/sbc/sbc_primitives.c [deleted file]
src/modules/bluetooth/sbc/sbc_primitives.h [deleted file]
src/modules/bluetooth/sbc/sbc_primitives_armv6.c [deleted file]
src/modules/bluetooth/sbc/sbc_primitives_armv6.h [deleted file]
src/modules/bluetooth/sbc/sbc_primitives_iwmmxt.c [deleted file]
src/modules/bluetooth/sbc/sbc_primitives_iwmmxt.h [deleted file]
src/modules/bluetooth/sbc/sbc_primitives_mmx.c [deleted file]
src/modules/bluetooth/sbc/sbc_primitives_mmx.h [deleted file]
src/modules/bluetooth/sbc/sbc_primitives_neon.c [deleted file]
src/modules/bluetooth/sbc/sbc_primitives_neon.h [deleted file]
src/modules/bluetooth/sbc/sbc_tables.h [deleted file]
src/modules/dbus/iface-card-profile.c [new file with mode: 0644]
src/modules/dbus/iface-card-profile.h [new file with mode: 0644]
src/modules/dbus/iface-card.c [new file with mode: 0644]
src/modules/dbus/iface-card.h [new file with mode: 0644]
src/modules/dbus/iface-client.c [new file with mode: 0644]
src/modules/dbus/iface-client.h [new file with mode: 0644]
src/modules/dbus/iface-core.c [new file with mode: 0644]
src/modules/dbus/iface-core.h [new file with mode: 0644]
src/modules/dbus/iface-device-port.c [new file with mode: 0644]
src/modules/dbus/iface-device-port.h [new file with mode: 0644]
src/modules/dbus/iface-device.c [new file with mode: 0644]
src/modules/dbus/iface-device.h [new file with mode: 0644]
src/modules/dbus/iface-memstats.c [new file with mode: 0644]
src/modules/dbus/iface-memstats.h [new file with mode: 0644]
src/modules/dbus/iface-module.c [new file with mode: 0644]
src/modules/dbus/iface-module.h [new file with mode: 0644]
src/modules/dbus/iface-sample.c [new file with mode: 0644]
src/modules/dbus/iface-sample.h [new file with mode: 0644]
src/modules/dbus/iface-stream.c [new file with mode: 0644]
src/modules/dbus/iface-stream.h [new file with mode: 0644]
src/modules/dbus/module-dbus-protocol.c [new file with mode: 0644]
src/modules/echo-cancel/adrian-aec-orc-dist.c [deleted file]
src/modules/echo-cancel/adrian-aec-orc-dist.h [deleted file]
src/modules/echo-cancel/adrian-aec.c
src/modules/echo-cancel/adrian-aec.h
src/modules/echo-cancel/adrian-aec.orc [moved from src/modules/echo-cancel/adrian-aec-orc.orc with 100% similarity]
src/modules/echo-cancel/adrian.c
src/modules/echo-cancel/adrian.h
src/modules/echo-cancel/echo-cancel.h
src/modules/echo-cancel/module-echo-cancel-symdef.h [deleted file]
src/modules/echo-cancel/module-echo-cancel.c
src/modules/echo-cancel/null.c [new file with mode: 0644]
src/modules/echo-cancel/speex.c
src/modules/echo-cancel/webrtc.cc [new file with mode: 0644]
src/modules/gconf/module-gconf-symdef.h [deleted file]
src/modules/gconf/module-gconf.c
src/modules/hal-util.c [deleted file]
src/modules/jack/module-jack-sink-symdef.h [deleted file]
src/modules/jack/module-jack-sink.c
src/modules/jack/module-jack-source-symdef.h [deleted file]
src/modules/jack/module-jack-source.c
src/modules/jack/module-jackdbus-detect.c [new file with mode: 0644]
src/modules/macosx/module-bonjour-publish.c [new file with mode: 0644]
src/modules/macosx/module-coreaudio-detect.c [new file with mode: 0644]
src/modules/macosx/module-coreaudio-device.c [new file with mode: 0644]
src/modules/module-always-sink-symdef.h [deleted file]
src/modules/module-always-sink.c
src/modules/module-augment-properties-symdef.h [deleted file]
src/modules/module-augment-properties.c
src/modules/module-card-restore-symdef.h [deleted file]
src/modules/module-card-restore.c
src/modules/module-cli-protocol-tcp-symdef.h [deleted file]
src/modules/module-cli-protocol-unix-symdef.h [deleted file]
src/modules/module-cli-symdef.h [deleted file]
src/modules/module-cli.c
src/modules/module-combine-sink.c [new file with mode: 0644]
src/modules/module-combine-symdef.h [deleted file]
src/modules/module-combine.c
src/modules/module-console-kit-symdef.h [deleted file]
src/modules/module-console-kit.c
src/modules/module-cork-music-on-phone-symdef.h [deleted file]
src/modules/module-default-device-restore-symdef.h [deleted file]
src/modules/module-default-device-restore.c
src/modules/module-detect-symdef.h [deleted file]
src/modules/module-detect.c
src/modules/module-device-manager-symdef.h [deleted file]
src/modules/module-device-manager.c
src/modules/module-device-restore-symdef.h [deleted file]
src/modules/module-device-restore.c
src/modules/module-equalizer-sink.c [new file with mode: 0644]
src/modules/module-esound-compat-spawnfd-symdef.h [deleted file]
src/modules/module-esound-compat-spawnfd.c
src/modules/module-esound-compat-spawnpid-symdef.h [deleted file]
src/modules/module-esound-compat-spawnpid.c
src/modules/module-esound-protocol-tcp-symdef.h [deleted file]
src/modules/module-esound-protocol-unix-symdef.h [deleted file]
src/modules/module-esound-sink-symdef.h [deleted file]
src/modules/module-esound-sink.c
src/modules/module-filter-apply.c [new file with mode: 0644]
src/modules/module-filter-heuristics.c [new file with mode: 0644]
src/modules/module-hal-detect-symdef.h [deleted file]
src/modules/module-hal-detect.c [deleted file]
src/modules/module-http-protocol-tcp-symdef.h [deleted file]
src/modules/module-http-protocol-unix-symdef.h [deleted file]
src/modules/module-intended-roles-symdef.h [deleted file]
src/modules/module-intended-roles.c
src/modules/module-ladspa-sink-symdef.h [deleted file]
src/modules/module-ladspa-sink.c
src/modules/module-lirc-symdef.h [deleted file]
src/modules/module-lirc.c
src/modules/module-loopback-symdef.h [deleted file]
src/modules/module-loopback.c
src/modules/module-match-symdef.h [deleted file]
src/modules/module-match.c
src/modules/module-mmkbd-evdev-symdef.h [deleted file]
src/modules/module-mmkbd-evdev.c
src/modules/module-native-protocol-fd-symdef.h [deleted file]
src/modules/module-native-protocol-fd.c
src/modules/module-native-protocol-tcp-symdef.h [deleted file]
src/modules/module-native-protocol-unix-symdef.h [deleted file]
src/modules/module-null-sink-symdef.h [deleted file]
src/modules/module-null-sink.c
src/modules/module-null-source.c [new file with mode: 0644]
src/modules/module-pipe-sink-symdef.h [deleted file]
src/modules/module-pipe-sink.c
src/modules/module-pipe-source-symdef.h [deleted file]
src/modules/module-pipe-source.c
src/modules/module-policy-symdef.h [deleted file]
src/modules/module-policy.c [changed mode: 0644->0755]
src/modules/module-position-event-sounds-symdef.h [deleted file]
src/modules/module-position-event-sounds.c
src/modules/module-protocol-stub.c
src/modules/module-remap-sink-symdef.h [deleted file]
src/modules/module-remap-sink.c
src/modules/module-remap-source.c [new file with mode: 0644]
src/modules/module-rescue-streams-symdef.h [deleted file]
src/modules/module-rescue-streams.c
src/modules/module-role-cork.c [moved from src/modules/module-cork-music-on-phone.c with 57% similarity]
src/modules/module-role-ducking.c [new file with mode: 0644]
src/modules/module-rygel-media-server-symdef.h [deleted file]
src/modules/module-rygel-media-server.c
src/modules/module-simple-protocol-tcp-symdef.h [deleted file]
src/modules/module-simple-protocol-unix-symdef.h [deleted file]
src/modules/module-sine-source-symdef.h [deleted file]
src/modules/module-sine-source.c
src/modules/module-sine-symdef.h [deleted file]
src/modules/module-sine.c
src/modules/module-solaris-symdef.h [deleted file]
src/modules/module-solaris.c
src/modules/module-stream-mgr.c [new file with mode: 0644]
src/modules/module-stream-restore-symdef.h [deleted file]
src/modules/module-stream-restore.c
src/modules/module-suspend-on-idle-symdef.h [deleted file]
src/modules/module-suspend-on-idle.c [changed mode: 0644->0755]
src/modules/module-switch-on-connect.c [new file with mode: 0644]
src/modules/module-switch-on-port-available.c [new file with mode: 0644]
src/modules/module-systemd-login.c [new file with mode: 0644]
src/modules/module-tunnel-sink-symdef.h [deleted file]
src/modules/module-tunnel-source-symdef.h [deleted file]
src/modules/module-tunnel.c
src/modules/module-udev-detect-symdef.h [deleted file]
src/modules/module-udev-detect.c
src/modules/module-virtual-sink-symdef.h [deleted file]
src/modules/module-virtual-sink.c
src/modules/module-virtual-source-symdef.h [deleted file]
src/modules/module-virtual-source.c
src/modules/module-virtual-surround-sink.c [new file with mode: 0644]
src/modules/module-volume-restore-symdef.h [deleted file]
src/modules/module-volume-restore.c
src/modules/module-waveout-symdef.h [deleted file]
src/modules/module-waveout.c [new file with mode: 0644]
src/modules/module-zeroconf-discover-symdef.h [deleted file]
src/modules/module-zeroconf-discover.c
src/modules/module-zeroconf-publish-symdef.h [deleted file]
src/modules/module-zeroconf-publish.c
src/modules/oss/module-oss-symdef.h [deleted file]
src/modules/oss/module-oss.c
src/modules/oss/oss-util.c
src/modules/pm-util.c [new file with mode: 0644]
src/modules/pm-util.h [moved from src/modules/hal-util.h with 81% similarity]
src/modules/raop/base64.c
src/modules/raop/module-raop-discover-symdef.h [deleted file]
src/modules/raop/module-raop-discover.c
src/modules/raop/module-raop-sink-symdef.h [deleted file]
src/modules/raop/module-raop-sink.c
src/modules/raop/raop_client.c
src/modules/raop/raop_client.h
src/modules/reserve-monitor.c
src/modules/reserve-monitor.h
src/modules/reserve-wrap.c
src/modules/reserve.c
src/modules/reserve.h
src/modules/rtp/headerlist.c
src/modules/rtp/module-rtp-recv-symdef.h [deleted file]
src/modules/rtp/module-rtp-recv.c
src/modules/rtp/module-rtp-send-symdef.h [deleted file]
src/modules/rtp/module-rtp-send.c
src/modules/rtp/rtp.c
src/modules/rtp/rtp.h
src/modules/rtp/rtsp_client.c
src/modules/rtp/rtsp_client.h
src/modules/rtp/sap.c
src/modules/rtp/sdp.c
src/modules/tizen-audio.h [new file with mode: 0755]
src/modules/udev-util.c
src/modules/udev-util.h
src/modules/x11/module-x11-bell-symdef.h [deleted file]
src/modules/x11/module-x11-bell.c
src/modules/x11/module-x11-cork-request-symdef.h [deleted file]
src/modules/x11/module-x11-cork-request.c
src/modules/x11/module-x11-publish-symdef.h [deleted file]
src/modules/x11/module-x11-publish.c
src/modules/x11/module-x11-xsmp-symdef.h [deleted file]
src/modules/x11/module-x11-xsmp.c
src/modules/xen/gntalloc.h [new file with mode: 0644]
src/modules/xen/gntdev.h [new file with mode: 0644]
src/modules/xen/module-xenpv-sink.c [new file with mode: 0644]
src/pulse/.gitignore [new file with mode: 0644]
src/pulse/browser.c [deleted file]
src/pulse/browser.h [deleted file]
src/pulse/channelmap.c
src/pulse/channelmap.h
src/pulse/client-conf-x11.c
src/pulse/client-conf.c
src/pulse/client-conf.h
src/pulse/client.conf.in
src/pulse/context.c
src/pulse/context.h
src/pulse/def.h
src/pulse/error.c
src/pulse/error.h
src/pulse/ext-device-manager.c
src/pulse/ext-device-manager.h
src/pulse/ext-device-restore.c [new file with mode: 0644]
src/pulse/ext-device-restore.h [new file with mode: 0644]
src/pulse/ext-echo-cancel.c [new file with mode: 0644]
src/pulse/ext-echo-cancel.h [new file with mode: 0644]
src/pulse/ext-policy.c [changed mode: 0644->0755]
src/pulse/ext-policy.h [changed mode: 0644->0755]
src/pulse/ext-stream-restore.c
src/pulse/ext-stream-restore.h
src/pulse/ext-suspend-on-idle.c [new file with mode: 0644]
src/pulse/ext-suspend-on-idle.h [new file with mode: 0644]
src/pulse/format.c [new file with mode: 0644]
src/pulse/format.h [new file with mode: 0644]
src/pulse/gccmacro.h
src/pulse/glib-mainloop.c
src/pulse/glib-mainloop.h
src/pulse/internal.h
src/pulse/introspect.c
src/pulse/introspect.h
src/pulse/mainloop-api.c
src/pulse/mainloop-api.h
src/pulse/mainloop-signal.c
src/pulse/mainloop.c
src/pulse/mainloop.h
src/pulse/operation.c
src/pulse/operation.h
src/pulse/proplist.c
src/pulse/proplist.h
src/pulse/pulseaudio.h
src/pulse/rtclock.c
src/pulse/rtclock.h
src/pulse/sample.c
src/pulse/sample.h
src/pulse/scache.c
src/pulse/scache.h
src/pulse/simple.c [changed mode: 0644->0755]
src/pulse/simple.h
src/pulse/stream.c
src/pulse/stream.h
src/pulse/subscribe.c
src/pulse/subscribe.h
src/pulse/thread-mainloop.c
src/pulse/thread-mainloop.h
src/pulse/timeval.c
src/pulse/timeval.h
src/pulse/utf8.c
src/pulse/utf8.h
src/pulse/util.c
src/pulse/util.h
src/pulse/version.h.in
src/pulse/volume.c
src/pulse/volume.h
src/pulsecore/arpa-inet.c [moved from src/pulsecore/inet_ntop.c with 75% similarity]
src/pulsecore/arpa-inet.h [new file with mode: 0644]
src/pulsecore/asyncmsgq.c
src/pulsecore/asyncq.c
src/pulsecore/asyncq.h
src/pulsecore/atomic.h
src/pulsecore/aupdate.h
src/pulsecore/auth-cookie.c
src/pulsecore/auth-cookie.h
src/pulsecore/authkey.c
src/pulsecore/authkey.h
src/pulsecore/avahi-wrap.c
src/pulsecore/card.c
src/pulsecore/card.h
src/pulsecore/cli-command.c
src/pulsecore/cli-text.c
src/pulsecore/cli.c
src/pulsecore/client.c
src/pulsecore/conf-parser.c
src/pulsecore/conf-parser.h
src/pulsecore/core-error.c
src/pulsecore/core-error.h
src/pulsecore/core-rtclock.c
src/pulsecore/core-rtclock.h
src/pulsecore/core-scache.c
src/pulsecore/core-subscribe.c
src/pulsecore/core-util.c
src/pulsecore/core-util.h
src/pulsecore/core.c
src/pulsecore/core.h
src/pulsecore/cpu-arm.c
src/pulsecore/cpu-arm.h
src/pulsecore/cpu-orc.c [new file with mode: 0644]
src/pulsecore/cpu-orc.h [new file with mode: 0644]
src/pulsecore/cpu-x86.c
src/pulsecore/cpu-x86.h
src/pulsecore/cpu.h [new file with mode: 0644]
src/pulsecore/creds.h
src/pulsecore/database-gdbm.c
src/pulsecore/database-simple.c
src/pulsecore/database-tdb.c
src/pulsecore/database.h
src/pulsecore/dbus-shared.c
src/pulsecore/dbus-util.c
src/pulsecore/dbus-util.h
src/pulsecore/device-port.c [new file with mode: 0644]
src/pulsecore/device-port.h [new file with mode: 0644]
src/pulsecore/dllmain.c
src/pulsecore/dynarray.c
src/pulsecore/dynarray.h
src/pulsecore/envelope.c [deleted file]
src/pulsecore/envelope.h [deleted file]
src/pulsecore/esound.h
src/pulsecore/fdsem.c
src/pulsecore/fdsem.h
src/pulsecore/ffmpeg/resample2.c
src/pulsecore/flist.c
src/pulsecore/flist.h
src/pulsecore/hashmap.c
src/pulsecore/hashmap.h
src/pulsecore/hook-list.c
src/pulsecore/hook-list.h
src/pulsecore/i18n.c [moved from src/pulse/i18n.c with 97% similarity]
src/pulsecore/i18n.h [moved from src/pulse/i18n.h with 96% similarity]
src/pulsecore/idxset.c
src/pulsecore/idxset.h
src/pulsecore/inet_ntop.h [deleted file]
src/pulsecore/inet_pton.c [deleted file]
src/pulsecore/inet_pton.h [deleted file]
src/pulsecore/iochannel.c
src/pulsecore/iochannel.h
src/pulsecore/ioline.c
src/pulsecore/ioline.h
src/pulsecore/ipacl.c
src/pulsecore/lock-autospawn.c
src/pulsecore/log.c
src/pulsecore/log.h
src/pulsecore/ltdl-helper.c
src/pulsecore/macro.h
src/pulsecore/mcalign.c
src/pulsecore/mcalign.h
src/pulsecore/memblock.c
src/pulsecore/memblock.h
src/pulsecore/memblockq.c
src/pulsecore/memblockq.h
src/pulsecore/memchunk.c
src/pulsecore/memchunk.h
src/pulsecore/memtrap.c
src/pulsecore/mime-type.c
src/pulsecore/mime-type.h
src/pulsecore/mix.c [new file with mode: 0644]
src/pulsecore/mix.h [new file with mode: 0644]
src/pulsecore/mix_neon.c [new file with mode: 0644]
src/pulsecore/modargs.c
src/pulsecore/modargs.h
src/pulsecore/modinfo.c
src/pulsecore/module.c
src/pulsecore/module.h
src/pulsecore/msgobject.h
src/pulsecore/mutex-posix.c
src/pulsecore/mutex-win32.c
src/pulsecore/mutex.h
src/pulsecore/namereg.c [changed mode: 0644->0755]
src/pulsecore/native-common.h
src/pulsecore/object.c
src/pulsecore/object.h
src/pulsecore/once.c
src/pulsecore/once.h
src/pulsecore/parseaddr.c
src/pulsecore/pdispatch.c
src/pulsecore/pid.c
src/pulsecore/pipe.c
src/pulsecore/play-memblockq.c
src/pulsecore/play-memblockq.h
src/pulsecore/play-memchunk.c
src/pulsecore/play-memchunk.h
src/pulsecore/poll-posix.c [moved from src/pulsecore/poll.c with 71% similarity]
src/pulsecore/poll-win32.c [new file with mode: 0644]
src/pulsecore/poll.h
src/pulsecore/prioq.c [deleted file]
src/pulsecore/prioq.h [deleted file]
src/pulsecore/proplist-util.c
src/pulsecore/proplist-util.h
src/pulsecore/protocol-cli.c
src/pulsecore/protocol-dbus.c [new file with mode: 0644]
src/pulsecore/protocol-dbus.h [new file with mode: 0644]
src/pulsecore/protocol-esound.c
src/pulsecore/protocol-http.c
src/pulsecore/protocol-native.c [changed mode: 0644->0755]
src/pulsecore/protocol-simple.c
src/pulsecore/pstream.c
src/pulsecore/pstream.h
src/pulsecore/queue.c
src/pulsecore/queue.h
src/pulsecore/random.c
src/pulsecore/ratelimit.c
src/pulsecore/ratelimit.h
src/pulsecore/remap.c
src/pulsecore/remap_mmx.c
src/pulsecore/remap_sse.c
src/pulsecore/resampler.c
src/pulsecore/resampler.h
src/pulsecore/rtkit.c
src/pulsecore/rtkit.h
src/pulsecore/rtpoll.c
src/pulsecore/rtpoll.h
src/pulsecore/sample-util.c
src/pulsecore/sample-util.h
src/pulsecore/sconv-s16le.c
src/pulsecore/sconv.c
src/pulsecore/sconv.h
src/pulsecore/sconv_neon.c [new file with mode: 0644]
src/pulsecore/sconv_sse.c
src/pulsecore/semaphore-osx.c [new file with mode: 0644]
src/pulsecore/semaphore-win32.c
src/pulsecore/shared.c
src/pulsecore/shm.c
src/pulsecore/sink-input.c [changed mode: 0644->0755]
src/pulsecore/sink-input.h
src/pulsecore/sink.c
src/pulsecore/sink.h
src/pulsecore/sndfile-util.c
src/pulsecore/socket-client.c
src/pulsecore/socket-server.c
src/pulsecore/socket-server.h
src/pulsecore/socket-util.c
src/pulsecore/socket-util.h
src/pulsecore/socket.h [moved from src/pulsecore/winsock.h with 77% similarity]
src/pulsecore/sound-file-stream.c
src/pulsecore/sound-file.c
src/pulsecore/source-output.c
src/pulsecore/source-output.h
src/pulsecore/source.c
src/pulsecore/source.h
src/pulsecore/start-child.c
src/pulsecore/strbuf.c
src/pulsecore/strlist.c
src/pulsecore/strlist.h
src/pulsecore/svolume.orc [new file with mode: 0644]
src/pulsecore/svolume_arm.c
src/pulsecore/svolume_c.c
src/pulsecore/svolume_mmx.c
src/pulsecore/svolume_orc.c [new file with mode: 0644]
src/pulsecore/svolume_sse.c
src/pulsecore/tags [deleted file]
src/pulsecore/tagstruct.c
src/pulsecore/tagstruct.h
src/pulsecore/thread-mq.c
src/pulsecore/thread-mq.h
src/pulsecore/thread-posix.c
src/pulsecore/thread-win32.c
src/pulsecore/thread.h
src/pulsecore/time-smoother.c
src/pulsecore/tokenizer.c
src/pulsecore/usergroup.c
src/pulsecore/vector.h [deleted file]
src/pulsecore/x11prop.c
src/pulsecore/x11prop.h
src/pulsecore/x11wrap.c
src/pulsecore/x11wrap.h
src/tests/alsa-mixer-path-test.c [new file with mode: 0644]
src/tests/alsa-time-test.c
src/tests/asyncmsgq-test.c
src/tests/asyncq-test.c
src/tests/channelmap-test.c
src/tests/connect-stress.c [new file with mode: 0644]
src/tests/cpu-test.c [new file with mode: 0644]
src/tests/cpulimit-test.c
src/tests/envelope-test.c [deleted file]
src/tests/extended-test.c [new file with mode: 0644]
src/tests/flist-test.c
src/tests/format-test.c [new file with mode: 0644]
src/tests/get-binary-name-test.c
src/tests/hook-list-test.c
src/tests/interpol-test.c
src/tests/ipacl-test.c
src/tests/lock-autospawn-test.c
src/tests/mainloop-test.c
src/tests/mcalign-test.c
src/tests/memblock-test.c
src/tests/memblockq-test.c
src/tests/mix-special-test.c [new file with mode: 0644]
src/tests/mix-test.c
src/tests/mult-s16-test.c [new file with mode: 0644]
src/tests/once-test.c [new file with mode: 0644]
src/tests/pacat-simple.c
src/tests/parec-simple.c
src/tests/prioq-test.c [deleted file]
src/tests/proplist-test.c
src/tests/queue-test.c
src/tests/remix-test.c
src/tests/resampler-test.c
src/tests/rtpoll-test.c
src/tests/rtstutter.c
src/tests/sig2str-test.c
src/tests/sigbus-test.c
src/tests/smoother-test.c
src/tests/strlist-test.c
src/tests/sync-playback.c
src/tests/thread-mainloop-test.c
src/tests/thread-test.c
src/tests/usergroup-test.c
src/tests/utf8-test.c
src/tests/vector-test.c [deleted file]
src/tests/volume-test.c [moved from src/tests/voltest.c with 66% similarity]
src/utils/pabrowse.c [deleted file]
src/utils/pacat.c
src/utils/pacmd.c
src/utils/pactl.c
src/utils/padsp.c
src/utils/padsp.in [moved from src/utils/padsp with 95% similarity, mode: 0644]
src/utils/pasuspender.c
src/utils/pax11publish.c
src/utils/qpaeq [new file with mode: 0755]
todo
vala/libpulse-mainloop-glib.deps [new file with mode: 0644]
vala/libpulse-mainloop-glib.vapi [new file with mode: 0644]
vala/libpulse.deps [new file with mode: 0644]
vala/libpulse.vapi

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..38d26f3
--- /dev/null
@@ -0,0 +1,34 @@
+.tarball-version
+.version
+.*.swp
+ABOUT-NLS
+intltool-extract.in
+intltool-merge.in
+intltool-update.in
+*~
+*.tar.gz
+*.pc
+PulseAudioConfig.cmake
+PulseAudioConfigVersion.cmake
+/Makefile
+/Makefile.in
+aclocal.m4
+autom4te.cache
+compile
+config.guess
+config.h
+config.h.in
+config.log
+config.rpath
+config.status
+config.sub
+configure
+pulse-daemon.log
+depcomp
+install-sh
+libltdl
+libtool
+ltmain.sh
+missing
+mkinstalldirs
+stamp-*
diff --git a/.tarball-version b/.tarball-version
new file mode 100644 (file)
index 0000000..5186d07
--- /dev/null
@@ -0,0 +1 @@
+4.0
diff --git a/ABOUT-NLS b/ABOUT-NLS
deleted file mode 100644 (file)
index 83bc72e..0000000
--- a/ABOUT-NLS
+++ /dev/null
@@ -1,1068 +0,0 @@
-1 Notes on the Free Translation Project
-***************************************
-
-Free software is going international!  The Free Translation Project is
-a way to get maintainers of free software, translators, and users all
-together, so that free software will gradually become able to speak many
-languages.  A few packages already provide translations for their
-messages.
-
-   If you found this `ABOUT-NLS' file inside a distribution, you may
-assume that the distributed package does use GNU `gettext' internally,
-itself available at your nearest GNU archive site.  But you do _not_
-need to install GNU `gettext' prior to configuring, installing or using
-this package with messages translated.
-
-   Installers will find here some useful hints.  These notes also
-explain how users should proceed for getting the programs to use the
-available translations.  They tell how people wanting to contribute and
-work on translations can contact the appropriate team.
-
-   When reporting bugs in the `intl/' directory or bugs which may be
-related to internationalization, you should tell about the version of
-`gettext' which is used.  The information can be found in the
-`intl/VERSION' file, in internationalized packages.
-
-1.1 Quick configuration advice
-==============================
-
-If you want to exploit the full power of internationalization, you
-should configure it using
-
-     ./configure --with-included-gettext
-
-to force usage of internationalizing routines provided within this
-package, despite the existence of internationalizing capabilities in the
-operating system where this package is being installed.  So far, only
-the `gettext' implementation in the GNU C library version 2 provides as
-many features (such as locale alias, message inheritance, automatic
-charset conversion or plural form handling) as the implementation here.
-It is also not possible to offer this additional functionality on top
-of a `catgets' implementation.  Future versions of GNU `gettext' will
-very likely convey even more functionality.  So it might be a good idea
-to change to GNU `gettext' as soon as possible.
-
-   So you need _not_ provide this option if you are using GNU libc 2 or
-you have installed a recent copy of the GNU gettext package with the
-included `libintl'.
-
-1.2 INSTALL Matters
-===================
-
-Some packages are "localizable" when properly installed; the programs
-they contain can be made to speak your own native language.  Most such
-packages use GNU `gettext'.  Other packages have their own ways to
-internationalization, predating GNU `gettext'.
-
-   By default, this package will be installed to allow translation of
-messages.  It will automatically detect whether the system already
-provides the GNU `gettext' functions.  If not, the included GNU
-`gettext' library will be used.  This library is wholly contained
-within this package, usually in the `intl/' subdirectory, so prior
-installation of the GNU `gettext' package is _not_ required.
-Installers may use special options at configuration time for changing
-the default behaviour.  The commands:
-
-     ./configure --with-included-gettext
-     ./configure --disable-nls
-
-will, respectively, bypass any pre-existing `gettext' to use the
-internationalizing routines provided within this package, or else,
-_totally_ disable translation of messages.
-
-   When you already have GNU `gettext' installed on your system and run
-configure without an option for your new package, `configure' will
-probably detect the previously built and installed `libintl.a' file and
-will decide to use this.  This might not be desirable.  You should use
-the more recent version of the GNU `gettext' library.  I.e. if the file
-`intl/VERSION' shows that the library which comes with this package is
-more recent, you should use
-
-     ./configure --with-included-gettext
-
-to prevent auto-detection.
-
-   The configuration process will not test for the `catgets' function
-and therefore it will not be used.  The reason is that even an
-emulation of `gettext' on top of `catgets' could not provide all the
-extensions of the GNU `gettext' library.
-
-   Internationalized packages usually have many `po/LL.po' files, where
-LL gives an ISO 639 two-letter code identifying the language.  Unless
-translations have been forbidden at `configure' time by using the
-`--disable-nls' switch, all available translations are installed
-together with the package.  However, the environment variable `LINGUAS'
-may be set, prior to configuration, to limit the installed set.
-`LINGUAS' should then contain a space separated list of two-letter
-codes, stating which languages are allowed.
-
-1.3 Using This Package
-======================
-
-As a user, if your language has been installed for this package, you
-only have to set the `LANG' environment variable to the appropriate
-`LL_CC' combination.  If you happen to have the `LC_ALL' or some other
-`LC_xxx' environment variables set, you should unset them before
-setting `LANG', otherwise the setting of `LANG' will not have the
-desired effect.  Here `LL' is an ISO 639 two-letter language code, and
-`CC' is an ISO 3166 two-letter country code.  For example, let's
-suppose that you speak German and live in Germany.  At the shell
-prompt, merely execute `setenv LANG de_DE' (in `csh'),
-`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash').
-This can be done from your `.login' or `.profile' file, once and for
-all.
-
-   You might think that the country code specification is redundant.
-But in fact, some languages have dialects in different countries.  For
-example, `de_AT' is used for Austria, and `pt_BR' for Brazil.  The
-country code serves to distinguish the dialects.
-
-   The locale naming convention of `LL_CC', with `LL' denoting the
-language and `CC' denoting the country, is the one use on systems based
-on GNU libc.  On other systems, some variations of this scheme are
-used, such as `LL' or `LL_CC.ENCODING'.  You can get the list of
-locales supported by your system for your language by running the
-command `locale -a | grep '^LL''.
-
-   Not all programs have translations for all languages.  By default, an
-English message is shown in place of a nonexistent translation.  If you
-understand other languages, you can set up a priority list of languages.
-This is done through a different environment variable, called
-`LANGUAGE'.  GNU `gettext' gives preference to `LANGUAGE' over `LANG'
-for the purpose of message handling, but you still need to have `LANG'
-set to the primary language; this is required by other parts of the
-system libraries.  For example, some Swedish users who would rather
-read translations in German than English for when Swedish is not
-available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'.
-
-   Special advice for Norwegian users: The language code for Norwegian
-bokma*l changed from `no' to `nb' recently (in 2003).  During the
-transition period, while some message catalogs for this language are
-installed under `nb' and some older ones under `no', it's recommended
-for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and
-older translations are used.
-
-   In the `LANGUAGE' environment variable, but not in the `LANG'
-environment variable, `LL_CC' combinations can be abbreviated as `LL'
-to denote the language's main dialect.  For example, `de' is equivalent
-to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT'
-(Portuguese as spoken in Portugal) in this context.
-
-1.4 Translating Teams
-=====================
-
-For the Free Translation Project to be a success, we need interested
-people who like their own language and write it well, and who are also
-able to synergize with other translators speaking the same language.
-Each translation team has its own mailing list.  The up-to-date list of
-teams can be found at the Free Translation Project's homepage,
-`http://translationproject.org/', in the "Teams" area.
-
-   If you'd like to volunteer to _work_ at translating messages, you
-should become a member of the translating team for your own language.
-The subscribing address is _not_ the same as the list itself, it has
-`-request' appended.  For example, speakers of Swedish can send a
-message to `sv-request@li.org', having this message body:
-
-     subscribe
-
-   Keep in mind that team members are expected to participate
-_actively_ in translations, or at solving translational difficulties,
-rather than merely lurking around.  If your team does not exist yet and
-you want to start one, or if you are unsure about what to do or how to
-get started, please write to `coordinator@translationproject.org' to
-reach the coordinator for all translator teams.
-
-   The English team is special.  It works at improving and uniformizing
-the terminology in use.  Proven linguistic skills are praised more than
-programming skills, here.
-
-1.5 Available Packages
-======================
-
-Languages are not equally supported in all packages.  The following
-matrix shows the current state of internationalization, as of November
-2007.  The matrix shows, in regard of each package, for which languages
-PO files have been submitted to translation coordination, with a
-translation percentage of at least 50%.
-
-     Ready PO files       af am ar az be bg bs ca cs cy da de el en en_GB eo
-                        +----------------------------------------------------+
-     Compendium         |                      []       [] []        []      |
-     a2ps               |             []                [] [] []     []      |
-     aegis              |                                  ()                |
-     ant-phone          |                                  ()                |
-     anubis             |                                  []                |
-     ap-utils           |                                                    |
-     aspell             |                      [] []    [] []        []      |
-     bash               |                                                 [] |
-     bfd                |                                                    |
-     bibshelf           |                                  []                |
-     binutils           |                                                    |
-     bison              |                               [] []                |
-     bison-runtime      |                                  []                |
-     bluez-pin          | []                      []       [] []          [] |
-     cflow              |                               []                   |
-     clisp              |                               [] []    []          |
-     console-tools      |                         []       []                |
-     coreutils          |                []    [] []       []                |
-     cpio               |                                                    |
-     cpplib             |                      []       [] []                |
-     cryptonit          |                                  []                |
-     dialog             |                                                    |
-     diffutils          |                      [] []    [] [] []          [] |
-     doodle             |                                  []                |
-     e2fsprogs          |                         []       []                |
-     enscript           |                      []       [] []        []      |
-     fetchmail          |                      []       [] () []     []      |
-     findutils          |                []                                  |
-     findutils_stable   |                []    []       []                   |
-     flex               |                      []       [] []                |
-     fslint             |                                                    |
-     gas                |                                                    |
-     gawk               |                      []       [] []                |
-     gcal               |                      []                            |
-     gcc                |                                  []                |
-     gettext-examples   | []                   []          [] []          [] |
-     gettext-runtime    |             []       []       [] []             [] |
-     gettext-tools      |                      []          []                |
-     gip                |                []                                  |
-     gliv               |                []                []                |
-     glunarclock        |                []                                  |
-     gmult              | []                               []                |
-     gnubiff            |                                  ()                |
-     gnucash            |                      [] []       () ()     []      |
-     gnuedu             |                                                    |
-     gnulib             |                []                                  |
-     gnunet             |                                                    |
-     gnunet-gtk         |                                                    |
-     gnutls             |                                  []                |
-     gpe-aerial         |                         []       []                |
-     gpe-beam           |                         []       []                |
-     gpe-calendar       |                                                    |
-     gpe-clock          |                         []       []                |
-     gpe-conf           |                         []       []                |
-     gpe-contacts       |                                                    |
-     gpe-edit           |                         []                         |
-     gpe-filemanager    |                                                    |
-     gpe-go             |                         []                         |
-     gpe-login          |                         []       []                |
-     gpe-ownerinfo      |                         []       []                |
-     gpe-package        |                                                    |
-     gpe-sketchbook     |                         []       []                |
-     gpe-su             |                         []       []                |
-     gpe-taskmanager    |                         []       []                |
-     gpe-timesheet      |                         []                         |
-     gpe-today          |                         []       []                |
-     gpe-todo           |                                                    |
-     gphoto2            |                         []    [] []        []      |
-     gprof              |                               [] []                |
-     gpsdrive           |                                                    |
-     gramadoir          | []                               []                |
-     grep               |                         []                      [] |
-     gretl              |                                  ()                |
-     gsasl              |                                                    |
-     gss                |                                                    |
-     gst-plugins-bad    |                []             []                   |
-     gst-plugins-base   |                []             []                   |
-     gst-plugins-good   |                []    []       []                   |
-     gst-plugins-ugly   |                []             []                   |
-     gstreamer          | []             []    [] []    [] []        []      |
-     gtick              |                                  ()                |
-     gtkam              |             []          []    [] []                |
-     gtkorphan          |                []                []                |
-     gtkspell           |             []                   [] []          [] |
-     gutenprint         |                               []                   |
-     hello              |                []    []       [] []             [] |
-     herrie             |                                  []                |
-     hylafax            |                                                    |
-     idutils            |                               [] []                |
-     indent             |                      [] []       []             [] |
-     iso_15924          |                                                    |
-     iso_3166           |       []    [] [] [] [] [] [] [] [] []          [] |
-     iso_3166_2         |                                                    |
-     iso_4217           |                         []    [] []                |
-     iso_639            |                         []    [] []             [] |
-     jpilot             |                         []                         |
-     jtag               |                                                    |
-     jwhois             |                                                    |
-     kbd                |                         []    [] [] []             |
-     keytouch           |                      []          []                |
-     keytouch-editor    |                                  []                |
-     keytouch-keyboa... |                      []                            |
-     latrine            |                                  ()                |
-     ld                 |                               []                   |
-     leafpad            |                []    [] []       [] []             |
-     libc               |                      [] []    [] []                |
-     libexif            |                                  []                |
-     libextractor       |                                  []                |
-     libgpewidget       |                         []    [] []                |
-     libgpg-error       |                                  []                |
-     libgphoto2         |                               [] []                |
-     libgphoto2_port    |                               [] []                |
-     libgsasl           |                                                    |
-     libiconv           |                                  []             [] |
-     libidn             |                         []    []                [] |
-     lifelines          |                               [] ()                |
-     lilypond           |                                  []                |
-     lingoteach         |                                                    |
-     lprng              |                                                    |
-     lynx               |                      [] []    [] []                |
-     m4                 |                         []    [] [] []             |
-     mailfromd          |                                                    |
-     mailutils          |                      []                            |
-     make               |                               [] []                |
-     man-db             |                      []       [] []                |
-     minicom            |                         []    [] []                |
-     nano               |                []    []          []                |
-     opcodes            |                                  []                |
-     parted             |                         []       []                |
-     pilot-qof          |                                                    |
-     popt               |                         []    [] []                |
-     psmisc             |                []                                  |
-     pwdutils           |                                                    |
-     qof                |                                                    |
-     radius             |                      []                            |
-     recode             |             []       []       [] [] []          [] |
-     rpm                |                               []                   |
-     screem             |                                                    |
-     scrollkeeper       |          [] []       [] [] [] [] []        []      |
-     sed                |                      []          []             [] |
-     shared-mime-info   |                []    [] []    [] () []     []   [] |
-     sharutils          |                []    [] []    [] [] []             |
-     shishi             |                                                    |
-     skencil            |                               [] ()                |
-     solfege            |                                                    |
-     soundtracker       |                               [] []                |
-     sp                 |                                  []                |
-     system-tools-ba... |       []       [] [] [] []    [] [] []     []      |
-     tar                |                []                []                |
-     texinfo            |                               [] []             [] |
-     tin                |                                  ()        ()      |
-     tuxpaint           | []             []             [] []        []   [] |
-     unicode-han-tra... |                                                    |
-     unicode-transla... |                                                    |
-     util-linux         |                      [] []    [] []                |
-     util-linux-ng      |                      [] []    [] []                |
-     vorbis-tools       |                         []                         |
-     wastesedge         |                                  ()                |
-     wdiff              |                      []       [] []        []      |
-     wget               |                      [] []       []                |
-     xchat              |             [] []    [] []       [] []     []      |
-     xkeyboard-config   |                []                                  |
-     xpad               |                []             []           []      |
-                        +----------------------------------------------------+
-                          af am ar az be bg bs ca cs cy da de el en en_GB eo
-                           6  0  2  1  8 26  2 40 48  2 56 88 15  1  15   18
-
-                          es et eu fa fi fr  ga gl gu he hi hr hu id is it
-                        +--------------------------------------------------+
-     Compendium         | []          [] []  []                []          |
-     a2ps               |    []       [] []                             () |
-     aegis              |                                                  |
-     ant-phone          |                []                                |
-     anubis             |                []                                |
-     ap-utils           |             [] []                                |
-     aspell             |                []  []                         [] |
-     bash               | []                                               |
-     bfd                | []          []                                   |
-     bibshelf           | []                 []                         [] |
-     binutils           | []          [] []                                |
-     bison              | [] []          []  []                   []    [] |
-     bison-runtime      |    []          []  []                   []    [] |
-     bluez-pin          |             [] []  []                [] []       |
-     cflow              |                    []                            |
-     clisp              | []             []                                |
-     console-tools      |                                                  |
-     coreutils          | [] []       [] []  []                []          |
-     cpio               | []             []  []                            |
-     cpplib             | []             []                                |
-     cryptonit          |                []                                |
-     dialog             |       []           []                         [] |
-     diffutils          | []          [] []  [] []    []       [] []    [] |
-     doodle             |                    []                         [] |
-     e2fsprogs          | []             []                             [] |
-     enscript           |                []  []             []             |
-     fetchmail          | []                                               |
-     findutils          |    []              []                []          |
-     findutils_stable   |    []          []  []                []          |
-     flex               | []             []  []                            |
-     fslint             |                                                  |
-     gas                | []             []                                |
-     gawk               | []             []  []       []                () |
-     gcal               | []             []                                |
-     gcc                | []                                               |
-     gettext-examples   | []          [] []  []                [] []    [] |
-     gettext-runtime    | []          [] []  []                   []    [] |
-     gettext-tools      | []    []       []                             [] |
-     gip                | []    []       []  []                            |
-     gliv               |                ()                                |
-     glunarclock        |             []     []                []          |
-     gmult              |       []       []                             [] |
-     gnubiff            |                ()                             () |
-     gnucash            | ()             ()                    ()          |
-     gnuedu             | []                                               |
-     gnulib             | [] []              []                            |
-     gnunet             |                                                  |
-     gnunet-gtk         |                                                  |
-     gnutls             |                                                  |
-     gpe-aerial         | []             []                                |
-     gpe-beam           | []             []                                |
-     gpe-calendar       |                                                  |
-     gpe-clock          | []          [] []                    []          |
-     gpe-conf           |                []                                |
-     gpe-contacts       | []             []                                |
-     gpe-edit           | []             []                    [] []       |
-     gpe-filemanager    | []                                               |
-     gpe-go             | []             []                    []          |
-     gpe-login          | []             []                    []          |
-     gpe-ownerinfo      | []          [] []                    [] []       |
-     gpe-package        | []                                               |
-     gpe-sketchbook     | []             []                                |
-     gpe-su             | []          [] []                    []          |
-     gpe-taskmanager    | []          [] []                                |
-     gpe-timesheet      | []             []  []                   []       |
-     gpe-today          | []          [] []  []                            |
-     gpe-todo           | []                                               |
-     gphoto2            | []          [] []                    []       [] |
-     gprof              | []          [] []  []                   []       |
-     gpsdrive           |    []                                            |
-     gramadoir          |                []  []                            |
-     grep               | []          []     []                            |
-     gretl              | []    []       []                             () |
-     gsasl              |                    []                   []       |
-     gss                |                []  []                            |
-     gst-plugins-bad    | []          []                       []       [] |
-     gst-plugins-base   | []          []                       []       [] |
-     gst-plugins-good   | []    []    []                       []       [] |
-     gst-plugins-ugly   | []          []                       []       [] |
-     gstreamer          |             []                       []       [] |
-     gtick              |             []     []                         [] |
-     gtkam              | []             []                    []       [] |
-     gtkorphan          |                []                             [] |
-     gtkspell           | []    []    [] []  []                []       [] |
-     gutenprint         |                                      []          |
-     hello              | [] [] [] [] [] []  [] []    []    [] [] []    [] |
-     herrie             |                    []                            |
-     hylafax            |                                                  |
-     idutils            |                []  []                [] []    [] |
-     indent             | [] [] []    [] []  [] []             [] []    [] |
-     iso_15924          |                []                                |
-     iso_3166           | [] [] []    [] []     [] [] [] [] [] [] []    [] |
-     iso_3166_2         |                []                                |
-     iso_4217           | [] []       [] []                    []       [] |
-     iso_639            | []       [] [] []  []                []          |
-     jpilot             | []             []                                |
-     jtag               |                []                                |
-     jwhois             | []             []                    [] []    [] |
-     kbd                | []             []                                |
-     keytouch           |                []  []                         [] |
-     keytouch-editor    |                    []                            |
-     keytouch-keyboa... |                    []                         [] |
-     latrine            |                    []                         [] |
-     ld                 | []          [] []  []                            |
-     leafpad            | []             []  []       []       []       [] |
-     libc               | []          [] []     []             []          |
-     libexif            | []                                               |
-     libextractor       |                    []                            |
-     libgpewidget       | []             []  []                [] []       |
-     libgpg-error       |                []                                |
-     libgphoto2         | []             []                             [] |
-     libgphoto2_port    |                []                             [] |
-     libgsasl           |                []  []                            |
-     libiconv           |    []       []     []                            |
-     libidn             |                []                             [] |
-     lifelines          |                ()                                |
-     lilypond           | []          [] []                                |
-     lingoteach         |                []                       []    [] |
-     lprng              |                                                  |
-     lynx               |    []                                []       [] |
-     m4                 |                []  [] []                []       |
-     mailfromd          |                                                  |
-     mailutils          | []             []                                |
-     make               | []          [] []  [] []    []    []    []       |
-     man-db             |                                               [] |
-     minicom            | []          [] []                    []          |
-     nano               | []    []       []  [] []             []       [] |
-     opcodes            | []          [] []  []                            |
-     parted             |                []                       []    [] |
-     pilot-qof          |                                                  |
-     popt               |                []  [] []                   []    |
-     psmisc             |                                      []       [] |
-     pwdutils           |                                                  |
-     qof                |                                         []       |
-     radius             | []             []                                |
-     recode             | []             []  [] []    []       [] []    [] |
-     rpm                |                []                       []       |
-     screem             |                                                  |
-     scrollkeeper       | []          []                       []          |
-     sed                | [] []          []  []                []          |
-     shared-mime-info   | []    []    [] []                    []       [] |
-     sharutils          | [] []       [] []  [] []             []       [] |
-     shishi             |                []                                |
-     skencil            | []             []                                |
-     solfege            |                                               [] |
-     soundtracker       | []             []                             [] |
-     sp                 |                []                                |
-     system-tools-ba... | []    []    [] []  []             [] [] []    [] |
-     tar                |    [] []    []     []                []          |
-     texinfo            |                []           []       []          |
-     tin                |    []          ()                                |
-     tuxpaint           |                    []                []          |
-     unicode-han-tra... |                                                  |
-     unicode-transla... |                []  []                            |
-     util-linux         | [] []       [] []                    [] []    [] |
-     util-linux-ng      | [] []       [] []                    [] []    [] |
-     vorbis-tools       |                                                  |
-     wastesedge         |                ()                                |
-     wdiff              | [] []          []  [] []             [] []    [] |
-     wget               |    []       [] []  []             [] [] []    [] |
-     xchat              | []          [] []        []    []    []       [] |
-     xkeyboard-config   | []          [] []                    []          |
-     xpad               | []                 []                []          |
-                        +--------------------------------------------------+
-                          es et eu fa fi fr  ga gl gu he hi hr hu id is it
-                          85 22 14  2 48 101 61 12  2  8  2  6 53 29  1 52
-
-                          ja ka ko ku ky lg lt lv mk mn ms mt nb ne nl  nn
-                        +--------------------------------------------------+
-     Compendium         |                                           []     |
-     a2ps               |       ()                      []          []     |
-     aegis              |                                           ()     |
-     ant-phone          |                                           []     |
-     anubis             |                               []    []    []     |
-     ap-utils           |                               []                 |
-     aspell             |                            []             []     |
-     bash               |                                           []     |
-     bfd                |                                                  |
-     bibshelf           |                               []                 |
-     binutils           |                                                  |
-     bison              |                               []    []    []     |
-     bison-runtime      |                               []    []    []     |
-     bluez-pin          |          []                   []          []     |
-     cflow              |                                                  |
-     clisp              |                                           []     |
-     console-tools      |                                                  |
-     coreutils          |                                           []     |
-     cpio               |                                           []     |
-     cpplib             |                                           []     |
-     cryptonit          |                                           []     |
-     dialog             |                               []          []     |
-     diffutils          | []                            []          []     |
-     doodle             |                                                  |
-     e2fsprogs          |                                           []     |
-     enscript           |                                           []     |
-     fetchmail          | []                                        []     |
-     findutils          |                                           []     |
-     findutils_stable   |                                           []     |
-     flex               |       []                                  []     |
-     fslint             |                                                  |
-     gas                |                                                  |
-     gawk               | []                                        []     |
-     gcal               |                                                  |
-     gcc                |                                                  |
-     gettext-examples   | []                            []          []     |
-     gettext-runtime    | []    []                                  []     |
-     gettext-tools      | []    []                                         |
-     gip                |                               []          []     |
-     gliv               |                                           []     |
-     glunarclock        |                               []          []     |
-     gmult              | []                            []          []     |
-     gnubiff            |                                                  |
-     gnucash            | ()                                  () ()        |
-     gnuedu             |                                                  |
-     gnulib             | []                                        []     |
-     gnunet             |                                                  |
-     gnunet-gtk         |                                                  |
-     gnutls             |                               []                 |
-     gpe-aerial         |                                           []     |
-     gpe-beam           |                                           []     |
-     gpe-calendar       | []                                               |
-     gpe-clock          | []    []                                  []     |
-     gpe-conf           | []    []                                  []     |
-     gpe-contacts       |       []                                         |
-     gpe-edit           | []    []                                  []     |
-     gpe-filemanager    | []    []                                         |
-     gpe-go             | []    []                                  []     |
-     gpe-login          | []    []                                  []     |
-     gpe-ownerinfo      | []                                        []     |
-     gpe-package        | []    []                                         |
-     gpe-sketchbook     |       []                                  []     |
-     gpe-su             | []    []                                  []     |
-     gpe-taskmanager    | []    [] []                               []     |
-     gpe-timesheet      |                                           []     |
-     gpe-today          | []                                        []     |
-     gpe-todo           | []                                               |
-     gphoto2            | []                                        []     |
-     gprof              |                               []                 |
-     gpsdrive           |                                           []     |
-     gramadoir          |                                           ()     |
-     grep               |             []                            []     |
-     gretl              |                                                  |
-     gsasl              |                                           []     |
-     gss                |                                                  |
-     gst-plugins-bad    |                                           []     |
-     gst-plugins-base   |                                           []     |
-     gst-plugins-good   |                                           []     |
-     gst-plugins-ugly   |                                           []     |
-     gstreamer          |                                           []     |
-     gtick              |                                           []     |
-     gtkam              | []                                        []     |
-     gtkorphan          |                                           []     |
-     gtkspell           |                            []             []     |
-     gutenprint         |                                           []     |
-     hello              | [] [] []                      []    []    []  [] |
-     herrie             |                                           []     |
-     hylafax            |                                                  |
-     idutils            |                                           []     |
-     indent             | []                                        []     |
-     iso_15924          |                                           []     |
-     iso_3166           | []    [] []       []    []          []    []  [] |
-     iso_3166_2         |                                           []     |
-     iso_4217           | []                []                      []     |
-     iso_639            | []                []                      []  [] |
-     jpilot             | ()                                        ()     |
-     jtag               |                                                  |
-     jwhois             |                                           []     |
-     kbd                |                                           []     |
-     keytouch           |                                           []     |
-     keytouch-editor    |                                           []     |
-     keytouch-keyboa... |                                                  |
-     latrine            |                                           []     |
-     ld                 |                                                  |
-     leafpad            | []                []                             |
-     libc               | []    []                                  []     |
-     libexif            |                                                  |
-     libextractor       |                                                  |
-     libgpewidget       |                                           []     |
-     libgpg-error       |                                                  |
-     libgphoto2         | []                                               |
-     libgphoto2_port    | []                                               |
-     libgsasl           |                                           []     |
-     libiconv           |                                           []     |
-     libidn             | []                                        []     |
-     lifelines          |                                           []     |
-     lilypond           |                                           []     |
-     lingoteach         |                                           []     |
-     lprng              |                                                  |
-     lynx               | []                                        []     |
-     m4                 | []                                        []     |
-     mailfromd          |                                                  |
-     mailutils          |                                                  |
-     make               | []    []                                  []     |
-     man-db             |                                                  |
-     minicom            | []                                               |
-     nano               |                               []    []    []     |
-     opcodes            |                                           []     |
-     parted             | []                                        []     |
-     pilot-qof          |                                                  |
-     popt               | []    []                                  []     |
-     psmisc             | []                                  []    []     |
-     pwdutils           |                                                  |
-     qof                |                                                  |
-     radius             |                                                  |
-     recode             |                                           []     |
-     rpm                | []    []                                         |
-     screem             | []                                               |
-     scrollkeeper       |                                     [] [] []  [] |
-     sed                | []                                        []     |
-     shared-mime-info   | []    []          []          []    []    []  [] |
-     sharutils          | []                                        []     |
-     shishi             |                                                  |
-     skencil            |                                                  |
-     solfege            |                                     ()        () |
-     soundtracker       |                                                  |
-     sp                 | ()                                               |
-     system-tools-ba... | []    []          []                      []     |
-     tar                | []          []                            []     |
-     texinfo            |                                     []    []     |
-     tin                |                                                  |
-     tuxpaint           |                                     ()    []  [] |
-     unicode-han-tra... |                                                  |
-     unicode-transla... |                                                  |
-     util-linux         | []                                        []     |
-     util-linux-ng      | []                                        []     |
-     vorbis-tools       |                                                  |
-     wastesedge         |                                           []     |
-     wdiff              |                               []    []           |
-     wget               | []                                        []     |
-     xchat              | []    []                []                []     |
-     xkeyboard-config   |    [] []                                  []     |
-     xpad               |       []                      []          []     |
-                        +--------------------------------------------------+
-                          ja ka ko ku ky lg lt lv mk mn ms mt nb ne nl  nn
-                          51  2 25  3  2  0  6  0  2  2 20  0 11  1 103  6
-
-                          or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv  ta
-                        +--------------------------------------------------+
-     Compendium         |          []  []      []       []          []     |
-     a2ps               |       ()     []      [] []       []    [] []     |
-     aegis              |                      () ()                       |
-     ant-phone          |                      []                   []     |
-     anubis             |       []             [] []                       |
-     ap-utils           |       ()                                         |
-     aspell             |                      [] []    []                 |
-     bash               |       []                      []                 |
-     bfd                |                                                  |
-     bibshelf           |                                           []     |
-     binutils           |                         []    []                 |
-     bison              |       []     []      [] []                []     |
-     bison-runtime      |       []     []      []          []       []     |
-     bluez-pin          |       []     []   [] [] []    [] []    [] []     |
-     cflow              |       []                                         |
-     clisp              |                         []                       |
-     console-tools      |                         []                       |
-     coreutils          |       []                []       []       []     |
-     cpio               |       []                []                []     |
-     cpplib             |                                           []     |
-     cryptonit          |              []                           []     |
-     dialog             |                                           []     |
-     diffutils          |       []     []      [] []             [] []     |
-     doodle             |                                     []    []     |
-     e2fsprogs          |       []                                  []     |
-     enscript           |              []      [] []       []       []     |
-     fetchmail          |       []                []          []           |
-     findutils          |       [] []                               []     |
-     findutils_stable   |       [] []          []       [] []       []     |
-     flex               |       []     []      [] []                []     |
-     fslint             |                                           []     |
-     gas                |                                                  |
-     gawk               |       []     []      []                   []     |
-     gcal               |                                           []     |
-     gcc                |                                        [] []     |
-     gettext-examples   |       [] []          [] []    [] []    [] []     |
-     gettext-runtime    |       [] []          [] []    [] []    [] []     |
-     gettext-tools      |       []             [] []    [] []    [] []     |
-     gip                |                   []          []       [] []     |
-     gliv               |       []     []      [] []    []          []     |
-     glunarclock        |              []      [] []    []       [] []     |
-     gmult              |                   [] []                [] []     |
-     gnubiff            |                      ()                   []     |
-     gnucash            |       ()                                  []     |
-     gnuedu             |                                                  |
-     gnulib             |       []                         []       []     |
-     gnunet             |                                                  |
-     gnunet-gtk         |                                           []     |
-     gnutls             |       []                                  []     |
-     gpe-aerial         |          []  []      [] []       []    [] []     |
-     gpe-beam           |          []  []      [] []       []    [] []     |
-     gpe-calendar       |                         []       []    [] []     |
-     gpe-clock          |          []  []      [] []    [] []    [] []     |
-     gpe-conf           |          []  []      [] []    [] []       []     |
-     gpe-contacts       |                      [] []       []    [] []     |
-     gpe-edit           |       [] []  []      [] []    [] []    [] []     |
-     gpe-filemanager    |                                  []       []     |
-     gpe-go             |       []     []      [] []    [] []    [] []     |
-     gpe-login          |          []  []      [] []    [] []    [] []     |
-     gpe-ownerinfo      |          []  []      [] []    [] []    [] []     |
-     gpe-package        |                                  []       []     |
-     gpe-sketchbook     |          []  []      [] []    [] []    [] []     |
-     gpe-su             |          []  []      [] []    [] []    [] []     |
-     gpe-taskmanager    |          []  []      [] []    [] []    [] []     |
-     gpe-timesheet      |          []  []      [] []    [] []    [] []     |
-     gpe-today          |          []  []      [] []    [] []    [] []     |
-     gpe-todo           |                         []       []    [] []     |
-     gphoto2            |    [] []             []       []       [] []     |
-     gprof              |              []      []                   []     |
-     gpsdrive           |                         []                []     |
-     gramadoir          |                               []          []     |
-     grep               |       []                      [] []       []     |
-     gretl              |       [] []  []                                  |
-     gsasl              |       []                               [] []     |
-     gss                |       []             []       []          []     |
-     gst-plugins-bad    |       []     []                           []     |
-     gst-plugins-base   |       []                                  []     |
-     gst-plugins-good   |       []                                  []     |
-     gst-plugins-ugly   |       []     []                           []     |
-     gstreamer          |       []                            [] [] []     |
-     gtick              |                         []                       |
-     gtkam              |    [] []     []         []                []     |
-     gtkorphan          |                                           []     |
-     gtkspell           |              []   [] [] []    [] []    [] []     |
-     gutenprint         |                                           []     |
-     hello              |       []     []      [] []    [] []    [] []     |
-     herrie             |       []                []                []     |
-     hylafax            |                                                  |
-     idutils            |       []     []      [] []                []     |
-     indent             |       []     []      [] []    []       [] []     |
-     iso_15924          |                                                  |
-     iso_3166           |    [] [] []  []      [] [] [] [] [] [] [] []  [] |
-     iso_3166_2         |                                                  |
-     iso_4217           |       [] []             [] []    []    [] []     |
-     iso_639            |       []                [] [] [] []    [] []     |
-     jpilot             |                                                  |
-     jtag               |                               []                 |
-     jwhois             |       []     []      []                   []     |
-     kbd                |       []             []                   []     |
-     keytouch           |                                           []     |
-     keytouch-editor    |                                           []     |
-     keytouch-keyboa... |                                           []     |
-     latrine            |                                                  |
-     ld                 |                                           []     |
-     leafpad            |       [] []             []    []          []  [] |
-     libc               |       []                []    []          []     |
-     libexif            |       []                      []                 |
-     libextractor       |                      []                   []     |
-     libgpewidget       |       [] []  []      []       [] []    [] []     |
-     libgpg-error       |       []             []                   []     |
-     libgphoto2         |       []                                         |
-     libgphoto2_port    |       []                []                []     |
-     libgsasl           |       []             []                [] []     |
-     libiconv           |                                  []    [] []     |
-     libidn             |       []                               [] ()     |
-     lifelines          |       []                                  []     |
-     lilypond           |                                                  |
-     lingoteach         |              []                                  |
-     lprng              |       []                                         |
-     lynx               |              []         []                []     |
-     m4                 |       []     []      [] []                []     |
-     mailfromd          |       []                                         |
-     mailutils          |       []                []                []     |
-     make               |       []     []         []                []     |
-     man-db             |       []             [] []                []     |
-     minicom            |       []     []      [] []                []     |
-     nano               |              []      [] []                []     |
-     opcodes            |                      []                   []     |
-     parted             |       []                                         |
-     pilot-qof          |                                                  |
-     popt               |       [] []             []                []     |
-     psmisc             |       []                                  []     |
-     pwdutils           |       []                                  []     |
-     qof                |              []                           []     |
-     radius             |       []                []                       |
-     recode             |       [] []  []      [] []       []       []     |
-     rpm                |       [] []             []                []     |
-     screem             |                                                  |
-     scrollkeeper       |       []             [] []    []    [] [] []     |
-     sed                |       [] []  []      [] []    [] []    [] []     |
-     shared-mime-info   |       [] []  []                     [] [] []     |
-     sharutils          |       []                []             [] []     |
-     shishi             |       []                                         |
-     skencil            |          []  []                           []     |
-     solfege            |              []                                  |
-     soundtracker       |                               []          []     |
-     sp                 |                                                  |
-     system-tools-ba... |    [] [] []  []      []             [] [] []  [] |
-     tar                |       []                []       []       []     |
-     texinfo            |       []             [] []                []     |
-     tin                |                         ()                       |
-     tuxpaint           |       [] []                      [] [] [] []     |
-     unicode-han-tra... |                                                  |
-     unicode-transla... |                                                  |
-     util-linux         |              []         []       []       []     |
-     util-linux-ng      |              []         []       []       []     |
-     vorbis-tools       |                         []                       |
-     wastesedge         |                                                  |
-     wdiff              |       []     []      [] []    [] []       []     |
-     wget               |          []             []    []          []     |
-     xchat              |    []                   []    [] [] [] [] []     |
-     xkeyboard-config   |                               [] []       []     |
-     xpad               |                               [] []       []     |
-                        +--------------------------------------------------+
-                          or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv  ta
-                           0  5 77 31  53    4 58 72  3 45 46  9 45 122  3
-
-                          tg th tk tr uk ven vi  wa xh zh_CN zh_HK zh_TW zu
-                        +---------------------------------------------------+
-     Compendium         |          []        []         []          []      | 19
-     a2ps               |          [] []     []                             | 19
-     aegis              |                    []                             |  1
-     ant-phone          |          []        []                             |  6
-     anubis             |          [] []     []                             | 11
-     ap-utils           |             ()     []                             |  4
-     aspell             |             []     []  []                         | 16
-     bash               |          []                                       |  6
-     bfd                |                                                   |  2
-     bibshelf           |                    []                             |  7
-     binutils           |          [] []     []                     []      |  9
-     bison              |          [] []     []                     []      | 20
-     bison-runtime      |             []     []         []          []      | 18
-     bluez-pin          |          [] []     []  []     []          []      | 28
-     cflow              |             []     []                             |  5
-     clisp              |                                                   |  9
-     console-tools      |          []        []                             |  5
-     coreutils          |          [] []     []                             | 18
-     cpio               |          [] []     []         []                  | 11
-     cpplib             |          [] []     []         []          []      | 12
-     cryptonit          |                    []                             |  6
-     dialog             |                    []  []     []                  |  9
-     diffutils          |          [] []     []         []          []      | 29
-     doodle             |                    []                             |  6
-     e2fsprogs          |          []        []                             | 10
-     enscript           |          [] []     []                             | 16
-     fetchmail          |          []        []                             | 12
-     findutils          |          [] []     []                             | 11
-     findutils_stable   |          [] []     []                     []      | 18
-     flex               |          []        []                             | 15
-     fslint             |                    []                             |  2
-     gas                |          []                                       |  3
-     gawk               |          []        []         []                  | 16
-     gcal               |          []                                       |  5
-     gcc                |          []                   []          []      |  7
-     gettext-examples   |          [] []     []         []    []    []      | 29
-     gettext-runtime    |          [] []     []         []    []    []      | 28
-     gettext-tools      |          [] []     []         []          []      | 20
-     gip                |                    []                     []      | 13
-     gliv               |          []        []                             | 11
-     glunarclock        |                    []  []                 []      | 15
-     gmult              |          []        []         []          []      | 16
-     gnubiff            |                    []                             |  2
-     gnucash            |          () []                                    |  5
-     gnuedu             |                    []                             |  2
-     gnulib             |                    []                             | 10
-     gnunet             |                                                   |  0
-     gnunet-gtk         |          []        []                             |  3
-     gnutls             |                                                   |  4
-     gpe-aerial         |                    []         []                  | 14
-     gpe-beam           |                    []         []                  | 14
-     gpe-calendar       |                    []  []                         |  7
-     gpe-clock          |          []        []  []     []                  | 21
-     gpe-conf           |                    []  []     []                  | 16
-     gpe-contacts       |                    []         []                  | 10
-     gpe-edit           |          []        []  []     []          []      | 22
-     gpe-filemanager    |                    []  []                         |  7
-     gpe-go             |          []        []  []     []                  | 19
-     gpe-login          |          []        []  []     []          []      | 21
-     gpe-ownerinfo      |          []        []         []          []      | 21
-     gpe-package        |                    []                             |  6
-     gpe-sketchbook     |          []        []                             | 16
-     gpe-su             |          []        []  []     []                  | 21
-     gpe-taskmanager    |          []        []  []     []                  | 21
-     gpe-timesheet      |          []        []         []          []      | 18
-     gpe-today          |          []        []  []     []          []      | 21
-     gpe-todo           |                    []  []                         |  8
-     gphoto2            |             []     []         []          []      | 21
-     gprof              |          []        []                             | 13
-     gpsdrive           |                    []                             |  5
-     gramadoir          |                    []                             |  7
-     grep               |                    []                             | 12
-     gretl              |                                                   |  6
-     gsasl              |                    []         []          []      |  9
-     gss                |                    []                             |  7
-     gst-plugins-bad    |             []     []         []                  | 13
-     gst-plugins-base   |             []     []                             | 11
-     gst-plugins-good   |             []     []         []    []    []      | 16
-     gst-plugins-ugly   |             []     []         []                  | 13
-     gstreamer          |          [] []     []                             | 18
-     gtick              |             []     []                             |  7
-     gtkam              |                    []                             | 16
-     gtkorphan          |                    []                             |  7
-     gtkspell           |             []     []  []     []    []    []      | 27
-     gutenprint         |                                                   |  4
-     hello              |          [] []     []         []          []      | 38
-     herrie             |          []        []                             |  8
-     hylafax            |                                                   |  0
-     idutils            |          []        []                             | 15
-     indent             |          [] []     []         []          []      | 28
-     iso_15924          |                    []         []                  |  4
-     iso_3166           |    [] [] [] []     []  []     []    []    []      | 54
-     iso_3166_2         |                    []         []                  |  4
-     iso_4217           |    []    []        []         []    []            | 24
-     iso_639            |             []     []  []     []    []            | 26
-     jpilot             |          [] []     []         []                  |  7
-     jtag               |                    []                             |  3
-     jwhois             |          []        []                     []      | 13
-     kbd                |          [] []     []                             | 13
-     keytouch           |                    []                             |  8
-     keytouch-editor    |                    []                             |  5
-     keytouch-keyboa... |                    []                             |  5
-     latrine            |          []        []                             |  5
-     ld                 |          []        []         []          []      | 10
-     leafpad            |          [] []     []         []          []      | 24
-     libc               |          []                   []          []      | 19
-     libexif            |                    []                             |  5
-     libextractor       |                    []                             |  5
-     libgpewidget       |                    []  []     []                  | 20
-     libgpg-error       |                    []                             |  6
-     libgphoto2         |             []     []                             |  9
-     libgphoto2_port    |             []     []                     []      | 11
-     libgsasl           |                    []                             |  8
-     libiconv           |                    []  []                         | 11
-     libidn             |                    []         []                  | 11
-     lifelines          |                                                   |  4
-     lilypond           |                    []                             |  6
-     lingoteach         |                    []                             |  6
-     lprng              |                    []                             |  2
-     lynx               |          [] []     []                             | 15
-     m4                 |                    []         []          []      | 18
-     mailfromd          |             []     []                             |  3
-     mailutils          |             []     []                             |  8
-     make               |          []        []         []                  | 20
-     man-db             |                    []                             |  9
-     minicom            |                    []                             | 14
-     nano               |                    []         []          []      | 20
-     opcodes            |          []        []                             | 10
-     parted             |          [] []                            []      | 11
-     pilot-qof          |                    []                             |  1
-     popt               |          []        []         []          []      | 18
-     psmisc             |                    []         []                  | 10
-     pwdutils           |                    []                             |  3
-     qof                |                    []                             |  4
-     radius             |             []     []                             |  7
-     recode             |          []        []         []                  | 25
-     rpm                |          [] []     []                     []      | 13
-     screem             |                    []                             |  2
-     scrollkeeper       |          [] []     []                     []      | 26
-     sed                |          []        []         []          []      | 23
-     shared-mime-info   |             []     []         []                  | 29
-     sharutils          |          []        []                     []      | 23
-     shishi             |                    []                             |  3
-     skencil            |                    []                             |  7
-     solfege            |                    []                             |  3
-     soundtracker       |          []        []                             |  9
-     sp                 |          []                                       |  3
-     system-tools-ba... |    []    [] []     []     []  []          []      | 38
-     tar                |          [] []     []                             | 17
-     texinfo            |          []        []         []                  | 15
-     tin                |                                                   |  1
-     tuxpaint           |                    []  []                 []      | 19
-     unicode-han-tra... |                                                   |  0
-     unicode-transla... |                                                   |  2
-     util-linux         |          [] []     []                             | 20
-     util-linux-ng      |          [] []     []                             | 20
-     vorbis-tools       |             []     []                             |  4
-     wastesedge         |                                                   |  1
-     wdiff              |          []        []                             | 23
-     wget               |          []        []                     []      | 20
-     xchat              |             []     []         []          []      | 29
-     xkeyboard-config   |          [] []     []                             | 14
-     xpad               |                    []         []          []      | 15
-                        +---------------------------------------------------+
-       76 teams           tg th tk tr uk ven vi  wa xh zh_CN zh_HK zh_TW zu
-      163 domains          0  3  1 74 51  0  143 21  1  57     7    45    0  2036
-
-   Some counters in the preceding matrix are higher than the number of
-visible blocks let us expect.  This is because a few extra PO files are
-used for implementing regional variants of languages, or language
-dialects.
-
-   For a PO file in the matrix above to be effective, the package to
-which it applies should also have been internationalized and
-distributed as such by its maintainer.  There might be an observable
-lag between the mere existence a PO file and its wide availability in a
-distribution.
-
-   If November 2007 seems to be old, you may fetch a more recent copy
-of this `ABOUT-NLS' file on most GNU archive sites.  The most
-up-to-date matrix with full percentage details can be found at
-`http://translationproject.org/extra/matrix.html'.
-
-1.6 Using `gettext' in new packages
-===================================
-
-If you are writing a freely available program and want to
-internationalize it you are welcome to use GNU `gettext' in your
-package.  Of course you have to respect the GNU Library General Public
-License which covers the use of the GNU `gettext' library.  This means
-in particular that even non-free programs can use `libintl' as a shared
-library, whereas only free software can use `libintl' as a static
-library or use modified versions of `libintl'.
-
-   Once the sources are changed appropriately and the setup can handle
-the use of `gettext' the only thing missing are the translations.  The
-Free Translation Project is also available for packages which are not
-developed inside the GNU project.  Therefore the information given above
-applies also for every other Free Software Project.  Contact
-`coordinator@translationproject.org' to make the `.pot' files available
-to the translation teams.
-
diff --git a/ChangeLog b/ChangeLog
deleted file mode 100644 (file)
index 8169429..0000000
--- a/ChangeLog
+++ /dev/null
@@ -1,7324 +0,0 @@
-2010-02-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * m4/gettext.m4: New file, from gettext-0.17.
-       * m4/po.m4: New file, from gettext-0.17.
-       * m4/progtest.m4: New file, from gettext-0.17.
-
-
-2009-11-23     Lennart Poettering
-       06327b1: bump soname
-
-2009-11-20     Lennart Poettering
-       7ab8e83: alsa: fix minor sampling rate deviations before adjusting the buffer size
-       366e3eb: alsa: fix log output when the audio device refuses to give us again the same period settings we had before
-       a281aad: pulse: ask for timing updates both *before* and *after* triggering a stream state change so that in the STARTED/UNDERFLOW callbacks we accurate transport latency information
-       c13bf3d: pulse: delay smoother update only when unpausing, not when pausing, since we don't want the timer to advance when we are supposedly already paused
-       d6a851c: pulse: try to fix inaccuracy with uncork timing for streams that are created in corked state
-       5c90723: daemon: complain if user passes too many arguments
-
-2009-11-20     Colin Guthrie
-       3014081: Merge branch '0.9.20-stable' into stable-queue
-
-2009-11-18     Lennart Poettering
-       231417c: rygel: fix itemCount property for sources
-
-2009-11-16     Colin Guthrie
-       9f41584: build-sys: Fix missing trailing slash in 14eaf2
-
-2009-11-14     Sjoerd Simons
-       8edf2f0: build-sys: Make sure all alsa path config files are installed
-
-2009-11-11     Colin Guthrie
-       25537ff: device-manager: Update docs version -> 0.9.20
-
-2009-11-09     Colin Guthrie
-       725ab6c: device-manager: Update docs version -> 0.9.20
-
-2009-10-19     Colin Guthrie
-       ff71cbf: device-manager: Fix compiler warning.
-
-2009-10-10     Colin Guthrie
-       5382455: device-manager: Rather than flagging the device as available, just include the sink/source index with PA_INVALID_INDEX meaning unavailable
-
-2009-10-02     Colin Guthrie
-       af55f07: device-manager: Play nice with module-stream-restore.
-       1b31d8a: device-manager: Make use of PA_IDXSET_FOREACH when applying entries.
-       ab3502f: device-manager: Keep track as to whether or not the user specifically renamed the device.
-       654df0f: device-manager: No need to check the version after calling read_entry()
-       324eb21: device-manager: Fix typo in module loading script.
-
-2009-10-01     Colin Guthrie
-       3130403: device-manager: Add some scripts that are only run under KDE to load/initialise module-device-manager with routing turned on.
-       996fc1f: device-manager: Misc fixes to co-exist with other stream management/routing modules.
-       6e0dde1: device-manager: Misc fixes.
-       763de9e: device-manager: Fix the writing of the database when priority doesn't change.
-       d5dc700: device-manager: Add extra debug messages
-       8a5778d: device-manager: Change the prefer/defer options to a single 'reorder' command.
-
-2009-09-27     Colin Guthrie
-       45a4d26: device-manager: Don't notify clients on every subscription (it happens all the time).
-       ff633cb: device-manager: Save icon and report current availability over protocol.
-
-2009-09-26     Colin Guthrie
-       055ad89: device-manager: Expose the priority lists in the protocol extension.
-
-2009-09-21     Colin Guthrie
-       aa93410: device-manager: Add a function to dump the database which we do whenever we save it (and on startup)
-
-2009-09-20     Colin Guthrie
-       d9a3131: device-manager: Reroute streams when they change allowing the media.role to be updated mid-stream.
-       3072f65: device-manager: Refactor the routing method to allow the routing of a single stream
-       888a515: device-manager: More sensible names for internal functions
-       d81fa00: device-manager: Reroute the streams on startup and update our cache on enable.
-       df893f6: device-manager: Keep a cache of the highest priority devices for each role.
-       009d087: device-manager: Fix the database write mode
-       8863dbe: device-manager: Update exports
-       6e67653: device-manager: Some efficiency and safety tweaks
-       26f1ec7: device-manager: Allow the routing component to be turned on via a module argument as well as via protocol extn.
-       8d3d0d3: device-manager: Remove unused variables
-       5077fe1: device-manager: Set the most appropriate sink/source when new streams are created
-       470b625: device-manager: Add routing functions that are triggered when sinks/soruces are added/removed.
-       8c99667: device-manager: Add a function to get a list of the highest priority device indexes for each role.
-       d69eba3: device-manager: Remove unneeded logic for checking for and (un)loading module-stream-restore. We can co-exist
-       a0567fb: device-manager: Rough framework (slots etc.) for handling routing.
-       fd5a508: device-manager: debug and comments
-       2b71480: device-manager: Fix the freeing of the datum on prefer/defer.
-       0541028: device-manager: When a new device is encountered, initialise the priority list to an appropriate value
-       5e3f1c2: device-manager: Let subscribed clients know when something changes.
-       6d4afac: device-manager: Change the write function to a rename function.
-
-2009-09-19     Colin Guthrie
-       4981268: device-manager: Provide a method for prefering/defering a device.
-       a9bd1ab: device-manager: Fix copy+paste code that looped over the tagstruct when not necessary
-       c1ece6c: device-manager: Provide a way for clients to enable/disable role-based device-priority routing.
-       25f0545: device-manager: Update docs version -> 0.9.19 (predicted)
-
-2009-07-05     Colin Guthrie
-       bddebbf: device-manager: Fix copy+paste leftover
-
-2009-06-29     Colin Guthrie
-       58bc037: device-manager: Only store and save details for non-monitor sources
-
-2009-06-28     Colin Guthrie
-       276e953: device-restore: Fix the application of an entry to allow changing the name of devices.
-       b8b28ef: device-manager: Fix tagstruct description extraction (copy+paste blunder)
-       89c1f57: device-manager: Link native protocol library.
-       11f01de: device-manager: Export device-manager extension functions
-
-2009-06-27     Colin Guthrie
-       97eb065: device-manager: Fix indentation
-       0f6ace7: device-manager: Add an untested protocol extension.
-       4c68fe7: device-manager: Add a new module to keep track of the names and descriptions of various sinks.
-
-2009-11-11     Lennart Poettering
-       a79585e: i18n: fix LINGUAS
-       5471643: Merge remote branch 'origin/master-tx' into 0.9.19-stable
-       de2654c: daemon: add missing tty_fd definition
-       bff94c1: build-sys: bump soname
-       2c12df9: core: make cpuid code compile cleanly with 32bit PIC
-       ed5af77: core: adjust volume only when there is actually a memory block
-
-2009-11-10     Wim Taymans
-       9ad5671: protocol: use the right sample rate for sources
-
-2009-11-05     Lennart Poettering
-       409a9d0: jack: never try to autoconnect to MIDI ports
-       75f3b19: man: fix build with --disable-manpages
-       3b25302: alsa: disable timer-based scheduling inside a VM
-       5da0297: daemon: during startup say whether we run in a VM
-       1460374: core-util: add call to detect if we are called from within a VM
-       b47a9e7: alsa: introduce more standard path names
-
-2009-11-04     Lennart Poettering
-       ab573f2: alsa: cover 'Analog Output' control
-
-2009-10-31     Lennart Poettering
-       4323c9f: alsa: create a seperate mixer path for Speaker elements
-       8a26fbf: alsa: leave other headphone control enabled if possible
-       08d0654: alsa: lower priority for Headphone2 path
-       18018b3: alsa: cover Input Source:AUX IN
-       d711caa: alsa: cover Headphone2 mixer element
-       82d7b75: alsa: cover 'Digital Input Source' element
-       6fad765: alsa: cover Mic Jack Mode element
-       70da8d6: bluetooth: do not hand out access to devices that are not fully configured yet
-
-2009-10-30     David Yoder
-       bfb1735: daemon: realpath segfault fix
-
-2009-10-29     Wim Taymans
-       973a4eb: sink: simplify silence checks
-
-2009-10-30     Lennart Poettering
-       320d76f: daemon: don't crash if pa_realpath() fails
-
-2009-10-28     Lennart Poettering
-       732b468: protocol-native: if a client set volume/mute/device store it since it is user input
-       3dcdab6: libpulse: explain semantics of pa_stream_connect_playback() in more detail
-       0c31723: protocol-native: declare that user configured volumes are always absolute
-
-2009-10-12     Lennart Poettering
-       84e77cb: libpulse: add missing includes
-
-2009-10-07     Diego Elio 'Flameeyes' Pettenò
-       8d612d5: Fix build when using -fweb, accept both register and memory constraints.
-
-2009-10-06     Lennart Poettering
-       3201aec: position-event-sounds: never position test sounds in space
-       833bf30: alsa: disable period event only with tsched=1
-
-2009-10-02     Tor-Björn Claesson
-       c15bd97: loopback: Setting latency of module-loopback
-
-2009-10-04     Lennart Poettering
-       df49370: bluetooth: don't set auto_connect flag when discovering bt devices
-
-2009-11-09     vpv
-       ecaf971: Sending translation for Finnish
-       05ccf10: Sending translation for Finnish
-       7d5d76e: Sending translation for Finnish
-
-2009-10-30     kmilos
-       151c746: Sending translation for Serbian (Latin)
-       4392888: Sending translation for Serbian
-
-2009-10-29     Wim Taymans
-       cc1e90f: svolume: fix MMX error
-
-2009-10-26     thalia
-       e4259e7: Sending translation for Greek
-
-2009-10-23     igor
-       99dcbc7: Sending translation for Brazilian Portuguese
-
-2009-10-22     igor
-       6d8d0ff: Sending translation for Brazilian Portuguese
-
-2009-10-22     kami911
-       037df85: Sending translation for Hungarian
-       80e43f6: Sending translation for Hungarian
-
-2009-10-18     perplex
-       45409d5: Sending translation for Italian
-
-2009-10-17     pmkovar
-       662986f: Sending translation for Czech
-
-2009-10-17     kami911
-       6e8c64f: Sending translation for Hungarian
-       6614be9: Sending translation for Hungarian
-       497b981: Sending translation for Hungarian
-
-2009-10-15     kami911
-       55ccda6: Sending translation for Hungarian
-
-2009-10-14     reinouts
-       a620a39: Sending translation for Dutch
-
-2009-10-09     kami911
-       72ac187: Sending translation for Hungarian
-
-2009-10-06     mvdz
-       5331e60: Sending translation for Ukrainian
-
-2009-10-04     fgonz
-       3aec580: Sending translation for Spanish
-
-2009-10-02     warrink
-       e8bab13: Sending translation for Dutch
-
-2009-10-01     kami911
-       8cfd01e: Sending translation for po/hu.po
-
-2009-09-30     pmkovar
-       7e0bccf: Sending translation for Czech
-
-2009-09-30     raven
-       fc74fc1: Sending translation for Polish
-
-2009-09-30     warrink
-       f2f37b5: Sending translation for Dutch
-
-2009-09-30     Lennart Poettering
-       afd1b6d: build-sys: bump soname
-       c622f77: i18n: run make update-po
-
-2009-09-29     Lennart Poettering
-       6a3b51a: i18n: ad more .c files to POTFILES.in
-       b8de3bd: polkit: drop left-over polkit policy file from git tree
-
-2009-09-26     Nix
-       eac5662: Don't refuse to start on systems using GNU stow, graft, STORE et al
-
-2009-09-29     Lennart Poettering
-       faf113d: i18n: run make update-po
-       0c84757: Merge remote branch 'origin/master-tx'
-
-2009-09-28     Lennart Poettering
-       d06f2ea: reserve: downgrade reserve logic messages, so that reusing pa in two sessions does not create spew in syslog
-
-2009-09-28     jsimon
-       c992ad2: Sending translation for German
-       966a259: Sending translation for German
-
-2009-09-27     raven
-       31d59de: Sending translation for Polish
-
-2009-09-23     Wim Taymans
-       5eecd8e: svolume: tweak constraints for 32 bits
-
-2009-09-22     ruigo
-       c04b75a: Sending translation for Portuguese
-
-2009-09-22     Colin Guthrie
-       8f4940b: libpulse: Add *_NOFLAGS flags with value 0 for various enums
-
-2009-09-22     shanky
-       183c9ab: Sending translation for Kannada
-
-2009-09-21     anipeter
-       c4b154b: Sending translation for Malayalam
-
-2009-09-21     sandeeps
-       f078e69: Sending translation for Marathi
-
-2009-09-21     kkrothap
-       20a5b0e: Sending translation for Telugu
-
-2009-09-21     rajesh
-       e8692bc: Sending translation for Hindi
-
-2009-09-20     Colin Guthrie
-       c194db7: tunnel: fix parsing of source info from newer servers
-       cc6932c: stream-restore: Comment fix
-
-2009-09-20     Emil Renner Berthing
-       592345f: tunnel: fix parsing of sink info from newer servers
-
-2009-09-20     Lennart Poettering
-       e7686a6: core: dump proplist when creating stream similar to how we already to it for sinks/sources
-       88b7773: alsa: make build gcc clean on 32bit
-
-2009-09-19     Lennart Poettering
-       33b45cd: Merge remote branch 'origin/master-tx'
-       6c0317d: build-sys: bump soname for release
-       ab6ed06: vala: install .vapi file by default
-       3fe9f8f: vala: numerous updates
-
-2009-09-18     ricardopinto
-       e141ddc: Sending translation for Portuguese
-
-2009-09-19     Lennart Poettering
-       996051e: memtrap: properly add items to linked list
-
-2009-09-18     Lennart Poettering
-       56e1290: gconf: run the wrapper script when running gconf-helper from build tree
-       8ad8e39: namereg: choose default sink/source as soon as one becomes available
-       1d19d6b: i18n: run make update-po
-       3cb8e01: Merge remote branch 'origin/master-tx'
-       9697c5d: memblock: don't try to reuse PA_MEMBLOCK_APPENDED memblocks since they usually are much bigger than we want them
-       f84d755: mainloop: fix detection of rt clocks
-       cd5d6e7: socket-client: modernizations
-       c010172: memblock: modernizations
-       d629151: mainloop: pass monotonic times back to user if he passed monotonic times to us
-       c024aea: timeval: make timeval conversion routines handle PA_USEC_INVALID special
-       a1da83b: timeval: add UNLIKELY annotation
-       05f6236: timeval: make pa_timeval_sub saturating
-       fdec460: core-rtclock: introduce pa_timespec_store() akin pa_timeval_store()
-       f7d3896: timeval: introduce PA_USEC_MAX
-       56f217f: macro: introduce PA_INT_TYPE_MIN, PA_INT_TYPE_MAX, PA_INT_TYPE_SIGNED macros
-       fb4a2a1: mainloop: sum up dispatched events in an unsigned to clarify range
-       18d69c5: mainloop: use PA_LLIST_FOREACH macros where applicable
-       b32f599: mainloop: don't initialize fields we don't have to
-       a049909: mainloop: calculate in pa_usec_t everywhere
-       a43118b: mainloop: properly convert time to wallclock time when handing it to the user
-       a37e48a: alsa: fix Surround mixer element name
-
-2009-09-18     Colin Guthrie
-       8f29968: conf: Fix typo in daemon.conf: rlimit-rtttime - too many t's
-       fd25e8f: alsa: Give all ports a human name to allow UI tools to present the choice to users.
-       0323e48: rtp: Remove 'fix me' comment after it was actually fixed in [56b6e1]
-       56b6e18: rtp: Factor out direct io writing and use ioline instead.
-
-2009-09-18     ifelix
-       62b8780: Sending translation for Tamil
-
-2009-09-18     ricardopinto
-       774b37e: Sending translation for Portuguese
-
-2009-09-16     Colin Guthrie
-       94d20a5: raop: Use pa_module_unload_request_by_index as per module-zeroconf-discover
-
-2009-09-17     Lennart Poettering
-       7b76ea3: core-util: unify how we determine the temporary directory
-       2d9168c: Improve TMPDIR handling
-       3de5c49: cli: properly destruct cli object
-       b4d4f2b: cli: don't accidentaly set O_NDELAY on stderr
-       94f28b9: proplist: introduce PA_PROP_WINDOW_DESKTOP property
-       add4cbf: position-event-sounds: don't warn that loud about vpos/hpos out of range
-       cdbeac6: libpulse: as a special exception, don't require a non-NULL context in pa_context_errno
-       231c17b: svolume_mmx: disable test accidentaly left on
-       4e6dce5: Merge remote branch 'wtay/optimize'
-       1a6974a: pacat: use fully automatic buffer sizes if possible
-       e2899f8: memblock: make it easy to disable mempool usage with $PULSE_MEMPOOL_DISABLE
-       6b8fdc4: CANCELLED vs. CANCELED
-
-2009-09-17     Vladimir Kokarev
-       e63c867: alsa: correct assumptions about channels an element lacks
-
-2009-09-16     kmilos
-       15da2f2: Sending translation for Serbian (Latin)
-       0c8498a: Sending translation for Serbian
-
-2009-09-12     Wim Taymans
-       3d5a572: svolume_mmx: optimize some more
-       d397a82: svolume_sse: fix comment
-
-2009-09-15     vpv
-       3c89dc0: Sending translation for Finnish
-
-2009-09-15     Lennart Poettering
-       12f2111: gccmacro: enable weakrefs only on ELF
-
-2009-09-14     fab
-       19968fe: Sending translation for Swiss German
-       7c80d2c: Sending translation for German
-
-2009-09-14     mvdz
-       4382519: Sending translation for Ukrainian
-
-2009-09-12     xconde
-       e35101b: Sending translation for Catalan
-
-2009-09-12     raven
-       6e76544: Sending translation for Polish
-
-2009-09-11     warrink
-       66eb022: Sending translation for Dutch
-
-2009-09-11     beckerde
-       cc597d6: Sending translation for Spanish
-
-2009-09-11     swkothar
-       030dfad: Sending translation for Gujarati
-
-2009-09-11     mgiri
-       9267201: Sending translation for Oriya
-
-2009-09-11     jassy
-       e706a84: Sending translation for Punjabi
-
-2009-09-11     Lennart Poettering
-       180ef1e: position-event-sounds: apply volume factor after, not before resampling
-       a015d56: core: add an additional volume factor that is applied after resampling took place
-       6fa2445: position-event-sounds: honour window position if set, position both vertically and horizontally
-       5919337: proplist: define properties for storing window position
-       42b795b: doxygen: don't confuse doxygen with spurious ..
-       4e3f7d5: doxygen: add rtclock.h to documentation
-       297f318: doxygen: drop references to pacat.c and paplay.c as examples since tehy are not useful as such and in the case of paplay not even existant anymore
-       7e43371: build-sys: increase library version
-       a7ab04f: i18n: run make update-po
-       2f11884: i18n: add ja to LINGUAS
-       67bed86: Merge remote branch 'origin/master-tx'
-       80b4457: alsa: properly report suspension error codes
-       bb36bb4: alsa: properly convert sample buffer sizes
-       5460967: libpulse: add new error code PA_ERR_BUSY
-
-2009-09-10     warrink
-       64e8eb7: Sending translation for Dutch
-
-2009-09-10     hyuuga
-       8bdec63: Sending translation for po/ja.po
-
-2009-09-10     kkrothap
-       27b3a74: Sending translation for Telugu
-
-2009-09-10     runab
-       5d264fd: Sending translation for Bengali (India)
-
-2009-09-10     rajesh
-       c67c46e: Sending translation for Hindi
-
-2009-09-10     ifelix
-       d0df346: Sending translation for Tamil
-
-2009-09-10     sandeeps
-       a81ee39: Sending translation for Marathi
-
-2009-09-10     swkothar
-       c49f3f9: Sending translation for Gujarati
-
-2009-09-10     anipeter
-       c471d4d: Sending translation for Malayalam
-
-2009-09-10     jassy
-       3fd8e7d: Sending translation for Punjabi
-
-2009-09-10     amitakhya
-       7f799d4: Sending translation for Assamese
-
-2009-09-10     Lennart Poettering
-       12c7460: libpulse: don't support pa_context_get_card_info_list() on servers that cannot handle it
-       807f2a9: native: send PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED messages only to clients that understand it
-       b043207: i18n: run make update-po
-       a41c510: Merge remote branch 'origin/master-tx'
-       f3879f8: i18n: run make update-po
-       b2de8d8: i18n: get rid of ko.po/ru.po since they contain exactly 0 translated strings
-       9c65e5b: add ml to LINGUAS
-       43c3164: Merge remote branch 'origin/master-tx'
-
-2009-09-09     Lennart Poettering
-       d5f43bd: alsa: disable tsched for software devices before we configure the buffer metrics so that we don't accidently set a buffer size that is suitable for tsched where we don't use tsched
-       8364b95: alsa: when probing for profiles configure buffer/period sizes since some broken drivers apparently need that
-       84ade21: alsa: pass SND_PCM_NONBLOCK when opening device during unsuspend, the same way we do it for initial opening
-       557c429: alsa: rework buffer/period configuration
-       71e066c: simd: be more precise which SIMD optimizations we activate
-       1f0904b: sample-util: add pa_convert_size() call for converting sizes between two sample specs
-       c2f1994: udev: ratelimit device initializations
-       12df686: ratelimit: allow non-static ratelimit structs
-
-2009-09-09     kmilos
-       4f24a62: Sending translation for Serbian (Latin)
-       8a9166f: Sending translation for Serbian
-
-2009-09-09     soko
-       4dee032: Sending translation for Serbian (Latin)
-       3984dd5: Sending translation for Serbian
-
-2009-09-09     mgiri
-       399b0ad: Sending translation for Oriya
-
-2009-09-09     kkrothap
-       4539250: Sending translation for Telugu
-
-2009-09-09     pmkovar
-       3a47c80: Sending translation for Czech
-
-2009-09-08     Lennart Poettering
-       7cc100d: padsp: properly return return values (llvm-clang-analyzer)
-       b51f5e5: pacat: don't convert stream name twice (llvm-clang-analyzer)
-       49bc6bc: stripnul: initialize 'found' bool properly (llvm-clang-analyzer)
-       31d1d90: protocol-native: log explicitly when someone asks us to quit
-       31ae7de: core-util: properly fill in exception array for pa_reset_sigs() (llvm-clang-analyzer)
-       1516b7c: conf-parser: properly initialize variable we free() later (llvm-clang-analyzer)
-       3c9a09b: cli-command: don't necessarily ovveride failure code of files (llvm-clang-analyzer)
-       5fd751f: cli-command: modernizations
-       05506d7: utf8: minor simplification
-       f3be47f: rtsp: document that rtsp_exec() needs fixing (llvm-clang-analyzer)
-       157ec79: hal: check properly for failure of libhal_find_device_by_capability() (llvm-clang-analyzer)
-       1380f18: blueooth: actually honour 'room' variable (llvm-clang-analyzer)
-       382eced: alsa-sink: init after_avail earlier (llvm-clang-analyzer)
-       f504675: llvm-clang-analyzer: drop a few unnecessary assignments and other trivial fixes
-
-2009-09-08     shanky
-       98fcf4e: Sending translation for Kannada
-
-2009-09-08     mvdz
-       6bdda4c: Sending translation for Ukrainian
-
-2009-09-07     Lennart Poettering
-       b2606cf: i18n: move \r out of translatable string
-       508c462: Merge remote branch 'wtay/optimize'
-       08a4d57: libpulse: allow invocation of pa_context_play_sample_with_proplist() with NULL proplist
-       f8f8cdc: vala: reindent
-       b705a9b: vector: don't try to build vector stuff on altivec
-       a02861e: vala: s/PropList/Proplist/g since the C version does not use an underscore there
-       0b8f239: vala: add vala .vapi file for the PulseAudio APIs, but don't include them in the tarball for now
-       41a0dc1: volume: if pa_cvolume_set_{balance     d000dd6: volume: when passing NULL as channel map to pa_cvolume_scale_mask() handle this the same way as pa_cvolume_scale()
-       9755bfa: volume: drop some redundant but expensive validity checks
-       cc6c4fe: volume: add a couple of validity checks for pa_volume_t arguments
-       3bbc5e6: volume: fix definition of PA_VOLUME_MAX and introduce PA_VOLUME_INVALID and use it wherever applicable
-
-2009-09-07     shanky
-       6c385eb: Sending translation for Kannada
-
-2009-09-07     jassy
-       b96de8e: Sending translation for Punjabi
-
-2009-09-07     Wim Taymans
-       7234994: x86: also call see init for SSE2
-       b5ac383: x86: only install some functions when SSE2
-
-2009-09-07     warrink
-       942bd46: Sending translation for Dutch
-
-2009-09-07     mgiri
-       f969ce6: Sending translation for Oriya
-
-2009-09-07     sandeeps
-       35ffd1b: Sending translation for Marathi
-
-2009-09-07     ifelix
-       efebe09: Sending translation for Tamil
-
-2009-09-06     Lennart Poettering
-       5cf0c1e: introspect: rearrange order of functions a bit
-       e6a666d: libpulse: introduce PA_BYTES_SNPRINT_MAX and make use of it wherever applicable
-
-2009-09-05     xconde
-       646f666: Sending translation for Catalan
-
-2009-09-04     vpv
-       14ec32f: Sending translation for Finnish
-
-2009-09-04     warrink
-       124e3dc: Sending translation for Dutch
-
-2009-09-04     runab
-       d5fb6d3: Sending translation for Bengali (India)
-       8d03381: Sending translation for Bengali (India)
-
-2009-09-04     anipeter
-       b6030d3: Sending translation for po/ml.po
-
-2009-09-04     rajesh
-       2ad5e33: Sending translation for Hindi
-
-2009-09-04     Lennart Poettering
-       812be32: daemon: disable CPU load limiter by default
-       5daecea: always-sink: rename null sink created to 'dummy sink' and make it translatable
-       0ad6a57: null: make name of null sink translatable
-
-2009-09-03     beckerde
-       ab1af38: Sending translation for Spanish
-
-2009-09-03     raven
-       71dd5a0: Sending translation for Polish
-
-2009-09-03     swkothar
-       ef9138d: Sending translation for Gujarati
-
-2009-09-03     Lennart Poettering
-       8cd635b: alsa: add more input sources to path set
-       7ca81bd: i18n: run make update-po
-       8539539: i18n: fix LINGUAS
-       1213a7c: Merge commit 'origin/master-tx'
-       6f396c8: remap: build sse code only on x86
-       14a9771: core: drop unnecessary variable initialization
-       d088c8f: daemon: make use of SIMD optional via config variable to ease debugging
-       9f4f374: remap_sse: fix inner loop increment on SSE
-       51423ca: remap_sse: reindent macro so that diff to MMX is nicer
-
-2009-09-02     Wim Taymans
-       26164ff: sconv_sse: fix leftover counter
-
-2009-09-02     Lennart Poettering
-       51fc176: Merge branch 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
-       39e4652: daemon: drop polkit code from git repo we weren't using anymore
-       297afad: core-util: don't leak memory in pa_unset_env_recorded()
-       767c7c7: core-util: call dbus_connection_set_exit_on_disconnect() on shared busses to make sure dbus_shutdown() isn't fatal
-       470e9a8: build-sys: drop LIBOIL_{FLAGS  1200a0b: sink: simplify pa_sink_render_full() by replacing it by a pa_sink_render() plus a couple of pa_sink_render_full()
-       a8c0f65: daemon: clean up environment when forking off children
-       5f92996: core-util: add api for setting env vars and record them so that we can undo them n fork
-
-2009-09-01     Lennart Poettering
-       45513a2: core: fill up memblock with pa_sink_render_into_full() in pa_sink_render_full() instead of doing our own loop
-       17f609a: core: handle suspended state in pa_sink_render_full() similar to the other render functions
-       ce6dff4: core: add missing sink_unref()
-       b245b54: ladspa,remap: make description of sink follow moves
-       46b9ca7: alsa: by default increase watermarks only on real underruns, don't try to be smart
-       6b6d146: alsa: distuingish real underruns from left_to_play=0
-       dfe3f90: daemon: don't override path env vars if they are already set
-
-2009-09-01     sandeeps
-       350b8ac: Sending translation for Marathi
-
-2009-09-01     ifelix
-       605fa59: Sending translation for Tamil
-
-2009-08-29     Wim Taymans
-       dc221f2: remap: fix counters for mmx and sse remap
-
-2009-08-31     Lennart Poettering
-       dee2aa3: pactl: drop unnecessary newlines from pa_log() invocations
-       5b61a19: pactl: implement pactl commands for changing volumes/mute stati
-       e20d906: cli: make sure 'dump' uses pa_cvolume_max() to deduce a single-channel volume from a multi-channel volume
-       7c6a0ec: cli: apply single-channel volume changes equally to all channels
-       2970c11: core: always allow volume setting with single-channel pa_cvolume
-
-2009-08-31     perplex
-       9efc2af: Sending translation for Italian
-
-2009-08-30     vpv
-       b143a8f: Sending translation for Finnish
-       8774166: Sending translation for Finnish
-
-2009-08-29     raven
-       844399d: Sending translation for po/LINGUAS
-
-2009-08-29     Lennart Poettering
-       e1ce365: native: make sure clients cannot trigger an assert by sending us invalid volume info
-       8bf2e3f: core: initialize sink/source priorities automatically based on their proplists
-       18b13a8: namereg: select default sink by priority
-       a7b3125: protocol-native: replace use of pa_namereg_is_valid_name() by pa_namereg_is_valid_name_or_wildcard() where applicable to allow use of @@ wildcards
-       85a683f: namereg: add new pa_namereg_is_valid_name_or_wildcard() call
-
-2009-08-28     pmkovar
-       5111101: Sending translation for Czech
-
-2009-08-28     Lennart Poettering
-       3b54849: core: add priority field to pa_sink/pa_source
-       ca2c0f2: sconv: quieten gcc a bit
-       f029041: suspend-on-idle: don't resume devices for corked streams
-       84eb661: core: move 'flags' field into 'pa_sink_input_new_data' structure so that hooks can access it
-       9011c4e: build-sys: make proximity helper properly suid
-       63f3dc0: bluetooth: remove left-over debug line
-
-2009-08-28     Andy Shevchenko
-       300384c: Fix checking for NULL after usage
-       ae38353: core-util: Fix logic of pa_make_path_absolute()
-       4e8562c: raop: Fix memory leak
-
-2009-08-27     Lennart Poettering
-       db835de: Merge commit 'vudentz/master'
-
-2009-08-27     Luiz Augusto von Dentz
-       8169a6a: Handle DisconnectRequested in bluetooth module.
-
-2009-08-26     Wim Taymans
-       beb180b: convert: add sse/sse2 s16 to float32ne conversions
-       27bfb76: macro: add macro to align variables
-       5907089: remap: cleanup assembler a little
-
-2009-08-25     Wim Taymans
-       9d25467: sample-util: avoid stack overrun
-       509d9f0: remap: add sse optimized mono to stereo
-
-2009-08-24     Wim Taymans
-       26bd090: sconv: fix indentation
-
-2009-08-27     Lennart Poettering
-       35fcb27: proplist: allow setting of zero-length data properties
-       5df842d: sink-input: extend comments on rewinding logic a bit
-       c372b52: protocol-native: print more volume change debug messages to easy tracking down of feedback loops
-       cab48d4: protocol-native: compare uint64_t variable with (uint64_t) -1 instead of (size_t) -1 for compat with 32bit archs
-
-2009-08-26     Lennart Poettering
-       44b7982: pdispatch: various modernizations
-       34829eb: pdispatch: add missing commands to command table
-       4e1298d: llist: add PA_LLIST_FOREACH_SAFE macro for iteration that allows deleting
-       368c3e3: loopback: quieten gcc on 32bit
-       4614412: loopback: update description and icons when moving loopback streams
-       d909f59: loopback: make sure a monitor can't be looped back to its sink
-       99d3e6b: combine: store adjust time in usec
-       ea4b65b: loopback: add loopback module for direct connections of sinks and sources
-       827ae07: macro: add PA_CLIP_SUB() for saturated subtraction
-
-2009-08-25     mvdz
-       4544873: Sending translation for Ukrainian
-
-2009-08-25     giallu
-       956ff24: Sending translation for Italian
-
-2009-08-25     ypoyarko
-       cdf7e02: Sending translation for po/ru.po
-
-2009-08-25     Finn Thain
-       457b973: Solaris: debug my latest enbugging, take 2
-
-2009-08-24     igor
-       7a2d1d3: Sending translation for Brazilian Portuguese
-
-2009-08-24     Lennart Poettering
-       57e1f84: Merge commit 'jprvita2/master'
-       57fb771: remap: fix build for non-x86 builds
-       419b071: detect: recommend module-udev-detect instead of module-hal-detect
-       ba17ff4: build-sys: add missing header files to tarball
-
-2009-07-24     João Paulo Rechi Vita
-       2772521: bluetooth: add discover of bluetooth sources
-
-2009-07-30     João Paulo Rechi Vita
-       65c3e65: bluetooth: handle bluetooth source
-
-2009-08-24     Lennart Poettering
-       be46eaa: i18n: run make update-po
-       60a3502: Merge commit 'origin/master-tx'
-       050a3a9: alsa: automatically decrease watermark after a time of stability
-
-2009-08-23     Lennart Poettering
-       80c6937: alsa: increase interval between smoother updates exponentially for alsa sources, following the scheme for sinks
-       a0f01dd: port a few things over to use xmalloc and friends instead of low-level libc malloc/free directly
-       ab5ac06: Merge commit 'wtay/optimize'
-
-2009-08-23     beckerde
-       57117d4: Sending translation for Spanish
-
-2009-08-22     Lennart Poettering
-       d6fb8d1: udev: check busy status of alsa cards before loading alsa modules and hence initiating profile probing
-       560da5b: udev: process all inotify events queued up, not just the first one in the queue
-       1a05d67: core: relex validity checks when destructing half-set up source outputs/sink inputs
-       5b0683d: ladspa/remap: handle failing stream moves properly
-       2595b9d: add usergroup-test to .gitignore
-       aa54298: daemon: don't free script_commands twice
-
-2009-08-22     raven
-       857e055: Sending translation for Polish
-
-2009-08-21     Ted Percival
-       17dc410: core: Remove wrong doc on how to free returned data
-       15eb03a: core: Add thread-safe group info functions with dynamic buffers
-
-2009-08-21     Finn Thain
-       601fb63: Solaris: fixed latency (resent)
-       87d2dde: Solaris: use smoother (resent)
-       44c7aa5: Solaris: build fixes (resent)
-       b96390f: Solaris: bootstrap portability
-
-2009-08-22     Lennart Poettering
-       9d1cc13: i18n: run make update-po
-       aaf0d5a: Merge commit 'origin/master-tx'
-
-2009-08-21     Scott Reeves
-       de19bdd: daemon: fix leak of script_commands
-
-2009-08-21     Lennart Poettering
-       066e160: udev: tell inotify to actually inform us about ACL changes
-       2d01204: udev: watch for both ACL changes and processes closing devices
-       4ec701a: udev: don't access string after free()
-       d06680a: udev: always verify access before loading modules
-       14c27c7: gconf: use correct path for gconf-helper tool when running from build tree
-       9abc010: object: speed up type verification by not relying on strcmp()
-       5317e35: udev: when a device appears that we cannot access right-away try again later on inotify
-       fe9a577: alsa: leave headphone jack enabled in normal mixer paths
-       ac05619: combine: quieten gcc a bit
-       8a2a6b2: adjust various data/library paths automatically if we are run from a build tree
-       a562978: ladspa: forward volume changes from ladspa sink to stream and hence via flat volume logic to master sink
-       9f97b7c: sink-input: add callbacks that are called whenever the mute/volume changes
-
-2009-08-21     igor
-       c5d7860: Sending translation for Brazilian Portuguese
-
-2009-08-20     Wim Taymans
-       6076cef: remap: make the MMX code pretier
-       6e5dbed: remap: add MMX mono to stereo
-       e961efc: remap: init the do_remap function to NULL
-       28baa53: remap: allow specialisations to install NULL
-       ac1f2e0: remap: move remapping code in separate file
-       a3f4a4f: resamples; refactor the channel remapping bits
-       05fef5f: sconv: allow for setting custom functions
-       c1b6a87: alsa-sink: reduce the amount of smoother updates
-       f8ffe0d: svolume: cleanups
-       f09b511: whitespace fixes
-
-2009-08-19     Wim Taymans
-       3cc1278: resampler: avoid some multiplies when we can
-       aeae567: svolume: add comment
-       8aa86f5: arm: implement ARM cpu detection
-       078bde1: x86: keep the cpu flags local
-       370016c: svolume: fix compilation in 32bits
-       d2389ef: sample: manually inline table lookups
-       548b735: resampler: fix identity check
-       d04a6e9: resample: fix counters
-       b4e9942: resample: refactor the channel remapping a little
-       bd49d43: svolume: add CPU guards around code
-       951bf1b: svolume: add ARM optimized volume scaling
-       a98fa95: svolume: remove unneeded compare
-
-2009-08-17     Wim Taymans
-       601e5f1: resampler: cache integer channel_map
-
-2009-08-14     Wim Taymans
-       25724cd: Get rid of liboil
-       591baac: volume: remove ref functions
-       f24c24c: volume: improved comments
-       a123544: volume: make the benchmark more meaningfull
-       dcae9a3: svolume: add some comments
-
-2009-08-13     Wim Taymans
-       e396fe6: cpu-x86: guard header with ifdef
-       563cb2d: main: hook up cpu detection code
-       a83f552: cpu-x86: add cpu detection code and helpers
-       5998cf9: svolume: improve SSE and MMX code
-
-2009-08-12     Wim Taymans
-       7086784: volume_sse: add sse optimisations
-       08f3e16: volume_mmx: fix mmx code a bit
-       3a0b012: volume: add first mmx optimized function
-       2d73f13: samples-util: add padding to volume array
-
-2009-08-11     Wim Taymans
-       3d00896: sample-util: move volume code to separate file
-       e71e644: sample-util: move some functions around
-       5b8b654: sample-utils: coding style cleanup
-       26839c4: sample-utils: split out functions from case
-
-2009-06-30     Xabier Rodriguez Calvar
-       52e5d4b: Modification of the thread-mainloop doc to ensure that nobody frees the api as it is owned by the loop.
-       65f86ef: Modification of the mainloop doc to ensure that nobody frees the api as it is owned by the loop.
-       30ba903: Modification of the glib-mainloop doc to ensure that nobody frees the api as it is owned by the loop.
-
-2009-08-20     Lennart Poettering
-       c5bd725: core: check return value of getgrnam_r() instead of errno
-
-2009-08-19     raven
-       d2f50ea: Sending translation for Polish
-
-2009-08-19     beckerde
-       9b6add3: Sending translation for Spanish
-
-2009-08-19     Lennart Poettering
-       f4f16ab: i18n: run make update-po
-       8f29090: i18n: add ko to LINGUAS
-       b2cb8ef: Merge commit 'origin/master-tx'
-       7af3833: lirc: replace manual code by pa_cvolume_{inc   2f54798: mmkbd: replace manual code by pa_cvolume_{inc  8c31974: sink: volume handling rework, new flat volume logic
-       5207e19: match: document how broken the module-match logic is
-       cfef930: volume: introduce pa_cvolume_{inc      1421eff: volume: use PA_VOLUME_MAX instead of (pa_volume_t) -1
-       d6f598a: udev: allow passing of ignore_dB= parameter to alsa modules
-       24e5828: source: rework volume handling
-       2838b78: macro: extend comments a bit
-       a69b729: voltest: extend test to verify correctness of _multiply() and _divide()
-       2223a9f: dbus: never return DBUS_HANDLER_RESULT_HANDLED in filter callbacks, since other callbacks might stell want to have the messages
-       ef01baf: volume: round properly when showing human readable volume percentages
-       96f01b8: volume: simplify volume multiplifactions, do them in integer only
-       d634555: volume: introduce pa_cvolume_min() and pa_cvolume_min_mask()
-
-2009-08-17     Lennart Poettering
-       8f928b2: macro: simplify page/word alignment macros a bit
-       fe3a21f: macro: add PA_ROUND_UP/PA_ROUND_DOWN macros
-       319d187: bluetooth: fix match syntax
-       90a0743: bluetooth: make NameOwnerChanged filter matches more focussed
-       ffeb1b8: volume: document when arguments of certain functions may overlap
-       caa7928: libpulse: some minor optimizations when checking equality
-       50de2d8: channelmap: minor doxygen fix
-       6dd580d: channelmap: document where the WAVEX channelmap is documented
-       32a1ef3: channelmap: adjust RFC3551 channel maps to follow spec more closely
-       c579cb5: reserver: update from upstream git
-       8208214: volume: add pa_cvolume_merge() call
-
-2009-08-17     pmkovar
-       91e06c1: Sending translation for Czech
-
-2009-08-16     Lennart Poettering
-       01e4b61: aupdate: implicitly call _write_swap() if it wasn't called explicitly
-       8dd0d87: core: add to FIXMEs
-       4c29ba9: modules: add various checks to avoid selecting objects that are not linked or in another unclear state
-       2a39663: bluetooth: move installation of mq's earlier to avoid context asserts to be triggered
-
-2009-08-15     Lennart Poettering
-       de4968c: bluetooth: ask first for Headset and AudioSink properties, followed by Audio
-       fa52a91: bluetooth: recognize only those BT devices that implement both the Audio and either AudioSink or Headset interfaces
-       5c90cf2: bluetooth: drop PA_BT_AUDIO_STATE_LAST since it is unused and we normally call that _MAX anyway
-       011add1: thread-mq: do final q flush only when we aren't dispatching anyway
-       0c20e74: asyncmsgq: introduce pa_asyncmsgq_dispatching()
-       e5b08a8: ladspa/remap: sync latency flags from master sink when moving between sinks
-       0c08dbd: core: introduce pa_{sink
-2009-07-20     Marc-André Lureau
-       d8a90a3: pulse: even in case of record stream, let's initialize req_bytes to 0
-       3ecb80e: bluetooth: fix typo with service_{read,write}_type
-
-2009-07-06     Marc-André Lureau
-       fd32fee: bluetooth: don't call pa_sink_render with 0 bytes request
-
-2009-08-12     Juho Hämäläinen
-       ea5cdcb: database: simple hashmap based database implementation
-
-2009-08-15     Maarten Bosmans
-       61105df: combine: determine sample parameters of combined sink from underlying sinks
-
-2009-08-15     Lennart Poettering
-       1eeddd8: combine: warn when the latency of a stream gets too high
-       e1f3f5e: combine: big rework
-       8947d65: combine: drop adjust_timestamp variable because it is unused
-       a5b2dee: ladspa: name sink after human readable plugin name, not the id string
-       7638662: module-ladspa: allow moving of sink, forward fixed latency
-       1b3848e: module-remap: allow moving of sink, forward fixed latency
-       c44f518: ladspa: move LADSPA_Data size check to compile time
-       fb5205d: remap: unify argument order with other modules
-       d9e4605: hook-list: make use of PA_LLIST_FOREACH
-       d7d86e3: native-protocol: downgrade volume change log messages
-       3c271ae: core: document difference between IO and main thread view on requested latency
-       c6080d8: core: don't update latency range if not changed
-       3f9c67a: core: call pa_sink_get_latency_within_thread() instead of going directly via process_msg()
-       350a2bc: core: make fixed latency dynamically changeable
-       4eb59fb: core: move rtpoll to thread_info sub structure
-       58d441f: log: place more rate limit invocations
-       fd1266c: rescure-stream: handle failed moves as well as dying sinks/sources
-       e4db56b: core: split of FAIL_ON_SUSPEND into KILL_ON_SUSPEND and NO_CREATE_ON_SUSPEND
-       e53d2fc: native: handle moving() callback with NULL destination properly
-       0989be1: core: introduce pa_{sink_input
-2009-08-14     Lennart Poettering
-       7891f96: module-stream-restore: don't fiddle with sinks/sources/streams that are not fully set up yet
-       0f2a4ed: volume: guarantee dB/linear conversion is reversible
-       72d2540: protocol-native: log explicitly each time a client triggers a volume change
-       a1598c7: daemon: reset gids too, not just uids
-       fecd0dc: resampler: round up when estimating input/output sizes
-       9e21182: thread-mq: never drop queued messages for the main loop
-       446fb2c: asyncmsgq: add pa_asyncmsgq_flush() call
-       a42c597: memblockq: add pa_memblockq_get_maxrewind() API
-       b0cabfe: shm: bump shm size limit to 1GB
-       aae7054: pacmd: handle multi word commands in argv[] properly
-
-2009-08-13     eukim
-       82b7e72: Sending translation for po/ko.po
-
-2009-08-13     Lennart Poettering
-       5ee4069: core: add functions to query max_rewind/max_request values from streams
-       9a95fe4: core: add assert macros for verifying calling context
-
-2009-08-12     Lennart Poettering
-       17d5741: start-child: clean up child environment a bit better
-       5fcb8a3: pacmd: port pacmd from select() to poll() so that we notice writer side hangups
-       286ab2f: memblock: rate limit 'Pool full' message
-       5921324: context: document why we only do minimal cleanups before the autospawn exec()
-       27b8cd7: daemon: reset scheduling priority on startup, too
-       ef176ec: core-util: move personality resetting into core-util
-       9f53aa5: daemon: unconditionally clean up priviliges
-       facae1f: conf: invert all negative boolean configuration option
-       8998cba: conf: add pa_config_parse_not_bool() for parsing inverse boolean configuration options
-       eb40da2: daemon: install D-Bus system policy file for PA system instances
-       e834034: alsa: enable ext. amplifier by default
-       462cdf4: alsa: adjust priority bonus of mappings that match the configured default channel map
-
-2009-08-11     Lennart Poettering
-       d27e26d: volume-restore: forward module load return value of stream-restore back to caller
-       c117feb: hal: replace subdevs= parameter by subdevices= parameter
-       c1039c9: udev: drop definition of LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE
-       c904f97: hal: add stub module that loads module-udev-detect instead of module-hal-detect
-
-2009-08-10     Lennart Poettering
-       ebe3596: Revert "build-sys: drop libcap checks, since we don't use caps anymore"
-       a99e3b5: Merge commit 'origin/master-tx'
-       d8d2697: Merge commit 'flameeyes/master'
-
-2009-08-09     Maxim Levitsky
-       23a294c: Correctly deal with events in the past in calc_next_timeout
-
-2009-08-10     logan
-       0f77afe: Sending translation for Spanish
-
-2009-08-08     igor
-       de68d36: Sending translation for Brazilian Portuguese
-
-2009-08-08     Lennart Poettering
-       9bd3398: mix-test: fix test for s24-32 samples
-       9ade136: build-sys: drop libcap checks, since we don't use caps anymore
-
-2009-08-08     Diego Elio 'Flameeyes' Pettenò
-       10e4171: Update the end-of-configuration summary for OSS output/wrapper split.
-       4c15115: Split OSS support in output and wrapper.
-
-2009-08-07     Lennart Poettering
-       7d49163: ladspa/remap: make sure we process all requested rewinds unconditionally
-       51b3899: core: save volume/mute changes coming from the hardware automatically
-
-2009-08-05     Lennart Poettering
-       aa7408b: run make update-po
-       42f92a8: Merge commit 'origin/master-tx'
-       8483de4: simple: bump libpulse-simple library revision
-       ff52588: smoother: readd #ifdef protection
-
-2009-08-05     ruigo
-       19f2ffb: Sending translation for Portuguese
-       40b2dde: Sending translation for Portuguese
-
-2009-08-04     ruigo
-       20d62e2: Sending translation for Portuguese
-
-2009-08-05     Lennart Poettering
-       2cab6a2: simple: check for == RUNNING instead of != DONE when waiting for operations
-       5bbeb51: simple: split data/length validity checks into two
-       53fcf3a: simple: call pa_context_disconnect() just to be sure
-       a73c615: simple: always loop around pa_threaded_mainloop_wait() to handle spurious wakeups properly
-       b553e72: simple: use pa_xnew0 instead of manual reset to 0
-       a4bc41a: simple: use PA_xxx_IS_GOOD for state checks
-
-2009-08-04     Luke Yelavich
-       5e61111: POTFILES - Remove references to more non-existant files in the source tree
-
-2009-08-04     Lennart Poettering
-       9b2534b: alsa: properly treat ESTRPIPE as system suspend
-
-2009-08-03     Lennart Poettering
-       3e2ab9b: client: extend documentation on pa_operation_cancel() a bit
-       a44cb64: build-sys: take preset CFLAGS into account
-
-2009-08-02     Lubomir Rintel
-       34f31f6: Recover stream when it's suspended upon rewind
-
-2009-08-01     Lennart Poettering
-       2778220: autospawn: if creating the lock file fails, pass error code cleanly back to main process
-       49fd8ee: core-util: replace remaining fixed size destination string functions by _malloc() versions
-       c6ea9fe: core-util: rework pa_strlcpy() to not rely on strncpy()
-       e5c2256: pipe: replace PIPE_BUF macro pa pa_pipe_buf call
-
-2009-07-31     Lennart Poettering
-       0113e72: hal: add option to initialize all subdevices of an OSS device
-       478f325: client: documented that pa_stream_drain() may only have a single operation active at a time
-       2952f28: client: fix documentation for threaded mainloop
-
-2009-07-01     Alam Arias
-       66db0c8: update pulse-daemon.conf.5.xml.in about realtime-scheduling
-       6d0c5a1: update pulse-daemon.conf.5.xml.in about exit-idle-time
-
-2009-07-31     Lennart Poettering
-       39aa1cf: alsa: revert to first set number of periods, then set buffer size
-       c14f6c1: tunnel: don't assert on misaligned reads, closes #597 and rhbz #496310
-
-2009-07-30     Lennart Poettering
-       4f5e2b7: threaded-mainloop: loop around pa_cond_wait() invocation in pa_threaded_mainloop_signal()
-
-2009-07-28     igor
-       7463edd: Sending translation for Brazilian Portuguese
-
-2009-07-28     raven
-       1cc375c: Sending translation for Polish
-
-2009-07-28     Lennart Poettering
-       f8873ab: build-sys: bump binary version
-       115d853: i18n: run make-update-po
-       09e57c2: Merge branch 'master' into master-tx
-
-2009-07-25     Lennart Poettering
-       8343360: client: minor modernizations
-       6ce7d20: client: if a child we created was already reaped, assume that it was successful
-
-2009-07-24     Lennart Poettering
-       59659e1: interpol-test: allow configuration of latency
-       211d0f3: client: limit block size for zero-copy operations to mempool block size
-       e7ca058: client: make volume struct const
-       5efb072: alsa: throw timing data away after device resume
-       f676391: autospawn: refuse autospawning if process disabled waitpid()
-       5e24b6d: memblock: try to hit an assert earlier when ref counting doesn't work
-       2bbdf63: udev: explain what happened when inotify_add_watch() returned ENOSPC, rhbz #513571
-       18433c1: alsa: handle correctly if alsa returns us 0 or EAGAIN on snd_pcm_mmap_begin if we didn't call snd_pcm_avail immediately before
-
-2009-07-23     logan
-       835a2ae: Sending translation for Spanish
-
-2009-07-23     Lennart Poettering
-       a81244a: pacat: use zero-copy write calls when playing audio file
-       e02e025: client: include zerocopy write calls in map file
-       c325b93: alsa: don't reset volume/mute when selecting path
-       5a0ef5f: daemon: replace colons by dash in per-machine directory names for compat with weird filesystems
-       ac38c4d: build-sys: add a couple of stub Makefiles
-       1160cad: alsa: control 'Speaker' element as well
-       efe5b65: po: run make update-po
-       638f9a5: Merge branch 'master-tx'
-       88d5749: Merge branch 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
-       3d6278b: Merge commit 'flameeyes/osx'
-
-2009-07-23     raven
-       097c0cb: Sending translation for Polish
-
-2009-07-23     Wim Taymans
-       3b01d3a: protocol-native: use the right samplerate
-
-2009-07-22     Lennart Poettering
-       41ad33d: Merge branch 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
-       e3b0ce5: udev: don't fail if /dev/snd is not available right-away
-       2f54b5d: daemon: reset personality, to make the autospawn env cleaup complete
-       7e2afff: alsa: deal properly with IO functions asking us to write 0 bytes
-
-2009-07-20     Lennart Poettering
-       0225ef6: memtrap: clarify that we are not interested in the return value of write()
-       23039af: client: allow zero-copy writing to the stream
-       a2b207e: daemon: before exec'ing ourselves, make sure nobody plays games with /proc/self/exe
-
-2009-07-18     xconde
-       0aca5ad: Sending translation for Catalan
-
-2009-07-17     Diego Elio 'Flameeyes' Pettenò
-       d18eb61: Again make sure that the wait() definition is not shadowed.
-       542607f: Make the rtstutter tests mostly pointless without CLOCK_REALTIME.
-       8c85c99: Further simplify on Daniel's patch for bootstrap.sh.
-       0a5257b: Also request Darwin extensions, as they are needed for stuff like NSIG.
-       a6d6718: Request explicitly POSIX.1-2001 for clock_gettime.
-       673112b: Check for support of -z nodelete LD flag, don't use it unconditionally.
-
-2009-07-17     Daniel Mack
-       191c57e: make bootstrap.sh aware of Darwin environment
-
-2009-07-16     Colin Guthrie
-       7e4509f: Merge commit 'flameeyes/master'
-
-2009-07-07     Diego Elio 'Flameeyes' Pettenò
-       84200b4: Remove exploitable LD_BIND_NOW hack (CVE-2009-1894).
-
-2009-07-12     Colin Guthrie
-       61fefd6: introspect: Fix two memory issues in port handling code.
-
-2009-07-07     pmkovar
-       cea1b8c: Sending translation for Czech
-
-2009-07-04     Diego Elio 'Flameeyes' Pettenò
-       ff252cb: Check for the library containing the backtrace() function.
-
-2009-07-01     Lennart Poettering
-       6fdd584: stream-restore: mark volume changes from instant apply as saved ones
-
-2009-06-29     Marc-André Lureau
-       95d3faa: bluetooth: don't connect on unconnected profile
-
-2009-07-01     Marc-André Lureau
-       e93c6c3: bluetooth: warn on EAGAIN after POLLOUT
-
-2009-07-01     Lennart Poettering
-       7dabe05: memtrap: properly lock access to memtrap changer
-       28e4625: memblock: rearrange locking order
-       efdd3d0: reserve: update from upstream git repo
-       5d4769b: alsa: fix a few comments
-       5bb1883: build-sys: add missing dependency to libcli
-       b174a51: libpulse: minor cleanups
-       a10b7cd: native: don't hit assert when user uploads zero-sized sample
-       cd70d7f: bluetooth: don't busy loop when device is not writable but we want to write
-       c3958aa: bluetooth: handle absence of bluez D-Bus service properly
-
-2009-06-30     Lennart Poettering
-       1104141: reserve: fix build without D-Bus
-
-2009-06-28     Colin Guthrie
-       00c392d: bootstrap: Ship git-version-gen with the tarball.
-       59376b0: introspect: Fix a bug in sink/source info protocol handling related to ports.
-
-2009-06-27     Colin Guthrie
-       a007d47: combine: Do not set (and update) description if the user passed one in during load.
-       7ee1b47: udev: Don't install the udev rules if we're not compiling udev support
-
-2009-06-25     Diego Elio 'Flameeyes' Pettenò
-       1ca7603: Add missing headers includes for FreeBSD.
-       bce211e: Rename the flock variable to f_lock.
-       6f44792: Only declare saved_errno when it's going to be used (on Linux).
-       9a2ac32: Rename the wait parameter to wait_op, to avoid shadowing wait().
-       2266a39: Remove the call for pa_rtpoll_install() in the Solaris module.
-       24564af: Fix the moved rtclock.h header in the Solaris module.
-
-2009-06-24     Diego Elio 'Flameeyes' Pettenò
-       de40e41: Also alias MAP_ANONYMOUS to MAP_ANON in shm.c, for FreeBSD.
-       2f7bce9: Add a missing sys/stat.h include for FreeBSD to declare umask().
-       fc649ad: Don't try to compile the rtkit sources when dbus is not enabled.
-       ad4e025: Implement mix-test for s24le and s24be sample formats.
-       595f80f: Use static constants to keep the generated sample blocks.
-       080f630: Ignore IPv6 tests, if IPv6 was built in but the system doesn't have it.
-       cd375da: Use the new CC_CHECK_CFLAGS_APPEND macro instead of a manual for.
-       e7c3a12: Properly link module-zeroconf-publish against libnative-protocol.
-       a4703ce: Check for and use flags to reject undefined symbols in libraries.
-       e61795c: Update attributes.m4 file from xine-lib.
-
-2009-06-13     Diego Elio 'Flameeyes' Pettenò
-       e832383: Make it more clear that PulseAudio needs libtool 2.2.
-
-2009-06-23     Lennart Poettering
-       2654eb7: sndfile: fix build on BE archs
-       0b52bf4: build-sys: don't make pulseaudio binary suid on install anymore
-       390c275: build-sys: properly drop '-' from major/minor/micro strings
-       b4b1f03: build-sys: teacch git versioning script to not kill - in version strings
-       5651c03: build-sys: drop compat with old git versions so that tarballs for -test1 style evrsions are properly created
-       5b78752: intended-roles: drop quite a few unnecessary includes
-       ef85558: modules: pass properly initialized userdata pointers to various hooks
-       b6d0b0e: intended-roles: properly initialize split state
-       d965000: rtclock: make use of constants when converting between nsec and usec
-       b627d68: intended-roles: fix symdef header inclusion
-       bcae796: build-sys: use pax tar format to allow longer file names
-       da6b156: builds-sys: work around automake 1.11 borkage
-       38e3d83: build-sys: bump udev revision to pull in new rules files
-       882cdfc: rtclock: fix type of PA_TIMEVAL_RTCLOCK
-       9217b47: timeval: don't create the wrong illusion that nsecs should be stored in pa_usec_t
-       f3bbbd0: rtclock: document that we fallback to wallclock time if monotonic time is not supported
-
-2009-06-22     Lennart Poettering
-       f753ef2: rtclock: enable rtclock for our own mainloop implementations
-       3ee2900: rtclock: fix build after merge
-       fc33f7e: Merge most of elmarco/rtclock2
-       048e576: build-sys: dropo shave support, depend on automake's new silent build support instead
-       de5219a: daemon: enable module-intended-roles by default
-       374efbd: Merge branch 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
-       aa2570c: rescue: make sure module-rescue-streams is used only as last fallback
-       60d36c7: module-stream-restore: recheck stream database on hotplug/unplug and potentially move streams
-       27af460: modules: add module-intended-roles that automatically puts streams marked with a role on devices that are intended for that role
-       c4d90ea: restore: change 'save' flag behaviour to reflect whether an entry shall and/or is in the on-disk databases
-
-2009-06-20     Marc-André Lureau
-       e4d914c: rtclock: fix issues found by Lennart
-
-2009-04-05     Marc-André Lureau
-       0955e3d: Base mainloop on pa_rtclock_now()
-
-2009-04-04     Marc-André Lureau
-       125c528: pulse: move pa_rtclock_now in pulsecommon
-
-2009-06-19     Lennart Poettering
-       32e2cd6: core: get rid of rt sig/timer handling since modern Linux' ppooll() is finally fixed for granularity
-       a62db27: daemon: enable real-time by default
-       06ec5fd: mergo
-
-2009-04-04     Marc-André Lureau
-       5dcdd5e: perl -p -i -e 's/pa_rtclock_usec/pa_rtclock_now/g' `find . -name '*.[ch]'`
-
-2009-06-19     Lennart Poettering
-       9c438bc: daemon: strip all special suid/caps log from our startup code, we'll now rely on RealtimeKit for all high-priority/RT scheduling policy issues
-       bacc5ca: core: use rtkit to acquire high-priority scheduling
-       8474fd7: core: ask RealtimeKit for RT scheduling
-       6ad3855: alsa: synthesize volume values more sensibly for channels that are not controllable in hw
-       b1ea7c0: alsa: document alsa mixer path/profile sets a bit more
-       b70b5ed: alsa: add copyright blobs and comments to all mixer paths/profile sets
-
-2009-06-19     logan
-       f21457e: Sending translation for Spanish
-
-2009-06-19     barney
-       8f81555: Sending translation for German
-
-2009-06-18     Lennart Poettering
-       11d2a7e: alsa: move udev rules file behind the other sound related rules
-       131f76a: alsa: move mixer config files to subdir in /usr/share
-       0fd17c6: alsa: document default profile set a bit better
-       8a5f8f4: alsa: add profile set for Native Instruments 4 DJ
-       348dcd6: alsa: unify alsa log handling and snd_config_update_free_global() handling in one place
-       25e5197: alsa: merge mic boost into volume slider
-       8fe50b0: alsa,core: include mapping name in description strings
-       ca560cc: alsa: add profile set for Native Instruments Audio 8 DJ sound card
-       60df970: alsa: properly count mappings of manually defined profiles
-       b5cea8d: alsa: fix duplicate mapping detection
-       34b4888: alsa: when creating alsa sinks/sources include mapping name in device name to allow profiles mit multiple sinks or multiple sources
-       8d3362c: device-restore: properly check save_muted flag when storing muted state
-       39b37a2: core: be a bit more verbose when registering a sink/source fails
-       4951e08: card,stream-restore: minor cleanups
-       0e4ac56: device-restore: save last used port in database
-       59bd793: card-restore: we don't need to save card data that came from the database
-       d773638: stream-restore: e don't need to save stream data that came from the database
-
-2009-06-18     raven
-       4dccbe3: Sending translation for Polish
-
-2009-06-17     Lennart Poettering
-       53b8703: Merge commit 'origin/master' into master-tx
-       a9f82f1: i18n: update i18n
-       f1ef2f6: Merge commit 'origin/master-tx'
-       75256fb: pactl: show list of supported ports
-       46b8ca2: native-protocol: allow enumerating ports
-       c65ebee: raop: move all raop files to subdir
-       6b2ca09: pactl: implement pactl set-{sink       914ef89: libpulse: implement client side for sink/source port selection commands
-       6d7cf14: native: implement command to change sink/source port
-       bd8e043: bluetooth: return sensible error code in set_profile()
-       334325e: alsa: allow placing device id in alsa device strings at arbitrary positions
-       31575f7: alsa: rework mixer logic
-       e9c70ac: pdispatch: fix s/recieve/receive/ typos
-       1ec33f3: pstream: fix s/recieve/receive/ typos
-       dddb4b0: gdbm: set default block size to 1K
-       279e0d6: card: get rid of description field which is unused
-       4f44fe8: card: make sure to always hand failure code back in some calls
-       325c01b: card: some modernizations
-       dda0f5a: rtp: fix s/recieve/receive/ typo
-       0fa1ddf: core-util: implement pa_maybe_prefix_path()
-       7fa05be: core-util: implement pa_split_spaces_strv()
-       c5dbf75: core-util: implement pa_xstrfreev()
-       7de7b01: conf-parse: implement .include directive
-       083b17b: volume,channelmap: reimplement a couple of calls based on channel masks
-       77901e5: channelmap: define a couple of standard channel masks
-       697b8de: malloc: implement pa_xrenew()
-       4f36cc7: channelmap: make sure a mask is generated is 64 bit int
-       26d5f28: version: fix prefix in PA_CHECK_VERSION macro
-       d993969: channelmap: implement pa_channel_position_from_string()
-       64b0f38: volume: implement functions for multiplicating a cvolume with a scalar
-       c6830bd: hashmap: implement pa_hashmap_last()
-       a1d84e3: hashmap: implement api to iterate a hashmap backwards
-       277e8c5: idxset: implement pa_idxset_copy()
-       0b479ff: daemon: write a warning blurb to syslog when folks use --system mode
-
-2009-06-13     ruigo
-       550b619: Sending translation for Portuguese
-
-2009-06-12     xconde
-       f0f30fb: Sending translation for Catalan
-
-2009-06-12     dennistobar
-       88730fd: Sending translation for Spanish
-
-2009-06-10     Lennart Poettering
-       1e8a374: alsa: fix bad memory access for devices that lack a mixer
-
-2009-06-08     raven
-       a87f8a2: Sending translation for Polish
-
-2009-06-08     Lennart Poettering
-       89e3adf: sample: fix build on BE archs
-       3c4c1f4: udev: reshuffle the properties we read from udev a bit
-       f13bbd5: prop: introduce new PA_PROP_DEVICE_INTENDED_ROLES property
-       12d5382: i18n: update po data
-       983aa5d: Merge commit 'origin/master-tx'
-       e7a6d53: core: replace tabs by spaces
-       587fc2a: core: make sure soft mute status stays in sync with hw mute status
-
-2009-06-08     rajesh
-       cc9354f: Sending translation for po/hi.po
-
-2009-06-07     Lennart Poettering
-       ab5adce: rtstutter: increase log level by default
-
-2009-06-07     ruigo
-       00cc168: Sending translation for Portuguese
-
-2009-05-14     Jyri Sarha
-       8eaea3a: optimization: Optimized pa_sink_render_full.
-
-2009-06-07     Lennart Poettering
-       8adf1d5: man: document that tsched doesn't use fragment settings
-       3aefc45: man: document 24bit sample types in man page
-       5be1cc5: man: document log related daemon.conf options
-       78bccde: conf: remove obsolete module-idle-time directive from default config file/man page
-       a9b38b3: daemon: optionally call mlockall() on startup
-       71ce195: udev: properly initialize userdata to 0
-
-2009-06-06     Lennart Poettering
-       3a118f2: build-sys: bump libsndfile dependency
-       bab4b94: udev: try to unsuspend devices whenever they are closed by other processes
-       d1646f7: core: monitor sources need to inherit the suspend cause from their sinks
-       69eab1e: core: suppress suspending/resume when we are already in the right state
-       496be21: hashmap: introduce PA_HASHMAP_FOREACH macro
-       e84644a: hal,udev: deprecate HAL support in favour of udev
-       8080ab1: udev: add module-udev-detect for discovering and configuring devices
-
-2009-06-06     aalam
-       86f3961: Sending translation for Punjabi
-
-2009-06-05     Lennart Poettering
-       e5dd9df: rtp: remove gcc warning
-       f398407: augment: try to deduce the media role from the menu category
-       561c0af: alsa: monitor device reservation status and resume automatically when device becomes unused
-       00797b8: core: add a suspend cause flags field
-       3af5f8c: reserve: wrap device reservation monitor reference implementation
-       1748fd2: reserve: update reserve.[ch] from upstream git
-
-2009-06-04     Lennart Poettering
-       3e10f3f: tdb: include signal.h before tdb.h for compat reasons
-       4d87475: utils: use pa_path_get_filename() where applicable
-
-2009-05-28     Lennart Poettering
-       8bada74: Merge branch 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
-       c224aac: modules: introduce PA_MODULE_DEPRECATED() macro for marking modules deprecated
-       1c4393a: modules: add {sink
-2009-05-27     Lennart Poettering
-       6044aab: Merge commit 'flameeyes/master'
-       2088626: null: introduce sink_properties= argument
-       6601e09: simple: set ADJUST_LATENCY by default
-       19d7ced: modargs: introduce pa_modargs_get_proplist()
-
-2009-05-27     jassy
-       8c6c8e5: Sending translation for Punjabi
-
-2009-05-26     Lennart Poettering
-       699bd54: libpulse: introduce PA_CHECK_VERSION macro
-       e8f7eb6: oss: don't deadlock when we try to resume an OSS device that lacks a mixer
-       d2198c9: alsa: fix wording, we are speaking of card profiles, not output profiles
-       5c10b84: sndfile: big rework of libsndfile interfacing code
-
-2009-05-26     jassy
-       ed105ef: Sending translation for Punjabi
-
-2009-05-25     Lennart Poettering
-       759a9d0: core-util: introduce pa_disable_sigpipe()
-       ebce318: cli: allow easy repeating of commands with '/'
-       8b180b6: volume: implement pa_cvolume_{scale    5f2d848: map-file: add missing channel map/cvolume position functions
-       8f23a2e: proplist: add two new generic properties, media.copyright and media.software
-       01fa34b: channelmap: introduce pa_channel_map_mask() and pa_channel_position_mask_t
-       261a483: sample: introduce pa_proplist_setp()
-       346a708: sample: introduce pa_sample_format_is_{le,be,ne,re}()
-       3533599: upnp: s/org.Rygel./org.gnome.UPnP/ following the newest version of the spec
-
-2009-05-24     ruigo
-       911f890: Sending translation for Portuguese
-
-2009-05-24     Lennart Poettering
-       f809284: channelmap: document how apple's/microsoft's channel names map to ours
-
-2009-05-22     Lennart Poettering
-       e2aba15: core-util: fall back to sysconf(_SC_OPEN_MAX) to find maximum file descriptor
-       ce3fbb5: tests: show dB in volume-ui.py
-       000bdb8: volume: change pa_volume_t mapping to cubic
-
-2009-05-21     ruigo
-       4b9aac2: Sending translation for Portuguese
-
-2009-05-20     ruigo
-       0ba756b: Sending translation for po/LINGUAS
-       0e23210: Sending translation for po/pt.po
-
-2009-05-19     Lennart Poettering
-       e7bca90: upnp: s/url/URL/ in GetAll() D-Bus call
-
-2009-05-17     Diego Elio 'Flameeyes' Pettenò
-       ce6643e: Use the _ONCE variation of AC_CHECKs where applicable.
-
-2009-05-15     Diego Elio 'Flameeyes' Pettenò
-       ff5b7fb: Add missing headers' include to build on FreeBSD 7.1.
-       99f2541: Add missing include directory path for OSS modules.
-       d45c909: When MAP_ANONYMOUS is missing, fallback to MAP_ANON.
-       0de6877: Don't use == for comparison in tests. Fix build with non-bash shells.
-
-2009-05-15     Lennart Poettering
-       862a05f: upnp: update to newest spec
-
-2009-05-14     Lennart Poettering
-       0921b1b: shm: rework alignment when punching memory
-       763954c: upnp: convert all property names to CamelCase to follow D-Bus spec
-       1a39acc: rescue: make we don't end up in an endless loop when we can't move a sink input
-       234c61b: upnp: implement item-count/container-count properties
-       0cb3837: alsa: be a bit more verbose when a hwparam call fails
-       b7e2223: database: port restore modules to new database API
-       003e03d: macro: include string.h because we need it for memset
-       6df14e0: database: add tdb backend
-       46bceed: database: add gdbm backend
-       c69ed91: database: add abstracted database API
-
-2009-05-13     Lennart Poettering
-       905c800: volume: introduce pa_cvolume_{get      28069ef: core: automatically add icons for headsets/headphones/speakers for devices
-
-2009-05-12     Lennart Poettering
-       dfd6b61: alsa: include mixer name in sink/source properties
-       21ab720: http: fix segfault on connection termination
-
-2009-05-12     Marc-André Lureau
-       86caf45: context: don't fail if session bus is not there
-       4c3aef3: suspend-on-idle: add per-device timeout property
-
-2009-05-11     Lennart Poettering
-       a7a7358: git: activate default commit hook
-       37c3620: upnp: rework property handling
-       35b7ce5: upnp: use new rygel @HOSTNAME@ wildcard for server name
-       dc5dce5: upnp: properly issue method not found exception when we don't now it
-       98a6454: upnp: update to newest spec, generate 'Updated' signal
-       6c4c61d: upnp: fix URL of MediaServer spec
-       eb20564: mime: drop additional whitespace from mime types
-
-2009-05-07     Jyri Sarha
-       35faedb: core: Take samples from silence cache rather than write zeros
-       d7b8947: core: optimize pa_sink_render_full()
-
-2009-05-08     Lennart Poettering
-       a714861: channelmap: add pa_channel_map_has_position()
-       7f767e5: core: liberalize 99a6a4 a bit
-       8d9c26e: core: cache requested latency only when we are running, not while we are still constructing
-       99a6a47: core: make sure we fix up flags/monitor flags already in pa_sink_new() instead of pa_sink_put()
-       3766850: core: introduce pa_{sink,source}_set_fixed_latency()
-
-2009-05-08     Jyri Sarha
-       44e566a: bluetooth-device: Add safe guard against BT streaming irregularities.
-
-2009-05-07     Lennart Poettering
-       92a6141: macro: add macros for initializing memory
-
-2009-05-05     troubi51
-       9dd1af6: Sending translation for French
-       dd1cd9e: Sending translation for French
-
-2009-05-03     pmkovar
-       4caa33b: Sending translation for Czech
-
-2009-05-01     Lennart Poettering
-       e0f0821: sconv: fix a few minor conversion issues
-       5caf09d: resampler-test: add tests for 24bit sample formats
-       76caa27: resampler-test: use global PA_FLOAT32_SWAP implementation
-       4bffc78: alsa: initialize buffer size before number of periods to improve compat with some backends
-       d2b5ae5: sample-util: fix iteration loop when adjusting volume of s24 samples
-       3a7b287: sample-util: properly allocate silence block for s24-32 formats
-       076830a: endian: fix LE/BE order for 24 bit accessor functions
-       947bf5d: zeroconf: properly unref native protocol object
-       d4b10d8: sample: correctly pass s24-32 formats
-       4129f51: alsa: don't hit an assert when invalid module arguments are passed
-
-2009-04-30     Lennart Poettering
-       5a2898d: zeroconf: use pa_get_{user     3522b7d: zeroconf: copy more sink/source properties into DNS-SD TXT data
-       407a810: zeroconf: computer native protocol port automatically
-       d696416: headers: minor cleanups
-       5326f5f: rygel: get rid of forgotten debug trap
-       93db3cb: rygel: instead of always handing out wildcard address find out the actual address we are listening on
-       8dfdfd4: http: export information about currently active server strings
-       23a798c: strlist: add new calls pa_strlist_{next        9208b86: parseaddr: add new call pa_is_ip_address()
-
-2009-04-29     Lennart Poettering
-       d5f9057: rygel: make server name configurable
-       c95cc9e: rygel: add module that interfaces with Rygel UPnP
-       390fe02: http: split out mime type handling calls
-       84a92f2: protocol-http: allow listening into sinks/sources via HTTP
-       c215011: ioline: add new calls pa_ioline_detach_iochannel() and pa_ioline_is_drained()
-       a64097a: ioline: add callback that can be called when the ioline object is fully drained
-       4cb6ea2: simple-protocol: don't hit an assert when we call connection_unlink() early
-       0b2d96d: protocol-http: substantial modernizations
-       d871071: alsa: allow configuration of fallback device strings in profiles
-       ad5a1f3: protocol-native,proplist-util: port to pa_get_{user    a8f0d7e: core-util: introduce pa_get_host_name_malloc() and pa_get_user_name_malloc()
-       4abd5fa: memtrap: implicitly page align memory areas
-       bd0e4ce: macro: make pa_page_align roung up instead of down
-       68f3ca9: macro: add new macro pa_align_ptr()
-       8247e45: shm: minor modernizations
-       595c22a: shm: page align shm size when mmap()ing it
-       9745483: strbuf: add new call pa_strbuf_putc()
-       5d39b8d: idxset: add enumeration macro PA_IDXSET_FOREACH
-
-2009-04-28     Lennart Poettering
-       0368d6e: build-system: move x11 and jack modules into subdirectories
-
-2009-04-24     Lennart Poettering
-       908b0e6: build-system: hide .version from git
-       af8f058: build-system: run make update-shave
-
-2009-04-23     Marc-André Lureau
-       35382d6: build: there is no such thing as SHAVE_OUTPUT anymore
-       ebe22ad: build: generate git tarball using git describe
-
-2009-04-22     Lennart Poettering
-       edba78c: start-pulseaudio-x11: don't start a local sound server if a remote sound server is configured
-       ad12d7d: memtrap,aupdate: split atomic update from memtrap into seperate aupdate framework
-
-2009-04-21     Lennart Poettering
-       bb07c16: i18n: run make update-po
-       79c8826: i18n: add missing file to LINGUAS ... again
-       6919424: Merge commit 'origin/master-tx'
-       26383c6: memtrap: add a bit of documentation for memtrap
-       67efc76: memtrap: fix parameter type
-       684b4c1: memtrap: hook up core to memtrap system
-       928adf4: memtrap: make installation of SIGBUS handler explicit to ease integration into libraries
-       7b00861: memtrap: when we fail to handle sigbus say so
-       6224fac: memtrap: add new logic to trap and handle SIGBUS
-       fbbcfae: semaphore: introduce static semaphores
-       391d50c: mutex: add initializer for static mutexes
-       b304a98: mutex: when we fail to fill in mutex into static mutex ptr free it again
-       12065f3: llist: add PA_LLIST_FOREACH
-
-2009-04-20     marionline
-       3c36836: Sending translation for Italian
-
-2009-04-19     mvdz
-       ed10a15: Sending translation for po/uk.po
-
-2009-04-19     Lennart Poettering
-       8fbf626: object: revert to old unref() behaviour
-       eb04d0f: object: fix ref counting of objects on destruction
-       ad2a0ab: alsa: remove debug code
-       98a25c5: alsa: properly convert return values of snd_strerror() to utf8
-       39a26d8: log: use pa_logl() instead of pa_log_level()
-       b9f1af4: log: print file name only when we have it
-       6773d00: util: if NULL is passed to pa_path_get_filename() just hand it through
-
-2009-04-15     Erich Boleyn
-       b03a650: reserve-device: allow building without D-Bus
-
-2009-04-17     Finn Thain
-       1c0667d: solaris: 0.9.15 solaris module build failure
-
-2009-04-18     Lennart Poettering
-       12c5afe: object: keep refcount at 1 while destructing objects
-       ad447d1: core-util: handle EINTR already inside of pa_read/pa_write
-
-2009-04-18     beckerde
-       4ec5375: Sending translation for Spanish
-
-2009-04-18     fab
-       0093379: Sending translation for po/LINGUAS
-       ae3caa6: Sending translation for po/de_CH.po
-       8a1938c: Sending translation for German
-
-2009-04-04     Marc-André Lureau
-       099b328: bluetoth-device: be less strict on CONNECTED state to switch profile
-
-2009-04-17     Marc-André Lureau
-       344eea4: pulse/context: when NOFAIL, don't try_next_connection() if c->client
-
-2009-04-17     Lennart Poettering
-       d775cf6: rescue-streams: when one stream move fails try to continue with the remaining ones
-
-2009-04-15     warrink
-       83e7186: Sending translation for Dutch
-
-2009-04-14     warrink
-       0846b68: Sending translation for Dutch
-
-2009-04-14     raven
-       5faacd8: Sending translation for Polish
-
-2009-04-14     Lennart Poettering
-       ca9cd14: add a few missing initializations
-       40d71e1: explcitly ignore return values of some functions marked with gcc's warn_unused_result attribute
-       845b312: bump version for final 0.9.15 release
-       a4cea4e: core: when applying delay memblockq take monitored sink latency into account
-       2d94c93: pacat: add missing newline
-       4ee4a55: core: use pa_{source
-2009-04-13     Lennart Poettering
-       16324fc: sort LINGUAS
-       a654155: run make update-po
-       c96f6f3: update LINGUAS
-       0948dca: Merge commit 'origin/master-tx'
-       fe8b10c: core: introduce new 'reference' volume for sinks
-       49dcf09: alsa: include the alsa mixer control that is used in the property list
-       6fd8fd1: alsa: store mixer controls to use in profile data
-       89f74cb: alsa: when passing emptry mixer control name, force sw volume
-       237a9e1: volume: increase dB range to -90dB
-       0ac038e: client-conf-x11: unbreak autospawn due to stale X11 properties
-       0aed5ea: client-conf: when  is set, disable autospawn setting
-       4cc4cbd: client-conf: make setting a default server independant from the autospawn setting
-       20aba71: proplist-util: use pa_session_id() instead of accessing 7b816367b01393ed3e3e650047d78f6e-1239640487.203609-1061245823 directly
-       43650de: client-conf: modernize a few things
-       a36197c: print session id when starting up
-       1d8da03: core-util: filter utf8 in pa_machine_id()
-       1b4e5f1: core-util: add pa_session_id()
-       17f1784: cork-music-on-phone: make sure that we don't check the refcnt of pa_core when the daemon goes down
-       62db10c: lirc: fix logic behind mute buttons
-       66d2184: mmkbd: get rid of support for ancient kernels
-       f1d3dfb: mmkbd,lirc: make use of pa_assert_not_reached()
-       270a698: lirc, mmkbd: extend controllable volume range to PA_VOLUME_MAX
-       6d218e9: api: introduce PA_VOLUME_MAX
-       e9dd7a5: lirc: drop lirc_in_use, it's made redundant by PA_MODULE_LOAD_ONCE
-       d8de5d3: make sure we never overflow when calculating sleep time
-
-2009-04-13     warrink
-       2ba882c: Sending translation for po/nl.po
-
-2009-04-11     ifelix
-       362ec7b: Sending translation for Tamil
-
-2009-04-10     Lennart Poettering
-       6eaeaea: Downgrade default log level to NOTICE to follow documentation
-       a26c945: add missing languages to LINGUAS
-       3e29fd7: prepare another snapshot
-       991cb06: set fixed latencies at more places where appropriate
-
-2009-04-06     Finn Thain
-       80e18c8: make dbus optional during build
-
-2009-04-10     Lennart Poettering
-       e011230: run make update-po
-       d6f019e: Merge commit 'origin/master-tx'
-       5388b44: alsa: when printing warning about bogus data from alsa include snd_pcm_dump()
-       ee6657a: bluetooth: when starting up HSP stream, send 2 packets first, only afterwards enter one-read-one-write logic
-       d77b28c: bluetooth: rework timing logic, properly implement latency callbacks
-       e9a4dec: bluetooth: be a bit more verbose if we exit due to bad poll() revents flag
-       48cff5b: bluetooth: rename sco to hsp also for the user
-       f7c229d: core: add a seperate fixed_latency field for sinks/sources with fixed latency
-       9ae8ca2: core: memory leak, fix ref counting when moving streams
-       dcd4a73: dbus: memory leak, actually free dbus wrapper
-       d827ecd: dbus: drop pa_ prefix from static symbol
-       f8ebe85: protocol-native: downgrade message if we receive pcm block for dead stream
-       5b87196: protocol-native: print underrun message only once for each underrun
-       3507d1e: socket-server: memory leak, free machine id after use
-       669703d: dbus: memory leak, free pending calls
-       9ba9883: dbus: memory leak, free server id after use
-       9ee6a41: bluetooth: memory leak, actually free discovery struct itself
-       f65b276: interpol-test: make it easier to test corking only optionally
-
-2009-04-09     elsupergomez
-       dac687d: Sending translation for Spanish
-
-2009-04-09     mgiri
-       d1cf6eb: Sending translation for Oriya
-       6c5bbd3: Sending translation for Oriya
-
-2009-04-08     mgiri
-       8e1a9b7: Sending translation for Oriya
-
-2009-04-08     kkrothap
-       27784c4: Sending translation for Telugu
-
-2009-04-08     ifelix
-       0474762: Sending translation for po/ta.po
-
-2009-04-08     runab
-       bb7beeb: Sending translation for Bengali (India)
-
-2009-04-08     amitakhya
-       89f5da8: Sending translation for Assamese
-       b445f79: Sending translation for po/as.po
-
-2009-04-08     Lennart Poettering
-       6c04a1c: bluetooth: make sure to set max_request
-       c32c6c8: introduce relative_volume field in sink_input and make use of it on sink flat volume change
-       14e89d4: when calculating volume from dB use ceil()
-       4ff41ec: print smallest attenuation/sample
-
-2009-04-07     kkrothap
-       091a0f2: Sending translation for po/te.po
-
-2009-04-07     kmilos
-       f5eca5d: Sending translation for po/sr@latin.po
-       7202d52: Sending translation for Serbian
-
-2009-04-07     mgiri
-       5b0d1bf: Sending translation for Oriya
-       54c895c: Sending translation for po/or.po
-
-2009-04-07     runab
-       7154f06: Sending translation for po/bn_IN.po
-
-2009-04-07     Lennart Poettering
-       aacb11b: update documentation regarding stream timing a bit
-       c523b16: after propagating a sink volume change to the sink inputs recalculate their soft volumes
-       93e14d3: we need to make our multiplications with linear values
-       02686cc: reduce number of conversions to/from linear volumes
-       d612fbb: compare with doubles, not integer
-       e356a03: If the sink volume is lowered to 0 and then increased again, make sure all stream volumes follow instead of staying at 0
-       2c2713a: make use of SO_TIMESTAMP timestamp for accuracy and leave smoother paused until we have data
-       f204c0f: mark null sink as support dynamic latency
-       298bd0b: adjust max_rewind/max_request whenever the latency changes
-       e976034: send the source latency based on the MTU size
-       61b0776: add suspend_within_thread() callbacks to pa_sink_input/pa_source_output
-       35a4a0b: enable debugging output based on if DEBUG_DATA macro is set
-
-2009-04-07     swkothar
-       ff2dc1b: Sending translation for Gujarati
-
-2009-04-07     shanky
-       682c101: Sending translation for po/kn.po
-
-2009-04-06     Lennart Poettering
-       886ddc3: make sure we don't apply sampling rate fixes that bring the sampling freq > PA_RATE_MAX
-       e61728e: Make sure we don't get stuck when prebuf is too high
-       ff8d66d: extend documentation for pa_stream_cork() a bit
-       7fc2382: properly handle interpolation when queried x is left of last data position
-       daa945a: don't fail device reservation if the D-Bus connection is dead
-       4b521e5: be a bit more verbose about the busses we are connected to
-       90f4fdb: make sure we keep a reference of the bus connection during the whole runtime if we manage to acquire the bus name
-
-2009-04-06     swkothar
-       f598776: Sending translation for Gujarati
-       b9b470e: Sending translation for Gujarati
-       4c0a2e0: Sending translation for po/gu.po
-
-2009-04-06     sandeeps
-       a55c236: Sending translation for po/mr.po
-
-2009-04-06     leahliu
-       f709f2b: Sending translation for Chinese (Simplified)
-
-2009-04-05     soko
-       6c0ce4d: Sending translation for po/sr@latin.po
-       c66e3fd: Sending translation for Serbian
-
-2009-04-05     raven
-       015d66e: Sending translation for Polish
-
-2009-04-05     vpv
-       4053e35: Sending translation for Finnish
-       d5e8488: Sending translation for Finnish
-       f5ec110: Sending translation for Finnish
-
-2009-04-05     Lennart Poettering
-       ecba42b: run make po-update
-       9416cdf: Merge commit 'origin/master-tx'
-       6ba3333: Merge branch 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
-       923c5bc: make it easy to disable interpolation in the interpolation test tool
-       14e11e4: Fix a couple of races in native protocol
-       7dafa87: don't try to outsmart the transport
-       ce73e71: introduce pa_{sink     d035f4a: Modify smoothing code to make cubic interpolation optional and allow 'quick fixups' on resuming
-
-2009-04-04     vpv
-       82d1301: Sending translation for Finnish
-
-2009-04-04     Lennart Poettering
-       ca39fa2: initialize sound cards only after the 'control' object appeared
-       9bea250: increase log buffer further
-       77a1e38: refuse to initialize on modem devices
-       f708328: add missing files to POTFILES.in
-       99f45a6: run make update-po
-       f446f0e: Merge commit 'origin/master-tx'
-
-2009-04-01     Maarten Bosmans
-       8bcb9c6: various spelling fixes
-
-2009-04-01     Luke Yelavich
-       ccaf765: POTFILES.IN: Refer to src/pulsecore/dbus-util.c
-
-2009-04-03     soko
-       a12f4e6: Sending translation for po/sr@latin.po
-       310d47a: Sending translation for Serbian
-       398e381: Sending translation for po/sr@latin.po
-       a0e46c2: Sending translation for Serbian
-
-2009-04-03     Lennart Poettering
-       6152c52: Merge branch 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
-       143e1ba: downgrade a few messages
-
-2009-04-02     soko
-       089a081: Sending translation for Serbian
-
-2009-04-02     leahliu
-       cb40e85: Sending translation for Chinese (Simplified)
-
-2009-04-01     Lennart Poettering
-       1c26d7e: plot the difference between system and sound card time
-       373b5ef: properly account for seeks in the requested_bytes counter
-       380e97a: use machine id instead of hostname to identify local connections
-       dcb24f5: load bt discover module only when installed
-       707acab: prepare test7
-       75a8d18: pass destination source/sink when moving streams so that we can access them
-       c2f6d09: don't access i->sink if it is not set
-       d9b19f8: prepare test6
-       5348cc1: increase timing update interval exponentially
-       aa1ad0d: in verbose mode log buffer attr changes
-       0aa99c4: add buffer_attr callback stuff to exported symbol list
-
-2009-04-01     tombo
-       1fa761a: Sending translation for Italian
-
-2009-03-31     Lennart Poettering
-       4e8ceae: fix buffer defaults
-       76c44d1: be a bit more verbose about max_request changes
-       cebaa98: Log underruns
-       917e8cd: handle buffer_attr changed messages properly
-       5cbd4b7: update command name table
-       ef5af55: fix an error where a signal was accidently freed when it is tried to register it twice
-       2a32de1: Merge commit 'origin/master-tx'
-
-2009-03-31     beckerde
-       c29e9cf: Sending translation for Spanish
-       2cd93ab: Sending translation for Spanish
-       1e99255: Sending translation for Spanish
-
-2009-03-07     Finn Thain
-       5e11972: revive solaris module
-
-2009-03-30     Kyle Cronan
-       92ae5f1: Specifying ALSA mixer control
-
-2009-03-29     Maarten Bosmans
-       facc46d: fix some typos in doxygen comments
-
-2009-03-30     Maarten Bosmans
-       4a40aed: handle failure to parse proplist in cli-command gracefully
-
-2009-03-31     Lennart Poettering
-       cab1e54: explain ff7033c11d9248fe837204b03c8397231dc511fe
-       ff7033c: Revert "make sure we always read in all properties"
-
-2009-03-30     Lennart Poettering
-       29a282a: allow nofail mode only when no server string was specified
-       b6135b3: minor cleanups
-       3df9eef: take org.pulseaudio.Server instead of org.pulseaudio to match the interface name already used in the HAL module
-       857a1f4: fix compiler warning
-       90fbc03: make sure we never access an invalid pa_bluetooth_device object
-       1c8f968: make sure we always read in all properties
-       66b80e9: get rid of old 'Connected' property parsing and make sure we don't execute two case branches
-       91355a1: introduce typedef for pa_bt_audio_state and use it everywhere
-       1390564: Merge commit 'elmarco/bluetooth-fixes'
-       d33be12: Merge commit 'elmarco/dbus'
-       649c982: Use pa_source_set_max_rewind_within_thread() for updating the monitor source's max_rewind
-
-2009-03-27     Marc-André Lureau
-       8491b47: gtk-test: updated to use PA_CONTEXT_NOAUTOSPAWN
-2009-03-20     Marc-André Lureau
-       1dad83b: pulse: client connect to dbus
-       b4ef64d: daemon: take org.pulseaudio
-
-2009-03-19     Marc-André Lureau
-       eb93e25: dbus: split dbus-util into dbus-shared
-
-2009-03-30     Lennart Poettering
-       1743322: Merge commit 'coling/master'
-       061344f: Merge commit 'origin/master'
-       aa68036: rework tunneling code
-       65b787d: notify clients about tlength changes
-       491aafd: typo fix
-       b349dae: add pa_memblockq_apply_attr()/pa_memblockq_get_attr()
-       7c37c37: document more often the context certain functions are called in
-       7f5481e: simplify latency config functions a bit and make them callable in more contexts
-       d04f3e1: Trigger move callback a little bit earlier so that no IO thread is running
-       e3f1510: don't enabled tsched on software ALSA devices
-
-2009-03-27     Marc-André Lureau
-       87fcb3d: bluetooth: use new audio State properties
-       38825d7: bluetooth: GetProperties after profile UUID show up
-       20bd1c6: bluetooth: remove racy GetProperties to check profile
-
-2009-03-26     Marc-André Lureau
-       9e8c2d3: bluetooth: don't access outside array range
-
-2009-03-24     Marc-André Lureau
-       61cd6d4: bluetooth: fail when switching on non-connected profile
-       62a4e36: bluetooth: connected can be -1, check > 0
-
-2009-03-27     Lennart Poettering
-       87d63b1: Small fix for MacOSX compat
-       db714bf: fix typo
-
-2009-03-26     Luiz Augusto von Dentz
-       13f1c44: Do not reconfigure capabilities.
-
-2009-03-24     Luiz Augusto von Dentz
-       168c741: Query and make use of the current configuration.
-
-2009-03-25     Luiz Augusto von Dentz
-       071b3e7: Update ipc to match new message headers introduced on BlueZ 4.34.
-
-2009-03-23     Luiz Augusto von Dentz
-       b03c545: Fix misuse of 'frame.joint' when estimating the frame length.
-       f80a1f6: Maintain the original code style for sbc.
-
-2009-03-25     Colin Guthrie
-       205cbe8: raop: Add call to pa_sink_set_max_request()
-
-2009-03-25     Lennart Poettering
-       3813034: add missing initialization
-       cbbd986: make sure the discovery module is only loaded once
-       39576ec: on monitor source be fine with any latency range set by the sink
-       6defb1a: add missing whitespace
-       2c1eaa7: copy latency flags from sink to monitor source
-       4edb109: use u->use_tsched everywhere
-       8282efc: fix value of DYNAMIC_LATENCY
-       c367a88: fix misplace _ref() calls that should have been _assert_ref()
-       f6a6d01: optionally skip initial frames in backtrace
-       8460fac: don't show full so path in backtrace
-       e41ec51: add simple ref counting debugging framework
-       577259b: trivial simplification
-       119698a: beef up esd sink properties a bit
-       fdbe054: initialize max_request to SO_SNDBUF
-       98a5f4a: don't fiddle with latency range in sources with static latency
-       d0bd3d9: initialize max_request
-       bcfe51f: again, don't fiddle with latency range in sinks with static latency
-       59b7e53: Don't initialize userdata twice
-       b815a1c: don't fiddle with latency range because we cannot adjust it dynamically
-       0316dba: set latency range only in tsched mode
-       171c88f: link jack modules's max_request to the jack buffer size
-       892a839: simplify things and make sure timing setters can be called in most contexts
-       44ca897: introduce new flag that marks sinks/sources which can adjust the latency dynamically
-       9bca59e: make pa_source_set_max_rewind() work similar to pa_sink_set_max_rewind()
-       9151107: get rid of 'default' min/max latencies, simplify things by just having absolute boundaries
-
-2009-03-24     Marc-André Lureau
-       a7246bd: bluetooth: fix #NOKIA, correctly unlink sink/src
-
-2009-03-24     Lennart Poettering
-       5b523d0: fix bad memory access when destroying m-b-d
-       c64d8cb: Allow calling pa_{sink 50695d9: minimal reordering
-       2f9a784: set request/rewind sizes only via accessor functions
-       aa92ff4: simplify latency range by not allowing stored 'wildcard' ranges anymore
-       e6be948: only decrease timer slack, never increase
-
-2009-03-23     Lennart Poettering
-       bcbfd5b: don't fail when no session bus is available
-       52dcb95: add pa_assert_cc() for compile time assertions
-
-2009-03-16     Marc-André Lureau
-       a467bec: pulse: check context (do not user pstream when NULL)
-
-2009-03-23     Lennart Poettering
-       0815455: only store card profile if flagged for that
-       124de50: enable bluetooth default by support
-       906fd57: Merge commit 'origin/master-tx'
-
-2009-03-21     kmilos
-       4c381cd: Sending translation for po/sr@latin.po
-       29d1db6: Sending translation for po/sr.po
-
-2009-03-21     Lennart Poettering
-       c14da67: readd volume control logic
-       b3675c2: add functions that modules can call whenever they now the volume changed
-       8d5b375: at a couple of #ifdef NOKIAs for now
-       3aa3972: rework device discovery to share a single device list among all modules
-       20488fb: add pa_hook_is_firing
-
-2009-03-20     Lennart Poettering
-       f5c8990: make sure we dispatch messages in order
-       77a1db1: fix a misplaced assert
-       888e44f: rework bluetooth IO loops
-       d2bee57: fix prototypes of remaining sbc.[ch] API regarding size_t/const
-       99dae9b: don't try to unref reserve stuff if we don't use it
-       0251078: fix channel mapping for a52 devices. Closes #508
-       33a8f53: simply bluetooth nrec handling a bit
-       dfb3d2e: always remap relative volume properly
-       a998038: introduce pa_sink_input_get_relative_volume()
-       bd3154a: introduce pa_assert_fp() for fast path assertions
-
-2009-03-19     Xavier Conde
-       5cc7d00: Update catalan po
-
-2009-03-19     Lennart Poettering
-       fe3709c: fix a comment
-       dd40006: document things that need to be fixed with FIXME
-       3762299: unfuck i18n
-       86439a4: Merge commit 'origin/master-tx'
-       0a1af8e: Merge branch 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
-       4a98312: Merge commit 'elmarco/bluetooth-fixes'
-       291d21c: fix prototypes of sbc functions a bit
-       794775b: document todo items discussed at bt meeting
-       303cd90: get rid of setsockopt() calls since they have never been implemented upstream
-
-2009-03-19     Marc-André Lureau
-       e836217: bluetooth: rework the info_valid logic to be more tolerant
-       f1daa28: bluetooth: mark info_valid when receive Connected
-
-2009-03-06     Marc-André Lureau
-       af9f92b: bluetooth: update SCO over PCM with latest changes
-
-2009-03-19     Marc-André Lureau
-       df3f4ee: bluetooth: load bluetooth device with connected profile
-
-2009-03-19     Lennart Poettering
-       9744595: Merge commit '2d903bae9a2e57f997a3d3f335379c3880f95c77'
-       4ebdee5: deduce a proper icon for TV sets
-       3e8c7ac: Ignore HAL NoSuchProperty errors when looking for capabilities field. Closes rhbz #489394
-
-2009-03-12     Lennart Poettering
-       2928b44: Merge commit 'elmarco/bluetooth-fixes'
-
-2009-03-12     A S Alam
-       000f0b8: Adding Punjabi Language
-
-2009-03-05     Marc-André Lureau
-       9e93b9c: bluetooth: stream also when source is suspended
-       018cadd: bluetooth: restart timer when write begin
-       362d196: bluetooth: accept temporarily unavailable error
-       2d903ba: bluetooth: s/handled/not_yet_handled for signals
-       12ea570: bluetooth: reset read/write index when starting to stream
-
-2009-03-05     Piotr DrÄ\85g
-       5d00693: Updated Polish translation
-
-2009-03-05     Lennart Poettering
-       47bc3b7: prepare test5
-       c589da7: prepare release 0.9.15-test4
-       c6ed0e8: run make update-po
-       57baff5: Merge commit 'origin/master-tx'
-       420ee3f: Merge commit 'elmarco/bluetooth-fixes'
-       81323b5: Merge branch 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
-       3122008: try to detect when stupid clients forks and refuse all service from then on
-       9d29b96: make interpol test more interesting by corking/uncorking multiple times
-
-2009-03-05     Diego Elio 'Flameeyes' Pettenò
-       21547d7: Properly check for versioning flags.
-       cad3dd2: Make sure to set 'no' on the variable cached.
-
-2009-03-04     Lennart Poettering
-       dcee888: Merge branch 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
-       3dd8800: fix typo in FOREIGN_CFLAGS
-       6427c70: try more things to get a proper icon for sinks/sources
-
-2009-03-04     Marc-André Lureau
-       7a8be7f: bluetooth: don't init profile when off
-
-2009-02-27     Marc-André Lureau
-       683548e: bluetooth: service_fd could be 0
-
-2009-02-25     Marc-André Lureau
-       fa73688: bluetooth: hsp case, check l for appropriate error message
-
-2009-03-04     Lennart Poettering
-       656fc66: never try to suspend monitor sources, suspend the sinks they belong to instead
-       ec1c923: print error code when suspend/resume fails
-       0dd8a33: handle negative error codes
-       341f44f: fix handling of _suspend_all(), return first failure error code
-       ecbc320: make suspend state of monitor source follow the suspend state of the sink it belongs to
-       bffa8be: Don't allow suspending of monitor sources.
-       d09287d: Fix a NULL pointer access when sutting down esound/simple connections
-       8693417: various smaller cleanups
-       c8abe64: pa_xnew cannot fail -- that's what the x is in the name
-       946d072: document more closely from which context certain functions may be called
-
-2009-03-03     Lennart Poettering
-       f3de61e: fix device reservation for system mode
-
-2009-02-26     Finn Thain
-       0329edd: revive solaris module
-
-2009-03-03     Lennart Poettering
-       ff38eaf: Merge commit 'coling/lgpl21'
-       297515a: pass profile priority value to clients
-
-2009-03-03     Colin Guthrie
-       86dee05: Use LGPL 2.1 on all files previously using LGPL 2
-
-2009-03-02     Lennart Poettering
-       f8a085f: properly handle directed card info requests
-       7794108: Merge commit 'coling/master'
-       45ae4ab: run make update-ffmpeg
-       505df22: run make update-sbc
-       e435241: run update-reserve
-       4e86a4c: run make update-shave
-       ea1d429: add update-shave target
-       77514c1: Merge commit 'coling/master'
-       5c514aa: make dependency on udev versioned
-
-2009-03-02     Colin Guthrie
-       c083177: Use pa_assert_se() when the containing code has side effects.
-
-2009-03-01     Colin Guthrie
-       8a00c00: raop: Handle the reponse header memory allocation more sensibly.
-       b75a4b4: raop: Log teardown explicitly
-       d293f08: raop: Allow for nice sink descriptions to be set (interpolated from avahi)
-
-2009-03-01     Lennart Poettering
-       ba4765a: For now don't list icon property (in favour of icon name property) since icon negotiation is probably much more complex (i.e. sizes...) than just putting icon data somewhere.
-       671b927: add logic for initializing a useful icon name
-       784ac5b: get additional device data from udev
-       cc8d51a: rename PA_PROP_DEVICE_CONNECTOR to PA_PROP_DEVICE_BUS
-       cce56ab: revise form factor list a bit, simplify and use singular everywhere
-       e008333: introduce seperate vendor/product id fields
-       abdffe9: make example code a bit more robust/change-proof
-
-2009-02-28     Colin Guthrie
-       8fc9b19: Don't assume that device reservation is enabled.
-
-2009-02-27     Xavier Conde
-       34cefed: Updated catalan po
-
-2009-02-27     Lennart Poettering
-       116b38c: Merge commit 'coling/master'
-       798e39a: when alsa tweaks our sample_spec make sure we adjust the watermark accordingly
-       1c86267: when an underrun happens, increase watermark by 10ms instead of doubling it
-       0d8f67b: revise list of form factors a little
-
-2009-02-26     Colin Guthrie
-       07f9842: bluetooth: Fix under linked module-bluetooth-device
-       dd3c96d: Fix a very strange 'file not found' error in module-alsa-card.
-
-2009-02-25     Lennart Poettering
-       620bf84: try to vacuum a little when nothing is going on
-
-2009-02-24     Piotr DrÄ\85g
-       90ffe2d: Updated Polish translation
-
-2009-02-24     Lennart Poettering
-       e8d7c50: forgot to bump the revision
-       3d04300: hide shave in gitignore
-       00839dd: make sure we check the sink status for PA_SINK_INPUT_FAIL_ON_SUSPEND only after module-suspend-on-idle had the chance to resume the device
-       7f5fff9: Merge commit 'elmarco/shave'
-       7126392: ignore tags file
-       07a45c7: run make update-po
-       364786e: Merge commit 'origin/master-tx'
-       8314858: set reserve interface application device name
-       03ac71b: don't put both the card and the pcm name in the description of a device if one contains the other
-       ba3c766: update reserve.c from upstream git
-       c341010: implement device reservation scheme
-       3c73025: in case alsa lies to use don't spin forever
-       ec9f8f1: if ALSA gives us nonsensical data at least try to fix it up a little
-
-2009-02-23     Marc-André Lureau
-       16bb658: build: shave it!
-
-2009-02-24     Lennart Poettering
-       9eb5070: introduce new well-known role 'a11y'
-       fb49399: Merge commit 'coling/master'
-       c73887d: update gitignore
-
-2009-02-21     Kelemen Gábor
-       9372733: Make .desktop and .policy file in src/daemon translatable
-       1ddf64a: Make pulseaudio.desktop and org.pulseaudio.policy translatable.
-
-2009-02-23     Lennart Poettering
-       998aa40: fix handling of stereo
-       e0b5507: it's probably more appropriate to return the configured latency instead of the actual latency
-       385a560: complete esd suspend/resume implementation
-       2e9479b: implement esd sample panning. closes #428
-       73c763c: set esound.byte_order property
-       5fa3f0c: allow scache entries to have arbitrary names
-       023ba89: use pa_alsa_safe_delay() where appropriate
-       33601af: print driver name when we encounter driver bugs
-       557a90c:  add new wrapper pa_alsa_safe_delay() around snd_pcm_delay()
-       5cc9d97: add new function pa_alsa_get_driver_name_by_pcm()
-
-2009-02-23     Francesco Tombolini
-       b063e53: Updated linguas file for it lang
-       0be0fc0: Italian language by ubuntu team
-
-2009-02-22     Colin Guthrie
-       2a0d252: Add the module dir to the libpulse pkgconfig file (needed for paprefs)
-       4ebc6cf: Remove references to trademarked terms.
-
-2009-02-22     Lennart Poettering
-       3bc60ca: a couple of boring updates
-       3bccb70: Allow passing a NULL proplist to pa_xxxx_update_proplist() to just fire a notification
-       e335b3d: prepare test for tracking down ens1371 issue
-       2d9ae49: rework suspending/resuming
-       504384a: initialize selem index
-
-2009-02-21     Lennart Poettering
-       194d899: make sure we don't choke on overly long lines in .desktop files
-       edfa39a: make sure we don't choke on PULSE_PROP_OVERRIDE
-       77779ea: rework logging to make it more modular
-       9b74afc: make string translatable (fixes #483)
-       fa5e10f: fix wording, closes #484
-       1a45569: prefer profiles that match the default channel map
-       14ee8d4: print warnings about driver bugs at most once
-       4505bc9: introduce default channel map in addition to the default sample spec
-       27bfa60: add new property PA_PROP_APPLICATION_PROCESS_SESSION_ID and initialize it by default
-       2d0c68a: check for ENABLE_LEGACY_RUNTIME_DIR with #ifdef, not #if
-       e4e6e28: split off foreign code into a convenience library to make gcc warnings go away
-       4c3648a: tell gcc to ignore invalid gtk header files
-
-2009-02-20     Piotr DrÄ\85g
-       a305770: Updated Polish translation
-
-2009-02-20     Lennart Poettering
-       ed67b07: simplify some code
-
-2009-02-17     Marc-André Lureau
-       9f89907: bluetooth: fix suspend on a2dp (to do on HSP non SCO over PCM)
-
-2009-02-20     Lennart Poettering
-       6aa110a: run make update-po
-       3da3ea2: Merge commit 'origin/master-tx'
-       7bc1847: Merge branch 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
-       26a270a: big alsa module rework to make things more robust to broken sound drivers and make it easier to debug them
-       adc9c2d: fix comment
-       fa2e07a: add test tool for debugging broken timing in sound drivers
-       9f813dd: Make sure we actually call _() for translating profile names
-       ef189d5: make it easier to debug timing related problems
-       fdca6ed: make profile names translatable
-       d69bd03: don't try to use weakref stuff on older compilers that don't really support it
-
-2009-02-19     Fabian Affolter
-       aae5b15: Updated German translation
-
-2009-02-19     Lennart Poettering
-       2e250aa: Merge commit '38ded3bb31bc49664641965f856a35f432a8a956'
-       b0c0106: Merge commit 'elmarco/legacy-dir'
-
-2009-02-18     Marc-André Lureau
-       7c78c3f: alsa-util: check if mixer_poll_descriptors_count() < 0
-       800489e: pulsecore: don't leak p when make_random_dir_and_link()
-       f1dcbe0: pulsecore: don't leak d in case of error
-       4722fec: rtp: remove unused variable a
-       88fc458: protocol-native: don't leak a proplist
-       0684b23: stream-resotre: don't leak a name
-       c0cf22d: protocol-esound: don't accept a request of PROTOCOL_MAX
-       2c6abb8: daemon-conf: make sure c->log_level < LEVEL_MAX
-       4f1380b: pulsecore: use r returned from fgets()
-       204083c: pulsecore: unused variable e in hashmap_put()
-
-2009-02-17     Marc-André Lureau
-       60d53c6: tests/ipacl-test: check inet_pton()
-       bb52a67: padsp: don't use si if it's NULL
-       d1306e3: pulsecore: fix check for cb (m is already checked before)
-       67b0bae: pacat: remove unused variable
-       4512a2c: rtp-recv: remove unused variable assignment
-       927e501: pulsecore: remove unused variable from cli_command_load()
-       a252b61: main: remove unused lf variable
-       c3eb908: pactl: return in case of error reading file (avoid using freed d)
-       25bbea6: tests/thread-mainloop-test: check if threaded_mainloop_start() succeed
-       5ea7dac: tests/interpol-test: check if mainloop_start() succeed
-       a836927: tests/sync-playback: check if pa_context_connect succeed
-       93ed27d: pactl: check if pa_context_connect succeed
-       2aeab75: paplay: check if pa_context_connect() succeed
-       6c8d851: protocol-native: fix get_info() for cards
-
-2009-02-19     Marc-André Lureau
-       01f81d6: card-restore: it's not useful to check an array, let's check the length
-
-2009-02-17     Marc-André Lureau
-       ee0b5f7: log: don't leak bt
-       83cdcf2: alsa-util: make sure we check an initialized cn variable
-       7737b10: hal-detect: make sure r is initialized, so we don't take random path
-       7d16dcb: dbus-util: avoid double free
-
-2009-02-19     Lennart Poettering
-       205b0ba: split out mixer setup into seperate functions to make things more readable
-       e1608d5: modernize pa_msleep() a bit
-       9cbdd3a: add pa_timespec_load
-       45218aa: make interpol-test useful for recording as well
-       5f5396b: additional validity check
-       928920c: additional validity check
-       7f8ccf9: handle both positive and negative errno's
-
-2009-02-18     Lennart Poettering
-       6db3073: export card information for sinks/sources and number of sinks/sources a profile would create to clients
-       7b8bed3: introduce pa_realpath()
-       d85ef71: export pa_match()
-       be81a68: if we fail to import a memblock fill in silence to guarantee stability of timing
-       1737a19: allow importing of more memory blocks than exporting
-       07333f8: refer folks to the ALSA devs, not us
-       dc1ad08: minor optimizations
-       ff58fa8: simplify pa_alsa_init_proplist_pcm() a bit and include resolution bits in alsa device props
-       c9c63c2: allow pa to be run in a chroot() environment tht lacks /proc
-       c1892f2: bump required alsa version
-
-2009-02-18     Marc-André Lureau
-       05b7440: pulse/context: add --enable-legacy-runtime-dir
-
-2009-02-13     Marc-André Lureau
-       38ded3b: bluetooth: print SBC encoder implementation info
-       b4c391e: bluetooth: don't crash on pa_thread_mq_done() if pa_init() fail
-
-2009-02-18     Marc-André Lureau
-       b51e613: bluetooth: update SBC from upstream
-
-2009-02-13     Lennart Poettering
-       0b8a6c6: bluetooth: fix message queue/rtpoll
-
-2009-02-15     Lennart Poettering
-       a571565: don't open the alsa devices in hw:xxx mode
-
-2009-02-14     Lennart Poettering
-       6790c03: unify ALSA mixer initialization
-
-2009-02-13     Lennart Poettering
-       023998e: add doxygen comment for PA_GCC_WEAKREF
-       d447a8d: document all currently known properties
-       9334d90: show whether gtk+ support is enabled after configure
-       fffe0ba: ignore gtk-test
-       e954a89: properly read icon/application name/display from gtk/glib/gdk
-       f863756: make PULSE_PROP env vars non-overriding but introduce PULSE_PROP_OVERRIDE for allowing overriding
-       689e6f8: add definition for GCC style weak references
-       44bca66: make PA_GCC_PACKED and PA_GCC_MALLOC actually work
-       c0fb91d: drop check for PA_PROP_APPLICATION_NAME since often enough we can deduce this better from g_get_application_name()
-       15e9b96: we reinit proplist since the server will copy from client proplist anyway
-       62818b8: fix aiff channel mapping for 6 channels
-       433751f: add a module that forwards cork/uncork requests to X11 as fake pause/resume key events
-
-2009-02-13     Iain Hibbert
-       dc590c7: Optionally disable IPv6
-
-2009-02-13     Xavier Conde
-       555527d: Updated catalan po
-
-2009-02-13     Timo Jyrinki
-       b82fccc: Updated Finnish translation against current trunk.
-
-2009-02-12     Lennart Poettering
-       4fab9bf: add full set of argument description
-       6bb3dc8: don't try to recycle rtpoll objects
-       87e1342: don't claim that profile changes are always successful
-       52bfd47: use the same service fd shutdown logic when destructing module and changing profile
-       b18c875: minor service IO fixes
-       d9e3aba: the service fd is a stream socket, so handle things accordingly
-       923dc1b: run make update-po
-       cc526a0: prepare test2
-       e82b2fd: handle errors from BT service properly
-       c3b0d84: make module-hal-detect pick up all cards even when they have no device 0
-       84666db: properly free modargs object when init fails; don't abbreviate modargs in struct
-       a371306: tabs are evil
-       a7b992f: some minor fixups
-       6ada8d1: instead of reparsing the rate module argument when changing profile, simply restore the originally requested sample_spec, this also makes sure the channel count is properly reset
-       752f815: addendum to f56da9893: don't crash when s->sink is NULL
-       1837a96: call _kill functions instead of _unlink since the latter should only be called be the stream implementor
-       f0cc23d: Merge commit 'elmarco/bt-wip'
-       5d15425: minor reformatting
-       60c50bb: declare 'animation' stream role for Flash and suchlike
-       12db1a5: make gcc 4.4 shut up
-       a729786: implement a module that corks music/video streams automatically when a phone call is active
-       823431e: allow sending meta/policy events to clients
-
-2009-02-11     Marc-André Lureau
-       86bec09: pulsecore: add PA_CORE_HOOK_*_MOVE_FAIL
-       f56da98: suspend-on-idle: don't crash when so->source is NULL
-
-2009-02-10     Marc-André Lureau
-       cce4359: bluetooth: reinitialize the sample spec when switching profile
-
-2009-02-03     Marc-André Lureau
-       cac0f9e: bluetooth: export nrec
-       452e2b9: bluetooth: suspend SCO state when over PCM
-       c8a240c: bluetooth: SCO over PCM
-
-2009-02-09     Marc-André Lureau
-       b35ae7f: bluetooth: reconnect to audio service when switching profile
-
-2009-02-06     Lennart Poettering
-       4bd9737: Merge branch 'master-tx'
-       6bb2c49: add #defines for all enums that lacked it
-       04c3c67: A few MacOS X portability fixes
-
-2009-02-06     Erich Boleyn
-       64926ff: RTP segfault/uninitialized resampler
-
-2009-02-05     Piotr DrÄ\85g
-       108e08c: Updated Polish translation
-
-2009-02-05     Lennart Poettering
-       9f39a44: add new module-augment-properties module for augmenting properties from .desktop files
-       d6201cf: parse ini-style sections properly
-       ee5abc3: make native protocol use pa_{sink_input        524d78f: add missing hook
-       291589e: allow overwriting of process properties with environment variables
-       f42afc4: make return value of pa_{sink_input    a67406d: add pa_client_update_proplist() call
-       63e2343: handle default volume initialization properly
-       f6ffd2d: make module-position-event-sounds use volume factor
-       de86c6e: add a 'volume factor' that is implicitly multiplied into the volume of a sink input without being visible to the outside
-
-2009-02-04     Lennart Poettering
-       3fc1233: add a .mailmap file for git shortlog
-       12c29e1: store the identification key in the module-stream-restore.id property
-       9e2a2f8: run make update-po
-       9a4e03c: bump version and soname
-       ae06517: make pacmd work in a pipe
-       3d33172: rate limit underrun messages
-       0933f1a: Merge commit 'flameeyes/flameeyes'
-       d4618c8: Merge commit 'vudentz/master'
-       9a93157: Merge commit 'coling/master'
-       d802a76: remove soft volume from pa_sink_input_new_info since it should be handled internally and automatically by the sink input
-       b2c923e: properly handle failing stream creation
-       786398d: fix a validity check
-       1db6478: version all entries in the database
-       4cf82c7: merge in properties earlier to make identification of streams from hooks easier
-       f6ec971: clarify things a bit
-       12b7359: add a few additional validity checks
-       83ddc09: add new calls pa_replace() and pa_unescape()
-       a625ca7: make gcc shut up
-       078a8d5: rearrange a few things
-       d6dd907: simplify code a bit by using pa_sample_size_of_format()
-       a6fe991: beef up proplist test a bit
-       9a27b8f: in addition to per-property env vars PULSE_PROP_xxx look for for a stringified PULSE_PROP env var
-       b445741: fix up parser in pa_proplist_from_string() to handle escapes correctly; make pa_proplist_to_string() escape quotes properly
-       0fc59e4: add new API pa_ascii_valid(), pa_ascii_filter()
-       ce76216: add pa_sample_size_of_format()
-
-2009-02-02     Luiz Augusto von Dentz
-       004b38f: Prevent changing volume on wrong device.
-
-2009-02-03     Colin Guthrie
-       871389a: A couple of dependancy ordering fixes.
-       d1957b8: Trivial typo in a comment
-
-2009-01-28     Colin Guthrie
-       e28903e: Clean up volume/mute settings a bit. As the APEX device only has one channel of volume (e.g. it's always matched) we emulate any variation in channel volumes in software. Remove the unnecessary callback defininitions.
-
-2009-02-03     Lennart Poettering
-       32e5e64: add a lot of validity checking
-       b51ed38: add a bit of missing i18n
-       543115a: add new API pa_cvolume_compatible_with_channel_map()
-
-2009-02-02     Marc-André Lureau
-       539abc3: bluetooth: typo
-
-2008-10-19     Sjoerd Simons
-       921882d: Load module gconf earlier
-
-2009-02-03     Lennart Poettering
-       fc31d21: when moving a sink between sinks make volume relative
-       554c818: before applying balance/fade check it actually makes sense
-       f9696c0: add a macro definition for each error code
-       2739261: Merge commit 'origin/master-tx'
-       08800c3: make a couple of functions return proper error codes
-       162e43b: make a few functions return void where the retval isn't used/never != 0
-       50bfa77: add new error code PA_ERR_NOTIMPLEMENTED
-       e47d03d: implement PA_STREAM_FAIL_ON_SUSPEND logic
-       c61ad2a: make iterating with pa_idxset_next() robust in regards to idxset modifications
-       f8190be: make update-sbc should also update other BT related sources
-       59f3001: pull in new SBC/BT files
-
-2009-02-02     Lennart Poettering
-       fea6757: don't use PA_STREAM_NOT_MONOTONOUS anymore
-       390133f: big module-bluetooth-device.c rework
-       62f1f3e: make rtp.h ANSI C compliant
-       e412f1c: whitespace cleanup
-       121a8b9: handle EAGAIN properly
-       2854afb: fix soft_mute handling
-       a41d72b: update sbc stuff
-       537424a: reset rewind_requested when we enter suspend mode
-       a9e9ab3: shortcut pa_sink_process_rewind() when no rewind is happenning and none was requested
-       5fc11a0: Fix a few sink/source calls when they are called in suspended state.
-       d6fdd71: add new functions pa_bluetooth_cleanup_name() and pa_bluetooth_get_form_factor()
-       16e3694: set PA_PROP_WINDOW_X11_DISPLAY from :0.0 and initialize PA_PROP_APPLICATION_PROCESS_MACHINE_ID properly
-       8ccc9aa: try to use glib's g_get_application_name() to set PA_PROP_APPLICATION_NAME
-       8fbce6e: when determining the minimum volume of all sink inputs make sure to handle the case when there are no sink inputs correctly
-       55e6331: store the module index shifted by 1 to map PA_INVALID_INDEX to NULL
-       69a9ed9: drop -pedantic
-       04acc23: download everything from gitweb twice to make sure we don't get a 'Generating...' message
-       e0d6b75: add a few new form factors
-       2c97c15: introduce PA_PROP_APPLICATION_PROCESS_MACHINE_ID
-       e0fd99b: work around dlsym() return value mistyping as suggested in POSIX
-       b092f2e: use uintpr_t when casting between pointers and integers
-       55f643d: check for NULL before accessing the name
-       e7007fc: allow passing of channel map on command line and hide unused sliders
-       2c7f2c5: look for libpulse in multiple different places
-
-2009-02-01     Xavier Conde
-       db2a425: Updated catalan po
-
-2009-01-31     Diego Elio 'Flameeyes' Pettenò
-       e9ca8b1: Disable portability warnings from automake.
-
-2009-01-31     ç\94\98é\9c²(Gan Lu)
-       9d65392: Add zh_CN entry for Chinese Simplified translation.
-
-2009-01-31     Lennart Poettering
-       b979ab3: implement pa_channel_map_can_fade
-       f725b06: drop -Wpacked
-
-2009-01-30     Lennart Poettering
-       6b80321: Merge branch 'master' into lennartsbtfixes
-       dbb8951: dump properties when we create a new sink or source
-       2557017: suppress lines made up only of whitespace
-       e6f4586: include ALSA driver in properties for cards/sink
-       4bd6545: add new function pa_alsa_get_driver_name()
-       3442d58: Merge branch 'master' into lennartsbtfixes
-       1c94cfe: Add a little Gtk test tool to show how balance/fade/value and the channel volumes play together
-       1b53f82: implement pa_cvolume_{get      9314db7: fix a bogus assert
-       634afed: properly deal with the case when l/r is silent when adjust balance
-
-2009-01-29     Lennart Poettering
-       4a75002: add missing files
-       a71fa02: temporary commit of lennarts new bt changes
-       47a9b96: add some helpers for dealing with DBusPendingCall based on Mrc-Andre's work in module-bluetooth-discover
-       746dc2a: get rid of nonsensical late initialization of namereg/scache and things
-       4a06af6: make use of new functions pa_dbus_add_matches/pa_dbus_remove_matches
-       509535d: add new functions pa_dbus_add_matches()/pa_dbus_remove_matches()
-
-2009-01-28     Lennart Poettering
-       daf0612: make things compile again
-       86e83d5: Run make update-po
-       f7c3ca7: Merge commit 'origin/master-tx'
-       b56e038: Merge commit '12db687acf3befe485bfff3700111999c95247fa'
-       a5401a5: store the default sink/source in proper pa_sink*/pa_source* pointers instead of a string
-       fc3ff11: fix two typos
-       98821c7: print the right software volume
-
-2009-01-19     Marc-André Lureau
-       12db687: bluetooth: cold hsp/a2dp device detection
-       a6a1b42: bluetooth: hsp volume control
-
-2009-01-28     Lennart Poettering
-       611154c: Merge commit 'coling/master'
-       3affa7e: make m-v-r a stub that simply load m-s-r
-       63157a6: add missing usage strings
-
-2009-01-27     Colin Guthrie
-       6e31178: Fix the message processing for PA_SINK_MESSAGE_GET_LATENCY by returning rather than breaking and falling through.
-
-2009-01-27     Lennart Poettering
-       514661e: don't make m-e-s hit an assert when the latency is queried
-       0f664b7: instead of making the volume relative our own, let' pa_sink_input_new() do it for us
-       e439c18: make m-p-e-s use pa_cvolume_set_balance()
-       d1b754d: only store volume/device information that has been flagged for saving, and store both relative and absolute volumes
-       64b0543: when changing volume, store whether it is worth remembering or no
-       ee17772: add missing 'const'
-       0ca16ca: add new paramter ignore_dB= to alsa modules
-       d5f46e8: move flat volume logic into the core. while doing so add n_volume_steps field to sinks/sources
-       4bfa5d7: fix size calculation
-       eca3223: get rid of module-flat-volumes since we are moving this into the core
-       1be39e4: allow samples to be played with 'default' (i.e. unspecified) volume.
-       5449d79: swap argument order of pa_cvolume_get_balance() to be a bit more systematic
-       df8ad5d: add a few missing doxygen comments
-       6058530: import version.h in all header files to make sure that version-based feature testing works
-       1249cf6: always define PA_MAJOR/PA_MINOR/PA_MICRO to ease feature checking in client applications
-       948be36: invert an ill-placed assert
-       0658d9a: show pretty channel map name if possible
-       07db64b: remove redundant cast
-       9ba4084: store requested resampling method in a seperate field and use it when create a new resampler after a move
-       ccd21f3: make a few comments appear in doxygen
-       3bcbe1d: check for availability of RLIMIT_NOFILE and RLIMIT_AS before we make use of it
-       4e31e00: implement pa_cvolume_scale()
-       e52c5ea: implement new API functions pa_channel_map_can_balance(), pa_channel_map_to_name() and pa_channel_map_to_pretty_name()
-       24b3a74: add a bitset implementation
-
-2009-01-24     Wang Zeguo
-       085ca5f: Updated Chinese(zh_CN) translation.
-
-2009-01-24     Lennart Poettering
-       afd817a: rate limit a warning
-       a365c82: include a few HAL properties in our card/sink/source properties for ALSA devices
-       54dad91: use pa_log_ratelimit() at a few places
-
-2009-01-23     Lennart Poettering
-       77c4ccf: add pa_log_rate_limit()
-       3dfe70c: add generic rate limiting implementation
-       e960125: add support for static mutexes
-       db27c63: make module-alsa-card move streams between the old and new sink/source, allowing 'hot' switching between profiles
-       640d317: add functions to move all inputs of a sink away/similar for source outputs
-       29cb778: move sink input/source output move functions into two parts so that we can start the move, delete the original sink, create a new sink, finish the move; similar for source outputs
-       cf24b57: in most cases we can use i->core instead of i->sink->core and o->coure instead of o->source->core
-       d5e088d: include list of sinks/source in card dump
-       967c17a: teach module-rescue-streams and module-always-sink to not do anything if we are shutting down anyway
-       a3162a3: maintain a pa_core state variable
-       88c9f9f: allow sample spec/channel map to be queried for pa_resampler objects
-       7bdbcd0: drop --ltdl from the libtoolize invocation, since we don't ship ltdl anymore
-       f6fcbed: Merge commit 'flameeyes/flameeyes'
-       5cb29f3: add a simple abstraction for SIMD operations
-       2a238b2: don't overflow when we do digital amplification of 16 bit samples
-
-2009-01-23     daniel cabrera
-       5487bc6: Updated Spanich translation
-
-2009-01-22     Diego E. 'Flameeyes' Pettenò
-       3e5d9fd: Use #ifdef to avoid warning about undefined macro.
-       a257448: Improve the ltdl discovery code by checking for libtool 2.x functions.
-       3293251: Move the safety check about pkg-config in bootstrap.sh.
-       1b20d28: Fix logic thinko.
-       c65d3a9: Remove support for internal distributing and bundling of libltdl.
-
-2009-01-22     Lennart Poettering
-       ddbe612: use pthread_setaffinity_np() only when it is available
-       cef5f48: make rtstutter use pa_ncpus()
-       4dc1916: add API pa_ncpus()
-       bb23932: When resuming an OSS device ask for the very same fragment settings as we did the first time
-       3be4c31: rework module-hal-detect and make it use module-alsa-card instead of module-alsa-sink/-source
-       b2ef19a: include PA_SINK_INVALID_STATE in all switch/case statements to make gcc shut up
-       4b2a682: fix minor memleak in prober
-       b606c09: rework logic how alsa sinks/sources/cards are named
-       7c11554: make gcc shut up
-       1c84251: fix segfault when in record-only mode
-       8519f54: only reread volume if we actually have a good mixer. Closes #466
-       40f2e21: make gcc shut up a bit more
-       a5c9546: fix copy'n'paste error
-       251f720: add new function pa_strna
-       36362f6: add new function pa_card_suspend()
-       bdfec1f: mark a few more ALSA dB values as 'valid' for valgrind
-       0f7954a: don't include full path in driver name.
-       bf7217b: require autoconf 2.63
-
-2009-01-22     Jared D. McNeill
-       7c7133e: NetBSD sometimes doesn't know SNDCTL_DSP_GETODELAY
-       c0e4e5a: NetBSD doesn't know getgrnam_r()/getpwnam_r()
-       61075a7: NetBSD doesn't know ENOLINK
-       ca6b791: It is more portable to assume that SO_RCVBUF/SO_SNDBUF takes and int instead of a size_t
-       8d89ccd: NetBSD specific atomic operation implementation
-       cc425ed: NetBSD doesn't know RLIMIT_AS
-       75eeea6: NetBSD needs to include sys/uio.h for some socket functions
-
-2009-01-21     Lennart Poettering
-       601293d: implement pactl set-card-profile
-       996bba7: implement PA_COMMAND_SET_CARD_PROFILE
-       1375a9a: enable module-card-restore by default
-       13315a7: add a card profile restore module
-       c512ebf: minor cleanups
-       10e5c70: don't restore mute/volume when already set
-       9661cd0: make pa_card_new_data::active_profile a string
-       e8f93b1: make implementation of module-alsa-card complete
-       7ca0e00: fill in dev_id properly
-       28f05e0: remove leftover define
-       cba4c6b: when changing profiles do the actual assignment in the generic implementation
-       1d0bd6e: remove bogus pa_core_check_idle() call
-       dc2a4bd: add set-card-profile CLI command
-       9a0dbda: allow cards be referenced by their index
-       b6b0e07: fix copy/paste error
-       16d200e: add an API to create arbitrary alsa sinks/sources dynamically without having to load/unload modules
-
-2009-01-20     Lennart Poettering
-       b88b89a: add new call pa_alsa_open_by_device_id_profile()
-       04e9214: export pa_channel_map_superset()
-       7368a6e: add priority logic to find best default profile
-       b3a043f: always add 'disabled' profile
-       e0f8c13: remove unused variable
-       86f3fb8: show active profile
-       a65c2c7: add client API for querying card information
-       85bc5eb: dump active profile
-       7aa7a7b: fix destruction when no profiles are defined
-       9368623: don't divide by zero if no left resp. no right channels are defined
-       67fcc76: fix profile names to include input/output specifier
-       b23efc0: add missing eof checks
-       47a2f9e: Merge commit 'flameeyes/buildfixes-2'
-       d5e895d: document that I am a retard
-       8839d86: remove misplaced whitespace
-
-2009-01-20     Diego E. 'Flameeyes' Pettenò
-       bc41fdb: Include the alsa/ subdirectory for modules in the search path.
-       bd70e80: Allow to opt-out from building tests.
-
-2009-01-19     Lennart Poettering
-       8c4e2be: include sink/source state in pactl output
-       8886e66: Document explicitly that the internal sink/source states are not considered part of the ABI/API
-
-2009-01-16     Marc-André Lureau
-       310f433: pulse: share private enum values with client side
-
-2009-01-15     Marc-André Lureau
-       a3762a2: cli: fix broken array access with signed state enums
-       6374f8e: sink: trigger subscribe event on sink state change
-       9c4f8e6: pulse: introspect sink state
-
-2009-01-19     Lennart Poettering
-       f83111d: Merge commit 'vudentz/master'
-       96f01bf: Merge commit '7104d54bbce8f9bd2553e16f45f3a0f69ac75b8b'
-       5f6641c: Beef pactl output up a bit
-       ed65081: show dB and balance for cached samples
-       033791c: fix up balance format string a bit
-       23cd942: fix doxygen version references
-       b987e5e: fix bad free()
-       b43a45d: allow setting properties for modules, too
-       fe70301: show balance value in CLI listings
-       723d71a: add api for manipulating volume balances
-
-2009-01-19     Diego E. 'Flameeyes' Pettenò
-       7104d54: Add proper -I directives for out-of-tree builds.
-       348c2ca: Create only the directory the current target should be created into.
-
-2009-01-19     Luiz Augusto von Dentz
-       4460a5d: Fix hsp rate and channels.
-
-2009-01-17     Lennart Poettering
-       606cf8a: get rid of pa_module_get_info because it is not used
-       76ca5b8: beautify cli output a bit
-       f8ba3a9: dump profiles when listing cards
-       c06e43d: actually create pa_card object in module-alsa-card
-       c560aea: Don't enumerate invalid profile
-       f03a7e4: Split up pa_alsa_init_proplist into two seperate functions for the card and snd_pcm_t specific parts
-       a45f971: add pa_proplist_to_string_sep()
-       4a66837: add pa_strbuf_isempty
-
-2009-01-16     Lennart Poettering
-       b4d8046: add card profile prober
-       b2b2eb1: remvoe a bit of duplicate code
-       5793f93: make use of PR_SET_TIMERSLACK
-       4a13763: Add support for 24bit samples encoded in the LSB of 32 bit words
-       6dc76d1: add support for 24bit packed samples
-       9955398: fix version info in protocol history
-
-2009-01-15     Lennart Poettering
-       4d4956e: Add SPDIF/HDMI ALSA devices and device descriptions to device search table
-       33c22b0: rename card config to card profile
-       d4bda31: include libcli.la in libprotocol-cli's dependencies
-       4210119: add stub makefiles for oss and alsa subdirs
-       c7fff97: move alsa and oss modules into their own subdirectories
-       bae221c: rework module usage counter stuff to be pull based
-       edf88a5: don't show autoload flag anymore since it is obsolete
-       47a2b17: make proplist inheritance scheme automatic and implicit
-       e68e4a5: make things compile again
-       395523a: we don't support glib1.2 anymore
-       29c7a28: kill autoload stuff as planned
-
-2008-11-10     Marc-André Lureau
-       43762ed: flat-volume: use pa_sink_get_volume(s, TRUE) to work with slaved sink
-
-2009-01-15     Lennart Poettering
-       a861ffa: Merge commit 'e0f8ffe41f99789fafac575e944acf02e940bbf7'
-       d2757c9: redirect folks to the ALSA developers not me when their sound drivers are broken
-       615e055: add functionality to dump list of cards
-       344c934: maintain a list of sink inputs/source outputs as part of the pa_client object
-       b6deb0c: add new pa_card object as a way to logically combine multiple sinks and sources
-       aeb0707: fix bad memory access
-       0b0b3d8: make PA_CONTEXT_IS_GOOD/PA_STREAM_IS_GOOD a macro so that we can easily check for its availability
-       a3695dd: port missing modules to new pa_client_new() API
-       5abda63: convert pa_client instantiation to use a pa_client_new_data struct and add hooks for manipulating it
-       75119e9: add new dont_rewind_render flag to allow quick starts of newly created streams
-       06de639: don't rely on PA_SINK_RUNNING vs. PA_SINK_IDLE for optimizations since it might not be fully up to date
-       d1cf0e7: fix a potential format string vulnerability
-       fd3f5db: document that PA_API_VERSION is only for incompatible API changes
-
-2008-11-17     Marc-André Lureau
-       e0f8ffe: match: add "key" argument to match different properties
-       e97ed21: match: can now change properties also
-
-2008-11-10     Marc-André Lureau
-       6ec0162: sink: add a virtual_volume to sink
-
-2009-01-14     Lennart Poettering
-       20edd84: make pa_asyncq_push() fail under no circumstances.
-       587a08b: Fix a typo I know owe Marc-Andre a beer for.
-
-2009-01-13     Colin Guthrie
-       df56404: Fix a potentially non-returning function in base64 code.
-
-2009-01-14     Lennart Poettering
-       f310113: Merge commit 'elmarco/master'
-       ab97364: remove calc_sine() since we don't need it anymore
-       cd45cd9: include new proplist functions in export list
-       407b4fe: fix calculation of avail_min
-       1872526: add pa_proplist_size() and pa_proplist_isempty()
-       ef5a2b5: Fix version info
-
-2009-01-13     Marc-André Lureau
-       09641cc: build: fix few warnings
-       49ae383: cli: add missing update-*-proplist
-       2204bbe: core: add source, si, so proplist_update
-
-2008-11-10     Marc-André Lureau
-       3d631df: build: print more informations about preopen
-
-2008-10-31     Marc-André Lureau
-       9d6e9f5: cli: update-sink-proplist
-
-2008-10-27     Marc-André Lureau
-       01f71ac: libpulse: add proplist_from_string
-
-2008-12-04     Marc-André Lureau
-       9e978c9: core: report remaining shared objects when cleanup
-
-2008-10-31     Marc-André Lureau
-       ebb903a: core: add pa_source_update_proplist
-       9444347: core: add pa_sink_update_proplist
-
-2009-01-12     Lennart Poettering
-       f6ac7b4: bump version/soname
-       2ecf4c3: Merge commit 'origin/master-tx'
-       f67066b: Port sine modules to pa_memchunk_sine()
-       b8e6aae: add new API function pa_memchunk_sine()
-       949de81: Extend command name lookup tables to cover complete protocol
-       aff7243: Fix suspending of all sinks/sources
-       d94d39d: read base volume only in proto 15
-       b9e96e0: for record streams fill in the latency as the fragsize
-       947a828: fix version check
-
-2009-01-10     Lennart Poettering
-       b6804ee: Make sure we don't drop any data on the client side
-       8a3dc57: make module-sine-source actually work
-       4e8ada5: show maximum usable slot size
-       c850aa0: Add new pa_reduce() and pa_gcd() functions
-
-2009-01-09     Piotr DrÄ\85g
-       cf3abcd: Updated Polish translation
-
-2009-01-08     Lennart Poettering
-       98049fb: make things compile again
-       7b52840: add a few missing parens
-       5daf141: drop a few warning options, add a few new ones
-       c2002dc: Merge branch 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
-       9fc726c: Add new test source module-sine-source
-       e5c0938: A few minor cleanups and updates
-       aff7768: Add new debuuging API pa_memchunk_dump_to_file()
-       7ca0f38: run "make update-po"
-       6b9056c: Merge commit 'origin/master-tx'
-
-2009-01-08     Marc-André Lureau
-       a1a1119: build: fix missing x11 modules dependencies
-       7e6309c: bluetooth: Update sbc from git upstream.
-       d096ad7: bluetooth: add update-sbc and friends
-       8e200ed: build: run some tests during make check (and distcheck)
-       de57edd: build: Use proper -disable-static instead of removing .a
-       c8b3d8b: build: add atomic.h and refcnt.h to libpulsecommon
-       db193f1: build: introduce $SKIP_GIT for make dist (off-line or behind a proxy).
-       a206ac0: build: Don't include builddir, but only srcdir.
-       e92b0ae: build: compile libltdl directory first
-
-2009-01-07     Marc-André Lureau
-       dd9ca70: build: use pkg-config for X11
-
-2009-01-08     Lennart Poettering
-       c245050: Prefer mixer controls with volumes over switches
-       e67bc1d: -Wconvert is pain, let's drop it again
-
-2009-01-07     Sean McNamara
-       81cd219: --check: Updated manpage slightly and pulseaudio --help slightly.
-
-2009-01-07     Lennart Poettering
-       2f681a3: Merge commit 'vudentz/master'
-
-2008-11-27     chocolateboy
-       78e636e: Fix typo in log message: s/Recevied/Received/
-
-2009-01-06     Luiz Augusto von Dentz
-       e7e6f86: Fix sending wrong codec capability length.
-       1a96c9b: Fix send and recv message sizes.
-
-2009-01-05     Luiz Augusto von Dentz
-       be49c92: Send packets with proper size.
-
-2008-12-20     Tom Bamford
-       fe2b8c3: Multicast SDP packets sent with same IP TTL as RTP packets
-
-2008-12-30     Piotr DrÄ\85g
-       17ae579: Updated Polish translation
-
-2008-12-24     A S Alam
-       cb5af19: Add Punjabi Translation for Module
-
-2008-12-24     Lennart Poettering
-       2ff20ce: Rework handling of the PA_SINK_LATENCY/PA_SOURCE_LATENCY flags
-       fb4c111: Implement base_volume for ALSA sinks/sources
-       6130c5c: Add "base volume" field to sinks/sources
-       3e3c103: Add APIs to pass pa_volume_t fields in a tagstruct
-       6342053: Add new API functions pa_volume_snprint() and pa_sw_volume_snprint_dB()
-
-2008-12-23     Lennart Poettering
-       f24e4c1: Merge commit 'vudentz/master'
-       c2bd8dc: fix a gcc warning
-       22c3373: If we cannot open an ALSA device with SND_PCM_NO_AUTO_FORMAT retry without
-
-2008-12-17     Luiz Augusto von Dentz
-       7323e1a: Update module-bluetooth-device to the new ipc.
-       5db081a: Disable warnings for bluetooth-device-module.
-
-2008-12-21     Lennart Poettering
-       03aa91d: make sure we don't hit an assert when we issue two rewind requests in a single iteration
-       606c9ca: Implement PA_SOURCE_MESSAGE_GET_LATENCY
-       10cc4ba: Use FIONREAD instead of TIOCINQ
-
-2008-12-18     Lennart Poettering
-       63fc26e: Allow access("/dev/dsp", W_OK) succeed
-       1d2e5cb: Make sure we drop CAP_NICE if RT is not allowed
-
-2008-12-17     Lennart Poettering
-       d71d79c: downgrade a few warnings
-       906d06b: it's better to always use the index of a module instead of the pa_module*
-       f5d40fa: unload tunnel modules from a new stack frame
-       b95539b: actually unload the modules from a new stack frame
-       86c6fd8: Don't store pointer to pa_module
-       c5b8eb7: introduce new function pa_module_unload_request_by_index
-
-2008-12-05     Luiz Augusto von Dentz
-       dcd498c: Fix bug walking on module list.
-
-2008-12-17     Lennart Poettering
-       82f09b6: Don't hit an assert when checking for idleness
-       cb6a919: Load module-volume-restore and module-device-restore before all other modules
-       3f20a15: Pass GDBM_NOLOCK to gdbm
-       209a8d7: Don't mix front-center into rear channels
-
-2008-12-16     Lennart Poettering
-       b8fe1b6: fix implementation of bind now ltdl loader for libtool 2.2
-       e4aa5f2: Fix return value of --dump-resample-methods
-       8977b2e: libtool 2.2 updates
-       7013849: Check if environ is actually set before we use it
-       2ee9276: Merge commit 'flameeyes/libtool-2.2'
-
-2008-12-01     Timo Jyrinki
-       55d846f: Argh, send pulseaudio Finnish translation (instead of paprefs) by Timo Jyrinki.
-       fe5c651: Add fi (Finnish) to LINGUAS.
-       ba64071: Add Finnish (fi) translation by Timo Jyrinki.
-
-2008-11-23     sainrysec
-       e9ca860: Only creat zh_CN.po
-
-2008-11-21     Henrique Junior
-       7f9a6ae: Updated brazilian portuguese translation
-
-2008-11-11     Piotr DrÄ\85g
-       946b34b: Updated Polish translation
-
-2008-11-07     Xavier Conde
-       7582bf5: Added catalan locale
-       69aaaf1: Added catalan translation
-
-2008-11-01     Lennart Poettering
-       f826ded: make shm marker architecture independant, patch from michich, closes #401
-       84cd233: Make sure libpulse never gets unloaded
-       58b53bb: a bit of pa_bool_t'ization
-
-2008-10-26     Lennart Poettering
-       adc2973: Implement new flags DONT_INHIBIT_AUTO_SUSPEND and START_UNMUTED
-
-2008-10-25     Lennart Poettering
-       c180cb5: bump micro version
-       1d978ce: Merge branch 'new-world-order'
-
-2008-10-24     Lennart Poettering
-       b712e7b: make sure to use 64bit rounding even on 32bit machines when converting to pa_usec_t
-
-2008-10-22     Lennart Poettering
-       3294c89: warn if ALSA wakes us up and there is actually nothing to do
-       6ff9c1f: don't set the volume of pacat unless it is explicitly set
-       a2b3d25: update map file
-
-2008-10-21     Lennart Poettering
-       1cd25f1: reorder setting of AM_CFLAGS a bit
-
-2008-10-22     Lennart Poettering
-       ef0cc74: a lot more build system updates
-       695d300: make new build logic actually work
-       b978d84: update map file
-
-2008-10-21     Fabian Affolter
-       8dce771: Updated German translation
-
-2008-10-21     Lennart Poettering
-       df6e38b: temporary commit to allow flameeyes a look
-       260fc50: reorder setting of AM_CFLAGS a bit
-       c4b3462: make the debug trap macro a proper macro in macro.h
-       ef9f3f6: Try to catch certain driver errors
-       1647191: make log meta, time, backtrace configurable using command line
-       496499c: Make log meta, time, backtrace configurable using config file
-       651a451: support changing logging parameters during runtime using the CLI
-       f4320d8: Support showing a backtrace on log messages
-       f92a814: include log.h near the end so that macro.h can be included in log.h and defines pa_bool_t properly
-       d4c6342: add pa_config_parse_unsigned()
-       c7ed771: fix arguments to format string
-       7fecb23: convert argument to boolean int in PA_UNLIKELY, too
-       519bb55: fix return value of pa_frame_aligned()
-       4ee5e06: implement may_move_to for ladspa/remap sinks
-       358824b: add new virtual function may_move_to to sink inputs/source outputs to allow modules to forbid certain connections
-       309bc71: fix invalid validity check
-
-2008-10-21     Micha Pietsch
-       737beea: German translation done.
-
-2008-10-20     Lennart Poettering
-       b709e1d: Make missing git-changelog.perl non-fatal
-
-2008-10-19     Petr KováÅ\99
-       e88a115: Updated Czech translation.
-
-2008-10-19     Lennart Poettering
-       d675058: Fix spelling of privilige
-       d395792: always check for libtool prefix binary name to avoid confusion when using both installed and run-from-build-tree versions of PA in parallel
-
-2008-10-18     PabloMartin-Gomez
-       38b08a2: Last strings translated to French
-
-2008-10-17     Piotr DrÄ\85g
-       304526b: Updated LINGUAS
-
-2008-10-14     Piotr DrÄ\85g
-       a34b8ab: Updated Polish translation
-
-2008-10-13     Lennart Poettering
-       60c2a82: Merge commit 'vudentz/master'
-
-2008-10-11     Colin Guthrie
-       d8465f2: Fix two typos that broke tunnels
-
-2008-10-13     Lennart Poettering
-       5a5d288: properly remove dbus matches an filters when unloading m-b-d
-       65ea1a2: correctly load module-flat-volume instead of module-flat-volumes
-
-2008-10-12     Petr KováÅ\99
-       0ad8e7e: LINGUAS: Added cs.
-       dda7ab1: Added Czech translation.
-
-2008-10-12     Domingo Becker
-       a78cf07: updated spanish translation
-
-2008-10-09     Luiz Augusto von Dentz
-       931cbd1: Fix possible invalid read while attempting to load module-bluetooth-device.
-
-2008-10-08     Lennart Poettering
-       8e3e88d: Merge commit 'coling/airtunes-0.9.13'
-
-2008-10-08     Colin Guthrie
-       91b64bc: Fix a potential C++/C99 ism, add a log message on error condition
-
-2008-08-22     Colin Guthrie
-       59eb649: Follow master change r34dd4a and fix shutdown when --disallow-module-loading=1 is passed
-
-2008-08-03     Colin Guthrie
-       8715121: Modularise the RAOP stuff that requires OpenSSL and make it optional at compile time
-       c3d8bb5: Remove $Id$ lines left over from SVN
-       19d2831: Make module-raop-sink/discover work with 0.9.11 API
-
-2008-07-03     Colin Guthrie
-       ded09d1: Implement hardware volume control. This allows near instant change of volume when controlling the hardware but the stream volume still suffers from a sizable delay.
-       e543e04: Implement a set volume function to expose this capability to higher layers
-
-2008-06-24     Colin Guthrie
-       36f2aad: Use the new pa_namereg_make_valid_name() function.
-
-2008-06-11     Colin Guthrie
-       0ff75ae: Add Lennart back in to Copyright as I copied these files from his originals and was a bit overzealous in changing things ;)
-       729bbaf: Automatic discovery of airtunes devices via Bonjour/Avahi.
-       d997420: Minor correction of help text
-       15e8420: Still send silence when we are not doing anything else, but also flush the buffers correctly upon recovery from suspension.
-
-2008-06-10     Colin Guthrie
-       c49be78: Add some new public API functions to connect and flush.
-       d86fc75: Change the API of the RTSP client a bit.
-
-2008-06-09     Colin Guthrie
-       19dcb52: Remove unneeded headers accidentially added in r2500.
-       5f527dc: Add seq and rtptime params to record/flush with a view to using these for timing and device suspension
-       651da7d: Minor update to copywrite (I still plan to replace this completely but in the mean time....)
-
-2008-06-03     Colin Guthrie
-       7f0cf0c: Fix up a couple of values related to encoding overhead.
-
-2008-05-26     Colin Guthrie
-       13bc075: A few related changes:
-       b93e9e8: Keep track of the memblock pointer internally and do not rely on subsequent calls to pass it back in for unref'ing
-       8108121: Set forgotten keyword property
-       6dc5e07: Set the send buffer size to prevent rendering silence in amongst our good data (this should be more sophisticated but that can wait for a glitch-free port)
-       6c1dd6e: Move the encoding loop around a bit such that it does not grab the data and keep it for the next loop iteration.
-
-2008-05-11     Colin Guthrie
-       3767cdb: Do tidy up on disconnection.
-       9216684: Do not prefix internal function rtsp_exec.
-       eca94fe: Don't try to free stack variables.
-       be73d37: unref the raw data memblock before requesting more data.
-       cb8c5a9: Some misc fixes. consts, base64 optimisation (not that it will be with us long anyway), and c comments
-       4b7b7b1: Fix up IPv6 address format to enclose it in []
-       d195d06: Change suggested by Lennart. Do not return a memchunk, instead pass in the pointer.
-       e00127f: Various changes suggested by Lennart.
-       ec9a618: Listen to the on_close callback. This still causes asserts in the mainloop, so this is not a complete solution
-       899492c: Add a new callback structure to propigate when the RTSP connection dies
-       5eecfa2: Move the ownership of the encoded data memchunk into the raop_client.
-       4dd3185: Do not assert on NULL values of s. This means the connection was closed. This change somehow kills the mainloop with an assert, so I need to sort that out.
-       d51f594: A very rough first version of the sink.
-       264a1c2: Add more libraries to librtp now that it's doing a lot more.
-       f97c5de: Properly duplicate the hostname passed in on connect.
-
-2008-05-10     Colin Guthrie
-       1fb0465: Combine pa_raop_client_new and pa_raop_client_connect (no point in having them separate)
-
-2008-05-07     Colin Guthrie
-       41e31ab: Rename rtsp.{c,h} to rtsp_client.{c,h}.
-       e596f42: Wrap the io_callback to ensure that all data is written before asking for more.
-       6510d97: Use a more stateful response parser.
-
-2008-05-06     Colin Guthrie
-       22e299a: Add a pa_iochannel callback for when the RAOP connection connects.
-       8fb58e3: Add a function for packing bits into a byte buffer. This will be needed when encoding the audio data in ALAC format.
-       66cf1d1: Some minor tidyup to remove code now in raop client. Still nowhere near functional.
-       20478a4: Add a skeleton raop client which builds on the rtsp client.
-       d423605: Move closer to an asynchronous structure (still some parsing code to be converted).
-       a0d3582: Trivial change to allocate memory using pulse methods.
-
-2008-05-04     Colin Guthrie
-       a08d733: Fix svn properties and some minor indentation
-       27ed970: Convert the return values to fit with the rest of pulse 0 == success, < 0 == failure
-       405cf72: Convert to using pa_socket_client rather than using blocking IO.
-
-2008-05-02     Colin Guthrie
-       ce9a41e: Use _free rather than _destroy so as not to mix naming conventions.
-       91edf9e: Use pa_sprintf_malloc to do simple concatenation rather than using the higher overhead of pa_strbuf
-
-2008-05-01     Colin Guthrie
-       6570620: Start the raop sink. It's based on pipe sink and isn't anywhere near finished. It does however compile.
-       fef102e: Add a simple base64 library that will be used by the sink
-       4847706: Add a RTSP client impelmentation.
-       8c1c565: Add a small lib to interpret and produce headers as used in http style requests.
-
-2008-10-08     Lennart Poettering
-       068afb3: define 0dB in PA as maximum amplification
-       a8dc2aa: enable flat volumes by default
-       2dfc265: Merge branch 'flatvol'
-       37b8c45: query the sink volume outside of the loop because it might be quite expensive
-       34f6a51: use pa_sink_set_volume() for changing the volume
-       b048ae9: check the maximum volume of all sink inputs instead of the average volume to avoid digital amplification in favour of attenuation
-       404cf74: some minor reformatting
-       8bc58cc: ignore sinks that do not carry decibel information
-       776c8de: remove $Id$
-       b6ccea3: add a comment that pa_sink_input_set_volume and module-flat-volume.c are related
-       9f4033d: if a stream comes with now sensible properties attached, use common fallback db entry.
-
-2008-10-07     Lennart Poettering
-       68cc299: after calling PA_CORE_HOOK_SINK_SET_VOLUME hook, check again whether the volume changed
-       46f73fb: additional validity checks
-       e053fa0: if the channel map was modified due to PA_SINK_INPUT_FIX_CHANNELS, remap the specified volume properly
-       e1dbc75: use pa_channel_map_init_extend() instead of pa_channel_map_init_auto() as channel map for sink inputs/source outputs in case no map is specified
-       ae83483: modernize a few checks
-       72024cd: when the volume is changed make sure we send out a subscription event
-       624f220: instead of resetting virtual_volume unconditionally on initialization, do so only when no volume was set before
-       5925d44: Merge commit 'origin/master-tx' into master-tx
-
-2008-10-06     Luiz Augusto von Dentz
-       3d7b76d: Unload module-bluetooth-device if the remote device disconnects.
-
-2008-10-07     Lennart Poettering
-       c8a963a: Initialize exit_idle_time to -1 instead of 0  when in system mode.
-       1e513c3: Initialize exit_idle_time to -1 instead of 0  when in system mode.
-
-2008-10-07     Marc-Andre Lureau
-       80a79b1: flat-volume thingy
-       4541274: volume hooks
-
-2008-10-06     Lennart Poettering
-       fa93cb7: make distcheck pass
-       e26ffc9: Merge branch 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
-       be667af: Merge branch 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
-       0274651: bump version and sonames
-       f64d6af: Merge commit 'vudentz/master'
-       aa43739: make sure we send a started messages when we are uncorking
-
-2008-10-05     Lennart Poettering
-       5996f59: update module-tunnel for recent protocol changes
-       f728e9c: disable valgrind macro usage for now since valgrind generates a lot of spurious warnings as it seems
-       6d52a41: add missing include
-
-2008-10-04     Lennart Poettering
-       a9c1bb3: substract the unused record buffer size from the overall size before calculating the space still left for recording
-       83b1d7a: get rid of pa_alsa_volume_divide() since we have pa_sw_volume_divide() now
-       da4ad5e: implement pa_sw_volume_divide() and pa_sw_cvolume_divide()
-       87c8132: increase suspend timeout to 5s so that it is always longer then the default tsched buffer size of 2s
-       530b95f: don't call snd_pcm_drain() when we suspend because that might take awfully long with our long buffer sizes these days
-       88130eb: add missing inclusion
-       82c46f2: do not cleanup staticly allocated memory unless we are in valgrind mode
-       3c19352: show valgrind status on startup
-       9b00664: instead of checking for  directly use new function pa_in_valgrind()
-       8222f12: add new API function pa_in_valgrind() to check for
-
-2008-10-03     Luiz Augusto von Dentz
-       fef63d7: Fix loading module-bluetooth-device with an invalid parameter.
-       0c998b0: Replace handlers of deprecated Connected signals with new PropertyChanged.
-
-2008-10-01     Luiz Augusto von Dentz
-       b205fcc: Cleanup module-bluetooth-discover.
-       20f68bc: Fix Connected signal handler.
-       04677cb: Fix match rule problems.
-       0be845f: Remove PropertyChanged signal handler.
-       3b427b7: Add signal handlers for Connected signals.
-       443ea47: Add match rules for org.bluez.Headset and org.bluez.AudioSink.
-
-2008-10-03     Lennart Poettering
-       7a1a147: rename pa_cvolume_snprint_dB to pa_sw_cvolume_snprint_dB since it is useful only for software volumes
-       c0815de: allow - in sample names
-       28af994: increase PA_CVOLUME_SNPRINT_MAX to a proper value and document that it is not considered part of the ABI
-       bde142c: when checking the validity of a cvolume check whether all values are not -1
-       c0a9e8b: add missing calls to map file
-       ebb2ecb: add new API call pa_cvolume_compatible()
-       619ed8a: add new API call pa_cvolume_snprint_dB()
-       be77bcd: add new API call pa_cvolume_init()
-       db975c7: extend documentation for pa_channel_map_init()
-       2367212: make a few casts explicit to remove compiler warnings
-       7c2cb77: a bit of late pa_bool_t'ization
-       d56f375: treat a channel map only then as compatible with a sample spec if it is valid
-       8919898: add new API function pa_sample_spec_init()
-       8a50105: if a volume or channel map is invalid show so when printing it
-       33b186e: user lrint() and friends in inner loops instead of normal C casts to speed up a few things
-       1bb5e58: use PA_FLOAT32_SWAP where useful
-       7d442e3: optimize mixing routines a bit by pulling the multiplication with the global volume out of the inner loop by applying it first to the per-stream volumes
-
-2008-10-02     Lennart Poettering
-       a0f4ffd: make sure we call pa_sink_process_rewind() if a rewind was requested under all circumstances
-       ea82dec: when we mix into a 16bit accumulator make sure we clamp before we scale with a volume to avoid range faults when multiplying
-       08cf9db: properly parse response to pa_stream_set_buffer_attr() calls. closes #370
-       54afcf2: inform dsp_empty_socket() *after* we emptied the dsp socket, that it is now empty
-       9f5d052: make simple protocol not crash when allocating a memory block
-
-2008-10-01     Lennart Poettering
-       cf3f80e: when killing gconf helper, loop over EINTR
-       ea15ca9: PA_WARN_REFERENCE works only for ELF targets
-       3853070: don't hit an assert if a kernel driver reports invalid dB information, instead just warn the user
-       5d18b62: remove useless log message
-       4b67ea1: remove useless log message, re #367
-       99acad7: fix support for ALSA devices which lack dB information
-       c4bdc2f: it's --daemonize, not --daemon
-       9e79c87: Merge commit 'coling/master'
-       644f39d: a few FreeBSD fixes, from alexis
-       f04cfcd: replace module-volume-restore by module-stream-restore in system mode, too
-       6d74504: it might be a bit too early to initialize bluetooth by default for now, since it's still very rough around the edges
-       0c3eb9f: fix typo in default.conf, closes bug #354
-       00b70a8: follow PropertyChanged signals from BlueZ
-       d299ac5: Some man page updates, add missing documentation, other fixes.
-       79ad4e6: Make the shared memory segment size configurable
-
-2008-09-26     Nix
-       a84b72b: esound auth-ip-acl fix
-
-2008-09-23     Stelian Ionescu
-       564ef2b: have make_random_dir respect $TMPDIR
-
-2008-09-29     Lennart Poettering
-       f5c301d: make module-bluetooth-discover actually load modules and smaller other fixes
-       3f4bc03: all kinds of minor type, memory leak, initializatio fixes
-       a35f84a: instead of failing when the requested sampling rate is not available find the next one that is higher
-       aa1974b: Use the same module parameter names for module-bluetooth-device as for most other modules
-       7923731: use TRUE for pa_bool_t arguments
-       60e9744: remove a few compiler warnings in BlueZ code
-
-2008-09-29     Fabian Affolter
-       8c2a7c8: Some strings done in German translation
-
-2008-09-27     Lennart Poettering
-       87971c8: fix compilation errors in priority queue code
-
-2008-09-26     Lennart Poettering
-       9adf7c5: ignore bt proximity helper
-       3ad8c04: add a generic priority queue implementation
-       3e16d2f: make pa_idxset_trivial_compare_func() do a full compare instea of just equakity check
-       183f2e0: some minor fixes and cleanups in the bt code
-
-2008-09-24     Igor Pires Soares
-       4b45985: pt_BR added to LINGUAS
-
-2008-09-21     Herli Joaquim de Menezes
-       7f8d4bc: Transmitted-via: Transifex (translate.fedoraproject.org)
-       5108b3d: Transmitted-via: Transifex (translate.fedoraproject.org)
-       62b4b58: Strings do PulseAudio traduzidas para o português do Brasil.
-
-2008-09-12     Lennart Poettering
-       6188737: make sure ~/.pulse exists before we create the runtime dir link beneath it
-
-2008-09-11     Fabian Affolter
-       18d8999: Some strings done in German translation
-
-2008-09-11     Lennart Poettering
-       d68c2c9: replace Makefile stub copies by symlinks
-       8257214: enable bluetooth by default
-       c0a1706: downgrade a D-Bus log message to debug
-       db955e8: add trivial redirecting makefile to bt dir
-
-2008-08-31     João Paulo Rechi Vita
-       4ae124b: Move bluetooth proximity module to src/modules/bluetooth/
-
-2008-08-30     João Paulo Rechi Vita
-       8b02c2f: Change all int vars that doesn't allow negative values to uint
-
-2008-08-29     João Paulo Rechi Vita
-       78a3c72: Move bluetooth discover and device modules to src/modules/bluetooth
-       76bae38: Cleanup some code
-       6093e32: Remove some warnings
-       02a9273: Free mempool
-
-2008-08-28     Russ Dill
-       447e027: Fix "file not found" error on load of module-bt-device for Ubuntu Intrepid Ibex
-
-2008-08-26     João Paulo Rechi Vita
-       8769bf4: Merge A2DP and SCO thread functions
-
-2008-08-25     João Paulo Rechi Vita
-       199bdf2: Add some more device properties to the sink properties list
-       e2f3a86: Remove check for SIOCOUTQ and add proper includes
-       dc4f796: Use union instead of different pointer types to the same memory area to make the code C99 compliant
-
-2008-08-21     João Paulo Rechi Vita
-       d1cc632: Move render and write to the fd to a separate function
-       88a21e9: Change MIN/MAX to PA_MIN/PA_MAX
-       27bc1ea: Remove unnecessary initialization of getcaps_req->flags
-       027940b: Remove u->channels and u->rates, since it's redundant info
-       0e81757: Fix some memory leaking
-       e752cac: Change sbc_initialized to pa_bool_t
-
-2008-08-20     João Paulo Rechi Vita
-       708905c: pa__done for module-bt-device
-
-2008-08-19     João Paulo Rechi Vita
-       61013fb: Fix some debug messages and other cosmetic changes
-       e570767: Refactor a2dp thread execution flow and improve time estimation
-
-2008-08-17     João Paulo Rechi Vita
-       2f455bf: A2DP poorly working
-       c89301d: Fix sample size
-       e545479: Fix block_size calculation
-
-2008-08-16     João Paulo Rechi Vita
-       b5c4d2e: Configure bt connection for a2dp
-       85a931f: Get rid of hw_constraint function. It's code now lives inside bt_setconf().
-       77138dd: Change default sink name to bluetooth_sink
-
-2008-08-15     João Paulo Rechi Vita
-       6c10b10: Try to improve time estimation
-       123ba4f: Fix handling of PA_SINK_MESSAGE_GET_LATENCY
-       0d37b91: Remove PA_SINK_NETWORK flag and move the passage of streamfd to the rt thread just before the thread creation
-
-2008-08-14     João Paulo Rechi Vita
-       435eb07: Change pa_sink_render to pa_sink_render_into_full and remove some unnecessary checks on the rt thread
-       2e51b93: Make stream socket non-blocking
-       71f1d68: Fix block size for SCO
-       fcd7dc1: Add include for core-util.h
-       eb1e308: Initialize rtpoll_item
-
-2008-08-13     João Paulo Rechi Vita
-       0519e5d: Add include for sample.h
-       d48961f: Change close() to pa_close()
-       b4ded21: Change strerror() to pa_cstrerror()
-       16d5aab: Get rid of SINK_MESSAGE_PASS_SOCKET, since we don't really need it
-       aa310a4: Changes for pa_modargs_get_value_u32 for integer arguments and correct some error messages
-       0396a60: Copy arguments values instead of just getting a pointer for them
-
-2008-08-11     João Paulo Rechi Vita
-       f992296: Hand the stream socket to the rt thread
-       255f9b0: Initial code for rt thread
-       b8b761a: Fix PA_USEC_PER_SEC missing
-       a3f0756: BlueZ connection configuration done
-       e7b0839: Adds SBC Codec to pa tree
-
-2008-07-31     João Paulo Rechi Vita
-       c62c2ff: Add module-bt-device and dependencies to automake
-       ee68292: Initial file for module-bt-device
-       d8a0ec5: Add code from bluez/audio/ipc.[ch]
-       ffe76a2: Add sender=org.bluez to dbus add match
-
-2008-07-24     João Paulo Rechi Vita
-       fe8bd53: Remove modargs, since module-bt-discover doesn't have any argument
-
-2008-07-23     João Paulo Rechi Vita
-       1e03c32: Refactor all linked lists to use pulsecore/llist.h
-
-2008-07-22     João Paulo Rechi Vita
-       d893a1f: Remove block delimiters from single line if blocks
-       cadc666: Remove some unused vars and labels
-       a69c020: Change booleans to pa_bool_t
-       d90bb18: We don't need call_dbus_method anymore
-       9907b46: Don't need to explicity check if hcid is running anymore
-       2b68562: Improve dbus communication
-
-2008-07-21     João Paulo Rechi Vita
-       e5d25e0: Changing all private functions to static
-       3909d9b: Remove VERBOSE definition
-       c9f5659: Adding dynamic bluetooth audio devices detection
-
-2008-07-18     João Paulo Rechi Vita
-       314dade: Fix the symdef include
-
-2008-07-17     João Paulo Rechi Vita
-       6fccd58: Fix comparison of strings of different case
-       9d18b90: Adding module-bt-discover to Makefile.am
-       8b511f5: Adding module-bt-discover
-
-2008-09-10     Omair Majid
-       2ab4bb7: fix pa_stream_set_name
-
-2008-09-10     Piotr DrÄ\85g
-       64a81d9: Added Polish translation to LINGUAS
-       42fdcb7: Initial Polish translation
-
-2008-09-09     Arthur Taylor
-       f6670a1: stream_started_callback userdata bug
-
-2008-09-10     Lennart Poettering
-       636b520: fix S32 validity check
-
-2008-09-09     Lennart Poettering
-       5538c18: add src/pulsecore/lock-autospawn.c to POTFILES.in
-       8f604bf: bump revisions
-       17436b2: make sure peaks resampler also works for very short input buffers
-       0deb6a4: minor improvements in debug handling
-       4050447: unbreak pa_idxset_rrobin
-       3a46bbe: When returning from a suspend, pass exactly the same flags as originally when we opened the device.
-       25b200c: fix minor typo
-       f4c2f00: Work around presumable ALSA bug that treats the dir argument to snd_pcm_hw_params_set_periods_near() actually as > or < instead of >= and <=.
-
-2008-09-08     Lennart Poettering
-       c7a7765: Merge branch 'master' into master-tx
-       821dc17: move autospawn lock to pulsecore/ since we don't need it in the client anymore
-
-2008-09-06     Colin Guthrie
-       cd704f8: Linking fix for rtclock on libpulsedsp
-
-2008-09-06     Robert-André Mauchin
-       6b034f5: Updated LINGUAS: el, fr, sv added.
-       a571242: Added French translation.
-
-2008-09-05     Daniel Nylander
-       77f57f3: Added Swedish translation.
-
-2008-09-05     Lennart Poettering
-       f216402: Add new option to disable remixing from/to LFE and set it to on by default
-       33d349d: include build and runtime host information in debug output
-       fb837f0: rework autospawning to allow to multiple parallel autospawning contexts
-       994ff98: connect to localhost via IP address instead of host name, to avoid needless NSS lookup
-       89ed507: if we are exiting due to cpu overload, say so via syslog, too
-       f52fb64: if we are exiting due to idleness, say so
-       a609e4a: check for errors returned by pa_context_connect()
-       3f6f13f: use pa_channel_map_compatible() where applicable
-       b56f344: a few minor clean-ups
-       3429072: introduce upper channel map definition limit PA_CHANNEL_MAP_DEF_MAX
-       ece297f: update map file
-       cb0c97d: add new API function pa_channel_map_compatible()
-       5a9a602: update map-file script to ignore gcc malloc attributes
-       4562849: update documentation and help texts for s32le/s32be sample types
-       12c5c62: Downgrade hrtimer warning to notice level
-
-2008-09-03     Lennart Poettering
-       11cc072: Merge commit 'origin/master-tx'
-       bf403fe: introduce macros for all flags so that clients can check for them with #ifdef
-       cbd8e60: use PA_STREAM_EARLY_REQUESTS for OSS streams
-
-2008-09-01     Marc-André Lureau
-       79009d2: command_get_info() segv in some conditions
-
-2008-09-03     Lennart Poettering
-       c402de7: reindent comments a bit
-       40b66a0: Implement "early requests" mode.
-       99d5ec6: Rework pa_machine_id() a bit
-       5f93113: fix misuse of return value
-
-2008-09-01     Lennart Poettering
-       2c2b271: use gcc malloc attribute macros for internal functions, too
-       5467cc3: drop -Winline from build cflags
-       4348faf: don't include leagacy definition PA_STREAM_NOT_MONOTONOUS in docs
-       f6e187f: prefix  internally used inline function with _
-       70b820d: add gcc malloc related function attributes where appropriate
-       e015879: add malloc related gcc attribute macros
-       82ea8dd: avoid rounding errors on requested buffering metrics
-       002e7a7: output relative timestamps in addition to absolute timestamps when logging
-       a1c857a: include more build info in debug output
-
-2008-08-31     Lennart Poettering
-       1c4ad4b: rework device opening code: work around broken SND_PCM_NO_AUTO_xxx support in ALSA <= 1.0.17a
-
-2008-08-31     Fabian Affolter
-       1d319b0: Some string in German translation done
-
-2008-08-30     Lennart Poettering
-       34bcba6: remove a few more gcc warnings
-
-2008-08-29     Lennart Poettering
-       13018d6: fix a few compiler warnings on older gcc
-       506eacc: reword amd64 message
-       1acf394: change default log level for the library to PA_LOG_ERROR to avoid spamming to stderr more often
-       086fa95: downgrade a few messages
-       a45440d: the native atomic ops implementation for amd64 seems to work fine
-       ca38446: Change return value of cmpxchg atomic op to pa_bool_t
-       bdcb3a4: optionally add timestampts to every line logged
-       54da71e: reduce needlessly large gdbm cache a bit
-       450fe17: fix up latency before calling into stream code, to make sure we don't ask for too much data to early
-       63505be: add missing config.h inclusion
-       6723699: rework pa_ulog2 and base it on __builtin_clz if available, make pa_make_power_of_two based on it
-
-2008-08-29     Marc-André Lureau
-       d10e5e5: Add CFLAGS information on start-up
-
-2008-08-29     Fabian Affolter
-       f2c790d: Initial German translation
-
-2008-08-28     Lennart Poettering
-       bb8263b: add byte-to-usec and usec-to-byte converters that round up, not down
-       f79c665: document in which direction we round
-
-2008-08-27     Dimitris Glezos
-       6685a14: Started Greek translation
-
-2008-08-26     Ed Catmur
-       3d07cc8: alsa_error_handler should note source of errors
-
-2008-08-26     Lennart Poettering
-       8df5b2d: increase pa_xmalloc() limit to 96 MB, closes #344
-       fd3c6b0: fix typo
-       f9713d1: Fix error code in pa_stream_get_timing_info()
-       0a1f654: call close() in a loop to catch EINTR
-
-2008-08-22     Colin Guthrie
-       2a78f86: Fix more linking issues in x11-publish and stream-restore
-       4282b72: Merge branch 'master' of git://git.0pointer.de/pulseaudio
-
-2008-08-20     Lennart Poettering
-       dc9b8dc: add a few missing casts
-       a3e57da: add doxygen documentation for ext-stream-restore.h
-
-2008-08-19     Lennart Poettering
-       6baec25: use final glibc eventfd() instead of our homegrown syscall invocations
-       8e71787: rework cpu limit logic to use monotonic instead of wall clock time
-       961aa18: simplify pa_start_child_for_read by using pa_close_all()/pa_reset_sigs()/pa_unblock_sigs()
-       b7026bf: add a few more gcc warning flags and fix quite a few problems found by doing so
-       047eb52: run autoupdate
-       2ca0533: update gitignore
-       70f4a85: require ac 2.62 in bootstrap.sh
-
-2008-08-18     Lennart Poettering
-       3d2d6ca: Merge commit 'flameeyes/autoconf-2.62'
-       46f0f9e: a few modernizations
-       e65c514: don't unref pa_native_options object twice
-       5cc2187: add some code to make invalid valgrind warnings go away
-       c6b1888: bump release
-       b8ba2de: restore volume/device for streams only when it wasn't set before
-       ec62596: allow clients to not specify the volume for their streams
-       c35d1bb: rework validity checking of sink/source/... names
-       d315dcf: save a bit of memory
-       67858c6: fix type error
-
-2008-08-17     Russ Dill
-       74719c2: Fix up overzealous HAVE_LT_DLMUTEX_REGISTER block
-
-2008-08-15     Lennart Poettering
-       8d596a9: Make Multicast TTL for RTP configurable, patch from 'dfort'
-       f84536b: apply newly configured rules properly
-       63402b3: apply volumes properly more than once in a row
-       512c24c: apply the correct rules to sink inputs
-       f68a6e5: don't restore devices for direct-on-input streams
-       5a0e014: disable hotplug sounds by default
-
-2008-08-13     Lennart Poettering
-       916899a: pass force_refresh=FALSE to all volume/mute read invocations
-       abd85af: drop 0db reset functions since they are not necessary anymore
-       8a10eba: extend hardware dB scale in software to full range if necessary, instead of reverting back to software-only volume control
-       3ec4a5d: rework volume/mute APIs: split out pa_xx_set_soft_volume() and add force_refresh argument to read functions
-       29daef7: add new function pa_alsa_volume_divide()
-       8ab85fd: reword some log messages
-       e4adcf7: add new API function pa_cvolume_max()
-       a176f68: reset lock_fd_mutex after destruction
-       3c88af7: fix protocol destruction
-
-2008-08-11     Lennart Poettering
-       7c5a959: initialize IP ACLs properly
-       8ca254c: fix two uninitialized memory accesses
-       c4dff4d: otpimize mixing code a bit by moving a few checks out of the inner loops
-       5b2a837: optimize volume changing a bit by only using a single counter for the inner loops instead of two
-       b604290: adhere to struct gcc aliasing rules
-
-2008-08-09     Lennart Poettering
-       b218404: fix bad memory access
-       72f520f: make gcc shut up
-       afbfd5d: adhere to C strict aliasing rules
-       432b4e5: don't use PA_GCC_UNUSED anymore
-       9996213: free regex_t after use
-       15cebba: rework autospawning code to survive multiple pa_contexts in a single process
-       b4a5669: print reason when we fail to kill a running daemon
-       ee4c350: set errno properly in all functions from pid.c
-       d8119af: set errno properly in all functions from core-util.c
-       9cf1a4e: add locale support to pa_parse_boolean()
-       c4d32ec: set errno properly in all cases
-
-2008-08-08     Lennart Poettering
-       6df029a: make sure we don't crash if pa_thread_join() is called more than once on the same pa_thread object
-
-2008-08-08     Diego 'Flameeyes' Pettenò
-       016fcd9: Reduce rules for man pages generation to pattern rules.
-       89f492a: Replace some manual build tests with AC_CACHE_CHECK and AC_COMPILE_IFELSE.
-       daf3e8b: Create a new macro for checking compiler support for TLS.
-       81969a7: Replace the CFLAGS-checking code with a common macro from xine-lib.
-       a6e4507: Use AC_PROG_CC_C99 to discover C99-compliant compiler.
-       f46ae10: Create an m4 directory for common macros and use it.
-       66512f3: Remove gettext macros from configure.ac, intltool is used.
-
-2008-08-07     Diego 'Flameeyes' Pettenò
-       07395ce: Bump autoconf requirement to 2.62 (latest released version).
-
-2008-08-08     Diego 'Flameeyes' Pettenò
-       29fca62: Fix man pages generation when building out of tree.
-       8a3d666: Fix building again libtool/ltdl 2.2.4.
-       f8197cf: Update code to use libtool 2.2. Use convenience recursive libltdl.
-       2da79d5: Create an m4 directory for common macros and use it.
-       f4e9b7d: Remove gettext macros from configure.ac, intltool is used.
-
-2008-08-07     Diego 'Flameeyes' Pettenò
-       4a51e1c: Bump autoconf requirement to 2.62 (latest released version).
-
-2008-08-07     Lennart Poettering
-       40ff5fa: add compatibility with older PA socket paths
-       75b28e9: remove some leftover debug string
-       ecb2bc4: Modify pa_state_path() to take an additional argument for prepending the machine id to the file name.
-       bd05b36: Rework state/runtime directory logic
-       4e6fb67: don't spam to stderr in API functions
-       0075649: print machine id during startup
-       73e2577: add new function pa_machine_id()
-       b84f738: translate error strings
-
-2008-08-06     Lennart Poettering
-       b983c0b: include host name in default sink/default source file
-       bb7f80d: fix a few things in the translations
-       4a44084: add basic german translation
-       31bfd6a: fix channel position string
-       ff6bb7a: add a few configuration sanity checks for system mode
-       a4762ab: add disallow-exit to default configuration file
-       756fac8: add new switch --disallow-exit
-       f1d2bf8: add i18n support
-       c4a953d: remove authkey-prop from tree
-       b4e8cac: don't include authkey-prop.h anymore
-       9fde00e: fix a few potential bad memory accesses
-
-2008-08-05     Lennart Poettering
-       34dd4a2: fix shutdown when --disallow-module-loading=1 is passed
-       ca12753: add a function to dump the stream database for debugging purposes
-       8a156d1: don't enforce valid callbacks for extension module APIs
-       98b8163: allow extension messages to actually carry information
-       e0dd72a: fix error path (spotted by Coling Guthrie)
-       f57b915: fix a few more copy/paste errors
-
-2008-08-04     Lennart Poettering
-       78236af: fix copy/paste error
-       163f107: fix documentation to follow what actually happens
-       64a2367: inherit proplist on sample playback from client
-       03cd37e: remove port definitions from header file since they are not actually used yet
-       7de3ab5: add missing C++ checks in header
-       9f5c1c6: pa_bool_t is not exported
-       dd07276: ignore PA_GCC_DEPRECATED and PA_GCC_PRINTF_ATTR when generating map file
-       51d181c: update list of exported symbols
-
-2008-08-03     Colin Guthrie
-       580c434: Fix linking
-
-2008-08-04     Lennart Poettering
-       0cc674d: wrap protocol extension of module-stream-restore
-       88c3db6: add protocol extension to module-stream-restore
-       6cc3a61: store channel map in database and remap volumes if necessary
-       eec623a: add hooks for connection creation/deletion, for that export pa_native_connection
-       c01f0bc: split out save trigger function
-       32cf9db: store channel map in database and remap volumes if ncessary
-       5880516: add new API function pa_cvolume_remap()
-       cd5afb8: don't hit an assert if  when process_rewind() is called with nbytes=0
-
-2008-08-03     Colin Guthrie
-       bf17dbb: Merge branch 'master' of git://git.0pointer.de/pulseaudio
-       ec78981: Fix linking
-       5744237: Merge branch 'master' of git://git.0pointer.de/pulseaudio
-
-2008-08-03     Lennart Poettering
-       5f69b5d: load module-device-restore and module-stream-restore by default, don't load module-volume-restore anymore
-       ad76ca0: add new module module-stream-restore
-       ec19f2b: a bit of refactoring
-       d7b138d: fix uninitialized memory access
-       a6c11be: define CANONICAL_HOST as macro for the GNU canonical host
-       04ffac5: add extension system for native protocol
-       9bfd67f: store load_once flag for module
-       114f290: add a new error code PA_ERR_NOEXTENSION
-       23bde22: start idle timer even when no module is ever loaded
-       f417bb4: some pa_bool_t'ization
-       065e764: make all protocol objects global singletons
-       aaaafb0: use pa_channel_map_init_extend() instead of pa_channel_map_init_auto() to make things more robust
-       1ae1dfc: simplify a bit
-       0a2fced: add new api function pa_cli_get_module()
-       5042284: introduce pa_cli_eof_cb_t
-       084f429: rename pa_hook_free() to pa_hook_done() since the hook struct is allocated on the stack not via malloc
-       34c4354: use @ as seperator between shared name variable and instance
-       5916b5b: make sure we don't leak userdata struct
-       32f63f2: allow running of PA with a valgring that doesn't know cap_set_caps
-       06712c2: add new auth cookie singleton
-
-2008-08-03     Sjoerd Simons
-       98fbd24: fix iteration over random devices
-
-2008-08-01     Lennart Poettering
-       d36c5c9: rename props.[ch] to shared.[ch]
-       edc56a7: rename pa_property_xxx to pa_shared_xxx to avoid confusion with property lists
-       a5a7b79: fix build without ALSA
-
-2008-07-31     Lennart Poettering
-       d757dc7: Merge branch 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
-       5150738: a bit of pa_bool_t'ization
-       4f3193d: allow global tsched setting for all modules loaded by module-hal
-       4ccbc4d: reword comment on dbus a bit
-       026a6bd: Work around D-Bus bug that involves dbus_shutdown() to call exit() when it shouldn't. Patch from Coling Guthrie
-
-2008-07-31     Stanley Cai
-       80428d8: A fix on src/Makefile.am
-
-2008-07-30     Colin Guthrie
-       b30a5d6: Merge branch 'master' of git://git.0pointer.de/pulseaudio
-
-2008-07-30     Lennart Poettering
-       0b428e7: don't allow --start in system mode
-       656d243: use the right LIBICONV macro, spotted by woglinde, closes #324
-       c39a0bf: bump needed automake version
-       881046b: install a default system.pa
-
-2008-07-26     Petteri Räty
-       90569d3: Make the alsa error message give out the needed version.
-
-2008-07-30     Lennart Poettering
-       3c6da6e: don't pass rediculously high values to umask()
-       b7b4b5e: remove debug message
-
-2008-07-29     Lennart Poettering
-       bb00934: hide doxygen docs from git
-       68ae1d4: fix two thinkos in signal reset/close_all code
-
-2008-07-24     Lennart Poettering
-       e3fb086: make module-hal and module-ck live together in peace
-       49f09d6: fix destruction of dbus modules: make sure we don't leave filter function registered after unreffing the dbus connection
-       23a3c55: hide start-pulseaudio-x11
-       888256b: reset dbus error struct before retrying parsing messages
-
-2008-07-23     Lennart Poettering
-       e7b9da3: add missing pieces for new startup logic
-       c95d0d7: bump api verson
-       32e93d5: follow consolekit's recent D-Bus API change, original patch from William Jon McCan
-       c415479: allow module-x11-xsmp to be loaded more than once
-       1f10ca4: don't break if we fail to resume access to an audio device
-       7140bdd: bump alsa dep to 1.0.17
-       1401d36: make missing gdbm fatal (spotted by Betelgeuse)
-
-2008-07-22     Lennart Poettering
-       5edbb57: don't drop caps if we are started as normal root user
-       3888bfc: enable exit-on-idle by default
-
-2008-07-21     Lennart Poettering
-       c1f9f95: prepare doxygen docs for 0.9.11
-       d0530b0: fix gconf autoconf check
-
-2008-07-21     Colin Guthrie
-       0e1936f: Merge branch 'master' of git://git.0pointer.de/pulseaudio
-
-2008-07-16     Lennart Poettering
-       46a35c6: forward process_msg calls to the generic source handler, not the generic sink handler
-       ff3f435: try to bypass alsa softvol, since it is broken when used with snd_pcm_rewind()
-
-2008-07-03     Colin Guthrie
-       0786de2: Fix documentation of constant: PA_VOLUME_MUTED (not PA_VOLUME_MUTE)
-
-2008-07-04     Lennart Poettering
-       297267b: Merge branches 'master' and 'master' of ssh://rootserver/home/lennart/git/public/pulseaudio
-
-2008-06-28     Lennart Poettering
-       1568fcc: get rid of our internal copy of the speex resampler. Instead, link against a system-installes libspeexdsp
-       98c26b1: add proper update_max_request handler to native protocol streams
-       e6ffec5: make sure we call pa_sink_process_rewind() under all circumstances if a rewind was requested before we call pa_sink_render()
-
-2008-06-27     Lennart Poettering
-       c7ebe2b: ignore ~ files
-       c0e3c25: add additional file when updating speex resampler
-       32fce4d: update speex resampler
-       2490f69: update ffmpeg resampler from upstream SVN
-       0fb402c: simplify handling of rewrite requests
-       89620d3: handle rewind requests
-       f0e5cd1: handle rewind requests
-       913bbd4: save a bit of memory
-       36021b1: modernize idxset a bit, reduce memory consumption, get rid of pa_idxset_foreach()
-       113c62b: halve memory consumption of mempool flist, since we know we cannot have more than n_blocks entries in it
-       c26be0d: modernize hashmap implementation a bit, reduce memory consumption a bit
-       6dca92b: rework the flist implementation to halve memory consumption by merging the state field and the pointer in the flist cells
-       a087014: some modernizations
-       232c955: rename pa_queu_is_empty() to pa_queue_isempty() to follow idxset/hashmap nomenclatura
-       3db7dcb: save some memory by increasing the dynamic array at a slower rate
-       c0f97aa: some modernizations
-       12278f4: fix typo in man page, closes rhbz #447355
-       0540032: fix underrun detection for prebuf=0 streams
-       7755f75: use (uint32_t) -1 to signify default buffer_attr values instead of 0, to allow prebuf=0
-       2b764d4: fix crash when using sync'ed streams
-       06ab488: cork/uncork before we ask for the rewrite, to make sure the rewrite actually gets trhough
-
-2008-06-26     Lennart Poettering
-       9f0afb3: always forward rewind requests to the sink, and don't abort on nbytes=0
-       d08cac0: some svn->git updates in the Makefile
-       ee79b05: rework logic to request automatic timing updates a bit
-       4b8c4ef: reorder a few things to get rid of an uneeded comparison
-       97084e8: add a FIXME
-       7d3d3fc: move initialization order of validity bools around a bit
-       36d6c71: unify smoother pause/resume handling in a single function check_smoother_status()
-       dcbb7f2: convert to double only once, and make sure we can deal with negative results of -y
-       eab1cb8: make sure to call process_rewind() under all circumstances before we do the next loop iteration
-       1e36b57: use the newer name for monotonic/monotonous
-       2c5a33d: remove redundant check
-       85b83e8: properly initialize pa_stream::corked based on the flags
-       1514d13: split pa_memblockq_flush() into two flush commands, one which fixes up the read ptr, and one which fixes up the write ptr
-       5fccac9: comment two functions in memblockq.c
-       ec10f5f: use the bight lighter _silence() instead of _flush() when destructing our little q
-       dd8b909: fix up if the smoother shall be resumed 'before' it was actually paused
-       b4302ca: fix up monotonicity of input to _get() instead of hitting an assert
-       63b68f4: call the enum PA_STREAM_NOT_MONOTONIC and make PA_STREAM_NOT_MONOTONOUS an alias for that
-       df2650e: fix return value of pa_namereg_make_valid_name()
-
-2008-06-25     Lennart Poettering
-       c5cbeb5: choose more sensible default buffer sizes for old clients
-
-2008-06-25     Colin Guthrie
-       517727e: Add xmltoman to the distribution. This saves pulling in an external dependancy
-
-2008-06-24     Colin Guthrie
-       5099ab7: Export the cleanup_name() function and rename it to pa_namereg_make_valid_name(). This will allow it to be used by modules to create valid sink names.
-
-2008-06-24     Lennart Poettering
-       ac03254: Merge branch 'master' of git://git.debian.org/git/pkg-pulseaudio/pulseaudio-upstream
-       398514f: call update_source_requested_latency callback for source outputs only when it is set to non-NULL
-
-2008-06-23     Lennart Poettering
-       c22d8b9: don't refer to nonexisting pa_stream_read() function
-       57aee6d: include proplist.h in pulseaudio.h
-
-2008-06-23     CJ van den Berg
-       1562671: Merge dead branch 'glitch-free'
-       126e4cf: Merge dead branch 'lennart'
-       0be9bc2: Merge dead branch 'lockfree'
-       63c1eb1: Merge dead branch 'ossman'
-       a87ba42: Merge dead branch 'liboil-test'
-       1a3984c: Merge dead branch 'prepare-0.9.10'
-
-2008-06-22     Lennart Poettering
-       8885ddf: support file-based capabilities instead of SUID root for giving PA rights to acquire RT/HP scheduling: setcap cap_sys_nice=ep /usr/bin/pulseaudio
-
-2008-06-21     Lennart Poettering
-       ab93f2a: fix deadlock when resuming oss sinks
-       2199b8e: Properly check for home directory
-       d0e26a5: Don't fail when we cannot determine the lock file path
-       d1362b5: call the right function in the right context
-       d9f8b6a: since the sink is unlinked before the sink input we need to make sure we don't call any function for unlinked sinks from any sink input callback
-       947d8b4: execute detach callback before we change the state to UNLINKED
-       37bc240: allow sinks to be created with max_request initialized to 0, so that the data can be filled in later when attaching to some piggybacked sink
-
-2008-06-20     Lennart Poettering
-       d3c1c92: Request a rewrite immediately after we have been linked, so that playback starts immediately
-       add6c03: Rework module-combine to work with glitch-free core; add new max_request field to pa_sink
-       1420e1d: fix interpretation of remix parameter
-       6c980c2: add new abstract device class
-       2b112fe: add new function pa_smoother_reset()
-
-2008-06-19     Lennart Poettering
-       11e55fe: add new remix= parameter to remap sink
-
-2008-06-18     Lennart Poettering
-       fd5a1b1: remove trailing spaces
-       c2fa11e: make user of pa_channel_map_init_extend() wherever it makes sense
-       132e73b: add new API pa_channel_map_init_extend() to synthesize a channel map if noone is known
-       b95cf52: ignore tarballs
-       822366a: remove remaining $
-       8ae83d6: get rid of svn $ keywords
-       6c4edd1: add missing gitignore files
-       b5a0802: add another .gitignore file, this time for pulse/
-       3bf61ba: Add a .gitignore file for the src/ directory.
-       63daee5: Add a small README with the new git URLs and stuff
-
-2008-06-17     Lennart Poettering
-       9020543: if building a man page fails remove the output to make sure that calling make repeatedly will actually work
-       ac58f8d: fix man page xml
-       ba64de8: reset prebuf if it is too large
-       038a033: limit the prebuf value by tlength
-       b28c6e9: bring module-tunnel back to life
-       8ba8265: server side of new shm negotiation scheme; fix a bad memory access
-       0d0911f: rework shm usage negotiation; merge a few pa_bool_t in a single bit field to save a bit of memory; drop redundant implementation of pa_init_proplist()
-       36c5259: minor modernizations
-       53987e6: make use of the pa_init_proplist() version in proplist-util.[ch]
-       0e32db2: move pa_init_proplist() to proplist-util.[ch]
-
-2008-06-16     Lennart Poettering
-       ce001aa: add missing const to a few functions
-       fa53443: add pa_memblockq_get_base()
-       7dffccd: add Nokia copyright
-       71aca29: check for packet size on server info data
-       1fe2f2c: use new pa_sink_set_latency_range() in null sink
-       f2efe93: a few modernizations
-       f4e2750: add new function pa_iochannel_socket_is_local()
-       3b691c2: make use of the new pa_socket_address_is_local() function
-       30a8800: add new functions pa_socket_is_local() and pa_socket_address_is_local()
-       2af2433: add missing inclusion
-
-2008-06-14     Lennart Poettering
-       4cf508e: minor modernizations, increase unload timeout to 60s
-       ce53497: avoid division by zero when informing user about unloaded lazy samples in the sample cache
-
-2008-06-13     Lennart Poettering
-       bf51a4a: update todo
-       b27cc1d: fix a bad memory access pulsecore/client.c
-       7bae1ba: rearrange things
-       e9c13e2: consider passing the same argument twice to a module an error, also consider a variable name without following = an error
-       8dd59a6: sometimes a simple memset() is much faster
-       5c149e2: fix a minor memory leak when unloading m-c-k
-
-2008-06-12     Lennart Poettering
-       d39d6c9: drop hal inclusion from module-console-kit.c
-
-2008-06-12     Colin Guthrie
-       39f59cd: Trivial typo fix in debug log message.
-
-2008-06-11     Lennart Poettering
-       92e4fb3: merge Colin Guthrie's module-always-sink module, and add priorization to the hook subsystem while doing so.
-       1337afd: enable auto-spawning by default
-       b3444d6: enable ConsoleKit support and positioned event sounds by default
-       ac0f527: add new switch --start to the PA binary which allows starting PA if it is not running yet. In contrast to normal startup an already running PA will not be considered an error. Also, take the autospawn lock so we can guarantee that after this call returns PA is ralive and running
-       c33db3c: don't exit when the XSM signals us a session exit. instead just unload all X11 modules
-       a180edd: move pa_core_check_quit() a bit later
-       46d17f0: reformat things
-       f7ff9e2: install auto unload time event only when we have at least one auto unload module
-       2cc95df: add new module-console-kit which tracks ck sessions to avoid termination when there is still some session using the PA instance
-       62dde3f: add new module module-position-event-sounds for positioning event sounds in space
-       67fde59: replace pa_atof() by pa_atod() because floats are lame
-       ca36968: update well-known property list
-
-2008-06-09     Colin Guthrie
-       71fefa7: Do not invalidate the cookie if no file was specified. Only invalidate it when a cookie-file is specified and it is not loaded/parsed correctly. This fixes a bug introduced in r2494
-
-2008-06-03     Colin Guthrie
-       3e4afae: Rejig r2495 slightly and directly compile the necessary source files as libpulsecore.so is not available when libpulsedsp.so is built
-       3166ce8: Also link libpulsecore.la to some libraries (needed for logging). Discovered while compiling with --as-needed
-       78ae612: Perfer client.conf over X11 property variables. To explain: X11 properties are always set on the root window if pulseaudio is started during X11 login (which is the most likey time to start it). This means that any settings specified in client.conf will almost never be used. As the default client.conf is empty it makes more sense to listen to it if a user cares to bother altering it.
-
-2008-06-03     Lennart Poettering
-       9a501ef: fix a compiler warning on ARM due to missing cast, patch from Jyri Sarha
-
-2008-05-29     Lennart Poettering
-       c98516b: update props
-       8431fb1: allow on-the-fly deleting of hashmap entries wile we iterate through them
-
-2008-05-27     Lennart Poettering
-       c4f60d5: never hand out more data from a sink input than requested. Otherwise the resampler might run for too long and we get a heavy delay/underrun
-       7297bd9: always expect name field in upload datagram
-       307645e: fix esound proto to not crash
-       21dedcb: readd name field to upload datagram
-       d332439: fix a minor memory leak
-
-2008-05-21     Lennart Poettering
-       28405e3: big mumbo jumo of interleaved patches. * Use seperate "state" and "config" paths * Pass the fact that we are in system mode via an env var $PULSE_SYSTEM instead of as var in pa_core * Properly check proc name when checking PID files. Don't check exename, because we cannot read that for other uids
-       6be0c75: move device volume file to state dir
-       9f86d0f: move default device from runtime to state dir
-       32c53f3: move volume restore table from runtime to state dir, fix another compiler warning
-       2ed84ed: define PA_SYSTEM_CONFIG_PATH and PA_SYSTEM_STATE_PATH for C
-       29c7ded: deal with failing pa_runtime_path()
-       dd662d5: properly handle if pa_runtime_path() fails
-       341042b: make state and config path for system instance configurable
-       8125a75: fix a compiler warning
-       9303cdd: add O_NOCTTY
-       a9c80b4: add new functions pa_state_path()/pa_get_state_dir(), change return value of pa_startswith()/pa_endswith() pa_bool, add pa_in_system_mode() and pa_streq(); alow pa_unlock_lockfile() without file name spec
-
-2008-05-18     Lennart Poettering
-       d65b901: fix daemon shutdown with active monitor streams
-       174d830: ignore close-test binary
-       b467791: add a small test program for pa_close_all()
-       ef4c6bf: remove a misplaced assert
-       7df3c4f: make sure we don't hit an assert when autospawning
-       3c7a795: fix pa_close_all() to make it actually work as advertised
-       0a2b6dd: fix a misplaced assert
-
-2008-05-17     Lennart Poettering
-       940f898: fix return value of noop pa_limit_caps()
-       3bbc376: add another assert to catch sleep time miscalculations easier
-       7d0b595: use pa_source_set_latency_range()/pa_sink_set_latency_range() in the ALSA drivers; fix sleep time calculation
-       de8a386: use pa_source_set_latency_range()/pa_sink_set_latency_range() in the ALSA drivers; fix sleep time calculation
-       58487ee: use pa_sink_set_latency_range() where applicable
-       7e5e015: link latency of monitor source to sink
-       9b44665: add new function pa_source_set_latency_range(), fix type of requested_latency
-       2e71f4d: only unref memblock if there is one
-       971342d: dump latency metrics for recording streams, too
-       6285a46: fix peak detection pseudo resampler
-       e35bae8: fix pa_stream flag checking
-       856a2f9: type fixes for constants
-       b2f8aec: type fixes for constants
-       b709ab5: fix a minor compiler warning
-       85d9abe: declare the explicit type for our PA_xSEC_PER_ySEC constants
-
-2008-05-15     Lennart Poettering
-       b8849f5: bump so revisions
-       a1639e1: also update PROTOCOL
-       045c1d6: merge glitch-free branch back into trunk
-       3aadad1: update protocol spec
-       43dfc2a: follow recent alsa sink changes in the alsa source
-       734f071: decrease default tsched buffer to 2s to reduce overall memory consumption
-       813d40c: fix up requested latency when we move a record stream
-       e3c5a77: fix moving of record streams
-       99a4516: don't access stream before it is valid
-       74f8a67: fix suspend for alsa sink
-       f021538: export a couple of more functions from libpulse
-       e0dc1e4: Print message when stream started playback, use terminal sequence to clear line when printing that message
-       86ea73a: reduce malloc() usage when logging, to minimize the hit of logging in RT threads. Not complete yet, i18n still uses malloc
-       b57c520: add pa_vsnprintf()
-       1a2e5a8: add adaptive resampler to the RTP receiver, other modernizations
-       cfc4842: export a few more properties for RTP streams
-       f96a8ad: increase default mempool size, make mempool_slot an abstract struct because the only fields it defined where actually unused
-       70c5967: increase shm size limit, modernizations
-       2bc77ff: reduce number of allocated memblocks when receiving RTP data by reusing blocks
-       d10ee7d: more pa_bool_t'ization
-       c801d08: use pa_bool_t
-       076ffa3: add 'stream' as media role
-       1b7157a: add PA_REFCNT_INIT_ZERO
-       6895280: add pa_ulog2()
-       103ceaa: add pa_memblockq_get_nblocks()
-
-2008-05-14     Lennart Poettering
-       df73688: modernizations
-       37813d9: modernizations
-       787b869: initialize volume properly, set more properties, modernizations
-       2eca8c9: don't spam us with wakeup msgs in non-tsched mode
-       9c48ed1: update pipe source for glitch-free, too
-       8baa1a4: fix pipe sink for glitch-free
-       dd29f67: fix braindead mistake
-       94c269e: some fixes to make the esound protocol work on glitch-free again
-       8df6529: some fixes to make the simple protocol work on glitch-free again
-       c5faeb1: store peer name in native-protocol.peer property
-       aae8beb: if zero is passed to pa_memblock_new() allocate largest memory block possible from mempool
-
-2008-05-09     Lennart Poettering
-       f124445: fix module-sine for glitch-free
-       df92b23: - Fix moving of sink inputs between sinks - Don't write more than a single buffer size in the ALSA driver at a time, to give the clients time to fill up the memblockq again - Add API for querying the requested latency of a sink input/source output - Drop get_letancy() from vtable of sinks/sources
-       580d563: modify test to generate data events out-of-order
-       0ea0e06: make sure the smoother code can deal with incoming data that is out-of-order; start smoothing only when we have at least a configurable number of entries in our history
-       e97a347: bah, english sucks
-
-2008-05-08     Lennart Poettering
-       1f196e7: fix some comments
-
-2008-05-07     Lennart Poettering
-       7b5c6a3: fix recording
-       21fa1cf: double default asyncq size
-       876d5b4: fix a race condition when tearing down the ladspa/remap sink
-       6f4d44b: apparently alsa expects us to free the memory for card names
-       d21f458: fix a memory leak
-       9354da4: make memchunk/memblockq streams work with glitch-free
-       dafcf20: beefup proplist handling for sound events
-       8afbdc3: update to new rewinding logic
-       9d7fde5: rework the rewinding logic once again, fixing
-       6c28f1d: decrease verbosity a bit
-       44241ac: define callback function types; allow pa_signal_done() to be called even without prior pa_signal_init()
-
-2008-05-06     Lennart Poettering
-       91fbb69: explain why changing rlimits at this time is safe
-       dee3555: rename 'routing' to 'filter'
-       4fa6cb4: add a few more asserts, don't allow pa_limit_caps() to fail
-
-2008-05-03     Lennart Poettering
-       71d14d4: fix remapping sink for glitch-free
-       a1c10b5: update LADSPA module for glitch-free moed
-       59835d9: explain why a rewind was requested
-       82caf5a: when rewinding after the end of an underrun, make sure to rewind as much as we can, so that we deal properly with changed latencies of the sink
-       3167e0f: follow _unlink() changes from sink-input
-       d2da344: send PA_SINK_MESSAGE_REMOVE_INPUT only when an asyncmsgq is available, reset resampler only when we really need to
-       d2be471: make sure to call sink->update_requested_latency() always when we change latency, same for source
-       59a7467: don't require a module name when resolving a dl symbol
-
-2008-05-02     Tanu Kaskinen
-       ff09fa3: Fix typo: "now"->"not".
-       43a30a2: Fix setrlimit() return value comparsion.
-
-2008-05-02     Lennart Poettering
-       bb4f83b: only send PA_SINK_MESSAGE_SET_STATE if there's still an asyncmsqg around to do so
-       bfb2691: a few modernizations
-       06b9140: reorderer a few things
-       792ef5c: fix a compiler warning
-       775bc6c: some modernizations
-       7d6269e: add multiarch paths to default LADSPA search path
-       49b1b15: don't enable prebuffering if we just call is_readable()
-
-2008-05-01     Lennart Poettering
-       52e3628: Yes, yet another evil all-in-one commit of intervowen changes. I suck. * Drop "state" directory, fold that into "runtime directory" * No longer automatically rewind when a new stream connects * Rework sound file stream, to cause a rewind on initialisation, shorten _pop() code a bit * Fix reference counting of pa_socket_server in the protocol implementations * Rework daemon initialization code to be compatible with non-SUID-root setups where RLIMIT_RTPRIO is non-zero * Print warning if RT/HP is enabled in the config, but due to missing caps, rlimits, policy we cannot enable it. * Fix potential memory leak in pa_open_config_file() * Add pa_find_config_file() which works much like pa_open_config_file() but doesn't actually open the config file in question. Just searches for it. * Add portable pa_is_path_absolute() * Add pa_close_all() and use it on daemon startup to close leaking file descriptors (inspired from what I did for libdaemon) * Add pa_unblock_sigs() and use it on daemon startup to unblock all signals (inspired from libdaemon, too) * Add pa_reset_sigs() and use it on daemon startup to reset all signal handlers (inspired from libdaemon as well) * Implement pa_set_env() * Define RLIMIT_RTTIME and friends if not defined by glibc * Add pa_strempty() * rename state testing macros to include _IS_, to make clearer that they are no states, but testing macros * Implement pa_source_output_set_requested_latency_within_thread() to be able to forward latency info to sources from within the IO thread * Similar for sink inputs * generelize since_underrun counter in sink inputs to "playing_for" and "underrun_for". Use only this for ignore potential rewind requests over underruns * Add new native protocol message PLAYBACK_STREAM_MESSAGE_STARTED for notification about the end of an underrun * Port native protocol to use underrun_for/playing_for which is maintained by the sink input anyway * Pass underrun_for/playing_for in timing info to client * Drop pa_sink_skip() since it breaks underrun detection code * Move PID file and unix sockets to the runtime dir (i.e. ~/.pulse). This fixes a potention DoS attack from other users stealing dirs in /tmp from us so that we cannot take them anymore) * Allow setting of more resource limits from the config file. Set RTTIME by default * Streamline daemon startup code * Rework algorithm to find default configuration files * If run in system mode use "system.pa" instead of "default.pa" as default script file * Change ladspa sink to use pa_clamp_samples() for clamping samples * Teach module-null-sink how to deal with rewinding * Try to support ALSA devices with no implicit channel map. Synthesize one by padding with PA_CHANNEL_POSITION_AUX channels. This is not tested since I lack hardware with these problems. * Make use of time smoother in the client libraries. * Add new pa_stream_is_corked() and pa_stream_set_started_callback() functions to public API * Since our native socket moved, add some code for finding sockets created by old versions of PA. This should ease upgrades
-       f94fae3: move unlinking code to operation_unlink()
-       f3cc178: some minor updates
-       11559a6: parse boolean parameters as boolean instead of int wherever applicable. add new function pa_cli_command_execute_file_stream()
-       414f1d9: install gccmacro.h properly, drop  unused core-def.h file
-       d7cc1f5: change pa_rtpoll_set_timer_absolute() to take a pa_usec_t instead of struct timeval
-       5816871: save and restore errno in log functions
-       b93ea18: minor reformat
-       4f99c43: check for $PULSE_INTERNAL before enabling padsp
-       18ad6f8: don't allow overwriting of callback pointers when we're already dead
-       b70edf7: port pa_sample_clamp() to liboil
-       9dd8f6c: add new function pa_sample_clamp()
-       264385a: strip CRLF line breaks from read CLI commands. This should fix the cli interface for people accessing it via telnet.
-       f49df7a: * Increase history set to 64 to simplify reduction of indexes * Decrease memory consumption a bit by using bitfields for some bools * Rework reduction code * Drop an unnessacary counter * Before adding a new entry to the history, try to figure out if we already have an existing entry with the same x value and replace that. This fixes a division by zero * Fix up input x for all functions, according to the time offset
-       563f4b6: make check for $DISPLAY=="" more readable, pa_bool_tization
-       06a05bc: a bit of pa_bool_t'ization
-       b12b8ee: save errno before calling free()
-
-2008-04-23     Lennart Poettering
-       caf742a: define minimal and maximal wakeup/sleep times; check for underrun condition only once during buffer fillup
-       5353cf4: fix size of requested_latency
-       067a68a: fix build for auxiliary modules
-       c8fc223: add stripnul to build
-       76031df: Big pile of interdependant changes: * Fix a deadlock when an asyncq overflows and an RT thread needed to wait until space became available again while the main thread was waiting for a operation to complete and thus didn't free any new items. Now, if the asyncq overflows, queue those items temporarily, and return immediately. Then, when the queue becomes writable again, flush it. * Modify pa_thread_mq_init() to also set up pa_rtpoll events properly for the MQ * Some more pa_bool_t'ization * Unify more common code between alsa-sink and alsa-source * The upper limit for the tsched watermark is max_use minus one frame * make module-alsa-source work * make the alsa modules use pa_alsa_build_pollfd() now * fix detection of dB scale for alsa-source
-       a197644: add new tool 'stripnul' which can be used to drop leading zeros from a file which is useful to do byte-by-byte comparison of what goes in and comes out of PA
-       f2dffb7: pa_bool_t'ization
-       0b183fb: respect the resampler's maximum block size to avoid that we get kicked out of the memory pool due to resampling. actually drop data from the delay queue after we used it
-       998ed8e: add missing header definitions for last commit
-       3f57d3a: add new function pa_alsa_build_pollfd() to alsa-util to unify a bit more common code from the sink and the source
-       ed0af46: unify code that fixes up buffering metrics
-       af03dd4: drop a misplaced newline
-       3c8e83f: do not fix automatic buffer attrs anymore, the new protocol version doesn't need this anymore and it creates more problems than it solves. Also drop the initial timing info query. Correct programs shouldn't depend on it anyway
-
-2008-04-22     Lennart Poettering
-       5e6aacd: * don't increase tsched_watermark on underrun without limits * fix the watermark when we change the latency * fix latency measurement * move rewinding code into its own function * make use of new function pa_alsa_recover_from_poll() were applicable
-       6b4b95b: show configure latency metrics
-       1adbe82: some beautification updates, show msec instead of usec everywhere
-       cdb077b: if no timer was armed, we don't need to disarm it
-       4a1971a: if no latency was configure for a sink/source, fill in the max latency automatically
-       69f6bdf: add new function pa_alsa_recover_from_poll() to merge common core from module-alsa-sink and module-alsa-source
-       9a486ef: implement --process-time
-       0d01c43: make sure the client buffer has space for 2*minreq+tlength. Explain why
-       e16a198: - Change meaning of special values of latency request: 0 -> "minimal latency, please"; (pa_usec_t)-1 -> "don't care" - Remove "source" word from monitor source description - Increase default tsched watermark to 20ms again - For the first iteration after snd_pcm_start() halve the sleep time as workaround for USB devices with quick starts
-       88227c4: properly initialize memblock->is_silence for imported memory blocks; make is_silence and read_only a bit field
-
-2008-04-20     Lennart Poettering
-       5e7e827: improve dB volume calculation
-       ba6c0e1: fix C++ compat
-       8181db1: initialize properties for ALSA sinks/sources more elaborately, re #277
-       c2c833c: use the sink description instead of the name to choose the description for the monitor source
-       64e048c: drop a redundant pa_init_proplist(), properly set MEDIA_NAME property on stream, not on context
-       5971345: rename sink_input->rewind to process_rewind() and set_max_rewind to update_max_rewind()
-       62e7bc1: Big pile of dependant changes: * Change pa_memblockq to carry silence memchunk instead of memblock and adapt all users * Add new call pa_sink_input_get_silence() to get the suitable silence block for a sink input * Implement monitoring sources properly by adding a delay queue to even out rewinds * Remove pa_{sink     7556ef5: maintain a global silence memblock cache
-       a0671aa: fix for new location of gccmacro.h
-       d1d7a07: we have not periodic timers anymore
-       33a35b6: update to recent changes of proplist api
-       33cb589: split user supplied data in multiple memory blocks if necessary to fit in one mempool tile. If the caller supplied a free_cb and we use shm it's better to copy the data immediately to the shm region instead of keeping it around as user memblock
-       ed36f31: increase the default pool size to 16MB because we now need to keep a lot more memory around due to glitch-free.
-       03df088: add lower boundary for artifical latencies
-       af25697: follow pa_pstream_use_shm->pa_pstream_enable_shm rename
-       687aa29: add new pa_pstream_get_shm() API, rename pa_pstream_use_shm() to pa_pstream_enable_shm(); pa_bool_t-ization
-       bee409a: remove debug messages
-       1ddb95a: add new silence memblock caching subsystem
-       4b1d684: add new API function pa_memchunk_memcpy()
-       144b237: print a message on xrun
-
-2008-04-17     Lennart Poettering
-       22ceb15: add new rtstutter tool which can be used generate artifical scheduling latencies in the OS to trigger buffer underrun events in your software. it's an awesome debug tool for glitch-free; also move test programs from automake's check_ back to noinst_ to make sure it is built everytime Lennart presses F9 in his emacs
-       c9d0159: define PA_xxxSEC_PER_yyySEC for usec, too
-
-2008-04-14     Lennart Poettering
-       1f0a52d: the pointer to rewind() may actually be NULL
-       68e4a93: properly ask the sink to rewind on new sink inputs and when they disappear
-       6946d2a: make sure to clear all queued RT signals before arm a new timer
-       04178d4: add _cb suffix to _max_rewind function like with all other functions, too
-
-2008-04-13     Sjoerd Simons
-       91f092e: Let bootstrap.sh require version 1.10 of the various autofoo bits. Otherwise things will break during compilation
-
-2008-04-11     Lennart Poettering
-       14fd32e: add missing 'break's in switch
-       55f273e: s/pulsecore\/gccmacro.h/pulse\/gccmacro.h/
-       07f5c1d: register sink/source name as first step when creating a new sink/source so that we can hand the valid name string to the hook functions; se tup props for monitor sources correctly; fix implicit flag setting logic
-       aad9d39: dump all info we know about sinks/sources/... in pactl
-       dbe3633: properly initialize ->memblockq
-       cdb273d: add new pa_get_state_dir() function, move pa_strnull() here
-       dcf7173: fix help string for volume commands
-       fe3c42d: fix packet formatting for a few commands
-       2c6176f: mark shm marker struct as packed, to guarantee identical sizes between archs
-       29cbd88: add new PA_GCC_PACKED macro
-       096e7f0: make shm magic marker compat with multiarch systems where 64bit and 32bit processes might share SHM areas
-       c9db6d2: don't fail if a signalled writability of STDOUT is no longer true when we try it because some other thread already wrote something
-       413656b: update list-xxx commands a bit
-       28ab2a0: don't print 'signal' each time a rtpoll poll() call is canceled
-       50d585e: fix linker warning macro code, move pa_strnull() to core-util.h, move PA_LIKELY definitions here from gccmacro.h
-       d0ebb71: don't use fqdn if we don't have to
-       78368db: redirect alsa errors to normal PA log system; export buffer settings in device props
-       1c5f665: make use of new alsa SND_PCM_NO_AUTO_xxx flags; redirect alsa errors to normal PA log system
-       0f28de6: mark autoload functions as deprecated
-       d7e260b: remove misplaced PA_GCC_PURE
-       e832b0c: add C++ safety to header file
-       7dad635: fix bit depth guarantee for pa_usec_t
-       919bd98: add new API function pa_timeval_add()
-       566322a: remove gcc macros from cdecl.h because we have them in gccmacro.h now
-       007f82d: fix bad memory access when initializing client proplist
-       d491adf: add gccmacro.h to doxygen docs
-       e084e4b: add new module module-device-restore
-       c61c3b6: increase version of required ALSA to 1.0.16. check for gdbm
-       6cddf61: add new API pa_rtclock_from_wallclock()
-       e1c1a78: fix proplist serialization
-       bb9792a: move gccmacro from pulsecore/ to pulse/
-
-2008-04-09     Lennart Poettering
-       5d7128a: add new describe-module CLI command
-       39afb14: add new pa_proplist_setf() API function
-       d69aeeb: implement server side of new sink/source reconfiguration commands
-       fc9d827: remove doxygen \since tag for API changes older than 0.9; properly implement new latency query APIs
-       cc1e265: init min/max latency properly; fix avail_min updating
-       f3109be: show configured latency and its ranges
-       da37a7e: export both min and max latency that is configured for a sink; add API for querying the requested latency of a sink/source from the main thread
-       ad18107: add new latency argument
-       0f9e977: bump protocol version
-       3138928: include proplist.h in doxygen docs
-
-2008-04-07     Lennart Poettering
-       b3b8a63: call snd_pcm_hwsync() expclicitly before we access any of the status fields, since this seems to be necessary. try to find the right mixer device via the card index
-       c84a64c: fix bug where we silently dropped data that didn't fit into one mempool tile
-       98b0152: add utility functions to dump alsa PCM state
-
-2008-04-04     Lennart Poettering
-       b9c10f2: propery calculate min_avail in frames instead of bytes. don't use device_id= parameter in alsa modules if parameter wasn't specified
-       064aa12: drop support for periodic timers, cleanup code a bit
-       122861f: mark libpulse-browse as obsolete
-
-2008-04-03     Lennart Poettering
-       cdfcf66: - deprecate autoload stuff - allow setting of the requested latency of a sink input/source output before _put() is called - allow sinks/sources to have a "minimal" latency which applies to all requested latencies by sink inputs/source outputs - add new client library flags PA_STREAM_ADJUST_LATENCY, PA_STREAM_START_MUTED - allow client library to fill in 0 to buffer_attr fields - update module-alsa-source following module-alsa-sink - other cleanups and fixes
-
-2008-03-31     Lennart Poettering
-       ecf6439: catch up with trunk HEAD (i.e. 2118:2213)
-       0e983e5: fix caps stuff for crazy people who disable caps
-       316e39d: update copyright year
-       fa0b9b0: merge r2136 from prepare-0.9.10
-       a9971d2: merge r2195 from prepare-0.9.10
-       b39da92: merge r2194 from prepare-0.9.10
-       1af0d94: merge r2193 from prepare-0.9.10
-       9f71611: merge r2192 from prepare-0.9.10
-       70a459b: merge r2191 from prepare-0.9.10
-       690807e: merge r2189 from prepare-0.9.10
-       5181f79: merge r2190 from prepare-0.9.10
-       a826937: merge r2187 from prepare-0.9.10
-       79938c9: merge r2186 from prepare-0.9.10
-       6734fba: merge r2185 from prepare-0.9.10
-       78bdb97: merge r2184 from prepare-0.9.10
-       e382f22: merge r2183 from prepare-0.9.10
-       1be481f: merge r2182 from prepare-0.9.10
-
-2008-03-31     Diego Petteno
-       25f9507: fix the help for --disable-per-user-esound-socket so that it actually refers to the --disable action.
-
-2008-03-30     Lennart Poettering
-       3e314b7: fix buildsystem to provide pa_log() in all binaries
-       cf37df4: rework pa_assert_se() to make sure it never gets optmized away, even if NDEBUG is defined
-       68b131d: make pa_drop_caps() abort on failure
-       dbf9037: avoid name clash with libc's remove() function
-
-2008-03-29     Lennart Poettering
-       829197d: fix compiler warning
-       ed5528f: require autoconf 2.60 since we use AC_PROG_MKDIR_P
-       1c82694: bump soname
-       a3b8311: merge r2187 from trunk
-
-2008-03-28     Lennart Poettering
-       0a108ec: don't fail on init if the default device does not exist and .nofail is active
-       fad6b41: don't segfault when module-tunnel is used without a sink_name/source_name parameter. Closes #197
-       13b9951: if we are run as root, always use 'root' as username, regardless of any env vars
-       8e60b01: actually set lennart to the user name, not the group name. Set lennart too.
-       2599213: Fix ioctl() definition for solaris compat. Patch from yippi. Closes #253
-       b0dc80d: work around yet another solaris braindamage
-
-2008-03-27     Lennart Poettering
-       bc5e3f1: properly notify clients about suspended state when moving source output streams. Closes #244. Patch from slicer
-       8298b6b: merge r2179 from prepare-0.9.10
-       4ddc327: initialize gconf module before we publish our X11 credentials -- because gconf might cause network support enabled in the first place
-       e21a69e: merge r2146 from trunk
-       2b593d2: merge r2134 from trunk
-       e5e9ed6: merge r2133 from trunk
-       ac82029: merge r2132 from trunk
-       95422a8: merge r2131 from trunk
-       edd1a50: merge r2130 from trunk
-       02840a3: merge r2129 from trunk
-       a1ec3d7: merge r2128 from trunk
-       46cd225: merge r2127 from trunk
-       daaf70b: merge r2117 from trunk
-       28b7ddc: merge r2116 from trunk
-       cca3f49: merge r2113,r2214,r2115 from trunk
-       184dda8: merge r2112 from trunk
-       1eb7239: merge r2111 from trunk
-       5045d26: merge r2110 from trunk
-       39de4dd: merge r2109 from trunk
-       bc58240: merge r2108 from trunk
-       ec39786: merge r2107 from trunk
-       e704fd3: merge r2106 from trunk
-       b79c6b6: merge r2105 from trunk
-       b0a2049: merge r2104 from trunk
-       a451de1: merge r2098 from trunk
-       2735309: merge r2097 from trunk
-       640033a: merge r2096 from trunk
-       9dfbfce: merge r2095 from trunk
-       cc59e76: merge r2092,r2093,r2094,r2152 from trunk
-       1908e82: remove a redundant if check
-       db208e3: merge r2091 from trunk
-       9f0045a: merge r2090 from trunk
-       f10b531: merge r2084 from trunk
-       66d9e87: merge r2145 from trunk
-       d055127: merge r2083 from trunk
-       6c106c9: copy originial l2ping license from bluez into bt helper
-       14ed19c: Enable per-user esound sockets by default. Esound CVS already enables this by default, and all sane distributions ship a patched esd anyway. And those which do not should get a life and start patching esd
-       cefa0eb: merge r2081 from trunk
-       0e23606: merge r2079 from trunk
-       a86a48c: merge r2077 from trunk
-       5e13249: merge r2076 from trunk
-       aceb800: merge r2075 from trunk
-       e721ecd: merge r2073 from trunk
-       8d5ee50: merge r2074 from trunk
-       c59a90c: merge r2078 from trunk
-       05a7f5d: bump revision
-       e6bb276: create branch for 0.9.10
-       5addad2: make loading of a few more modules non-fatal
-       dcdf419: Double maximum sample size for some overly huge samples some distros ship
-       a25a459: Attempt to resolve the multilib conflicts by getting all the config files look equally for all plattforms.  This includes getting rid go pathnames with libdir; let's make ps search for files with relative paths there.
-       7ad0b64: modernize polkit code a bit, use new functions from pk 0.7 instead of our home-grown ones
-       8a14304: rename polkit policy file to org.pulseaudio.policy to follow upstream guidelines
-       be9b32e: add vendor data to pk policy file
-       c5f78bf: Abort instead of cleanly exiting, so we can obtain a core dump and find out what was wrong. (rhbz #438594, Patch from Lubomir Kundrak)
-
-2008-03-26     Lennart Poettering
-       7262e2f: add proper arm atomic ops support, patch from Jyri Sarha
-
-2008-03-15     Lennart Poettering
-       106ddb9: remaining bits and pieces
-       b5c5064: commit glitch-free work
-       d6bd152: commit glitch-free work
-       ebecf3d: commit glitch-free work
-       12c01e9: commit glitch-free work
-       347cfc3: commit glitch-free work
-       8d9bdac: really create glitch-free branch
-       dd81a90: create glitch-free branch
-
-2008-03-14     Lennart Poettering
-       6ad7621: work around solaris printf %s and NULL string brain damage
-       70d0083: change policy file to not show polkit auth dlg by default
-
-2008-03-09     Diego Petteno
-       666b952: And one more.
-       30e2a77: Test for _struct_ lt_user_dlloader, otherwise it won't be found.
-
-2008-03-08     Diego Petteno
-       9ad7bb6: Build and run using libltdl from libtool 2.2. The user module loader support has changed drastically.
-
-2008-02-15     Tanu Kaskinen
-       46d804d: Clarify the explanation of the in_action field in pa_autoload_entry.
-
-2008-02-15     Lennart Poettering
-       dc3682d: only call pa_ltdl_done() if we called pa_ltdl_init() before
-       2b8bc5c: allow compilation on systems that lack POSIX shared memory. Patch from matthijs, closes #200
-       5552139: explicitly recommend the usage of -- in the pasuspender command line, Closes #203
-       a1b2a83: look for timer_create in librt, Closes #210, patch supplied by matthijs
-       0a807b3: print pa version id each time we start up, so that it is easier to identify the version people are reporting bugs again
-       75e1ebd: Improve compatibility with applications which like to pass invalid strings to the libc functions we overwrite, by handing directly to the original function. Patch by Colin Guthrie and Gustavo De Nardin, Closes #227
-
-2008-02-13     Lennart Poettering
-       86b9ef8: deal with a possibly failing pa_channel_map_init_auto() correctly
-
-2008-01-24     Diego Petteno
-       a3e820f: Mark long_options constant.
-       c8a9c9b: Use check_PROGRAMS rather than noinst_PROGRAMS for test programs.
-       be4c0f2: Apply the fix for CVE-2008-0008 from 0.9.9 release on trunk.
-
-2008-01-24     Lennart Poettering
-       90a7f3b: bump revision
-       4d4dafb: fix CVE-2008-0008.patch
-       9423e67: prepare 0.9.9
-
-2008-01-06     Lennart Poettering
-       d36a1b8: use __BYTE_ORDER macro for detecting byte order, as suggested on http://unixpapa.com/incnote/byteorder.html
-
-2008-01-04     Sjoerd Simons
-       c5678ae: Don't send opcodes introduced in protocol versions 12 to clients using protocol version 11. (fixes #183)
-       02f49a2: Implement opcodes in the tunnel modules that were added in version 12 of the protocol. Based on a patch by coling. (fixes #193)
-       9774cc7: Add forgotted #ifdef __linux__ and only use SIGRTMIN if it is defined. Fixes compilation on non-linux platforms like GNU/kFreeBSD. Thanks to Aurelien Jarno for the patch
-
-2008-01-03     Tanu Kaskinen
-       1e74aa9: Add a missing pa_xfree.
-       4e77176: The previous commit introduced a new bug: giving too many values in the "control" argument wasn't detected any more. Fixed.
-       39ba68b: Fix the parsing of trailing default values in the "control" module argument.
-
-2008-01-02     Tanu Kaskinen
-       dccf411: Downgraded the priority of a message, because it's really quite uninteresting.
-
-2007-12-29     Lennart Poettering
-       9d00b9d: convert argument to boolean value before passing it on to __builtin_expect in PA_LIKELY
-       2cb1b2c: add new function pa_proplist_contains()
-
-2007-12-23     Lennart Poettering
-       2a44213: add API for resetting allocated resamplers
-       7f65e79: wrap speex_resampler_reset_mem()
-       81e85ce: hide proplist-test
-       63c616e: add new property list implementation
-
-2007-12-14     Tanu Kaskinen
-       8ed2a8c: Increase the maximum line length of default.pa from 256 to 1024. Load commands of modules that need multiple channel maps may grow rather long.
-
-2007-12-06     Diego Petteno
-       b94a6bc: Add a configure switch to enable the per-user ESounD socket path, but default to vanilla ESounD's path. This way distributions and users can configure PulseAudio according to their ESounD library.
-
-2007-11-24     Lennart Poettering
-       95a98fe: Add new subsystem for applying envelopes (such as volume ramps) to audio signals
-       2d34bca: rearrange #includes
-       0312890: add new pa_mutex_try_lock() API
-       7a42425: add new endianess macros for FLOAT32
-       ca0c5af: make sure to create ~/.pulse before using any configuration file from it
-
-2007-11-23     Diego Petteno
-       04d7a7e: Check for mkdir -p or equivalent, and use that rather than simple mkdir to create the modules, modules/gconf and modules/rtp directories.
-       19ee3b6: Enable D-Bus if Bluez or HAL are enabled; use DBUS_LIBS/DBUS_CFLAGS when building libdbus-util.la.
-       ec91380: Fix detection of polkit_context_is_caller_authorized() function, also reported by Nix. Also fix detection of policydir for prefixes different from /usr.~
-
-2007-11-22     Lennart Poettering
-       9d2255d: fix uploading of samples into PA. Problem discovered by Colin Guthrie
-       3e4f820: update speex resampler with newer snapshot from Speex SVN
-
-2007-11-21     Lennart Poettering
-       d41744a: Tagging release 0.9.8
-       23e3d7c: bump version and soname
-       6b932f0: update man pages a bit
-       40db06d: when speaking to a client with a version < 12, hide S32 sample specs, and make them appaear as FLOAT32
-       0f5fa47: increment api and protocol version
-       14a9b80: - Check process name when dealing with PID files - Add new PA_STREAM_FIX_CHANNELS, FIX_RATE, FIX_FORMAT, DONT_MOVE, VARIABLE_RATES to pa_sream_flags_t adn implement it - Expose those flags in pacat - Add notifications about device suspend/resume to the protocol and expose them in libpulse - Allow changing of buffer_attr during playback - allow disabling for remixing globally - hookup polkit support
-       4ac6b53: minor typo fix
-       5a4959e: add short version history of the PA protocol
-       63fa021: add a couple of new opcodes, and document the versions the opcodes where added
-       d1d0778: add API to allow runtime reconfiguration of memblockqs
-
-2007-11-16     Lennart Poettering
-       07832d0: detect whether PolicyKit support is available
-       cf0d43e: build PolicyKit support
-       8bdad29: add interface to PolicyKit
-
-2007-11-14     Lennart Poettering
-       413a8f8: use a prio inheriting mutex for the threaded mainloop, to ease writing of RT clients
-       461e369: use a free list for allocation pa_operation objects
-       1765b13: use a free list for allocating reply_info structs
-       9b75b9d: add missing pa_boolization
-
-2007-11-13     Lennart Poettering
-       7462ab1: Rework ALSA mixer channel detection code. This time we actually care about the channel names the ALSA mixer exports for us
-       4c47617: add array size to increase chance of detecting missing updates
-       4a39c2e: don't fail if the bt-proximity-helper is not built
-       15f56de: don't touch RLIMIT:MEMBLOCK by default. This should improve out-of-the-box comaptibility with JACK
-       7b321ed: increase the pacmd timeout a bit
-       d17bb53: Completely rework ALSA device selection code: choose the device to open depending on the requested number of channels and channel map. In most cases it will now suffice to set default-channels=6 to enable 5.1 sound for all devices that support it
-       f752882: fix loading of load-once modules if no other modules was loaded before
-
-2007-11-11     Lennart Poettering
-       5054f36: add new fun module that automatically mutes your audio devices when you leave with your bluetooth phone, and unmutes when you come back
-       e8092be: Port module-gconf to make use of the new API pa_start_child_for_read()
-       daf3a3e: pull code for starting helper processes out of module-gconf, clean it up, and stick into a new API pa_start_child_for_read()
-       e043eaa: add new function pa_strnull() to simplify passing null strings to non-linux printf()
-       f873a2a: add a simple fully-automatic fully-linearupmixer/downmixer and enable it by default
-
-2007-11-09     Lennart Poettering
-       e313fe1: tag modules that may only be loaded once at most especially, and enforce that in the module loader
-       d8e0c1c: minor typo
-       b0a68fd: optimize mixing code a bit. Add mixers for S32LE, S32BE, ULAW, ALAW and FLOAT32BE. Add volume adjusters for FLOAT32BE, ALAW, ULAW.
-       c1985c2: replace a few CLAMPs by PA_CLAMP_UNLIKELY
-       0149031: remove PA_CLAMP_LIKELY macro because it doesn't really make sense.
-       7bd3c03: .la files for modules can probably be removed safely on all archs now
-       7e0f547: add support for 32bit integer samples
-       3c17c7d: fix CLAMP_LIKELY/UNLIKELY definition
-       ecf349d: add missing #include
-       42ef051: add a few missing macro definitions
-       cb66762: add PA_CLAMP_LIKELY and PA_CLAMP_UNLIKELY macros
-       c8cdb06: add support for likely()/unlikely() type macros
-
-2007-11-08     Lennart Poettering
-       14b974a: parse the pasuspend argument like any other boolean in PulseAudio
-       a2121d5: strip most comments from the default configuration files, since the man page is now more elaborate and we don't want to maintain those docs redundantly at two places
-       4459912: add remaing man pages
-
-2007-11-07     Lennart Poettering
-       1ef4baf: warn if the sound server is not local
-       1821f1f: add man pages for padsp, pabrowse, pasuspender
-
-2007-11-06     Lennart Poettering
-       5dbab0b: complete pactl man page
-
-2007-11-05     Lennart Poettering
-       0eb011b: minor cleanups of --help texts
-       7fdc1ee: add a couple of more man pages
-       bff4ca4: add a man page for the pulseaudio binary. More will follow.
-
-2007-11-04     Lennart Poettering
-       961ce33: fix two alignment issues found by the debian buildd gcc on sparc
-       faf1fd7: pa_boolization
-       0184d70: add eventfd syscall nr for arm; patch from Sjoerd Simons; Closes #150
-       9ac9328: Properly terminate pa_readlink() strings. Patch from Sjoerd Simons. Closes #149
-       95af1e6: Add linker version script to hide non-ABI stable symbols in the client libraries. While this helps defining a more streamlined ABI, this also requires linking a lot of additional symbols into some PA client utilities which until now made use of the non-ABI stable symbols in libpulse. To minimize the effect on there size a bit, strip unused symbols by linking with -ffunction-sections -fdata-sections -Wl,--gc-sections
-
-2007-11-01     Lennart Poettering
-       bc161b4: comment the library versions a bit
-       cb0d7ff: add missing pthread libs
-       81233c1: make disallow-module-loading config option work again (original patch from Diego Petteno)
-       7bfd1b2: make rtprio and nice level actually configurable
-       641d1fa: drop rt scheduling before we start our helper process
-       41ea3b2: add new option --realtime
-       005ed41: save and restore errno in sig handler
-       44d7c9a: add nice and rtprio resource limit support; make rtprio and nice level to use configurable; some minor updates
-       e706f7b: pa_boolize the client config
-       65a6bff: more pa_boolization
-       b343497: make the bool config parser actually parse bools
-       cecd8d4: fix comment
-       38a1525: add new function pa_yes_no()
-
-2007-10-30     Lennart Poettering
-       5058a1e: save and restore errno in the sig handler
-       111b759: bump sonames
-       0f0e729: make sjoerd happy: include ChangeLog built from svn logs in tarball
-       099e690: make make distcheck pass
-       b03b574: rename 'length' parameters in the API to 'bytes', to make their unit clear
-       b84489d: handle tcp4: prefix for server specs correctly. (Closes #136)
-       72817f9: rename stream names too, when the sink name changes
-       201dff7: ignore updates not relevant to us
-       1e0454e: rework the tunnel naming scheme, and make it follow the description changes of the underlying devices; never check for tagstruct eof, to ease later extensions
-       bb2e1af: initialize userdata struct with 0
-       0991a1b: remove libltdl from SVN
-       2d265a9: deal properly with signals interrupting us when we wait for data from gconf helper
-
-2007-10-29     Lennart Poettering
-       f1be931: keep track of configured tunnels and make sure to unload them when they disappear from zeroconf again
-       e406bba: don't announce monitor sources
-       5ef242c: don't try to send pause request before our stream is properly set up
-       33c238b: ignore network sinks/sources
-       625a872: make gcc shut up a bit more
-       1dae2e6: we don't want to include assert.h anymore
-       43b5c65: reverse server order for PULSE_SERVER x11 property, to follow order in which modules are loaded
-       cc88385: add new API pa_strlist_reverse()
-       87be856: add new module module-zeroconf-discover
-       9f44659: publish dns-sd subtypes to allow distinction of virtual, hardware and monitor sinks/source
-       9ca7ed1: export pa_namereg_is_valid_name()
-       0ce32bd: fail on name clash
-       ac83631: bring back module-tunnel, yay!
-       9ccbd86: downgrade a few log messages
-       6e1f7bd: properly deal with time pausing
-       a46804a: use real path of binary instead of /proc/self/exe to execute ourselves
-       27d6b7b: make use of new pa_readlink() where applicable
-       ca98c54: add new pa_readlink() API
-       1c06907: make speex-float-3 the default resampler
-
-2007-10-28     Lennart Poettering
-       c6a7f06: add missing dependency on socket-util
-       a67c21f: merge 'lennart' branch back into trunk.
-       575541d: Merge r1502 from trunk: Move pthreads detection as it gets confused by things in LIBS.
-       f096ca4: Merge r1504 from trunk: Solaris hides inet_ntop in nsl
-       c6071b0: Merge r1505 from trunk: Make sure we link to the core to get all symbols.
-       9eb840c: Merge r1503 from trunk: Make -no-undefined actually work (and fix up error found by it).
-       d8976a2: Merge r1473 from trunk (mixer ioctls on /dev/dsp)
-       b718d18: fix error handling
-       daa2863: don't use errno on EOF
-
-2007-10-27     Lennart Poettering
-       94cf167: port module-esound-sink to new core
-       66dc0b4: don't use SIGRTMAX, for compatibility with valgrind which apparently uses this signal
-       98d363c: minor cleanup
-       87faa54: minor fix to make gcc shut up
-       56804de: minor fixups, to make the test more deterministic
-       581e7f1: add ability to "pause" the input time temporarily. don't accidently overwrite variables we still need.
-       55e4a3e: modernize pa_iochannel a bit, add pa_iochannel_get_send_fd()
-       c4d9a2b: add missing pa_smoother destructor
-       b4bb747: add pa_rtclock_usec() API
-       ca744a4: add pa_timeval_load() API
-
-2007-10-26     Lennart Poettering
-       ce5250e: hide smoother test
-
-2007-10-25     Tanu Kaskinen
-       7ccf40e: Add "support" for plugins that have control output ports, i.e. don't crash on them anymore (the plugins correctly assume that every port is connected to a buffer, so we connect them to a dummy buffer that isn't used anywhere).
-       81ed6e6: A couple of comment typo fixes.
-
-2007-10-24     Lennart Poettering
-       0d84e4c: fix alsa mmap initialization bogosity, discovered by Jyri Sarha
-
-2007-10-23     Lennart Poettering
-       dc987e9: add better time interpolator: use linear regression to determine gradient from measurements, predict a short distance ahead, and smoothen estimation function with 3rd degree spline interpolation.
-       9464b9b: add definition of PA_USEC_PER_MSEC
-       65b570c: properly copy error string
-
-2007-10-22     Lennart Poettering
-       498a156: also port over JACK source to new core
-       02adb5f: enable jack sink in Makefile
-       468c13e: Port JACK sink module over from old core
-       4029504: minor fixup
-       925eadd: add interleaving/deinterleaving APIs
-
-2007-10-17     Lennart Poettering
-       1900817: Properly handle if ALSA sends us an POLLERR event, this should allow us to survive a system suspend cycle better
-
-2007-10-15     Lennart Poettering
-       2385efe: fix url
-
-2007-10-07     Lennart Poettering
-       b0bce20: add missing poll.h inclusion
-       215cac8: add missing poll.h inclusion
-       a687c31: add missing poll.h inclusion
-       3736246: s/timespec/timeval
-       2198c2e: fix build
-       efc81a8: add new API function pa_timeval_store()
-       d74fa66: Fix build; change return value of pa_rtclock_hrtimer() to pa_bool
-
-2007-10-04     Lennart Poettering
-       87cc073: fix poll.h check, bad boy ossman broke
-
-2007-10-03     Pierre Ossman
-       cb40087: Don't call pa_rtsig_configure() when we lack the necessary defines.
-       60a935b: module_ladspa used libltdl so make sure it links against it.
-       586ef22: Platform dependent semaphore implementation for Windows.
-       cef6563: Assorted minor Windows compatibility fixes for recent code updates.
-       ce74146: Add stubs when RT signals aren't available.
-       8dcc1fa: Adapt rtpoll and friends to Windows by replacing timespec with timeval and add a fallback when clock_gettime() isn't available.
-       ef8812e: Replace all references to sys/poll.h with poll.h as that's what POSIX defines.
-
-2007-10-01     Lennart Poettering
-       7c1768d: update native protocol to make use of pa_memblockq_pop_missing
-       2e780e8: Move request size handling into pa_memblockq, function pa_memblockq_pop_missing()
-       d6a2203: Fix race condition between IO thread creation and pa_sink_put(). Move activation of rtpoll fds when we change the state INIT->IDLE.
-       9d34a1e: fix trivial typo
-       abd692e: fix silence initializer for alaw and ulaw
-
-2007-09-30     Tanu Kaskinen
-       dbcd086: Fixed PA_GCC_CONST definition.
-
-2007-09-28     Pierre Ossman
-       bdf9746: Update module-solaris to new structure.
-       6d8aea7: Incorrectly used str2sig() instead of sig2str().
-
-2007-09-28     Lennart Poettering
-       67b899a: treat timer_enabled like a real, grown-up boolean variable
-       33f2f49: rework module-combine once again. We now run the data generation always in a seperate thread. This should help use to avoid all the awful race conditions we had in previously
-       229afb5: Move the poll() call outside the #ifdef checking for ppoll, since we want the poll in all cases. Prior to this change the check for negative return values of poll/ppoll was never actually executed when ppoll() was available
-       f8c1786: use the full range of RTSIGS for our stuff
-       3cdff5f: Allocate rtsigs from back to front, to avoid clashes with other libraries makeing use of rtsigs
-       df33b4c: only do IO if we are RUNNING or IDLE, but not when we are in INIT
-       584ca61: don't free silence memblocks that don't exist
-       107f12a: speed up semaphore allocation with an flist
-
-2007-09-26     Lennart Poettering
-       008c709: Use Linux eventfd() if kernel supports it
-       e99bc33: fix build with compilers that lack __thread
-
-2007-09-25     Lennart Poettering
-       a9e667b: make sure when can shutdown PA cleanly without segfault
-       5fe1589: work around newest open() magic in fedora glibc
-       1687226: fix make dist
-
-2007-09-24     Lennart Poettering
-       86ec421: fix suspending in module-combine.c
-       609ad12: * decouple suspending of monitor sources and their sinks * implement resume-on-uncork
-       0e3e9e2: only post data into the monitor source when it is not suspended
-       f0f9df9: * add new state changed hook for streams * update sink->n_corked properly when moving streams
-       ac86fa1: fix IDLE vs. RUNNING state handling of sinks/sources when changing cork status for streams
-       3c75d35: rework zeroconf service publishing, to use synchronous hooks instead of asynchronous subscription events. Don't push autoload entries anymore.
-       e37fa01: add hooks for name/description changes of sinks/source and streams
-       ef020c6: fix stream corking: ignore pa_sink_input() when we are in corked state
-       55651ec: don't count streams using the monitor source in pa_sink_used_by(), because this would disallow suspending a sink ehn an rtp stream is connected
-       ba322a4: drop the PA_SOURCE_CAN_SUSPEND and PA_SINK_CAN_SUSPEND flags, since they were a bad idea in the first place. All sinks/sources are now *required* to handle suspending in one way or another. Luckily all current sink/source implementations handle it fine anyway.
-
-2007-09-23     Lennart Poettering
-       77ed60c: instead of using the mixer ioctl()s on the dsp fd, open a seperate fd for the mixer. This allows us the keep the mixer fd open while closing the dsp device while suspending.
-       fc00eaf: use O_NOFOLLOW when creating lock files, too
-       2860685: use O_NOFOLLOW when creating PID file, to avoid symlink vulnerability
-
-2007-09-23     Tanu Kaskinen
-       de079ac: Added an assertion for the case when the sink programmer hasn't installed the thread_mq properly.
-       7bcbf16: Comment typo fix.
-
-2007-09-22     Tanu Kaskinen
-       ecad937: Fix the assignment of control values by using the right variable for indexing.
-       1c44be2: Correct the parameter positions with the pa_cvolume_set() call.
-
-2007-09-22     Lennart Poettering
-       e04a857: minor optimization
-       6cfb096: include the name of the master sink in the name for piggy-backed virtual sinks
-       c6b43bf: prefix by order macros with PA_
-       6683400: rework a couple of sample type converters, to actually work
-       78a9ad3: - rework volume adjustment code to not require fp - don't hit an assert when we cannot do a volume adjustment, instead, print a warning and go on
-       d7a0876: fix selection of working format
-       9db4267: make use of byte swap builtins of gcc if they are available
-       f26de80: add test program for the resampler
-
-2007-09-21     Lennart Poettering
-       c34a263: allow _unlink() functions to be called as many times as people want, even before _put() was called
-       1fc168b: clamp sample data to -1 .. 1, before passing it to the plugin; if a control port data specification is left empty, initialize with the default value of the plugin
-       29d25ec: add CLAMP macro
-
-2007-09-20     Lennart Poettering
-       e205bb2: don't segfault when the master changes
-       3b2835d: properly detach/attach when moving sink inputs
-       f3f44da: rework module-combine again
-       c40c168: maintain the attach status in a boolean variable 'attach' accessible from the IO thread for sink_inputs/source_outputs
-
-2007-09-19     Lennart Poettering
-       75647bc: render new data always in the master sink's thread, fixing missing locking
-       a8a9ee4: make sure we initialize thread private data before we move our ghost sink to the rt thread, not after
-       42b71ff: fix trivial typo
-       d716e3c: fix check for lrintf, make resample2.c again identical to upstream ffmpeg
-       75f799a: make O_CLOEXEC, O_NONBLOCK and socket low latency fd ops more uniform: always return void, name them similarly, only pass a single fd
-       0fcad97: copy free_cb into a temporary variable first, to avoid compiler warning
-
-2007-09-18     Lennart Poettering
-       ac66b6a: fall back to plughw:, if hw: doesn't work, in the alsa source, too
-       781cf49: properly release memblock always abd as soon as possible
-       1fd9afd: make use of pa_bool_t on a few places where applicable; really start work_cb
-       b3093d8: lower SO_PRIORITY priority to 6, since this is the best we get without being root
-       ef8df41: make rtp send socket low delay
-       f44ddd1: add new pa_socket_udp_low_delay() API
-       6b2fd23: add two missing header file inclusions
-       eb23601: bug fixes for module-rtp-recv
-       8fdf054: make sure we don't call pa_source_post() for a monitor source after it was unlinked
-       ca71764: If PTHREAD_PRIO_INHERIT mutexes are not available fall back to normal mutexes
-       a558e93: port module-rtp-send.c to lock-free core
-       08d4b23: actually close the alsa device before we try to reopen it as plughw
-
-2007-09-18     Pierre Ossman
-       4ed41f3: strtof() is a rather recent addition to C. Fall back to strtod() if it isn't available.
-       aff22cf: NSIG seems to be more common than _NSIG.
-       03d9863: Emulate lrintf with simple truncation if it isn't available.
-       31dfb31: Make sure the header file is only included on linux (as this is a linux-only feature).
-       df1d347: NSIG is not defined by neither C99 nor POSIX so we can't rely on it.
-
-2007-09-17     Lennart Poettering
-       4cde507: add LADSPA sink than can be piggy-backed ontop of another sink
-       7b4f981: print a message when we fall back on plughw
-       8ff7d56: add a locale-independant pa_atof() implementation
-       4cdf2ce: hide sig2str-test
-       1ae473b: fall back to plughw: if hw: doesn't work
-       26a1ae7: Rename pa_strsignal() to pa_sig2str(), since we return the symbolical signal name, not a human readable string. This follows the Solaris API of sig2str() a bit. Also, add all remaining signals to the list of signal names.
-       d3b8985: drop a couple of WARNING prefixes in log messages, since we have pa_log_warn anyway for marking warnings especially
-       19eb7eb: once.c is no longer POSIX specific. Since it is now considerably more advanced than it used to be, use it on windows, too
-       7f9fea7: on Linu disable lazy binding altogether
-       a1526f1: add missing initialization
-       061e806: Add a special ltdl .so loader that avoids lazy frelocations during runtime
-       2741685: use priority inheritance on mutexes where applicable
-
-2007-09-16     Lennart Poettering
-       61b90a0: add proper boolean type pa_bool_t
-       116ddaa: use gcc const and pure function attributes wherever applicable
-       35483ee: add a new module module-remap-sink which can be used to remap the channel maps of an already existant sink. one use case is to create a virtual sink that redirects stereo data to the rear speakers of a surround card.
-       1d1eda6: add a "length" argument to the seek functions, as an optimization to request a certain block size if any data needs to be generated. this is merely a hint.
-       5df7a85: split memblocks into multiples of the mempool tile size
-       ac1ee4e: add new API pa_mempool_block_size_max() to query the maximum tile size
-       fce8507: * add a new resampler "copy" which is does not change sample rates but copies data unmodified from input to output. * add a new API pa_resampler_max_block_size() which can be used to determine the maximum input buffer size for the resampler so that the bounce buffers don't grow larger then the mempool tile size
-       d079b48: properly define MAX/MIN macros
-       87795b0: add missing header file changes for frame alignment apis
-       e17fbf0: be a little bit more elaborate on the reason why we drop to software volume control if hw is not featureful enough for us
-       0469c84: add frame alignment APIs; don't require memory to be writable when silencing it (required of the mmap modes drivers where the hw data needs to be silenced, although it is not writable to others)
-
-2007-09-15     Lennart Poettering
-       298d239: trivial typo
-       8389264: count corked streams per sink/source and make pa_sink_used_by() return only the number of streams that are not corked. Introduce pa_sink_linked_by() returning the number of streams connected at all. This will allow suspending of sinks/sources when all streams connected to a sink are corked.
-
-2007-09-14     Lennart Poettering
-       5ae4eed: Move attaching/detaching from a pa_rtpoll into pa_sink proper, remove it from module-combine
-       3396b65: simplify rt loops a bit by moving more code into pa_rtpoll. It is now possible to attach "work" functions to a pa_rtpoll_item, which will be called in each loop iteration. This allows us to hide the message processing in the RT loops and to drop the seperate sink_input->process hooks. Basically, only the driver-specific code remains in the RT loops.
-       f0b9dce: explicitly destory TLS data before destroying TLS
-       bf274cb: add two new macros PA_ONCE_BEGIN and PA_ONCE_END which allow usage of pa_once without declaring a function to be called
-       04ed0f9: call dbus_shutdown() before exiting, to make valgrind output more useful
-       8775309: fix two typos in reference count handling
-       9be0d70: make newer gcc shut up
-
-2007-09-12     Lennart Poettering
-       ef83a19: extend rtpoll API to allow registration of arbitray functions to be executed in the event loop. Add priority system for specifying the order of these functions.
-       cf3e9da: add missing config.h inclusion
-       03f311a: reindent, and s/assert/pa_assert/g
-       4137865: change pa_modargs_get_channel_map() to take an extra argument for specifying the name of the modargs attribute to parse
-       d9c4c95: add new pa_pipe_close() API to close two fds at the same time
-       7f92542: consolidate close() calls to pa_close(), and make sure on every occasion that we handle failures of close() sensibly
-
-2007-09-11     Lennart Poettering
-       54506ab: on systems where we know that POSIX shm is mapped to /dev/shm, add the ability to cleanup stale SHM segments. (Right now only Linux)
-       d5bedbc: remaining s/assert/pa_assert/ and refcnt.h modernizations
-       2988c3d: Rework core-error.c on top of PA_STATIC_TLS_DECLARE, the windows specific parts need to be moved to thread-win32.c
-       abb18d9: explcitly initialize tls memory to NULL
-       9c523e0: more modernizations, s/assert/pa_assert/g
-       27f13b3: finish modernizations in pulse/, s/assert/pa_assert/g
-       038e560: More s/assert/pa_assert/ modernizations
-       391d09c: add 'wait' parameter to pa_rtpoll_run(), if zero pa_rtpoll_runn will only update the struct pollfd but not wait for an event
-       597a1c4: port client libs to refcnt.h
-       55d9fcb: add globally defined PA_PATH_SEP macro, replacing private per-file macros
-       6ac66e4: add missing config.h includes
-       e2e2ce7: Instead of including config.h from header files, check whether PACKAGE is defined and if not, fail (thus using PACKAGE as a check for inclusion of config.h)
-       848a4d7: more s/assert/pa_assert/ modernizations
-
-2007-09-10     Lennart Poettering
-       9b0ab39: unify static TLS support, make use of gcc __thread attribute if available
-       3d122d0: s/assert/pa_assert/ modernizations
-       de21b54: add new API pa_threaded_mainloop_in_thread(), update test case for it
-       a6f8b81: simple modernizations: s/assert/pa_assert
-       6629886: make sure we send each memblock only once when recording, not twice
-       d5caa02: minor cleanup
-       a77158e: make the memchunk writeable before silencing it
-       841fcb4: beef up comment
-       98f9bd6: make sure that the device volume is properly read before we call pa_sink_put() and thus make the pa_sink available
-       69ece66: add pulseaudio logo with text
-       44e514c: update todo file a little
-       6c1682c: hide a couple of files
-       27c3bd4: document that the native amd64 atomic ops implementation is incomplete
-       06db921: don't call pa_source_process_msg() for PA_SOURCE_MESSAGE_GET_LATENCY, since it makes querying the latency always fail
-
-2007-09-10     Pierre Ossman
-       d9b3c0e: posix_madvise and posix_fadvise aren't present on all systems.
-       9630e8d: Remove mkdir_p again...
-       028632f: TIOCINQ isn't present on all systems.
-       e176601: Monotonic clock is optional so treat is as such.
-       717b164: POSIX realtime clock functions are in time.h so make sure to include it.
-
-2007-09-09     Tanu Kaskinen
-       dfdf1d7: Changed PA_SAMPLE_S16_NE to PA_SAMPLE_S16NE in the example code in the Simple API Doxygen documentation.
-
-2007-09-06     Lennart Poettering
-       b41dbfd: fix an assert when runnig module-oss in record only-mode. optimize allocation of memblocks on playback
-       d60940d: install libpulsecore again, since libtool otherwise links it statically into every single module
-       e4eefb8: fix copynpaste error
-       45ba711: downgrade realtime group membership warning to 'info' at be a little bit more elaborate
-       3b2cf1a: update default config: - check for existance of modules before loading them - disable all event sounds except hotplug by default
-       b1fd53b: explicitly test for the availability of dbus_watch_get_unix_fd() before using it. The previous version-based check didn't work anyway since the constants checked for weren't set.
-
-2007-09-04     Lennart Poettering
-       a0d19c0: update libltdl copy
-       a4757a1: add native amd64 atomic int implementation
-       984ef82: detect whether gcc atomic builtins are available
-       4c31ff9: fix a couple of compiler warnings
-       2dbe137: if available, use native gcc atomicity builtins
-       31c04a9: create config.rpath to fix build on fedora
-       ac5f978: add a few missing files for make dist
-       738f7d7: drop initial libtool_lock() call since this is a debian-specific borkage
-       d1927c7: initialize libltdl for multi-thread support
-       65ac0ea: When in PA_STREAM_AUTO_TIMING_UPDATE mode, delay completion of initialization until we have the first timing data
-
-2007-09-03     Lennart Poettering
-       c029038: actually add source code of module-default-device-restore
-       11bf380: add a new module module-default-device-restore which automatically saves and restores the selected default device. Enable it by default.
-       1d3e70c: header file cleanup
-       104feb0: only list supported resampling methods when --dump-resample-methods is executed
-       c9a0df3: add new API function pa_resample_method_supported() which tests whether a resampling method is supported. Fix building with libsamplerate enabled
-       5bc1221: actually define HAVE_LIBSAMPLERATE with AC_DEFINE
-
-2007-09-02     Lennart Poettering
-       b2c4779: make libpulse-core a noinst lib, because it does not have yet a stable API and won't get one anytime. Also, don't install its header files
-       b6bfaa9: add missing configure.ac part of the libsamplerate patch from r1753, re #125
-       2e8244b: Allow compilation without libsamplerate; based on patch from Marc-Andre Lureau; re #125
-       cc8c499: fix dbus version check for dbus_watch_get_unix_fd()
-       011dfa5: make argument to pa_memchunk_will_need() const
-       68981e5: fix build for dbus < 1.1.1, re #126, patch from Marc-Andre Lureau
-       ca059ab: Don't set RLIMIT_MEMBLOCK to 0 on startup. Retain 4 pages
-       3e188b1: make use of pa_memchunk_will_need() before handing sample cache audio to the RT threads
-       7dbabc4: add new pa_memchunk_will_need() API, similar to pa_memblock_will_need()
-       f36ca79: add new API pa_memblock_will_need() and make use of PA_PAGE_SIZE macro
-       2f7b6fe: add new pa_will_need() API for paging in memory
-       8cf822a: make use of new PA_PAGE_SIZE macro
-       b54e71a: make use of new memory page alignment macros, reindent
-       fe1f55b: add a couple of macros for memory page alignment
-
-2007-08-31     Lennart Poettering
-       1df817c: add pa_channel_position_to_pretty_string() to header
-       718b1d2: add pa_channel_position_to_pretty_string() for usage in pavucontrol/pavumeter
-       02811bf: make sure that we make include paths absolute before calling chdir()
-       a132226: minor reformatting
-       6eb2f88: add two new functions pa_make_path_absolute()/pa_getcwd()
-       c627871: replace a pa_assert() by an pa_assert_se()
-       f59dd18: - fix suspend handling - set sink description properly - honour resample_method setting
-
-2007-08-30     Lennart Poettering
-       241ad04: port module-combine to new core
-       4d623f0: Lots of assorted minor cleanups and fixes: * s/disconnect/unlink/ at many places where it makes sense * make "start_corked" a normal pa_sink_input/pa_source_output flag instead of a seperate boolean variable * add generic process() function to pa_sink_input/pa_source_output vtable that can be used by streams to do some arbitrary processing in each rt loop iteration even the sink/source is suspended * add detach()/attach() functions to pa_sink_input/pa_source_output vtable that are called when ever the rtpoll object of the event thread changes * add suspend() functions to pa_sink_input/pa_source_output vtable which are called whenever the sink/source they are attached to suspends/resumes * add PA_SINK_INIT/PA_SOURCE_INIT/PA_SINK_INPUT_INIT/PA_SINK_OUTPUT_INIT states to state machines which is active between _new() and _put() * seperate _put() from _new() for pa_sink/pa_source * add PA_SOURCE_OUTPUT_DONT_MOVE/PA_SINK_INPUT_DONT_MOVE flags * make the pa_rtpoll object a property of pa_sink/pa_source to allow streams attached to them make use of it * fix skipping over move_silence * update module-pipe-source to make use of pa_rtpoll * add pa_sink_skip() as optimization in cases where the actualy data returned by pa_sink_render() doesn't matter
-       b552541: reorder initialization of pa_core variables
-       ca72adf: modernize and make use of a static flist for allocating idxset entries
-       821eb8e: move queue processing code into pa_thread_mq
-       687f1f1: add new function pa_memblock_ref_is_one()
-       c2e4328: fix pa_memchunk_make_writable(), make memchunk functions return the memchunk they modify
-       bfe69ce: add an assert()
-       6817987: add pa_timespec_reset()
-       747b01b: make passing a code pointer to pa_asyncmsgq_get() optional
-       ee97c42: add new PA_SINK_CAN_SUSPEND/PA_SOURCE_CAN_SUSPEND flag
-
-2007-08-26     Lennart Poettering
-       d88514c: drop check for gid < 500, since this isn't really a security improvement, re: #111
-
-2007-08-25     Lennart Poettering
-       0362350: Add option --dump-resample-methods to list available resampler implementations
-       782d5a5: make floating point speex resampler the default
-       89fcd51: enable -ffast-math for gcc
-       f82067f: lower suspend timeout to 1s
-       f4e2d23: include ffmpeg resampler in build
-       9439e81: make ffmpeg resampler actually work
-
-2007-08-24     Tanu Kaskinen
-       6687dd0: Corrected a bogus comment.
-
-2007-08-24     Lennart Poettering
-       f0dbbe9: add makefiles to speex/ and ffmpeg/ to easy compilation from emacs
-       640ae04: Copy resampler from ffmpeg into our sources
-
-2007-08-23     Lennart Poettering
-       f754a24: make speex resampler the default
-       ed4dc16: big resampler rework: support integer-only resampling, support speex resampler
-       4eb9bb0: fix a bad memory access when destructing pa_memimports
-       c1cdcfd: a couple of modernizations; parse RE sample types properly
-       c72d4c6: add a small speex wrapper so that we can include both the fp and the fixed-point resampler in the same binary
-       fdead57: build speex resampler tiwce, once for fixed point, one for floating point
-       5ff891c: add a copy of the speex resampler to our sources
-
-2007-08-22     Lennart Poettering
-       b3b382d: fix minor typo
-       9d38159: port remaining sinks to pa_rtpoll
-       1bfa180: minor cleanups
-       0ff2afd: support absolute, relative and periodic timers in pa_rtpoll
-       53b872c: port alsa driver to make use of new pa_rtpoll object
-       79d3ddd: reverse hrtimer check, add missing #include
-       b937009: add convenience functions to hook up pa_fdsem and pa_asyncmsgq to an pa_rtpoll; add pa_rtpoll_item_get_userdata(), on EINTR/EAGAIN, reset revents; automatically destory left over items
-       7490977: add missing include
-       0449966: make pa_make_power_of_two() and pa_is_power_of_two() inline functions
-       190648a: add missing #include
-       0da65cf: add message about hrtimers, and initialize pa_core::high_priority
-       0af0fb8: hide rtpoll-test from svn
-       7fca890: check pa_core::high_priority before becoming rt thread
-       b302946: add new option to pa_core stating whether we are running as high prio process
-       3546198: add check for ppoll()
-       8568f70: add rtpoll, rtclock, rtsig to Makefile
-       dc9d803: add test program for pa_rtpoll
-       78c362c: add new realtime event loop abstraction which precise time keeping by using hrtimers on Linux, if they are available
-       8972d06: add facility for managing realtime signals
-       ef2bc41: add monotonic clock abstraction pa_rtclock
-       6bfeef1: rename a few things in a macro to make name collisions less likely
-       531cc3c: make use of new public function pa_is_power_of_two()
-       b7b119a: add pa_is_power_of_two() and pa_make_power_of_two() functions
-       a0ad42a: add macro for creating static TLS objects
-       b0b06b0: add more PA_PTR_TO_XXX macros
-       fa7fc31: modernizations
-
-2007-08-20     Tanu Kaskinen
-       eaafb79: Modified the JACK sink heavily: * Made the sink realtime-safe. * To achieve the previous item, internal buffering was be added. New module   argument: buffersize. * Removed the user's need to set the JACK transport to playing state before he   could hear anything from PulseAudio. * In process of achieving the previous item, latency calculation got more   inaccurate: the reported latency is now always a multiple of the JACK   processing block size, and constant. * The JACK ports now have a running numbering in their names.
-
-2007-08-16     Lennart Poettering
-       2d292be: use realtime scheduling for ALSA and OSS driver threads
-       876e682: never stay root after startup, even if we don't have capabilites
-       5e93816: seperately get high nice level and acquire realtime sched
-       d5cbf4f: Keep CAP_SYS_NICE not only in PERMITTED but also in EFFECTIVE capset
-       843dcce: only suspend device when server is local
-       39d1e65: truncate service names if necessary, include user name in service string
-       03b0b1d: add pa_truncate_utf8() function for truncating a string and guaranteeing it stays valid UTF8 afterwards
-
-2007-08-15     Lennart Poettering
-       81cdb37: add fedora-snapshot target
-       c0d6684: fix an awful race condition when handling data requests
-       1ff4786: don't fail if no pa is srunning
-       a96c5f8: add new tool pasuspender which temporarily suspends all sinks and resumes them later again
-       33c6f9d: set CLOEXEC on more fds
-       5679de5: add new commands suspend-source, suspend-sink
-       d2d0978: add protocol support for muting sink inputs and suspending sinks/sources
-       0640615: bump protocol revision and soname of libpulse
-       b20d204: use pa_source_suspend_all/pa_sink_suspend_all for suspending all sinks/sources
-       a74e804: fix muting for sink inputs
-       3d92990: actually mute sinks when asked for i, add new function pa_sink_suspend_all
-       6f714d9: actually mute sinks when asked for i, add new function pa_sink_suspend_all
-
-2007-08-13     Lennart Poettering
-       44f91cf: load module-x11-xsmp from a /etc/xdg/autostart file, to make sure it is loaded when we have XSMP
-       80f5abf: add load-module and unload-module commands to pactl
-       8a663d4: a couple of build fixes
-
-2007-08-12     Lennart Poettering
-       1d5e9f0: deactivate module-x11-xsmp by default, due to a deadlock when pa is being started from gnome-session
-       e381dd9: 64 bit fixes and minor gcc shut ups
-       5e96d5d: yet another new glibc build fix
-       3cbcb98: build fix for newer glibc
-       e6714e1: make make distcheck pass
-       db7fdf6: make make dist work
-       55f3d34: ship full libltdl tree in SVN to make sure we can build this crack on fedora
-       b16d8e2: bump soname and stuff for fedora pre-release
-
-2007-08-11     Lennart Poettering
-       1cecd46: Resurrect ability to move streams between sinks
-       79a586d: add comments describing the context these functions are called from
-       3d81dde: modernize pa_play_memblockq() and add a new function pa_memblockq_sink_input_new() which allows creation of memblockq streams without activating them immediately
-       14d93fc: minor cleanup
-       45e4954: fix latency reporting for oss and alsa modules
-       06f2799: minor modernizations
-       57734ec: hook into move operations for resuming/suspending devices appropriately
-       44b82a1: Add 'via DMA' to sink/source description if device is accessed with mmap()
-       e71a347: restore the ability move record streams between sources
-       50e014e: use single array for storing pa_core hook lists, add sink state changed hook, drop NO_HOOKS flags for sink inputs/source outputs, listen for resume events in module-suspend-on-idle.c
-       a3cd800: port oss driver to make use of the default fragment sizes as defined in pa_core: store in the sink/source description whether mmap is used; if mmap() fails, fall back to UNIX read/write mode instead of bailing out immediately
-       b71dde0: make sure that the device access event sound is only generated once
-       447c4a5: deal with messages properly which are recieved after destruction of a stream
-       107b23d: fix module-hal when no api= argument is specified
-       c1c59b4: add proper refcounting to pa_asyncmsgq objects, to allow destruction from the dispatched callbacks
-       f7b707b: allow destruction of pa_fdsem object that are still in 'poll' state
-       e1100b5: modify alsa drivers to make use of new global fragment setting variables
-       793f750: fix default device naming and fix api selection code
-       a7a5f43: modernization
-       e2a10de: allow setting the default sample and fragment settings from the config file
-       b44ce9e: add default fragment settings variables to pa_core
-       59c9ed5: move pstream item allocation to pa_flist
-
-2007-08-10     Lennart Poettering
-       d2fed9d: make revoke/release thread safe in the native protocol
-       ff4814c: add callbacks for the revoke/release stuff, so that we can make this thing thread-safe
-       4e145b6: if no thread-mq is attached to the current thread, return an error, don't hit an assert
-       3eae903: make use of pa_thread_mq everywhere
-       b3f1a13: minor update
-       f7171e8: Wrap two pa_asyncmsq in a new pa_thread_mq object for bidirectional, lock-free communication between a main loop and a thread
-       aff77c1: update thread test to use pa_once instead of pa_once_t
-       27f75a5: Rename pa_once_t to pa_once
-       d4cb042: move pa_queue to an implementation based on pa_flist
-       ac49cc2: do not acces playback pa_messagq from main thread
-       72840ab: minor cleanliness fixes
-       357c0e4: fix closing of fds in gconf module
-       ffa1708: * drop redundant pa_core argument from module initialization functions * make pa__done() implementations optional * a couple of modernizations * wrap lt_dlsym() at a single place * allow passing of an "api" argument to the HAL module, to choose whether OSS devices or ALSA devices should be picked up * optimize fd closing a little on linux in the forked gconf helper * save a little memory in the xsmp module
-       e621071: fix minor memory leakage
-       10b135a: avoid duplicate loading of modules
-       1e5ca51: handle ACLAdded messages for previously unknown devices identically to a really new device
-       3b078b2: Avoid a race condition when one PA instance gets HAL's ACLAdded message before the previous owner instance has given up access to the device, and thus the device is blocked
-
-2007-08-09     Lennart Poettering
-       d9e44c5: Add X11 XSMP module for hooking into the X11 session manager, for being notified about X11 disconnects before they actually happen, so that we are not killed by the bloody xlibs
-       5831677: modernize
-       3dfdb21: don't assume that sink/source is already unregistered from namereg when disconnect hook is called
-       1c7b842: play ACL event sound only when gained access, not when losing it
-       b751f3a: s/login.wav/startup3.wav
-       02bf2f2: update default configuration
-       0f15574: protect memimpors with a recursive mutex to avoid deadlock when shutting down
-       e76efa9: forgot to actually add the new suspend-on-idle module source code
-       bb46da3: add new module-suspend-on-idle module which suspends sinks/sources which are idle for more than 5s (or any other configurable time). Power saving, here we come\!
-       9c89f37: if we get access to a device we don't know yet, add it to our tree instead of ignoring it
-       30ccf9a: add a couple of additional hooks for modules to use
-       ed01e1a: don't hit an assert when we cannot resume a device
-       eaddc01: by default, store esd socket in /tmp/.esd-`id -u`/socket, instead of /tmp/.esd/socket, to allow multiple simultaneous esd instances. this is only compatible with a patched esd, which however ubuntu and fedora ship now. other distros need to patch their esd as well, or may pass socket=/tmp/.esd/socket to module-protocol-esound-unix
-       33cd5e2: listen for HAL ACL events; play an event sound on hw coldplug, hotplug and ACL access
-       0c29a2f: add new function pa_scache_play_item_by_name
-       23ba125: fix bug in handling of defer events
-
-2007-08-08     Lennart Poettering
-       a69f470: modernize module-hal-detect.c and check for ALSA pcm_class != modem
-       26a0246: modernize dbus-util.c
-       e4e9a06: be more verbose when device does not support sampling parameters
-       fedca91: Remove warning when client is too slow to handle our data
-       df9522c: properly reinitialize pollfd array after resume
-       54b9f55: properly reinitialize pollfd array after resume
-       981d5fa: don't print error on socket read/write failure
-
-2007-08-07     Lennart Poettering
-       366d1d3: reinitialize sw params after resume
-       0a6f9af: add global suspend command to cli
-
-2007-08-06     Lennart Poettering
-       1f9ce59: port esound protocol to new lock-free core
-       243f2fc: minor fixes and cleanups
-       74b3b6d: fix playback status querying
-       455ff8d: fix a memory leak
-       62790cc: fix playback over native protocol
-       c306b83: initialize 'length' properly
-
-2007-08-05     Lennart Poettering
-       6775386: make sure to handle disconnecting our own connection properly
-       41d67c4: minor optimization for cacheing in of samples by using posix_fadvise
-       872951c: use posix_fadvise to avoid page faults when reading audio files from disk
-       9d1eb1b: play memchunks completely
-       bd0782e: initialize method pointers properly
-       241a9e1: follow rename of pstream_close() to pstream_unlink()
-       55e0866: typesafe casts
-       23d01bb: Modernize pstream.[ch], reintroduce defer event to make things actually work
-       36dd781: modernize play-memchunk and port it to the new core
-       34e4165: minor cleanups
-
-2007-08-04     Lennart Poettering
-       81760ad: merge compat changes from trunk
-       5ecaf31: compat with automake 1.10
-       7455571: jack driver build fix which became apparent on fedora
-
-2007-08-03     Lennart Poettering
-       95fab18: Don't stop hardware on buffer underruns. Instead continue playing to guarantee that our time function stays as linear as possible.
-       a6c44c0: Remove unnecessary snd_pcm_hwsync()
-       9a4e84a: On recommendation of Takashi Iwai prefer Master volume control over PCM and don't control Mic control
-
-2007-07-31     Lennart Poettering
-       d3eca28: rename pa_source_output_new_data::corked to start_corked to match pa_sink_input_new_data::start_corked
-       0defdfb: A lot of updates, all necessary to get the native protocol ported:
-
-2007-07-28     Lennart Poettering
-       a82505e: port module-alsa-source to new lock-free core
-       13a4327: minor cleanups
-       6afbbba: fix suspending logic
-       81aa8ea: drop data from inputs only when in running state
-       1615450: It is now allowed to call pa_sink_get_volume() from thread context
-       8aee345: Fix suspending/resuming
-       5fbb8e1: add PA_SINK_OPENED/PA_SOURCE_OPENED macros for easier checking for _IDLE or _RUNNING states
-       10cb048: restore proper mixer volume control
-       9dac60c: reload OSS volume after unsuspend
-       dd40020: bring back alsa fd list managemet, since we need it for proper mixer change notification
-       787f935: port module-alsa-sink to new lock-free core. also add mmmap'ing support while doing so.
-       c7df4ba: minor modernizations
-
-2007-07-26     Lennart Poettering
-       8e4660a: Disable memory mapping if we open the device in O_WRONLY. Unfortunately we cannot do mmap() in Linux without opening the device for reading as well.
-       c936e53: Fix channel remapping in resample; other modernizations
-       4cc0d0a: remove some log messages
-       86abfbf: remove debug messages; don't queue request messages like nothing when send file is finished
-       bbb347f: properly free memblocks when skipping over them
-       042cb09: make valgrind shut up regarding non-freed ident strings. other modernizations
-       bc17b8e: reverse order flist destruction and mempool allocation warning
-       222a6d2: Increase ref counter of sink input as long as it is included in the sink idxset
-       d80fd10: properly deref sink_input/source_output objects when removing them from a sink/source
-       58af737: Add fdsem to makefile
-       8cdde28: reverse order of printf and push to make output more readable
-       bc36932: port asyncq to make use of new fdsem object
-       6ad165c: add abstracted file descriptor based semaphore object that is lock-free in the best cases
-
-2007-07-25     Lennart Poettering
-       8836396: Store strings directly in strlst elements, other modernizations
-       98d36ef: fix some alignment issues and modernize file a little bit
-       929526d: Convert most snprintf() calls to pa_snprintf()
-       8e83838: Modernize things a little bith more
-       2a43bbf: Modernize things a little
-       2380ad9: add our own implementation for pa_snprintf() because NUL termination is apparently not guaranteed on windows and a couple of other libcs
-       9e9dc0b: Simplify implementation of pa_assert_se()
-       068f5d5: drop chunk argument from various drop() functions, since it doesn't make any sense if we want to guarantee always monotonously increasing read pointers; a couple of other fixes
-       9cc20b4: update static free list usage in asyncmsgq
-       e339d4b: update static free list usage in hashmap
-       f42e443: destruct freelists properly, by using gcc destructors. we do this only to make valgrind shut up, not because it would have any real value during runtime
-       279b1b3: wrap destructor gcc attribute in macro
-       a094923: change order of munmap and freeing of memblocks
-
-2007-07-14     Lennart Poettering
-       c76d035: Fix a couple of typos in the resampler code
-
-2007-07-13     Lennart Poettering
-       2a19c46: Fix typo in pa_memblock_release() call; s/assert/pa_assert/
-       65d54d6: s/assert/pa_assert/g; make use of static flist for memblock allocation where applicable; properly initialize length value in pa_memexport_put()
-       0e84f04: Minor clarification
-       f2c98d7: Make use of static flist for hashmap entry alllocation
-       69bfa35: Actually make the static flist static
-       3b912ac: Port module-sine to the new lock-free core
-       8442926: Reenable a couple of more modules
-       59faa5d: Remove a superfluous pa_memblock_release(); properly handle buf4 allocation
-       63c231e: Fix concurrency bug when turning memblock into a local memblock
-       481b425: Fix off-by-one in mixing code
-       ca5874d: Replace a couple of assert()s by pa_assert()s
-       ac1387d: Remove module-oss-mmap, since it is now merged into module-oss
-       a42c19e: Merge module-oss-mmap into module-oss and make suspending working properly
-       295e1c8: Make pa_sink_render_* and pa_source_post work only when in RUNNING state, to fix handling of monitor sources when their sink is suspended
-
-2007-07-12     Lennart Poettering
-       0a095f6: Properly initialize all revents on EINTR
-       1a84664: Make sure pollfd[POLLFD_ASYNCQ].revents is properly initialized on signal
-       683fc4c: fix segfault when recording with module-oss.c
-
-2007-07-10     Pierre Ossman
-       b0f692c: Make sure we link to the core to get all symbols.
-       a228a51: Solaris hides inet_ntop in nsl.
-       689fd70: Make -no-undefined actually work (and fix up error found by it).
-       405d675: Move pthreads detection as it gets confused by things in LIBS.
-
-2007-06-25     Lennart Poettering
-       eec2fbe: Port module-oss to the new lock-free core
-       6312938: remove pa_memblockq_is_writable() (because it is stupid and not used anywhere anyway, and replace all assert()s with pa_assert()s
-       a482b9f: make sure we don't free the same connection twice
-
-2007-06-24     Lennart Poettering
-       6776678: Limit silence buffer size for pa_sink_render()
-       de02c74: Track the 'missing' variable safely between the threads
-       d873731: rework the logic of pa_asyncq
-       77ebe70: Make sure the returned pa_msgobject object has a valid refcnt before returning it
-       099f3f2: Include assert.h, since we use assert() for our pa_assert() macro
-       a9fcd59: Fix length calculation in pa_silence_memblock_new() and make use of pa_assert() everywhere instead of assert()
-       fdd3ac9: Make use of dbus_watch_get_unix_fd() instead of dbus_watch_get_fd() because of deprecation of the latter
-
-2007-06-23     Lennart Poettering
-       bb3ad9d: Update OSS driver for new lock-free core
-       013a55a: remove underrun condition in pa_sinks. Instead return silence in pa_sink_render() when necessary. This is required to guarantee that the time functions in connected sink inputs stays linear
-       780f736: don't handle underrun special
-       f061636: drop silence generation from sink drivers
-       fff9081: fix a typo and some minor optimizations
-       1c9bd20: minor cleanups and optimizations
-       e24c8de: Fix minor typo
-
-2007-06-14     Lennart Poettering
-       deb523e: Port module-pipe-source to the new threaded design
-       94f6ab5: Fix another ugly typo, which made source outputs unusable
-       e279778: use pa_memblockq_push_align() instead of pa_memblockq_push() to deal with unaligned data coming from clients
-       1d7096b: Show memchunk length in debug output
-       1c62ce6: Fix a nasty typo in pa_asyncq_pop
-       572c77f: Remove anotify.[ch], since it is now entirely replaced by pa_asyncmsgq
-       5e72ac3: rework sink input/source output state machine
-       260dd1e: Make debug message more useful
-       1b99fd2: Move a few things between the threads
-       111dcd5: trivial cleanups
-
-2007-06-13     Lennart Poettering
-       be4a882: A lot of more work to get the lock-free stuff in place
-
-2007-06-13     Pierre Ossman
-       0694d2a: Make sure mixer ioctls work on /dev/dsp aswell.
-
-2007-06-11     Lennart Poettering
-       6911568: make untabify
-       590ae20: Add new untabify makefile target
-       a4fed0f: make eolspace
-       00da37f: Merge HUGE set of changes temporarily into a branch, to allow me to move them from one machine to another (lock-free and stuff)
-       6aeec56: add a new private branch
-
-2007-06-11     Pierre Ossman
-       14cbbe1: Support stat() and friends as some programs (audacity) likes to check if the device node is there first.
-
-2007-06-04     Pierre Ossman
-       13a4c52: Add support for the poorly documented SNDCTL_DSP_GETTRIGGER.
-
-2007-05-29     Lennart Poettering
-       1e12e0e: Kill spaces on EOL
-       e4d63d0: add target "eolspace" to makefil to remove trailing newlines from all source files
-
-2007-05-29     Pierre Ossman
-       5530d32: We now use gid unconditionally, so make sure it's defined.
-
-2007-05-28     Lennart Poettering
-       67cb775: build fix for systems lacking capability suppoort. (Problem identified and original patch supplied by Diego Petteno
-
-2007-05-27     Lennart Poettering
-       707def1: Bump revision of libs and package
-       918cacb: Replace AO_xxx usage with pa_atomic_xxx and friends wherever it makes sense
-       6a2dffd: unfortunately we cannot detect if a foreign thread is still running. Thus sucks. But what can we do? U. Drepper thinks our use case is invalid.
-       872018e: Minor optimization: read log level character code from array
-
-2007-05-26     Lennart Poettering
-       d949983: Add a new meta command ".ifexists" to the CLI language, to execute commands only if a specified file exists. Original patch from cjvdb. Closes #36
-
-2007-05-25     Lennart Poettering
-       4d88fcd: when called with the setid bit change euid to uid sooner to make sure that we can access our own files even when we dropped most capabilities. (Closes #21)
-       65e8761: fix suid Makefile target
-
-2007-05-23     Lennart Poettering
-       0032642: only browse for ipv4 pa servers for now. Needs better fixing which however is not trivial and probably breaks the API
-       79c94db: Fix another DoS vulnerability that has been identified by Luigi Auriemma. (Finally closes #67)
-       30c52e5: add a missing initialization that causes a crash when parsing invalid volume restoration tables (Problem identified by Luigi Auriemma, re #67)
-       33304ba: Fix a DoS with allocating overly large silence buffers. (Identified by Luigi Auriemma (re #67)
-       4a05bc9: don't allow excessively high sample rates
-       cf925b1: Fix yet another DoS vulnerability, also identified Luigi Auriemma (re #67)
-       c3b5de7: fix minor typo
-       f903395: Fix another DoS vulnerability, also identified Luigi Auriemma (closes #67)
-       407a1b6: fix a DoS vulnerability (re #67), originally identified by Luigi Auriemma
-       8e738ed: fix a few obvious copynpaste errors when handling volumes
-       0e53f93: Treat empty :0.0 identically to unset :0.0 when trying to find a PA server. (Closes #87)
-       312c326: Fix module-oss for devices that return EAGAIN when we don't expect it. (Closes #66)
-
-2007-05-22     Lennart Poettering
-       01ddb54: show socket directory when we fail to create it. (Closes #85)
-       960b5cb: Fix build and only load OSS xor ALSA modules if both are available
-       e41b91e: drop unused variable
-       16dd5f7: fix comment
-
-2007-03-07     Pierre Ossman
-       9ee3981: Add support for SNDCTL_DSP_SETTRIGGER. (closes #56)
-
-2007-03-06     Pierre Ossman
-       f6023cb: Fix some instances where we printed a string without first checking that the pointer was valid.
-       e042a90: Pulsecore should be linked into all modules.
-       0b14c02: Don't fail if hal doesn't currently contain any devices. (closes #55)
-
-2007-03-02     Pierre Ossman
-       2b82336: Handle suspended alsa devices. Based on patch by ranma. (closes #26)
-
-2007-03-01     Pierre Ossman
-       19b17ff: Revert stuff from commit 1431 that wasn't supposed to be there.
-       bb81243: Handle when ALSA tweaks our sample spec so much that the frame size changes. (closes #57).
-       6ba21d4: Add some debugging output from sample cache subsystem.
-
-2007-02-14     Pierre Ossman
-       df47c7b: Add a wrapper around close() to work around Windows' ass backwards way of handling sockets.
-       8bf7943: Allow a formatted string in the validation warning.
-       3016c75: Prefix log lines with a character indicating level.
-
-2007-02-13     Pierre Ossman
-       06211b7: Add copyright notices to all relevant files. (based on svn log)
-
-2007-02-12     Pierre Ossman
-       1d0e8e4: Make sure we get proper host identifiers.
-       de7a883: Allow specification of device number.
-
-2007-02-05     Pierre Ossman
-       f65ab1b: Don't abort config loading when the user specific cannot be loaded.
-
-2007-01-19     Pierre Ossman
-       4171f25: Make sure we report success for SNDCTL_DSP_SETDUPLEX.
-
-2007-01-04     Pierre Ossman
-       4c0a481: Report IO error on ioctl() when we're in a fatal error state.
-       c992ed9: Free stream objects when they've been invalidated.
-       19bd914: Fix error messages for failure connecting streams.
-       521daf6: Huge trailing whitespace cleanup. Let's keep the tree pure from here on, mmmkay?
-
-2006-12-04     Pierre Ossman
-       1a460ee: Fix silly copy-and-paste error. (closes #45)
-
-2006-11-24     Pierre Ossman
-       68bcbd2: Fix incorrect assert.
-
-2006-11-10     Pierre Ossman
-       7933cba: Add atomic.h as a dependency at relevant places.
-       86f4c21: Make sure we package version.h.in.
-
-2006-11-09     Pierre Ossman
-       0a37ec2: Yet again try to fix the creation of necessary directories when srcdir != builddir.
-
-2006-11-08     Pierre Ossman
-       0ef2d7e: Support reversed endian floats. (closes #28) (closes #35)
-       55c25c6: Check correct variable for return value. Closes #37.
-
-2006-11-06     Pierre Ossman
-       d4ca81f: Fix some missing line breaks.
-       8dc6214: Revert r1404 and keep it on a development branch until it is fully tested.
-       d664492: Create branch for lock free memblock implementation.
-       6ca8193: The OSS spec is unclear what should happen when a reset is requested. Let's have a nicer attitude and keep as much settings as possible.
-       9776596: Handle when threaded mainloop is freed before it is started.
-
-2006-09-26     Lennart Poettering
-       d210ebb: rework memory block management to be thread-safe and mostly lock-free.
-       5ad143b: upgrade refcnt.h to make use of our new pa_atomic_xxx() API
-       736de36: add asynchronous inter-thread notification API
-
-2006-09-20     Lennart Poettering
-       f1021b9: enable module-hal-detect in the default configuration file only if HAL support is enabled (closes #30)
-       bf83a96: rename default realtime group from "realtime" to "pulse-rt", since it is pulseaudio specific. you may still pass --with-realtime-group=realtime to configure to get the old behaviour
-
-2006-09-19     Pierre Ossman
-       71a6ceb: Revert r1398 as it broke the srcdir != builddir patch. New fix that doesn't use the $(mkdir_p) define as it isn't present on many systems.
-       534eeb1: No need to create these dirs as they're part of the source tree.
-
-2006-09-14     Pierre Ossman
-       29ab939: Stop using x86-isms and use ISO C (oversized shifts are undefined).
-       5f828c2: Fix debug output for SNDCTL_DSP_SETFRAGMENT.
-
-2006-09-11     Pierre Ossman
-       7726459: Fix up build structure for platform dependent modules. Also add implementation on Win32 for pa_once().
-       a85b3e2: Use platform independent sleep.
-       7c6088d: Fix typo.
-
-2006-09-09     Lennart Poettering
-       fc08db2: ignore flist-test in the correct dir
-       6b1794d: ignore flist-test
-       9358d28: update Makefile
-       0e96d8b: make pa_mutex_new() and pa_cond_new() succeed in all cases. Similar behaviour to pa_xmalloc().
-       3ae98db: add pa_once testing code
-       d0dcde0: rework pa_once once again, because the once function needs to have terminated before pa_once returns, regardless whether the local call executes it or another thread does.
-       6d53202: update for newer APIs: replace direct usage of libatomic_ops by usage of our own atomic.h; remove pa_once implementation; always use our pa_once implementation instead of the POSIX version
-       3426a39: implement trival pa_once API based on atomic operations
-       c89cb6a: add static initializer PA_ATOMIC_INIT()
-       b93fedd: add a test program for the free list
-       ee40a34: implement a simple lock-free free list
-
-2006-09-08     Lennart Poettering
-       bfaa358: add a tiny wrapper around libatomic_ops: pa_atomic_int_t and pa_atomit_ptr_t.
-
-2006-09-07     Lennart Poettering
-       791bbd8: don't maintain a list of allocated mempool slots, we don't use it anyway
-       1728e3a: make pa_stream thread-safe: use new refcounting system, protect access using mutexes
-       0669c99: add missing channel names (fixes a segfault when parsing invalid channel maps)
-       40f18d9: fix alsa-sink example
-
-2006-09-06     Lennart Poettering
-       40ecf86: don't hit an assert in the client if posix shm is not available
-       ead67cd: fix indentation
-       66ec460: fix a bogus debug line
-       6569199: implement a few more ioctl()s, including a subset of SNDCTL_DSP_GETOPTR. Just enough to make JavaSound work.
-
-2006-09-04     Lennart Poettering
-       e00ba02: remove yet another occurence of pthread_yield() by pa_thread_yield()
-       6bbfb43: add accessor functions for the userdata attached to a pa_thread object
-       3be920d: fix pa_thread_is_running() for foreign threads; fix a memory leak for foreign threads
-       813e95f: port the threaded mainloop to our new abstract mutex/thread API
-       8e7c2a3: make pa_thread_self() return a sensible pointer on foreign threads
-
-2006-09-02     Lennart Poettering
-       6db6c83: add missing g_type_init()
-       2536ba9: rework handling of srcdir != builddir (patch from Flameeyes)
-       e504e80: include PTRHEAD_LIBS in pkg-config file (patch from Flameeyes)
-       b01fabf: update acx_pthread.m4
-       6528b6b: allow building when srcdir != builddir (patch from Flameeyes)
-       a00c3cb: fix a few autoconf warnings (patch by Flameeyes)
-       11b6c45: fix esdcompat for non-gnu systems
-       161c2c0: make esdcompat executable
-       5fa9cdb: Merge FreeBSD compatibility patch (from Flameeyes)
-
-2006-09-01     Pierre Ossman
-       647ef18: Fix call to pa_mutex_new().
-       f84c65e: Add pthread_once() equivalent support.
-       3571bf1: Thread implementation for Win32.
-
-2006-09-01     Lennart Poettering
-       97202d1: fix a race condition with stream connection vs. latency measuremtn (found by theBear)
-
-2006-08-31     Pierre Ossman
-       6e3de3d: Make sure libatomic_ops.a isn't included in win32 builds as libtool doesn't like static libs in dlls. Everything is in the headers anyway, so we do not need it.
-       6e9706b: Also wrap yield functionality so that it can be platform independent.
-
-2006-08-31     Lennart Poettering
-       0f6098b: work around bug in firefox which apparently misuses access() as NULL pointer test. Original patch by "alon". (Closes #27)
-       aee4a37: define AO_REQUIRE_CAS in the Makefile instead of each source file, effectively reversing r1348
-       7ce39d3: update todo
-
-2006-08-30     Lennart Poettering
-       2f6cc4f: fix handling of "running" variable
-
-2006-08-30     Pierre Ossman
-       ad0535b: Add AO_REQUIRE_CAS as we do.
-       a6b99d5: Make sure the libatomic_ops lib is included.
-       c4e47c6: Remove check for libatomic_ops library as some systems have no (zero, nada) symbols in it.
-       078420a: We need to have a callback when changing volume or we might deadlock.
-
-2006-08-29     Lennart Poettering
-       b2c341f: add a threading primitive API
-       5264d23: make pa_mempool_stat thread-safe/lock-free
-       327e0cd: modify memory block reference counting to use the new reference counting API
-       9948cb0: add lock-free reference counting macros, based on libatomic-ops
-       91d8025: add libatomic-ops to hard dependencies
-
-2006-08-28     Lennart Poettering
-       a633944: fix an misdesigned assert()
-
-2006-08-28     Pierre Ossman
-       5ecbd9e: Add PulseAudio logo to tree.
-       cd47673: update todo
-
-2006-08-27     Lennart Poettering
-       1ed3347: increase operation timeout
-
-2006-08-26     Lennart Poettering
-       bc87a58: bump version and sonames
-       b8ea488: fix module-combine when used on top of a tunnel sink
-
-2006-08-25     Lennart Poettering
-       93e005a: update module-tunnel to latest protocol
-       8ead68f: activate HAL in the default config
-
-2006-08-24     Pierre Ossman
-       aec3888: Add missing header.
-
-2006-08-23     Lennart Poettering
-       8f5b86b: fix handling of "mtu" module argument (patch by "theBear")
-
-2006-08-23     Pierre Ossman
-       2575b44: fix typo
-       79c4a68: Make the recording a bit more chunky so that we can fit in the pool and have efficient blocks.
-
-2006-08-22     Pierre Ossman
-       b27ffbe: Remove silence generation in solaris module.
-       d194604: Remove silence generation in waveout module.
-       095f357: Proceed with connect even when no cookie is loaded. Allows you to connect to server which do not require a cookie under all circumstances.
-       306aea7: Fix memory leak in waveout module.
-       0249651: Log when there is a problem opening the waveOut/waveIn device.
-       7bf2540: Fall back to creating a "normal" memory pool if unable to get a shared one.
-       26bfce6: Improve error messages a bit.
-       cf7b401: Fix up portability of memory pool handling a bit.
-       10bbc4b: Fix detection of shared memory support and proper fallback.
-       568c8ea: Fix typo.
-       eeabf63: Add missing header.
-       b5ef414: Fix call to pa_memblock_new().
-       d964459: Fix detection of page size for non-POSIX systems.
-       7bc7110: Fix missing header for timeval helpers.
-       1c320fe: Fix calls to pa_memblock_new().
-       6e3d8af: Add header for pa_cstrerror().
-       8a16c73: Fix call to pa_pstream_send_tagstruct().
-       25c0640: Add an ifdef for when we do not have creds.
-
-2006-08-22     Lennart Poettering
-       fef4a20: update todo
-       22d8e0e: fix typo
-
-2006-08-21     Lennart Poettering
-       26201b2: fix pactl output (sink drivers and names where switched)
-
-2006-08-19     Lennart Poettering
-       3d32b96: update todo
-       3dbc4ae: restore the sink/source for a client in addition to the playback volume. This changes the file format of the table file. To avoid parse errors ~/.pulse/volume.table has been renamed to ~/.pulse/volume-restore.table
-       bffde5d: If a client leaves the sink/source for a stream unspecified by passing NULL as sink/source name sink/source we should pass NULL to pa_sink_input_new()/pa_source_output_new() as too. This allows hooks to change the sink/source device only if it is left unspecified by the client
-       bf62e77: fix a bad memory access
-       ce11b1f: update todo
-       c0b3e8b: when transferring large memory chunks of a pa_pstream, split them up
-       79b2628: update todo
-       84d1d3e: update todo
-       b642325: check for posix_memalign and friends
-       3e0f00f: if MAP_ANONYMOUS is not supported use posix_memalign if possible to allocate the memory pool
-       d50c56a: update todo
-       c6ca9a8: print per-type memory block statistics on "stat"
-       57f0b08: generate per-type memory block statistics
-       16ff83f: update todo
-       af87c7d: rework the resample to allocate temporary memory with pa_memblock_new() instead of pa_xrealloc()
-       521d15b: fix a memory leak
-       1b7fff3: update todo
-       47c7a14: add --disable-shm command line option to the daemon
-       a8519d5: add "disable-shm=" to default daemon configuration file
-       dbc658d: add new "disable-shm" server config option
-       c9b6d55: add default "disable-shm" option to client.conf
-       d785b8f: add new "disable-shm" option to client.conf
-       206ac6f: allow importing of external shm data blocks unconditionally, even when local SHM support is disabled
-       046bdd9: deal properly with pa_mempool_new() failing
-       8c9bdb8: fix allocation of anonymous memory
-       c2db5f8: fix a memory leak
-
-2006-08-18     Lennart Poettering
-       c979b87: update todo
-       40875d6: enable SHM support on the client side only if both the client and the server run as the same user and the server supports it
-       e33abc3: activate SHM support on the server side only when new client supports it and when client and server have the same UID.
-       c313b23: one s/0/NULL/
-       7ac7909: remove export/import objects when SHM is disable for a pa_pstream object
-       fd3fe96: add new function pa_mempool_is_shared() to test whether a memory pool is suitable for SHM data transfers
-       7e01b1c: hide memblock-test
-       e385d93: remove all occurences of
-       1bc62d5: rework logging subsystem, to implicitly include __FILE__ in pa_log() calls. In addition we now record the line numbers and function names of pa_log calls. However, those are only shown If $PULSE_LOG_META is set.
-       666eca3: update todo
-       8ebef4d: look for shm_open in -lrt
-       35caf0c: add new test memblock-test for testing SHM import/export
-       c3fc2ea: update tests for new memory manager
-       0e436a6: Rework memory management to allow shared memory data transfer. The central idea is to allocate all audio memory blocks from a per-process memory pool which is available as read-only SHM segment to other local processes. Then, instead of writing the actual audio data to the socket just write references to this shared memory pool.
-       ff48681: add abstracted shared memory API
-       20d0823: fix a bad type cast
-       dfa17b9: cleanup hashmap.[ch] a little: use hash/compare func prototypes defined in idxset.h, add pa_hashmpa_{get,steal}_first
-       8be0cf6: cleanup idxset.[ch] a little: define proper types for the hash/compare funcs, do ptr->int/int->ptr conversions with clean macros
-
-2006-08-17     Lennart Poettering
-       c3df1ce: fix a PA_LLIST_HEAD_INIT invocation
-       a847f74: add missing #include
-       d890660: modify pa_bytes_snprint() to return the string we just wrote to. This should be binary compat with older versions which returned void
-       99db067: make PA_LLIST_HEAD_INIT thread safe
-
-2006-08-15     Lennart Poettering
-       1c3bfc4: use the description field of sinks/sources to name the zeroconf services, instead of the logical name
-
-2006-08-14     Pierre Ossman
-       6c39af7: update todo
-
-2006-08-13     Lennart Poettering
-       5d8d916: update todo
-       2bf4653: extend module-rescue-streams to move also source outputs when a source dies
-       3334814: fix a segfault when registering a service with avahi fails
-       cdb173f: create rtp source output on correct source
-       d182a0b: minor optimization
-       a75e1ed: implement hook_source_ouput_new. For this I modified the pa_source_output_new constructor to take a struct similar to what I already did for pa_sink_input_new()
-       e0f7e86: split a validity check into two
-       79cb80c: implement hook_source_disconnect
-       8f91b1f: define new hooks: hook_source_output_new, hook_source_disconnect
-       a09a49e: update todo
-       a7b9a7d: Load module-rescue-streams by default
-       dd87061: implement new module "module-rescue-streams" which moves sink inputs away when their sink is removed.
-       8180832: properly implement a pa_sink_disconnect() hook
-       87e64d5: Clean up module description a little
-       abbabd8: ignore if we recieved a memory block for an invalid stream, since this might happen unwillingly due to the asychnronous nature of the protocol
-       72cf211: remove pa_sink_input::variable_rate field since it has been folded into pa_sink_input::flags
-       3beef50: hide hook-list-test
-       b37ad1f: modify module-volume-restore to change the initial volume of a sink input from a hook instead of an asyncronous subscription event.
-       a621d90: allow hooking into the process of creating playback streams. To implement this I modified the pa_sink_input_new() signature to take a pa_sink_input_new_data structure instead of direct arguments.
-       b5cbea9: fix bad printf()
-       db3f561: rework hook list stuff once again: change the callback prototype to recieve three data pointers: one to the data for the hook, once for the slot and once for the call
-       281125c: rework hook list stuff again, and replace macros with real functins. We loose type safety but things are much cleaner now
-
-2006-08-12     Lennart Poettering
-       2622b0c: update hook list test
-       82a913d: reall add type safe hook list
-       80d73dd: implement typeafe hook chain
-       7f70ca3: extend maximum sink/source name length, because HAL UDIs can get ridiculously long
-       17964dd: update todo
-       02e083c: test if sink->monitor_source is set before making use of it
-       dbe6bdd: make use of pa_sink_used_by()/pa_source_used_by() wherever applicable
-       b5207fc: add pa_sink_used_by()/pa_source_used_by()
-       b45c392: categorize todo file
-       28f86ea: name the sink/source after the device file, just like we already do for the non-mmaped driver
-       bf79e97: generate default sink/source names from the device files they belong to
-       0050176: update todo
-       4c9c426: handle hot-remeving of OSS devices properly
-       3cfed30: print the device capabilities after opening the device
-       fbeeb8b: when the requested sample format is not available for OSS devices, print a nice warning and take what we can get instead
-       0547b0f: there's no need to queue subscription events if noone is listening, hence don't do it!
-       c86890d: * only load an OSS driver for the first device of a sound card, similar to what is done for ALSA. * fix a mem leak
-       7fa0744: fix a segfault in module-oss
-       2d70271: fix pa_gettimeofday() return value testing
-       adfa76c: update todo
-       365ceec: update todo
-       3aba099: clean up event generation a little: suppress unnecessary events and generate new ones on owner change
-       47d009a: rework subscription code: try to drop redundant queued events
-       f8e5f47: fix a compiler warning
-       e9d9356: add new macro PA_LLIST_INSERT_AFTER
-       1e12c75: update todo
-       8da9b94: allow setting the null sink description by a module parameter
-
-2006-08-12     Shahms E. King
-       bb96156: increase module argument buffer size to prevent truncating names
-
-2006-08-11     Lennart Poettering
-       bfa6604: don't set the sink/source descriptions manually, use the new functions pa_{sink,source}_set_description() instead
-       af1b031: comment which values in pa_{sink,source,sink_input,source_output} structures may be NULL
-       c90dd53: * introduce new functions pa_sink_set_description() and pa_source_set_description() for changing the description of a sink/source * allow sinks without monitor sources attached
-       0aebc03: update todo
-       bfff23d: shorten sink/source device descriptions a little
-       1d7b8e1: use the HAL UDI for naming input/output devices
-       539612a: do not export name validity checking routes and apply them only to sink/source names, not sample names
-       e1316f5: fix bad memory access and a leak when detructing ALSA fd lists
-       576c4dd: rework name register a litle to only allow "valid" names.
-       bf854c4: Build HAL support only when either OSS or ALSA is available
-       dcd3acc: remove OSS specific code from module-hal-detect if HAVE_OSS is not set. Same for ALSA
-       7a4e1c9: ALSA: handle write()/read() errors properly by unloading the driver module. This should fix problems when removing USB audio device while pulseaudio is running.
-       b0b968d: change order of the ALSA event dispatch code to make sure that the code survives if the event dispatcher frees the ALSA client
-       59f1a67: use the copied udi string as hash key for the device table, because the temporary one is freed when the function exits
-
-2006-08-08     Shahms E. King
-       7ee7a23: add HAL support for OSS devices and capability changes
-
-2006-08-07     Shahms E. King
-       b382df5: clean up hal patch to use pa_xnew and timeval compatibility wrappers
-
-2006-08-07     Lennart Poettering
-       5d8ccfd: try to reduce volume updates in the ALSA sinks/sources: only touch the shadowed hw volme if necessary
-
-2006-08-06     Lennart Poettering
-       d953870: * add SVN $Id$ tags * add a const
-       050b739: merge HAL support from Shams E. King
-
-2006-08-03     Lennart Poettering
-       f74e5ef: update todo
-       ad95c96: implement "pactl move-source-output"
-       e52436b: implement pa_context_move_source_output_by_{name,index}()
-       5fdc39d: wrap pa_source_output_move_to() in the native protocol
-       1c45061: add new CLI command move-source-output as wrapper around pa_source_output_move_to()
-       2d00de5: Implement pa_source_input_move_to() for moving record streams between sources
-       ddc69fc: - don't call pa_sink_notify in pa_sink_input_new() because the virtual methods are not yet initialized at this time - some minor cleanups
-
-2006-08-01     Lennart Poettering
-       7f93d08: bump API and protocol version. Return PA_ERR_NOTSUPPORTED if pa_context_move_sink_input_by_*()is called for servers that don't support it
-
-2006-07-31     Lennart Poettering
-       bc30e2d: add new "move-sink-input" command to pactl
-       bb9b087: wrap PA_COMMAND_MOVE_SINK_INPUT for libpulse
-       785477b: add new native protocol function for moving sink inputs between sinks
-       304fcbb: add new commands opcode for moving sink inputs and source outputs
-       ccf67d2: deal properly with recursive module unloading
-       e2e94ca: fix bad memory access if a non-existing entry shall be removed from a pa_idxset by index
-
-2006-07-29     Lennart Poettering
-       d7ee1bc: fix module-gconf initialization
-       646deea: don't hit an assetr if there are operations outstanding when the pa_context is destroyed
-       a7cf5e0: fix two typos (pierre, have you been sleeping? next time please the comments wrong but the code right, not the other way round! ;-))
-       a1e8b09: add new CLI function "move-sink-input" as wrapper around pa_sink_input_move_to()
-       5e92950: * implement "hot" moving of playback streams between sinks (pa_sink_input_move_to()). * optimize the adjusting of the volume in pa_sink_input_peek() a little
-       4dd3b31: free the memblockq if we decide not to play it
-       f15b4c7: if the memblockq is empty, return -1 in all cases
-       9310a2e: fix calculation of pa_usec_to_bytes, to make sure that it never returns fractions of a frame size
-       b325e07: handle EOF correctly if it is read before the stream was created
-
-2006-07-28     Lennart Poettering
-       d1db037: for the playing field of pa_timing_info use pa_sink_input::state == PA_SINK_INPUT_RUNNING. This means that this variable will now refer to the current state and not to the expected future state, which is probably more what clients expect.
-       f1c4611: fold the seperate variable pa_sink_input::playing into pa_sink_input::state as state PA_SINK_INPUT_DRAINED. The following mappings hold:
-       12aa842: introduce pa_play_memblockq() which creates a playback stream and passes the data from the memblockq to it. after that is done, frees the memblockq
-
-2006-07-27     Lennart Poettering
-       ecd4655: update todo
-       c21f88c: load module-gconf in default install
-       0dea223: introduce three virtual sink/source names: @DEFAULT_SINK@, @DEFAULT_SOURCE@, @DEFAULT_MONITOR@. Especially the latter is useful for connecting to the monitor source of the default sink.
-       fec7e9b: if possible do not unload already loaded modules when the gconf settings change. instead try to reuse already loaded modules as much as possible
-       87d4f0b: because gconf doesn't provide real transactions we emulate our own with a "locked" gconf key
-       6afb61e: remove superfluous code
-
-2006-07-26     Lennart Poettering
-       358e577: remove two superfluous lines
-       0d7be31: mainloop fixes: when disabling time events when dispatching them, make sure to adjust the cache time event and enabled time event counters
-       b2ad9a9: add some protection that the gconf helper process will be killed when the daemon process dies. make sure the gconf helper process doesn't keep open file descriptors belonging to the daemon; if gconf helper path
-       f5d29ac: add missing configure.ac checks for module-gconf
-       cc1d821: add new module "module-gconf" which reads configuration information from gconf. this will be used in my upcoming paconf module
-
-2006-07-25     Lennart Poettering
-       61ce8bb: add new command line option --no-cpu-limit. This is useful when running PulseAudio in valgrind's massif or callgrind tools
-       563fab9: Results of profiling PulseAudio with valgrind's callgrind module: rework the default event loop implementation to use PA_LLIST_xxx instead of pa_idxset; don't generate weakeup events if we aren't in STATE_POLLING; minimize dispatching of io events; cache next time event instead of traversing the list of time events on every event loop iteration; other optimizations
-       216bdd4: split a few asserts
-       32444f0: split a few assert()s
-       c41d749: add a few more g_assert()s and change all assert()s to g_assert()s
-
-2006-07-24     Lennart Poettering
-       675bf2f: add autogen.sh for jhbuild (for you, elmarco!)
-       0f8f5bc: bump version and sonames
-
-2006-07-23     Lennart Poettering
-       3aac893: add massif target to Makefile
-       c85351b: as a result of memory profiling with valgrind/massif: decrease default hash table size from 1024 to 127. the hashtables are sparsely filled most of the time, so there is no point in allocating to much memory by default.
-       95eee87: update todo
-
-2006-07-22     Lennart Poettering
-       07a1c45: fix horribly broken glib timeout event handling
-
-2006-07-21     Pierre Ossman
-       b345af2: Use proper @libdir@ in pc.in files to handle x86_64 machines.
-
-2006-07-21     Lennart Poettering
-       a84a2f9: raise the default value for RLIMIT_NOFILE to 200 since 25 is apparently too small if every single GNOME apps thinks it needs to create its own server connection!
-
-2006-07-20     Pierre Ossman
-       09e01af: Get ACL:s to work on Win32.
-       4a59581: Fix incorrect call to nonexistant pa_log_warning().
-       0762af2: Only warn when running as root and not --system.
-       f3d4924: Centralise check if we're running as root.
-       57d8a31: Move check for SUID into the caps functions.
-       8d2dc9c: Handle user switch in a more platform independent manner.
-       b12f29d: Make sure parse_rlimit is only used when rlimits are supported.
-       246e30a: Add missing header.
-       a3e7595: Make -1 mean "current group/user" so that some platform dependent calls can be centralised.
-       7ba93eb: Protect platform dependent headers with ifdefs.
-       2ad6938: Remove unneeded headers.
-
-2006-07-20     Lennart Poettering
-       40b4089: remove access group setting from default client.conf
-       55e97b8: fix a few @@ replacments
-       6ad1f33: even more FreeBSD portability (thanks Flameeyes, again!)
-       90b521d: add missing #ifdef HAVE_CREDS (thanks, Flameeyes)
-       2683f25: some more FreeBSD compat from Flameeyes
-       b3d3d16: bump release and sonames
-       da1ec27: remove configurable client access group, since can never work on Linux anway, since SCM_CREDENTAILS doesn't allow sending supplementary GIDs
-       dd5fd8d: update todo
-       44beeaa: implement "auth-ip-acl=" in the native and esound protocols
-       db75f68: actually ship src/pulsecore/creds.h in the tarballs
-       30ada90: add IP address ACL subsystem
-       2409f1a: add support to set resource limits for the daemon and set some of them to some sane values
-       0ff247d: undo r1111 in some way: include sys/socket.h and sys/un.h but wrap it in #ifdef HAVE_xxx_H. This should be safe because config.h should be the first included header in all .c files and creds.h is never included by any external tools
-
-2006-07-19     Lennart Poettering
-       703bb49: add a few comments
-       a382492: * add new function pa_check_in_group() * abstract credential APis a little bit by introducing HAVE_CREDS and a structure pa_creds * rework credential authentication * fix module-volume-restore and friends for usage in system-wide instance * remove loopback= argument from moulde-*-protocol-tcp since it is a superset of listen= and usually a bad idea anyway since the user shouldn't load the TCP module at all if he doesn't want remote access * rename a few variables in the jack modules to make sure they don't conflict with symbols defined in the system headers * add server address for system-wide daemons to the default server list for the the client libs * update todo
-       340803b: use access group dedclared in ~/.pulse/client.conf instead of PA_ACCESS_GROUP
-       2b31a90: update @@ tokens according to recent Makefile.am change
-       45a9a8b: fix sed scripts according to #define renames
-       9c87a65: * add new --system command line parameter to the daemon for running PulseAudio as system-wide instance * add PA_ prefixes to all global #defines * modify auth-by-creds: define a new group "pulse-access" which is used for authentication * add proper privilige dropping when running in --system mode * create runtime directory once on startup and not by each module seperately
-
-2006-07-18     Lennart Poettering
-       9db7068: remove glib 1.2 adapter. It started to bitrot and wasn't used by anything anyway.
-       d7cdaf2: add two more \since
-       f4ec7d4: fix module-detect on FreeBSD (patch from Diego "Flameeyes" Pettenó)
-       2c2abbb: turn the glib adapter into a single GSource instead of creating a bunch of seperate GSources for each event
-       ddd5acf: define proper typdefs for callback prototypes
-
-2006-07-17     Lennart Poettering
-       64d87ac: change licensing blurb form "Library GPL" to "Lesser GPL" on request of Loic Minier. Effectively this means using the same license blurb like in all other source files.
-
-2006-07-17     Pierre Ossman
-       f5afb7b: Forgot to protect one access to with_creds with an ifdef.
-       4b352e5: Restore SIGPIPE warning when the platform doesn't have MSG_NOSIGNAL.
-
-2006-07-16     Lennart Poettering
-       ba31adc: make pulseaudio compile again on FreeBSD (patch from Diego "Flameeyes" Petteno)
-       e45b1dc: todo
-       9ced7f6: show summary after "configure" has run (closes: #22)
-       3b2843d: show value of PA_SINK_HARDWARE/PA_SOURCE_HARDWARE in pactl
-       b91dd23: set is_hardware flag for a few hw plugins
-       494fa68: add new PA_SOURCE_HARDWARE/PA_SINK_HARDWARE flag
-       6e38949: add a new boolean variable is_hardware to pa_sink/pa_source to denote wether the specific device is a hardware device or virtual/software
-
-2006-07-15     Lennart Poettering
-       a537b01: update todo
-
-2006-07-14     Lennart Poettering
-       55a8db8: improve latency calculation of NULL sink
-       d43bcb3: update todo
-       b8f9ae0: remove checking for SIGPIPE blocking from client code. Because we use send(,,MSG_NOSIGNAL) for most socket writes now the reason for SIGPIPE blocking is no longer give. We keep this check for the server side however, because pipes create SIGPIPE too but cannot be used with MSG_NOSIGNAL. Some modules use pipes for internal and external communication.
-       fc544a6: don't send SCM_CREDENTIALS on every sendmsg(), instead do it only on handshake
-       3eeecdc: don't set MSG_NOSIGNAL for recvmsg(), since it doesn't make sense there
-       860be2e: try to use send(,,MSG_NOSIGNAL) instead of write() wherever possible (which will allow us to drop the SIGPIPE check). Cache the results of the last write()/send() to make sure that we do not issue more than necessary system calls.
-       350a253: remove vi'ism
-       dfd864a: update todo
-       883ce83: add new test get-binary-name-test for testing pa_get_binary_name()
-       a87c43d: Don't call pa_path_get_filename() anymore since it is implicitly called by pa_get_binary_name() anyway
-       881d4dd: * fall back to prctl(PR_GET_NAME) in pa_get_binary_name() if readlink() fails * call pa_path_get_filename() in all cases before returning in pa_get_binary_name(). We already did so on Win32, but didn't on Linux.
-
-2006-07-14     Pierre Ossman
-       82e680c: Make sure the win32 default conf gets shipped.
-
-2006-07-13     Lennart Poettering
-       5529604: support time events with NULL timevals which are OK in avahi, but not in PA. This makes padevchooser actually work on top of the new avahi browsing stuff
-       7484b62: update todo
-       ceb1b6f: remove avahi/howl item from todo list
-       3f0f4f5: remove howl-wrap.[ch]
-       6f24a9d: remove HOWL snippet from configure script
-       1fd18d6: * add proper error handling to pabrowse.c * properly destroy pa_browser object on exit
-       d989c69: add browser.h to doxygen docs
-       76f93a0: * port libpulse-browse to use the native avahi API instead of the HOWL cruft * add new function pa_browser_set_error_callback() * add doxygen docs to browser.h
-       3a81620: update module-zeroconf-publish to make use of the native AVAHI API, instead of HOWL
-       10f7a64: make sure gccmacro.h and cdecl.h may be included at the same time as those headers from the avahi project
-       8162164: check for avahi in configure.ac
-
-2006-07-10     Lennart Poettering
-       3428f03: mark HAL for shams king
-
-2006-07-08     Lennart Poettering
-       9c96bdc: * remove doc/ directory * move doc/todo to root dir
-       f87f3c8: unhide a few files
-
-2006-07-08     Pierre Ossman
-       e12ead7: Remove some unused m4 files.
-       eb4abb2: Fix typo.
-
-2006-07-07     Lennart Poettering
-       e16cdb5: remove all docs from tarball since they are now available on pulseaudio.org
-       9a778bd: s/avahi/pulseuaiod/
-       7fe5e5f: replace remaining ML refs to polyp
-       81eb4a2: fix mailman URL
-       9e45991: update readme for 0.9.2
-
-2006-06-30     Pierre Ossman
-       8b0d134: Make sure we print the file name we actually use.
-
-2006-06-21     Lennart Poettering
-       18b8b84: increase the maxium number of concurrent esd and native connections
-       045b05c: include config.h in browser.c (closes #20)
-       1710041: only interpolate when the last timing info told us the stream is indeed playing
-
-2006-06-20     Lennart Poettering
-       74e958c: bump version number
-       84907e6: fix segfault when module-alsa-source fails to load
-
-2006-06-20     Pierre Ossman
-       320bedb: Fix handling of the io flags in duplex mode.
-       1040b69: Warn when applications use SNDCTL_DSP_GET[IO]PTR even when they shouldn't.
-       07edf59: Make fix_metrics() exit early so that it doesn't spam the output needlessly.
-       1342999: Make sure we do not use pthread_yield() on platforms that do not have them.
-       3b28358: Check for pthread_yield() as not all platforms have that.
-       6ca46f4: Make interpol-test build on Win32 and non-pthread systems.
-       3ff68bd: Fix the final few occurences of polyp.
-
-2006-06-19     Lennart Poettering
-       230f97a: s/POLYP/PULSE/g
-       6654e98: update docs
-       3cf1621: * more s/pulseaudio/PulseAudio/ replacements * name the per-user dir ~/.pulse (instead of .pulseaudio), just like /etc/pulse/
-       fe1dadb: update references to the pkg-config files in the docs
-       0d97ac6: name the pkg-config files after the library names
-       10b5e99: replace a few remaining uppercase "Polypaudio" occurences with "PulseAudio"
-       955e33d: hide pulseadudio binary from SVN
-       25f7969: rename polypaudio.h to pulseaudio.h
-       f44ba09: big s/polyp/pulse/g
-       dd21f11: unhide padsp
-       f6d1154: hide interpol-test
-       40494c3: * rework latency interpolation to make it smoother * increase latency update interval to 100ms
-       6eabab6: minor cleanups
-       9f59b4e: add new test "interpol-test"
-
-2006-06-19     Pierre Ossman
-       c6d4cc0: Handle clients that just want to set fragment size (and not count).
-
-2006-06-18     Lennart Poettering
-       bd432f0: * add new argument 'exit_on_eof' to module-cli and make use of it if "-C" is passed to the daemon
-
-2006-06-17     Lennart Poettering
-       5e1127a: * implement volume adjusting and mixing for S16RE * some optimizations
-       e26bd47: * make hw param settings easier to debug by splitting up long if * actually set the sample rate * disable resampling done by ALSA
-
-2006-06-16     Pierre Ossman
-       8485a47: /dev/dsp should default to U8, not mulaw.
-       e66b0e6: Creating a stream might take some time, so check that it's in the right state before transferring data.
-       6684264: Record support.
-
-2006-06-16     Lennart Poettering
-       a529b28: if S16NE is not supported, fall back to S16RE. If FLOAT32NE is not supported, fall back to FLOAT32NE. If still nothing is supported, try everything else in order
-
-2006-06-15     Lennart Poettering
-       8e37d68: update todo
-
-2006-06-15     Pierre Ossman
-       3fa491d: Make debug output in padsp a bit less verbose. Specifying -d twice will give original output.
-
-2006-06-13     Pierre Ossman
-       dd0f80e: Make a copy of the va_list as vsnprintf() is free to change it.
-       0f13c43: Catch the access() system call as some applications do this to test if they can open /dev/dsp.
-       b5a8815: Make sure our inet_ntop() implementation gets linked into the new users.
-       9288479: Tweak the printing of client connections a bit so that it's more apparent what and who it is that's connecting.
-       7582f74: Handle pretty printing of IPv6 socket names.
-
-2006-06-12     Pierre Ossman
-       519aa9b: Use AM_ICONV to determine what needs to be done for iconv support. (closes #19)
-       c32176b: Fix AC_CHECK_DEFINE so that we can look in different files for the same define.
-       7c770e2: Also look in winsock2.h for INADDR_NONE. (solves #18)
-       15a0b28: Properly escape the m4 macros and make the code a bit more readable.
-
-2006-06-11     Pierre Ossman
-       75ac45b: Add all the preopen libs to the polypaudio binary's dependency list as they aren't automatically detected. (Closes #17)
-
-2006-06-03     Lennart Poettering
-       d8dafa0: rework ioline EOF handling to actually work properly
-       2fa08ba: fix pa_xstrndup() implementation to not access potentially uninitialized memory
-
-2006-06-02     Lennart Poettering
-       16a275a: actually build cpulimit support if SIGXCPU is available
-       441362a: fix ugly access-after-free bug when doing asyncronous NS lookups
-       8b0e6f6: update docs for 0.9.1
-       e092336: bump version and soname
-       7b961bd: Add new configure options to disable/enable specific modules at configure time. Original patch by ed@catmur.co.uk. (Closes #16)
-
-2006-06-01     Pierre Ossman
-       02bfa3c: update todo
-       7a52eab: Try the ltdl mangled name ourselves so that .la files for modules are optional.
-
-2006-05-31     Lennart Poettering
-       8ca9568: remove superfluous prefixes from service names
-       ac7213d: update TODO
-       79b6c31: decrease maximum allowed sample frequency for ALSA devices to 5%, since 48000 would otherwise match with 44100
-
-2006-05-30     Lennart Poettering
-       9f2026d: downgrade a log message
-       64fa5b8: * alsa-sink: if "PCM" is not found as mixer track name, fallback to "Master" * alsa-source: if "Capture" is not found as mixer track name, fallback to "Mic"
-       bb820db: * if an ALSA device doesn't support the channel count requested, use what ALSA suggests instead * if an ALSA device doesn't support the sampling freq requested, use what ALSA suggests and resample if this deviates more than 10% from what we requested * fix segfault freeing an unitialized mixer_fdl field
-       821a49b: update todo
-       73eedcb: load alsa modules with device string hw:0 instead of hw:0,0
-       6140619: fix amd64 portability issues
-
-2006-05-29     Lennart Poettering
-       21cb51b: merge patch from Igor Zubkov, fixing linking of the HOWL modules
-       ce04f0b: update svn:ignore to reflect the esdcompat name change
-       632f5b4: drop the .sh suffix from esdcompat
-
-2006-05-26     Lennart Poettering
-       3a868be: update README for 0.9.0
-       f5a8885: disable padsp for the polypaudio daemon itself by defining the __padsp_disabled__ symbol
-
-2006-05-26     Pierre Ossman
-       c8e9fa3: update todo
-       12dc4c2: Fix the fix_metrics() function so that we don't get a tiny buffer by default.
-       7d90e3a: Fix typos.
-       6aeaaf9: Returned buffer attr is const.
-       d142408: Explicitly check version number when determining which fields are in a stream create response.
-
-2006-05-25     Lennart Poettering
-       099304a: update todo
-       7d97534: * add new API function pa_stream_get_buffer_attr(). * modify pacat.c to make use of that new API * extend protocol to allow transfer of the necessary information * update protocol version accordingly
-       f3b7259: really fix a superfluous warning when building padsp.c
-       4413b89: * split pa_cstrerror() into its own file polypcore/core-error.[ch] * fix building of padsp * remove a warning when compiling padsp.c
-       f8aa55c: move modules to ${libdir}/polypaudio-${PA_MAJORMINOR}/modules/
-       fc8a2c4: add item about moving pa_cstrerror() to TODO
-       e07b262: update todo
-       ae80ab3: read stream and client name from $PADSP_STREAM_NAME resp. $PADSP_CLIENT_NAME, if available
-       2bbd7ba: add support to disable emulation of /dev/dsp,/dev/mixer,/dev/sndstat selectively by either passing an environment variable or by defining a symbol __padsp_disable__ in the process
-       2bb05ea: fix evil, evil typo that cause all gtk2 based apps to crash
-       59d00e2: * issue volume updates syncrhonously * correct channel order of OSS volumes (swap left,right)
-       0fb63e7: update TODO
-
-2006-05-25     Pierre Ossman
-       b754d50: Wrong prefix used in the padsp script.
-       d39740f: We only need the so for libpolypdsp.
-       ea7995b: Fix padsp script so that it accepts parameters, setting relevant environment variables as needed.
-       0387b30: Use only the basename of libpolypdsp.so so that it will work on multi-arch systems.
-       1799b7a: Move libpolypdsp in the makefile to avoid the libtool bug where it must come after any things it depends on.
-
-2006-05-24     Pierre Ossman
-       6a7172e: padsp needs dlsym & co so make sure we get that lib included.
-       3fa19ab: Fix warnings.
-       2843b1a: Remove the exceedingly anal warnings. It's impossible to write a non-trivial C program and not trigger these.
-       c4328cd: Fix stray \
-
-2006-05-24     Lennart Poettering
-       ca08e57: implement a /dev/mixer interface
-       440b901: fix playback of small sound files
-
-2006-05-23     Lennart Poettering
-       46fee46: implement emulation of /dev/sndstat
-       23b123d: - use pthread_atfork() to disable open sound streams in the child after a fork.   Obviusly sound won't work in child process but at least we don't leak fds   from the parent. Now any operation on the device fd in the child will result   in an EBADF error, which seems somewhat clean to me.
-       e99afda: pass the binary name as client name to polypaudio
-       1031549: add new padsp utility: a $LD_PRELOAD wrapper for using the OSS API with polypaudio
-       8f111b0: change return type of pa_cstrerror() to "const char*"
-
-2006-05-23     Pierre Ossman
-       7906985: Cast size_t to long to be more compatible with 64-bit systems.
-       1b72d02: Fix some warnings.
-
-2006-05-22     Pierre Ossman
-       d71dc9b: Fix TLS on Win32 to something a bit more safe and portable (compiler-wise).
-       4e3dc7c: Wrap strerror() in a function that makes it thread safe and converts the output to UTF-8.
-       bf09399: update todo
-
-2006-05-22     Lennart Poettering
-       97ec77c: add missing #include
-
-2006-05-21     Lennart Poettering
-       cc84fc9: add missing #include
-       651e575: add new function pa_usec_to_bytes() as inverse of pa_bytes_to_usec()
-
-2006-05-20     Lennart Poettering
-       bc87137: doc update
-       13329d3: fix long-standing buf that could cause polypaudio to eat 100% CPU: fix handling of event bits for pa_iochannel
-       cc61b57: rename pa_simple_get_playback_latency() to pa_simple_get_latency() and allow its usage on capture streams
-
-2006-05-19     Lennart Poettering
-       acc6552: generate PA_MAJORMINOR properly - only from major and minor, not from micro
-
-2006-05-19     Pierre Ossman
-       a3fe39a: Fix some missing headers.
-       a034b61: Fix which headers get installed for libpolyp.
-       c811351: Sort source files.
-
-2006-05-18     Pierre Ossman
-       1dfe8f8: update todo
-       1379831: Convert log text to current locale before passing it on to stderr or syslog.
-       8359188: Make paplay convert names to UTF-8 before sending to the server.
-       4981092: And functions for convertion to and from current locale and UTF-8.
-       40d9f5d: Missing include of util.h.
-       24a7819: Don't include util.h from core-util.h as it is not needed by many users.
-       3ee2051: PATH_MAX needs limits.h.
-       9ec9d28: update todo
-       0796ead: Move timeval calculation functions into their own file.
-
-2006-05-17     Lennart Poettering
-       5f458db: update README for 0.9.0
-       38cb138: modify lirc module to use pa_sink_mute() for muting and unmuting
-       53a285e: fix include line for "core-util.h"
-       40feedb: add C++ macros to utf8.h
-       ee4d6b0: add C++ macros to xmalloc.h
-       dc9151d: * add doxygen docs to header file * add C++ macros to header file
-       6766a3b: add util.h to doxygen
-       813868e: include util.h in polypaudio.h
-       c47e937: split polypcore/util.[ch] into polypcore/core-util.[ch] and polyp/util.[ch]
-       fbdb063: replace memory allocation function calls with pa_xXXXX()
-       43813dc: include more files in polypaudio.h
-       41baddd: add doxygen docs for utf8.h
-       56d8e56: * make pa_xfree() a real function * update doxygen docs for xmalloc.h
-       6e9f2d7: add utf8.h and xmalloc.h to doxygen docs
-       ee35a06: add new channel map argument to pa_simple_new()
-       5f6d8c9: fix svn tag
-       cdd3588: more sensible default.pa file
-       1cfb01a: add proper locking when accessing the file match.table
-       e0bf4a3: add proper locking when accessing the file volume.table
-       1267285: add documentation for module-volume-restore
-       6d281a5: update todo
-       db242e1: update todo
-       fa53ed7: * support native ULAW/ALAW file streams * fix shutdown of file streams
-       b47b257: support loading ULAW/ALAW files into ULAW/ALAW memchunks
-       e669553: * use S16NE for SF_FORMAT_PCM_S8 formats, too
-       31a9d4f: when playing an ULAW or ALAW audio file, do not convert to S16NE unconditionally, instead use sf_read_raw() to read raw audio data
-       106fb20: increase PA_CHANNELS_MAX to 32
-       270a409: use PA_CHANNEL_MAP_OSS in module-oss, module-oss-mmap
-       ed3606c: add new channel mapping standard PA_CHANNEL_MAP_OSS
-
-2006-05-17     Pierre Ossman
-       7ca25e5: Move utf8 to the public part (libpolyp).
-       d9cc2cf: Move xmalloc to the public side (libpolyp).
-       e767fda: update todo
-       6ab4213: Update documentation to contain the UTF-8 requirement.
-       d4d1e5e: Documentation for the threaded main loop API.
-       71f681a: Set default channel map system for waveout module.
-       c752e11: Add Microsoft's WAVEFORMWATEEXTENSIBLE channel mapping.
-       05c1468: Use default channel map for Solaris module. There doesn't seem to be a standard for > 2 channels, so we'll have to rely on the user.
-
-2006-05-16     Lennart Poettering
-       4b6ab29: * modify pa_channel_map_init_auto() to take an extra argument specifying the standard to use (ALSA, AIFF, ...) * add some more validity checks to pa_source_new(),pa_sink_new(),pa_sink_input_new(),pa_source_output_new()
-       c63cc7b: change version number from "0.9" to "0.9.0" to make version comparisons easier
-       c2c8539: bump version number to 0.9
-       5521559: * add new configure option --with-module-dir= * drop version suffix from soname of libpolyp and friends * add version suffix by default to $(modlibexecdir)
-       9298990: update todo
-       c12206b: * remove .a files from the modules directory after installation * rename $(modlibdir) to $(modlibexecdir) in accordance with secion 11.2 of the automake docs ("The two parts of install")
-       f272e59: tell svn to ignore the utf8-test binary
-       56b685a: instead of kicking clients with invalid UTF8 stream names, filter invalid characters and use that instead
-       5359593: add new test programme utf8-test.c
-       bf58753: add svn:keywords property
-       78b23cc: add double include protection
-       e8cc63d: * remove "const" from return type of pa_utf8_filter() since it desn't make any sense * fix pa_utf8_filter() to not skip the next character too if it found an invalid one
-       23e7454: use the new latency update callback to be notified when latency data becomes available again after PA_ERR_NODATA is returned by pa_stream_get_latency()
-       724cd9d: downgrade a log message
-       713637c: * fix segfault in pa_utf8_validate() * remove some compiler warnings * use our own pa_xmalloc() implementation instead of libc's malloc()
-
-2006-05-15     Lennart Poettering
-       19167a1: add notification callback which is called when new latency data becomes available
-       7a92f36: undo r868
-       147da3e: remove regex.h from include, since it is actually not used
-
-2006-05-15     Pierre Ossman
-       9c8661c: Add function to filter a string of any invalid UTF-8 sequences. User must free() the result.
-       e91740f: Clean up the UTF-8 validation code.
-       9c38744: module-volume-restore uses regexp() so make sure it's only built on systems that have it.
-       f468308: Include utf8.h for the validation function.
-
-2006-05-14     Lennart Poettering
-       3f42878: update TODO
-       45bbb34: add utf8 validity checking to esound protocol
-       d419d87: remove superfluous log line
-       cfb082a: take the filename specified on the command line as default stream name
-       a414cc2: check for valid utf8 strings
-       bf52fb9: add utf8 validity checking API
-       b10f2dc: update todo
-       b3e1655: add new module module-volume-restore which saves and restores volume of playback streams
-       be05b18: * add new parameter to pa_open_config_file() to specify open mode * modify pa_sink_input_new() to take initial volume settings as argument * call pa_sink_input_set_volume() when changing stream volume in protocol-esound.c to make sure that subscribe events are issued properly
-       e46f8f8: modify argument order of pa_client_new() to actually match how it is usually called
-
-2006-05-13     Lennart Poettering
-       682dfd7: fix esound sample cache names
-       0f22d63: * set default fragment metrics depending on the sample specs of the device in OSS and ALSA * fix fragment size calculation in module-alsa-sink
-       0231e6e: first set buffer size, and afterwards period size
-       c3b9c3d: don't hit an assert when trying to resample data for 6channel audio
-       7abf17e: fix fragment size calculation for module-alsa-source
-       b681202: use default alsa channel map for alsa devices
-       afdec05: remove superfluous log message
-
-2006-05-11     Lennart Poettering
-       11782f0: fix hangup detection for recording streams
-       eecc04c: fix iochannel for hangup signals
-       f931486: update doxygen docs
-       68b98f7: don't signal the accept_cond automatically when waiting for a signal event
-       e929aab: split of signal releasing into its own function and name it pa_threaded_mainloop_accept()
-       dbf62d4: add thread-mainloop.h to doxygen docs
-
-2006-05-11     Pierre Ossman
-       af54f9f: Windows support for the threaded API.
-       3890f03: Remove some debug code that wasn't supposed to be committed.
-       5328afe: pa_write() should use a const pointer.
-       48d66cd: Handle pipes on platforms where they are non-existant of broken. We do this by creating a TCP socket pair instead of a normal pipe. Since Windows isn't UNIX-y enough to support read()/write() on sockets, we also need a wrapper to handle read() vs recv() and write() vs send().
-       12d4b5d: Include log header to get rid of warnings.
-       18c5340: ANSI codes aren't supported on Windows terminals.
-       6d2a936: Do WSAStartup() in the DLL entry routine instead of at context creation.
-
-2006-05-09     Lennart Poettering
-       2687017: fix handling of timing status requests
-       9efc206: update todo
-
-2006-05-09     Pierre Ossman
-       4e71f20: Add stubs for the threaded main loop so that we can compile it on non-supported platforms (still can't run it though).
-       06e1867: Use pa_msleep() to get platform independence.
-
-2006-05-06     Lennart Poettering
-       df3306c: rework the simple API to make use of the new threaded mainloop implementation
-       4b4c8fd: * optionally, make pa_threaded_mainloop_signal() wait until the main thread took over control * more header file comments
-       5f9bbf0: add support for reading audio data from a file instead of plain STDIN in pacat-simple.c
-       bb6c45d: remove bogus check that disallowed latency interpolation and stuff for record streams
-       3f92e3e: allow signalling from event loop thread
-
-2006-05-03     Pierre Ossman
-       4cff5d3: update todo
-
-2006-05-02     Pierre Ossman
-       c2c9f25: Fix control flow in pa_oss_open(). Also fall back to half duplex when device doesn't support full.
-       27cee2e: We need to read the cookie in binary mode for things to work correctly.
-       1438bd4: Windows doesn't have POSIX thread. ifdef out things for now.
-
-2006-04-30     Lennart Poettering
-       9e60bad: add new threaded main loop implementation (with test/example)
-       f2fbceb: * make sure the wakeup fd is polled on wven when no other fd is registered for polling * initialize mainloop return value to -1 * some optimizations
-
-2006-04-28     Lennart Poettering
-       19c9dbf: fix date
-
-2006-04-28     Pierre Ossman
-       6060bff: When a control is removed, all bits are set so we need to test for that first.
-       53930f4: Zero the fd list since we do a memcmp on it later.
-
-2006-04-27     Lennart Poettering
-       cd93661: ouch!
-
-2006-04-27     Pierre Ossman
-       22c679e: Clarify how the automatic channel map is generated.
-       99612dd: Channel map argument support for solaris.
-       0b95438: Channel map argument support for waveout.
-       2c08180: update todo
-
-2006-04-26     Lennart Poettering
-       c29b3f1: doc update for 0.8.1
-       dff0822: bump version number
-       9564cef: fail if the channel map doesn't match the sample specs
-       c27b140: allow the user to specify an alternative channel map in paplay too
-       d78e466: fix volume range printed on --help
-       7b83904: if a sample is not yet loaded, don't print rubbish about its channel map
-       d4bad65: it was a bad idea to require that a channel map doesn't contain the same position twice
-       c3cc141: allow specifying the channel map to use on the command line
-       c478b0f: * make a validity check of parsed channel maps before rteurning theme * don't overwrite the return buffer unless the parsed channel map is known to be valid
-       185a57c: support new channel_map argument in sink/source modules
-       fbb0d14: add support for parsing channel maps as module arguments
-       292b237: don't allow channel positions to be specified twice in the same channelmap
-       5f7cc0c: add new test 'channelmap-test'
-       195e969: * add new function pa_channel_map_parse() * increase PA_CHANNEL_MAP_SNPRINT_MAX * add "top" channel positions
-
-2006-04-26     Pierre Ossman
-       31ad62f: update todo
-
-2006-04-25     Pierre Ossman
-       129853f: update todo
-       69096f2: Fall back to software volume if hardware mixer cannot control all channels.
-       f426b58: glibc <= 2.2 has a broken unistd.h, lacking setresuid().
-
-2006-04-24     Lennart Poettering
-       820c118: * rework reference counting in the client libraries: now refcounting goes   strictly "one-way" - the "bigger" object refcounts the "smaller" one, never the   other way round.
-
-2006-04-24     Pierre Ossman
-       d266213: chown() and chmod() aren't available on Windows.
-       fade8b0: Undo invalid automake version requirement.
-
-2006-04-23     Lennart Poettering
-       b92344f: fix a segfault when uploading samples with esound
-       3590ee7: * add validity checking for sample_spec, channel_map and cvolume structures * return PA_ERR_TOOLARGE when the user tries to upload a over-sized sample * notify the user if uploading a simple faield due to some reason
-       286310a: small optimization
-       9b52ac4: fix sample uploading
-       e1ac42d: enforce maximum sample size in sample cache
-       cdba052: * fix ref counting of pa_stream: strictly refcount from context to stream and never vice versa to make sure that we never loose memory * don't hit an assert() in case of a  timeout events
-       193fb12: introduce a new error PA_ERR_TOOLARGE
-       335e234: * when playing back a sample from the sample cache, just take a pa_volume_t and not a pa_cvolume_t as argument for the volume. Usually it is not known to the player of theses samples how many channels it has, hence it doesn't make any sense to allow him to pass a by-channel volume structure here. * fix volume calculation when playing samples from the sample cache
-       4e61ebb: fix multiplication of software pa_cvolumes
-       b4ac6d0: allow recieving of invalid channel maps, volumes and sample specs. This makes handling of uninitialized data better, e.g. when sending info about lazy-load sample chache entries, where the channel mapping and sample spec is still unknown.
-       8345063: * Merge build system patch from Igor Zubkov * Build libparseaddr.so before libsocket-client.so
-
-2006-04-22     Lennart Poettering
-       2bb8283: remove superfluous "set -ex" line
-       985da9b: require automake 1.9 in configure.ac
-       f6fc410: modify x11 modules to not cache the Display variable since pa_x11wrap_get_display() is now used as notification that the x11 output buffer needs flushing
-       ec65ca6: when loading sound files, initialize channel map data properly
-       5e50f84: fix x11 handling
-       55e19cb: fix sample cache
-       0e02e84: * for unix sockets: remove the right parent directory on shutdown * other cleanups
-       a4fedcf: add new function pa_parent_dir()
-       513df3b: first unlink the socket, the close it
-       b0059c6: try to remove the directory where the PID file resides in after removing the PID file
-       0cc2e04: chown() and chmod() /tmp/.esd/ before checking if everything is ok with it
-
-2006-04-20     Lennart Poettering
-       a7c5ed1: replace copy by symlink when installing homepage
-       5f804cb: minor improvements to the LICENSE text
-       9c06f5a: ship GPL and LGPL files with the tarball
-       81381c4: add new explaining LICENSE file
-       2decb6a: * rename "LICENSE" to "LGPL" * add GPL text * update LGPL text in regards to FSF addresses
-
-2006-04-20     Pierre Ossman
-       1b46097: update todo
-
-2006-04-19     Pierre Ossman
-       e4b53b2: Tweaks for the solaris module. The sound system requires complete frames to be written. Also, the sample counter can magically go backwards sometimes, causing havoc with our buffer handling.
-       989fa58: Sun's documentation about SIGPOLL on EOF:s is wrong, so use a timer based solution instead.
-       1d51247: Minor fixes for the way Windows handles sockets.
-       e1513ce: WaveOut needs to have rather large chunks. This is about as low as we can go without getting underflows.
-       5342f3a: Win32 needs to have the socket subsystem initialised.
-       6ae8511: Having constant deferred events isn't allowed and causes problems. Use timers instead.
-       4bb5822: Reverse order of IPv6/IPv4 binding to handle systems without IPV6_V6ONLY.
-
-2006-04-18     Lennart Poettering
-       494f602: make proper use of the muting facility of sinks in module-mmkbd-evdev
-       746adcf: fix a couple of issues I found when compiling polypaudio with gcc 2.95
-       60008cb: fix CFLAGS for jack modules
-       9ad753e: fix "make distccheck" properly
-       65fd9b3: fix make distcheck
-       e454bb1: Documentation updates
-       c35052a: add JACK module documentation
-       a5100be: fix connecting of jack source in jack daemon
-       a809129: build jack source
-       768a6f2: fix code for pre-C99
-       f8dbc2f: * fix pa_random_seet() function prototype * drop pa_ prefix from pa_random_proper(), because it is a static function
-       abea726: add a jack source module
-       cf85794: * allow the user to set the jack client name * take the number of channels for the sink from the number of physical ports in the jack server * name the polypaudio ports in the jack server after their channel position in polypaudio
-
-2006-04-18     Pierre Ossman
-       c22a0c1: Make the probe for RNG sources at runtime since the configure script isn't compatible with cross-compiling.
-       e4b2a47: Clarify that JACK libs are optional.
-       074b7c1: More fixes caused by Sun's complete inability to follow any standard whatsoever.
-       18055e4: update todo
-       2d6ab01: We need to emulate sendmsg/recvmsg to support rtp on Windows. Will do this some time in the future.
-       c3087d0: Avoid including non-portable header sys/poll.h.
-       8b99a06: C99 requires explicit marking of integer literals' size.
-
-2006-04-17     Lennart Poettering
-       4482e68: add new JACK sink
-
-2006-04-16     Lennart Poettering
-       40f171f: * add pa_mainloop_wakeup() calls for deferred events * place pa_mainloop_wakeup() calls a little bit more carfully, to minimize needless wakeups.
-       76296ca: add new API to replace the poll() function used by the main loop implementation
-       a8bb073: properly initialize session counter
-       7871f41: add documentation for the new RTP modules
-       2f3fa42: limit number of concurrent RTP streams
-       08397d9: fix typo in module description
-       e1887b5: change default mcast address once again, to make sure our traffic doesn't leave the network by default
-       68a6d61: ignore symdef file of module-rtp-send
-       b04a4e6: rename module-rtp-monitor to module-rtp-send
-       3b803e7: * make sure RTP ports are chosen to be even
-       c999fe4: * deal properly with underruns, overflows and packet losses * change default mcast address * detect RTP loops
-       67b105b: * increase default MTU * change default mcast address to 224.0.1.3 * randomize RTP ports by default
-       998affc: replace homegrown endswith() with pa_endswith() from util.h
-       0990d8c: initialize random seed globaly from $RANDOM_DEVICE
-       d50255a: * add new check for $RANDOM_DEVICE * move AC_SYS_LARGEFILE to avoid autoconf warning
-       a176d77: todo update
-       f1ddf05: * add RTP/SAP/SDP reciever module * use server cookie as RTP SSRC * enable SVN keywords * add new option "loop" for RTP sender module
-
-2006-04-16     Pierre Ossman
-       e75cc68: Fix ALSA fd handling to be compatible with blocking deferred events.
-       e8d9a5d: Clarify behaviour of deferred events.
-
-2006-04-15     Lennart Poettering
-       1fec416: * change default multicast address * fix timestamp calculation
-       71227de: correct some types
-
-2006-04-14     Lennart Poettering
-       e0e2b8f: * ignore some more files * make necessary changes to Makefile to compile RTP module
-       9522b44: add an RTP sender module
-       86ad601: minor beautification
-
-2006-04-13     Lennart Poettering
-       9539dc4: minor doc updates
-       c383a4c: * add a link to Cendio to the README
-       d981ace: remove yet another item from the todo list! This means we are now read for 0.8!
-       7e8d46e: unbreak module-tunnel
-       d153fda: remove yet another item from the todo list
-       010c049: include in-flux resampled chunk in latency calculations of playback streams
-       c25c549: fix latency calculations of module-combine
-       9854cfc: hmm, nothing important
-       fe64b89: add code to allow polypaudio dump preloaded modules using "--dump-modules"
-       d4b22f3: make --enable-force-preopen the default for SVN builds
-       1f7a008: add new configure option to enable preloading even on architectures that support dlopen(). Useful for debugging
-       df108af: update documentation for release 0.8
-       5639b7e: doc updates
-       20f4ae6: more documentation updates
-       ceb09d8: Documentation updates
-
-2006-04-12     Lennart Poettering
-       b33ae79: remove yet another item from the todo
-       7fa8323: include local record memblockq in latency calculations
-       06bd27b: when storing recording data in file, create file with proper access rights
-       4a8d318: yet anotrher fix for slow links
-       0af582a: small fix to deal properly with slow links
-       bf88854: * dispatch defer events in pa_mainloop_dispatch() and not already in pa_mainloop_prepare() * fix the "timeout" parameter of pa_mainloop_prepare() * remove pa_mainloop_deferred_pending() and update the simple API accordingly
-       853caf1: * fix latency calculation where a full playback buffer was erroneously taken as empty buffer and vice versa.
-       0fa56f9: remove a bunch of log messages
-       d427942: beefup pacat a little: * when -v is passed, show current playback time and latency * modify SIGUSR1 behaviour to show only playback time and latency
-       49b3150: * rename "latency correction" to "write index correction" * add read index invalidation code * rename "ipol_event" stuff to "auto_timing_update" * remove buffer_usec field from pa_timing_info, since it can be easily calculated from write_index and read_index anyway * add read_index_corrupt field to "pa_timing_info", similar to the already existing write_index_corrupt field * restart automatic timing update event every time a query is issued, not just when the last event elapsed * proper invalidation code for pa_stream_flush() * do tarsnport/sink/source latency correction for playback time only when device is not corked
-       77c2a1f: protocol change: don't send stream buffer size in latency update. This data is redundant, since it can be calculated from write_index - read_index anyway
-       b5d177d: proper validity checking for pa_context_is_pending()
-       a0c7ca0: when flushin a memblockq, set the write index to the read index
-       64d0d9b: todo update
-
-2006-04-10     Lennart Poettering
-       268c857: unbreak fresh SVN builds
-       b2668ca: return the error code and not just -1 when pa_context_is_pending() fails
-       a81209f: validity checks for pa_context_is_pending()
-       09589a7: update todo
-       021744d: * Beef up latency calculation in module-oss-mmap * Add recording latency code for module-oss-mmap * other cleanups
-       8f2d9ae: minor cleanups for OSS module
-       9332708: when using record mode, allow file to save data to to be passed on the command line
-       6a3b8ae: todo update
-       137f0a7: * implement PA_STREAM_AUTO_TIMING_UPDATE * accept PA_STREAM_NOT_MONOTONOUS properly
-       190a869: add new PA_STREAM_AUTO_TIMING_UPDATE
-       4496954: Lennart is blind
-       35ea8ac: update TODO
-       f4119ad: unbreak last commit from ossman
-
-2006-04-09     Pierre Ossman
-       0d200ee: Use the modern Ki/Mi/Gi prefixes to clarify that 1024 is the base.
-       a6ce5c4: Big documentation update. Describe the client API in a more tutorial like manner.
-
-2006-04-08     Lennart Poettering
-       a742536: clip volume at PA_VOLUME_NORM for alsa devices
-       025228f: add proper volume clipping support for OSS devices
-       b4a5474: when doing software volume adjustments, don't use the volume value as linear factor, but pass it through pa_sw_volume_to_linear() first.
-
-2006-04-07     Lennart Poettering
-       107525c: remove another item from the todo list
-       a546c76: * show flags value when dumping sink/source info in pactl. * show volume for sources, too * show value of "mute" field for sinks/sources
-       f6d95b7: add new introspection data field for sinks/sources: a flags field which specifies whether the sink/source supports hw volume control and latency querying
-       272ab20: todo update
-       4af16e4: minor cleanups
-       7261494: remove item from TODO list, since it requires the SNDCTL_DSP_GETERROR ioctl() which isn't supported by the Linux kernel
-       2f918f0: todo update
-       fdb48b4: * enable write_index correction and timing interpolation only for playback (and record) streams
-       22558b5: fix pkg-config files
-       e5a5b56: remove yet another item from the todo list
-       a9f4896: hdie some more
-       b8a729a: * update docs for reworked latency API * rename pa_latency_info to pa_timing_info, since that describes better what it is. Most people will only use pa_stream_get_time() anyway
-       c0592bb: update simple API for new latency API
-       53a0056: update pacat.c for new latency API
-       920f045: rework latency querying API (this needs more testing)
-       cc302f2: remove queue length field from latency request (server side)
-
-2006-04-07     Pierre Ossman
-       add110b: Some memcpy arithmetic that wasn't removed when doing the redesign to update the data pointer instead.
-
-2006-04-06     Lennart Poettering
-       dd9605b: * really pass the ipv6 socket server to protocol_new in case of ipv6. * create the pa_modargs object properly when using TCP * other cleanups
-       1be0017: change pa_gettimeofday() to return a pointer to the struct timeval*, instead of an int
-       e872c75: s/index/idx/, to avoid gcc warning
-       73035a8: * set IPV6_V6ONLY for IPv6 sockets, to avoid warning when both ipv6 and the ipv4 sockets try to bind to the same port * enable SO_REUSEADDR only on platforms that support it
-       ac3d11f: remove some GCC warnings introduced by improperly casting to (char*) instead of (const char*)
-
-2006-03-31     Pierre Ossman
-       acb96c9: Fix some warnings caused by size_t having varying size.
-       3285403: Large file support. Polypaudio probably doesn't need it, but it causes warnings when linking libpolyp with applications that do. So this is just to make life easier for other applications.
-
-2006-03-17     Pierre Ossman
-       8d4af80: update todo
-
-2006-03-11     Pierre Ossman
-       dc5b2c5: We no longer guarantee that an operation object is returned. Need to tweak some parts to handle this.
-       da90b05: Remember to store the struct with module info.
-
-2006-03-08     Pierre Ossman
-       3ef4970: We filled the volume with the wrong channel count (we used the input, not the output) causing static. Also swapped the comments since they were misplaced.
-
-2006-03-07     Pierre Ossman
-       528d150: The extra stream ref actually did some good. Re-add it, but with some more symmetry, assertions and comments.
-       b67963c: We've already set an initial reference count of 1 so don't count it up again.
-       6457137: Trying to listen on an IPv6 socket by default and only do IPv4 if that fails (which it doesn't most of the time) is terribly confusing. What the user most likely wants is for it to listen to both IPv4 and IPv6 and gracefully continue if only of them succeed.
-
-2006-03-05     Pierre Ossman
-       90d6a91: update todo
-       53c266f: Fetch sound card name into sink/source description.
-       06eaebf: update todo
-       7387342: Volume support in tunnel module.
-       4e56725: It's safer to set buffer size than to try setting number of periods.
-       f22d8ab: Return the proper error code so that we get a correct error message.
-       7b6a9c3: Tried to get the volume information even upon init failure.
-
-2006-03-04     Pierre Ossman
-       dcd202f: Update module-tunnel to the new protocol.
-       45baa69: Fix warning caused by missing return in main().
-       ad7640b: update todo
-       4e52294: Alignment safe protocol handling in esound module.
-
-2006-03-02     Pierre Ossman
-       bc97b29: Negotiate protocol version between server and client. Will allow smoother protocol modifications in the future.
-       fbaaf5a: The tag argument is no longer unused.
-       50268e0: Fix warnings on 64-bit systems.
-       6cc11fb: Handle the new latency protocol. This is just a quick fix and does not handle the new memblockq system.
-       7f04568: typo fix
-
-2006-03-02     Lennart Poettering
-       8cf9b97: protocol changes for new latency API (partial!)
-
-2006-02-27     Pierre Ossman
-       76f56ab: update todo
-       5b9849e: update todo
-       4756d18: We have both sink and source in this module.
-       e8b3819: Catch volume update events.
-       1bb14c3: 64-bit fixes.
-       f59bc1f: Fix some signed/unsigned warnings.
-       e37f008: Function prototype didn't match actual definition.
-
-2006-02-26     Pierre Ossman
-       0c65922: update todo
-       1e68539: Get notifications about mixer changes from ALSA.
-       ae07d5a: Handle ALSA file descriptors more correctly. This means a bit more overhead, but following their API properly should avoid problems in the future.
-       c119996: Fix correct default device.
-       b125e1c: Hardware volume support in ALSA modules.
-
-2006-02-24     Lennart Poettering
-       c5ec39d: move scatter/gather todo item to post-0.8, since it's impact on perfomance might not even be worth the effort.
-       0d8da54: todo update
-       4358977: * Add new "auth-group=" parameter to protocol-native-unix * Rename "public=" argument  of protocol-{esound,native} to "auth-anonymous"
-       3f264b2: add support for authentication using SCM_CREDENTIALS
-       b967aeb: todo update
-       903b8c0: todo update
-       c2304d6: add a few more validity checks to protocol-esound
-
-2006-02-24     Pierre Ossman
-       25bcc10: Do an explicit cast to shut up gcc.
-       c3a2670: This wasn't supposed to be checked in.
-       b418809: Wrong variable used for port.
-       9f1b793: Tweak the handling of missing credential support so that we minimise non-POSIX headers in our headers.
-       a1f5573: Call correct function.
-       c205ea6: Make local function static.
-       9366ab9: Hardware sink mute support.
-       3374df5: IGAIN is a better choice than IMIX for source volume.
-
-2006-02-23     Pierre Ossman
-       65736a2: Some new additions were mislabeled as '\since 0.9'.
-       04c8926: Mute switch for sinks and sources. This is independent of the volume setting (similar to ALSA).
-       bd4ae44: update todo
-       607b279: update todo
-       79e8009: Hardware source volume support.
-       4e8faa6: inet_pton expects in[6]_addr structures, nothing else.
-       adad7dc: Add inet_pton emulation for platforms that lack it. Only support IPv4 at this point.
-       7050dbf: Update hardware volume to a correct initial value.
-       f8aca21: Wrong function name.
-       12e35c5: Make sure hardware volume gets a correct initial value.
-       ce9b035: Hardware source volume support in OSS.
-
-2006-02-23     Lennart Poettering
-       c2290c5: update todo
-       a4ab652: really ignore pabrowse
-       2756117: ignore pabrowse
-       4a64b0d: change pa_log() and friends to not require a trailing \n on all logged strings
-       cb59817: simplify tagstruct creation
-       5771335: fix source volume adjustment: copy memchunk before changing the volume of it
-
-2006-02-22     Lennart Poettering
-       708c650: enforce maximum memblockq length for clients
-       bad8fd7: update todo
-       ecd346f: add listen= parameter to tcp protocol modules
-       8df72bc: todo update
-       5c7ab77: pkg-config update
-       7f68c91: revive howl support
-       361f167: unbreak Makefile.am
-       63165d8: todo test
-       a99e46d: rework parameter validity checking in protocol-native server side
-       f62b66a: todo update
-       bf013f8: todo update - outline what i consider pre-0.8 and post-0.8 issues
-
-2006-02-22     Pierre Ossman
-       71fd26f: Wrong userdata used to init operation.
-       cc2178e: Support for setting volume on sources.
-       6cd2250: Remove polyplib-error and polyplib-mainloop for requirements.
-
-2006-02-21     Lennart Poettering
-       8d88264: add hw info to description for oss-mmap, too
-       5014db9: include hw description gathered from /dev/sndstat in sink/source description string
-       6169bd8: add new utility function pa_endswith()
-       13b4213: remove left-over log line in protocol-esound.c
-       9d3dcef: todo update
-       a10257d: fix pacat
-       36c8861: todo update
-       8c80dd6: * Don't build seperate ipv4/ipv6 versions of the protocol plugins * Instead try IPv6 and if that fails fall back to IPv4
-       c07928a: todo update
-       4f511bb: * Get rid of libpolyp-mainloop * Remove pkg-config file of polyplib-error
-       f1a0ee7: todo update
-       893204f: add hw volume control for module-oss-mmap
-
-2006-02-21     Pierre Ossman
-       48b2e1a: update todo
-       7e51237: Hardware volume support on Windows.
-
-2006-02-20     Lennart Poettering
-       86124ab: todo update
-       cae2d80: disable SIGPIPE before calling pa_core_new(), this way the warning message is not printed
-       1506c15: build defer() function in src/polyp/mainloop-signal.c only on win32
-       9bcb413: fix snd_pcm_hw_params_set_rate_near() usage
-       56ce62a: build dllmain.c only on win32 (makes gcc shut up a little more)
-       f5e8953: todo update
-       d48912b: improve error checking in simple API
-       2bdc07e: add validity check for the "server" parameter of pa_context_connect()
-       0858ef9: fix yet another pa_context_connect() occurance with regards to the flags parameter
-       a8e85ba: remove a superfluous log line
-       31a027b: change calls of pa_context_connect() to pass flags arugment correctly
-       b008941: fix moddir
-       71b3bff: * modify pa_context_exit_daemon() to return a pa_operation object * add callback prototypes to all introspection functions in client lib * add proper validity checking and error handling to all functions in the client lib * other minor cleanups * todo update
-       98cb6aa: * a lot of doxygen updates * s/pa_operation_callback/pa_operation_callback_t/g * add more typedefs for function prototypes * add API to query the channel map used by a pa_stream
-       71e063a: todo update
-       ddd51e2: add doxygen docs for channel map
-       3bc0902: minor doxygen fixes
-       6d09602: replace "spawn" parameter of pa_context_new() with a proper flags parameter
-       e078f08: explcitily cast strings to make gcc shut up
-       4566d56: * Make typdefs for the pa_context callback prototypes * s/pa_context_notify_cb/pa_context_notify_cb_t/g
-       b36ed4d: remove cdecl.h from doxygen docs
-       081fb74: update TODO
-       16285f9: make doxygen ignore PA_CDECL_BEGIN/PA_CDECL_END
-       3044490: 1) Add flexible seeking support (including absolute) for memory block queues and playback streams 2) Add support to synchronize multiple playback streams 3) add two tests for 1) and 2) 4) s/PA_ERROR/PA_ERR/ 5) s/PA_ERROR_OK/PA_OK/ 6) update simple API to deal properly with new peek/drop recording API 7) add beginnings of proper validity checking on API calls in client libs (needs to be extended) 8) report playback buffer overflows/underflows to the client 9) move client side recording mcalign stuff into the memblockq 10) create typedefs for a bunch of API callback prototypes 11) simplify handling of HUP poll() events
-
-2006-02-20     Pierre Ossman
-       7905e81: Add aligment fix in esound to todo.
-       5d253cd: Fix some warnings by making sure we have the right signedness on things.
-       502d3f5: Hardware volume support for Solaris.
-       f2292ae: Fixes for the Solaris detection.
-       5cc0d0e: Add mute switch to todo.
-       6c2d414: Detect support for Windows' waveout.
-       d1bc972: Detect support for Solaris (/dev/audio).
-       0eed96d: Remove a debug fprintf that was left in.
-       e9658bb: util.c uses some socket functions so we need winsock on Windows.
-
-2006-02-18     Lennart Poettering
-       0876b1b: update todo
-
-2006-02-17     Pierre Ossman
-       b26df7e: Properly clear members during init.
-       d142c12: That's a delta parameter, not a size parameter.
-       45700da: Have a memblock queue on the client side during recording. This makes the record callback optional in stead of mandatory.
-       6f9a367: Ignore generated win32 binaries.
-       162a95d: Module needs stuff in libpolypcore.
-       2686857: Fix path to poll.h.
-       c4cf7ad: Fix typo in #ifndef.
-       da665d5: Integrate error routines into libpolyp. Not much point in having this as a separate library.
-       1eae42f: Make sure that all polypcore headers are installed.
-       5eda18b: Cleaned up the includes after the restructuring. Indicate which headers are public and which are internal through <> vs "".
-       c278bc6: Move the util libs to the modules section since they're in that directory.
-
-2006-02-17     Lennart Poettering
-       b951308: fix doxygen
-
-2006-02-16     Lennart Poettering
-       2e0dcc4: include header files in simple.h with <> instead of ""
-       5ccf414: * rename polypcore/subscribe.[ch] to polypcore/core-subscribe.[ch] to avoid confusion with polyp/subscribe.[ch] * same for scache.[ch]
-       b4cb249: shorten include list of utils a little
-       19b5b71: * drop polylib prefix from #define * include error.h from polypaudio.h
-       45b1eee: fix compilation of simple API
-       22c8ceb: drop polyplib- prefix from client library files
-       f49b09d: make channel naming somewhat RFC2551 compliant
-       4ad2926: add a bunch of simple Makefile in the subdirs, just to make compilation with emacs easier
-       c75972f: move alsa-util.[ch], oss-util.[ch] and howl-wrap.[ch] to the modules directory since they are just helper source used exclusively by the modules
-       b56b9e5: * svn:ignore some files * move configuration files to the directories they belong to * built esd-compat.sh in the src/ dir
-       5b881e6: add simple hardware auto detection module
-       6ad876e: Add HAVE_ALSA and HAVE_OSS defines
-       61fbafc: allow polypaudio to startup without any enabled module
-       a9950d4: print ALSA error messages on failure
-       cc3fe43: fix warning text
-
-2006-02-16     Pierre Ossman
-       e205b25: Reorganised the source tree. We now have src/ with a couple of subdirs:
-
-2006-02-15     Lennart Poettering
-       22e1f40: todo update
-
-2006-02-14     Pierre Ossman
-       0f0fc32: Fix api. Setting volume is done through a pa_cvolume struct, not a pa_volume_t scalar.
-
-2006-02-13     Pierre Ossman
-       f77d5e1: Add function to "wake up", i.e. interrupt, a running poll(). This is needed when having the poll() in a separate thread.
-       bbaf154: Split mainloop_iterate() into three, distinct parts. Allows for more flexible use, like having the poll() run in a separate thread.
-
-2006-02-10     Pierre Ossman
-       4ab432a: Fix some new alignment bugs in the tagstruct handling.
-       8d91ffe: Install the new headers for channels and volume.
-
-2006-02-03     Pierre Ossman
-       d9bfd5b: Let's have just one endian conversion macro suite.
-       5c01c10: Fix endian conversion macros and reformat them to be a bit more readable.
-       d431e00: Use defines and not hard coded values for volume levels. Caused incorrect volume levels for all esound clients that changed the volume.
-       bbc6dd6: Volume adjustment must be done _after_ dropping the chunk since drop will reject a modified chunk.
-       c34f35a: Reverting an incorrect checkin.
-
-2006-01-30     Pierre Ossman
-       dd7b380: Fixes for the new infrastructure so that the waveout module compiles.
-       7da06d3: Fixes for the new infrastructure so that the solaris module compiles.
-       22db575: Breaks missing from conversion to a switch statement.
-       f8808a2: Print an error message before aborting.
-
-2006-01-28     Lennart Poettering
-       db6dc13: * add variadic function pa_tagstruct_get() and pa_tagstruct_put() for parsing/constructing tagstruct records * convert some of the tagstruct uses to this new API
-
-2006-01-27     Lennart Poettering
-       8580967: add support more for up to 16 auxiliary channel positions
-       dd10c98: Mega patch:
-
-2006-01-27     Pierre Ossman
-       759721c: Remove the version number from the module directory. Makes life easier for any external projects that need to use that directory.
-
-2006-01-25     Pierre Ossman
-       917d876: We get the -lcap through LIBS, so no need for CAP_LIBS.
-       104797b: Use AC_SEARCH_LIBS instead of AC_CHECK_LIBS since it is a lot smarter and doesn't add unnecessary libs.
-
-2006-01-20     Pierre Ossman
-       30bb5ce: Fix so that peer name can be determined on Windows. We do not support console on Windows at this time so we do not have to worry about that right now.
-
-2006-01-19     Pierre Ossman
-       60dbf8b: Open the device in non-blocking mode.
-       0ca9a0e: Ugly hack to get around Solaris particularly brain dead sound system. The system has a buffer size of 0.5 MB which cannot be changed. We emulate a smaller buffer through some SIGPOLL trickery.
-
-2006-01-16     Pierre Ossman
-       719c377: We need a logical, not an arithmetic shift here. So use unsigned types when doing the shifting.
-
-2006-01-12     Pierre Ossman
-       262c60f: Under win32 we freed the wrong pointer causing a segmentation fault.
-       cb2a7ed: Some crappy hardware generate noise on the output when reading input. To avoid triggering this needlesly we tweak the algorithm a bit to avoid reading when nothing is connected to the source.
-       289c914: Some drivers (via82xx) doesn't start recording until we read something. This is ugly, but unfortunately required.
-       fc93e4b: Used 0 as an invalid fd. Changed to -1.
-       f61be8b: If the card couldn't do duplex when required we would incorrectly return success from this function with a closed fd.
-
-2006-01-11     Pierre Ossman
-       72316cc: Many (FSF and Sun at least) have interpreted the C99 standard in a way that int64_t and similar types are only defined on 64 bit platforms. Using -std=gnu99 lifts this rather silly restriction.
-       2623edc: Remove the old compiler flag test now that we have a new shiny one.
-       70ac72e: Our makefiles work just fine on older automakes (1.7 tested). Let's keep this out until we run into something that doesn't work.
-
-2006-01-11     Lennart Poettering
-       1f09613: * remove a lot of compiler warnings introduced by using some new GCC flags * add typedefs for public structs and enums and drop the struct/enum prefixs from all uses where it makes sense
-
-2006-01-10     Lennart Poettering
-       6c512fb: build system updates, including support for some newer GCC options
-       f7a99e9: Merge Pierre's changes
-
-2006-01-10     Pierre Ossman
-       34e81ff: Handle Windows paths when normalizing authkey path.
-       29118f5: Make sure the caps header check can also be disabled.
-       1015ea4: Store previous reported time in order to assure a monotonic clock.
-       d429222: Accidental use of a swapped int.
-       11c6cac: buf is needed on Windows aswell.
-       abdf9b1: Add needed error code.
-       0a9abdd: Unfortunately Windows has two different values for EBADF depending on if it's a file or a socket. We'll have to deal with these as they show up.
-       ba06340: Add some required headers.
-       357ab88: Make sure socklen_t is defined.
-       5e5808a: Static libs bork the creation of dlls and AC_CHECK_LIB isn't very bright, so we have to do a test first to see if getopt_long() is included in the system libs.
-       ff4cc62: Move library checks to a separate section and make sure it's before function checks. It could miss functions because they are hidden in extra libs otherwise.
-       f5a2cf1: getopt_long resides in libiberty on many platforms.
-
-2006-01-09     Pierre Ossman
-       76bc56c: Put inet_ntop() emulation in a seperate file.
-       d3cb144: Update comment for pa_lock_fd() to reflect that locks are mandatory on Windows.
-       160d886: Merge with trunk.
-       8258146: Generalise lstat fallback.
-       5fcbf04: Condense winsock includes and defines into one header.
-       9818d67: Make the tagstruct handling safe on machines with alignment restrictions.
-       8a32357: Make sure the data gets endianness conversion.
-
-2006-01-09     Lennart Poettering
-       80ae72c: improve sync clock change
-       794033a: fix synchronized clock change
-
-2006-01-05     Pierre Ossman
-       067c00f: Reversing incorrect commit.
-       72795fc: Use autoconf detected define for getgroups() type.
-       d5ce3ec: Ignore windows exe:s.
-       1b472f7: Solaris support.
-       6781628: The Windows sound interface module.
-       19d9fcb: Port to Windows. This is mostly glue layers for the poor POSIX support on Windows. A few notes
-       2f74bb9: Protect pthread.h with an ifdef.
-       bdc02f7: Protect sys/resource.h with an ifdef.
-       67833c2: Protect sched.h with ifdef.
-       57dccd2: Replace paths with defines.
-       2c4d42e: ctime_r() is not available everywhere.
-       e72bbdb: c was used before it was assigned.
-       010476f: Protect getuid() with an ifdef.
-       5ac2cb9: No regexp funtions are used in this file.
-       ecaf8d8: PATH_MAX is defined in limits.h.
-       983fdb3: Stub uses socket defines so include the header.
-       7aba34b: config.h should always be included so that necessary fixes can take effect.
-       2cf165d: ifdef-protect setpgid and setsid.
-       08bbfd2: Make it possible to disable caps support since it breaks fully static builds.
-       be2ba90: Add option to select which modules get linked in during static builds.
-       9550c8e: No need for conditional generation of symdef files.
-       971e370: Add possibility for linking semi-static executables (libtools definition of static).
-       e2495c7: We need explicit actions here.
-       268aebb: Protect sys/wait.h with an ifdef.
-       8f3c364: Make sure all socket headers are protected by ifdefs.
-       e28ce8c: Use pa_get_path_filename() instead of duplicating code.
-       29a5b85: Emulate poll() through select() where needed.
-       d3bc7b2: Fix test for mkfifo(). HAVE_MKFIFO is only generated as a config.h define by default.
-       5cd8703: Remove ftruncate test since we're not doing anything with the result.
-       a24102c: Fix indentation.
-       e9be6fa: Handle platforms that do not support the UNIX user/group database.
-       59aa6ca: There was a race condition here that caused latency calculation to fail miserably under some conditions.
-       ec87cb1: Fall back to signal() when sigaction isn't supported.
-       3ed983c: SIGQUIT is an optional signal.
-       b8859b4: Compiler warning about uninitialized variable.
-       3728854: Make sure the array is never too small.
-       b69d881: Fix printf string.
-       7192238: Old kernel headers didn't define the input_id structure. Therefore we cannot rely on it.
-       c5bee95: Fix correct type.
-       4deeaef: Don't include sys/socket.h in the header when we do not need to.
-       14474ae: Esound latency should not include buffer length. This added an extra second to esound already horrible latency calculations.
-       f0e8c65: Two variables with the same name causing corrupt strings.
-       4384d31: Fix warning.
-       ff49e63: inet_ntop can't be found on all platforms. Do a stupid emulation when not found.
-       456e256: Fix some compiler warnings about unused variables.
-       cd3691d: PIPE_BUF has nothing to do with the esound buffers.
-       13496bb: Handle when the platform doesn't have UNIX sockets.
-       3a3b4af: AF_UNIX and PF_UNIX is more portable than the _LOCAL equivalent.
-       dbad54a: Remove any warnings about incorrect type to setsockopt() (char* vs void*).
-       7dcf4e4: The standard declares some signals as optional. Make sure we handle this gracefully.
-       eacffc3: To access the new pa_gettimeofday() we need to include util.h.
-       8c5a75d: Syslog is not present on all platforms.
-       3996c5f: SIXCPU isn't present on all platforms. Replace cpulimit with dummy functions on those systems.
-       2ce05b2: Glob is not present on all systems.
-       70223ba: Fallbacks for systems that do not have getaddrinfo(). Does not handle IPv6 though.
-       3f2ac7e: We have a generic function for extracting the filename, let's use it.
-       f6b0f87: Remove unnecessary dependency on timeval definition.
-       687e2d7: Abstract the gettimeofday call into a utility function to ease porting.
-       70710e1: Check for OSS by looking for its header. Win32 isn't the only platform where OSS isn't supported.
-       11a4c67: Remove unused automake conditional.
-       e8c71ed: Since README is generated conditionally we must make sure there are no dependencies on it when it's not built.
-       1f11ee3: Big cleanup of the build structure.
-       22f6694: Creating branch for patches from Pierre Ossman
-
-2005-09-16     Lennart Poettering
-       656cf87: fix alsa memory leak
-       9177ef4: chance ALSA sink to use "default" as default alsa device
-       3a61b36: initialize running_as_daemon
-       d50bfd8: increase number of allowed connections
-       e4395c2: add new field running_as_daemon to pa_core
-       48b2a87: add pa_sound_file_too_big_to_cache()
-       668f3cd: handle float values in sound files sensibly
-       652e000: print a nice message when libltdl is missing
-       e0d0f1b: git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@352 fefdeb5f-60dc-0310-8127-8f9354f1896f
-       6d9dffe: build fix
-       c57cad9: bail out if no sink is defined
-
-2005-09-15     Lennart Poettering
-       b993e33: alter alsa periods number
-       db4b25d: handle EOF in ioline.c
-       fda09b9: remove esound protocol directory on unload of module-protocol-esound
-       f1da8ad: fix start_timeout()
-       b5f5707: add libsamplerate/libsndfile CFLAGS
-       e1f008f: commit liboil porting changes
-       0c9873e: create a copy for liboil porting
-
-2005-01-12     Lennart Poettering
-       4daa0c1: * fix LIRC configuration
-       f586ce0: * extend HTTP module
-       4590f09: * make pa_sample_spec_snprint return point to written string * first try of a http module
-
-2005-01-11     Lennart Poettering
-       32bf3a1: * new environment variable $POLYP_LOG * fix connection establishing algorithm * add timeout for establishing connections * add fqdn to the server directive to connect to in browse API * quieten ESOUND protocol
-
-2005-01-09     Lennart Poettering
-       5ab3064: * add new module module-mmkbd-evdev * fix stupid error message in main.c
-
-2005-01-08     Lennart Poettering
-       474b568: * todo update * lirc warning fix * c++ compat
-       6911d7e: * increase timeout in pacmd
-       c29c95d: * make lirc program name configurable
-       fb4cba4: * add new module for LIRC volume control
-       1e78a1d: change doxygen build stuff for better compat with moderm automakes
-       9a59d01: update todo list
-       9b0ec37: * add support for asynchronous name resolution * remove directories listing from doxygen
-
-2005-01-06     Lennart Poettering
-       fb11e45: minor fixes
-
-2004-12-18     Lennart Poettering
-       8199925: fix conditional X11 compilation
-
-2004-12-16     Lennart Poettering
-       47ab6bd: gcc 2.95 compat
-
-2004-12-15     Lennart Poettering
-       b1369d2: * fix error message when starting polypaudio while it is already running
-       400dacd: cleanup zeroconf service names
-       99e0779: * Publish server info in mDNS in addition to sinks/sources * Split off address parser * Add port= argument to module-zeroconf-publish
-
-2004-12-14     Lennart Poettering
-       bc5b917: do mor daemonizing work
-       a370e6e: * fix daemonizing
-       fa48de8: * prepare polyplib-browse for installation
-
-2004-12-12     Lennart Poettering
-       e02be6c: * fix include file names in installed header files * add browsing API * add new tool pabrowse * add typeid subsystem * bump API version * split off random.c * add an identification cookie
-       9a01cf4: * complete zeroconf publisher * make cli.c shut up unless run with -v
-
-2004-12-11     Lennart Poettering
-       2d97e75: * fix alsa initialisation * add some missing zeroconf files * make module-match shut up a bit
-       73eabec: * add first part of zeroconf publisher * bump version to 0.7.1. * improve logging subsystem (introducing log levels) * remove verbose flag on cli * add new API pa_sample_format_to_string() * replace strtol() by usages of pa_atou() and pa_atoi()
-
-2004-11-27     Lennart Poettering
-       5be9641: * really fix integer only resampler
-       7f3c92b: * fix autospawn lock file creation
-
-2004-11-26     Lennart Poettering
-       9a9309f: * use setresuid() instead of setruid() if available * if fix for the non-fp resampler
-
-2004-11-23     Lennart Poettering
-       7586478: * install fix * use syslog as standard log target when run from esdcompat.sh
-       29ec9d3: * some fixes for MacOS X by Conrad Parker * Minor build fixes
-
-2004-11-21     Lennart Poettering
-       c827fca: prepare for release
-       9f23c8f: Documentation updates
-       4763ca1: Comment some more files
-       2fb83d1: * make --help fit in 80 columns terminal
-       82a3626: * update todo
-       d45abba: calculate buffer sizes from sample spec
-       4583c22: * create parec as link to pacat
-       28d9744: * new tool pacmd * fix pacat/paplay/pactl for new API version * fix memory leak in pa_ioline
-       c90409e: bump version number
-       b03f390: * add some missing "static"s * include libltdl in distribution
-       966c78c: fixes for bugs found when compiling with gcc 2.95
-       92f73a7: * fix the trivial resampler
-       f2b11db: * PID and lock file fixes
-       fa751e5: some commenting
-       6985eda: * some minor pid file fixes
-
-2004-11-20     Lennart Poettering
-       3c77c6e: * remove autospawn lock file usage * fix some compiler warnings * implement PID file support
-       acc8b78: option to use ALSA default fragment number and size
-       5f647c8: * add µlaw/alaw support * abstracted resampler API * add integer-only resampler ("trivial") * show used resampler wherever useful * add mixing/volume adjusting for float32ne and u8
-
-2004-11-18     Lennart Poettering
-       8641af3: * some iochannel fixes * introduce reference counting in ioline * fix memory leak in socket-client.c * fix double-free error in protocol-esound.c
-       eef235d: limit the number of concurrent connections for all four protocols kick a client if it doesn't authenticate within 5s on ESD and native protocol
-
-2004-11-17     Lennart Poettering
-       c57d5de: minor fixes for latency interpolation
-       cd3a98a: todo update
-       a58f248: fix module-tunnel.c
-       ddf9970: update todo list
-       5ea2783: * fix a long standing bug in ioline.c (large prints failed) * fix a bug regarding ipv6 binding
-       0a2bbc5: * some commenting work * add new field "read_only" to memory blocks * add new API function pa_context_get_server() * filter capture data through mcalign on client * make module-tunnel use pa_socket_client_new_string() instead of using pa_resolve_server() directly. * remove pa_resolve_server() * remove debug.h and replace it by a macro definition on the gcc command line * some strbuf cleanups * small fixes in pa_stream for cleanup when server dies * new CLI command "load-sample-dir-lazy" * send FQDN as part of server info * rework mcalign, this time with memory block merging * fix iochannel cleanup when connection dies * check getaddrinfo() results
-
-2004-11-14     Lennart Poettering
-       f5f6605: todo update
-       fa499da: Make the whole stuff LGPL only
-       be6a1c2: * implement module-esound-sink
-       d7d8529: * remove as superfluous assert() in polyplib-stream which broke the gstreamer plugin * fix module-tunnel meta info
-
-2004-11-12     Lennart Poettering
-       6de0cda: remove a debug message
-
-2004-11-11     Lennart Poettering
-       c005bd4: add username to runtime directory name in /tmp/ rework autospawning code and x11 credential publishing add support for IPv6 reenable LOWDELAY for tcp sockets
-
-2004-11-09     Lennart Poettering
-       dbaa83c: split out x11prop.[ch] add client support for auth daemon info in X display
-       3fcd7a4: use fqdn in module-x11-publish as well
-       3916a66: export FQDN instead of hostname
-
-2004-11-08     Lennart Poettering
-       89e39f1: build pax11publish only when X11 is available
-       4bb1483: implemented pax11publish.c
-
-2004-11-07     Lennart Poettering
-       b55923a: * Look for M4 in configure.ac * Share auth cookies in module-tunnel.c, module-x11-publish.c and native-protocol.c * disable TCP_NODELAY * publish auth cookie in module-x11-publish
-
-2004-11-04     Lennart Poettering
-       5844a33: some commenting change alogrithm for checking for configuration files
-       2aad9e3: compilation fix
-       344ced4: add some more comments
-       1f6a90c: fix client libaryr in case no latency interpolation is required
-
-2004-11-01     Lennart Poettering
-       cd3ba7d: Apply Joe Marcus Clarke's FreeBSD patches
-
-2004-10-30     Lennart Poettering
-       899788b: some updates for pa_hashmap add property infrastructure add module module-x11-publish allow ldpreloading of all modules abstract x11wrap from module-x11-bell
-
-2004-10-29     Lennart Poettering
-       4e5c44d: use setreuid() instead of setuid()/seteuid() when dropping root chdir to / on daemon startup (both are suggestions by alan cox)
-
-2004-10-28     Lennart Poettering
-       e34c65d: require newer libsndfile update todo file
-
-2004-10-27     Lennart Poettering
-       c82105d: prepare next release 0.6
-       1bcec3e: make autoload list use idxset
-       f252edb: minor updates
-       929104a: update todo
-       19f2acb: add null sink
-       49e16ff: latency calculation fix
-       ee452b0: two latency interpolation fixes
-       148202d: support for latency interpolation
-
-2004-10-24     Lennart Poettering
-       da45617: add user volume API
-
-2004-10-12     Lennart Poettering
-       a6471e2: gcc 2.95 fix default.pa fix
-
-2004-10-11     Lennart Poettering
-       6ede161: enlarge default buffers
-
-2004-10-01     Lennart Poettering
-       fde3d13: todo update
-
-2004-09-29     Lennart Poettering
-       68d50dc: add sample spec parameters to pacat
-       66999e5: Add support for libwrap
-       d092401: really fix API version API
-       6dfab4e: renamed module-tunnel to module-tunnel-sink new module module-tunnel-source fix recording
-
-2004-09-28     Lennart Poettering
-       d8f700e: fix module-tunnel for to aborting when connection fails
-       33c85ae: add latency measurement support to tunnel module
-       6f59ae1: Add module-tunnel add proper locking when autospawning a daemon
-
-2004-09-27     Lennart Poettering
-       450ad85: try to use file sample type for cache entries and play-file playback allow paplay to use STDIN add new module: module-match
-       f014d46: really fix cpu usage when using esddsp with polypaudio
-       35148d8: add POSIX locking to authkey.c fix esound protocol cpu consumption when finishing a stream
-
-2004-09-26     Lennart Poettering
-       949014e: add new tool paplay
-       5bac3c3: bum version number add new macro PA_API_VERSION for preprocessor level conditional compiling add new native APIs:      - counter       - cork & flush for record streams       - add flags parameters to pa_stream_connect_xx()        - new prebuf command    - time api, and total latency calculator        - return sample spec ability to cork source output streams dump server status on SIGHUP to syslog show sink input/source outputs status in cli-text.c don't flush esound output buffer when client disconnects move version api to polyplib-version.h
-
-2004-09-23     Lennart Poettering
-       405fac5: bump version number and update documentation
-       ed36241: allow high priority scheduling only for users in group "realtime"
-       8176b3a: ignore default.in
-       6d20544: place full binary path in default.pa's shebang line
-       dfcd161: Fix a bug in the build system reported by Iain Fothergill
-       9e3890a: OSX protability patches from Conrad Parker
-       03ee5e2: add support for capabilities
-
-2004-09-21     Lennart Poettering
-       370ff1d: improve esound module
-       12949d0: support for esd arguments: -spawnpid and -spawnfd
-       3e1bdac: add noop implementation of standby/resume ESOUND commands
-       df953a1: show which command is unknown in esound protocol fix esdcompat.sh
-
-2004-09-20     Lennart Poettering
-       7668418: add link to mailing list
-       4d9af54: build updates
-       2d87bd2: documentation update
-       bb31eda: fix xmms spawn bug
-       42bba49: update module descriptions
-
-2004-09-19     Lennart Poettering
-       b118982: remove obnoxious assert from module-combine tagstruct: add support for NULL strings improve pactl correct pa_bytes_snprint() pa_sample_spec_snprint(): don't fail on invalid sample spec rename PA_SAMPLE_SNPRINT_MAX_LENGTH to PA_SAMPLE_SPEC_SNPRINT_MAX
-       70a3053: add new function pa_mainloop_deferred_pending()
-
-2004-09-18     Lennart Poettering
-       29653ab: add pacat command line parsing
-       73125ad: work around gcc 2.95 limitation
-       4e31feb: work around gcc 2.95 limitation
-
-2004-09-17     Lennart Poettering
-       9ad4aa3: minor stuff
-       0b9bc03: change sysconf path
-       61ec86c: add resample_method option module-combine
-       0895356: add --resample-method argument
-       95612b6: rename some more
-       f077958: rename some stuff
-       24f3781: make daemon.conf/client.conf autogenerated
-       63b35d0: new configuration subsystem
-
-2004-09-16     Lennart Poettering
-       07d563d: update according to autoscan
-       078f2aa: gcc 2.95 compatibility, take 2
-       19294e4: fix two gcc 2.95 incompatibilities
-       daf3938: add support for subscribing to autoload table changes fix module-combine so that the sample rate of at least one streams is not changed from the original
-       f9e2058: add input latency measurement add GETOSPACE support to module-oss
-
-2004-09-15     Lennart Poettering
-       f5d47a2: work around C99/GCC incompatibility native protocol:   add "local" field to pa_context         add volume paramter to pa_stream_connect_playback       add support for renaming streams/clients        support lazy samples    add functions to kill clients/source inputs/sink outputs        add functions for loading/unloading modules     add autoload management API
-       9ca72dc: remove auto-load-sample stuff introduce "lazy samples"
-       8c110d9: correct autospawning
-
-2004-09-14     Lennart Poettering
-       935826f: make module-combine autoloadable clean up cli language introduce lazy sample cache
-       6e01979: add refernce counting for sinks, sources, sink-inputs and source-outputs
-       8c6593d: add module-combine remove option "stay-root" clean up pa_conf
-
-2004-09-13     Lennart Poettering
-       829656c: new configuration subsystem
-       fbefe67: correct latency calculation
-       1231598: fix parsing of POLYP_SERVER environment variable
-
-2004-09-12     Lennart Poettering
-       b1ab686: fix public= on native and esound protocol
-       b681622: build system update
-       b772564: update simple API
-       f05a4ac: extend pa_usec_t to 64 bit
-
-2004-09-11     Lennart Poettering
-       a9ca9c4: add modinfo support
-       11f0aae: add version number to library names
-
-2004-09-10     Lennart Poettering
-       2512346: add support for module search path as command line argument protocol-native: move first data request into ack of stream creation improve mainloop API: return the number of dispatched sources on iterate() fix a resampling bug introduce network latency measurement
-
-2004-09-08     Lennart Poettering
-       0c99fb3: add FAQ to homepage
-
-2004-09-07     Lennart Poettering
-       5fc0cf2: date fix
-       13248fd: documentation update
-       7000717: implemented new CLI command: dump add prefork() and postfork() arguments to pa_context_connect_spawn()
-       93c8fe6: change the way the default sink/source is selected
-
-2004-09-06     Lennart Poettering
-       0fa499d: add support for setting/getting default sink/source via native protocol
-       3536be4: correct a recording bug in native protocol
-       566e469: add module-pipe-source
-
-2004-09-05     Lennart Poettering
-       6c4fd62: implement proper logging
-
-2004-09-04     Lennart Poettering
-       57e473b: add support for automatic termination of the daemon after the last client quit remove all gcc warnings add boolean types for tagstruct and modargs
-
-2004-09-03     Lennart Poettering
-       fb962b6: add option to disallow module loading after startup
-       4a9239f: add CPU load limiter
-
-2004-09-01     Lennart Poettering
-       c73a298: add total sample cache size to statistics add size to sample cache entry info
-       5f52999: make use F_CLOEXEC wherever useful
-       3487387: daemon auto spawn
-       ee91cb6: add esd compatible startup script add default configuration script
-       dfd440b: add sound file streaming
-       50f592b: introduce sink input and source output limits
-       0205fc5: add PA_MININFTY
-       63c76bd: cleanup comment
-       9939fba: add \since to dB functions
-       9c4fd2a: add support for dB volumes
-       fa19d6a: implement missing scache_get_id_by_name add some more consts to idxset add module-sine, a sine generating sink_input module
-       36550f4: remove most -W compiler warnings
-       34fe8bd: add support for SCHED_FIFO
-
-2004-08-27     Lennart Poettering
-       9618aea: fix module path
-       8c887ab: fix homepage script
-       5020326: minor fixes
-       b014340: readme update (licensing)
-       4efa9d1: add LGPL/GPL to dist package
-       41d8c13: relicense client library to LGPL
-       8cb1cab: document every polyplib function
-       761a895: minor cleanups
-       92bf0a3: latency work major main loop bugfix
-
-2004-08-23     Lennart Poettering
-       b6b428e: minor documentation update
-
-2004-08-22     Lennart Poettering
-       41295bb: new features:   future cancellation   corking   flushing for playback streams in native protocol
-
-2004-08-20     Lennart Poettering
-       ea4805a: add pkg config file glib12-mainloop
-       5e8bb14: add support for glib12
-       669452e: documentation update
-       8c756d5: documentation update
-       9b5ba2b: doxygen fix
-       0b9f91d: readme update
-       8f90450: Doxygen stuff
-       6bc5340: build fixes
-
-2004-08-19     Lennart Poettering
-       f9b58fb: move sample cache to namereg documentation
-       e0fe68a: minor stuff
-
-2004-08-18     Lennart Poettering
-       befd734: add version routines to polyplib
-
-2004-08-17     Lennart Poettering
-       ac59518: add missing copyright headers
-       e75b657: remove global memblock statistic variables in favor of memblock_stat objects
-       81822a7: fix x11 build disable prebuf on drain
-       2d6d3e5: todo update
-       711de8d: autoconf beefup build fixes
-       ca2265f: Documentation work add pkg-config support for GLIB main loop
-       f693aa4: remove native-common-internal
-       bee750b: create native-common-internal.h
-       aff43dd: update todo file
-       a0d54dd: make clitext to cli-text renaming complete
-       e4be616: rename clitext to cli-text
-
-2004-08-16     Lennart Poettering
-       126fede: fix sink iunput and source output stuff
-       369a908: add sink input/source output support to the native protocol
-
-2004-08-15     Lennart Poettering
-       efc3491: add support for volume manipulation
-       c175451: proper ref counting for more objects some documentation update
-
-2004-08-14     Lennart Poettering
-       22cb23e: implement proper refcounting in polyplib split polyplib to multiple modules add some prelimenary documentation add doxygen support
-
-2004-08-13     Lennart Poettering
-       1c2ec47: rename polyplib-sample to polyplib-scache
-       50b9fc2: add polyplib-sample.c
-       56bcba9: add polyplib-sample
-       821afd6: add internal header file for polyplib
-       79a4e75: split polyplib.h
-       7b52d5d: some preliminary cleanup
-
-2004-08-12     Lennart Poettering
-       cd5809c: todo fix
-       886041a: add more subscription events add support for clients/modules in native protocol
-
-2004-08-11     Lennart Poettering
-       cbfaf40: info and subscription work
-       b297d0b: todo update
-       3d374e9: add subscription subsystem
-
-2004-08-10     Lennart Poettering
-       fc618e9: compile fix
-       37d930a: glib mainloop fix implement server status command support for sink_list/source_list in polyplib
-
-2004-08-07     Lennart Poettering
-       e9bed20: better mainloop test build system
-       209c9dd: rename mainloop testing tool
-       6f0936f: cleanup priority management in main loop
-
-2004-08-06     Lennart Poettering
-       68eb5dd: add mainloop test utility fix glib mainloop support
-
-2004-08-05     Lennart Poettering
-       964bdfd: add initial glib mainloop adapter clean up mainloop API
-
-2004-08-04     Lennart Poettering
-       839f99f: forgot some files
-       46091a9: introduce pa_xmalloc() and friends implement module auto loading
-
-2004-08-03     Lennart Poettering
-       24291af: sample cache work
-
-2004-08-02     Lennart Poettering
-       e10b918: add support for querying sample ist with esound protocol
-       8705af7: add new module "module-x11-bell" fix scache memory leak
-
-2004-07-20     Lennart Poettering
-       5a694fd: add a todo item
-       bb0b105: sample cache work
-
-2004-07-18     Lennart Poettering
-       527faf0: minor fixes
-
-2004-07-17     Lennart Poettering
-       8540718: readme update
-       765d2f7: two simple fixes
-       d6d50b0: some makefile fixes
-       78a799e: make distcheck clean
-       141ab85: make polypaudio run when installed update docs
-       6601d95: fix Makefile.am and configure.ac to match directory renaming
-       41f6aea: rename src to polyp
-       563201e: rename configuration file make sure the todo file is packaged
-       86f5b30: move todo file
-       539eb02: ignore README
-       7b8c329: add documentation
-
-2004-07-16     Lennart Poettering
-       3e379ca: add pkgconfig stuff
-       cf965cb: add missing liecenses
-       e0d510d: include copyright and svn tag in *.[ch]
-       b5384e0: include config.h in every file
-       dc812da: fix distcheck
-       005cb3e: adjust file references due to renaming
-       2a6ee77: rename a bunch of files
-       00b53f3: make a symbol in module-ptorocol-stub static
-       554b01b: make oss sample spec configurable
-       74bbf31: implement alsa source split off alsa-util.c
-       f2e08d5: split PA_SAMPLE_FLOAT32 into PA_SAMPLE_FLOAT{LE,BE} add more configuration arguments to alsa sink
-       b8eb0c0: add alsa sink
-
-2004-07-15     Lennart Poettering
-       b240564: optimize esound latency for xmms
-       710233b: implement get_latency native command
-       d8f1300: add pactl tool
-       c36dadd: remove global exported variables:   pa_memblock statistics   pa_default_sample_spec
-       1a6fea2: implement daemonizing
-       ed9bd5f: fix modargs memory leak
-       1416fef: implement client side TCP support
-
-2004-07-14     Lennart Poettering
-       e83b710: update todo fix polypaudio.run
-       e61e924: complete implementation of the command line
-
-2004-07-12     Lennart Poettering
-       b69178b: add preliminary command line parsing
-
-2004-07-11     Lennart Poettering
-       d4e0d51: make module-oss-* use modargs
-       216591d: make the protocol plugins make use of modargs
-       a96ed34: rename hashset to hashmap add module arguments parse in modargs.c make module-pipe-sink use it
-       ccfd554: add dependency script fix some dependencies split off socket-util.c and clitext.c
-
-2004-07-10     Lennart Poettering
-       c7bd759: add description field for sinks/sources add owner field to all entities add client file to source outputs and sink inputs
-       0253896: make memblockq merge chunks
-       5ee3a59: forgot to add parec-simple
-       5ea96e3: implement parec-simple and matching simple recording API add support for killing source outputs in native protocol fix channel management in client library
-       70bb816: implement recording in native API fix a memory leak in memblock.c
-
-2004-07-09     Lennart Poettering
-       cffc776: fix recording for simpel and esound protocols
-
-2004-07-07     Lennart Poettering
-       863fb90: add output stream draining
-       e8d1185: draining ind native protocol fixes in callback code on object destruction simple protocol
-
-2004-07-06     Lennart Poettering
-       f8cbde5: auth support in esound and native AUTH and SET_NAME operatins in native simple library
-
-2004-07-04     Lennart Poettering
-       722c2c8: add kill_* and default_* commands to CLI make module-cli unload itself on EOF clean up stdio usage add sink pointer to monitor sources
-
-2004-07-03     Lennart Poettering
-       e61c2dd: add pa_ prefix to all identifiers. fix downsampling/resampling add support for U8 samples
-       a8a5ab1: fix minor typo
-       3ac2437: add libsamplerate dependency
-       253c540: forgot to add memchunk.[ch]
-       741aa44: add resampling
-
-2004-07-02     Lennart Poettering
-       13b35a2: add resampler
-
-2004-06-30     Lennart Poettering
-       961fb44: latency esound volume changing
-
-2004-06-29     Lennart Poettering
-       d571be6: volume work
-       e31bac0: extended esound protocol
-       ef422fa: esound protocol
-
-2004-06-27     Lennart Poettering
-       a74cd2a: add name registrar
-       0103786: make native playback work
-       57dc427: many fixes
-
-2004-06-24     Lennart Poettering
-       1ad4ff1: some fixes
-
-2004-06-23     Lennart Poettering
-       a1b59db: make rename of oss.[ch] to oss-util.[ch] complete
-       c050d72: rename oss.[ch] to oss-util.[ch]
-       b9e0fa8: minor compile work
-       3b50a7c: ignore some more stuff
-       acb25b3: main part of the native protocol
-
-2004-06-20     Lennart Poettering
-       eecf602: partial implementation of native protocol
-
-2004-06-19     Lennart Poettering
-       a84f38e: mofiy keyword expansion
-       81447ed: cli protocol
-       6eddcc2: rename module-simple-protocol to module-protocol-stub
-       787bf6c: minor work
-       b4e3f5c: add simple ptorocol with unix
-       56f8c95: some more work on the cli
-
-2004-06-18     Lennart Poettering
-       382e7ae: some more work
-       993d1bc: basic cli interface
-
-2004-06-16     Lennart Poettering
-       eb946db: configure fix
-       4b86ff0: got mmap oss output working
-
-2004-06-15     Lennart Poettering
-       a8f7881: fix mixing
-       b24546b: cleanup
-       78f386a: more work
-       98f41f1: minor work
-       1a50607: oss output works
-
-2004-06-14     Lennart Poettering
-       bfcde99: rename some more
-       f78e9b6: commit some work and rename
-       0575fc6: remove oss.c
-       5ce2048: more cleanups
-       c8cf0c1: a bunch of fixes
-
-2004-06-11     Lennart Poettering
-       edfad83: remove moddep files (since they are obsolete)
-       7dfeb1f: make the whole stuff run and clean it self up again
-       aae40dc: module dependencie foo
-       8584356: ignore fix
-       9e3ad23: autoconf
-
-2004-06-10     Lennart Poettering
-       a5daff7: make it compile
diff --git a/LICENSE b/LICENSE
index f8fdb7a..cd5e42f 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -1,18 +1,30 @@
 All PulseAudio source files are licensed under the GNU Lesser General Public
 License. (see file LGPL for details)
 
-However, the server side links to the GPL-only library 'libsamplerate' which
-practically downgrades the license of the server part to GPL (see file GPL for
-details), exercising section 3 of the LGPL.
+However, the server side has optional GPL dependencies.  These include the
+libsamplerate and gdbm (core libraries), LIRC (lirc module), FFTW (equalizer
+module) and bluez (bluetooth proximity helper program) libraries, although
+others may also be included in the future.  If PulseAudio is compiled with these
+optional components, this effectively downgrades the license of the server part
+to GPL (see the file GPL for details), exercising section 3 of the LGPL.  In
+such circumstances, you should treat the client library (libpulse) of PulseAudio
+as being LGPL licensed and the server part (libpulsecore) as being GPL licensed.
+Since the PulseAudio daemon, tests, various utilities/helpers and the modules
+link to libpulsecore and/or the afore mentioned optional GPL dependencies they
+are of course also GPL licensed also in this scenario.
 
-Hence you should treat the client library ('libpulse') of PulseAudio as being
-LGPL licensed and the server part ('libpulsecore') as being GPL licensed. Since
-the PulseAudio daemon and the modules link to 'libpulsecore' they are of course
-also GPL licensed.
+Andre Adrian's echo cancellation implementation is licensed under a less
+restrictive license - see src/modules/echo-cancel/adrian-license.txt for
+details.
 
--- Lennart Poettering, April 20th, 2006.
+Some other files pulled into PA source (i.e. reference implementations that are
+considered too small and stable to be considered as an external library) use the
+more permissive MIT license. This include the device reservation DBus protocol
+and realtime kit implementations.
 
-GPL CODE (see file GPL for details) :
-       src/modules/bluetooth/proximity-helper.c
+Additionally, a more permissive Sun license is used for code that performs
+u-law, A-law and linear PCM conversions.
 
--- August 23rd, 2011.
+While we attempt to provide a summary here, it is the ultimate responsibility of
+the packager to ensure the components they use in their build of PulseAudio
+meets their license requirements.
index bb5cacd..53e1c7d 100644 (file)
@@ -26,20 +26,31 @@ EXTRA_DIST = \
        doxygen/Makefile.am \
        doxygen/Makefile.in \
        doxygen/doxygen.conf.in \
+       PROTOCOL \
        README \
        todo \
-       vala/libpulse.vapi
-
-SUBDIRS = libltdl src doxygen man po
+       shell-completion/pulseaudio-zsh-completion.zsh \
+       .gitignore \
+       doxygen/.gitignore \
+       m4/.gitignore \
+       man/.gitignore \
+       po/.gitignore \
+       src/.gitignore \
+       src/daemon/.gitignore \
+       src/pulse/.gitignore
+
+SUBDIRS = src doxygen man po
 
 MAINTAINERCLEANFILES =
 noinst_DATA =
 
 vapidir = $(datadir)/vala/vapi
-vapi_DATA = vala/libpulse.vapi
+dist_vapi_DATA = \
+               vala/libpulse.deps vala/libpulse.vapi \
+               vala/libpulse-mainloop-glib.deps vala/libpulse-mainloop-glib.vapi
 
 pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libpulse.pc libpulse-simple.pc
+pkgconfig_DATA = libpulse.pc libpulse-simple.pc pulsecore.pc
 
 filterdir = /etc/pulse/filter
 filter_DATA = filter/filter_44100_48000.dat \
@@ -47,20 +58,22 @@ filter_DATA = filter/filter_44100_48000.dat \
              filter/filter_48000_44100.dat \
              filter/filter_8000_44100.dat
 
-if HAVE_AVAHI
-pkgconfig_DATA += \
-        libpulse-browse.pc
-endif
-
 if HAVE_GLIB20
 pkgconfig_DATA += \
         libpulse-mainloop-glib.pc
 endif
 
+cmakedir = $(libdir)/cmake/PulseAudio
+cmake_DATA = PulseAudioConfig.cmake PulseAudioConfigVersion.cmake
+
+bashcompletiondir=$(sysconfdir)/bash_completion.d
+dist_bashcompletion_DATA = shell-completion/pulseaudio-bash-completion.sh
+
 homepage: all dist doxygen
        test -d $$HOME/homepage/private
        mkdir -p $$HOME/homepage/private/projects/pulseaudio $$HOME/homepage/private/projects/pulseaudio/doxygen
        cp pulseaudio-@PACKAGE_VERSION@.tar.gz $$HOME/homepage/private/projects/pulseaudio
+       cp pulseaudio-@PACKAGE_VERSION@.tar.gz $$HOME/git.fedora/pulseaudio
        cp -a doxygen/html/* $$HOME/homepage/private/projects/pulseaudio/doxygen
 
 doxygen:
@@ -73,15 +86,14 @@ untabify:
        find \( -name '*.c' -o -name '*.h' \) -exec perl -i -pe 's/\t/        /g;' \{\} \;
 
 fedora-snapshot: dist
-       cp $(distdir).tar.gz $$HOME/cvs.fedora/pulseaudio/devel/$(distdir).tar.gz
+       cp $(distdir).tar.gz $$HOME/git.fedora/pulseaudio/$(distdir).tar.gz
 
 dist-hook:
-       if test -d .git ; then \
-               test -z $$SKIP_GIT && git pull ; \
-               chmod u+w ${distdir}/ChangeLog || true ; \
-               ( git-changelog.perl || echo "git-changelog.perl failed." ) > ${distdir}/ChangeLog 2>&1 ; \
-       fi
        echo $(VERSION) > $(distdir)/.tarball-version
+       echo $(VERSION) > $(distdir)/.version
+
+check-daemon:
+       $(MAKE) -C src check-daemon
 
 .PHONY: homepage distcleancheck doxygen
 
@@ -92,3 +104,5 @@ $(top_srcdir)/.version:
 
 DISTCLEANFILES = \
         po/.intltool-merge-cache
+
+DISTCHECK_CONFIGURE_FLAGS = --with-udev-rules-dir="$$dc_install_base/lib/udev/rules.d"
diff --git a/PROTOCOL b/PROTOCOL
new file mode 100644 (file)
index 0000000..185b91a
--- /dev/null
+++ b/PROTOCOL
@@ -0,0 +1,349 @@
+### v8, implemented by >= 0.8
+
+First version supported.
+
+### v9, implemented by >= 0.9.0
+
+Reply for PA_COMMAND_CREATE_PLAYBACK_STREAM,
+PA_COMMAND_CREATE_RECORD_STREAM now returns buffer_attrs that are used:
+
+Four new fields in reply of PA_COMMAND_CREATE_PLAYBACK_STREAM:
+
+   maxlength
+   tlength
+   prebuf
+   minreq
+
+Two new fields in reply of PA_COMMAND_CREATE_RECORD_STREAM:
+
+   maxlength
+   fragsize
+
+### v10, implemented by >= 0.9.5
+
+New opcodes:
+
+ PA_COMMAND_MOVE_SINK_INPUT
+ PA_COMMAND_MOVE_SOURCE_OUTPUT
+
+SHM data transfer support
+
+### v11, implemented by >= 0.9.7
+
+Reply to to PA_COMMAND_GET_SINK_INPUT_INFO, PA_COMMAND_GET_SINK_INPUT_INFO_LIST gets new field at the end:
+
+ mute
+
+New opcodes:
+
+ PA_COMMAND_SET_SINK_INPUT_MUTE
+ PA_COMMAND_SUSPEND_SINK
+ PA_COMMAND_SUSPEND_SOURCE
+
+### v12, implemented by >= 0.9.8
+
+S32LE, S32BE is now known as sample spec.
+
+Gained six new bool fields for PA_COMMAND_CREATE_PLAYBACK_STREAM, PA_COMMAND_CREATE_RECORD_STREAM request at the end:
+
+ no_remap_channels
+ no_remix_channels
+ fix_format
+ fix_rate
+ fix_channels
+ no_move
+ variable_rate
+
+Reply to these opcodes now includes:
+
+ sample_spec
+ channel_map
+ device_index
+ device_name
+ suspended
+
+New opcodes for changing buffer attrs:
+
+ PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR
+ PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR
+
+New opcodes for changing sampling rate:
+
+ PA_COMMAND_UPDATE_PLAYBACK_STREAM_SAMPLE_RATE
+ PA_COMMAND_UPDATE_RECORD_STREAM_SAMPLE_RATE
+
+New opcodes for notifications:
+
+ PA_COMMAND_PLAYBACK_STREAM_SUSPENDED
+ PA_COMMAND_CAPTURE_STREAM_SUSPENDED
+ PA_COMMAND_PLAYBACK_STREAM_MOVED
+ PA_COMMAND_CAPTURE_STREAM_MOVED
+
+### v13, implemented by >= 0.9.11
+
+New fields for PA_COMMAND_CREATE_PLAYBACK_STREAM, PA_COMMAND_CREATE_RECORD_STREAM request at the end:
+
+ peak_detect (bool)
+ adjust_latency  (bool)
+
+Replace field "name" for PA_COMMAND_CREATE_PLAYBACK_STREAM, PA_COMMAND_CREATE_RECORD_STREAM at the end:
+
+ proplist
+
+Replace field "name" for PA_COMMAND_SET_CLIENT_NAME request at the end:
+
+ proplist
+
+On response of PA_COMMAND_SET_CLIENT_NAME:
+
+ client_index
+
+New proplist field for sink, source, sink input, source output introspection opcodes and at the end:
+
+ proplist
+
+New opcodes for proplist modifications
+
+  PA_COMMAND_UPDATE_RECORD_STREAM_PROPLIST
+  PA_COMMAND_UPDATE_PLAYBACK_STREAM_PROPLIST
+  PA_COMMAND_UPDATE_CLIENT_PROPLIST
+  PA_COMMAND_REMOVE_RECORD_STREAM_PROPLIST
+  PA_COMMAND_REMOVE_PLAYBACK_STREAM_PROPLIST
+  PA_COMMAND_REMOVE_CLIENT_PROPLIST
+
+New field for PA_COMMAND_PLAY_SAMPLE:
+
+  proplist
+
+New field for PA_COMMAND_PLAY_SAMPLE response:
+
+  idx
+
+New field for PA_COMMAND_CREATE_PLAYBACK_STREAM at the end:
+
+  start_muted
+
+Buffer attributes for PA_COMMAND_CREATE_PLAYBACK_STREAM and
+PA_COMMAND_CREATE_RECORD_STREAM may now be 0 for default values.
+
+New field for PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR,
+PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR at the end:
+
+  adjust_latency (bool)
+
+new message:
+
+  PA_COMMAND_STARTED
+
+### v14, implemented by >= 0.9.12
+
+new message:
+
+  PA_COMMAND_EXTENSION
+
+PA_COMMAND_CREATE_PLAYBACK_STREAM:
+
+  bool volume_set at the end
+
+PA_COMMAND_CREATE_RECORD_STREAM, PA_COMMAND_CREATE_PLAYBACK_STREAM:
+
+  bool early_requests at the end
+
+New field for PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR,
+PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR at the end:
+
+  early_requests (bool)
+
+### v15, implemented by >= 0.9.15
+
+PA_COMMAND_CREATE_PLAYBACK_STREAM
+
+  bool muted at the end
+
+PA_COMMAND_CREATE_PLAYBACK_STREAM, PA_COMMAND_CREATE_RECORD_STREAM:
+
+  bool dont_inhibit_auto_suspend at the end
+
+PA_COMMAND_GET_MODULE_INFO_LIST
+
+  remove bool auto_unload
+  add proplist at the end
+
+new messages:
+
+  PA_COMMAND_GET_CARD_INFO
+  PA_COMMAND_GET_CARD_INFO_LIST
+  PA_COMMAND_SET_CARD_PROFILE
+
+  PA_COMMAND_CLIENT_EVENT
+  PA_COMMAND_PLAYBACK_STREAM_EVENT
+  PA_COMMAND_RECORD_STREAM_EVENT
+
+  PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED
+  PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED
+
+### v16, implemented by >= 0.9.15
+
+new messages:
+
+  PA_COMMAND_SET_SINK_PORT
+  PA_COMMAND_SET_SOURCE_PORT
+
+## v17, implemented by >= 0.9.20
+
+new flag at end of CREATE_PLAYBACK_STREAM:
+
+    bool relative_volume
+
+## v18, implemented by >= 0.9.22
+
+new flag at end of CREATE_PLAYBACK_STREAM:
+
+    bool passthrough
+
+## v19, implemented by >= 0.9.22
+
+New flag at the end of sink input and source output introspection data:
+
+    bool corked
+
+## v20, implemented by >= 1.0
+
+Two new flags at the end of sink input introspection data:
+
+    bool has_volume
+    bool volume_writable
+
+## v21, implemented by >= 1.0
+
+Changes for format negotiation in the extended API.
+
+New fields PA_COMMAND_CREATE_PLAYBACK_STREAM:
+
+    uint8_t n_formats
+    format_info format1
+    ...
+    format_info formatn
+
+One new field in reply from PA_COMMAND_CREATE_PLAYBACK_STREAM:
+
+    format_info format
+
+New fields in reply from PA_COMMAND_GET_SINK_INFO (and thus
+PA_COMMAND_GET_SINK_INFO_LIST)
+
+    uint8_t n_formats
+    format_info format1
+    ...
+    format_info formatn
+
+One new field in reply from PA_COMMAND_GET_SINK_INPUT_INFO (and thus
+PA_COMMAND_GET_SINK_INPUT_INFO_LIST)
+
+    format_info format
+
+## v22, implemented by >= 1.0
+
+New fields PA_COMMAND_CREATE_RECORD_STREAM:
+
+    uint8_t n_formats
+    format_info format1
+    ...
+    format_info formatn
+    volume
+    bool muted
+    bool volume_set
+    bool muted_set
+    bool relative_volume
+    bool passthrough
+
+One new field in reply from PA_COMMAND_CREATE_RECORD_STREAM:
+
+    format_info format
+
+New fields in reply from PA_COMMAND_GET_SOURCE_INFO (and thus
+PA_COMMAND_GET_SOURCE_INFO_LIST)
+
+    uint8_t n_formats
+    format_info format1
+    ...
+    format_info formatn
+
+Five new fields in reply from PA_COMMAND_GET_SOURCE_OUTPUT_INFO (and thus
+PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST)
+
+    volume
+    bool mute
+    bool has_volume
+    bool volume_writable
+    format_info format
+
+## v23, implemented by >= 1.0
+
+New field in PA_COMMAND_UNDERFLOW:
+
+    int64_t index
+
+## v24, implemented by >= 2.0
+
+New field in all commands that send/receive port introspection data
+(PA_COMMAND_GET_(SOURCE|SINK)_INFO,
+PA_COMMAND_GET_(SOURCE|SINK)_INFO_LIST):
+
+    uint32_t available
+
+The field is added once for every port.
+
+## v25, implemented by >= 2.0
+
+When port availability changes, send a subscription event for the
+owning card.
+
+## v26, implemented by >= 2.0
+
+In reply from PA_COMMAND_GET_CARD_INFO (and thus
+PA_COMMAND_GET_CARD_INFO_LIST), the following is added:
+
+    uint32_t n_ports
+
+...followed by n_ports extended port entries, which look like this:
+
+    string name
+    string description
+    uint32_t priority
+    uint32_t available
+    uint8_t direction
+    proplist
+    uint32_t n_profiles
+    string profile_name_1
+    ...
+    string profile_name_n
+
+Profile names must match earlier sent profile names for the same card.
+
+## v27, implemented by >= 3.0
+
+New opcodes:
+    PA_COMMAND_SET_PORT_LATENCY_OFFSET
+
+New field in the card commands that send/receive port introspection data
+PA_COMMAND_GET_CARD_INFO(_LIST)):
+
+    int64_t latency_offset
+
+The field is added once for every port.
+
+## v28, implemented by >= 4.0
+
+New value for encoding format type in format_info
+PA_COMMAND_CREATE_(PLAYBACK|RECORDING)_STREAM and its reply,
+In reply from PA_COMMAND_GET_(SOURCE|SOURCE_OUTPUT|SINK|SINK_INPUT)_INFO[_LIST],
+SUBCOMMAND_SAVE_FORMATS, in reply from SUBCOMMAND_READ_FORMATS[_ALL]
+
+    (uint8_t ) PA_ENCODING_MPEG2_AAC_IEC61937 := 6
+
+#### If you just changed the protocol, read this
+## module-tunnel depends on the sink/source/sink-input/source-input protocol
+## internals, so if you changed these, you might have broken module-tunnel.
+## Don't forget to test module-tunnel-{source,sink} when pushing protocol
+## changes.
diff --git a/PulseAudioConfig.cmake.in b/PulseAudioConfig.cmake.in
new file mode 100644 (file)
index 0000000..191eb67
--- /dev/null
@@ -0,0 +1,12 @@
+set(PULSEAUDIO_FOUND TRUE)
+
+set(PULSEAUDIO_VERSION_MAJOR @PA_MAJOR@)
+set(PULSEAUDIO_VERSION_MINOR @PA_MINOR@)
+set(PULSEAUDIO_VERSION @PA_MAJOR@.@PA_MINOR@)
+set(PULSEAUDIO_VERSION_STRING "@PA_MAJOR@.@PA_MINOR@")
+
+find_path(PULSEAUDIO_INCLUDE_DIR pulse/pulseaudio.h HINTS "@PA_INCDIR@")
+find_library(PULSEAUDIO_LIBRARY NAMES pulse libpulse HINTS "@PA_LIBDIR@")
+ifelse(@HAVE_GLIB20@, 1, dnl
+find_library(PULSEAUDIO_MAINLOOP_LIBRARY NAMES pulse-mainloop-glib libpulse-mainloop-glib HINTS "@PA_LIBDIR@")
+)dnl
diff --git a/PulseAudioConfigVersion.cmake.in b/PulseAudioConfigVersion.cmake.in
new file mode 100644 (file)
index 0000000..e2947de
--- /dev/null
@@ -0,0 +1,11 @@
+set(PACKAGE_VERSION @PA_MAJOR@.@PA_MINOR@)
+
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+  set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+  set(PACKAGE_VERSION_COMPATIBLE TRUE)
+  if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+    set(PACKAGE_VERSION_EXACT TRUE)
+  endif( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+endif("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+
diff --git a/README b/README
index 43cd265..66c1847 100644 (file)
--- a/README
+++ b/README
@@ -4,19 +4,19 @@ WEB SITE:
        http://pulseaudio.org/
 
 GIT:
-       git://git.0pointer.de/pulseaudio.git
+       git://anongit.freedesktop.org/pulseaudio/pulseaudio
 
-GITWEB:
-       http://git.0pointer.de/?p=pulseaudio.git;a=summary
+GITWEB/CGIT:
+       http://cgit.freedesktop.org/pulseaudio/pulseaudio/
 
 MAILING LIST:
-       https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
+       http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
 
 GIT COMMITS MAILING LIST:
-       https://tango.0pointer.de/mailman/listinfo/pulseaudio-commits
+       http://lists.freedesktop.org/mailman/listinfo/pulseaudio-commits
 
-TRAC TICKET CHANGES MAILING LIST:
-       https://tango.0pointer.de/mailman/listinfo/pulseaudio-tickets
+TRAC/BUGZILLA TICKET CHANGES MAILING LIST:
+       http://lists.freedesktop.org/mailman/listinfo/pulseaudio-bugs
 
 IRC:
        #pulseaudio on irc.freenode.org
@@ -33,5 +33,14 @@ OHLOH:
 AUTHORS:
        Several
 
-GPL CODE (see file GPL for details) :
-       src/modules/bluetooth/proximity-helper.c
+HACKING:
+       In order to run pulseaudio from the build dir __OPTIMIZE__ should be
+       disabled (look at src/pulsecore/core-util.h::pa_run_from_build_tree()),
+       this can be done by passing "CFLAGS=-O0" to the configure script:
+         ./autogen.sh
+         CFLAGS="-ggdb3 -O0" LDFLAGS="-ggdb3" ./configure
+         make
+         ./src/pulseaudio -n -F src/default.pa -p $(pwd)/src/
+
+SPELLING:
+        PulseAudio
diff --git a/autogen.sh b/autogen.sh
deleted file mode 100755 (executable)
index 45f7073..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-aclocal -I m4
-autoheader
-autoconf
-libtoolize --force --copy
-automake -a -c --foreign
index c7c8582..d0baf95 100755 (executable)
@@ -45,6 +45,7 @@ case $(uname) in
                LIBTOOLIZE="glibtoolize"
                ;;
 esac
+test "x$LIBTOOLIZE" = "x" && LIBTOOLIZE=libtoolize
 
 if [ -f .git/hooks/pre-commit.sample -a ! -f .git/hooks/pre-commit ] ; then
     cp -p .git/hooks/pre-commit.sample .git/hooks/pre-commit && \
@@ -63,9 +64,15 @@ fi
 # configure file faulty.
 if ! pkg-config --version &>/dev/null; then
     echo "pkg-config is required to bootstrap this program" &>/dev/null
-    exit 1
+    DIE=1
 fi
 
+# Other necessary programs
+glib-gettextize --version >/dev/null || DIE=1
+intltoolize --version >/dev/null || DIE=1
+$LIBTOOLIZE --version >/dev/null || DIE=1
+test "$DIE" = 1 && exit 1
+
 if type -p colorgcc > /dev/null ; then
    export CC=colorgcc
 fi
@@ -78,14 +85,11 @@ else
     rm -f config.cache
 
     rm -f Makefile.am~ configure.ac~
-    # Evil, evil, evil, evil hack
-    sed 's/read dummy/\#/' `which gettextize` | bash -s -- --copy --force
+    glib-gettextize --copy --force
     test -f Makefile.am~ && mv Makefile.am~ Makefile.am
     test -f configure.ac~ && mv configure.ac~ configure.ac
 
     touch config.rpath
-    test "x$LIBTOOLIZE" = "x" && LIBTOOLIZE=libtoolize
-
     intltoolize --copy --force --automake
     "$LIBTOOLIZE" -c --force
     run_versioned aclocal "$VERSION" -I m4
diff --git a/build/orc.mak b/build/orc.mak
deleted file mode 100644 (file)
index 90d403a..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#
-# This is a makefile.am fragment to build Orc code.
-#
-# Define ORC_SOURCE and then include this file, such as:
-#
-#  ORC_SOURCE=gstadderorc
-#  include $(top_srcdir)/common/orc.mak
-#
-# This fragment will create tmp-orc.c and gstadderorc.h from
-# gstadderorc.orc.
-#
-# When 'make dist' is run at the top level, or 'make orc-update'
-# in a directory including this fragment, the generated source
-# files will be copied to $(ORC_SOURCE)-dist.[ch].  These files
-# should be checked in to git, since they are used if Orc is
-# disabled.
-#
-# Note that this file defines BUILT_SOURCES, so any later usage
-# of BUILT_SOURCES in the Makefile.am that includes this file
-# must use '+='.
-#
-
-
-EXTRA_DIST += $(ORC_SOURCE).orc
-
-ORC_NODIST_SOURCES = tmp-orc.c $(ORC_SOURCE).h
-BUILT_SOURCES += tmp-orc.c $(ORC_SOURCE).h
-
-
-orc-update: tmp-orc.c $(ORC_SOURCE).h
-       cp tmp-orc.c $(srcdir)/$(ORC_SOURCE)-dist.c
-       cp $(ORC_SOURCE).h $(srcdir)/$(ORC_SOURCE)-dist.h
-
-orcc_v_gen = $(orcc_v_gen_$(V))
-orcc_v_gen_ = $(orcc_v_gen_$(AM_DEFAULT_VERBOSITY))
-orcc_v_gen_0 = @echo "  ORCC   $@";
-
-cp_v_gen = $(cp_v_gen_$(V))
-cp_v_gen_ = $(cp_v_gen_$(AM_DEFAULT_VERBOSITY))
-cp_v_gen_0 = @echo "  CP     $@";
-
-if HAVE_ORC
-tmp-orc.c: $(srcdir)/$(ORC_SOURCE).orc
-       $(orcc_v_gen)$(ORCC) --implementation -o $(builddir)/tmp-orc.c $(srcdir)/$(ORC_SOURCE).orc
-
-$(ORC_SOURCE).h: $(srcdir)/$(ORC_SOURCE).orc
-       mkdir -p $$(dirname $(builddir)/$(ORC_SOURCE).h)
-       $(orcc_v_gen)$(ORCC) --header -o $(builddir)/$(ORC_SOURCE).h $(srcdir)/$(ORC_SOURCE).orc
-else
-tmp-orc.c: $(srcdir)/$(ORC_SOURCE).orc
-       $(cp_v_gen)cp $(srcdir)/$(ORC_SOURCE)-dist.c tmp-orc.c
-
-$(ORC_SOURCE).h: $(srcdir)/$(ORC_SOURCE).orc
-       $(cp_v_gen)cp $(srcdir)/$(ORC_SOURCE)-dist.h $(ORC_SOURCE).h
-endif
-
-clean-local: clean-orc
-.PHONY: clean-orc
-clean-orc:
-       rm -f tmp-orc.c $(ORC_SOURCE).h
-
-dist-hook: dist-hook-orc
-.PHONY: dist-hook-orc
-dist-hook-orc: tmp-orc.c $(ORC_SOURCE).h
-       rm -f tmp-orc.c~
-       cmp -s tmp-orc.c $(srcdir)/$(ORC_SOURCE)-dist.c || \
-         cp tmp-orc.c $(srcdir)/$(ORC_SOURCE)-dist.c
-       cmp -s $(ORC_SOURCE).h $(srcdir)/$(ORC_SOURCE)-dist.h || \
-         cp $(ORC_SOURCE).h $(srcdir)/$(ORC_SOURCE)-dist.h
-       mkdir -p $$(dirname $(ORC_SOURCE))
-       cp -p $(srcdir)/$(ORC_SOURCE)-dist.c $(distdir)/$$(dirname $(ORC_SOURCE))
-       cp -p $(srcdir)/$(ORC_SOURCE)-dist.h $(distdir)/$$(dirname $(ORC_SOURCE))
diff --git a/compile b/compile
new file mode 100755 (executable)
index 0000000..862a14e
--- /dev/null
+++ b/compile
@@ -0,0 +1,343 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-03-05.13; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009, 2010, 2012 Free
+# Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program 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 General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" ""       $nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[!/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+       # lazily determine how to convert abs files
+       case `uname -s` in
+         MINGW*)
+           file_conv=mingw
+           ;;
+         CYGWIN*)
+           file_conv=cygwin
+           ;;
+         *)
+           file_conv=wine
+           ;;
+       esac
+      fi
+      case $file_conv/,$2, in
+       *,$file_conv,*)
+         ;;
+       mingw/*)
+         file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+         ;;
+       cygwin/*)
+         file=`cygpath -m "$file" || echo "$file"`
+         ;;
+       wine/*)
+         file=`winepath -w "$file" || echo "$file"`
+         ;;
+      esac
+      ;;
+  esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+  func_file_conv "$1"
+  if test -z "$lib_path"; then
+    lib_path=$file
+  else
+    lib_path="$lib_path;$file"
+  fi
+  linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+  lib=$1
+  found=no
+  save_IFS=$IFS
+  IFS=';'
+  for dir in $lib_path $LIB
+  do
+    IFS=$save_IFS
+    if $shared && test -f "$dir/$lib.dll.lib"; then
+      found=yes
+      lib=$dir/$lib.dll.lib
+      break
+    fi
+    if test -f "$dir/$lib.lib"; then
+      found=yes
+      lib=$dir/$lib.lib
+      break
+    fi
+  done
+  IFS=$save_IFS
+
+  if test "$found" != yes; then
+    lib=$lib.lib
+  fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+  # Assume a capable shell
+  lib_path=
+  shared=:
+  linker_opts=
+  for arg
+  do
+    if test -n "$eat"; then
+      eat=
+    else
+      case $1 in
+       -o)
+         # configure might choose to run compile as 'compile cc -o foo foo.c'.
+         eat=1
+         case $2 in
+           *.o | *.[oO][bB][jJ])
+             func_file_conv "$2"
+             set x "$@" -Fo"$file"
+             shift
+             ;;
+           *)
+             func_file_conv "$2"
+             set x "$@" -Fe"$file"
+             shift
+             ;;
+         esac
+         ;;
+       -I)
+         eat=1
+         func_file_conv "$2" mingw
+         set x "$@" -I"$file"
+         shift
+         ;;
+       -I*)
+         func_file_conv "${1#-I}" mingw
+         set x "$@" -I"$file"
+         shift
+         ;;
+       -l)
+         eat=1
+         func_cl_dashl "$2"
+         set x "$@" "$lib"
+         shift
+         ;;
+       -l*)
+         func_cl_dashl "${1#-l}"
+         set x "$@" "$lib"
+         shift
+         ;;
+       -L)
+         eat=1
+         func_cl_dashL "$2"
+         ;;
+       -L*)
+         func_cl_dashL "${1#-L}"
+         ;;
+       -static)
+         shared=false
+         ;;
+       -Wl,*)
+         arg=${1#-Wl,}
+         save_ifs="$IFS"; IFS=','
+         for flag in $arg; do
+           IFS="$save_ifs"
+           linker_opts="$linker_opts $flag"
+         done
+         IFS="$save_ifs"
+         ;;
+       -Xlinker)
+         eat=1
+         linker_opts="$linker_opts $2"
+         ;;
+       -*)
+         set x "$@" "$1"
+         shift
+         ;;
+       *.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+         func_file_conv "$1"
+         set x "$@" -Tp"$file"
+         shift
+         ;;
+       *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+         func_file_conv "$1" mingw
+         set x "$@" "$file"
+         shift
+         ;;
+       *)
+         set x "$@" "$1"
+         shift
+         ;;
+      esac
+    fi
+    shift
+  done
+  if test -n "$linker_opts"; then
+    linker_opts="-link$linker_opts"
+  fi
+  exec "$@" $linker_opts
+  exit 1
+}
+
+eat=
+
+case $1 in
+  '')
+     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit $?
+    ;;
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+    func_cl_wrapper "$@"      # Doesn't return...
+    ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+       # configure might choose to run compile as 'compile cc -o foo foo.c'.
+       # So we strip '-o arg' only if arg is an object.
+       eat=1
+       case $2 in
+         *.o | *.obj)
+           ofile=$2
+           ;;
+         *)
+           set x "$@" -o "$2"
+           shift
+           ;;
+       esac
+       ;;
+      *.c)
+       cfile=$1
+       set x "$@" "$1"
+       shift
+       ;;
+      *)
+       set x "$@" "$1"
+       shift
+       ;;
+    esac
+  fi
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no '-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # '.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+  if mkdir "$lockdir" >/dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
old mode 100755 (executable)
new mode 100644 (file)
index c547c68..e69de29
@@ -1,666 +0,0 @@
-#! /bin/sh
-# Output a system dependent set of variables, describing how to set the
-# run time search path of shared libraries in an executable.
-#
-#   Copyright 1996-2007 Free Software Foundation, Inc.
-#   Taken from GNU libtool, 2001
-#   Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
-#
-#   This file is free software; the Free Software Foundation gives
-#   unlimited permission to copy and/or distribute it, with or without
-#   modifications, as long as this notice is preserved.
-#
-# The first argument passed to this file is the canonical host specification,
-#    CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or
-#    CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
-# should be set by the caller.
-#
-# The set of defined variables is at the end of this script.
-
-# Known limitations:
-# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
-#   than 256 bytes, otherwise the compiler driver will dump core. The only
-#   known workaround is to choose shorter directory names for the build
-#   directory and/or the installation directory.
-
-# All known linkers require a `.a' archive for static linking (except MSVC,
-# which needs '.lib').
-libext=a
-shrext=.so
-
-host="$1"
-host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-
-# Code taken from libtool.m4's _LT_CC_BASENAME.
-
-for cc_temp in $CC""; do
-  case $cc_temp in
-    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
-    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
-    \-*) ;;
-    *) break;;
-  esac
-done
-cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
-
-# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
-
-wl=
-if test "$GCC" = yes; then
-  wl='-Wl,'
-else
-  case "$host_os" in
-    aix*)
-      wl='-Wl,'
-      ;;
-    darwin*)
-      case $cc_basename in
-        xlc*)
-          wl='-Wl,'
-          ;;
-      esac
-      ;;
-    mingw* | cygwin* | pw32* | os2*)
-      ;;
-    hpux9* | hpux10* | hpux11*)
-      wl='-Wl,'
-      ;;
-    irix5* | irix6* | nonstopux*)
-      wl='-Wl,'
-      ;;
-    newsos6)
-      ;;
-    linux* | k*bsd*-gnu)
-      case $cc_basename in
-        icc* | ecc*)
-          wl='-Wl,'
-          ;;
-        pgcc | pgf77 | pgf90)
-          wl='-Wl,'
-          ;;
-        ccc*)
-          wl='-Wl,'
-          ;;
-        como)
-          wl='-lopt='
-          ;;
-        *)
-          case `$CC -V 2>&1 | sed 5q` in
-            *Sun\ C*)
-              wl='-Wl,'
-              ;;
-          esac
-          ;;
-      esac
-      ;;
-    osf3* | osf4* | osf5*)
-      wl='-Wl,'
-      ;;
-    rdos*)
-      ;;
-    solaris*)
-      wl='-Wl,'
-      ;;
-    sunos4*)
-      wl='-Qoption ld '
-      ;;
-    sysv4 | sysv4.2uw2* | sysv4.3*)
-      wl='-Wl,'
-      ;;
-    sysv4*MP*)
-      ;;
-    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
-      wl='-Wl,'
-      ;;
-    unicos*)
-      wl='-Wl,'
-      ;;
-    uts4*)
-      ;;
-  esac
-fi
-
-# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
-
-hardcode_libdir_flag_spec=
-hardcode_libdir_separator=
-hardcode_direct=no
-hardcode_minus_L=no
-
-case "$host_os" in
-  cygwin* | mingw* | pw32*)
-    # FIXME: the MSVC++ port hasn't been tested in a loooong time
-    # When not using gcc, we currently assume that we are using
-    # Microsoft Visual C++.
-    if test "$GCC" != yes; then
-      with_gnu_ld=no
-    fi
-    ;;
-  interix*)
-    # we just hope/assume this is gcc and not c89 (= MSVC++)
-    with_gnu_ld=yes
-    ;;
-  openbsd*)
-    with_gnu_ld=no
-    ;;
-esac
-
-ld_shlibs=yes
-if test "$with_gnu_ld" = yes; then
-  # Set some defaults for GNU ld with shared library support. These
-  # are reset later if shared libraries are not supported. Putting them
-  # here allows them to be overridden if necessary.
-  # Unlike libtool, we use -rpath here, not --rpath, since the documented
-  # option of GNU ld is called -rpath, not --rpath.
-  hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
-  case "$host_os" in
-    aix3* | aix4* | aix5*)
-      # On AIX/PPC, the GNU linker is very broken
-      if test "$host_cpu" != ia64; then
-        ld_shlibs=no
-      fi
-      ;;
-    amigaos*)
-      hardcode_libdir_flag_spec='-L$libdir'
-      hardcode_minus_L=yes
-      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
-      # that the semantics of dynamic libraries on AmigaOS, at least up
-      # to version 4, is to share data among multiple programs linked
-      # with the same dynamic library.  Since this doesn't match the
-      # behavior of shared libraries on other platforms, we cannot use
-      # them.
-      ld_shlibs=no
-      ;;
-    beos*)
-      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
-        :
-      else
-        ld_shlibs=no
-      fi
-      ;;
-    cygwin* | mingw* | pw32*)
-      # hardcode_libdir_flag_spec is actually meaningless, as there is
-      # no search path for DLLs.
-      hardcode_libdir_flag_spec='-L$libdir'
-      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
-        :
-      else
-        ld_shlibs=no
-      fi
-      ;;
-    interix[3-9]*)
-      hardcode_direct=no
-      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
-      ;;
-    gnu* | linux* | k*bsd*-gnu)
-      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
-        :
-      else
-        ld_shlibs=no
-      fi
-      ;;
-    netbsd*)
-      ;;
-    solaris*)
-      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
-        ld_shlibs=no
-      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
-        :
-      else
-        ld_shlibs=no
-      fi
-      ;;
-    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
-      case `$LD -v 2>&1` in
-        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
-          ld_shlibs=no
-          ;;
-        *)
-          if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
-            hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
-          else
-            ld_shlibs=no
-          fi
-          ;;
-      esac
-      ;;
-    sunos4*)
-      hardcode_direct=yes
-      ;;
-    *)
-      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
-        :
-      else
-        ld_shlibs=no
-      fi
-      ;;
-  esac
-  if test "$ld_shlibs" = no; then
-    hardcode_libdir_flag_spec=
-  fi
-else
-  case "$host_os" in
-    aix3*)
-      # Note: this linker hardcodes the directories in LIBPATH if there
-      # are no directories specified by -L.
-      hardcode_minus_L=yes
-      if test "$GCC" = yes; then
-        # Neither direct hardcoding nor static linking is supported with a
-        # broken collect2.
-        hardcode_direct=unsupported
-      fi
-      ;;
-    aix4* | aix5*)
-      if test "$host_cpu" = ia64; then
-        # On IA64, the linker does run time linking by default, so we don't
-        # have to do anything special.
-        aix_use_runtimelinking=no
-      else
-        aix_use_runtimelinking=no
-        # Test if we are trying to use run time linking or normal
-        # AIX style linking. If -brtl is somewhere in LDFLAGS, we
-        # need to do runtime linking.
-        case $host_os in aix4.[23]|aix4.[23].*|aix5*)
-          for ld_flag in $LDFLAGS; do
-            if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
-              aix_use_runtimelinking=yes
-              break
-            fi
-          done
-          ;;
-        esac
-      fi
-      hardcode_direct=yes
-      hardcode_libdir_separator=':'
-      if test "$GCC" = yes; then
-        case $host_os in aix4.[012]|aix4.[012].*)
-          collect2name=`${CC} -print-prog-name=collect2`
-          if test -f "$collect2name" && \
-            strings "$collect2name" | grep resolve_lib_name >/dev/null
-          then
-            # We have reworked collect2
-            :
-          else
-            # We have old collect2
-            hardcode_direct=unsupported
-            hardcode_minus_L=yes
-            hardcode_libdir_flag_spec='-L$libdir'
-            hardcode_libdir_separator=
-          fi
-          ;;
-        esac
-      fi
-      # Begin _LT_AC_SYS_LIBPATH_AIX.
-      echo 'int main () { return 0; }' > conftest.c
-      ${CC} ${LDFLAGS} conftest.c -o conftest
-      aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`
-      if test -z "$aix_libpath"; then
-        aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
-}'`
-      fi
-      if test -z "$aix_libpath"; then
-        aix_libpath="/usr/lib:/lib"
-      fi
-      rm -f conftest.c conftest
-      # End _LT_AC_SYS_LIBPATH_AIX.
-      if test "$aix_use_runtimelinking" = yes; then
-        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
-      else
-        if test "$host_cpu" = ia64; then
-          hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
-        else
-          hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
-        fi
-      fi
-      ;;
-    amigaos*)
-      hardcode_libdir_flag_spec='-L$libdir'
-      hardcode_minus_L=yes
-      # see comment about different semantics on the GNU ld section
-      ld_shlibs=no
-      ;;
-    bsdi[45]*)
-      ;;
-    cygwin* | mingw* | pw32*)
-      # When not using gcc, we currently assume that we are using
-      # Microsoft Visual C++.
-      # hardcode_libdir_flag_spec is actually meaningless, as there is
-      # no search path for DLLs.
-      hardcode_libdir_flag_spec=' '
-      libext=lib
-      ;;
-    darwin* | rhapsody*)
-      hardcode_direct=no
-      if test "$GCC" = yes ; then
-        :
-      else
-        case $cc_basename in
-          xlc*)
-            ;;
-          *)
-            ld_shlibs=no
-            ;;
-        esac
-      fi
-      ;;
-    dgux*)
-      hardcode_libdir_flag_spec='-L$libdir'
-      ;;
-    freebsd1*)
-      ld_shlibs=no
-      ;;
-    freebsd2.2*)
-      hardcode_libdir_flag_spec='-R$libdir'
-      hardcode_direct=yes
-      ;;
-    freebsd2*)
-      hardcode_direct=yes
-      hardcode_minus_L=yes
-      ;;
-    freebsd* | dragonfly*)
-      hardcode_libdir_flag_spec='-R$libdir'
-      hardcode_direct=yes
-      ;;
-    hpux9*)
-      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
-      hardcode_libdir_separator=:
-      hardcode_direct=yes
-      # hardcode_minus_L: Not really in the search PATH,
-      # but as the default location of the library.
-      hardcode_minus_L=yes
-      ;;
-    hpux10*)
-      if test "$with_gnu_ld" = no; then
-        hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
-        hardcode_libdir_separator=:
-        hardcode_direct=yes
-        # hardcode_minus_L: Not really in the search PATH,
-        # but as the default location of the library.
-        hardcode_minus_L=yes
-      fi
-      ;;
-    hpux11*)
-      if test "$with_gnu_ld" = no; then
-        hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
-        hardcode_libdir_separator=:
-        case $host_cpu in
-          hppa*64*|ia64*)
-            hardcode_direct=no
-            ;;
-          *)
-            hardcode_direct=yes
-            # hardcode_minus_L: Not really in the search PATH,
-            # but as the default location of the library.
-            hardcode_minus_L=yes
-            ;;
-        esac
-      fi
-      ;;
-    irix5* | irix6* | nonstopux*)
-      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
-      hardcode_libdir_separator=:
-      ;;
-    netbsd*)
-      hardcode_libdir_flag_spec='-R$libdir'
-      hardcode_direct=yes
-      ;;
-    newsos6)
-      hardcode_direct=yes
-      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
-      hardcode_libdir_separator=:
-      ;;
-    openbsd*)
-      if test -f /usr/libexec/ld.so; then
-        hardcode_direct=yes
-        if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
-          hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
-        else
-          case "$host_os" in
-            openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
-              hardcode_libdir_flag_spec='-R$libdir'
-              ;;
-            *)
-              hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
-              ;;
-          esac
-        fi
-      else
-        ld_shlibs=no
-      fi
-      ;;
-    os2*)
-      hardcode_libdir_flag_spec='-L$libdir'
-      hardcode_minus_L=yes
-      ;;
-    osf3*)
-      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
-      hardcode_libdir_separator=:
-      ;;
-    osf4* | osf5*)
-      if test "$GCC" = yes; then
-        hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
-      else
-        # Both cc and cxx compiler support -rpath directly
-        hardcode_libdir_flag_spec='-rpath $libdir'
-      fi
-      hardcode_libdir_separator=:
-      ;;
-    solaris*)
-      hardcode_libdir_flag_spec='-R$libdir'
-      ;;
-    sunos4*)
-      hardcode_libdir_flag_spec='-L$libdir'
-      hardcode_direct=yes
-      hardcode_minus_L=yes
-      ;;
-    sysv4)
-      case $host_vendor in
-        sni)
-          hardcode_direct=yes # is this really true???
-          ;;
-        siemens)
-          hardcode_direct=no
-          ;;
-        motorola)
-          hardcode_direct=no #Motorola manual says yes, but my tests say they lie
-          ;;
-      esac
-      ;;
-    sysv4.3*)
-      ;;
-    sysv4*MP*)
-      if test -d /usr/nec; then
-        ld_shlibs=yes
-      fi
-      ;;
-    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
-      ;;
-    sysv5* | sco3.2v5* | sco5v6*)
-      hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
-      hardcode_libdir_separator=':'
-      ;;
-    uts4*)
-      hardcode_libdir_flag_spec='-L$libdir'
-      ;;
-    *)
-      ld_shlibs=no
-      ;;
-  esac
-fi
-
-# Check dynamic linker characteristics
-# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
-# Unlike libtool.m4, here we don't care about _all_ names of the library, but
-# only about the one the linker finds when passed -lNAME. This is the last
-# element of library_names_spec in libtool.m4, or possibly two of them if the
-# linker has special search rules.
-library_names_spec=      # the last element of library_names_spec in libtool.m4
-libname_spec='lib$name'
-case "$host_os" in
-  aix3*)
-    library_names_spec='$libname.a'
-    ;;
-  aix4* | aix5*)
-    library_names_spec='$libname$shrext'
-    ;;
-  amigaos*)
-    library_names_spec='$libname.a'
-    ;;
-  beos*)
-    library_names_spec='$libname$shrext'
-    ;;
-  bsdi[45]*)
-    library_names_spec='$libname$shrext'
-    ;;
-  cygwin* | mingw* | pw32*)
-    shrext=.dll
-    library_names_spec='$libname.dll.a $libname.lib'
-    ;;
-  darwin* | rhapsody*)
-    shrext=.dylib
-    library_names_spec='$libname$shrext'
-    ;;
-  dgux*)
-    library_names_spec='$libname$shrext'
-    ;;
-  freebsd1*)
-    ;;
-  freebsd* | dragonfly*)
-    case "$host_os" in
-      freebsd[123]*)
-        library_names_spec='$libname$shrext$versuffix' ;;
-      *)
-        library_names_spec='$libname$shrext' ;;
-    esac
-    ;;
-  gnu*)
-    library_names_spec='$libname$shrext'
-    ;;
-  hpux9* | hpux10* | hpux11*)
-    case $host_cpu in
-      ia64*)
-        shrext=.so
-        ;;
-      hppa*64*)
-        shrext=.sl
-        ;;
-      *)
-        shrext=.sl
-        ;;
-    esac
-    library_names_spec='$libname$shrext'
-    ;;
-  interix[3-9]*)
-    library_names_spec='$libname$shrext'
-    ;;
-  irix5* | irix6* | nonstopux*)
-    library_names_spec='$libname$shrext'
-    case "$host_os" in
-      irix5* | nonstopux*)
-        libsuff= shlibsuff=
-        ;;
-      *)
-        case $LD in
-          *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
-          *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
-          *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
-          *) libsuff= shlibsuff= ;;
-        esac
-        ;;
-    esac
-    ;;
-  linux*oldld* | linux*aout* | linux*coff*)
-    ;;
-  linux* | k*bsd*-gnu)
-    library_names_spec='$libname$shrext'
-    ;;
-  knetbsd*-gnu)
-    library_names_spec='$libname$shrext'
-    ;;
-  netbsd*)
-    library_names_spec='$libname$shrext'
-    ;;
-  newsos6)
-    library_names_spec='$libname$shrext'
-    ;;
-  nto-qnx*)
-    library_names_spec='$libname$shrext'
-    ;;
-  openbsd*)
-    library_names_spec='$libname$shrext$versuffix'
-    ;;
-  os2*)
-    libname_spec='$name'
-    shrext=.dll
-    library_names_spec='$libname.a'
-    ;;
-  osf3* | osf4* | osf5*)
-    library_names_spec='$libname$shrext'
-    ;;
-  rdos*)
-    ;;
-  solaris*)
-    library_names_spec='$libname$shrext'
-    ;;
-  sunos4*)
-    library_names_spec='$libname$shrext$versuffix'
-    ;;
-  sysv4 | sysv4.3*)
-    library_names_spec='$libname$shrext'
-    ;;
-  sysv4*MP*)
-    library_names_spec='$libname$shrext'
-    ;;
-  sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
-    library_names_spec='$libname$shrext'
-    ;;
-  uts4*)
-    library_names_spec='$libname$shrext'
-    ;;
-esac
-
-sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
-escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
-shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
-escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
-escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
-escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
-
-LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
-
-# How to pass a linker flag through the compiler.
-wl="$escaped_wl"
-
-# Static library suffix (normally "a").
-libext="$libext"
-
-# Shared library suffix (normally "so").
-shlibext="$shlibext"
-
-# Format of library name prefix.
-libname_spec="$escaped_libname_spec"
-
-# Library names that the linker finds when passed -lNAME.
-library_names_spec="$escaped_library_names_spec"
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator="$hardcode_libdir_separator"
-
-# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct="$hardcode_direct"
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L="$hardcode_minus_L"
-
-EOF
index a2616e7..07aef28 100644 (file)
 
 AC_PREREQ(2.63)
 
-#AC_INIT([pulseaudio], m4_esyscmd([./git-version-gen .tarball-version]), #     [mzchyfrnhqvb (at) 0pointer (dot) net])
-
-AC_INIT([pulseaudio],[0.9.21-rebootstrapped],[])
-
-
+AC_INIT([pulseaudio],[m4_esyscmd(./git-version-gen .tarball-version)],[pulseaudio-discuss (at) lists (dot) freedesktop (dot) org],[pulseaudio],[http://pulseaudio.org/])
 AC_CONFIG_SRCDIR([src/daemon/main.c])
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_HEADERS([config.h])
-AM_INIT_AUTOMAKE([foreign 1.11 -Wall -Wno-portability silent-rules tar-pax])
+AM_INIT_AUTOMAKE([foreign 1.11 -Wall -Wno-portability silent-rules color-tests dist-xz tar-ustar])
+
+AS_IF([! test -n "$VERSION"], [
+   AC_MSG_ERROR([git-version-gen failed])
+])
 
 m4_define(pa_major, `echo $VERSION | cut -d. -f1 | cut -d- -f1`)
 m4_define(pa_minor, `echo $VERSION | cut -d. -f2 | cut -d- -f1`)
-m4_define(pa_micro, `echo $VERSION | cut -d. -f3 | cut -d- -f1`)
 
 AC_SUBST(PA_MAJOR, pa_major)
 AC_SUBST(PA_MINOR, pa_minor)
-AC_SUBST(PA_MICRO, pa_micro)
 AC_SUBST(PA_MAJORMINOR, pa_major.pa_minor)
-AC_SUBST(PA_MAJORMINORMICRO, pa_major.pa_minor.pa_micro)
-AC_SUBST(PACKAGE_URL, [http://pulseaudio.org/])
 
 AC_SUBST(PA_API_VERSION, 12)
-AC_SUBST(PA_PROTOCOL_VERSION, 16)
+AC_SUBST(PA_PROTOCOL_VERSION, 28)
 
 # The stable ABI for client applications, for the version info x:y:z
 # always will hold y=z
-AC_SUBST(LIBPULSE_VERSION_INFO, [12:2:12])
+AC_SUBST(LIBPULSE_VERSION_INFO, [16:2:16])
 
 # A simplified, synchronous, ABI-stable interface for client
 # applications, for the version info x:y:z always will hold y=z
-AC_SUBST(LIBPULSE_SIMPLE_VERSION_INFO, [0:3:0])
-
-# The ABI-stable network browsing interface for client applications,
-# for the version info x:y:z always will hold y=z
-AC_SUBST(LIBPULSE_BROWSE_VERSION_INFO, [1:1:1])
+AC_SUBST(LIBPULSE_SIMPLE_VERSION_INFO, [0:4:0])
 
 # The ABI-stable GLib adapter for client applications, for the version
 # info x:y:z always will hold y=z
@@ -65,26 +57,16 @@ AC_SUBST(LIBPULSE_MAINLOOP_GLIB_VERSION_INFO, [0:4:0])
 AC_CANONICAL_HOST
 AC_DEFINE_UNQUOTED([CANONICAL_HOST], "$host", [Canonical host string.])
 
-if type -p stow > /dev/null && test -d /usr/local/stow ; then
-   AC_MSG_NOTICE([*** Found /usr/local/stow: default install prefix set to /usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION} ***])
-   ac_default_prefix="/usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION}"
-fi
-
-#### Platform hacks ####
+AC_CHECK_PROG([STOW], [stow], [yes], [no])
 
-case $host in
-   *-*-solaris* )
-      AC_DEFINE(_XOPEN_SOURCE,        600, Needed to get declarations for msg_control and msg_controllen on Solaris)
-      AC_DEFINE(__EXTENSIONS__,         1, Needed to get declarations for msg_control and msg_controllen on Solaris)
-      ;;
-   *-*-darwin* )
-      AC_DEFINE([_POSIX_C_SOURCE], [200112L], [Needed to get clock_gettime on Mac OS X])
-      AC_DEFINE([_DARWIN_C_SOURCE], [200112L], [Needed to get NSIG on Mac OS X])
-      ;;
-esac
+AS_IF([test "x$STOW" = "xyes" && test -d /usr/local/stow], [
+    AC_MSG_NOTICE([*** Found /usr/local/stow: default install prefix set to /usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION} ***])
+    ac_default_prefix="/usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION}"
+])
 
 AM_SILENT_RULES([yes])
 
+
 #### Checks for programs. ####
 
 # mkdir -p
@@ -96,115 +78,153 @@ AC_PROG_MKDIR_P
 AC_PROG_CC
 AC_PROG_CC_C99
 AM_PROG_CC_C_O
+# Only required if you want the WebRTC canceller -- no runtime dep on
+# libstdc++ otherwise
+AC_PROG_CXX
 AC_PROG_GCC_TRADITIONAL
 AC_USE_SYSTEM_EXTENSIONS
 
 # M4
 
 AC_CHECK_PROGS([M4], gm4 m4, no)
-if test "x$M4" = xno ; then
-   AC_MSG_ERROR([m4 missing])
+AS_IF([test "x$M4" = "xno"], AC_MSG_ERROR([m4 missing]))
+
+# pkg-config
+
+PKG_PROG_PKG_CONFIG
+
+# gettext
+
+if test "x$enable_nls" != "xno"; then
+IT_PROG_INTLTOOL([0.35.0])
+GETTEXT_PACKAGE=pulseaudio
+AC_SUBST([GETTEXT_PACKAGE])
+AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],["$GETTEXT_PACKAGE"],[Gettext package])
+AM_GLIB_GNU_GETTEXT
+
+pulselocaledir='${prefix}/${DATADIRNAME}/locale'
+AX_DEFINE_DIR(PULSE_LOCALEDIR, pulselocaledir, [Gettext locale dir])
+else
+# workaround till an intltool m4 bug is fixed upstream
+# (https://bugs.launchpad.net/intltool/+bug/904647)
+USE_NLS=no
+AC_SUBST(USE_NLS)
 fi
 
-dnl Compiler flags
-CC_CHECK_CFLAGS_APPEND([-Wall -W -Wextra -pipe -Wno-long-long -Winline -Wvla -Wno-overlength-strings -Wunsafe-loop-optimizations -Wundef -Wformat=2 -Wlogical-op -Wsign-compare -Wformat-security -Wmissing-include-dirs -Wformat-nonliteral -Wold-style-definition -Wpointer-arith -Winit-self -Wdeclaration-after-statement -Wfloat-equal -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wmissing-declarations -Wmissing-noreturn -Wshadow -Wendif-labels -Wcast-align -Wstrict-aliasing=2 -Wwrite-strings -Wno-unused-parameter -ffast-math -Wp,-D_FORTIFY_SOURCE=2 -fno-common -fdiagnostics-show-option])
 
-dnl Linker flags.
-dnl Check whether the linker supports the -version-script option.
+#### Determine host OS ####
+
+os_is_linux=0
+os_is_win32=0
+os_is_darwin=0
+
+AC_MSG_CHECKING([host operating system])
+case "$host_os" in
+    linux*)
+        AC_MSG_RESULT([linux])
+        os_is_linux=1
+    ;;
+    darwin*)
+        AC_MSG_RESULT([darwin])
+        os_is_darwin=1
+        AC_DEFINE([OS_IS_DARWIN], 1, [Build target is Darwin.])
+    ;;
+    mingw*)
+        AC_MSG_RESULT([win32])
+        os_is_win32=1
+        AC_DEFINE([OS_IS_WIN32], 1, [Build target is Windows.])
+    ;;
+    *)
+        AC_MSG_RESULT([unknown])
+    ;;
+esac
+
+AM_CONDITIONAL(OS_IS_DARWIN, test "x$os_is_darwin" = "x1")
+AM_CONDITIONAL(OS_IS_WIN32, test "x$os_is_win32" = "x1")
+AC_SUBST([OS_IS_WIN32], [$os_is_win32])
+
+# Platform specific hacks
+case "$host_os" in
+    darwin* )
+        AC_DEFINE([_DARWIN_C_SOURCE], [200112L], [Needed to get NSIG on Mac OS X])
+    ;;
+    mingw* )
+        AC_DEFINE([WIN32_LEAN_AND_MEAN], 1, [Needed to avoid including unnecessary headers on Windows])
+    ;;
+    solaris* )
+        AC_DEFINE(_XOPEN_SOURCE,       600, [Needed to get declarations for msg_control and msg_controllen on Solaris])
+        AC_DEFINE(__EXTENSIONS__,        1, [Needed to get declarations for msg_control and msg_controllen on Solaris])
+    ;;
+esac
+
+
+#### Compiler flags ####
 
-dnl This variable is used to make sure ${srcdir} is expanded and not
-dnl passed to the CC_CHECK_LDFLAGS macro as a name.
-tmp_ldflag="-Wl,-version-script=${srcdir}/src/map-file"
+AX_APPEND_COMPILE_FLAGS(
+    [-Wall -W -Wextra -pipe -Wno-long-long -Wno-overlength-strings -Wunsafe-loop-optimizations -Wundef -Wformat=2 -Wlogical-op -Wsign-compare -Wformat-security -Wmissing-include-dirs -Wformat-nonliteral -Wold-style-definition -Wpointer-arith -Winit-self -Wdeclaration-after-statement -Wfloat-equal -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wmissing-declarations -Wmissing-noreturn -Wshadow -Wendif-labels -Wcast-align -Wstrict-aliasing -Wwrite-strings -Wno-unused-parameter -ffast-math -Wp,-D_FORTIFY_SOURCE=2 -fno-common -fdiagnostics-show-option],
+    [], [-pedantic -Werror])
 
-CC_CHECK_LDFLAGS([${tmp_ldflag}],
-    [VERSIONING_LDFLAGS='-Wl,-version-script=$(srcdir)/map-file'])
+# Only enable fastpath asserts when doing a debug build, e.g. from bootstrap.sh.
+AS_CASE([" $CFLAGS "], [*" -O0 "*], [], [AX_APPEND_FLAG(["-DFASTPATH"], [CPPFLAGS])])
+
+
+#### Linker flags ####
+
+# Check whether the linker supports the -version-script option.
+# The Make variable $(srcdir) needs to be in the LDFLAGS in that form,
+# so that it is expanded the right way in every subdir.
+AX_CHECK_LINK_FLAG(["-Wl,-version-script=${srcdir}/src/map-file"],
+    [VERSIONING_LDFLAGS='-Wl,-version-script=$(abs_top_srcdir)/src/map-file'])
 AC_SUBST([VERSIONING_LDFLAGS])
 
-dnl Use immediate (now) bindings; avoids the funky re-call in itself
-dnl  the -z now syntax is lifted from Sun's linker and works with GNU's too
-dnl  other linkes might be added later
-CC_CHECK_LDFLAGS([-Wl,-z,now], [IMMEDIATE_LDFLAGS="-Wl,-z,now"])
+# Use immediate (now) bindings; avoids the funky re-call in itself.
+# The -z now syntax is lifted from Sun's linker and works with GNU's too, other linkers might be added later.
+AX_APPEND_LINK_FLAGS([-Wl,-z,now], [IMMEDIATE_LDFLAGS])
 AC_SUBST([IMMEDIATE_LDFLAGS])
 
-dnl On ELF systems we don't want the libraries to be unloaded since we
-dnl don't clean them up properly, so we request the nodelete flag to be
-dnl enabled.
-dnl
-dnl On other systems, we don't really know how to do that, but it's
-dnl welcome if somebody can tell.
-CC_CHECK_LDFLAGS([-Wl,-z,nodelete], [NODELETE_LDFLAGS="-Wl,-z,nodelete"])
+# On ELF systems we don't want the libraries to be unloaded since we don't clean them up properly,
+# so we request the nodelete flag to be enabled.
+# On other systems, we don't really know how to do that, but it's welcome if somebody can tell.
+AX_APPEND_LINK_FLAGS([-Wl,-z,nodelete], [NODELETE_LDFLAGS])
 AC_SUBST([NODELETE_LDFLAGS])
 
-dnl Check for the proper way to build libraries that have no undefined
-dnl symbols; on some hosts this needs to be avoided but the macro
-dnl takes care of it.
-CC_NOUNDEFINED
+# Check for the proper way to build libraries that have no undefined symbols
+case $host in
+    # FreeBSD (et al.) does not complete linking for shared objects when pthreads
+    # are requested, as different implementations are present.
+    *-freebsd* | *-openbsd*) ;;
+    *)
+        for possible_flag in "-Wl,--no-undefined" "-Wl,-z,defs"; do
+            AX_CHECK_LINK_FLAG([$possible_flag], [NOUNDEFINED_LDFLAGS="$possible_flag"; break])
+        done
+    ;;
+esac
+AC_SUBST([NOUNDEFINED_LDFLAGS])
 
-dnl Check whether to build tests by default (as compile-test) or not
-AC_ARG_ENABLE([default-build-tests],
-    AS_HELP_STRING([--disable-default-build-tests], [Build test programs only during make check]))
 
-AM_CONDITIONAL([BUILD_TESTS_DEFAULT], [test "x$enable_default_build_tests" != "xno"])
+#### Atomic operations ####
 
 # Native atomic operation support
 AC_ARG_ENABLE([atomic-arm-linux-helpers],
-    AS_HELP_STRING([--disable-atomic-arm-linux-helpers],[use inline asm or libatomic_ops instead]),
-        [
-            case "${enableval}" in
-                yes) atomic_arm_linux_helpers=yes ;;
-                no) atomic_arm_linux_helpers=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-atomic-arm-linux-helpers) ;;
-            esac
-        ],
-        [atomic_arm_linux_helpers=auto])
+    AS_HELP_STRING([--disable-atomic-arm-linux-helpers],[use inline asm or libatomic_ops instead]))
 
 AC_ARG_ENABLE([atomic-arm-memory-barrier],
-    AS_HELP_STRING([--enable-atomic-arm-memory-barrier],[only really needed in SMP arm systems]),
-        [
-            case "${enableval}" in
-                yes) AC_DEFINE_UNQUOTED(ATOMIC_ARM_MEMORY_BARRIER_ENABLED, 1, [Enable memory barriers]) ;;
-                no) ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-atomic-arm-linux-helpers) ;;
-            esac
-        ],)
-
-AC_ARG_ENABLE([netbsd-atomic-ops],
-    AS_HELP_STRING([--enable-netbsd-atomic-ops],[Use the native NetBSD atomic_ops implementation]),
-        [
-            case "${enableval}" in
-                yes) atomic_netbsd_helpers=yes ;;
-                no) atomic_netbsd_helpers=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --enable-netbsd-atomic-ops) ;;
-            esac
-        ],
-        [atomic_netbsd_helpers=auto])
+    AS_HELP_STRING([--enable-atomic-arm-memory-barrier],[only really needed in SMP arm systems]))
 
-AC_MSG_CHECKING([target operating system])
-case $host in
-        *-*-linux*)
-            AC_MSG_RESULT([linux])
-            pulse_target_os=linux
-        ;;
-        *-*-netbsd*)
-            AC_MSG_RESULT([netbsd])
-            pulse_target_os=netbsd
-        ;;
-        *)
-            AC_MSG_RESULT([unknown])
-            pulse_target_os=unknown
-        ;;
-esac
+if test "x$enable_atomic_arm_memory_barrier" = "xyes"; then
+    AC_DEFINE_UNQUOTED(ATOMIC_ARM_MEMORY_BARRIER_ENABLED, 1, [Enable memory barriers])
+fi
 
 # If everything else fails use libatomic_ops
 need_libatomic_ops=yes
 
 AC_CACHE_CHECK([whether $CC knows __sync_bool_compare_and_swap()],
-  pulseaudio_cv_sync_bool_compare_and_swap,
-  [AC_LINK_IFELSE(
-     AC_LANG_PROGRAM([], [[int a = 4; __sync_bool_compare_and_swap(&a, 4, 5);]]),
-     [pulseaudio_cv_sync_bool_compare_and_swap=yes],
-     [pulseaudio_cv_sync_bool_compare_and_swap=no])
-  ])
+    pulseaudio_cv_sync_bool_compare_and_swap, [
+    AC_LINK_IFELSE(
+        AC_LANG_PROGRAM([], [[int a = 4; __sync_bool_compare_and_swap(&a, 4, 5);]]),
+        [pulseaudio_cv_sync_bool_compare_and_swap=yes],
+        [pulseaudio_cv_sync_bool_compare_and_swap=no])
+    ])
 
 if test "$pulseaudio_cv_sync_bool_compare_and_swap" = "yes" ; then
     AC_DEFINE([HAVE_ATOMIC_BUILTINS], 1, [Have __sync_bool_compare_and_swap() and friends.])
@@ -212,79 +232,121 @@ if test "$pulseaudio_cv_sync_bool_compare_and_swap" = "yes" ; then
 else
     # HW specific atomic ops stuff
     AC_MSG_CHECKING([architecture for native atomic operations])
-    case $host_cpu in
+    case $host in
         arm*)
             AC_MSG_RESULT([arm])
             AC_MSG_CHECKING([whether we can use Linux kernel helpers])
             # The Linux kernel helper functions have been there since 2.6.16. However
             # compile time checking for kernel version in cross compile environment
             # (which is usually the case for arm cpu) is tricky (or impossible).
-            if test "x$pulse_target_os" = "xlinux" && test "x$atomic_arm_linux_helpers" != "xno"; then
+            if test "x$os_is_linux" = "x1" && test "x$enable_atomic_arm_linux_helpers" != "xno"; then
                 AC_MSG_RESULT([yes])
                 AC_DEFINE_UNQUOTED(ATOMIC_ARM_LINUX_HELPERS, 1, [special arm linux implementation])
                 need_libatomic_ops=no
             else
-               AC_MSG_RESULT([no])
-               AC_CACHE_CHECK([compiler support for arm inline asm atomic operations],
-                 pulseaudio_cv_support_arm_atomic_ops,
-                 [AC_COMPILE_IFELSE(
-                    AC_LANG_PROGRAM([],
-                      [[volatile int a=0;
-                        int o=0, n=1, r;
-                        asm volatile ("ldrex    %0, [%1]\n"
-                                         "subs  %0, %0, %2\n"
-                                         "strexeq %0, %3, [%1]\n"
-                                         : "=&r" (r)
-                                         : "r" (&a), "Ir" (o), "r" (n)
-                                         : "cc");
-                        return (a==1 ? 0 : -1);
-                      ]]),
-                    [pulseaudio_cv_support_arm_atomic_ops=yes],
-                    [pulseaudio_cv_support_arm_atomic_ops=no])
-                 ])
-               AS_IF([test "$pulseaudio_cv_support_arm_atomic_ops" = "yes"], [
-                   AC_DEFINE([ATOMIC_ARM_INLINE_ASM], 1, [Have ARMv6 instructions.])
-                   need_libatomic_ops=no
-                 ])
-           fi
+                AC_MSG_RESULT([no])
+                AC_CACHE_CHECK([compiler support for arm inline asm atomic operations],
+                    pulseaudio_cv_support_arm_atomic_ops, [
+                    AC_COMPILE_IFELSE(
+                        AC_LANG_PROGRAM([], [[
+                            volatile int a=0;
+                            int o=0, n=1, r;
+                            asm volatile ("ldrex    %0, [%1]\n"
+                                          "subs  %0, %0, %2\n"
+                                          "strexeq %0, %3, [%1]\n"
+                                          : "=&r" (r)
+                                          : "r" (&a), "Ir" (o), "r" (n)
+                                          : "cc");
+                            return (a==1 ? 0 : -1);
+                        ]]),
+                        [pulseaudio_cv_support_arm_atomic_ops=yes],
+                        [pulseaudio_cv_support_arm_atomic_ops=no])
+                ])
+                AS_IF([test "$pulseaudio_cv_support_arm_atomic_ops" = "yes"], [
+                    AC_DEFINE([ATOMIC_ARM_INLINE_ASM], 1, [Have ARM atomic instructions.])
+                    need_libatomic_ops=no
+                ])
+            fi
+        ;;
+        *-netbsdelf5*)
+            AC_MSG_RESULT([yes])
+            need_libatomic_ops=no
+        ;;
+        *-freebsd*)
+            AC_MSG_RESULT([yes])
+            need_libatomic_ops=no
         ;;
         *)
-            if test "x$pulse_target_os" = "xnetbsd" && test "x$atomic_netbsd_helpers" = "xyes"; then
-                AC_MSG_RESULT([yes])
-                AC_DEFINE_UNQUOTED(NETBSD_ATOMIC_OPS, 1, [netbsd implementation])
-                need_libatomic_ops=no
-            else
-                AC_MSG_RESULT([unknown])
-            fi
+            AC_MSG_RESULT([unknown])
         ;;
     esac
 fi
 
-CC_CHECK_TLS
+# If we're on ARM, check for the ARMV6 instructions we need */
+case $host in
+  arm*)
+    AC_CACHE_CHECK([support for required armv6 instructions],
+      pulseaudio_cv_support_armv6,
+      [AC_COMPILE_IFELSE(
+         AC_LANG_PROGRAM([],
+           [[volatile int a = -60000, b = 0xaaaabbbb, c = 0xccccdddd;
+             asm volatile ("ldr r0, %2 \n"
+                           "ldr r2, %3 \n"
+                           "ldr r3, %4 \n"
+                           "ssat r1, #8, r0 \n"
+                           "str r1, %0 \n"
+                           "pkhbt r1, r3, r2, LSL #8 \n"
+                           "str r1, %1 \n"
+                           : "=m" (a), "=m" (b)
+                           : "m" (a), "m" (b), "m" (c)
+                           : "r0", "r1", "r2", "r3", "cc");
+             return (a == -128 && b == 0xaabbdddd) ? 0 : -1;
+           ]]),
+         [pulseaudio_cv_support_armv6=yes],
+         [pulseaudio_cv_support_armv6=no])
+      ])
+    AS_IF([test "$pulseaudio_cv_support_armv6" = "yes"], [
+        AC_DEFINE([HAVE_ARMV6], 1, [Have ARMv6 instructions.])
+      ])
+  ;;
+  *)
+  ;;
+esac
 
-AC_CACHE_CHECK([whether $CC knows _Bool],
-  pulseaudio_cv__Bool,
-  [AC_COMPILE_IFELSE(
-     AC_LANG_PROGRAM([], [[_Bool b;]]),
-     [pulseaudio_cv__Bool=yes],
-     [pulseaudio_cv__Bool=no])
-  ])
+#### NEON optimisations ####
+AC_ARG_ENABLE([neon-opt],
+    AS_HELP_STRING([--enable-neon-opt], [Enable NEON optimisations on ARM CPUs that support it]))
+
+AS_IF([test "x$enable_neon_opt" != "xno"],
+    [save_CFLAGS="$CFLAGS"; CFLAGS="$CFLAGS -mfpu=neon"
+     AC_COMPILE_IFELSE(
+        AC_LANG_PROGRAM([], []),
+        [
+         HAVE_NEON=1
+         NEON_CFLAGS="-mfpu=neon"
+        ],
+        [
+         HAVE_NEON=0
+         NEON_CFLAGS=
+        ])
+     CFLAGS="$save_CFLAGS"
+    ],
+    [HAVE_NEON=0])
+
+AS_IF([test "x$enable_neon_opt" = "xyes" && test "x$HAVE_NEON" = "x0"],
+      [AC_MSG_ERROR([*** Compiler does not support -mfpu=neon])])
+
+AC_SUBST(HAVE_NEON)
+AC_SUBST(NEON_CFLAGS)
+AM_CONDITIONAL([HAVE_NEON], [test "x$HAVE_NEON" = x1])
+AS_IF([test "x$HAVE_NEON" = "x1"], AC_DEFINE([HAVE_NEON], 1, [Have NEON support?]))
 
-AS_IF([test "$pulseaudio_cv__Bool" = "yes"], [
-    AC_DEFINE([HAVE_STD_BOOL], 1, [Have _Bool.])
-  ])
 
 #### libtool stuff ####
+
 LT_PREREQ(2.2)
-LT_CONFIG_LTDL_DIR([libltdl])
 LT_INIT([dlopen win32-dll disable-static])
-LTDL_INIT([convenience])
 
-dnl Unfortunately, even up to libtool 2.2.6a there is no way to know
-dnl exactly which version of libltdl is present in the system, so we
-dnl just assume that it's a working version as long as we have the
-dnl library and the header files.
-dnl
 dnl As an extra safety device, check for lt_dladvise_init() which is
 dnl only implemented in libtool 2.x, and refine as we go if we have
 dnl refined requirements.
@@ -297,26 +359,14 @@ dnl We don't need any special variable for this though, since the user
 dnl can give the proper place to find libltdl through the standard
 dnl variables like LDFLAGS and CPPFLAGS.
 
-#AC_CHECK_HEADER([ltdl.h],
-#    [AC_CHECK_LIB([ltdl], [lt_dladvise_init], [LIBLTDL=-lltdl], [LIBLTDL=])],
-#    [LIBLTDL=], libltdl)
+AC_CHECK_HEADER([ltdl.h],
+    [AC_CHECK_LIB([ltdl], [lt_dladvise_init], [LIBLTDL=-lltdl], [LIBLTDL=])],
+    [LIBLTDL=])
 
-#AS_IF([test "x$LIBLTDL" = "x"],
-#    [AC_MSG_ERROR([Unable to find libltdl version 2. Makes sure you have libtool 2.2 or later installed.])])
+AS_IF([test "x$LIBLTDL" = "x"],
+    [AC_MSG_ERROR([Unable to find libltdl version 2. Makes sure you have libtool 2.2 or later installed.])])
 AC_SUBST([LIBLTDL])
 
-#### Determine build environment ####
-
-os_is_win32=0
-
-case "$host_os" in
-        mingw*)
-        AC_DEFINE([OS_IS_WIN32], 1, [Build target is Windows.])
-        os_is_win32=1
-                ;;
-        esac
-
-AM_CONDITIONAL(OS_IS_WIN32, test "x$os_is_win32" = "x1")
 
 ###################################
 #   Basic environment checks      #
@@ -330,7 +380,7 @@ AC_HEADER_STDC
 # POSIX
 AC_CHECK_HEADERS_ONCE([arpa/inet.h glob.h grp.h netdb.h netinet/in.h \
     netinet/in_systm.h netinet/tcp.h poll.h pwd.h sched.h \
-    sys/mman.h sys/resource.h sys/select.h sys/socket.h sys/wait.h \
+    sys/mman.h sys/select.h sys/socket.h sys/wait.h \
     sys/uio.h syslog.h sys/dl.h dlfcn.h linux/sockios.h])
 AC_CHECK_HEADERS([netinet/ip.h], [], [],
                  [#include <sys/types.h>
@@ -341,15 +391,14 @@ AC_CHECK_HEADERS([netinet/ip.h], [], [],
                   # include <netinet/in_systm.h>
                   #endif
                  ])
-AC_CHECK_HEADERS([regex.h], [HAVE_REGEX=1], [HAVE_REGEX=0])
+AC_CHECK_HEADERS([sys/resource.h], [HAVE_SYS_RESOURCE_H=1], [HAVE_SYS_RESOURCE_H=0])
+AC_SUBST(HAVE_SYS_RESOURCE_H)
 AC_CHECK_HEADERS([sys/un.h], [HAVE_AF_UNIX=1], [HAVE_AF_UNIX=0])
-
-AM_CONDITIONAL(HAVE_REGEX, test "x$HAVE_REGEX" = "x1")
 AM_CONDITIONAL(HAVE_AF_UNIX, test "x$HAVE_AF_UNIX" = "x1")
+AC_SUBST(HAVE_AF_UNIX)
 
 # Linux
 AC_CHECK_HEADERS([linux/input.h], [HAVE_EVDEV=1], [HAVE_EVDEV=0])
-
 AM_CONDITIONAL([HAVE_EVDEV], [test "x$HAVE_EVDEV" = "x1"])
 
 AC_CHECK_HEADERS_ONCE([sys/prctl.h])
@@ -369,6 +418,9 @@ AC_CHECK_HEADERS_ONCE([byteswap.h])
 AC_CHECK_HEADERS_ONCE([sys/syscall.h])
 AC_CHECK_HEADERS_ONCE([sys/eventfd.h])
 AC_CHECK_HEADERS_ONCE([execinfo.h])
+AC_CHECK_HEADERS_ONCE([langinfo.h])
+AC_CHECK_HEADERS_ONCE([regex.h pcreposix.h])
+
 
 #### Typdefs, structures, etc. ####
 
@@ -376,27 +428,48 @@ AC_C_CONST
 AC_C_BIGENDIAN
 AC_TYPE_PID_T
 AC_TYPE_SIZE_T
-AC_CHECK_TYPES(ssize_t, , [AC_DEFINE([ssize_t], [signed long],
-    [Define ssize_t if it is not done by the standard libs.])])
+AC_CHECK_TYPES(ssize_t, , AC_DEFINE([ssize_t], [signed long], [Define ssize_t if it is not done by the standard libs.]))
 AC_TYPE_OFF_T
 
 AC_TYPE_UID_T
 AC_CHECK_DECLS(environ)
 
-AC_CHECK_DEFINE([SIGXCPU], [signal.h], [
-HAVE_SIGXCPU=1
-AC_DEFINE([HAVE_SIGXCPU], 1, [Have SIGXCPU?])
-], [HAVE_SIGXCPU=0])
+# SIGXCPU
+AX_CHECK_DEFINE([signal.h], [SIGXCPU], [HAVE_SIGXCPU=1], [HAVE_SIGXCPU=0])
+AS_IF([test "x$HAVE_SIGXCPU" = "x1"], AC_DEFINE([HAVE_SIGXCPU], 1, [Have SIGXCPU?]))
 AM_CONDITIONAL(HAVE_SIGXCPU, test "x$HAVE_SIGXCPU" = "x1")
 
-# Solaris lacks this
-AC_CHECK_DEFINE([INADDR_NONE], [netinet/in.h], [],
-    [AC_CHECK_DEFINE([INADDR_NONE], [winsock2.h], [],
+# INADDR_NONE, Solaris lacks this
+AX_CHECK_DEFINE([netinet/in.h], [INADDR_NONE], [],
+    [AX_CHECK_DEFINE([winsock2.h], [INADDR_NONE], [],
         [AC_DEFINE([INADDR_NONE],  [0xffffffff], [Define INADDR_NONE if not found in <netinet/in.h>])])])
 
-#### POSIX threads ####
 
-ACX_PTHREAD
+# _Bool
+AC_CACHE_CHECK([whether $CC knows _Bool],
+    pulseaudio_cv__Bool,
+    [AC_COMPILE_IFELSE(
+        AC_LANG_PROGRAM([], [[_Bool b;]]),
+        [pulseaudio_cv__Bool=yes],
+        [pulseaudio_cv__Bool=no])
+    ])
+
+AS_IF([test "$pulseaudio_cv__Bool" = "yes"], AC_DEFINE([HAVE_STD_BOOL], 1, [Have _Bool.]))
+
+
+#### Thread support ####
+
+AX_TLS
+AS_IF([test "$ac_cv_tls" == "__thread"],
+    AC_DEFINE([SUPPORT_TLS___THREAD], 1, [Define this if the compiler supports __thread for Thread-Local Storage]))
+
+# Win32 build breaks with win32 pthread installed
+AS_IF([test "x$os_is_win32" != "x1"],
+  [AX_PTHREAD])
+
+AS_IF([test "x$ax_pthread_ok" == "xyes"],
+    AC_DEFINE([_POSIX_PTHREAD_SEMANTICS], 1, [Needed on Solaris]))
+
 
 #### Check for libs ####
 
@@ -409,17 +482,39 @@ AC_SEARCH_LIBS([dlopen], [dl])
 AC_SEARCH_LIBS([shm_open], [rt])
 AC_SEARCH_LIBS([inet_ntop], [nsl])
 AC_SEARCH_LIBS([timer_create], [rt])
+AC_SEARCH_LIBS([pthread_setaffinity_np], [pthread])
+AC_SEARCH_LIBS([pthread_getname_np], [pthread])
+AC_SEARCH_LIBS([pthread_setname_np], [pthread])
 
 # BSD
 AC_SEARCH_LIBS([connect], [socket])
-AC_SEARCH_LIBS([backtrace], [execinfo])
+AC_SEARCH_LIBS([backtrace], [execinfo ubacktrace])
 
-# Non-standard
+# Darwin/OS X
+if test "x$os_is_darwin" = "x1" ; then
+    AC_MSG_CHECKING([looking for Apple CoreService Framework])
+    # How do I check a framework "library" - AC_CHECK_LIB prob. won't work??, just assign LIBS & hope
+    AC_CHECK_HEADER([/Developer/Headers/FlatCarbon/CoreServices.h],
+        [LIBS="$LIBS -framework CoreServices"],
+        [AC_CHECK_HEADERS([/System/Library/Frameworks/CoreServices.framework/Headers/CoreServices.h],
+            [LIBS="$LIBS -framework CoreServices"],
+            [AC_MSG_ERROR([CoreServices.h header file not found])]
+        )]
+    )
+
+    AC_MSG_RESULT([ok])
+    AC_DEFINE([HAVE_CLOCK_GETTIME], 1, [Using clock_gettime() replacement])
+    HAVE_BONJOUR=1
+fi
 
-# This magic is needed so we do not needlessly add static libs to the win32
-# build, disabling its ability to make dlls.
+AM_CONDITIONAL([HAVE_BONJOUR], [test "x$HAVE_BONJOUR" = x1])
+
+# Windows
+AC_SEARCH_LIBS([regexec], [pcreposix])
+# This magic is needed so we do not needlessly add static libs to the win32  build, disabling its ability to make dlls.
 AC_CHECK_FUNCS([getopt_long], [], [AC_CHECK_LIB([iberty], [getopt_long])])
 
+
 #### Check for functions ####
 
 # ISO
@@ -428,13 +523,12 @@ AC_CHECK_FUNCS_ONCE([lrintf strtof])
 # POSIX
 AC_FUNC_FORK
 AC_FUNC_GETGROUPS
-AC_FUNC_SELECT_ARGTYPES
-AC_CHECK_FUNCS_ONCE([chmod chown clock_gettime getaddrinfo getgrgid_r getgrnam_r \
-    getpwnam_r getpwuid_r gettimeofday getuid inet_ntop inet_pton mlock nanosleep \
+AC_CHECK_FUNCS_ONCE([chmod chown fstat fchown fchmod clock_gettime getaddrinfo getgrgid_r getgrnam_r \
+    getpwnam_r getpwuid_r gettimeofday getuid mlock nanosleep \
     pipe posix_fadvise posix_madvise posix_memalign setpgid setsid shm_open \
-    sigaction sleep sysconf pthread_setaffinity_np])
+    sigaction sleep symlink sysconf uname pthread_setaffinity_np pthread_getname_np pthread_setname_np])
 AC_CHECK_FUNCS([mkfifo], [HAVE_MKFIFO=1], [HAVE_MKFIFO=0])
-
+AC_SUBST(HAVE_MKFIFO)
 AM_CONDITIONAL(HAVE_MKFIFO, test "x$HAVE_MKFIFO" = "x1")
 
 # X/OPEN
@@ -450,105 +544,51 @@ AC_CHECK_FUNCS_ONCE([strerror_r])
 AC_CHECK_FUNCS_ONCE([lstat])
 
 # Non-standard
-
-AC_CHECK_FUNCS_ONCE([setresuid setresgid setreuid setregid seteuid setegid ppoll strsignal sig2str strtof_l])
+AC_CHECK_FUNCS_ONCE([setresuid setresgid setreuid setregid seteuid setegid ppoll strsignal sig2str strtof_l pipe2 accept4])
 
 AC_FUNC_ALLOCA
 
-AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
-  pulseaudio_cv_PTHREAD_PRIO_INHERIT,
-  [save_CC=$CC; CC=$PTHREAD_CC
-   save_CFLAGS=$CFLAGS; CFLAGS=$PTHREAD_CFLAGS
-   save_LIBS=$LIBS; LIBS=$PTHREAD_LIBS
-   AC_LINK_IFELSE(
-     AC_LANG_PROGRAM(
-       [[
-         #include <pthread.h>
-       ]],
-       [[int i = PTHREAD_PRIO_INHERIT;]]),
-     [pulseaudio_cv_PTHREAD_PRIO_INHERIT=yes],
-     [pulseaudio_cv_PTHREAD_PRIO_INHERIT=no])
-   CC=$save_CC
-   CFLAGS=$save_CFLAGS
-   LIBS=$save_LIBS
-  ])
-
-AS_IF([test "$pulseaudio_cv_PTHREAD_PRIO_INHERIT" = "yes"], [
-    AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])
-  ])
-
-AC_DEFINE_UNQUOTED(PA_CFLAGS,"$CFLAGS", [The CFLAGS used during compilation])
-
-#### Large File-Support (LFS) ####
+AC_CHECK_FUNCS([regexec], [HAVE_REGEX=1], [HAVE_REGEX=0])
+AM_CONDITIONAL(HAVE_REGEX, [test "x$HAVE_REGEX" = "x1"])
 
+# Large File-Support (LFS)
 AC_SYS_LARGEFILE
-
 # Check for open64 to know if the current system does have open64() and similar functions
 AC_CHECK_FUNCS_ONCE([open64])
 
-#### [lib]iconv ####
-
-AM_ICONV
-
-IT_PROG_INTLTOOL([0.35.0])
-GETTEXT_PACKAGE=pulseaudio
-AC_SUBST([GETTEXT_PACKAGE])
-AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],["$GETTEXT_PACKAGE"],[Gettext package])
-AM_GLIB_GNU_GETTEXT
-
-pulselocaledir='${prefix}/${DATADIRNAME}/locale'
-AC_SUBST(pulselocaledir)
 
 ###################################
 #      External libraries         #
 ###################################
 
-#### pkg-config ####
+#### [lib]iconv ####
 
-PKG_PROG_PKG_CONFIG
+AM_ICONV
 
 #### X11 (optional) ####
 
 AC_ARG_ENABLE([x11],
-    AS_HELP_STRING([--disable-x11],[Disable optional X11 support]),
-        [
-            case "${enableval}" in
-                yes) x11=yes ;;
-                no) x11=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-x11) ;;
-            esac
-        ],
-        [x11=auto])
+    AS_HELP_STRING([--disable-x11],[Disable optional X11 support]))
 
-if test "x${x11}" != xno ; then
-    PKG_CHECK_MODULES(X11, [ x11 ice sm xtst ],
-        HAVE_X11=1,
-        [
-            HAVE_X11=0
-            if test "x$x11" = xyes ; then
-                AC_MSG_ERROR([*** X11 not found])
-            fi
-        ])
-else
-    HAVE_X11=0
-fi
+AS_IF([test "x$enable_x11" != "xno"],
+    [PKG_CHECK_MODULES(X11, [ x11-xcb xcb >= 1.6 ice sm xtst ], HAVE_X11=1, HAVE_X11=0)],
+    HAVE_X11=0)
 
-if test "x${HAVE_X11}" = x1 ; then
-   AC_DEFINE([HAVE_X11], 1, [Have X11?])
-fi
+AS_IF([test "x$enable_x11" = "xyes" && test "x$HAVE_X11" = "x0"],
+    [AC_MSG_ERROR([*** X11 not found])])
 
 AC_SUBST(X11_CFLAGS)
 AC_SUBST(X11_LIBS)
 AC_SUBST(HAVE_X11)
 AM_CONDITIONAL([HAVE_X11], [test "x$HAVE_X11" = x1])
+AS_IF([test "x$HAVE_X11" = "x1"], AC_DEFINE([HAVE_X11], 1, [Have X11?]))
 
 #### Capabilities (optional) ####
 
 CAP_LIBS=''
 
-AC_ARG_WITH(
-        [caps],
-        AS_HELP_STRING([--without-caps],[Omit support for POSIX capabilities.]))
+AC_ARG_WITH([caps],
+    AS_HELP_STRING([--without-caps],[Omit support for POSIX capabilities.]))
 
 if test "x${with_caps}" != "xno"; then
     AC_SEARCH_LIBS([cap_init], [cap], [], [
@@ -565,24 +605,44 @@ fi
 
 AC_CHECK_HEADERS_ONCE([valgrind/memcheck.h])
 
+#### check unit tests ####
+
+AC_ARG_ENABLE([tests],
+    AS_HELP_STRING([--disable-tests],[Disable unit tests]))
+
+AS_IF([test "x$enable_tests" != "xno"],
+    [PKG_CHECK_MODULES(LIBCHECK, [ check ], HAVE_LIBCHECK=1, HAVE_LIBCHECK=0)],
+    HAVE_LIBCHECK=0)
+
+AC_SUBST(LIBCHECK_CFLAGS)
+AC_SUBST(LIBCHECK_LIBS)
+
+AS_IF([test "x$enable_tests" = "xyes" && test "x$HAVE_LIBCHECK" = "x0"],
+    [AC_MSG_ERROR([*** check library not found])])
+
+AM_CONDITIONAL([HAVE_TESTS], [test "x$HAVE_LIBCHECK" = x1])
+
+#### json parsing ####
+
+PKG_CHECK_MODULES(LIBJSON, [ json-c >= 0.11 ], [],
+                 [PKG_CHECK_MODULES(LIBJSON, [ json >= 0.9 ])])
+AC_SUBST(LIBJSON_CFLAGS)
+AC_SUBST(LIBJSON_LIBS)
+
 #### Sound file ####
 
 PKG_CHECK_MODULES(LIBSNDFILE, [ sndfile >= 1.0.20 ])
 AC_SUBST(LIBSNDFILE_CFLAGS)
 AC_SUBST(LIBSNDFILE_LIBS)
 
-PKG_CHECK_MODULES(LIBSPEEX, [ speexdsp >= 1.2 ])
-AC_SUBST(LIBSPEEX_CFLAGS)
-AC_SUBST(LIBSPEEX_LIBS)
-
-PKG_CHECK_MODULES(PMAPI, capi-system-power)
-AC_SUBST(PMAPI_CFLAGS)
-AC_SUBST(PMAPI_LIBS)
-
 PKG_CHECK_MODULES(VCONF, vconf)
 AC_SUBST(VCONF_CFLAGS)
 AC_SUBST(VCONF_LIBS)
 
+PKG_CHECK_MODULES(INIPARSER, iniparser)
+AC_SUBST(INIPARSER_CFLAGS)
+AC_SUBST(INIPARSER_LIBS)
+
 dnl use dlog --------------------------------------------------------------------------
 AC_ARG_ENABLE(dlog, AC_HELP_STRING([--enable-dlog], [using dlog]),
 [
@@ -601,742 +661,573 @@ fi
 AM_CONDITIONAL(USE_DLOG, test "x$USE_DLOG" = "xyes")
 dnl end --------------------------------------------------------------------
 
-#### atomic-ops ###
+dnl use security --------------------------------------------------------------------------
+AC_ARG_ENABLE(security, AC_HELP_STRING([--enable-security], [using security]),
+[
+ case "${enableval}" in
+               yes) USE_SECURITY=yes ;;
+               no)  USE_SECURITY=no ;;
+               *)   AC_MSG_ERROR(bad value ${enableval} for --enable-security) ;;
+ esac
+ ],[USE_SECURITY=no])
+
+if test "x$USE_SECURITY" = "xyes"; then
+               PKG_CHECK_MODULES(SECURITY, security-server)
+               AC_SUBST(SECURITY_CFLAGS)
+               AC_SUBST(SECURITY_LIBS)
+fi
+AM_CONDITIONAL(USE_SECURITY, test "x$USE_SECURITY" = "xyes")
+dnl end --------------------------------------------------------------------
+
+#### atomic-ops ####
 
 AC_MSG_CHECKING([whether we need libatomic_ops])
 if test "x$need_libatomic_ops" = "xyes"; then
-   AC_MSG_RESULT([yes])
-   AC_CHECK_HEADERS([atomic_ops.h], [], [
-   AC_MSG_ERROR([*** libatomic-ops headers not found])
-   ])
-
-   # Win32 does not need the lib and breaks horribly if we try to include it
-   if test "x$os_is_win32" != "x1" ; then
-       LIBS="$LIBS -latomic_ops"
-   fi
+    AC_MSG_RESULT([yes])
+    AC_CHECK_HEADERS([atomic_ops.h],
+        [CFLAGS="$CFLAGS -DAO_REQUIRE_CAS"],
+        [AC_MSG_ERROR([*** libatomic-ops headers not found])])
+
+    # Win32 does not need the lib and breaks horribly if we try to include it
+    AS_IF([test "x$os_is_win32" != "x1"], [LIBS="$LIBS -latomic_ops"])
 else
-   AC_MSG_RESULT([no])
+    AC_MSG_RESULT([no])
 fi
 
 #### Libsamplerate support (optional) ####
 
 AC_ARG_ENABLE([samplerate],
-    AS_HELP_STRING([--disable-samplerate],[Disable optional libsamplerate support]),
-        [
-            case "${enableval}" in
-                yes) samplerate=yes ;;
-                no) samplerate=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-samplerate) ;;
-            esac
-        ],
-        [samplerate=auto])
+    AS_HELP_STRING([--disable-samplerate],[Disable optional libsamplerate support]))
 
-if test "x${samplerate}" != xno ; then
-    PKG_CHECK_MODULES(LIBSAMPLERATE, [ samplerate >= 0.1.0 ],
-        HAVE_LIBSAMPLERATE=1,
-        [
-            HAVE_LIBSAMPLERATE=0
-            if test "x$samplerate" = xyes ; then
-                AC_MSG_ERROR([*** Libsamplerate not found])
-            fi
-        ])
-else
-    HAVE_LIBSAMPLERATE=0
-fi
+AS_IF([test "x$enable_samplerate" != "xno"],
+    [PKG_CHECK_MODULES(LIBSAMPLERATE, [ samplerate >= 0.1.0 ], HAVE_LIBSAMPLERATE=1, HAVE_LIBSAMPLERATE=0)],
+    HAVE_LIBSAMPLERATE=0)
 
-if test "x${HAVE_LIBSAMPLERATE}" = x1 ; then
-   AC_DEFINE([HAVE_LIBSAMPLERATE], 1, [Have libsamplerate?])
-fi
+AS_IF([test "x$enable_samplerate" = "xyes" && test "x$HAVE_LIBSAMPLERATE" = "x0"],
+    [AC_MSG_ERROR([*** Libsamplerate not found])])
 
 AC_SUBST(LIBSAMPLERATE_CFLAGS)
 AC_SUBST(LIBSAMPLERATE_LIBS)
-AC_SUBST(HAVE_LIBSAMPLERATE)
 AM_CONDITIONAL([HAVE_LIBSAMPLERATE], [test "x$HAVE_LIBSAMPLERATE" = x1])
+AS_IF([test "x$HAVE_LIBSAMPLERATE" = "x1"], AC_DEFINE([HAVE_LIBSAMPLERATE], 1, [Have libsamplerate?]))
 
 #### Database support ####
 
-HAVE_TDB=0
-HAVE_GDBM=0
-HAVE_SIMPLEDB=0
+AC_ARG_WITH([database],
+    AS_HELP_STRING([--with-database=auto|tdb|gdbm|simple],[Choose database backend.]),[],[with_database=auto])
 
-AC_ARG_WITH(
-        [database],
-        AS_HELP_STRING([--with-database=auto|tdb|gdbm|simple],[Choose database backend.]),[],[with_database=auto])
 
-if test "x${with_database}" = "xauto" -o "x${with_database}" = "xtdb" ; then
-    PKG_CHECK_MODULES(TDB, [ tdb ],
-        [
-            HAVE_TDB=1
-            with_database=tdb
-        ], [
-            if test "x${with_database}" = "xtdb" ; then
-                AC_MSG_ERROR([*** tdb not found])
-            fi
-        ])
-fi
+AS_IF([test "x$with_database" = "xauto" -o "x$with_database" = "xtdb"],
+    [PKG_CHECK_MODULES(TDB, [ tdb ], HAVE_TDB=1, HAVE_TDB=0)],
+    HAVE_TDB=0)
+AS_IF([test "x$HAVE_TDB" = "x1"], with_database=tdb)
 
-if test "x${with_database}" = "xauto" -o "x${with_database}" = "xgdbm" ; then
-   have_gdbm=yes
+AS_IF([test "x$with_database" = "xtdb" && test "x$HAVE_TDB" = "x0"],
+    [AC_MSG_ERROR([*** tdb not found])])
 
-   AC_CHECK_LIB(gdbm, gdbm_open, [], [have_gdbm=no])
-   AC_CHECK_HEADERS(gdbm.h, [], [have_gdbm=no])
 
-   if test "x${have_gdbm}" = "xyes" ; then
-       HAVE_GDBM=1
-       GDBM_CFLAGS=
-       GDBM_LIBS=-lgdbm
-       with_database=gdbm
-   elif test "x${with_database}" = "xgdbm"; then
-       AC_MSG_ERROR([*** gdbm not found])
-   fi
-fi
+AS_IF([test "x$with_database" = "xauto" -o "x$with_database" = "xgdbm"],
+    [
+        HAVE_GDBM=1
+        AC_CHECK_LIB(gdbm, gdbm_open, [], HAVE_GDBM=0)
+        AC_CHECK_HEADERS(gdbm.h, [], HAVE_GDBM=0)
+    ],
+    HAVE_GDBM=0)
+AS_IF([test "x$HAVE_GDBM" = "x1"],
+    [
+        with_database=gdbm
+        GDBM_CFLAGS=
+        GDBM_LIBS=-lgdbm
+    ])
 
-if test "x${with_database}" = "xauto" -o "x${with_database}" = "xsimple" ; then
-    HAVE_SIMPLEDB=1
-    with_database=simple
-fi
+AS_IF([test "x$with_database" = "xgdbm" && test "x$HAVE_GDBM" = "x0"],
+    [AC_MSG_ERROR([*** gdbm not found])])
 
-if test "x${HAVE_TDB}" != x1 -a "x${HAVE_GDBM}" != x1 -a "x${HAVE_SIMPLEDB}" != x1; then
-   AC_MSG_ERROR([*** missing database backend])
-fi
 
-if test "x${HAVE_TDB}" = x1 ; then
-   AC_DEFINE([HAVE_TDB], 1, [Have tdb?])
-fi
+AS_IF([test "x$with_database" = "xauto" -o "x$with_database" = "xsimple"],
+    HAVE_SIMPLEDB=1,
+    HAVE_SIMPLEDB=0)
+AS_IF([test "x$HAVE_SIMPLEDB" = "x1"], with_database=simple)
 
-if test "x${HAVE_GDBM}" = x1 ; then
-   AC_DEFINE([HAVE_GDBM], 1, [Have gdbm?])
-fi
+AS_IF([test "x$HAVE_TDB" != x1 -a "x$HAVE_GDBM" != x1 -a "x$HAVE_SIMPLEDB" != x1],
+    AC_MSG_ERROR([*** missing database backend]))
 
-if test "x${HAVE_SIMPLEDB}" = x1 ; then
-    AC_DEFINE([HAVE_SIMPLEDB], 1, [Have simple?])
-fi
 
 AC_SUBST(TDB_CFLAGS)
 AC_SUBST(TDB_LIBS)
-AC_SUBST(HAVE_TDB)
 AM_CONDITIONAL([HAVE_TDB], [test "x$HAVE_TDB" = x1])
+AS_IF([test "x$HAVE_TDB" = "x1"], AC_DEFINE([HAVE_TDB], 1, [Have tdb?]))
 
 AC_SUBST(GDBM_CFLAGS)
 AC_SUBST(GDBM_LIBS)
-AC_SUBST(HAVE_GDBM)
 AM_CONDITIONAL([HAVE_GDBM], [test "x$HAVE_GDBM" = x1])
+AS_IF([test "x$HAVE_GDBM" = "x1"], AC_DEFINE([HAVE_GDBM], 1, [Have gdbm?]))
 
-AC_SUBST(HAVE_SIMPLEDB)
 AM_CONDITIONAL([HAVE_SIMPLEDB], [test "x$HAVE_SIMPLEDB" = x1])
+AS_IF([test "x$HAVE_SIMPLEDB" = "x1"], AC_DEFINE([HAVE_SIMPLEDB], 1, [Have simple?]))
 
 #### OSS support (optional) ####
 
 AC_ARG_ENABLE([oss-output],
-    AS_HELP_STRING([--disable-oss-output],[Disable optional OSS output support]),
-        [
-            case "${enableval}" in
-                yes) oss_output=yes ;;
-                no) oss_output=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-oss-output) ;;
-            esac
-        ],
-        [oss_output=auto])
+    AS_HELP_STRING([--disable-oss-output],[Disable optional OSS output support]))
 
 AC_ARG_ENABLE([oss-wrapper],
-    AS_HELP_STRING([--disable-oss-wrapper],[Disable optional OSS wrapper support]),
-        [
-            case "${enableval}" in
-                yes) oss_wrapper=yes ;;
-                no) oss_wrapper=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-oss-wrapper) ;;
-            esac
-        ],
-        [oss_wrapper=auto])
+    AS_HELP_STRING([--disable-oss-wrapper],[Disable optional OSS wrapper support]))
 
-if test "x${oss_output}" != xno || test "x${oss_wrapper}" != "xno"; then
-    AC_CHECK_HEADERS([sys/soundcard.h],
-        [
-            if test "x${oss_output}" != "xno"; then
-                AC_DEFINE([HAVE_OSS_OUTPUT], 1, [Have OSS output?])
-            fi
-            if test "x${oss_wrapper}" != "xno"; then
-                AC_DEFINE([HAVE_OSS_WRAPPER], 1, [Have OSS wrapper (padsp)?])
-            fi
-            HAVE_OSS=1
-        ],
-        [
-            HAVE_OSS=0
-            if test "x$oss_output" = xyes || test "x$oss_wrapper" = "xyes"; then
-                AC_MSG_ERROR([*** OSS support not found])
-            fi
-        ])
-else
-    HAVE_OSS=0
-fi
+AS_IF([test "x$enable_oss_output" != "xno" -o "x$enable_oss_wrapper" != "xno"],
+    [AC_CHECK_HEADERS([sys/soundcard.h], HAVE_OSS=1, HAVE_OSS=0)],
+    HAVE_OSS=0)
+
+AS_IF([test "x$enable_oss_output" = "xyes" -o "x$enable_oss_wrapper" = "xyes" && test "x$HAVE_OSS" = "x0"],
+    [AC_MSG_ERROR([*** OSS support not found])])
+
+AS_IF([test "x$enable_oss_output" != "xno"],
+    [AS_IF([test "x$HAVE_OSS" = "x1"], HAVE_OSS_OUTPUT=1, HAVE_OSS_OUTPUT=0)],
+    HAVE_OSS_OUTPUT=0)
+
+AS_IF([test "x$enable_oss_wrapper" != "xno"],
+    [AS_IF([test "x$HAVE_OSS" = "x1"], HAVE_OSS_WRAPPER=1, HAVE_OSS_WRAPPER=0)],
+    HAVE_OSS_WRAPPER=0)
+
+AC_SUBST(HAVE_OSS_OUTPUT)
+AM_CONDITIONAL([HAVE_OSS_OUTPUT], [test "x$HAVE_OSS_OUTPUT" = "x1"])
+AM_CONDITIONAL([HAVE_OSS_WRAPPER], [test "x$HAVE_OSS_WRAPPER" = "x1"])
+AS_IF([test "x$HAVE_OSS_OUTPUT" = "x1"], AC_DEFINE([HAVE_OSS_OUTPUT], 1, [Have OSS output?]))
+AS_IF([test "x$HAVE_OSS_WRAPPER" = "x1"], AC_DEFINE([HAVE_OSS_WRAPPER], 1, [Have OSS wrapper (padsp)?]))
+
+#### CoreAudio support (optional) ####
+
+AC_ARG_ENABLE([coreaudio-output],
+    AS_HELP_STRING([--disable-coreaudio-output],[Disable optional CoreAudio output support]))
 
-AC_SUBST(HAVE_OSS)
-AM_CONDITIONAL([HAVE_OSS_OUTPUT], [test "x$HAVE_OSS" = x1 && test "x${oss_output}" != "xno"])
-AM_CONDITIONAL([HAVE_OSS_WRAPPER], [test "x$HAVE_OSS" = x1 && test "x${oss_wrapper}" != "xno"])
+AS_IF([test "x$enable_coreaudio_output" != "xno"],
+    [AC_CHECK_HEADERS([CoreAudio/CoreAudio.h], HAVE_COREAUDIO=1, HAVE_COREAUDIO=0)],
+    HAVE_COREAUDIO=0)
+
+AS_IF([test "x$enable_coreaudio_output" = "xyes" && test "x$HAVE_COREAUDIO" = "x0"],
+    [AC_MSG_ERROR([*** CoreAudio output support not found])])
+
+AM_CONDITIONAL([HAVE_COREAUDIO], [test "x$HAVE_COREAUDIO" = "x1" && test "x$enable_coreaudio_output" != "xno"])
 
 #### ALSA support (optional) ####
 
 AC_ARG_ENABLE([alsa],
-    AS_HELP_STRING([--disable-alsa],[Disable optional ALSA support]),
-        [
-            case "${enableval}" in
-                yes) alsa=yes ;;
-                no) alsa=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-alsa) ;;
-            esac
-        ],
-        [alsa=auto])
+    AS_HELP_STRING([--disable-alsa],[Disable optional ALSA support]))
 
-if test "x${alsa}" != xno ; then
-    PKG_CHECK_MODULES(ASOUNDLIB, [ alsa >= 1.0.19 ],
-        [
-            HAVE_ALSA=1
-            AC_DEFINE([HAVE_ALSA], 1, [Have ALSA?])
-        ],
-        [
-            HAVE_ALSA=0
-            if test "x$alsa" = xyes ; then
-                AC_MSG_ERROR([*** Needed alsa >= 1.0.19 support not found])
-            fi
-        ])
-else
-    HAVE_ALSA=0
-fi
+AS_IF([test "x$enable_alsa" != "xno"],
+    [PKG_CHECK_MODULES(ASOUNDLIB, [ alsa >= 1.0.24 ], HAVE_ALSA=1, HAVE_ALSA=0)],
+    HAVE_ALSA=0)
+
+AS_IF([test "x$enable_alsa" = "xyes" && test "x$HAVE_ALSA" = "x0"],
+    [AC_MSG_ERROR([*** Needed alsa >= 1.0.24 support not found])])
 
 AC_SUBST(ASOUNDLIB_CFLAGS)
 AC_SUBST(ASOUNDLIB_LIBS)
 AC_SUBST(HAVE_ALSA)
 AM_CONDITIONAL([HAVE_ALSA], [test "x$HAVE_ALSA" = x1])
+AS_IF([test "x$HAVE_ALSA" = "x1"], AC_DEFINE([HAVE_ALSA], 1, [Have ALSA?]))
+
+#### EsounD support (optional) ####
+
+AC_ARG_ENABLE([esound],
+    AS_HELP_STRING([--disable-esound],[Disable optional EsounD support]))
+AM_CONDITIONAL([HAVE_ESOUND], [test "x$enable_esound" != "xno"])
+AS_IF([test "x$enable_esound" != "xno"], [HAVE_ESOUND=1])
 
 #### Solaris audio support (optional) ####
 
 AC_ARG_ENABLE([solaris],
-    AS_HELP_STRING([--disable-solaris],[Disable optional Solaris audio support]),
-        [
-            case "${enableval}" in
-                yes) solaris=yes ;;
-                no) solaris=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-solaris) ;;
-            esac
-        ],
-        [solaris=auto])
+    AS_HELP_STRING([--disable-solaris],[Disable optional Solaris audio support]))
 
-if test "x${solaris}" != xno ; then
-    AC_CHECK_HEADERS([sys/audio.h],
-        [
-            HAVE_SOLARIS=1
-            AC_DEFINE([HAVE_SOLARIS], 1, [Have Solaris audio?])
-        ],
-        [
-            HAVE_SOLARIS=0
-            if test "x$solaris" = xyes ; then
-                AC_MSG_ERROR([*** Solaris audio support not found])
-            fi
-        ])
-else
-    HAVE_SOLARIS=0
-fi
+AS_IF([test "x$enable_solaris" != "xno"],
+    [AC_CHECK_HEADERS([sys/audio.h], HAVE_SOLARIS=1, HAVE_SOLARIS=0)],
+    HAVE_SOLARIS=0)
+
+AS_IF([test "x$enable_solaris" = "xyes" && test "x$HAVE_SOLARIS" = "x0"],
+    [AC_MSG_ERROR([*** Solaris audio support not found])])
 
-AC_SUBST(HAVE_SOLARIS)
 AM_CONDITIONAL([HAVE_SOLARIS], [test "x$HAVE_SOLARIS" = x1])
+AS_IF([test "x$HAVE_SOLARIS" = "x1"], AC_DEFINE([HAVE_SOLARIS], 1, [Have Solaris audio?]))
+
+#### WaveOut audio support (optional) ####
+
+AC_ARG_ENABLE([waveout],
+    AS_HELP_STRING([--disable-waveout],[Disable optional WaveOut audio support]))
+
+AS_IF([test "x$enable_waveout" != "xno"],
+    [AC_CHECK_HEADERS([mmsystem.h], HAVE_WAVEOUT=1, HAVE_WAVEOUT=0, [#include <windows.h>])],
+    HAVE_WAVEOUT=0)
+
+AS_IF([test "x$enable_waveout" = "xyes" && test "x$HAVE_WAVEOUT" = "x0"],
+    [AC_MSG_ERROR([*** WaveOut audio support not found])])
+
+AC_SUBST(HAVE_WAVEOUT)
+AM_CONDITIONAL([HAVE_WAVEOUT], [test "x$HAVE_WAVEOUT" = x1])
+AS_IF([test "x$HAVE_WAVEOUT" = "x1"], AC_DEFINE([HAVE_WAVEOUT], 1, [Have WaveOut audio?]))
 
 #### GLib 2 support (optional) ####
 
 AC_ARG_ENABLE([glib2],
-    AS_HELP_STRING([--disable-glib2],[Disable optional GLib 2 support]),
-        [
-            case "${enableval}" in
-                yes) glib2=yes ;;
-                no) glib2=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-glib2) ;;
-            esac
-        ],
-        [glib2=auto])
+    AS_HELP_STRING([--disable-glib2],[Disable optional GLib 2 support]))
 
-if test "x${glib2}" != xno ; then
-    PKG_CHECK_MODULES(GLIB20, [ glib-2.0 >= 2.4.0 ],
-        HAVE_GLIB20=1,
-        [
-            HAVE_GLIB20=0
-            if test "x$glib2" = xyes ; then
-                AC_MSG_ERROR([*** GLib 2 support not found])
-            fi
-        ])
-else
-    HAVE_GLIB20=0
-fi
+AS_IF([test "x$enable_glib2" != "xno"],
+    [PKG_CHECK_MODULES(GLIB20, [ glib-2.0 >= 2.4.0 ], HAVE_GLIB20=1, HAVE_GLIB20=0)],
+    HAVE_GLIB20=0)
+
+AS_IF([test "x$enable_glib2" = "xyes" && test "x$HAVE_GLIB20" = "x0"],
+    [AC_MSG_ERROR([*** GLib 2 support not found])])
 
 AC_SUBST(GLIB20_CFLAGS)
 AC_SUBST(GLIB20_LIBS)
 AC_SUBST(HAVE_GLIB20)
 AM_CONDITIONAL([HAVE_GLIB20], [test "x$HAVE_GLIB20" = x1])
+AS_IF([test "x$HAVE_GLIB20" = "x1"], AC_DEFINE([HAVE_GLIB], 1, [Have GLIB?]))
 
-if test "x$HAVE_GLIB20" = x1 ; then
-   AC_DEFINE([HAVE_GLIB], 1, [Have GLIB?])
-fi
-
-#### GTK2 support (optional) ####
+#### GTK3 support (optional) ####
 
-AC_ARG_ENABLE([gtk2],
-    AS_HELP_STRING([--disable-gtk2],[Disable optional Gtk+ 2 support]),
-        [
-            case "${enableval}" in
-                yes) gtk2=yes ;;
-                no) gtk2=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-gtk2) ;;
-            esac
-        ],
-        [gtk2=auto])
+AC_ARG_ENABLE([gtk3],
+    AS_HELP_STRING([--disable-gtk3],[Disable optional Gtk+ 3 support]))
 
-if test "x${gtk2}" != xno ; then
-    PKG_CHECK_MODULES(GTK20, [ gtk+-2.0 >= 2.4.0 ],
-        HAVE_GTK20=1,
-        [
-            HAVE_GTK20=0
-            if test "x$gtk2" = xyes ; then
-                AC_MSG_ERROR([*** Gtk+ 2 support not found])
-            fi
-        ])
-else
-    HAVE_GTK20=0
-fi
+AS_IF([test "x$enable_gtk3" != "xno"],
+    [PKG_CHECK_MODULES(GTK30, [ gtk+-3.0 ], HAVE_GTK30=1, HAVE_GTK30=0)],
+    HAVE_GTK30=0)
 
-AC_SUBST(GTK20_CFLAGS)
-AC_SUBST(GTK20_LIBS)
-AC_SUBST(HAVE_GTK20)
-AM_CONDITIONAL([HAVE_GTK20], [test "x$HAVE_GTK20" = x1])
+AS_IF([test "x$enable_gtk3" = "xyes" && test "x$HAVE_GTK30" = "x0"],
+    [AC_MSG_ERROR([*** Gtk+ 3 support not found])])
 
-if test "x$HAVE_GTK20" = x1 ; then
-   AC_DEFINE([HAVE_GTK], 1, [Have GTK?])
-fi
+AC_SUBST(GTK30_CFLAGS)
+AC_SUBST(GTK30_LIBS)
+AM_CONDITIONAL([HAVE_GTK30], [test "x$HAVE_GTK30" = x1])
+AS_IF([test "x$HAVE_GTK30" = "x1"], AC_DEFINE([HAVE_GTK], 1, [Have GTK?]))
 
 #### GConf support (optional) ####
 
 AC_ARG_ENABLE([gconf],
-    AS_HELP_STRING([--disable-gconf],[Disable optional GConf support]),
-        [
-            case "${enableval}" in
-                yes) gconf=yes ;;
-                no) gconf=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-gconf) ;;
-            esac
-        ],
-        [gconf=auto])
+    AS_HELP_STRING([--disable-gconf],[Disable optional GConf support]))
 
-if test "x${gconf}" != xno ; then
-    PKG_CHECK_MODULES(GCONF, [ gconf-2.0 >= 2.4.0 ],
-        HAVE_GCONF=1,
-        [
-            HAVE_GCONF=0
-            if test "x$gconf" = xyes ; then
-                AC_MSG_ERROR([*** GConf support not found])
-            fi
-        ])
-else
-    HAVE_GCONF=0
-fi
+AS_IF([test "x$enable_gconf" != "xno"],
+    [PKG_CHECK_MODULES(GCONF, [ gconf-2.0 >= 2.4.0 gobject-2.0 ], HAVE_GCONF=1, HAVE_GCONF=0)],
+    HAVE_GCONF=0)
+
+AS_IF([test "x$enable_gconf" = "xyes" && test "x$HAVE_GCONF" = "x0"],
+    [AC_MSG_ERROR([*** GConf support not found])])
 
 AC_SUBST(GCONF_CFLAGS)
 AC_SUBST(GCONF_LIBS)
-AC_SUBST(HAVE_GCONF)
 AM_CONDITIONAL([HAVE_GCONF], [test "x$HAVE_GCONF" = x1])
 
 #### Avahi support (optional) ####
 
 AC_ARG_ENABLE([avahi],
-    AS_HELP_STRING([--disable-avahi],[Disable optional Avahi support]),
-        [
-            case "${enableval}" in
-                yes) avahi=yes ;;
-                no) avahi=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-avahi) ;;
-            esac
-        ],
-        [avahi=auto])
+    AS_HELP_STRING([--disable-avahi],[Disable optional Avahi support]))
 
-if test "x${avahi}" != xno ; then
-    PKG_CHECK_MODULES(AVAHI, [ avahi-client >= 0.6.0 ],
-        HAVE_AVAHI=1,
-        [
-                HAVE_AVAHI=0
-                if test "x$avahi" = xyes ; then
-                        AC_MSG_ERROR([*** Avahi support not found])
-                fi
-        ])
-else
-    HAVE_AVAHI=0
-fi
+AS_IF([test "x$enable_avahi" != "xno"],
+    [PKG_CHECK_MODULES(AVAHI, [ avahi-client >= 0.6.0 ], HAVE_AVAHI=1, HAVE_AVAHI=0)],
+    HAVE_AVAHI=0)
+
+AS_IF([test "x$enable_avahi" = "xyes" && test "x$HAVE_AVAHI" = "x0"],
+    [AC_MSG_ERROR([*** Avahi support not found])])
 
 AC_SUBST(AVAHI_CFLAGS)
 AC_SUBST(AVAHI_LIBS)
 AC_SUBST(HAVE_AVAHI)
 AM_CONDITIONAL([HAVE_AVAHI], [test "x$HAVE_AVAHI" = x1])
 
-### JACK (optional) ####
+#### JACK (optional) ####
 
 AC_ARG_ENABLE([jack],
-    AS_HELP_STRING([--disable-jack],[Disable optional JACK support]),
-        [
-            case "${enableval}" in
-                yes) jack=yes ;;
-                no) jack=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-jack) ;;
-            esac
-        ],
-        [jack=auto])
+    AS_HELP_STRING([--disable-jack],[Disable optional JACK support]))
 
-if test "x${jack}" != xno ; then
-    PKG_CHECK_MODULES(JACK, [ jack >= 0.100 ],
-        HAVE_JACK=1,
-        [
-            HAVE_JACK=0
-            if test "x$jack" = xyes ; then
-                AC_MSG_ERROR([*** JACK support not found])
-            fi
-        ])
-else
-    HAVE_JACK=0
-fi
+AS_IF([test "x$enable_jack" != "xno"],
+    [PKG_CHECK_MODULES(JACK, [ jack >= 0.117.0 ], HAVE_JACK=1, HAVE_JACK=0)],
+    HAVE_JACK=0)
+
+AS_IF([test "x$enable_jack" = "xyes" && test "x$HAVE_JACK" = "x0"],
+    [AC_MSG_ERROR([*** JACK support not found])])
 
 AC_SUBST(JACK_CFLAGS)
 AC_SUBST(JACK_LIBS)
-AC_SUBST(HAVE_JACK)
 AM_CONDITIONAL([HAVE_JACK], [test "x$HAVE_JACK" = x1])
 
 #### Async DNS support (optional) ####
 
 AC_ARG_ENABLE([asyncns],
-    AS_HELP_STRING([--disable-asyncns],[Disable optional Async DNS support]),
-        [
-            case "${enableval}" in
-                yes) asyncns=yes ;;
-                no) asyncns=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-asyncns) ;;
-            esac
-        ],
-        [asyncns=auto])
+    AS_HELP_STRING([--disable-asyncns],[Disable optional Async DNS support]))
 
-if test "x${asyncns}" != xno ; then
-    PKG_CHECK_MODULES(LIBASYNCNS, [ libasyncns >= 0.1 ],
-        HAVE_LIBASYNCNS=1,
-        [
-            HAVE_LIBASYNCNS=0
-            if test "x$asyncns" = xyes ; then
-                AC_MSG_ERROR([*** Async DNS support not found])
-            fi
-        ])
-else
-    HAVE_LIBASYNCNS=0
-fi
+AS_IF([test "x$enable_asyncns" != "xno"],
+    [PKG_CHECK_MODULES(LIBASYNCNS, [ libasyncns >= 0.1 ], HAVE_LIBASYNCNS=1, HAVE_LIBASYNCNS=0)],
+    HAVE_LIBASYNCNS=0)
+
+AS_IF([test "x$enable_asyncns" = "xyes" && test "x$HAVE_LIBASYNCNS" = "x0"],
+    [AC_MSG_ERROR([*** Async DNS support not found])])
 
 AC_SUBST(LIBASYNCNS_CFLAGS)
 AC_SUBST(LIBASYNCNS_LIBS)
-AC_SUBST(HAVE_LIBASYNCNS)
 AM_CONDITIONAL([HAVE_LIBASYNCNS], [test "x$HAVE_LIBASYNCNS" = x1])
-
-if test "x$HAVE_LIBASYNCNS" != "x0" ; then
-   AC_DEFINE([HAVE_LIBASYNCNS], 1, [Have libasyncns?])
-fi
+AS_IF([test "x$HAVE_LIBASYNCNS" = "x1"], AC_DEFINE([HAVE_LIBASYNCNS], 1, [Have libasyncns?]))
 
 #### TCP wrappers (optional) ####
 
 AC_ARG_ENABLE([tcpwrap],
-    AS_HELP_STRING([--disable-tcpwrap],[Disable optional TCP wrappers support]),
-        [
-            case "${enableval}" in
-                yes) tcpwrap=yes ;;
-                no) tcpwrap=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-tcpwrap) ;;
-            esac
-        ],
-        [tcpwrap=auto])
+    AS_HELP_STRING([--disable-tcpwrap],[Disable optional TCP wrappers support]))
 
-if test "x${tcpwrap}" != xno ; then
-    ACX_LIBWRAP
-    if test "x${LIBWRAP_LIBS}" = x && test "x$tcpwrap" = xyes ; then
-        AC_MSG_ERROR([*** TCP wrappers support not found])
-    fi
-else
-    LIBWRAP_LIBS=
-fi
+AS_IF([test "x$enable_tcpwrap" != "xno"],
+    [
+        ACX_LIBWRAP
+        AS_IF([test "x$LIBWRAP_LIBS" != "x"], HAVE_TCPWRAP=1, HAVE_TCPWRAP=0)
+    ],
+    HAVE_TCPWRAP=0)
+
+AS_IF([test "x$enable_tcpwrap" = "xyes" && test "x$HAVE_TCPWRAP" = "x0"],
+    [AC_MSG_ERROR([*** TCP wrappers support not found])])
 
 AC_SUBST(LIBWRAP_LIBS)
 
 #### LIRC support (optional) ####
 
 AC_ARG_ENABLE([lirc],
-    AS_HELP_STRING([--disable-lirc],[Disable optional LIRC support]),
-        [
-            case "${enableval}" in
-                yes) lirc=yes ;;
-                no) lirc=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-lirc) ;;
-            esac
-        ],
-        [lirc=auto])
+    AS_HELP_STRING([--disable-lirc],[Disable optional LIRC support]))
 
-if test "x${lirc}" != xno ; then
-    ACX_LIRC
-    if test "x${HAVE_LIRC}" = x0 && test "x$lirc" = xyes ; then
-        AC_MSG_ERROR([*** LIRC support not found])
-    fi
-else
-    HAVE_LIRC=0
-fi
+LIRC_CFLAGS=
+LIRC_LIBS=
+
+AS_IF([test "x$enable_lirc" != "xno"],
+    [
+        HAVE_LIRC=1
+        AC_CHECK_HEADER(lirc/lirc_client.h, [], [HAVE_LIRC=0])
+        AC_CHECK_LIB(lirc_client, lirc_init, [LIRC_LIBS=-llirc_client], [HAVE_LIRC=0])
+    ],
+    HAVE_LIRC=0)
+
+AS_IF([test "x$enable_lirc" = "xyes" && test "x$HAVE_LIRC" = "x0"],
+    [AC_MSG_ERROR([*** LIRC support not found])])
 
 AC_SUBST(LIRC_CFLAGS)
 AC_SUBST(LIRC_LIBS)
 AM_CONDITIONAL([HAVE_LIRC], [test "x$HAVE_LIRC" = x1])
 
-#### HAL support (optional) ####
+#### D-Bus support (optional) ####
 
-AC_ARG_ENABLE([hal],
-    AS_HELP_STRING([--disable-hal],[Disable optional HAL support]),
-        [
-            case "${enableval}" in
-                yes) hal=yes ;;
-                no) hal=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-hal) ;;
-            esac
-        ],
-        [hal=auto])
-if test "x${hal}" != xno -a \( "x$HAVE_OSS" = "x1" -o "x$HAVE_ALSA" = "x1" \) ; then
-    PKG_CHECK_MODULES(HAL, [ hal >= 0.5.11 ],
-        [
-            HAVE_HAL=1
-            AC_DEFINE([HAVE_HAL], 1, [Have HAL.])
-        ],
-        [
-            HAVE_HAL=0
-            if test "x$hal" = xyes ; then
-                AC_MSG_ERROR([*** HAL support not found])
-            fi
-        ])
-else
-    HAVE_HAL=0
-fi
+AC_ARG_ENABLE([dbus],
+    AS_HELP_STRING([--disable-dbus],[Disable optional D-Bus support]))
 
-AC_SUBST(HAL_CFLAGS)
-AC_SUBST(HAL_LIBS)
-AC_SUBST(HAVE_HAL)
-AM_CONDITIONAL([HAVE_HAL], [test "x$HAVE_HAL" = x1])
+AS_IF([test "x$enable_dbus" != "xno"],
+    [PKG_CHECK_MODULES(DBUS, [ dbus-1 >= 1.4.12 ], HAVE_DBUS=1, HAVE_DBUS=0)],
+    HAVE_DBUS=0)
+
+AS_IF([test "x$enable_dbus" = "xyes" && test "x$HAVE_DBUS" = "x0"],
+    [AC_MSG_ERROR([*** D-Bus not available or too old version])])
+
+AS_IF([test "x$HAVE_DBUS" = "x1"],
+    [
+        save_CFLAGS="$CFLAGS"; CFLAGS="$CFLAGS $DBUS_CFLAGS"
+        save_LIBS="$LIBS"; LIBS="$LIBS $DBUS_LIBS"
+        AC_CHECK_FUNCS(dbus_watch_get_unix_fd)
+        CFLAGS="$save_CFLAGS"
+        LIBS="$save_LIBS"
+    ])
+
+AC_SUBST(DBUS_CFLAGS)
+AC_SUBST(DBUS_LIBS)
+AC_SUBST(HAVE_DBUS)
+AM_CONDITIONAL([HAVE_DBUS], [test "x$HAVE_DBUS" = x1])
+AS_IF([test "x$HAVE_DBUS" = "x1"], AC_DEFINE([HAVE_DBUS], 1, [Have D-Bus.]))
+
+PA_MACHINE_ID="${sysconfdir}/machine-id"
+AX_DEFINE_DIR(PA_MACHINE_ID, PA_MACHINE_ID, [D-Bus machine-id file])
+PA_MACHINE_ID_FALLBACK="${localstatedir}/lib/dbus/machine-id"
+AX_DEFINE_DIR(PA_MACHINE_ID_FALLBACK, PA_MACHINE_ID_FALLBACK,
+             [Fallback machine-id file])
+
+#### BlueZ support (optional, dependent on D-Bus and SBC) ####
+
+AC_ARG_ENABLE([bluez4],
+    AS_HELP_STRING([--disable-bluez4],[Disable optional BlueZ 4 support]))
+AC_ARG_ENABLE([bluez5],
+    AS_HELP_STRING([--disable-bluez5],[Disable optional BlueZ 5 support]))
+
+## SBC ##
+AS_IF([test "x$enable_bluez4" != "xno" || test "x$enable_bluez5" != "xno"],
+    [PKG_CHECK_MODULES(SBC, [ sbc >= 1.0 ], HAVE_SBC=1, HAVE_SBC=0)],
+    HAVE_SBC=0)
+
+## BlueZ 4 ##
+AS_IF([test "x$enable_bluez4" != "xno" && test "x$HAVE_DBUS" = "x1" && test "x$HAVE_SBC" = "x1"], HAVE_BLUEZ_4=1)
+AS_IF([test "x$enable_bluez4" = "xyes" && test "x$HAVE_BLUEZ_4" != "x1"],
+    [AC_MSG_ERROR([*** BLUEZ 4 support not found (requires sbc and D-Bus)])])
+AC_SUBST(HAVE_BLUEZ_4)
+AM_CONDITIONAL([HAVE_BLUEZ_4], [test "x$HAVE_BLUEZ_4" = x1])
+
+## BlueZ 5 ##
+AS_IF([test "x$enable_bluez5" != "xno" && test "x$HAVE_DBUS" = "x1" && test "x$HAVE_SBC" = "x1"], HAVE_BLUEZ_5=1)
+AS_IF([test "x$enable_bluez5" = "xyes" && test "x$HAVE_BLUEZ_5" != "x1"],
+    [AC_MSG_ERROR([*** BLUEZ 5 support not found (requires sbc and D-Bus)])])
+AC_SUBST(HAVE_BLUEZ_5)
+AM_CONDITIONAL([HAVE_BLUEZ_5], [test "x$HAVE_BLUEZ_5" = x1])
+
+AS_IF([test "x$HAVE_BLUEZ_4" = "x1" || test "x$HAVE_BLUEZ_5" = "x1"], HAVE_BLUEZ=1)
+AC_SUBST(HAVE_BLUEZ)
+AM_CONDITIONAL([HAVE_BLUEZ], [test "x$HAVE_BLUEZ" = x1])
 
 #### UDEV support (optional) ####
 
 AC_ARG_ENABLE([udev],
-    AS_HELP_STRING([--disable-udev],[Disable optional UDEV support]),
-        [
-            case "${enableval}" in
-                yes) udev=yes ;;
-                no) udev=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-udev) ;;
-            esac
-        ],
-        [udev=auto])
-if test "x${udev}" != xno -a \( "x$HAVE_OSS" = "x1" -o "x$HAVE_ALSA" = "x1" \) ; then
-    PKG_CHECK_MODULES(UDEV, [ libudev >= 143 ],
-        [
-            HAVE_UDEV=1
-            AC_DEFINE([HAVE_UDEV], 1, [Have UDEV.])
-        ],
-        [
-            HAVE_UDEV=0
-            if test "x$udev" = xyes ; then
-                AC_MSG_ERROR([*** UDEV support not found])
-            fi
-        ])
-else
-    HAVE_UDEV=0
-fi
+    AS_HELP_STRING([--disable-udev],[Disable optional UDEV support]))
+
+AS_IF([test "x$enable_udev" != "xno" -a \( "x$HAVE_OSS" = "x1" -o "x$HAVE_ALSA" = "x1" \)],
+    [PKG_CHECK_MODULES(UDEV, [ libudev >= 143 ], HAVE_UDEV=1, HAVE_UDEV=0)],
+    HAVE_UDEV=0)
+
+AS_IF([test "x$enable_udev" = "xyes" && test "x$HAVE_UDEV" = "x0"],
+    [AC_MSG_ERROR([*** UDEV support not found])])
 
 AC_SUBST(UDEV_CFLAGS)
 AC_SUBST(UDEV_LIBS)
 AC_SUBST(HAVE_UDEV)
 AM_CONDITIONAL([HAVE_UDEV], [test "x$HAVE_UDEV" = x1])
+AS_IF([test "x$HAVE_UDEV" = "x1"], AC_DEFINE([HAVE_UDEV], 1, [Have UDEV.]))
 
-#### HAL compat support (optional) ####
+#### HAL compat support (optional, dependant on UDEV) ####
 
 AC_ARG_ENABLE([hal-compat],
-    AS_HELP_STRING([--disable-hal-compat],[Disable optional HAL->udev transition compatibility support]),
-        [
-            case "${enableval}" in
-                yes) halcompat=yes ;;
-                no) halcompat=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-hal-compat) ;;
-            esac
-        ],
-        [halcompat=auto])
-if test "x${halcompat}" != xno -a "x$HAVE_HAL" = "x0" -a "x$HAVE_UDEV" = "x1" ; then
-    HAVE_HAL_COMPAT=1
-    AC_DEFINE([HAVE_HAL_COMPAT], 1, [Have HAL compatibility.])
-else
-    HAVE_HAL_COMPAT=0
-fi
+    AS_HELP_STRING([--disable-hal-compat],[Disable optional HAL->udev transition compatibility support]))
+
+AS_IF([test "x$enable_hal_compat" != "xno"],
+    [AS_IF([test "x$HAVE_UDEV" = "x1"], HAVE_HAL_COMPAT=1, HAVE_HAL_COMPAT=0)],
+    HAVE_HAL_COMPAT=0)
 
-AC_SUBST(HAVE_HAL_COMPAT)
 AM_CONDITIONAL([HAVE_HAL_COMPAT], [test "x$HAVE_HAL_COMPAT" = x1])
+AS_IF([test "x$HAVE_HAL_COMPAT" = "x1"], AC_DEFINE([HAVE_HAL_COMPAT], 1, [Have HAL compatibility.]))
 
-#### BlueZ support (optional) ####
+#### IPv6 connection support (optional) ####
 
-AC_ARG_ENABLE([bluez],
-    AS_HELP_STRING([--disable-bluez],[Disable optional BlueZ support]),
-        [
-            case "${enableval}" in
-                yes) bluez=yes ;;
-                no) bluez=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-bluez) ;;
-            esac
-        ],
-        [bluez=auto])
-if test "x${bluez}" != xno ; then
-    PKG_CHECK_MODULES(BLUEZ, [ bluez >= 3.0 ],
-        HAVE_BLUEZ=1,
-        [
-            HAVE_BLUEZ=0
-            if test "x$bluez" = xyes ; then
-                AC_MSG_ERROR([*** BLUEZ support not found])
-            fi
-        ])
-else
-    HAVE_BLUEZ=0
-fi
+AC_ARG_ENABLE([ipv6],
+    AS_HELP_STRING([--disable-ipv6],[Disable optional IPv6 support]))
 
-AC_SUBST(BLUEZ_CFLAGS)
-AC_SUBST(BLUEZ_LIBS)
-AC_SUBST(HAVE_BLUEZ)
-AM_CONDITIONAL([HAVE_BLUEZ], [test "x$HAVE_BLUEZ" = x1])
+AS_IF([test "x$enable_ipv6" != "xno"], [HAVE_IPV6=1], [HAVE_IPV6=0])
 
-#### Bluetooth A2DP aptx codec support(optional) ####
-AC_ARG_ENABLE([bt_a2dp_aptx],
-    AS_HELP_STRING([--enable-bt-a2dp-aptx],[Enable optional Bluetooth A2DP aptx codec support(arm only)]),
-        [
-            case "${enableval}" in
-                yes) bt_a2dp_aptx=yes ;;
-                no) bt_a2dp_aptx=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --enable-bt-a2dp-aptx) ;;
-            esac
-        ],
-        [bt_a2dp_aptx=false])
-if test "x${bt_a2dp_aptx}" == xyes ; then
-       HAVE_BT_A2DP_APTX=1
-else
-       HAVE_BT_A2DP_APTX=0
-fi
+AS_IF([test "x$HAVE_IPV6" = "x1"], AC_DEFINE([HAVE_IPV6], 1, [Define this to enable IPv6 connection support]))
 
-AC_SUBST(HAVE_BT_A2DP_APTX)
-AM_CONDITIONAL([HAVE_BT_A2DP_APTX], [test "x$HAVE_BT_A2DP_APTX" = x1])
+#### OpenSSL support (optional) ####
 
-#### D-Bus support (optional) ####
+AC_ARG_ENABLE([openssl],
+    AS_HELP_STRING([--disable-openssl],[Disable OpenSSL support (used for Airtunes/RAOP)]))
 
-AC_ARG_ENABLE([dbus],
-    AS_HELP_STRING([--disable-dbus],[Disable optional D-Bus support]),
-        [
-            case "${enableval}" in
-                yes) dbus=yes ;;
-                no) dbus=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-dbus) ;;
-            esac
-        ],
-        [dbus=auto])
+AS_IF([test "x$enable_openssl" != "xno"],
+    [PKG_CHECK_MODULES(OPENSSL, [ openssl > 0.9 ], HAVE_OPENSSL=1, HAVE_OPENSSL=0)],
+    HAVE_OPENSSL=0)
 
-if test "x$HAVE_HAL" = x1 ; then
-   dbus=yes
-fi
+AS_IF([test "x$enable_openssl" = "xyes" && test "x$HAVE_OPENSSL" = "x0"],
+    [AC_MSG_ERROR([*** OpenSSL support not found])])
 
-if test "x${dbus}" != xno || test "x${bluez}" != xno || test "x${hal}" != xno ; then
+AC_SUBST(OPENSSL_CFLAGS)
+AC_SUBST(OPENSSL_LIBS)
+AM_CONDITIONAL([HAVE_OPENSSL], [test "x$HAVE_OPENSSL" = x1])
+AS_IF([test "x$HAVE_OPENSSL" = "x1"], AC_DEFINE([HAVE_OPENSSL], 1, [Have OpenSSL]))
 
-    PKG_CHECK_MODULES(DBUS, [ dbus-1 >= 1.0.0 ],
-        [
-            HAVE_DBUS=1
-            saved_LIBS="$LIBS"
-            LIBS="$LIBS $DBUS_LIBS"
-            AC_CHECK_FUNCS(dbus_watch_get_unix_fd)
-            LIBS="$saved_LIBS"
-            AC_DEFINE([HAVE_DBUS], 1, [Have D-Bus.])
-        ],
-        [
-            HAVE_DBUS=0
-            if test "x$dbus" = xyes ; then
-                AC_MSG_ERROR([*** D-Bus support not found])
-            fi
-        ])
-else
-    HAVE_DBUS=0
-fi
+#### FFTW (optional) ####
 
-AC_SUBST(DBUS_CFLAGS)
-AC_SUBST(DBUS_LIBS)
-AC_SUBST(HAVE_DBUS)
-AM_CONDITIONAL([HAVE_DBUS], [test "x$HAVE_DBUS" = x1])
+AC_ARG_WITH([fftw],
+    AS_HELP_STRING([--without-fftw],[Omit FFTW-using modules (equalizer)]))
 
-### IPv6 connection support (optional) ###
+AS_IF([test "x$with_fftw" != "xno"],
+    [PKG_CHECK_MODULES(FFTW, [ fftw3f ], HAVE_FFTW=1, HAVE_FFTW=0)],
+    HAVE_FFTW=0)
 
-AC_ARG_ENABLE([ipv6],
-    AS_HELP_STRING([--disable-ipv6],[Disable optional IPv6 support]),
-        [
-            case "${enableval}" in
-                yes) ipv6=yes ;;
-                no) ipv6=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-ipv6) ;;
-            esac
-        ],
-        [ipv6=auto])
+AS_IF([test "x$with_fftw" = "xyes" && test "x$HAVE_FFTW" = "x0"],
+    [AC_MSG_ERROR([*** FFTW support not found])])
 
-if test "x${ipv6}" != xno ; then
-    AC_DEFINE([HAVE_IPV6], [1], [Define this to enable IPv6 connection support])
-    HAVE_IPV6=1
-else
-    HAVE_IPV6=0
-fi
+AM_CONDITIONAL([HAVE_FFTW], [test "x$HAVE_FFTW" = "x1"])
 
-#### OpenSSL support (optional) ####
+#### speex (optional) ####
 
-AC_ARG_ENABLE([openssl],
-    AS_HELP_STRING([--disable-openssl],[Disable OpenSSL support (used for Airtunes/RAOP)]),
-        [
-            case "${enableval}" in
-                yes) openssl=yes ;;
-                no) openssl=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-openssl) ;;
-            esac
-        ],
-        [openssl=auto])
+AC_ARG_WITH([speex],
+    AS_HELP_STRING([--without-speex],[Omit speex (resampling, AEC)]))
 
-if test "x${openssl}" != xno ; then
+AS_IF([test "x$with_speex" != "xno"],
+    [PKG_CHECK_MODULES(LIBSPEEX, [ speexdsp >= 1.2 ], HAVE_SPEEX=1, HAVE_SPEEX=0)],
+    HAVE_SPEEX=0)
 
-    PKG_CHECK_MODULES(OPENSSL, [ openssl > 0.9 ],
-        [
-            HAVE_OPENSSL=1
-            AC_DEFINE([HAVE_OPENSSL], 1, [Have OpenSSL])
-        ],
-        [
-            HAVE_OPENSSL=0
-            if test "x$openssl" = xyes ; then
-                AC_MSG_ERROR([*** OpenSSL support not found])
-            fi
-        ])
-else
-    HAVE_OPENSSL=0
-fi
+AS_IF([test "x$with_speex" = "xyes" && test "x$HAVE_SPEEX" = "x0"],
+    [AC_MSG_ERROR([*** speex support not found])])
 
-AC_SUBST(OPENSSL_CFLAGS)
-AC_SUBST(OPENSSL_LIBS)
-AC_SUBST(HAVE_OPENSSL)
-AM_CONDITIONAL([HAVE_OPENSSL], [test "x$HAVE_OPENSSL" = x1])
+AM_CONDITIONAL([HAVE_SPEEX], [test "x$HAVE_SPEEX" = "x1"])
+AS_IF([test "x$HAVE_SPEEX" = "x1"], AC_DEFINE([HAVE_SPEEX], 1, [Have speex]))
+
+AC_SUBST(LIBSPEEX_CFLAGS)
+AC_SUBST(LIBSPEEX_LIBS)
+
+#### Xen support (optional) ####
+
+AC_ARG_ENABLE([xen],
+    AS_HELP_STRING([--disable-xen],[Disable optional Xen paravirtualized driver]))
+
+XEN_CFLAGS=
+XEN_LIBS=
+
+AS_IF([test "x$enable_xen" != "xno"],
+    [
+        HAVE_XEN=1
+        AC_CHECK_HEADER(xenctrl.h, [], [HAVE_XEN=0])
+        AC_CHECK_HEADER(xs.h, [], [HAVE_XEN=0])
+        AC_CHECK_LIB(xenctrl, xc_interface_open, [XEN_LIBS="$XEN_LIBS -lxenctrl"], [HAVE_XEN=0])
+        AC_CHECK_LIB(xenstore, xs_domain_open, [XEN_LIBS="$XEN_LIBS -lxenstore"], [HAVE_XEN=0])
+    ],
+    HAVE_XEN=0)
+
+AS_IF([test "x$enable_xen" = "xyes" && test "x$HAVE_XEN" = "x0"],
+    [AC_MSG_ERROR([*** Xen development headers or libraries not found])])
+
+AC_SUBST(XEN_CFLAGS)
+AC_SUBST(XEN_LIBS)
+AM_CONDITIONAL([HAVE_XEN], [test "x$HAVE_XEN" = x1])
 
-### ORC (optional) ###
-ORC_CHECK([0.4.9])
+#### gcov support (optional) #####
 
-### Build and Install man pages ###
-AC_ARG_ENABLE(manpages,
-        AS_HELP_STRING([--disable-manpages],[Disable building and installation of man pages]),
-[case "${enableval}" in
-  yes) manpages=yes ;;
-  no)  manpages=no ;;
-  *) AC_MSG_ERROR([bad value ${enableval} for --disable-manpages]) ;;
-esac],[manpages=yes])
+AC_ARG_ENABLE([gcov],
+    AS_HELP_STRING([--enable-gcov],[Enable optional gcov coverage analysis]))
 
-AM_CONDITIONAL([BUILD_MANPAGES], [test "x$manpages" = xyes])
+GCOV_CFLAGS=
+GCOV_LIBS=" -lgcov"
+
+AS_IF([test "x$enable_gcov" = "xyes"],
+    [
+        HAVE_GCOV=1
+        GCOV_CFLAGS="$GCOV_CFLAGS -fprofile-arcs -ftest-coverage"
+        GCOV_LIBS="$GCOV_LIBS -fprofile-arcs"
+    ],
+    HAVE_GCOV=0)
+
+AC_SUBST(GCOV_CFLAGS)
+AC_SUBST(GCOV_LIBS)
+AM_CONDITIONAL([HAVE_GCOV], [test "x$HAVE_GCOV" = x1])
+
+#### ORC (optional) ####
+
+ORC_CHECK([0.4.11])
+
+#### systemd support (optional) ####
+
+AC_ARG_ENABLE([systemd],
+    AS_HELP_STRING([--disable-systemd],[Disable optional systemd support]))
+
+AS_IF([test "x$enable_systemd" != "xno"],
+    [PKG_CHECK_MODULES(SYSTEMD, [ libsystemd-login ], HAVE_SYSTEMD=1, HAVE_SYSTEMD=0)],
+    HAVE_SYSTEMD=0)
+
+AS_IF([test "x$enable_systemd" = "xyes" && test "x$HAVE_SYSTEMD" = "x0"],
+    [AC_MSG_ERROR([*** Needed systemd support not found])])
+
+AC_SUBST(HAVE_SYSTEMD)
+AM_CONDITIONAL([HAVE_SYSTEMD], [test "x$HAVE_SYSTEMD" = x1])
+AS_IF([test "x$HAVE_SYSTEMD" = "x1"], AC_DEFINE([HAVE_SYSTEMD], 1, [Have SYSTEMD?]))
+
+#### Build and Install man pages ####
+
+AC_ARG_ENABLE([manpages],
+    AS_HELP_STRING([--disable-manpages],[Disable building and installation of man pages]))
+
+AM_CONDITIONAL([BUILD_MANPAGES], [test "x$enable_manpages" != "xno"])
 
 #### PulseAudio system group & user  #####
 
 AC_SUBST(PA_ACCESS_GROUP)
 AC_DEFINE_UNQUOTED(PA_ACCESS_GROUP,"$PA_ACCESS_GROUP", [Access group])
 
-AC_ARG_ENABLE(
-        per_user_esound_socket,
-        AS_HELP_STRING([--disable-per-user-esound-socket], [Use global esound socket directory /tmp/.esd/socket.]),
-        [
-            case "${enableval}" in
-                yes) per_user_esound_socket=1 ;;
-                no) per_user_esound_socket=0 ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --disable-per-user-esound-socket) ;;
-            esac
-        ],
-        [per_user_esound_socket=1])
+AC_ARG_ENABLE([per-user-esound-socket],
+    AS_HELP_STRING([--disable-per-user-esound-socket],[Use global esound socket directory /tmp/.esd/socket.]))
 
-if test "x$per_user_esound_socket" = "x1"; then
-   AC_DEFINE([USE_PER_USER_ESOUND_SOCKET], [1], [Define this if you want per-user esound socket directories])
+if test "x$enable_per_user_esound_socket" != "xno"; then
+    USE_PER_USER_ESOUND_SOCKET=1
+    AC_DEFINE([USE_PER_USER_ESOUND_SOCKET], [1], [Define this if you want per-user esound socket directories])
+else
+    USE_PER_USER_ESOUND_SOCKET=0
 fi
 
 #### PulseAudio system runtime dir ####
+
 PA_SYSTEM_RUNTIME_PATH="${localstatedir}/run/pulse"
-AC_SUBST(PA_SYSTEM_RUNTIME_PATH)
+AX_DEFINE_DIR(PA_SYSTEM_RUNTIME_PATH, PA_SYSTEM_RUNTIME_PATH, [System runtime dir])
 PA_SYSTEM_CONFIG_PATH="${localstatedir}/lib/pulse"
-AC_SUBST(PA_SYSTEM_CONFIG_PATH)
+AX_DEFINE_DIR(PA_SYSTEM_CONFIG_PATH, PA_SYSTEM_CONFIG_PATH, [System config dir])
 PA_SYSTEM_STATE_PATH="${localstatedir}/lib/pulse"
-AC_SUBST(PA_SYSTEM_STATE_PATH)
+AX_DEFINE_DIR(PA_SYSTEM_STATE_PATH, PA_SYSTEM_STATE_PATH, [System state dir])
+
+PA_BINARY=${bindir}/pulseaudio${EXEEXT}
+AX_DEFINE_DIR(PA_BINARY, PA_BINARY, [Location of pulseaudio binary])
+
+PACTL_BINARY=${bindir}/pactl${EXEEXT}
+AX_DEFINE_DIR(PACTL_BINARY, PACTL_BINARY, [Location of pactl binary])
+
+AC_SUBST(PA_SOEXT, [.so])
+AC_DEFINE(PA_SOEXT, [".so"], [Shared object extension])
+
+AC_SUBST(pulseconfdir, ["${sysconfdir}/pulse"])
+AX_DEFINE_DIR(PA_DEFAULT_CONFIG_DIR, pulseconfdir, [Location of configuration files])
+
+#### Mac OSX specific stuff #####
+
+AC_ARG_ENABLE(mac-universal,
+    AS_HELP_STRING([--enable-mac-universal], [Build Mac universal binaries]),
+    enable_mac_universal=$enableval, enable_mac_universal="no")
+
+AC_ARG_WITH(mac-version-min,
+    AS_HELP_STRING([--with-mac-version-min=<version>], [Defines the earliest version of MacOS X that the executables will run on.]),
+    mac_version_min=$withval, mac_version_min="10.5")
+
+AC_ARG_WITH(mac-sysroot,
+    AS_HELP_STRING([--with-mac-sysroot=<path>], [SDK basedir to use as the logical root directory for headers and libraries.]),
+    mac_sysroot=$withval, mac_sysroot="/Developer/SDKs/MacOSX10.5.sdk")
+
+if test "x$os_is_darwin" = "x1" ; then
+    LDFLAGS="$LDFLAGS -isysroot $mac_sysroot -mmacosx-version-min=$mac_version_min"
+    CFLAGS="$CFLAGS -isysroot $mac_sysroot -mmacosx-version-min=$mac_version_min"
+
+    if test "x$enable_mac_universal" = "xyes" ; then
+        mac_arches="-arch i386 -arch x86_64"
+        LDFLAGS="$LDFLAGS $mac_arches"
+        CFLAGS="$CFLAGS $mac_arches"
+    fi
+fi
+
+AC_ARG_ENABLE([webrtc-aec],
+    AS_HELP_STRING([--enable-webrtc-aec], [Enable the optional WebRTC-based echo canceller]))
+
+AS_IF([test "x$enable_webrtc_aec" != "xno"],
+    [PKG_CHECK_MODULES(WEBRTC, [ webrtc-audio-processing ], [HAVE_WEBRTC=1], [HAVE_WEBRTC=0])],
+    [HAVE_WEBRTC=0])
+
+AS_IF([test "x$enable_webrtc_aec" = "xyes" && test "x$HAVE_WEBRTC" = "x0"],
+    [AC_MSG_ERROR([*** webrtc-audio-processing library not found])])
+
+AC_SUBST(WEBRTC_CFLAGS)
+AC_SUBST(WEBRTC_LIBS)
+AM_CONDITIONAL([HAVE_WEBRTC], [test "x$HAVE_WEBRTC" = "x1"])
+
+AC_ARG_ENABLE([adrian-aec],
+    AS_HELP_STRING([--enable-adrian-aec], [Enable Adrian's optional echo canceller]))
+AS_IF([test "x$enable_adrian_aec" != "xno"],
+    [HAVE_ADRIAN_EC=1])
+AM_CONDITIONAL([HAVE_ADRIAN_EC], [test "x$HAVE_ADRIAN_EC" = "x1"])
+
+
 
 ###################################
 #            Output               #
 ###################################
 
-AC_ARG_ENABLE([legacy-runtime-dir],
-        AS_HELP_STRING([--disable-legacy-runtime-dir], [Try to connect on legacy (< 0.9.12) socket paths.]))
-if test "x$enable_legacy_runtime_dir" != "xno" ; then
-        AC_DEFINE(ENABLE_LEGACY_RUNTIME_DIR, [1], [Legacy runtime dir])
+AC_DEFINE_UNQUOTED(PA_CFLAGS, "$CFLAGS", [The CFLAGS used during compilation])
+
+# Check whether to build tests by default (as compile-test) or not
+AC_ARG_ENABLE([default-build-tests],
+    AS_HELP_STRING([--disable-default-build-tests], [Build test programs only during make check]))
+AM_CONDITIONAL([BUILD_TESTS_DEFAULT], [test "x$enable_default_build_tests" != "xno"])
+
+AC_ARG_ENABLE([legacy-database-entry-format],
+        AS_HELP_STRING([--disable-legacy-database-entry-format], [Try to load legacy (< 1.0) database files (card, device and volume restore).]))
+if test "x$enable_legacy_database_entry_format" != "xno" ; then
+        AC_DEFINE(ENABLE_LEGACY_DATABASE_ENTRY_FORMAT, [1], [Legacy database entry format])
 fi
+AC_DEFINE([WIBBLE], 1, [Just a test.])
 
-AC_ARG_ENABLE(
-        [static-bins],
-        AS_HELP_STRING([--enable-static-bins],[Statically link executables.]),
-        [STATIC_BINS=1], [STATIC_BINS=0])
-AM_CONDITIONAL([STATIC_BINS], [test "x$STATIC_BINS" = "x1"])
+AC_ARG_ENABLE([static-bins],
+    AS_HELP_STRING([--enable-static-bins],[Statically link executables.]))
+AM_CONDITIONAL([STATIC_BINS], [test "x$enable_static_bins" = "xyes"])
 
 AC_ARG_WITH(
         [preopen-mods],
@@ -1423,15 +1374,28 @@ fi
 
 AC_ARG_WITH(
         [module-dir],
-        AS_HELP_STRING([--with-module-dir],[Directory where to install the modules to (defaults to ${libdir}/pulse-${PA_MAJORMINORMICRO}/modules]),
-        [modlibexecdir=$withval], [modlibexecdir="${libdir}/pulse-${PA_MAJORMINORMICRO}/modules"])
+        AS_HELP_STRING([--with-module-dir],[Directory where to install the modules to (defaults to ${libdir}/pulse-${PA_MAJORMINOR}/modules]),
+        [modlibexecdir=$withval], [modlibexecdir="${libdir}/pulse-${PA_MAJORMINOR}/modules"])
 
 AC_SUBST(modlibexecdir)
+AX_DEFINE_DIR(PA_DLSEARCHPATH, modlibexecdir, [Modules dir])
+
+AC_ARG_WITH(
+        [udev-rules-dir],
+        AS_HELP_STRING([--with-udev-rules-dir],[Directory where to install udev rules to (defaults to /lib/udev/rules.d)]),
+        [udevrulesdir=$withval], [udevrulesdir="/lib/udev/rules.d"])
+
+AC_SUBST(udevrulesdir)
+
+AC_ARG_ENABLE([force-preopen],
+    AS_HELP_STRING([--enable-force-preopen],[Preopen modules, even when dlopen() is supported.]))
+
+if test "x$enable_force_preopen" = "xyes"; then
+    FORCE_PREOPEN=yes
+else
+    FORCE_PREOPEN=no
+fi
 
-AC_ARG_ENABLE(
-        [force-preopen],
-        AS_HELP_STRING([--enable-force-preopen],[Preopen modules, even when dlopen() is supported.]),
-        [FORCE_PREOPEN=$enableval], [FORCE_PREOPEN=no])
 AM_CONDITIONAL([FORCE_PREOPEN], [test "x$FORCE_PREOPEN" = "xyes"])
 
 AC_CONFIG_FILES([
@@ -1440,143 +1404,92 @@ src/Makefile
 man/Makefile
 libpulse.pc
 libpulse-simple.pc
-libpulse-browse.pc
 libpulse-mainloop-glib.pc
+pulsecore.pc
 doxygen/Makefile
 doxygen/doxygen.conf
 src/pulse/version.h
 po/Makefile.in
+man/pulseaudio.1.xml
+man/esdcompat.1.xml
+man/pax11publish.1.xml
+man/paplay.1.xml
+man/pacat.1.xml
+man/pacmd.1.xml
+man/pactl.1.xml
+man/pasuspender.1.xml
+man/padsp.1.xml
+man/pulse-daemon.conf.5.xml
+man/pulse-client.conf.5.xml
+man/default.pa.5.xml
+man/pulse-cli-syntax.5.xml
+man/start-pulseaudio-kde.1.xml
+man/start-pulseaudio-x11.1.xml
 ])
 
+AC_CONFIG_FILES([src/esdcompat:src/daemon/esdcompat.in], [chmod +x src/esdcompat])
+AC_CONFIG_FILES([src/start-pulseaudio-x11:src/daemon/start-pulseaudio-x11.in], [chmod +x src/start-pulseaudio-x11])
+AC_CONFIG_FILES([src/start-pulseaudio-kde:src/daemon/start-pulseaudio-kde.in], [chmod +x src/start-pulseaudio-kde])
+AC_CONFIG_FILES([src/client.conf:src/pulse/client.conf.in])
+AC_CONFIG_FILES([src/daemon.conf:src/daemon/daemon.conf.in],
+    [m4 src/daemon.conf > src/daemon.conf.gen && mv src/daemon.conf.gen src/daemon.conf])
+AC_CONFIG_FILES([src/default.pa:src/daemon/default.pa.in],
+    [m4 src/default.pa > src/default.pa.gen && mv src/default.pa.gen src/default.pa])
+AC_CONFIG_FILES([src/system.pa:src/daemon/system.pa.in],
+    [m4 src/system.pa > src/system.pa.gen && mv src/system.pa.gen src/system.pa])
+
+# CMake related ProjectConfig files
+PA_LIBDIR="$libdir"
+AX_DEFINE_DIR(PA_LIBDIR, PA_LIBDIR, [PulseAudio library dir])
+PA_INCDIR="$includedir"
+AX_DEFINE_DIR(PA_INCDIR, PA_INCDIR, [PulseAudio include dir])
+
+AC_CONFIG_FILES([PulseAudioConfig.cmake:PulseAudioConfig.cmake.in],
+    [m4 PulseAudioConfig.cmake > PulseAudioConfig.cmake.gen && mv PulseAudioConfig.cmake.gen PulseAudioConfig.cmake])
+AC_CONFIG_FILES([PulseAudioConfigVersion.cmake])
+
 AC_OUTPUT
 
 # ==========================================================================
-ENABLE_X11=no
-if test "x$HAVE_X11" = "x1" ; then
-   ENABLE_X11=yes
-fi
-
-ENABLE_OSS_OUTPUT=no
-ENABLE_OSS_WRAPPER=no
-if test "x$HAVE_OSS" = "x1" ; then
-   if test "x$enable_oss_output" != "xno"; then
-      ENABLE_OSS_OUTPUT=yes
-   fi
-   if test "x$enable_oss_wrapper" != "xno"; then
-      ENABLE_OSS_WRAPPER=yes
-   fi
-fi
-
-ENABLE_ALSA=no
-if test "x$HAVE_ALSA" = "x1" ; then
-   ENABLE_ALSA=yes
-fi
-
-ENABLE_SOLARIS=no
-if test "x$HAVE_SOLARIS" = "x1" ; then
-   ENABLE_SOLARIS=yes
-fi
-
-ENABLE_GTK20=no
-if test "x$HAVE_GTK20" = "x1" ; then
-   ENABLE_GTK20=yes
-fi
-
-ENABLE_GLIB20=no
-if test "x$HAVE_GLIB20" = "x1" ; then
-   ENABLE_GLIB20=yes
-fi
-
-ENABLE_GCONF=no
-if test "x$HAVE_GCONF" = "x1" ; then
-   ENABLE_GCONF=yes
-fi
 
-ENABLE_AVAHI=no
-if test "x$HAVE_AVAHI" = "x1" ; then
-   ENABLE_AVAHI=yes
-fi
-
-ENABLE_JACK=no
-if test "x$HAVE_JACK" = "x1" ; then
-   ENABLE_JACK=yes
-fi
-
-ENABLE_LIBASYNCNS=no
-if test "x$HAVE_LIBASYNCNS" = "x1" ; then
-   ENABLE_LIBASYNCNS=yes
-fi
-
-ENABLE_LIRC=no
-if test "x$HAVE_LIRC" = "x1" ; then
-   ENABLE_LIRC=yes
-fi
-
-ENABLE_HAL=no
-if test "x$HAVE_HAL" = "x1" ; then
-   ENABLE_HAL=yes
-fi
-
-ENABLE_UDEV=no
-if test "x$HAVE_UDEV" = "x1" ; then
-   ENABLE_UDEV=yes
-fi
-
-ENABLE_HAL_COMPAT=no
-if test "x$HAVE_HAL_COMPAT" = "x1" ; then
-   ENABLE_HAL_COMPAT=yes
-fi
-
-ENABLE_TCPWRAP=no
-if test "x${LIBWRAP_LIBS}" != x ; then
-   ENABLE_TCPWRAP=yes
-fi
-
-ENABLE_LIBSAMPLERATE=no
-if test "x${HAVE_LIBSAMPLERATE}" = "x1" ; then
-   ENABLE_LIBSAMPLERATE=yes
-fi
-
-ENABLE_BLUEZ=no
-if test "x${HAVE_BLUEZ}" = "x1" ; then
-   ENABLE_BLUEZ=yes
-fi
-
-ENABLE_BT_A2DP_APTX=no
-if test "x${HAVE_BT_A2DP_APTX}" = "x1" ; then
-   ENABLE_BT_A2DP_APTX=yes
-fi
-
-
-ENABLE_GDBM=no
-if test "x${HAVE_GDBM}" = "x1" ; then
-   ENABLE_GDBM=yes
-fi
-
-ENABLE_TDB=no
-if test "x${HAVE_TDB}" = "x1" ; then
-   ENABLE_TDB=yes
-fi
-
-ENABLE_SIMPLEDB=no
-if test "x${HAVE_SIMPLEDB}" = "x1" ; then
-    ENABLE_SIMPLEDB=yes
-fi
-
-ENABLE_OPENSSL=no
-if test "x${HAVE_OPENSSL}" = "x1" ; then
-   ENABLE_OPENSSL=yes
-fi
-
-ENABLE_IPV6=no
-if test "x${HAVE_IPV6}" = "x1" ; then
-   ENABLE_IPV6=yes
-fi
-
-ENABLE_PER_USER_ESOUND_SOCKET=no
-if test "x$per_user_esound_socket" = "x1" ; then
-   ENABLE_PER_USER_ESOUND_SOCKET=yes
-fi
+AS_IF([test "x$HAVE_X11" = "x1"], ENABLE_X11=yes, ENABLE_X11=no)
+AS_IF([test "x$HAVE_OSS_OUTPUT" = "x1"], ENABLE_OSS_OUTPUT=yes, ENABLE_OSS_OUTPUT=no)
+AS_IF([test "x$HAVE_OSS_WRAPPER" = "x1"], ENABLE_OSS_WRAPPER=yes, ENABLE_OSS_WRAPPER=no)
+AS_IF([test "x$HAVE_ALSA" = "x1"], ENABLE_ALSA=yes, ENABLE_ALSA=no)
+AS_IF([test "x$HAVE_COREAUDIO" = "x1"], ENABLE_COREAUDIO=yes, ENABLE_COREAUDIO=no)
+AS_IF([test "x$HAVE_SOLARIS" = "x1"], ENABLE_SOLARIS=yes, ENABLE_SOLARIS=no)
+AS_IF([test "x$HAVE_WAVEOUT" = "x1"], ENABLE_WAVEOUT=yes, ENABLE_WAVEOUT=no)
+AS_IF([test "x$HAVE_GLIB20" = "x1"], ENABLE_GLIB20=yes, ENABLE_GLIB20=no)
+AS_IF([test "x$HAVE_GTK30" = "x1"], ENABLE_GTK30=yes, ENABLE_GTK30=no)
+AS_IF([test "x$HAVE_GCONF" = "x1"], ENABLE_GCONF=yes, ENABLE_GCONF=no)
+AS_IF([test "x$HAVE_AVAHI" = "x1"], ENABLE_AVAHI=yes, ENABLE_AVAHI=no)
+AS_IF([test "x$HAVE_JACK" = "x1"], ENABLE_JACK=yes, ENABLE_JACK=no)
+AS_IF([test "x$HAVE_LIBASYNCNS" = "x1"], ENABLE_LIBASYNCNS=yes, ENABLE_LIBASYNCNS=no)
+AS_IF([test "x$HAVE_LIRC" = "x1"], ENABLE_LIRC=yes, ENABLE_LIRC=no)
+AS_IF([test "x$HAVE_XEN" = "x1"], ENABLE_XEN=yes, ENABLE_XEN=no)
+AS_IF([test "x$HAVE_DBUS" = "x1"], ENABLE_DBUS=yes, ENABLE_DBUS=no)
+AS_IF([test "x$HAVE_UDEV" = "x1"], ENABLE_UDEV=yes, ENABLE_UDEV=no)
+AS_IF([test "x$HAVE_SYSTEMD" = "x1"], ENABLE_SYSTEMD=yes, ENABLE_SYSTEMD=no)
+AS_IF([test "x$HAVE_BLUEZ_4" = "x1"], ENABLE_BLUEZ_4=yes, ENABLE_BLUEZ_4=no)
+AS_IF([test "x$HAVE_BLUEZ_5" = "x1"], ENABLE_BLUEZ_5=yes, ENABLE_BLUEZ_5=no)
+AS_IF([test "x$HAVE_HAL_COMPAT" = "x1"], ENABLE_HAL_COMPAT=yes, ENABLE_HAL_COMPAT=no)
+AS_IF([test "x$HAVE_TCPWRAP" = "x1"], ENABLE_TCPWRAP=yes, ENABLE_TCPWRAP=no)
+AS_IF([test "x$HAVE_LIBSAMPLERATE" = "x1"], ENABLE_LIBSAMPLERATE=yes, ENABLE_LIBSAMPLERATE=no)
+AS_IF([test "x$HAVE_IPV6" = "x1"], ENABLE_IPV6=yes, ENABLE_IPV6=no)
+AS_IF([test "x$HAVE_OPENSSL" = "x1"], ENABLE_OPENSSL=yes, ENABLE_OPENSSL=no)
+AS_IF([test "x$HAVE_FFTW" = "x1"], ENABLE_FFTW=yes, ENABLE_FFTW=no)
+AS_IF([test "x$HAVE_ORC" = "xyes"], ENABLE_ORC=yes, ENABLE_ORC=no)
+AS_IF([test "x$HAVE_ADRIAN_EC" = "x1"], ENABLE_ADRIAN_EC=yes, ENABLE_ADRIAN_EC=no)
+AS_IF([test "x$HAVE_SPEEX" = "x1"], ENABLE_SPEEX=yes, ENABLE_SPEEX=no)
+AS_IF([test "x$HAVE_WEBRTC" = "x1"], ENABLE_WEBRTC=yes, ENABLE_WEBRTC=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)
+AS_IF([test "x$HAVE_ESOUND" = "x1"], ENABLE_ESOUND=yes, ENABLE_ESOUND=no)
+AS_IF([test "x$HAVE_ESOUND" = "x1" -a "x$USE_PER_USER_ESOUND_SOCKET" = "x1"], ENABLE_PER_USER_ESOUND_SOCKET=yes, ENABLE_PER_USER_ESOUND_SOCKET=no)
+AS_IF([test "x$HAVE_GCOV" = "x1"], ENABLE_GCOV=yes, ENABLE_GCOV=no)
+AS_IF([test "x$HAVE_LIBCHECK" = "x1"], ENABLE_TESTS=yes, ENABLE_TESTS=no)
+AS_IF([test "x$enable_legacy_database_entry_format" != "xno"], ENABLE_LEGACY_DATABASE_ENTRY_FORMAT=yes, ENABLE_LEGACY_DATABASE_ENTRY_FORMAT=no)
 
 echo "
  ---{ $PACKAGE_NAME $VERSION }---
@@ -1584,36 +1497,51 @@ echo "
     prefix:                        ${prefix}
     sysconfdir:                    ${sysconfdir}
     localstatedir:                 ${localstatedir}
+    modlibexecdir:                 ${modlibexecdir}
     System Runtime Path:           ${PA_SYSTEM_RUNTIME_PATH}
     System State Path:             ${PA_SYSTEM_STATE_PATH}
     System Config Path:            ${PA_SYSTEM_CONFIG_PATH}
     Compiler:                      ${CC}
     CFLAGS:                        ${CFLAGS}
+    LIBS:                          ${LIBS}
 
-    Have X11:                      ${ENABLE_X11}
+    Enable X11:                    ${ENABLE_X11}
     Enable OSS Output:             ${ENABLE_OSS_OUTPUT}
     Enable OSS Wrapper:            ${ENABLE_OSS_WRAPPER}
+    Enable EsounD:                 ${ENABLE_ESOUND}
     Enable Alsa:                   ${ENABLE_ALSA}
+    Enable CoreAudio:              ${ENABLE_COREAUDIO}
     Enable Solaris:                ${ENABLE_SOLARIS}
+    Enable WaveOut:                ${ENABLE_WAVEOUT}
     Enable GLib 2.0:               ${ENABLE_GLIB20}
-    Enable Gtk+ 2.0:               ${ENABLE_GTK20}
+    Enable Gtk+ 3.0:               ${ENABLE_GTK30}
     Enable GConf:                  ${ENABLE_GCONF}
     Enable Avahi:                  ${ENABLE_AVAHI}
     Enable Jack:                   ${ENABLE_JACK}
     Enable Async DNS:              ${ENABLE_LIBASYNCNS}
     Enable LIRC:                   ${ENABLE_LIRC}
-    Enable HAL:                    ${ENABLE_HAL}
+    Enable Xen PV driver:          ${ENABLE_XEN}
+    Enable D-Bus:                  ${ENABLE_DBUS}
+      Enable BlueZ 4:              ${ENABLE_BLUEZ_4}
+      Enable BlueZ 5:              ${ENABLE_BLUEZ_5}
     Enable udev:                   ${ENABLE_UDEV}
-    Enable HAL->udev compat:       ${ENABLE_HAL_COMPAT}
-    Enable BlueZ:                  ${ENABLE_BLUEZ}
+      Enable HAL->udev compat:     ${ENABLE_HAL_COMPAT}
+    Enable systemd login:          ${ENABLE_SYSTEMD}
     Enable TCP Wrappers:           ${ENABLE_TCPWRAP}
     Enable libsamplerate:          ${ENABLE_LIBSAMPLERATE}
     Enable IPv6:                   ${ENABLE_IPV6}
     Enable OpenSSL (for Airtunes): ${ENABLE_OPENSSL}
-    Enable tdb:                    ${ENABLE_TDB}
-    Enable gdbm:                   ${ENABLE_GDBM}
-    Enable simple database:        ${ENABLE_SIMPLEDB}
+    Enable fftw:                   ${ENABLE_FFTW}
     Enable orc:                    ${ENABLE_ORC}
+    Enable Adrian echo canceller:  ${ENABLE_ADRIAN_EC}
+    Enable speex (resampler, AEC): ${ENABLE_SPEEX}
+    Enable WebRTC echo canceller:  ${ENABLE_WEBRTC}
+    Enable gcov coverage:          ${ENABLE_GCOV}
+    Enable unit tests:             ${ENABLE_TESTS}
+    Database
+      tdb:                         ${ENABLE_TDB}
+      gdbm:                        ${ENABLE_GDBM}
+      simple database:             ${ENABLE_SIMPLEDB}
 
     System User:                   ${PA_SYSTEM_USER}
     System Group:                  ${PA_SYSTEM_GROUP}
@@ -1621,4 +1549,45 @@ echo "
     Enable per-user EsounD socket: ${ENABLE_PER_USER_ESOUND_SOCKET}
     Force preopen:                 ${FORCE_PREOPEN}
     Preopened modules:             ${PREOPEN_MODS}
+
+    Legacy Database Entry Support: ${ENABLE_LEGACY_DATABASE_ENTRY_FORMAT}
+"
+
+if test "${ENABLE_SPEEX}" = "no" && test "${ENABLE_WEBRTC}" = "no" && test "${ENABLE_ADRIAN_EC}" = "no" ; then
+AC_MSG_ERROR([At least one echo canceller implementation must be available.])
+fi
+
+if test "${ENABLE_DBUS}" = "no" && test "x$os_is_win32" != "x1" ; then
+   echo "
+===== WARNING WARNING WARNING WARNING WARNING WARNING WARNING =====
+You do not have D-Bus support enabled. It is strongly recommended
+that you enable D-Bus support if your platform supports it.
+Many parts of PulseAudio use D-Bus, from ConsoleKit interaction
+to the Device Reservation Protocol to speak to JACK, Bluetooth
+support and even a native control protocol for communicating and
+controling the PulseAudio daemon itself.
+===== WARNING WARNING WARNING WARNING WARNING WARNING WARNING =====
 "
+fi
+
+if test "${ENABLE_UDEV}" = "no" && test "x$os_is_win32" != "x1" ; then
+   echo "
+===== WARNING WARNING WARNING WARNING WARNING WARNING WARNING =====
+You do not have udev support enabled. It is strongly recommended
+that you enable udev support if your platform supports it as it is
+the primary method used to detect hardware audio devices (on Linux)
+and is thus a critical part of PulseAudio on that platform.
+===== WARNING WARNING WARNING WARNING WARNING WARNING WARNING =====
+"
+fi
+
+if test "${ENABLE_SPEEX}" = "no" && test "x$os_is_win32" != "x1" ; then
+   echo "
+===== WARNING WARNING WARNING WARNING WARNING WARNING WARNING =====
+You do not have speex support enabled. It is strongly recommended
+that you enable speex support if your platform supports it as it is
+the primary method used for audio resampling and is thus a critical
+part of PulseAudio on that platform.
+===== WARNING WARNING WARNING WARNING WARNING WARNING WARNING =====
+"
+fi
diff --git a/depcomp b/depcomp
new file mode 100755 (executable)
index 0000000..25a39e6
--- /dev/null
+++ b/depcomp
@@ -0,0 +1,708 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2012-03-27.16; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
+# 2011, 2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program 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 General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by 'PROGRAMS ARGS'.
+  object      Object file output by 'PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputting dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+# A tabulation character.
+tab='  '
+# A newline character.
+nl='
+'
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+   # This is just like msvisualcpp but w/o cygpath translation.
+   # Just convert the backslash-escaped backslashes to single forward
+   # slashes to satisfy depend.m4
+   cygpath_u='sed s,\\\\,/,g'
+   depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+   # This is just like msvc7 but w/o cygpath translation.
+   # Just convert the backslash-escaped backslashes to single forward
+   # slashes to satisfy depend.m4
+   cygpath_u='sed s,\\\\,/,g'
+   depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+   # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations.
+   gccflag=-qmakedep=gcc,-MF
+   depmode=gcc
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$@" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$@"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the "deleted header file" problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' "$nl" < "$tmpdepfile" |
+## Some versions of gcc put a space before the ':'.  On the theory
+## that the space means something, we add a space to the output as
+## well.  hp depmode also adds that space, but also prefixes the VPATH
+## to the object.  Take care to not repeat it in the output.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+      | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like '#:fec' to the end of the
+    # dependency line.
+    tr ' ' "$nl" < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr "$nl" ' ' >> "$depfile"
+    echo >> "$depfile"
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' "$nl" < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+xlc)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts '$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
+    "$@" -Wc,-M
+  else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
+    "$@" -M
+  fi
+  stat=$?
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form 'foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # '$object: dependent.h' and one to simply 'dependent.h:'.
+    sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+    sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'.
+  # However on
+  #    $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using '\':
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+  # tcc 0.9.26 (FIXME still under development at the moment of writing)
+  # will emit a similar output, but also prepend the continuation lines
+  # with horizontal tabulation characters.
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form 'foo.o: dependent.h',
+  # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # '$object: dependent.h' and one to simply 'dependent.h:'.
+  sed -e "s/^[ $tab][ $tab]*/  /" -e "s,^[^:]*:,$object :," \
+    < "$tmpdepfile" > "$depfile"
+  sed '
+    s/[ '"$tab"'][ '"$tab"']*/ /g
+    s/^ *//
+    s/ *\\*$//
+    s/^[^:]*: *//
+    /^$/d
+    /:$/d
+    s/$/ :/
+  ' < "$tmpdepfile" >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$@" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$@" +Maked
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add 'dependent.h:' lines.
+    sed -ne '2,${
+              s/^ *//
+              s/ \\*$//
+              s/$/:/
+              p
+            }' "$tmpdepfile" >> "$depfile"
+  else
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in 'foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # With Tru64 cc, shared objects can also be used to make a
+      # static library.  This mechanism is used in libtool 1.4 series to
+      # handle both shared and static libraries in a single compilation.
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+      #
+      # With libtool 1.5 this exception was removed, and libtool now
+      # generates 2 separate objects for the 2 libraries.  These two
+      # compilations output dependencies in $dir.libs/$base.o.d and
+      # in $dir$base.o.d.  We have to check for both files, because
+      # one of the two compilations can be disabled.  We should prefer
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+      # automatically cleaned when .libs/ is deleted, while ignoring
+      # the former would cause a distcleancheck panic.
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1=$dir$base.o.d
+      tmpdepfile2=$dir$base.d
+      tmpdepfile3=$dir$base.d
+      tmpdepfile4=$dir$base.d
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+      exit $stat
+   fi
+
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+   do
+     test -f "$tmpdepfile" && break
+   done
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+msvc7)
+  if test "$libtool" = yes; then
+    showIncludes=-Wc,-showIncludes
+  else
+    showIncludes=-showIncludes
+  fi
+  "$@" $showIncludes > "$tmpdepfile"
+  stat=$?
+  grep -v '^Note: including file: ' "$tmpdepfile"
+  if test "$stat" = 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  # The first sed program below extracts the file names and escapes
+  # backslashes for cygpath.  The second sed program outputs the file
+  # name when reading, but also accumulates all include files in the
+  # hold buffer in order to output them again at the end.  This only
+  # works with sed implementations that can handle large buffers.
+  sed < "$tmpdepfile" -n '
+/^Note: including file:  *\(.*\)/ {
+  s//\1/
+  s/\\/\\\\/g
+  p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+  s/.*/'"$tab"'/
+  G
+  p
+}' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvc7msys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove '-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for ':'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' "$nl" < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no eat=no
+  for arg
+  do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    if test $eat = yes; then
+      eat=no
+      continue
+    fi
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -arch)
+      eat=yes ;;
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix=`echo "$object" | sed 's/^.*\././'`
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  # makedepend may prepend the VPATH from the source file name to the object.
+  # No need to regex-escape $object, excess matching of '.' is harmless.
+  sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove '-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+       -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+       set fnord "$@"
+       shift
+       shift
+       ;;
+    *)
+       set fnord "$@" "$arg"
+       shift
+       shift
+       ;;
+    esac
+  done
+  "$@" -E 2>/dev/null |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+  echo "$tab" >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvcmsys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/doxygen/.gitignore b/doxygen/.gitignore
new file mode 100644 (file)
index 0000000..189d6c7
--- /dev/null
@@ -0,0 +1,4 @@
+/doxygen.conf
+/html/
+/Makefile
+/Makefile.in
index 7dc0f8b..1369070 100644 (file)
@@ -417,7 +417,37 @@ WARN_LOGFILE           =
 # directories like "/usr/src/myproject". Separate the files or directories
 # with spaces.
 
-INPUT                  = ../src/pulse/context.h ../src/pulse/stream.h ../src/pulse/pulseaudio.h ../src/pulse/sample.h ../src/pulse/def.h ../src/pulse/subscribe.h ../src/pulse/introspect.h ../src/pulse/scache.h ../src/pulse/mainloop-api.h ../src/pulse/glib-mainloop.h ../src/pulse/mainloop.h ../src/pulse/mainloop-signal.h ../src/pulse/error.h ../src/pulse/operation.h ../src/pulse/simple.h ../src/pulse/version.h ../src/pulse/volume.h ../src/pulse/channelmap.h ../src/pulse/thread-mainloop.h ../src/pulse/xmalloc.h ../src/pulse/utf8.h ../src/pulse/util.h ../src/pulse/timeval.h ../src/pulse/proplist.h ../src/pulse/gccmacro.h ../src/pulse/ext-stream-restore.h ../src/pulse/rtclock.h
+INPUT = \
+    ../src/pulse/channelmap.h \
+    ../src/pulse/context.h \
+    ../src/pulse/def.h \
+    ../src/pulse/error.h \
+    ../src/pulse/ext-stream-restore.h \
+    ../src/pulse/ext-device-manager.h \
+    ../src/pulse/ext-device-restore.h \
+    ../src/pulse/format.h \
+    ../src/pulse/gccmacro.h \
+    ../src/pulse/glib-mainloop.h \
+    ../src/pulse/introspect.h \
+    ../src/pulse/mainloop-api.h \
+    ../src/pulse/mainloop-signal.h \
+    ../src/pulse/mainloop.h \
+    ../src/pulse/operation.h \
+    ../src/pulse/proplist.h \
+    ../src/pulse/pulseaudio.h \
+    ../src/pulse/rtclock.h \
+    ../src/pulse/sample.h \
+    ../src/pulse/scache.h \
+    ../src/pulse/simple.h \
+    ../src/pulse/stream.h \
+    ../src/pulse/subscribe.h \
+    ../src/pulse/thread-mainloop.h \
+    ../src/pulse/timeval.h \
+    ../src/pulse/utf8.h \
+    ../src/pulse/util.h \
+    ../src/pulse/version.h \
+    ../src/pulse/volume.h \
+    ../src/pulse/xmalloc.h \
 
 # If the value of the INPUT tag contains directories, you can use the
 # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
index ae3988e..9d65b80 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
 # Print a version string.
-scriptversion=2008-04-08.07
+scriptversion=2012-09-25.20
 
 # Copyright (C) 2007-2008 Free Software Foundation
 #
@@ -67,6 +67,7 @@ scriptversion=2008-04-08.07
 #      echo $(VERSION) > $@-t && mv $@-t $@
 # dist-hook:
 #      echo $(VERSION) > $(distdir)/.tarball-version
+#      echo $(VERSION) > $(distdir)/.version
 
 case $# in
     1) ;;
@@ -76,6 +77,7 @@ esac
 tarball_version_file=$1
 nl='
 '
+v=
 
 # First see if there is a tarball-only version file.
 # then try "git describe", then default.
@@ -91,17 +93,33 @@ then
        && echo "$0: WARNING: $tarball_version_file seems to be damaged" 1>&2
 fi
 
+# This is presently used by the GNOME-OSTree build system; it
+# helps support the case where the meta-build system has already
+# determined the git revision, but we may not be able to run "git describe"
+# because we're inside a chroot.
+if test -n "$GIT_DESCRIBE_FOR_BUILD";
+then
+    v=$GIT_DESCRIBE_FOR_BUILD
+fi
+
 if test -n "$v"
 then
     : # use $v
 elif test -d .git \
-    && v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
-         || git describe --abbrev=4 HEAD 2>/dev/null` \
-    && case $v in
-        v[0-9]*) ;;
-        *) (exit 1) ;;
-       esac
+    && v=`git describe --abbrev=4 --match='v[0-9]*' HEAD 2>/dev/null` \
+    && [ -n "$v" ]
 then
+    # If we are on a "dev" tag, we need to check that it is not the same
+    # reference as the a previous version tag (this only happens when we are
+    # working with a release tag).
+    # NB The below trick relies on the $v being an exact tag to work which
+    # will only work when HEAD == tag. When further commits have been made on top
+    # of the tag, the $v will be supplimented with the number of commits since
+    # that tag and the commit ref of the most recent commit and thus will
+    # fail the test below (as intended)
+    v2=`git describe --abbrev=4 --match='v[0-9]\.[0-9]' --contains $v 2>/dev/null | cut -d'^' -f1`
+    [ -n "$v2" ] && v=$v2
+
     # Is this a new git that lists number of commits since the last
     # tag or the previous older version that did not?
     #   Newer: v6.10-77-g0f8faeb
@@ -124,7 +142,8 @@ then
 #    v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`;
     :
 else
-    v=UNKNOWN
+    echo 1>&2 "$0: Failed to determine git revision"
+    exit 1
 fi
 
 v=`echo "$v" |sed 's/^v//'`
diff --git a/install-sh b/install-sh
new file mode 100755 (executable)
index 0000000..a9244eb
--- /dev/null
@@ -0,0 +1,527 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2011-01-19.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" ""       $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+       shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+       case $mode in
+         *' '* | *'    '* | *'
+'*       | *'*'* | *'?'* | *'['*)
+           echo "$0: invalid mode: $mode" >&2
+           exit 1;;
+       esac
+       shift;;
+
+    -o) chowncmd="$chownprog $2"
+       shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t) dst_arg=$2
+       # Protect names problematic for `test' and other utilities.
+       case $dst_arg in
+         -* | [=\(\)!]) dst_arg=./$dst_arg;;
+       esac
+       shift;;
+
+    -T) no_target_directory=true;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)        shift
+       break;;
+
+    -*)        echo "$0: invalid option: $1" >&2
+       exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+    # Protect names problematic for `test' and other utilities.
+    case $dst_arg in
+      -* | [=\(\)!]) dst_arg=./$dst_arg;;
+    esac
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  do_exit='(exit $ret); exit $ret'
+  trap "ret=129; $do_exit" 1
+  trap "ret=130; $do_exit" 2
+  trap "ret=141; $do_exit" 13
+  trap "ret=143; $do_exit" 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+       u_plus_rw=
+      else
+       u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+       u_plus_rw=
+      else
+       u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names problematic for `test' and other utilities.
+  case $src in
+    -* | [=\(\)!]) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+    dst=$dst_arg
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+       echo "$0: $dst_arg: Is a directory" >&2
+       exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+       (dirname "$dst") 2>/dev/null ||
+       expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+            X"$dst" : 'X\(//\)[^/]' \| \
+            X"$dst" : 'X\(//\)$' \| \
+            X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+       echo X"$dst" |
+           sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+                  s//\1/
+                  q
+                }
+                /^X\(\/\/\)[^/].*/{
+                  s//\1/
+                  q
+                }
+                /^X\(\/\/\)$/{
+                  s//\1/
+                  q
+                }
+                /^X\(\/\).*/{
+                  s//\1/
+                  q
+                }
+                s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+       # Create intermediate dirs using mode 755 as modified by the umask.
+       # This is like FreeBSD 'install' as of 1997-10-28.
+       umask=`umask`
+       case $stripcmd.$umask in
+         # Optimize common cases.
+         *[2367][2367]) mkdir_umask=$umask;;
+         .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+         *[0-7])
+           mkdir_umask=`expr $umask + 22 \
+             - $umask % 100 % 40 + $umask % 20 \
+             - $umask % 10 % 4 + $umask % 2
+           `;;
+         *) mkdir_umask=$umask,go-w;;
+       esac
+
+       # With -d, create the new directory with the user-specified mode.
+       # Otherwise, rely on $mkdir_umask.
+       if test -n "$dir_arg"; then
+         mkdir_mode=-m$mode
+       else
+         mkdir_mode=
+       fi
+
+       posix_mkdir=false
+       case $umask in
+         *[123567][0-7][0-7])
+           # POSIX mkdir -p sets u+wx bits regardless of umask, which
+           # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+           ;;
+         *)
+           tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+           trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+           if (umask $mkdir_umask &&
+               exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+           then
+             if test -z "$dir_arg" || {
+                  # Check for POSIX incompatibilities with -m.
+                  # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+                  # other-writeable bit of parent directory when it shouldn't.
+                  # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+                  ls_ld_tmpdir=`ls -ld "$tmpdir"`
+                  case $ls_ld_tmpdir in
+                    d????-?r-*) different_mode=700;;
+                    d????-?--*) different_mode=755;;
+                    *) false;;
+                  esac &&
+                  $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+                    ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+                    test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+                  }
+                }
+             then posix_mkdir=:
+             fi
+             rmdir "$tmpdir/d" "$tmpdir"
+           else
+             # Remove any dirs left behind by ancient mkdir implementations.
+             rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+           fi
+           trap '' 0;;
+       esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+       umask $mkdir_umask &&
+       $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+       /*) prefix='/';;
+       [-=\(\)!]*) prefix='./';;
+       *)  prefix='';;
+      esac
+
+      eval "$initialize_posix_glob"
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
+      shift
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+       test X"$d" = X && continue
+
+       prefix=$prefix$d
+       if test -d "$prefix"; then
+         prefixes=
+       else
+         if $posix_mkdir; then
+           (umask=$mkdir_umask &&
+            $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+           # Don't fail if two instances are running concurrently.
+           test -d "$prefix" || exit 1
+         else
+           case $prefix in
+             *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+             *) qprefix=$prefix;;
+           esac
+           prefixes="$prefixes '$qprefix'"
+         fi
+       fi
+       prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+       # Don't fail if two instances are running concurrently.
+       (umask $mkdir_umask &&
+        eval "\$doit_exec \$mkdirprog $prefixes") ||
+         test -d "$dstdir" || exit 1
+       obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"    2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+       # Now remove or move aside any old file at destination location.
+       # We try this two ways since rm can't unlink itself on some
+       # systems and the destination file might be busy for other
+       # reasons.  In this case, the final cleanup might fail but the new
+       # file should still install successfully.
+       {
+         test ! -f "$dst" ||
+         $doit $rmcmd -f "$dst" 2>/dev/null ||
+         { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+           { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+         } ||
+         { echo "$0: cannot unlink or rename $dst" >&2
+           (exit 1); exit 1
+         }
+       } &&
+
+       # Now rename the file to the real destination.
+       $doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/libpulse-browse.pc.in b/libpulse-browse.pc.in
deleted file mode 100644 (file)
index 54705b3..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: libpulse-browse
-Description: PulseAudio Network Browsing Interface
-Version: @PACKAGE_VERSION@
-Libs: -L${libdir} -lpulse-browse @PTHREAD_LIBS@
-Libs.private: -lpulsecommon-@PA_MAJORMINORMICRO@
-Cflags: -I${includedir} -D_REENTRANT
-Requires: libpulse
index 45ae47c..ad7e2f0 100644 (file)
@@ -7,6 +7,6 @@ Name: libpulse-mainloop-glib
 Description: PulseAudio GLib 2.0 Main Loop Wrapper
 Version: @PACKAGE_VERSION@
 Libs: -L${libdir} -lpulse-mainloop-glib @PTHREAD_LIBS@
-Libs.private: -lpulsecommon-@PA_MAJORMINORMICRO@
-Cflags: -I${includedir} -D_REENTRANT
+Libs.private: -L${libdir}/pulseaudio -lpulsecommon-@PA_MAJORMINOR@
+Cflags: -I${includedir} -D_REENTRANT -DPA_EXT_USE_VOLUME_FADING -D__TIZEN__ -D__TIZEN_BT__
 Requires: libpulse glib-2.0
index 443be28..91e292b 100644 (file)
@@ -7,6 +7,6 @@ Name: libpulse-simple
 Description: PulseAudio Simplified Synchronous Client Interface
 Version: @PACKAGE_VERSION@
 Libs: -L${libdir} -lpulse-simple @PTHREAD_LIBS@
-Libs.private: -lpulsecommon-@PA_MAJORMINORMICRO@
-Cflags: -I${includedir} -D_REENTRANT
+Libs.private: -L${libdir}/pulseaudio -lpulsecommon-@PA_MAJORMINOR@
+Cflags: -I${includedir} -D_REENTRANT -DPA_EXT_USE_VOLUME_FADING -D__TIZEN__ -D__TIZEN_BT__
 Requires: libpulse
index c78b123..a6957f9 100644 (file)
@@ -8,5 +8,5 @@ Name: libpulse
 Description: PulseAudio Client Interface
 Version: @PACKAGE_VERSION@
 Libs: -L${libdir} -lpulse @PTHREAD_LIBS@
-Libs.private: -lpulsecommon-@PA_MAJORMINORMICRO@
-Cflags: -I${includedir} -D_REENTRANT
+Libs.private: -L${libdir}/pulseaudio -lpulsecommon-@PA_MAJORMINOR@
+Cflags: -I${includedir} -D_REENTRANT -DPA_EXT_USE_VOLUME_FADING -D__TIZEN__ -D__TIZEN_BT__
diff --git a/ltmain.sh b/ltmain.sh
new file mode 100644 (file)
index 0000000..63ae69d
--- /dev/null
+++ b/ltmain.sh
@@ -0,0 +1,9655 @@
+
+# libtool (GNU libtool) 2.4.2
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+#       --config             show all configuration variables
+#       --debug              enable verbose shell tracing
+#   -n, --dry-run            display commands without modifying any files
+#       --features           display basic configuration information and exit
+#       --mode=MODE          use operation mode MODE
+#       --preserve-dup-deps  don't remove duplicate dependency libraries
+#       --quiet, --silent    don't print informational messages
+#       --no-quiet, --no-silent
+#                            print informational messages (default)
+#       --no-warn            don't display warning messages
+#       --tag=TAG            use configuration variables from tag TAG
+#   -v, --verbose            print more informational messages than default
+#       --no-verbose         don't print the extra informational messages
+#       --version            print version information
+#   -h, --help, --help-all   print short, long, or detailed help message
+#
+# MODE must be one of the following:
+#
+#         clean              remove files from the build directory
+#         compile            compile a source file into a libtool object
+#         execute            automatically set library path, then run a program
+#         finish             complete the installation of libtool libraries
+#         install            install libraries or executables
+#         link               create a library or an executable
+#         uninstall          remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE.  When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+#         host-triplet:        $host
+#         shell:               $SHELL
+#         compiler:            $LTCC
+#         compiler flags:              $LTCFLAGS
+#         linker:              $LD (gnu? $with_gnu_ld)
+#         $progname:   (GNU libtool) 2.4.2
+#         automake:    $automake_version
+#         autoconf:    $autoconf_version
+#
+# Report bugs to <bug-libtool@gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION=2.4.2
+TIMESTAMP=""
+package_revision=1.3337
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+  eval "if test \"\${$lt_var+set}\" = set; then
+          save_$lt_var=\$$lt_var
+          $lt_var=C
+         export $lt_var
+         lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+         lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+       fi"
+done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
+
+$lt_unset CDPATH
+
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+
+
+: ${CP="cp -f"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77     # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS="  $lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+    func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+} # func_dirname may be replaced by extended shell implementation
+
+
+# func_basename file
+func_basename ()
+{
+    func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+    # Extract subdirectory from the argument.
+    func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+    func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+    case ${2} in
+      .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+      *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+    esac
+} # func_stripname may be replaced by extended shell implementation
+
+
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+               s@/\./@/@g
+               t dotsl
+               s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
+
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+#             value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+  # Start from root dir and reassemble the path.
+  func_normal_abspath_result=
+  func_normal_abspath_tpath=$1
+  func_normal_abspath_altnamespace=
+  case $func_normal_abspath_tpath in
+    "")
+      # Empty path, that just means $cwd.
+      func_stripname '' '/' "`pwd`"
+      func_normal_abspath_result=$func_stripname_result
+      return
+    ;;
+    # The next three entries are used to spot a run of precisely
+    # two leading slashes without using negated character classes;
+    # we take advantage of case's first-match behaviour.
+    ///*)
+      # Unusual form of absolute path, do nothing.
+    ;;
+    //*)
+      # Not necessarily an ordinary path; POSIX reserves leading '//'
+      # and for example Cygwin uses it to access remote file shares
+      # over CIFS/SMB, so we conserve a leading double slash if found.
+      func_normal_abspath_altnamespace=/
+    ;;
+    /*)
+      # Absolute path, do nothing.
+    ;;
+    *)
+      # Relative path, prepend $cwd.
+      func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+    ;;
+  esac
+  # Cancel out all the simple stuff to save iterations.  We also want
+  # the path to end with a slash for ease of parsing, so make sure
+  # there is one (and only one) here.
+  func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+  while :; do
+    # Processed it all yet?
+    if test "$func_normal_abspath_tpath" = / ; then
+      # If we ascended to the root using ".." the result may be empty now.
+      if test -z "$func_normal_abspath_result" ; then
+        func_normal_abspath_result=/
+      fi
+      break
+    fi
+    func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcar"`
+    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcdr"`
+    # Figure out what to do with it
+    case $func_normal_abspath_tcomponent in
+      "")
+        # Trailing empty path component, ignore it.
+      ;;
+      ..)
+        # Parent dir; strip last assembled component from result.
+        func_dirname "$func_normal_abspath_result"
+        func_normal_abspath_result=$func_dirname_result
+      ;;
+      *)
+        # Actual path component, append it.
+        func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+      ;;
+    esac
+  done
+  # Restore leading double-slash if one was found on entry.
+  func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+#             value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+  func_relative_path_result=
+  func_normal_abspath "$1"
+  func_relative_path_tlibdir=$func_normal_abspath_result
+  func_normal_abspath "$2"
+  func_relative_path_tbindir=$func_normal_abspath_result
+
+  # Ascend the tree starting from libdir
+  while :; do
+    # check if we have found a prefix of bindir
+    case $func_relative_path_tbindir in
+      $func_relative_path_tlibdir)
+        # found an exact match
+        func_relative_path_tcancelled=
+        break
+        ;;
+      $func_relative_path_tlibdir*)
+        # found a matching prefix
+        func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+        func_relative_path_tcancelled=$func_stripname_result
+        if test -z "$func_relative_path_result"; then
+          func_relative_path_result=.
+        fi
+        break
+        ;;
+      *)
+        func_dirname $func_relative_path_tlibdir
+        func_relative_path_tlibdir=${func_dirname_result}
+        if test "x$func_relative_path_tlibdir" = x ; then
+          # Have to descend all the way to the root!
+          func_relative_path_result=../$func_relative_path_result
+          func_relative_path_tcancelled=$func_relative_path_tbindir
+          break
+        fi
+        func_relative_path_result=../$func_relative_path_result
+        ;;
+    esac
+  done
+
+  # Now calculate path; take care to avoid doubling-up slashes.
+  func_stripname '' '/' "$func_relative_path_result"
+  func_relative_path_result=$func_stripname_result
+  func_stripname '/' '/' "$func_relative_path_tcancelled"
+  if test "x$func_stripname_result" != x ; then
+    func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+  fi
+
+  # Normalisation. If bindir is libdir, return empty string,
+  # else relative path ending with a slash; either way, target
+  # file name can be directly appended.
+  if test ! -z "$func_relative_path_result"; then
+    func_stripname './' '' "$func_relative_path_result/"
+    func_relative_path_result=$func_stripname_result
+  fi
+}
+
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+  [\\/]*|[A-Za-z]:\\*) ;;
+  *[\\/]*)
+     progdir=$func_dirname_result
+     progdir=`cd "$progdir" && pwd`
+     progpath="$progdir/$progname"
+     ;;
+  *)
+     save_IFS="$IFS"
+     IFS=${PATH_SEPARATOR-:}
+     for progdir in $PATH; do
+       IFS="$save_IFS"
+       test -x "$progdir/$progname" && break
+     done
+     IFS="$save_IFS"
+     test -n "$progdir" || progdir=`pwd`
+     progpath="$progdir/$progname"
+     ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes.  A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same.  If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'.  `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+  s/$bs4/&\\
+/g
+  s/^$bs2$dollar/$bs&/
+  s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+  s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+    $opt_verbose && func_echo ${1+"$@"}
+
+    # A bug in bash halts the script if the last line of a function
+    # fails when set -e is in force, so we need another command to
+    # work around that:
+    :
+}
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+    $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
+
+    # bash bug again:
+    :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+    func_error ${1+"$@"}
+    exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+    func_error ${1+"$@"}
+    func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information."  ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+    $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+    my_directory_path="$1"
+    my_dir_list=
+
+    if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+      # Protect directory names starting with `-'
+      case $my_directory_path in
+        -*) my_directory_path="./$my_directory_path" ;;
+      esac
+
+      # While some portion of DIR does not yet exist...
+      while test ! -d "$my_directory_path"; do
+        # ...make a list in topmost first order.  Use a colon delimited
+       # list incase some portion of path contains whitespace.
+        my_dir_list="$my_directory_path:$my_dir_list"
+
+        # If the last portion added has no slash in it, the list is done
+        case $my_directory_path in */*) ;; *) break ;; esac
+
+        # ...otherwise throw away the child directory and loop
+        my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
+      done
+      my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
+
+      save_mkdir_p_IFS="$IFS"; IFS=':'
+      for my_dir in $my_dir_list; do
+       IFS="$save_mkdir_p_IFS"
+        # mkdir can fail with a `File exist' error if two processes
+        # try to create one of the directories concurrently.  Don't
+        # stop in that case!
+        $MKDIR "$my_dir" 2>/dev/null || :
+      done
+      IFS="$save_mkdir_p_IFS"
+
+      # Bail out if we (or some other process) failed to create a directory.
+      test -d "$my_directory_path" || \
+        func_fatal_error "Failed to create \`$1'"
+    fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible.  If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+    if test "$opt_dry_run" = ":"; then
+      # Return a directory name, but don't create it in dry-run mode
+      my_tmpdir="${my_template}-$$"
+    else
+
+      # If mktemp works, use that first and foremost
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+      if test ! -d "$my_tmpdir"; then
+        # Failing that, at least try and use $RANDOM to avoid a race
+        my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+        save_mktempdir_umask=`umask`
+        umask 0077
+        $MKDIR "$my_tmpdir"
+        umask $save_mktempdir_umask
+      fi
+
+      # If we're not in dry-run mode, bomb out on failure
+      test -d "$my_tmpdir" || \
+        func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+    fi
+
+    $ECHO "$my_tmpdir"
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+    case $1 in
+      *[\\\`\"\$]*)
+       func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+      *)
+        func_quote_for_eval_unquoted_result="$1" ;;
+    esac
+
+    case $func_quote_for_eval_unquoted_result in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and and variable
+      # expansion for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+        func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+        ;;
+      *)
+        func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+    esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+    case $1 in
+      *[\\\`\"]*)
+       my_arg=`$ECHO "$1" | $SED \
+           -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+      *)
+        my_arg="$1" ;;
+    esac
+
+    case $my_arg in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting and command substitution for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+        my_arg="\"$my_arg\""
+        ;;
+    esac
+
+    func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$my_cmd"
+      my_status=$?
+      if test "$my_status" -eq 0; then :; else
+       eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.  Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$lt_user_locale
+           $my_cmd"
+      my_status=$?
+      eval "$lt_safe_locale"
+      if test "$my_status" -eq 0; then :; else
+       eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result.  All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+  case $1 in
+  [0-9]* | *[!a-zA-Z0-9_]*)
+    func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+    ;;
+  * )
+    func_tr_sh_result=$1
+    ;;
+  esac
+}
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+    $opt_debug
+
+    $SED -n '/(C)/!b go
+       :more
+       /\./!{
+         N
+         s/\n# / /
+         b more
+       }
+       :go
+       /^# '$PROGRAM' (GNU /,/# warranty; / {
+        s/^# //
+       s/^# *$//
+        s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+        p
+     }' < "$progpath"
+     exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/^#  *.*--help/ {
+        s/^# //
+       s/^# *$//
+       s/\$progname/'$progname'/
+       p
+    }' < "$progpath"
+    echo
+    $ECHO "run \`$progname --help | more' for full usage"
+    exit $?
+}
+
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
+func_help ()
+{
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/# Report bugs to/ {
+       :print
+        s/^# //
+       s/^# *$//
+       s*\$progname*'$progname'*
+       s*\$host*'"$host"'*
+       s*\$SHELL*'"$SHELL"'*
+       s*\$LTCC*'"$LTCC"'*
+       s*\$LTCFLAGS*'"$LTCFLAGS"'*
+       s*\$LD*'"$LD"'*
+       s/\$with_gnu_ld/'"$with_gnu_ld"'/
+       s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+       s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
+       p
+       d
+     }
+     /^# .* home page:/b print
+     /^# General help using/b print
+     ' < "$progpath"
+    ret=$?
+    if test -z "$1"; then
+      exit $ret
+    fi
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+    $opt_debug
+
+    func_error "missing argument for $1."
+    exit_cmd=exit
+}
+
+
+# func_split_short_opt shortopt
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+func_split_short_opt ()
+{
+    my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+    my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
+
+    func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+    func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
+
+
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
+{
+    my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+    my_sed_long_arg='1s/^--[^=]*=//'
+
+    func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+    func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
+
+exit_cmd=:
+
+
+
+
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+    eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
+
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
+{
+    func_quote_for_eval "${2}"
+    eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
+
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+    func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
+
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+    func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
+
+
+# func_lo2o object
+func_lo2o ()
+{
+    func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
+
+
+# func_xform libobj-or-source
+func_xform ()
+{
+    func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
+
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+    func_error ${1+"$@"}
+    func_error "See the $PACKAGE documentation for more information."
+    func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+    re_begincf='^# ### BEGIN LIBTOOL'
+    re_endcf='^# ### END LIBTOOL'
+
+    # Default configuration.
+    $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+    done
+
+    exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+    echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      echo "enable shared libraries"
+    else
+      echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      echo "enable static libraries"
+    else
+      echo "disable static libraries"
+    fi
+
+    exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+  # Global variable:
+  tagname="$1"
+
+  re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+  re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+  sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+  # Validate tagname.
+  case $tagname in
+    *[!-_A-Za-z0-9,/]*)
+      func_fatal_error "invalid tag name: $tagname"
+      ;;
+  esac
+
+  # Don't test for the "default" C tag, as we know it's
+  # there but not specially marked.
+  case $tagname in
+    CC) ;;
+    *)
+      if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+       taglist="$taglist $tagname"
+
+       # Evaluate the configuration.  Be careful to quote the path
+       # and the sed script, to avoid splitting on whitespace, but
+       # also don't use non-portable quotes within backquotes within
+       # quotes we have to do it in 2 steps:
+       extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+       eval "$extractedcf"
+      else
+       func_error "ignoring unknown tag $tagname"
+      fi
+      ;;
+  esac
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+  if test "$package_revision" != "$macro_revision"; then
+    if test "$VERSION" != "$macro_version"; then
+      if test -z "$macro_version"; then
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      else
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      fi
+    else
+      cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+    fi
+
+    exit $EXIT_MISMATCH
+  fi
+}
+
+
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+  shift; set dummy --mode clean ${1+"$@"}; shift
+  ;;
+compile|compil|compi|comp|com|co|c)
+  shift; set dummy --mode compile ${1+"$@"}; shift
+  ;;
+execute|execut|execu|exec|exe|ex|e)
+  shift; set dummy --mode execute ${1+"$@"}; shift
+  ;;
+finish|finis|fini|fin|fi|f)
+  shift; set dummy --mode finish ${1+"$@"}; shift
+  ;;
+install|instal|insta|inst|ins|in|i)
+  shift; set dummy --mode install ${1+"$@"}; shift
+  ;;
+link|lin|li|l)
+  shift; set dummy --mode link ${1+"$@"}; shift
+  ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+  shift; set dummy --mode uninstall ${1+"$@"}; shift
+  ;;
+esac
+
+
+
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
+
+
+# Parse options once, thoroughly.  This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
+{
+  # this just eases exit handling
+  while test $# -gt 0; do
+    opt="$1"
+    shift
+    case $opt in
+      --debug|-x)      opt_debug='set -x'
+                       func_echo "enabling shell trace mode"
+                       $opt_debug
+                       ;;
+      --dry-run|--dryrun|-n)
+                       opt_dry_run=:
+                       ;;
+      --config)
+                       opt_config=:
+func_config
+                       ;;
+      --dlopen|-dlopen)
+                       optarg="$1"
+                       opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+                       shift
+                       ;;
+      --preserve-dup-deps)
+                       opt_preserve_dup_deps=:
+                       ;;
+      --features)
+                       opt_features=:
+func_features
+                       ;;
+      --finish)
+                       opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+                       ;;
+      --help)
+                       opt_help=:
+                       ;;
+      --help-all)
+                       opt_help_all=:
+opt_help=': help-all'
+                       ;;
+      --mode)
+                       test $# = 0 && func_missing_arg $opt && break
+                       optarg="$1"
+                       opt_mode="$optarg"
+case $optarg in
+  # Valid mode arguments:
+  clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+  # Catch anything else as an error
+  *) func_error "invalid argument for $opt"
+     exit_cmd=exit
+     break
+     ;;
+esac
+                       shift
+                       ;;
+      --no-silent|--no-quiet)
+                       opt_silent=false
+func_append preserve_args " $opt"
+                       ;;
+      --no-warning|--no-warn)
+                       opt_warning=false
+func_append preserve_args " $opt"
+                       ;;
+      --no-verbose)
+                       opt_verbose=false
+func_append preserve_args " $opt"
+                       ;;
+      --silent|--quiet)
+                       opt_silent=:
+func_append preserve_args " $opt"
+        opt_verbose=false
+                       ;;
+      --verbose|-v)
+                       opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+                       ;;
+      --tag)
+                       test $# = 0 && func_missing_arg $opt && break
+                       optarg="$1"
+                       opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+                       shift
+                       ;;
+
+      -\?|-h)          func_usage                              ;;
+      --help)          func_help                               ;;
+      --version)       func_version                            ;;
+
+      # Separate optargs to long options:
+      --*=*)
+                       func_split_long_opt "$opt"
+                       set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+                       shift
+                       ;;
+
+      # Separate non-argument short options:
+      -\?*|-h*|-n*|-v*)
+                       func_split_short_opt "$opt"
+                       set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+                       shift
+                       ;;
+
+      --)              break                                   ;;
+      -*)              func_fatal_help "unrecognized option \`$opt'" ;;
+      *)               set dummy "$opt" ${1+"$@"};     shift; break  ;;
+    esac
+  done
+
+  # Validate options:
+
+  # save first non-option argument
+  if test "$#" -gt 0; then
+    nonopt="$opt"
+    shift
+  fi
+
+  # preserve --debug
+  test "$opt_debug" = : || func_append preserve_args " --debug"
+
+  case $host in
+    *cygwin* | *mingw* | *pw32* | *cegcc*)
+      # don't eliminate duplications in $postdeps and $predeps
+      opt_duplicate_compiler_generated_deps=:
+      ;;
+    *)
+      opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+      ;;
+  esac
+
+  $opt_help || {
+    # Sanity checks first:
+    func_check_version_match
+
+    if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+      func_fatal_configuration "not configured to build any kind of library"
+    fi
+
+    # Darwin sucks
+    eval std_shrext=\"$shrext_cmds\"
+
+    # Only execute mode is allowed to have -dlopen flags.
+    if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+      func_error "unrecognized option \`-dlopen'"
+      $ECHO "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Change the help message to a mode-specific one.
+    generic_help="$help"
+    help="Try \`$progname --help --mode=$opt_mode' for more information."
+  }
+
+
+  # Bail if the options were screwed
+  $exit_cmd $EXIT_FAILURE
+}
+
+
+
+
+## ----------- ##
+##    Main.    ##
+## ----------- ##
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+    test -f "$1" &&
+      $SED -e 4q "$1" 2>/dev/null \
+        | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs.  To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway.  Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+    lalib_p=no
+    if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+       for lalib_p_l in 1 2 3 4
+       do
+           read lalib_p_line
+           case "$lalib_p_line" in
+               \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+           esac
+       done
+       exec 0<&5 5<&-
+    fi
+    test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+    func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+    func_ltwrapper_exec_suffix=
+    case $1 in
+    *.exe) ;;
+    *) func_ltwrapper_exec_suffix=.exe ;;
+    esac
+    $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+    func_dirname_and_basename "$1" "" "."
+    func_stripname '' '.exe' "$func_basename_result"
+    func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+    func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+    $opt_debug
+    save_ifs=$IFS; IFS='~'
+    for cmd in $1; do
+      IFS=$save_ifs
+      eval cmd=\"$cmd\"
+      func_show_eval "$cmd" "${2-:}"
+    done
+    IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)!  Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+    $opt_debug
+    case $1 in
+    */* | *\\*)        . "$1" ;;
+    *)         . "./$1" ;;
+    esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot.  Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+  func_resolve_sysroot_result=$1
+  case $func_resolve_sysroot_result in
+  =*)
+    func_stripname '=' '' "$func_resolve_sysroot_result"
+    func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+    ;;
+  esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+  case "$lt_sysroot:$1" in
+  ?*:"$lt_sysroot"*)
+    func_stripname "$lt_sysroot" '' "$1"
+    func_replace_sysroot_result="=$func_stripname_result"
+    ;;
+  *)
+    # Including no sysroot.
+    func_replace_sysroot_result=$1
+    ;;
+  esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+    $opt_debug
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+       func_append_quoted CC_quoted "$arg"
+      done
+      CC_expanded=`func_echo_all $CC`
+      CC_quoted_expanded=`func_echo_all $CC_quoted`
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+      " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+       for z in $available_tags; do
+         if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+           # Evaluate the configuration.
+           eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+           CC_quoted=
+           for arg in $CC; do
+             # Double-quote args containing other shell metacharacters.
+             func_append_quoted CC_quoted "$arg"
+           done
+           CC_expanded=`func_echo_all $CC`
+           CC_quoted_expanded=`func_echo_all $CC_quoted`
+           case "$@ " in
+           " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+           " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+             # The compiler in the base compile command matches
+             # the one in the tagged configuration.
+             # Assume this is the tagged configuration we want.
+             tagname=$z
+             break
+             ;;
+           esac
+         fi
+       done
+       # If $tagname still isn't set, then no tagged configuration
+       # was found and let the user know that the "--tag" command
+       # line option must be used.
+       if test -z "$tagname"; then
+         func_echo "unable to infer tagged configuration"
+         func_fatal_error "specify a tag with \`--tag'"
+#      else
+#        func_verbose "using $tagname tagged configuration"
+       fi
+       ;;
+      esac
+    fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+    write_libobj=${1}
+    if test "$build_libtool_libs" = yes; then
+      write_lobj=\'${2}\'
+    else
+      write_lobj=none
+    fi
+
+    if test "$build_old_libs" = yes; then
+      write_oldobj=\'${3}\'
+    else
+      write_oldobj=none
+    fi
+
+    $opt_dry_run || {
+      cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+      $MV "${write_libobj}T" "${write_libobj}"
+    }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+  $opt_debug
+  func_convert_core_file_wine_to_w32_result="$1"
+  if test -n "$1"; then
+    # Unfortunately, winepath does not exit with a non-zero error code, so we
+    # are forced to check the contents of stdout. On the other hand, if the
+    # command is not found, the shell will set an exit code of 127 and print
+    # *an error message* to stdout. So we must check for both error code of
+    # zero AND non-empty stdout, which explains the odd construction:
+    func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+    if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
+      func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+        $SED -e "$lt_sed_naive_backslashify"`
+    else
+      func_convert_core_file_wine_to_w32_result=
+    fi
+  fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+  $opt_debug
+  # unfortunately, winepath doesn't convert paths, only file names
+  func_convert_core_path_wine_to_w32_result=""
+  if test -n "$1"; then
+    oldIFS=$IFS
+    IFS=:
+    for func_convert_core_path_wine_to_w32_f in $1; do
+      IFS=$oldIFS
+      func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+      if test -n "$func_convert_core_file_wine_to_w32_result" ; then
+        if test -z "$func_convert_core_path_wine_to_w32_result"; then
+          func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
+        else
+          func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+        fi
+      fi
+    done
+    IFS=$oldIFS
+  fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+  $opt_debug
+  if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+    func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+    if test "$?" -ne 0; then
+      # on failure, ensure result is empty
+      func_cygpath_result=
+    fi
+  else
+    func_cygpath_result=
+    func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
+  fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format.  Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+  $opt_debug
+  # awkward: cmd appends spaces to result
+  func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+    $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+  $opt_debug
+  if test -z "$2" && test -n "$1" ; then
+    func_error "Could not determine host file name corresponding to"
+    func_error "  \`$1'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback:
+    func_to_host_file_result="$1"
+  fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+  $opt_debug
+  if test -z "$4" && test -n "$3"; then
+    func_error "Could not determine the host path corresponding to"
+    func_error "  \`$3'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback.  This is a deliberately simplistic "conversion" and
+    # should not be "improved".  See libtool.info.
+    if test "x$1" != "x$2"; then
+      lt_replace_pathsep_chars="s|$1|$2|g"
+      func_to_host_path_result=`echo "$3" |
+        $SED -e "$lt_replace_pathsep_chars"`
+    else
+      func_to_host_path_result="$3"
+    fi
+  fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+  $opt_debug
+  case $4 in
+  $1 ) func_to_host_path_result="$3$func_to_host_path_result"
+    ;;
+  esac
+  case $4 in
+  $2 ) func_append func_to_host_path_result "$3"
+    ;;
+  esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via `$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+  $opt_debug
+  $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result.  If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+  $opt_debug
+  case ,$2, in
+    *,"$to_tool_file_cmd",*)
+      func_to_tool_file_result=$1
+      ;;
+    *)
+      $to_tool_file_cmd "$1"
+      func_to_tool_file_result=$func_to_host_file_result
+      ;;
+  esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+  func_to_host_file_result="$1"
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_to_host_file_result="$func_convert_core_msys_to_w32_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+    # LT_CYGPATH in this case.
+    func_to_host_file_result=`cygpath -m "$1"`
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format.  Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_file_wine_to_w32 "$1"
+    func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_msys_to_w32_result"
+    func_to_host_file_result="$func_cygpath_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format.  Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set.  Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+    func_convert_core_file_wine_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+    func_to_host_file_result="$func_cygpath_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format.  If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+#   file name conversion function    : func_convert_file_X_to_Y ()
+#   path conversion function         : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same.  If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+  $opt_debug
+  if test -z "$to_host_path_cmd"; then
+    func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+    to_host_path_cmd="func_convert_path_${func_stripname_result}"
+  fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+  $opt_debug
+  func_init_to_host_path_cmd
+  $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+  func_to_host_path_result="$1"
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from ARG.  MSYS
+    # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+    # and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result="$func_convert_core_msys_to_w32_result"
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format.  Requires a wine environment and
+# a working winepath.  Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+    func_to_host_path_result="$func_cygpath_result"
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format.  Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set.  Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from
+    # ARG. msys behavior is inconsistent here, cygpath turns them
+    # into '.;' and ';.', and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+    func_to_host_path_result="$func_cygpath_result"
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+    $opt_debug
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+    pie_flag=
+
+    for arg
+    do
+      case $arg_mode in
+      arg  )
+       # do not "continue".  Instead, add this to base_compile
+       lastarg="$arg"
+       arg_mode=normal
+       ;;
+
+      target )
+       libobj="$arg"
+       arg_mode=normal
+       continue
+       ;;
+
+      normal )
+       # Accept any command-line options.
+       case $arg in
+       -o)
+         test -n "$libobj" && \
+           func_fatal_error "you cannot specify \`-o' more than once"
+         arg_mode=target
+         continue
+         ;;
+
+       -pie | -fpie | -fPIE)
+          func_append pie_flag " $arg"
+         continue
+         ;;
+
+       -shared | -static | -prefer-pic | -prefer-non-pic)
+         func_append later " $arg"
+         continue
+         ;;
+
+       -no-suppress)
+         suppress_opt=no
+         continue
+         ;;
+
+       -Xcompiler)
+         arg_mode=arg  #  the next one goes into the "base_compile" arg list
+         continue      #  The current "srcfile" will either be retained or
+         ;;            #  replaced later.  I would guess that would be a bug.
+
+       -Wc,*)
+         func_stripname '-Wc,' '' "$arg"
+         args=$func_stripname_result
+         lastarg=
+         save_ifs="$IFS"; IFS=','
+         for arg in $args; do
+           IFS="$save_ifs"
+           func_append_quoted lastarg "$arg"
+         done
+         IFS="$save_ifs"
+         func_stripname ' ' '' "$lastarg"
+         lastarg=$func_stripname_result
+
+         # Add the arguments to base_compile.
+         func_append base_compile " $lastarg"
+         continue
+         ;;
+
+       *)
+         # Accept the current argument as the source file.
+         # The previous "srcfile" becomes the current argument.
+         #
+         lastarg="$srcfile"
+         srcfile="$arg"
+         ;;
+       esac  #  case $arg
+       ;;
+      esac    #  case $arg_mode
+
+      # Aesthetically quote the previous argument.
+      func_append_quoted base_compile "$lastarg"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      func_fatal_error "you must specify an argument for -Xcompile"
+      ;;
+    target)
+      func_fatal_error "you must specify a target with \`-o'"
+      ;;
+    *)
+      # Get the name of the library object.
+      test -z "$libobj" && {
+       func_basename "$srcfile"
+       libobj="$func_basename_result"
+      }
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    case $libobj in
+    *.[cCFSifmso] | \
+    *.ada | *.adb | *.ads | *.asm | \
+    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+    *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+      func_xform "$libobj"
+      libobj=$func_xform_result
+      ;;
+    esac
+
+    case $libobj in
+    *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+    *)
+      func_fatal_error "cannot determine name of library object from \`$libobj'"
+      ;;
+    esac
+
+    func_infer_tag $base_compile
+
+    for arg in $later; do
+      case $arg in
+      -shared)
+       test "$build_libtool_libs" != yes && \
+         func_fatal_configuration "can not build a shared library"
+       build_old_libs=no
+       continue
+       ;;
+
+      -static)
+       build_libtool_libs=no
+       build_old_libs=yes
+       continue
+       ;;
+
+      -prefer-pic)
+       pic_mode=yes
+       continue
+       ;;
+
+      -prefer-non-pic)
+       pic_mode=no
+       continue
+       ;;
+      esac
+    done
+
+    func_quote_for_eval "$libobj"
+    test "X$libobj" != "X$func_quote_for_eval_result" \
+      && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'   &()|`$[]' \
+      && func_warning "libobj name \`$libobj' may not contain shell special characters."
+    func_dirname_and_basename "$obj" "/" ""
+    objname="$func_basename_result"
+    xdir="$func_dirname_result"
+    lobj=${xdir}$objdir/$objname
+
+    test -z "$base_compile" && \
+      func_fatal_help "you must specify a compilation command"
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2* | cegcc*)
+      pic_mode=default
+      ;;
+    esac
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+       func_echo "Waiting for $lockfile to be removed"
+       sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+       $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $opt_dry_run || $RM $removelist
+       exit $EXIT_FAILURE
+      fi
+      func_append removelist " $output_obj"
+      $ECHO "$srcfile" > "$lockfile"
+    fi
+
+    $opt_dry_run || $RM $removelist
+    func_append removelist " $lockfile"
+    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+    func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+    srcfile=$func_to_tool_file_result
+    func_quote_for_eval "$srcfile"
+    qsrcfile=$func_quote_for_eval_result
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test "$pic_mode" != no; then
+       command="$base_compile $qsrcfile $pic_flag"
+      else
+       # Don't build PIC code
+       command="$base_compile $qsrcfile"
+      fi
+
+      func_mkdir_p "$xdir$objdir"
+
+      if test -z "$output_obj"; then
+       # Place PIC objects in $objdir
+       func_append command " -o $lobj"
+      fi
+
+      func_show_eval_locale "$command" \
+          'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+      if test "$need_locks" = warn &&
+        test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+       $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $opt_dry_run || $RM $removelist
+       exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+       func_show_eval '$MV "$output_obj" "$lobj"' \
+         'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+
+      # Allow error messages only from the first compilation.
+      if test "$suppress_opt" = yes; then
+       suppress_output=' >/dev/null 2>&1'
+      fi
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
+       # Don't build PIC code
+       command="$base_compile $qsrcfile$pie_flag"
+      else
+       command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test "$compiler_c_o" = yes; then
+       func_append command " -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      func_append command "$suppress_output"
+      func_show_eval_locale "$command" \
+        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+      if test "$need_locks" = warn &&
+        test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+       $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $opt_dry_run || $RM $removelist
+       exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+       func_show_eval '$MV "$output_obj" "$obj"' \
+         'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+    fi
+
+    $opt_dry_run || {
+      func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+      # Unlock the critical section if it was locked
+      if test "$need_locks" != no; then
+       removelist=$lockfile
+        $RM "$lockfile"
+      fi
+    }
+
+    exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+  test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+    # We need to display help for each of the modes.
+    case $opt_mode in
+      "")
+        # Generic help is extracted from the usage comments
+        # at the start of this file.
+        func_help
+        ;;
+
+      clean)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      compile)
+      $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -no-suppress      do not suppress compiler output for multiple passes
+  -prefer-pic       try to build PIC objects only
+  -prefer-non-pic   try to build non-PIC objects only
+  -shared           do not build a \`.o' file suitable for static linking
+  -static           only build a \`.o' file suitable for static linking
+  -Wc,FLAG          pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+        ;;
+
+      execute)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+        ;;
+
+      finish)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+        ;;
+
+      install)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+  -inst-prefix-dir PREFIX-DIR  Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+        ;;
+
+      link)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -bindir BINDIR    specify path to binaries directory (for systems where
+                    libraries must be found in the PATH setting at runtime)
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
+  -precious-files-regex REGEX
+                    don't remove output files matching REGEX
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -shared           only do dynamic linking of libtool libraries
+  -shrext SUFFIX    override the standard shared library file extension
+  -static           do not do any dynamic linking of uninstalled libtool libraries
+  -static-libtool-libs
+                    do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                    specify library version info [each variable defaults to 0]
+  -weak LIBNAME     declare that the target provides the LIBNAME interface
+  -Wc,FLAG
+  -Xcompiler FLAG   pass linker-specific FLAG directly to the compiler
+  -Wl,FLAG
+  -Xlinker FLAG     pass linker-specific FLAG directly to the linker
+  -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+        ;;
+
+      uninstall)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      *)
+        func_fatal_help "invalid operation mode \`$opt_mode'"
+        ;;
+    esac
+
+    echo
+    $ECHO "Try \`$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+  if test "$opt_help" = :; then
+    func_mode_help
+  else
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+       func_mode_help
+      done
+    } | sed -n '1p; 2,$s/^Usage:/  or: /p'
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+       echo
+       func_mode_help
+      done
+    } |
+    sed '1d
+      /^When reporting/,/^Report/{
+       H
+       d
+      }
+      $x
+      /information about other modes/d
+      /more detailed .*MODE/d
+      s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+  fi
+  exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+    $opt_debug
+    # The first argument is the command name.
+    cmd="$nonopt"
+    test -z "$cmd" && \
+      func_fatal_help "you must specify a COMMAND"
+
+    # Handle -dlopen flags immediately.
+    for file in $opt_dlopen; do
+      test -f "$file" \
+       || func_fatal_help "\`$file' is not a file"
+
+      dir=
+      case $file in
+      *.la)
+       func_resolve_sysroot "$file"
+       file=$func_resolve_sysroot_result
+
+       # Check to see that this really is a libtool archive.
+       func_lalib_unsafe_p "$file" \
+         || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+       # Read the libtool library.
+       dlname=
+       library_names=
+       func_source "$file"
+
+       # Skip this library if it cannot be dlopened.
+       if test -z "$dlname"; then
+         # Warn if it was a shared library.
+         test -n "$library_names" && \
+           func_warning "\`$file' was not linked with \`-export-dynamic'"
+         continue
+       fi
+
+       func_dirname "$file" "" "."
+       dir="$func_dirname_result"
+
+       if test -f "$dir/$objdir/$dlname"; then
+         func_append dir "/$objdir"
+       else
+         if test ! -f "$dir/$dlname"; then
+           func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+         fi
+       fi
+       ;;
+
+      *.lo)
+       # Just add the directory containing the .lo file.
+       func_dirname "$file" "" "."
+       dir="$func_dirname_result"
+       ;;
+
+      *)
+       func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+       continue
+       ;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+       eval "$shlibpath_var=\"\$dir\""
+      else
+       eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -* | *.la | *.lo ) ;;
+      *)
+       # Do a test to see if this is really a libtool program.
+       if func_ltwrapper_script_p "$file"; then
+         func_source "$file"
+         # Transform arg to wrapped name.
+         file="$progdir/$program"
+       elif func_ltwrapper_executable_p "$file"; then
+         func_ltwrapper_scriptname "$file"
+         func_source "$func_ltwrapper_scriptname_result"
+         # Transform arg to wrapped name.
+         file="$progdir/$program"
+       fi
+       ;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      func_append_quoted args "$file"
+    done
+
+    if test "X$opt_dry_run" = Xfalse; then
+      if test -n "$shlibpath_var"; then
+       # Export the shlibpath_var.
+       eval "export $shlibpath_var"
+      fi
+
+      # Restore saved environment variables
+      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+      do
+       eval "if test \"\${save_$lt_var+set}\" = set; then
+                $lt_var=\$save_$lt_var; export $lt_var
+             else
+               $lt_unset $lt_var
+             fi"
+      done
+
+      # Now prepare to actually exec the command.
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+       eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+       echo "export $shlibpath_var"
+      fi
+      $ECHO "$cmd$args"
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+    $opt_debug
+    libs=
+    libdirs=
+    admincmds=
+
+    for opt in "$nonopt" ${1+"$@"}
+    do
+      if test -d "$opt"; then
+       func_append libdirs " $opt"
+
+      elif test -f "$opt"; then
+       if func_lalib_unsafe_p "$opt"; then
+         func_append libs " $opt"
+       else
+         func_warning "\`$opt' is not a valid libtool archive"
+       fi
+
+      else
+       func_fatal_error "invalid argument \`$opt'"
+      fi
+    done
+
+    if test -n "$libs"; then
+      if test -n "$lt_sysroot"; then
+        sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+        sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+      else
+        sysroot_cmd=
+      fi
+
+      # Remove sysroot references
+      if $opt_dry_run; then
+        for lib in $libs; do
+          echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
+        done
+      else
+        tmpdir=`func_mktempdir`
+        for lib in $libs; do
+         sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+           > $tmpdir/tmp-la
+         mv -f $tmpdir/tmp-la $lib
+       done
+        ${RM}r "$tmpdir"
+      fi
+    fi
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for libdir in $libdirs; do
+       if test -n "$finish_cmds"; then
+         # Do each command in the finish commands.
+         func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+       fi
+       if test -n "$finish_eval"; then
+         # Do the single finish_eval.
+         eval cmds=\"$finish_eval\"
+         $opt_dry_run || eval "$cmds" || func_append admincmds "
+       $cmds"
+       fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    $opt_silent && exit $EXIT_SUCCESS
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      echo "----------------------------------------------------------------------"
+      echo "Libraries have been installed in:"
+      for libdir in $libdirs; do
+       $ECHO "   $libdir"
+      done
+      echo
+      echo "If you ever happen to want to link against installed libraries"
+      echo "in a given directory, LIBDIR, you must either use libtool, and"
+      echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+      echo "flag during linking and do at least one of the following:"
+      if test -n "$shlibpath_var"; then
+       echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+       echo "     during execution"
+      fi
+      if test -n "$runpath_var"; then
+       echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+       echo "     during linking"
+      fi
+      if test -n "$hardcode_libdir_flag_spec"; then
+       libdir=LIBDIR
+       eval flag=\"$hardcode_libdir_flag_spec\"
+
+       $ECHO "   - use the \`$flag' linker flag"
+      fi
+      if test -n "$admincmds"; then
+       $ECHO "   - have your system administrator run these commands:$admincmds"
+      fi
+      if test -f /etc/ld.so.conf; then
+       echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+      fi
+      echo
+
+      echo "See any operating system documentation about shared libraries for"
+      case $host in
+       solaris2.[6789]|solaris2.1[0-9])
+         echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+         echo "pages."
+         ;;
+       *)
+         echo "more information, such as the ld(1) and ld.so(8) manual pages."
+         ;;
+      esac
+      echo "----------------------------------------------------------------------"
+    fi
+    exit $EXIT_SUCCESS
+}
+
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+    $opt_debug
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+       # Allow the use of GNU shtool's install command.
+       case $nonopt in *shtool*) :;; *) false;; esac; then
+      # Aesthetically quote it.
+      func_quote_for_eval "$nonopt"
+      install_prog="$func_quote_for_eval_result "
+      arg=$1
+      shift
+    else
+      install_prog=
+      arg=$nonopt
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    func_quote_for_eval "$arg"
+    func_append install_prog "$func_quote_for_eval_result"
+    install_shared_prog=$install_prog
+    case " $install_prog " in
+      *[\\\ /]cp\ *) install_cp=: ;;
+      *) install_cp=false ;;
+    esac
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    no_mode=:
+    for arg
+    do
+      arg2=
+      if test -n "$dest"; then
+       func_append files " $dest"
+       dest=$arg
+       continue
+      fi
+
+      case $arg in
+      -d) isdir=yes ;;
+      -f)
+       if $install_cp; then :; else
+         prev=$arg
+       fi
+       ;;
+      -g | -m | -o)
+       prev=$arg
+       ;;
+      -s)
+       stripme=" -s"
+       continue
+       ;;
+      -*)
+       ;;
+      *)
+       # If the previous option needed an argument, then skip it.
+       if test -n "$prev"; then
+         if test "x$prev" = x-m && test -n "$install_override_mode"; then
+           arg2=$install_override_mode
+           no_mode=false
+         fi
+         prev=
+       else
+         dest=$arg
+         continue
+       fi
+       ;;
+      esac
+
+      # Aesthetically quote the argument.
+      func_quote_for_eval "$arg"
+      func_append install_prog " $func_quote_for_eval_result"
+      if test -n "$arg2"; then
+       func_quote_for_eval "$arg2"
+      fi
+      func_append install_shared_prog " $func_quote_for_eval_result"
+    done
+
+    test -z "$install_prog" && \
+      func_fatal_help "you must specify an install program"
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prev' option requires an argument"
+
+    if test -n "$install_override_mode" && $no_mode; then
+      if $install_cp; then :; else
+       func_quote_for_eval "$install_override_mode"
+       func_append install_shared_prog " -m $func_quote_for_eval_result"
+      fi
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+       func_fatal_help "no file or destination specified"
+      else
+       func_fatal_help "you must specify a destination"
+      fi
+    fi
+
+    # Strip any trailing slash from the destination.
+    func_stripname '' '/' "$dest"
+    dest=$func_stripname_result
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      func_dirname_and_basename "$dest" "" "."
+      destdir="$func_dirname_result"
+      destname="$func_basename_result"
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files; shift
+      test "$#" -gt 1 && \
+       func_fatal_help "\`$dest' is not a directory"
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+       case $file in
+       *.lo) ;;
+       *)
+         func_fatal_help "\`$destdir' must be an absolute directory name"
+         ;;
+       esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+       # Do the static libraries later.
+       func_append staticlibs " $file"
+       ;;
+
+      *.la)
+       func_resolve_sysroot "$file"
+       file=$func_resolve_sysroot_result
+
+       # Check to see that this really is a libtool archive.
+       func_lalib_unsafe_p "$file" \
+         || func_fatal_help "\`$file' is not a valid libtool archive"
+
+       library_names=
+       old_library=
+       relink_command=
+       func_source "$file"
+
+       # Add the libdir to current_libdirs if it is the destination.
+       if test "X$destdir" = "X$libdir"; then
+         case "$current_libdirs " in
+         *" $libdir "*) ;;
+         *) func_append current_libdirs " $libdir" ;;
+         esac
+       else
+         # Note the libdir as a future libdir.
+         case "$future_libdirs " in
+         *" $libdir "*) ;;
+         *) func_append future_libdirs " $libdir" ;;
+         esac
+       fi
+
+       func_dirname "$file" "/" ""
+       dir="$func_dirname_result"
+       func_append dir "$objdir"
+
+       if test -n "$relink_command"; then
+         # Determine the prefix the user has applied to our future dir.
+         inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+         # Don't allow the user to place us outside of our expected
+         # location b/c this prevents finding dependent libraries that
+         # are installed to the same prefix.
+         # At present, this check doesn't affect windows .dll's that
+         # are installed into $libdir/../bin (currently, that works fine)
+         # but it's something to keep an eye on.
+         test "$inst_prefix_dir" = "$destdir" && \
+           func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+         if test -n "$inst_prefix_dir"; then
+           # Stick the inst_prefix_dir data into the link command.
+           relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+         else
+           relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+         fi
+
+         func_warning "relinking \`$file'"
+         func_show_eval "$relink_command" \
+           'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+       fi
+
+       # See the names of the shared library.
+       set dummy $library_names; shift
+       if test -n "$1"; then
+         realname="$1"
+         shift
+
+         srcname="$realname"
+         test -n "$relink_command" && srcname="$realname"T
+
+         # Install the shared library and build the symlinks.
+         func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+             'exit $?'
+         tstripme="$stripme"
+         case $host_os in
+         cygwin* | mingw* | pw32* | cegcc*)
+           case $realname in
+           *.dll.a)
+             tstripme=""
+             ;;
+           esac
+           ;;
+         esac
+         if test -n "$tstripme" && test -n "$striplib"; then
+           func_show_eval "$striplib $destdir/$realname" 'exit $?'
+         fi
+
+         if test "$#" -gt 0; then
+           # Delete the old symlinks, and create new ones.
+           # Try `ln -sf' first, because the `ln' binary might depend on
+           # the symlink we replace!  Solaris /bin/ln does not understand -f,
+           # so we also need to try rm && ln -s.
+           for linkname
+           do
+             test "$linkname" != "$realname" \
+               && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+           done
+         fi
+
+         # Do each command in the postinstall commands.
+         lib="$destdir/$realname"
+         func_execute_cmds "$postinstall_cmds" 'exit $?'
+       fi
+
+       # Install the pseudo-library for information purposes.
+       func_basename "$file"
+       name="$func_basename_result"
+       instname="$dir/$name"i
+       func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+       # Maybe install the static library, too.
+       test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+       ;;
+
+      *.lo)
+       # Install (i.e. copy) a libtool object.
+
+       # Figure out destination file name, if it wasn't already specified.
+       if test -n "$destname"; then
+         destfile="$destdir/$destname"
+       else
+         func_basename "$file"
+         destfile="$func_basename_result"
+         destfile="$destdir/$destfile"
+       fi
+
+       # Deduce the name of the destination old-style object file.
+       case $destfile in
+       *.lo)
+         func_lo2o "$destfile"
+         staticdest=$func_lo2o_result
+         ;;
+       *.$objext)
+         staticdest="$destfile"
+         destfile=
+         ;;
+       *)
+         func_fatal_help "cannot copy a libtool object to \`$destfile'"
+         ;;
+       esac
+
+       # Install the libtool object if requested.
+       test -n "$destfile" && \
+         func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+       # Install the old object if enabled.
+       if test "$build_old_libs" = yes; then
+         # Deduce the name of the old-style object file.
+         func_lo2o "$file"
+         staticobj=$func_lo2o_result
+         func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+       fi
+       exit $EXIT_SUCCESS
+       ;;
+
+      *)
+       # Figure out destination file name, if it wasn't already specified.
+       if test -n "$destname"; then
+         destfile="$destdir/$destname"
+       else
+         func_basename "$file"
+         destfile="$func_basename_result"
+         destfile="$destdir/$destfile"
+       fi
+
+       # If the file is missing, and there is a .exe on the end, strip it
+       # because it is most likely a libtool script we actually want to
+       # install
+       stripped_ext=""
+       case $file in
+         *.exe)
+           if test ! -f "$file"; then
+             func_stripname '' '.exe' "$file"
+             file=$func_stripname_result
+             stripped_ext=".exe"
+           fi
+           ;;
+       esac
+
+       # Do a test to see if this is really a libtool program.
+       case $host in
+       *cygwin* | *mingw*)
+           if func_ltwrapper_executable_p "$file"; then
+             func_ltwrapper_scriptname "$file"
+             wrapper=$func_ltwrapper_scriptname_result
+           else
+             func_stripname '' '.exe' "$file"
+             wrapper=$func_stripname_result
+           fi
+           ;;
+       *)
+           wrapper=$file
+           ;;
+       esac
+       if func_ltwrapper_script_p "$wrapper"; then
+         notinst_deplibs=
+         relink_command=
+
+         func_source "$wrapper"
+
+         # Check the variables that should have been set.
+         test -z "$generated_by_libtool_version" && \
+           func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+         finalize=yes
+         for lib in $notinst_deplibs; do
+           # Check to see that each library is installed.
+           libdir=
+           if test -f "$lib"; then
+             func_source "$lib"
+           fi
+           libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
+           if test -n "$libdir" && test ! -f "$libfile"; then
+             func_warning "\`$lib' has not been installed in \`$libdir'"
+             finalize=no
+           fi
+         done
+
+         relink_command=
+         func_source "$wrapper"
+
+         outputname=
+         if test "$fast_install" = no && test -n "$relink_command"; then
+           $opt_dry_run || {
+             if test "$finalize" = yes; then
+               tmpdir=`func_mktempdir`
+               func_basename "$file$stripped_ext"
+               file="$func_basename_result"
+               outputname="$tmpdir/$file"
+               # Replace the output file specification.
+               relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+               $opt_silent || {
+                 func_quote_for_expand "$relink_command"
+                 eval "func_echo $func_quote_for_expand_result"
+               }
+               if eval "$relink_command"; then :
+                 else
+                 func_error "error: relink \`$file' with the above command before installing it"
+                 $opt_dry_run || ${RM}r "$tmpdir"
+                 continue
+               fi
+               file="$outputname"
+             else
+               func_warning "cannot relink \`$file'"
+             fi
+           }
+         else
+           # Install the binary that we compiled earlier.
+           file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+         fi
+       fi
+
+       # remove .exe since cygwin /usr/bin/install will append another
+       # one anyway
+       case $install_prog,$host in
+       */usr/bin/install*,*cygwin*)
+         case $file:$destfile in
+         *.exe:*.exe)
+           # this is ok
+           ;;
+         *.exe:*)
+           destfile=$destfile.exe
+           ;;
+         *:*.exe)
+           func_stripname '' '.exe' "$destfile"
+           destfile=$func_stripname_result
+           ;;
+         esac
+         ;;
+       esac
+       func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+       $opt_dry_run || if test -n "$outputname"; then
+         ${RM}r "$tmpdir"
+       fi
+       ;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      func_basename "$file"
+      name="$func_basename_result"
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+      func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+      tool_oldlib=$func_to_tool_file_result
+
+      func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+       func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+      fi
+
+      # Do each command in the postinstall commands.
+      func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+    done
+
+    test -n "$future_libdirs" && \
+      func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      $opt_dry_run && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+    $opt_debug
+    my_outputname="$1"
+    my_originator="$2"
+    my_pic_p="${3-no}"
+    my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+    my_dlsyms=
+
+    if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+      if test -n "$NM" && test -n "$global_symbol_pipe"; then
+       my_dlsyms="${my_outputname}S.c"
+      else
+       func_error "not configured to extract global symbols from dlpreopened files"
+      fi
+    fi
+
+    if test -n "$my_dlsyms"; then
+      case $my_dlsyms in
+      "") ;;
+      *.c)
+       # Discover the nlist of each of the dlfiles.
+       nlist="$output_objdir/${my_outputname}.nm"
+
+       func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+       # Parse the name list into a source file.
+       func_verbose "creating $output_objdir/$my_dlsyms"
+
+       $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+       if test "$dlself" = yes; then
+         func_verbose "generating symbol list for \`$output'"
+
+         $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+         # Add our own program objects to the symbol list.
+         progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+         for progfile in $progfiles; do
+           func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+           func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
+           $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+         done
+
+         if test -n "$exclude_expsyms"; then
+           $opt_dry_run || {
+             eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+             eval '$MV "$nlist"T "$nlist"'
+           }
+         fi
+
+         if test -n "$export_symbols_regex"; then
+           $opt_dry_run || {
+             eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+             eval '$MV "$nlist"T "$nlist"'
+           }
+         fi
+
+         # Prepare the list of exported symbols
+         if test -z "$export_symbols"; then
+           export_symbols="$output_objdir/$outputname.exp"
+           $opt_dry_run || {
+             $RM $export_symbols
+             eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+             case $host in
+             *cygwin* | *mingw* | *cegcc* )
+                eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+                eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+               ;;
+             esac
+           }
+         else
+           $opt_dry_run || {
+             eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+             eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+             eval '$MV "$nlist"T "$nlist"'
+             case $host in
+               *cygwin* | *mingw* | *cegcc* )
+                 eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+                 eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+                 ;;
+             esac
+           }
+         fi
+       fi
+
+       for dlprefile in $dlprefiles; do
+         func_verbose "extracting global C symbols from \`$dlprefile'"
+         func_basename "$dlprefile"
+         name="$func_basename_result"
+          case $host in
+           *cygwin* | *mingw* | *cegcc* )
+             # if an import library, we need to obtain dlname
+             if func_win32_import_lib_p "$dlprefile"; then
+               func_tr_sh "$dlprefile"
+               eval "curr_lafile=\$libfile_$func_tr_sh_result"
+               dlprefile_dlbasename=""
+               if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+                 # Use subshell, to avoid clobbering current variable values
+                 dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+                 if test -n "$dlprefile_dlname" ; then
+                   func_basename "$dlprefile_dlname"
+                   dlprefile_dlbasename="$func_basename_result"
+                 else
+                   # no lafile. user explicitly requested -dlpreopen <import library>.
+                   $sharedlib_from_linklib_cmd "$dlprefile"
+                   dlprefile_dlbasename=$sharedlib_from_linklib_result
+                 fi
+               fi
+               $opt_dry_run || {
+                 if test -n "$dlprefile_dlbasename" ; then
+                   eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+                 else
+                   func_warning "Could not compute DLL name from $name"
+                   eval '$ECHO ": $name " >> "$nlist"'
+                 fi
+                 func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+                 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+                   $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+               }
+             else # not an import lib
+               $opt_dry_run || {
+                 eval '$ECHO ": $name " >> "$nlist"'
+                 func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+                 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+               }
+             fi
+           ;;
+           *)
+             $opt_dry_run || {
+               eval '$ECHO ": $name " >> "$nlist"'
+               func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+               eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+             }
+           ;;
+          esac
+       done
+
+       $opt_dry_run || {
+         # Make sure we have at least an empty file.
+         test -f "$nlist" || : > "$nlist"
+
+         if test -n "$exclude_expsyms"; then
+           $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+           $MV "$nlist"T "$nlist"
+         fi
+
+         # Try sorting and uniquifying the output.
+         if $GREP -v "^: " < "$nlist" |
+             if sort -k 3 </dev/null >/dev/null 2>&1; then
+               sort -k 3
+             else
+               sort +2
+             fi |
+             uniq > "$nlist"S; then
+           :
+         else
+           $GREP -v "^: " < "$nlist" > "$nlist"S
+         fi
+
+         if test -f "$nlist"S; then
+           eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+         else
+           echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+         fi
+
+         echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols.  */
+typedef struct {
+  const char *name;
+  void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+  { \"$my_originator\", (void *) 0 },"
+
+         case $need_lib_prefix in
+         no)
+           eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+           ;;
+         *)
+           eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+           ;;
+         esac
+         echo >> "$output_objdir/$my_dlsyms" "\
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+       } # !$opt_dry_run
+
+       pic_flag_for_symtable=
+       case "$compile_command " in
+       *" -static "*) ;;
+       *)
+         case $host in
+         # compiling the symbol table file with pic_flag works around
+         # a FreeBSD bug that causes programs to crash when -lm is
+         # linked before any other PIC object.  But we must not use
+         # pic_flag when linking with -static.  The problem exists in
+         # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+         *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+           pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+         *-*-hpux*)
+           pic_flag_for_symtable=" $pic_flag"  ;;
+         *)
+           if test "X$my_pic_p" != Xno; then
+             pic_flag_for_symtable=" $pic_flag"
+           fi
+           ;;
+         esac
+         ;;
+       esac
+       symtab_cflags=
+       for arg in $LTCFLAGS; do
+         case $arg in
+         -pie | -fpie | -fPIE) ;;
+         *) func_append symtab_cflags " $arg" ;;
+         esac
+       done
+
+       # Now compile the dynamic symbol file.
+       func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+       # Clean up the generated files.
+       func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+       # Transform the symbol file into the correct name.
+       symfileobj="$output_objdir/${my_outputname}S.$objext"
+       case $host in
+       *cygwin* | *mingw* | *cegcc* )
+         if test -f "$output_objdir/$my_outputname.def"; then
+           compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+           finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+         else
+           compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+           finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+         fi
+         ;;
+       *)
+         compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+         finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+         ;;
+       esac
+       ;;
+      *)
+       func_fatal_error "unknown suffix for \`$my_dlsyms'"
+       ;;
+      esac
+    else
+      # We keep going just in case the user didn't refer to
+      # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+      # really was required.
+
+      # Nullify the symbol file.
+      compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+      finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+    fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+  $opt_debug
+  win32_libid_type="unknown"
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+      func_to_tool_file "$1" func_convert_file_msys_to_w32
+      win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+       $SED -n -e '
+           1,100{
+               / I /{
+                   s,.*,import,
+                   p
+                   q
+               }
+           }'`
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+  $opt_debug
+  sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+  $opt_debug
+  match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+  $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+    $SED '/^Contents of section '"$match_literal"':/{
+      # Place marker at beginning of archive member dllname section
+      s/.*/====MARK====/
+      p
+      d
+    }
+    # These lines can sometimes be longer than 43 characters, but
+    # are always uninteresting
+    /:[         ]*file format pe[i]\{,1\}-/d
+    /^In archive [^:]*:/d
+    # Ensure marker is printed
+    /^====MARK====/p
+    # Remove all lines with less than 43 characters
+    /^.\{43\}/!d
+    # From remaining lines, remove first 43 characters
+    s/^.\{43\}//' |
+    $SED -n '
+      # Join marker and all lines until next marker into a single line
+      /^====MARK====/ b para
+      H
+      $ b para
+      b
+      :para
+      x
+      s/\n//g
+      # Remove the marker
+      s/^====MARK====//
+      # Remove trailing dots and whitespace
+      s/[\. \t]*$//
+      # Print
+      /./p' |
+    # we now have a list, one entry per line, of the stringified
+    # contents of the appropriate section of all members of the
+    # archive which possess that section. Heuristic: eliminate
+    # all those which have a first or second character that is
+    # a '.' (that is, objdump's representation of an unprintable
+    # character.) This should work for all archives with less than
+    # 0x302f exports -- but will fail for DLLs whose name actually
+    # begins with a literal '.' or a single character followed by
+    # a '.'.
+    #
+    # Of those that remain, print the first one.
+    $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+  test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+  test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+  $opt_debug
+  if func_cygming_gnu_implib_p "$1" ; then
+    # binutils import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+  elif func_cygming_ms_implib_p "$1" ; then
+    # ms-generated import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+  else
+    # unknown
+    sharedlib_from_linklib_result=""
+  fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    $opt_debug
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+    if test "$lock_old_archive_extraction" = yes; then
+      lockfile=$f_ex_an_ar_oldlib.lock
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+       func_echo "Waiting for $lockfile to be removed"
+       sleep 2
+      done
+    fi
+    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+                  'stat=$?; rm -f "$lockfile"; exit $stat'
+    if test "$lock_old_archive_extraction" = yes; then
+      $opt_dry_run || rm -f "$lockfile"
+    fi
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+    fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    $opt_debug
+    my_gentop="$1"; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
+
+    for my_xlib in $my_oldlibs; do
+      # Extract the objects.
+      case $my_xlib in
+       [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+       *) my_xabs=`pwd`"/$my_xlib" ;;
+      esac
+      func_basename "$my_xlib"
+      my_xlib="$func_basename_result"
+      my_xlib_u=$my_xlib
+      while :; do
+        case " $extracted_archives " in
+       *" $my_xlib_u "*)
+         func_arith $extracted_serial + 1
+         extracted_serial=$func_arith_result
+         my_xlib_u=lt$extracted_serial-$my_xlib ;;
+       *) break ;;
+       esac
+      done
+      extracted_archives="$extracted_archives $my_xlib_u"
+      my_xdir="$my_gentop/$my_xlib_u"
+
+      func_mkdir_p "$my_xdir"
+
+      case $host in
+      *-darwin*)
+       func_verbose "Extracting $my_xabs"
+       # Do not bother doing anything if just a dry run
+       $opt_dry_run || {
+         darwin_orig_dir=`pwd`
+         cd $my_xdir || exit $?
+         darwin_archive=$my_xabs
+         darwin_curdir=`pwd`
+         darwin_base_archive=`basename "$darwin_archive"`
+         darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+         if test -n "$darwin_arches"; then
+           darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+           darwin_arch=
+           func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+           for darwin_arch in  $darwin_arches ; do
+             func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+             $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+             cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+             func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+             cd "$darwin_curdir"
+             $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+           done # $darwin_arches
+            ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+           darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+           darwin_file=
+           darwin_files=
+           for darwin_file in $darwin_filelist; do
+             darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+             $LIPO -create -output "$darwin_file" $darwin_files
+           done # $darwin_filelist
+           $RM -rf unfat-$$
+           cd "$darwin_orig_dir"
+         else
+           cd $darwin_orig_dir
+           func_extract_an_archive "$my_xdir" "$my_xabs"
+         fi # $darwin_arches
+       } # !$opt_dry_run
+       ;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+       ;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+    done
+
+    func_extract_archives_result="$my_oldobjs"
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable.  Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take.  If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory.  This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+       func_emit_wrapper_arg1=${1-no}
+
+       $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variables:
+  generated_by_libtool_version='$macro_version'
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$ECHO are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    file=\"\$0\""
+
+    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+    $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+    ECHO=\"$qECHO\"
+  fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+  lt_script_arg0=\$0
+  shift
+  for lt_opt
+  do
+    case \"\$lt_opt\" in
+    --lt-debug) lt_option_debug=1 ;;
+    --lt-dump-script)
+        lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+        test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+        lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+        cat \"\$lt_dump_D/\$lt_dump_F\"
+        exit 0
+      ;;
+    --lt-*)
+        \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+        exit 1
+      ;;
+    esac
+  done
+
+  # Print the debug banner immediately:
+  if test -n \"\$lt_option_debug\"; then
+    echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
+  fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+  lt_dump_args_N=1;
+  for lt_arg
+  do
+    \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
+    lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+  done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+  case $host in
+  # Backslashes separate directories on plain windows
+  *-*-mingw | *-*-os2* | *-cegcc*)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+    ;;
+
+  *)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+    ;;
+  esac
+  $ECHO "\
+      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+      exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+  case \" \$* \" in
+  *\\ --lt-*)
+    for lt_wr_arg
+    do
+      case \$lt_wr_arg in
+      --lt-*) ;;
+      *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+      esac
+      shift
+    done ;;
+  esac
+  func_exec_program_core \${1+\"\$@\"}
+}
+
+  # Parse options
+  func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+  done
+
+  # Usually 'no', except on cygwin/mingw when embedded into
+  # the cwrapper.
+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+  if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+    # special case for '.'
+    if test \"\$thisdir\" = \".\"; then
+      thisdir=\`pwd\`
+    fi
+    # remove .libs from thisdir
+    case \"\$thisdir\" in
+    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+    $objdir )   thisdir=. ;;
+    esac
+  fi
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+       if test "$fast_install" = yes; then
+         $ECHO "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" ||
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $MKDIR \"\$progdir\"
+    else
+      $RM \"\$progdir/\$file\"
+    fi"
+
+         $ECHO "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+       $ECHO \"\$relink_command_output\" >&2
+       $RM \"\$progdir/\$file\"
+       exit 1
+      fi
+    fi
+
+    $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $RM \"\$progdir/\$program\";
+      $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $RM \"\$progdir/\$file\"
+  fi"
+       else
+         $ECHO "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+       fi
+
+       $ECHO "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+       # fixup the dll searchpath if we need to.
+       #
+       # Fix the DLL searchpath if we need to.  Do this before prepending
+       # to shlibpath, because on Windows, both are PATH and uninstalled
+       # libraries must come first.
+       if test -n "$dllsearchpath"; then
+         $ECHO "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+       fi
+
+       # Export our shlibpath_var if we have one.
+       if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+         $ECHO "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+       fi
+
+       $ECHO "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+      func_exec_program \${1+\"\$@\"}
+    fi
+  else
+    # The program doesn't exist.
+    \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+    \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+    \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+       cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+   The $output program cannot be directly executed until all the libtool
+   libraries that it depends on are installed.
+
+   This wrapper executable should never be moved out of the build directory.
+   If it is, it will not operate correctly.
+*/
+EOF
+           cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+#  include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* declarations of non-ANSI functions */
+#if defined(__MINGW32__)
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined(__CYGWIN__)
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined (other platforms) ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined(_MSC_VER)
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+# define S_IXUSR _S_IEXEC
+# ifndef _INTPTR_T_DEFINED
+#  define _INTPTR_T_DEFINED
+#  define intptr_t int
+# endif
+#elif defined(__MINGW32__)
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+#elif defined(__CYGWIN__)
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined (other platforms) ... */
+#endif
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+#  define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+       (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#if defined(LT_DEBUGWRAPPER)
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+           cat <<EOF
+volatile const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+           if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+              func_to_host_path "$temp_rpath"
+             cat <<EOF
+const char * LIB_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+           else
+             cat <<"EOF"
+const char * LIB_PATH_VALUE   = "";
+EOF
+           fi
+
+           if test -n "$dllsearchpath"; then
+              func_to_host_path "$dllsearchpath:"
+             cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+           else
+             cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE   = "";
+EOF
+           fi
+
+           if test "$fast_install" = yes; then
+             cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+           else
+             cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+           fi
+
+
+           cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX         "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt            = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int  newargc;
+  char *tmp_pathspec;
+  char *actual_cwrapper_path;
+  char *actual_cwrapper_name;
+  char *target_name;
+  char *lt_argv_zero;
+  intptr_t rval = 127;
+
+  int i;
+
+  program_name = (char *) xstrdup (base_name (argv[0]));
+  newargz = XMALLOC (char *, argc + 1);
+
+  /* very simple arg parsing; don't want to rely on getopt
+   * also, copy all non cwrapper options to newargz, except
+   * argz[0], which is handled differently
+   */
+  newargc=0;
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[i], dumpscript_opt) == 0)
+       {
+EOF
+           case "$host" in
+             *mingw* | *cygwin* )
+               # make stdout use "unix" line endings
+               echo "          setmode(1,_O_BINARY);"
+               ;;
+             esac
+
+           cat <<"EOF"
+         lt_dump_script (stdout);
+         return 0;
+       }
+      if (strcmp (argv[i], debug_opt) == 0)
+       {
+          lt_debug = 1;
+          continue;
+       }
+      if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
+        {
+          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+             namespace, but it is not one of the ones we know about and
+             have already dealt with, above (inluding dump-script), then
+             report an error. Otherwise, targets might begin to believe
+             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+             namespace. The first time any user complains about this, we'll
+             need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+             or a configure.ac-settable value.
+           */
+          lt_fatal (__FILE__, __LINE__,
+                   "unrecognized %s option: '%s'",
+                    ltwrapper_option_prefix, argv[i]);
+        }
+      /* otherwise ... */
+      newargz[++newargc] = xstrdup (argv[i]);
+    }
+  newargz[++newargc] = NULL;
+
+EOF
+           cat <<EOF
+  /* The GNU banner must be the first non-error debug message */
+  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
+EOF
+           cat <<"EOF"
+  lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+  tmp_pathspec = find_executable (argv[0]);
+  if (tmp_pathspec == NULL)
+    lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (before symlink chase) at: %s\n",
+                 tmp_pathspec);
+
+  actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (after symlink chase) at: %s\n",
+                 actual_cwrapper_path);
+  XFREE (tmp_pathspec);
+
+  actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+  strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+  /* wrapper name transforms */
+  strendzap (actual_cwrapper_name, ".exe");
+  tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+  XFREE (actual_cwrapper_name);
+  actual_cwrapper_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  /* target_name transforms -- use actual target program name; might have lt- prefix */
+  target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+  strendzap (target_name, ".exe");
+  tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+  XFREE (target_name);
+  target_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  lt_debugprintf (__FILE__, __LINE__,
+                 "(main) libtool target name: %s\n",
+                 target_name);
+EOF
+
+           cat <<EOF
+  newargz[0] =
+    XMALLOC (char, (strlen (actual_cwrapper_path) +
+                   strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+  strcpy (newargz[0], actual_cwrapper_path);
+  strcat (newargz[0], "$objdir");
+  strcat (newargz[0], "/");
+EOF
+
+           cat <<"EOF"
+  /* stop here, and copy so we don't have to do this twice */
+  tmp_pathspec = xstrdup (newargz[0]);
+
+  /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+  strcat (newargz[0], actual_cwrapper_name);
+
+  /* DO want the lt- prefix here if it exists, so use target_name */
+  lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+  XFREE (tmp_pathspec);
+  tmp_pathspec = NULL;
+EOF
+
+           case $host_os in
+             mingw*)
+           cat <<"EOF"
+  {
+    char* p;
+    while ((p = strchr (newargz[0], '\\')) != NULL)
+      {
+       *p = '/';
+      }
+    while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+      {
+       *p = '/';
+      }
+  }
+EOF
+           ;;
+           esac
+
+           cat <<"EOF"
+  XFREE (target_name);
+  XFREE (actual_cwrapper_path);
+  XFREE (actual_cwrapper_name);
+
+  lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+  lt_setenv ("DUALCASE", "1");  /* for MSK sh */
+  /* Update the DLL searchpath.  EXE_PATH_VALUE ($dllsearchpath) must
+     be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+     because on Windows, both *_VARNAMEs are PATH but uninstalled
+     libraries must come first. */
+  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+  lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+                 nonnull (lt_argv_zero));
+  for (i = 0; i < newargc; i++)
+    {
+      lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+                     i, nonnull (newargz[i]));
+    }
+
+EOF
+
+           case $host_os in
+             mingw*)
+               cat <<"EOF"
+  /* execv doesn't actually work on mingw as expected on unix */
+  newargz = prepare_spawn (newargz);
+  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+  if (rval == -1)
+    {
+      /* failed to start process */
+      lt_debugprintf (__FILE__, __LINE__,
+                     "(main) failed to launch target \"%s\": %s\n",
+                     lt_argv_zero, nonnull (strerror (errno)));
+      return 127;
+    }
+  return rval;
+EOF
+               ;;
+             *)
+               cat <<"EOF"
+  execv (lt_argv_zero, newargz);
+  return rval; /* =127, but avoids unused variable warning */
+EOF
+               ;;
+           esac
+
+           cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+  void *p = (void *) malloc (num);
+  if (!p)
+    lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+  return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+                         string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+  const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  /* Skip over the disk name in MSDOS pathnames. */
+  if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+    name += 2;
+#endif
+
+  for (base = name; *name; name++)
+    if (IS_DIR_SEPARATOR (*name))
+      base = name + 1;
+  return base;
+}
+
+int
+check_executable (const char *path)
+{
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if ((stat (path, &st) >= 0)
+      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+    return 1;
+  else
+    return 0;
+}
+
+int
+make_executable (const char *path)
+{
+  int rval = 0;
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if (stat (path, &st) >= 0)
+    {
+      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+    }
+  return rval;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise
+   Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+  int has_slash = 0;
+  const char *p;
+  const char *p_next;
+  /* static buffer for getcwd */
+  char tmp[LT_PATHMAX + 1];
+  int tmp_len;
+  char *concat_name;
+
+  lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+                  nonempty (wrapper));
+
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
+
+  /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable (concat_name))
+       return concat_name;
+      XFREE (concat_name);
+    }
+  else
+    {
+#endif
+      if (IS_DIR_SEPARATOR (wrapper[0]))
+       {
+         concat_name = xstrdup (wrapper);
+         if (check_executable (concat_name))
+           return concat_name;
+         XFREE (concat_name);
+       }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+    }
+#endif
+
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+      {
+       has_slash = 1;
+       break;
+      }
+  if (!has_slash)
+    {
+      /* no slashes; search PATH */
+      const char *path = getenv ("PATH");
+      if (path != NULL)
+       {
+         for (p = path; *p; p = p_next)
+           {
+             const char *q;
+             size_t p_len;
+             for (q = p; *q; q++)
+               if (IS_PATH_SEPARATOR (*q))
+                 break;
+             p_len = q - p;
+             p_next = (*q == '\0' ? q : q + 1);
+             if (p_len == 0)
+               {
+                 /* empty path: current directory */
+                 if (getcwd (tmp, LT_PATHMAX) == NULL)
+                   lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+                              nonnull (strerror (errno)));
+                 tmp_len = strlen (tmp);
+                 concat_name =
+                   XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+                 memcpy (concat_name, tmp, tmp_len);
+                 concat_name[tmp_len] = '/';
+                 strcpy (concat_name + tmp_len + 1, wrapper);
+               }
+             else
+               {
+                 concat_name =
+                   XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+                 memcpy (concat_name, p, p_len);
+                 concat_name[p_len] = '/';
+                 strcpy (concat_name + p_len + 1, wrapper);
+               }
+             if (check_executable (concat_name))
+               return concat_name;
+             XFREE (concat_name);
+           }
+       }
+      /* not found in PATH; assume curdir */
+    }
+  /* Relative path | not found in path: prepend cwd */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+              nonnull (strerror (errno)));
+  tmp_len = strlen (tmp);
+  concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
+
+  if (check_executable (concat_name))
+    return concat_name;
+  XFREE (concat_name);
+  return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+  return xstrdup (pathspec);
+#else
+  char buf[LT_PATHMAX];
+  struct stat s;
+  char *tmp_pathspec = xstrdup (pathspec);
+  char *p;
+  int has_symlinks = 0;
+  while (strlen (tmp_pathspec) && !has_symlinks)
+    {
+      lt_debugprintf (__FILE__, __LINE__,
+                     "checking path component for symlinks: %s\n",
+                     tmp_pathspec);
+      if (lstat (tmp_pathspec, &s) == 0)
+       {
+         if (S_ISLNK (s.st_mode) != 0)
+           {
+             has_symlinks = 1;
+             break;
+           }
+
+         /* search backwards for last DIR_SEPARATOR */
+         p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+         while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+           p--;
+         if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+           {
+             /* no more DIR_SEPARATORS left */
+             break;
+           }
+         *p = '\0';
+       }
+      else
+       {
+         lt_fatal (__FILE__, __LINE__,
+                   "error accessing file \"%s\": %s",
+                   tmp_pathspec, nonnull (strerror (errno)));
+       }
+    }
+  XFREE (tmp_pathspec);
+
+  if (!has_symlinks)
+    {
+      return xstrdup (pathspec);
+    }
+
+  tmp_pathspec = realpath (pathspec, buf);
+  if (tmp_pathspec == 0)
+    {
+      lt_fatal (__FILE__, __LINE__,
+               "could not follow symlinks for %s", pathspec);
+    }
+  return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+  size_t len, patlen;
+
+  assert (str != NULL);
+  assert (pat != NULL);
+
+  len = strlen (str);
+  patlen = strlen (pat);
+
+  if (patlen <= len)
+    {
+      str += len - patlen;
+      if (strcmp (str, pat) == 0)
+       *str = '\0';
+    }
+  return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+  va_list args;
+  if (lt_debug)
+    {
+      (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+      va_start (args, fmt);
+      (void) vfprintf (stderr, fmt, args);
+      va_end (args);
+    }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+              int line, const char *mode,
+              const char *message, va_list ap)
+{
+  fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+  va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+  return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+  return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+                 "(lt_setenv) setting '%s' to '%s'\n",
+                  nonnull (name), nonnull (value));
+  {
+#ifdef HAVE_SETENV
+    /* always make a copy, for consistency with !HAVE_SETENV */
+    char *str = xstrdup (value);
+    setenv (name, str, 1);
+#else
+    int len = strlen (name) + 1 + strlen (value) + 1;
+    char *str = XMALLOC (char, len);
+    sprintf (str, "%s=%s", name, value);
+    if (putenv (str) != EXIT_SUCCESS)
+      {
+        XFREE (str);
+      }
+#endif
+  }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+  char *new_value;
+  if (orig_value && *orig_value)
+    {
+      int orig_value_len = strlen (orig_value);
+      int add_len = strlen (add);
+      new_value = XMALLOC (char, add_len + orig_value_len + 1);
+      if (to_end)
+        {
+          strcpy (new_value, orig_value);
+          strcpy (new_value + orig_value_len, add);
+        }
+      else
+        {
+          strcpy (new_value, add);
+          strcpy (new_value + add_len, orig_value);
+        }
+    }
+  else
+    {
+      new_value = xstrdup (add);
+    }
+  return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+                 "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      /* some systems can't cope with a ':'-terminated path #' */
+      int len = strlen (new_value);
+      while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+        {
+          new_value[len-1] = '\0';
+        }
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+                 "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+EOF
+           case $host_os in
+             mingw*)
+               cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+   Note that spawn() does not by itself call the command interpreter
+     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+         GetVersionEx(&v);
+         v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+      }) ? "cmd.exe" : "command.com").
+   Instead it simply concatenates the arguments, separated by ' ', and calls
+   CreateProcess().  We must quote the arguments since Win32 CreateProcess()
+   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+   special way:
+   - Space and tab are interpreted as delimiters. They are not treated as
+     delimiters if they are surrounded by double quotes: "...".
+   - Unescaped double quotes are removed from the input. Their only effect is
+     that within double quotes, space and tab are treated like normal
+     characters.
+   - Backslashes not followed by double quotes are not special.
+   - But 2*n+1 backslashes followed by a double quote become
+     n backslashes followed by a double quote (n >= 0):
+       \" -> "
+       \\\" -> \"
+       \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+  size_t argc;
+  char **new_argv;
+  size_t i;
+
+  /* Count number of arguments.  */
+  for (argc = 0; argv[argc] != NULL; argc++)
+    ;
+
+  /* Allocate new argument vector.  */
+  new_argv = XMALLOC (char *, argc + 1);
+
+  /* Put quoted arguments into the new argument vector.  */
+  for (i = 0; i < argc; i++)
+    {
+      const char *string = argv[i];
+
+      if (string[0] == '\0')
+       new_argv[i] = xstrdup ("\"\"");
+      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+       {
+         int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+         size_t length;
+         unsigned int backslashes;
+         const char *s;
+         char *quoted_string;
+         char *p;
+
+         length = 0;
+         backslashes = 0;
+         if (quote_around)
+           length++;
+         for (s = string; *s != '\0'; s++)
+           {
+             char c = *s;
+             if (c == '"')
+               length += backslashes + 1;
+             length++;
+             if (c == '\\')
+               backslashes++;
+             else
+               backslashes = 0;
+           }
+         if (quote_around)
+           length += backslashes + 1;
+
+         quoted_string = XMALLOC (char, length + 1);
+
+         p = quoted_string;
+         backslashes = 0;
+         if (quote_around)
+           *p++ = '"';
+         for (s = string; *s != '\0'; s++)
+           {
+             char c = *s;
+             if (c == '"')
+               {
+                 unsigned int j;
+                 for (j = backslashes + 1; j > 0; j--)
+                   *p++ = '\\';
+               }
+             *p++ = c;
+             if (c == '\\')
+               backslashes++;
+             else
+               backslashes = 0;
+           }
+         if (quote_around)
+           {
+             unsigned int j;
+             for (j = backslashes; j > 0; j--)
+               *p++ = '\\';
+             *p++ = '"';
+           }
+         *p = '\0';
+
+         new_argv[i] = quoted_string;
+       }
+      else
+       new_argv[i] = (char *) string;
+    }
+  new_argv[argc] = NULL;
+
+  return new_argv;
+}
+EOF
+               ;;
+           esac
+
+            cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+           func_emit_wrapper yes |
+             $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/  fputs ("\1", f);/p
+g
+D'
+            cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+    $opt_debug
+    case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+    *import*) : ;;
+    *) false ;;
+    esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+    $opt_debug
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args=$nonopt
+    base_compile="$nonopt $@"
+    compile_command=$nonopt
+    finalize_command=$nonopt
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+    new_inherited_linker_flags=
+
+    avoid_version=no
+    bindir=
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    non_pic_objects=
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+    weak_libs=
+    single_module="${wl}-single_module"
+    func_infer_tag $base_compile
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -shared)
+       test "$build_libtool_libs" != yes && \
+         func_fatal_configuration "can not build a shared library"
+       build_old_libs=no
+       break
+       ;;
+      -all-static | -static | -static-libtool-libs)
+       case $arg in
+       -all-static)
+         if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+           func_warning "complete static linking is impossible in this configuration"
+         fi
+         if test -n "$link_static_flag"; then
+           dlopen_self=$dlopen_self_static
+         fi
+         prefer_static_libs=yes
+         ;;
+       -static)
+         if test -z "$pic_flag" && test -n "$link_static_flag"; then
+           dlopen_self=$dlopen_self_static
+         fi
+         prefer_static_libs=built
+         ;;
+       -static-libtool-libs)
+         if test -z "$pic_flag" && test -n "$link_static_flag"; then
+           dlopen_self=$dlopen_self_static
+         fi
+         prefer_static_libs=yes
+         ;;
+       esac
+       build_libtool_libs=no
+       build_old_libs=yes
+       break
+       ;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg="$1"
+      shift
+      func_quote_for_eval "$arg"
+      qarg=$func_quote_for_eval_unquoted_result
+      func_append libtool_args " $func_quote_for_eval_result"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+       case $prev in
+       output)
+         func_append compile_command " @OUTPUT@"
+         func_append finalize_command " @OUTPUT@"
+         ;;
+       esac
+
+       case $prev in
+       bindir)
+         bindir="$arg"
+         prev=
+         continue
+         ;;
+       dlfiles|dlprefiles)
+         if test "$preload" = no; then
+           # Add the symbol object into the linking commands.
+           func_append compile_command " @SYMFILE@"
+           func_append finalize_command " @SYMFILE@"
+           preload=yes
+         fi
+         case $arg in
+         *.la | *.lo) ;;  # We handle these cases below.
+         force)
+           if test "$dlself" = no; then
+             dlself=needless
+             export_dynamic=yes
+           fi
+           prev=
+           continue
+           ;;
+         self)
+           if test "$prev" = dlprefiles; then
+             dlself=yes
+           elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+             dlself=yes
+           else
+             dlself=needless
+             export_dynamic=yes
+           fi
+           prev=
+           continue
+           ;;
+         *)
+           if test "$prev" = dlfiles; then
+             func_append dlfiles " $arg"
+           else
+             func_append dlprefiles " $arg"
+           fi
+           prev=
+           continue
+           ;;
+         esac
+         ;;
+       expsyms)
+         export_symbols="$arg"
+         test -f "$arg" \
+           || func_fatal_error "symbol file \`$arg' does not exist"
+         prev=
+         continue
+         ;;
+       expsyms_regex)
+         export_symbols_regex="$arg"
+         prev=
+         continue
+         ;;
+       framework)
+         case $host in
+           *-*-darwin*)
+             case "$deplibs " in
+               *" $qarg.ltframework "*) ;;
+               *) func_append deplibs " $qarg.ltframework" # this is fixed later
+                  ;;
+             esac
+             ;;
+         esac
+         prev=
+         continue
+         ;;
+       inst_prefix)
+         inst_prefix_dir="$arg"
+         prev=
+         continue
+         ;;
+       objectlist)
+         if test -f "$arg"; then
+           save_arg=$arg
+           moreargs=
+           for fil in `cat "$save_arg"`
+           do
+#            func_append moreargs " $fil"
+             arg=$fil
+             # A libtool-controlled object.
+
+             # Check to see that this really is a libtool object.
+             if func_lalib_unsafe_p "$arg"; then
+               pic_object=
+               non_pic_object=
+
+               # Read the .lo file
+               func_source "$arg"
+
+               if test -z "$pic_object" ||
+                  test -z "$non_pic_object" ||
+                  test "$pic_object" = none &&
+                  test "$non_pic_object" = none; then
+                 func_fatal_error "cannot find name of object for \`$arg'"
+               fi
+
+               # Extract subdirectory from the argument.
+               func_dirname "$arg" "/" ""
+               xdir="$func_dirname_result"
+
+               if test "$pic_object" != none; then
+                 # Prepend the subdirectory the object is found in.
+                 pic_object="$xdir$pic_object"
+
+                 if test "$prev" = dlfiles; then
+                   if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+                     func_append dlfiles " $pic_object"
+                     prev=
+                     continue
+                   else
+                     # If libtool objects are unsupported, then we need to preload.
+                     prev=dlprefiles
+                   fi
+                 fi
+
+                 # CHECK ME:  I think I busted this.  -Ossama
+                 if test "$prev" = dlprefiles; then
+                   # Preload the old-style object.
+                   func_append dlprefiles " $pic_object"
+                   prev=
+                 fi
+
+                 # A PIC object.
+                 func_append libobjs " $pic_object"
+                 arg="$pic_object"
+               fi
+
+               # Non-PIC object.
+               if test "$non_pic_object" != none; then
+                 # Prepend the subdirectory the object is found in.
+                 non_pic_object="$xdir$non_pic_object"
+
+                 # A standard non-PIC object
+                 func_append non_pic_objects " $non_pic_object"
+                 if test -z "$pic_object" || test "$pic_object" = none ; then
+                   arg="$non_pic_object"
+                 fi
+               else
+                 # If the PIC object exists, use it instead.
+                 # $xdir was prepended to $pic_object above.
+                 non_pic_object="$pic_object"
+                 func_append non_pic_objects " $non_pic_object"
+               fi
+             else
+               # Only an error if not doing a dry-run.
+               if $opt_dry_run; then
+                 # Extract subdirectory from the argument.
+                 func_dirname "$arg" "/" ""
+                 xdir="$func_dirname_result"
+
+                 func_lo2o "$arg"
+                 pic_object=$xdir$objdir/$func_lo2o_result
+                 non_pic_object=$xdir$func_lo2o_result
+                 func_append libobjs " $pic_object"
+                 func_append non_pic_objects " $non_pic_object"
+               else
+                 func_fatal_error "\`$arg' is not a valid libtool object"
+               fi
+             fi
+           done
+         else
+           func_fatal_error "link input file \`$arg' does not exist"
+         fi
+         arg=$save_arg
+         prev=
+         continue
+         ;;
+       precious_regex)
+         precious_files_regex="$arg"
+         prev=
+         continue
+         ;;
+       release)
+         release="-$arg"
+         prev=
+         continue
+         ;;
+       rpath | xrpath)
+         # We need an absolute path.
+         case $arg in
+         [\\/]* | [A-Za-z]:[\\/]*) ;;
+         *)
+           func_fatal_error "only absolute run-paths are allowed"
+           ;;
+         esac
+         if test "$prev" = rpath; then
+           case "$rpath " in
+           *" $arg "*) ;;
+           *) func_append rpath " $arg" ;;
+           esac
+         else
+           case "$xrpath " in
+           *" $arg "*) ;;
+           *) func_append xrpath " $arg" ;;
+           esac
+         fi
+         prev=
+         continue
+         ;;
+       shrext)
+         shrext_cmds="$arg"
+         prev=
+         continue
+         ;;
+       weak)
+         func_append weak_libs " $arg"
+         prev=
+         continue
+         ;;
+       xcclinker)
+         func_append linker_flags " $qarg"
+         func_append compiler_flags " $qarg"
+         prev=
+         func_append compile_command " $qarg"
+         func_append finalize_command " $qarg"
+         continue
+         ;;
+       xcompiler)
+         func_append compiler_flags " $qarg"
+         prev=
+         func_append compile_command " $qarg"
+         func_append finalize_command " $qarg"
+         continue
+         ;;
+       xlinker)
+         func_append linker_flags " $qarg"
+         func_append compiler_flags " $wl$qarg"
+         prev=
+         func_append compile_command " $wl$qarg"
+         func_append finalize_command " $wl$qarg"
+         continue
+         ;;
+       *)
+         eval "$prev=\"\$arg\""
+         prev=
+         continue
+         ;;
+       esac
+      fi # test -n "$prev"
+
+      prevarg="$arg"
+
+      case $arg in
+      -all-static)
+       if test -n "$link_static_flag"; then
+         # See comment for -static flag below, for more details.
+         func_append compile_command " $link_static_flag"
+         func_append finalize_command " $link_static_flag"
+       fi
+       continue
+       ;;
+
+      -allow-undefined)
+       # FIXME: remove this flag sometime in the future.
+       func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+       ;;
+
+      -avoid-version)
+       avoid_version=yes
+       continue
+       ;;
+
+      -bindir)
+       prev=bindir
+       continue
+       ;;
+
+      -dlopen)
+       prev=dlfiles
+       continue
+       ;;
+
+      -dlpreopen)
+       prev=dlprefiles
+       continue
+       ;;
+
+      -export-dynamic)
+       export_dynamic=yes
+       continue
+       ;;
+
+      -export-symbols | -export-symbols-regex)
+       if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+         func_fatal_error "more than one -exported-symbols argument is not allowed"
+       fi
+       if test "X$arg" = "X-export-symbols"; then
+         prev=expsyms
+       else
+         prev=expsyms_regex
+       fi
+       continue
+       ;;
+
+      -framework)
+       prev=framework
+       continue
+       ;;
+
+      -inst-prefix-dir)
+       prev=inst_prefix
+       continue
+       ;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+       case $with_gcc/$host in
+       no/*-*-irix* | /*-*-irix*)
+         func_append compile_command " $arg"
+         func_append finalize_command " $arg"
+         ;;
+       esac
+       continue
+       ;;
+
+      -L*)
+       func_stripname "-L" '' "$arg"
+       if test -z "$func_stripname_result"; then
+         if test "$#" -gt 0; then
+           func_fatal_error "require no space between \`-L' and \`$1'"
+         else
+           func_fatal_error "need path for \`-L' option"
+         fi
+       fi
+       func_resolve_sysroot "$func_stripname_result"
+       dir=$func_resolve_sysroot_result
+       # We need an absolute path.
+       case $dir in
+       [\\/]* | [A-Za-z]:[\\/]*) ;;
+       *)
+         absdir=`cd "$dir" && pwd`
+         test -z "$absdir" && \
+           func_fatal_error "cannot determine absolute directory name of \`$dir'"
+         dir="$absdir"
+         ;;
+       esac
+       case "$deplibs " in
+       *" -L$dir "* | *" $arg "*)
+         # Will only happen for absolute or sysroot arguments
+         ;;
+       *)
+         # Preserve sysroot, but never include relative directories
+         case $dir in
+           [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+           *) func_append deplibs " -L$dir" ;;
+         esac
+         func_append lib_search_path " $dir"
+         ;;
+       esac
+       case $host in
+       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+         testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+         case :$dllsearchpath: in
+         *":$dir:"*) ;;
+         ::) dllsearchpath=$dir;;
+         *) func_append dllsearchpath ":$dir";;
+         esac
+         case :$dllsearchpath: in
+         *":$testbindir:"*) ;;
+         ::) dllsearchpath=$testbindir;;
+         *) func_append dllsearchpath ":$testbindir";;
+         esac
+         ;;
+       esac
+       continue
+       ;;
+
+      -l*)
+       if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+         case $host in
+         *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+           # These systems don't actually have a C or math library (as such)
+           continue
+           ;;
+         *-*-os2*)
+           # These systems don't actually have a C library (as such)
+           test "X$arg" = "X-lc" && continue
+           ;;
+         *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+           # Do not include libc due to us having libc/libc_r.
+           test "X$arg" = "X-lc" && continue
+           ;;
+         *-*-rhapsody* | *-*-darwin1.[012])
+           # Rhapsody C and math libraries are in the System framework
+           func_append deplibs " System.ltframework"
+           continue
+           ;;
+         *-*-sco3.2v5* | *-*-sco5v6*)
+           # Causes problems with __ctype
+           test "X$arg" = "X-lc" && continue
+           ;;
+         *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+           # Compiler inserts libc in the correct place for threads to work
+           test "X$arg" = "X-lc" && continue
+           ;;
+         esac
+       elif test "X$arg" = "X-lc_r"; then
+        case $host in
+        *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+          # Do not include libc_r directly, use -pthread flag.
+          continue
+          ;;
+        esac
+       fi
+       func_append deplibs " $arg"
+       continue
+       ;;
+
+      -module)
+       module=yes
+       continue
+       ;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      # Darwin uses the -arch flag to determine output architecture.
+      -model|-arch|-isysroot|--sysroot)
+       func_append compiler_flags " $arg"
+       func_append compile_command " $arg"
+       func_append finalize_command " $arg"
+       prev=xcompiler
+       continue
+       ;;
+
+      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+      |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+       func_append compiler_flags " $arg"
+       func_append compile_command " $arg"
+       func_append finalize_command " $arg"
+       case "$new_inherited_linker_flags " in
+           *" $arg "*) ;;
+           * ) func_append new_inherited_linker_flags " $arg" ;;
+       esac
+       continue
+       ;;
+
+      -multi_module)
+       single_module="${wl}-multi_module"
+       continue
+       ;;
+
+      -no-fast-install)
+       fast_install=no
+       continue
+       ;;
+
+      -no-install)
+       case $host in
+       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+         # The PATH hackery in wrapper scripts is required on Windows
+         # and Darwin in order for the loader to find any dlls it needs.
+         func_warning "\`-no-install' is ignored for $host"
+         func_warning "assuming \`-no-fast-install' instead"
+         fast_install=no
+         ;;
+       *) no_install=yes ;;
+       esac
+       continue
+       ;;
+
+      -no-undefined)
+       allow_undefined=no
+       continue
+       ;;
+
+      -objectlist)
+       prev=objectlist
+       continue
+       ;;
+
+      -o) prev=output ;;
+
+      -precious-files-regex)
+       prev=precious_regex
+       continue
+       ;;
+
+      -release)
+       prev=release
+       continue
+       ;;
+
+      -rpath)
+       prev=rpath
+       continue
+       ;;
+
+      -R)
+       prev=xrpath
+       continue
+       ;;
+
+      -R*)
+       func_stripname '-R' '' "$arg"
+       dir=$func_stripname_result
+       # We need an absolute path.
+       case $dir in
+       [\\/]* | [A-Za-z]:[\\/]*) ;;
+       =*)
+         func_stripname '=' '' "$dir"
+         dir=$lt_sysroot$func_stripname_result
+         ;;
+       *)
+         func_fatal_error "only absolute run-paths are allowed"
+         ;;
+       esac
+       case "$xrpath " in
+       *" $dir "*) ;;
+       *) func_append xrpath " $dir" ;;
+       esac
+       continue
+       ;;
+
+      -shared)
+       # The effects of -shared are defined in a previous loop.
+       continue
+       ;;
+
+      -shrext)
+       prev=shrext
+       continue
+       ;;
+
+      -static | -static-libtool-libs)
+       # The effects of -static are defined in a previous loop.
+       # We used to do the same as -all-static on platforms that
+       # didn't have a PIC flag, but the assumption that the effects
+       # would be equivalent was wrong.  It would break on at least
+       # Digital Unix and AIX.
+       continue
+       ;;
+
+      -thread-safe)
+       thread_safe=yes
+       continue
+       ;;
+
+      -version-info)
+       prev=vinfo
+       continue
+       ;;
+
+      -version-number)
+       prev=vinfo
+       vinfo_number=yes
+       continue
+       ;;
+
+      -weak)
+        prev=weak
+       continue
+       ;;
+
+      -Wc,*)
+       func_stripname '-Wc,' '' "$arg"
+       args=$func_stripname_result
+       arg=
+       save_ifs="$IFS"; IFS=','
+       for flag in $args; do
+         IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+         func_append arg " $func_quote_for_eval_result"
+         func_append compiler_flags " $func_quote_for_eval_result"
+       done
+       IFS="$save_ifs"
+       func_stripname ' ' '' "$arg"
+       arg=$func_stripname_result
+       ;;
+
+      -Wl,*)
+       func_stripname '-Wl,' '' "$arg"
+       args=$func_stripname_result
+       arg=
+       save_ifs="$IFS"; IFS=','
+       for flag in $args; do
+         IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+         func_append arg " $wl$func_quote_for_eval_result"
+         func_append compiler_flags " $wl$func_quote_for_eval_result"
+         func_append linker_flags " $func_quote_for_eval_result"
+       done
+       IFS="$save_ifs"
+       func_stripname ' ' '' "$arg"
+       arg=$func_stripname_result
+       ;;
+
+      -Xcompiler)
+       prev=xcompiler
+       continue
+       ;;
+
+      -Xlinker)
+       prev=xlinker
+       continue
+       ;;
+
+      -XCClinker)
+       prev=xcclinker
+       continue
+       ;;
+
+      # -msg_* for osf cc
+      -msg_*)
+       func_quote_for_eval "$arg"
+       arg="$func_quote_for_eval_result"
+       ;;
+
+      # Flags to be passed through unchanged, with rationale:
+      # -64, -mips[0-9]      enable 64-bit mode for the SGI compiler
+      # -r[0-9][0-9]*        specify processor for the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+      # +DA*, +DD*           enable 64-bit mode for the HP compiler
+      # -q*                  compiler args for the IBM compiler
+      # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+      # -F/path              path to uninstalled frameworks, gcc on darwin
+      # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC
+      # @file                GCC response files
+      # -tp=*                Portland pgcc target processor selection
+      # --sysroot=*          for sysroot support
+      # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+      -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*|-flto*|-fwhopr*|-fuse-linker-plugin)
+        func_quote_for_eval "$arg"
+       arg="$func_quote_for_eval_result"
+        func_append compile_command " $arg"
+        func_append finalize_command " $arg"
+        func_append compiler_flags " $arg"
+        continue
+        ;;
+
+      # Some other compiler flag.
+      -* | +*)
+        func_quote_for_eval "$arg"
+       arg="$func_quote_for_eval_result"
+       ;;
+
+      *.$objext)
+       # A standard object.
+       func_append objs " $arg"
+       ;;
+
+      *.lo)
+       # A libtool-controlled object.
+
+       # Check to see that this really is a libtool object.
+       if func_lalib_unsafe_p "$arg"; then
+         pic_object=
+         non_pic_object=
+
+         # Read the .lo file
+         func_source "$arg"
+
+         if test -z "$pic_object" ||
+            test -z "$non_pic_object" ||
+            test "$pic_object" = none &&
+            test "$non_pic_object" = none; then
+           func_fatal_error "cannot find name of object for \`$arg'"
+         fi
+
+         # Extract subdirectory from the argument.
+         func_dirname "$arg" "/" ""
+         xdir="$func_dirname_result"
+
+         if test "$pic_object" != none; then
+           # Prepend the subdirectory the object is found in.
+           pic_object="$xdir$pic_object"
+
+           if test "$prev" = dlfiles; then
+             if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+               func_append dlfiles " $pic_object"
+               prev=
+               continue
+             else
+               # If libtool objects are unsupported, then we need to preload.
+               prev=dlprefiles
+             fi
+           fi
+
+           # CHECK ME:  I think I busted this.  -Ossama
+           if test "$prev" = dlprefiles; then
+             # Preload the old-style object.
+             func_append dlprefiles " $pic_object"
+             prev=
+           fi
+
+           # A PIC object.
+           func_append libobjs " $pic_object"
+           arg="$pic_object"
+         fi
+
+         # Non-PIC object.
+         if test "$non_pic_object" != none; then
+           # Prepend the subdirectory the object is found in.
+           non_pic_object="$xdir$non_pic_object"
+
+           # A standard non-PIC object
+           func_append non_pic_objects " $non_pic_object"
+           if test -z "$pic_object" || test "$pic_object" = none ; then
+             arg="$non_pic_object"
+           fi
+         else
+           # If the PIC object exists, use it instead.
+           # $xdir was prepended to $pic_object above.
+           non_pic_object="$pic_object"
+           func_append non_pic_objects " $non_pic_object"
+         fi
+       else
+         # Only an error if not doing a dry-run.
+         if $opt_dry_run; then
+           # Extract subdirectory from the argument.
+           func_dirname "$arg" "/" ""
+           xdir="$func_dirname_result"
+
+           func_lo2o "$arg"
+           pic_object=$xdir$objdir/$func_lo2o_result
+           non_pic_object=$xdir$func_lo2o_result
+           func_append libobjs " $pic_object"
+           func_append non_pic_objects " $non_pic_object"
+         else
+           func_fatal_error "\`$arg' is not a valid libtool object"
+         fi
+       fi
+       ;;
+
+      *.$libext)
+       # An archive.
+       func_append deplibs " $arg"
+       func_append old_deplibs " $arg"
+       continue
+       ;;
+
+      *.la)
+       # A libtool-controlled library.
+
+       func_resolve_sysroot "$arg"
+       if test "$prev" = dlfiles; then
+         # This library was specified with -dlopen.
+         func_append dlfiles " $func_resolve_sysroot_result"
+         prev=
+       elif test "$prev" = dlprefiles; then
+         # The library was specified with -dlpreopen.
+         func_append dlprefiles " $func_resolve_sysroot_result"
+         prev=
+       else
+         func_append deplibs " $func_resolve_sysroot_result"
+       fi
+       continue
+       ;;
+
+      # Some other compiler argument.
+      *)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       func_quote_for_eval "$arg"
+       arg="$func_quote_for_eval_result"
+       ;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+       func_append compile_command " $arg"
+       func_append finalize_command " $arg"
+      fi
+    done # argument parsing loop
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prevarg' option requires an argument"
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      func_append compile_command " $arg"
+      func_append finalize_command " $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    func_basename "$output"
+    outputname="$func_basename_result"
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    func_dirname "$output" "/" ""
+    output_objdir="$func_dirname_result$objdir"
+    func_to_tool_file "$output_objdir/"
+    tool_output_objdir=$func_to_tool_file_result
+    # Create the object directory.
+    func_mkdir_p "$output_objdir"
+
+    # Determine the type of output
+    case $output in
+    "")
+      func_fatal_help "you must specify an output file"
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if $opt_preserve_dup_deps ; then
+       case "$libs " in
+       *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+       esac
+      fi
+      func_append libs " $deplib"
+    done
+
+    if test "$linkmode" = lib; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if $opt_duplicate_compiler_generated_deps; then
+       for pre_post_dep in $predeps $postdeps; do
+         case "$pre_post_deps " in
+         *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+         esac
+         func_append pre_post_deps " $pre_post_dep"
+       done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    notinst_path= # paths that contain not-installed libtool libraries
+
+    case $linkmode in
+    lib)
+       passes="conv dlpreopen link"
+       for file in $dlfiles $dlprefiles; do
+         case $file in
+         *.la) ;;
+         *)
+           func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+           ;;
+         esac
+       done
+       ;;
+    prog)
+       compile_deplibs=
+       finalize_deplibs=
+       alldeplibs=no
+       newdlfiles=
+       newdlprefiles=
+       passes="conv scan dlopen dlpreopen link"
+       ;;
+    *)  passes="conv"
+       ;;
+    esac
+
+    for pass in $passes; do
+      # The preopen pass in lib mode reverses $deplibs; put it back here
+      # so that -L comes before libs that need it for instance...
+      if test "$linkmode,$pass" = "lib,link"; then
+       ## FIXME: Find the place where the list is rebuilt in the wrong
+       ##        order, and fix it there properly
+        tmp_deplibs=
+       for deplib in $deplibs; do
+         tmp_deplibs="$deplib $tmp_deplibs"
+       done
+       deplibs="$tmp_deplibs"
+      fi
+
+      if test "$linkmode,$pass" = "lib,link" ||
+        test "$linkmode,$pass" = "prog,scan"; then
+       libs="$deplibs"
+       deplibs=
+      fi
+      if test "$linkmode" = prog; then
+       case $pass in
+       dlopen) libs="$dlfiles" ;;
+       dlpreopen) libs="$dlprefiles" ;;
+       link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+       esac
+      fi
+      if test "$linkmode,$pass" = "lib,dlpreopen"; then
+       # Collect and forward deplibs of preopened libtool libs
+       for lib in $dlprefiles; do
+         # Ignore non-libtool-libs
+         dependency_libs=
+         func_resolve_sysroot "$lib"
+         case $lib in
+         *.la) func_source "$func_resolve_sysroot_result" ;;
+         esac
+
+         # Collect preopened libtool deplibs, except any this library
+         # has declared as weak libs
+         for deplib in $dependency_libs; do
+           func_basename "$deplib"
+            deplib_base=$func_basename_result
+           case " $weak_libs " in
+           *" $deplib_base "*) ;;
+           *) func_append deplibs " $deplib" ;;
+           esac
+         done
+       done
+       libs="$dlprefiles"
+      fi
+      if test "$pass" = dlopen; then
+       # Collect dlpreopened libraries
+       save_deplibs="$deplibs"
+       deplibs=
+      fi
+
+      for deplib in $libs; do
+       lib=
+       found=no
+       case $deplib in
+       -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+        |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+         if test "$linkmode,$pass" = "prog,link"; then
+           compile_deplibs="$deplib $compile_deplibs"
+           finalize_deplibs="$deplib $finalize_deplibs"
+         else
+           func_append compiler_flags " $deplib"
+           if test "$linkmode" = lib ; then
+               case "$new_inherited_linker_flags " in
+                   *" $deplib "*) ;;
+                   * ) func_append new_inherited_linker_flags " $deplib" ;;
+               esac
+           fi
+         fi
+         continue
+         ;;
+       -l*)
+         if test "$linkmode" != lib && test "$linkmode" != prog; then
+           func_warning "\`-l' is ignored for archives/objects"
+           continue
+         fi
+         func_stripname '-l' '' "$deplib"
+         name=$func_stripname_result
+         if test "$linkmode" = lib; then
+           searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+         else
+           searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+         fi
+         for searchdir in $searchdirs; do
+           for search_ext in .la $std_shrext .so .a; do
+             # Search the libtool library
+             lib="$searchdir/lib${name}${search_ext}"
+             if test -f "$lib"; then
+               if test "$search_ext" = ".la"; then
+                 found=yes
+               else
+                 found=no
+               fi
+               break 2
+             fi
+           done
+         done
+         if test "$found" != yes; then
+           # deplib doesn't seem to be a libtool library
+           if test "$linkmode,$pass" = "prog,link"; then
+             compile_deplibs="$deplib $compile_deplibs"
+             finalize_deplibs="$deplib $finalize_deplibs"
+           else
+             deplibs="$deplib $deplibs"
+             test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+           fi
+           continue
+         else # deplib is a libtool library
+           # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+           # We need to do some special things here, and not later.
+           if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+             case " $predeps $postdeps " in
+             *" $deplib "*)
+               if func_lalib_p "$lib"; then
+                 library_names=
+                 old_library=
+                 func_source "$lib"
+                 for l in $old_library $library_names; do
+                   ll="$l"
+                 done
+                 if test "X$ll" = "X$old_library" ; then # only static version available
+                   found=no
+                   func_dirname "$lib" "" "."
+                   ladir="$func_dirname_result"
+                   lib=$ladir/$old_library
+                   if test "$linkmode,$pass" = "prog,link"; then
+                     compile_deplibs="$deplib $compile_deplibs"
+                     finalize_deplibs="$deplib $finalize_deplibs"
+                   else
+                     deplibs="$deplib $deplibs"
+                     test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+                   fi
+                   continue
+                 fi
+               fi
+               ;;
+             *) ;;
+             esac
+           fi
+         fi
+         ;; # -l
+       *.ltframework)
+         if test "$linkmode,$pass" = "prog,link"; then
+           compile_deplibs="$deplib $compile_deplibs"
+           finalize_deplibs="$deplib $finalize_deplibs"
+         else
+           deplibs="$deplib $deplibs"
+           if test "$linkmode" = lib ; then
+               case "$new_inherited_linker_flags " in
+                   *" $deplib "*) ;;
+                   * ) func_append new_inherited_linker_flags " $deplib" ;;
+               esac
+           fi
+         fi
+         continue
+         ;;
+       -L*)
+         case $linkmode in
+         lib)
+           deplibs="$deplib $deplibs"
+           test "$pass" = conv && continue
+           newdependency_libs="$deplib $newdependency_libs"
+           func_stripname '-L' '' "$deplib"
+           func_resolve_sysroot "$func_stripname_result"
+           func_append newlib_search_path " $func_resolve_sysroot_result"
+           ;;
+         prog)
+           if test "$pass" = conv; then
+             deplibs="$deplib $deplibs"
+             continue
+           fi
+           if test "$pass" = scan; then
+             deplibs="$deplib $deplibs"
+           else
+             compile_deplibs="$deplib $compile_deplibs"
+             finalize_deplibs="$deplib $finalize_deplibs"
+           fi
+           func_stripname '-L' '' "$deplib"
+           func_resolve_sysroot "$func_stripname_result"
+           func_append newlib_search_path " $func_resolve_sysroot_result"
+           ;;
+         *)
+           func_warning "\`-L' is ignored for archives/objects"
+           ;;
+         esac # linkmode
+         continue
+         ;; # -L
+       -R*)
+         if test "$pass" = link; then
+           func_stripname '-R' '' "$deplib"
+           func_resolve_sysroot "$func_stripname_result"
+           dir=$func_resolve_sysroot_result
+           # Make sure the xrpath contains only unique directories.
+           case "$xrpath " in
+           *" $dir "*) ;;
+           *) func_append xrpath " $dir" ;;
+           esac
+         fi
+         deplibs="$deplib $deplibs"
+         continue
+         ;;
+       *.la)
+         func_resolve_sysroot "$deplib"
+         lib=$func_resolve_sysroot_result
+         ;;
+       *.$libext)
+         if test "$pass" = conv; then
+           deplibs="$deplib $deplibs"
+           continue
+         fi
+         case $linkmode in
+         lib)
+           # Linking convenience modules into shared libraries is allowed,
+           # but linking other static libraries is non-portable.
+           case " $dlpreconveniencelibs " in
+           *" $deplib "*) ;;
+           *)
+             valid_a_lib=no
+             case $deplibs_check_method in
+               match_pattern*)
+                 set dummy $deplibs_check_method; shift
+                 match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+                 if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+                   | $EGREP "$match_pattern_regex" > /dev/null; then
+                   valid_a_lib=yes
+                 fi
+               ;;
+               pass_all)
+                 valid_a_lib=yes
+               ;;
+             esac
+             if test "$valid_a_lib" != yes; then
+               echo
+               $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+               echo "*** I have the capability to make that library automatically link in when"
+               echo "*** you link to this library.  But I can only do this if you have a"
+               echo "*** shared version of the library, which you do not appear to have"
+               echo "*** because the file extensions .$libext of this argument makes me believe"
+               echo "*** that it is just a static archive that I should not use here."
+             else
+               echo
+               $ECHO "*** Warning: Linking the shared library $output against the"
+               $ECHO "*** static library $deplib is not portable!"
+               deplibs="$deplib $deplibs"
+             fi
+             ;;
+           esac
+           continue
+           ;;
+         prog)
+           if test "$pass" != link; then
+             deplibs="$deplib $deplibs"
+           else
+             compile_deplibs="$deplib $compile_deplibs"
+             finalize_deplibs="$deplib $finalize_deplibs"
+           fi
+           continue
+           ;;
+         esac # linkmode
+         ;; # *.$libext
+       *.lo | *.$objext)
+         if test "$pass" = conv; then
+           deplibs="$deplib $deplibs"
+         elif test "$linkmode" = prog; then
+           if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+             # If there is no dlopen support or we're linking statically,
+             # we need to preload.
+             func_append newdlprefiles " $deplib"
+             compile_deplibs="$deplib $compile_deplibs"
+             finalize_deplibs="$deplib $finalize_deplibs"
+           else
+             func_append newdlfiles " $deplib"
+           fi
+         fi
+         continue
+         ;;
+       %DEPLIBS%)
+         alldeplibs=yes
+         continue
+         ;;
+       esac # case $deplib
+
+       if test "$found" = yes || test -f "$lib"; then :
+       else
+         func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+       fi
+
+       # Check to see that this really is a libtool archive.
+       func_lalib_unsafe_p "$lib" \
+         || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+       func_dirname "$lib" "" "."
+       ladir="$func_dirname_result"
+
+       dlname=
+       dlopen=
+       dlpreopen=
+       libdir=
+       library_names=
+       old_library=
+       inherited_linker_flags=
+       # If the library was installed with an old release of libtool,
+       # it will not redefine variables installed, or shouldnotlink
+       installed=yes
+       shouldnotlink=no
+       avoidtemprpath=
+
+
+       # Read the .la file
+       func_source "$lib"
+
+       # Convert "-framework foo" to "foo.ltframework"
+       if test -n "$inherited_linker_flags"; then
+         tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+         for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+           case " $new_inherited_linker_flags " in
+             *" $tmp_inherited_linker_flag "*) ;;
+             *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+           esac
+         done
+       fi
+       dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+       if test "$linkmode,$pass" = "lib,link" ||
+          test "$linkmode,$pass" = "prog,scan" ||
+          { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+         test -n "$dlopen" && func_append dlfiles " $dlopen"
+         test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+       fi
+
+       if test "$pass" = conv; then
+         # Only check for convenience libraries
+         deplibs="$lib $deplibs"
+         if test -z "$libdir"; then
+           if test -z "$old_library"; then
+             func_fatal_error "cannot find name of link library for \`$lib'"
+           fi
+           # 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"
+         elif test "$linkmode" != prog && test "$linkmode" != lib; 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
+
+
+       # Get the name of the library we link against.
+       linklib=
+       if test -n "$old_library" &&
+          { test "$prefer_static_libs" = yes ||
+            test "$prefer_static_libs,$installed" = "built,no"; }; then
+         linklib=$old_library
+       else
+         for l in $old_library $library_names; do
+           linklib="$l"
+         done
+       fi
+       if test -z "$linklib"; then
+         func_fatal_error "cannot find name of link library for \`$lib'"
+       fi
+
+       # This library was specified with -dlopen.
+       if test "$pass" = dlopen; then
+         if test -z "$libdir"; then
+           func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+         fi
+         if test -z "$dlname" ||
+            test "$dlopen_support" != yes ||
+            test "$build_libtool_libs" = no; then
+           # If there is no dlname, no dlopen support or we're linking
+           # statically, we need to preload.  We also need to preload any
+           # dependent libraries so libltdl's deplib preloader doesn't
+           # bomb out in the load deplibs phase.
+           func_append dlprefiles " $lib $dependency_libs"
+         else
+           func_append newdlfiles " $lib"
+         fi
+         continue
+       fi # $pass = dlopen
+
+       # We need an absolute path.
+       case $ladir in
+       [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+       *)
+         abs_ladir=`cd "$ladir" && pwd`
+         if test -z "$abs_ladir"; then
+           func_warning "cannot determine absolute directory name of \`$ladir'"
+           func_warning "passing it literally to the linker, although it might fail"
+           abs_ladir="$ladir"
+         fi
+         ;;
+       esac
+       func_basename "$lib"
+       laname="$func_basename_result"
+
+       # Find the relevant object directory and library name.
+       if test "X$installed" = Xyes; then
+         if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+           func_warning "library \`$lib' was moved."
+           dir="$ladir"
+           absdir="$abs_ladir"
+           libdir="$abs_ladir"
+         else
+           dir="$lt_sysroot$libdir"
+           absdir="$lt_sysroot$libdir"
+         fi
+         test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+       else
+         if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+           dir="$ladir"
+           absdir="$abs_ladir"
+           # Remove this search path later
+           func_append notinst_path " $abs_ladir"
+         else
+           dir="$ladir/$objdir"
+           absdir="$abs_ladir/$objdir"
+           # Remove this search path later
+           func_append notinst_path " $abs_ladir"
+         fi
+       fi # $installed = yes
+       func_stripname 'lib' '.la' "$laname"
+       name=$func_stripname_result
+
+       # This library was specified with -dlpreopen.
+       if test "$pass" = dlpreopen; then
+         if test -z "$libdir" && test "$linkmode" = prog; then
+           func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+         fi
+         case "$host" in
+           # special handling for platforms with PE-DLLs.
+           *cygwin* | *mingw* | *cegcc* )
+             # Linker will automatically link against shared library if both
+             # static and shared are present.  Therefore, ensure we extract
+             # symbols from the import library if a shared library is present
+             # (otherwise, the dlopen module name will be incorrect).  We do
+             # this by putting the import library name into $newdlprefiles.
+             # We recover the dlopen module name by 'saving' the la file
+             # name in a special purpose variable, and (later) extracting the
+             # dlname from the la file.
+             if test -n "$dlname"; then
+               func_tr_sh "$dir/$linklib"
+               eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+               func_append newdlprefiles " $dir/$linklib"
+             else
+               func_append newdlprefiles " $dir/$old_library"
+               # Keep a list of preopened convenience libraries to check
+               # that they are being used correctly in the link pass.
+               test -z "$libdir" && \
+                 func_append dlpreconveniencelibs " $dir/$old_library"
+             fi
+           ;;
+           * )
+             # Prefer using a static library (so that no silly _DYNAMIC symbols
+             # are required to link).
+             if test -n "$old_library"; then
+               func_append newdlprefiles " $dir/$old_library"
+               # Keep a list of preopened convenience libraries to check
+               # that they are being used correctly in the link pass.
+               test -z "$libdir" && \
+                 func_append dlpreconveniencelibs " $dir/$old_library"
+             # Otherwise, use the dlname, so that lt_dlopen finds it.
+             elif test -n "$dlname"; then
+               func_append newdlprefiles " $dir/$dlname"
+             else
+               func_append newdlprefiles " $dir/$linklib"
+             fi
+           ;;
+         esac
+       fi # $pass = dlpreopen
+
+       if test -z "$libdir"; then
+         # Link the convenience library
+         if test "$linkmode" = lib; then
+           deplibs="$dir/$old_library $deplibs"
+         elif test "$linkmode,$pass" = "prog,link"; then
+           compile_deplibs="$dir/$old_library $compile_deplibs"
+           finalize_deplibs="$dir/$old_library $finalize_deplibs"
+         else
+           deplibs="$lib $deplibs" # used for prog,scan pass
+         fi
+         continue
+       fi
+
+
+       if test "$linkmode" = prog && test "$pass" != link; then
+         func_append newlib_search_path " $ladir"
+         deplibs="$lib $deplibs"
+
+         linkalldeplibs=no
+         if test "$link_all_deplibs" != no || test -z "$library_names" ||
+            test "$build_libtool_libs" = no; then
+           linkalldeplibs=yes
+         fi
+
+         tmp_libs=
+         for deplib in $dependency_libs; do
+           case $deplib in
+           -L*) func_stripname '-L' '' "$deplib"
+                func_resolve_sysroot "$func_stripname_result"
+                func_append newlib_search_path " $func_resolve_sysroot_result"
+                ;;
+           esac
+           # Need to link against all dependency_libs?
+           if test "$linkalldeplibs" = yes; then
+             deplibs="$deplib $deplibs"
+           else
+             # Need to hardcode shared library paths
+             # or/and link against static libraries
+             newdependency_libs="$deplib $newdependency_libs"
+           fi
+           if $opt_preserve_dup_deps ; then
+             case "$tmp_libs " in
+             *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+             esac
+           fi
+           func_append tmp_libs " $deplib"
+         done # for deplib
+         continue
+       fi # $linkmode = prog...
+
+       if test "$linkmode,$pass" = "prog,link"; then
+         if test -n "$library_names" &&
+            { { test "$prefer_static_libs" = no ||
+                test "$prefer_static_libs,$installed" = "built,yes"; } ||
+              test -z "$old_library"; }; then
+           # We need to hardcode the library path
+           if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+             # Make sure the rpath contains only unique directories.
+             case "$temp_rpath:" in
+             *"$absdir:"*) ;;
+             *) func_append temp_rpath "$absdir:" ;;
+             esac
+           fi
+
+           # Hardcode the library path.
+           # Skip directories that are in the system default run-time
+           # search path.
+           case " $sys_lib_dlsearch_path " in
+           *" $absdir "*) ;;
+           *)
+             case "$compile_rpath " in
+             *" $absdir "*) ;;
+             *) func_append compile_rpath " $absdir" ;;
+             esac
+             ;;
+           esac
+           case " $sys_lib_dlsearch_path " in
+           *" $libdir "*) ;;
+           *)
+             case "$finalize_rpath " in
+             *" $libdir "*) ;;
+             *) func_append finalize_rpath " $libdir" ;;
+             esac
+             ;;
+           esac
+         fi # $linkmode,$pass = prog,link...
+
+         if test "$alldeplibs" = yes &&
+            { test "$deplibs_check_method" = pass_all ||
+              { test "$build_libtool_libs" = yes &&
+                test -n "$library_names"; }; }; then
+           # We only need to search for static libraries
+           continue
+         fi
+       fi
+
+       link_static=no # Whether the deplib will be linked statically
+       use_static_libs=$prefer_static_libs
+       if test "$use_static_libs" = built && test "$installed" = yes; then
+         use_static_libs=no
+       fi
+       if test -n "$library_names" &&
+          { test "$use_static_libs" = no || test -z "$old_library"; }; then
+         case $host in
+         *cygwin* | *mingw* | *cegcc*)
+             # No point in relinking DLLs because paths are not encoded
+             func_append notinst_deplibs " $lib"
+             need_relink=no
+           ;;
+         *)
+           if test "$installed" = no; then
+             func_append notinst_deplibs " $lib"
+             need_relink=yes
+           fi
+           ;;
+         esac
+         # This is a shared library
+
+         # Warn about portability, can't link against -module's on some
+         # systems (darwin).  Don't bleat about dlopened modules though!
+         dlopenmodule=""
+         for dlpremoduletest in $dlprefiles; do
+           if test "X$dlpremoduletest" = "X$lib"; then
+             dlopenmodule="$dlpremoduletest"
+             break
+           fi
+         done
+         if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+           echo
+           if test "$linkmode" = prog; then
+             $ECHO "*** Warning: Linking the executable $output against the loadable module"
+           else
+             $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+           fi
+           $ECHO "*** $linklib is not portable!"
+         fi
+         if test "$linkmode" = lib &&
+            test "$hardcode_into_libs" = yes; then
+           # Hardcode the library path.
+           # Skip directories that are in the system default run-time
+           # search path.
+           case " $sys_lib_dlsearch_path " in
+           *" $absdir "*) ;;
+           *)
+             case "$compile_rpath " in
+             *" $absdir "*) ;;
+             *) func_append compile_rpath " $absdir" ;;
+             esac
+             ;;
+           esac
+           case " $sys_lib_dlsearch_path " in
+           *" $libdir "*) ;;
+           *)
+             case "$finalize_rpath " in
+             *" $libdir "*) ;;
+             *) func_append finalize_rpath " $libdir" ;;
+             esac
+             ;;
+           esac
+         fi
+
+         if test -n "$old_archive_from_expsyms_cmds"; then
+           # figure out the soname
+           set dummy $library_names
+           shift
+           realname="$1"
+           shift
+           libname=`eval "\\$ECHO \"$libname_spec\""`
+           # use dlname if we got it. it's perfectly good, no?
+           if test -n "$dlname"; then
+             soname="$dlname"
+           elif test -n "$soname_spec"; then
+             # bleh windows
+             case $host in
+             *cygwin* | mingw* | *cegcc*)
+               func_arith $current - $age
+               major=$func_arith_result
+               versuffix="-$major"
+               ;;
+             esac
+             eval soname=\"$soname_spec\"
+           else
+             soname="$realname"
+           fi
+
+           # Make a new name for the extract_expsyms_cmds to use
+           soroot="$soname"
+           func_basename "$soroot"
+           soname="$func_basename_result"
+           func_stripname 'lib' '.dll' "$soname"
+           newlib=libimp-$func_stripname_result.a
+
+           # If the library has no export list, then create one now
+           if test -f "$output_objdir/$soname-def"; then :
+           else
+             func_verbose "extracting exported symbol list from \`$soname'"
+             func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+           fi
+
+           # Create $newlib
+           if test -f "$output_objdir/$newlib"; then :; else
+             func_verbose "generating import library for \`$soname'"
+             func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+           fi
+           # make sure the library variables are pointing to the new library
+           dir=$output_objdir
+           linklib=$newlib
+         fi # test -n "$old_archive_from_expsyms_cmds"
+
+         if test "$linkmode" = prog || test "$opt_mode" != relink; then
+           add_shlibpath=
+           add_dir=
+           add=
+           lib_linked=yes
+           case $hardcode_action in
+           immediate | unsupported)
+             if test "$hardcode_direct" = no; then
+               add="$dir/$linklib"
+               case $host in
+                 *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+                 *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+                 *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+                   *-*-unixware7*) add_dir="-L$dir" ;;
+                 *-*-darwin* )
+                   # if the lib is a (non-dlopened) module then we can not
+                   # link against it, someone is ignoring the earlier warnings
+                   if /usr/bin/file -L $add 2> /dev/null |
+                        $GREP ": [^:]* bundle" >/dev/null ; then
+                     if test "X$dlopenmodule" != "X$lib"; then
+                       $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+                       if test -z "$old_library" ; then
+                         echo
+                         echo "*** And there doesn't seem to be a static archive available"
+                         echo "*** The link will probably fail, sorry"
+                       else
+                         add="$dir/$old_library"
+                       fi
+                     elif test -n "$old_library"; then
+                       add="$dir/$old_library"
+                     fi
+                   fi
+               esac
+             elif test "$hardcode_minus_L" = no; then
+               case $host in
+               *-*-sunos*) add_shlibpath="$dir" ;;
+               esac
+               add_dir="-L$dir"
+               add="-l$name"
+             elif test "$hardcode_shlibpath_var" = no; then
+               add_shlibpath="$dir"
+               add="-l$name"
+             else
+               lib_linked=no
+             fi
+             ;;
+           relink)
+             if test "$hardcode_direct" = yes &&
+                test "$hardcode_direct_absolute" = no; then
+               add="$dir/$linklib"
+             elif test "$hardcode_minus_L" = yes; then
+               add_dir="-L$absdir"
+               # Try looking first in the location we're being installed to.
+               if test -n "$inst_prefix_dir"; then
+                 case $libdir in
+                   [\\/]*)
+                     func_append add_dir " -L$inst_prefix_dir$libdir"
+                     ;;
+                 esac
+               fi
+               add="-l$name"
+             elif test "$hardcode_shlibpath_var" = yes; then
+               add_shlibpath="$dir"
+               add="-l$name"
+             else
+               lib_linked=no
+             fi
+             ;;
+           *) lib_linked=no ;;
+           esac
+
+           if test "$lib_linked" != yes; then
+             func_fatal_configuration "unsupported hardcode properties"
+           fi
+
+           if test -n "$add_shlibpath"; then
+             case :$compile_shlibpath: in
+             *":$add_shlibpath:"*) ;;
+             *) func_append compile_shlibpath "$add_shlibpath:" ;;
+             esac
+           fi
+           if test "$linkmode" = prog; then
+             test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+             test -n "$add" && compile_deplibs="$add $compile_deplibs"
+           else
+             test -n "$add_dir" && deplibs="$add_dir $deplibs"
+             test -n "$add" && deplibs="$add $deplibs"
+             if test "$hardcode_direct" != yes &&
+                test "$hardcode_minus_L" != yes &&
+                test "$hardcode_shlibpath_var" = yes; then
+               case :$finalize_shlibpath: in
+               *":$libdir:"*) ;;
+               *) func_append finalize_shlibpath "$libdir:" ;;
+               esac
+             fi
+           fi
+         fi
+
+         if test "$linkmode" = prog || test "$opt_mode" = relink; then
+           add_shlibpath=
+           add_dir=
+           add=
+           # Finalize command for both is simple: just hardcode it.
+           if test "$hardcode_direct" = yes &&
+              test "$hardcode_direct_absolute" = no; then
+             add="$libdir/$linklib"
+           elif test "$hardcode_minus_L" = yes; then
+             add_dir="-L$libdir"
+             add="-l$name"
+           elif test "$hardcode_shlibpath_var" = yes; then
+             case :$finalize_shlibpath: in
+             *":$libdir:"*) ;;
+             *) func_append finalize_shlibpath "$libdir:" ;;
+             esac
+             add="-l$name"
+           elif test "$hardcode_automatic" = yes; then
+             if test -n "$inst_prefix_dir" &&
+                test -f "$inst_prefix_dir$libdir/$linklib" ; then
+               add="$inst_prefix_dir$libdir/$linklib"
+             else
+               add="$libdir/$linklib"
+             fi
+           else
+             # We cannot seem to hardcode it, guess we'll fake it.
+             add_dir="-L$libdir"
+             # Try looking first in the location we're being installed to.
+             if test -n "$inst_prefix_dir"; then
+               case $libdir in
+                 [\\/]*)
+                   func_append add_dir " -L$inst_prefix_dir$libdir"
+                   ;;
+               esac
+             fi
+             add="-l$name"
+           fi
+
+           if test "$linkmode" = prog; then
+             test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+             test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+           else
+             test -n "$add_dir" && deplibs="$add_dir $deplibs"
+             test -n "$add" && deplibs="$add $deplibs"
+           fi
+         fi
+       elif test "$linkmode" = prog; then
+         # Here we assume that one of hardcode_direct or hardcode_minus_L
+         # is not unsupported.  This is valid on all known static and
+         # shared platforms.
+         if test "$hardcode_direct" != unsupported; then
+           test -n "$old_library" && linklib="$old_library"
+           compile_deplibs="$dir/$linklib $compile_deplibs"
+           finalize_deplibs="$dir/$linklib $finalize_deplibs"
+         else
+           compile_deplibs="-l$name -L$dir $compile_deplibs"
+           finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+         fi
+       elif test "$build_libtool_libs" = yes; then
+         # Not a shared library
+         if test "$deplibs_check_method" != pass_all; then
+           # We're trying link a shared library against a static one
+           # but the system doesn't support it.
+
+           # Just print a warning and add the library to dependency_libs so
+           # that the program can be linked against the static library.
+           echo
+           $ECHO "*** Warning: This system can not link to static lib archive $lib."
+           echo "*** I have the capability to make that library automatically link in when"
+           echo "*** you link to this library.  But I can only do this if you have a"
+           echo "*** shared version of the library, which you do not appear to have."
+           if test "$module" = yes; then
+             echo "*** But as you try to build a module library, libtool will still create "
+             echo "*** a static module, that should work as long as the dlopening application"
+             echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+             if test -z "$global_symbol_pipe"; then
+               echo
+               echo "*** However, this would only work if libtool was able to extract symbol"
+               echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+               echo "*** not find such a program.  So, this module is probably useless."
+               echo "*** \`nm' from GNU binutils and a full rebuild may help."
+             fi
+             if test "$build_old_libs" = no; then
+               build_libtool_libs=module
+               build_old_libs=yes
+             else
+               build_libtool_libs=no
+             fi
+           fi
+         else
+           deplibs="$dir/$old_library $deplibs"
+           link_static=yes
+         fi
+       fi # link shared/static library?
+
+       if test "$linkmode" = lib; then
+         if test -n "$dependency_libs" &&
+            { test "$hardcode_into_libs" != yes ||
+              test "$build_old_libs" = yes ||
+              test "$link_static" = yes; }; then
+           # Extract -R from dependency_libs
+           temp_deplibs=
+           for libdir in $dependency_libs; do
+             case $libdir in
+             -R*) func_stripname '-R' '' "$libdir"
+                  temp_xrpath=$func_stripname_result
+                  case " $xrpath " in
+                  *" $temp_xrpath "*) ;;
+                  *) func_append xrpath " $temp_xrpath";;
+                  esac;;
+             *) func_append temp_deplibs " $libdir";;
+             esac
+           done
+           dependency_libs="$temp_deplibs"
+         fi
+
+         func_append newlib_search_path " $absdir"
+         # Link against this library
+         test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+         # ... and its dependency_libs
+         tmp_libs=
+         for deplib in $dependency_libs; do
+           newdependency_libs="$deplib $newdependency_libs"
+           case $deplib in
+              -L*) func_stripname '-L' '' "$deplib"
+                   func_resolve_sysroot "$func_stripname_result";;
+              *) func_resolve_sysroot "$deplib" ;;
+            esac
+           if $opt_preserve_dup_deps ; then
+             case "$tmp_libs " in
+             *" $func_resolve_sysroot_result "*)
+                func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+             esac
+           fi
+           func_append tmp_libs " $func_resolve_sysroot_result"
+         done
+
+         if test "$link_all_deplibs" != no; then
+           # Add the search paths of all dependency libraries
+           for deplib in $dependency_libs; do
+             path=
+             case $deplib in
+             -L*) path="$deplib" ;;
+             *.la)
+               func_resolve_sysroot "$deplib"
+               deplib=$func_resolve_sysroot_result
+               func_dirname "$deplib" "" "."
+               dir=$func_dirname_result
+               # We need an absolute path.
+               case $dir in
+               [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+               *)
+                 absdir=`cd "$dir" && pwd`
+                 if test -z "$absdir"; then
+                   func_warning "cannot determine absolute directory name of \`$dir'"
+                   absdir="$dir"
+                 fi
+                 ;;
+               esac
+               if $GREP "^installed=no" $deplib > /dev/null; then
+               case $host in
+               *-*-darwin*)
+                 depdepl=
+                 eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+                 if test -n "$deplibrary_names" ; then
+                   for tmp in $deplibrary_names ; do
+                     depdepl=$tmp
+                   done
+                   if test -f "$absdir/$objdir/$depdepl" ; then
+                     depdepl="$absdir/$objdir/$depdepl"
+                     darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+                      if test -z "$darwin_install_name"; then
+                          darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
+                      fi
+                     func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+                     func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
+                     path=
+                   fi
+                 fi
+                 ;;
+               *)
+                 path="-L$absdir/$objdir"
+                 ;;
+               esac
+               else
+                 eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+                 test -z "$libdir" && \
+                   func_fatal_error "\`$deplib' is not a valid libtool archive"
+                 test "$absdir" != "$libdir" && \
+                   func_warning "\`$deplib' seems to be moved"
+
+                 path="-L$absdir"
+               fi
+               ;;
+             esac
+             case " $deplibs " in
+             *" $path "*) ;;
+             *) deplibs="$path $deplibs" ;;
+             esac
+           done
+         fi # link_all_deplibs != no
+       fi # linkmode = lib
+      done # for deplib in $libs
+      if test "$pass" = link; then
+       if test "$linkmode" = "prog"; then
+         compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+         finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+       else
+         compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+       fi
+      fi
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
+       # Link the dlpreopened libraries before other libraries
+       for deplib in $save_deplibs; do
+         deplibs="$deplib $deplibs"
+       done
+      fi
+      if test "$pass" != dlopen; then
+       if test "$pass" != conv; then
+         # Make sure lib_search_path contains only unique directories.
+         lib_search_path=
+         for dir in $newlib_search_path; do
+           case "$lib_search_path " in
+           *" $dir "*) ;;
+           *) func_append lib_search_path " $dir" ;;
+           esac
+         done
+         newlib_search_path=
+       fi
+
+       if test "$linkmode,$pass" != "prog,link"; then
+         vars="deplibs"
+       else
+         vars="compile_deplibs finalize_deplibs"
+       fi
+       for var in $vars dependency_libs; do
+         # Add libraries to $var in reverse order
+         eval tmp_libs=\"\$$var\"
+         new_libs=
+         for deplib in $tmp_libs; do
+           # FIXME: Pedantically, this is the right thing to do, so
+           #        that some nasty dependency loop isn't accidentally
+           #        broken:
+           #new_libs="$deplib $new_libs"
+           # Pragmatically, this seems to cause very few problems in
+           # practice:
+           case $deplib in
+           -L*) new_libs="$deplib $new_libs" ;;
+           -R*) ;;
+           *)
+             # And here is the reason: when a library appears more
+             # than once as an explicit dependence of a library, or
+             # is implicitly linked in more than once by the
+             # compiler, it is considered special, and multiple
+             # occurrences thereof are not removed.  Compare this
+             # with having the same library being listed as a
+             # dependency of multiple other libraries: in this case,
+             # we know (pedantically, we assume) the library does not
+             # need to be listed more than once, so we keep only the
+             # last copy.  This is not always right, but it is rare
+             # enough that we require users that really mean to play
+             # such unportable linking tricks to link the library
+             # using -Wl,-lname, so that libtool does not consider it
+             # for duplicate removal.
+             case " $specialdeplibs " in
+             *" $deplib "*) new_libs="$deplib $new_libs" ;;
+             *)
+               case " $new_libs " in
+               *" $deplib "*) ;;
+               *) new_libs="$deplib $new_libs" ;;
+               esac
+               ;;
+             esac
+             ;;
+           esac
+         done
+         tmp_libs=
+         for deplib in $new_libs; do
+           case $deplib in
+           -L*)
+             case " $tmp_libs " in
+             *" $deplib "*) ;;
+             *) func_append tmp_libs " $deplib" ;;
+             esac
+             ;;
+           *) func_append tmp_libs " $deplib" ;;
+           esac
+         done
+         eval $var=\"$tmp_libs\"
+       done # for var
+      fi
+      # Last step: remove runtime libs from dependency_libs
+      # (they stay in deplibs)
+      tmp_libs=
+      for i in $dependency_libs ; do
+       case " $predeps $postdeps $compiler_lib_search_path " in
+       *" $i "*)
+         i=""
+         ;;
+       esac
+       if test -n "$i" ; then
+         func_append tmp_libs " $i"
+       fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
+    fi
+    if test "$linkmode" = prog || test "$linkmode" = lib; then
+      dlprefiles="$newdlprefiles"
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       func_warning "\`-dlopen' is ignored for archives"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+       func_warning "\`-l' and \`-L' are ignored for archives" ;;
+      esac
+
+      test -n "$rpath" && \
+       func_warning "\`-rpath' is ignored for archives"
+
+      test -n "$xrpath" && \
+       func_warning "\`-R' is ignored for archives"
+
+      test -n "$vinfo" && \
+       func_warning "\`-version-info/-version-number' is ignored for archives"
+
+      test -n "$release" && \
+       func_warning "\`-release' is ignored for archives"
+
+      test -n "$export_symbols$export_symbols_regex" && \
+       func_warning "\`-export-symbols' is ignored for archives"
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      func_append objs "$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case $outputname in
+      lib*)
+       func_stripname 'lib' '.la' "$outputname"
+       name=$func_stripname_result
+       eval shared_ext=\"$shrext_cmds\"
+       eval libname=\"$libname_spec\"
+       ;;
+      *)
+       test "$module" = no && \
+         func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+       if test "$need_lib_prefix" != no; then
+         # Add the "lib" prefix for modules if required
+         func_stripname '' '.la' "$outputname"
+         name=$func_stripname_result
+         eval shared_ext=\"$shrext_cmds\"
+         eval libname=\"$libname_spec\"
+       else
+         func_stripname '' '.la' "$outputname"
+         libname=$func_stripname_result
+       fi
+       ;;
+      esac
+
+      if test -n "$objs"; then
+       if test "$deplibs_check_method" != pass_all; then
+         func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+       else
+         echo
+         $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+         $ECHO "*** objects $objs is not portable!"
+         func_append libobjs " $objs"
+       fi
+      fi
+
+      test "$dlself" != no && \
+       func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+      set dummy $rpath
+      shift
+      test "$#" -gt 1 && \
+       func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+      install_libdir="$1"
+
+      oldlibs=
+      if test -z "$rpath"; then
+       if test "$build_libtool_libs" = yes; then
+         # Building a libtool convenience library.
+         # Some compilers have problems with a `.al' extension so
+         # convenience libraries should have the same extension an
+         # archive normally would.
+         oldlibs="$output_objdir/$libname.$libext $oldlibs"
+         build_libtool_libs=convenience
+         build_old_libs=yes
+       fi
+
+       test -n "$vinfo" && \
+         func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+       test -n "$release" && \
+         func_warning "\`-release' is ignored for convenience libraries"
+      else
+
+       # Parse the version information argument.
+       save_ifs="$IFS"; IFS=':'
+       set dummy $vinfo 0 0 0
+       shift
+       IFS="$save_ifs"
+
+       test -n "$7" && \
+         func_fatal_help "too many parameters to \`-version-info'"
+
+       # convert absolute version numbers to libtool ages
+       # this retains compatibility with .la files and attempts
+       # to make the code below a bit more comprehensible
+
+       case $vinfo_number in
+       yes)
+         number_major="$1"
+         number_minor="$2"
+         number_revision="$3"
+         #
+         # There are really only two kinds -- those that
+         # use the current revision as the major version
+         # and those that subtract age and use age as
+         # a minor version.  But, then there is irix
+         # which has an extra 1 added just for fun
+         #
+         case $version_type in
+         # correct linux to gnu/linux during the next big refactor
+         darwin|linux|osf|windows|none)
+           func_arith $number_major + $number_minor
+           current=$func_arith_result
+           age="$number_minor"
+           revision="$number_revision"
+           ;;
+         freebsd-aout|freebsd-elf|qnx|sunos)
+           current="$number_major"
+           revision="$number_minor"
+           age="0"
+           ;;
+         irix|nonstopux)
+           func_arith $number_major + $number_minor
+           current=$func_arith_result
+           age="$number_minor"
+           revision="$number_minor"
+           lt_irix_increment=no
+           ;;
+         esac
+         ;;
+       no)
+         current="$1"
+         revision="$2"
+         age="$3"
+         ;;
+       esac
+
+       # Check that each of the things are valid numbers.
+       case $current in
+       0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+       *)
+         func_error "CURRENT \`$current' must be a nonnegative integer"
+         func_fatal_error "\`$vinfo' is not valid version information"
+         ;;
+       esac
+
+       case $revision in
+       0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+       *)
+         func_error "REVISION \`$revision' must be a nonnegative integer"
+         func_fatal_error "\`$vinfo' is not valid version information"
+         ;;
+       esac
+
+       case $age in
+       0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+       *)
+         func_error "AGE \`$age' must be a nonnegative integer"
+         func_fatal_error "\`$vinfo' is not valid version information"
+         ;;
+       esac
+
+       if test "$age" -gt "$current"; then
+         func_error "AGE \`$age' is greater than the current interface number \`$current'"
+         func_fatal_error "\`$vinfo' is not valid version information"
+       fi
+
+       # Calculate the version variables.
+       major=
+       versuffix=
+       verstring=
+       case $version_type in
+       none) ;;
+
+       darwin)
+         # Like Linux, but with the current version available in
+         # verstring for coding it into the library header
+         func_arith $current - $age
+         major=.$func_arith_result
+         versuffix="$major.$age.$revision"
+         # Darwin ld doesn't like 0 for these options...
+         func_arith $current + 1
+         minor_current=$func_arith_result
+         xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+         verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+         ;;
+
+       freebsd-aout)
+         major=".$current"
+         versuffix=".$current.$revision";
+         ;;
+
+       freebsd-elf)
+         major=".$current"
+         versuffix=".$current"
+         ;;
+
+       irix | nonstopux)
+         if test "X$lt_irix_increment" = "Xno"; then
+           func_arith $current - $age
+         else
+           func_arith $current - $age + 1
+         fi
+         major=$func_arith_result
+
+         case $version_type in
+           nonstopux) verstring_prefix=nonstopux ;;
+           *)         verstring_prefix=sgi ;;
+         esac
+         verstring="$verstring_prefix$major.$revision"
+
+         # Add in all the interfaces that we are compatible with.
+         loop=$revision
+         while test "$loop" -ne 0; do
+           func_arith $revision - $loop
+           iface=$func_arith_result
+           func_arith $loop - 1
+           loop=$func_arith_result
+           verstring="$verstring_prefix$major.$iface:$verstring"
+         done
+
+         # Before this point, $major must not contain `.'.
+         major=.$major
+         versuffix="$major.$revision"
+         ;;
+
+       linux) # correct to gnu/linux during the next big refactor
+         func_arith $current - $age
+         major=.$func_arith_result
+         versuffix="$major.$age.$revision"
+         ;;
+
+       osf)
+         func_arith $current - $age
+         major=.$func_arith_result
+         versuffix=".$current.$age.$revision"
+         verstring="$current.$age.$revision"
+
+         # Add in all the interfaces that we are compatible with.
+         loop=$age
+         while test "$loop" -ne 0; do
+           func_arith $current - $loop
+           iface=$func_arith_result
+           func_arith $loop - 1
+           loop=$func_arith_result
+           verstring="$verstring:${iface}.0"
+         done
+
+         # Make executables depend on our current version.
+         func_append verstring ":${current}.0"
+         ;;
+
+       qnx)
+         major=".$current"
+         versuffix=".$current"
+         ;;
+
+       sunos)
+         major=".$current"
+         versuffix=".$current.$revision"
+         ;;
+
+       windows)
+         # Use '-' rather than '.', since we only want one
+         # extension on DOS 8.3 filesystems.
+         func_arith $current - $age
+         major=$func_arith_result
+         versuffix="-$major"
+         ;;
+
+       *)
+         func_fatal_configuration "unknown library version type \`$version_type'"
+         ;;
+       esac
+
+       # Clear the version info if we defaulted, and they specified a release.
+       if test -z "$vinfo" && test -n "$release"; then
+         major=
+         case $version_type in
+         darwin)
+           # we can't check for "0.0" in archive_cmds due to quoting
+           # problems, so we reset it completely
+           verstring=
+           ;;
+         *)
+           verstring="0.0"
+           ;;
+         esac
+         if test "$need_version" = no; then
+           versuffix=
+         else
+           versuffix=".0.0"
+         fi
+       fi
+
+       # Remove version info from name if versioning should be avoided
+       if test "$avoid_version" = yes && test "$need_version" = no; then
+         major=
+         versuffix=
+         verstring=""
+       fi
+
+       # Check to see if the archive will have undefined symbols.
+       if test "$allow_undefined" = yes; then
+         if test "$allow_undefined_flag" = unsupported; then
+           func_warning "undefined symbols not allowed in $host shared libraries"
+           build_libtool_libs=no
+           build_old_libs=yes
+         fi
+       else
+         # Don't allow undefined symbols.
+         allow_undefined_flag="$no_undefined_flag"
+       fi
+
+      fi
+
+      func_generate_dlsyms "$libname" "$libname" "yes"
+      func_append libobjs " $symfileobj"
+      test "X$libobjs" = "X " && libobjs=
+
+      if test "$opt_mode" != relink; then
+       # Remove our outputs, but don't remove object files since they
+       # may have been created when compiling PIC objects.
+       removelist=
+       tempremovelist=`$ECHO "$output_objdir/*"`
+       for p in $tempremovelist; do
+         case $p in
+           *.$objext | *.gcno)
+              ;;
+           $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+              if test "X$precious_files_regex" != "X"; then
+                if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+                then
+                  continue
+                fi
+              fi
+              func_append removelist " $p"
+              ;;
+           *) ;;
+         esac
+       done
+       test -n "$removelist" && \
+         func_show_eval "${RM}r \$removelist"
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+       func_append oldlibs " $output_objdir/$libname.$libext"
+
+       # Transform .lo files to .o files.
+       oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      #for path in $notinst_path; do
+      #        lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+      #        deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+      #        dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+      #done
+
+      if test -n "$xrpath"; then
+       # If the user specified any rpath flags, then add them.
+       temp_xrpath=
+       for libdir in $xrpath; do
+         func_replace_sysroot "$libdir"
+         func_append temp_xrpath " -R$func_replace_sysroot_result"
+         case "$finalize_rpath " in
+         *" $libdir "*) ;;
+         *) func_append finalize_rpath " $libdir" ;;
+         esac
+       done
+       if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+         dependency_libs="$temp_xrpath $dependency_libs"
+       fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles="$dlfiles"
+      dlfiles=
+      for lib in $old_dlfiles; do
+       case " $dlprefiles $dlfiles " in
+       *" $lib "*) ;;
+       *) func_append dlfiles " $lib" ;;
+       esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles="$dlprefiles"
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+       case "$dlprefiles " in
+       *" $lib "*) ;;
+       *) func_append dlprefiles " $lib" ;;
+       esac
+      done
+
+      if test "$build_libtool_libs" = yes; then
+       if test -n "$rpath"; then
+         case $host in
+         *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+           # these systems don't actually have a c library (as such)!
+           ;;
+         *-*-rhapsody* | *-*-darwin1.[012])
+           # Rhapsody C library is in the System framework
+           func_append deplibs " System.ltframework"
+           ;;
+         *-*-netbsd*)
+           # Don't link with libc until the a.out ld.so is fixed.
+           ;;
+         *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+           # Do not include libc due to us having libc/libc_r.
+           ;;
+         *-*-sco3.2v5* | *-*-sco5v6*)
+           # Causes problems with __ctype
+           ;;
+         *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+           # Compiler inserts libc in the correct place for threads to work
+           ;;
+         *)
+           # Add libc to deplibs on all other systems if necessary.
+           if test "$build_libtool_need_lc" = "yes"; then
+             func_append deplibs " -lc"
+           fi
+           ;;
+         esac
+       fi
+
+       # Transform deplibs into only deplibs that can be linked in shared.
+       name_save=$name
+       libname_save=$libname
+       release_save=$release
+       versuffix_save=$versuffix
+       major_save=$major
+       # I'm not sure if I'm treating the release correctly.  I think
+       # release should show up in the -l (ie -lgmp5) so we don't want to
+       # add it in twice.  Is that correct?
+       release=""
+       versuffix=""
+       major=""
+       newdeplibs=
+       droppeddeps=no
+       case $deplibs_check_method in
+       pass_all)
+         # Don't check for shared/static.  Everything works.
+         # This might be a little naive.  We might want to check
+         # whether the library exists or not.  But this is on
+         # osf3 & osf4 and I'm not really sure... Just
+         # implementing what was already the behavior.
+         newdeplibs=$deplibs
+         ;;
+       test_compile)
+         # This code stresses the "libraries are programs" paradigm to its
+         # limits. Maybe even breaks it.  We compile a program, linking it
+         # against the deplibs as a proxy for the library.  Then we can check
+         # whether they linked in statically or dynamically with ldd.
+         $opt_dry_run || $RM conftest.c
+         cat > conftest.c <<EOF
+         int main() { return 0; }
+EOF
+         $opt_dry_run || $RM conftest
+         if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+           ldd_output=`ldd conftest`
+           for i in $deplibs; do
+             case $i in
+             -l*)
+               func_stripname -l '' "$i"
+               name=$func_stripname_result
+               if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+                 case " $predeps $postdeps " in
+                 *" $i "*)
+                   func_append newdeplibs " $i"
+                   i=""
+                   ;;
+                 esac
+               fi
+               if test -n "$i" ; then
+                 libname=`eval "\\$ECHO \"$libname_spec\""`
+                 deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+                 set dummy $deplib_matches; shift
+                 deplib_match=$1
+                 if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+                   func_append newdeplibs " $i"
+                 else
+                   droppeddeps=yes
+                   echo
+                   $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+                   echo "*** I have the capability to make that library automatically link in when"
+                   echo "*** you link to this library.  But I can only do this if you have a"
+                   echo "*** shared version of the library, which I believe you do not have"
+                   echo "*** because a test_compile did reveal that the linker did not use it for"
+                   echo "*** its dynamic dependency list that programs get resolved with at runtime."
+                 fi
+               fi
+               ;;
+             *)
+               func_append newdeplibs " $i"
+               ;;
+             esac
+           done
+         else
+           # Error occurred in the first compile.  Let's try to salvage
+           # the situation: Compile a separate program for each library.
+           for i in $deplibs; do
+             case $i in
+             -l*)
+               func_stripname -l '' "$i"
+               name=$func_stripname_result
+               $opt_dry_run || $RM conftest
+               if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+                 ldd_output=`ldd conftest`
+                 if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+                   case " $predeps $postdeps " in
+                   *" $i "*)
+                     func_append newdeplibs " $i"
+                     i=""
+                     ;;
+                   esac
+                 fi
+                 if test -n "$i" ; then
+                   libname=`eval "\\$ECHO \"$libname_spec\""`
+                   deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+                   set dummy $deplib_matches; shift
+                   deplib_match=$1
+                   if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+                     func_append newdeplibs " $i"
+                   else
+                     droppeddeps=yes
+                     echo
+                     $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+                     echo "*** I have the capability to make that library automatically link in when"
+                     echo "*** you link to this library.  But I can only do this if you have a"
+                     echo "*** shared version of the library, which you do not appear to have"
+                     echo "*** because a test_compile did reveal that the linker did not use this one"
+                     echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+                   fi
+                 fi
+               else
+                 droppeddeps=yes
+                 echo
+                 $ECHO "*** Warning!  Library $i is needed by this library but I was not able to"
+                 echo "*** make it link in!  You will probably need to install it or some"
+                 echo "*** library that it depends on before this library will be fully"
+                 echo "*** functional.  Installing it before continuing would be even better."
+               fi
+               ;;
+             *)
+               func_append newdeplibs " $i"
+               ;;
+             esac
+           done
+         fi
+         ;;
+       file_magic*)
+         set dummy $deplibs_check_method; shift
+         file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+         for a_deplib in $deplibs; do
+           case $a_deplib in
+           -l*)
+             func_stripname -l '' "$a_deplib"
+             name=$func_stripname_result
+             if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+               case " $predeps $postdeps " in
+               *" $a_deplib "*)
+                 func_append newdeplibs " $a_deplib"
+                 a_deplib=""
+                 ;;
+               esac
+             fi
+             if test -n "$a_deplib" ; then
+               libname=`eval "\\$ECHO \"$libname_spec\""`
+               if test -n "$file_magic_glob"; then
+                 libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+               else
+                 libnameglob=$libname
+               fi
+               test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
+               for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+                 if test "$want_nocaseglob" = yes; then
+                   shopt -s nocaseglob
+                   potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+                   $nocaseglob
+                 else
+                   potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+                 fi
+                 for potent_lib in $potential_libs; do
+                     # Follow soft links.
+                     if ls -lLd "$potent_lib" 2>/dev/null |
+                        $GREP " -> " >/dev/null; then
+                       continue
+                     fi
+                     # The statement above tries to avoid entering an
+                     # endless loop below, in case of cyclic links.
+                     # We might still enter an endless loop, since a link
+                     # loop can be closed while we follow links,
+                     # but so what?
+                     potlib="$potent_lib"
+                     while test -h "$potlib" 2>/dev/null; do
+                       potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+                       case $potliblink in
+                       [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+                       *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
+                       esac
+                     done
+                     if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+                        $SED -e 10q |
+                        $EGREP "$file_magic_regex" > /dev/null; then
+                       func_append newdeplibs " $a_deplib"
+                       a_deplib=""
+                       break 2
+                     fi
+                 done
+               done
+             fi
+             if test -n "$a_deplib" ; then
+               droppeddeps=yes
+               echo
+               $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+               echo "*** I have the capability to make that library automatically link in when"
+               echo "*** you link to this library.  But I can only do this if you have a"
+               echo "*** shared version of the library, which you do not appear to have"
+               echo "*** because I did check the linker path looking for a file starting"
+               if test -z "$potlib" ; then
+                 $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+               else
+                 $ECHO "*** with $libname and none of the candidates passed a file format test"
+                 $ECHO "*** using a file magic. Last file checked: $potlib"
+               fi
+             fi
+             ;;
+           *)
+             # Add a -L argument.
+             func_append newdeplibs " $a_deplib"
+             ;;
+           esac
+         done # Gone through all deplibs.
+         ;;
+       match_pattern*)
+         set dummy $deplibs_check_method; shift
+         match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+         for a_deplib in $deplibs; do
+           case $a_deplib in
+           -l*)
+             func_stripname -l '' "$a_deplib"
+             name=$func_stripname_result
+             if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+               case " $predeps $postdeps " in
+               *" $a_deplib "*)
+                 func_append newdeplibs " $a_deplib"
+                 a_deplib=""
+                 ;;
+               esac
+             fi
+             if test -n "$a_deplib" ; then
+               libname=`eval "\\$ECHO \"$libname_spec\""`
+               for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+                 potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+                 for potent_lib in $potential_libs; do
+                   potlib="$potent_lib" # see symlink-check above in file_magic test
+                   if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+                      $EGREP "$match_pattern_regex" > /dev/null; then
+                     func_append newdeplibs " $a_deplib"
+                     a_deplib=""
+                     break 2
+                   fi
+                 done
+               done
+             fi
+             if test -n "$a_deplib" ; then
+               droppeddeps=yes
+               echo
+               $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+               echo "*** I have the capability to make that library automatically link in when"
+               echo "*** you link to this library.  But I can only do this if you have a"
+               echo "*** shared version of the library, which you do not appear to have"
+               echo "*** because I did check the linker path looking for a file starting"
+               if test -z "$potlib" ; then
+                 $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+               else
+                 $ECHO "*** with $libname and none of the candidates passed a file format test"
+                 $ECHO "*** using a regex pattern. Last file checked: $potlib"
+               fi
+             fi
+             ;;
+           *)
+             # Add a -L argument.
+             func_append newdeplibs " $a_deplib"
+             ;;
+           esac
+         done # Gone through all deplibs.
+         ;;
+       none | unknown | *)
+         newdeplibs=""
+         tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+         if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+           for i in $predeps $postdeps ; do
+             # can't use Xsed below, because $i might contain '/'
+             tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
+           done
+         fi
+         case $tmp_deplibs in
+         *[!\  \ ]*)
+           echo
+           if test "X$deplibs_check_method" = "Xnone"; then
+             echo "*** Warning: inter-library dependencies are not supported in this platform."
+           else
+             echo "*** Warning: inter-library dependencies are not known to be supported."
+           fi
+           echo "*** All declared inter-library dependencies are being dropped."
+           droppeddeps=yes
+           ;;
+         esac
+         ;;
+       esac
+       versuffix=$versuffix_save
+       major=$major_save
+       release=$release_save
+       libname=$libname_save
+       name=$name_save
+
+       case $host in
+       *-*-rhapsody* | *-*-darwin1.[012])
+         # On Rhapsody replace the C library with the System framework
+         newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+         ;;
+       esac
+
+       if test "$droppeddeps" = yes; then
+         if test "$module" = yes; then
+           echo
+           echo "*** Warning: libtool could not satisfy all declared inter-library"
+           $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
+           echo "*** a static module, that should work as long as the dlopening"
+           echo "*** application is linked with the -dlopen flag."
+           if test -z "$global_symbol_pipe"; then
+             echo
+             echo "*** However, this would only work if libtool was able to extract symbol"
+             echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+             echo "*** not find such a program.  So, this module is probably useless."
+             echo "*** \`nm' from GNU binutils and a full rebuild may help."
+           fi
+           if test "$build_old_libs" = no; then
+             oldlibs="$output_objdir/$libname.$libext"
+             build_libtool_libs=module
+             build_old_libs=yes
+           else
+             build_libtool_libs=no
+           fi
+         else
+           echo "*** The inter-library dependencies that have been dropped here will be"
+           echo "*** automatically added whenever a program is linked with this library"
+           echo "*** or is declared to -dlopen it."
+
+           if test "$allow_undefined" = no; then
+             echo
+             echo "*** Since this library must not contain undefined symbols,"
+             echo "*** because either the platform does not support them or"
+             echo "*** it was explicitly requested with -no-undefined,"
+             echo "*** libtool will only create a static version of it."
+             if test "$build_old_libs" = no; then
+               oldlibs="$output_objdir/$libname.$libext"
+               build_libtool_libs=module
+               build_old_libs=yes
+             else
+               build_libtool_libs=no
+             fi
+           fi
+         fi
+       fi
+       # Done checking deplibs!
+       deplibs=$newdeplibs
+      fi
+      # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+      case $host in
+       *-*-darwin*)
+         newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+         new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+         deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+         ;;
+      esac
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+       case " $new_libs " in
+       *" -L$path/$objdir "*) ;;
+       *)
+         case " $deplibs " in
+         *" -L$path/$objdir "*)
+           func_append new_libs " -L$path/$objdir" ;;
+         esac
+         ;;
+       esac
+      done
+      for deplib in $deplibs; do
+       case $deplib in
+       -L*)
+         case " $new_libs " in
+         *" $deplib "*) ;;
+         *) func_append new_libs " $deplib" ;;
+         esac
+         ;;
+       *) func_append new_libs " $deplib" ;;
+       esac
+      done
+      deplibs="$new_libs"
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+       # Remove ${wl} instances when linking with ld.
+       # FIXME: should test the right _cmds variable.
+       case $archive_cmds in
+         *\$LD\ *) wl= ;;
+        esac
+       if test "$hardcode_into_libs" = yes; then
+         # Hardcode the library paths
+         hardcode_libdirs=
+         dep_rpath=
+         rpath="$finalize_rpath"
+         test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
+         for libdir in $rpath; do
+           if test -n "$hardcode_libdir_flag_spec"; then
+             if test -n "$hardcode_libdir_separator"; then
+               func_replace_sysroot "$libdir"
+               libdir=$func_replace_sysroot_result
+               if test -z "$hardcode_libdirs"; then
+                 hardcode_libdirs="$libdir"
+               else
+                 # Just accumulate the unique libdirs.
+                 case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+                 *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+                   ;;
+                 *)
+                   func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+                   ;;
+                 esac
+               fi
+             else
+               eval flag=\"$hardcode_libdir_flag_spec\"
+               func_append dep_rpath " $flag"
+             fi
+           elif test -n "$runpath_var"; then
+             case "$perm_rpath " in
+             *" $libdir "*) ;;
+             *) func_append perm_rpath " $libdir" ;;
+             esac
+           fi
+         done
+         # Substitute the hardcoded libdirs into the rpath.
+         if test -n "$hardcode_libdir_separator" &&
+            test -n "$hardcode_libdirs"; then
+           libdir="$hardcode_libdirs"
+           eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+         fi
+         if test -n "$runpath_var" && test -n "$perm_rpath"; then
+           # We should set the runpath_var.
+           rpath=
+           for dir in $perm_rpath; do
+             func_append rpath "$dir:"
+           done
+           eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+         fi
+         test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+       fi
+
+       shlibpath="$finalize_shlibpath"
+       test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+       if test -n "$shlibpath"; then
+         eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+       fi
+
+       # Get the real and link names of the library.
+       eval shared_ext=\"$shrext_cmds\"
+       eval library_names=\"$library_names_spec\"
+       set dummy $library_names
+       shift
+       realname="$1"
+       shift
+
+       if test -n "$soname_spec"; then
+         eval soname=\"$soname_spec\"
+       else
+         soname="$realname"
+       fi
+       if test -z "$dlname"; then
+         dlname=$soname
+       fi
+
+       lib="$output_objdir/$realname"
+       linknames=
+       for link
+       do
+         func_append linknames " $link"
+       done
+
+       # Use standard objects if they are pic
+       test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+       test "X$libobjs" = "X " && libobjs=
+
+       delfiles=
+       if test -n "$export_symbols" && test -n "$include_expsyms"; then
+         $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+         export_symbols="$output_objdir/$libname.uexp"
+         func_append delfiles " $export_symbols"
+       fi
+
+       orig_export_symbols=
+       case $host_os in
+       cygwin* | mingw* | cegcc*)
+         if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+           # exporting using user supplied symfile
+           if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+             # and it's NOT already a .def file. Must figure out
+             # which of the given symbols are data symbols and tag
+             # them as such. So, trigger use of export_symbols_cmds.
+             # export_symbols gets reassigned inside the "prepare
+             # the list of exported symbols" if statement, so the
+             # include_expsyms logic still works.
+             orig_export_symbols="$export_symbols"
+             export_symbols=
+             always_export_symbols=yes
+           fi
+         fi
+         ;;
+       esac
+
+       # Prepare the list of exported symbols
+       if test -z "$export_symbols"; then
+         if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+           func_verbose "generating symbol list for \`$libname.la'"
+           export_symbols="$output_objdir/$libname.exp"
+           $opt_dry_run || $RM $export_symbols
+           cmds=$export_symbols_cmds
+           save_ifs="$IFS"; IFS='~'
+           for cmd1 in $cmds; do
+             IFS="$save_ifs"
+             # Take the normal branch if the nm_file_list_spec branch
+             # doesn't work or if tool conversion is not needed.
+             case $nm_file_list_spec~$to_tool_file_cmd in
+               *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+                 try_normal_branch=yes
+                 eval cmd=\"$cmd1\"
+                 func_len " $cmd"
+                 len=$func_len_result
+                 ;;
+               *)
+                 try_normal_branch=no
+                 ;;
+             esac
+             if test "$try_normal_branch" = yes \
+                && { test "$len" -lt "$max_cmd_len" \
+                     || test "$max_cmd_len" -le -1; }
+             then
+               func_show_eval "$cmd" 'exit $?'
+               skipped_export=false
+             elif test -n "$nm_file_list_spec"; then
+               func_basename "$output"
+               output_la=$func_basename_result
+               save_libobjs=$libobjs
+               save_output=$output
+               output=${output_objdir}/${output_la}.nm
+               func_to_tool_file "$output"
+               libobjs=$nm_file_list_spec$func_to_tool_file_result
+               func_append delfiles " $output"
+               func_verbose "creating $NM input file list: $output"
+               for obj in $save_libobjs; do
+                 func_to_tool_file "$obj"
+                 $ECHO "$func_to_tool_file_result"
+               done > "$output"
+               eval cmd=\"$cmd1\"
+               func_show_eval "$cmd" 'exit $?'
+               output=$save_output
+               libobjs=$save_libobjs
+               skipped_export=false
+             else
+               # The command line is too long to execute in one step.
+               func_verbose "using reloadable object file for export list..."
+               skipped_export=:
+               # Break out early, otherwise skipped_export may be
+               # set to false by a later but shorter cmd.
+               break
+             fi
+           done
+           IFS="$save_ifs"
+           if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+             func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+             func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+           fi
+         fi
+       fi
+
+       if test -n "$export_symbols" && test -n "$include_expsyms"; then
+         tmp_export_symbols="$export_symbols"
+         test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+         $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+       fi
+
+       if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+         # The given exports_symbols file has to be filtered, so filter it.
+         func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+         # FIXME: $output_objdir/$libname.filter potentially contains lots of
+         # 's' commands which not all seds can handle. GNU sed should be fine
+         # though. Also, the filter scales superlinearly with the number of
+         # global variables. join(1) would be nice here, but unfortunately
+         # isn't a blessed tool.
+         $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+         func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+         export_symbols=$output_objdir/$libname.def
+         $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+       fi
+
+       tmp_deplibs=
+       for test_deplib in $deplibs; do
+         case " $convenience " in
+         *" $test_deplib "*) ;;
+         *)
+           func_append tmp_deplibs " $test_deplib"
+           ;;
+         esac
+       done
+       deplibs="$tmp_deplibs"
+
+       if test -n "$convenience"; then
+         if test -n "$whole_archive_flag_spec" &&
+           test "$compiler_needs_object" = yes &&
+           test -z "$libobjs"; then
+           # extract the archives, so we have objects to list.
+           # TODO: could optimize this to just extract one archive.
+           whole_archive_flag_spec=
+         fi
+         if test -n "$whole_archive_flag_spec"; then
+           save_libobjs=$libobjs
+           eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+           test "X$libobjs" = "X " && libobjs=
+         else
+           gentop="$output_objdir/${outputname}x"
+           func_append generated " $gentop"
+
+           func_extract_archives $gentop $convenience
+           func_append libobjs " $func_extract_archives_result"
+           test "X$libobjs" = "X " && libobjs=
+         fi
+       fi
+
+       if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+         eval flag=\"$thread_safe_flag_spec\"
+         func_append linker_flags " $flag"
+       fi
+
+       # Make a backup of the uninstalled library when relinking
+       if test "$opt_mode" = relink; then
+         $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+       fi
+
+       # Do each of the archive commands.
+       if test "$module" = yes && test -n "$module_cmds" ; then
+         if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+           eval test_cmds=\"$module_expsym_cmds\"
+           cmds=$module_expsym_cmds
+         else
+           eval test_cmds=\"$module_cmds\"
+           cmds=$module_cmds
+         fi
+       else
+         if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+           eval test_cmds=\"$archive_expsym_cmds\"
+           cmds=$archive_expsym_cmds
+         else
+           eval test_cmds=\"$archive_cmds\"
+           cmds=$archive_cmds
+         fi
+       fi
+
+       if test "X$skipped_export" != "X:" &&
+          func_len " $test_cmds" &&
+          len=$func_len_result &&
+          test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+         :
+       else
+         # The command line is too long to link in one step, link piecewise
+         # or, if using GNU ld and skipped_export is not :, use a linker
+         # script.
+
+         # Save the value of $output and $libobjs because we want to
+         # use them later.  If we have whole_archive_flag_spec, we
+         # want to use save_libobjs as it was before
+         # whole_archive_flag_spec was expanded, because we can't
+         # assume the linker understands whole_archive_flag_spec.
+         # This may have to be revisited, in case too many
+         # convenience libraries get linked in and end up exceeding
+         # the spec.
+         if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+           save_libobjs=$libobjs
+         fi
+         save_output=$output
+         func_basename "$output"
+         output_la=$func_basename_result
+
+         # Clear the reloadable object creation command queue and
+         # initialize k to one.
+         test_cmds=
+         concat_cmds=
+         objlist=
+         last_robj=
+         k=1
+
+         if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+           output=${output_objdir}/${output_la}.lnkscript
+           func_verbose "creating GNU ld script: $output"
+           echo 'INPUT (' > $output
+           for obj in $save_libobjs
+           do
+             func_to_tool_file "$obj"
+             $ECHO "$func_to_tool_file_result" >> $output
+           done
+           echo ')' >> $output
+           func_append delfiles " $output"
+           func_to_tool_file "$output"
+           output=$func_to_tool_file_result
+         elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+           output=${output_objdir}/${output_la}.lnk
+           func_verbose "creating linker input file list: $output"
+           : > $output
+           set x $save_libobjs
+           shift
+           firstobj=
+           if test "$compiler_needs_object" = yes; then
+             firstobj="$1 "
+             shift
+           fi
+           for obj
+           do
+             func_to_tool_file "$obj"
+             $ECHO "$func_to_tool_file_result" >> $output
+           done
+           func_append delfiles " $output"
+           func_to_tool_file "$output"
+           output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+         else
+           if test -n "$save_libobjs"; then
+             func_verbose "creating reloadable object files..."
+             output=$output_objdir/$output_la-${k}.$objext
+             eval test_cmds=\"$reload_cmds\"
+             func_len " $test_cmds"
+             len0=$func_len_result
+             len=$len0
+
+             # Loop over the list of objects to be linked.
+             for obj in $save_libobjs
+             do
+               func_len " $obj"
+               func_arith $len + $func_len_result
+               len=$func_arith_result
+               if test "X$objlist" = X ||
+                  test "$len" -lt "$max_cmd_len"; then
+                 func_append objlist " $obj"
+               else
+                 # The command $test_cmds is almost too long, add a
+                 # command to the queue.
+                 if test "$k" -eq 1 ; then
+                   # The first file doesn't have a previous command to add.
+                   reload_objs=$objlist
+                   eval concat_cmds=\"$reload_cmds\"
+                 else
+                   # All subsequent reloadable object files will link in
+                   # the last one created.
+                   reload_objs="$objlist $last_robj"
+                   eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+                 fi
+                 last_robj=$output_objdir/$output_la-${k}.$objext
+                 func_arith $k + 1
+                 k=$func_arith_result
+                 output=$output_objdir/$output_la-${k}.$objext
+                 objlist=" $obj"
+                 func_len " $last_robj"
+                 func_arith $len0 + $func_len_result
+                 len=$func_arith_result
+               fi
+             done
+             # Handle the remaining objects by creating one last
+             # reloadable object file.  All subsequent reloadable object
+             # files will link in the last one created.
+             test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+             reload_objs="$objlist $last_robj"
+             eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
+             if test -n "$last_robj"; then
+               eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+             fi
+             func_append delfiles " $output"
+
+           else
+             output=
+           fi
+
+           if ${skipped_export-false}; then
+             func_verbose "generating symbol list for \`$libname.la'"
+             export_symbols="$output_objdir/$libname.exp"
+             $opt_dry_run || $RM $export_symbols
+             libobjs=$output
+             # Append the command to create the export file.
+             test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+             eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+             if test -n "$last_robj"; then
+               eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+             fi
+           fi
+
+           test -n "$save_libobjs" &&
+             func_verbose "creating a temporary reloadable object file: $output"
+
+           # Loop through the commands generated above and execute them.
+           save_ifs="$IFS"; IFS='~'
+           for cmd in $concat_cmds; do
+             IFS="$save_ifs"
+             $opt_silent || {
+                 func_quote_for_expand "$cmd"
+                 eval "func_echo $func_quote_for_expand_result"
+             }
+             $opt_dry_run || eval "$cmd" || {
+               lt_exit=$?
+
+               # Restore the uninstalled library and exit
+               if test "$opt_mode" = relink; then
+                 ( cd "$output_objdir" && \
+                   $RM "${realname}T" && \
+                   $MV "${realname}U" "$realname" )
+               fi
+
+               exit $lt_exit
+             }
+           done
+           IFS="$save_ifs"
+
+           if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+             func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+             func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+           fi
+         fi
+
+          if ${skipped_export-false}; then
+           if test -n "$export_symbols" && test -n "$include_expsyms"; then
+             tmp_export_symbols="$export_symbols"
+             test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+             $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+           fi
+
+           if test -n "$orig_export_symbols"; then
+             # The given exports_symbols file has to be filtered, so filter it.
+             func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+             # FIXME: $output_objdir/$libname.filter potentially contains lots of
+             # 's' commands which not all seds can handle. GNU sed should be fine
+             # though. Also, the filter scales superlinearly with the number of
+             # global variables. join(1) would be nice here, but unfortunately
+             # isn't a blessed tool.
+             $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+             func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+             export_symbols=$output_objdir/$libname.def
+             $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+           fi
+         fi
+
+         libobjs=$output
+         # Restore the value of output.
+         output=$save_output
+
+         if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+           eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+           test "X$libobjs" = "X " && libobjs=
+         fi
+         # Expand the library linking commands again to reset the
+         # value of $libobjs for piecewise linking.
+
+         # Do each of the archive commands.
+         if test "$module" = yes && test -n "$module_cmds" ; then
+           if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+             cmds=$module_expsym_cmds
+           else
+             cmds=$module_cmds
+           fi
+         else
+           if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+             cmds=$archive_expsym_cmds
+           else
+             cmds=$archive_cmds
+           fi
+         fi
+       fi
+
+       if test -n "$delfiles"; then
+         # Append the command to remove temporary files to $cmds.
+         eval cmds=\"\$cmds~\$RM $delfiles\"
+       fi
+
+       # Add any objects from preloaded convenience libraries
+       if test -n "$dlprefiles"; then
+         gentop="$output_objdir/${outputname}x"
+         func_append generated " $gentop"
+
+         func_extract_archives $gentop $dlprefiles
+         func_append libobjs " $func_extract_archives_result"
+         test "X$libobjs" = "X " && libobjs=
+       fi
+
+       save_ifs="$IFS"; IFS='~'
+       for cmd in $cmds; do
+         IFS="$save_ifs"
+         eval cmd=\"$cmd\"
+         $opt_silent || {
+           func_quote_for_expand "$cmd"
+           eval "func_echo $func_quote_for_expand_result"
+         }
+         $opt_dry_run || eval "$cmd" || {
+           lt_exit=$?
+
+           # Restore the uninstalled library and exit
+           if test "$opt_mode" = relink; then
+             ( cd "$output_objdir" && \
+               $RM "${realname}T" && \
+               $MV "${realname}U" "$realname" )
+           fi
+
+           exit $lt_exit
+         }
+       done
+       IFS="$save_ifs"
+
+       # Restore the uninstalled library and exit
+       if test "$opt_mode" = relink; then
+         $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+         if test -n "$convenience"; then
+           if test -z "$whole_archive_flag_spec"; then
+             func_show_eval '${RM}r "$gentop"'
+           fi
+         fi
+
+         exit $EXIT_SUCCESS
+       fi
+
+       # Create links to the real library.
+       for linkname in $linknames; do
+         if test "$realname" != "$linkname"; then
+           func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+         fi
+       done
+
+       # If -module or -export-dynamic was specified, set the dlname.
+       if test "$module" = yes || test "$export_dynamic" = yes; then
+         # On all known operating systems, these are identical.
+         dlname="$soname"
+       fi
+      fi
+      ;;
+
+    obj)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       func_warning "\`-dlopen' is ignored for objects"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+       func_warning "\`-l' and \`-L' are ignored for objects" ;;
+      esac
+
+      test -n "$rpath" && \
+       func_warning "\`-rpath' is ignored for objects"
+
+      test -n "$xrpath" && \
+       func_warning "\`-R' is ignored for objects"
+
+      test -n "$vinfo" && \
+       func_warning "\`-version-info' is ignored for objects"
+
+      test -n "$release" && \
+       func_warning "\`-release' is ignored for objects"
+
+      case $output in
+      *.lo)
+       test -n "$objs$old_deplibs" && \
+         func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+       libobj=$output
+       func_lo2o "$libobj"
+       obj=$func_lo2o_result
+       ;;
+      *)
+       libobj=
+       obj="$output"
+       ;;
+      esac
+
+      # Delete the old objects.
+      $opt_dry_run || $RM $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec and hope we can get by with
+      # turning comma into space..
+      wl=
+
+      if test -n "$convenience"; then
+       if test -n "$whole_archive_flag_spec"; then
+         eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+         reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+       else
+         gentop="$output_objdir/${obj}x"
+         func_append generated " $gentop"
+
+         func_extract_archives $gentop $convenience
+         reload_conv_objs="$reload_objs $func_extract_archives_result"
+       fi
+      fi
+
+      # If we're not building shared, we need to use non_pic_objs
+      test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
+
+      # Create the old-style object.
+      reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+      output="$obj"
+      func_execute_cmds "$reload_cmds" 'exit $?'
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+       if test -n "$gentop"; then
+         func_show_eval '${RM}r "$gentop"'
+       fi
+
+       exit $EXIT_SUCCESS
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+       if test -n "$gentop"; then
+         func_show_eval '${RM}r "$gentop"'
+       fi
+
+       # Create an invalid libtool object if no PIC, so that we don't
+       # accidentally link it into a program.
+       # $show "echo timestamp > $libobj"
+       # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+       exit $EXIT_SUCCESS
+      fi
+
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
+       # Only do commands if we really have different PIC objects.
+       reload_objs="$libobjs $reload_conv_objs"
+       output="$libobj"
+       func_execute_cmds "$reload_cmds" 'exit $?'
+      fi
+
+      if test -n "$gentop"; then
+       func_show_eval '${RM}r "$gentop"'
+      fi
+
+      exit $EXIT_SUCCESS
+      ;;
+
+    prog)
+      case $host in
+       *cygwin*) func_stripname '' '.exe' "$output"
+                 output=$func_stripname_result.exe;;
+      esac
+      test -n "$vinfo" && \
+       func_warning "\`-version-info' is ignored for programs"
+
+      test -n "$release" && \
+       func_warning "\`-release' is ignored for programs"
+
+      test "$preload" = yes \
+        && test "$dlopen_support" = unknown \
+       && test "$dlopen_self" = unknown \
+       && test "$dlopen_self_static" = unknown && \
+         func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+       # On Rhapsody replace the C library is the System framework
+       compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+       finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+       ;;
+      esac
+
+      case $host in
+      *-*-darwin*)
+       # Don't allow lazy linking, it breaks C++ global constructors
+       # But is supposedly fixed on 10.4 or later (yay!).
+       if test "$tagname" = CXX ; then
+         case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+           10.[0123])
+             func_append compile_command " ${wl}-bind_at_load"
+             func_append finalize_command " ${wl}-bind_at_load"
+           ;;
+         esac
+       fi
+       # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+       compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+       finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+       ;;
+      esac
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+       case " $new_libs " in
+       *" -L$path/$objdir "*) ;;
+       *)
+         case " $compile_deplibs " in
+         *" -L$path/$objdir "*)
+           func_append new_libs " -L$path/$objdir" ;;
+         esac
+         ;;
+       esac
+      done
+      for deplib in $compile_deplibs; do
+       case $deplib in
+       -L*)
+         case " $new_libs " in
+         *" $deplib "*) ;;
+         *) func_append new_libs " $deplib" ;;
+         esac
+         ;;
+       *) func_append new_libs " $deplib" ;;
+       esac
+      done
+      compile_deplibs="$new_libs"
+
+
+      func_append compile_command " $compile_deplibs"
+      func_append finalize_command " $finalize_deplibs"
+
+      if test -n "$rpath$xrpath"; then
+       # If the user specified any rpath flags, then add them.
+       for libdir in $rpath $xrpath; do
+         # This is the magic to use -rpath.
+         case "$finalize_rpath " in
+         *" $libdir "*) ;;
+         *) func_append finalize_rpath " $libdir" ;;
+         esac
+       done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+       if test -n "$hardcode_libdir_flag_spec"; then
+         if test -n "$hardcode_libdir_separator"; then
+           if test -z "$hardcode_libdirs"; then
+             hardcode_libdirs="$libdir"
+           else
+             # Just accumulate the unique libdirs.
+             case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+               ;;
+             *)
+               func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+               ;;
+             esac
+           fi
+         else
+           eval flag=\"$hardcode_libdir_flag_spec\"
+           func_append rpath " $flag"
+         fi
+       elif test -n "$runpath_var"; then
+         case "$perm_rpath " in
+         *" $libdir "*) ;;
+         *) func_append perm_rpath " $libdir" ;;
+         esac
+       fi
+       case $host in
+       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+         testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+         case :$dllsearchpath: in
+         *":$libdir:"*) ;;
+         ::) dllsearchpath=$libdir;;
+         *) func_append dllsearchpath ":$libdir";;
+         esac
+         case :$dllsearchpath: in
+         *":$testbindir:"*) ;;
+         ::) dllsearchpath=$testbindir;;
+         *) func_append dllsearchpath ":$testbindir";;
+         esac
+         ;;
+       esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+        test -n "$hardcode_libdirs"; then
+       libdir="$hardcode_libdirs"
+       eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+       if test -n "$hardcode_libdir_flag_spec"; then
+         if test -n "$hardcode_libdir_separator"; then
+           if test -z "$hardcode_libdirs"; then
+             hardcode_libdirs="$libdir"
+           else
+             # Just accumulate the unique libdirs.
+             case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+               ;;
+             *)
+               func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+               ;;
+             esac
+           fi
+         else
+           eval flag=\"$hardcode_libdir_flag_spec\"
+           func_append rpath " $flag"
+         fi
+       elif test -n "$runpath_var"; then
+         case "$finalize_perm_rpath " in
+         *" $libdir "*) ;;
+         *) func_append finalize_perm_rpath " $libdir" ;;
+         esac
+       fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+        test -n "$hardcode_libdirs"; then
+       libdir="$hardcode_libdirs"
+       eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+       # Transform all the library objects into standard objects.
+       compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+       finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+      fi
+
+      func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+      # template prelinking step
+      if test -n "$prelink_cmds"; then
+       func_execute_cmds "$prelink_cmds" 'exit $?'
+      fi
+
+      wrappers_required=yes
+      case $host in
+      *cegcc* | *mingw32ce*)
+        # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+        wrappers_required=no
+        ;;
+      *cygwin* | *mingw* )
+        if test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      *)
+        if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      esac
+      if test "$wrappers_required" = no; then
+       # Replace the output file specification.
+       compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+       link_command="$compile_command$compile_rpath"
+
+       # We have no uninstalled library dependencies, so finalize right now.
+       exit_status=0
+       func_show_eval "$link_command" 'exit_status=$?'
+
+       if test -n "$postlink_cmds"; then
+         func_to_tool_file "$output"
+         postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+         func_execute_cmds "$postlink_cmds" 'exit $?'
+       fi
+
+       # Delete the generated files.
+       if test -f "$output_objdir/${outputname}S.${objext}"; then
+         func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+       fi
+
+       exit $exit_status
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+       compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+       finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+       if test -n "$perm_rpath"; then
+         # We should set the runpath_var.
+         rpath=
+         for dir in $perm_rpath; do
+           func_append rpath "$dir:"
+         done
+         compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+       fi
+       if test -n "$finalize_perm_rpath"; then
+         # We should set the runpath_var.
+         rpath=
+         for dir in $finalize_perm_rpath; do
+           func_append rpath "$dir:"
+         done
+         finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+       fi
+      fi
+
+      if test "$no_install" = yes; then
+       # We don't need to create a wrapper script.
+       link_command="$compile_var$compile_command$compile_rpath"
+       # Replace the output file specification.
+       link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+       # Delete the old output file.
+       $opt_dry_run || $RM $output
+       # Link the executable and exit
+       func_show_eval "$link_command" 'exit $?'
+
+       if test -n "$postlink_cmds"; then
+         func_to_tool_file "$output"
+         postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+         func_execute_cmds "$postlink_cmds" 'exit $?'
+       fi
+
+       exit $EXIT_SUCCESS
+      fi
+
+      if test "$hardcode_action" = relink; then
+       # Fast installation is not supported
+       link_command="$compile_var$compile_command$compile_rpath"
+       relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+       func_warning "this platform does not like uninstalled shared libraries"
+       func_warning "\`$output' will be relinked during installation"
+      else
+       if test "$fast_install" != no; then
+         link_command="$finalize_var$compile_command$finalize_rpath"
+         if test "$fast_install" = yes; then
+           relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+         else
+           # fast_install is set to needless
+           relink_command=
+         fi
+       else
+         link_command="$compile_var$compile_command$compile_rpath"
+         relink_command="$finalize_var$finalize_command$finalize_rpath"
+       fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      func_show_eval "$link_command" 'exit $?'
+
+      if test -n "$postlink_cmds"; then
+       func_to_tool_file "$output_objdir/$outputname"
+       postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+       func_execute_cmds "$postlink_cmds" 'exit $?'
+      fi
+
+      # Now create the wrapper script.
+      func_verbose "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+       # Preserve any variables that may affect compiler behavior
+       for var in $variables_saved_for_relink; do
+         if eval test -z \"\${$var+set}\"; then
+           relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+         elif eval var_value=\$$var; test -z "$var_value"; then
+           relink_command="$var=; export $var; $relink_command"
+         else
+           func_quote_for_eval "$var_value"
+           relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+         fi
+       done
+       relink_command="(cd `pwd`; $relink_command)"
+       relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if not in dry run mode.
+      $opt_dry_run || {
+       # win32 will think the script is a binary if it has
+       # a .exe suffix, so we strip it off here.
+       case $output in
+         *.exe) func_stripname '' '.exe' "$output"
+                output=$func_stripname_result ;;
+       esac
+       # test for cygwin because mv fails w/o .exe extensions
+       case $host in
+         *cygwin*)
+           exeext=.exe
+           func_stripname '' '.exe' "$outputname"
+           outputname=$func_stripname_result ;;
+         *) exeext= ;;
+       esac
+       case $host in
+         *cygwin* | *mingw* )
+           func_dirname_and_basename "$output" "" "."
+           output_name=$func_basename_result
+           output_path=$func_dirname_result
+           cwrappersource="$output_path/$objdir/lt-$output_name.c"
+           cwrapper="$output_path/$output_name.exe"
+           $RM $cwrappersource $cwrapper
+           trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+           func_emit_cwrapperexe_src > $cwrappersource
+
+           # The wrapper executable is built using the $host compiler,
+           # because it contains $host paths and files. If cross-
+           # compiling, it, like the target executable, must be
+           # executed on the $host or under an emulation environment.
+           $opt_dry_run || {
+             $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+             $STRIP $cwrapper
+           }
+
+           # Now, create the wrapper script for func_source use:
+           func_ltwrapper_scriptname $cwrapper
+           $RM $func_ltwrapper_scriptname_result
+           trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+           $opt_dry_run || {
+             # note: this script will not be executed, so do not chmod.
+             if test "x$build" = "x$host" ; then
+               $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+             else
+               func_emit_wrapper no > $func_ltwrapper_scriptname_result
+             fi
+           }
+         ;;
+         * )
+           $RM $output
+           trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+           func_emit_wrapper no > $output
+           chmod +x $output
+         ;;
+       esac
+      }
+      exit $EXIT_SUCCESS
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+       oldobjs="$libobjs_save $symfileobj"
+       addlibs="$convenience"
+       build_libtool_libs=no
+      else
+       if test "$build_libtool_libs" = module; then
+         oldobjs="$libobjs_save"
+         build_libtool_libs=no
+       else
+         oldobjs="$old_deplibs $non_pic_objects"
+         if test "$preload" = yes && test -f "$symfileobj"; then
+           func_append oldobjs " $symfileobj"
+         fi
+       fi
+       addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+       gentop="$output_objdir/${outputname}x"
+       func_append generated " $gentop"
+
+       func_extract_archives $gentop $addlibs
+       func_append oldobjs " $func_extract_archives_result"
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+       cmds=$old_archive_from_new_cmds
+      else
+
+       # Add any objects from preloaded convenience libraries
+       if test -n "$dlprefiles"; then
+         gentop="$output_objdir/${outputname}x"
+         func_append generated " $gentop"
+
+         func_extract_archives $gentop $dlprefiles
+         func_append oldobjs " $func_extract_archives_result"
+       fi
+
+       # POSIX demands no paths to be encoded in archives.  We have
+       # to avoid creating archives with duplicate basenames if we
+       # might have to extract them afterwards, e.g., when creating a
+       # static archive out of a convenience library, or when linking
+       # the entirety of a libtool archive into another (currently
+       # not supported by libtool).
+       if (for obj in $oldobjs
+           do
+             func_basename "$obj"
+             $ECHO "$func_basename_result"
+           done | sort | sort -uc >/dev/null 2>&1); then
+         :
+       else
+         echo "copying selected object files to avoid basename conflicts..."
+         gentop="$output_objdir/${outputname}x"
+         func_append generated " $gentop"
+         func_mkdir_p "$gentop"
+         save_oldobjs=$oldobjs
+         oldobjs=
+         counter=1
+         for obj in $save_oldobjs
+         do
+           func_basename "$obj"
+           objbase="$func_basename_result"
+           case " $oldobjs " in
+           " ") oldobjs=$obj ;;
+           *[\ /]"$objbase "*)
+             while :; do
+               # Make sure we don't pick an alternate name that also
+               # overlaps.
+               newobj=lt$counter-$objbase
+               func_arith $counter + 1
+               counter=$func_arith_result
+               case " $oldobjs " in
+               *[\ /]"$newobj "*) ;;
+               *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+               esac
+             done
+             func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+             func_append oldobjs " $gentop/$newobj"
+             ;;
+           *) func_append oldobjs " $obj" ;;
+           esac
+         done
+       fi
+       func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+       tool_oldlib=$func_to_tool_file_result
+       eval cmds=\"$old_archive_cmds\"
+
+       func_len " $cmds"
+       len=$func_len_result
+       if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+         cmds=$old_archive_cmds
+       elif test -n "$archiver_list_spec"; then
+         func_verbose "using command file archive linking..."
+         for obj in $oldobjs
+         do
+           func_to_tool_file "$obj"
+           $ECHO "$func_to_tool_file_result"
+         done > $output_objdir/$libname.libcmd
+         func_to_tool_file "$output_objdir/$libname.libcmd"
+         oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+         cmds=$old_archive_cmds
+       else
+         # the command line is too long to link in one step, link in parts
+         func_verbose "using piecewise archive linking..."
+         save_RANLIB=$RANLIB
+         RANLIB=:
+         objlist=
+         concat_cmds=
+         save_oldobjs=$oldobjs
+         oldobjs=
+         # Is there a better way of finding the last object in the list?
+         for obj in $save_oldobjs
+         do
+           last_oldobj=$obj
+         done
+         eval test_cmds=\"$old_archive_cmds\"
+         func_len " $test_cmds"
+         len0=$func_len_result
+         len=$len0
+         for obj in $save_oldobjs
+         do
+           func_len " $obj"
+           func_arith $len + $func_len_result
+           len=$func_arith_result
+           func_append objlist " $obj"
+           if test "$len" -lt "$max_cmd_len"; then
+             :
+           else
+             # the above command should be used before it gets too long
+             oldobjs=$objlist
+             if test "$obj" = "$last_oldobj" ; then
+               RANLIB=$save_RANLIB
+             fi
+             test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+             eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+             objlist=
+             len=$len0
+           fi
+         done
+         RANLIB=$save_RANLIB
+         oldobjs=$objlist
+         if test "X$oldobjs" = "X" ; then
+           eval cmds=\"\$concat_cmds\"
+         else
+           eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+         fi
+       fi
+      fi
+      func_execute_cmds "$cmds" 'exit $?'
+    done
+
+    test -n "$generated" && \
+      func_show_eval "${RM}r$generated"
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      func_verbose "creating $output"
+
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+       if eval test -z \"\${$var+set}\"; then
+         relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+       elif eval var_value=\$$var; test -z "$var_value"; then
+         relink_command="$var=; export $var; $relink_command"
+       else
+         func_quote_for_eval "$var_value"
+         relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+       fi
+      done
+      # Quote the link command for shipping.
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      if test "$hardcode_automatic" = yes ; then
+       relink_command=
+      fi
+
+      # Only create the output if not a dry run.
+      $opt_dry_run || {
+       for installed in no yes; do
+         if test "$installed" = yes; then
+           if test -z "$install_libdir"; then
+             break
+           fi
+           output="$output_objdir/$outputname"i
+           # Replace all uninstalled libtool libraries with the installed ones
+           newdependency_libs=
+           for deplib in $dependency_libs; do
+             case $deplib in
+             *.la)
+               func_basename "$deplib"
+               name="$func_basename_result"
+               func_resolve_sysroot "$deplib"
+               eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+               test -z "$libdir" && \
+                 func_fatal_error "\`$deplib' is not a valid libtool archive"
+               func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+               ;;
+             -L*)
+               func_stripname -L '' "$deplib"
+               func_replace_sysroot "$func_stripname_result"
+               func_append newdependency_libs " -L$func_replace_sysroot_result"
+               ;;
+             -R*)
+               func_stripname -R '' "$deplib"
+               func_replace_sysroot "$func_stripname_result"
+               func_append newdependency_libs " -R$func_replace_sysroot_result"
+               ;;
+             *) func_append newdependency_libs " $deplib" ;;
+             esac
+           done
+           dependency_libs="$newdependency_libs"
+           newdlfiles=
+
+           for lib in $dlfiles; do
+             case $lib in
+             *.la)
+               func_basename "$lib"
+               name="$func_basename_result"
+               eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+               test -z "$libdir" && \
+                 func_fatal_error "\`$lib' is not a valid libtool archive"
+               func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+               ;;
+             *) func_append newdlfiles " $lib" ;;
+             esac
+           done
+           dlfiles="$newdlfiles"
+           newdlprefiles=
+           for lib in $dlprefiles; do
+             case $lib in
+             *.la)
+               # Only pass preopened files to the pseudo-archive (for
+               # eventual linking with the app. that links it) if we
+               # didn't already link the preopened objects directly into
+               # the library:
+               func_basename "$lib"
+               name="$func_basename_result"
+               eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+               test -z "$libdir" && \
+                 func_fatal_error "\`$lib' is not a valid libtool archive"
+               func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+               ;;
+             esac
+           done
+           dlprefiles="$newdlprefiles"
+         else
+           newdlfiles=
+           for lib in $dlfiles; do
+             case $lib in
+               [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+               *) abs=`pwd`"/$lib" ;;
+             esac
+             func_append newdlfiles " $abs"
+           done
+           dlfiles="$newdlfiles"
+           newdlprefiles=
+           for lib in $dlprefiles; do
+             case $lib in
+               [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+               *) abs=`pwd`"/$lib" ;;
+             esac
+             func_append newdlprefiles " $abs"
+           done
+           dlprefiles="$newdlprefiles"
+         fi
+         $RM $output
+         # place dlname in correct position for cygwin
+         # In fact, it would be nice if we could use this code for all target
+         # systems that can't hard-code library paths into their executables
+         # and that have no shared library path variable independent of PATH,
+         # but it turns out we can't easily determine that from inspecting
+         # libtool variables, so we have to hard-code the OSs to which it
+         # applies here; at the moment, that means platforms that use the PE
+         # object format with DLL files.  See the long comment at the top of
+         # tests/bindir.at for full details.
+         tdlname=$dlname
+         case $host,$output,$installed,$module,$dlname in
+           *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+             # If a -bindir argument was supplied, place the dll there.
+             if test "x$bindir" != x ;
+             then
+               func_relative_path "$install_libdir" "$bindir"
+               tdlname=$func_relative_path_result$dlname
+             else
+               # Otherwise fall back on heuristic.
+               tdlname=../bin/$dlname
+             fi
+             ;;
+         esac
+         $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+         if test "$installed" = no && test "$need_relink" = yes; then
+           $ECHO >> $output "\
+relink_command=\"$relink_command\""
+         fi
+       done
+      }
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+      ;;
+    esac
+    exit $EXIT_SUCCESS
+}
+
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+    func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+    $opt_debug
+    RM="$nonopt"
+    files=
+    rmforce=
+    exit_status=0
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    for arg
+    do
+      case $arg in
+      -f) func_append RM " $arg"; rmforce=yes ;;
+      -*) func_append RM " $arg" ;;
+      *) func_append files " $arg" ;;
+      esac
+    done
+
+    test -z "$RM" && \
+      func_fatal_help "you must specify an RM program"
+
+    rmdirs=
+
+    for file in $files; do
+      func_dirname "$file" "" "."
+      dir="$func_dirname_result"
+      if test "X$dir" = X.; then
+       odir="$objdir"
+      else
+       odir="$dir/$objdir"
+      fi
+      func_basename "$file"
+      name="$func_basename_result"
+      test "$opt_mode" = uninstall && odir="$dir"
+
+      # Remember odir for removal later, being careful to avoid duplicates
+      if test "$opt_mode" = clean; then
+       case " $rmdirs " in
+         *" $odir "*) ;;
+         *) func_append rmdirs " $odir" ;;
+       esac
+      fi
+
+      # Don't error if the file doesn't exist and rm -f was used.
+      if { test -L "$file"; } >/dev/null 2>&1 ||
+        { test -h "$file"; } >/dev/null 2>&1 ||
+        test -f "$file"; then
+       :
+      elif test -d "$file"; then
+       exit_status=1
+       continue
+      elif test "$rmforce" = yes; then
+       continue
+      fi
+
+      rmfiles="$file"
+
+      case $name in
+      *.la)
+       # Possibly a libtool archive, so verify it.
+       if func_lalib_p "$file"; then
+         func_source $dir/$name
+
+         # Delete the libtool libraries and symlinks.
+         for n in $library_names; do
+           func_append rmfiles " $odir/$n"
+         done
+         test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+         case "$opt_mode" in
+         clean)
+           case " $library_names " in
+           *" $dlname "*) ;;
+           *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+           esac
+           test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+           ;;
+         uninstall)
+           if test -n "$library_names"; then
+             # Do each command in the postuninstall commands.
+             func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+           fi
+
+           if test -n "$old_library"; then
+             # Do each command in the old_postuninstall commands.
+             func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+           fi
+           # FIXME: should reinstall the best remaining shared library.
+           ;;
+         esac
+       fi
+       ;;
+
+      *.lo)
+       # Possibly a libtool object, so verify it.
+       if func_lalib_p "$file"; then
+
+         # Read the .lo file
+         func_source $dir/$name
+
+         # Add PIC object to the list of files to remove.
+         if test -n "$pic_object" &&
+            test "$pic_object" != none; then
+           func_append rmfiles " $dir/$pic_object"
+         fi
+
+         # Add non-PIC object to the list of files to remove.
+         if test -n "$non_pic_object" &&
+            test "$non_pic_object" != none; then
+           func_append rmfiles " $dir/$non_pic_object"
+         fi
+       fi
+       ;;
+
+      *)
+       if test "$opt_mode" = clean ; then
+         noexename=$name
+         case $file in
+         *.exe)
+           func_stripname '' '.exe' "$file"
+           file=$func_stripname_result
+           func_stripname '' '.exe' "$name"
+           noexename=$func_stripname_result
+           # $file with .exe has already been added to rmfiles,
+           # add $file without .exe
+           func_append rmfiles " $file"
+           ;;
+         esac
+         # Do a test to see if this is a libtool program.
+         if func_ltwrapper_p "$file"; then
+           if func_ltwrapper_executable_p "$file"; then
+             func_ltwrapper_scriptname "$file"
+             relink_command=
+             func_source $func_ltwrapper_scriptname_result
+             func_append rmfiles " $func_ltwrapper_scriptname_result"
+           else
+             relink_command=
+             func_source $dir/$noexename
+           fi
+
+           # note $name still contains .exe if it was in $file originally
+           # as does the version of $file that was added into $rmfiles
+           func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+           if test "$fast_install" = yes && test -n "$relink_command"; then
+             func_append rmfiles " $odir/lt-$name"
+           fi
+           if test "X$noexename" != "X$name" ; then
+             func_append rmfiles " $odir/lt-${noexename}.c"
+           fi
+         fi
+       fi
+       ;;
+      esac
+      func_show_eval "$RM $rmfiles" 'exit_status=1'
+    done
+
+    # Try to remove the ${objdir}s in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+       func_show_eval "rmdir $dir >/dev/null 2>&1"
+      fi
+    done
+
+    exit $exit_status
+}
+
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+    func_mode_uninstall ${1+"$@"}
+
+test -z "$opt_mode" && {
+  help="$generic_help"
+  func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+  func_fatal_help "invalid operation mode \`$opt_mode'"
+
+if test -n "$exec_cmd"; then
+  eval exec "$exec_cmd"
+  exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries.  Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them.  This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration.  But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
diff --git a/m4/.gitignore b/m4/.gitignore
new file mode 100644 (file)
index 0000000..f883d98
--- /dev/null
@@ -0,0 +1,16 @@
+gettext.m4
+iconv.m4
+lib-ld.m4
+lib-link.m4
+lib-prefix.m4
+nls.m4
+po.m4
+progtest.m4
+argz.m4
+intltool.m4
+libtool.m4
+ltdl.m4
+ltoptions.m4
+ltsugar.m4
+ltversion.m4
+lt~obsolete.m4
diff --git a/m4/acx_lirc.m4 b/m4/acx_lirc.m4
deleted file mode 100644 (file)
index d3f8ea7..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-AC_DEFUN([ACX_LIRC], [
-LIRC_CFLAGS=
-LIRC_LIBS=
-AC_CHECK_HEADER(lirc/lirc_client.h,[AC_CHECK_LIB(lirc_client,lirc_init,[HAVE_LIRC=1
-LIRC_LIBS=-llirc_client],HAVE_LIRC=0)],HAVE_LIRC=0)
-])
diff --git a/m4/acx_pthread.m4 b/m4/acx_pthread.m4
deleted file mode 100644 (file)
index cbd6bfa..0000000
+++ /dev/null
@@ -1,348 +0,0 @@
-dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
-dnl
-dnl @summary figure out how to build C programs using POSIX threads
-dnl
-dnl This macro figures out how to build C programs using POSIX threads.
-dnl It sets the PTHREAD_LIBS output variable to the threads library and
-dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
-dnl C compiler flags that are needed. (The user can also force certain
-dnl compiler flags/libs to be tested by setting these environment
-dnl variables.)
-dnl
-dnl Also sets PTHREAD_CC to any special C compiler that is needed for
-dnl multi-threaded programs (defaults to the value of CC otherwise).
-dnl (This is necessary on AIX to use the special cc_r compiler alias.)
-dnl
-dnl NOTE: You are assumed to not only compile your program with these
-dnl flags, but also link it with them as well. e.g. you should link
-dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
-dnl $LIBS
-dnl
-dnl If you are only building threads programs, you may wish to use
-dnl these variables in your default LIBS, CFLAGS, and CC:
-dnl
-dnl        LIBS="$PTHREAD_LIBS $LIBS"
-dnl        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-dnl        CC="$PTHREAD_CC"
-dnl
-dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
-dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
-dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
-dnl
-dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
-dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
-dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
-dnl default action will define HAVE_PTHREAD.
-dnl
-dnl Please let the authors know if this macro fails on any platform, or
-dnl if you have any other suggestions or comments. This macro was based
-dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
-dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
-dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
-dnl We are also grateful for the helpful feedback of numerous users.
-dnl
-dnl @category InstalledPackages
-dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
-dnl @version 2006-05-29
-dnl @license GPLWithACException
-dnl
-dnl Checks for GCC shared/pthread inconsistency based on work by
-dnl Marcin Owsiany <marcin@owsiany.pl>
-
-
-AC_DEFUN([ACX_PTHREAD], [
-AC_REQUIRE([AC_CANONICAL_HOST])
-AC_LANG_SAVE
-AC_LANG_C
-acx_pthread_ok=no
-
-# We used to check for pthread.h first, but this fails if pthread.h
-# requires special compiler flags (e.g. on True64 or Sequent).
-# It gets checked for in the link test anyway.
-
-# First of all, check if the user has set any of the PTHREAD_LIBS,
-# etcetera environment variables, and if threads linking works using
-# them:
-if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
-        save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-        save_LIBS="$LIBS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
-        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
-        AC_MSG_RESULT($acx_pthread_ok)
-        if test x"$acx_pthread_ok" = xno; then
-                PTHREAD_LIBS=""
-                PTHREAD_CFLAGS=""
-        fi
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-fi
-
-# We must check for the threads library under a number of different
-# names; the ordering is very important because some systems
-# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
-# libraries is broken (non-POSIX).
-
-# Create a list of thread flags to try.  Items starting with a "-" are
-# C compiler flags, and other items are library names, except for "none"
-# which indicates that we try without any flags at all, and "pthread-config"
-# which is a program returning the flags for the Pth emulation library.
-
-acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
-
-# The ordering *is* (sometimes) important.  Some notes on the
-# individual items follow:
-
-# pthreads: AIX (must check this before -lpthread)
-# none: in case threads are in libc; should be tried before -Kthread and
-#       other compiler flags to prevent continual compiler warnings
-# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
-# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
-# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
-# -pthreads: Solaris/gcc
-# -mthreads: Mingw32/gcc, Lynx/gcc
-# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
-#      doesn't hurt to check since this sometimes defines pthreads too;
-#      also defines -D_REENTRANT)
-#      ... -mt is also the pthreads flag for HP/aCC
-# pthread: Linux, etcetera
-# --thread-safe: KAI C++
-# pthread-config: use pthread-config program (for GNU Pth library)
-
-case "${host_cpu}-${host_os}" in
-        *solaris*)
-
-        # On Solaris (at least, for some versions), libc contains stubbed
-        # (non-functional) versions of the pthreads routines, so link-based
-        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
-        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
-        # a function called by this macro, so we could check for that, but
-        # who knows whether they'll stub that too in a future libc.)  So,
-        # we'll just look for -pthreads and -lpthread first:
-
-        acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
-        ;;
-esac
-
-if test x"$acx_pthread_ok" = xno; then
-for flag in $acx_pthread_flags; do
-
-        case $flag in
-                none)
-                AC_MSG_CHECKING([whether pthreads work without any flags])
-                ;;
-
-                -*)
-                AC_MSG_CHECKING([whether pthreads work with $flag])
-                PTHREAD_CFLAGS="$flag"
-                ;;
-
-               pthread-config)
-               AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
-               if test x"$acx_pthread_config" = xno; then continue; fi
-               PTHREAD_CFLAGS="`pthread-config --cflags`"
-               PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
-               ;;
-
-                *)
-                AC_MSG_CHECKING([for the pthreads library -l$flag])
-                PTHREAD_LIBS="-l$flag"
-                ;;
-        esac
-
-        save_LIBS="$LIBS"
-        save_CFLAGS="$CFLAGS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
-        # Check for various functions.  We must include pthread.h,
-        # since some functions may be macros.  (On the Sequent, we
-        # need a special flag -Kthread to make this header compile.)
-        # We check for pthread_join because it is in -lpthread on IRIX
-        # while pthread_create is in libc.  We check for pthread_attr_init
-        # due to DEC craziness with -lpthreads.  We check for
-        # pthread_cleanup_push because it is one of the few pthread
-        # functions on Solaris that doesn't have a non-functional libc stub.
-        # We try pthread_create on general principles.
-        AC_TRY_LINK([#include <pthread.h>],
-                    [pthread_t th; pthread_join(th, 0);
-                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
-                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
-                    [acx_pthread_ok=yes])
-
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-
-        AC_MSG_RESULT($acx_pthread_ok)
-        if test "x$acx_pthread_ok" = xyes; then
-                break;
-        fi
-
-        PTHREAD_LIBS=""
-        PTHREAD_CFLAGS=""
-done
-fi
-
-# Various other checks:
-if test "x$acx_pthread_ok" = xyes; then
-        save_LIBS="$LIBS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
-        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
-       AC_MSG_CHECKING([for joinable pthread attribute])
-       attr_name=unknown
-       for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
-           AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
-                        [attr_name=$attr; break])
-       done
-        AC_MSG_RESULT($attr_name)
-        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
-            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
-                               [Define to necessary symbol if this constant
-                                uses a non-standard name on your system.])
-        fi
-
-        AC_MSG_CHECKING([if more special flags are required for pthreads])
-        flag=no
-        case "${host_cpu}-${host_os}" in
-            *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
-            *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
-        esac
-        AC_MSG_RESULT(${flag})
-        if test "x$flag" != xno; then
-            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
-        fi
-
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-        # More AIX lossage: must compile with xlc_r or cc_r
-       if test x"$GCC" != xyes; then
-          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
-        else
-          PTHREAD_CC=$CC
-       fi
-
-   # The next part tries to detect GCC inconsistency with -shared on some
-   # architectures and systems. The problem is that in certain
-   # configurations, when -shared is specified, GCC "forgets" to
-   # internally use various flags which are still necessary.
-
-   AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies])
-   check_inconsistencies=yes
-   case "${host_cpu}-${host_os}" in
-     *-darwin*) check_inconsistencies=no ;;
-   esac
-   if test x"$GCC" != xyes -o "x$check_inconsistencies" != xyes ; then
-      AC_MSG_RESULT([no])
-   else
-      AC_MSG_RESULT([yes])
-
-      # In order not to create several levels of indentation, we test
-      # the value of "$ok" until we find out the cure or run out of
-      # ideas.
-      ok="no"
-
-      #
-      # Prepare the flags
-      #
-      save_CFLAGS="$CFLAGS"
-      save_LIBS="$LIBS"
-      save_CC="$CC"
-      # Try with the flags determined by the earlier checks.
-      #
-      # -Wl,-z,defs forces link-time symbol resolution, so that the
-      # linking checks with -shared actually have any value
-      #
-      # FIXME: -fPIC is required for -shared on many architectures,
-      # so we specify it here, but the right way would probably be to
-      # properly detect whether it is actually required.
-      CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
-      LIBS="$PTHREAD_LIBS $LIBS"
-      CC="$PTHREAD_CC"
-
-      AC_MSG_CHECKING([whether -pthread is sufficient with -shared])
-      AC_TRY_LINK([#include <pthread.h>],
-         [pthread_t th; pthread_join(th, 0);
-         pthread_attr_init(0); pthread_cleanup_push(0, 0);
-         pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
-         [ok=yes])
-
-      if test "x$ok" = xyes; then
-         AC_MSG_RESULT([yes])
-      else
-         AC_MSG_RESULT([no])
-      fi
-
-      #
-      # Linux gcc on some architectures such as mips/mipsel forgets
-      # about -lpthread
-      #
-      if test x"$ok" = xno; then
-         AC_MSG_CHECKING([whether -lpthread fixes that])
-         LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
-         AC_TRY_LINK([#include <pthread.h>],
-            [pthread_t th; pthread_join(th, 0);
-            pthread_attr_init(0); pthread_cleanup_push(0, 0);
-            pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
-            [ok=yes])
-
-         if test "x$ok" = xyes; then
-            AC_MSG_RESULT([yes])
-            PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
-         else
-            AC_MSG_RESULT([no])
-         fi
-      fi
-      #
-      # FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc
-      #
-      if test x"$ok" = xno; then
-         AC_MSG_CHECKING([whether -lc_r fixes that])
-         LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
-         AC_TRY_LINK([#include <pthread.h>],
-             [pthread_t th; pthread_join(th, 0);
-              pthread_attr_init(0); pthread_cleanup_push(0, 0);
-              pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
-             [ok=yes])
-
-         if test "x$ok" = xyes; then
-            AC_MSG_RESULT([yes])
-            PTHREAD_LIBS="-lc_r $PTHREAD_LIBS"
-         else
-            AC_MSG_RESULT([no])
-         fi
-      fi
-      if test x"$ok" = xno; then
-         # OK, we have run out of ideas
-         AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries])
-
-         # so it's not safe to assume that we may use pthreads
-         acx_pthread_ok=no
-      fi
-
-      CFLAGS="$save_CFLAGS"
-      LIBS="$save_LIBS"
-      CC="$save_CC"
-   fi
-else
-        PTHREAD_CC="$CC"
-fi
-
-AC_SUBST(PTHREAD_LIBS)
-AC_SUBST(PTHREAD_CFLAGS)
-AC_SUBST(PTHREAD_CC)
-
-# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
-if test x"$acx_pthread_ok" = xyes; then
-        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
-        :
-else
-        acx_pthread_ok=no
-        $2
-fi
-AC_LANG_RESTORE
-])dnl ACX_PTHREAD
diff --git a/m4/attributes.m4 b/m4/attributes.m4
deleted file mode 100644 (file)
index 28fac27..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-dnl Macros to check the presence of generic (non-typed) symbols.
-dnl Copyright (c) 2006-2008 Diego Pettenò <flameeyes@gmail.com>
-dnl Copyright (c) 2006-2008 xine project
-dnl
-dnl This program is free software; you can redistribute it and/or modify
-dnl it under the terms of the GNU General Public License as published by
-dnl the Free Software Foundation; either version 2, or (at your option)
-dnl any later version.
-dnl
-dnl This program is distributed in the hope that it will be useful,
-dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
-dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-dnl GNU General Public License for more details.
-dnl
-dnl You should have received a copy of the GNU General Public License
-dnl along with this program; if not, write to the Free Software
-dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-dnl 02110-1301, USA.
-dnl
-dnl As a special exception, the copyright owners of the
-dnl macro gives unlimited permission to copy, distribute and modify the
-dnl configure scripts that are the output of Autoconf when processing the
-dnl Macro. You need not follow the terms of the GNU General Public
-dnl License when using or distributing such scripts, even though portions
-dnl of the text of the Macro appear in them. The GNU General Public
-dnl License (GPL) does govern all other use of the material that
-dnl constitutes the Autoconf Macro.
-dnl 
-dnl This special exception to the GPL applies to versions of the
-dnl Autoconf Macro released by this project. When you make and
-dnl distribute a modified version of the Autoconf Macro, you may extend
-dnl this special exception to the GPL to apply to your modified version as
-dnl well.
-
-dnl Check if the flag is supported by compiler
-dnl CC_CHECK_CFLAGS_SILENT([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
-
-AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [
-  AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]),
-    [ac_save_CFLAGS="$CFLAGS"
-     CFLAGS="$CFLAGS $1"
-     AC_COMPILE_IFELSE([int a;],
-       [eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"],
-       [eval "AS_TR_SH([cc_cv_cflags_$1])='no'"])
-     CFLAGS="$ac_save_CFLAGS"
-    ])
-
-  AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
-    [$2], [$3])
-])
-
-dnl Check if the flag is supported by compiler (cacheable)
-dnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
-
-AC_DEFUN([CC_CHECK_CFLAGS], [
-  AC_CACHE_CHECK([if $CC supports $1 flag],
-    AS_TR_SH([cc_cv_cflags_$1]),
-    CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!
-  )
-
-  AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
-    [$2], [$3])
-])
-
-dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found])
-dnl Check for CFLAG and appends them to CFLAGS if supported
-AC_DEFUN([CC_CHECK_CFLAG_APPEND], [
-  AC_CACHE_CHECK([if $CC supports $1 flag],
-    AS_TR_SH([cc_cv_cflags_$1]),
-    CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!
-  )
-
-  AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
-    [CFLAGS="$CFLAGS $1"; DEBUG_CFLAGS="$DEBUG_CFLAGS $1"; $2], [$3])
-])
-
-dnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not])
-AC_DEFUN([CC_CHECK_CFLAGS_APPEND], [
-  for flag in $1; do
-    CC_CHECK_CFLAG_APPEND($flag, [$2], [$3])
-  done
-])
-
-dnl Check if the flag is supported by linker (cacheable)
-dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
-
-AC_DEFUN([CC_CHECK_LDFLAGS], [
-  AC_CACHE_CHECK([if $CC supports $1 flag],
-    AS_TR_SH([cc_cv_ldflags_$1]),
-    [ac_save_LDFLAGS="$LDFLAGS"
-     LDFLAGS="$LDFLAGS $1"
-     AC_LINK_IFELSE([int main() { return 1; }],
-       [eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"],
-       [eval "AS_TR_SH([cc_cv_ldflags_$1])="])
-     LDFLAGS="$ac_save_LDFLAGS"
-    ])
-
-  AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes],
-    [$2], [$3])
-])
-
-dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for
-dnl the current linker to avoid undefined references in a shared object.
-AC_DEFUN([CC_NOUNDEFINED], [
-  dnl We check $host for which systems to enable this for.
-  AC_REQUIRE([AC_CANONICAL_HOST])
-
-  case $host in
-     dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads
-     dnl are requested, as different implementations are present; to avoid problems
-     dnl use -Wl,-z,defs only for those platform not behaving this way.
-     *-freebsd* | *-openbsd*) ;;
-     *)
-        dnl First of all check for the --no-undefined variant of GNU ld. This allows
-        dnl for a much more readable commandline, so that people can understand what
-        dnl it does without going to look for what the heck -z defs does.
-        for possible_flags in "-Wl,--no-undefined" "-Wl,-z,defs"; do
-          CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"])
-         break
-        done
-       ;;
-  esac
-
-  AC_SUBST([LDFLAGS_NOUNDEFINED])
-])
-
-dnl Check for a -Werror flag or equivalent. -Werror is the GCC
-dnl and ICC flag that tells the compiler to treat all the warnings
-dnl as fatal. We usually need this option to make sure that some
-dnl constructs (like attributes) are not simply ignored.
-dnl
-dnl Other compilers don't support -Werror per se, but they support
-dnl an equivalent flag:
-dnl  - Sun Studio compiler supports -errwarn=%all
-AC_DEFUN([CC_CHECK_WERROR], [
-  AC_CACHE_CHECK(
-    [for $CC way to treat warnings as errors],
-    [cc_cv_werror],
-    [CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror],
-      [CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])])
-    ])
-])
-
-AC_DEFUN([CC_CHECK_ATTRIBUTE], [
-  AC_REQUIRE([CC_CHECK_WERROR])
-  AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))],
-    AS_TR_SH([cc_cv_attribute_$1]),
-    [ac_save_CFLAGS="$CFLAGS"
-     CFLAGS="$CFLAGS $cc_cv_werror"
-     AC_COMPILE_IFELSE([$3],
-       [eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"],
-       [eval "AS_TR_SH([cc_cv_attribute_$1])='no'"])
-     CFLAGS="$ac_save_CFLAGS"
-    ])
-
-  AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes],
-    [AC_DEFINE(
-       AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1,
-         [Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))]
-         )
-     $4],
-    [$5])
-])
-
-AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [
-  CC_CHECK_ATTRIBUTE(
-    [constructor],,
-    [void __attribute__((constructor)) ctor() { int a; }],
-    [$1], [$2])
-])
-
-AC_DEFUN([CC_ATTRIBUTE_FORMAT], [
-  CC_CHECK_ATTRIBUTE(
-    [format], [format(printf, n, n)],
-    [void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }],
-    [$1], [$2])
-])
-
-AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [
-  CC_CHECK_ATTRIBUTE(
-    [format_arg], [format_arg(printf)],
-    [char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }],
-    [$1], [$2])
-])
-
-AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [
-  CC_CHECK_ATTRIBUTE(
-    [visibility_$1], [visibility("$1")],
-    [void __attribute__((visibility("$1"))) $1_function() { }],
-    [$2], [$3])
-])
-
-AC_DEFUN([CC_ATTRIBUTE_NONNULL], [
-  CC_CHECK_ATTRIBUTE(
-    [nonnull], [nonnull()],
-    [void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }],
-    [$1], [$2])
-])
-
-AC_DEFUN([CC_ATTRIBUTE_UNUSED], [
-  CC_CHECK_ATTRIBUTE(
-    [unused], ,
-    [void some_function(void *foo, __attribute__((unused)) void *bar);],
-    [$1], [$2])
-])
-
-AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [
-  CC_CHECK_ATTRIBUTE(
-    [sentinel], ,
-    [void some_function(void *foo, ...) __attribute__((sentinel));],
-    [$1], [$2])
-])
-
-AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [
-  CC_CHECK_ATTRIBUTE(
-    [deprecated], ,
-    [void some_function(void *foo, ...) __attribute__((deprecated));],
-    [$1], [$2])
-])
-
-AC_DEFUN([CC_ATTRIBUTE_ALIAS], [
-  CC_CHECK_ATTRIBUTE(
-    [alias], [weak, alias],
-    [void other_function(void *foo) { }
-     void some_function(void *foo) __attribute__((weak, alias("other_function")));],
-    [$1], [$2])
-])
-
-AC_DEFUN([CC_ATTRIBUTE_MALLOC], [
-  CC_CHECK_ATTRIBUTE(
-    [malloc], ,
-    [void * __attribute__((malloc)) my_alloc(int n);],
-    [$1], [$2])
-])
-
-AC_DEFUN([CC_ATTRIBUTE_PACKED], [
-  CC_CHECK_ATTRIBUTE(
-    [packed], ,
-    [struct astructure { char a; int b; long c; void *d; } __attribute__((packed));],
-    [$1], [$2])
-])
-
-AC_DEFUN([CC_ATTRIBUTE_CONST], [
-  CC_CHECK_ATTRIBUTE(
-    [const], ,
-    [int __attribute__((const)) twopow(int n) { return 1 << n; } ],
-    [$1], [$2])
-])
-
-AC_DEFUN([CC_FLAG_VISIBILITY], [
-  AC_REQUIRE([CC_CHECK_WERROR])
-  AC_CACHE_CHECK([if $CC supports -fvisibility=hidden],
-    [cc_cv_flag_visibility],
-    [cc_flag_visibility_save_CFLAGS="$CFLAGS"
-     CFLAGS="$CFLAGS $cc_cv_werror"
-     CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden],
-       cc_cv_flag_visibility='yes',
-       cc_cv_flag_visibility='no')
-     CFLAGS="$cc_flag_visibility_save_CFLAGS"])
-  
-  AS_IF([test "x$cc_cv_flag_visibility" = "xyes"],
-    [AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1,
-       [Define this if the compiler supports the -fvisibility flag])
-     $1],
-    [$2])
-])
-
-AC_DEFUN([CC_FUNC_EXPECT], [
-  AC_REQUIRE([CC_CHECK_WERROR])
-  AC_CACHE_CHECK([if compiler has __builtin_expect function],
-    [cc_cv_func_expect],
-    [ac_save_CFLAGS="$CFLAGS"
-     CFLAGS="$CFLAGS $cc_cv_werror"
-     AC_COMPILE_IFELSE(
-       [int some_function() {
-        int a = 3;
-        return (int)__builtin_expect(a, 3);
-       }],
-       [cc_cv_func_expect=yes],
-       [cc_cv_func_expect=no])
-     CFLAGS="$ac_save_CFLAGS"
-    ])
-
-  AS_IF([test "x$cc_cv_func_expect" = "xyes"],
-    [AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1,
-     [Define this if the compiler supports __builtin_expect() function])
-     $1],
-    [$2])
-])
-
-AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [
-  AC_REQUIRE([CC_CHECK_WERROR])
-  AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported],
-    [cc_cv_attribute_aligned],
-    [ac_save_CFLAGS="$CFLAGS"
-     CFLAGS="$CFLAGS $cc_cv_werror"
-     for cc_attribute_align_try in 64 32 16 8 4 2; do
-        AC_COMPILE_IFELSE([
-          int main() {
-            static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0;
-            return c;
-          }], [cc_cv_attribute_aligned=$cc_attribute_align_try; break])
-     done
-     CFLAGS="$ac_save_CFLAGS"
-  ])
-
-  if test "x$cc_cv_attribute_aligned" != "x"; then
-     AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned],
-       [Define the highest alignment supported])
-  fi
-])
diff --git a/m4/ax_check_define.m4 b/m4/ax_check_define.m4
new file mode 100644 (file)
index 0000000..4bc6948
--- /dev/null
@@ -0,0 +1,92 @@
+# ===========================================================================
+#      http://www.gnu.org/software/autoconf-archive/ax_check_define.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AC_CHECK_DEFINE([symbol], [ACTION-IF-FOUND], [ACTION-IF-NOT])
+#   AX_CHECK_DEFINE([includes],[symbol], [ACTION-IF-FOUND], [ACTION-IF-NOT])
+#
+# DESCRIPTION
+#
+#   Complements AC_CHECK_FUNC but it does not check for a function but for a
+#   define to exist. Consider a usage like:
+#
+#    AC_CHECK_DEFINE(__STRICT_ANSI__, CFLAGS="$CFLAGS -D_XOPEN_SOURCE=500")
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+#
+#   This program is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation; either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program 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 General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 8
+
+AU_ALIAS([AC_CHECK_DEFINED], [AC_CHECK_DEFINE])
+AC_DEFUN([AC_CHECK_DEFINE],[
+AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$1])dnl
+AC_CACHE_CHECK([for $1 defined], ac_var,
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[
+  #ifdef $1
+  int ok;
+  #else
+  choke me
+  #endif
+]])],[AS_VAR_SET(ac_var, yes)],[AS_VAR_SET(ac_var, no)]))
+AS_IF([test AS_VAR_GET(ac_var) != "no"], [$2], [$3])dnl
+AS_VAR_POPDEF([ac_var])dnl
+])
+
+AU_ALIAS([AX_CHECK_DEFINED], [AX_CHECK_DEFINE])
+AC_DEFUN([AX_CHECK_DEFINE],[
+AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$2_$1])dnl
+AC_CACHE_CHECK([for $2 defined in $1], ac_var,
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <$1>]], [[
+  #ifdef $2
+  int ok;
+  #else
+  choke me
+  #endif
+]])],[AS_VAR_SET(ac_var, yes)],[AS_VAR_SET(ac_var, no)]))
+AS_IF([test AS_VAR_GET(ac_var) != "no"], [$3], [$4])dnl
+AS_VAR_POPDEF([ac_var])dnl
+])
+
+AC_DEFUN([AX_CHECK_FUNC],
+[AS_VAR_PUSHDEF([ac_var], [ac_cv_func_$2])dnl
+AC_CACHE_CHECK([for $2], ac_var,
+dnl AC_LANG_FUNC_LINK_TRY
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([$1
+                #undef $2
+                char $2 ();],[
+                char (*f) () = $2;
+                return f != $2; ])],
+                [AS_VAR_SET(ac_var, yes)],
+                [AS_VAR_SET(ac_var, no)])])
+AS_IF([test AS_VAR_GET(ac_var) = yes], [$3], [$4])dnl
+AS_VAR_POPDEF([ac_var])dnl
+])# AC_CHECK_FUNC
diff --git a/m4/ax_check_flag.m4 b/m4/ax_check_flag.m4
new file mode 100644 (file)
index 0000000..52405fd
--- /dev/null
@@ -0,0 +1,147 @@
+# ===========================================================================
+#       http://www.gnu.org/software/autoconf-archive/ax_check_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_PREPROC_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#   AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#   AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#   AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
+#   AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS])
+#   AX_APPEND_LINK_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+#   Check whether the given FLAG works with the current language's
+#   preprocessor/compiler/linker, or whether they give an error. (Warnings,
+#   however, are ignored.)
+#
+#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+#   success/failure.
+#
+#   If EXTRA-FLAGS is defined, it is added to the current language's default
+#   flags (e.g.  CFLAGS) when the check is done.  The check us thus made
+#   with the following flags: "CFLAGS EXTRA-FLAGS FLAG".  EXTRA-FLAGS can
+#   for example be used to force the compiler to issue an error when a bad
+#   flag is given.
+#
+#   AX_APPEND_FLAG appends the FLAG to the FLAG-VARIABLE shell variable or
+#   the current language's flags if not specified.  FLAG is not added to
+#   FLAG-VARIABLE if it is already in the shell variable.
+#
+#   AX_APPEND_COMPILE_FLAGS checks for each FLAG1, FLAG2, etc. using
+#   AX_CHECK_COMPILE_FLAG and if the check is successful the flag is added
+#   to the appropriate FLAGS variable with AX_APPEND_FLAG.  The
+#   FLAGS-VARIABLE and EXTRA-FLAGS arguments are the same as in the other
+#   macros. AX_APPEND_LINK_FLAGS does the same for linker flags.
+#
+#   NOTE: Based on AX_CHECK_COMPILER_FLAGS and AX_CFLAGS_GCC_OPTION.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+#   Copyright (c) 2009 Steven G. Johnson <stevenj@alum.mit.edu>
+#   Copyright (c) 2009 Matteo Frigo
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program 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 General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_PREPROC_FLAG],
+[AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]cppflags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG preprocessor accepts $1], CACHEVAR, [
+  ax_check_save_flags=$CPPFLAGS
+  CPPFLAGS="$CPPFLAGS $4 $1"
+  AC_PREPROC_IFELSE([AC_LANG_PROGRAM()],
+    [AS_VAR_SET([CACHEVAR],[yes])],
+    [AS_VAR_SET([CACHEVAR],[no])])
+  CPPFLAGS=$ax_check_save_flags])
+AS_VAR_IF([CACHEVAR], "yes",
+  [m4_default([$2], :)],
+  [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_PREPROC_FLAGS
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+  ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+  _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
+    [AS_VAR_SET([CACHEVAR],[yes])],
+    [AS_VAR_SET([CACHEVAR],[no])])
+  _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_VAR_IF([CACHEVAR], "yes",
+  [m4_default([$2], :)],
+  [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS
+
+AC_DEFUN([AX_CHECK_LINK_FLAG],
+[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
+AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS $4 $1"
+  AC_LINK_IFELSE([AC_LANG_PROGRAM()],
+    [AS_VAR_SET([CACHEVAR],[yes])],
+    [AS_VAR_SET([CACHEVAR],[no])])
+  LDFLAGS=$ax_check_save_flags])
+AS_VAR_IF([CACHEVAR], "yes",
+  [m4_default([$2], :)],
+  [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_LINK_FLAGS
+
+
+AC_DEFUN([AX_APPEND_FLAG],
+[AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX
+AC_REQUIRE([AC_PROG_GREP])
+AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[]FLAGS)])dnl
+AS_VAR_SET_IF([FLAGS],
+  [AS_IF([AS_ECHO(" $[]FLAGS ") | $GREP " $1 " 2>&1 >/dev/null],
+    [AC_RUN_LOG([: FLAGS already contains $1])],
+    [AC_RUN_LOG([: FLAGS="$FLAGS $1"])
+    AS_VAR_APPEND([FLAGS], [" $1"])])],
+  [AS_VAR_SET([FLAGS],[$1])])
+AS_VAR_POPDEF([FLAGS])dnl
+])dnl AX_APPEND_FLAG
+
+AC_DEFUN([AX_APPEND_COMPILE_FLAGS],
+[for flag in $1; do
+  AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3])
+done
+])dnl AX_APPEND_COMPILE_FLAGS
+
+AC_DEFUN([AX_APPEND_LINK_FLAGS],
+[for flag in $1; do
+  AX_CHECK_LINK_FLAG([$flag], [AX_APPEND_FLAG([$flag], [m4_default([$2], [LDFLAGS])])], [], [$3])
+done
+])dnl AX_APPEND_LINK_FLAGS
diff --git a/m4/ax_define_dir.m4 b/m4/ax_define_dir.m4
new file mode 100644 (file)
index 0000000..b74d155
--- /dev/null
@@ -0,0 +1,49 @@
+# ===========================================================================
+#       http://www.gnu.org/software/autoconf-archive/ax_define_dir.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_DEFINE_DIR(VARNAME, DIR [, DESCRIPTION])
+#
+# DESCRIPTION
+#
+#   This macro sets VARNAME to the expansion of the DIR variable, taking
+#   care of fixing up ${prefix} and such.
+#
+#   VARNAME is then offered as both an output variable and a C preprocessor
+#   symbol.
+#
+#   Example:
+#
+#     AX_DEFINE_DIR([DATADIR], [datadir], [Where data are placed to.])
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Stepan Kasal <kasal@ucw.cz>
+#   Copyright (c) 2008 Andreas Schwab <schwab@suse.de>
+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+#   Copyright (c) 2008 Alexandre Oliva
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 6
+
+AU_ALIAS([AC_DEFINE_DIR], [AX_DEFINE_DIR])
+AC_DEFUN([AX_DEFINE_DIR], [
+  prefix_NONE=
+  exec_prefix_NONE=
+  test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix
+  test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix
+dnl In Autoconf 2.60, ${datadir} refers to ${datarootdir}, which in turn
+dnl refers to ${prefix}.  Thus we have to use `eval' twice.
+  eval ax_define_dir="\"[$]$2\""
+  eval ax_define_dir="\"$ax_define_dir\""
+  AC_SUBST($1, "$ax_define_dir")
+  AC_DEFINE_UNQUOTED($1, "$ax_define_dir", [$3])
+  test "$prefix_NONE" && prefix=NONE
+  test "$exec_prefix_NONE" && exec_prefix=NONE
+])
diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4
new file mode 100644 (file)
index 0000000..94a3b0e
--- /dev/null
@@ -0,0 +1,302 @@
+# ===========================================================================
+#        http://www.gnu.org/software/autoconf-archive/ax_pthread.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   This macro figures out how to build C programs using POSIX threads. It
+#   sets the PTHREAD_LIBS output variable to the threads library and linker
+#   flags, and the PTHREAD_CFLAGS output variable to any special C compiler
+#   flags that are needed. (The user can also force certain compiler
+#   flags/libs to be tested by setting these environment variables.)
+#
+#   Also sets PTHREAD_CC to any special C compiler that is needed for
+#   multi-threaded programs (defaults to the value of CC otherwise). (This
+#   is necessary on AIX to use the special cc_r compiler alias.)
+#
+#   NOTE: You are assumed to not only compile your program with these flags,
+#   but also link it with them as well. e.g. you should link with
+#   $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+#
+#   If you are only building threads programs, you may wish to use these
+#   variables in your default LIBS, CFLAGS, and CC:
+#
+#     LIBS="$PTHREAD_LIBS $LIBS"
+#     CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+#     CC="$PTHREAD_CC"
+#
+#   In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
+#   has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
+#   (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#
+#   Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
+#   PTHREAD_PRIO_INHERIT symbol is defined when compiling with
+#   PTHREAD_CFLAGS.
+#
+#   ACTION-IF-FOUND is a list of shell commands to run if a threads library
+#   is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
+#   is not found. If ACTION-IF-FOUND is not specified, the default action
+#   will define HAVE_PTHREAD.
+#
+#   Please let the authors know if this macro fails on any platform, or if
+#   you have any other suggestions or comments. This macro was based on work
+#   by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
+#   from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
+#   Alejandro Forero Cuervo to the autoconf macro repository. We are also
+#   grateful for the helpful feedback of numerous users.
+#
+#   Updated for Autoconf 2.68 by Daniel Richard G.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+#   Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program 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 General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 14
+
+AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
+AC_DEFUN([AX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_PUSH([C])
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+        AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
+        AC_MSG_RESULT($ax_pthread_ok)
+        if test x"$ax_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+        *solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
+        ;;
+
+        *-darwin*)
+        ax_pthread_flags="-pthread $ax_pthread_flags"
+        ;;
+esac
+
+if test x"$ax_pthread_ok" = xno; then
+for flag in $ax_pthread_flags; do
+
+        case $flag in
+                none)
+                AC_MSG_CHECKING([whether pthreads work without any flags])
+                ;;
+
+                -*)
+                AC_MSG_CHECKING([whether pthreads work with $flag])
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+                pthread-config)
+                AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
+                if test x"$ax_pthread_config" = xno; then continue; fi
+                PTHREAD_CFLAGS="`pthread-config --cflags`"
+                PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+                ;;
+
+                *)
+                AC_MSG_CHECKING([for the pthreads library -l$flag])
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+                        static void routine(void *a) { a = 0; }
+                        static void *start_routine(void *a) { return a; }],
+                       [pthread_t th; pthread_attr_t attr;
+                        pthread_create(&th, 0, start_routine, 0);
+                        pthread_join(th, 0);
+                        pthread_attr_init(&attr);
+                        pthread_cleanup_push(routine, 0);
+                        pthread_cleanup_pop(0) /* ; */])],
+                [ax_pthread_ok=yes],
+                [])
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        AC_MSG_RESULT($ax_pthread_ok)
+        if test "x$ax_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$ax_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+        AC_MSG_CHECKING([for joinable pthread attribute])
+        attr_name=unknown
+        for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+            AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
+                           [int attr = $attr; return attr /* ; */])],
+                [attr_name=$attr; break],
+                [])
+        done
+        AC_MSG_RESULT($attr_name)
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
+                               [Define to necessary symbol if this constant
+                                uses a non-standard name on your system.])
+        fi
+
+        AC_MSG_CHECKING([if more special flags are required for pthreads])
+        flag=no
+        case "${host_cpu}-${host_os}" in
+            *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
+            *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+        esac
+        AC_MSG_RESULT(${flag})
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
+            ax_cv_PTHREAD_PRIO_INHERIT, [
+                AC_LINK_IFELSE(
+                    AC_LANG_PROGRAM([[#include <pthread.h>]], [[int i = PTHREAD_PRIO_INHERIT;]]),
+                    [ax_cv_PTHREAD_PRIO_INHERIT=yes],
+                    [ax_cv_PTHREAD_PRIO_INHERIT=no])
+            ])
+        AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
+            AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        # More AIX lossage: must compile with xlc_r or cc_r
+        if test x"$GCC" != xyes; then
+          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
+        else
+          PTHREAD_CC=$CC
+        fi
+else
+        PTHREAD_CC="$CC"
+fi
+
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_CC)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$ax_pthread_ok" = xyes; then
+        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+        :
+else
+        ax_pthread_ok=no
+        $2
+fi
+AC_LANG_POP
+])dnl AX_PTHREAD
diff --git a/m4/ax_tls.m4 b/m4/ax_tls.m4
new file mode 100644 (file)
index 0000000..033e3b1
--- /dev/null
@@ -0,0 +1,76 @@
+# ===========================================================================
+#          http://www.gnu.org/software/autoconf-archive/ax_tls.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_TLS([action-if-found], [action-if-not-found])
+#
+# DESCRIPTION
+#
+#   Provides a test for the compiler support of thread local storage (TLS)
+#   extensions. Defines TLS if it is found. Currently knows about GCC/ICC
+#   and MSVC. I think SunPro uses the same as GCC, and Borland apparently
+#   supports either.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Alan Woodland <ajw05@aber.ac.uk>
+#   Copyright (c) 2010 Diego Elio Petteno` <flameeyes@gmail.com>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program 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 General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 10
+
+AC_DEFUN([AX_TLS], [
+  AC_MSG_CHECKING(for thread local storage (TLS) class)
+  AC_CACHE_VAL(ac_cv_tls, [
+    ax_tls_keywords="__thread __declspec(thread) none"
+    for ax_tls_keyword in $ax_tls_keywords; do
+       AS_CASE([$ax_tls_keyword],
+          [none], [ac_cv_tls=none ; break],
+          [AC_TRY_COMPILE(
+              [#include <stdlib.h>
+               static void
+               foo(void) {
+               static ] $ax_tls_keyword [ int bar;
+               exit(1);
+               }],
+               [],
+               [ac_cv_tls=$ax_tls_keyword ; break],
+               ac_cv_tls=none
+           )])
+    done
+  ])
+  AC_MSG_RESULT($ac_cv_tls)
+
+  AS_IF([test "$ac_cv_tls" != "none"],
+    AC_DEFINE_UNQUOTED([TLS], $ac_cv_tls, [If the compiler supports a TLS storage class define it to that here])
+      m4_ifnblank([$1], [$1]),
+    m4_ifnblank([$2], [$2])
+  )
+])
diff --git a/m4/check_define.m4 b/m4/check_define.m4
deleted file mode 100644 (file)
index 43edc78..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-AC_DEFUN([AC_CHECK_DEFINE],[
-AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$1_$2])dnl
-AC_CACHE_CHECK([for $1 in $2], ac_var,
-AC_TRY_COMPILE([#include <$2>],[
-  #ifdef $1
-  int ok;
-  #else
-  choke me
-  #endif
-],AS_VAR_SET(ac_var, yes),AS_VAR_SET(ac_var, no)))
-AS_IF([test AS_VAR_GET(ac_var) != "no"], [$3], [$4])dnl
-AS_VAR_POPDEF([ac_var])dnl
-])
diff --git a/m4/gettext.m4 b/m4/gettext.m4
deleted file mode 100644 (file)
index c9ae1f7..0000000
+++ /dev/null
@@ -1,381 +0,0 @@
-# gettext.m4 serial 60 (gettext-0.17)
-dnl Copyright (C) 1995-2007 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 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 They are *not* in the public domain.
-
-dnl Authors:
-dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
-dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2006.
-
-dnl Macro to add for using GNU gettext.
-
-dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]).
-dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The
-dnl    default (if it is not specified or empty) is 'no-libtool'.
-dnl    INTLSYMBOL should be 'external' for packages with no intl directory,
-dnl    and 'no-libtool' or 'use-libtool' for packages with an intl directory.
-dnl    If INTLSYMBOL is 'use-libtool', then a libtool library
-dnl    $(top_builddir)/intl/libintl.la will be created (shared and/or static,
-dnl    depending on --{enable,disable}-{shared,static} and on the presence of
-dnl    AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library
-dnl    $(top_builddir)/intl/libintl.a will be created.
-dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext
-dnl    implementations (in libc or libintl) without the ngettext() function
-dnl    will be ignored.  If NEEDSYMBOL is specified and is
-dnl    'need-formatstring-macros', then GNU gettext implementations that don't
-dnl    support the ISO C 99 <inttypes.h> formatstring macros will be ignored.
-dnl INTLDIR is used to find the intl libraries.  If empty,
-dnl    the value `$(top_builddir)/intl/' is used.
-dnl
-dnl The result of the configuration is one of three cases:
-dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled
-dnl    and used.
-dnl    Catalog format: GNU --> install in $(datadir)
-dnl    Catalog extension: .mo after installation, .gmo in source tree
-dnl 2) GNU gettext has been found in the system's C library.
-dnl    Catalog format: GNU --> install in $(datadir)
-dnl    Catalog extension: .mo after installation, .gmo in source tree
-dnl 3) No internationalization, always use English msgid.
-dnl    Catalog format: none
-dnl    Catalog extension: none
-dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur.
-dnl The use of .gmo is historical (it was needed to avoid overwriting the
-dnl GNU format catalogs when building on a platform with an X/Open gettext),
-dnl but we keep it in order not to force irrelevant filename changes on the
-dnl maintainers.
-dnl
-AC_DEFUN([AM_GNU_GETTEXT],
-[
-  dnl Argument checking.
-  ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], ,
-    [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT
-])])])])])
-  ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], ,
-    [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT
-])])])])
-  define([gt_included_intl],
-    ifelse([$1], [external],
-      ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]),
-      [yes]))
-  define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], []))
-  gt_NEEDS_INIT
-  AM_GNU_GETTEXT_NEED([$2])
-
-  AC_REQUIRE([AM_PO_SUBDIRS])dnl
-  ifelse(gt_included_intl, yes, [
-    AC_REQUIRE([AM_INTL_SUBDIR])dnl
-  ])
-
-  dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
-  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
-  AC_REQUIRE([AC_LIB_RPATH])
-
-  dnl Sometimes libintl requires libiconv, so first search for libiconv.
-  dnl Ideally we would do this search only after the
-  dnl      if test "$USE_NLS" = "yes"; then
-  dnl        if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
-  dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT
-  dnl the configure script would need to contain the same shell code
-  dnl again, outside any 'if'. There are two solutions:
-  dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'.
-  dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE.
-  dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not
-  dnl documented, we avoid it.
-  ifelse(gt_included_intl, yes, , [
-    AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
-  ])
-
-  dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation.
-  gt_INTL_MACOSX
-
-  dnl Set USE_NLS.
-  AC_REQUIRE([AM_NLS])
-
-  ifelse(gt_included_intl, yes, [
-    BUILD_INCLUDED_LIBINTL=no
-    USE_INCLUDED_LIBINTL=no
-  ])
-  LIBINTL=
-  LTLIBINTL=
-  POSUB=
-
-  dnl Add a version number to the cache macros.
-  case " $gt_needs " in
-    *" need-formatstring-macros "*) gt_api_version=3 ;;
-    *" need-ngettext "*) gt_api_version=2 ;;
-    *) gt_api_version=1 ;;
-  esac
-  gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc"
-  gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl"
-
-  dnl If we use NLS figure out what method
-  if test "$USE_NLS" = "yes"; then
-    gt_use_preinstalled_gnugettext=no
-    ifelse(gt_included_intl, yes, [
-      AC_MSG_CHECKING([whether included gettext is requested])
-      AC_ARG_WITH(included-gettext,
-        [  --with-included-gettext use the GNU gettext library included here],
-        nls_cv_force_use_gnu_gettext=$withval,
-        nls_cv_force_use_gnu_gettext=no)
-      AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
-
-      nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
-      if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
-    ])
-        dnl User does not insist on using GNU NLS library.  Figure out what
-        dnl to use.  If GNU gettext is available we use this.  Else we have
-        dnl to fall back to GNU NLS library.
-
-        if test $gt_api_version -ge 3; then
-          gt_revision_test_code='
-#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
-#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
-#endif
-changequote(,)dnl
-typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
-changequote([,])dnl
-'
-        else
-          gt_revision_test_code=
-        fi
-        if test $gt_api_version -ge 2; then
-          gt_expression_test_code=' + * ngettext ("", "", 0)'
-        else
-          gt_expression_test_code=
-        fi
-
-        AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc],
-         [AC_TRY_LINK([#include <libintl.h>
-$gt_revision_test_code
-extern int _nl_msg_cat_cntr;
-extern int *_nl_domain_bindings;],
-            [bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings],
-            [eval "$gt_func_gnugettext_libc=yes"],
-            [eval "$gt_func_gnugettext_libc=no"])])
-
-        if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
-          dnl Sometimes libintl requires libiconv, so first search for libiconv.
-          ifelse(gt_included_intl, yes, , [
-            AM_ICONV_LINK
-          ])
-          dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL
-          dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv])
-          dnl because that would add "-liconv" to LIBINTL and LTLIBINTL
-          dnl even if libiconv doesn't exist.
-          AC_LIB_LINKFLAGS_BODY([intl])
-          AC_CACHE_CHECK([for GNU gettext in libintl],
-            [$gt_func_gnugettext_libintl],
-           [gt_save_CPPFLAGS="$CPPFLAGS"
-            CPPFLAGS="$CPPFLAGS $INCINTL"
-            gt_save_LIBS="$LIBS"
-            LIBS="$LIBS $LIBINTL"
-            dnl Now see whether libintl exists and does not depend on libiconv.
-            AC_TRY_LINK([#include <libintl.h>
-$gt_revision_test_code
-extern int _nl_msg_cat_cntr;
-extern
-#ifdef __cplusplus
-"C"
-#endif
-const char *_nl_expand_alias (const char *);],
-              [bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
-              [eval "$gt_func_gnugettext_libintl=yes"],
-              [eval "$gt_func_gnugettext_libintl=no"])
-            dnl Now see whether libintl exists and depends on libiconv.
-            if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then
-              LIBS="$LIBS $LIBICONV"
-              AC_TRY_LINK([#include <libintl.h>
-$gt_revision_test_code
-extern int _nl_msg_cat_cntr;
-extern
-#ifdef __cplusplus
-"C"
-#endif
-const char *_nl_expand_alias (const char *);],
-                [bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
-               [LIBINTL="$LIBINTL $LIBICONV"
-                LTLIBINTL="$LTLIBINTL $LTLIBICONV"
-                eval "$gt_func_gnugettext_libintl=yes"
-               ])
-            fi
-            CPPFLAGS="$gt_save_CPPFLAGS"
-            LIBS="$gt_save_LIBS"])
-        fi
-
-        dnl If an already present or preinstalled GNU gettext() is found,
-        dnl use it.  But if this macro is used in GNU gettext, and GNU
-        dnl gettext is already preinstalled in libintl, we update this
-        dnl libintl.  (Cf. the install rule in intl/Makefile.in.)
-        if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \
-           || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \
-                && test "$PACKAGE" != gettext-runtime \
-                && test "$PACKAGE" != gettext-tools; }; then
-          gt_use_preinstalled_gnugettext=yes
-        else
-          dnl Reset the values set by searching for libintl.
-          LIBINTL=
-          LTLIBINTL=
-          INCINTL=
-        fi
-
-    ifelse(gt_included_intl, yes, [
-        if test "$gt_use_preinstalled_gnugettext" != "yes"; then
-          dnl GNU gettext is not found in the C library.
-          dnl Fall back on included GNU gettext library.
-          nls_cv_use_gnu_gettext=yes
-        fi
-      fi
-
-      if test "$nls_cv_use_gnu_gettext" = "yes"; then
-        dnl Mark actions used to generate GNU NLS library.
-        BUILD_INCLUDED_LIBINTL=yes
-        USE_INCLUDED_LIBINTL=yes
-        LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV $LIBTHREAD"
-        LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD"
-        LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'`
-      fi
-
-      CATOBJEXT=
-      if test "$gt_use_preinstalled_gnugettext" = "yes" \
-         || test "$nls_cv_use_gnu_gettext" = "yes"; then
-        dnl Mark actions to use GNU gettext tools.
-        CATOBJEXT=.gmo
-      fi
-    ])
-
-    if test -n "$INTL_MACOSX_LIBS"; then
-      if test "$gt_use_preinstalled_gnugettext" = "yes" \
-         || test "$nls_cv_use_gnu_gettext" = "yes"; then
-        dnl Some extra flags are needed during linking.
-        LIBINTL="$LIBINTL $INTL_MACOSX_LIBS"
-        LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS"
-      fi
-    fi
-
-    if test "$gt_use_preinstalled_gnugettext" = "yes" \
-       || test "$nls_cv_use_gnu_gettext" = "yes"; then
-      AC_DEFINE(ENABLE_NLS, 1,
-        [Define to 1 if translation of program messages to the user's native language
-   is requested.])
-    else
-      USE_NLS=no
-    fi
-  fi
-
-  AC_MSG_CHECKING([whether to use NLS])
-  AC_MSG_RESULT([$USE_NLS])
-  if test "$USE_NLS" = "yes"; then
-    AC_MSG_CHECKING([where the gettext function comes from])
-    if test "$gt_use_preinstalled_gnugettext" = "yes"; then
-      if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
-        gt_source="external libintl"
-      else
-        gt_source="libc"
-      fi
-    else
-      gt_source="included intl directory"
-    fi
-    AC_MSG_RESULT([$gt_source])
-  fi
-
-  if test "$USE_NLS" = "yes"; then
-
-    if test "$gt_use_preinstalled_gnugettext" = "yes"; then
-      if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
-        AC_MSG_CHECKING([how to link with libintl])
-        AC_MSG_RESULT([$LIBINTL])
-        AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL])
-      fi
-
-      dnl For backward compatibility. Some packages may be using this.
-      AC_DEFINE(HAVE_GETTEXT, 1,
-       [Define if the GNU gettext() function is already present or preinstalled.])
-      AC_DEFINE(HAVE_DCGETTEXT, 1,
-       [Define if the GNU dcgettext() function is already present or preinstalled.])
-    fi
-
-    dnl We need to process the po/ directory.
-    POSUB=po
-  fi
-
-  ifelse(gt_included_intl, yes, [
-    dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL
-    dnl to 'yes' because some of the testsuite requires it.
-    if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then
-      BUILD_INCLUDED_LIBINTL=yes
-    fi
-
-    dnl Make all variables we use known to autoconf.
-    AC_SUBST(BUILD_INCLUDED_LIBINTL)
-    AC_SUBST(USE_INCLUDED_LIBINTL)
-    AC_SUBST(CATOBJEXT)
-
-    dnl For backward compatibility. Some configure.ins may be using this.
-    nls_cv_header_intl=
-    nls_cv_header_libgt=
-
-    dnl For backward compatibility. Some Makefiles may be using this.
-    DATADIRNAME=share
-    AC_SUBST(DATADIRNAME)
-
-    dnl For backward compatibility. Some Makefiles may be using this.
-    INSTOBJEXT=.mo
-    AC_SUBST(INSTOBJEXT)
-
-    dnl For backward compatibility. Some Makefiles may be using this.
-    GENCAT=gencat
-    AC_SUBST(GENCAT)
-
-    dnl For backward compatibility. Some Makefiles may be using this.
-    INTLOBJS=
-    if test "$USE_INCLUDED_LIBINTL" = yes; then
-      INTLOBJS="\$(GETTOBJS)"
-    fi
-    AC_SUBST(INTLOBJS)
-
-    dnl Enable libtool support if the surrounding package wishes it.
-    INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix
-    AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX)
-  ])
-
-  dnl For backward compatibility. Some Makefiles may be using this.
-  INTLLIBS="$LIBINTL"
-  AC_SUBST(INTLLIBS)
-
-  dnl Make all documented variables known to autoconf.
-  AC_SUBST(LIBINTL)
-  AC_SUBST(LTLIBINTL)
-  AC_SUBST(POSUB)
-])
-
-
-dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized.
-m4_define([gt_NEEDS_INIT],
-[
-  m4_divert_text([DEFAULTS], [gt_needs=])
-  m4_define([gt_NEEDS_INIT], [])
-])
-
-
-dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL])
-AC_DEFUN([AM_GNU_GETTEXT_NEED],
-[
-  m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"])
-])
-
-
-dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version])
-AC_DEFUN([AM_GNU_GETTEXT_VERSION], [])
diff --git a/m4/iconv.m4 b/m4/iconv.m4
deleted file mode 100644 (file)
index 66bc76f..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-# iconv.m4 serial AM6 (gettext-0.17)
-dnl Copyright (C) 2000-2002, 2007 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 From Bruno Haible.
-
-AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
-[
-  dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
-  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
-  AC_REQUIRE([AC_LIB_RPATH])
-
-  dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
-  dnl accordingly.
-  AC_LIB_LINKFLAGS_BODY([iconv])
-])
-
-AC_DEFUN([AM_ICONV_LINK],
-[
-  dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
-  dnl those with the standalone portable GNU libiconv installed).
-  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
-
-  dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
-  dnl accordingly.
-  AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
-
-  dnl Add $INCICONV to CPPFLAGS before performing the following checks,
-  dnl because if the user has installed libiconv and not disabled its use
-  dnl via --without-libiconv-prefix, he wants to use it. The first
-  dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed.
-  am_save_CPPFLAGS="$CPPFLAGS"
-  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
-
-  AC_CACHE_CHECK([for iconv], am_cv_func_iconv, [
-    am_cv_func_iconv="no, consider installing GNU libiconv"
-    am_cv_lib_iconv=no
-    AC_TRY_LINK([#include <stdlib.h>
-#include <iconv.h>],
-      [iconv_t cd = iconv_open("","");
-       iconv(cd,NULL,NULL,NULL,NULL);
-       iconv_close(cd);],
-      am_cv_func_iconv=yes)
-    if test "$am_cv_func_iconv" != yes; then
-      am_save_LIBS="$LIBS"
-      LIBS="$LIBS $LIBICONV"
-      AC_TRY_LINK([#include <stdlib.h>
-#include <iconv.h>],
-        [iconv_t cd = iconv_open("","");
-         iconv(cd,NULL,NULL,NULL,NULL);
-         iconv_close(cd);],
-        am_cv_lib_iconv=yes
-        am_cv_func_iconv=yes)
-      LIBS="$am_save_LIBS"
-    fi
-  ])
-  if test "$am_cv_func_iconv" = yes; then
-    AC_CACHE_CHECK([for working iconv], am_cv_func_iconv_works, [
-      dnl This tests against bugs in AIX 5.1 and HP-UX 11.11.
-      am_save_LIBS="$LIBS"
-      if test $am_cv_lib_iconv = yes; then
-        LIBS="$LIBS $LIBICONV"
-      fi
-      AC_TRY_RUN([
-#include <iconv.h>
-#include <string.h>
-int main ()
-{
-  /* 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 */
-        char buf[10];
-        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,
-                            &outptr, &outbytesleft);
-        if (res == 0)
-          return 1;
-      }
-  }
-#if 0 /* This bug could be worked around by the caller.  */
-  /* Test against HP-UX 11.11 bug: Positive return value instead of 0.  */
-  {
-    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";
-        char buf[50];
-        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,
-                            &outptr, &outbytesleft);
-        if ((int)res > 0)
-          return 1;
-      }
-  }
-#endif
-  /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
-     provided.  */
-  if (/* Try standardized names.  */
-      iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
-      /* Try IRIX, OSF/1 names.  */
-      && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
-      /* Try AIX names.  */
-      && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
-      /* Try HP-UX names.  */
-      && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
-    return 1;
-  return 0;
-}], [am_cv_func_iconv_works=yes], [am_cv_func_iconv_works=no],
-        [case "$host_os" in
-           aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
-           *)            am_cv_func_iconv_works="guessing yes" ;;
-         esac])
-      LIBS="$am_save_LIBS"
-    ])
-    case "$am_cv_func_iconv_works" in
-      *no) am_func_iconv=no am_cv_lib_iconv=no ;;
-      *)   am_func_iconv=yes ;;
-    esac
-  else
-    am_func_iconv=no am_cv_lib_iconv=no
-  fi
-  if test "$am_func_iconv" = yes; then
-    AC_DEFINE(HAVE_ICONV, 1,
-      [Define if you have the iconv() function and it works.])
-  fi
-  if test "$am_cv_lib_iconv" = yes; then
-    AC_MSG_CHECKING([how to link with libiconv])
-    AC_MSG_RESULT([$LIBICONV])
-  else
-    dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
-    dnl either.
-    CPPFLAGS="$am_save_CPPFLAGS"
-    LIBICONV=
-    LTLIBICONV=
-  fi
-  AC_SUBST(LIBICONV)
-  AC_SUBST(LTLIBICONV)
-])
-
-AC_DEFUN([AM_ICONV],
-[
-  AM_ICONV_LINK
-  if test "$am_cv_func_iconv" = yes; then
-    AC_MSG_CHECKING([for iconv declaration])
-    AC_CACHE_VAL(am_cv_proto_iconv, [
-      AC_TRY_COMPILE([
-#include <stdlib.h>
-#include <iconv.h>
-extern
-#ifdef __cplusplus
-"C"
-#endif
-#if defined(__STDC__) || defined(__cplusplus)
-size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
-#else
-size_t iconv();
-#endif
-], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const")
-      am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
-    am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
-    AC_MSG_RESULT([$]{ac_t:-
-         }[$]am_cv_proto_iconv)
-    AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1,
-      [Define as const if the declaration of iconv() needs const.])
-  fi
-])
diff --git a/m4/intltool.m4 b/m4/intltool.m4
deleted file mode 100644 (file)
index 122d773..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-## intltool.m4 - Configure intltool for the target system. -*-Shell-script-*-
-## Copyright (C) 2001 Eazel, Inc.
-## Author: Maciej Stachowiak <mjs@noisehavoc.org>
-##         Kenneth Christiansen <kenneth@gnu.org>
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2 of the License, or
-## (at your option) any later version.
-##
-## This program 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 General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-##
-## As a special exception to the GNU General Public License, if you
-## distribute this file as part of a program that contains a
-## configuration script generated by Autoconf, you may include it under
-## the same distribution terms that you use for the rest of that program.
-
-dnl IT_PROG_INTLTOOL([MINIMUM-VERSION], [no-xml])
-# serial 40 IT_PROG_INTLTOOL
-AC_DEFUN([IT_PROG_INTLTOOL], [
-AC_PREREQ([2.50])dnl
-AC_REQUIRE([AM_NLS])dnl
-
-case "$am__api_version" in
-    1.[01234])
-       AC_MSG_ERROR([Automake 1.5 or newer is required to use intltool])
-    ;;
-    *)
-    ;;
-esac
-
-if test -n "$1"; then
-    AC_MSG_CHECKING([for intltool >= $1])
-
-    INTLTOOL_REQUIRED_VERSION_AS_INT=`echo $1 | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'`
-    INTLTOOL_APPLIED_VERSION=`intltool-update --version | head -1 | cut -d" " -f3`
-    [INTLTOOL_APPLIED_VERSION_AS_INT=`echo $INTLTOOL_APPLIED_VERSION | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'`
-    ]
-    AC_MSG_RESULT([$INTLTOOL_APPLIED_VERSION found])
-    test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT" ||
-       AC_MSG_ERROR([Your intltool is too old.  You need intltool $1 or later.])
-fi
-
-AC_PATH_PROG(INTLTOOL_UPDATE, [intltool-update])
-AC_PATH_PROG(INTLTOOL_MERGE, [intltool-merge])
-AC_PATH_PROG(INTLTOOL_EXTRACT, [intltool-extract])
-if test -z "$INTLTOOL_UPDATE" -o -z "$INTLTOOL_MERGE" -o -z "$INTLTOOL_EXTRACT"; then
-    AC_MSG_ERROR([The intltool scripts were not found. Please install intltool.])
-fi
-
-  INTLTOOL_DESKTOP_RULE='%.desktop:   %.desktop.in   $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
-INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
-     INTLTOOL_KEYS_RULE='%.keys:      %.keys.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
-     INTLTOOL_PROP_RULE='%.prop:      %.prop.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
-      INTLTOOL_OAF_RULE='%.oaf:       %.oaf.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -p $(top_srcdir)/po $< [$]@'
-     INTLTOOL_PONG_RULE='%.pong:      %.pong.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
-   INTLTOOL_SERVER_RULE='%.server:    %.server.in    $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
-    INTLTOOL_SHEET_RULE='%.sheet:     %.sheet.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
-INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
-       INTLTOOL_UI_RULE='%.ui:        %.ui.in        $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
-      INTLTOOL_XML_RULE='%.xml:       %.xml.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
-      INTLTOOL_XML_NOMERGE_RULE='%.xml:       %.xml.in       $(INTLTOOL_MERGE) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< [$]@' 
-      INTLTOOL_XAM_RULE='%.xam:       %.xml.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
-      INTLTOOL_KBD_RULE='%.kbd:       %.kbd.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
-    INTLTOOL_CAVES_RULE='%.caves:     %.caves.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
-  INTLTOOL_SCHEMAS_RULE='%.schemas:   %.schemas.in   $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
-    INTLTOOL_THEME_RULE='%.theme:     %.theme.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
-    INTLTOOL_SERVICE_RULE='%.service: %.service.in   $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
-   INTLTOOL_POLICY_RULE='%.policy:    %.policy.in    $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
-
-_IT_SUBST(INTLTOOL_DESKTOP_RULE)
-_IT_SUBST(INTLTOOL_DIRECTORY_RULE)
-_IT_SUBST(INTLTOOL_KEYS_RULE)
-_IT_SUBST(INTLTOOL_PROP_RULE)
-_IT_SUBST(INTLTOOL_OAF_RULE)
-_IT_SUBST(INTLTOOL_PONG_RULE)
-_IT_SUBST(INTLTOOL_SERVER_RULE)
-_IT_SUBST(INTLTOOL_SHEET_RULE)
-_IT_SUBST(INTLTOOL_SOUNDLIST_RULE)
-_IT_SUBST(INTLTOOL_UI_RULE)
-_IT_SUBST(INTLTOOL_XAM_RULE)
-_IT_SUBST(INTLTOOL_KBD_RULE)
-_IT_SUBST(INTLTOOL_XML_RULE)
-_IT_SUBST(INTLTOOL_XML_NOMERGE_RULE)
-_IT_SUBST(INTLTOOL_CAVES_RULE)
-_IT_SUBST(INTLTOOL_SCHEMAS_RULE)
-_IT_SUBST(INTLTOOL_THEME_RULE)
-_IT_SUBST(INTLTOOL_SERVICE_RULE)
-_IT_SUBST(INTLTOOL_POLICY_RULE)
-
-# Check the gettext tools to make sure they are GNU
-AC_PATH_PROG(XGETTEXT, xgettext)
-AC_PATH_PROG(MSGMERGE, msgmerge)
-AC_PATH_PROG(MSGFMT, msgfmt)
-AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
-if test -z "$XGETTEXT" -o -z "$MSGMERGE" -o -z "$MSGFMT"; then
-    AC_MSG_ERROR([GNU gettext tools not found; required for intltool])
-fi
-xgversion="`$XGETTEXT --version|grep '(GNU ' 2> /dev/null`"
-mmversion="`$MSGMERGE --version|grep '(GNU ' 2> /dev/null`"
-mfversion="`$MSGFMT --version|grep '(GNU ' 2> /dev/null`"
-if test -z "$xgversion" -o -z "$mmversion" -o -z "$mfversion"; then
-    AC_MSG_ERROR([GNU gettext tools not found; required for intltool])
-fi
-
-AC_PATH_PROG(INTLTOOL_PERL, perl)
-if test -z "$INTLTOOL_PERL"; then
-   AC_MSG_ERROR([perl not found])
-fi
-AC_MSG_CHECKING([for perl >= 5.8.1])
-$INTLTOOL_PERL -e "use 5.8.1;" > /dev/null 2>&1
-if test $? -ne 0; then
-   AC_MSG_ERROR([perl 5.8.1 is required for intltool])
-else
-   IT_PERL_VERSION="`$INTLTOOL_PERL -e \"printf '%vd', $^V\"`"
-   AC_MSG_RESULT([$IT_PERL_VERSION])
-fi
-if test "x$2" != "xno-xml"; then
-   AC_MSG_CHECKING([for XML::Parser])
-   if `$INTLTOOL_PERL -e "require XML::Parser" 2>/dev/null`; then
-       AC_MSG_RESULT([ok])
-   else
-       AC_MSG_ERROR([XML::Parser perl module is required for intltool])
-   fi
-fi
-
-# Substitute ALL_LINGUAS so we can use it in po/Makefile
-AC_SUBST(ALL_LINGUAS)
-
-# Set DATADIRNAME correctly if it is not set yet
-# (copied from glib-gettext.m4)
-if test -z "$DATADIRNAME"; then
-  AC_LINK_IFELSE(
-    [AC_LANG_PROGRAM([[]],
-                     [[extern int _nl_msg_cat_cntr;
-                       return _nl_msg_cat_cntr]])],
-    [DATADIRNAME=share],
-    [case $host in
-    *-*-solaris*)
-    dnl On Solaris, if bind_textdomain_codeset is in libc,
-    dnl GNU format message catalog is always supported,
-    dnl since both are added to the libc all together.
-    dnl Hence, we'd like to go with DATADIRNAME=share
-    dnl in this case.
-    AC_CHECK_FUNC(bind_textdomain_codeset,
-      [DATADIRNAME=share], [DATADIRNAME=lib])
-    ;;
-    *)
-    [DATADIRNAME=lib]
-    ;;
-    esac])
-fi
-AC_SUBST(DATADIRNAME)
-
-IT_PO_SUBDIR([po])
-
-])
-
-
-# IT_PO_SUBDIR(DIRNAME)
-# ---------------------
-# All po subdirs have to be declared with this macro; the subdir "po" is
-# declared by IT_PROG_INTLTOOL.
-#
-AC_DEFUN([IT_PO_SUBDIR],
-[AC_PREREQ([2.53])dnl We use ac_top_srcdir inside AC_CONFIG_COMMANDS.
-dnl
-dnl The following CONFIG_COMMANDS should be exetuted at the very end
-dnl of config.status.
-AC_CONFIG_COMMANDS_PRE([
-  AC_CONFIG_COMMANDS([$1/stamp-it], [
-    if [ ! grep "^# INTLTOOL_MAKEFILE$" "$1/Makefile.in" > /dev/null ]; then
-       AC_MSG_ERROR([$1/Makefile.in.in was not created by intltoolize.])
-    fi
-    rm -f "$1/stamp-it" "$1/stamp-it.tmp" "$1/POTFILES" "$1/Makefile.tmp"
-    >"$1/stamp-it.tmp"
-    [sed '/^#/d
-        s/^[[].*] *//
-        /^[    ]*$/d
-       '"s|^|  $ac_top_srcdir/|" \
-      "$srcdir/$1/POTFILES.in" | sed '$!s/$/ \\/' >"$1/POTFILES"
-    ]
-    [sed '/^POTFILES =/,/[^\\]$/ {
-               /^POTFILES =/!d
-               r $1/POTFILES
-         }
-        ' "$1/Makefile.in" >"$1/Makefile"]
-    rm -f "$1/Makefile.tmp"
-    mv "$1/stamp-it.tmp" "$1/stamp-it"
-  ])
-])dnl
-])
-
-# _IT_SUBST(VARIABLE)
-# -------------------
-# Abstract macro to do either _AM_SUBST_NOTMAKE or AC_SUBST
-#
-AC_DEFUN([_IT_SUBST],
-[
-AC_SUBST([$1])
-m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([$1])])
-]
-)
-
-# deprecated macros
-AU_ALIAS([AC_PROG_INTLTOOL], [IT_PROG_INTLTOOL])
-# A hint is needed for aclocal from Automake <= 1.9.4:
-# AC_DEFUN([AC_PROG_INTLTOOL], ...)
-
diff --git a/m4/lib-ld.m4 b/m4/lib-ld.m4
deleted file mode 100644 (file)
index 96c4e2c..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-# lib-ld.m4 serial 3 (gettext-0.13)
-dnl Copyright (C) 1996-2003 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 Subroutines of libtool.m4,
-dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
-dnl with libtool.m4.
-
-dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
-AC_DEFUN([AC_LIB_PROG_LD_GNU],
-[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld,
-[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
-  acl_cv_prog_gnu_ld=yes ;;
-*)
-  acl_cv_prog_gnu_ld=no ;;
-esac])
-with_gnu_ld=$acl_cv_prog_gnu_ld
-])
-
-dnl From libtool-1.4. Sets the variable LD.
-AC_DEFUN([AC_LIB_PROG_LD],
-[AC_ARG_WITH(gnu-ld,
-[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
-test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
-AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([AC_CANONICAL_HOST])dnl
-# Prepare PATH_SEPARATOR.
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
-ac_prog=ld
-if test "$GCC" = yes; then
-  # Check if gcc -print-prog-name=ld gives a path.
-  AC_MSG_CHECKING([for ld used by GCC])
-  case $host in
-  *-*-mingw*)
-    # gcc leaves a trailing carriage return which upsets mingw
-    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
-  *)
-    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
-  esac
-  case $ac_prog in
-    # Accept absolute paths.
-    [[\\/]* | [A-Za-z]:[\\/]*)]
-      [re_direlt='/[^/][^/]*/\.\./']
-      # Canonicalize the path of ld
-      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
-      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
-       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
-      done
-      test -z "$LD" && LD="$ac_prog"
-      ;;
-  "")
-    # If it fails, then pretend we aren't using GCC.
-    ac_prog=ld
-    ;;
-  *)
-    # If it is relative, then search for the first ld in PATH.
-    with_gnu_ld=unknown
-    ;;
-  esac
-elif test "$with_gnu_ld" = yes; then
-  AC_MSG_CHECKING([for GNU ld])
-else
-  AC_MSG_CHECKING([for non-GNU ld])
-fi
-AC_CACHE_VAL(acl_cv_path_LD,
-[if test -z "$LD"; then
-  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
-  for ac_dir in $PATH; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      acl_cv_path_LD="$ac_dir/$ac_prog"
-      # Check to see if the program is GNU ld.  I'd rather use --version,
-      # but apparently some GNU ld's only accept -v.
-      # Break only if it was the GNU/non-GNU ld that we prefer.
-      case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
-      *GNU* | *'with BFD'*)
-       test "$with_gnu_ld" != no && break ;;
-      *)
-       test "$with_gnu_ld" != yes && break ;;
-      esac
-    fi
-  done
-  IFS="$ac_save_ifs"
-else
-  acl_cv_path_LD="$LD" # Let the user override the test with a path.
-fi])
-LD="$acl_cv_path_LD"
-if test -n "$LD"; then
-  AC_MSG_RESULT($LD)
-else
-  AC_MSG_RESULT(no)
-fi
-test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
-AC_LIB_PROG_LD_GNU
-])
diff --git a/m4/lib-link.m4 b/m4/lib-link.m4
deleted file mode 100644 (file)
index e3d26fc..0000000
+++ /dev/null
@@ -1,709 +0,0 @@
-# lib-link.m4 serial 13 (gettext-0.17)
-dnl Copyright (C) 2001-2007 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 From Bruno Haible.
-
-AC_PREREQ(2.54)
-
-dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
-dnl the libraries corresponding to explicit and implicit dependencies.
-dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
-dnl augments the CPPFLAGS variable.
-dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
-dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
-AC_DEFUN([AC_LIB_LINKFLAGS],
-[
-  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
-  AC_REQUIRE([AC_LIB_RPATH])
-  define([Name],[translit([$1],[./-], [___])])
-  define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
-                               [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
-  AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
-    AC_LIB_LINKFLAGS_BODY([$1], [$2])
-    ac_cv_lib[]Name[]_libs="$LIB[]NAME"
-    ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
-    ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
-    ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX"
-  ])
-  LIB[]NAME="$ac_cv_lib[]Name[]_libs"
-  LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
-  INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
-  LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix"
-  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
-  AC_SUBST([LIB]NAME)
-  AC_SUBST([LTLIB]NAME)
-  AC_SUBST([LIB]NAME[_PREFIX])
-  dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
-  dnl results of this search when this library appears as a dependency.
-  HAVE_LIB[]NAME=yes
-  undefine([Name])
-  undefine([NAME])
-])
-
-dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode)
-dnl searches for libname and the libraries corresponding to explicit and
-dnl implicit dependencies, together with the specified include files and
-dnl the ability to compile and link the specified testcode. If found, it
-dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and
-dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and
-dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
-dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
-dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
-dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
-AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
-[
-  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
-  AC_REQUIRE([AC_LIB_RPATH])
-  define([Name],[translit([$1],[./-], [___])])
-  define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
-                               [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
-
-  dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
-  dnl accordingly.
-  AC_LIB_LINKFLAGS_BODY([$1], [$2])
-
-  dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
-  dnl because if the user has installed lib[]Name and not disabled its use
-  dnl via --without-lib[]Name-prefix, he wants to use it.
-  ac_save_CPPFLAGS="$CPPFLAGS"
-  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
-
-  AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
-    ac_save_LIBS="$LIBS"
-    LIBS="$LIBS $LIB[]NAME"
-    AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no])
-    LIBS="$ac_save_LIBS"
-  ])
-  if test "$ac_cv_lib[]Name" = yes; then
-    HAVE_LIB[]NAME=yes
-    AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.])
-    AC_MSG_CHECKING([how to link with lib[]$1])
-    AC_MSG_RESULT([$LIB[]NAME])
-  else
-    HAVE_LIB[]NAME=no
-    dnl If $LIB[]NAME didn't lead to a usable library, we don't need
-    dnl $INC[]NAME either.
-    CPPFLAGS="$ac_save_CPPFLAGS"
-    LIB[]NAME=
-    LTLIB[]NAME=
-    LIB[]NAME[]_PREFIX=
-  fi
-  AC_SUBST([HAVE_LIB]NAME)
-  AC_SUBST([LIB]NAME)
-  AC_SUBST([LTLIB]NAME)
-  AC_SUBST([LIB]NAME[_PREFIX])
-  undefine([Name])
-  undefine([NAME])
-])
-
-dnl Determine the platform dependent parameters needed to use rpath:
-dnl   acl_libext,
-dnl   acl_shlibext,
-dnl   acl_hardcode_libdir_flag_spec,
-dnl   acl_hardcode_libdir_separator,
-dnl   acl_hardcode_direct,
-dnl   acl_hardcode_minus_L.
-AC_DEFUN([AC_LIB_RPATH],
-[
-  dnl Tell automake >= 1.10 to complain if config.rpath is missing.
-  m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
-  AC_REQUIRE([AC_PROG_CC])                dnl we use $CC, $GCC, $LDFLAGS
-  AC_REQUIRE([AC_LIB_PROG_LD])            dnl we use $LD, $with_gnu_ld
-  AC_REQUIRE([AC_CANONICAL_HOST])         dnl we use $host
-  AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
-  AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [
-    CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
-    ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
-    . ./conftest.sh
-    rm -f ./conftest.sh
-    acl_cv_rpath=done
-  ])
-  wl="$acl_cv_wl"
-  acl_libext="$acl_cv_libext"
-  acl_shlibext="$acl_cv_shlibext"
-  acl_libname_spec="$acl_cv_libname_spec"
-  acl_library_names_spec="$acl_cv_library_names_spec"
-  acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
-  acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
-  acl_hardcode_direct="$acl_cv_hardcode_direct"
-  acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
-  dnl Determine whether the user wants rpath handling at all.
-  AC_ARG_ENABLE(rpath,
-    [  --disable-rpath         do not hardcode runtime library paths],
-    :, enable_rpath=yes)
-])
-
-dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
-dnl the libraries corresponding to explicit and implicit dependencies.
-dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
-dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found
-dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
-AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
-[
-  AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
-  define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
-                               [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
-  dnl Autoconf >= 2.61 supports dots in --with options.
-  define([N_A_M_E],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit([$1],[.],[_])],[$1])])
-  dnl By default, look in $includedir and $libdir.
-  use_additional=yes
-  AC_LIB_WITH_FINAL_PREFIX([
-    eval additional_includedir=\"$includedir\"
-    eval additional_libdir=\"$libdir\"
-  ])
-  AC_LIB_ARG_WITH([lib]N_A_M_E[-prefix],
-[  --with-lib]N_A_M_E[-prefix[=DIR]  search for lib$1 in DIR/include and DIR/lib
-  --without-lib]N_A_M_E[-prefix     don't search for lib$1 in includedir and libdir],
-[
-    if test "X$withval" = "Xno"; then
-      use_additional=no
-    else
-      if test "X$withval" = "X"; then
-        AC_LIB_WITH_FINAL_PREFIX([
-          eval additional_includedir=\"$includedir\"
-          eval additional_libdir=\"$libdir\"
-        ])
-      else
-        additional_includedir="$withval/include"
-        additional_libdir="$withval/$acl_libdirstem"
-      fi
-    fi
-])
-  dnl Search the library and its dependencies in $additional_libdir and
-  dnl $LDFLAGS. Using breadth-first-seach.
-  LIB[]NAME=
-  LTLIB[]NAME=
-  INC[]NAME=
-  LIB[]NAME[]_PREFIX=
-  rpathdirs=
-  ltrpathdirs=
-  names_already_handled=
-  names_next_round='$1 $2'
-  while test -n "$names_next_round"; do
-    names_this_round="$names_next_round"
-    names_next_round=
-    for name in $names_this_round; do
-      already_handled=
-      for n in $names_already_handled; do
-        if test "$n" = "$name"; then
-          already_handled=yes
-          break
-        fi
-      done
-      if test -z "$already_handled"; then
-        names_already_handled="$names_already_handled $name"
-        dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
-        dnl or AC_LIB_HAVE_LINKFLAGS call.
-        uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
-        eval value=\"\$HAVE_LIB$uppername\"
-        if test -n "$value"; then
-          if test "$value" = yes; then
-            eval value=\"\$LIB$uppername\"
-            test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
-            eval value=\"\$LTLIB$uppername\"
-            test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
-          else
-            dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
-            dnl that this library doesn't exist. So just drop it.
-            :
-          fi
-        else
-          dnl Search the library lib$name in $additional_libdir and $LDFLAGS
-          dnl and the already constructed $LIBNAME/$LTLIBNAME.
-          found_dir=
-          found_la=
-          found_so=
-          found_a=
-          eval libname=\"$acl_libname_spec\"    # typically: libname=lib$name
-          if test -n "$acl_shlibext"; then
-            shrext=".$acl_shlibext"             # typically: shrext=.so
-          else
-            shrext=
-          fi
-          if test $use_additional = yes; then
-            dir="$additional_libdir"
-            dnl The same code as in the loop below:
-            dnl First look for a shared library.
-            if test -n "$acl_shlibext"; then
-              if test -f "$dir/$libname$shrext"; then
-                found_dir="$dir"
-                found_so="$dir/$libname$shrext"
-              else
-                if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
-                  ver=`(cd "$dir" && \
-                        for f in "$libname$shrext".*; do echo "$f"; done \
-                        | sed -e "s,^$libname$shrext\\\\.,," \
-                        | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
-                        | sed 1q ) 2>/dev/null`
-                  if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
-                    found_dir="$dir"
-                    found_so="$dir/$libname$shrext.$ver"
-                  fi
-                else
-                  eval library_names=\"$acl_library_names_spec\"
-                  for f in $library_names; do
-                    if test -f "$dir/$f"; then
-                      found_dir="$dir"
-                      found_so="$dir/$f"
-                      break
-                    fi
-                  done
-                fi
-              fi
-            fi
-            dnl Then look for a static library.
-            if test "X$found_dir" = "X"; then
-              if test -f "$dir/$libname.$acl_libext"; then
-                found_dir="$dir"
-                found_a="$dir/$libname.$acl_libext"
-              fi
-            fi
-            if test "X$found_dir" != "X"; then
-              if test -f "$dir/$libname.la"; then
-                found_la="$dir/$libname.la"
-              fi
-            fi
-          fi
-          if test "X$found_dir" = "X"; then
-            for x in $LDFLAGS $LTLIB[]NAME; do
-              AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-              case "$x" in
-                -L*)
-                  dir=`echo "X$x" | sed -e 's/^X-L//'`
-                  dnl First look for a shared library.
-                  if test -n "$acl_shlibext"; then
-                    if test -f "$dir/$libname$shrext"; then
-                      found_dir="$dir"
-                      found_so="$dir/$libname$shrext"
-                    else
-                      if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
-                        ver=`(cd "$dir" && \
-                              for f in "$libname$shrext".*; do echo "$f"; done \
-                              | sed -e "s,^$libname$shrext\\\\.,," \
-                              | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
-                              | sed 1q ) 2>/dev/null`
-                        if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
-                          found_dir="$dir"
-                          found_so="$dir/$libname$shrext.$ver"
-                        fi
-                      else
-                        eval library_names=\"$acl_library_names_spec\"
-                        for f in $library_names; do
-                          if test -f "$dir/$f"; then
-                            found_dir="$dir"
-                            found_so="$dir/$f"
-                            break
-                          fi
-                        done
-                      fi
-                    fi
-                  fi
-                  dnl Then look for a static library.
-                  if test "X$found_dir" = "X"; then
-                    if test -f "$dir/$libname.$acl_libext"; then
-                      found_dir="$dir"
-                      found_a="$dir/$libname.$acl_libext"
-                    fi
-                  fi
-                  if test "X$found_dir" != "X"; then
-                    if test -f "$dir/$libname.la"; then
-                      found_la="$dir/$libname.la"
-                    fi
-                  fi
-                  ;;
-              esac
-              if test "X$found_dir" != "X"; then
-                break
-              fi
-            done
-          fi
-          if test "X$found_dir" != "X"; then
-            dnl Found the library.
-            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
-            if test "X$found_so" != "X"; then
-              dnl Linking with a shared library. We attempt to hardcode its
-              dnl directory into the executable's runpath, unless it's the
-              dnl standard /usr/lib.
-              if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then
-                dnl No hardcoding is needed.
-                LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
-              else
-                dnl Use an explicit option to hardcode DIR into the resulting
-                dnl binary.
-                dnl Potentially add DIR to ltrpathdirs.
-                dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
-                haveit=
-                for x in $ltrpathdirs; do
-                  if test "X$x" = "X$found_dir"; then
-                    haveit=yes
-                    break
-                  fi
-                done
-                if test -z "$haveit"; then
-                  ltrpathdirs="$ltrpathdirs $found_dir"
-                fi
-                dnl The hardcoding into $LIBNAME is system dependent.
-                if test "$acl_hardcode_direct" = yes; then
-                  dnl Using DIR/libNAME.so during linking hardcodes DIR into the
-                  dnl resulting binary.
-                  LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
-                else
-                  if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
-                    dnl Use an explicit option to hardcode DIR into the resulting
-                    dnl binary.
-                    LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
-                    dnl Potentially add DIR to rpathdirs.
-                    dnl The rpathdirs will be appended to $LIBNAME at the end.
-                    haveit=
-                    for x in $rpathdirs; do
-                      if test "X$x" = "X$found_dir"; then
-                        haveit=yes
-                        break
-                      fi
-                    done
-                    if test -z "$haveit"; then
-                      rpathdirs="$rpathdirs $found_dir"
-                    fi
-                  else
-                    dnl Rely on "-L$found_dir".
-                    dnl But don't add it if it's already contained in the LDFLAGS
-                    dnl or the already constructed $LIBNAME
-                    haveit=
-                    for x in $LDFLAGS $LIB[]NAME; do
-                      AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-                      if test "X$x" = "X-L$found_dir"; then
-                        haveit=yes
-                        break
-                      fi
-                    done
-                    if test -z "$haveit"; then
-                      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
-                    fi
-                    if test "$acl_hardcode_minus_L" != no; then
-                      dnl FIXME: Not sure whether we should use
-                      dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
-                      dnl here.
-                      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
-                    else
-                      dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH
-                      dnl here, because this doesn't fit in flags passed to the
-                      dnl compiler. So give up. No hardcoding. This affects only
-                      dnl very old systems.
-                      dnl FIXME: Not sure whether we should use
-                      dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
-                      dnl here.
-                      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
-                    fi
-                  fi
-                fi
-              fi
-            else
-              if test "X$found_a" != "X"; then
-                dnl Linking with a static library.
-                LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
-              else
-                dnl We shouldn't come here, but anyway it's good to have a
-                dnl fallback.
-                LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
-              fi
-            fi
-            dnl Assume the include files are nearby.
-            additional_includedir=
-            case "$found_dir" in
-              */$acl_libdirstem | */$acl_libdirstem/)
-                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
-                LIB[]NAME[]_PREFIX="$basedir"
-                additional_includedir="$basedir/include"
-                ;;
-            esac
-            if test "X$additional_includedir" != "X"; then
-              dnl Potentially add $additional_includedir to $INCNAME.
-              dnl But don't add it
-              dnl   1. if it's the standard /usr/include,
-              dnl   2. if it's /usr/local/include and we are using GCC on Linux,
-              dnl   3. if it's already present in $CPPFLAGS or the already
-              dnl      constructed $INCNAME,
-              dnl   4. if it doesn't exist as a directory.
-              if test "X$additional_includedir" != "X/usr/include"; then
-                haveit=
-                if test "X$additional_includedir" = "X/usr/local/include"; then
-                  if test -n "$GCC"; then
-                    case $host_os in
-                      linux* | gnu* | k*bsd*-gnu) haveit=yes;;
-                    esac
-                  fi
-                fi
-                if test -z "$haveit"; then
-                  for x in $CPPFLAGS $INC[]NAME; do
-                    AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-                    if test "X$x" = "X-I$additional_includedir"; then
-                      haveit=yes
-                      break
-                    fi
-                  done
-                  if test -z "$haveit"; then
-                    if test -d "$additional_includedir"; then
-                      dnl Really add $additional_includedir to $INCNAME.
-                      INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
-                    fi
-                  fi
-                fi
-              fi
-            fi
-            dnl Look for dependencies.
-            if test -n "$found_la"; then
-              dnl Read the .la file. It defines the variables
-              dnl dlname, library_names, old_library, dependency_libs, current,
-              dnl age, revision, installed, dlopen, dlpreopen, libdir.
-              save_libdir="$libdir"
-              case "$found_la" in
-                */* | *\\*) . "$found_la" ;;
-                *) . "./$found_la" ;;
-              esac
-              libdir="$save_libdir"
-              dnl We use only dependency_libs.
-              for dep in $dependency_libs; do
-                case "$dep" in
-                  -L*)
-                    additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
-                    dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
-                    dnl But don't add it
-                    dnl   1. if it's the standard /usr/lib,
-                    dnl   2. if it's /usr/local/lib and we are using GCC on Linux,
-                    dnl   3. if it's already present in $LDFLAGS or the already
-                    dnl      constructed $LIBNAME,
-                    dnl   4. if it doesn't exist as a directory.
-                    if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
-                      haveit=
-                      if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
-                        if test -n "$GCC"; then
-                          case $host_os in
-                            linux* | gnu* | k*bsd*-gnu) haveit=yes;;
-                          esac
-                        fi
-                      fi
-                      if test -z "$haveit"; then
-                        haveit=
-                        for x in $LDFLAGS $LIB[]NAME; do
-                          AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-                          if test "X$x" = "X-L$additional_libdir"; then
-                            haveit=yes
-                            break
-                          fi
-                        done
-                        if test -z "$haveit"; then
-                          if test -d "$additional_libdir"; then
-                            dnl Really add $additional_libdir to $LIBNAME.
-                            LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
-                          fi
-                        fi
-                        haveit=
-                        for x in $LDFLAGS $LTLIB[]NAME; do
-                          AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-                          if test "X$x" = "X-L$additional_libdir"; then
-                            haveit=yes
-                            break
-                          fi
-                        done
-                        if test -z "$haveit"; then
-                          if test -d "$additional_libdir"; then
-                            dnl Really add $additional_libdir to $LTLIBNAME.
-                            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
-                          fi
-                        fi
-                      fi
-                    fi
-                    ;;
-                  -R*)
-                    dir=`echo "X$dep" | sed -e 's/^X-R//'`
-                    if test "$enable_rpath" != no; then
-                      dnl Potentially add DIR to rpathdirs.
-                      dnl The rpathdirs will be appended to $LIBNAME at the end.
-                      haveit=
-                      for x in $rpathdirs; do
-                        if test "X$x" = "X$dir"; then
-                          haveit=yes
-                          break
-                        fi
-                      done
-                      if test -z "$haveit"; then
-                        rpathdirs="$rpathdirs $dir"
-                      fi
-                      dnl Potentially add DIR to ltrpathdirs.
-                      dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
-                      haveit=
-                      for x in $ltrpathdirs; do
-                        if test "X$x" = "X$dir"; then
-                          haveit=yes
-                          break
-                        fi
-                      done
-                      if test -z "$haveit"; then
-                        ltrpathdirs="$ltrpathdirs $dir"
-                      fi
-                    fi
-                    ;;
-                  -l*)
-                    dnl Handle this in the next round.
-                    names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
-                    ;;
-                  *.la)
-                    dnl Handle this in the next round. Throw away the .la's
-                    dnl directory; it is already contained in a preceding -L
-                    dnl option.
-                    names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
-                    ;;
-                  *)
-                    dnl Most likely an immediate library name.
-                    LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
-                    LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
-                    ;;
-                esac
-              done
-            fi
-          else
-            dnl Didn't find the library; assume it is in the system directories
-            dnl known to the linker and runtime loader. (All the system
-            dnl directories known to the linker should also be known to the
-            dnl runtime loader, otherwise the system is severely misconfigured.)
-            LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
-            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
-          fi
-        fi
-      fi
-    done
-  done
-  if test "X$rpathdirs" != "X"; then
-    if test -n "$acl_hardcode_libdir_separator"; then
-      dnl Weird platform: only the last -rpath option counts, the user must
-      dnl pass all path elements in one option. We can arrange that for a
-      dnl single library, but not when more than one $LIBNAMEs are used.
-      alldirs=
-      for found_dir in $rpathdirs; do
-        alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
-      done
-      dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl.
-      acl_save_libdir="$libdir"
-      libdir="$alldirs"
-      eval flag=\"$acl_hardcode_libdir_flag_spec\"
-      libdir="$acl_save_libdir"
-      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
-    else
-      dnl The -rpath options are cumulative.
-      for found_dir in $rpathdirs; do
-        acl_save_libdir="$libdir"
-        libdir="$found_dir"
-        eval flag=\"$acl_hardcode_libdir_flag_spec\"
-        libdir="$acl_save_libdir"
-        LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
-      done
-    fi
-  fi
-  if test "X$ltrpathdirs" != "X"; then
-    dnl When using libtool, the option that works for both libraries and
-    dnl executables is -R. The -R options are cumulative.
-    for found_dir in $ltrpathdirs; do
-      LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
-    done
-  fi
-])
-
-dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
-dnl unless already present in VAR.
-dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
-dnl contains two or three consecutive elements that belong together.
-AC_DEFUN([AC_LIB_APPENDTOVAR],
-[
-  for element in [$2]; do
-    haveit=
-    for x in $[$1]; do
-      AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-      if test "X$x" = "X$element"; then
-        haveit=yes
-        break
-      fi
-    done
-    if test -z "$haveit"; then
-      [$1]="${[$1]}${[$1]:+ }$element"
-    fi
-  done
-])
-
-dnl For those cases where a variable contains several -L and -l options
-dnl referring to unknown libraries and directories, this macro determines the
-dnl necessary additional linker options for the runtime path.
-dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])
-dnl sets LDADDVAR to linker options needed together with LIBSVALUE.
-dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,
-dnl otherwise linking without libtool is assumed.
-AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
-[
-  AC_REQUIRE([AC_LIB_RPATH])
-  AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
-  $1=
-  if test "$enable_rpath" != no; then
-    if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
-      dnl Use an explicit option to hardcode directories into the resulting
-      dnl binary.
-      rpathdirs=
-      next=
-      for opt in $2; do
-        if test -n "$next"; then
-          dir="$next"
-          dnl No need to hardcode the standard /usr/lib.
-          if test "X$dir" != "X/usr/$acl_libdirstem"; then
-            rpathdirs="$rpathdirs $dir"
-          fi
-          next=
-        else
-          case $opt in
-            -L) next=yes ;;
-            -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
-                 dnl No need to hardcode the standard /usr/lib.
-                 if test "X$dir" != "X/usr/$acl_libdirstem"; then
-                   rpathdirs="$rpathdirs $dir"
-                 fi
-                 next= ;;
-            *) next= ;;
-          esac
-        fi
-      done
-      if test "X$rpathdirs" != "X"; then
-        if test -n ""$3""; then
-          dnl libtool is used for linking. Use -R options.
-          for dir in $rpathdirs; do
-            $1="${$1}${$1:+ }-R$dir"
-          done
-        else
-          dnl The linker is used for linking directly.
-          if test -n "$acl_hardcode_libdir_separator"; then
-            dnl Weird platform: only the last -rpath option counts, the user
-            dnl must pass all path elements in one option.
-            alldirs=
-            for dir in $rpathdirs; do
-              alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir"
-            done
-            acl_save_libdir="$libdir"
-            libdir="$alldirs"
-            eval flag=\"$acl_hardcode_libdir_flag_spec\"
-            libdir="$acl_save_libdir"
-            $1="$flag"
-          else
-            dnl The -rpath options are cumulative.
-            for dir in $rpathdirs; do
-              acl_save_libdir="$libdir"
-              libdir="$dir"
-              eval flag=\"$acl_hardcode_libdir_flag_spec\"
-              libdir="$acl_save_libdir"
-              $1="${$1}${$1:+ }$flag"
-            done
-          fi
-        fi
-      fi
-    fi
-  fi
-  AC_SUBST([$1])
-])
diff --git a/m4/lib-prefix.m4 b/m4/lib-prefix.m4
deleted file mode 100644 (file)
index a8684e1..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-# lib-prefix.m4 serial 5 (gettext-0.15)
-dnl Copyright (C) 2001-2005 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 From Bruno Haible.
-
-dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
-dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
-dnl require excessive bracketing.
-ifdef([AC_HELP_STRING],
-[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
-[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
-
-dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
-dnl to access previously installed libraries. The basic assumption is that
-dnl a user will want packages to use other packages he previously installed
-dnl with the same --prefix option.
-dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
-dnl libraries, but is otherwise very convenient.
-AC_DEFUN([AC_LIB_PREFIX],
-[
-  AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
-  AC_REQUIRE([AC_PROG_CC])
-  AC_REQUIRE([AC_CANONICAL_HOST])
-  AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
-  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
-  dnl By default, look in $includedir and $libdir.
-  use_additional=yes
-  AC_LIB_WITH_FINAL_PREFIX([
-    eval additional_includedir=\"$includedir\"
-    eval additional_libdir=\"$libdir\"
-  ])
-  AC_LIB_ARG_WITH([lib-prefix],
-[  --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
-  --without-lib-prefix    don't search for libraries in includedir and libdir],
-[
-    if test "X$withval" = "Xno"; then
-      use_additional=no
-    else
-      if test "X$withval" = "X"; then
-        AC_LIB_WITH_FINAL_PREFIX([
-          eval additional_includedir=\"$includedir\"
-          eval additional_libdir=\"$libdir\"
-        ])
-      else
-        additional_includedir="$withval/include"
-        additional_libdir="$withval/$acl_libdirstem"
-      fi
-    fi
-])
-  if test $use_additional = yes; then
-    dnl Potentially add $additional_includedir to $CPPFLAGS.
-    dnl But don't add it
-    dnl   1. if it's the standard /usr/include,
-    dnl   2. if it's already present in $CPPFLAGS,
-    dnl   3. if it's /usr/local/include and we are using GCC on Linux,
-    dnl   4. if it doesn't exist as a directory.
-    if test "X$additional_includedir" != "X/usr/include"; then
-      haveit=
-      for x in $CPPFLAGS; do
-        AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-        if test "X$x" = "X-I$additional_includedir"; then
-          haveit=yes
-          break
-        fi
-      done
-      if test -z "$haveit"; then
-        if test "X$additional_includedir" = "X/usr/local/include"; then
-          if test -n "$GCC"; then
-            case $host_os in
-              linux* | gnu* | k*bsd*-gnu) haveit=yes;;
-            esac
-          fi
-        fi
-        if test -z "$haveit"; then
-          if test -d "$additional_includedir"; then
-            dnl Really add $additional_includedir to $CPPFLAGS.
-            CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
-          fi
-        fi
-      fi
-    fi
-    dnl Potentially add $additional_libdir to $LDFLAGS.
-    dnl But don't add it
-    dnl   1. if it's the standard /usr/lib,
-    dnl   2. if it's already present in $LDFLAGS,
-    dnl   3. if it's /usr/local/lib and we are using GCC on Linux,
-    dnl   4. if it doesn't exist as a directory.
-    if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
-      haveit=
-      for x in $LDFLAGS; do
-        AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-        if test "X$x" = "X-L$additional_libdir"; then
-          haveit=yes
-          break
-        fi
-      done
-      if test -z "$haveit"; then
-        if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
-          if test -n "$GCC"; then
-            case $host_os in
-              linux*) haveit=yes;;
-            esac
-          fi
-        fi
-        if test -z "$haveit"; then
-          if test -d "$additional_libdir"; then
-            dnl Really add $additional_libdir to $LDFLAGS.
-            LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
-          fi
-        fi
-      fi
-    fi
-  fi
-])
-
-dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
-dnl acl_final_exec_prefix, containing the values to which $prefix and
-dnl $exec_prefix will expand at the end of the configure script.
-AC_DEFUN([AC_LIB_PREPARE_PREFIX],
-[
-  dnl Unfortunately, prefix and exec_prefix get only finally determined
-  dnl at the end of configure.
-  if test "X$prefix" = "XNONE"; then
-    acl_final_prefix="$ac_default_prefix"
-  else
-    acl_final_prefix="$prefix"
-  fi
-  if test "X$exec_prefix" = "XNONE"; then
-    acl_final_exec_prefix='${prefix}'
-  else
-    acl_final_exec_prefix="$exec_prefix"
-  fi
-  acl_save_prefix="$prefix"
-  prefix="$acl_final_prefix"
-  eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
-  prefix="$acl_save_prefix"
-])
-
-dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
-dnl variables prefix and exec_prefix bound to the values they will have
-dnl at the end of the configure script.
-AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
-[
-  acl_save_prefix="$prefix"
-  prefix="$acl_final_prefix"
-  acl_save_exec_prefix="$exec_prefix"
-  exec_prefix="$acl_final_exec_prefix"
-  $1
-  exec_prefix="$acl_save_exec_prefix"
-  prefix="$acl_save_prefix"
-])
-
-dnl AC_LIB_PREPARE_MULTILIB creates a variable acl_libdirstem, containing
-dnl the basename of the libdir, either "lib" or "lib64".
-AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
-[
-  dnl There is no formal standard regarding lib and lib64. The current
-  dnl practice is that on a system supporting 32-bit and 64-bit instruction
-  dnl sets or ABIs, 64-bit libraries go under $prefix/lib64 and 32-bit
-  dnl libraries go under $prefix/lib. We determine the compiler's default
-  dnl mode by looking at the compiler's library search path. If at least
-  dnl of its elements ends in /lib64 or points to a directory whose absolute
-  dnl pathname ends in /lib64, we assume a 64-bit ABI. Otherwise we use the
-  dnl default, namely "lib".
-  acl_libdirstem=lib
-  searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
-  if test -n "$searchpath"; then
-    acl_save_IFS="${IFS=       }"; IFS=":"
-    for searchdir in $searchpath; do
-      if test -d "$searchdir"; then
-        case "$searchdir" in
-          */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
-          *) searchdir=`cd "$searchdir" && pwd`
-             case "$searchdir" in
-               */lib64 ) acl_libdirstem=lib64 ;;
-             esac ;;
-        esac
-      fi
-    done
-    IFS="$acl_save_IFS"
-  fi
-])
diff --git a/m4/nls.m4 b/m4/nls.m4
deleted file mode 100644 (file)
index 7967cc2..0000000
--- a/m4/nls.m4
+++ /dev/null
@@ -1,31 +0,0 @@
-# nls.m4 serial 3 (gettext-0.15)
-dnl Copyright (C) 1995-2003, 2005-2006 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 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 They are *not* in the public domain.
-
-dnl Authors:
-dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
-dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2003.
-
-AC_PREREQ(2.50)
-
-AC_DEFUN([AM_NLS],
-[
-  AC_MSG_CHECKING([whether NLS is requested])
-  dnl Default is enabled NLS
-  AC_ARG_ENABLE(nls,
-    [  --disable-nls           do not use Native Language Support],
-    USE_NLS=$enableval, USE_NLS=yes)
-  AC_MSG_RESULT($USE_NLS)
-  AC_SUBST(USE_NLS)
-])
index 92bf21e..983d462 100644 (file)
--- a/m4/orc.m4
+++ b/m4/orc.m4
@@ -5,7 +5,7 @@ dnl ORC_CHECK([REQUIRED_VERSION])
 
 AC_DEFUN([ORC_CHECK],
 [
-  ORC_REQ=ifelse([$1], , "0.4.5", [$1])
+  ORC_REQ=ifelse([$1], , "0.4.6", [$1])
 
   AC_ARG_ENABLE(orc,
   AC_HELP_STRING([--enable-orc],[use Orc if installed]),
@@ -21,21 +21,34 @@ AC_DEFUN([ORC_CHECK],
   if test "x$enable_orc" != "xno" ; then
     PKG_CHECK_MODULES(ORC, orc-0.4 >= $ORC_REQ, [
       AC_DEFINE(HAVE_ORC, 1, [Use Orc])
-      ORCC=`$PKG_CONFIG --variable=orcc orc-0.4`
-      AC_SUBST(ORCC)
       HAVE_ORC=yes
+      if test "x$ORCC" = "x" ; then
+        AC_MSG_CHECKING(for usable orcc)
+        ORCC=`$PKG_CONFIG --variable=orcc orc-0.4`
+        dnl check whether the orcc found by pkg-config can be run from the build environment
+        dnl if this is not the case (e.g. when cross-compiling) fall back to orcc from PATH
+        AS_IF([$ORCC --version 1> /dev/null 2> /dev/null], [], [ORCC=`which orcc`])
+        AC_MSG_RESULT($ORCC)
+      fi
+      AC_SUBST(ORCC)
+      ORCC_FLAGS="--compat $ORC_REQ"
+      AC_SUBST(ORCC_FLAGS)
+      AS_IF([test "x$ORCC" = "x"], [HAVE_ORCC=no], [HAVE_ORCC=yes])
     ], [
       if test "x$enable_orc" = "xyes" ; then
         AC_MSG_ERROR([--enable-orc specified, but Orc >= $ORC_REQ not found])
       fi
       AC_DEFINE(DISABLE_ORC, 1, [Disable Orc])
       HAVE_ORC=no
+      HAVE_ORCC=no
     ])
   else
     AC_DEFINE(DISABLE_ORC, 1, [Disable Orc])
     HAVE_ORC=no
+    HAVE_ORCC=no
   fi
-  AM_CONDITIONAL(HAVE_ORC, test "x$HAVE_ORC" = "xyes")
+  AM_CONDITIONAL(HAVE_ORC, [test "x$HAVE_ORC" = "xyes"])
+  AM_CONDITIONAL(HAVE_ORCC, [test "x$HAVE_ORCC" = "xyes"])
 
 ]))
 
diff --git a/m4/po.m4 b/m4/po.m4
deleted file mode 100644 (file)
index 0734762..0000000
--- a/m4/po.m4
+++ /dev/null
@@ -1,449 +0,0 @@
-# po.m4 serial 15 (gettext-0.17)
-dnl Copyright (C) 1995-2007 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 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 They are *not* in the public domain.
-
-dnl Authors:
-dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
-dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2003.
-
-AC_PREREQ(2.50)
-
-dnl Checks for all prerequisites of the po subdirectory.
-AC_DEFUN([AM_PO_SUBDIRS],
-[
-  AC_REQUIRE([AC_PROG_MAKE_SET])dnl
-  AC_REQUIRE([AC_PROG_INSTALL])dnl
-  AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake
-  AC_REQUIRE([AM_NLS])dnl
-
-  dnl Release version of the gettext macros. This is used to ensure that
-  dnl the gettext macros and po/Makefile.in.in are in sync.
-  AC_SUBST([GETTEXT_MACRO_VERSION], [0.17])
-
-  dnl Perform the following tests also if --disable-nls has been given,
-  dnl because they are needed for "make dist" to work.
-
-  dnl Search for GNU msgfmt in the PATH.
-  dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions.
-  dnl The second test excludes FreeBSD msgfmt.
-  AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
-    [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
-     (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
-    :)
-  AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
-
-  dnl Test whether it is GNU msgfmt >= 0.15.
-changequote(,)dnl
-  case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
-    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;;
-    *) MSGFMT_015=$MSGFMT ;;
-  esac
-changequote([,])dnl
-  AC_SUBST([MSGFMT_015])
-changequote(,)dnl
-  case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
-    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;;
-    *) GMSGFMT_015=$GMSGFMT ;;
-  esac
-changequote([,])dnl
-  AC_SUBST([GMSGFMT_015])
-
-  dnl Search for GNU xgettext 0.12 or newer in the PATH.
-  dnl The first test excludes Solaris xgettext and early GNU xgettext versions.
-  dnl The second test excludes FreeBSD xgettext.
-  AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
-    [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
-     (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
-    :)
-  dnl Remove leftover from FreeBSD xgettext call.
-  rm -f messages.po
-
-  dnl Test whether it is GNU xgettext >= 0.15.
-changequote(,)dnl
-  case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
-    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;;
-    *) XGETTEXT_015=$XGETTEXT ;;
-  esac
-changequote([,])dnl
-  AC_SUBST([XGETTEXT_015])
-
-  dnl Search for GNU msgmerge 0.11 or newer in the PATH.
-  AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge,
-    [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :)
-
-  dnl Installation directories.
-  dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we
-  dnl have to define it here, so that it can be used in po/Makefile.
-  test -n "$localedir" || localedir='${datadir}/locale'
-  AC_SUBST([localedir])
-
-  dnl Support for AM_XGETTEXT_OPTION.
-  test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS=
-  AC_SUBST([XGETTEXT_EXTRA_OPTIONS])
-
-  AC_CONFIG_COMMANDS([po-directories], [[
-    for ac_file in $CONFIG_FILES; do
-      # Support "outfile[:infile[:infile...]]"
-      case "$ac_file" in
-        *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
-      esac
-      # PO directories have a Makefile.in generated from Makefile.in.in.
-      case "$ac_file" in */Makefile.in)
-        # Adjust a relative srcdir.
-        ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
-        ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
-        ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
-        # In autoconf-2.13 it is called $ac_given_srcdir.
-        # In autoconf-2.50 it is called $srcdir.
-        test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
-        case "$ac_given_srcdir" in
-          .)  top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
-          /*) top_srcdir="$ac_given_srcdir" ;;
-          *)  top_srcdir="$ac_dots$ac_given_srcdir" ;;
-        esac
-        # Treat a directory as a PO directory if and only if it has a
-        # POTFILES.in file. This allows packages to have multiple PO
-        # directories under different names or in different locations.
-        if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
-          rm -f "$ac_dir/POTFILES"
-          test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
-          cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[  ]*\$/d" -e "s,.*,     $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
-          POMAKEFILEDEPS="POTFILES.in"
-          # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend
-          # on $ac_dir but don't depend on user-specified configuration
-          # parameters.
-          if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
-            # The LINGUAS file contains the set of available languages.
-            if test -n "$OBSOLETE_ALL_LINGUAS"; then
-              test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
-            fi
-            ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
-            # Hide the ALL_LINGUAS assigment from automake < 1.5.
-            eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
-            POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
-          else
-            # The set of available languages was given in configure.in.
-            # Hide the ALL_LINGUAS assigment from automake < 1.5.
-            eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
-          fi
-          # Compute POFILES
-          # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
-          # Compute UPDATEPOFILES
-          # as      $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
-          # Compute DUMMYPOFILES
-          # as      $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
-          # Compute GMOFILES
-          # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
-          case "$ac_given_srcdir" in
-            .) srcdirpre= ;;
-            *) srcdirpre='$(srcdir)/' ;;
-          esac
-          POFILES=
-          UPDATEPOFILES=
-          DUMMYPOFILES=
-          GMOFILES=
-          for lang in $ALL_LINGUAS; do
-            POFILES="$POFILES $srcdirpre$lang.po"
-            UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
-            DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
-            GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
-          done
-          # CATALOGS depends on both $ac_dir and the user's LINGUAS
-          # environment variable.
-          INST_LINGUAS=
-          if test -n "$ALL_LINGUAS"; then
-            for presentlang in $ALL_LINGUAS; do
-              useit=no
-              if test "%UNSET%" != "$LINGUAS"; then
-                desiredlanguages="$LINGUAS"
-              else
-                desiredlanguages="$ALL_LINGUAS"
-              fi
-              for desiredlang in $desiredlanguages; do
-                # Use the presentlang catalog if desiredlang is
-                #   a. equal to presentlang, or
-                #   b. a variant of presentlang (because in this case,
-                #      presentlang can be used as a fallback for messages
-                #      which are not translated in the desiredlang catalog).
-                case "$desiredlang" in
-                  "$presentlang"*) useit=yes;;
-                esac
-              done
-              if test $useit = yes; then
-                INST_LINGUAS="$INST_LINGUAS $presentlang"
-              fi
-            done
-          fi
-          CATALOGS=
-          if test -n "$INST_LINGUAS"; then
-            for lang in $INST_LINGUAS; do
-              CATALOGS="$CATALOGS $lang.gmo"
-            done
-          fi
-          test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
-          sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
-          for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do
-            if test -f "$f"; then
-              case "$f" in
-                *.orig | *.bak | *~) ;;
-                *) cat "$f" >> "$ac_dir/Makefile" ;;
-              esac
-            fi
-          done
-        fi
-        ;;
-      esac
-    done]],
-   [# Capture the value of obsolete ALL_LINGUAS because we need it to compute
-    # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it
-    # from automake < 1.5.
-    eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"'
-    # Capture the value of LINGUAS because we need it to compute CATALOGS.
-    LINGUAS="${LINGUAS-%UNSET%}"
-   ])
-])
-
-dnl Postprocesses a Makefile in a directory containing PO files.
-AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE],
-[
-  # When this code is run, in config.status, two variables have already been
-  # set:
-  # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in,
-  # - LINGUAS is the value of the environment variable LINGUAS at configure
-  #   time.
-
-changequote(,)dnl
-  # Adjust a relative srcdir.
-  ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
-  ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
-  ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
-  # In autoconf-2.13 it is called $ac_given_srcdir.
-  # In autoconf-2.50 it is called $srcdir.
-  test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
-  case "$ac_given_srcdir" in
-    .)  top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
-    /*) top_srcdir="$ac_given_srcdir" ;;
-    *)  top_srcdir="$ac_dots$ac_given_srcdir" ;;
-  esac
-
-  # Find a way to echo strings without interpreting backslash.
-  if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then
-    gt_echo='echo'
-  else
-    if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then
-      gt_echo='printf %s\n'
-    else
-      echo_func () {
-        cat <<EOT
-$*
-EOT
-      }
-      gt_echo='echo_func'
-    fi
-  fi
-
-  # A sed script that extracts the value of VARIABLE from a Makefile.
-  sed_x_variable='
-# Test if the hold space is empty.
-x
-s/P/P/
-x
-ta
-# Yes it was empty. Look if we have the expected variable definition.
-/^[     ]*VARIABLE[     ]*=/{
-  # Seen the first line of the variable definition.
-  s/^[  ]*VARIABLE[     ]*=//
-  ba
-}
-bd
-:a
-# Here we are processing a line from the variable definition.
-# Remove comment, more precisely replace it with a space.
-s/#.*$/ /
-# See if the line ends in a backslash.
-tb
-:b
-s/\\$//
-# Print the line, without the trailing backslash.
-p
-tc
-# There was no trailing backslash. The end of the variable definition is
-# reached. Clear the hold space.
-s/^.*$//
-x
-bd
-:c
-# A trailing backslash means that the variable definition continues in the
-# next line. Put a nonempty string into the hold space to indicate this.
-s/^.*$/P/
-x
-:d
-'
-changequote([,])dnl
-
-  # Set POTFILES to the value of the Makefile variable POTFILES.
-  sed_x_POTFILES=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/POTFILES/g'`
-  POTFILES=`sed -n -e "$sed_x_POTFILES" < "$ac_file"`
-  # Compute POTFILES_DEPS as
-  #   $(foreach file, $(POTFILES), $(top_srcdir)/$(file))
-  POTFILES_DEPS=
-  for file in $POTFILES; do
-    POTFILES_DEPS="$POTFILES_DEPS "'$(top_srcdir)/'"$file"
-  done
-  POMAKEFILEDEPS=""
-
-  if test -n "$OBSOLETE_ALL_LINGUAS"; then
-    test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
-  fi
-  if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
-    # The LINGUAS file contains the set of available languages.
-    ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
-    POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
-  else
-    # Set ALL_LINGUAS to the value of the Makefile variable LINGUAS.
-    sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/LINGUAS/g'`
-    ALL_LINGUAS_=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"`
-  fi
-  # Hide the ALL_LINGUAS assigment from automake < 1.5.
-  eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
-  # Compute POFILES
-  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
-  # Compute UPDATEPOFILES
-  # as      $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
-  # Compute DUMMYPOFILES
-  # as      $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
-  # Compute GMOFILES
-  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
-  # Compute PROPERTIESFILES
-  # as      $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).properties)
-  # Compute CLASSFILES
-  # as      $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).class)
-  # Compute QMFILES
-  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm)
-  # Compute MSGFILES
-  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang)).msg)
-  # Compute RESOURCESDLLFILES
-  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang))/$(DOMAIN).resources.dll)
-  case "$ac_given_srcdir" in
-    .) srcdirpre= ;;
-    *) srcdirpre='$(srcdir)/' ;;
-  esac
-  POFILES=
-  UPDATEPOFILES=
-  DUMMYPOFILES=
-  GMOFILES=
-  PROPERTIESFILES=
-  CLASSFILES=
-  QMFILES=
-  MSGFILES=
-  RESOURCESDLLFILES=
-  for lang in $ALL_LINGUAS; do
-    POFILES="$POFILES $srcdirpre$lang.po"
-    UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
-    DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
-    GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
-    PROPERTIESFILES="$PROPERTIESFILES \$(top_srcdir)/\$(DOMAIN)_$lang.properties"
-    CLASSFILES="$CLASSFILES \$(top_srcdir)/\$(DOMAIN)_$lang.class"
-    QMFILES="$QMFILES $srcdirpre$lang.qm"
-    frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
-    MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg"
-    frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
-    RESOURCESDLLFILES="$RESOURCESDLLFILES $srcdirpre$frobbedlang/\$(DOMAIN).resources.dll"
-  done
-  # CATALOGS depends on both $ac_dir and the user's LINGUAS
-  # environment variable.
-  INST_LINGUAS=
-  if test -n "$ALL_LINGUAS"; then
-    for presentlang in $ALL_LINGUAS; do
-      useit=no
-      if test "%UNSET%" != "$LINGUAS"; then
-        desiredlanguages="$LINGUAS"
-      else
-        desiredlanguages="$ALL_LINGUAS"
-      fi
-      for desiredlang in $desiredlanguages; do
-        # Use the presentlang catalog if desiredlang is
-        #   a. equal to presentlang, or
-        #   b. a variant of presentlang (because in this case,
-        #      presentlang can be used as a fallback for messages
-        #      which are not translated in the desiredlang catalog).
-        case "$desiredlang" in
-          "$presentlang"*) useit=yes;;
-        esac
-      done
-      if test $useit = yes; then
-        INST_LINGUAS="$INST_LINGUAS $presentlang"
-      fi
-    done
-  fi
-  CATALOGS=
-  JAVACATALOGS=
-  QTCATALOGS=
-  TCLCATALOGS=
-  CSHARPCATALOGS=
-  if test -n "$INST_LINGUAS"; then
-    for lang in $INST_LINGUAS; do
-      CATALOGS="$CATALOGS $lang.gmo"
-      JAVACATALOGS="$JAVACATALOGS \$(DOMAIN)_$lang.properties"
-      QTCATALOGS="$QTCATALOGS $lang.qm"
-      frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
-      TCLCATALOGS="$TCLCATALOGS $frobbedlang.msg"
-      frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
-      CSHARPCATALOGS="$CSHARPCATALOGS $frobbedlang/\$(DOMAIN).resources.dll"
-    done
-  fi
-
-  sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e "s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e "s|@MSGFILES@|$MSGFILES|g" -e "s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e "s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e "s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' < "$ac_file" > "$ac_file.tmp"
-  if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then
-    # Add dependencies that cannot be formulated as a simple suffix rule.
-    for lang in $ALL_LINGUAS; do
-      frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
-      cat >> "$ac_file.tmp" <<EOF
-$frobbedlang.msg: $lang.po
-       @echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \
-       \$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
-EOF
-    done
-  fi
-  if grep -l '@CSHARPCATALOGS@' "$ac_file" > /dev/null; then
-    # Add dependencies that cannot be formulated as a simple suffix rule.
-    for lang in $ALL_LINGUAS; do
-      frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
-      cat >> "$ac_file.tmp" <<EOF
-$frobbedlang/\$(DOMAIN).resources.dll: $lang.po
-       @echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r \$(DOMAIN)"; \
-       \$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r "\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
-EOF
-    done
-  fi
-  if test -n "$POMAKEFILEDEPS"; then
-    cat >> "$ac_file.tmp" <<EOF
-Makefile: $POMAKEFILEDEPS
-EOF
-  fi
-  mv "$ac_file.tmp" "$ac_file"
-])
-
-dnl Initializes the accumulator used by AM_XGETTEXT_OPTION.
-AC_DEFUN([AM_XGETTEXT_OPTION_INIT],
-[
-  XGETTEXT_EXTRA_OPTIONS=
-])
-
-dnl Registers an option to be passed to xgettext in the po subdirectory.
-AC_DEFUN([AM_XGETTEXT_OPTION],
-[
-  AC_REQUIRE([AM_XGETTEXT_OPTION_INIT])
-  XGETTEXT_EXTRA_OPTIONS="$XGETTEXT_EXTRA_OPTIONS $1"
-])
diff --git a/m4/progtest.m4 b/m4/progtest.m4
deleted file mode 100644 (file)
index a56365c..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-# progtest.m4 serial 4 (gettext-0.14.2)
-dnl Copyright (C) 1996-2003, 2005 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 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 They are *not* in the public domain.
-
-dnl Authors:
-dnl   Ulrich Drepper <drepper@cygnus.com>, 1996.
-
-AC_PREREQ(2.50)
-
-# Search path for a program which passes the given test.
-
-dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
-dnl   TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
-AC_DEFUN([AM_PATH_PROG_WITH_TEST],
-[
-# Prepare PATH_SEPARATOR.
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
-
-# Find out how to test for executable files. Don't use a zero-byte file,
-# as systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
-  ac_executable_p="test -x"
-else
-  ac_executable_p="test -f"
-fi
-rm -f conf$$.file
-
-# Extract the first word of "$2", so it can be a program name with args.
-set dummy $2; ac_word=[$]2
-AC_MSG_CHECKING([for $ac_word])
-AC_CACHE_VAL(ac_cv_path_$1,
-[case "[$]$1" in
-  [[\\/]]* | ?:[[\\/]]*)
-    ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
-    ;;
-  *)
-    ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
-    for ac_dir in ifelse([$5], , $PATH, [$5]); do
-      IFS="$ac_save_IFS"
-      test -z "$ac_dir" && ac_dir=.
-      for ac_exec_ext in '' $ac_executable_extensions; do
-        if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
-          echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD
-          if [$3]; then
-            ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext"
-            break 2
-          fi
-        fi
-      done
-    done
-    IFS="$ac_save_IFS"
-dnl If no 4th arg is given, leave the cache variable unset,
-dnl so AC_PATH_PROGS will keep looking.
-ifelse([$4], , , [  test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
-])dnl
-    ;;
-esac])dnl
-$1="$ac_cv_path_$1"
-if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
-  AC_MSG_RESULT([$]$1)
-else
-  AC_MSG_RESULT(no)
-fi
-AC_SUBST($1)dnl
-])
diff --git a/m4/tls.m4 b/m4/tls.m4
deleted file mode 100644 (file)
index 3808f06..0000000
--- a/m4/tls.m4
+++ /dev/null
@@ -1,17 +0,0 @@
-AC_DEFUN([CC_CHECK_TLS], [
-  AC_CACHE_CHECK([whether $CC knows __thread for Thread-Local Storage],
-    cc_cv_tls___thread,
-    [AC_COMPILE_IFELSE(
-      AC_LANG_PROGRAM(
-        [[static __thread int a = 6;]],
-        [[a = 5;]]),
-      [cc_cv_tls___thread=yes],
-      [cc_cv_tls___thread=no])
-    ])
-  
-  AS_IF([test "x$cc_cv_tls___thread" = "xyes"],
-    [AC_DEFINE([SUPPORT_TLS___THREAD], 1,
-     [Define this if the compiler supports __thread for Thread-Local Storage])
-     $1],
-    [$2])
-])
diff --git a/man/.gitignore b/man/.gitignore
new file mode 100644 (file)
index 0000000..abf96d9
--- /dev/null
@@ -0,0 +1,6 @@
+/*.1
+/*.1.xml
+/*.5
+/*.5.xml
+/Makefile
+/Makefile.in
index 7793fe7..d0cc8e7 100644 (file)
@@ -15,9 +15,7 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 # USA.
 
-pulseconfdir=$(sysconfdir)/pulse
-
-CLEANFILES = \
+DISTCLEANFILES = \
        $(noinst_DATA)
 
 noinst_DATA = \
@@ -30,15 +28,12 @@ noinst_DATA = \
        pactl.1.xml \
        pasuspender.1.xml \
        padsp.1.xml \
-       pabrowse.1.xml \
        pulse-daemon.conf.5.xml \
        pulse-client.conf.5.xml \
-       default.pa.5.xml
-
-%.xml: %.xml.in Makefile
-       sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
-           -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
-            -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
+       default.pa.5.xml \
+       pulse-cli-syntax.5.xml \
+       start-pulseaudio-kde.1.xml \
+       start-pulseaudio-x11.1.xml
 
 xmllint: $(noinst_DATA)
        for f in $(noinst_DATA) ; do \
@@ -57,16 +52,18 @@ dist_man_MANS = \
        pactl.1 \
        pasuspender.1 \
        padsp.1 \
-       pabrowse.1 \
        pulse-daemon.conf.5 \
        pulse-client.conf.5 \
-       default.pa.5
+       default.pa.5 \
+       pulse-cli-syntax.5 \
+       start-pulseaudio-kde.1 \
+       start-pulseaudio-x11.1
 
-CLEANFILES += \
+CLEANFILES = \
        $(dist_man_MANS)
 
 %: %.xml Makefile
-       perl $(srcdir)/xmltoman $< > $@ || rm -f $@
+       $(AM_V_GEN) perl $(srcdir)/xmltoman $< > $@ || rm -f $@
 
 endif
 
@@ -80,10 +77,12 @@ EXTRA_DIST = \
        pactl.1.xml.in \
        pasuspender.1.xml.in \
        padsp.1.xml.in \
-       pabrowse.1.xml.in \
        pulse-daemon.conf.5.xml.in \
        pulse-client.conf.5.xml.in \
        default.pa.5.xml.in \
+       pulse-cli-syntax.5.xml.in \
+       start-pulseaudio-kde.1.xml.in \
+       start-pulseaudio-x11.1.xml.in \
        xmltoman \
        xmltoman.css \
        xmltoman.xsl \
index 4caad7c..5690541 100644 (file)
@@ -24,17 +24,17 @@ USA.
 <manpage name="default.pa" section="5" desc="PulseAudio Sound Server Startup Script">
 
   <synopsis>
-    <p><file>~/.pulse/default.pa</file></p>
+    <p><file>~/.config/pulse/default.pa</file></p>
 
-    <p><file>@pulseconfdir@/default.pa</file></p>
+    <p><file>@PA_DEFAULT_CONFIG_DIR@/default.pa</file></p>
   </synopsis>
 
   <description>
     <p>The PulseAudio sound server interprets the file
-    <file>~/.pulse/default.pa</file> on startup, and when that file
-    doesn't exist <file>@pulseconfdir@/default.pa</file>. It
-    should contain directives in the PulseAudio CLI languages, as
-    documented on <url href="http://pulseaudio.org/wiki/CLI"/>.</p>
+    <file>~/.config/pulse/default.pa</file> on startup, and when that file
+    doesn't exist <file>@PA_DEFAULT_CONFIG_DIR@/default.pa</file>. It
+    should contain directives in the PulseAudio CLI language, as
+    documented in <manref name="pulse-cli-syntax" section="5"/>.</p>
 
     <p>The same commands can also be entered during runtime in the <manref name="pacmd"
       section="1"/> tool, allowing flexible runtime reconfiguration.</p>
@@ -47,9 +47,10 @@ USA.
 
   <section name="See also">
     <p>
-      <manref name="pulse-daemon.conf" section="5"/>, <manref
-      name="pulseaudio" section="1"/>, <manref name="pacmd"
-      section="1"/>
+      <manref name="pulse-cli-syntax" section="5"/>,
+      <manref name="pulse-daemon.conf" section="5"/>,
+      <manref name="pulseaudio" section="1"/>,
+      <manref name="pacmd" section="1"/>
     </p>
   </section>
 
index 61fefa3..8ef16ff 100644 (file)
@@ -30,7 +30,7 @@ USA.
   </synopsis>
 
   <description>
-    <p><file>esdcompat</file> is a compatiblity script that takes the
+    <p><file>esdcompat</file> is a compatibility script that takes the
     same arguments as the ESD sound daemon <manref name="esd"
     section="1"/>, but uses them to start a the PulseAudio sound server with the appropriate parameters. It is
     required to make PulseAudio a drop-in replacement for esd, i.e. it
index 68a3a12..868e772 100644 (file)
@@ -21,18 +21,22 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 USA.
 -->
 
-<manpage name="pacat" section="1" desc="Play back or record raw audio streams on a PulseAudio sound server">
+<manpage name="pacat" section="1" desc="Play back or record raw or encoded audio streams on a PulseAudio sound server">
 
   <synopsis>
+    <cmd>paplay [<arg>options</arg>] [<arg>FILE</arg>]</cmd>
+    <cmd>parecord [<arg>options</arg>] [<arg>FILE</arg>]</cmd>
     <cmd>pacat [<arg>options</arg>] [<arg>FILE</arg>]</cmd>
     <cmd>parec [<arg>options</arg>] [<arg>FILE</arg>]</cmd>
-    <cmd>paplay <opt>--help</opt></cmd>
-    <cmd>paplay <opt>--version</opt></cmd>
+    <cmd>pamon [<arg>options</arg>] [<arg>FILE</arg>]</cmd>
+    <cmd>pacat <opt>--help</opt></cmd>
+    <cmd>pacat <opt>--version</opt></cmd>
   </synopsis>
 
   <description>
     <p><file>pacat</file> is a simple tool for playing back or
-    capturing raw audio files on a PulseAudio sound server.</p>
+    capturing raw or encoded audio files on a PulseAudio sound
+    server.</p>
   </description>
 
   <options>
@@ -52,13 +56,13 @@ USA.
     <option>
       <p><opt>-r | --record</opt></p>
 
-      <optdesc><p>Capture raw audio data and write it to the specified file or to STDOUT if none is specified. If the tool is called under the name <file>parec</file> this is the default.</p></optdesc>
+      <optdesc><p>Capture audio data and write it to the specified file or to STDOUT if none is specified. If the tool is called under the name <file>parec</file> this is the default.</p></optdesc>
     </option>
 
     <option>
       <p><opt>-p | --playback</opt></p>
 
-      <optdesc><p>Read raw audio data from the specified file or STDIN if none is specified, and play it back. If the tool is called under the name <file>pacat</file> this is the default.</p></optdesc>
+      <optdesc><p>Read audio data from the specified file or STDIN if none is specified, and play it back. If the tool is called under the name <file>pacat</file> this is the default.</p></optdesc>
     </option>
 
     <option>
@@ -108,14 +112,17 @@ USA.
 
       <optdesc><p>Capture or play back audio with the specified sample
       format. Specify one of <opt>u8</opt>, <opt>s16le</opt>,
-      <opt>s16be</opt>, <opt>s32le</opt>,
-      <opt>s32be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
-      <opt>ulaw</opt>, <opt>alaw</opt>. Depending on the endianess of
-      the CPU the
-      formats <opt>s16ne</opt>, <opt>s16re</opt>, <opt>s32ne</opt>, <opt>s32re</opt>,
-      <opt>float32ne</opt>, <opt>float32re</opt> (for native,
-      resp. reverse endian) are available as aliases. Defaults to
-      s16ne.</p></optdesc>
+      <opt>s16be</opt>, <opt>s32le</opt>, <opt>s32be</opt>,
+      <opt>float32le</opt>, <opt>float32be</opt>, <opt>ulaw</opt>,
+      <opt>alaw</opt>, <opt>s32le</opt>, <opt>s32be</opt>,
+      <opt>s24le</opt>, <opt>s24be</opt>, <opt>s24-32le</opt>,
+      <opt>s24-32be</opt>. Depending on the endianness of the CPU the
+      formats <opt>s16ne</opt>, <opt>s16re</opt>, <opt>s32ne</opt>,
+      <opt>s32re</opt>, <opt>float32ne</opt>, <opt>float32re</opt>,
+      <opt>s32ne</opt>, <opt>s32re</opt>, <opt>s24ne</opt>,
+      <opt>s24re</opt>, <opt>s24-32ne</opt>, <opt>s24-32re</opt> (for
+      native, resp. reverse endian) are available as aliases. Defaults
+      to s16ne.</p></optdesc>
     </option>
 
     <option>
@@ -170,6 +177,65 @@ USA.
       <optdesc><p>Never remap channels. Instead of mapping channels by their name this will match them solely by their index/order.</p></optdesc>
     </option>
 
+    <option>
+      <p><opt>--latency</opt><arg>=BYTES</arg></p>
+      <optdesc><p>Explicitly configure the latency, with a time
+      specified in bytes in the selected sample format. If left out
+      the server will pick the latency, usually relatively high for
+      power saving reasons. Use either this option or
+      <opt>--latency-msec</opt>, but not both.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>--latency-msec</opt><arg>=MSEC</arg></p>
+      <optdesc><p>Explicitly configure the latency, with a time
+      specified in milliseconds. If left out the server will pick the
+      latency, usually relatively high for power saving reasons. Use
+      either this option or <opt>--latency</opt>, but not
+      both.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>--process-time</opt><arg>=BYTES</arg></p>
+      <optdesc><p>Explicitly configure the process time, with a time
+      specified in bytes in the selected sample format. If left out
+      the server will pick the process time. Use either this option or
+      <opt>--process-time-msec</opt>, but not both.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>--process-time-msec</opt><arg>=MSEC</arg></p>
+      <optdesc><p>Explicitly configure the process time, with a time
+      specified in miliseconds. If left out the server will pick the
+      process time. Use either this option or <opt>--process-time</opt>,
+      but not both.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>--property</opt><arg>=PROPERTY=VALUE</arg></p>
+      <optdesc><p>Attach a property to the client and stream. May be
+      used multiple times</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>--raw</opt></p>
+      <optdesc><p>Play/record raw audio data. This is the default if
+      this program is invoked as <cmd>pacat</cmd>, <cmd>parec</cmd> or
+      <cmd>pamon</cmd>.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>--file-format</opt><arg>[=FFORMAT]</arg></p>
+      <optdesc><p>Play/record encoded audio data in the file format
+      specified. This is the default if this program is invoked as
+      <cmd>paplay</cmd> and <cmd>parecord</cmd>.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>--list-file-formats</opt></p>
+      <optdesc><p>List supported file formats.</p></optdesc>
+    </option>
+
   </options>
 
   <section name="Authors">
@@ -178,7 +244,7 @@ USA.
 
   <section name="See also">
     <p>
-      <manref name="pulseaudio" section="1"/>, <manref name="paplay" section="1"/>
+      <manref name="pulseaudio" section="1"/>, <manref name="pactl" section="1"/>
     </p>
   </section>
 
index c20c016..7a555fe 100644 (file)
@@ -25,6 +25,8 @@ USA.
 
   <synopsis>
     <cmd>pacmd</cmd>
+    <cmd>pacmd <opt>--help</opt></cmd>
+    <cmd>pacmd <opt>--version</opt></cmd>
   </synopsis>
 
   <description>
@@ -34,16 +36,39 @@ USA.
     the commands also understood in the <file>default.pa</file>
     configuration scripts.</p>
 
-    <p>This program takes no command line options.</p>
+    <p>To exit the live shell, use ctrl+d. Note that the 'exit' command
+    inside the shell will tell the PulseAudio daemon itself to shutdown!</p>
+
+    <p>If any arguments are passed on the command line, they will be
+    passed into the live shell which will process the command and exit.</p>
   </description>
 
+  <options>
+
+    <option>
+      <p><opt>-h | --help</opt></p>
+
+      <optdesc><p>Show help.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>--version</opt></p>
+
+      <optdesc><p>Show version information.</p></optdesc>
+    </option>
+
+  </options>
+
   <section name="Authors">
     <p>The PulseAudio Developers &lt;@PACKAGE_BUGREPORT@&gt;; PulseAudio is available from <url href="@PACKAGE_URL@"/></p>
   </section>
 
   <section name="See also">
     <p>
-      <manref name="pulseaudio" section="1"/>, <manref name="pactl" section="1"/>, <manref name="default.pa" section="5"/>
+      <manref name="pulse-cli-syntax" section="5"/>,
+      <manref name="pulseaudio" section="1"/>,
+      <manref name="pactl" section="1"/>,
+      <manref name="default.pa" section="5"/>
     </p>
   </section>
 
index 8d5bf1d..29071b3 100644 (file)
@@ -24,18 +24,7 @@ USA.
 <manpage name="pactl" section="1" desc="Control a running PulseAudio sound server">
 
   <synopsis>
-    <cmd>pactl [<arg>options</arg>] stat</cmd>
-    <cmd>pactl [<arg>options</arg>] list</cmd>
-    <cmd>pactl [<arg>options</arg>] exit</cmd>
-    <cmd>pactl [<arg>options</arg>] upload-sample <arg>FILENAME</arg> [<arg>NAME</arg>]</cmd>
-    <cmd>pactl [<arg>options</arg>] play-sample <arg>NAME</arg> [<arg>SINK</arg>]</cmd>
-    <cmd>pactl [<arg>options</arg>] remove-sample <arg>NAME</arg></cmd>
-    <cmd>pactl [<arg>options</arg>] move-sink-input <arg>ID</arg> <arg>SINK</arg></cmd>
-    <cmd>pactl [<arg>options</arg>] move-source-input <arg>ID</arg> <arg>SOURCE</arg></cmd>
-    <cmd>pactl [<arg>options</arg>] load-module <arg>NAME</arg> [<arg>ARGUMENTS ...</arg>]</cmd>
-    <cmd>pactl [<arg>options</arg>] unload-module <arg>ID</arg></cmd>
-    <cmd>pactl [<arg>options</arg>] suspend-sink [<arg>SINK</arg>] <arg>1|0</arg></cmd>
-    <cmd>pactl [<arg>options</arg>] suspend-source [<arg>SOURCE</arg>] <arg>1|0</arg></cmd>
+    <cmd>pactl [<arg>options</arg>] <arg>COMMAND</arg> [<arg>ARGS ...</arg>]</cmd>
     <cmd>pactl <opt>--help</opt></cmd>
     <cmd>pactl <opt>--version</opt></cmd>
   </synopsis>
@@ -72,85 +61,80 @@ USA.
       <optdesc><p>Specify the client name <file>pactl</file> shall pass to the server when connecting.</p></optdesc>
     </option>
 
-    <option>
-      <p><opt>stat</opt></p>
+  </options>
+
+  <section name="Commands">
 
-      <optdesc><p>Dump a few statistics about the PulseAudio daemon.</p></optdesc>
+    <option>
+      <p><opt>stat</opt> [<arg>short</arg>]</p>
+      <optdesc><p>Dump a few statistics about the memory usage of the PulseAudio daemon. (Note: for backwards
+      compatibility, we also show the output of the <arg>info</arg> command. In order to only show
+      statistics, use the optional <arg>short</arg> argument. In a future version of PA we will
+      make this the default)</p></optdesc>
     </option>
 
     <option>
-      <p><opt>list</opt></p>
+      <p><opt>info</opt></p>
+      <optdesc><p>Dump some info about the PulseAudio daemon.</p></optdesc>
+    </option>
 
-      <optdesc><p>Dump all currently loaded modules, available sinks, sources, streams and clients.</p></optdesc>
+    <option>
+      <p><opt>list</opt> [<arg>short</arg>] [<arg>TYPE</arg>]</p>
+      <optdesc><p>Dump all currently loaded modules, available sinks, sources, streams, etc.  <arg>TYPE</arg> must be one of:
+      modules, sinks, sources, sink-inputs, source-outputs, clients, samples, cards.  If not specified, all info is listed.  If
+      short is given, output is in a tabular format, for easy parsing by scripts.</p></optdesc>
     </option>
 
     <option>
       <p><opt>exit</opt></p>
-
       <optdesc><p>Asks the PulseAudio server to terminate.</p></optdesc>
     </option>
 
-
     <option>
       <p><opt>upload-sample</opt> <arg>FILENAME</arg> [<arg>NAME</arg>]</p>
-
       <optdesc><p>Upload a sound from the specified audio file into
       the sample cache. The file types supported are those understood
       by <file>libsndfile</file>. The sample in the cache is named
       after the audio file, unless the name is explicitly
       specified.</p></optdesc>
-
     </option>
 
     <option>
       <p><opt>play-sample</opt> <arg>NAME</arg> [<arg>SINK</arg>]</p>
-
       <optdesc><p>Play the specified sample from the sample cache. It
       is played on the default sink, unless the symbolic name or the
       numerical index of the sink to play it on is
       specified.</p></optdesc>
-
     </option>
 
     <option>
       <p><opt>remove-sample</opt> <arg>NAME</arg></p>
-
       <optdesc><p>Remove the specified sample from the sample cache.</p></optdesc>
     </option>
 
     <option>
-      <p><opt>move-sink-input</opt> <arg>ID</arg> <arg>SINK</arg></p>
-
-      <optdesc><p>Move the specified playback stream (identified by its numerical index) to the specified sink (identified by its symbolic name or numerical index).</p></optdesc>
-    </option>
-
-    <option>
-      <p><opt>move-source-output</opt> <arg>ID</arg> <arg>SOURCE</arg></p>
-
-      <optdesc><p>Move the specified recording stream (identified by its numerical index) to the specified source (identified by its symbolic name or numerical index).</p></optdesc>
+      <p><opt>load-module</opt> <arg>NAME</arg> [<arg>ARGUMENTS ...</arg>]</p>
+      <optdesc><p>Load the specified module with the specified arguments into the running sound server.
+      Prints the numeric index of the module just loaded to STDOUT. You can use it to unload the module later.</p></optdesc>
     </option>
 
     <option>
-      <p><opt>load-module</opt> <arg>NAME</arg> [<arg>ARGUMENTS ...</arg>]</p>
-
-      <optdesc><p>Load the specified module with the specified arguments into the running sound server. Prints the numeric index of the module just loaded to STDOUT. You can use it to unload the module later.</p></optdesc>
+      <p><opt>unload-module</opt> <arg>ID|NAME</arg></p>
+      <optdesc><p>Unload the module instance identified by the specified numeric index or unload all modules by the specified name.</p></optdesc>
     </option>
 
     <option>
-      <p><opt>unload-module</opt> <arg>ID</arg></p>
-
-      <optdesc><p>Unload the module instance identified by the specified numeric index.</p></optdesc>
+      <p><opt>move-sink-input</opt> <arg>ID</arg> <arg>SINK</arg></p>
+      <optdesc><p>Move the specified playback stream (identified by its numerical index) to the specified sink (identified by its symbolic name or numerical index).</p></optdesc>
     </option>
 
     <option>
-      <p><opt>unload-module</opt> <arg>ID</arg></p>
-
-      <optdesc><p>Unload the module instance identified by the specified numeric index.</p></optdesc>
+      <p><opt>move-source-output</opt> <arg>ID</arg> <arg>SOURCE</arg></p>
+      <optdesc><p>Move the specified recording stream (identified by its numerical index) to the specified source (identified by its symbolic name or numerical index).</p></optdesc>
     </option>
 
     <option>
       <p><opt>suspend-sink</opt> <arg>SINK</arg> <arg>1|0</arg></p>
-
       <optdesc><p>Suspend or resume the specified sink (which my be
       specified either by its symbolic name, or by its numeric index),
       depending whether 1 (suspend) or 0 (resume) is passed as last
@@ -163,7 +147,6 @@ USA.
 
     <option>
       <p><opt>suspend-source</opt> <arg>SOURCE</arg> <arg>1|0</arg></p>
-
       <optdesc><p>Suspend or resume the specified source (which my be
       specified either by its symbolic name, or by its numeric index),
       depending whether 1 (suspend) or 0 (resume) is passed as last
@@ -174,16 +157,111 @@ USA.
       behaviour depends on the module.</p></optdesc>
     </option>
 
-  </options>
+    <option>
+      <p><opt>set-card-profile</opt> <arg>CARD</arg> <arg>PROFILE</arg></p>
+      <optdesc><p>Set the specified card (identified by its symbolic name or numerical index) to the specified profile (identified by its symbolic name).</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-default-sink</opt> <arg>SINK</arg></p>
+      <optdesc><p>Make the specified sink (identified by its symbolic name) the default sink.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-sink-port</opt> <arg>SINK</arg> <arg>PORT</arg></p>
+      <optdesc><p>Set the specified sink (identified by its symbolic name or numerical index) to the specified port (identified by its symbolic name).</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-default-source</opt> <arg>SOURCE</arg></p>
+      <optdesc><p>Make the specified source (identified by its symbolic name) the default source.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-source-port</opt> <arg>SOURCE</arg> <arg>PORT</arg></p>
+      <optdesc><p>Set the specified source (identified by its symbolic name or numerical index) to the specified port (identified by its symbolic name).</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-port-latency-offset</opt> <arg>CARD</arg> <arg>PORT</arg> <arg>OFFSET</arg></p>
+      <optdesc><p>Set a latency offset to a specified port (identified by its symbolic name) that belongs to a card (identified by its symbolic name or numerical index).
+      <arg>OFFSET</arg> is a number which represents the latency offset in microseconds</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-sink-volume</opt> <arg>SINK</arg> <arg>VOLUME</arg></p>
+      <optdesc><p>Set the volume of the specified sink (identified by its symbolic name or numerical index).
+      <arg>VOLUME</arg> can be specified as an integer (e.g. 2000, 16384), a linear factor (e.g. 0.4, 1.100), a percentage
+      (e.g.  10%, 100%) or a decibel value (e.g. 0dB, 20dB).  If the volume specification start with a + or - the volume
+      adjustment will be relative to the current sink volume.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-source-volume</opt> <arg>SOURCE</arg> <arg>VOLUME</arg></p>
+      <optdesc><p>Set the volume of the specified source (identified by its symbolic name or numerical index).
+      <arg>VOLUME</arg> can be specified as an integer (e.g. 2000, 16384), a linear factor (e.g. 0.4, 1.100), a percentage
+      (e.g.  10%, 100%) or a decibel value (e.g. 0dB, 20dB).  If the volume specification start with a + or - the volume
+      adjustment will be relative to the current source volume.</p></optdesc> </option>
+
+    <option>
+      <p><opt>set-sink-input-volume</opt> <arg>INPUT</arg> <arg>VOLUME</arg></p>
+      <optdesc><p>Set the volume of the specified sink input (identified by its numerical index).
+      <arg>VOLUME</arg> can be specified as an integer (e.g. 2000, 16384), a linear factor (e.g. 0.4, 1.100), a percentage
+      (e.g.  10%, 100%) or a decibel value (e.g. 0dB, 20dB).  If the volume specification start with a + or - the volume
+      adjustment will be relative to the current sink input volume.</p></optdesc> </option>
+
+    <option>
+      <p><opt>set-source-output-volume</opt> <arg>OUTPUT</arg> <arg>VOLUME</arg></p>
+      <optdesc><p>Set the volume of the specified source output (identified by its numerical index).
+      <arg>VOLUME</arg> can be specified as an integer (e.g. 2000, 16384), a linear factor (e.g. 0.4, 1.100), a percentage
+      (e.g.  10%, 100%) or a decibel value (e.g. 0dB, 20dB).  If the volume specification start with a + or - the volume
+      adjustment will be relative to the current source output volume.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-sink-mute</opt> <arg>SINK</arg> <arg>1|0|toggle</arg></p>
+      <optdesc><p>Set the mute status of the specified sink (identified by its symbolic name or numerical index).</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-source-mute</opt> <arg>SOURCE</arg> <arg>1|0|toggle</arg></p>
+      <optdesc><p>Set the mute status of the specified source (identified by its symbolic name or numerical index).</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-sink-input-mute</opt> <arg>INPUT</arg> <arg>1|0|toggle</arg></p>
+      <optdesc><p>Set the mute status of the specified sink input (identified by its numerical index).</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-source-output-mute</opt> <arg>INPUT</arg> <arg>1|0|toggle</arg></p>
+      <optdesc><p>Set the mute status of the specified source output (identified by its numerical index).</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-sink-formats</opt> <arg>SINK</arg> <arg>FORMATS</arg></p>
+      <optdesc><p>Set the supported formats of the specified sink (identified by its numerical index) if supported by the sink.
+      <arg>FORMATS</arg> is specified as a semi-colon (;) separated list of formats in the form
+      'encoding[, key1=value1, key2=value2, ...]' (for example, AC3 at 32000, 44100 and 48000 Hz would be specified as
+      'ac3-iec61937, format.rate = "[ 32000, 44100, 48000 ]"').
+      </p></optdesc> </option>
+
+    <option>
+      <p><opt>subscribe</opt></p>
+      <optdesc><p>Subscribe to events, pactl does not exit by itself, but keeps waiting for new events.</p></optdesc>
+    </option>
+
+  </section>
 
   <section name="Authors">
     <p>The PulseAudio Developers &lt;@PACKAGE_BUGREPORT@&gt;; PulseAudio is available from <url href="@PACKAGE_URL@"/></p>
   </section>
 
-  <section name="See also">
+  <seealso>
     <p>
-      <manref name="pulseaudio" section="1"/>, <manref name="pacmd" section="1"/>
+      <manref name="pulseaudio" section="1"/>,
+      <manref name="pacmd" section="1"/>
     </p>
-  </section>
+  </seealso>
 
 </manpage>
index 3b40b97..0628b9d 100644 (file)
@@ -73,7 +73,7 @@ USA.
       the <file>eval</file> 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
-      <file>~/.pulse-cookie</file>. </p></optdesc>
+      <file>~/.config/pulse/cookie</file>. </p></optdesc>
     </option>
 
     <option>
@@ -83,12 +83,12 @@ USA.
       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
-      <file>~/.pulse/client.conf</file> (or
-      <file>@pulseconfdir@/client.conf</file> if that file does not
+      <file>~/.config/pulse/client.conf</file> (or
+      <file>@PA_DEFAULT_CONFIG_DIR@/client.conf</file> if that file does not
       exist). If specific options are passed on the command line
       (<opt>-S</opt>, <opt>-O</opt>, <opt>-I</opt>, <opt>-c</opt>, see
       below), they take precedence. Also uploads the local
-      authentication cookie <file>~/.pulse-cookie</file> to the X11
+      authentication cookie <file>~/.config/pulse/cookie</file> to the X11
       server.</p></optdesc>
     </option>
 
@@ -133,7 +133,7 @@ USA.
 
       <optdesc><p>Only valid for <opt>-e</opt>: export the PulseAudio
       authentication cookie stored in the specified file to the X11
-      display instead of the one stored in <file>~/.pulse-cookie</file>.</p></optdesc>
+      display instead of the one stored in <file>~/.config/pulse/cookie</file>.</p></optdesc>
     </option>
 
   </options>
diff --git a/man/pulse-cli-syntax.5.xml.in b/man/pulse-cli-syntax.5.xml.in
new file mode 100644 (file)
index 0000000..92c7134
--- /dev/null
@@ -0,0 +1,339 @@
+<?xml version="1.0"?><!--*-nxml-*-->
+<!DOCTYPE manpage SYSTEM "xmltoman.dtd">
+<?xml-stylesheet type="text/xsl" href="xmltoman.xsl" ?>
+
+<!--
+This file is part of PulseAudio.
+
+PulseAudio is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as
+published by the Free Software Foundation; either version 2.1 of the
+License, or (at your option) any later version.
+
+PulseAudio is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with PulseAudio; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+USA.
+-->
+
+<manpage name="pulse-cli-syntax" section="5" desc="PulseAudio Command Line Interface Syntax">
+
+  <synopsis>
+    <p><file>~/.config/pulse/default.pa</file></p>
+    <p><file>@PA_DEFAULT_CONFIG_DIR@/default.pa</file></p>
+    <p><file>@PA_DEFAULT_CONFIG_DIR@/system.pa</file></p>
+  </synopsis>
+
+  <description>
+    <p>
+      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.
+    </p>
+
+    <p>
+      Note that any boolean arguments can be given positively as '1', 't', 'y',
+      'true', 'yes' or 'on'. Likewise, negative values can be given as '0',
+      'f', 'n', 'false', 'no' or 'off'. Case is ignored.
+    </p>
+  </description>
+
+  <section name="General Commands">
+
+    <option>
+      <p><opt>help</opt></p>
+      <optdesc><p>Show a quick help on the commands available.</p></optdesc>
+    </option>
+  </section>
+
+  <section name="Status_Commands">
+    <option>
+      <p><opt>list-modules</opt></p>
+      <optdesc><p>Show all currently loaded modules with their arguments.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>list-cards</opt></p>
+      <optdesc><p>Show all currently registered cards</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>list-sinks</opt> or <opt>list-sources</opt></p>
+      <optdesc><p>Show all currently registered sinks (resp. sources).</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>list-clients</opt></p>
+      <optdesc><p>Show all currently active clients.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>list-sink-inputs</opt> or <opt>list-source-outputs</opt></p>
+      <optdesc><p>Show all currently active inputs to sinks a.k.a. playback
+      streams (resp. outputs of sources a.k.a. recording streams).</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>stat</opt></p>
+      <optdesc><p>Show some simple statistics about the allocated memory blocks and the space used by them.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>info</opt> or <opt>ls</opt> or <opt>list</opt></p>
+      <optdesc><p>A combination of all status commands described above (all
+      three commands are synonyms).</p></optdesc>
+    </option>
+  </section>
+
+  <section name="Module Management">
+    <option>
+      <p><opt>load-module</opt> <arg>name</arg> [<arg>arguments...</arg>]</p>
+      <optdesc><p>Load a module specified by its name and arguments. For most
+      modules it is OK to be loaded more than once.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>unload-module</opt> <arg>index|name</arg></p>
+      <optdesc><p>Unload a module, specified either by its index in the module
+      list or its name.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>describe-module</opt> <arg>name</arg></p>
+      <optdesc><p>Give information about a module specified by its name.</p></optdesc>
+    </option>
+  </section>
+
+  <section name="Volume Commands">
+    <option>
+      <p><opt>set-sink-volume|set-source-volume</opt> <arg>index|name</arg> <arg>volume</arg></p>
+      <optdesc><p>Set the volume of the specified sink (resp. source). You may
+      specify the sink (resp. source) either by its index in the sink/source list
+      or by its name. The volume should be an integer value greater or equal than
+      0 (muted). Volume 65536 (0x10000) is 'normal' volume a.k.a. 100%. Values
+      greater than this amplify the audio signal (with clipping).</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-sink-mute|set-source-mute</opt> <arg>index|name</arg> <arg>boolean</arg></p>
+      <optdesc><p>Mute or unmute the specified sink (resp. source). You may
+      specify the sink (resp. source) either by its index or by its name.
+      The mute value is either 0 (not muted) or 1 (muted).</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-sink-input-volume|set-source-output-volume</opt> <arg>index</arg> <arg>volume</arg></p>
+      <optdesc><p>Set the volume of a sink input (resp. source output) specified
+      by its index. The same volume rules apply as with set-sink-volume.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-sink-input-mute|set-source-output-mute</opt> <arg>index</arg> <arg>boolean</arg></p>
+      <optdesc><p>Mute or unmute a sink input (resp. source output) specified
+      by its index. The same mute rules apply as with set-sink-mute.</p></optdesc>
+    </option>
+  </section>
+
+  <section name="Configuration Commands">
+    <option>
+      <p><opt>set-default-sink|set-default-source</opt> <arg>index|name</arg></p>
+      <optdesc><p>Make a sink (resp. source) the default. You may specify the
+      sink (resp. source) by its index in the sink (resp. source) list or by its
+      name.</p><p>Note that defaults may be overridden by various policy modules
+      or by specific stream configurations.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-card-profile</opt> <arg>index|name</arg> <arg>profile-name</arg></p>
+      <optdesc><p>Change the profile of a card.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-sink-port|set-source-port</opt> <arg>index|name</arg> <arg>port-name</arg></p>
+      <optdesc><p>Change the profile of a sink (resp. source).</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-port-latency-offset</opt> <arg>card-index|card-name</arg> <arg>port-name</arg> <arg>offset</arg> </p>
+      <optdesc><p>Change the latency offset of a port belonging to the specified card</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>suspend-sink|suspend-source</opt> <arg>index|name</arg> <arg>boolean</arg></p>
+      <optdesc><p>Suspend (i.e. disconnect from the underlying hardware) a sink
+      (resp. source).</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>suspend</opt> <arg>boolean</arg></p>
+      <optdesc><p>Suspend all sinks and sources.</p></optdesc>
+    </option>
+  </section>
+
+  <section name="Moving streams">
+    <option>
+      <p><opt>move-sink-input|move-source-output</opt> <arg>index</arg> <arg>sink-index|sink-name</arg></p>
+      <optdesc><p>Move sink input (resp. source output) to another sink
+      (resp. source).</p></optdesc>
+    </option>
+  </section>
+
+  <section name="Property lists">
+    <option>
+      <p><opt>update-sink-proplist|update-source-proplist</opt> <arg>index|name</arg> <arg>properties</arg></p>
+      <optdesc><p>Update the properties of a sink (resp. source) specified by
+      name or index. The property is specified as e.g. device.description="My
+      Preferred Name"</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>update-sink-input-proplist|update-source-output-proplist</opt> <arg>index</arg> <arg>properties</arg></p>
+      <optdesc><p>Update the properties of a sink input (resp. source output)
+      specified by index. The properties are specified as above.</p></optdesc>
+    </option>
+  </section>
+
+  <section name="Sample Cache">
+    <option>
+      <p><opt>list-samples</opt></p>
+      <optdesc><p>Lists the contents of the sample cache.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>play-sample</opt> <arg>name</arg> <arg>sink-index|sink-name</arg></p>
+      <optdesc><p>Play a sample cache entry to a sink.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>remove-sample</opt> <arg>name</arg></p>
+      <optdesc><p>Remove an entry from the sample cache.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>load-sample</opt> <arg>name</arg> <arg>filename</arg></p>
+      <optdesc><p>Load an audio file to the sample cache.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>load-sample-lazy</opt> <arg>name</arg> <arg>filename</arg></p>
+      <optdesc><p>Create a new entry in the sample cache, but don't load the
+      sample immediately. The sample is loaded only when it is first used.
+      After a certain idle time it is freed again.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>load-sample-dir-lazy</opt> <arg>path</arg></p>
+      <optdesc><p>Load all entries in the specified directory into the sample
+      cache as lazy entries. A shell globbing expression (e.g. *.wav) may be
+      appended to the path of the directory to add.</p></optdesc>
+    </option>
+  </section>
+
+  <section name="Killing Clients/Streams">
+    <option>
+      <p><opt>kill-client</opt> <arg>index</arg></p>
+      <optdesc><p>Remove a client forcibly from the server. There is no protection
+      against the client reconnecting immediately.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>kill-sink-input|kill-source-output</opt> <arg>index</arg></p>
+      <optdesc><p>Remove a sink input (resp. source output) forcibly from the
+      server. This will not remove the owning client or any other streams opened
+      by the same client from the server.</p></optdesc>
+    </option>
+  </section>
+
+  <section name="Log Commands">
+    <option>
+      <p><opt>set-log-level</opt> <arg>numeric-level</arg></p>
+      <optdesc><p>Change the log level.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-log-meta</opt> <arg>boolean</arg></p>
+      <optdesc><p>Show source code location in log messages.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-log-target</opt> <arg>target</arg></p>
+      <optdesc><p>Change the log target (null, auto, syslog, stderr, file:PATH).</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-log-time</opt> <arg>boolean</arg></p>
+      <optdesc><p>Show timestamps in log messages.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>set-log-backtrace</opt> <arg>num-frames</arg></p>
+      <optdesc><p>Show backtrace in log messages.</p></optdesc>
+    </option>
+  </section>
+
+  <section name="Miscellaneous Commands">
+    <option>
+      <p><opt>play-file</opt> <arg>filename</arg> <arg>sink-index|sink-name</arg></p>
+      <optdesc><p>Play an audio file to a sink.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>dump</opt></p>
+      <optdesc><p>Dump the daemon's current configuration in CLI commands.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>dump-volumes</opt></p>
+      <optdesc><p>Debug: Shows the current state of all volumes.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>shared</opt></p>
+      <optdesc><p>Debug: Show shared properties.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>exit</opt></p>
+      <optdesc><p>Terminate the daemon. If you want to terminate a CLI
+      connection ("log out") you might want to use ctrl+d</p></optdesc>
+    </option>
+  </section>
+
+  <section name="Meta Commands">
+    <p>
+      In addition to the commands described above there are a few meta directives
+      supported by the command line interpreter.
+    </p>
+    <option>
+      <p><opt>.include</opt> <arg>filename|folder</arg></p>
+      <optdesc><p>Executes the commands from the specified script file or in all
+      of the *.pa file within the folder.</p></optdesc>
+    </option>
+    <option>
+      <p><opt>.fail</opt> and <opt>.nofail</opt></p>
+      <optdesc><p>Enable (resp. disable) that following failing commands will
+      cancel the execution of the current script file. This is a ignored when
+      used on the interactive command line.</p></optdesc>
+    </option>
+  </section>
+
+  <section name="Authors">
+    <p>The PulseAudio Developers &lt;@PACKAGE_BUGREPORT@&gt;;
+    PulseAudio is available from <url href="@PACKAGE_URL@"/></p>
+  </section>
+
+  <section name="See also">
+    <p>
+      <manref name="default.pa" section="5"/>,
+      <manref name="pacmd" section="1"/>,
+      <manref name="pulseaudio" section="1"/>
+    </p>
+  </section>
+
+</manpage>
index 46cc845..45f02da 100644 (file)
@@ -24,16 +24,16 @@ USA.
 <manpage name="pulse-client.conf" section="5" desc="PulseAudio client configuration file">
 
   <synopsis>
-    <p><file>~/.pulse/client.conf</file></p>
+    <p><file>~/.config/pulse/client.conf</file></p>
 
-    <p><file>@pulseconfdir@/client.conf</file></p>
+    <p><file>@PA_DEFAULT_CONFIG_DIR@/client.conf</file></p>
   </synopsis>
 
   <description>
     <p>The PulseAudio client library reads configuration directives from
-    a file <file>~/.pulse/client.conf</file> on startup and when that
+    a file <file>~/.config/pulse/client.conf</file> on startup and when that
     file doesn't exist from
-    <file>@pulseconfdir@/client.conf</file>.</p>
+    <file>@PA_DEFAULT_CONFIG_DIR@/client.conf</file>.</p>
 
     <p>The configuration file is a simple collection of variable
     declarations. If the configuration file parser encounters either ;
@@ -69,7 +69,7 @@ USA.
 
     <option>
       <p><opt>autospawn=</opt> Autospawn a PulseAudio daemon when
-      needed. Takes a boolean value, defaults to "yes".</p>
+      needed. Takes a boolean value, defaults to <opt>yes</opt>.</p>
     </option>
 
     <option>
@@ -88,7 +88,7 @@ USA.
     <option>
       <p><opt>cookie-file=</opt> Specify the path to the PulseAudio
       authentication cookie. Defaults to
-      <file>~/.pulse-cookie</file>.</p>
+      <file>~/.config/pulse/cookie</file>.</p>
     </option>
 
     <option>
@@ -106,6 +106,23 @@ USA.
       memory overcommit.</p>
     </option>
 
+    <option>
+      <p><opt>auto-connect-localhost=</opt> Automatically try to
+      connect to localhost via IP. Enabling this is a potential
+      security hole since connections are only authenticated one-way
+      and a rogue server might hence fool a client into sending it its
+      private (e.g. VoIP call) data. This was enabled by default on
+      PulseAudio version 0.9.21 and older. Defaults to
+      <opt>no</opt>.</p>
+    </option>
+
+    <option>
+      <p><opt>auto-connect-display=</opt> Automatically try to connect
+      to the host X11's $DISPLAY variable is set to. The same security
+      issues apply as to <opt>auto-connect-localhost=</opt>. Defaults
+      to <opt>no</opt>.</p>
+    </option>
+
   </section>
 
   <section name="Authors">
index e6b1e19..c40d570 100644 (file)
@@ -24,16 +24,16 @@ USA.
 <manpage name="pulse-daemon.conf" section="5" desc="PulseAudio daemon configuration file">
 
   <synopsis>
-    <p><file>~/.pulse/daemon.conf</file></p>
+    <p><file>~/.config/pulse/daemon.conf</file></p>
 
-    <p><file>@pulseconfdir@/daemon.conf</file></p>
+    <p><file>@PA_DEFAULT_CONFIG_DIR@/daemon.conf</file></p>
   </synopsis>
 
   <description>
     <p>The PulseAudio sound server reads configuration directives from
-    a file <file>~/.pulse/daemon.conf</file> on startup and when that
+    a file <file>~/.config/pulse/daemon.conf</file> on startup and when that
     file doesn't exist from
-    <file>@pulseconfdir@/daemon.conf</file>. Please note that the
+    <file>@PA_DEFAULT_CONFIG_DIR@/daemon.conf</file>. Please note that the
     server also reads a configuration script on startup
     <file>default.pa</file> which also contains runtime configuration
     directives.</p>
@@ -53,21 +53,21 @@ USA.
 
     <option>
       <p><opt>daemonize= </opt> Daemonize after startup. Takes a
-      boolean value, defaults to "no". The <opt>--daemonize</opt>
+      boolean value, defaults to <opt>no</opt>. The <opt>--daemonize</opt>
       command line option takes precedence.</p>
     </option>
 
     <option>
       <p><opt>fail=</opt> Fail to start up if any of the directives
       in the configuration script <file>default.pa</file>
-      fail. Takes a boolean argument, defaults to "yes". The <opt>--fail</opt> command line
+      fail. Takes a boolean argument, defaults to <opt>yes</opt>. The <opt>--fail</opt> command line
       option takes precedence.</p>
     </option>
 
     <option>
       <p><opt>allow-module-loading=</opt> Allow/disallow module
       loading after startup. This is a security feature that if
-      dsabled makes sure that no further modules may be loaded into
+      disabled makes sure that no further modules may be loaded into
       the PulseAudio server after startup completed. It is recommended
       to disable this when <opt>system-instance</opt> is
       enabled. Please note that certain features like automatic
@@ -89,20 +89,21 @@ USA.
       <opt>src-zero-order-hold</opt>, <opt>src-linear</opt>,
       <opt>trivial</opt>, <opt>speex-float-N</opt>,
       <opt>speex-fixed-N</opt>, <opt>ffmpeg</opt>. See the
-      documentation of libsamplerate for an explanation for the
-      different src- methods. The method <opt>trivial</opt> is the most basic
-      algorithm implemented. If you're tight on CPU consider using
-      this. On the other hand it has the worst quality of them
-      all. The Speex resamplers take an integer quality setting in the
-      range 0..9 (bad...good). They exist in two flavours: <opt>fixed</opt> and
-      <opt>float</opt>. The former uses fixed point numbers, the latter relies on
-      floating point numbers. On most desktop CPUs the float point
-      resmampler is a lot faster, and it also offers slightly better
-      quality. See the output of <opt>dump-resample-methods</opt> for
-      a complete list of all available resamplers. Defaults to
-      <opt>speex-float-3</opt>. The <opt>--resample-method</opt>
-      command line option takes precedence. Note that some modules
-      overwrite or allow overwriting of the resampler to use.</p>
+      documentation of libsamplerate and speex for explanations of the
+      different src- and speex- methods, respectively. The method
+      <opt>trivial</opt> is the most basic algorithm implemented. If
+      you're tight on CPU consider using this. On the other hand it has
+      the worst quality of them all. The Speex resamplers take an
+      integer quality setting in the range 0..10 (bad...good). They
+      exist in two flavours: <opt>fixed</opt> and <opt>float</opt>. The former uses fixed point
+      numbers, the latter relies on floating point numbers. On most
+      desktop CPUs the float point resampler is a lot faster, and it
+      also offers slightly better quality. See the output of
+      <opt>dump-resample-methods</opt> for a complete list of all
+      available resamplers. Defaults to <opt>speex-float-1</opt>. The
+      <opt>--resample-method</opt> command line option takes precedence.
+      Note that some modules overwrite or allow overwriting of the
+      resampler to use.</p>
     </option>
 
     <option>
@@ -112,8 +113,8 @@ USA.
     </option>
 
     <option>
-      <p><opt>enable-lfe-remixing=</opt> if disabeld when upmixing or
-      downmixing ignore LFE channels. When this option is dsabled the
+      <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
@@ -122,13 +123,13 @@ USA.
     </option>
 
     <option>
-      <p><opt>use-pid-file=</opt> Create a PID file in
-      <file>/tmp/pulse-$USER/pid</file>. Of this is enabled you may
+      <p><opt>use-pid-file=</opt> Create a PID file in the runtime directory
+      (<file>$XDG_RUNTIMEDIR/pulse/pid</file>). If this is enabled you may
       use commands like <opt>--kill</opt> or <opt>--check</opt>. If
       you are planning to start more than one PulseAudio process per
       user, you better disable this option since it effectively
       disables multiple instances. Takes a boolean argument, defaults
-      to <opt>yes</opt>. The <opt>--no-cpu-limit</opt> command line
+      to <opt>yes</opt>. The <opt>--use-pid-file</opt> command line
       option takes precedence.</p>
     </option>
 
@@ -143,12 +144,28 @@ USA.
 
     <option>
       <p><opt>system-instance=</opt> Run the daemon as system-wide
-      instance, requires root priviliges. Takes a boolean argument,
+      instance, requires root privileges. Takes a boolean argument,
       defaults to <opt>no</opt>. The <opt>--system</opt> command line
       argument takes precedence.</p>
     </option>
 
     <option>
+      <p><opt>local-server-type=</opt> Please don't use this option if
+      you don't have to! This option is currently only useful when you
+      want D-Bus clients to use a remote server. This option may be
+      removed in future versions. If you only want to run PulseAudio
+      in the system mode, use the <opt>system-instance</opt> option.
+      This option takes one of <opt>user</opt>, <opt>system</opt> or
+      <opt>none</opt> as the argument. This is essentially a duplicate
+      for the <opt>system-instance</opt> option. The difference is the
+      <opt>none</opt> option, which is useful when you want to use a
+      remote server with D-Bus clients. If both this and
+      <opt>system-instance</opt> are defined, this option takes
+      precedence. Defaults to whatever the <opt>system-instance</opt>
+      is set.</p>
+    </option>
+
+    <option>
       <p><opt>enable-shm=</opt> Enable data transfer via POSIX
       shared memory. Takes a boolean argument, defaults to
       <opt>yes</opt>. The <opt>--disable-shm</opt> command line
@@ -191,7 +208,7 @@ USA.
       RLIMIT_NICE is used. root is dropped immediately after gaining
       the nice level on startup, thus it is presumably safe. See
       <manref section="1" name="pulseaudio"/> for more
-      information. Takes a boolean argument, defaults to "yes". The <opt>--high-priority</opt>
+      information. Takes a boolean argument, defaults to <opt>yes</opt>. The <opt>--high-priority</opt>
       command line option takes precedence.</p>
     </option>
 
@@ -205,7 +222,7 @@ USA.
       real-time. The controlling thread is left a normally scheduled
       thread. Thus enabling the high-priority option is orthogonal.
       See <manref section="1" name="pulseaudio"/> for more
-      information. Takes a boolean argument, defaults to "yes". The
+      information. Takes a boolean argument, defaults to <opt>yes</opt>. The
       <opt>--realtime</opt> command line option takes precedence.</p>
     </option>
 
@@ -215,7 +232,7 @@ USA.
       by default, 9 for clients. Thus it is recommended to choose the
       PulseAudio real-time priorities lower. Some PulseAudio threads
       might choose a priority a little lower or higher than the
-      specified value. Defaults to "5".</p>
+      specified value. Defaults to <opt>5</opt>.</p>
     </option>
 
     <option>
@@ -250,7 +267,7 @@ USA.
     <option>
       <p><opt>dl-search-path=</opt> The path were to look for dynamic
       shared objects (DSOs/plugins). You may specify more than one
-      path seperated by colons. The default path depends on compile
+      path separated by colons. The default path depends on compile
       time settings. The <opt>--dl-search-path</opt> command line
       option takes precedence. </p>
     </option>
@@ -259,10 +276,10 @@ USA.
       <p><opt>default-script-file=</opt> The default configuration
       script file to load. Specify an empty string for not loading a
       default script file. The default behaviour is to load
-      <file>~/.pulse/default.pa</file>, and if that file does not
+      <file>~/.config/pulse/default.pa</file>, and if that file does not
       exist fall back to the system wide installed version
-      <file>@pulseconfdir@/default.pa</file>. If run in system-wide
-      mode the file <file>@pulseconfdir@/system.pa</file> is used
+      <file>@PA_DEFAULT_CONFIG_DIR@/default.pa</file>. If run in system-wide
+      mode the file <file>@PA_DEFAULT_CONFIG_DIR@/system.pa</file> is used
       instead. If <opt>-n</opt> is passed on the command line
       or <opt>default-script-file=</opt> is disabled the default
       configuration script is ignored.</p>
@@ -280,12 +297,15 @@ USA.
 
     <option>
       <p><opt>log-target=</opt> The default log target. Use either
-      <opt>stderr</opt>, <opt>syslog</opt> or <opt>auto</opt>. The
-      latter is equivalent to <opt>sylog</opt> in case
-      <opt>daemonize</opt> is enabled, otherwise to
-      <opt>stderr</opt>. Defaults to <opt>auto</opt>. The
-      <opt>--log-target</opt> command line option takes
-      precedence.</p>
+      <opt>stderr</opt>, <opt>syslog</opt>, <opt>auto</opt>,
+      <opt>file:PATH</opt> or <opt>newfile:PATH</opt>. <opt>auto</opt> is
+      equivalent to <opt>sylog</opt> in case <opt>daemonize</opt> is enabled,
+      otherwise to <opt>stderr</opt>. If set to <opt>file:PATH</opt>, logging
+      is directed to the file indicated by PATH. <opt>newfile:PATH</opt> is
+      otherwise the same as <opt>file:PATH</opt>, but existing files are never
+      overwritten. If the specified file already exists, a suffix is added to
+      the file name to avoid overwriting. Defaults to <opt>auto</opt>. The
+      <opt>--log-target</opt> command line option takes precedence.</p>
     </option>
 
     <option>
@@ -311,7 +331,7 @@ USA.
 
     <option>
       <p><opt>log-backtrace=</opt> When greater than 0, with each
-      logged message log a code stack trace up the the specified
+      logged message log a code stack trace up the specified
       number of stack frames. Defaults to <opt>0</opt>.</p>
     </option>
 
@@ -393,7 +413,7 @@ USA.
       <opt>s16be</opt>, <opt>s24le</opt>, <opt>s24be</opt>,
       <opt>s24-32le</opt>, <opt>s24-32be</opt>, <opt>s32le</opt>,
       <opt>s32be</opt> <opt>float32le</opt>, <opt>float32be</opt>,
-      <opt>ulaw</opt>, <opt>alaw</opt>. Depending on the endianess of
+      <opt>ulaw</opt>, <opt>alaw</opt>. Depending on the endianness of
       the CPU the formats <opt>s16ne</opt>, <opt>s16re</opt>,
       <opt>s24ne</opt>, <opt>s24re</opt>, <opt>s24-32ne</opt>,
       <opt>s24-32re</opt>, <opt>s32ne</opt>, <opt>s32re</opt>,
@@ -413,6 +433,17 @@ USA.
       <p><opt>default-channel-map</opt> The default channel map.</p>
     </option>
 
+    <option>
+      <p><opt>alternate-sample-rate</opt> The alternate sample
+      frequency. Sinks and sources will use either the
+      default-rate-rate value or this alternate value, typically 44.1
+      or 48kHz. Switching between default and alternate values is
+      enabled only when the sinks/sources are suspended. This option
+      is ignored in passthrough mode where the stream rate will be used.
+      If set to the same as the default sample rate, this feature is
+      disabled.</p>
+    </option>
+
   </section>
 
   <section name="Default Fragment Settings">
@@ -437,6 +468,36 @@ USA.
 
   </section>
 
+  <section name="Default Deferred Volume Settings">
+
+    <p>With the flat volume feature enabled, the sink HW volume is set
+    to the same level as the highest volume input stream. Any other streams
+    (with lower volumes) have the appropriate adjustment applied in SW to
+    bring them to the correct overall level. Sadly hardware mixer changes
+    cannot be timed accurately and thus this change of volumes can sometimes
+    cause the resulting output sound to be momentarily too loud or too soft.
+    So to ensure SW and HW volumes are applied concurrently without any
+    glitches, their application needs to be synchronized. The sink
+    implementation needs to support deferred volumes. The following
+    parameters can be used to refine the process.</p>
+
+    <option>
+      <p><opt>enable-deferred-volume=</opt> Enable deferred volume for the sinks that
+      support it. This feature is enabled by default.</p>
+    </option>
+    <option>
+      <p><opt>deferred-volume-safety-margin-usec=</opt> The amount of time (in
+      usec) by which the HW volume increases are delayed and HW volume
+      decreases are advanced. Defaults to 8000 usec.</p>
+    </option>
+    <option>
+      <p><opt>deferred-volume-extra-delay-usec=</opt> The amount of time (in usec)
+      by which HW volume changes are delayed. Negative values are also allowed.
+      Defaults to 0.</p>
+    </option>
+
+  </section>
+
   <section name="Authors">
     <p>The PulseAudio Developers &lt;@PACKAGE_BUGREPORT@&gt;; PulseAudio is available from <url href="@PACKAGE_URL@"/></p>
   </section>
index 8810e90..d7d7458 100644 (file)
@@ -188,13 +188,6 @@ USA.
     </option>
 
     <option>
-      <p><opt>--module-idle-time</opt><arg>=SECS</arg></p>
-
-      <optdesc><p>Unload autoloaded modules when idle and the
-      specified number of seconds passed.</p></optdesc>
-    </option>
-
-    <option>
       <p><opt>--scache-idle-time</opt><arg>=SECS</arg></p>
 
       <optdesc><p>Unload autoloaded samples from the cache when the
@@ -224,12 +217,35 @@ USA.
     </option>
 
     <option>
-      <p><opt>--log-target</opt><arg>={auto,syslog,stderr}</arg></p>
+      <p><opt>--log-target</opt><arg>={auto,syslog,stderr,file:PATH,newfile:PATH}</arg></p>
 
       <optdesc><p>Specify the log target. If set to <arg>auto</arg>
       (which is the default), then logging is directed to syslog when
       <opt>--daemonize</opt> is passed, otherwise to
-      STDERR.</p></optdesc>
+      STDERR. If set to <arg>file:PATH</arg>, logging is directed to
+      the file indicated by PATH. <arg>newfile:PATH</arg> is otherwise
+      the same as file:PATH, but existing files are never overwritten.
+      If the specified file already exists, a suffix is added to the
+      file name to avoid overwriting.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>--log-meta</opt><arg>[=BOOL]</arg></p>
+
+      <optdesc><p>Show source code location in log messages.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>--log-time</opt><arg>[=BOOL]</arg></p>
+
+      <optdesc><p>Show timestamps in log messages.</p></optdesc>
+    </option>
+
+    <option>
+      <p><opt>--log-backtrace</opt><arg>=FRAMES</arg></p>
+
+      <optdesc><p>When FRAMES is greater than 0, log for each message a
+      stack trace up to the number of specified stack frames.</p></optdesc>
     </option>
 
     <option>
@@ -260,7 +276,7 @@ USA.
       support it. By default, PulseAudio will terminate itself when it
       notices that it takes up too much CPU time. This is useful as a
       protection against system lockups when real-time scheduling is
-      used (see below). Disabling this meachnism is useful when
+      used (see below). Disabling this mechanism is useful when
       debugging PulseAudio with tools like <manref name="valgrind"
       section="1"/> which slow down execution.</p></optdesc>
     </option>
@@ -313,22 +329,22 @@ USA.
 
   <section name="Files">
 
-    <p><file>~/.pulse/daemon.conf</file>,
-    <file>@pulseconfdir@/daemon.conf</file>: configuration settings
+    <p><file>~/.config/pulse/daemon.conf</file>,
+    <file>@PA_DEFAULT_CONFIG_DIR@/daemon.conf</file>: 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 <manref name="pulse-daemon.conf" section="5"/> for
     more information.</p>
 
-    <p><file>~/.pulse/default.pa</file>,
-    <file>@pulseconfdir@/default.pa</file>: the default configuration
+    <p><file>~/.config/pulse/default.pa</file>,
+    <file>@PA_DEFAULT_CONFIG_DIR@/default.pa</file>: 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 <manref name="default.pa"
     section="5"/> for more information.</p>
 
-    <p><file>~/.pulse/client.conf</file>,
-    <file>@pulseconfdir@/client.conf</file>: configuration settings
+    <p><file>~/.config/pulse/client.conf</file>,
+    <file>@PA_DEFAULT_CONFIG_DIR@/client.conf</file>: 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 <manref name="pulse-client.conf" section="5"/> for
@@ -369,7 +385,7 @@ USA.
 
     <p>User <arg>pulse</arg>, group <arg>pulse</arg>: if PulseAudio is running as a system
     daemon (see <opt>--system</opt> above) and is started as root the
-    daemon will drop priviliges and become a normal user process using
+    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.</p>
   </section>
@@ -383,7 +399,7 @@ USA.
     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 priviliges to a user process always comes with the risk
+    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.</p>
@@ -393,7 +409,7 @@ USA.
     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
-    priviliged operation on most systems, some special changes to the
+    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>
 
@@ -404,12 +420,12 @@ USA.
     <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 priviliges immediately on
+    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
-    capababilities are dropped immediately. The advantage of this
-    solution is that the real-time priviliges are only granted to the
+    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
@@ -417,7 +433,7 @@ USA.
     scheduling can be enabled instead (i.e. negative nice level). This
     can be enabled by passing <opt>--high-priority</opt> (see above)
     when starting PulseAudio and may also be enabled with the
-    approriate option in <file>daemon.conf</file>. Negative nice
+    appropriate option in <file>daemon.conf</file>. Negative nice
     levels can only be enabled when the appropriate resource limit
     RLIMIT_NICE is set (see <manref name="setrlimit" section="2"/> for
     more information), possibly configured in
@@ -427,10 +443,16 @@ USA.
 
   <section name="Environment variables">
 
-    <p>The PulseAudio client libraries check for the existance of the
+    <p>The PulseAudio client libraries check for the existence of the
     following environment variables and change their local configuration accordingly:</p>
 
-    <p><arg>$PULSE_SERVER</arg>: the server string specifying the server to connect to when a client asks for a sound server connection and doesn't explicitly ask for a specific server.</p>
+    <p><arg>$PULSE_SERVER</arg>: the server string specifying the server
+    to connect to when a client asks for a sound server connection and doesn't
+    explicitly ask for a specific server. The server string is a list of
+    server addresses separated by whitespace which are tried in turn. A server
+    address consists of an optional address type specifier (unix:, tcp:, tcp4:,
+    tcp6:), followed by a path or host address. A host address may include an
+    optional port number.</p>
 
     <p><arg>$PULSE_SINK</arg>: the symbolic name of the sink to connect to when a client creates a playback stream and doesn't explicitly ask for a specific sink.</p>
 
@@ -440,6 +462,9 @@ USA.
 
     <p><arg>$PULSE_CLIENTCONFIG</arg>: path of file that shall be read instead of <file>client.conf</file> (see above) for client configuration.</p>
 
+    <p><arg>$PULSE_COOKIE</arg>: path of file that contains the PulseAudio
+    authentication cookie. Defaults to <file>~/.config/pulse/cookie</file>.</p>
+
     <p>These environment settings take precedence -- if set -- over the configuration settings from <file>client.conf</file> (see above).</p>
 
   </section>
similarity index 66%
rename from man/pabrowse.1.xml.in
rename to man/start-pulseaudio-kde.1.xml.in
index 33f071b..ef32906 100644 (file)
@@ -21,26 +21,27 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 USA.
 -->
 
-<manpage name="pabrowse" section="1" desc="List PulseAudio sound servers on the network">
+<manpage name="start-pulseaudio-kde" section="1" desc="PulseAudio Sound Server KDE Startup Script">
 
   <synopsis>
-    <cmd>pabrowse</cmd>
+    <cmd>start-pulseaudio-kde [<arg>pulseaudio options</arg>]</cmd>
   </synopsis>
 
   <description>
-    <p><file>pabrowse</file> lists all PulseAudio sound servers on the
-    local network that are being announced with Zeroconf/Avahi.</p>
+    <p>This script starts pulseaudio (if not already running) and loads
+    module-device-manager to use KDE routing policies.</p>
 
-    <p>This program takes no command line arguments.</p>
+    <p>All arguments are directly passed to pulseaudio.</p>
   </description>
 
   <section name="Authors">
-    <p>The PulseAudio Developers &lt;@PACKAGE_BUGREPORT@&gt;; PulseAudio is available from <url href="@PACKAGE_URL@"/></p>
+    <p>The PulseAudio Developers &lt;@PACKAGE_BUGREPORT@&gt;;
+    PulseAudio is available from <url href="@PACKAGE_URL@"/></p>
   </section>
 
   <section name="See also">
     <p>
-      <manref name="pulseaudio" section="1"/>, <manref name="avahi-daemon" section="8"/>
+      <manref name="pulseaudio" section="1"/>
     </p>
   </section>
 
diff --git a/man/start-pulseaudio-x11.1.xml.in b/man/start-pulseaudio-x11.1.xml.in
new file mode 100644 (file)
index 0000000..32f1571
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version="1.0"?><!--*-nxml-*-->
+<!DOCTYPE manpage SYSTEM "xmltoman.dtd">
+<?xml-stylesheet type="text/xsl" href="xmltoman.xsl" ?>
+
+<!--
+This file is part of PulseAudio.
+
+PulseAudio is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as
+published by the Free Software Foundation; either version 2.1 of the
+License, or (at your option) any later version.
+
+PulseAudio is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with PulseAudio; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+USA.
+-->
+
+<manpage name="start-pulseaudio-x11" section="1" desc="PulseAudio Sound Server X11 Startup Script">
+
+  <synopsis>
+    <cmd>start-pulseaudio-x11 [<arg>pulseaudio options</arg>]</cmd>
+  </synopsis>
+
+  <description>
+    <p>This script starts pulseaudio (if not already running) and loads modules to
+    publish access credentials to the PulseAudio server in the X11 root window and to synthesize
+    X11 media key events on cork/uncork requests. Additionally it registers
+    PulseAudio to the X11 Session Manager.</p>
+
+    <p>All arguments are directly passed to pulseaudio.</p>
+  </description>
+
+  <section name="Authors">
+    <p>The PulseAudio Developers &lt;@PACKAGE_BUGREPORT@&gt;;
+    PulseAudio is available from <url href="@PACKAGE_URL@"/></p>
+  </section>
+
+  <section name="See also">
+    <p>
+      <manref name="pulseaudio" section="1"/>
+    </p>
+  </section>
+
+</manpage>
diff --git a/missing b/missing
new file mode 100755 (executable)
index 0000000..86a8fc3
--- /dev/null
+++ b/missing
@@ -0,0 +1,331 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2012-01-06.13; # UTC
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program 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 General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  autom4te     touch the output file, or create a stub one
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
+\`g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# normalize program name to check for.
+program=`echo "$1" | sed '
+  s/^gnu-//; t
+  s/^gnu//; t
+  s/^g//; t'`
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).  This is about non-GNU programs, so use $1 not
+# $program.
+case $1 in
+  lex*|yacc*)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $program in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case $f in
+      *:*) touch_files="$touch_files "`echo "$f" |
+                                      sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+          sed 's/\.am$/.in/' |
+          while read f; do touch "$f"; done
+    ;;
+
+  autom4te*)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+       touch $file
+    else
+       test -z "$file" || exec >$file
+       echo "#! /bin/sh"
+       echo "# Created by GNU Automake missing as a replacement of"
+       echo "#  $ $@"
+       echo "exit 0"
+       chmod +x $file
+       exit 1
+    fi
+    ;;
+
+  bison*|yacc*)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if test $# -ne 1; then
+        eval LASTARG=\${$#}
+       case $LASTARG in
+       *.y)
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+           if test -f "$SRCFILE"; then
+                cp "$SRCFILE" y.tab.c
+           fi
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+           if test -f "$SRCFILE"; then
+                cp "$SRCFILE" y.tab.h
+           fi
+         ;;
+       esac
+    fi
+    if test ! -f y.tab.h; then
+       echo >y.tab.h
+    fi
+    if test ! -f y.tab.c; then
+       echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex*|flex*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if test $# -ne 1; then
+        eval LASTARG=\${$#}
+       case $LASTARG in
+       *.l)
+           SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+           if test -f "$SRCFILE"; then
+                cp "$SRCFILE" lex.yy.c
+           fi
+         ;;
+       esac
+    fi
+    if test ! -f lex.yy.c; then
+       echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+        you modified a dependency of a manual page.  You may need the
+        \`Help2man' package in order for those modifications to take
+        effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+       touch $file
+    else
+       test -z "$file" || exec >$file
+       echo ".ab help2man is required to generate this page"
+       exit $?
+    fi
+    ;;
+
+  makeinfo*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    # The file to touch is that specified with -o ...
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -z "$file"; then
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '
+       /^@setfilename/{
+         s/.* \([^ ]*\) *$/\1/
+         p
+         q
+       }' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+    fi
+    # If the file does not exist, the user really needs makeinfo;
+    # let's fail without touching anything.
+    test -f $file || exit 1
+    touch $file
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/orc.mak b/orc.mak
new file mode 100644 (file)
index 0000000..5a6ff96
--- /dev/null
+++ b/orc.mak
@@ -0,0 +1,46 @@
+#
+# This is a Makefile.am fragment to build Orc code. It is based
+# on the orc.mak file distributed in the GStreamer common
+# repository.
+#
+# Include this file like this:
+#
+#  include $(top_srcdir)/orc.mak
+#
+# For each Orc source file, append its name (without the extension)
+# to ORC_SOURCE:
+#
+#  ORC_SOURCE += gstadderorc
+#
+# This will create gstadder-orc-gen.c and gstadder-orc-gen.h, which
+# you need to add to your nodist_module_SOURCES.
+#
+# Note that this file appends to BUILT_SOURCES and CLEANFILES, so
+# define them before including this file.
+#
+
+
+EXTRA_DIST += $(addsuffix .orc,$(ORC_SOURCE))
+
+ORC_BUILT_SOURCE = $(addsuffix -orc-gen.c,$(ORC_SOURCE))
+ORC_BUILT_HEADER = $(addsuffix -orc-gen.h,$(ORC_SOURCE))
+
+BUILT_SOURCES += $(ORC_BUILT_SOURCE) $(ORC_BUILT_HEADER)
+CLEANFILES += $(BUILT_SOURCES)
+
+
+orcc_v_gen = $(orcc_v_gen_$(V))
+orcc_v_gen_ = $(orcc_v_gen_$(AM_DEFAULT_VERBOSITY))
+orcc_v_gen_0 = @echo "  ORCC   $@";
+
+cp_v_gen = $(cp_v_gen_$(V))
+cp_v_gen_ = $(cp_v_gen_$(AM_DEFAULT_VERBOSITY))
+cp_v_gen_0 = @echo "  CP     $@";
+
+%-orc-gen.c: %.orc
+       @mkdir -p $(@D)
+       $(orcc_v_gen)$(ORCC) --implementation -o $@ $<
+
+%-orc-gen.h: %.orc
+       @mkdir -p $(@D)
+       $(orcc_v_gen)$(ORCC) --header -o $@ $<
diff --git a/packaging/pulseaudio.service b/packaging/pulseaudio.service
new file mode 100644 (file)
index 0000000..1f58574
--- /dev/null
@@ -0,0 +1,15 @@
+[Unit]
+Description=pulseaudio service
+After=syslog.target dbus.service alsa-restore.service adsp-loader.service
+
+[Service]
+Type=forking
+ExecStartPre=/bin/mkdir -p /tmp/pulseaudio ; /usr/bin/chsmack -a pulseaudio -t /tmp/pulseaudio
+ExecStart=/usr/bin/pulseaudio
+Restart=always
+KillSignal=SIGKILL
+MemoryLimit=50M
+PIDFile=/var/run/pulse/pid
+
+[Install]
+WantedBy=multi-user.target
old mode 100644 (file)
new mode 100755 (executable)
index f18f6e1..8603dfb
@@ -1,33 +1,45 @@
-%define pulseversion  0.9.21
-
+%define _unpackaged_files_terminate_build 0
+%define pulseversion  4.0
 Name:       pulseaudio
 Summary:    Improved Linux sound server
-Version:    0.9.21
-Release:    16
+Version:    4.0.154
+Release:    0
 Group:      Multimedia/PulseAudio
-License:    LGPLv2+
+License:    LGPL-2.1
 URL:        http://pulseaudio.org
 Source0:    http://0pointer.de/lennart/projects/pulseaudio/pulseaudio-%{version}.tar.gz
-Requires:   udev 
+Source1:    pulseaudio.service
+Requires:   systemd >= 183
+Requires:   dbus
+Requires:   bluez
+Requires(preun):  /usr/bin/systemctl
+Requires(post):   /usr/bin/systemctl
+Requires(postun): /usr/bin/systemctl
 Requires(post): /sbin/ldconfig
 Requires(postun): /sbin/ldconfig
-BuildRequires:  pkgconfig(capi-system-power)
-BuildRequires:  pkgconfig(sysman) 
+Requires(post):  sys-assert
 BuildRequires:  pkgconfig(speexdsp)
 BuildRequires:  pkgconfig(sndfile)
 BuildRequires:  pkgconfig(alsa)
 BuildRequires:  pkgconfig(glib-2.0)
-BuildRequires:  pkgconfig(gconf-2.0)
-BuildRequires:  pkgconfig(bluez)
+BuildRequires:  pkgconfig(dbus-1)
 BuildRequires:  pkgconfig(libudev)
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(vconf)
+BuildRequires:  pkgconfig(security-server)
+%ifarch %{arm}
+%endif
 BuildRequires:  m4
 BuildRequires:  libtool-ltdl-devel
 BuildRequires:  libtool
 BuildRequires:  intltool
 BuildRequires:  fdupes
+BuildRequires:  pkgconfig(json)
+BuildRequires:  pkgconfig(sbc)
+BuildRequires:  pkgconfig(iniparser)
 
+%define conf_option --disable-static --enable-alsa --disable-ipv6 --disable-oss-output --disable-oss-wrapper --enable-dlog --enable-bluez5 --disable-bluez4 --disable-hal --disable-hal-compat --disable-legacy-runtime-dir --with-udev-rules-dir=/usr/lib/udev/rules.d --disable-systemd
+%bcond_with pulseaudio_with_bluez5
 
 %description
 PulseAudio is a sound server for Linux and other Unix like operating
@@ -39,6 +51,7 @@ Summary:    PulseAudio client libraries
 Group:      Multimedia/PulseAudio
 Requires:   %{name} = %{version}-%{release}
 Requires:   /bin/sed
+Requires(post): /sbin/syslogd
 
 %description libs
 Client libraries used by applications that access a PulseAudio sound server
@@ -72,7 +85,6 @@ PulseAudio sound server. Included tools are:
    pactl - Send a control command to a PulseAudio server.
    padsp - /dev/dsp wrapper to transparently support OSS applications.
 
-
 %package module-bluetooth
 Summary:    Bluetooth module for PulseAudio sound server
 Group:      Multimedia/PulseAudio
@@ -88,17 +100,45 @@ This module enables PulseAudio to work with bluetooth devices, like headset
 
 
 %build
+%if 0%{?sec_build_binary_debug_enable}
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS –DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+%endif
+
+%if "%{?tizen_profile_name}" == "wearable"
+       echo "tizen profile werable"
+       export CFLAGS+=" -DTIZEN_MICRO -DPM_ASYNC -DPRIMARY_VOLUME -DADJUST_ANDROID_BITPOOL -DBURST_SHOT"
+%elseif "%{?tizen_profile_name}" == "mobile"
+       echo "tizen profile mobile"
+       export CFLAGS+=" -DTIZEN_MOBILE -DPM_ASYNC -DPRIMARY_VOLUME -DBURST_SHOT"
+%endif
+
 unset LD_AS_NEEDED
+%ifarch %{arm}
+export CFLAGS+=" -mfloat-abi=softfp -mfpu=neon"
+%endif
+export CFLAGS+=" -DPA_EXT_USE_VOLUME_FADING -D__TIZEN__ -D__TIZEN_BT__ -D__TIZEN_LOG__ -DBLUETOOTH_APTX_SUPPORT"
 export LDFLAGS+="-Wl,--no-as-needed"
-%reconfigure --disable-static --enable-alsa --disable-ipv6 --disable-oss-output --disable-oss-wrapper --enable-dlog --enable-bluez --disable-hal --disable-hal-compat --disable-legacy-runtime-dir
-make %{?jobs:-j%jobs}
+%ifarch %{ix86}
+%reconfigure %{conf_option}
+%else
+%reconfigure %{conf_option} --enable-security
+%endif
+make %{?_smp_mflags}
 
 %install
-rm -rf %{buildroot}
 %make_install
+mkdir -p %{buildroot}/%{_datadir}/license
+cp LGPL %{buildroot}/%{_datadir}/license/%{name}
+cp LGPL %{buildroot}/%{_datadir}/license/pulseaudio-libs
+cp LGPL %{buildroot}/%{_datadir}/license/pulseaudio-utils
+cp LGPL %{buildroot}/%{_datadir}/license/pulseaudio-module-bluetooth
 
-
-install -D -m0755 pulseaudio.sh.in %{buildroot}%{_sysconfdir}/rc.d/init.d/pulseaudio.sh
+mkdir -p %{buildroot}%{_libdir}/systemd/system
+install -m 644 %{SOURCE1} %{buildroot}%{_libdir}/systemd/system/pulseaudio.service
+mkdir -p  %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants
+ln -s  ../pulseaudio.service  %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/pulseaudio.service
 
 pushd %{buildroot}/etc/pulse/filter
 ln -sf filter_8000_44100.dat filter_11025_44100.dat
@@ -109,32 +149,42 @@ ln -sf filter_8000_44100.dat filter_24000_44100.dat
 ln -sf filter_8000_44100.dat filter_32000_44100.dat
 popd
 
-rm -rf  %{buildroot}/etc/xdg/autostart/pulseaudio-kde.desktop
-rm -rf  %{buildroot}/usr/bin/start-pulseaudio-kde
-rm -rf  %{buildroot}/usr/bin/start-pulseaudio-x11
+rm -f %{buildroot}/etc/xdg/autostart/pulseaudio-kde.desktop
+rm -f %{buildroot}/usr/bin/start-pulseaudio-kde
+rm -f %{buildroot}/usr/bin/start-pulseaudio-x11
 
 %find_lang pulseaudio
 %fdupes  %{buildroot}/%{_datadir}
 %fdupes  %{buildroot}/%{_includedir}
 
 
+%preun
+if [ $1 == 0 ]; then
+    systemctl stop pulseaudio.service
+fi
 
-%post 
+%post
 /sbin/ldconfig
-ln -s  /etc/rc.d/init.d/pulseaudio.sh /etc/rc.d/rc3.d/S20pulseaudio
-ln -s  /etc/rc.d/init.d/pulseaudio.sh /etc/rc.d/rc4.d/S20pulseaudio
+
+/usr/bin/vconftool set -t int memory/Sound/SoundCaptureStatus 0 -g 29 -f -i -s system::vconf_multimedia
+/usr/bin/vconftool set -t int memory/private/sound/pcm_dump 0 -g 29 -f -i -s system::vconf_multimedia
+/usr/bin/vconftool set -t int memory/private/sound/burstshot 0 -g 29 -f -i -s system::vconf_multimedia
+
+systemctl daemon-reload
+if [ $1 == 1 ]; then
+    systemctl restart pulseaudio.service
+fi
 
 %postun
 /sbin/ldconfig
-rm -f %{_sysconfdir}/rc.d/rc3.d/S20pulseaudio
-rm -f %{_sysconfdir}/rc.d/rc4.d/S20pulseaudio
+systemctl daemon-reload
 
 %post libs -p /sbin/ldconfig
 
 %postun libs -p /sbin/ldconfig
 
-
 %post module-bluetooth -p /sbin/ldconfig
+
 %postun module-bluetooth -p /sbin/ldconfig
 
 
@@ -142,29 +192,23 @@ rm -f %{_sysconfdir}/rc.d/rc4.d/S20pulseaudio
 
 %lang_package
 
-
 %files
-%defattr(-,root,root,-)
+%manifest pulseaudio.manifest
 %doc LICENSE GPL LGPL
-/etc/pulse/filter/*.dat
-
-
+%{_sysconfdir}/pulse/filter/*.dat
+%exclude %{_sysconfdir}/pulse/daemon.conf
+%exclude %{_sysconfdir}/pulse/default.pa
+%exclude %{_sysconfdir}/pulse/system.pa
 %dir %{_sysconfdir}/pulse/
-%exclude %config(noreplace) %{_sysconfdir}/pulse/daemon.conf
-%exclude %config(noreplace) %{_sysconfdir}/pulse/default.pa
-%exclude %config(noreplace) %{_sysconfdir}/pulse/system.pa
-%{_sysconfdir}/rc.d/init.d/pulseaudio.sh
-%{_bindir}/esdcompat
+%exclude %{_bindir}/esdcompat
 %{_bindir}/pulseaudio
-%dir %{_libexecdir}/pulse
-%{_libexecdir}/pulse/*
 %{_libdir}/libpulsecore-%{pulseversion}.so
 %exclude %{_libdir}/libpulse-mainloop-glib.so.*
-/lib/udev/rules.d/90-pulseaudio.rules
+%{_libdir}/udev/rules.d/90-pulseaudio.rules
 %exclude %{_datadir}/pulseaudio/alsa-mixer/paths/*
 %exclude %{_datadir}/pulseaudio/alsa-mixer/profile-sets/*
 %{_bindir}/pamon
-/etc/dbus-1/system.d/pulseaudio-system.conf
+%{_sysconfdir}/dbus-1/system.d/pulseaudio-system.conf
 #list all modules
 %{_libdir}/pulse-%{pulseversion}/modules/libalsa-util.so
 %{_libdir}/pulse-%{pulseversion}/modules/libcli.so
@@ -180,32 +224,32 @@ rm -f %{_sysconfdir}/rc.d/rc4.d/S20pulseaudio
 %{_libdir}/pulse-%{pulseversion}/modules/module-device-restore.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-device-manager.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-stream-restore.so
-%{_libdir}/pulse-%{pulseversion}/modules/module-cli-protocol-tcp.so
-%{_libdir}/pulse-%{pulseversion}/modules/module-cli-protocol-unix.so
+%exclude %{_libdir}/pulse-%{pulseversion}/modules/module-cli-protocol-tcp.so
+%exclude %{_libdir}/pulse-%{pulseversion}/modules/module-cli-protocol-unix.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-cli.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-combine.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-default-device-restore.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-detect.so
 %exclude %{_libdir}/pulse-%{pulseversion}/modules/module-esound-sink.so
-%{_libdir}/pulse-%{pulseversion}/modules/module-http-protocol-tcp.so
-%{_libdir}/pulse-%{pulseversion}/modules/module-http-protocol-unix.so
+%exclude %{_libdir}/pulse-%{pulseversion}/modules/module-http-protocol-tcp.so
+%exclude %{_libdir}/pulse-%{pulseversion}/modules/module-http-protocol-unix.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-intended-roles.so
-%%exclude %{_libdir}/pulse-%{pulseversion}/modules/module-ladspa-sink.so
+%exclude %{_libdir}/pulse-%{pulseversion}/modules/module-ladspa-sink.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-match.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-mmkbd-evdev.so
-%{_libdir}/pulse-%{pulseversion}/modules/module-native-protocol-fd.so
-%{_libdir}/pulse-%{pulseversion}/modules/module-native-protocol-tcp.so
+%exclude %{_libdir}/pulse-%{pulseversion}/modules/module-native-protocol-fd.so
+%exclude %{_libdir}/pulse-%{pulseversion}/modules/module-native-protocol-tcp.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-native-protocol-unix.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-null-sink.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-pipe-sink.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-pipe-source.so
-%%exclude %{_libdir}/pulse-%{pulseversion}/modules/module-position-event-sounds.so
+%exclude %{_libdir}/pulse-%{pulseversion}/modules/module-position-event-sounds.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-remap-sink.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-rescue-streams.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-rtp-recv.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-rtp-send.so
-%{_libdir}/pulse-%{pulseversion}/modules/module-simple-protocol-tcp.so
-%{_libdir}/pulse-%{pulseversion}/modules/module-simple-protocol-unix.so
+%exclude %{_libdir}/pulse-%{pulseversion}/modules/module-simple-protocol-tcp.so
+%exclude %{_libdir}/pulse-%{pulseversion}/modules/module-simple-protocol-unix.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-sine.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-tunnel-sink.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-tunnel-source.so
@@ -214,67 +258,88 @@ rm -f %{_sysconfdir}/rc.d/rc4.d/S20pulseaudio
 %{_libdir}/pulse-%{pulseversion}/modules/module-alsa-card.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-augment-properties.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-card-restore.so
-%{_libdir}/pulse-%{pulseversion}/modules/module-cork-music-on-phone.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-sine-source.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-loopback.so
 %exclude %{_libdir}/pulse-%{pulseversion}/modules/module-rygel-media-server.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-policy.so
+%{_libdir}/pulse-%{pulseversion}/modules/module-stream-mgr.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-echo-cancel.so
-%{_libdir}/pulse-%{pulseversion}/modules/module-virtual-sink.so
-%{_libdir}/pulse-%{pulseversion}/modules/module-virtual-source.so
 %exclude %{_libdir}/pulse-%{pulseversion}/modules/libprotocol-esound.so
 %exclude %{_libdir}/pulse-%{pulseversion}/modules/module-esound-compat-spawnfd.so
 %exclude %{_libdir}/pulse-%{pulseversion}/modules/module-esound-compat-spawnpid.so
 %exclude %{_libdir}/pulse-%{pulseversion}/modules/module-esound-protocol-tcp.so
 %exclude %{_libdir}/pulse-%{pulseversion}/modules/module-esound-protocol-unix.so
-%{_libdir}/pulse-%{pulseversion}/modules/module-gconf.so
 %{_libdir}/pulse-%{pulseversion}/modules/module-udev-detect.so
-
+%exclude %{_libdir}/pulse-%{pulseversion}/modules/libraop.so
+%exclude %{_libdir}/pulse-%{pulseversion}/modules/module-raop-sink.so
+%exclude /usr/share/vala/vapi/libpulse-mainloop-glib.deps
+%exclude /usr/share/vala/vapi/libpulse-mainloop-glib.vapi
+%exclude /usr/share/vala/vapi/libpulse.deps
+%exclude /usr/share/vala/vapi/libpulse.vapi
+%{_libdir}/systemd/system/pulseaudio.service
+%{_libdir}/systemd/system/multi-user.target.wants/pulseaudio.service
+%exclude %{_libdir}/cmake/PulseAudio/PulseAudioConfig.cmake
+%exclude %{_libdir}/cmake/PulseAudio/PulseAudioConfigVersion.cmake
+%{_libdir}/pulse-%{pulseversion}/modules/module-combine-sink.so
+%{_libdir}/pulse-%{pulseversion}/modules/module-dbus-protocol.so
+%{_libdir}/pulse-%{pulseversion}/modules/module-filter-apply.so
+%{_libdir}/pulse-%{pulseversion}/modules/module-filter-heuristics.so
+%{_libdir}/pulse-%{pulseversion}/modules/module-null-source.so
+%{_libdir}/pulse-%{pulseversion}/modules/module-remap-source.so
+%{_libdir}/pulse-%{pulseversion}/modules/module-role-cork.so
+%{_libdir}/pulse-%{pulseversion}/modules/module-role-ducking.so
+%{_libdir}/pulse-%{pulseversion}/modules/module-switch-on-connect.so
+%{_libdir}/pulse-%{pulseversion}/modules/module-switch-on-port-available.so
+%{_libdir}/pulse-%{pulseversion}/modules/module-virtual-sink.so
+%{_libdir}/pulse-%{pulseversion}/modules/module-virtual-source.so
+%{_libdir}/pulse-%{pulseversion}/modules/module-virtual-surround-sink.so
+%{_datadir}/license/%{name}
 
 %files libs
-%defattr(-,root,root,-)
-%exclude %config(noreplace) %{_sysconfdir}/pulse/client.conf
+%manifest pulseaudio_shared.manifest
+%exclude %{_sysconfdir}/pulse/client.conf
 %{_libdir}/libpulse.so.*
 %{_libdir}/libpulse-simple.so.*
-%{_libdir}/libpulsecommon-*.so
+%{_libdir}/pulseaudio/libpulsecommon-*.so
+%{_datadir}/license/pulseaudio-libs
 
 %files libs-devel
-%defattr(-,root,root,-)
 %{_includedir}/pulse/*
-#%{_includedir}/pulse-modules-headers/pulsecore/
+%{_includedir}/pulsecore/*
 %{_libdir}/libpulse.so
 %{_libdir}/libpulse-simple.so
 %{_libdir}/pkgconfig/libpulse-simple.pc
+%{_libdir}/pkgconfig/pulsecore.pc
 %{_libdir}/pkgconfig/libpulse.pc
-%{_datadir}/vala/vapi/libpulse.vapi
 %exclude %{_libdir}/pkgconfig/libpulse-mainloop-glib.pc
 %exclude %{_libdir}/libpulse-mainloop-glib.so
 
 %files utils
-%defattr(-,root,root,-)
-%doc %{_mandir}/man1/pabrowse.1.gz
+%manifest pulseaudio_shared.manifest
 %doc %{_mandir}/man1/pacat.1.gz
 %doc %{_mandir}/man1/pacmd.1.gz
 %doc %{_mandir}/man1/pactl.1.gz
-#%doc %{_mandir}/man1/padsp.1.gz
 %doc %{_mandir}/man1/paplay.1.gz
-%doc %{_mandir}/man1/pasuspender.1.gz
+%exclude %doc %{_mandir}/man1/pasuspender.1.gz
 %{_bindir}/pacat
+%{_bindir}/pacat-simple
 %{_bindir}/pacmd
 %{_bindir}/pactl
-#%{_bindir}/padsp
 %{_bindir}/paplay
 %{_bindir}/parec
 %{_bindir}/pamon
 %{_bindir}/parecord
-%{_bindir}/pasuspender
+%exclude %{_bindir}/pasuspender
+%{_datadir}/license/pulseaudio-utils
 
 %files module-bluetooth
-%defattr(-,root,root,-)
-%{_libdir}/pulse-%{pulseversion}/modules/module-bluetooth-proximity.so
-%{_libdir}/pulse-%{pulseversion}/modules/module-bluetooth-device.so
+%manifest pulseaudio_shared.manifest
 %{_libdir}/pulse-%{pulseversion}/modules/module-bluetooth-discover.so
-%{_libdir}/pulse-%{pulseversion}/modules/libbluetooth-ipc.so
-%{_libdir}/pulse-%{pulseversion}/modules/libbluetooth-sbc.so
-%{_libdir}/pulse-%{pulseversion}/modules/libbluetooth-util.so
-#%{_libdir}/pulseaudio/pulse/proximity-helper
+%{_libdir}/pulse-%{pulseversion}/modules/module-bluetooth-policy.so
+%{_libdir}/pulse-%{pulseversion}/modules/module-bluez5-discover.so
+%{_libdir}/pulse-%{pulseversion}/modules/module-bluez5-device.so
+%{_libdir}/pulse-%{pulseversion}/modules/libbluez5-util.so
+%exclude /etc/bash_completion.d/pulseaudio-bash-completion.sh
+%{_libdir}/pulse-%{pulseversion}/modules/module-bluetooth-policy.so
+%{_datadir}/license/pulseaudio-module-bluetooth
+
diff --git a/po/.gitignore b/po/.gitignore
new file mode 100644 (file)
index 0000000..1ebb427
--- /dev/null
@@ -0,0 +1,16 @@
+/.intltool-merge-cache
+/Makefile.in.in
+/Makevars.template
+/POTFILES
+/Rules-quot
+/boldquot.sed
+/en@boldquot.header
+/en@quot.header
+/insert-header.sin
+/pulseaudio.pot
+/quot.sed
+/remove-potcdate.sin
+/*.mo
+/*.gmo
+/Makefile
+/Makefile.in
diff --git a/po/ChangeLog b/po/ChangeLog
deleted file mode 100644 (file)
index c7f1a63..0000000
+++ /dev/null
@@ -1,702 +0,0 @@
-2010-02-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2010-02-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2010-02-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2010-02-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2010-02-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2010-02-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2010-02-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2010-02-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2010-02-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2010-02-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-       * Rules-quot: New file, from gettext-0.17.
-       * boldquot.sed: New file, from gettext-0.17.
-       * en@boldquot.header: New file, from gettext-0.17.
-       * en@quot.header: New file, from gettext-0.17.
-       * insert-header.sin: New file, from gettext-0.17.
-       * quot.sed: New file, from gettext-0.17.
-       * remove-potcdate.sin: New file, from gettext-0.17.
-
-2009-11-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-11-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-11-21  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-11-18  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-11-18  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-11-15  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-11-15  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-11-15  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-11-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-11-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-11-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-11-05  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-11-05  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-10-31  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-10-31  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-10-30  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-10-29  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-10-28  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-10-07  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-09-30  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-09-29  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-09-29  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-09-19  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-09-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-09-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-09-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-09-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-09-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-09-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-09-09  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-09-09  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-09-08  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-09-08  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-09-07  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-09-03  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-29  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-24  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-24  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-24  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-22  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-21  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-19  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-19  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-19  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-19  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-19  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-17  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-16  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-16  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-16  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-15  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-15  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-15  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-08  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-08  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-07  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-06  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-08-05  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-07-31  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-07-30  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-07-28  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-07-28  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-07-24  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-07-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-07-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-07-02  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-07-02  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-29  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: New file, from gettext-0.17.
-
-2009-06-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-22  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-22  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-22  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-19  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-19  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-19  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-18  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-17  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-17  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-17  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-17  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-06  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-06-06  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-28  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-28  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-28  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-25  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-21  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-21  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-16  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-16  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-14  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-14  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-14  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-14  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-14  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-14  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-14  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-11  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-05-07  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-04-28  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-04-28  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-04-24  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-04-19  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-04-14  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-04-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-04-10  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-04-01  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-04-01  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-03-31  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-03-31  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-03-05  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-03-05  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-03-05  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-03-05  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-03-05  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-03-05  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-03-05  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-03-03  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-03-03  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-03-03  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-03-02  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-03-02  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-02-24  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: Upgrade to gettext-0.17.
-
-2009-02-24  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.in.in: New file, from gettext-0.17.
-       * boldquot.sed: New file, from gettext-0.17.
-       * en@boldquot.header: New file, from gettext-0.17.
-       * en@quot.header: New file, from gettext-0.17.
-       * insert-header.sin: New file, from gettext-0.17.
-       * quot.sed: New file, from gettext-0.17.
-       * remove-potcdate.sin: New file, from gettext-0.17.
-       * Rules-quot: New file, from gettext-0.17.
-
index 363599e..3e3d9de 100644 (file)
@@ -2,15 +2,17 @@ as
 bn_IN
 ca
 cs
-de
 de_CH
+de
 el
 es
 fi
 fr
 gu
+he
 hi
 hu
+id
 it
 ja
 kn
@@ -20,12 +22,14 @@ nl
 or
 pa
 pl
-pt
 pt_BR
-sr
+pt
+ru
 sr@latin
+sr
 sv
 ta
 te
 uk
 zh_CN
+zh_TW
index cc8a222..06a8cfe 100644 (file)
@@ -49,8 +49,8 @@ MSGFMT = @MSGFMT@
 XGETTEXT = @XGETTEXT@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
-MSGMERGE = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist
-GENPOT   = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot
+MSGMERGE = INTLTOOL_EXTRACT="$(INTLTOOL_EXTRACT)" XGETTEXT="$(XGETTEXT)" srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist
+GENPOT   = INTLTOOL_EXTRACT="$(INTLTOOL_EXTRACT)" XGETTEXT="$(XGETTEXT)" srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot
 
 ALL_LINGUAS = @ALL_LINGUAS@
 
@@ -73,15 +73,20 @@ CATALOGS=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$l
 .SUFFIXES:
 .SUFFIXES: .po .pox .gmo .mo .msg .cat
 
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+INTLTOOL_V_MSGFMT = $(INTLTOOL__v_MSGFMT_$(V))
+INTLTOOL__v_MSGFMT_= $(INTLTOOL__v_MSGFMT_$(AM_DEFAULT_VERBOSITY))
+INTLTOOL__v_MSGFMT_0 = @echo "  MSGFMT" $@;
+
 .po.pox:
        $(MAKE) $(GETTEXT_PACKAGE).pot
        $(MSGMERGE) $< $(GETTEXT_PACKAGE).pot -o $*.pox
 
 .po.mo:
-       $(MSGFMT) -o $@ $<
+       $(INTLTOOL_V_MSGFMT)$(MSGFMT) -o $@ $<
 
 .po.gmo:
-       file=`echo $* | sed 's,.*/,,'`.gmo \
+       $(INTLTOOL_V_MSGFMT)file=`echo $* | sed 's,.*/,,'`.gmo \
          && rm -f $$file && $(GMSGFMT) -o $$file $<
 
 .po.cat:
index 0bf7087..b33a74e 100644 (file)
@@ -3,6 +3,8 @@ src/modules/module-tunnel.c
 src/modules/module-native-protocol-fd.c
 src/modules/module-zeroconf-discover.c
 src/modules/alsa/module-alsa-source.c
+src/modules/bluetooth/module-bluez4-device.c
+src/modules/bluetooth/module-bluez5-device.c
 src/modules/module-device-restore.c
 src/modules/module-match.c
 src/pulsecore/dbus-util.c
@@ -17,11 +19,10 @@ src/modules/module-solaris.c
 src/modules/module-default-device-restore.c
 src/modules/x11/module-x11-xsmp.c
 src/modules/module-remap-sink.c
-src/modules/bluetooth/module-bluetooth-proximity.c
+#src/modules/bluetooth/module-bluetooth-proximity.c
 src/modules/module-detect.c
 src/modules/module-always-sink.c
 src/modules/module-lirc.c
-src/modules/module-hal-detect.c
 src/modules/module-sine.c
 src/modules/module-zeroconf-publish.c
 src/modules/jack/module-jack-source.c
@@ -39,7 +40,7 @@ src/modules/module-esound-compat-spawnfd.c
 src/modules/module-esound-compat-spawnpid.c
 #src/modules/module-waveout.c
 src/modules/module-combine.c
-src/modules/bluetooth/proximity-helper.c
+#src/modules/bluetooth/proximity-helper.c
 src/modules/x11/module-x11-publish.c
 src/modules/rtp/module-rtp-recv.c
 src/modules/rtp/sdp.c
@@ -84,7 +85,6 @@ src/pulsecore/socket-client.c
 src/pulsecore/idxset.c
 src/pulsecore/pipe.c
 src/pulsecore/asyncmsgq.c
-src/pulsecore/inet_pton.c
 src/pulsecore/socket-util.c
 src/pulsecore/object.c
 src/pulsecore/sioman.c
@@ -93,7 +93,6 @@ src/pulsecore/x11prop.c
 src/pulsecore/sconv-s16be.c
 src/pulsecore/thread-posix.c
 src/pulsecore/client.c
-src/pulsecore/inet_ntop.c
 src/pulsecore/strlist.c
 src/pulsecore/msgobject.c
 src/pulsecore/mutex-win32.c
@@ -109,7 +108,6 @@ src/pulsecore/core-error.c
 src/pulsecore/strbuf.c
 src/pulsecore/play-memblockq.c
 src/pulsecore/dllmain.c
-src/pulsecore/envelope.c
 src/pulsecore/pid.c
 src/pulsecore/thread-mq.c
 src/pulsecore/shm.c
@@ -118,7 +116,8 @@ src/pulsecore/hashmap.c
 src/pulsecore/avahi-wrap.c
 src/pulsecore/authkey.c
 src/pulsecore/namereg.c
-src/pulsecore/poll.c
+src/pulsecore/poll-posix.c
+src/pulsecore/poll-win32.c
 src/pulsecore/tokenizer.c
 src/pulsecore/semaphore-posix.c
 src/pulsecore/cli-text.c
@@ -145,6 +144,7 @@ src/pulsecore/sound-file-stream.c
 src/pulsecore/memblockq.c
 src/pulsecore/protocol-http.c
 src/pulsecore/semaphore-win32.c
+src/pulsecore/i18n.c
 src/daemon/cpulimit.c
 src/daemon/ltdl-bind-now.c
 src/daemon/main.c
@@ -153,20 +153,19 @@ src/daemon/dumpmodules.c
 src/daemon/daemon-conf.c
 src/daemon/caps.c
 src/daemon/pulseaudio.desktop.in
+src/daemon/pulseaudio-kde.desktop.in
 src/pulse/channelmap.c
 src/pulse/error.c
 src/pulse/proplist.c
 src/pulse/xmalloc.c
 src/pulse/ext-stream-restore.c
 src/pulse/stream.c
-src/pulse/i18n.c
 src/pulse/util.c
 src/pulse/utf8.c
 src/pulse/mainloop-api.c
 src/pulse/sample.c
 src/pulse/client-conf-x11.c
 src/pulse/client-conf.c
-src/pulse/browser.c
 src/pulse/volume.c
 src/pulse/simple.c
 src/pulse/subscribe.c
@@ -179,9 +178,9 @@ src/pulse/thread-mainloop.c
 src/pulse/scache.c
 src/pulse/glib-mainloop.c
 src/pulse/timeval.c
+src/pulse/format.c
 src/utils/pacat.c
 src/utils/pasuspender.c
-src/utils/pabrowse.c
 src/utils/pactl.c
 src/utils/padsp.c
 src/utils/pax11publish.c
@@ -194,3 +193,9 @@ src/modules/bluetooth/module-bluetooth-device.c
 src/modules/reserve-wrap.c
 src/modules/module-rygel-media-server.c
 src/modules/alsa/alsa-mixer.c
+src/modules/echo-cancel/module-echo-cancel.c
+src/modules/module-equalizer-sink.c
+src/modules/module-filter-apply.c
+src/tests/resampler-test.c
+src/modules/module-virtual-surround-sink.c
+src/modules/macosx/module-coreaudio-device.c
index 4622d2f..8afd0d6 100644 (file)
@@ -1 +1,3 @@
 src/pulsecore/atomic.h
+src/modules/module-virtual-sink.c
+src/modules/module-virtual-source.c
index f7b2dee..c0e8422 100644 (file)
--- a/po/as.po
+++ b/po/as.po
@@ -1,28 +1,24 @@
 # translation of pulseaudio.master-tx.as.po to Assamese
 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the PACKAGE package.
+# Amitakhya Phukan <aphukan@fedoraproject.org>, 2009, 2012.
 #
-# Amitakhya Phukan <aphukan@fedoraproject.org>, 2009.
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx.as\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-09-08 21:04+0530\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:52+0000\n"
 "Last-Translator: Amitakhya Phukan <aphukan@fedoraproject.org>\n"
-"Language-Team: Assamese\n"
+"Language-Team: Assamese <>\n"
+"Language: as\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Generator: KBabel 1.11.4\n"
+"X-Generator: Lokalize 0.2\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -34,11 +30,11 @@ msgstr ""
 "অতি সম্ভৱ এইটো ALSA চালক '%s' ৰ এটা বাগ । অনুগ্ৰহ কৰি এই সমস্যা ALSA বিকাশকক "
 "জনাওক ।"
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
@@ -46,7 +42,19 @@ msgstr ""
 "অতি সম্ভৱ এইটো ALSA চালক '%s' ৰ এটা বাগ । অনুগ্ৰহ কৰি এই সমস্যা ALSA বিকাশকক "
 "জনাওক ।"
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() এ এটা বৰ ডাঙৰ মান ঘূৰালে: %lu bytes (%lu ms) ।\n"
+"অতি সম্ভৱ এইটো ALSA চালক '%s' ৰ এটা বাগ । অনুগ্ৰহ কৰি এই সমস্যা ALSA বিকাশকক "
+"জনাওক ।"
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -58,302 +66,332 @@ msgstr ""
 "অতি সম্ভৱ এইটো ALSA চালক '%s' ৰ এটা বাগ । অনুগ্ৰহ কৰি এই সমস্যা ALSA বিকাশকক "
 "জনাওক ।"
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
-msgstr ""
+msgstr "সদায়ে অন্তত এটা sink লোড কৰি ৰখা হ'ব, প্ৰয়োজনত null sink ব্যৱহাৰ কৰা হ'ব"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
-msgstr ""
+msgstr "ডামি নিৰ্গম"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
-msgstr "ভারà§\8dà¦\9aà§\81à§\9fাল LADSPA sink"
+msgstr "ভাৰà§\8dà¦\9aà§\81à§\9fাল LADSPA sink"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<name for the sink> sink_properties=<properties for the sink> "
 "master=<name of sink to filter> format=<sample format> rate=<sample rate> "
 "channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
+"plugin name> label=<ladspa plugin label> control=<comma separated list of "
 "input control values>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
-msgstr ""
+msgstr "NULL sink ৰ সময় নিৰ্ধাৰণ"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
-msgstr ""
+msgstr "Null ফলাফল"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "আভ্যন্তৰীণ অ'ডিঅ'"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "মোডেম"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "প্ৰাথমিক lt_dlopen loader পোৱা ন'গ'ল ।"
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "নতুন dl loader বিতৰণ কৰিবলৈ বিফল ।"
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
-msgstr "bind-now-loader যোগ কৰিবলৈ বিফল ।"
+msgstr "bind now loader যোগ কৰিবলৈ বিফল ।"
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "চিগ্নেল %s পোৱা গ'ল ।"
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "প্ৰস্থান কৰা হৈছে ।"
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "ব্যৱহাৰকৰ্তা '%s' পোৱা ন'গ'ল ।"
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "'%s' সমষ্টি পোৱা ন'গ'ল ।"
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "ব্যৱহাৰকৰ্তা '%s' (UID %lu) আৰু সমষ্টি '%s' (GID %lu) পোৱা গ'ল ।"
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "ব্যৱহাৰকৰ্তা '%s' আৰু সমষ্টি '%s' ৰ GID অমিল ।"
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "ব্যৱহাৰকৰ্তা '%s' ৰ ঘৰৰ পঞ্জিকা '%s' নহয়, আওকাণ কৰা হৈছে ।"
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "'%s' সৃষ্টি কৰিবলৈ বিফল: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "সমষ্টিৰ তালিকা সলনি কৰিবলৈ ব্যৰ্থ: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "GID সলনি কৰিবলৈ ব্যৰ্থ: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "UID সলনি কৰিবলৈ ব্যৰ্থ: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "ৰূটৰ অধিকাৰ সফলভাবে এৰোৱা গ'ল ।"
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "এই স্থাপত্যত প্ৰণালী ব্যাপক মোড অসমৰ্থিত ।"
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) বিফল: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "আদেশ শাৰী বিশ্লেষণ কৰিবলৈ বিফল ।"
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "ডেমন নাই চলা"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "PID %u ৰূপে ডেমন চলিছে"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "ডেমন kill কৰিবলৈ ব্যৰ্থ: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
 msgstr ""
-"root পৰিচয়ে এই প্ৰোগ্ৰাম সঞ্চালিত হোৱা উচিত নহয় (ন'হ'লে --system উল্লিখিত হয়) ।"
+"root পৰিচয়ে এই প্ৰোগ্ৰাম সঞ্চালিত হোৱা উচিত নহয় (ন'হ'লে   system উল্লিখিত হয়) ।"
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
-msgstr "Root-ৰ অধিকাৰ আৱশ্যক ।"
+msgstr "Root ৰ অধিকাৰ আৱশ্যক ।"
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
-msgstr "প্ৰণালী চানেকিৰ ক্ষেত্ৰত --start সমৰ্থিত নহয় ।"
+msgstr "প্ৰণালী চানেকিৰ ক্ষেত্ৰত   start সমৰ্থিত নহয় ।"
+
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
-msgstr "প্ৰণালী মোডত চলিছে, কিন্তু --disallow-exit নিৰ্ধাৰিত নহয়!"
+msgstr "প্ৰণালী মোডত চলিছে, কিন্তু   disallow exit নিৰ্ধাৰিত নহয়!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
-msgstr "প্ৰণালী মোডত চলিছে, কিন্তু --disallow-module-loading নিৰ্ধাৰিত নহয়!"
+msgstr "প্ৰণালী মোডত চলিছে, কিন্তু   disallow module loading নিৰ্ধাৰিত নহয়!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "প্ৰণালী মোডত চলিছে, SHM মোড বলপূৰ্বক নিষ্ক্ৰিয় কৰা হৈছে!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 "প্ৰণালী মোডত চলিছে, কাম নকৰা সময়ৰ পৰা প্ৰস্থান কৰা বলপূৰ্বক নিষ্ক্ৰিয় কৰা হৈছে!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "stdio প্ৰাপ্ত কৰিবলৈ ব্যৰ্থ ।"
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "pipe বিফল: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() বিফল: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() বিফল: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "ডেমন আৰম্ভ কৰিবলৈ বিফল ।"
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "সফলতাৰে ডেমন আৰম্ভ কৰা হৈছে ।"
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() বিফল: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "এইটো PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "সঙ্কলনৰ গৃহস্থ: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "সঙ্কলনৰ CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "গৃহস্থত চলোৱা হৈছে: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "%u CPU পোৱা গৈছে ।"
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "পেজৰ মাপ %lu bytes"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Valgrind সমৰ্থনৰ সৈতে সঙ্কলন কৰা হৈছে: হয়"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Valgrind সমৰ্থনৰ সৈতে সঙ্কলন কৰা হৈছে: নহয়"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "valgrind মোডত চলিছে: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "গৃহস্থত চলোৱা হৈছে: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "Optimized build: হয়"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "Optimized build: নহয়"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG ব্যাখ্যা কৰা হৈছে, সকলো asserts নিষ্ক্ৰিয় কৰা হৈছে ।"
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH ব্যাখ্যা কৰা হৈছে, অকল fast path asserts নিষ্ক্ৰিয় কৰা হৈছে ।"
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "সকলো asserts সক্ৰিয় কৰা হৈছে ।"
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "যন্ত্ৰ ID প্ৰাপ্ত কৰিবলৈ ব্যৰ্থ"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "যন্ত্ৰ ID হ'ল %s ।"
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "সেশান ID হল %s।"
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
-msgstr "ৰান-টাইম পঞ্জিকা %s ব্যৱহাৰ কৰা হৈছে ।"
+msgstr "ৰান টাইম পঞ্জিকা %s ব্যৱহাৰ কৰা হৈছে ।"
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "অৱস্থাসূচক পঞ্জিকা %s ব্যৱহাৰ কৰা হৈছে ।"
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
-msgstr "মডিà¦\89ল à¦¡à¦¿à¦°à§\87à¦\95à§\8dà¦\9fরি %s à¦¬à§\8dযবহার à¦\95রা à¦¹à¦\9aà§\8dà¦\9bà§\87।"
+msgstr "মডিà¦\89ল à¦¡à¦¿à§°à§\87à¦\95à§\8dà¦\9fৰি %s à¦¬à§\8dযৱহাৰ à¦\95ৰা à¦¹à¦\9aà§\8dà¦\9bà§\87।"
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "প্ৰণালী মোডত চলিছে: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -362,54 +400,54 @@ msgid ""
 "Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an "
 "explanation why system mode is usually a bad idea."
 msgstr ""
-"à¦\86পনি à¦¸à¦¿à¦¸à§\8dà¦\9fà§\87ম à¦®à§\8bডà§\87 PA à¦¸à¦\9eà§\8dà¦\9aালিত à¦\95রà¦\9bà§\87ন à¦\8fবà¦\82 à¦\8fà¦\9fি à¦¨à¦¾ à¦\95রাà¦\87 à¦¬à¦¾à¦\9eà§\8dà¦\9bনà§\80à§\9f।\n"
-"à¦\8fর à¦«à¦²à§\87 à¦ªà§\8dরতà§\8dযাশামত à¦«à¦²à¦¾à¦«à¦² à¦¨à¦¾ à¦ªà¦¾à¦\93à§\9fার à¦¸à¦®à§\8dভাবনা à¦°à§\9fà§\87à¦\9bà§\87।\n"
-"সিসà§\8dà¦\9fà§\87ম à¦®à§\8bডà§\87 à¦¬à§\8dযবহারà§\87র à¦¸à¦®à¦¸à§\8dযা à¦¸à¦®à§\8dপরà§\8dà¦\95à§\87 à¦\9cানতà§\87 à¦¹à¦²à§\87 http://pulseaudio.org/wiki/"
+"à¦\86পনি à¦¸à¦¿à¦¸à§\8dà¦\9fà§\87ম à¦®à§\8bডà§\87 PA à¦¸à¦\9eà§\8dà¦\9aালিত à¦\95ৰà¦\9bà§\87ন à¦\8fবà¦\82 à¦\8fà¦\9fি à¦¨à¦¾ à¦\95ৰাà¦\87 à¦¬à¦¾à¦\9eà§\8dà¦\9bনà§\80à§\9f।\n"
+"à¦\8fৰ à¦«à¦²à§\87 à¦ªà§\8dৰতà§\8dযাশামত à¦«à¦²à¦¾à¦«à¦² à¦¨à¦¾ à¦ªà¦¾à¦\93à§\9fাৰ à¦¸à¦®à§\8dভাবনা à§°à§\9fà§\87à¦\9bà§\87।\n"
+"সিসà§\8dà¦\9fà§\87ম à¦®à§\8bডà§\87 à¦¬à§\8dযৱহাৰà§\87ৰ à¦¸à¦®à¦¸à§\8dযা à¦¸à¦®à§\8dপৰà§\8dà¦\95à§\87 à¦\9cানতà§\87 à¦¹à¦²à§\87 http://pulseaudio.org/wiki/"
 "WhatIsWrongWithSystemMode দেখুন।"
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() ব্যৰ্থ ।"
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
-msgstr "নতুন high-resolution timers পোৱা হয়! অভিনন্দন!"
+msgstr "নতুন high resolution timers পোৱা হয়! অভিনন্দন!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
 msgstr ""
-"শ্ৰীমান, আপোনাৰ কাৰ্ণেল পূৰণি! high-resolution timer সক্ৰিয় থকা Linux ক আজি "
+"শ্ৰীমান, আপোনাৰ কাৰ্ণেল পূৰণি! high resolution timer সক্ৰিয় থকা Linux ক আজি "
 "উপদেশ দিয়া হয়!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() ব্যৰ্থ ।"
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "ডেমন আৰম্ভ কৰিবলৈ ব্যৰ্থ ।"
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 "তুলি লোৱা মডিউল নোহোৱাকে ডেমন আৰম্ভ কৰা হৈছে, কোনো কাম সঞ্চালন কৰা সম্ভৱ নহয় ।"
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "ডেমন আৰম্ভ কৰা সম্পূৰ্ণ ।"
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "ডেমন বন্ধ কৰাৰ প্ৰক্ৰিয়া আৰম্ভ কৰা হৈছে ।"
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "ডেমন বন্ধ কৰা হৈছে ।"
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -446,15 +484,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -484,249 +520,252 @@ msgstr ""
 "%s [options]\n"
 "\n"
 "COMMANDS:\n"
-"  -h, --help                            Show this help\n"
-"      --version                         Show version\n"
-"      --dump-conf                       Dump default configuration\n"
-"      --dump-modules                    Dump list of available modules\n"
-"      --dump-resample-methods           Dump available resample methods\n"
-"      --cleanup-shm                     Cleanup stale shared memory "
+"   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 "
+"        start                           Start the daemon if it is not "
 "running\n"
-"  -k  --kill                            Kill a running daemon\n"
-"      --check                           Check for a running daemon (only "
+"   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"
+"        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"
+"        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 "
+"        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 "
+"        disallow exit[=BOOL]            Disallow user requested exit\n"
+"        exit idle time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
+"        module idle time=SECS           Unload autoloaded modules when idle "
 "and\n"
 "                                        this time passed\n"
-"      --scache-idle-time=SECS           Unload autoloaded samples when idle "
+"        scache idle time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
-"      --log-level[=LEVEL]               Increase or set verbosity level\n"
-"  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
-"      --log-meta[=BOOL]                 Include code location in log "
+"        log level[=LEVEL]               Increase or set verbosity level\n"
+"   v                                    Increase the verbosity level\n"
+"        log target={auto,syslog,stderr} Specify the log target\n"
+"        log meta[=BOOL]                 Include code location in log "
 "messages\n"
-"      --log-time[=BOOL]                 Include timestamps in log messages\n"
-"      --log-backtrace=FRAMES            Include a backtrace in log messages\n"
-"  -p, --dl-search-path=PATH             Set the search path for dynamic "
+"        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"
+"        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"
+"        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"
+"        disable shm[=BOOL]              Disable shared memory support.\n"
 "\n"
 "STARTUP SCRIPT:\n"
-"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module "
+"   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 "
+"   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"
+"   n                                    Don't load default script file\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
-msgstr "--daemonize দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
+msgstr "  daemonize দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
-msgstr "--fail দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
+msgstr "  fail দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
 msgstr ""
-"--log-level ৰ কাৰণে লগ স্তৰৰ তৰ্ক প্ৰত্যাশিত (হয় সংখ্যা ০..৪ ৰ সীমাত বা debug, "
+"  log level ৰ কাৰণে লগ স্তৰৰ তৰ্ক প্ৰত্যাশিত (হয় সংখ্যা ০..৪ ৰ সীমাত বা debug, "
 "info, notice, warn, error ৰ যিকোনো এটা) ।"
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
-msgstr "--high-priority দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
+msgstr "  high priority দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
-msgstr "--realtime দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
+msgstr "  realtime দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
-msgstr "--disallow-module-loading দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
+msgstr "  disallow module loading দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
-msgstr "--disallow-exit দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
+msgstr "  disallow exit দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
-msgstr "--use-pid-file দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
+msgstr "  use pid file দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr "অবৈধ লগ লক্ষ্য: 'syslog', 'stderr' বা 'auto' ৰ এটা ব্যৱহাৰ কৰক"
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
-msgstr "--log-time দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
+msgstr "  log time দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
-msgstr "--log-meta দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
+msgstr "  log meta দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "resample পদ্ধতি '%s' বৈধ নহয় ।"
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
-msgstr "--system দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
+msgstr "  system দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
-msgstr "--no-cpu-limit দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
+msgstr "  no cpu limit দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
-msgstr "--disable-shm দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
+msgstr "  disable shm দ্বাৰা বুলিয়েন তৰ্ক প্ৰত্যাশিত"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "নাম: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "মডিউল সংক্ৰান্ত কোনো তথ্য উপলব্ধ নাই\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "সংস্কৰণ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "বিৱৰণ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "নিৰ্মাতা: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "ব্যৱহাৰ পদ্ধতি: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "এবাৰ তুলি লোৱা হ'ব: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
-msgstr "à¦\85বà¦\9aিত à¦\95রার à¦¸à¦¤à¦°à§\8dà¦\95বারà§\8dতা: %s\n"
+msgstr "à¦\85বà¦\9aিত à¦\95ৰাৰ à¦¸à¦¤à§°à§\8dà¦\95বাৰà§\8dতা: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "পাথ: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] লগ লক্ষ্য '%s' বৈধ নহয় ।"
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] লগৰ স্তৰ '%s' বৈধ নহয় ।"
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] resample পদ্ধতি '%s' বৈধ নহয় ।"
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] rlimit '%s' বৈধ নহয় ।"
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] এই স্থাপত্যত rlimit সমৰ্থিত নহয় ।"
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] চানেকিৰ বিন্যাস '%s' বৈধ নহয় ।"
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] চানেকিৰ মাত্ৰা '%s' বৈধ নহয় ।"
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] চানেকিৰ চেনেল '%s' বৈধ নহয়"
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] চেনেল মেপ '%s' বৈধ নহয় ।"
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] অংশৰ সংখ্যা '%s' বৈধ নহয় ।"
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] অংশৰ মাপ '%s' বৈধ নহয় ।"
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] nice স্তৰ '%s' বৈধ নহয় ।"
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] চানেকিৰ মাত্ৰা '%s' বৈধ নহয় ।"
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "বিন্যাস নথিপত্ৰ খুলিবলৈ ব্যৰ্থ: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -734,14 +773,14 @@ msgstr ""
 "নিৰ্ধাৰিত অবিকল্পিত চেনেল মেপত নিৰ্ধাৰিত অবিকল্পিত চেনেলৰ সংখ্যাতকে বেলেগ সংখ্যক "
 "চেনেল আছে ।"
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### চিহ্নিত বিন্যাস নথিপত্ৰৰ পৰা পঢ়া হ'ব: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
-msgstr "à¦\85ধিà¦\95ার à¦¬à¦°à§\8dà¦\9cন à¦\95রা à¦¹à¦\9aà§\8dà¦\9bà§\87।"
+msgstr "à¦\85ধিà¦\95াৰ à¦¬à§°à§\8dà¦\9cন à¦\95ৰা à¦¹à¦\9aà§\8dà¦\9bà§\87।"
 
 #: ../src/daemon/pulseaudio.desktop.in.h:1
 msgid "PulseAudio Sound System"
@@ -751,6 +790,16 @@ msgstr "PulseAudio শব্দ ব্যৱস্থা"
 msgid "Start the PulseAudio Sound System"
 msgstr "PulseAudio শব্দ ব্যৱস্থা আৰম্ভ কৰা হ'ব"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio শব্দ ব্যৱস্থা"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "PulseAudio শব্দ ব্যৱস্থা আৰম্ভ কৰা হ'ব"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "মোনো"
@@ -780,16 +829,16 @@ msgid "Rear Right"
 msgstr "পিছত সোঁফালে"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Low Frequency Emmiter"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
-msgstr "সন্মুখত কেন্দ্ৰৰ-বাওঁফালে"
+msgstr "সন্মুখত কেন্দ্ৰৰ বাওঁফালে"
 
 #: ../src/pulse/channelmap.c:118
 msgid "Front Right-of-center"
-msgstr "সন্মুখত কেন্দ্ৰৰ-সোঁফালে"
+msgstr "সন্মুখত কেন্দ্ৰৰ সোঁফালে"
 
 #: ../src/pulse/channelmap.c:120
 msgid "Side Left"
@@ -955,15 +1004,16 @@ msgstr "ওপৰত পিছত বাওঁফালে"
 msgid "Top Rear Right"
 msgstr "ওপৰত পিছত সোঁফালে"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(অবৈধ)"
 
 #: ../src/pulse/channelmap.c:761
 msgid "Stereo"
-msgstr "সà§\8dà¦\9fিৰিà¦\93"
+msgstr "সà§\8dà¦\9fিৰিà¦\85'"
 
 #: ../src/pulse/channelmap.c:766
 msgid "Surround 4.0"
@@ -985,332 +1035,349 @@ msgstr "ছাৰাউণ্ড ৫.১"
 msgid "Surround 7.1"
 msgstr "ছাৰাউণ্ড ৭.১"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "ঠিক আছে"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "ব্যৱহাৰৰ অধিকাৰ প্ৰত্যাখ্যাত"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "অজ্ঞাত নিৰ্দেশ"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "অবৈধ তৰ্ক"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "পদাৰ্থ উপস্থিত"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "এই ধৰনৰ কোনো পদাৰ্থ উপস্থিত নাই"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "সংযোগ নাকচ কৰা হৈছে"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "প্ৰোটোকল সংক্ৰান্ত ত্ৰুটি"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "সময়সীমা"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
-msgstr "কোনো অনুমোদনৰ-কি নাই"
+msgstr "কোনো অনুমোদনৰ কি নাই"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "অভ্যন্তৰীণ ত্ৰুটি"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "সংযোগ বন্ধ কৰা হৈছে"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "পদাৰ্থ kill কৰা হৈছে"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "সেৱক বৈধ নহয়"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "মডিউল আৰম্ভ কৰিবলৈ ব্যৰ্থ"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "অৱস্থা সঠিক নহয়"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "তথ্য অনুপস্থিত "
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "বিসঙ্গতিপূৰ্ণ প্ৰটকল সংস্কৰণ"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "অত্যাধিক বড়"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "সমৰ্থন কৰা নহয়"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "অজানা ত্ৰুটিৰ কোড"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "এই ধৰনৰ কোনো এক্সটেনশন নাই"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "অবচিত বৈশিষ্ট্য"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "অনুপস্থিত বাস্তবায়ন"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "গ্ৰাহক ফৰ্ক কৰা হৈছে"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
-msgstr ""
+msgstr "নিবেশ/নিৰ্গম ত্ৰুটি"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
-msgstr ""
+msgstr "যন্ত্ৰ বা সম্পদ ব্যস্ত"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() ব্যৰ্থ"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() ব্যৰ্থ: %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "কুকিৰ তথ্য বিশ্লেষণ কৰিবলৈ ব্যৰ্থ"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "বিন্যাস নথিপত্ৰ '%s' খুলিবলৈ ব্যৰ্থ: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "কোনো কুকি তুলি লোৱা নহয় । কুকি নোহোৱাকে সংযোগৰ প্ৰচেষ্টা কৰা হৈছে ।"
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
-msgstr "অজানা এক্সটেনশন '%s'-ৰ বাবে বাৰ্তা প্ৰাপ্ত হৈছে"
+msgstr "অজানা এক্সটেনশন '%s' ৰ বাবে বাৰ্তা প্ৰাপ্ত হৈছে"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
-msgstr "সà§\8dà¦\9fà§\8dরিম à¦¡à§\8dরà§\87à¦\87ন (à¦\85রà§\8dথাà§\8e à¦«à¦¾à¦\81à¦\95া) à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "সà§\8dà¦\9fà§\8dৰিম à¦¡à§\8dৰà§\87à¦\87ন (à¦\85ৰà§\8dথাà§\8e à¦«à¦¾à¦\81à¦\95া) à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
-msgstr "প্লে-বà§\8dযাà¦\95 à¦¸à§\8dà¦\9fà§\8dরিম à¦«à¦¾à¦\81à¦\95া à¦\95রা à¦¹à§\9fà§\87à¦\9bà§\87।"
+msgstr "প্লে à¦¬à§\8dযাà¦\95 à¦¸à§\8dà¦\9fà§\8dৰিম à¦«à¦¾à¦\81à¦\95া à¦\95ৰা à¦¹à§\9fà§\87à¦\9bà§\87।"
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
-msgstr "সারà§\8dভারà§\87র à¦¸à¦¾à¦¥à§\87 à¦¸à§\8dথাপিত à¦¸à¦\82যà§\8bà¦\97 à¦«à¦¾à¦\81à¦\95া à¦\95রা à¦¹à¦\9aà§\8dà¦\9bà§\87।"
+msgstr "সাৰà§\8dভাৰà§\87ৰ à¦¸à¦¾à¦¥à§\87 à¦¸à§\8dথাপিত à¦¸à¦\82যà§\8bà¦\97 à¦«à¦¾à¦\81à¦\95া à¦\95ৰা à¦¹à¦\9aà§\8dà¦\9bà§\87।"
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
-msgstr "pa_stream_write() à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "pa_stream_write() à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
-msgstr "pa_stream_write() à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "pa_stream_write() à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
-msgstr "pa_stream_peek() à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "pa_stream_peek() à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
-msgstr "সাফলà§\8dযà§\87র à¦¸à¦¾à¦¥à§\87 à¦¸à§\8dà¦\9fà§\8dরিম à¦¨à¦¿à¦°à§\8dমিত à¦¹à§\9fà§\87à¦\9bà§\87।"
+msgstr "সাফলà§\8dযà§\87ৰ à¦¸à¦¾à¦¥à§\87 à¦¸à§\8dà¦\9fà§\8dৰিম à¦¨à¦¿à§°à§\8dমিত à¦¹à§\9fà§\87à¦\9bà§\87।"
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
-msgstr "pa_stream_get_buffer_attr() à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "pa_stream_get_buffer_attr() à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
-msgstr "বাফারà§\87র à¦®à¦¾à¦ª: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
+msgstr "বাফাৰà§\87ৰ à¦®à¦¾à¦ª: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
-msgstr "বাফারà§\87র à¦®à¦¾à¦ª: maxlength=%u, fragsize=%u"
+msgstr "বাফাৰà§\87ৰ à¦®à¦¾à¦ª: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
-msgstr "সà§\8dযামà§\8dপà§\87লà§\87র spec '%s', à¦\93 à¦\9aà§\8dযানà§\87ল à¦®à§\8dযাপ '%s' à¦¬à§\8dযবহার à¦\95রা à¦¹à¦\9aà§\8dà¦\9bà§\87।"
+msgstr "সà§\8dযামà§\8dপà§\87লà§\87ৰ spec '%s', à¦\93 à¦\9aà§\8dযানà§\87ল à¦®à§\8dযাপ '%s' à¦¬à§\8dযৱহাৰ à¦\95ৰা à¦¹à¦\9aà§\8dà¦\9bà§\87।"
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
-msgstr "ডিভাà¦\87স %s-র à¦¸à¦¾à¦¥à§\87 à¦¸à¦\82যà§\8bà¦\97 à¦\95রা à¦¹à§\9fà§\87à¦\9bà§\87 (%u, %ssuspended)।"
+msgstr "যনà§\8dতà§\8dৰ %s à§° à¦¸à¦¾à¦¥à§\87 à¦¸à¦\82যà§\8bà¦\97 à¦\95ৰা à¦¹à§\9fà§\87à¦\9bà§\87 (%u, %ssuspended)।"
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
-msgstr "ষà§\8dà¦\9fà§\8dরিম à¦¸à¦\82à¦\95à§\8dরানà§\8dত à¦¤à§\8dরà§\81à¦\9fি: %s"
+msgstr "ষà§\8dà¦\9fà§\8dৰিম à¦¸à¦\82à¦\95à§\8dৰানà§\8dত à¦¤à§\8dৰà§\81à¦\9fি: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
-msgstr "সà§\8dà¦\9fà§\8dরিম à¦¡à¦¿à¦­à¦¾à¦\87স à¦¸à§\8dথà¦\97িত à¦\95রা à¦¹à§\9fà§\87à¦\9bà§\87। %s"
+msgstr "সà§\8dà¦\9fà§\8dৰিম à¦¯à¦¨à§\8dতà§\8dৰ à¦¸à§\8dথà¦\97িত à¦\95ৰা à¦¹à§\9fà§\87à¦\9bà§\87। %s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
-msgstr "সà§\8dà¦\9fà§\8dরিম à¦¡à¦¿à¦­à¦¾à¦\87স à¦ªà§\81নরারমà§\8dভ à¦\95রা à¦¹à§\9fà§\87à¦\9bà§\87। %s"
+msgstr "সà§\8dà¦\9fà§\8dৰিম à¦¯à¦¨à§\8dতà§\8dৰ à¦ªà§\81নৰাৰমà§\8dভ à¦\95ৰা à¦¹à§\9fà§\87à¦\9bà§\87। %s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
-msgstr "ধà§\80র à¦\97তির à¦¸à§\8dà¦\9fà§\8dরিম.%s"
+msgstr "ধà§\80ৰ à¦\97তিৰ à¦¸à§\8dà¦\9fà§\8dৰিম.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
-msgstr "সà§\8dà¦\9fà§\8dরিম à¦®à¦¾à¦¤à§\8dরা à¦\85তিà¦\95à§\8dরম à¦\95রà§\87ছে।%s"
+msgstr "সà§\8dà¦\9fà§\8dৰিম à¦®à¦¾à¦¤à§\8dৰা à¦\85তিà¦\95à§\8dৰম à¦\95ৰিছে।%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
-msgstr "সà§\8dà¦\9fà§\8dরিম à¦\86রমà§\8dভ à¦\95রা à¦¹à§\9fà§\87à¦\9bà§\87। %s"
+msgstr "সà§\8dà¦\9fà§\8dৰিম à¦\86ৰমà§\8dভ à¦\95ৰা à¦¹à§\9fà§\87à¦\9bà§\87। %s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
-msgstr "%s à¦¡à¦¿à¦­à¦¾à¦\87সà§\87 à¦¸à§\8dà¦\9fà§\8dরিম à¦¸à§\8dথানানà§\8dতর à¦\95রা à¦¹à§\9fà§\87à¦\9bà§\87 (%u, %ssuspended)।%s"
+msgstr "%s à¦¯à¦¨à§\8dতà§\8dৰà§\87 à¦¸à§\8dà¦\9fà§\8dৰিম à¦¸à§\8dথানানà§\8dতৰ à¦\95ৰা à¦¹à§\9fà§\87à¦\9bà§\87 (%u, %ssuspended)।%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "not "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
-msgstr "স্ট্রিম বাফারের অ্যাট্রিবিউট পরিবর্তিত হয়েছে। %s"
+msgstr "স্ট্ৰিম বাফাৰেৰ এট্ৰিবিউট পৰিবৰ্তিত হয়েছে। %s"
+
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "সংযোগ স্থাপিত হয়েছে।%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
-msgstr "pa_stream_new() à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "pa_stream_new() à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
-msgstr "pa_stream_connect_playback() à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "pa_stream_connect_playback() à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
-msgstr "pa_stream_connect_record() à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "pa_stream_connect_record() à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "সংযোগ বিফল: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
-msgstr "ফাà¦\87লà§\87র à¦¸à¦®à¦¾à¦ªà§\8dতি à¦¸à¦¨à¦¾à¦\95à§\8dত à¦¹à§\9fà§\87à¦\9bà§\87।"
+msgstr "ফাà¦\87লà§\87ৰ à¦¸à¦®à¦¾à¦ªà§\8dতি à¦¸à¦¨à¦¾à¦\95à§\8dত à¦¹à§\9fà§\87à¦\9bà§\87।"
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
-msgstr "write() à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "write() à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
-msgstr "সিà¦\97নà§\8dযাল à¦ªà§\8dরাপà§\8dত à¦¹à§\9fà§\87à¦\9bà§\87, à¦ªà§\8dরসà§\8dথান à¦\95রা à¦¹à¦¬à§\87।"
+msgstr "সিà¦\97নà§\8dযাল à¦ªà§\8dৰাপà§\8dত à¦¹à§\9fà§\87à¦\9bà§\87, à¦ªà§\8dৰসà§\8dথান à¦\95ৰা à¦¹'ব।"
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
-msgstr "লà§\87à¦\9fà§\87নà§\8dসির à¦ªà¦°à¦¿à¦®à¦¾à¦£ à¦ªà§\8dরাপà§\8dত à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "লà§\87à¦\9fà§\87নà§\8dসিৰ à¦ªà§°à¦¿à¦®à¦¾à¦£ à¦ªà§\8dৰাপà§\8dত à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pacat.c:580
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:622
+#, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
-msgstr "সময়: %0.3f sec; Latency: %0.0f usec.  \r"
+msgstr "সময়: %0.3f ছেকেণ্ড; লেটেন্সি: %0.0f usec ।"
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
-msgstr "pa_stream_update_timing_info() à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "pa_stream_update_timing_info() à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1362,69 +1429,74 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [options]\n"
 "\n"
-"  -h, --help                            Show this help\n"
-"      --version                         Show version\n"
+"   h,   help                            Show this help\n"
+"        version                         Show version\n"
 "\n"
-"  -r, --record                          Create a connection for recording\n"
-"  -p, --playback                        Create a connection for playback\n"
+"   r,   record                          Create a connection for recording\n"
+"   p,   playback                        Create a connection for playback\n"
 "\n"
-"  -v, --verbose                         Enable verbose operations\n"
+"   v,   verbose                         Enable verbose operations\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect "
+"   s,   server=SERVER                   The name of the server to connect "
 "to\n"
-"  -d, --device=DEVICE                   The name of the sink/source to "
+"   d,   device=DEVICE                   The name of the sink/source to "
 "connect to\n"
-"  -n, --client-name=NAME                How to call this client on the "
+"   n,   client name=NAME                How to call this client on the "
 "server\n"
-"      --stream-name=NAME                How to call this stream on the "
+"        stream name=NAME                How to call this stream on the "
 "server\n"
-"      --volume=VOLUME                   Specify the initial (linear) volume "
+"        volume=VOLUME                   Specify the initial (linear) volume "
 "in range 0...65536\n"
-"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to "
+"        rate=SAMPLERATE                 The sample rate in Hz (defaults to "
 "44100)\n"
-"      --format=SAMPLEFORMAT             The sample type, one of s16le, "
+"        format=SAMPLEFORMAT             The sample type, one of s16le, "
 "s16be, u8, float32le,\n"
 "                                        float32be, ulaw, alaw, s32le, s32be, "
 "s24le, s24be,\n"
-"                                        s24-32le, s24-32be (defaults to "
+"                                        s24 32le, s24 32be (defaults to "
 "s16ne)\n"
-"      --channels=CHANNELS               The number of channels, 1 for mono, "
+"        channels=CHANNELS               The number of channels, 1 for mono, "
 "2 for stereo\n"
 "                                        (defaults to 2)\n"
-"      --channel-map=CHANNELMAP          Channel map to use instead of the "
+"        channel map=CHANNELMAP          Channel map to use instead of the "
 "default\n"
-"      --fix-format                      Take the sample format from the sink "
+"        fix format                      Take the sample format from the sink "
 "the stream is\n"
 "                                        being connected to.\n"
-"      --fix-rate                        Take the sampling rate from the sink "
+"        fix rate                        Take the sampling rate from the sink "
 "the stream is\n"
 "                                        being connected to.\n"
-"      --fix-channels                    Take the number of channels and the "
+"        fix channels                    Take the number of channels and the "
 "channel map\n"
 "                                        from the sink the stream is being "
 "connected to.\n"
-"      --no-remix                        Don't upmix or downmix channels.\n"
-"      --no-remap                        Map channels by index instead of "
+"        no remix                        Don't upmix or downmix channels.\n"
+"        no remap                        Map channels by index instead of "
 "name.\n"
-"      --latency=BYTES                   Request the specified latency in "
+"        latency=BYTES                   Request the specified latency in "
 "bytes.\n"
-"      --process-time=BYTES              Request the specified process time "
+"        process time=BYTES              Request the specified process time "
 "per request in bytes.\n"
-"      --property=PROPERTY=VALUE         Set the specified property to the "
+"        property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
-"      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
-"      --list-file-formats               List available file formats.\n"
+"        raw                             Record/play raw PCM data.\n"
+"        file format=FFORMAT             Record/play formatted PCM data.\n"
+"        list file formats               List available file formats.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1435,173 +1507,178 @@ msgstr ""
 "libpulse ৰ সৈতে সঙ্কলন কৰা হৈছে %s\n"
 "libpulse ৰ সৈতে যুক্ত %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
-msgstr "à¦\95à§\8dলাà§\9fà§\87নà§\8dà¦\9fà§\87র à¦¨à¦¾à¦® '%s' à¦¬à§\88ধ à¦¨à§\9f"
+msgstr "à¦\95à§\8dলাà§\9fà§\87নà§\8dà¦\9fà§\87ৰ à¦¨à¦¾à¦® '%s' à¦¬à§\88ধ à¦¨à§\9f"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
-msgstr "সà§\8dà¦\9fà§\8dরিমà§\87র à¦¨à¦¾à¦® '%s' à¦¬à§\88ধ à¦¨à§\9f।"
+msgstr "সà§\8dà¦\9fà§\8dৰিমà§\87ৰ à¦¨à¦¾à¦® '%s' à¦¬à§\88ধ à¦¨à§\9f।"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "চ্যানেল ম্যাপ '%s' বৈধ নয়"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
-msgstr "লà§\87à¦\9fà§\87নà§\8dসির à¦\9cনà§\8dয à¦¨à¦¿à¦°à§\8dধারিত à¦¬à§\88শিষà§\8dà¦\9fà§\8dয '%s' à¦¬à§\88ধ à¦¨à§\9f"
+msgstr "লà§\87à¦\9fà§\87নà§\8dসিৰ à¦\9cনà§\8dয à¦¨à¦¿à§°à§\8dধাৰিত à¦¬à§\88শিষà§\8dà¦\9fà§\8dয '%s' à¦¬à§\88ধ à¦¨à§\9f"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
-msgstr "পà§\8dরসà§\87সà§\87র à¦¸à¦®à§\9fà§\87র à¦¬à§\88শিষà§\8dà¦\9fà§\8dয '%s' à¦¬à§\88ধ à¦¨à§\9f"
+msgstr "পà§\8dৰসà§\87সà§\87ৰ à¦¸à¦®à§\9fà§\87ৰ à¦¬à§\88শিষà§\8dà¦\9fà§\8dয '%s' à¦¬à§\88ধ à¦¨à§\9f"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "বৈশিষ্ট্য '%s' বৈধ নয়।"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
-msgstr "ফাà¦\87লà§\87র à¦\85à¦\9cানা à¦¬à¦¿à¦¨à§\8dযাস %s।"
+msgstr "ফাà¦\87লà§\87ৰ à¦\85à¦\9cানা à¦¬à¦¿à¦¨à§\8dযাস %s।"
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
-msgstr "à¦\85বà§\88ধ à¦¸à§\8dযামà§\8dপà§\87ল à¦¨à¦¿à¦°à§\8dধারিত"
+msgstr "à¦\85বà§\88ধ à¦¸à§\8dযামà§\8dপà§\87ল à¦¨à¦¿à§°à§\8dধাৰিত"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
-msgstr "à¦\85তà§\8dযাধিà¦\95 à¦\86রà§\8dà¦\97à§\81মà§\87নà§\8dà¦\9f।"
+msgstr "à¦\85তà§\8dযাধিà¦\95 à¦\86ৰà§\8dà¦\97à§\81মà§\87নà§\8dà¦\9f।"
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
-msgstr "সà§\8dযামà§\8dপà§\87লà§\87র à¦®à¦¾à¦¨ à¦¨à¦¿à¦°à§\8dধারণà§\87র à¦«à¦¾à¦\87ল à¦¨à¦¿à¦°à§\8dমাণ à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ"
+msgstr "সà§\8dযামà§\8dপà§\87লà§\87ৰ à¦®à¦¾à¦¨ à¦¨à¦¿à§°à§\8dধাৰণà§\87ৰ à¦«à¦¾à¦\87ল à¦¨à¦¿à§°à§\8dমাণ à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ"
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
-msgstr "শবà§\8dদà§\87র à¦«à¦¾à¦\87ল à¦\96à§\81লতà§\87 à¦¬à§\8dযরà§\8dথ।"
+msgstr "শবà§\8dদà§\87ৰ à¦«à¦¾à¦\87ল à¦\96à§\81লতà§\87 à¦¬à§\8dযৰà§\8dথ।"
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
 msgstr ""
-"সতরà§\8dà¦\95বারà§\8dতা: à¦\9aিহà§\8dনিত à¦¸à§\8dযামà§\8dপà§\87ল à¦¨à¦¿à¦°à§\8dধারণà§\87র à¦«à¦¾à¦\87লà¦\9fির à¦¤à¦¥à§\8dয, à¦\8fà¦\87 à¦«à¦¾à¦\87লà§\87র à¦¥à§\87à¦\95à§\87 উপলব্ধ তথ্য "
-"দà§\8dবারা à¦ªà§\8dরতিসà§\8dথাপিত à¦¹à¦¬à§\87।"
+"সতৰà§\8dà¦\95বাৰà§\8dতা: à¦\9aিহà§\8dনিত à¦¸à§\8dযামà§\8dপà§\87ল à¦¨à¦¿à§°à§\8dধাৰণà§\87ৰ à¦«à¦¾à¦\87লà¦\9fিৰ à¦¤à¦¥à§\8dয, à¦\8fà¦\87 à¦«à¦¾à¦\87লà§\87ৰৰ à¦ªà§°à¦¾ উপলব্ধ তথ্য "
+"দà§\8dবাৰা à¦ªà§\8dৰতিসà§\8dথাপিত à¦¹'ব।"
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
-msgstr "ফাইল à¦¥à§\87à¦\95à§\87 à¦¸à§\8dযামà§\8dপà§\87ল à¦¸à¦\82à¦\95à§\8dরানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dরাপà§\8dত à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ।"
+msgstr "ফাইলৰ à¦ªà§°à¦¾ à¦¸à§\8dযামà§\8dপà§\87ল à¦¸à¦\82à¦\95à§\8dৰানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dৰাপà§\8dত à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ।"
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
-msgstr "সতরà§\8dà¦\95বারà§\8dতা: à¦«à¦¾à¦\87ল à¦¥à§\87à¦\95à§\87 à¦\9aà§\8dযানà§\87লà§\87র à¦®à§\8dযাপ à¦¨à¦¿à¦°à§\8dধারণ à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ।"
+msgstr "সতৰà§\8dà¦\95বাৰà§\8dতা: à¦«à¦¾à¦\87লৰ à¦ªà§°à¦¾ à¦\9aà§\8dযানà§\87লà§\87ৰ à¦®à§\8dযাপ à¦¨à¦¿à§°à§\8dধাৰণ à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ।"
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
-msgstr "à¦\9aà§\8dযানà§\87লà§\87র à¦®à§\8dযাপ à¦\93 à¦¸à§\8dযামà§\8dপà§\87লà§\87র à¦¨à¦¿à¦°à§\8dধারিত à¦®à¦¾à¦¨à§\87 à¦\97রমিল"
+msgstr "à¦\9aà§\8dযানà§\87লà§\87ৰ à¦®à§\8dযাপ à¦\93 à¦¸à§\8dযামà§\8dপà§\87লà§\87ৰ à¦¨à¦¿à§°à§\8dধাৰিত à¦®à¦¾à¦¨à§\87 à¦\97ৰমিল"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
-msgstr "সতরà§\8dà¦\95বারà§\8dতা: à¦«à¦¾à¦\87লà§\87র à¦®à¦§à§\8dযà§\87 à¦\9aà§\8dযানà§\87লà§\87র à¦®à§\8dযাপ à¦²à¦¿à¦\96তà§\87 à¦¬à§\8dযরà§\8dথ।"
+msgstr "সতৰà§\8dà¦\95বাৰà§\8dতা: à¦«à¦¾à¦\87লà§\87ত à¦\9aà§\8dযানà§\87লà§\87ৰ à¦®à§\8dযাপ à¦²à¦¿à¦\96তà§\87 à¦¬à§\8dযৰà§\8dথ।"
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr ""
-"à¦\8fà¦\95à¦\9fি %s à¦¸à§\8dà¦\9fà§\8dরিম à¦\96à§\8bলা à¦¹à¦\9aà§\8dà¦\9bà§\87। à¦\8fà¦\9fির à¦\9cনà§\8dয '%s'-র à¦¸à§\8dযামà§\8dপà§\87লà§\87র à¦¨à¦¿à¦°à§\8dধারিত à¦®à¦¾à¦¨ à¦\93 '%s' "
-"à¦\9aà§\8dযানà§\87লà§\87র à¦®à§\8dযাপ à¦ªà§\8dরà§\9fà§\8bà¦\97 à¦\95রা à¦¹à¦¬à§\87।"
+"à¦\8fà¦\9fা %s à¦¸à§\8dà¦\9fà§\8dৰিম à¦\96à§\8bলা à¦¹à¦\9aà§\8dà¦\9bà§\87। à¦\8fà¦\9fিৰ à¦\9cনà§\8dয '%s' à§° à¦¸à§\8dযামà§\8dপà§\87লà§\87ৰ à¦¨à¦¿à§°à§\8dধাৰিত à¦®à¦¾à¦¨ à¦\93 '%s' "
+"à¦\9aà§\8dযানà§\87লà§\87ৰ à¦®à§\8dযাপ à¦ªà§\8dৰà§\9fà§\8bà¦\97 à¦\95ৰা à¦¹'ব।"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "ৰেকৰ্ড কৰা হৈছে"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
-msgstr "প্লে-বেক"
+msgstr "প্লে বেক"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "আদেশ শাৰী বিশ্লেষণ কৰিবলৈ বিফল ।"
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
-msgstr "pa_mainloop_new() à¦¬à§\8dযরà§\8dথ।"
+msgstr "pa_mainloop_new() à¦¬à§\8dযৰà§\8dথ।"
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
-msgstr "io_new() à¦¬à§\8dযরà§\8dথ।"
+msgstr "io_new() à¦¬à§\8dযৰà§\8dথ।"
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
-msgstr "pa_context_new() à¦¬à§\8dযরà§\8dথ।"
+msgstr "pa_context_new() à¦¬à§\8dযৰà§\8dথ।"
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() ব্যৰ্থ: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
-msgstr "pa_context_rttime_new() à¦¬à§\8dযরà§\8dথ।"
+msgstr "pa_context_rttime_new() à¦¬à§\8dযৰà§\8dথ।"
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
-msgstr "pa_mainloop_run() à¦¬à§\8dযরà§\8dথ।"
+msgstr "pa_mainloop_run() à¦¬à§\8dযৰà§\8dথ।"
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "স্থগিত কৰিবলৈ ব্যৰ্থ: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "পুনৰাৰম্ভ কৰিবলৈ ব্যৰ্থ: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "সতৰ্কবাৰ্তা: ধ্বনি সেৱক স্থানীয় নহয়, স্থগিত কৰা নহয় ।\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "<b>সংযোগৰ মোড</b>: %s<br>\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "SIGINT প্ৰাপ্ত হৈছে, প্ৰস্থান কৰা হৈছে ।\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "সতৰ্কবাৰ্তা: চিগ্নেল %u দ্বাৰা চাইল্ড প্ৰক্ৰিয়া বন্ধ কৰা হৈছে\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1614,9 +1691,9 @@ msgid ""
 msgstr ""
 "%s [options] ... \n"
 "\n"
-"  -h, --help                            Show this help\n"
-"      --version                         Show version\n"
-"  -s, --server=SERVER                   The name of the server to connect "
+"   h,   help                            Show this help\n"
+"        version                         Show version\n"
+"   s,   server=SERVER                   The name of the server to connect "
 "to\n"
 "\n"
 
@@ -1646,35 +1723,46 @@ msgstr "pa_context_new() ব্যৰ্থ ।\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() ব্যৰ্থ ।\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
-msgstr "পরিসà¦\82à¦\96à§\8dযান à¦ªà§\8dরাপà§\8dত à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "পৰিসà¦\82à¦\96à§\8dযান à¦ªà§\8dৰাপà§\8dত à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "বৰ্ত্তমানে ব্যৱহৃত: %u blocks containing %s bytes total.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "সম্পূৰ্ণ জীৱনকালত বিতৰণ কৰা: %u blocks containing %s bytes total.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "চানেকি কেশ্বৰ মাপ: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
-msgstr "সারà§\8dভার à¦¸à¦\82à¦\95à§\8dরানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dরাপà§\8dত à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "সাৰà§\8dভাৰ à¦¸à¦\82à¦\95à§\8dৰানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dৰাপà§\8dত à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1682,7 +1770,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "ব্যৱহাৰকৰ্তাৰ নাম: %s\n"
 "গৃহস্থৰ নাম: %s\n"
@@ -1694,13 +1782,13 @@ msgstr ""
 "অবিকল্পিত উৎস: %s\n"
 "কুকি: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
-msgstr "sink à¦¸à¦\82à¦\95à§\8dরানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dরাপà§\8dত à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "sink à¦¸à¦\82à¦\95à§\8dৰানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dৰাপà§\8dত à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1716,7 +1804,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1738,22 +1826,27 @@ msgstr ""
 "\tগুণ:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
-msgstr "\tপà§\8bরà§\8dà¦\9f:\n"
+msgstr "\tপà§\8bৰà§\8dà¦\9f:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
-msgstr "\tসà¦\95à§\8dরিà§\9f à¦ªà§\8bরà§\8dà¦\9f: %s\n"
+msgstr "\tসà¦\95à§\8dৰিà§\9f à¦ªà§\8bৰà§\8dà¦\9f: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tপোৰ্ট:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
-msgstr "à¦\89à§\8eস à¦¸à¦\82à¦\95à§\8dরানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dরাপà§\8dত à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "à¦\89à§\8eস à¦¸à¦\82à¦\95à§\8dৰানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dৰাপà§\8dত à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1792,20 +1885,20 @@ msgstr ""
 "\tগুণ:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "n/a"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
-msgstr "মডিà¦\89ল à¦¸à¦\82à¦\95à§\8dরানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dরাপà§\8dত à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "মডিà¦\89ল à¦¸à¦\82à¦\95à§\8dৰানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dৰাপà§\8dত à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1822,12 +1915,12 @@ msgstr ""
 "\tগুণ:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
-msgstr "à¦\95à§\8dলাà§\9fà§\87নà§\8dà¦\9f à¦¸à¦\82à¦\95à§\8dরানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dরাপà§\8dত à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "à¦\95à§\8dলাà§\9fà§\87নà§\8dà¦\9f à¦¸à¦\82à¦\95à§\8dৰানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dৰাপà§\8dত à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1842,12 +1935,12 @@ msgstr ""
 "\tগুণ:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
-msgstr "à¦\95ারà§\8dড à¦¸à¦\82à¦\95à§\8dরানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dরাপà§\8dত à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "à¦\95াৰà§\8dড à¦¸à¦\82à¦\95à§\8dৰানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dৰাপà§\8dত à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1864,23 +1957,23 @@ msgstr ""
 "\tগুণ:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tপাৰ্শ্বৰূপ:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tসক্ৰিয় পাৰ্শ্বৰূপ: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
-msgstr "sink à¦\87নপà§\81à¦\9f à¦¸à¦\82à¦\95à§\8dরানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dরাপà§\8dত à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "sink à¦¨à¦¿à¦¬à§\87শ à¦¸à¦\82à¦\95à§\8dৰানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dৰাপà§\8dত à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1889,6 +1982,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1916,13 +2010,13 @@ msgstr ""
 "\tগুণ:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
-msgstr "à¦\89à§\8eস à¦\86à¦\89à¦\9fপà§\81à¦\9f à¦¸à¦\82à¦\95à§\8dরানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dরাপà§\8dত à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "à¦\89à§\8eস à¦¨à¦¿à§°à§\8dà¦\97ম à¦¸à¦\82à¦\95à§\8dৰানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dৰাপà§\8dত à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1931,31 +2025,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"à¦\89à§\8eসৰ à¦¨à¦¿à§°à§\8dà¦\97ম #%u\n"
+"à¦\9aিà¦\99à§\8dà¦\95 à¦¨à¦¿à¦¬à§\87শ #%u\n"
 "\tচালক: %s\n"
 "\tগৰাকীৰ অংশ: %s\n"
 "\tগ্ৰাহক: %s\n"
-"\tà¦\89à§\8eস: %u\n"
+"\tà¦\9aিà¦\99à§\8dà¦\95: %u\n"
 "\tচানেকি নিৰ্ধাৰণ: %s\n"
 "\tচেনেল মেপ: %s\n"
+"\tমিউট: %s\n"
+"\tধ্বনি মাত্ৰা: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
-"\tSource Latency: %0.0f usec\n"
+"\tSink Latency: %0.0f usec\n"
 "\tResample ধৰণ: %s\n"
 "\tগুণ:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
-msgstr "সà§\8dযামà§\8dপà§\87ল à¦¸à¦\82à¦\95à§\8dরানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dরাপà§\8dত à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "সà§\8dযামà§\8dপà§\87ল à¦¸à¦\82à¦\95à§\8dৰানà§\8dত à¦¤à¦¥à§\8dয à¦ªà§\8dৰাপà§\8dত à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1986,48 +2089,163 @@ msgstr ""
 "\tগুণ:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
-msgstr "ব্যর্থতা: %s"
+msgstr "ব্যৰ্থতা: %s"
+
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "উৎস সংক্ৰান্ত তথ্য প্ৰাপ্ত কৰতে ব্যৰ্থ: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
-msgstr "সà§\8dযামà§\8dপà§\87ল à¦\86পলà§\8bড à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ: %s"
+msgstr "সà§\8dযামà§\8dপà§\87ল à¦\86পলà§\8bড à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
-msgstr "সমà§\8dপà§\82রà§\8dণ à¦¹à¦\93à§\9fার à¦ªà§\82রà§\8dবà§\87 à¦«à¦¾à¦\87ল à¦¸à¦®à¦¾à¦ªà§\8dত à¦¹à§\9fà§\87à¦\9bà§\87"
+msgstr "সমà§\8dপà§\82ৰà§\8dণ à¦¹à¦\93à§\9fাৰ à¦ªà§\82ৰà§\8dবà§\87 à¦«à¦¾à¦\87ল à¦¸à¦®à¦¾à¦ªà§\8dত à¦¹à§\9fà§\87à¦\9bà§\87"
 
-#: ../src/utils/pactl.c:863
-msgid "Got SIGINT, exiting."
-msgstr "SIGINT প্রাপ্ত হয়েছে, প্রস্থান করা হয়েছে।"
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
 
-#: ../src/utils/pactl.c:869
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "সেৱক বৈধ নহয়"
+
+#: ../src/utils/pactl.c:1041
 #, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
+msgid "Got SIGINT, exiting."
+msgstr "SIGINT প্ৰাপ্ত হয়েছে, প্ৰস্থান কৰা হয়েছে।"
+
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "অবৈধ শব্দেৰ মাত্ৰা নিৰ্ধাৰিত"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2037,37 +2255,15 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
-"\n"
-"  -h, --help                            Show this help\n"
-"      --version                         Show version\n"
+"%s [options] ... \n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect "
+"   h,   help                            Show this help\n"
+"        version                         Show version\n"
+"   s,   server=SERVER                   The name of the server to connect "
 "to\n"
-"  -n, --client-name=NAME                How to call this client on the "
-"server\n"
+"\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2076,108 +2272,140 @@ msgid ""
 msgstr ""
 "pactl %s\n"
 "libpulseৰ সৈতে সঙ্কলন কৰা %s\n"
-"libpulse-ৰ সৈতে যুক্ত %s\n"
+"libpulse ৰ সৈতে যুক্ত %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
-msgstr "লà§\8bড à¦\95রার à¦\89দà§\8dদà§\87শà§\8dযà§\87 à¦\85নà§\81à¦\97à§\8dরহ à¦\95রà§\87 à¦\8fà¦\95à¦\9fি à¦¸à§\8dযামà§\8dপà§\87ল à¦«à¦¾à¦\87ল à¦\89লà§\8dলà§\87à¦\96 à¦\95রà§\81ন"
+msgstr "লà§\8bড à¦\95ৰাৰ à¦\89দà§\8dদà§\87শà§\8dযà§\87 à¦\85নà§\81à¦\97à§\8dৰহ à¦\95ৰি à¦\8fà¦\9fা à¦¸à§\8dযামà§\8dপà§\87ল à¦«à¦¾à¦\87ল à¦\89লà§\8dলà§\87à¦\96 à¦\95ৰà§\81ন"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
-msgstr "শবà§\8dদà§\87র à¦«à¦¾à¦\87ল à¦\96à§\81লতà§\87 à¦¬à§\8dযরà§\8dথ।"
+msgstr "শবà§\8dদà§\87ৰ à¦«à¦¾à¦\87ল à¦\96à§\81লতà§\87 à¦¬à§\8dযৰà§\8dথ।"
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
-msgstr "সতরà§\8dà¦\95বারà§\8dতা: à¦«à¦¾à¦\87ল à¦¥à§\87à¦\95à§\87 à¦¸à§\8dযামà§\8dপà§\87লà§\87র à¦¨à¦¿à¦°à§\8dধারিত à¦®à¦¾à¦ª à¦¨à¦¿à¦°à§\8dমাণ à¦\95রতà§\87 à¦¬à§\8dযরà§\8dথ।"
+msgstr "সতৰà§\8dà¦\95বাৰà§\8dতা: à¦«à¦¾à¦\87লৰ à¦ªà§°à¦¾ à¦¸à§\8dযামà§\8dপà§\87লà§\87ৰ à¦¨à¦¿à§°à§\8dধাৰিত à¦®à¦¾à¦ª à¦¨à¦¿à§°à§\8dমাণ à¦\95ৰতà§\87 à¦¬à§\8dযৰà§\8dথ।"
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
-msgstr "বাà¦\9cানà§\8bর à¦\89দà§\8dদà§\87শà§\8dযà§\87 à¦\8fà¦\95à¦\9fি à¦¸à§\8dযামà§\8dপà§\87ল à¦«à¦¾à¦\87ল à¦\89লà§\8dলà§\87à¦\96 à¦\95রা à¦\86বশà§\8dযà¦\95"
+msgstr "বাà¦\9cানà§\8bৰ à¦\89দà§\8dদà§\87শà§\8dযà§\87 à¦\8fà¦\9fা à¦¸à§\8dযামà§\8dপà§\87ল à¦«à¦¾à¦\87ল à¦\89লà§\8dলà§\87à¦\96 à¦\95ৰা à¦\86বশà§\8dযà¦\95"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
-msgstr "à¦\85পসারণà§\87র à¦\89দà§\8dদà§\87শà§\8dযà§\87 à¦\8fà¦\95à¦\9fি à¦¸à§\8dযামà§\8dপà§\87ল à¦«à¦¾à¦\87ল à¦\89লà§\8dলà§\87à¦\96 à¦\95রা à¦\86বশà§\8dযà¦\95"
+msgstr "à¦\85পসাৰণà§\87ৰ à¦\89দà§\8dদà§\87শà§\8dযà§\87 à¦\8fà¦\9fা à¦¸à§\8dযামà§\8dপà§\87ল à¦«à¦¾à¦\87ল à¦\89লà§\8dলà§\87à¦\96 à¦\95ৰা à¦\86বশà§\8dযà¦\95"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
-msgstr "সিà¦\82à¦\95 à¦\87নপà§\81à¦\9f à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦\8fà¦\95à¦\9fি à¦¸à¦¿à¦\82à¦\95 à¦¨à¦¿à¦°à§\8dধারণ à¦\95রা à¦\86বশà§\8dযà¦\95"
+msgstr "সিà¦\82à¦\95 à¦¨à¦¿à¦¬à§\87শ à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦\8fà¦\9fা à¦¸à¦¿à¦\82à¦\95 à¦¨à¦¿à§°à§\8dধাৰণ à¦\95ৰা à¦\86বশà§\8dযà¦\95"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
-msgstr "সà§\8bরà§\8dস à¦\86à¦\89à¦\9fপà§\81à¦\9f à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦\8fà¦\95à¦\9fি à¦¸à§\8bরà§\8dস à¦¨à¦¿à¦°à§\8dধারণ à¦\95রা à¦\86বশà§\8dযà¦\95"
+msgstr "সà§\8bৰà§\8dস à¦¨à¦¿à§°à§\8dà¦\97ম à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦\8fà¦\9fা à¦¸à§\8bৰà§\8dস à¦¨à¦¿à§°à§\8dধাৰণ à¦\95ৰা à¦\86বশà§\8dযà¦\95"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
-msgstr "মডিà¦\89লà§\87র à¦¨à¦¾à¦® à¦\93 à¦\86রà§\8dà¦\97à§\81মà§\87নà§\8dà¦\9f à¦¨à¦¿à¦°à§\8dধারণ à¦\95রা à¦\86বশà§\8dযà¦\95।"
+msgstr "মডিà¦\89লà§\87ৰ à¦¨à¦¾à¦® à¦\93 à¦\86ৰà§\8dà¦\97à§\81মà§\87নà§\8dà¦\9f à¦¨à¦¿à§°à§\8dধাৰণ à¦\95ৰা à¦\86বশà§\8dযà¦\95।"
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
-msgstr "মডিà¦\89ল à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦¨à¦¿à¦°à§\8dধারণ à¦\95রা à¦\86বশà§\8dযà¦\95"
+msgstr "মডিà¦\89ল à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦¨à¦¿à§°à§\8dধাৰণ à¦\95ৰা à¦\86বশà§\8dযà¦\95"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
-msgstr "à¦\8fà¦\95াধিà¦\95 à¦¸à¦¿à¦\82à¦\95 à¦¨à¦¿à¦°à§\8dধারণ à¦\95রা à¦¯à¦¾à¦¬à§\87 à¦¨à¦¾à¥¤ à¦¬à§\81লিà§\9fà§\87ন à¦®à¦¾à¦¨ à¦¨à¦¿à¦°à§\8dধারণ à¦\95রা à¦\86বশà§\8dযà¦\95।"
+msgstr "à¦\8fà¦\95াধিà¦\95 à¦¸à¦¿à¦\82à¦\95 à¦¨à¦¿à§°à§\8dধাৰণ à¦\95ৰা à¦¯à¦¾à¦¬à§\87 à¦¨à¦¾à¥¤ à¦¬à§\81লিà§\9fà§\87ন à¦®à¦¾à¦¨ à¦¨à¦¿à§°à§\8dধাৰণ à¦\95ৰা à¦\86বশà§\8dযà¦\95।"
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
-msgstr "à¦\8fà¦\95াধিà¦\95 à¦¸à§\8bরà§\8dস à¦¨à¦¿à¦°à§\8dধারণ à¦\95রা à¦¯à¦¾à¦¬à§\87 à¦¨à¦¾à¥¤ à¦¬à§\81লিà§\9fà§\87ন à¦®à¦¾à¦¨ à¦¨à¦¿à¦°à§\8dধারণ à¦\95রা à¦\86বশà§\8dযà¦\95।"
+msgstr "à¦\8fà¦\95াধিà¦\95 à¦¸à§\8bৰà§\8dস à¦¨à¦¿à§°à§\8dধাৰণ à¦\95ৰা à¦¯à¦¾à¦¬à§\87 à¦¨à¦¾à¥¤ à¦¬à§\81লিà§\9fà§\87ন à¦®à¦¾à¦¨ à¦¨à¦¿à§°à§\8dধাৰণ à¦\95ৰা à¦\86বশà§\8dযà¦\95।"
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
-msgstr "à¦\95ারà§\8dডà§\87র à¦¨à¦¾à¦®/à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦\8fà¦\95à¦\9fি à¦ªà§\8dরà§\8bফাà¦\87লà§\87র à¦¨à¦¾à¦® à¦\89লà§\8dলà§\87à¦\96 à¦\95রা à¦\86বশà§\8dযà¦\95"
+msgstr "à¦\95াৰà§\8dডà§\87ৰ à¦¨à¦¾à¦®/à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦\8fà¦\9fা à¦ªà§\8dৰà§\8bফাà¦\87লà§\87ৰ à¦¨à¦¾à¦® à¦\89লà§\8dলà§\87à¦\96 à¦\95ৰা à¦\86বশà§\8dযà¦\95"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
-msgstr "sink-র à¦¨à¦¾à¦®/à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦\8fà¦\95à¦\9fি à¦ªà§\8bরà§\8dà¦\9fà§\87র à¦¨à¦¾à¦® à¦\89লà§\8dলà§\87à¦\96 à¦\95রা à¦\86বশà§\8dযà¦\95"
+msgstr "sink à§° à¦¨à¦¾à¦®/à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦\8fà¦\9fা à¦ªà§\8bৰà§\8dà¦\9fà§\87ৰ à¦¨à¦¾à¦® à¦\89লà§\8dলà§\87à¦\96 à¦\95ৰা à¦\86বশà§\8dযà¦\95"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
-msgstr "à¦\89à§\8eসà§\87র à¦¨à¦¾à¦®/à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦\8fà¦\95à¦\9fি à¦ªà§\8bরà§\8dà¦\9fà§\87 à¦¨à¦¾à¦® à¦\89লà§\8dলà§\87à¦\96 à¦\95রা à¦\86বশà§\8dযà¦\95"
+msgstr "à¦\89à§\8eসà§\87ৰ à¦¨à¦¾à¦®/à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦\8fà¦\9fা à¦ªà§\8bৰà§\8dà¦\9fà§\87 à¦¨à¦¾à¦® à¦\89লà§\8dলà§\87à¦\96 à¦\95ৰা à¦\86বশà§\8dযà¦\95"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
-msgstr "sink-র নাম/ইন্ডেক্স ও একটি পোর্টের নাম উল্লেখ করা আবশ্যক"
-
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "অবৈধ শব্দের মাত্রা নির্ধারিত"
+msgstr "sink ৰ নাম/ইন্ডেক্স ও এটা পোৰ্টেৰ নাম উল্লেখ কৰা আবশ্যক"
 
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
-msgstr "à¦\89à§\8eসà§\87র à¦¨à¦¾à¦®/à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦\8fà¦\95à¦\9fি à¦¶à¦¬à§\8dদà§\87র à¦®à¦¾à¦¤à§\8dরা à¦\89লà§\8dলà§\87à¦\96 à¦\95রা à¦\86বশà§\8dযà¦\95"
+msgstr "à¦\89à§\8eসà§\87ৰ à¦¨à¦¾à¦®/à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦\8fà¦\9fা à¦¶à¦¬à§\8dদà§\87ৰ à¦®à¦¾à¦¤à§\8dৰা à¦\89লà§\8dলà§\87à¦\96 à¦\95ৰা à¦\86বশà§\8dযà¦\95"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
-msgstr "সিà¦\82à¦\95 à¦\87নপà§\81à¦\9f à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦¶à¦¬à§\8dদà§\87র à¦®à¦¾à¦¤à§\8dরা à¦¨à¦¿à¦°à§\8dধারণ à¦\95রা à¦\86বশà§\8dযà¦\95"
+msgstr "সিà¦\82à¦\95 à¦¨à¦¿à¦¬à§\87শ à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦¶à¦¬à§\8dদà§\87ৰ à¦®à¦¾à¦¤à§\8dৰা à¦¨à¦¿à§°à§\8dধাৰণ à¦\95ৰা à¦\86বশà§\8dযà¦\95"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
-msgstr "সিà¦\82à¦\95 à¦\87নপà§\81à¦\9f ইন্ডেক্স বৈধ নয়"
+msgstr "সিà¦\82à¦\95 à¦¨à¦¿à¦¬à§\87শ ইন্ডেক্স বৈধ নয়"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "সোৰ্স নিৰ্গম ইন্ডেক্স ও এটা সোৰ্স নিৰ্ধাৰণ কৰা আবশ্যক"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "সিংক নিবেশ ইন্ডেক্স বৈধ নয়"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
-msgstr "sink-র à¦¨à¦¾à¦®/à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦\8fà¦\95à¦\9fি à¦¨à¦¿à¦\83শবà§\8dদতার à¦¬à§\81লিà§\9fান à¦\89লà§\8dলà§\87à¦\96 à¦\95রা à¦\86বশà§\8dযà¦\95"
+msgstr "sink à§° à¦¨à¦¾à¦®/à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦\8fà¦\9fা à¦¨à¦¿à¦\83শবà§\8dদতাৰ à¦¬à§\81লিà§\9fান à¦\89লà§\8dলà§\87à¦\96 à¦\95ৰা à¦\86বশà§\8dযà¦\95"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "অবৈধ স্যাম্পেল নিৰ্ধাৰিত"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
-msgstr "à¦\89à§\8eসà§\87র à¦¨à¦¾à¦®/à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦¨à¦¿à¦\83শবà§\8dদতার à¦¬à§\81লিà§\9fান à¦\89লà§\8dলà§\87à¦\96 à¦\95রা à¦\86বশà§\8dযà¦\95"
+msgstr "à¦\89à§\8eসà§\87ৰ à¦¨à¦¾à¦®/à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦¨à¦¿à¦\83শবà§\8dদতাৰ à¦¬à§\81লিà§\9fান à¦\89লà§\8dলà§\87à¦\96 à¦\95ৰা à¦\86বশà§\8dযà¦\95"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
-msgstr "সিà¦\82à¦\95 à¦\87নপà§\81à¦\9f à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦¨à¦¿à¦\83শবà§\8dদতার à¦¬à§\81লিà§\9fান à¦¨à¦¿à¦°à§\8dধারণ à¦\95রা à¦\86বশà§\8dযà¦\95"
+msgstr "সিà¦\82à¦\95 à¦¨à¦¿à¦¬à§\87শ à¦\87নà§\8dডà§\87à¦\95à§\8dস à¦\93 à¦¨à¦¿à¦\83শবà§\8dদতাৰ à¦¬à§\81লিà§\9fান à¦¨à¦¿à§°à§\8dধাৰণ à¦\95ৰা à¦\86বশà§\8dযà¦\95"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
-msgstr "অবৈধ সিংক ইনপুট ইন্ডেক্স নির্ধারিত"
+msgstr "অবৈধ সিংক নিবেশ ইন্ডেক্স নিৰ্ধাৰিত"
+
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "উৎসেৰ নাম/ইন্ডেক্স ও নিঃশব্দতাৰ বুলিয়ান উল্লেখ কৰা আবশ্যক"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "অবৈধ সিংক নিবেশ ইন্ডেক্স নিৰ্ধাৰিত"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "sink ৰ নাম/ইন্ডেক্স ও এটা নিঃশব্দতাৰ বুলিয়ান উল্লেখ কৰা আবশ্যক"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
-msgstr "à¦\95à§\8bনà§\8b à¦¬à§\88ধ à¦\95মানà§\8dড à¦¨à¦¿à¦°à§\8dধারিত à¦¹à§\9fনি।"
+msgstr "à¦\95à§\8bনà§\8b à¦¬à§\88ধ à¦\95মানà§\8dড à¦¨à¦¿à§°à§\8dধাৰিত à¦¹à§\9fনি।"
 
 #: ../src/utils/pax11publish.c:61
 #, c-format
@@ -2190,116 +2418,116 @@ msgid ""
 "variables and cookie file.\n"
 " -r    Remove PulseAudio data from X11 display\n"
 msgstr ""
-"%s [-D display] [-S server] [-O sink] [-I source] [-c file]  [-d|-e|-i|-r]\n"
+"%s [ D display] [ S server] [ O sink] [ I source] [ c file]  [ d| e| i| r]\n"
 "\n"
-" -d    Show current PulseAudio data attached to X11 display (default)\n"
-" -e    Export local PulseAudio data to X11 display\n"
-" -i    Import PulseAudio data from X11 display to local environment "
+"  d    Show current PulseAudio data attached to X11 display (default)\n"
+"  e    Export local PulseAudio data to X11 display\n"
+"  i    Import PulseAudio data from X11 display to local environment "
 "variables and cookie file.\n"
-" -r    Remove PulseAudio data from X11 display\n"
+"  r    Remove PulseAudio data from X11 display\n"
 
 #: ../src/utils/pax11publish.c:94
 #, c-format
 msgid "Failed to parse command line.\n"
-msgstr "আদেশ-শাৰী বিশ্লেষণ কৰিবলৈ ব্যৰ্থ ।\n"
+msgstr "আদেশ শাৰী বিশ্লেষণ কৰিবলৈ ব্যৰ্থ ।\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "সেৱক: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "উৎস: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "চিঙ্ক: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "কুকি: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "কুকি সংক্ৰান্ত তথ্য বিশ্লেষণ কৰিবলৈ ব্যৰ্থ\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "কুকি সংক্ৰান্ত তথ্য সংৰক্ষণ কৰিবলৈ ব্যৰ্থ\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "গ্ৰাহক বিন্যাস নথিপত্ৰ তুলিবলৈ ব্যৰ্থ ।\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "পৰিবেশ বিন্যাস সংক্ৰান্ত তথ্য পঢ়িবলৈ ব্যৰ্থ ।\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "FQDN প্ৰাপ্ত কৰিবলৈ ব্যৰ্থ ।\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "কুকি সংক্ৰান্ত তথ্য তুলিবলৈ ব্যৰ্থ\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "এতিয়াও বাস্তবায়িত নহয় ।\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
-msgstr "PulseAudio à¦¡à§\87মন à¦\9aলà¦\9bà§\87 à¦¨à¦¾ à¦\85থবা à¦¸à§\87শানà§\87র à¦¡à§\87মন à¦°à§\82পà§\87 à¦\9aলà¦\9bà§\87 à¦¨à¦¾à¥¤"
+msgstr "PulseAudio à¦¡à§\87মন à¦\9aলà¦\9bà§\87 à¦¨à¦¾ à¦¬à¦¾ à¦¸à§\87শানৰ à¦¡à§\87মন à§°à§\82পà§\87 à¦\9aলà¦\9bà§\87 à¦¨à¦¾à¥¤"
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "PulseAudio ডেমন kill কৰিবলৈ ব্যৰ্থ ।"
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "ডেমনৰ পৰা কোনো প্ৰতিক্ৰিয়া পোৱা নাযায় ।"
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "autospawn লক প্ৰয়োগ কৰিবলৈ ব্যৰ্থ ।"
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2312,10 +2540,10 @@ msgstr ""
 "ALSA ই আমাক যন্ত্ৰৰ পৰা নতুন তথ্য লিখিবলৈ উথালে, কিন্তু একো লিখিবলৈ নাছিল!\n"
 "অতি সম্ভৱ এইটো ALSA চালক '%s' ৰ এটা বাগ । অনুগ্ৰহ কৰি এই সমস্যা ALSA বিকাশকক "
 "জনাওক ।\n"
-"POLLOUT নিৰ্ধাৰিত হোৱাৰি পিছতো আমি উথিলো -- কিন্তু তাৰ পিছৰ snd_pcm_avail() এ ০ "
+"POLLOUT নিৰ্ধাৰিত হোৱাৰি পিছতো আমি উথিলো    কিন্তু তাৰ পিছৰ snd_pcm_avail() এ ০ "
 "দিলে বা অন্য এটা মান < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2328,244 +2556,469 @@ msgstr ""
 "ALSA ই আমাক যন্ত্ৰৰ পৰা নতুন তথ্য পঢ়িবলৈ উথালে, কিন্তু একো পঢ়িবলৈ নাছিল!\n"
 "অতি সম্ভৱ এইটো ALSA চালক '%s' ৰ এটা বাগ । অনুগ্ৰহ কৰি এই সমস্যা ALSA বিকাশকক "
 "জনাওক ।\n"
-"POLLIN নিৰ্ধাৰিত হোৱাৰি পিছতো আমি উথিলো -- কিন্তু তাৰ পিছৰ snd_pcm_avail() এ ০ "
+"POLLIN নিৰ্ধাৰিত হোৱাৰি পিছতো আমি উথিলো    কিন্তু তাৰ পিছৰ snd_pcm_avail() এ ০ "
 "দিলে বা অন্য এটা মান < min_avail."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "বন্ধ"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "High Fidelity Playback (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
-msgstr "হাই-ফিডà§\87লিà¦\9fি à¦\95à§\8dযাপà¦\9aার (A2DP)"
+msgstr "হাই à¦«à¦¿à¦¡à§\87লিà¦\9fি à¦\95à§\8dযাপà¦\9aাৰ (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Telephony Duplex (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "PulseAudio ধ্বনি সেৱক"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
-msgstr ""
+msgstr "নিৰ্গম যন্ত্ৰ"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
-msgstr ""
+msgstr "নিবেশ যন্ত্ৰ"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
-msgstr ""
+msgstr "@HOSTNAME@ ত অ'ডিঅ'"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
-msgstr ""
+msgstr "নিবেশ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
-msgstr ""
+msgstr "ডকিং স্টেছনৰ পৰা নিবেশ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
-msgstr ""
+msgstr "ডকিং স্টেছনৰ মাইক্ৰোফোন"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "ডকিং স্টেছনৰ পৰা নিবেশ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "লাইন ইন"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
-msgstr ""
+msgstr "মাইক্ৰোফোন"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
-msgid "External Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "ডকিং স্টেছনৰ মাইক্ৰোফোন"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
 #, fuzzy
+msgid "Rear Microphone"
+msgstr "মাইক্ৰোফোন"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "বহিস্থিত মাইক্ৰোফোন"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
-msgstr "à¦\86ভà§\8dযনà§\8dতৰà§\80ণ à¦\85'ডিà¦\85'"
+msgstr "à¦\85ভà§\8dযনà§\8dতৰà§\80ণ à¦®à¦¾à¦\87à¦\95à§\8dৰà§\8bফà§\8bন"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
-msgstr ""
+msgstr "ৰেডিঅ'"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
-msgstr ""
+msgstr "ভিডিঅ'"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
-msgstr ""
+msgstr "স্বয়ংক্ৰিয় গেইন নিয়ন্ত্ৰণ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
-msgstr ""
+msgstr "স্বয়ংক্ৰিয় গেইন নিয়ন্ত্ৰণ প্ৰয়োগ কৰা ন'হ'ব"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
-msgstr ""
+msgstr "বুস্ট"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
-msgstr ""
+msgstr "বুস্ট প্ৰয়োগ কৰা ন'হ'ব"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
-msgstr ""
+msgstr "বিবৰ্ধক"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
-msgstr ""
+msgstr "বিবৰ্ধন প্ৰয়োগ কৰা ন'হ'ব"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "বুস্ট"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "বুস্ট প্ৰয়োগ কৰা ন'হ'ব"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+#, fuzzy
+msgid "Headphones"
+msgstr "এনালগ হেড ফোন"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "এনালগ নিবেশ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "ডকিং স্টেছনৰ মাইক্ৰোফোন"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
-msgstr ""
+msgstr "এনালগ নিৰ্গম"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "এনালগ নিৰ্গম (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "লাইন ইন"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
+msgstr "এনালগ মোনো নিৰ্গম"
+
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "এনালগ স্টিৰিঅ'"
+
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, fuzzy, c-format
-msgid "%s+%s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "ডিজিটেল স্টিৰিঅ' (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, fuzzy, c-format
-msgid "%s / %s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "ডিজিটেল স্টিৰিঅ' (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
-msgstr ""
+msgstr "এনালগ মোনো"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
-msgstr "সà§\8dà¦\9fিৰিà¦\93"
+msgstr "à¦\8fনালà¦\97 à¦¸à§\8dà¦\9fিৰিà¦\85'"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
-msgstr "à¦\9bাৰাà¦\89ণà§\8dড à§ª.১"
+msgstr "à¦\8fনালà¦\97 à¦\9bাৰাà¦\89নà§\8dড à§¨.১"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
-msgstr "à¦\9bাৰাà¦\89ণà§\8dড à§ª.০"
+msgstr "à¦\8fনালà¦\97 à¦\9bাৰাà¦\89নà§\8dড à§©.০"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
-msgstr "à¦\9bাৰাà¦\89ণà§\8dড à§ª.১"
+msgstr "à¦\8fনালà¦\97 à¦\9bাৰাà¦\89নà§\8dড à§©.১"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
-msgstr "à¦\9bাৰাà¦\89ণ্ড ৪.০"
+msgstr "à¦\8fনালà¦\97 à¦\9bাৰাà¦\89ন্ড ৪.০"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
-msgstr "à¦\9bাৰাà¦\89ণ্ড ৪.১"
+msgstr "à¦\8fনালà¦\97 à¦\9bাৰাà¦\89ন্ড ৪.১"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
-msgstr "à¦\9bাৰাà¦\89ণ্ড ৫.০"
+msgstr "à¦\8fনালà¦\97 à¦\9bাৰাà¦\89ন্ড ৫.০"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
-msgstr "à¦\9bাৰাà¦\89ণ্ড ৫.১"
+msgstr "à¦\8fনালà¦\97 à¦\9bাৰাà¦\89ন্ড ৫.১"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
-msgstr "à¦\9bাৰাà¦\89ণà§\8dড à§ª.০"
+msgstr "à¦\8fনালà¦\97 à¦\9bাৰাà¦\89নà§\8dড à§¬.০"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
-msgstr "à¦\9bাৰাà¦\89ণà§\8dড à§ª.১"
+msgstr "à¦\8fনালà¦\97 à¦\9bাৰাà¦\89নà§\8dড à§¬.১"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
-msgstr "à¦\9bাৰাà¦\89ণà§\8dড à§ª.০"
+msgstr "à¦\8fনালà¦\97 à¦\9bাৰাà¦\89নà§\8dড à§­.০"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
-msgstr "à¦\9bাৰাà¦\89ণ্ড ৭.১"
+msgstr "à¦\8fনালà¦\97 à¦\9bাৰাà¦\89ন্ড ৭.১"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
-msgstr ""
+msgstr "ডিজিটেল স্টিৰিঅ' (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "ডিজিটেল স্টিৰিঅ' (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
-msgstr ""
+msgstr "ডিজিটেল ছাৰাউন্ড ৪.০ (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
-msgstr ""
+msgstr "ডিজিটেল ছাৰাউন্ড ৫.১ (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
-msgstr ""
+msgstr "ডিজিটেল স্টিৰিঅ' (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "ডিজিটেল ছাৰাউন্ড ৫.১ (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
-msgstr ""
+msgstr "এনালগ মোনো ডুপ্লেক্স"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
-msgstr ""
+msgstr "এনালগ স্টিৰিঅ' ডুপ্লেক্স"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
+msgstr "ডিজিটেল স্টিৰিঅ' ডুপ্লেক্স (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Null ফলাফল"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "নিবেশ"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
 msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<name for the sink> sink_properties=<properties for the sink> "
+"master=<name of sink to filter> format=<sample format> rate=<sample rate> "
+"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
+"plugin name> label=<ladspa plugin label> control=<comma separated list of "
+"input control values>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] এই স্থাপত্যত rlimit সমৰ্থিত নহয় ।"
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() ব্যৰ্থ"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "উৎসৰ নিৰ্গম #%u\n"
+#~ "\tচালক: %s\n"
+#~ "\tগৰাকীৰ অংশ: %s\n"
+#~ "\tগ্ৰাহক: %s\n"
+#~ "\tউৎস: %u\n"
+#~ "\tচানেকি নিৰ্ধাৰণ: %s\n"
+#~ "\tচেনেল মেপ: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample ধৰণ: %s\n"
+#~ "\tগুণ:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload sample FILENAME [NAME]\n"
+#~ "%s [options] play sample NAME [SINK]\n"
+#~ "%s [options] remove sample NAME\n"
+#~ "%s [options] move sink input SINKINPUT SINK\n"
+#~ "%s [options] move source output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load module NAME [ARGS ...]\n"
+#~ "%s [options] unload module MODULE\n"
+#~ "%s [options] suspend sink SINK 1|0\n"
+#~ "%s [options] suspend source SOURCE 1|0\n"
+#~ "%s [options] set card profile CARD PROFILE\n"
+#~ "%s [options] set sink port SINK PORT\n"
+#~ "%s [options] set source port SOURCE PORT\n"
+#~ "%s [options] set sink volume SINK VOLUME\n"
+#~ "%s [options] set source volume SOURCE VOLUME\n"
+#~ "%s [options] set sink input volume SINKINPUT VOLUME\n"
+#~ "%s [options] set sink mute SINK 1|0\n"
+#~ "%s [options] set source mute SOURCE 1|0\n"
+#~ "%s [options] set sink input mute SINKINPUT 1|0\n"
+#~ "\n"
+#~ "   h,   help                            Show this help\n"
+#~ "        version                         Show version\n"
+#~ "\n"
+#~ "   s,   server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "   n,   client name=NAME                How to call this client on the "
+#~ "server\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s %s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "ডিজিটেল ছাৰাউন্ড ৪.০ (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Low Frequency Emmiter"
index 45adef1..1c35a2d 100644 (file)
@@ -1,29 +1,24 @@
 # translation of pulseaudio.master-tx.bn_IN.po to Bengali INDIA
 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the PACKAGE package.
+# Runa Bhattacharjee <runab@redhat.com>, 2009, 2012.
 #
-# Runa Bhattacharjee <runab@fedoraproject.org>, 2009.
-# Runa Bhattacharjee <runab@redhat.com>, 2009.
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx.bn_IN\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-09-10 17:08+0530\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:52+0000\n"
 "Last-Translator: Runa Bhattacharjee <runab@redhat.com>\n"
 "Language-Team: Bengali INDIA <anubad@lists.ankur.org.in>\n"
+"Language: \n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: KBabel 1.11.4\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -35,11 +30,11 @@ msgstr ""
 "সম্ভবত এটি ALSA ড্রাইভার '%s'-র একটি বাগ। অনুগ্রহ করে এই সমস্যা সম্বন্ধে ALSA "
 "ডিভেলপরদের সূচিত করুন।"
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
@@ -47,7 +42,19 @@ msgstr ""
 "সম্ভবত এটি ALSA ড্রাইভার '%s'-র একটি বাগ। অনুগ্রহ করে এই সমস্যা সম্বন্ধে ALSA "
 "ডিভেলপরদের সূচিত করুন।"
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() থেকে প্রাপ্ত মান অত্যাধিক বড়: %lu বাইট (%lu ms)।\n"
+"সম্ভবত এটি ALSA ড্রাইভার '%s'-র একটি বাগ। অনুগ্রহ করে এই সমস্যা সম্বন্ধে ALSA "
+"ডিভেলপরদের সূচিত করুন।"
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -59,306 +66,336 @@ msgstr ""
 "সম্ভবত এটি ALSA ড্রাইভার '%s'-র একটি বাগ। অনুগ্রহ করে এই সমস্যা সম্বন্ধে ALSA "
 "ডিভেলপরদের সূচিত করুন।"
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr ""
 "সর্বদা অন্তত একটি sink লোড করে রাখা হবে, প্রয়োজনে null sink ব্যবহার করা হবে"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "ডামি আউটপুট"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "ভার্চুয়াল LADSPA sink"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<name for the sink> sink_properties=<properties for the sink> "
 "master=<name of sink to filter> format=<sample format> rate=<sample rate> "
 "channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
+"plugin name> label=<ladspa plugin label> control=<comma separated list of "
 "input control values>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "NULL sink-র সময় নির্ধারণ"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "Null ফলাফল"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "অভ্যন্তরীণ অডিও"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "মোডেম"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "মূল lt_dlopen লোডার সনাক্ত করতে ব্যর্থ।"
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "নতুন dl লোডার বরাদ্দ করতে ব্যর্থ।"
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "bind-now-loader যোগ করতে ব্যর্থ।"
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "%s সিগন্যাল প্রাপ্ত হয়েছে।"
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "প্রস্থান করা হচ্ছে।"
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "'%s' ব্যবহারকারী সন্ধান করতে ব্যর্থ।"
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "দল '%s' সন্ধান করতে ব্যর্থ।"
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "ব্যবহারকারী '%s' (UID %lu) ও দল '%s' (GID %lu) প্রাপ্ত হয়েছে।"
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "'%s' ব্যবহারকারীর ও '%s' দলের GID-র মধ্যে গরমিল।"
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr ""
 "'%s' ব্যবহারকারী ব্যক্তিগত ডিরেক্টরি রূপে '%s' ধার্য করা হয়নি, অগ্রাহ্য করা হবে।"
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "'%s' নির্মাণ করতে ব্যর্থ: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "দলের তালিকা পরিবর্তন করতে ব্যর্থ: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "GID পরিবর্তন করতে ব্যর্থ: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "UID পরিবর্তন করতে ব্যর্থ: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "root-র অধিকার সাফল্যের সাথে বর্জন করা হয়েছে।"
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "এই প্ল্যাটফর্মে, সিস্টেমব্যাপী মোড সমর্থিত নয়।"
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) বিফল: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "কমান্ড-লাইন পার্স করতে ব্যর্থ।"
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "ডেমন চলছে না"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "PID %u রূপে ডেমন চলছে"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "ডেমন kill করতে ব্যর্থ: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
 msgstr ""
 "root পরিচয়ে এই প্রোগ্রামটি সঞ্চালিত হওয়া উচিত নয় (যদি না --system উল্লিখিত হয়)।"
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "Root-র অধিকার আবশ্যক।"
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "সিস্টেম ইনস্ট্যান্সের ক্ষেত্রে --start সমর্থিত নয়।"
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "সিস্টেম মোডে চলছে, কিন্তু --disallow-exit নির্ধারিত হয়নি!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr "সিস্টেম মোডে চলছে, কিন্তু --disallow-module-loading নির্ধারিত হয়নি!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "সিস্টেম মোডে চলছে, SHM মোড বলপূর্বক নিষ্ক্রিয় করা হচ্ছে!"
 
 # http://linux.die.net/man/1/pulseaudio এখানে রেফারেন্স পাওয়া যাবে
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 "সিস্টেম মোডে চলছে, কর্মহীন অবস্থার জন্য ধার্য সময়সীমা পূর্তী পরে প্রস্থানের ব্যবস্থা "
 "বলপূর্বক নিষ্ক্রিয় করা হচ্ছে!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "stdio প্রাপ্ত করতে ব্যর্থ।"
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "পাইপ বিফল: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() বিফল: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() বিফল: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "ডেমন আরম্ভ করতে বিফল।"
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "সাফল্যের সাথে ডেমন আরম্ভ করা হয়েছে।"
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() বিফল: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "এটি PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "কম্পাইলেশনের হোস্ট: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "কম্পাইলশনের CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "চিহ্নিত হোস্টে চলছে: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "%u CPU পাওয়া গিয়েছে।"
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "পেজের মাপ %lu বাইট"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Valgrind সমর্থন সহ কম্পাইল করা হয়েছে: হ্যাঁ"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Valgrind সমর্থন সহ কম্পাইল করা হয়েছে: না"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "valgrind মোডে চলছে: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "চিহ্নিত হোস্টে চলছে: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "সর্বাপেক্ষ উত্তম বিল্ড: হ্যাঁ"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "সর্বাপেক্ষ উত্তম বিল্ড: না"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG ব্যাখ্যা করা হয়েছে, সকল অ্যাসার্ট নিষ্ক্রিয় করা হয়েছে।"
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH ব্যাখ্যা করা হয়েছে, শুধুমাত্র ফাস্ট পাথ অ্যাসার্ট নিষ্ক্রিয় করা হয়েছে।"
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "সকল অ্যাসার্ট সক্রিয় করা হয়েছে।"
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "মেশিন ID প্রাপ্ত করতে ব্যর্থ"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "মেশিন ID হল %s।"
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "সেশান ID হল %s।"
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "রান-টাইম ডিরেক্টরি %s ব্যবহার করা হচ্ছে।"
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "অবস্থাসূচক ডিরেক্টরি %s ব্যবহার করা হচ্ছে।"
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "মডিউল ডিরেক্টরি %s ব্যবহার করা হচ্ছে।"
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "সিস্টেম মোডে চলছে: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -372,47 +409,47 @@ msgstr ""
 "সিস্টেম মোডে ব্যবহারের সমস্যা সম্পর্কে জানতে হলে http://pulseaudio.org/wiki/"
 "WhatIsWrongWithSystemMode দেখুন।"
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() ব্যর্থ।"
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "উচ্চ-রেসোলিউশনের নতুন টাইমার উপলব্ধ রয়েছে! পরীক্ষা করে দেখুন!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
 msgstr "উচ্চ-রেসোলিউশনের নতুন টাইমার সহ Linux সক্রিয় করা বাঞ্ছনীয়!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() ব্যর্থ।"
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "ডেমন আরম্ভ করতে ব্যর্থ।"
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 "লোড করা মডিউল বিনা ডেমন আরম্ভ করা হয়েছে এবং কোনো কর্ম সঞ্চালন করা সম্ভব নয়।"
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "ডেমন আরম্ভ করা হয়েছে।"
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "ডেমন বন্ধ করার প্রক্রিয়া আরম্ভ করা হয়েছে।"
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "ডেমন বন্ধ করা হয়েছে।"
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -449,15 +486,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -563,15 +598,15 @@ msgstr ""
 "\n"
 "  -n                                    ডিফল্ট স্ক্রিপ্ট ফাইল লোড করা হবে না\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize দ্বারা বুলিয়ান আর্গুমেন্ট প্রত্যাশিত"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail দ্বারা বুলিয়ান আর্গুমেন্ট প্রত্যাশিত"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -579,166 +614,169 @@ msgstr ""
 "--log-level-র ক্ষেত্রে লগ স্তরের আর্গুমেন্ট প্রত্যাশিত (0..4 সীমার মধ্যে একটি সংখ্যা "
 "অথবা debug, info, notice, warn, ও error-র মধ্যে একটি মান)।"
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority দ্বারা বুলিয়ান আর্গুমেন্ট প্রত্যাশিত"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime দ্বারা বুলিয়ান আর্গুমেন্ট প্রত্যাশিত"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading দ্বারা বুলিয়ান আর্গুমেন্ট প্রত্যাশিত"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit দ্বারা বুলিয়ান আর্গুমেন্ট প্রত্যাশিত"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file দ্বারা বুলিয়ান আর্গুমেন্ট প্রত্যাশিত"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr "লগের উদ্দিষ্ট স্থন বৈধ নয়: 'syslog', 'stderr' অথবা 'auto' প্রয়োগ করুন।"
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time দ্বারা বুলিয়ান আর্গুমেন্ট প্রত্যাশিত"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta দ্বারা বুলিয়ান আর্গুমেন্ট প্রত্যাশিত"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "রি-স্যাম্পেল পদ্ধতি '%s' বৈধ নয়।"
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system দ্বারা বুলিয়ান আর্গুমেন্ট প্রত্যাশিত"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit দ্বারা বুলিয়ান আর্গুমেন্ট প্রত্যাশিত"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm দ্বারা বুলিয়ান আর্গুমেন্ট প্রত্যাশিত"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "নাম: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "মডিউল সংক্রান্ত কোনো তথ্য উপলব্ধ নেই\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "সংস্করণ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "বিবরণ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "নির্মাতা: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "ব্যবহার পদ্ধতি: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "একবার লোড করা হবে: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "অবচিত করার সতর্কবার্তা: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "পাথ: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] লগ টার্গেট '%s' বৈধ নয়।"
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] লগের স্তর '%s' বৈধ নয়।"
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] রি-স্যাম্পেল পদ্ধতি '%s' বৈধ নয়।"
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] rlimit '%s' বৈধ নয়।"
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] এই প্ল্যাটফর্মে rlimit সমর্থিত নয়।"
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] স্যাম্পেলের বিন্যাস '%s' বৈধ নয়।"
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] স্যাম্পেলের মাত্রা '%s' বৈধ নয়।"
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] স্যাম্পেলের চ্যানেল '%s' বৈধ নয়"
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] চ্যানেল ম্যাপ '%s' বৈধ নয়।"
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] অংশ সংখ্যা '%s' বৈধ নয়।"
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] অংশের মাপ '%s' বৈধ নয়।"
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] nice স্তর '%s' বৈধ নয়।"
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] স্যাম্পেলের মাত্রা '%s' বৈধ নয়।"
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "কনফিগারেশন ফাইল খুলতে ব্যর্থ: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -746,12 +784,12 @@ msgstr ""
 "ডিফল্ট চ্যানেল ম্যাপের মধ্যে অন্তর্ভুক্ত চ্যানেলের সংখ্যা ও চ্যানেলের ডিফল্ট সংখ্যার মধ্যে "
 "গরমিল।"
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### চিহ্নিত কনফিগারেশন ফাইল থেকে পড়া হবে: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "অধিকার বর্জন করা হচ্ছে।"
 
@@ -763,6 +801,16 @@ msgstr "PulseAudio শব্দ ব্যবস্থা"
 msgid "Start the PulseAudio Sound System"
 msgstr "PulseAudio শব্দ ব্যবস্থা আরম্ভ করা হবে"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio শব্দ ব্যবস্থা"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "PulseAudio শব্দ ব্যবস্থা আরম্ভ করা হবে"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "মোনো"
@@ -792,8 +840,8 @@ msgid "Rear Right"
 msgstr "পিছনে ডানদিকে"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "কম ফ্রিকোয়েন্সির নিঃসরণকারী"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -967,9 +1015,10 @@ msgstr "উপরে পিছনে বাঁদিকে"
 msgid "Top Rear Right"
 msgstr "উপরে পিছনে ডানদিকে"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(অবৈধ)"
 
@@ -997,337 +1046,354 @@ msgstr "সারাউন্ড ৫.১"
 msgid "Surround 7.1"
 msgstr "সারাউন্ড ৭.১"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "ঠিক আছে"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "ব্যবহারাধিকার প্রত্যাখ্যাত"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "অজানা কমান্ড"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "অবৈধ আর্গুমেন্ট"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "এনটিটি উপস্থিত রয়েছে"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "এই ধরনের কোনো এনটিটি উপস্থিত নেই"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "সংযোগ প্রত্যাখ্যান করা হয়েছে"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "প্রোটোকল সংক্রান্ত ত্রুটি"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "সময়সীমা"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "কোনো অনুমোদনের-কি নেই"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "অভ্যন্তরীণ ত্রুটি"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "সংযোগ বন্ধ করা হয়েছে"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "এনটিটি kill করা হয়েছে"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "সার্ভার বৈধ নয়"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "মডিউল আরম্ভ করতে ব্যর্থ"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "অবস্থা সঠিক নয়"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "তথ্য অনুপস্থিত "
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "প্রোটোকলের সংস্করণে গরমিল"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "অত্যাধিক বড়"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "সমর্থিত নয়"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "অজানা ত্রুটির কোড"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "এই ধরনের কোনো এক্সটেনশন নেই"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "অবচিত বৈশিষ্ট্য"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "অনুপস্থিত বাস্তবায়ন"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "ক্লায়েন্ট ফর্ক করা হয়েছে"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
-msgstr ""
+msgstr "ইনপুট/আউটপুট ত্রুটি"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
-msgstr ""
+msgstr "ডিভাইস অথবা রিসোর্সটি ব্যস্ত"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f গিবিবাইট"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f মিবিবাইট"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f কিবিবাইট"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u বাইট"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() ব্যর্থ"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() ব্যর্থ: %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "কুকির তথ্য পার্স করতে ব্যর্থ"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "কনফিগারেশন ফাইল '%s' খুলতে ব্যর্থ: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "কোনো কুকি লোড করা হয়নি। কুকি বিনা সংযোগের প্রচেষ্টা করা হচ্ছে।"
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "অজানা এক্সটেনশন '%s'-র জন্য বার্তা প্রাপ্ত হয়েছে"
 
 # drain a stream = যখন স্ট্রিমের মধ্যে উপস্থিত সকল তথ্য আহরণ করা হয় ও স্ট্রিমটি সম্পূর্ণরূপে ফাঁকা হয়ে যায়।
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "স্ট্রিম ড্রেইন (অর্থাৎ ফাঁকা) করতে ব্যর্থ: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "প্লে-ব্যাক স্ট্রিম ফাঁকা করা হয়েছে।"
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "সার্ভারের সাথে স্থাপিত সংযোগ ফাঁকা করা হচ্ছে।"
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() ব্যর্থ: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_write() ব্যর্থ: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() ব্যর্থ: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "সাফল্যের সাথে স্ট্রিম নির্মিত হয়েছে।"
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() ব্যর্থ: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, 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:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "বাফারের মাপ: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "স্যাম্পেলের spec '%s', ও চ্যানেল ম্যাপ '%s' ব্যবহার করা হচ্ছে।"
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "ডিভাইস %s-র সাথে সংযোগ করা হয়েছে (%u, %ssuspended)।"
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "ষ্ট্রিম সংক্রান্ত ত্রুটি: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "স্ট্রিম ডিভাইস স্থগিত করা হয়েছে। %s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "স্ট্রিম ডিভাইস পুনরারম্ভ করা হয়েছে। %s"
 
 # underrun = ধীর গতির স্ট্রিম
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "ধীর গতির স্ট্রিম.%s"
 
 # overrun=the stream fills up the allocated buffer space and there is no more space for it
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "স্ট্রিম মাত্রা অতিক্রম করেছে।%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "স্ট্রিম আরম্ভ করা হয়েছে। %s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "%s ডিভাইসে স্ট্রিম স্থানান্তর করা হয়েছে (%u, %ssuspended)।%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "না "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "স্ট্রিম বাফারের অ্যাট্রিবিউট পরিবর্তিত হয়েছে। %s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "সংযোগ স্থাপিত হয়েছে।%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() ব্যর্থ: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() ব্যর্থ: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() ব্যর্থ: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "সংযোগ বিফল: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "ফাইলের সমাপ্তি সনাক্ত হয়েছে।"
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() ব্যর্থ: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "সিগন্যাল প্রাপ্ত হয়েছে, প্রস্থান করা হবে।"
 
 # latency here = delay (technical term
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "লেটেন্সির পরিমাণ প্রাপ্ত করতে ব্যর্থ: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "সময়: %0.3f সেকেন্ড; লেটেন্সি: %0.0f usec।"
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() ব্যর্থ: %s"
 
 # reverting this to english because the command line text gets messed up
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1379,10 +1445,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [options]\n"
@@ -1441,7 +1512,7 @@ msgstr ""
 "      --file-format=FFORMAT             Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1452,68 +1523,68 @@ msgstr ""
 "libpulse সহযোগে কম্পাইল করা হয়েছে %s\n"
 "libpulse-র সাথে যুক্ত %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "ক্লায়েন্টের নাম '%s' বৈধ নয়"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "স্ট্রিমের নাম '%s' বৈধ নয়।"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "চ্যানেল ম্যাপ '%s' বৈধ নয়"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "লেটেন্সির জন্য নির্ধারিত বৈশিষ্ট্য '%s' বৈধ নয়"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "প্রসেসের সময়ের বৈশিষ্ট্য '%s' বৈধ নয়"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "বৈশিষ্ট্য '%s' বৈধ নয়।"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "ফাইলের অজানা বিন্যাস %s।"
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "অবৈধ স্যাম্পেল নির্ধারিত"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "অত্যাধিক আর্গুমেন্ট।"
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "স্যাম্পেলের মান নির্ধারণের ফাইল নির্মাণ করতে ব্যর্থ"
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "শব্দের ফাইল খুলতে ব্যর্থ।"
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
@@ -1521,23 +1592,23 @@ msgstr ""
 "সতর্কবার্তা: চিহ্নিত স্যাম্পেল নির্ধারণের ফাইলটির তথ্য, এই ফাইলের থেকে উপলব্ধ তথ্য "
 "দ্বারা প্রতিস্থাপিত হবে।"
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "ফাইল থেকে স্যাম্পেল সংক্রান্ত তথ্য প্রাপ্ত করতে ব্যর্থ।"
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "সতর্কবার্তা: ফাইল থেকে চ্যানেলের ম্যাপ নির্ধারণ করতে ব্যর্থ।"
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "চ্যানেলের ম্যাপ ও স্যাম্পেলের নির্ধারিত মানে গরমিল"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "সতর্কবার্তা: ফাইলের মধ্যে চ্যানেলের ম্যাপ লিখতে ব্যর্থ।"
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
@@ -1545,80 +1616,85 @@ msgstr ""
 "একটি %s স্ট্রিম খোলা হচ্ছে। এটির জন্য '%s'-র স্যাম্পেলের নির্ধারিত মান ও '%s' "
 "চ্যানেলের ম্যাপ প্রয়োগ করা হবে।"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "রেকর্ড করা হচ্ছে"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "প্লে-ব্যাক"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "কমান্ড-লাইন পার্স করতে ব্যর্থ।"
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() ব্যর্থ।"
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() ব্যর্থ।"
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() ব্যর্থ।"
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() ব্যর্থ: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_rttime_new() ব্যর্থ।"
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() ব্যর্থ।"
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "স্থগিত করতে ব্যর্থ: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "পুনরারম্ভ করতে ব্যর্থ: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "সতর্কবার্তা: শব্দের সার্ভারটি স্থানীয় নয় ও স্থগিত করা হচ্ছে না।\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "সংযোগ বিফল: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "SIGINT প্রাপ্ত হয়েছে, প্রস্থান করা হয়েছে।\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "সতর্কবার্তা: সিগন্যাল %u দ্বারা চাইল্ড প্রসেস বন্ধ করা হয়েছে\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1663,36 +1739,47 @@ msgstr "pa_context_new() ব্যর্থ।\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() ব্যর্থ।\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "পরিসংখ্যান প্রাপ্ত করতে ব্যর্থ: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "বর্তমানে ব্যবহৃত: %u ব্লকের মধ্যে উপস্থিত সর্বমোট %s বাইট।\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr ""
 "সম্পূর্ণ কর্মকালের জন্য বরাদ্দ করা হয়েছে: %u ব্লকের মধ্যে উপস্থিত সর্বমোট %s বাইট।\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "স্যাম্পেল ক্যাশের মাপ: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "সার্ভার সংক্রান্ত তথ্য প্রাপ্ত করতে ব্যর্থ: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1700,7 +1787,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "ব্যবহারকারীর নাম: %s\n"
 "হোস্ট-নেম: %s\n"
@@ -1712,13 +1799,13 @@ msgstr ""
 "ডিফল্ট সোর্স: %s\n"
 "কুকি: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "sink সংক্রান্ত তথ্য প্রাপ্ত করতে ব্যর্থ: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1734,7 +1821,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1756,22 +1843,27 @@ msgstr ""
 "\tবিবিধ বৈশিষ্ট্য:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tপোর্ট:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tসক্রিয় পোর্ট: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tপোর্ট:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "উৎস সংক্রান্ত তথ্য প্রাপ্ত করতে ব্যর্থ: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1810,20 +1902,20 @@ msgstr ""
 "\tবিবিধ বৈশিষ্ট্য:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "n/a"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "মডিউল সংক্রান্ত তথ্য প্রাপ্ত করতে ব্যর্থ: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1840,12 +1932,12 @@ msgstr ""
 "\tবিবিধ বৈশিষ্ট্য:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "ক্লায়েন্ট সংক্রান্ত তথ্য প্রাপ্ত করতে ব্যর্থ: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1860,12 +1952,12 @@ msgstr ""
 "\tবিবিধ বৈশিষ্ট্য:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "কার্ড সংক্রান্ত তথ্য প্রাপ্ত করতে ব্যর্থ: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1882,23 +1974,23 @@ msgstr ""
 "\tবিবিধ বৈশিষ্ট্য:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tপ্রোফাইল:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tসক্রিয় প্রোফাইল: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "sink ইনপুট সংক্রান্ত তথ্য প্রাপ্ত করতে ব্যর্থ: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1907,6 +1999,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1934,13 +2027,13 @@ msgstr ""
 "\tবিবিধ বৈশিষ্ট্য:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "উৎস আউটপুট সংক্রান্ত তথ্য প্রাপ্ত করতে ব্যর্থ: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1949,32 +2042,41 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"সà§\8bরà§\8dসà§\87র à¦\86à¦\89à¦\9fপুট #%u\n"
+"সিà¦\82à¦\95 à¦\87নপুট #%u\n"
 "\tড্রাইভার: %s\n"
 "\tচিহ্নিত মডিউলের মালিকানাধীন: %s\n"
 "\tক্লায়েন্ট: %s\n"
-"\tসà§\8bরà§\8dস: %u\n"
+"\tসিà¦\82à¦\95: %u\n"
 "\tস্যাম্পেলের বৈশিষ্ট্য: %s\n"
-"\tচ্যানেলের ম্যাপ: %s\n"
+"\tচ্যানেল ম্যাপ: %s\n"
+"\tনিঃশব্দ: %s\n"
+"\tআওয়াজ: %s\n"
+"\t        %s\n"
+"\t        ভারসাম্য %0.2f\n"
 "\tবাফারের লেটেন্সি: %0.0f usec\n"
-"\tসà§\8bরà§\8dসের লেটেন্সি: %0.0f usec\n"
-"\tরি-স্যাম্পেলের পদ্ধতি: %s\n"
+"\tসিà¦\82à¦\95ের লেটেন্সি: %0.0f usec\n"
+"\tরি-স্যাম্পেলের পদ্ধতি %s\n"
 "\tবিবিধ বৈশিষ্ট্য:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "স্যাম্পেল সংক্রান্ত তথ্য প্রাপ্ত করতে ব্যর্থ: %s"
 
 # Lazy = low quality sample
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -2005,49 +2107,163 @@ msgstr ""
 "\tবিবিধ বৈশিষ্ট্য:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "ব্যর্থতা: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "উৎস সংক্রান্ত তথ্য প্রাপ্ত করতে ব্যর্থ: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "স্যাম্পেল আপলোড করতে ব্যর্থ: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "সম্পূর্ণ হওয়ার পূর্বে ফাইল সমাপ্ত হয়েছে"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "সার্ভার বৈধ নয়"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "SIGINT প্রাপ্ত হয়েছে, প্রস্থান করা হয়েছে।"
 
-# reverting to english because the command line output gets messed up
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "অবৈধ শব্দের মাত্রা নির্ধারিত"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2057,37 +2273,15 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+"%s [options] ... \n"
 "\n"
-"  -h, --help                            Show this help\n"
-"      --version                         Show version\n"
+"  -h, --help                            এই সাহায্য বার্তা প্রদর্শন করা হবে\n"
+"      --version                         সংস্করণ প্রদর্শন করা হবে\n"
+"  -s, --server=SERVER                   সংযোগ করার উদ্দেশ্যে চিহ্নিত সার্ভারের "
+"নাম\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect "
-"to\n"
-"  -n, --client-name=NAME                How to call this client on the "
-"server\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2098,104 +2292,136 @@ msgstr ""
 "libpulse সহযোগে কম্পাইল করা %s\n"
 "libpulse-র সাথে যুক্ত %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "লোড করার উদ্দেশ্যে অনুগ্রহ করে একটি স্যাম্পেল ফাইল উল্লেখ করুন"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "শব্দের ফাইল খুলতে ব্যর্থ।"
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "সতর্কবার্তা: ফাইল থেকে স্যাম্পেলের নির্ধারিত মাপ নির্মাণ করতে ব্যর্থ।"
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "বাজানোর উদ্দেশ্যে একটি স্যাম্পেল ফাইল উল্লেখ করা আবশ্যক"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "অপসারণের উদ্দেশ্যে একটি স্যাম্পেল ফাইল উল্লেখ করা আবশ্যক"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "সিংক ইনপুট ইন্ডেক্স ও একটি সিংক নির্ধারণ করা আবশ্যক"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "সোর্স আউটপুট ইন্ডেক্স ও একটি সোর্স নির্ধারণ করা আবশ্যক"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "মডিউলের নাম ও আর্গুমেন্ট নির্ধারণ করা আবশ্যক।"
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "মডিউল ইন্ডেক্স নির্ধারণ করা আবশ্যক"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr "একাধিক সিংক নির্ধারণ করা যাবে না। বুলিয়েন মান নির্ধারণ করা আবশ্যক।"
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr "একাধিক সোর্স নির্ধারণ করা যাবে না। বুলিয়েন মান নির্ধারণ করা আবশ্যক।"
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "কার্ডের নাম/ইন্ডেক্স ও একটি প্রোফাইলের নাম উল্লেখ করা আবশ্যক"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "sink-র নাম/ইন্ডেক্স ও একটি পোর্টের নাম উল্লেখ করা আবশ্যক"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "উৎসের নাম/ইন্ডেক্স ও একটি পোর্টে নাম উল্লেখ করা আবশ্যক"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "sink-র নাম/ইন্ডেক্স ও একটি পোর্টের নাম উল্লেখ করা আবশ্যক"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "অবৈধ শব্দের মাত্রা নির্ধারিত"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "উৎসের নাম/ইন্ডেক্স ও একটি শব্দের মাত্রা উল্লেখ করা আবশ্যক"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "সিংক ইনপুট ইন্ডেক্স ও শব্দের মাত্রা নির্ধারণ করা আবশ্যক"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "সিংক ইনপুট ইন্ডেক্স বৈধ নয়"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "সোর্স আউটপুট ইন্ডেক্স ও একটি সোর্স নির্ধারণ করা আবশ্যক"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "সিংক ইনপুট ইন্ডেক্স বৈধ নয়"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "sink-র নাম/ইন্ডেক্স ও একটি নিঃশব্দতার বুলিয়ান উল্লেখ করা আবশ্যক"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "অবৈধ স্যাম্পেল নির্ধারিত"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "উৎসের নাম/ইন্ডেক্স ও নিঃশব্দতার বুলিয়ান উল্লেখ করা আবশ্যক"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "সিংক ইনপুট ইন্ডেক্স ও নিঃশব্দতার বুলিয়ান নির্ধারণ করা আবশ্যক"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "অবৈধ সিংক ইনপুট ইন্ডেক্স নির্ধারিত"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "উৎসের নাম/ইন্ডেক্স ও নিঃশব্দতার বুলিয়ান উল্লেখ করা আবশ্যক"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "অবৈধ সিংক ইনপুট ইন্ডেক্স নির্ধারিত"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "sink-র নাম/ইন্ডেক্স ও একটি নিঃশব্দতার বুলিয়ান উল্লেখ করা আবশ্যক"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "কোনো বৈধ কমান্ড নির্ধারিত হয়নি।"
 
@@ -2223,103 +2449,103 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "কমান্ড-লাইন পার্স করতে ব্যর্থ।\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "সার্ভার: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "সোর্স: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "সিংক: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "কুকি: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "কুকি সংক্রান্ত তথ্য পার্স করতে ব্যর্থ\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "কুকি সংক্রান্ত তথ্য সংরক্ষণ করতে ব্যর্থ\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "ক্লায়েন্ট কনফিগারেশন ফাইল লোড করতে ব্যর্থ।\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "পরিবেশ কনফিগারেশন সংক্রান্ত তথ্য পড়তে ব্যর্থ।\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "FQDN প্রাপ্ত করতে ব্যর্থ।\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "কুকি সংক্রান্ত তথ্য লোড করতে ব্যর্থ\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "এখনো বাস্তবায়িত হয়নি।\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr "PulseAudio ডেমন চলছে না অথবা সেশানের ডেমন রূপে চলছে না।"
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "PulseAudio ডেমন kill করতে ব্যর্থ।"
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "ডেমন থেকে কোনো প্রতিক্রিয়া পাওয়া যাচ্ছে না।"
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "autospawn লক প্রয়োগ করতে ব্যর্থ।"
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2336,7 +2562,7 @@ msgstr ""
 "POLLOUT set দ্বারা চেতাবনী সৃষ্টি হয়েছে -- পরবর্তী snd_pcm_avail() থেকে 0 অথবা < "
 "min_avail-র থেকে কম অন্য একটি মান প্রাপ্ত হয়েছে।"
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2353,242 +2579,466 @@ msgstr ""
 "POLLIN set দ্বারা চেতাবনী সৃষ্টি হয়েছে -- পরবর্তী snd_pcm_avail() থেকে 0 অথবা < "
 "min_avail-র থেকে কম অন্য একটি মান প্রাপ্ত হয়েছে।"
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "বন্ধ"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "হাই-ফিডেলিটি প্লে-ব্যাক (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "হাই-ফিডেলিটি ক্যাপচার (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "টেলিফোনি ডুপ্লে (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "PulseAudio শব্দের সার্ভার"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
-msgstr ""
+msgstr "আউটপুট ডিভাইস"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
-msgstr ""
+msgstr "ইনপুট ডিভাইস"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
-msgstr ""
+msgstr "@HOSTNAME@-র মধ্যে অডিও"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
-msgstr ""
+msgstr "ইনপুট"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
-msgstr ""
+msgstr "ডকিং স্টেশন থেকে ইনপুট"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
-msgstr ""
+msgstr "ডকিং স্টেশনের মাইক্রোফোন"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "ডকিং স্টেশন থেকে ইনপুট"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "লাইন-ইন"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
-msgstr ""
+msgstr "মাইক্রোফোন"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
-msgid "External Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "ডকিং স্টেশনের মাইক্রোফোন"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
 #, fuzzy
+msgid "Rear Microphone"
+msgstr "মাইক্রোফোন"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "বহিস্থিত মাইক্রোফোন"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
-msgstr "à¦\85ভà§\8dযনà§\8dতরà§\80ণ à¦\85ডিà¦\93"
+msgstr "à¦\85ভà§\8dযনà§\8dতরà§\80ণ à¦®à¦¾à¦\87à¦\95à§\8dরà§\8bফà§\8bন"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
-msgstr ""
+msgstr "রেডিও"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
-msgstr ""
+msgstr "ভিডিও"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
-msgstr ""
+msgstr "স্বয়ংক্রিয় গেইন নিয়ন্ত্রণ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
-msgstr ""
+msgstr "স্বয়ংক্রিয় গেইন নিয়ন্ত্রণ প্রয়োগ করা হবে না"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
-msgstr ""
+msgstr "বুস্ট"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
-msgstr ""
+msgstr "বুস্ট প্রয়োগ করা হবে না"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
-msgstr ""
+msgstr "বিবর্ধক"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
-msgstr ""
+msgstr "বিবর্ধন প্রয়োগ করা হবে না"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "বুস্ট"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "বুস্ট প্রয়োগ করা হবে না"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "অ্যানালগ হেড-ফোন"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "অ্যানালগ ইনপুট"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "ডকিং স্টেশনের মাইক্রোফোন"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
-msgstr "Null ফলাফল"
+msgstr "অ্যানালগ আউটপুট"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "অ্যানালগ আউটপুট (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "লাইন-ইন"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
+msgstr "অ্যানালগ মোনো আউটপুট"
+
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "অ্যানালগ স্টিরিও"
+
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, fuzzy, c-format
-msgid "%s+%s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "ডিজিট্যাল স্টিরিও (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, fuzzy, c-format
-msgid "%s / %s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "ডিজিট্যাল স্টিরিও (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
-msgstr ""
+msgstr "অ্যানালগ মোনো"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
-msgstr "স্টিরিও"
+msgstr "à¦\85à§\8dযানালà¦\97 à¦¸à§\8dà¦\9fিরিà¦\93"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
-msgstr "সারাà¦\89নà§\8dড à§ª.১"
+msgstr "à¦\85à§\8dযানালà¦\97 à¦¸à¦¾à¦°à¦¾à¦\89নà§\8dড à§¨.১"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
-msgstr "সারাà¦\89নà§\8dড à§ª.০"
+msgstr "à¦\85à§\8dযানালà¦\97 à¦¸à¦¾à¦°à¦¾à¦\89নà§\8dড à§©.০"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
-msgstr "সারাà¦\89নà§\8dড à§ª.১"
+msgstr "à¦\85à§\8dযানালà¦\97 à¦¸à¦¾à¦°à¦¾à¦\89নà§\8dড à§©.১"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
-msgstr "সারাউন্ড ৪.০"
+msgstr "à¦\85à§\8dযানালà¦\97 à¦¸à¦¾à¦°à¦¾à¦\89নà§\8dড à§ª.০"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
-msgstr "সারাউন্ড ৪.১"
+msgstr "à¦\85à§\8dযানালà¦\97 à¦¸à¦¾à¦°à¦¾à¦\89নà§\8dড à§ª.১"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
-msgstr "সারাউন্ড ৫.০"
+msgstr "à¦\85à§\8dযানালà¦\97 à¦¸à¦¾à¦°à¦¾à¦\89নà§\8dড à§«.০"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
-msgstr "সারাউন্ড ৫.১"
+msgstr "à¦\85à§\8dযানালà¦\97 à¦¸à¦¾à¦°à¦¾à¦\89নà§\8dড à§«.১"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
-msgstr "সারাà¦\89নà§\8dড à§ª.০"
+msgstr "à¦\85à§\8dযানালà¦\97 à¦¸à¦¾à¦°à¦¾à¦\89নà§\8dড à§¬.০"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
-msgstr "সারাà¦\89নà§\8dড à§ª.১"
+msgstr "à¦\85à§\8dযানালà¦\97 à¦¸à¦¾à¦°à¦¾à¦\89নà§\8dড à§¬.১"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
-msgstr "সারাà¦\89নà§\8dড à§ª.০"
+msgstr "à¦\85à§\8dযানালà¦\97 à¦¸à¦¾à¦°à¦¾à¦\89নà§\8dড à§­.০"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
-msgstr "সারাউন্ড ৭.১"
+msgstr "à¦\85à§\8dযানালà¦\97 à¦¸à¦¾à¦°à¦¾à¦\89নà§\8dড à§­.১"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
-msgstr ""
+msgstr "ডিজিট্যাল স্টিরিও (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "ডিজিট্যাল স্টিরিও (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
-msgstr ""
+msgstr "ডিজিট্যাল সারাউন্ড ৪.০ (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
-msgstr ""
+msgstr "ডিজিট্যাল সারাউন্ড ৫.১ (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
-msgstr ""
+msgstr "ডিজিট্যাল স্টিরিও (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "ডিজিট্যাল সারাউন্ড ৫.১ (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
-msgstr ""
+msgstr "অ্যানালগ মোনো ডুপ্লে"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
-msgstr ""
+msgstr "অ্যানালগ স্টিরিও ডুপ্লে"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
+msgstr "ডিজিট্যাল স্টিরিও ডুপ্লে (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Null ফলাফল"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "ইনপুট"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<name for the sink> sink_properties=<properties for the sink> "
+"master=<name of sink to filter> format=<sample format> rate=<sample rate> "
+"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
+"plugin name> label=<ladspa plugin label> control=<comma separated list of "
+"input control values>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
 msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] এই প্ল্যাটফর্মে rlimit সমর্থিত নয়।"
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() ব্যর্থ"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "সোর্সের আউটপুট #%u\n"
+#~ "\tড্রাইভার: %s\n"
+#~ "\tচিহ্নিত মডিউলের মালিকানাধীন: %s\n"
+#~ "\tক্লায়েন্ট: %s\n"
+#~ "\tসোর্স: %u\n"
+#~ "\tস্যাম্পেলের বৈশিষ্ট্য: %s\n"
+#~ "\tচ্যানেলের ম্যাপ: %s\n"
+#~ "\tবাফারের লেটেন্সি: %0.0f usec\n"
+#~ "\tসোর্সের লেটেন্সি: %0.0f usec\n"
+#~ "\tরি-স্যাম্পেলের পদ্ধতি: %s\n"
+#~ "\tবিবিধ বৈশিষ্ট্য:\n"
+#~ "\t\t%s\n"
+
+# reverting to english because the command line output gets messed up
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "ডিজিট্যাল সারাউন্ড ৪.০ (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "কম ফ্রিকোয়েন্সির নিঃসরণকারী"
index e9938df..6867f5e 100644 (file)
--- a/po/ca.po
+++ b/po/ca.po
@@ -5,7 +5,6 @@
 # Xavier Conde Rueda <xavi.conde@gmail.com>, 2008.
 # Agustí Grau <fletxa@gmail.com>, 2009.
 # Judith Pintó Subirada <judithp@gmail.com>
-# Josep Torné Llavall <josep.torne@gmail.com>, 2009
 #
 # This file is translated according to the glossary and style guide of
 # Softcatalà. If you plan to modify this file, please read first the page
 # us plau la pàgina de catalanització del projecte Fedora a:
 # http://www.softcatala.org/projectes/fedora/
 # i contacteu l'anterior traductor/a.
-#
+# Josep Torné Llavall <josep.torne@gmail.com>, 2009, 2012.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-09-12 11:40+0100\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:52+0000\n"
 "Last-Translator: Josep Torné Llavall <josep.torne@gmail.com>\n"
 "Language-Team: Catalan <fedora@softcatala.net>\n"
+"Language: ca\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -50,11 +45,11 @@ msgstr ""
 "Probablement es tracta d'un error del controlador de l'ALSA '%s'. Informeu "
 "d'aquest incident als desenvolupadors de l'ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
@@ -63,7 +58,20 @@ msgstr ""
 "Probablement es tracta d'un error del controlador de l'ALSA '%s'. Informeu "
 "d'aquest incident als desenvolupadors de l'ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() ha retornat un valor excepcionalment gran: %lu bytes (%lu "
+"ms).\n"
+"Probablement es tracta d'un error del controlador de l'ALSA '%s'. Informeu "
+"d'aquest incident als desenvolupadors de l'ALSA."
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -71,30 +79,33 @@ msgid ""
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 msgstr ""
-"snd_pcm_mmap_begin() ha retornat un valor excepcionalment gran: %lu bytes (%"
-"lu ms).\n"
+"snd_pcm_mmap_begin() ha retornat un valor excepcionalment gran: %lu bytes "
+"(%lu ms).\n"
 "Probablement es tracta d'un error del controlador de l'ALSA '%s'. Informeu "
 "d'aquest incident als desenvolupadors de l'ALSA."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "Conserva sempre almenys un conducte carregat fins i tot si és el nul"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "Sortida fingida"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "Conducte virtual LADSPA"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<nom per al conducte> sink_properties=<propietats per al conducte> "
 "master=<nom del conducte del filtre> format=<format de mostra> rate=<ràtio "
@@ -102,120 +113,126 @@ msgstr ""
 "pulgin=<nom del connector ladspa> label=<etiqueta del connector ladspa> "
 "control=<llista separada per comes dels valors de control d'entrada>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "Conducte NULL"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "Sortida nul·la"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "Audio intern"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "Mòdem"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "No s'ha trobat el carregador lt_dlopen original."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "No s'ha pogut allotjar el nou carregador dl."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "No s'ha pogut afegir bind-now-loader."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "S'ha obtingut la senyal %s."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "S'està sortint."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "No s'ha trobat l'usuari '%s'."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "No s'ha trobat el grup '%s'."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "S'han trobat l'usuari '%s' (UID %lu) i el grup '%s' (GID %lu)."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "El GID de l'usuari '%s' i del grup '%s' no coincideixen."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "El directori arrel de l'usuari '%s' no és '%s', s'ignorarà."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "No s'ha pogut crear '%s': %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "No s'ha pogut canviar la llista del grup: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "No s'ha pogut canviar el GID: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "No s'ha pogut canviar l'UID: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "S'han alliberat els permisos de root."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "El mode de sistema global no és compatible amb aquesta plataforma."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "S'ha produït un error en setrlimit(%s, (%u, %u)): %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "No s'ha pogut interpretar la línia d'ordres."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "El dimoni no s'està executant"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "El dimoni s'està executant amb PID %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "S'ha produït un error en matar el dimoni: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -223,163 +240,184 @@ msgstr ""
 "No és necessari executar aquesta aplicació com a root (excepte si "
 "s'especifica --system)"
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "Es requereixen privilegis de root."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "La opció --start no està suportada per a instàncies de sistema."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr ""
 "S'està executant en mode sistema, però no s'ha especificat l'opció --"
 "disallow-exit."
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
 "S'està executant en mode sistema, però no s'ha especificat l'opció --"
 "disallow-module-loading."
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr ""
 "S'està executant en mode sistema, es deshabilitarà el mode SHM forçosament."
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 "S'està executant en mode sistema, la sortida per temps d'inactivitat es "
 "deshabilita."
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "S'ha produït un error en adquirir stdio."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "Ha fallat la canonada: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "Ha fallat fork(): %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "Ha fallat read(): %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "S'ha produït un error en iniciar el dimoni."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "S'ha iniciat el dimoni."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "Ha fallat read(): %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Aquest és el PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Host de compilació: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "CFLAGS de compilació: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "S'està executant en el host: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "S'han trobat %u CPU's"
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "La mida de pàgina és de %lu bytes."
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Compilat amb suport per a Valgrind: sí"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Compilat amb suport per a Valgrind: no"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "S'està executant amb el mode valgrind: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "S'està executant en el host: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "Construcció optimitzada: sí"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "Construcció optmitzada: no"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG està definit, s'han desactivat totes les assercions."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr ""
 "FASTPATH està definit, només s'ha deshabilitat les assercions de camí ràpid."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "S'han habilitat totes les assercions."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "No s'ha pogut obtenir l'ID de la màquina"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "L'ID de la màquina és %s."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "L'ID de la sessió és %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "S'està utilitzant el directori d'execució %s."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "S'està utilitzant el directori d'estat %s."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "S'està utilitzant el directori dels móduls %s."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "S'està executant en mode sistema: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -395,15 +433,15 @@ msgstr ""
 "Si us plau, llegiu http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode per "
 "a una explicació de per què el mode sistema sol ser una mala idea."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "S'ha produït un error en pa_pid_file_create()."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "Estan disponibles els temporitzadors frescos d'alta resolució."
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -411,32 +449,32 @@ msgstr ""
 "Es recomana la utilització d'un nucli amb els temporitzadors d'alta "
 "resolució habilitats."
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "S'ha produït un error en pa_core_new()."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "S'ha produït un error en inicialitzar el dimoni."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "El dimoni s'ha iniciat sense cap mòdul carregat, no funcionarà."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "S'ha completat la inicialització del dimoni."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "S'ha iniciat l'aturada del dimoni."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "S'ha aturat el dimoni."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -473,15 +511,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -591,15 +627,15 @@ msgstr ""
 "  -n                                    No carreguis el fitxer de "
 "configuració per omissió\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -607,166 +643,169 @@ msgstr ""
 "--log-level necessita un argument de nivell de log (valor númeric 0..4 o "
 "debug, info, notice, warn, error)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr "Objectiu de log invàlid: utilitzeu 'syslog', 'stderr' o 'auto'."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--logtime necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Mètode de remostratge invàlid '%s'."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit necessita un argument booleà"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm necessita un argument booleà"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Nom: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "No hi ha informació del módul disponible\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Versió: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Descripció: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Autor: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Utilització: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "Càrrega: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "Advertència d'obsolescència: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Ruta: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Destí de registre incorrecte '%s'"
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Nivell de registre incorrecte '%s'."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Mètode de remostreig incorrecte '%s'."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] rlimit incorrecte '%s'."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit no disponible en aquesta plataforma."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Format de mostra incorrecte '%s'."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Velocitat de mostreig '%s'."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Canals de mostreig incorrectes '%s'."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] Mapa de canals incorrecte '%s'."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Nombre de fragments incorrecte '%s'."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Mida de fragment incorrecta '%s'."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Nivell de prioritat incorrecte '%s'."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Velocitat de mostreig '%s'."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Error en obrir el fitxer de configuració: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -774,12 +813,12 @@ msgstr ""
 "El mapa de canals especificat per omissió té un número de canals diferent "
 "del número de canals especificat per omissió."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Lectura del fitxer de configuració: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "Alliberant els privilegis."
 
@@ -791,6 +830,16 @@ msgstr "Sistema de so PulseAudio"
 msgid "Start the PulseAudio Sound System"
 msgstr "Inicialitza el sistema de so PulseAudio"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "Sistema de so PulseAudio"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "Inicialitza el sistema de so PulseAudio"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
@@ -820,8 +869,8 @@ msgid "Rear Right"
 msgstr "Posterior dreta"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Emissor de baixa freqüència"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -995,9 +1044,10 @@ msgstr "Superior posterior esquerra"
 msgid "Top Rear Right"
 msgstr "Superior posterior dreta"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(incorrecte)"
 
@@ -1025,334 +1075,351 @@ msgstr "Envolvent 5.1"
 msgid "Surround 7.1"
 msgstr "Envolvent 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "D'acord"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "S'ha denegat l'accès"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Ordre desconeguda"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "Argument incorrecte"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "L'entitat existeix"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "No existeix l'entitat"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "S'ha refusat la connexió"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "S'ha produït un error de protocol"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "S'ha esgotat el temps"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "No s'ha trobat la clau d'autorització"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "S'ha produït un error intern"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "S'ha finalitzat la connexió"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "S'ha matat l'entitat"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Servidor incorrecte"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "Ha fallat la inicialització del mòdul"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "Estat incorrecte"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Sense dades"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "Versió de protocol incorrecta"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "Massa gran"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "No suportat"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Codi d'error desconegut"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "No existeix l'extensió"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "Funcionalitat obsoleta"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "Manca la implementació"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "Client bifurcat"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "Error d'entrada/sortida"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "Dispositiu o recurs ocupat"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "Ha fallat XOpenDisplay()"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "Ha fallat pa_context_connect(): %s"
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "Ha fallat el parseig de les dades de la cookie"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "S'ha produït un error en obrir el fitxer de configuració '%s': %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "No s'ha carregat cap cookie. S'està intentant connectar sense aquesta."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "S'ha rebut un missatge per a una extensió desconeguda '%s'"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "S'ha produït un error en drenar el fluxe: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "Flux de reproducció drenat."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "S'està drenant la connexió amb el servidor."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "Ha fallat pa_stream_write(): %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "Ha fallat pa_stream_begin_write(): %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "Ha fallat pa_stream_peek(): %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "Flux creat correctament."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "Ha fallat pa_stream_get_buffer_attr(): %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 msgstr "Mètriques del búffer: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Mètriques del búffer: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr ""
-"S'estan utilitzant les especificacions de mostreig '%s', mapejat del canal '%"
-"s'."
+"S'estan utilitzant les especificacions de mostreig '%s', mapejat del canal "
+"'%s'."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "S'ha connectat al dispositiu %s (%u, %ssuspès)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "S'ha produït un error en l'stream: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "Flux del dispositiu suspès.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "Flux del dispositiu reprès.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "Dades insuficients al flux.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "Desbordament de flux.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "S'ha iniciat el flux.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "S'ha mogut el flux al dispositiu %s (%u, %ssuspès).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "no "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "Els atributs del flux de memòria intermèdia han canviat.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "S'ha establert la connexió.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "Ha fallat pa_stream_new(): %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "Ha fallat pa_stream_connect_playback(): %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "Ha fallat pa_stream_connect_record(): %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "Ha fallat la connexió: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "S'ha llegit el fi del fitxer."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "Ha fallat write(): %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "S'ha rebut un senyal, s'està sortint."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "No s'ha pogut obtenir la latència: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Temps: %0.3f segs; Latència: %0.0f microsegs."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "Ha fallat pa_stream_update_timing_info(): %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1404,10 +1471,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [opcions]\n"
@@ -1467,7 +1539,7 @@ msgstr ""
 "      --list-file-formats               Llista disponible de formats de "
 "fitxer.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1478,68 +1550,68 @@ msgstr ""
 "Compilat amb libpulse %s\n"
 "Enllaçat amb libpulse %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "Nom del client invàlid '%s'"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "Nom de flux de dades invàlid '%s'"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "Mapa de canals invàlid '%s'"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "Especificació de latència invàlida '%s'"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "Especificació de temps de procés invàlida '%s'"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "Propietat invàlida '%s'"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "Format desconegut de fitxer %s."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "Especificació de mostra invàlida"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "Massa arguments."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "No s'ha pogut generar l'especificació de mostra del fitxer."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "No s'ha pogut obrir el fitxer d'àudio."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
@@ -1547,24 +1619,24 @@ msgstr ""
 "Advertència: l'especificació de mostra especificada se sobreescriurà amb "
 "l'especificació del fitxer."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "No s'ha pogut determinar l'especificació de mostra del fitxer."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr ""
 "Advertència: no s'ha pogut determinar el mapeig de canals des del fitxer."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "El mapa de canals no coincideix amb l'especificació de mostra"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "Advertència: no s'ha pogut escriure el mapa de canals en un fitxer."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
@@ -1572,80 +1644,85 @@ msgstr ""
 "S'està obrint un flux de dades %s amb especificació de mostra '%s' i mapa de "
 "canals '%s'."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "enregistrant"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "reproducció"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "No s'ha pogut interpretar la línia d'ordres."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "Ha fallat el pa_mainloop_new()."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "Ha fallat el io_new()."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "Ha fallat el pa_context_new()."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "Ha fallat pa_context_connect(): %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "Ha fallat el pa_context_new()."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "Ha fallat el pa_mainloop_run()."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "No s'ha pogut suspendre: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "No s'ha pogut en rependre: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "ADVERTÈNCIA: el sevidor de so no és local, no s'està suspenent.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Ha fallat la connexió: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "S'ha rebut SIGINT, s'està sortint.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "ADVERTÈNCIA: procés fill acabat pel senyal %u\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1690,37 +1767,48 @@ msgstr "Ha fallat el pa_context_new().\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "Ha fallat el pa_mainloop_run().\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "No s'han pogut obtenir les estadístiques: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr ""
 "Actualment s'estan utilitzant: %u blocs que contenen %s bytes en total.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr ""
 "Allotjats durant el temps de vida: %u blocs que contenen %s bytes en total.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "Mida de la memòria cau de mostres: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "No s'ha pogut obtenir la informació del servidor: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1728,7 +1816,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "Nom d'usuari: %s\n"
 "Nom del host: %s\n"
@@ -1740,13 +1828,13 @@ msgstr ""
 "Font per omissió: %s\n"
 "Galeta: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "No s'ha pogut obtenir la informació del conducte: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1762,7 +1850,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1784,22 +1872,27 @@ msgstr ""
 "\tPropietats:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tPorts:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tPort actiu: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tPorts:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "No s'ha pogut obtenir la informació de la font: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1838,20 +1931,20 @@ msgstr ""
 "\tPropietats:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "n/a"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "No s'ha pogut obtenir informació del mòdul: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1868,12 +1961,12 @@ msgstr ""
 "\tPropietats:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "No s'ha pogut obtenir informació del client: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1888,12 +1981,12 @@ msgstr ""
 "\tPropietats:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "No s'ha pogut obtenir la informació de la targeta: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1910,23 +2003,23 @@ msgstr ""
 "\tPropietats:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tPerfils:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tPerfil actiu: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "No s'ha pogut obtenir informació del conducte d'entrada: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1935,6 +2028,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1962,13 +2056,13 @@ msgstr ""
 "\tPropietats:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "No s'ha pogut obtenir la informació del conducte de sortida: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1977,31 +2071,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Sortida de la font #%u\n"
-"\tControladr: %s\n"
+"Conducte d'entrada #%u\n"
+"\tControlador: %s\n"
 "\tPropietari del mòdul: %s\n"
 "\tClient: %s\n"
-"\tFont: %u\n"
+"\tConducte: %u\n"
 "\tEspecificació de mostra: %s\n"
 "\tMapa de canals: %s\n"
+"\tSilenciat: %s\n"
+"\tVolum: %s\n"
+"\t        %s\n"
+"\t        balanç %0.2f\n"
 "\tLatència de búffer: %0.0f microsegs.\n"
-"\tLatència de la font: %0.0f microsegs.\n"
+"\tLatència del conducte: %0.0f microsegs.\n"
 "\tMètode de remostreig: %s\n"
 "\tPropietats:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "No s'ha pogut obtenir informació de la mostra: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -2032,48 +2135,164 @@ msgstr ""
 "\tPropietats:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "Ha fallat: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "No s'ha pogut obtenir la informació de la font: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "No s'ha pogut pujar la mostra: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "S'ha trobat un fi de fitxer prematurament"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr "conducte"
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr "font"
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+#, fuzzy
+msgid "source-output"
+msgstr "font"
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "Servidor incorrecte"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "S'ha rebut SIGINT, s'està sortint."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "Especificació de volum invàlida"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2083,36 +2302,15 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [opcions] stat\n"
-"%s [opcions] list\n"
-"%s [opcions] exit\n"
-"%s [opcions] upload-sample NOMFITXER [NOM]\n"
-"%s [opcions] play-sample NOM [CONDUCTE]\n"
-"%s [opcions] remove-sample NOM\n"
-"%s [opcions] move-sink-input CONDUCTEENTRADA CONDUCTE\n"
-"%s [opcions] move-source-output FONTSORTIDA FONT\n"
-"%s [opcions] load-module NOM [ARGUMENTS ...]\n"
-"%s [opcions] unload-module MÒDUL\n"
-"%s [opcions] suspend-sink CONDUCTE 1|0\n"
-"%s [opcions] suspend-source FONT 1|0\n"
-"%s [opcions] set-card-profile TARGETA PERFIL \n"
-"%s [opcions] set-sink-port CONDUCTE PORT \n"
-"%s [opcions] set-source-port FONT PORT \n"
-"%s [options] set-sink-volume CONDUCTE VOLUM\n"
-"%s [options] set-source-volume FONT VOLUM\n"
-"%s [options] set-sink-input-volume CONDUCTEENTRADA VOLUM\n"
-"%s [options] set-sink-mute CONDUCTE 1|0\n"
-"%s [options] set-source-mute FONT 1|0\n"
-"%s [options] set-sink-input-mute CONDUCTEENTRADA 1|0\n"
+"%s [opcions] ... \n"
 "\n"
 "  -h, --help                            Mostra aquesta ajuda\n"
 "      --version                         Mostra la versió\n"
+"  -s, --server=SERVIDOR                 Nom del servidor al qual connectar-"
+"se\n"
 "\n"
-"  -s, --server=SERVIDOR                 Nom del servidor on connectar-s'hi\n"
-"  -n, --client-name=NOM                 Com cridar aquest client en el "
-"servidor\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2123,111 +2321,144 @@ msgstr ""
 "Compilat amb libpulse %s\n"
 "Enllaçat amb libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "Si us plau, especifiqueu un fitxer de mostra per a carregar"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "No s'ha pogut obrir el fitxer de so."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr ""
 "Advertiment: No s'ha pogut determinar l'especificació de mostra a partir del "
 "fitxer."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "Heu d'especificar un nom de mostra a reproduir"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "Heu d'especificar un nom de mostra a suprimir"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "Heu d'especificar una entrada del conducte i un conducte"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "Heu d'especificar un índex de font de sortida i una font"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "Heu d'especificar un nom de mòdul i els seus arguments."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "Heu d'especificar un índex de mòdul"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "No haríeu d'especificar més d'un conducte. Heu d'especificar un valor booleà."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr ""
 "No haríeu d'especificar més d'una font. Heu d'especificar un valor booleà."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "Heu d'especificar un nom o un índex de targeta i un nom de perfil"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "Heu d'especificar un nom o un índex de conducte i un nom de port"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "Heu d'especificar un nom o un índex de font i un nom de port"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "Heu d'especificar un nom o un índex de conducte i un volum"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "Especificació de volum invàlida"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "Heu d'especificar un nom o un índex de font i un volum"
 
 #
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "Heu d'especificar un índex entrada del conducte i un volum"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "Índex d'entrada del conducte invàlid"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "Heu d'especificar un índex de font de sortida i una font"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "Índex d'entrada del conducte invàlid"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr ""
 "Heu d'especificar un nom o un índex de conducte i un booleà de silenciat"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "Especificació de mostra invàlida"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "Heu d'especificar un nom o un índex de font i un booleà de silenciat"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr ""
 "Heu d'especificar un índex d'entrada del conducte i un booleà de silenciat"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "Especificació d'índex d'entrada del conducte invàlida"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "Heu d'especificar un nom o un índex de font i un booleà de silenciat"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "Especificació d'índex d'entrada del conducte invàlida"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr ""
+"Heu d'especificar un nom o un índex de conducte i un booleà de silenciat"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "Ordre especificada no vàlida."
 
@@ -2257,105 +2488,105 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "No s'ha pogut analitzar la línia d'ordres.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Servidor: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Font: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Conducte: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Galeta: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "No s'han pogut parsejar les dades de la galeta\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "No s'han pogut desar les dades de la galeta\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "No s'ha pogut carregar el fitxer de configuració del client.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "No s'han pogut llegir les dades de configuració de l'entorn.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "No s'ha pogut obtenir el nom de domini qualificat complet.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "No s'han pogut carregar les dades de la galeta\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Encara no s'ha implementat.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr ""
 "El dimoni PulseAudio no s'està executant, o no s'està executant com a dimoni "
 "de la sessió."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "No s'ha pogut matar el dimoni PulseAudio."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "El dimoni no respon."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "No s'ha pogut accedir al bloqueig d'autospawn."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2372,7 +2603,7 @@ msgstr ""
 "Ens han aixecat amb POLLOUT activat -- tanmateix una crida posterior a "
 "snd_pcm_avail() ha retornat 0 o un altre valor < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2389,253 +2620,487 @@ msgstr ""
 "Ens han aixecat amb POLLIN activat -- tanmateix una crida posterior a "
 "snd_pcm_avail() ha retornat 0 o un altre valor < min_avail."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "Inactiu"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "Reproducció d'alta fidelitat (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "Captura d'alta fidelitat (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Dúplex de telefonia (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "Servidor de so PulseAudio"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
 msgstr ""
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 #, fuzzy
 msgid "Input Devices"
 msgstr "Entrada %s"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 #, fuzzy
 msgid "Input"
 msgstr "Entrada %s"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
+msgstr "Audio intern"
+
+#: ../src/modules/alsa/alsa-mixer.c:2222
+msgid "Docking Station Line In"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
+#, fuzzy
 msgid "Microphone"
-msgstr ""
+msgstr "Mono analògic"
+
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "Mono analògic"
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "Mono analògic"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2227
 msgid "External Microphone"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 #, fuzzy
 msgid "Internal Microphone"
 msgstr "Audio intern"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
+#, fuzzy
 msgid "Radio"
-msgstr ""
+msgstr "Mono analògic"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
+#, fuzzy
 msgid "Video"
-msgstr ""
+msgstr "Estèreo analògic"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-#, fuzzy
-msgid "Analog Input"
-msgstr "Mono analògic"
+#: ../src/modules/alsa/alsa-mixer.c:2237
+msgid "Bass Boost"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-#, fuzzy
-msgid "Analog Microphone"
-msgstr "Mono analògic"
+#: ../src/modules/alsa/alsa-mixer.c:2238
+msgid "No Bass Boost"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
 #, fuzzy
-msgid "Analog Line-In"
+msgid "Headphones"
 msgstr "Mono analògic"
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
+#: ../src/modules/alsa/alsa-mixer.c:2301
 #, fuzzy
-msgid "Analog Radio"
+msgid "Analog Input"
 msgstr "Mono analògic"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-#, fuzzy
-msgid "Analog Video"
-msgstr "Estèreo analògic"
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2310
 #, fuzzy
 msgid "Analog Output"
 msgstr "Sortida nul·la"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-#, fuzzy
-msgid "Analog Headphones"
-msgstr "Mono analògic"
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
+#: ../src/modules/alsa/alsa-mixer.c:2313
+msgid "Line Out"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2314
 #, fuzzy
 msgid "Analog Mono Output"
 msgstr "Mono analògic"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, fuzzy, c-format
-msgid "%s+%s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "Estèreo analògic"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, fuzzy, c-format
-msgid "%s / %s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Estèreo digital (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Estèreo digital (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr "Mono analògic"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr "Estèreo analògic"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3758
 #, fuzzy
 msgid "Analog Surround 2.1"
 msgstr "Envolvent analògic 4.1 "
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3759
 #, fuzzy
 msgid "Analog Surround 3.0"
 msgstr "Envolvent analògic 4.0 "
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3760
 #, fuzzy
 msgid "Analog Surround 3.1"
 msgstr "Envolvent analògic 4.1 "
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr "Envolvent analògic 4.0 "
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr "Envolvent analògic 4.1 "
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr "Envolvent analògic 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr "Envolvent analògic 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3765
 #, fuzzy
 msgid "Analog Surround 6.0"
 msgstr "Envolvent analògic 4.0 "
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3766
 #, fuzzy
 msgid "Analog Surround 6.1"
 msgstr "Envolvent analògic 4.1 "
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3767
 #, fuzzy
 msgid "Analog Surround 7.0"
 msgstr "Envolvent analògic 4.0 "
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr "Envolvent analògic 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr "Estèreo digital (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
+#: ../src/modules/alsa/alsa-mixer.c:3770
 #, fuzzy
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "Envolvent digital 4.0 (IEC958/AC3)"
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Estèreo digital (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Envolvent digital 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Envolvent digital 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr "Estèreo digital (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Envolvent digital 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 #, fuzzy
 msgid "Analog Mono Duplex"
 msgstr "Mono analògic"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 #, fuzzy
 msgid "Analog Stereo Duplex"
 msgstr "Estèreo analògic"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 #, fuzzy
 msgid "Digital Stereo Duplex (IEC958)"
 msgstr "Estèreo digital (IEC958)"
 
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Sortida nul·la"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "Entrada %s"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<nom per al conducte> sink_properties=<propietats per al conducte> "
+"master=<nom del conducte del filtre> format=<format de mostra> rate=<ràtio "
+"de mostra> channels=<nombre de canals> channel_map=<mapa de canals> "
+"pulgin=<nom del connector ladspa> label=<etiqueta del connector ladspa> "
+"control=<llista separada per comes dels valors de control d'entrada>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit no disponible en aquesta plataforma."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "Ha fallat XOpenDisplay()"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Sortida de la font #%u\n"
+#~ "\tControladr: %s\n"
+#~ "\tPropietari del mòdul: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tFont: %u\n"
+#~ "\tEspecificació de mostra: %s\n"
+#~ "\tMapa de canals: %s\n"
+#~ "\tLatència de búffer: %0.0f microsegs.\n"
+#~ "\tLatència de la font: %0.0f microsegs.\n"
+#~ "\tMètode de remostreig: %s\n"
+#~ "\tPropietats:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [opcions] stat\n"
+#~ "%s [opcions] list\n"
+#~ "%s [opcions] exit\n"
+#~ "%s [opcions] upload-sample NOMFITXER [NOM]\n"
+#~ "%s [opcions] play-sample NOM [CONDUCTE]\n"
+#~ "%s [opcions] remove-sample NOM\n"
+#~ "%s [opcions] move-sink-input CONDUCTEENTRADA CONDUCTE\n"
+#~ "%s [opcions] move-source-output FONTSORTIDA FONT\n"
+#~ "%s [opcions] load-module NOM [ARGUMENTS ...]\n"
+#~ "%s [opcions] unload-module MÒDUL\n"
+#~ "%s [opcions] suspend-sink CONDUCTE 1|0\n"
+#~ "%s [opcions] suspend-source FONT 1|0\n"
+#~ "%s [opcions] set-card-profile TARGETA PERFIL \n"
+#~ "%s [opcions] set-sink-port CONDUCTE PORT \n"
+#~ "%s [opcions] set-source-port FONT PORT \n"
+#~ "%s [options] set-sink-volume CONDUCTE VOLUM\n"
+#~ "%s [options] set-source-volume FONT VOLUM\n"
+#~ "%s [options] set-sink-input-volume CONDUCTEENTRADA VOLUM\n"
+#~ "%s [options] set-sink-mute CONDUCTE 1|0\n"
+#~ "%s [options] set-source-mute FONT 1|0\n"
+#~ "%s [options] set-sink-input-mute CONDUCTEENTRADA 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Mostra aquesta ajuda\n"
+#~ "      --version                         Mostra la versió\n"
+#~ "\n"
+#~ "  -s, --server=SERVIDOR                 Nom del servidor on connectar-"
+#~ "s'hi\n"
+#~ "  -n, --client-name=NOM                 Com cridar aquest client en el "
+#~ "servidor\n"
+
+#, fuzzy
+#~ msgid "%s+%s"
+#~ msgstr "%s %s"
+
+#, fuzzy
+#~ msgid "%s / %s"
+#~ msgstr "%s %s"
+
+#, fuzzy
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Envolvent digital 4.0 (IEC958/AC3)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Emissor de baixa freqüència"
+
 #~ msgid "Invalid client name '%s'\n"
 #~ msgstr "Nom del client invàlid '%s'\n"
 
@@ -2928,9 +3393,3 @@ msgstr "Estèreo digital (IEC958)"
 #~ "Tipus: %s\n"
 #~ "Mòdul: %s\n"
 #~ "Arguments: %s\n"
-
-#~ msgid "sink"
-#~ msgstr "conducte"
-
-#~ msgid "source"
-#~ msgstr "font"
index 6d6c3a5..0d6689a 100644 (file)
--- a/po/cs.po
+++ b/po/cs.po
@@ -1,27 +1,24 @@
 # Czech translation of pulseaudio.
 # Copyright (C) 2008, 2009 the author(s) of pulseaudio.
 # This file is distributed under the same license as the pulseaudio package.
-# Petr Kovar <pknbe@volny.cz>, 2008, 2009.
+# Petr Kovar <pknbe@volny.cz>, 2008, 2009, 2012.
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-10-17 09:51+0000\n"
-"PO-Revision-Date: 2009-10-17 17:08+0200\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:52+0000\n"
 "Last-Translator: Petr Kovar <pknbe@volny.cz>\n"
 "Language-Team: Czech <translation-team-cs@lists.sourceforge.net>\n"
+"Language: cs\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
 "X-Generator: Lokalize 1.0\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -34,11 +31,11 @@ msgstr ""
 "S největší pravděpodobností se jedná o chybu v ovladači ALSA \"%s\". "
 "Nahlaste prosím tento problém vývojářům ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
@@ -47,7 +44,20 @@ msgstr ""
 "S největší pravděpodobností se jedná o chybu v ovladači ALSA \"%s\". "
 "Nahlaste prosím tento problém vývojářům ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() navrátil hodnotu, která je nezvykle vysoká: %lu bajtů (%lu "
+"ms).\n"
+"S největší pravděpodobností se jedná o chybu v ovladači ALSA \"%s\". "
+"Nahlaste prosím tento problém vývojářům ALSA."
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -55,30 +65,33 @@ msgid ""
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 msgstr ""
-"snd_pcm_mmap_begin() navrátil hodnotu, která je nezvykle vysoká: %lu bajtů (%"
-"lu ms).\n"
+"snd_pcm_mmap_begin() navrátil hodnotu, která je nezvykle vysoká: %lu bajtů "
+"(%lu ms).\n"
 "S největší pravděpodobností se jedná o chybu v ovladači ALSA \"%s\". "
 "Nahlaste prosím tento problém vývojářům ALSA."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "Udržuje nahraný vždy alespoň jeden cíl, i když se jedná o \"null\""
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "Prázdný výstup"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "Virtuální cíl LADSPA"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<název cíle> sink_properties=<vlastnosti cíle> master=<název "
 "filtrovaného cíle> format=<vzorkovací formát> rate=<vzorkovací frekvence> "
@@ -86,120 +99,126 @@ msgstr ""
 "modulu ladspa> label=<popisek zásuvného modulu ladspa> control=<čárkou "
 "oddělený seznam hodnot ovládání vstupu>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "Taktovaný cíl NULL"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "Výstup \"null\""
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "Vnitřní zvukový systém"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "Modem"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "Nezdařilo se nalézt původní nahrávací program lt_dlopen."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "Nezdařilo se přidělení nového nahrávacího programu dl."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "Nezdařilo se přidat bind-now-loader."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "Získán signál %s."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "Ukončování."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "Nezdařilo se nalézt uživatele \"%s\"."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "Nezdařilo se nalézt skupinu \"%s\"."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "Nalezen uživatel \"%s\" (UID %lu) a skupina \"%s\" (GID %lu)."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "GID uživatele \"%s\" a skupiny \"%s\" nesouhlasí."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "Domovský adresář uživatele \"%s\" není \"%s\", bude ignorováno."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Nezdařilo se vytvořit \"%s\": %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "Nezdařilo se změnit seznam skupin: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "Nezdařilo se změnit GID: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "Nezdařilo se změnit UID: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "Oprávnění superuživatele úspěšně zrušena."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "Režim celého systému není na této platformě podporován."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) selhalo: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "Nezdařila se analýza příkazového řádku."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "Démon neběží"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "Démon běží jako PID %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "Zabití démona se nezdařilo: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -207,155 +226,176 @@ msgstr ""
 "Tento program není určen ke spuštění pod superuživatelem (není-li zadáno --"
 "system)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "Jsou vyžadována oprávnění superuživatele."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start nepodporováno u systémových instancí."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "Běží v systémovém režimu, ale nenastaveno --disallow-exit!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr "Běží v systémovém režimu, ale nenastaveno --disallow-module-loading!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "Běží v systémovém režimu, vynuceně se vypíná režim SHM!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr "Běží v systémovém režimu, vynuceně se vypíná čas nečinnosti ukončení!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "Nezdařilo se získání stdio."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "pipe selhalo: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() selhalo: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() selhalo: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "Spuštění démona selhalo."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "Spuštění démona bylo úspěšné."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() selhalo: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Toto je PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Překladový počítač: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "Překladové CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "Běží na počítači: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "Nalezen následující počet CPU: %u."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "Velikost stránky je %lu bajtů"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Přeloženo s podporou Valgrind: ano"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Přeloženo s podporou Valgrind: ne"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "Běží v režimu valgrind: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "Běží na počítači: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "Optimalizované sestavení: ano"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "Optimalizované sestavení: ne"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG definováno, všechny výrazy zakázány."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH definováno, zakázány pouze výrazy rychlých cest."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "Všechny výrazy povoleny."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "Nezdařilo se získání ID počítače"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "ID počítače je %s."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "ID sezení je %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "Používán běhový adresář %s."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "Používán stavový adresář %s."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "Používán adresář modulů %s."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Běží v systémovém režimu: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -371,16 +411,16 @@ msgstr ""
 "Vysvětlení, proč je systémový režim obvykle velmi špatný nápad, si můžete "
 "přečíst na http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() selhalo."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr ""
 "Jsou dostupné výtečné časovače o vysokém rozlišení. Tak s chutí do toho!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -388,32 +428,32 @@ msgstr ""
 "Sorry, vole, kernel error! Tip šéfkuchaře na dnešní den zní: Linux se "
 "zapnutými časovači o vysokém rozlišení."
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() selhalo."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "Selhalo spuštění démona."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Spuštění démona bez jakýchkoliv nahraných modulů, běh bude odmítnut."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "Spuštění démona dokončeno."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "Vypínání démona spuštěno."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "Démon ukončen."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -450,15 +490,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -558,15 +596,15 @@ msgstr ""
 "\n"
 "  -n                                    Nenahraje výchozí soubor skriptu\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize předpokládá booleovský argument"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail předpokládá booleovský argument"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -574,167 +612,170 @@ msgstr ""
 "--log-level předpokládá argument protokolovací úrovně (buď číselný v rozmezí "
 "0..4, nebo jeden z debug, info, notice, warn, error)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority předpokládá booleovský argument"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime předpokládá booleovský argument"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading předpokládá booleovský argument"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit předpokládá booleovský argument"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file předpokládá booleovský argument"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr ""
 "Neplatný cíl protokolu: použijte buďto \"syslog\", \"stderr\" nebo \"auto\"."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time předpokládá booleovský argument"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta předpokládá booleovský argument"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Neplatná metoda převzorkování \"%s\"."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system předpokládá booleovský argument"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit předpokládá booleovský argument"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm předpokládá booleovský argument"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Název: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "O modulu nejsou dostupné žádné informace\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Verze: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Popis: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Autor: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Použití: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "Načíst jednou: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "VAROVÁNÍ ZASTARALOSTI: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Cesta: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Neplatný protokolovací cíl \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Neplatná protokolovací úroveň \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Neplatná metoda převzorkování \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] Neplatné rlimit \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit na této platformě není podporováno."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Neplatný vzorkovací formát \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Neplatná vzorkovací frekvence \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Neplatné vzorkovací kanály \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] Neplatná mapa kanálů \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Neplatný počet fragmentů \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Neplatná velikost fragmentu \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Neplatná úroveň nice \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Neplatná vzorkovací frekvence \"%s\"."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Nezdařilo se otevřít konfigurační soubor: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -742,12 +783,12 @@ msgstr ""
 "Zadaná výchozí mapa kanálů obsahuje odlišný počet kanálů než je zadaný "
 "výchozí počet kanálů."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Čtení z konfiguračního souboru: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "Rušení oprávnění."
 
@@ -759,6 +800,16 @@ msgstr "Zvukový systém PulseAudio"
 msgid "Start the PulseAudio Sound System"
 msgstr "Spustit zvukový systém PulseAudio"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "Zvukový systém PulseAudio"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "Spustit zvukový systém PulseAudio"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
@@ -788,8 +839,8 @@ msgid "Rear Right"
 msgstr "Zadní pravý"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Nízkofrekvenční zářič"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -963,9 +1014,10 @@ msgstr "Horní zadní levý"
 msgid "Top Rear Right"
 msgstr "Horní zadní pravý"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(neplatné)"
 
@@ -993,333 +1045,350 @@ msgstr "Surround 5.1"
 msgid "Surround 7.1"
 msgstr "Surround 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "Budiž"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "Přístup odepřen"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Neznámý příkaz"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "Neplatný argument"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "Entita existuje"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "Taková entita neexistuje"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "Spojení odmítnuto"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "Chyba protokolu"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "Časový limit"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "Bez autorizačního klíče"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "Vnitřní chyba"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "Spojení přerušeno"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "Entita zabita"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Neplatný server"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "Spuštění modulu selhalo"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "Chybný stav"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Žádná data"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "Nekompatibilní verze protokolu"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "Příliš velké"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "Nepodporováno"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Neznámý chybový kód"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "Takové rozšíření neexistuje"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "Zastaralá vlastnost"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "Scházející implementace"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "Klient rozvětven"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "Chyba vstupu/výstupu"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "Zařízení nebo zdroj se používá"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() selhalo"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() selhalo: %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "Selhala analýza dat cookie"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Selhalo otevření konfiguračního souboru \"%s\": %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "Žádný soubor cookie nenahrán. Pokus o spojení bez tohoto kroku."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "Přijata zpráva pro neznámé rozšíření \"%s\""
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "Nezdařilo se vyprázdnit proud: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "Proud přehrávání vyprázdněn."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "Vyprazdňování spojení se serverem."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() selhalo: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_begin_write() selhalo: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() selhalo: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "Proud úspěšně vytvořen."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() selhalo: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 msgstr ""
 "Metrika vyrovnávací paměti: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Metrika vyrovnávací paměti: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "Používáno určení vzorku \"%s\", mapa kanálů \"%s\"."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "Připojeno k zařízení %s (%u, %ssuspended)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "Chyba proudu: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "Proudové zařízení pozastaveno.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "Proudové zařízení obnoveno.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "Podběhnutí proudu.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "Přeběhnutí proudu.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "Proud spuštěn.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "Proud přesunut na zařízení %s (%u, %ssuspended).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "nikoliv "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "Změněny atributy vyrovnávací paměti proudu.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "Spojení navázáno.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() selhalo: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() selhalo: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() selhalo: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "Spojení selhalo: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "Získáno EOF."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() selhalo: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "Získán signál, ukončování."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "Nezdařilo se získat latenci: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Čas: %0.3f sekund; latence: %0.0f μs"
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() selhalo: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1371,10 +1440,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [přepínače]\n"
@@ -1429,7 +1503,7 @@ msgstr ""
 "      --list-file-formats               Zobrazí seznam dostupných formátů "
 "souborů.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1440,170 +1514,175 @@ msgstr ""
 "Přeloženo s libpulse %s\n"
 "Propojeno s libpulse %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "Neplatný název klienta \"%s\""
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "Neplatný název proudu \"%s\""
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "Neplatná mapa kanálů \"%s\""
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "Neplatné upřesnění latence \"%s\""
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "Neplatné upřesnění času zpracování \"%s\""
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "Neplatná vlastnost \"%s\""
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "Neznámý formát souboru %s."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "Neplatné určení vzorku"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "Příliš mnoho argumentů."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "Selhalo vytvoření určení vzorku souboru."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "Selhalo otevření zvukového souboru."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
 msgstr ""
 "Varování: zadané určení vzorku bude přepsáno určením získaným ze souboru."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "Selhalo zjištění určení vzorku ze souboru."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "Varování: Selhalo zjištění mapy kanálů ze souboru."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "Mapa kanálů se neshoduje s určením vzorku"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "Varování: selhal zápis mapy kanálů do souboru."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr "Otevírání proudu %s s určením vzorku \"%s\" a mapou kanálů \"%s\"."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "nahrávání"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "přehrávání"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "Nezdařila se analýza příkazového řádku."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() selhalo."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() selhalo."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() selhalo."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() selhalo: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_rttime_new() selhalo."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() selhalo."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "Nezdařilo se pozastavení: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "Nezdařilo se obnovení: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "VAROVÁNÍ: Zvukový server není místní, nedojde k pozastavení.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Spojení selhalo: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "Získáno SIGINT, ukončování.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "VAROVÁNÍ: Proces potomka ukončen signálem %u\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1647,35 +1726,46 @@ msgstr "pa_context_new() selhalo.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() selhalo.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "Selhalo získání statistik: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "Právě používáno: %u bloků obsahujících celkem %s bajtů.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "Alokováno během celého běhu: %u bloků obsahujících celkem %s bajtů.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "Velikost vzorkovací vyrovnávací paměti: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "Nezdařilo se získání informací o serveru: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1683,7 +1773,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "Uživatelské jméno: %s\n"
 "Název počítače: %s\n"
@@ -1695,13 +1785,13 @@ msgstr ""
 "Výchozí zdroj: %s\n"
 "Cookie: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "Nezdařilo se získání informací o cíli: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1717,7 +1807,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1739,22 +1829,27 @@ msgstr ""
 "\tVlastnosti:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tPorty:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tAktivní port: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tPorty:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "Nezdařilo se získání informací o zdroji: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1793,20 +1888,20 @@ msgstr ""
 "\tVlastnosti:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "nic"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "Selhalo získání informací o modulu: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1823,12 +1918,12 @@ msgstr ""
 "\tVlastnosti:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "Selhalo získání informací o klientu: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1843,12 +1938,12 @@ msgstr ""
 "\tVlastnosti:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "Selhalo získání informací o kartě: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1865,23 +1960,23 @@ msgstr ""
 "\tVlastnosti:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tProfily:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tAktivní profil: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "Nezdařilo se získání informací o vstupu cíle: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1890,6 +1985,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1917,13 +2013,13 @@ msgstr ""
 "\tVlastnosti:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "Selhalo získání informace o výstupu zdroje: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1932,31 +2028,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Výstup zdroje č. %u\n"
+"Vstup cíle č. %u\n"
 "\tOvladač: %s\n"
 "\tModul vlastníka: %s\n"
 "\tKlient: %s\n"
-"\tZdroj: %u\n"
+"\tCíl: %u\n"
 "\tUrčení vzorku: %s\n"
 "\tMapa kanálů: %s\n"
+"\tZtlumení: %s\n"
+"\tHlasitost: %s\n"
+"\t        %s\n"
+"\t        vyvážení %0.2f\n"
 "\tLatence vyrovnávací paměti: %0.0f μs\n"
-"\tLatence zdroje: %0.0f μs\n"
+"\tLatence cíle: %0.0f μs\n"
 "\tMetoda převzorkování: %s\n"
 "\tVlastnosti:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "Selhalo získání informace o vzorku: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1987,48 +2092,163 @@ msgstr ""
 "\tVlastnosti:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "Selhání: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Nezdařilo se získání informací o zdroji: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "Selhalo nahrání vzorku: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "Předčasný konec souboru"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "Neplatný server"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "Získáno SIGINT, ukončování."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "Neplatné určení hlasitosti"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2038,36 +2258,14 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [přepínače] stat\n"
-"%s [přepínače] list\n"
-"%s [přepínače] exit\n"
-"%s [přepínače] upload-sample NÁZEVSOUBORU [NÁZEV]\n"
-"%s [přepínače] play-sample NÁZEV [CÍL]\n"
-"%s [přepínače] remove-sample NÁZEV\n"
-"%s [přepínače] move-sink-input VSTUPCÍLE CÍL\n"
-"%s [přepínače] move-source-output VÝSTUPZDROJE ZDROJ\n"
-"%s [přepínače] load-module NÁZEV [ARG ...]\n"
-"%s [přepínače] unload-module MODUL\n"
-"%s [přepínače] suspend-sink CÍL 1|0\n"
-"%s [přepínače] suspend-source ZDROJ 1|0\n"
-"%s [přepínače] set-card-profile KARTA PROFIL\n"
-"%s [přepínače] set-sink-port CÍL PORT\n"
-"%s [přepínače] set-source-port ZDROJ PORT\n"
-"%s [přepínače] set-sink-volume CÍL HLASITOST\n"
-"%s [přepínače] set-source-volume ZDROJ HLASITOST\n"
-"%s [přepínače] set-sink-input-volume VSTUPCÍLE HLASITOST\n"
-"%s [přepínače] set-sink-mute CÍL 1|0\n"
-"%s [přepínače] set-source-mute ZDROJ 1|0\n"
-"%s [přepínače] set-sink-input-mute VSTUPCÍLE 1|0\n"
+"%s [přepínače] ... \n"
 "\n"
 "  -h, --help                            Zobrazí tuto nápovědu\n"
 "      --version                         Zobrazí verzi\n"
-"\n"
 "  -s, --server=SERVER                   Název připojovaného serveru\n"
-"  -n, --client-name=NÁZEV               Způsob volání tohoto klienta na "
-"serveru\n"
+"\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2078,104 +2276,136 @@ msgstr ""
 "Přeloženo s libpulse %s\n"
 "Propojeno s libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "Zadejte prosím soubor se vzorkem určeným k nahrání"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "Selhalo otevření zvukového souboru."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "Varování: Selhalo zjištění určení vzorku ze souboru."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "Je nutné zadat název vzorku určeného k přehrání"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "Je nutné zadat název vzorku určeného k odstranění"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "Je nutné zadat vstup cíle a cíl"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "Je nutné zadat index výstupu zdroje a zdroj"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "Je nutné zadat název modulu a argumenty."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "Je nutné zadat index modulu"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr "Nelze zadat více než jeden cíl. Je nutné zadat booleovskou hodnotu."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr "Nelze zadat více než jeden zdroj. Je nutné zadat booleovskou hodnotu."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "Je nutné upřesnit název karty/indexu a název profilu"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "Je nutné upřesnit název cíle/indexu a název portu"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "Je nutné upřesnit název zdroje/indexu a název portu"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "Je nutné upřesnit název cíle/indexu a hlasitost"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "Neplatné určení hlasitosti"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "Je nutné upřesnit název zdroje/indexu a hlasitost"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "Je nutné zadat index vstupu cíle a hlasitost"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "Neplatný index vstupu cíle"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "Je nutné zadat index výstupu zdroje a zdroj"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "Neplatný index vstupu cíle"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "Je nutné upřesnit název cíle/indexu a booleovskou hodnotu ztlumení"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "Neplatné určení vzorku"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "Je nutné upřesnit název zdroje/indexu a booleovskou hodnotu ztlumení"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "Je nutné zadat index vstupu cíle a booleovskou hodnotu ztlumení"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "Neplatné určení indexu vstupu cíle"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "Je nutné upřesnit název zdroje/indexu a booleovskou hodnotu ztlumení"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "Neplatné určení indexu vstupu cíle"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "Je nutné upřesnit název cíle/indexu a booleovskou hodnotu ztlumení"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "Nezadán žádný platný příkaz."
 
@@ -2203,103 +2433,103 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "Selhala analýza příkazového řádku.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Server: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Zdroj: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Cíl: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Cookie: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "Nezdařilo se analyzovat data cookie\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "Nezdařilo se uložit data cookie\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "Nezdařilo se nahrát konfigurační soubor klienta.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "Nezdařilo se přečtení konfiguračních dat prostředí.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "Nezdařilo se získání FQDN.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "Nezdařilo se nahrát data cookie\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Doposud neimplementováno.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr "Neběží žádný démon PulseAudio, nebo neběží jako démon sezení."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "Nezdařilo se zabít démona PulseAudio."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "Démon neodpovídá."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "Nelze přistoupit k zámku automatického spouštění."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2316,7 +2546,7 @@ msgstr ""
 "Probudilo nás nastavení POLLOUT - nicméně následné snd_pcm_avail() vrátilo 0 "
 "či jinou hodnotu < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2333,232 +2563,468 @@ msgstr ""
 "Probudilo nás nastavení POLLIN - nicméně následné snd_pcm_avail() vrátilo 0 "
 "či jinou hodnotu < min_avail."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "Vypnuto"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "Přehrávání s velmi věrnou reprodukcí (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "Záznam s velmi věrnou reprodukcí (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Duplexní telefonie (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "Zvukový server PulseAudio"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
 msgstr "Výstupní zařízení"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
 msgstr "Vstupní zařízení"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
 msgstr "Zvuk na @HOSTNAME@"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
 msgstr "Vstup"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
 msgstr "Vstup dokovací stanice"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
 msgstr "Mikrofon dokovací stanice"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "Vstup dokovací stanice"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
 msgstr "Linkový vstup"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
 msgstr "Mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "Mikrofon dokovací stanice"
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "Mikrofon"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
 msgid "External Microphone"
 msgstr "Externí mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
 msgstr "Interní mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
 msgstr "Rádio"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
 msgstr "Obraz"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
 msgstr "Automatické ovládání zesílení"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
 msgstr "Bez automatického ovládání zesílení"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
 msgstr "Zesílení"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
 msgstr "Bez zesílení"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
 msgstr "Zesilovač"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
 msgstr "Bez zesilovače"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr "Analogový vstup"
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "Zesílení"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr "Analogový mikrofon"
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "Bez zesílení"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
-msgstr "Analogový linkový vstup"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr "Analogové rádio"
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "Analogová sluchátka"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr "Analogový obraz"
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "Analogový vstup"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "Mikrofon dokovací stanice"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
 msgstr "Analogový výstup"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr "Analogová sluchátka"
-
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
 msgstr "Analogový výstup (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "Linkový vstup"
+
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
 msgstr "Analogový výstup mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, c-format
-msgid "%s+%s"
-msgstr "%s+%s"
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "Analogové stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, c-format
-msgid "%s / %s"
-msgstr "%s / %s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Digitální stereo (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Digitální stereo (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr "Analogové mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr "Analogové stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
 msgstr "Analogový Surround 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
 msgstr "Analogový Surround 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
 msgstr "Analogový Surround 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr "Analogový Surround 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr "Analogový Surround 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr "Analogový Surround 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr "Analogový Surround 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
 msgstr "Analogový Surround 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
 msgstr "Analogový Surround 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
 msgstr "Analogový Surround 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr "Analogový Surround 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr "Digitální stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "Digitální Surround 4.0 (IEC958)"
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Digitální stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Digitální Surround 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Digitální Surround 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr "Digitální stereo (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Digitální Surround 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
 msgstr "Analogové duplexní mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
 msgstr "Analogové duplexní stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
 msgstr "Digitální duplexní stereo (IEC958)"
 
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Výstup \"null\""
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "Vstup"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<název cíle> sink_properties=<vlastnosti cíle> master=<název "
+"filtrovaného cíle> format=<vzorkovací formát> rate=<vzorkovací frekvence> "
+"channels=<počet kanálů> channel_map=<mapa kanálů> plugin=<název zásuvného "
+"modulu ladspa> label=<popisek zásuvného modulu ladspa> control=<čárkou "
+"oddělený seznam hodnot ovládání vstupu>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit na této platformě není podporováno."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() selhalo"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Výstup zdroje č. %u\n"
+#~ "\tOvladač: %s\n"
+#~ "\tModul vlastníka: %s\n"
+#~ "\tKlient: %s\n"
+#~ "\tZdroj: %u\n"
+#~ "\tUrčení vzorku: %s\n"
+#~ "\tMapa kanálů: %s\n"
+#~ "\tLatence vyrovnávací paměti: %0.0f μs\n"
+#~ "\tLatence zdroje: %0.0f μs\n"
+#~ "\tMetoda převzorkování: %s\n"
+#~ "\tVlastnosti:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [přepínače] stat\n"
+#~ "%s [přepínače] list\n"
+#~ "%s [přepínače] exit\n"
+#~ "%s [přepínače] upload-sample NÁZEVSOUBORU [NÁZEV]\n"
+#~ "%s [přepínače] play-sample NÁZEV [CÍL]\n"
+#~ "%s [přepínače] remove-sample NÁZEV\n"
+#~ "%s [přepínače] move-sink-input VSTUPCÍLE CÍL\n"
+#~ "%s [přepínače] move-source-output VÝSTUPZDROJE ZDROJ\n"
+#~ "%s [přepínače] load-module NÁZEV [ARG ...]\n"
+#~ "%s [přepínače] unload-module MODUL\n"
+#~ "%s [přepínače] suspend-sink CÍL 1|0\n"
+#~ "%s [přepínače] suspend-source ZDROJ 1|0\n"
+#~ "%s [přepínače] set-card-profile KARTA PROFIL\n"
+#~ "%s [přepínače] set-sink-port CÍL PORT\n"
+#~ "%s [přepínače] set-source-port ZDROJ PORT\n"
+#~ "%s [přepínače] set-sink-volume CÍL HLASITOST\n"
+#~ "%s [přepínače] set-source-volume ZDROJ HLASITOST\n"
+#~ "%s [přepínače] set-sink-input-volume VSTUPCÍLE HLASITOST\n"
+#~ "%s [přepínače] set-sink-mute CÍL 1|0\n"
+#~ "%s [přepínače] set-source-mute ZDROJ 1|0\n"
+#~ "%s [přepínače] set-sink-input-mute VSTUPCÍLE 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Zobrazí tuto nápovědu\n"
+#~ "      --version                         Zobrazí verzi\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   Název připojovaného serveru\n"
+#~ "  -n, --client-name=NÁZEV               Způsob volání tohoto klienta na "
+#~ "serveru\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Digitální Surround 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Nízkofrekvenční zářič"
+
 #~ msgid "Invalid client name '%s'\n"
 #~ msgstr "Neplatný název klienta \"%s\"\n"
 
index 38a5006..7d7cc6a 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -1,30 +1,30 @@
+# translation of pulseaudio.master-tx.de.po to
 # German translation of pulseaudio
 # Copyright (C) 2008 pulseaudio
 # This file is distributed under the same license as the pulseaudio package.
 #
+#
 # Fabian Affolter <fab@fedoraproject.org>, 2008-2009.
 # Micha Pietsch <barney@fedoraproject.org>, 2008, 2009.
+# Hedda Peters <hpeters@redhat.com>, 2009, 2012.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: pulseaudio\n"
+"Project-Id-Version: pulseaudio.master-tx.de\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-09-28 16:49+0100\n"
-"Last-Translator: Joerg (kital) Simon <jsimon@fedoraproject.org>\n"
-"Language-Team: German <fedora-trans-de@redhat.com>\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:52+0000\n"
+"Last-Translator: Hedda Peters <hpeters@redhat.com>\n"
+"Language-Team: \n"
+"Language: \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"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 "X-Poedit-Language: German\n"
+"X-Generator: KBabel 1.11.4\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -32,25 +32,38 @@ msgid ""
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 msgstr ""
-"snd_pcm_avail() gibt einen Wert zurück, welche außerordentlich groß ist: %lu "
+"snd_pcm_avail() gibt einen Wert zurück, der ausserordentlich gross ist: %lu "
 "bytes (%lu ms).\n"
 "Dies ist wahrscheinlich ein Fehler im ALSA-Treiber '%s'. Bitte melden Sie "
-"diesen Punkt den ALSA-Entwicklern."
+"dieses Problem den ALSA-Entwicklern."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
-"snd_pcm_delay() gibt einen Wert zurück, welche außerordentlich groß ist: %li "
+"snd_pcm_delay() gibt einen Wert zurück, der ausserordentlich gross ist: %li "
 "bytes (%s%lu ms).\n"
 "Dies ist wahrscheinlich ein Fehler im ALSA-Treiber '%s'. Bitte melden Sie "
-"diesen Punkt den ALSA-Entwicklern."
+"dieses Problem den ALSA-Entwicklern."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() gibt einen Wert zurück, der ausserordentlich gross ist: %lu "
+"bytes (%lu ms).\n"
+"Dies ist wahrscheinlich ein Fehler im ALSA-Treiber '%s'. Bitte melden Sie "
+"dieses Problem den ALSA-Entwicklern."
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -58,148 +71,160 @@ msgid ""
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 msgstr ""
-"snd_pcm_mmap_begin() gibt einen Wert zurück, welche außerordentlich groß "
-"ist: %lu bytes (%lu ms).\n"
+"snd_pcm_mmap_begin() gibt einen Wert zurück, der ausserordentlich gross ist: "
+"%lu bytes (%lu ms).\n"
 "Dies ist wahrscheinlich ein Fehler im ALSA-Treiber '%s'. Bitte melden Sie "
-"diesen Punkt den ALSA-Entwicklern."
+"dieses Problem den ALSA-Entwicklern."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
-msgstr ""
+msgstr "Hält stets einen Sink geladen, selbst wenn dies ein Null-Sink ist"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "Dummy-Ausgabe"
 
-#: ../src/modules/module-ladspa-sink.c:49
-#, fuzzy
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "Virtueller LADSPA-Sink"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
+"sink_name=<Name des Sinks> sink_properties=<Eigenschaften des Sinks> "
+"master=<Name des zu filternden Sinks> format=<Sample-Format> rate=<Sample-"
+"Rate> channels=<Anzahl der Channels> channel_map=<Channel-Map> "
+"plugin=<ladspa Plugin-Name> label=<ladspa Plugin-Label> "
+"control=<kommagetrennte Liste von Eingabekontrollwerten>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
-msgstr ""
+msgstr "Clocked NULL Sink"
 
-#: ../src/modules/module-null-sink.c:291
-#, fuzzy
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
-msgstr "Ausgang %s"
+msgstr "Null-Ausgabe"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "Internes Audio"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "Modem"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "Ursprünglicher dlopen-Loader konnte nicht gefunden werden."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "Neuer dlopen-Loader konnte nicht gefunden werden."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "Hinzufügen von Bind-Now-Loader fehlgeschlagen."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "Signal %s empfangen."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "Wird beendet."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "Benutzer '%s' nicht gefunden."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "Gruppe '%s' nicht gefunden."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "Benutzer '%s' (UID %lu) und Gruppe '%s' (GID %lu) gefunden."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "GID von Benutzer '%s' und Gruppe '%s' stimmen nicht überein."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "Benutzerverzeichnis von Benutzer '%s' ist nicht '%s', ignoriere."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Konnte '%s' nciht erzeugen: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "Wechseln der Gruppen-Liste fehlgeschlagen: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "Wechseln der GID fehlgeschlagen: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "Wechseln der UID fehlgeschlagen: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "Root-Berechtigungen erfolgreich zurückgesetzt."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "System-Modus auf dieser Plattform nicht unterstützt."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) fehlgeschlagen: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "Parsen der Kommandzeile fehlgeschlagen."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "Daemon läuft nicht"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "Daemon läuft als PID %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "Konnte Prozess nicht abbrechen: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -207,155 +232,176 @@ msgstr ""
 "Dieses Programm sollte ohne die Option --system nicht als Administrator "
 "ausgeführt werden."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "Root-Berechtigungen benötigt."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start nicht unterstützt für System-Instanzen."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "System-Modus aktiv, jeodch --disallow-exit nicht gesetzt!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr "System-Modus aktiv, jedoch --disallow-module-loading nicht gesetzt!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "System-Modus aktiv, SHM-Modus gezwungenermaßen deaktiviert!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr "System-Modus aktiv, Exit-Idle-Time gezwungenermaßen deaktiviert!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "Reservieren von STDIO fehlgeschlagen."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "pipe fehlgeschlagen: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() fehlgeschlagen: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() fehlgeschlagen: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "Start des Daemons fehlgeschlagen."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "Start des Daemons erfolgreich."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() fehlgeschlagen: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Dies ist PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Kompilier-Host: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "Kompilier-CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "Laufe auf Host: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "%u CPUs gefunden."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "Seitengröße ist %lu Bytes."
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Kompiliere mit Valgrind-Unterstützung: ja"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Kompiliere mit Valgrind-Unterstützung: nein"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "Läuft im Valgrind-Modus: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "Laufe auf Host: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "Optimiertes Build: ja"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "Optimiertes Build: nein"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG definiert, alle Ansprüche deaktiviert."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH definiert, nur fast-path-Ansprüche deaktiviert."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "Alle Ansprüche aktiviert."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "Beziehen der Maschinen-ID fehlgeschlagen"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "System- ID ist %s."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "System- ID ist %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "Nutze Laufzeit-Verzeichnis %s."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "Nutze Zustands-Verzeichnis %s."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "Modul-Verzeichnis %s benutzen."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Laufe im System-Modus: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -370,45 +416,45 @@ msgstr ""
 "Für eine Erklärung warum System Mode eine schlechte Idee ist, bitte http://"
 "pulseaudio.org/wiki/WhatIsWrongWithSystemMode lesen"
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() fehlgeschlagen."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "Neue hochauslösende Timer verfügbar! Guten Appetit!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
 msgstr "Der Chefkoch empfiehlt: Linux mit aktivierten hochauslösenden Timern!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() fehlgeschlagen."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "Konnte Daemon nicht initialisieren."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Daemon verweigert Ausführung, da keine Module geladen."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "Start des Daemons abgeschlossen."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "Herunterfahren des Daemon gestartet."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "Daemon beendet."
 
-#: ../src/daemon/cmdline.c:115
+#: ../src/daemon/cmdline.c:113
 #, fuzzy, c-format
 msgid ""
 "%s [options]\n"
@@ -446,15 +492,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -489,8 +533,8 @@ msgstr ""
 "      --dump-conf                       Zeige Standardkonfiguration\n"
 "      --dump-modules                    Zeige Liste verfügbarer Module\n"
 "      --dump-resample-methods           Zeige verfügbare Resample-Methoden\n"
-"      --cleanup-shm                     Cleanup stale shared memory "
-"segments\n"
+"      --cleanup-shm                     Bereinige veraltete Bereiche des "
+"gemeinsamen Speichers\n"
 "      --start                           Starte Daemon, falls noch nicht "
 "geschehen\n"
 "  -k  --kill                            Laufenden Daemon beenden\n"
@@ -501,7 +545,8 @@ msgstr ""
 "      --system[=BOOL]                   Als systemweite Instanz ausführen\n"
 "  -D, --daemonize[=BOOL]                Nach Start zum Daemon machen\n"
 "      --fail[=BOOL]                     Beenden, wenn Start fehlschlägt\n"
-"      --high-priority[=BOOL]            Nutze höchste Priorität\n"
+"      --high-priority[=BOOL]            Versuche höchste Priorität zu "
+"setzen\n"
 "                                        (Nur verfügbar als root, wenn SUID "
 "oder\n"
 "                                        mit erhöhtem RLIMIT_NICE)\n"
@@ -511,219 +556,228 @@ msgstr ""
 "oder\n"
 "                                        mit erhöhtem RLIMIT_RTPRIO)\n"
 "      --disallow-module-loading[=BOOL]  Verbiete (Ent-)laden durch Nutzer "
-"angeforderter\n"
+"angefordertere\n"
 "                                        Module nach dem Start\n"
 "      --disallow-exit[=BOOL]            Verbiete Beenden auf Anfrage des "
 "Nutzers\n"
-"      --exit-idle-time=SECS             Beende Daemon, wenn für diese Zeit \n"
+"      --exit-idle-time=SECS             Beende Daemon, wenn für diese Zeit\n"
 "                                        untätig\n"
 "      --module-idle-time=SECS           Entlade untätige Module nach dieser "
 "Zeit\n"
 "      --scache-idle-time=SECS           Entlade untätige automatisch "
-"geladene \n"
+"geladene\n"
 "                                        Samples nach dieser Zeit\n"
-"      --log-level[=STUFE]               Grad der Ausführlichkeit angeben\n"
+"      --log-level[=LEVEL]               Grad der Ausführlichkeit angeben\n"
 "  -v                                    Ausführliche Meldungen\n"
 "      --log-target={auto,syslog,stderr} Protokoll-Ziel angeben\n"
-"  -p, --dl-search-path=PFAD             Suchpfad für dynamisch "
-"freigegebene \n"
-"                                        Objekte (Plugins)\n"
-"      --resample-method=METHODE          Nutze diese Resampling-Methode\n"
+"      --log-meta[=BOOL]                 Speicherort des Codes in "
+"Protokollnachrichtenangeben\n"
+"      --log-time[=BOOL]                 Zeitstempel in Protokollnachrichten "
+"angeben\n"
+"      --log-backtrace=FRAMES            Backtrace in Protokollnachrichten "
+"angeben\n"
+"  -p, --dl-search-path=PATH             Suchpfad für dynamisch freigegebene\n"
+"                                        Objekte (Plugins) angeben\n"
+"      --resample-method=METHOD          Nutze diese Resampling-Methode\n"
 "                                        (Siehe --dump-resample-methods für\n"
 "                                        mögliche Werte)\n"
 "      --use-pid-file[=BOOL]             Eine PID-Datei erstellen\n"
 "      --no-cpu-limit[=BOOL]             CPU-Lastbegrenzung auf "
 "unterstützten\n"
 "                                        Systemen nicht installieren.\n"
-"      --disable-shm[=BOOL]              Keine Unterstützung für Shared "
-"Memory.\n"
+"      --disable-shm[=BOOL]              Unterstützung für Shared Memory "
+"deaktivieren.\n"
 "\n"
-"STARTUP-SCRIPT:\n"
-"  -L, --load=\"MODUL-ARGUMENTE\"       Plugin-Modul mit diesen Parametern \n"
+"STARTUP SCRIPT:\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Plugin-Modul mit diesen "
+"Parametern\n"
 "                                        laden.\n"
-"  -F, --file=DATEINAMEN                   Dieses Skript ausführen\n"
-"  -C                                    Nach Start auf laufendem TTY \n"
+"  -F, --file=FILENAME                   Dieses Skript ausführen\n"
+"  -C                                    Nach Start auf laufendem TTY\n"
 "                                        eine Kommandozeile öffnen\n"
 "\n"
 "  -n                                    Standardskript nicht laden\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
-msgstr "Option --daemonize erfordert bool'schen Wert"
+msgstr "--daemonize erfordert Boolsche Variable"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
-msgstr "Option --fail erfordert bool'schen Wert"
+msgstr "--fail erfordert Boolsche Variable"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
 msgstr ""
-"--log-level erfordert Wert für Grad der Protokollierung (entweder numerisch "
-"im Bereich 0..4 or einen dieser: debug, info, notice, warn, error)."
+"--log-level erfordert Parameter für Grad der Protokollierung (entweder "
+"numerisch im Bereich 0..4 or einen dieser: debug, info, notice, warn, error)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
-msgstr "Option --high-priority erfordert bool'schen Wert"
+msgstr "--high-priority erfordert Boolsche Variable"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
-msgstr "Option --realtime erfordert bool'schen Wert"
+msgstr "--realtime erfordert Boolsche Variable"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
-msgstr "Option --disallow-module-loading erfordert bool'schen Wert"
+msgstr "--disallow-module-loading erfordert Boolsche Variable"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
-msgstr "--disallow-exit erfordert boolsches Argument"
+msgstr "--disallow-exit erfordert Boolsche Variable"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
-msgstr "Option --use-pid-file erfordert bool'schen Wert"
+msgstr "--use-pid-file erfordert Boolsche Variable"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr ""
 "Ungültiges Log-Ziel: Benutzen Sie entweder 'syslog', 'stderr' oder 'auto'."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
-msgstr "--realtime erfordert boolsches Argument"
+msgstr "--realtime erfordert Boolsche Variable"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
-msgstr "--log-meta erfordert boolschen Wert"
+msgstr "--log-meta erfordert Boolsche Variable"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Ungültige Resample-Methode '%s'."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
-msgstr "--System erwartet Boolean-Argument"
+msgstr "--system erfordert Boolsche Variable"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
-msgstr "Option --no-cpu-limit erfordert bool'schen Wert"
+msgstr "--no-cpu-limit erfordert Boolsche Variable"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
-msgstr "Option --disable-shm erfordert bool'schen Wert"
+msgstr "--disable-shm erfordert Boolsche Variable"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Name: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "Keine Modul-Informationen verfügbar\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Version: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Beschreibung: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Autor: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Verwendung: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "Lade einmalig: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
-#, fuzzy, c-format
+#: ../src/daemon/dumpmodules.c:74
+#, c-format
 msgid "DEPRECATION WARNING: %s\n"
-msgstr "DEPRECATION WARNING: %s\n"
+msgstr "WARNUNG (DEPRECATION): %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Pfad: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Ungültiges Log-Ziel '%s'."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Ungültige Log-Stufe '%s'."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Ungültige Resample-Methode '%s'."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] Ungültiges rlimit '%s'."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit auf dieser Plattform nicht unterstützt."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Ungültiges Sample-Format '%s'."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Ungültige Sample-Rate '%s'."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Ungültige Sample-Kanäle '%s'."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] Ungültige Kanal-Zuordnung '%s'."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Ungültige Anzahl von Fragmenten '%s'."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Ungültige Fragmentgröße '%s'."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Ungültige Nice-Stufe '%s'."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Ungültige Sample-Rate '%s'."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Öffnen der Konfigurationsdatei fehlgeschlagen : %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -731,12 +785,12 @@ msgstr ""
 "Die angegebene Standard-Kanalzuordnung hat eine andere Anzahl von Kanälen "
 "als die angegebene Standard-Kanal-Anzahl."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Lese von Konfigurationsdatei: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "Root-Privilegien aufräumen."
 
@@ -748,6 +802,16 @@ msgstr "PulseAudio Sound System"
 msgid "Start the PulseAudio Sound System"
 msgstr "Das PulseAudio Sound System starten"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio Sound System"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "Das PulseAudio Sound System starten"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
@@ -777,8 +841,8 @@ msgid "Rear Right"
 msgstr "Hinten Rechts"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Niedrigfrequenzemitter"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -952,9 +1016,10 @@ msgstr "Oben Hinten Links"
 msgid "Top Rear Right"
 msgstr "Oben Hinten Rechts"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(ungültig)"
 
@@ -982,331 +1047,348 @@ msgstr "Surround 5.1"
 msgid "Surround 7.1"
 msgstr "Surround 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "OK"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
-msgstr "Zugriff abgelehnt"
+msgstr "Zugriff verweigert"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Unbekannter Befehl"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
-msgstr "Ungültiges Argument"
+msgstr "Ungültiger Parameter"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "Entität existiert bereits"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "Entität nicht vorhanden"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "Verbindung verweigert"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "Protokollfehler"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "Zeitüberschreitung"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "Kein Authorisierungsschlüssel"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "Interner Fehler"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "Verbindung beendet"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "Entität terminiert"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Ungültiger Server"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "Modulinitialisierung fehlgeschlagen"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "Ungültiger Zustand"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Keine Daten"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "Inkompatible Protokollversion"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "Zu groß"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "Nicht unterstützt"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Unbekannter Fehlercode"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "Erweiterung nicht vorhanden"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "Veraltete Funktion"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "Fehlende Implementation"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "Client geteilt"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "Eingabe/Ausgabe-Fehler"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "Gerät oder Ressource beschäftigt"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() fehlgeschlagen"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_new() fehlgeschlagen: %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "Parsen der Cookie-Daten fehlgeschlagen"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Konfigurationsdatei '%s' konnte nicht geöffnet werden: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "Verbindungsversuch ohne Cookie, da keines geladen."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "Nachricht für unbekannte Erweiterung '%s' erhalten"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "Entleeren des Streams fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "Wiedergabe-Stream entleert."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "Verbindung zu Server entleert."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_write() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "Stream wurde erfolgreich erstellt."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 msgstr "Pufferdaten: maxlenght=%u, tlength=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Pufferdaten: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "Benutze Sample-Angabe '%s', Kanalzuordnung '%s'."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "Verbunden mit Gerät %s (%u, %sausgesetzt)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "Stream-Fehler: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "Stream-Gerät ausgesetzt.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "Stream-Gerät reaktiviert.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "Stream leergelaufen.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "Stream überlaufen.%s "
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "Stream gestartet: %s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "Stream an Gerät %s übergeben (%u, %sausgesetzt).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "nicht "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "Stream-Zwischenspeicher-Attribute geändert.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "Verbindung hergestellt.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "Verbindungsfehler: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "EOF empfangen."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "Signal empfangen, beenden."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "Erhalten der Latenz fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Zeit: %0.3f sec; Latenz: %0.0f usec."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:609
+#: ../src/utils/pacat.c:653
 #, fuzzy, c-format
 msgid ""
 "%s [options]\n"
@@ -1359,10 +1441,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [options]\n"
@@ -1376,7 +1463,8 @@ msgstr ""
 "  -v, --verbose                         Ausführliche Meldungen\n"
 "\n"
 "  -s, --server=SERVER                   Name des zu verbindenden Servers\n"
-"  -d, --device=DEVICE                   Name zu verbindender Sink/Quelle\n"
+"  -d, --device=DEVICE                   Name des/der zu verbindender Sink/"
+"Quelle\n"
 "  -n, --client-name=NAME                Rufname des Clients auf dem Server\n"
 "      --stream-name=NAME                Rufname des Streams auf dem Server\n"
 "      --volume=VOLUME                   Initiale (lineare) Lautstärke "
@@ -1384,10 +1472,12 @@ msgstr ""
 "      --rate=SAMPLERATE                 Sample-Rate in Hz (Standard 44100)\n"
 "      --format=SAMPLEFORMAT             Ein Sample-Format von s16le, s16be, "
 "u8, float32le,\n"
-"                                        float32be, ulaw, alaw, s32le, s32be "
-"(defaults to s16ne)\n"
-"      --channels=CHANNELS               Anzahl Kanäle, 1 für mono, 2 für "
-"stereo\n"
+"                                        float32be, ulaw, alaw, s32le, s32be, "
+"s24le, s24be,\n"
+"                                        s24-32le, s24-32be (Standard ist "
+"s16ne)\n"
+"      --channels=CHANNELS               Anzahl Kanäle, 1 für Mono, 2 für "
+"Stereo\n"
 "                                        (Standard ist 2)\n"
 "      --channel-map=CHANNELMAP          Diese geänderte Kanalzuordnung "
 "nutzen\n"
@@ -1404,8 +1494,14 @@ msgstr ""
 "      --latency=BYTES                   Diese Latenz verwenden.\n"
 "      --process-time=BYTES              Diese Prozesszeit pro Anfrage "
 "verwenden.\n"
+"      --property=PROPERTY=VALUE         Die angegebene Eigenschaft auf "
+"denspezifizierten Wert setzen.\n"
+"      --raw                             PCM-Rohdaten aufnehmen/wiedergeben.\n"
+"      --file-format=FFORMAT             Formatierte PCM-Daten aufnehmen/"
+"wiedergeben.\n"
+"      --list-file-formats               Verfügbare Dateiformate auflisten.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1416,170 +1512,175 @@ msgstr ""
 "Kompiliert mit libpulse %s\n"
 "Gelinkt mit libpulse %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "Ungültiger Client-Name '%s'"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "Ungültiger Stream-Name '%s'"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "Ungültige Kanal-Zuweisung '%s'"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "Ungültige Latenz-Angaben '%s'"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "Ungültige Prozesszeit-Angaben '%s'"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "Ungültige Eigenschaft '%s'"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "Unbekanntes Dateiformat %s."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "Ungültige Sample-Angaben"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "Zu viele Argumente."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "Beziehen der Sample-Informationen für die Datei fehlgeschlagen."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "Öffnen der Audio-Datei fehlgeschlagen."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
 msgstr "Warnung: Beziehen der Sample-Angabe aus Datei fehlgeschlagen."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "Beziehen der Sample-Informationen der Datei fehlgeschlagen."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "Warnung: Bestimmung der Kanalzuordnung aus Datei fehlgeschlagen."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "Kanalzuordnung entspricht nicht Einstellungen des Samples"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "Warnung: Schreiben der Kanalzuordnung in Datei fehlgeschlagen."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr ""
 "Öffnen eines %s-Streams mit Sample-Angabe '%s' und Kanalzuordnung '%s'."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "aufnehmen"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "abspielen"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "Parsen der Kommandzeile fehlgeschlagen."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() fehlgeschlagen"
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() fehlgeschlagen."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() fehlgeschlagen."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_new() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_new() fehlgeschlagen."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() fehlgeschlagen."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "Aussetzen fehlgeschlagen: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "Resume fehlgeschlagen: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "WARNUNG: Sound-Server läuft nicht lokal, nicht ausgesetzt.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Verbindungsfehler: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "SIGINT empfangen, beende.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "WARNUNG: Kind-Prozess durch Signal %u beendet\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1623,35 +1724,46 @@ msgstr "pa_context_new() fehlgeschlagen.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() fehlgeschlagen.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "Beziehen der Statistik fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "Momentane Nutzung: %u Blöcke mit insgesamt %s Bytes.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "Während gesamter Laufzeit: %u Blöcke mit insgesamt %s Bytes.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "Sample-Pufferspeichergrösse: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "Beziehen der Server-Information fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1659,25 +1771,25 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "Name des Nutzers: %s\n"
 "Rechnername: %s\n"
 "Name des Servers: %s\n"
-"Version des Server: %s\n"
+"Version des Servers: %s\n"
 "Standard-Sample-Angabe: %s\n"
 "Standard-Kanal-Zuordnung: %s\n"
-"Standard-Ausgabe: %s\n"
-"-Standard-Quelle: %s\n"
+"Standard-Sink: %s\n"
+"Standard-Quelle: %s\n"
 "Cookie: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "Erhalten der Sink-Informationen fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1693,44 +1805,49 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Senke #%u\n"
+"Sink #%u\n"
 "\tStatus: %s\n"
 "\tName: %s\n"
 "\tBeschreibung: %s\n"
 "\tTreiber: %s\n"
 "\tSample-Angabe: %s\n"
 "\tKanalzuordnung: %s\n"
-"\tOwner-Modul: %u\n"
+"\tBesitzer-Modul: %u\n"
 "\tStumm: %s\n"
 "\tLautstärke: %s%s%s\n"
 "\t        Verteilung %0.2f\n"
 "\tBasis-Lautstärke: %s%s%s\n"
-"\tQuelle Monitor: %s\n"
+"\tQuellen-Monitor: %s\n"
 "\tLatenz: %0.0f usec, eingestellt %0.0f usec\n"
 "\tFlags: %s%s%s%s%s%s\n"
 "\tEigenschaften:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tProfile:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tAktive Profile: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tProfile:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "Beziehen der Quellen-Informationen fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1763,26 +1880,26 @@ msgstr ""
 "\tLautstärke: %s%s%s\n"
 "\t        Verteilung %0.2f\n"
 "\tBasis-Lautstärke: %s%s%s\n"
-"\tSenke-Monitor: %s\n"
+"\tSink-Monitor: %s\n"
 "\tLatenz: %0.0f usec, eingestellt %0.0f usec\n"
 "\tFlags: %s%s%s%s%s%s\n"
 "\tEigenschaften:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "k. A."
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "Beziehen der Modul-Information fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1799,12 +1916,12 @@ msgstr ""
 "\tEigenschaften:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "Beziehen der Client-Information fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1819,12 +1936,12 @@ msgstr ""
 "\tEigenschaften:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "Beziehen der Karten-Information fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1841,23 +1958,23 @@ msgstr ""
 "\tEigenschaften:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tProfile:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tAktive Profile: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
-msgstr "Konnte Sink-Eingabe-Informationen nicht holen: %s"
+msgstr "Erhalten der Sink-Eingabe-Informationen fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1866,6 +1983,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1876,9 +1994,9 @@ msgid ""
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Eingabe-Senke #%u\n"
+"Sink-Eingabe #%u\n"
 "\tTreiber: %s\n"
-"\tOwner-Modul: %s\n"
+"\tBesitzer-Modul: %s\n"
 "\tClient: %s\n"
 "\tSink: %u\n"
 "\tSample-Angabe: %s\n"
@@ -1893,13 +2011,13 @@ msgstr ""
 "\tEigenschaften:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "Konnte Informationen über Quell-Ausgabe nicht holen: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1908,31 +2026,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Quell-Ausgabe #%u\n"
+"Sink-Eingabe #%u\n"
 "\tTreiber: %s\n"
-"\tOwner-Modul: %s\n"
+"\tBesitzer-Modul: %s\n"
 "\tClient: %s\n"
-"\tQuelle: %u\n"
-"\tSample-Spezifizierung: %s\n"
+"\tSink: %u\n"
+"\tSample-Angabe: %s\n"
 "\tKanalzuordnung: %s\n"
+"\tStumm: %s\n"
+"\tLautstärke: %s\n"
+"\t        %s\n"
+"\t        Verteilung %0.2f\n"
 "\tPufferlatenz: %0.0f usec\n"
-"\tQuelllatenz: %0.0f usec\n"
+"\tSink-Latenz: %0.0f usec\n"
 "\tResample-Methode: %s\n"
 "\tEigenschaften:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "Beziehen der Sample-Informationen fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1963,48 +2090,163 @@ msgstr ""
 "\tEigenschaften:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "Fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Beziehen der Quellen-Informationen fehlgeschlagen: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "Hochladen des Sample fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "Dateiende ist zu früh aufgetreten"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "Ungültiger Server"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "SIGINT empfangen, beenden."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "Ungültige Sample-Angaben"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2014,35 +2256,14 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
-"\n"
-"  -h, --help                            Diese Hilfe anzeigen\n"
-"      --version                         Version anzeigen\n"
+"%s [options] ... \n"
 "\n"
+"  -h, --help                            Diese Hilfe zeigen\n"
+"      --version                         Zeige Version\n"
 "  -s, --server=SERVER                   Name des Zielservers\n"
-"  -n, --client-name=NAME                Rufname des Clients auf dem Server\n"
+"\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2053,109 +2274,152 @@ msgstr ""
 "Kompiliert mit libpulse %s\n"
 "Gelinkt mit libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "Geben Sie eine zu öffnende Sample-Datei an"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "Öffnen der Audio-Datei fehlgeschlagen."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "Warnung: Beziehen der Sample-Angabe aus Datei fehlgeschlagen."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "Sie müssen eine abzuspielende Sample-Datei angeben"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "Sie müssen eine zu löschende Sample-Datei angeben"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "Sie müssen einen Sink-Eingabe-Indexwert und einen Sink angeben"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr ""
 "Sie müssen eine Indexwert für die Quell-Ausgabe und eine Quelle angeben"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "Sie müssen einen Modulnamen angeben und Argumente übergeben."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "Sie müssen einen Indexwert für ein Modul angeben"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
-"Sie sollten nur eine Senke angeben. Sie müssen zumindest einen bool'schen "
-"Wert übergeben."
+"Sie sollten nur einen Sink angeben. Sie müssen zumindest eine Boolsche "
+"Variable übergeben."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr ""
-"Sie sollten nur eine Quelle angeben. Sie müssen zumindest einen bool'schen "
-"Wert übergeben."
+"Sie sollten nur eine Quelle angeben. Sie müssen zumindest eine Boolsche "
+"Variable übergeben."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "Sie müssen einen Karten-Name/Indexwert und einen Profilnamen angeben"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
-msgstr "Sie müssen einen Senkennamen/-Indexwert und einen Portnamen angeben"
+msgstr "Sie müssen einen Sink-Namen/-Indexwert und einen Portnamen angeben"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "Sie müssen einen Quellennamen/-Indexwert und einen Portnamen angeben"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
-msgstr "Sie müssen einen Senkennamen/-Indexwert und einen Portnamen angeben"
-
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "Ungültige Sample-Angaben"
+msgstr "Sie müssen einen Sink-Namen/-Indexwert und eine Lautstärke angeben"
 
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "Sie müssen einen Quellennamen/-Indexwert und einen Portnamen angeben"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
-msgstr "Sie müssen einen Sink-Eingabe-Indexwert und einen Sink angeben"
+msgstr "Sie müssen einen Sink-Eingabe-Indexwert und eine Lautstärke angeben."
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "Ungültiger Sink-Eingabe-Index"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr ""
+"Sie müssen eine Indexwert für die Quell-Ausgabe und eine Quelle angeben"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "Ungültiger Sink-Eingabe-Index"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
-msgstr "Sie müssen einen Senkennamen/-Indexwert und einen Portnamen angeben"
+msgstr ""
+"Sie müssen einen Sink-Namen/-Indexwert und eine Boolsche Variable für "
+"Stummschaltung angeben"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "Ungültige Sample-Angaben"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
-msgstr "Sie müssen einen Quellennamen/-Indexwert und einen Portnamen angeben"
+msgstr ""
+"Sie müssen einen Quellennamen/-Indexwert und eine Boolsche Variable für "
+"Stummschaltung angeben"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
-msgstr "Sie müssen einen Sink-Eingabe-Indexwert und einen Sink angeben"
+msgstr ""
+"Sie müssen einen Sink-Eingabe-Indexwert und eine Boolsche Variable für "
+"Stummschaltung angeben"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "Ungültige Sink-Eingabe-Index-Angaben"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr ""
+"Sie müssen einen Quellennamen/-Indexwert und eine Boolsche Variable für "
+"Stummschaltung angeben"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "Ungültige Sink-Eingabe-Index-Angaben"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr ""
+"Sie müssen einen Sink-Namen/-Indexwert und eine Boolsche Variable für "
+"Stummschaltung angeben"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "Kein gültiger Befehl angegeben."
 
@@ -2183,103 +2447,103 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "Parsen der Kommandozeile fehlgeschlagen.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Server: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Quelle: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Sink: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Cookie: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
-msgstr "Paresen der Cookie-Daten fehlgeschlagen.\n"
+msgstr "Parsen der Cookie-Daten fehlgeschlagen.\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "Speichern der Cookie-Daten fehlgeschlagen\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "Laden der Client-Konfigurationsdatei fehlgeschlagen.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "Lesen the Umgebungsdaten fehlgeschlagen.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "Beziehen des FQDN fehlgeschlagen.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "Laden der Cookie-Daten fehlgeschlagen\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Noch nicht implementiert.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr "Es läuft kein PulseAudio-Dienst oder nicht als Sessiondienst."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
-msgstr "Terminieren des PulseAudio-Daemon fehlgeschlagen."
+msgstr "Beenden des PulseAudio-Daemon fehlgeschlagen."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "Daemon antwortet nicht."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
-msgstr "Fehler beim Zugriff auf Autostart -Sperre."
+msgstr "Fehler beim Zugriff auf Autostart-Sperre."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2289,8 +2553,15 @@ msgid ""
 "We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() "
 "returned 0 or another value < min_avail."
 msgstr ""
+"ALSA weckte uns auf, um neue Daten auf das Gerät zu schreiben, doch es gab "
+"nichts zum Schreiben!\n"
+"Dies ist höchstwahrscheinlich ein Fehler im ALSA-Treiber '%s'. Bitte melden "
+"Sie diesen Fehler den ALSA-Entwicklern.\n"
+"Wir wurden durch das POLLOUT-Set geweckt, allerdings lieferte ein "
+"anschliessender snd_pcm_avail() den Wert 0 oder einen anderen Wert < "
+"min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2300,510 +2571,472 @@ msgid ""
 "We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() "
 "returned 0 or another value < min_avail."
 msgstr ""
-
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+"ALSA weckte uns auf, um neue Daten vom Gerät zu lesen, doch es gab nichts "
+"zum Lesen!\n"
+"Dies ist höchstwahrscheinlich ein Fehler im ALSA-Treiber '%s'. Bitte melden "
+"Sie diesen Fehler den ALSA-Entwicklern.\n"
+"Wir wurden durch das POLLIN-Set geweckt, allerdings lieferte ein "
+"anschliessender snd_pcm_avail() den Wert 0 oder einen anderen Wert < "
+"min_avail."
+
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "Aus"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "High Fidelity Playback (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "High Fidelity-Wiedergabe (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Telephony Duplex (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "PulseAudio Sound Server"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
-msgstr ""
+msgstr "Ausgabegeräte"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
-#, fuzzy
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
-msgstr "Eingang %s"
+msgstr "Eingabegeräte"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
-msgstr ""
+msgstr "Audio auf @HOSTNAME@"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
-msgstr "Eingang %s"
+msgstr "Eingabe"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
-msgstr ""
+msgstr "Docking Station Eingabe"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
-msgstr ""
+msgstr "Docking Station Mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "Docking Station Eingabe"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "Line In"
+
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
-msgstr ""
+msgstr "Mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
-msgid "External Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "Docking Station Mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
 #, fuzzy
+msgid "Rear Microphone"
+msgstr "Mikrofon"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "Externes Mikrofon"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
-msgstr "Internes Audio"
+msgstr "Internes Mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
-msgstr ""
+msgstr "Radio"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
-msgstr ""
+msgstr "Video"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
-msgstr ""
+msgstr "Automatische Verstärkungsregelung"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
-msgstr ""
+msgstr "Keine automatische Verstärkungsregelung"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
-msgstr ""
+msgstr "Boost"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
-msgstr ""
+msgstr "Kein Boost"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
-msgstr ""
+msgstr "Verstärker"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
-msgstr ""
+msgstr "Kein Verstärker"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
+#: ../src/modules/alsa/alsa-mixer.c:2237
 #, fuzzy
-msgid "Analog Input"
-msgstr "Analog Mono"
+msgid "Bass Boost"
+msgstr "Boost"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
+#: ../src/modules/alsa/alsa-mixer.c:2238
 #, fuzzy
-msgid "Analog Microphone"
-msgstr "Analog Mono"
+msgid "No Bass Boost"
+msgstr "Kein Boost"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-#, fuzzy
-msgid "Analog Line-In"
-msgstr "Analog Mono"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-#, fuzzy
-msgid "Analog Radio"
-msgstr "Analog Mono"
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "Analoge Kopfhörer"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-#, fuzzy
-msgid "Analog Video"
-msgstr "Analog Stereo"
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "Analoge Eingabe"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "Docking Station Mikrofon"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
-msgstr "Ausgang %s"
+msgstr "Analoge Ausgabe"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "Analoge Ausgabe (LFE)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2313
 #, fuzzy
-msgid "Analog Headphones"
-msgstr "Analog Mono"
+msgid "Line Out"
+msgstr "Line In"
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2314
+msgid "Analog Mono Output"
+msgstr "Analoge Mono-Ausgabe"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2315
 #, fuzzy
-msgid "Analog Mono Output"
-msgstr "Analog Mono"
+msgid "Speakers"
+msgstr "Analog Stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, fuzzy, c-format
-msgid "%s+%s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, fuzzy, c-format
-msgid "%s / %s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Digital Stereo (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Digital Stereo (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr "Analog Mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr "Analog Stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
-msgstr "Analog Surround 4.1"
+msgstr "Analog Surround 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
-msgstr "Analog Surround 4.0"
+msgstr "Analog Surround 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
-msgstr "Analog Surround 4.1"
+msgstr "Analog Surround 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr "Analog Surround 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr "Analog Surround 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr "Analog Surround 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr "Analog Surround 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
-msgstr "Analog Surround 4.0"
+msgstr "Analog Surround 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
-msgstr "Analog Surround 4.1"
+msgstr "Analog Surround 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
-msgstr "Analog Surround 4.0"
+msgstr "Analog Surround 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr "Analog Surround 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr "Digital Stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
+#: ../src/modules/alsa/alsa-mixer.c:3770
 #, fuzzy
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "Digital Surround 4.0 (IEC958/AC3)"
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Digital Stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Digital Surround 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Digital Surround 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr "Digital Stereo (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
 #, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Digital Surround 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
-msgstr "Analog Mono"
+msgstr "Analog Mono Duplex"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
-msgstr "Analog Stereo"
+msgstr "Analog Stereo Duplex"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
-msgstr "Digital Stereo (IEC958)"
-
-#~ msgid "Invalid client name '%s'\n"
-#~ msgstr "Ungültiger Client-Name '%s'\n"
-
-#~ msgid "Failed to determine sample specification from file.\n"
-#~ msgstr "Beziehen der Sample-Informationen der Datei fehlgeschlagen.\n"
-
-#~ msgid "select(): %s"
-#~ msgstr "select(): %s"
+msgstr "Digital Stereo Duplex (IEC958)"
 
-#~ msgid "Cannot connect to system bus: %s"
-#~ msgstr "Kann nicht mit dem System-Bus verbinden: %s"
-
-#~ msgid "Cannot get caller from PID: %s"
-#~ msgstr "Kann Caller von PID nicht beziehen: %s"
-
-#~ msgid "Cannot set UID on caller object."
-#~ msgstr "Kann UID für Caller-Objekt nicht setzen."
-
-#~ msgid "Failed to get CK session."
-#~ msgstr "Kann CK-Session nicht beziehen."
-
-#~ msgid "Cannot set UID on session object."
-#~ msgstr "Kann UID für Session-Objekt nicht setzen."
-
-#~ msgid "Cannot allocate PolKitAction."
-#~ msgstr "Konnte PolKitAction nicht zuordnen."
-
-#~ msgid "Cannot set action_id"
-#~ msgstr "Kann action_id nicht setzen"
-
-#~ msgid "Cannot allocate PolKitContext."
-#~ msgstr "Konnte PolKitContext nicht zuordnen."
-
-#~ msgid "Cannot initialize PolKitContext: %s"
-#~ msgstr "Konnte PolKitContext nicht initialisieren: %s"
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Null-Ausgabe"
 
-#~ msgid "Could not determine whether caller is authorized: %s"
-#~ msgstr "Autorisierung des Callers konnte nicht sichergestellt werden: %s"
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "Eingabe"
 
-#~ msgid "Cannot obtain auth: %s"
-#~ msgstr "Keine Authorisierung erhalten: %s"
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
 
-#~ msgid "PolicyKit responded with '%s'"
-#~ msgstr "PolicyKit antwortete mit '%s'"
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
 
+#: ../src/modules/module-equalizer-sink.c:76
 #, fuzzy
-#~ msgid ""
-#~ "High-priority scheduling (negative Unix nice level) for the PulseAudio "
-#~ "daemon"
-#~ msgstr ""
-#~ "Hochprioritäts-Terminierung () (negative Unix nice level) für den "
-#~ "PulseAudio-Dienst"
-
-#~ msgid "Real-time scheduling for the PulseAudio daemon"
-#~ msgstr "Echtzeit-Terminierung des PulseAudio-Daemon"
-
-#~ msgid ""
-#~ "System policy prevents PulseAudio from acquiring high-priority scheduling."
-#~ msgstr ""
-#~ "System-Richtlinien verhindert PulseAudio beim Erlangen des high-priority "
-#~ "scheduling."
-
-#~ msgid ""
-#~ "System policy prevents PulseAudio from acquiring real-time scheduling."
-#~ msgstr ""
-#~ "System-Richtlinien verhindert PulseAudio beim Erlangen der Echtzeit-"
-#~ "Terminierung."
-
-#~ msgid "read() failed: %s\n"
-#~ msgstr "read() fehlgeschlagen: %s\n"
-
-#~ msgid "pa_context_connect() failed: %s\n"
-#~ msgstr "pa_context_connect() fehlgeschlagen: %s\n"
-
-#~ msgid "We're in the group '%s', allowing high-priority scheduling."
-#~ msgstr ""
-#~ "Wir befinden uns in der Gruppe '%s', was Scheduling höchster Priorität "
-#~ "ermöglicht."
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<Name des Sinks> sink_properties=<Eigenschaften des Sinks> "
+"master=<Name des zu filternden Sinks> format=<Sample-Format> rate=<Sample-"
+"Rate> channels=<Anzahl der Channels> channel_map=<Channel-Map> "
+"plugin=<ladspa Plugin-Name> label=<ladspa Plugin-Label> "
+"control=<kommagetrennte Liste von Eingabekontrollwerten>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
 
-#~ msgid "We're in the group '%s', allowing real-time scheduling."
-#~ msgstr ""
-#~ "Wir befinden uns in der Gruppe '%s', was Echtzeit-Scheduling ermöglicht."
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
 
-#~ msgid "PolicyKit grants us acquire-high-priority privilege."
-#~ msgstr "Richtlinien gewähren das Recht aquire-high-priority."
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
 
-#~ msgid "PolicyKit refuses acquire-high-priority privilege."
-#~ msgstr "Richtlinien verweigern das Recht acquire-high-priority."
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
 
-#~ msgid "PolicyKit grants us acquire-real-time privilege."
-#~ msgstr "Richtlinien gewähren das Recht aquire-real-time."
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit auf dieser Plattform nicht unterstützt."
 
-#~ msgid "PolicyKit refuses acquire-real-time privilege."
-#~ msgstr "Richtlinien verweigern das Recht acquire-real-time."
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() fehlgeschlagen"
 
-#, fuzzy
 #~ msgid ""
-#~ "Called SUID root and real-time and/or high-priority scheduling was "
-#~ "requested in the configuration. However, we lack the necessary "
-#~ "privileges:\n"
-#~ "We are not in group '%s', PolicyKit refuse to grant us the requested "
-#~ "privileges and we have no increase RLIMIT_NICE/RLIMIT_RTPRIO resource "
-#~ "limits.\n"
-#~ "For enabling real-time/high-priority scheduling please acquire the "
-#~ "appropriate PolicyKit privileges, or become a member of '%s', or increase "
-#~ "the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
 #~ msgstr ""
-#~ "' und PolicyKit verweigern diese Rechte. Verwerfe SUID wieder.\n"
-#~ "Erlangen Sie die den Richtlinien entsprechenden Rechte, um Echtzeit-"
-#~ "Scheduling zu aktivieren oder werden Sie Mitglied der Gruppe '"
-
-#~ msgid ""
-#~ "High-priority scheduling enabled in configuration but not allowed by "
-#~ "policy."
-#~ msgstr "Scheduling höchster Priorität konfiguriert, jedoch nicht erlaubt."
-
-#~ msgid "Successfully increased RLIMIT_RTPRIO"
-#~ msgstr "RLIMIT_RTPRIO erfolgreich erhöht"
-
-#~ msgid "RLIMIT_RTPRIO failed: %s"
-#~ msgstr "RLIMIT_RTPRIO fehlgeschlagen: %s"
-
-#~ msgid "Giving up CAP_NICE"
-#~ msgstr "Verwerfe CAP_NICE"
-
-#~ msgid ""
-#~ "Real-time scheduling enabled in configuration but not allowed by policy."
-#~ msgstr "Echtzeit-Scheduling konfiguriert, jedoch nicht erlaubt."
-
-#~ msgid "Limited capabilities successfully to CAP_SYS_NICE."
-#~ msgstr "Fähigkeiten erfolgreich auf CAP_SYS_NICE reduziert."
-
-#~ msgid "time_new() failed.\n"
-#~ msgstr "time_new() fehlgeschlagen.\n"
-
-#~ msgid "Output %s + Input %s"
-#~ msgstr "Ausgabe %s + Eingabe %s"
-
-#~ msgid "Stream successfully created\n"
-#~ msgstr "Stream erfolgreich erzeugt\n"
-
-#~ msgid "Stream errror: %s\n"
-#~ msgstr "Stream-Fehler: %s\n"
-
-#~ msgid "Connection established.\n"
-#~ msgstr "Verbindung hergestellt.\n"
+#~ "Quell-Ausgabe #%u\n"
+#~ "\tTreiber: %s\n"
+#~ "\tOwner-Modul: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tQuelle: %u\n"
+#~ "\tSample-Spezifizierung: %s\n"
+#~ "\tKanalzuordnung: %s\n"
+#~ "\tPufferlatenz: %0.0f usec\n"
+#~ "\tQuelllatenz: %0.0f usec\n"
+#~ "\tResample-Methode: %s\n"
+#~ "\tEigenschaften:\n"
+#~ "\t\t%s\n"
 
+#, fuzzy
 #~ msgid ""
-#~ "%s [options] [FILE]\n"
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
 #~ "\n"
 #~ "  -h, --help                            Show this help\n"
 #~ "      --version                         Show version\n"
 #~ "\n"
-#~ "  -v, --verbose                         Enable verbose operation\n"
-#~ "\n"
 #~ "  -s, --server=SERVER                   The name of the server to connect "
 #~ "to\n"
-#~ "  -d, --device=DEVICE                   The name of the sink to connect "
-#~ "to\n"
 #~ "  -n, --client-name=NAME                How to call this client on the "
 #~ "server\n"
-#~ "      --stream-name=NAME                How to call this stream on the "
-#~ "server\n"
-#~ "      --volume=VOLUME                   Specify the initial (linear) "
-#~ "volume in range 0...65536\n"
-#~ "      --channel-map=CHANNELMAP          Set the channel map to the use\n"
 #~ msgstr ""
-#~ "%s [options] [FILE]\n"
-#~ "\n"
-#~ "  -h, --help                            Zeige diese Hilfe\n"
-#~ "      --version                         Zeige Version\n"
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 #~ "\n"
-#~ "  -v, --verbose                         Ausführliche Meldungen\n"
+#~ "  -h, --help                            Diese Hilfe anzeigen\n"
+#~ "      --version                         Version anzeigen\n"
 #~ "\n"
 #~ "  -s, --server=SERVER                   Name des Zielservers\n"
-#~ "  -d, --device=DEVICE                   Name des Ziel-Sink\n"
 #~ "  -n, --client-name=NAME                Rufname des Clients auf dem "
 #~ "Server\n"
-#~ "      --stream-name=NAME                Rufname des Streams auf dem "
-#~ "Server\n"
-#~ "      --volume=VOLUME                   Initiale (lineare) Lautstärke "
-#~ "zwischen 0...65536\n"
-#~ "      --channel-map=CHANNELMAP          Diese Kanalzuordnung nutzen\n"
-
-#~ msgid ""
-#~ "paplay %s\n"
-#~ "Compiled with libpulse %s\n"
-#~ "Linked with libpulse %s\n"
-#~ msgstr ""
-#~ "paplay %s\n"
-#~ "Kompliert mit libpulse %s\n"
-#~ "Gelinkt mit libpulse %s\n"
-
-#~ msgid "Invalid channel map\n"
-#~ msgstr "Ungültige Kanal-Zuweisung\n"
-
-#~ msgid "Failed to open file '%s'\n"
-#~ msgstr "Öffnen der Datei '%s' fehlgeschlagen\n"
-
-#~ msgid "Channel map doesn't match file.\n"
-#~ msgstr "Kanal-Zuweisung stimmt mit Datei nicht überein.\n"
-
-#~ msgid "Using sample spec '%s'\n"
-#~ msgstr "Sampling-Angabe '%s' wird benutzt\n"
 
-#, fuzzy
-#~ msgid ""
-#~ "Called SUID root and real-time and/or high-priority scheduling was "
-#~ "requested in the configuration. However, we lack the necessary "
-#~ "privileges:\n"
-#~ "We are not in group '"
-#~ msgstr ""
-#~ "Konfiguration fordert Aufruf der SUID root und Echtzeit-Scheduling "
-#~ "höchster Priorität. Allerdings fehlen die nötigen Rechte:\n"
-#~ "Wir befinden uns nicht in der Gruppe '"
-
-#~ msgid "--log-time boolean argument"
-#~ msgstr "--log-time erfordert bool'schen Wert"
-
-#~ msgid ""
-#~ "', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this "
-#~ "user."
-#~ msgstr ""
-#~ "' oder erhöhen sie die RLIMIT_NICE/RLIMIT_RTPRIO-Ressourcenbegrenzungen "
-#~ "für diesen Nutzer."
-
-#~ msgid "Default sink name (%s) does not exist in name register."
-#~ msgstr "Vorgabename für Sink (%s) existiert nicht im Namensregister."
-
-#~ msgid "Buffer overrun, dropping incoming data\n"
-#~ msgstr "Pufferüberlauf, verwerfe eingehende Daten\n"
-
-#~ msgid "pa_stream_drop() failed: %s\n"
-#~ msgstr "pa_stream_drop() fehlgeschlagen: %s\n"
-
-#~ msgid "muted"
-#~ msgstr "stumm"
-
-#~ msgid ""
-#~ "*** Autoload Entry #%u ***\n"
-#~ "Name: %s\n"
-#~ "Type: %s\n"
-#~ "Module: %s\n"
-#~ "Argument: %s\n"
-#~ msgstr ""
-#~ "*** Autoload-Eintrag #%u ***\n"
-#~ "Name: %s\n"
-#~ "Typ: %s\n"
-#~ "Modul: %s\n"
-#~ "Argument: %s\n"
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
 
-#~ msgid "sink"
-#~ msgstr "Sink"
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
 
-#~ msgid "source"
-#~ msgstr "Quelle"
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Digital Surround 4.0 (IEC958)"
 
-#~ msgid "socketpair(): %s"
-#~ msgstr "socketpair(): %s"
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Niedrigfrequenzemitter"
index e239deb..4cd49d3 100644 (file)
@@ -2,29 +2,25 @@
 # Copyright (C) 2008 pulseaudio
 # This file is distributed under the same license as the pulseaudio package.
 #
-# Fabian Affolter <fab@fedoraproject.org>, 2008-2009.
 # Micha Pietsch <barney@fedoraproject.org>, 2008, 2009.
+# Fabian Affolter <fab@fedoraproject.org>, 2008-2009, 2012.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-09-14 10:22+0100\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:53+0000\n"
 "Last-Translator: Fabian Affolter <fab@fedoraproject.org>\n"
 "Language-Team: German <fedora-trans-de@redhat.com>\n"
+"Language: de\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 "X-Poedit-Language: German\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -37,11 +33,11 @@ msgstr ""
 "Dies ist wahrscheinlich ein Fehler im ALSA-Treiber '%s'. Bitte melden Sie "
 "diesen Punkt den ALSA-Entwicklern."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
@@ -50,7 +46,20 @@ msgstr ""
 "Dies ist wahrscheinlich ein Fehler im ALSA-Treiber '%s'. Bitte melden Sie "
 "diesen Punkt den ALSA-Entwicklern."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() gibt einen Wert zurück, welche außerordentlich groß ist: %lu "
+"bytes (%lu ms).\n"
+"Dies ist wahrscheinlich ein Fehler im ALSA-Treiber '%s'. Bitte melden Sie "
+"diesen Punkt den ALSA-Entwicklern."
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -63,143 +72,151 @@ msgstr ""
 "Dies ist wahrscheinlich ein Fehler im ALSA-Treiber '%s'. Bitte melden Sie "
 "diesen Punkt den ALSA-Entwicklern."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr ""
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "Dummy-Ausgabe"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 #, fuzzy
 msgid "Virtual LADSPA sink"
 msgstr "Virtueller LADSPA-Sink"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr ""
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 #, fuzzy
 msgid "Null Output"
 msgstr "Ausgang %s"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "Internes Audio"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "Modem"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "Ursprünglicher dlopen-Loader konnte nicht gefunden werden."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "Neuer dlopen-Loader konnte nicht gefunden werden."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "Hinzufügen von Bind-Now-Loader fehlgeschlagen."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "Signal %s empfangen."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "Wird beendet."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "Benutzer '%s' nicht gefunden."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "Gruppe '%s' nicht gefunden."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "Benutzer '%s' (UID %lu) und Gruppe '%s' (GID %lu) gefunden."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "GID von Benutzer '%s' und Gruppe '%s' stimmen nicht überein."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "Benutzerverzeichnis von Benutzer '%s' ist nicht '%s', ignoriere."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Konnte '%s' nciht erzeugen: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "Wechseln der Gruppen-Liste fehlgeschlagen: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "Wechseln der GID fehlgeschlagen: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "Wechseln der UID fehlgeschlagen: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "Root-Berechtigungen erfolgreich zurückgesetzt."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "System-Modus auf dieser Plattform nicht unterstützt."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) fehlgeschlagen: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "Parsen der Kommandzeile fehlgeschlagen."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "Daemon läuft nicht"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "Daemon läuft als PID %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "Konnte Prozess nicht abbrechen: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -207,155 +224,176 @@ msgstr ""
 "Dieses Programm sollte ohne die Option --system nicht als Administrator "
 "ausgeführt werden."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "Root-Berechtigungen benötigt."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start nicht unterstützt für System-Instanzen."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "System-Modus aktiv, jeodch --disallow-exit nicht gesetzt!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr "System-Modus aktiv, jedoch --disallow-module-loading nicht gesetzt!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "System-Modus aktiv, SHM-Modus gezwungenermaßen deaktiviert!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr "System-Modus aktiv, Exit-Idle-Time gezwungenermaßen deaktiviert!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "Reservieren von STDIO fehlgeschlagen."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "pipe fehlgeschlagen: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() fehlgeschlagen: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() fehlgeschlagen: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "Start des Daemons fehlgeschlagen."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "Start des Daemons erfolgreich."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() fehlgeschlagen: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Dies ist PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Kompilier-Host: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "Kompilier-CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "Laufe auf Host: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "%u CPUs gefunden."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "Seitengröße ist %lu Bytes."
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Kompiliere mit Valgrind-Unterstützung: ja"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Kompiliere mit Valgrind-Unterstützung: nein"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "Läuft im Valgrind-Modus: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "Laufe auf Host: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "Optimiertes Build: ja"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "Optimiertes Build: nein"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG definiert, alle Ansprüche deaktiviert."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH definiert, nur fast-path-Ansprüche deaktiviert."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "Alle Ansprüche aktiviert."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "Beziehen der Maschinen-ID fehlgeschlagen"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "System- ID ist %s."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "System- ID ist %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "Nutze Laufzeit-Verzeichnis %s."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "Nutze Zustands-Verzeichnis %s."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "Modul-Verzeichnis %s benutzen."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Laufe im System-Modus: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -365,45 +403,45 @@ msgid ""
 "explanation why system mode is usually a bad idea."
 msgstr ""
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() fehlgeschlagen."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "Neue hochauslösende Timer verfügbar! Guten Appetit!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
 msgstr "Der Chefkoch empfiehlt: Linux mit aktivierten hochauslösenden Timern!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() fehlgeschlagen."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "Konnte Daemon nicht initialisieren."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Daemon verweigert Ausführung, da keine Module geladen."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "Start des Daemons abgeschlossen."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "Herunterfahren des Daemon gestartet."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "Daemon beendet."
 
-#: ../src/daemon/cmdline.c:115
+#: ../src/daemon/cmdline.c:113
 #, fuzzy, c-format
 msgid ""
 "%s [options]\n"
@@ -441,15 +479,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -542,15 +578,15 @@ msgstr ""
 "\n"
 "  -n                                    Standardskript nicht laden\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "Option --daemonize erfordert bool'schen Wert"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "Option --fail erfordert bool'schen Wert"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -558,167 +594,170 @@ msgstr ""
 "--log-level erfordert Wert für Grad der Protokollierung (entweder numerisch "
 "im Bereich 0..4 or einen dieser: debug, info, notice, warn, error)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "Option --high-priority erfordert bool'schen Wert"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "Option --realtime erfordert bool'schen Wert"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "Option --disallow-module-loading erfordert bool'schen Wert"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit erfordert boolsches Argument"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "Option --use-pid-file erfordert bool'schen Wert"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr ""
 "Ungültiges Log-Ziel: Benutzen Sie entweder 'syslog', 'stderr' oder 'auto'."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--realtime erfordert boolsches Argument"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta erfordert boolschen Wert"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Ungültige Resample-Methode '%s'."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--System erwartet Boolean-Argument"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "Option --no-cpu-limit erfordert bool'schen Wert"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "Option --disable-shm erfordert bool'schen Wert"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Name: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "Keine Modul-Informationen verfügbar\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Version: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Beschreibung: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Autor: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Verwendung: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "Lade einmalig: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, fuzzy, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "DEPRECATION WARNING: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Pfad: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Ungültiges Log-Ziel '%s'."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Ungültige Log-Stufe '%s'."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Ungültige Resample-Methode '%s'."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] Ungültiges rlimit '%s'."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit auf dieser Plattform nicht unterstützt."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Ungültiges Sample-Format '%s'."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Ungültige Sample-Rate '%s'."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Ungültige Sample-Kanäle '%s'."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] Ungültige Kanal-Zuordnung '%s'."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Ungültige Anzahl von Fragmenten '%s'."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Ungültige Fragmentgröße '%s'."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Ungültige Nice-Stufe '%s'."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Ungültige Sample-Rate '%s'."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Öffnen der Konfigurationsdatei fehlgeschlagen : %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -726,12 +765,12 @@ msgstr ""
 "Die angegebene Standard-Kanalzuordnung hat eine andere Anzahl von Kanälen "
 "als die angegebene Standard-Kanal-Anzahl."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Lese von Konfigurationsdatei: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "Root-Privilegien aufräumen."
 
@@ -743,6 +782,16 @@ msgstr "PulseAudio Sound System"
 msgid "Start the PulseAudio Sound System"
 msgstr "Das PulseAudio Sound System starten"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio Sound System"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "Das PulseAudio Sound System starten"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
@@ -772,8 +821,8 @@ msgid "Rear Right"
 msgstr "Hinten Rechts"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Niedrigfrequenzemitter"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -947,9 +996,10 @@ msgstr "Oben Hinten Links"
 msgid "Top Rear Right"
 msgstr "Oben Hinten Rechts"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(ungültig)"
 
@@ -977,331 +1027,348 @@ msgstr "Surround 5.1"
 msgid "Surround 7.1"
 msgstr "Surround 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "OK"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "Zugriff abgelehnt"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Unbekannter Befehl"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "Ungültiges Argument"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "Entität existiert bereits"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "Entität nicht vorhanden"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "Verbindung verweigert"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "Protokollfehler"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "Zeitüberschreitung"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "Kein Authorisierungsschlüssel"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "Interner Fehler"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "Verbindung beendet"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "Entität terminiert"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Ungültiger Server"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "Modulinitialisierung fehlgeschlagen"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "Ungültiger Zustand"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Keine Daten"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "Inkompatible Protokollversion"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "Zu groß"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "Nicht unterstützt"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Unbekannter Fehlercode"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "Erweiterung nicht vorhanden"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "Veraltete Funktion"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "Fehlende Implementation"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "Client geteilt"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "Eingabe/Ausgabe-Fehler"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "Gerät oder Ressource beschäftigt"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() fehlgeschlagen"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_new() fehlgeschlagen: %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "Parsen der Cookie-Daten fehlgeschlagen"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Konfigurationsdatei '%s' konnte nicht geöffnet werden: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "Verbindungsversuch ohne Cookie, da keines geladen."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "Nachricht für unbekannte Erweiterung '%s' erhalten"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "Entleeren des Streams fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "Wiedergabe-Stream entleert."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "Verbindung zu Server entleert."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_write() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "Stream wurde erfolgreich erstellt."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 msgstr "Pufferdaten: maxlenght=%u, tlength=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Pufferdaten: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "Benutze Sample-Angabe '%s', Kanalzuordnung '%s'."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "Verbunden mit Gerät %s (%u, %sausgesetzt)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "Stream-Fehler: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "Stream-Gerät ausgesetzt.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "Stream-Gerät reaktiviert.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "Stream leergelaufen.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "Stream überlaufen.%s "
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "Stream gestartet: %s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "Stream an Gerät %s übergeben (%u, %sausgesetzt).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "nicht "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "Stream-Zwischenspeicher-Attribute geändert.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "Verbindung hergestellt.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "Verbindungsfehler: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "EOF empfangen."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "Signal empfangen, beenden."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "Erhalten der Latenz fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Zeit: %0.3f sec; Latenz: %0.0f usec."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:609
+#: ../src/utils/pacat.c:653
 #, fuzzy, c-format
 msgid ""
 "%s [options]\n"
@@ -1354,10 +1421,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [options]\n"
@@ -1400,7 +1472,7 @@ msgstr ""
 "      --process-time=BYTES              Diese Prozesszeit pro Anfrage "
 "verwenden.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1411,170 +1483,175 @@ msgstr ""
 "Kompiliert mit libpulse %s\n"
 "Gelinkt mit libpulse %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "Ungültiger Client-Name '%s'"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "Ungültiger Stream-Name '%s'"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "Ungültige Kanal-Zuweisung '%s'"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "Ungültige Latenz-Angaben '%s'"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "Ungültige Prozesszeit-Angaben '%s'"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "Ungültige Eigenschaft '%s'"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "Unbekanntes Dateiformat %s."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "Ungültige Sample-Angaben"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "Zu viele Argumente."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "Beziehen der Sample-Informationen für die Datei fehlgeschlagen."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "Öffnen der Audio-Datei fehlgeschlagen."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
 msgstr "Warnung: Beziehen der Sample-Angabe aus Datei fehlgeschlagen."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "Beziehen der Sample-Informationen der Datei fehlgeschlagen."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "Warnung: Bestimmung der Kanalzuordnung aus Datei fehlgeschlagen."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "Kanalzuordnung entspricht nicht Einstellungen des Samples"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "Warnung: Schreiben der Kanalzuordnung in Datei fehlgeschlagen."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr ""
 "Öffnen eines %s-Streams mit Sample-Angabe '%s' und Kanalzuordnung '%s'."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "aufnehmen"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "abspielen"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "Parsen der Kommandzeile fehlgeschlagen."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() fehlgeschlagen"
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() fehlgeschlagen."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() fehlgeschlagen."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_new() fehlgeschlagen: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_new() fehlgeschlagen."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() fehlgeschlagen."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "Aussetzen fehlgeschlagen: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "Resume fehlgeschlagen: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "WARNUNG: Sound-Server läuft nicht lokal, nicht ausgesetzt.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Verbindungsfehler: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "SIGINT empfangen, beende.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "WARNUNG: Kind-Prozess durch Signal %u beendet\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1618,35 +1695,46 @@ msgstr "pa_context_new() fehlgeschlagen.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() fehlgeschlagen.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "Beziehen der Statistik fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "Momentane Nutzung: %u Blöcke mit insgesamt %s Bytes.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "Während gesamter Laufzeit: %u Blöcke mit insgesamt %s Bytes.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "Sample-Pufferspeichergrösse: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "Beziehen der Server-Information fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1654,7 +1742,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "Name des Nutzers: %s\n"
 "Rechnername: %s\n"
@@ -1666,13 +1754,13 @@ msgstr ""
 "-Standard-Quelle: %s\n"
 "Cookie: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "Erhalten der Sink-Informationen fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1688,7 +1776,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1710,22 +1798,27 @@ msgstr ""
 "\tEigenschaften:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tProfile:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tAktive Profile: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tProfile:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "Beziehen der Quellen-Informationen fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1764,20 +1857,20 @@ msgstr ""
 "\tEigenschaften:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "k. A."
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "Beziehen der Modul-Information fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1794,12 +1887,12 @@ msgstr ""
 "\tEigenschaften:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "Beziehen der Client-Information fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1814,12 +1907,12 @@ msgstr ""
 "\tEigenschaften:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "Beziehen der Karten-Information fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1836,23 +1929,23 @@ msgstr ""
 "\tEigenschaften:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tProfile:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tAktive Profile: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "Konnte Sink-Eingabe-Informationen nicht holen: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1861,6 +1954,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1888,13 +1982,13 @@ msgstr ""
 "\tEigenschaften:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "Konnte Informationen über Quell-Ausgabe nicht holen: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1903,31 +1997,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Quell-Ausgabe #%u\n"
+"Eingabe-Senke #%u\n"
 "\tTreiber: %s\n"
 "\tOwner-Modul: %s\n"
 "\tClient: %s\n"
-"\tQuelle: %u\n"
-"\tSample-Spezifizierung: %s\n"
+"\tSink: %u\n"
+"\tSample-Angabe: %s\n"
 "\tKanalzuordnung: %s\n"
+"\tStumm: %s\n"
+"\tLautstärke: %s\n"
+"\t        %s\n"
+"\t        Verteilung %0.2f\n"
 "\tPufferlatenz: %0.0f usec\n"
-"\tQuelllatenz: %0.0f usec\n"
+"\tSink-Latenz: %0.0f usec\n"
 "\tResample-Methode: %s\n"
 "\tEigenschaften:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "Beziehen der Sample-Informationen fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1958,48 +2061,164 @@ msgstr ""
 "\tEigenschaften:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "Fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Beziehen der Quellen-Informationen fehlgeschlagen: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "Hochladen des Sample fehlgeschlagen: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "Dateiende ist zu früh aufgetreten"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr "Sink"
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr "Quelle"
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+#, fuzzy
+msgid "source-output"
+msgstr "Quelle"
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "Ungültiger Server"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "SIGINT empfangen, beenden."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "Ungültige Sample-Angaben"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2009,35 +2228,14 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
-"\n"
-"  -h, --help                            Diese Hilfe anzeigen\n"
-"      --version                         Version anzeigen\n"
+"%s [options] ... \n"
 "\n"
+"  -h, --help                            Diese Hilfe zeigen\n"
+"      --version                         Zeige Version\n"
 "  -s, --server=SERVER                   Name des Zielservers\n"
-"  -n, --client-name=NAME                Rufname des Clients auf dem Server\n"
+"\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2048,51 +2246,56 @@ msgstr ""
 "Kompiliert mit libpulse %s\n"
 "Gelinkt mit libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "Geben Sie eine zu öffnende Sample-Datei an"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "Öffnen der Audio-Datei fehlgeschlagen."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "Warnung: Beziehen der Sample-Angabe aus Datei fehlgeschlagen."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "Sie müssen eine abzuspielende Sample-Datei angeben"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "Sie müssen eine zu löschende Sample-Datei angeben"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "Sie müssen einen Sink-Eingabe-Indexwert und einen Sink angeben"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr ""
 "Sie müssen eine Indexwert für die Quell-Ausgabe und eine Quelle angeben"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "Sie müssen einen Modulnamen angeben und Argumente übergeben."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "Sie müssen einen Indexwert für ein Modul angeben"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "Sie sollten nur eine Senke angeben. Sie müssen zumindest einen bool'schen "
 "Wert übergeben."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
@@ -2100,57 +2303,85 @@ msgstr ""
 "Sie sollten nur eine Quelle angeben. Sie müssen zumindest einen bool'schen "
 "Wert übergeben."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "Sie müssen einen Karten-Name/Indexwert und einen Profilnamen angeben"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "Sie müssen einen Senkennamen/-Indexwert und einen Portnamen angeben"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "Sie müssen einen Quellennamen/-Indexwert und einen Portnamen angeben"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "Sie müssen einen Senkennamen/-Indexwert und einen Portnamen angeben"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "Ungültige Sample-Angaben"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "Sie müssen einen Quellennamen/-Indexwert und einen Portnamen angeben"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "Sie müssen einen Sink-Eingabe-Indexwert und einen Sink angeben"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "Ungültiger Sink-Eingabe-Index"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr ""
+"Sie müssen eine Indexwert für die Quell-Ausgabe und eine Quelle angeben"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "Ungültiger Sink-Eingabe-Index"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "Sie müssen einen Senkennamen/-Indexwert und einen Portnamen angeben"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "Ungültige Sample-Angaben"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "Sie müssen einen Quellennamen/-Indexwert und einen Portnamen angeben"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "Sie müssen einen Sink-Eingabe-Indexwert und einen Sink angeben"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "Ungültige Sink-Eingabe-Index-Angaben"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "Sie müssen einen Quellennamen/-Indexwert und einen Portnamen angeben"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "Ungültige Sink-Eingabe-Index-Angaben"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "Sie müssen einen Senkennamen/-Indexwert und einen Portnamen angeben"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "Kein gültiger Befehl angegeben."
 
@@ -2178,103 +2409,103 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "Parsen der Kommandozeile fehlgeschlagen.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Server: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Quelle: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Sink: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Cookie: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "Paresen der Cookie-Daten fehlgeschlagen.\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "Speichern der Cookie-Daten fehlgeschlagen\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "Laden der Client-Konfigurationsdatei fehlgeschlagen.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "Lesen the Umgebungsdaten fehlgeschlagen.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "Beziehen des FQDN fehlgeschlagen.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "Laden der Cookie-Daten fehlgeschlagen\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Noch nicht implementiert.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr "Es läuft kein PulseAudio-Dienst oder nicht als Sessiondienst."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "Terminieren des PulseAudio-Daemon fehlgeschlagen."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "Daemon antwortet nicht."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "Fehler beim Zugriff auf Autostart -Sperre."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2285,7 +2516,7 @@ msgid ""
 "returned 0 or another value < min_avail."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2296,253 +2527,477 @@ msgid ""
 "returned 0 or another value < min_avail."
 msgstr ""
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "Aus"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "High Fidelity-Wiedergabe (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "High Fidelity-Aufnahme (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Telephony Duplex (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "PulseAudio Sound Server"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
 msgstr ""
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 #, fuzzy
 msgid "Input Devices"
 msgstr "Eingang %s"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 #, fuzzy
 msgid "Input"
 msgstr "Eingang %s"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
+msgstr "Internes Audio"
+
+#: ../src/modules/alsa/alsa-mixer.c:2222
+msgid "Docking Station Line In"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "Internes Audio"
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "Internes Audio"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
 msgid "External Microphone"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 #, fuzzy
 msgid "Internal Microphone"
 msgstr "Internes Audio"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-#, fuzzy
-msgid "Analog Input"
-msgstr "Analog Mono"
+#: ../src/modules/alsa/alsa-mixer.c:2237
+msgid "Bass Boost"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-#, fuzzy
-msgid "Analog Microphone"
-msgstr "Analog Mono"
+#: ../src/modules/alsa/alsa-mixer.c:2238
+msgid "No Bass Boost"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
 #, fuzzy
-msgid "Analog Line-In"
+msgid "Headphones"
 msgstr "Analog Mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
+#: ../src/modules/alsa/alsa-mixer.c:2301
 #, fuzzy
-msgid "Analog Radio"
+msgid "Analog Input"
 msgstr "Analog Mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-#, fuzzy
-msgid "Analog Video"
-msgstr "Analog Stereo"
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2310
 #, fuzzy
 msgid "Analog Output"
 msgstr "Ausgang %s"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-#, fuzzy
-msgid "Analog Headphones"
-msgstr "Analog Mono"
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
+#: ../src/modules/alsa/alsa-mixer.c:2313
+msgid "Line Out"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2314
 #, fuzzy
 msgid "Analog Mono Output"
 msgstr "Analog Mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, fuzzy, c-format
-msgid "%s+%s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "Analog Stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, fuzzy, c-format
-msgid "%s / %s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Digital Stereo (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Digital Stereo (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr "Analog Mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr "Analog Stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3758
 #, fuzzy
 msgid "Analog Surround 2.1"
 msgstr "Analog Surround 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3759
 #, fuzzy
 msgid "Analog Surround 3.0"
 msgstr "Analog Surround 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3760
 #, fuzzy
 msgid "Analog Surround 3.1"
 msgstr "Analog Surround 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr "Analog Surround 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr "Analog Surround 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr "Analog Surround 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr "Analog Surround 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3765
 #, fuzzy
 msgid "Analog Surround 6.0"
 msgstr "Analog Surround 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3766
 #, fuzzy
 msgid "Analog Surround 6.1"
 msgstr "Analog Surround 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3767
 #, fuzzy
 msgid "Analog Surround 7.0"
 msgstr "Analog Surround 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr "Analog Surround 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr "Digital Stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
+#: ../src/modules/alsa/alsa-mixer.c:3770
 #, fuzzy
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "Digital Surround 4.0 (IEC958/AC3)"
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Digital Stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Digital Surround 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Digital Surround 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr "Digital Stereo (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Digital Surround 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 #, fuzzy
 msgid "Analog Mono Duplex"
 msgstr "Analog Mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 #, fuzzy
 msgid "Analog Stereo Duplex"
 msgstr "Analog Stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 #, fuzzy
 msgid "Digital Stereo Duplex (IEC958)"
 msgstr "Digital Stereo (IEC958)"
 
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Ausgang %s"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "Eingang %s"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit auf dieser Plattform nicht unterstützt."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() fehlgeschlagen"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Quell-Ausgabe #%u\n"
+#~ "\tTreiber: %s\n"
+#~ "\tOwner-Modul: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tQuelle: %u\n"
+#~ "\tSample-Spezifizierung: %s\n"
+#~ "\tKanalzuordnung: %s\n"
+#~ "\tPufferlatenz: %0.0f usec\n"
+#~ "\tQuelllatenz: %0.0f usec\n"
+#~ "\tResample-Methode: %s\n"
+#~ "\tEigenschaften:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Diese Hilfe anzeigen\n"
+#~ "      --version                         Version anzeigen\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   Name des Zielservers\n"
+#~ "  -n, --client-name=NAME                Rufname des Clients auf dem "
+#~ "Server\n"
+
+#, fuzzy
+#~ msgid "%s+%s"
+#~ msgstr "%s %s"
+
+#, fuzzy
+#~ msgid "%s / %s"
+#~ msgstr "%s %s"
+
+#, fuzzy
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Digital Surround 4.0 (IEC958/AC3)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Niedrigfrequenzemitter"
+
 #~ msgid "Invalid client name '%s'\n"
 #~ msgstr "Ungültiger Client-Name '%s'\n"
 
@@ -2794,11 +3249,5 @@ msgstr "Digital Stereo (IEC958)"
 #~ "Modul: %s\n"
 #~ "Argument: %s\n"
 
-#~ msgid "sink"
-#~ msgstr "Sink"
-
-#~ msgid "source"
-#~ msgstr "Quelle"
-
 #~ msgid "socketpair(): %s"
 #~ msgstr "socketpair(): %s"
index d9b2a4d..dedd12e 100644 (file)
--- a/po/el.po
+++ b/po/el.po
 # This file is distributed under the same license as the PACKAGE package.
 #
 # Dimitris Glezos <dimitris@glezos.com>, 2008.
-# Thalia Papoutsaki <saliyath@gmail.com>, 2009.
+# Thalia Papoutsaki <saliyath@gmail.com>, 2009, 2012.
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: el\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-10-26 09:45+0000\n"
-"PO-Revision-Date: 2009-10-26 17:15+0200\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:53+0000\n"
 "Last-Translator: Thalia Papoutsaki <saliyath@gmail.com>\n"
 "Language-Team: Greek <fedora-trans-el@redhat.com>\n"
+"Language: el\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Generator: KAider 0.1\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: KAider 0.1\n"
 
-#: ../src/modules/alsa/alsa-util.c:858
-#: ../src/pulsecore/sink.c:2629
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
-msgid "%s %s"
-msgstr "%s %s"
+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 ""
 
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1179
 #, 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."
+"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 ""
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1220
 #, 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."
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1263
 #, 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."
+"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 ""
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr ""
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr ""
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr ""
 
-#: ../src/modules/module-ladspa-sink.c:53
-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> channels=<number of channels> channel_map=<channel map> plugin=<ladspa plugin name> label=<ladspa plugin label> control=<comma seperated list of input control values>"
+#: ../src/modules/module-ladspa-sink.c:52
+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> "
+"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> "
 msgstr ""
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr ""
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr ""
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
-msgstr ""
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
+msgstr "Εσωτερικός ήχος"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "Modem"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr ""
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr ""
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr ""
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
-msgstr ""
+msgstr "Έγινε λήψη σήματος %s."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "Έξοδος."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "Αποτυχία εύρεσης χρήστη '%s'."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "Αποτυχία εύρεσης ομάδας χρηστών '%s'."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr ""
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr ""
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr ""
 
-#: ../src/daemon/main.c:208
-#: ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr ""
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr ""
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr ""
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr ""
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr ""
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr ""
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:571
-msgid "This program is not intended to be run as root (unless --system is specified)."
+#: ../src/daemon/main.c:657
+msgid ""
+"This program is not intended to be run as root (unless --system is "
+"specified)."
 msgstr ""
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr ""
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr ""
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr ""
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr ""
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr ""
 
-#: ../src/daemon/main.c:627
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
 #, c-format
-msgid "pipe failed: %s"
+msgid "pipe() failed: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:646
-#: ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr ""
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr ""
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "Αποτυχία σύνδεσης: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Αυτό είναι το PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr ""
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr ""
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr ""
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr ""
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, c-format
+msgid "Running in VM: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr ""
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr ""
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr ""
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr ""
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr ""
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr ""
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr ""
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr ""
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr ""
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr ""
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr ""
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
-"OK, so you are running PA in system mode. Please note that you most likely shouldn't be doing that.\n"
-"If you do it nonetheless then it's your own fault if things don't work as expected.\n"
-"Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an explanation why system mode is usually a bad idea."
+"OK, so you are running PA in system mode. Please note that you most likely "
+"shouldn't be doing that.\n"
+"If you do it nonetheless then it's your own fault if things don't work as "
+"expected.\n"
+"Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an "
+"explanation why system mode is usually a bad idea."
 msgstr ""
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr ""
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr ""
 
-#: ../src/daemon/main.c:821
-msgid "Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"
-msgstr "Δικέ μου, ο πυρήνας σου είναι για τα μπάζα! Η πρόταση του σεφ σήμερα είναι Linux με ενεργοποιημένα τα high-resolution timers!"
+#: ../src/daemon/main.c:993
+msgid ""
+"Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
+"resolution timers enabled!"
+msgstr ""
+"Δικέ μου, ο πυρήνας σου είναι για τα μπάζα! Η πρόταση του σεφ σήμερα είναι "
+"Linux με ενεργοποιημένα τα high-resolution timers!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr ""
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr ""
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr ""
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr ""
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr ""
 
-#: ../src/daemon/cmdline.c:115
+#: ../src/daemon/cmdline.c:113
 #, c-format
 msgid ""
 "%s [options]\n"
@@ -381,37 +433,46 @@ msgid ""
 "      --dump-conf                       Dump default configuration\n"
 "      --dump-modules                    Dump list of available modules\n"
 "      --dump-resample-methods           Dump available resample methods\n"
-"      --cleanup-shm                     Cleanup stale shared memory segments\n"
-"      --start                           Start the daemon if it is not running\n"
+"      --cleanup-shm                     Cleanup stale shared memory "
+"segments\n"
+"      --start                           Start the daemon if it is not "
+"running\n"
 "  -k  --kill                            Kill a running daemon\n"
-"      --check                           Check for a running daemon (only returns exit code)\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"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_NICE)\n"
 "      --realtime[=BOOL]                 Try to enable realtime scheduling\n"
-"                                        (only available as root, when SUID or\n"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_RTPRIO)\n"
-"      --disallow-module-loading[=BOOL]  Disallow module user requested module\n"
+"      --disallow-module-loading[=BOOL]  Disallow module user requested "
+"module\n"
 "                                        loading/unloading after startup\n"
 "      --disallow-exit[=BOOL]            Disallow user requested exit\n"
-"      --exit-idle-time=SECS             Terminate the daemon when idle and this\n"
+"      --exit-idle-time=SECS             Terminate the daemon when idle and "
+"this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle and\n"
-"                                        this time passed\n"
-"      --scache-idle-time=SECS           Unload autoloaded samples when idle and\n"
+"      --scache-idle-time=SECS           Unload autoloaded samples when idle "
+"and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
-"      --log-meta[=BOOL]                 Include code location in log messages\n"
+"      --log-target={auto,syslog,stderr,file: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"
+"  -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"
@@ -422,196 +483,204 @@ msgid ""
 "      --disable-shm[=BOOL]              Disable shared memory support.\n"
 "\n"
 "STARTUP SCRIPT:\n"
-"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module with\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module "
+"with\n"
 "                                        the specified argument\n"
 "  -F, --file=FILENAME                   Run the specified script\n"
-"  -C                                    Open a command line on the running TTY\n"
+"  -C                                    Open a command line on the running "
+"TTY\n"
 "                                        after startup\n"
 "\n"
 "  -n                                    Don't load default script file\n"
 msgstr ""
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr ""
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr ""
 
-#: ../src/daemon/cmdline.c:264
-msgid "--log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error)."
+#: ../src/daemon/cmdline.c:261
+msgid ""
+"--log-level expects log level argument (either numeric in range 0..4 or one "
+"of debug, info, notice, warn, error)."
 msgstr ""
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr ""
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr ""
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr ""
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr ""
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr ""
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr ""
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr ""
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr ""
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr ""
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr ""
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr ""
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr ""
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Όνομα: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr ""
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Έκδοση: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Περιγραφή: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Συγγραφέας: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Χρήση: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr ""
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr ""
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr ""
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:562
-msgid "The specified default channel map has a different number of channels than the specified default number of channels."
+#: ../src/daemon/daemon-conf.c:657
+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:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr ""
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr ""
 
@@ -623,8 +692,15 @@ msgstr ""
 msgid "Start the PulseAudio Sound System"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:105
-#: ../src/pulse/channelmap.c:757
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr ""
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
 
@@ -653,7 +729,7 @@ msgid "Rear Right"
 msgstr ""
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
+msgid "Subwoofer"
 msgstr ""
 
 #: ../src/pulse/channelmap.c:117
@@ -828,12 +904,10 @@ msgstr ""
 msgid "Top Rear Right"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:484
-#: ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295
-#: ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341
-#: ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(μη έγκυρο)"
 
@@ -861,334 +935,348 @@ msgstr "Surround 5.1"
 msgid "Surround 7.1"
 msgstr "Surround 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "Εντάξει"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr ""
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr ""
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr ""
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr ""
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr ""
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr ""
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr ""
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr ""
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr ""
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr ""
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr ""
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr ""
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr ""
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr ""
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr ""
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr ""
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr ""
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr ""
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr ""
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr ""
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr ""
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr ""
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr ""
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr ""
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr ""
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr ""
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55
-#: ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "σύνδεση(): %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
 msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr ""
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr ""
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr ""
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, fuzzy, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, fuzzy, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr ""
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, fuzzy, c-format
 msgid "Failed to drain stream: %s"
 msgstr "Αποτυχία εύρεσης χρήστη '%s'."
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr ""
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr ""
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr ""
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr ""
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr ""
 
-#: ../src/utils/pacat.c:237
-#: ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr ""
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr ""
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr ""
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 msgstr ""
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr ""
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr ""
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr ""
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr ""
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr ""
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr ""
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr ""
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr ""
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr ""
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr ""
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr ""
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr ""
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr ""
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr ""
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr ""
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr ""
 
-#: ../src/utils/pacat.c:470
-#: ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "Αποτυχία σύνδεσης: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr ""
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr ""
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr ""
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, fuzzy, c-format
 msgid "Failed to get latency: %s"
 msgstr "Αποτυχία εύρεσης χρήστη '%s'."
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr ""
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr ""
 
-#: ../src/utils/pacat.c:609
+#: ../src/utils/pacat.c:653
 #, c-format
 msgid ""
 "%s [options]\n"
@@ -1201,35 +1289,59 @@ msgid ""
 "\n"
 "  -v, --verbose                         Enable verbose operations\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -d, --device=DEVICE                   The name of the sink/source to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
-"      --stream-name=NAME                How to call this stream on the server\n"
-"      --volume=VOLUME                   Specify the initial (linear) volume in range 0...65536\n"
-"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to 44100)\n"
-"      --format=SAMPLEFORMAT             The sample type, one of s16le, s16be, u8, float32le,\n"
-"                                        float32be, ulaw, alaw, s32le, s32be, s24le, s24be,\n"
-"                                        s24-32le, s24-32be (defaults to s16ne)\n"
-"      --channels=CHANNELS               The number of channels, 1 for mono, 2 for stereo\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -d, --device=DEVICE                   The name of the sink/source to "
+"connect to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
+"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to "
+"44100)\n"
+"      --format=SAMPLEFORMAT             The sample type, one of s16le, "
+"s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be, "
+"s24le, s24be,\n"
+"                                        s24-32le, s24-32be (defaults to "
+"s16ne)\n"
+"      --channels=CHANNELS               The number of channels, 1 for mono, "
+"2 for stereo\n"
 "                                        (defaults to 2)\n"
-"      --channel-map=CHANNELMAP          Channel map to use instead of the default\n"
-"      --fix-format                      Take the sample format from the sink the stream is\n"
+"      --channel-map=CHANNELMAP          Channel map to use instead of the "
+"default\n"
+"      --fix-format                      Take the sample format from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-rate                        Take the sampling rate from the sink the stream is\n"
+"      --fix-rate                        Take the sampling rate from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-channels                    Take the number of channels and the channel map\n"
-"                                        from the sink the stream is being connected to.\n"
+"      --fix-channels                    Take the number of channels and the "
+"channel map\n"
+"                                        from the sink the stream is being "
+"connected to.\n"
 "      --no-remix                        Don't upmix or downmix channels.\n"
-"      --no-remap                        Map channels by index instead of name.\n"
-"      --latency=BYTES                   Request the specified latency in bytes.\n"
-"      --process-time=BYTES              Request the specified process time per request in bytes.\n"
-"      --property=PROPERTY=VALUE         Set the specified property to the specified value.\n"
+"      --no-remap                        Map channels by index instead of "
+"name.\n"
+"      --latency=BYTES                   Request the specified latency in "
+"bytes.\n"
+"      --process-time=BYTES              Request the specified process time "
+"per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
+"      --property=PROPERTY=VALUE         Set the specified property to the "
+"specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1237,179 +1349,182 @@ msgid ""
 "Linked with libpulse %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:764
-#: ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr ""
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr ""
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr ""
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr ""
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr ""
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr ""
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr ""
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr ""
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr ""
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr ""
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr ""
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr ""
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr ""
 
-#: ../src/utils/pacat.c:959
-msgid "Warning: specified sample specification will be overwritten with specification from file."
+#: ../src/utils/pacat.c:1036
+msgid ""
+"Warning: specified sample specification will be overwritten with "
+"specification from file."
 msgstr ""
 
-#: ../src/utils/pacat.c:962
-#: ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr ""
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr ""
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr ""
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr ""
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
-msgid "Opening a %s stream with sample specification '%s' and channel map '%s'."
+msgid ""
+"Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr ""
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr ""
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr ""
 
-#: ../src/utils/pacat.c:1035
-#: ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "Αποτυχία ανοίγματος αρχείου ήχου."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr ""
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr ""
 
-#: ../src/utils/pacat.c:1061
-#: ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr ""
 
-#: ../src/utils/pacat.c:1069
-#: ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr ""
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr ""
 
-#: ../src/utils/pacat.c:1082
-#: ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr ""
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, fuzzy, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, fuzzy, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr ""
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr ""
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr ""
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr ""
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr ""
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr ""
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
 "\n"
 msgstr ""
 
@@ -1436,35 +1551,46 @@ msgstr ""
 msgid "pa_mainloop_run() failed.\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, fuzzy, c-format
 msgid "Failed to get statistics: %s"
 msgstr "Αποτυχία εύρεσης χρήστη '%s'."
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, fuzzy, c-format
 msgid "Failed to get server information: %s"
 msgstr "Αποτυχία εύρεσης χρήστη '%s'."
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
+#, c-format
+msgid ""
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
 #, c-format
 msgid ""
-"User name: %s\n"
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1472,15 +1598,15 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, fuzzy, c-format
 msgid "Failed to get sink information: %s"
 msgstr "Αποτυχία εύρεσης χρήστη '%s'."
 
-#: ../src/utils/pactl.c:221
+#: ../src/utils/pactl.c:270
 #, c-format
 msgid ""
 "Sink #%u\n"
@@ -1497,29 +1623,32 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:268
-#: ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:274
-#: ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, c-format
+msgid "\tFormats:\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, fuzzy, c-format
 msgid "Failed to get source information: %s"
 msgstr "Αποτυχία εύρεσης χρήστη '%s'."
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1541,28 +1670,20 @@ msgid ""
 "\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:345
-#: ../src/utils/pactl.c:401
-#: ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473
-#: ../src/utils/pactl.c:532
-#: ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543
-#: ../src/utils/pactl.c:587
-#: ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594
-#: ../src/utils/pactl.c:637
-#: ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr ""
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, fuzzy, c-format
 msgid "Failed to get module information: %s"
 msgstr "Αποτυχία εύρεσης χρήστη '%s'."
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1573,12 +1694,12 @@ msgid ""
 "\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, fuzzy, c-format
 msgid "Failed to get client information: %s"
 msgstr "Αποτυχία εύρεσης χρήστη '%s'."
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1588,12 +1709,12 @@ msgid ""
 "\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, fuzzy, c-format
 msgid "Failed to get card information: %s"
 msgstr "Αποτυχία εύρεσης χρήστη '%s'."
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1604,22 +1725,22 @@ msgid ""
 "\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, fuzzy, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "Αποτυχία εύρεσης χρήστη '%s'."
 
-#: ../src/utils/pactl.c:515
+#: ../src/utils/pactl.c:622
 #, c-format
 msgid ""
 "Sink Input #%u\n"
@@ -1629,6 +1750,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1640,12 +1762,12 @@ msgid ""
 "\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, fuzzy, c-format
 msgid "Failed to get source output information: %s"
 msgstr "Αποτυχία εύρεσης χρήστη '%s'."
 
-#: ../src/utils/pactl.c:574
+#: ../src/utils/pactl.c:693
 #, c-format
 msgid ""
 "Source Output #%u\n"
@@ -1655,6 +1777,11 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
@@ -1662,12 +1789,12 @@ msgid ""
 "\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, fuzzy, c-format
 msgid "Failed to get sample information: %s"
 msgstr "Αποτυχία εύρεσης χρήστη '%s'."
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1685,58 +1812,173 @@ msgid ""
 "\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:653
-#: ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "Αποτυχία: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Αποτυχία εύρεσης χρήστη '%s'."
+
+#: ../src/utils/pactl.c:954
 #, fuzzy, c-format
 msgid "Failed to upload sample: %s"
 msgstr "Αποτυχία εύρεσης χρήστη '%s'."
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr ""
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+msgid "server"
+msgstr ""
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr ""
 
-#: ../src/utils/pactl.c:869
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr ""
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
 #, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -1744,104 +1986,131 @@ msgid ""
 "Linked with libpulse %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr ""
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "Αποτυχία ανοίγματος αρχείου ήχου."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr ""
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr ""
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr ""
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr ""
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr ""
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr ""
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr ""
 
-#: ../src/utils/pactl.c:1090
-msgid "You may not specify more than one sink. You have to specify a boolean value."
+#: ../src/utils/pactl.c:1560
+msgid ""
+"You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 
-#: ../src/utils/pactl.c:1103
-msgid "You may not specify more than one source. You have to specify a boolean value."
+#: ../src/utils/pactl.c:1573
+msgid ""
+"You may not specify more than one source. You have to specify a boolean "
+"value."
 msgstr ""
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr ""
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr ""
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr ""
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr ""
 
-#: ../src/utils/pactl.c:1154
-#: ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193
-#: ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226
-#: ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr ""
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr ""
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr ""
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr ""
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+msgid "You have to specify a source output index and a volume"
+msgstr ""
+
+#: ../src/utils/pactl.c:1665
+msgid "Invalid source output index"
+msgstr ""
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr ""
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+msgid "Invalid mute specification"
+msgstr ""
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr ""
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr ""
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr ""
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+msgid "You have to specify a source output index and a mute boolean"
+msgstr ""
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "Αποτυχία εύρεσης χρήστη '%s'."
+
+#: ../src/utils/pactl.c:1756
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr ""
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr ""
 
@@ -1852,7 +2121,8 @@ msgid ""
 "\n"
 " -d    Show current PulseAudio data attached to X11 display (default)\n"
 " -e    Export local PulseAudio data to X11 display\n"
-" -i    Import PulseAudio data from X11 display to local environment variables and cookie file.\n"
+" -i    Import PulseAudio data from X11 display to local environment "
+"variables and cookie file.\n"
 " -r    Remove PulseAudio data from X11 display\n"
 msgstr ""
 
@@ -1861,347 +2131,471 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr ""
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr ""
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr ""
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "σύνδεση(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr ""
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr ""
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr ""
 
-#: ../src/utils/pacmd.c:171
-#: ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr ""
 
-#: ../src/utils/pacmd.c:207
-#: ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr ""
 
-#: ../src/pulsecore/lock-autospawn.c:136
-#: ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-sink.c:530
-#: ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, 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."
+"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:506
-#: ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, 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."
+"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 ""
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr ""
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr ""
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr ""
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr ""
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr ""
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
 msgstr ""
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
 msgstr ""
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
 msgid "Docking Station Microphone"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2222
+msgid "Docking Station Line In"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+msgid "Front Microphone"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+msgid "Rear Microphone"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
 msgid "External Microphone"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
 msgstr "Radio"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
 msgstr "Video"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
+#: ../src/modules/alsa/alsa-mixer.c:2237
+msgid "Bass Boost"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
+#: ../src/modules/alsa/alsa-mixer.c:2238
+msgid "No Bass Boost"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr "Analog Radio"
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr "Analog Video"
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
-msgid "Analog Output"
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
+#: ../src/modules/alsa/alsa-mixer.c:2310
+msgid "Analog Output"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
 msgstr "Analog Output (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2313
+msgid "Line Out"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
 msgstr "Analog Mono Output"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, c-format
-msgid "%s+%s"
-msgstr "%s+%s"
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "Analog Stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984
-#: ../src/modules/alsa/alsa-mixer.c:3404
-#, c-format
-msgid "%s / %s"
-msgstr "%s / %s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Digital Stereo (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Digital Stereo (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr "Analog Mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr "Analog Stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
 msgstr "Analog Surround 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
 msgstr "Analog Surround 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
 msgstr "Analog Surround 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr "Analog Surround 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr "Analog Surround 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr "Analog Surround 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr "Analog Surround 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
 msgstr "Analog Surround 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
 msgstr "Analog Surround 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
 msgstr "Analog Surround 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr "Analog Surround 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr "Digital Stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "Digital Surround 4.0 (IEC958)"
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Digital Stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Digital Surround 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Digital Surround 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr "Digital Stereo (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Digital Surround 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
 msgstr "Analog Mono Duplex"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
 msgstr "Analog Stereo Duplex"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
 msgstr "Digital Stereo Duplex (IEC958)"
 
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, c-format
+msgid "%s Output"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, c-format
+msgid "%s Input"
+msgstr ""
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Digital Surround 4.0 (IEC958)"
index 48a4f13..e950c6a 100644 (file)
--- a/po/es.po
+++ b/po/es.po
@@ -3,28 +3,24 @@
 #
 # Domingo Becker <domingobecker@gmail.com>, 2009.
 # Héctor Daniel Cabrera <h.daniel.cabrera@gmail.com>, 2009.
+# Fernando Gonzalez Blanco <fgonz@fedoraproject.org>, 2009, 2012.
 #
-# Fernando Gonzalez Blanco <fgonz@fedoraproject.org>, 2009.
 msgid ""
 msgstr ""
 "Project-Id-Version: PulseAudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-10-04 16:37+0000\n"
-"PO-Revision-Date: 2009-10-04 21:16+0200\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:53+0000\n"
 "Last-Translator: Fernando Gonzalez Blanco <fgonz@fedoraproject.org>\n"
 "Language-Team: Spanish <fedora-trans-es@redhat.com>\n"
+"Language: es\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "X-Poedit-Language: Spanish\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -37,11 +33,11 @@ msgstr ""
 "Lo más probable es que sea un error del controlador ALSA '%s'. Por favor, "
 "informe ésto a los desarrolladores de ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
@@ -50,7 +46,20 @@ msgstr ""
 "Lo más probable es que sea un error del controlador ALSA '%s'. Por favor, "
 "informe ésto a los desarrolladores de ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() devolvió un valor que es excepcionalmente grande: %lu bytes "
+"(%lu ms).\n"
+"Lo más probable es que sea un error del controlador ALSA '%s'. Por favor, "
+"informe ésto a los desarrolladores de ALSA."
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -63,25 +72,28 @@ msgstr ""
 "Lo más probable es que sea un error del controlador ALSA '%s'. Por favor, "
 "informe ésto a los desarrolladores de ALSA."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "Siempre tenga al menos un sumidero cargado aunque sea uno nulo"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "Salida Boba"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "Sumidero virtual LADSPA"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<nombre para el sumidero> sink_properties=<propiedades para el "
 "sumidero> master=<nombre del sumidero a filtrar> format=<formato de ejemplo> "
@@ -90,120 +102,126 @@ msgstr ""
 "complemento ladspa> control=<lista separada por comas de valores de control "
 "de entrada>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "Sumidero nulo sincronizado"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "Salida Nula"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "Audio Interno"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "Módem"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "Falló al buscar cargador el cargador llt_dlopen original."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "Falló al asignar el cargador dl nuevo."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "Falló al agregar bind-now-loader."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "Se obtuvo la señal %s."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "Saliendo."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "Falló al buscar usuario '%s'."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "Falló al buscar grupo '%s'."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "Se encontró el usuario '%s' (UID %lu) y el grupo '%s' (GID %lu)."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "GID del usuario '%s' y del grupo '%s' no son similares."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "El directorio de inicio del usuario '%s' no es '%s', ignorando."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Falló al crear '%s': %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "Falló al cambiar la lista de grupo: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "Falló al cambiar GID: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "Falló al cambiar UID: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "Se han liberado con éxitos los privilegios de root."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "El modo a nivel de sistema no es soportado en esta plataforma."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) falló: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "Falló al analizar la línea de comando."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "El demonio no está funcionando"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "El demonio está funcionando como PID %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "No se ha podido detener el demonio: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -211,160 +229,181 @@ msgstr ""
 "Este programa no tiene por qué ser ejecutado como root (a menos que --system "
 "sea especificado)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "Se necesitan privilegios de root."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start no está soportado para las instancias del sistema."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr ""
 "Ejecutándose en modo de sistema, ¡pero no se ha configurado --disallow-exit! "
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
 "Ejecutándose en modo de sistema, ¡pero no se ha configurado --disallow-"
 "module-loading!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr ""
 "Ejecutándose en modo de sistema, ¡desactivando forzadamente el modo SHM!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 "Ejecutándose en modo de sistema, ¡desactivando forzadamente exit idle time!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "Fallo al intentar adquirir stdio."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "Falló el pipe: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "Falló el fork(): %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "Falló la operación read(): %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "Falló el inicio del demonio. "
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "El demonio se inició exitosamente."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "Falló la operación read(): %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Esto es PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Host de compilación: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "Compilación CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "Ejecutándose en el host: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "Se encontraron %u CPUs."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "El tamaño de la página es de %lu bytes"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Soporte para compilar con Valgrind: si"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Soporte para compilar con Valgrind: no"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "Ejecutándose en modo valgrind: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "Ejecutándose en el host: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "Build optimizado: si"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "Build optimizado: no"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG definido, todos los chequeos deshabilitados."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH definido, sólo se deshabilitan los chequeos fast path."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "Todos los chequeos habilitados."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "Fallo al intentar obtener el ID de la máquina"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "El ID de la máquina es %s"
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "El ID de la sesión es %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "Utilizando directorio de tiempo de ejecución %s."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "Utilizando directorio de estado %s."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "Utilizando directorio de módulos %s."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Ejecutándose en modo de sistema: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -381,17 +420,17 @@ msgstr ""
 "obtener una explicación acerca de por qué es una mala idea utilizar el  modo "
 "sistema."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "Ha fallado pa_pid_file_create()."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr ""
 "¡Existen cronómetros de alta resolución fresquitos y disponibles! ¡Bon "
 "appetit!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -399,34 +438,34 @@ msgstr ""
 "¡Amigo, su kernel deja mucho que desear! ¡El plato que hoy recomienda el "
 "chef es Linux con cronómetros de alta resolución activados!  "
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "Falló pa_core_new()."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "Fallo al intentar iniciar el demonio."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 "El demonio se ha iniciado sin ningún módulo cargado, y por ello se niega a "
 "funcionar."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "El demonio se inició completamente."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "Comienza a apagarse el demonio."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "El demonio se ha apagado."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -463,15 +502,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -577,15 +614,15 @@ msgstr ""
 "  -n                                    No carga el archivo script "
 "predeterminado\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize espera un argumento booleano"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail espera un argumento booleano"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -594,166 +631,169 @@ msgstr ""
 "caiga en el rango de 0..4; ya sea uno de debug, info, notice, warn, o "
 "error). "
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority espera un argumento booleano"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime espera un argumento booleano"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading espera un argumento booleano"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit espera un argumento booleano"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use pid-file espera un argumento booleano"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr "Log target inválido: use o \"syslog\", o \"stderr\", o \"auto\"."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time espera un argumento booleano"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta espera un argumento booleano"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Método de remuestreo inválido '%s'"
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system espera un argumento booleano"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit espera un argumento booleano"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm espera un argumento booleano"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Nombre: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "No existe información disponible acerca del módulo\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Versión: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Descripción: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Autor: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Uso: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "Carga una vez: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "ADVERTENCIA DE COMPATIBILIDAD: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Ruta: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Destino de log inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Nivel de log inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Método de remuestreo inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] Rlimit inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] Rlimit no soportado en esta plataforma."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Formato de muestra inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Tasa de muestra inválida '%s'."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Canales de muestra inválidos '%s'."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] Mapa de canal inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Cantidad de fragmentoa inválidos '%s'."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Tamaño inválido de fragmento '%s'."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Nivel de nice inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Tasa de muestra inválida '%s'."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "No se pudo abrir el archivo de configuración: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -761,12 +801,12 @@ msgstr ""
 "El mapa de canal predeterminado especificado tiene un número de canales "
 "distinto al especificado como predeterminado."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Leyendo desde el archivo de confioguración: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "Abandonando privilegios."
 
@@ -778,6 +818,16 @@ msgstr "Sistema de Sonido PulseAudio"
 msgid "Start the PulseAudio Sound System"
 msgstr "Iniciar el Sistema de Sonido PulseAudio"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "Sistema de Sonido PulseAudio"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "Iniciar el Sistema de Sonido PulseAudio"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
@@ -807,8 +857,8 @@ msgid "Rear Right"
 msgstr "POsterior derecho"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Emisor de baja frecuencia"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -982,9 +1032,10 @@ msgstr "Posterior izquierdo superior"
 msgid "Top Rear Right"
 msgstr "Posterior derecho superior"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(inválido)"
 
@@ -1012,332 +1063,349 @@ msgstr "Envolvente 5.1"
 msgid "Surround 7.1"
 msgstr "Envolvente 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "OK"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "Acceso negado"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Comando desconocido"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "Argumento inválido"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "Entidad existente"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "No existe tal entidad"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "Conexión negada"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "Error de protocolo"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "Timeout"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "Sin hay llave de autorización"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "Error interno"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "Conexión finalizada"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "Entidad terminada"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Servidor inválido"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "Falló la inicialización del módulo"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "Mal estado"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Sin datos"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "Versión de protocolo incompatible"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "Demasiado largo"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "No soportado"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Código de error desconocido"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "No existe tal extensión"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "Funcionalidad Obsoleta"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "Falta implementación"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "Cliente iniciado"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "Error de Entrada/Salida"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "Dispositivo o recurso ocupado"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() falló"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() falló: %s"
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "Fallo al analizar los datos de la cookie"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Fallo al abrir el archivo de configuración '%s': %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "No se ha cargado ninguna cookie. Intentando conectar de todos modos."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(:) %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "Se ha recibido un mensaje para una extensión desconocida '%s'"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "Falló al drenar el flujo: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "El flujo de reproducción ha sido drenado."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "Drenando conexión con el servidor."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() falló: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_write() falló: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() falló: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "Se ha creado exitosamente el flujo (stream)."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() falló: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 msgstr "Métrica del búfer: maxlenght=%u, tlenghth=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Métrica del búfer: maxlenght=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "Utilizando especificaciones de muestra '%s', mapa del canal '%s'."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "Conectado al dispositivo %s (%u, %ssuspended)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "Error de flujo: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "Dispositivo de flujo suspendido.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "Dispositivo de flujo reestablecido.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "Flujo agotado.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "Flujo saturado.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "Flujo iniciado.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "Fujo trasladado al dispositivo %s (%u, %ssuspended).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "no"
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "Los atributos del búfer de flujo han cambiado.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "Conexión establecida.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() falló: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() falló: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() falló: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "Error en la conexión: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "Se tiene EOF."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() falló: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "Hay señal, saliendo (exiting)."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "No se pudo obtener latencia: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Tiempo: %0.3f seg; Latencia: %0.0f useg."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() falló: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1389,10 +1457,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [opciones]\n"
@@ -1454,7 +1527,7 @@ msgstr ""
 "      --list-file-formats               Muestra una lista con los formatos "
 "de archivo disponibles.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1465,68 +1538,68 @@ msgstr ""
 "Compilado con libpulse %s\n"
 "Linkeado con libpulse %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "Nombre de cliente '%s' inválido"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "Nombre de flujo '%s' inválido"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "Mapa de canales '%s' inválido"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "Especificación de latencia '%s' inválida"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "Especificación de tiempo de proceso '%s' inválida"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "Propiedad '%s' inválida"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "Formato de archivo desconocido %s."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "Especificación de muestra inválida"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open() %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "Demasiados argumentos."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "Falló al generar especificación de ejemplo para el archivo."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "Falló al abrir el archivo de sonido."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
@@ -1534,104 +1607,109 @@ msgstr ""
 "Aviso: el ejemplo de especificación indicado será sobreescrito con las "
 "especificaciones del archivo."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "Falló al determinar especificación de ejemplo del archivo."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "Aviso: Falló al determinar el mapeo del canal desde el archivo."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "El mapa del canal no se corresponde con la especificación de muestra"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "Aviso: Faló al escribir el mapeo del canal en el archivo."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr ""
-"Abriendo un flujo %s con especificación de muestra '%s' y mapeo de canal '%"
-"s'."
+"Abriendo un flujo %s con especificación de muestra '%s' y mapeo de canal "
+"'%s'."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "grabando"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "playback"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "Falló al analizar la línea de comando."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() falló."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() falló."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() falló."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() falló: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_rttime_new() falló."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() falló."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "Error al suspender: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "Error al continuar: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "AVISO: El servidor de sonido no es local, no se suspende.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Error en la conexión: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "Hay SIGINT, saliendo.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "AVISO: El proceso niño terminado por la señal %u\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1676,37 +1754,48 @@ msgstr "pa_context_new() falló.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() falló.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "Error al intentar obtener estadísticas: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "Actualmente en uso: %u bloques conteniendo %s bytes en total.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr ""
 "Ubicados durante a lo largo del tiempo: %u bloques conteniendo %s bytes en "
 "total.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "Tamaño del cache de muestra: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "Error al intentar obtener información del servidor: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1714,7 +1803,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "Nombre de usuario: %s\n"
 "Nombre del equipo: %s\n"
@@ -1726,13 +1815,13 @@ msgstr ""
 "Fuente por defecto: %s\n"
 "Cookie: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "Error al intentar obtener información del sumidero: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1748,7 +1837,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1770,22 +1859,27 @@ msgstr ""
 "\tPropiedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tPuertos:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tPuerto Activo: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tPuertos:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "Error al intentar obtener información de la fuente: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1824,20 +1918,20 @@ msgstr ""
 "\tPropiedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "n/a"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "Error al intentar obtener información del módulo: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1854,12 +1948,12 @@ msgstr ""
 "\tPropiedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "Error al intentar obtener información del cliente: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1874,12 +1968,12 @@ msgstr ""
 "\tPropiedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "Fallo al obtener la información de la placa: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1896,23 +1990,23 @@ msgstr ""
 "\tPropiedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tPerfiles:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tPerfil Activo: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "Error al intentar obtener información de entrada del sumidero: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1921,6 +2015,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1948,13 +2043,13 @@ msgstr ""
 "\tPropiedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "Falló al obtener información de salida de la fuente: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1963,31 +2058,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Salida de la fuente #%u\n"
+"Entrada del sumidero #%u\n"
 "\tControlador: %s\n"
 "\tMódulo dueño: %s\n"
 "\tCliente: %s\n"
-"\tFuente: %u\n"
+"\tSumidero: %u\n"
 "\tEspecificación de muestra: %s\n"
-"\tMapa del canal: %s\n"
+"\tMapa de canales: %s\n"
+"\tMudo: %s\n"
+"\tVolumen: %s\n"
+"\t         %s\n"
+"\t         balance %0.2f\n"
 "\tLatencia del búfer: %0.0f useg\n"
-"\tLatencia de la fuente: %0.0f useg\n"
+"\tLatencia del sumidero: %0.0f useg\n"
 "\tMétodo de remuestreo: %s\n"
 "\tPropiedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "Falló al obtener información de la muestra: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -2018,48 +2122,164 @@ msgstr ""
 "\tPropiedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "Falla: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Error al intentar obtener información de la fuente: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "Falló al subir muestra: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "Fin de archivo prematuro"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr "destino"
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr "fuente"
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+#, fuzzy
+msgid "source-output"
+msgstr "fuente"
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "Servidor inválido"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "Hay un SIGINT, saliendo."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "Especificación de volumen inválida"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2069,37 +2289,15 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [opciones] stat\n"
-"%s [opciones] list\n"
-"%s [opciones] exit\n"
-"%s [opciones] upload-sample FILENAME [NAME]\n"
-"%s [opciones] play-sample NAME [SINK]\n"
-"%s [opciones] remove-sample NAME\n"
-"%s [opciones] move-sink-input ID SINK\n"
-"%s [opciones] move-source-output ID SOURCE\n"
-"%s [opciones] load-module NAME [ARGS ...]\n"
-"%s [opciones] unload-module ID\n"
-"%s [opciones] suspend-sink [SINK] 1|0\n"
-"%s [opciones] suspend-source [SOURCE] 1|0\n"
-"%s [opciones] set-card-profile [CARD] [PROFILE] \n"
-"%s [opciones] set-sink-port [SINK] [PORT] \n"
-"%s [opciones] set-source-port [SOURCE] [PORT] \n"
-"%s [opciones] set-sink-volume SINK VOLUME\n"
-"%s [opciones] set-source-volume SOURCE VOLUME\n"
-"%s [opciones] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [opciones] set-sink-mute SINK 1|0\n"
-"%s [opciones] set-source-mute SOURCE 1|0\n"
-"%s [opciones] set-sink-input-mute SINKINPUT 1|0\n"
+"%s [opciones] ... \n"
 "\n"
 "  -h, --help                            Muestra esta ayuda\n"
 "      --version                         Muestra la versión\n"
-"\n"
-"  -s, --server=SERVER                   El nombre del servidor al que "
+"  -s, --server=SERVER                   El nombre del servidor con el que "
 "conectarse\n"
-"  -n, --client-name=NAME                El nombre de este cliente en el "
-"servidor\n"
+"\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2110,52 +2308,57 @@ msgstr ""
 "Compilado con libpulse %s\n"
 "Linked con libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "Por favor, especifique un archivo de muestra a cargar"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "Error al intentar abrir el archivo de sonido."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr ""
 "Aviso: Falló al intentar determinar especificación de la muestra desde el "
 "archivo."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "Debe especificar un nombre de muestra para reproducir"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "Debe especificar un nombre de muestra a eliminar"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "Debe especificar un índice para la entrada al sumidero y un sumidero"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "Debe especificar un índice para las salida de la fuente y una fuente"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "Debe especificar un nombre de módulo y los argumentos."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "Debe especificar un índice de módulo"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "No puede especificar más de un sumidero. Tiene que especificar un valor "
 "booleano."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
@@ -2163,58 +2366,85 @@ msgstr ""
 "No puede especificar más de una fuente. Tiene que especificar un valor "
 "booleano."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "Debe especificar un nombre/índice de placa y un nombre de perfil"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "Debe especificar un nombre/índice de sumidero y un nombre de puerto"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "Debe especificar un nombre/índice de fuente y un nombre de puerto"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "Debe especificar un nombre/índice de sumidero y el volumen"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "Especificación de volumen inválida"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "Debe especificar un nombre/índice de fuente y un volumen"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "Debe especificar un índice de sumidero y un volumen"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "Indice de entrada a sumidero inválido"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "Debe especificar un índice para las salida de la fuente y una fuente"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "Indice de entrada a sumidero inválido"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "Debe especificar un nombre/índice de sumidero y un booleano para mudo"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "Especificación de muestra inválida"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "Debe especificar un nombre/índice de fuente y un booleano para mudo"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr ""
 "Debe especificar un índice de entrada a sumidero y un booleano para mudo"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "Especificación de índice de entrada a sumidero inválida"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "Debe especificar un nombre/índice de fuente y un booleano para mudo"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "Especificación de índice de entrada a sumidero inválida"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "Debe especificar un nombre/índice de sumidero y un booleano para mudo"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "No se ha especificado ningún comando válido."
 
@@ -2243,105 +2473,105 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "Error al interpretar una línea de comando.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Servidor: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Fuente: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Destino: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Cookie: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "Error al intepretar datos de cookie\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "Error al intentar guardar datos de cookie\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "Error al intentar cargar el archivo de configuración del cliente.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "Error al intentar leer datos de configuración de entorno.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "Error al obtener FQDN.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "Error al cargar datos de cookie\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Aún no se ha implementado.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr ""
 "El demonio PulseAudio no está ejecutándose, o no se está ejecutando como un "
 "demonio de sesión."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "Error al intentar detener el demonio de PulseAudio."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "El demonio no responde."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "No se puede acceder al candado de autogeneración."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2358,7 +2588,7 @@ msgstr ""
 "Nos despertaron con POLLOUT puesto -- sin embargo, una llamada a "
 "snd_pcm_avail() devolvió 0 u otro valor < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2375,232 +2605,470 @@ msgstr ""
 "Nos despertaron con POLLIN puesto -- sin embargo, una llamada a snd_pcm_avail"
 "() devolvió 0 u otro valor < min_avail."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "Apagado"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "Reproducción de Alta Fidelidad (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "Captura de Alta Fidelidad (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Telefonía Duplex (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "Servidor de Sonido PulseAudio"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
 msgstr "Dispositivos de salida"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
 msgstr "Dispositivos de entrada"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
 msgstr "Audio en @HOSTNAME@"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
 msgstr "Entrada"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
 msgstr "Estación dock de entrada"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
 msgstr "Micrófono de la estación Dock"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "Estación dock de entrada"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
 msgstr "En línea"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
 msgstr "Micrófono"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "Micrófono de la estación Dock"
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "Micrófono"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
 msgid "External Microphone"
 msgstr "Micrófono externo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
 msgstr "Micrófono interno"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
 msgstr "Radio"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
 msgstr "Vídeo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
 msgstr "Control automático de ganancia"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
 msgstr "Sin control automático de ganancia"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
 msgstr "Incremento de ganancia"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
 msgstr "Sin incremento de ganancia"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
 msgstr "Amplificador"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
 msgstr "Sin amplificador"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr "Entrada analógica"
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "Incremento de ganancia"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr "Micrófono analógico"
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "Sin incremento de ganancia"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
-msgstr "Entrada en línea analógica"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr "Radio analógico"
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "Auriculares analógicos"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr "Vídeo analógico"
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "Entrada analógica"
+
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "Micrófono de la estación Dock"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
 msgstr "Salida analógica"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr "Auriculares analógicos"
-
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
 msgstr "Salida analógica (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "En línea"
+
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
 msgstr "Salida Mono analógica "
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, c-format
-msgid "%s+%s"
-msgstr "%s+%s"
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "Estéreo Analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, c-format
-msgid "%s / %s"
-msgstr "%s / %s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Estéreo Digital (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Estéreo Digital (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr "Mono Analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr "Estéreo Analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
 msgstr "Análogico Envolvente 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
 msgstr "Análogico Envolvente 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
 msgstr "Análogico Envolvente 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr "Análogo Envolvente 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr "Análogo Envolvente 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr "Análogo Envolvente 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr "Análogo Envolvente 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
 msgstr "Análogico Envolvente 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
 msgstr "Análogico Envolvente 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
 msgstr "Análogico Envolvente 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr "Análogo Envolvénte 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr "Estéreo Digital (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "Digital Envolvente 4.0 (IEC9588)"
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Estéreo Digital (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Digital Envolvente 4.0 (IEC9588/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Digital Envolvente 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr "Estéreo Digital (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Digital Envolvente 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
 msgstr "Mono Analógico.Duplex"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
 msgstr "Estéreo Analógico.Duplex"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
 msgstr "Estéreo Digital Duplex(IEC958)"
 
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Salida Nula"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "Entrada"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<nombre para el sumidero> sink_properties=<propiedades para el "
+"sumidero> master=<nombre del sumidero a filtrar> format=<formato de ejemplo> "
+"rate=<tasa de ejemplo> channels=<cantidad de canaless> channel_map=<mapeo de "
+"canales> plugin=<nombre del complemento ladspa> label=<etiqueta del "
+"complemento ladspa> control=<lista separada por comas de valores de control "
+"de entrada>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] Rlimit no soportado en esta plataforma."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() falló"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Salida de la fuente #%u\n"
+#~ "\tControlador: %s\n"
+#~ "\tMódulo dueño: %s\n"
+#~ "\tCliente: %s\n"
+#~ "\tFuente: %u\n"
+#~ "\tEspecificación de muestra: %s\n"
+#~ "\tMapa del canal: %s\n"
+#~ "\tLatencia del búfer: %0.0f useg\n"
+#~ "\tLatencia de la fuente: %0.0f useg\n"
+#~ "\tMétodo de remuestreo: %s\n"
+#~ "\tPropiedades:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [opciones] stat\n"
+#~ "%s [opciones] list\n"
+#~ "%s [opciones] exit\n"
+#~ "%s [opciones] upload-sample FILENAME [NAME]\n"
+#~ "%s [opciones] play-sample NAME [SINK]\n"
+#~ "%s [opciones] remove-sample NAME\n"
+#~ "%s [opciones] move-sink-input ID SINK\n"
+#~ "%s [opciones] move-source-output ID SOURCE\n"
+#~ "%s [opciones] load-module NAME [ARGS ...]\n"
+#~ "%s [opciones] unload-module ID\n"
+#~ "%s [opciones] suspend-sink [SINK] 1|0\n"
+#~ "%s [opciones] suspend-source [SOURCE] 1|0\n"
+#~ "%s [opciones] set-card-profile [CARD] [PROFILE] \n"
+#~ "%s [opciones] set-sink-port [SINK] [PORT] \n"
+#~ "%s [opciones] set-source-port [SOURCE] [PORT] \n"
+#~ "%s [opciones] set-sink-volume SINK VOLUME\n"
+#~ "%s [opciones] set-source-volume SOURCE VOLUME\n"
+#~ "%s [opciones] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [opciones] set-sink-mute SINK 1|0\n"
+#~ "%s [opciones] set-source-mute SOURCE 1|0\n"
+#~ "%s [opciones] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Muestra esta ayuda\n"
+#~ "      --version                         Muestra la versión\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   El nombre del servidor al que "
+#~ "conectarse\n"
+#~ "  -n, --client-name=NAME                El nombre de este cliente en el "
+#~ "servidor\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Digital Envolvente 4.0 (IEC9588)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Emisor de baja frecuencia"
+
 #~ msgid "Invalid client name '%s'\n"
 #~ msgstr "Nombre de cliente inválido '%s'\n"
 
@@ -2712,9 +3180,9 @@ msgstr "Estéreo Digital Duplex(IEC958)"
 #~ "necesario y no se puede aumentar los límites del recurso RLIMIT_NICE/"
 #~ "RLIMIT_RTPRIO.\n"
 #~ "Para habilitar la planifiación de tiempo real/alta prioridad por favor "
-#~ "adquiera los privilegios apropiados en PolicyKit, o hágase miembro de '%"
-#~ "s', o aumente los límites del recurso RLIMIT_NICE/RLIMIT_RTPRIO para este "
-#~ "usuario."
+#~ "adquiera los privilegios apropiados en PolicyKit, o hágase miembro de "
+#~ "'%s', o aumente los límites del recurso RLIMIT_NICE/RLIMIT_RTPRIO para "
+#~ "este usuario."
 
 #~ msgid ""
 #~ "High-priority scheduling enabled in configuration but not allowed by "
@@ -2875,9 +3343,3 @@ msgstr "Estéreo Digital Duplex(IEC958)"
 #~ "Tipo: %s\n"
 #~ "Módulo: %s\n"
 #~ "Argumento: %s\n"
-
-#~ msgid "sink"
-#~ msgstr "destino"
-
-#~ msgid "source"
-#~ msgstr "fuente"
index cfb1437..0dfbc67 100644 (file)
--- a/po/fi.po
+++ b/po/fi.po
@@ -2,26 +2,23 @@
 # Copyright (C) 2008 Timo Jyrinki
 # This file is distributed under the same license as the pulseaudio package.
 # Timo Jyrinki <timo.jyrinki@iki.fi>, 2008.
-# Ville-Pekka Vainio <vpivaini@cs.helsinki.fi>, 2009.
+# Ville-Pekka Vainio <vpivaini@cs.helsinki.fi>, 2009, 2012.
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: git trunk\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-11-09 15:16+0200\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:53+0000\n"
 "Last-Translator: Ville-Pekka Vainio <vpivaini@cs.helsinki.fi>\n"
 "Language-Team: Finnish <laatu@lokalisointi.org>\n"
+"Language: fi\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -33,11 +30,11 @@ msgstr ""
 "Tämä on todennäköisesti ohjelmavirhe ALSA-ajurissa ”%s”. Ilmoita tästä "
 "ongelmasta ALSA-kehittäjille."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
@@ -46,7 +43,19 @@ msgstr ""
 "Tämä on todennäköisesti ohjelmavirhe ALSA-ajurissa ”%s”. Ilmoita tästä "
 "ongelmasta ALSA-kehittäjille."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() palautti poikkeuksellisen suuren arvon: %lu tavua (%lu ms).\n"
+"Tämä on todennäköisesti ohjelmavirhe ALSA-ajurissa ”%s”. Ilmoita tästä "
+"ongelmasta ALSA-kehittäjille."
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -59,25 +68,28 @@ msgstr ""
 "Tämä on todennäköisesti ohjelmavirhe ALSA-ajurissa ”%s”. Ilmoita tästä "
 "ongelmasta ALSA-kehittäjille."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "Pidä aina vähintään yksi nielu ladattuna, vaikka se olisi tyhjä nielu"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "Valeulostulo"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "Virtuaalinen LADSPA-nielu"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<nielun nimi> sink_properties=<nielun asetukset> "
 "master=<suodatettavan nielun nimi> format=<näytemuoto> "
@@ -86,120 +98,126 @@ msgstr ""
 "liitännäisen nimiö (label)> control=<pilkulla erotettu luettelo "
 "syötteenhallinta-arvoja>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "Kellotettu tyhjä nielu"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "Tyhjä ulostulo"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "Sisäinen äänentoisto"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "Modeemi"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "Alkuperäisen lt_dlopen-lataimen löytäminen epäonnistui."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "Uuden dl-lataaminen varaaminen epäonnistui."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "bind-now-loaderin lisääminen epäonnistui."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "Saatiin signaali %s."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "Poistutaan."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "Käyttäjää ”%s” ei löydetty."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "Ryhmää ”%s” ei löydetty."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "Löydettiin käyttäjä ”%s” (UID %lu) ja ryhmä ”%s” (GID %lu)."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "Käyttäjän ”%s” ja ryhmän ”%s” GID:t eivät vastaa toisiaan."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "Käyttäjän ”%s” kotihakemisto ei ole ”%s”, ohitetaan."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Hakemiston ”%s” luominen epäonnistui: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "Ryhmäluettelon vaihtaminen epäonnistui: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "GID:n vaihtaminen epäonnistui: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "UID:n vaihtaminen epäonnistui: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "Root-oikeuksista luopuminen onnistui."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "Järjestelmänlaajuista tilaa ei tueta tällä alustalla."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) epäonnistui: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "Komentorivin jäsentäminen epäonnistui."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "Taustaprosessi ei ole käynnissä"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "Taustaprosessi käynnissä prosessitunnisteella %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "Taustaprosessin lopettaminen epäonnistui: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -207,161 +225,182 @@ msgstr ""
 "Tätä ohjelmaa ei ole tarkoitettu suoritettavaksi pääkäyttäjänä (ellei --"
 "system ole määritelty)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "Pääkäyttäjän (root) oikeudet vaaditaan."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start-valitsinta ei tueta järjestelmätilassa."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr ""
 "Suoritetaan järjestelmätilassa, mutta --disallow-exit ei ole asetettuna!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
-"Suoritetaan järjestelmätilassa, mutta -disallow-module-loading ei ole "
+"Suoritetaan järjestelmätilassa, mutta --disallow-module-loading ei ole "
 "asetettuna!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr ""
 "Suoritetaan järjestelmätilassa, otetaan SHM-tila pakotetusti pois käytöstä."
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 "Suoritetaan järjestelmätilassa, otetaan poistumisen joutenoloaika "
 "pakotetusti pois käytöstä."
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "stdio:n saaminen epäonnistui."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "putki epäonnistui: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() epäonnistui: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() epäonnistui: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "Taustaprosessin käynnistys epäonnistui."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "Taustaprosessin käynnistys onnistui."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() epäonnistui: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Tämä on PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Käännöksen isäntäkone: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "Käännösaikaiset C-liput (CFLAGS): %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "Käynnissä isäntäkoneella: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "Löydettiin %u CPU:ta."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "Sivun koko on %lu tavua"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Käännetty Valgrind-tuella: kyllä"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Käännetty Valgrind-tuella: ei"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "Käynnissä valgrind-tilassa: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "Käynnissä isäntäkoneella: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "Optimoitu rakentaminen: kyllä"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "Optimoitu rakentaminen: ei"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG on määritelty, kaikki assertit ovat poissa käytöstä."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH on määritelty, vain fast path -assertit ovat poissa käytöstä."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "Kaikki assertit ovat käytössä."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "Konetunnisteen nouto epäonnistui"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "Konetunniste on %s."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "Istunnon tunniste on %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "Käytetään ajonaikaista hakemistoa %s."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "Käytetään tilahakemistoa %s."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "Käytetään moduulihakemistoa %s."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Suoritetaan järjestelmätilassa: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -375,15 +414,15 @@ msgstr ""
 "Lisätietoja siitä, miksi järjestelmätilan käyttäminen on yleensä huono "
 "ajatus on osoitteessa http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode"
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() epäonnistui."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "Korkean tarkkuuden ajastimet käytettävissä."
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -391,34 +430,34 @@ msgstr ""
 "Hei, ytimesi on kehno! Linux korkean tarkkuuden ajastimien tuella on hyvin "
 "suositeltava!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() epäonnistui."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "Taustaprosessin alustus epäonnistui."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 "Taustaprosessin käynnistys ilman ladattavia moduuleita, kieltäydytään "
 "toiminnasta."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "Taustaprosessin käynnistys valmis."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "Taustaprosessin sulkeminen käynnistetty."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "Taustaprosessi lopetettu."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -455,15 +494,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -572,15 +609,15 @@ msgstr ""
 "  -n                                    Älä lataa oletuskomentosarja-\n"
 "                                        tiedostoa\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize vaatii totuusarvoisen argumentin"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail vaatii totuusarvoisen argumentin"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -588,168 +625,171 @@ msgstr ""
 "--log-level vaatii lokikirjoituksen tason argumentiksi (joko numero väliltä "
 "0..4 tai yksi seuraavista: debug, info, notice, warn, error)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority vaatii totuusarvoisen argumentin"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime vaatii totuusarvoisen argumentin"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading vaatii totuusarvoisen argumentin"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit vaatii totuusarvoisen argumentin"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file vaatii totuusarvoisen argumentin"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr ""
 "Virheellinen lokikirjoituksen kohde: käytä jotain seuraavista: ”syslog”, "
 "”stderr” tai ”auto”."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time vaatii totuusarvoisen argumentin"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta vaatii totuusarvoisen argumentin"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Virheellinen uudelleennäytteistyksen tapa ”%s”."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system vaatii totuusarvoisen argumentin"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit vaatii totuusarvoisen argumentin"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm vaatii totuusarvoisen argumentin"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Nimi: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "Moduulitietoja ei saatavilla\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Versio: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Kuvaus: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Tekijä: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Käyttö: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "Lataa kerran: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "VAROITUS VANHENTUNEISUUDESTA: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Polku: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Virheellinen lokikirjoituksen kohde ”%s”."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Virheellinen lokikirjoituksen taso ”%s”."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Virheellinen uudelleennäytteistyksen tapa ”%s”."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] Virheellinen rlimit ”%s”."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimitiä ei tueta tällä alustalla."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Virheellinen näytemuoto ”%s”."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Virheellinen näytteenottotaajuus ”%s”."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Virheelliset näytekanavat ”%s”."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] Virheellinen kanavakartta ”%s”."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Virheellinen fragmenttimäärä ”%s”."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Virheellinen fragmenttikoko ”%s”."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Virheellinen nice-taso ”%s”."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Virheellinen näytteenottotaajuus ”%s”."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Asetustiedoston avaaminen epäonnistui: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -757,12 +797,12 @@ msgstr ""
 "Kanavien oletusmäärä ja oletuskanavakartan kanavien määrä poikkeavat "
 "toisistaan."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Luettu asetustiedostosta: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "Luovutaan oikeuksista."
 
@@ -774,6 +814,16 @@ msgstr "PulseAudio-äänijärjestelmä"
 msgid "Start the PulseAudio Sound System"
 msgstr "Käynnistä PulseAudio-äänijärjestelmä"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio-äänijärjestelmä"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "Käynnistä PulseAudio-äänijärjestelmä"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
@@ -803,8 +853,8 @@ msgid "Rear Right"
 msgstr "Oikea taka"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Alataajuus"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -978,9 +1028,10 @@ msgstr "Vasen ylä taka"
 msgid "Top Rear Right"
 msgstr "Oikea ylä taka"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(virheellinen)"
 
@@ -1008,332 +1059,349 @@ msgstr "5.1-tilaääni"
 msgid "Surround 7.1"
 msgstr "7.1-tilaääni"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "OK"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "Pääsy evätty"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Tuntematon komento"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "Virheellinen argumentti"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "Entiteetti on jo olemassa"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "Ei kyseisenlaista entiteettiä"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "Yhteys hylätty"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "Yhteyskäytäntövirhe"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "Aikakatkaisu"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "Ei todentamisavainta"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "Sisäinen virhe"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "Yhteys katkennut"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "Entiteetti lopetettu"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Virheellinen palvelin"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "Moduulin alustus epäonnistui"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "Virheellinen tila"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Ei dataa"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "Epäyhteensopiva yhteyskäytännön versio"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "Liian suuri"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "Ei tuettu"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Tuntematon virhekoodi"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "Ei kyseisenlaista laajennusta"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "Puuttuva toiminnallisuus"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "Puuttuva toteutus"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "Asiakasohjelma haarautui"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "Siirräntävirhe"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "Laite tai resurssi on varattu"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %u kan. %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() epäonnistui"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() epäonnistui: %s"
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "Evästetietojen jäsennys epäonnistui"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Asetustiedoston avaaminen epäonnistui: ”%s”: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "Ei ladattua evästettä. Yritetään yhdistämistä ilman."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "Saatiin viesti tuntemattomalle laajennokselle ”%s”"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "Virran tyhjentäminen epäonnistui: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "Toistovirta on tyhjennetty."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "Tyhjennetään yhteyttä palvelimelle."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() epäonnistui: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_write() epäonnistui: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() epäonnistui: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "Virran luonti onnistui."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() epäonnistui: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 msgstr "Puskuritiedot: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Puskuritiedot: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "Käytetään näytemäärittelyä ”%s”, kanavakarttaa ”%s”."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "Yhdistetty laitteeseen %s (%u, %ssuspended)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "Virtavirhe: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "Virtalaite keskeytetty.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "Virtalaite palautettu.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "Virran alivuoto.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "Virran ylivuoto.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "Virta käynnistetty.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "Virta siirretty laitteelle %s (%u, %ssuspended).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "ei "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "Virran puskuriattribuutteja muutettu.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "Yhteys muodostettu.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() epäonnistui: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() epäonnistui: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() epäonnistui: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "Yhteysvirhe: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "Saatiin EOF."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() epäonnistui: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "Saatiin signaali, lopetetaan."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "Latenssin selvittäminen epäonnistui: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Aika: %0.3f s; Latenssi: %0.0f μs."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() epäonnistui: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1385,10 +1453,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [valitsimet]\n"
@@ -1444,7 +1517,7 @@ msgstr ""
 "      --list-file-formats               Luettele käytettävissä olevat "
 "tiedostomuodot.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1455,170 +1528,175 @@ msgstr ""
 "Käännetty libpulsen versiolle %s\n"
 "Linkitetty libpulsen versiolle %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "Virheellinen asiakasohjelman nimi ”%s”"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "Virheellinen virran nimi ”%s”"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "Virheellinen kanavakartta ”%s”"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "Virheellinen latenssimääritys ”%s”"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "Virheellinen prosessiajan määritys ”%s”"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "Virheellinen asetus ”%s”"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "Tuntematon tiedostomuoto %s."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "Virheellinen näytemääritys"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "Liian monta argumenttia."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "Näytemäärityksen generointi tiedostolle epäonnistui."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "Äänitiedoston avaaminen epäonnistui."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
 msgstr ""
 "Varoitus: tiedostosta luettava näytemääritys korvaa annetun määrityksen."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "Näytemäärityksen selvittäminen tiedostosta epäonnistui."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "Varoitus: Kanavakartan selvittäminen tiedostosta epäonnistui."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "Kanavakartta ei vastaa näytemääritystä"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "Varoitus: kanavakartan kirjoittaminen tiedostoon epäonnistui."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr "Avataan %svirta näytemäärityksellä ”%s” ja kanavakartalla ”%s”."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "nauhoitus"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "toisto"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "Komentorivin jäsentäminen epäonnistui."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() epäonnistui."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() epäonnistui."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() epäonnistui."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() epäonnistui: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_new() epäonnistui."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() epäonnistui."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "Keskeytys epäonnistui: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "Palautus epäonnistui: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "VAROITUS: Äänipalvelin ei ole paikallinen, ei keskeytetä.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Yhteysvirhe: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "Saatiin SIGINT, lopetetaan.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "VAROITUS: Lapsiprosessi lopetettiin signaalilla %u\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1663,35 +1741,46 @@ msgstr "pa_context_new() epäonnistui.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() epäonnistui.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "Tilastojen selvittäminen epäonnistui: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "Nyt käytössä: %u lohkoa sisältäen yhteensä %s tavua.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "Koko käyttöaikana varattu: %u lohkoa sisältäen yhteensä %s tavua.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "Näytevälimuistin koko: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "Palvelintietojen selvittäminen epäonnistui: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1699,7 +1788,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "Käyttäjänimi: %s\n"
 "Konenimi: %s\n"
@@ -1711,13 +1800,13 @@ msgstr ""
 "Oletuslähde: %s\n"
 "Eväste: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "Nielun tietojen nouto epäonnistui: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1733,7 +1822,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1755,22 +1844,27 @@ msgstr ""
 "\tOminaisuudet:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tPortit:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tAktiivinen portti: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tPortit:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "Lähteen tietojen nouto epäonnistui: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1809,20 +1903,20 @@ msgstr ""
 "\tOminaisuudet:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "-"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "Moduulin tietojen nouto epäonnistui: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1839,12 +1933,12 @@ msgstr ""
 "\tOminaisuudet:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "Asiakkaan tietojen nouto epäonnistui: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1859,12 +1953,12 @@ msgstr ""
 "\tOminaisuudet:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "Kortin tietojen nouto epäonnistui: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1881,23 +1975,23 @@ msgstr ""
 "\tOminaisuudet:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tProfiilit:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tAktiivinen profiili: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "Nielun sisääntulon tietojen nouto epäonnistui: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1906,6 +2000,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1933,13 +2028,13 @@ msgstr ""
 "\tOminaisuudet:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "Lähteen ulostulon tietojen nouto epäonnistui: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1948,31 +2043,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Lähteen ulostulo #%u\n"
+"Nielun sisääntulo #%u\n"
 "\tAjuri: %s\n"
 "\tOmistava moduuli: %s\n"
 "\tAsiakas: %s\n"
-"\tLähde: %u\n"
+"\tNielu: %u\n"
 "\tNäytemäärittely: %s\n"
 "\tKanavakartta: %s\n"
+"\tVaimennus: %s\n"
+"\tÄänenvoimakkuus: %s\n"
+"\t                 %s\n"
+"\t                 balanssi %0.2f\n"
 "\tPuskurin latenssi: %0.0f μs\n"
-"\tLähteen latenssi: %0.0f μs\n"
+"\tNielun latenssi: %0.0f μs\n"
 "\tUudelleennäytteistyksen tapa: %s\n"
 "\tOminaisuudet:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "Näytetietojen nouto epäonnistui: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -2003,48 +2107,164 @@ msgstr ""
 "\tOminaisuudet:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "Epäonnistuminen: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Lähteen tietojen nouto epäonnistui: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "Näytteen lähettäminen epäonnistui: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "Ennenaikainen tiedoston päättyminen"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr "nielu"
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr "lähde"
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+#, fuzzy
+msgid "source-output"
+msgstr "lähde"
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "Virheellinen palvelin"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "Saatiin SIGINT, lopetetaan."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "Virheellinen äänenvoimakkuuden määritys"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2054,37 +2274,15 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [valitsimet] stat\n"
-"%s [valitsimet] list\n"
-"%s [valitsimet] exit\n"
-"%s [valitsimet] upload-sample TIEDOSTONIMI [NIMI]\n"
-"%s [valitsimet] play-sample NIMI [NIELU]\n"
-"%s [valitsimet] remove-sample NIMI\n"
-"%s [valitsimet] move-sink-input NIELUSISÄÄNMENO NIELU\n"
-"%s [valitsimet] move-source-output LÄHDEULOSTULO LÄHDE\n"
-"%s [valitsimet] load-module NIMI [ARGUMENTIT ...]\n"
-"%s [valitsimet] unload-module MODUULI\n"
-"%s [valitsimet] suspend-sink NIELU 1|0\n"
-"%s [valitsimet] suspend-source LÄHDE 1|0\n"
-"%s [valitsimet] set-card-profile KORTTI PROFIILI\n"
-"%s [valitsimet] set-sink-port NIELU PORTTI\n"
-"%s [valitsimet] set-source-port LÄHDE PORTTI\n"
-"%s [valitsimet] set-sink-volume NIELU VOIMAKKUUS\n"
-"%s [valitsimet] set-source-volume LÄHDE VOIMAKKUUS\n"
-"%s [valitsimet] set-sink-input-volume NIELUSISÄÄNMENO VOIMAKKUUS\n"
-"%s [valitsimet] set-sink-mute NIELU 1|0\n"
-"%s [valitsimet] set-source-mute LÄHDE 1|0\n"
-"%s [valitsimet] set-sink-input-mute NIELUSISÄÄNMENO 1|0\n"
+"%s [valitsimet] ... \n"
 "\n"
 "  -h, --help                            Näytä tämä ohje\n"
 "      --version                         Näytä versio\n"
+"  -s, --server=PALVELIN                 Sen palvelimen nimi, johon\n"
+"                                        yhdistetään\n"
 "\n"
-"  -s, --server=PALVELIN                 Sen palvelimen nimi, johon "
-"yhdistetään\n"
-"  -n, --client-name=NIMI                Kuinka tätä asiakasohjelmaa "
-"kutsutaan palvelimella\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2095,104 +2293,136 @@ msgstr ""
 "Käännetty libpulsen versiolle %s\n"
 "Linkitetty libpulsen versiolle %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "Anna ladattava näytetiedosto"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "Äänitiedoston avaaminen epäonnistui."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "Varoitus: näytemäärityksen selvitys tiedostosta epäonnistui."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "Soitettavan näytteen nimi on annettava"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "Poistettavan näytteen nimi on annettava"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "Nielun syöteindeksi ja nielu on annettava"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "Lähteen ulostuloindeksi ja lähde on annettava"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "Moduulin nimi ja argumentit on annettava."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "Moduulin indeksi on annettava"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr "Ei voi antaa enempää kuin yhden nielun. Totuusarvo on annettava."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr "Ei voi antaa enempää kuin yhden lähteen. Totuusarvo on annettava."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "Kortin nimi/indeksi ja profiilin nimi on annettava"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "Nielun nimi/indeksi ja portin nimi on annettava"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "Lähteen nimi/indeksi ja portin nimi on annettava"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "Nielun nimi/indeksi ja portin nimi on annettava"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "Virheellinen äänenvoimakkuuden määritys"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "Lähteen nimi/indeksi ja äänenvoimakkuus on annettava"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "Nielun syöteindeksi ja äänenvoimakkuus on annettava"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "Virheellinen nielun syöteindeksi"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "Lähteen ulostuloindeksi ja lähde on annettava"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "Virheellinen nielun syöteindeksi"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "Nielun nimi/indeksi ja vaimennuksen totuusarvo on annettava"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "Virheellinen näytemääritys"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "Lähteen nimi/indeksi ja vaimennuksen totuusarvo on annettava"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "Nielun syöteindeksi ja vaimennuksen totuusarvo on annettava"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "Virheellinen nielun syöteindeksin määritys"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "Lähteen nimi/indeksi ja vaimennuksen totuusarvo on annettava"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "Virheellinen nielun syöteindeksin määritys"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "Nielun nimi/indeksi ja vaimennuksen totuusarvo on annettava"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "Mitään kelvollista komentoa ei annettu."
 
@@ -2222,105 +2452,105 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "Komentorivin jäsentäminen epäonnistui.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Palvelin: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Lähde: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Nielu: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Eväste: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "Evästetietojen jäsennys epäonnistui\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "Evästetietojen tallennus epäonnistui\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "Asiakasohjelman asetustiedoston lataaminen epäonnistui.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "Ympäristön asetustietojen lukeminen epäonnistui.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "Verkkonimen saaminen epäonnistui.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "Evästetietojen lataaminen epäonnistui\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Toteutusta ei vielä ole.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr ""
 "PulseAudio-taustaprosessi ei ole käynnissä eikä PulseAudiota suoriteta "
 "istunnon taustaprosessina."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "PulseAudio-taustaprosessin lopettaminen epäonnistui."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "Taustaprosessi ei vastaa."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "Automaattisen käynnistyksen lukkoa ei voida käyttää."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2337,7 +2567,7 @@ msgstr ""
 "asetettuna,  snd_pcm_avail() palautti kuitenkin 0 tai jonkin muun arvon, "
 "joka on < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2353,234 +2583,469 @@ msgstr ""
 "ongelmasta ALSA-kehittäjille. Taustaprosessi herätettiin POLLIN asetettuna,  "
 "snd_pcm_avail() palautti kuitenkin 0 tai jonkin muun arvon, on < min_avail."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "Poissa"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "Korkean äänenlaadun toisto (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "Korkean äänenlaadun tallennus (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
+msgstr "Puhelut, molemmat suunnat (HSP/HFP)"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
 msgstr ""
 
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "PulseAudio-äänipalvelin"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
 msgstr "Ulostulolaitteet"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
 msgstr "Sisääntulolaitteet"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
 msgstr "Ääni koneella @HOSTNAME@"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
 msgstr "Sisääntulo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
 msgstr "Telakan sisääntulo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
 msgstr "Telakan mikrofoni"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "Telakan sisääntulo"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
 msgstr "Linjasisääntulo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
 msgstr "Mikrofoni"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "Telakan mikrofoni"
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "Mikrofoni"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
 msgid "External Microphone"
 msgstr "Ulkoinen mikrofoni"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
 msgstr "Sisäinen mikrofoni"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
 msgstr "Radio"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
 msgstr "Video"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
 msgstr "Automaattinen äänenvoimakkuuden säätö"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
 msgstr "Ei automaattista äänenvoimakkuuden säätöä"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
 msgstr "Vahvistus"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
 msgstr "Ei vahvistusta"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
 msgstr "Vahvistin"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
 msgstr "Ei vahvistinta"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr "Analoginen sisääntulo"
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "Vahvistus"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr "Analoginen mikrofoni"
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "Ei vahvistusta"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
-msgstr "Analoginen linjasisääntulo"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr "Analoginen radio"
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "Analoginen kuulokeliitäntä"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr "Analoginen video"
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "Analoginen sisääntulo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "Telakan mikrofoni"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
 msgstr "Analoginen ulostulo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr "Analoginen kuulokeliitäntä"
-
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
 msgstr "Analoginen ulostulo (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "Linjasisääntulo"
+
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
 msgstr "Analoginen monoulostulo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, c-format
-msgid "%s+%s"
-msgstr "%s+%s"
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "Analoginen stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, c-format
-msgid "%s / %s"
-msgstr "%s / %s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Digitaalinen stereo (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Digitaalinen stereo (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr "Analoginen mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr "Analoginen stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
 msgstr "Analoginen tilaääni 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
 msgstr "Analoginen tilaääni 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
 msgstr "Analoginen tilaääni 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr "Analoginen tilaääni 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr "Analoginen tilaääni 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr "Analoginen tilaääni 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr "Analoginen tilaääni 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
 msgstr "Analoginen tilaääni 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
 msgstr "Analoginen tilaääni 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
 msgstr "Analoginen tilaääni 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr "Analoginen tilaääni 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr "Digitaalinen stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "Digitaalinen tilaääni 4.0 (IEC958)"
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Digitaalinen stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Digitaalinen tilaääni 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Digitaalinen tilaääni 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr "Digitaalinen stereo (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
 #, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Digitaalinen tilaääni 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
-msgstr "Analoginen mono"
+msgstr "Analoginen mono, molemmat suunnat"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
-msgstr "Analoginen stereo"
+msgstr "Analoginen stereo, molemmat suunnat"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
-msgstr "Digitaalinen stereo (IEC958)"
+msgstr "Digitaalinen stereo, molemmat suunnat (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Tyhjä ulostulo"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "Sisääntulo"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<nielun nimi> sink_properties=<nielun asetukset> "
+"master=<suodatettavan nielun nimi> format=<näytemuoto> "
+"rate=<näytteenottotaajuus> channels=<kanavien määrä> "
+"channel_map=<kanavakartta> plugin=<ladspa-liitännäisen nimi> label=<ladspa-"
+"liitännäisen nimiö (label)> control=<pilkulla erotettu luettelo "
+"syötteenhallinta-arvoja>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimitiä ei tueta tällä alustalla."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() epäonnistui"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Lähteen ulostulo #%u\n"
+#~ "\tAjuri: %s\n"
+#~ "\tOmistava moduuli: %s\n"
+#~ "\tAsiakas: %s\n"
+#~ "\tLähde: %u\n"
+#~ "\tNäytemäärittely: %s\n"
+#~ "\tKanavakartta: %s\n"
+#~ "\tPuskurin latenssi: %0.0f μs\n"
+#~ "\tLähteen latenssi: %0.0f μs\n"
+#~ "\tUudelleennäytteistyksen tapa: %s\n"
+#~ "\tOminaisuudet:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [valitsimet] stat\n"
+#~ "%s [valitsimet] list\n"
+#~ "%s [valitsimet] exit\n"
+#~ "%s [valitsimet] upload-sample TIEDOSTONIMI [NIMI]\n"
+#~ "%s [valitsimet] play-sample NIMI [NIELU]\n"
+#~ "%s [valitsimet] remove-sample NIMI\n"
+#~ "%s [valitsimet] move-sink-input NIELUSISÄÄNMENO NIELU\n"
+#~ "%s [valitsimet] move-source-output LÄHDEULOSTULO LÄHDE\n"
+#~ "%s [valitsimet] load-module NIMI [ARGUMENTIT ...]\n"
+#~ "%s [valitsimet] unload-module MODUULI\n"
+#~ "%s [valitsimet] suspend-sink NIELU 1|0\n"
+#~ "%s [valitsimet] suspend-source LÄHDE 1|0\n"
+#~ "%s [valitsimet] set-card-profile KORTTI PROFIILI\n"
+#~ "%s [valitsimet] set-sink-port NIELU PORTTI\n"
+#~ "%s [valitsimet] set-source-port LÄHDE PORTTI\n"
+#~ "%s [valitsimet] set-sink-volume NIELU VOIMAKKUUS\n"
+#~ "%s [valitsimet] set-source-volume LÄHDE VOIMAKKUUS\n"
+#~ "%s [valitsimet] set-sink-input-volume NIELUSISÄÄNMENO VOIMAKKUUS\n"
+#~ "%s [valitsimet] set-sink-mute NIELU 1|0\n"
+#~ "%s [valitsimet] set-source-mute LÄHDE 1|0\n"
+#~ "%s [valitsimet] set-sink-input-mute NIELUSISÄÄNMENO 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Näytä tämä ohje\n"
+#~ "      --version                         Näytä versio\n"
+#~ "\n"
+#~ "  -s, --server=PALVELIN                 Sen palvelimen nimi, johon "
+#~ "yhdistetään\n"
+#~ "  -n, --client-name=NIMI                Kuinka tätä asiakasohjelmaa "
+#~ "kutsutaan palvelimella\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Digitaalinen tilaääni 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Alataajuus"
 
 #~ msgid "Invalid client name '%s'\n"
 #~ msgstr "Virheellinen asiakasohjelman nimi ”%s”\n"
@@ -2810,9 +3275,3 @@ msgstr "Digitaalinen stereo (IEC958)"
 #~ "Tyyppi: %s\n"
 #~ "Moduuli: %s\n"
 #~ "Argumentto: %s\n"
-
-#~ msgid "sink"
-#~ msgstr "nielu"
-
-#~ msgid "source"
-#~ msgstr "lähde"
index 1cdea52..4c298e4 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -1,31 +1,30 @@
 # French translation of pulseaudio.
 # Copyright (C) 2006-2008 Lennart Poettering
 # This file is distributed under the same license as the pulseaudio package.
+#
+#
 # Robert-André Mauchin <zebob.m@pengzone.org>, 2008.
 # Michaël Ughetto <telimektar esraonline com>, 2008.
 # Pablo Martin-Gomez <pablo.martin-gomez@laposte.net>, 2008.
 # Corentin Perard <corentin.perard@gmail.com>, 2009.
-#
+# Thomas Canniot <mrtom@fedoraproject.org>, 2009, 2012.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio trunk\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-04-26 17:22+0200\n"
-"Last-Translator: Corentin Perard <corentin.perard@gmail.com>\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:53+0000\n"
+"Last-Translator: Thomas Canniot <mrtom@fedoraproject.org>\n"
 "Language-Team: French <fedora-trans-fr@redhat.com>\n"
+"Language: fr\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n>1;\n"
+"X-Generator: Lokalize 1.0\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr ""
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -38,11 +37,11 @@ msgstr ""
 "Il s'agit très probablement d'un bogue dans le pilote ALSA « %s ». Veuillez "
 "rapporter ce problème aux développeurs d'ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
@@ -51,7 +50,20 @@ msgstr ""
 "Il s'agit très probablement d'un bogue dans le pilote ALSA « %s ». Veuillez "
 "rapporter ce problème aux développeurs d'ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() a retourné une valeur qui est exceptionnellement large : %lu "
+"octets (%lu ms).\n"
+"Il s'agit très probablement d'un bogue dans le pilote ALSA « %s ». Veuillez "
+"rapporter ce problème aux développeurs d'ALSA."
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -64,143 +76,157 @@ msgstr ""
 "Il s'agit très probablement d'un bogue dans le pilote ALSA « %s ». Veuillez "
 "rapporter ce problème aux développeurs d'ALSA."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
-msgstr ""
+msgstr "Garde toujours au moins une destination même si elle est vide"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
-msgstr ""
+msgstr "Sortie factice"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
-msgstr ""
+msgstr "Destination virtuelle LADSPA"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
-msgstr ""
-
-#: ../src/modules/module-null-sink.c:55
+"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> "
+msgstr ""
+"sink_name=<nom de la destination> sink_properties=<propriétés de la "
+"destination> master=<nom de la destination à filter> format=<format de "
+"l'échantillon> rate=<taux d'échantillonage> channels=<nombre de canaux> "
+"channel_map=<plan des canaux> plugin=<nom de l'extension ladspa> "
+"label=<étiquette de l'extension ladspa> control=<liste des valeurs de "
+"contrôle de l'entrée séparées par des virgules>"
+
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
-msgstr ""
+msgstr "Horloge de la destination vide"
 
-#: ../src/modules/module-null-sink.c:291
-#, fuzzy
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
-msgstr "Sortie %s"
+msgstr "Sortie vide"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "Audio interne"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "Modem"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "Échec lors de la recherche du chargeur lt_dlopen original."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "Échec lors de l'allocation du nouveau chargeur dl."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "Échec lors de l'ajout du chargeur bind-now."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "Signal %s obtenu."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "Fermeture."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "Impossible de trouver l'utilisateur « %s »."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "Impossible de trouver le groupe « %s »."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "Utilisateur « %s ” (UID %lu) et groupe « %s » (GID %lu) trouvé."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr ""
 "Le GID de l'utilisateur « %s » et du groupe « %s » ne sont pas identiques."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "Le dossier personnel de l'utilisateur « %s » n'est pas « %s », ignoré."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Échec lors de la création de « %s » : %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "Échec lors du changement de la liste du groupe : %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "Échec lors du changement de GID : %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "Échec lors du changement d'UID : %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "Les privilèges root ont été correctement abandonnés."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "Mode système étendu non pris en charge sur cette plateforme."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) a échoué : %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "Échec lors de l'analyse de la ligne de commande"
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "Lé démon n'est pas lancé"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "Le démon est lancé avec le PID %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "Impossible de tuer le démon : %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -208,161 +234,182 @@ msgstr ""
 "Le programme n'est pas conçu pour être lancé en tant que root (sauf si --"
 "system est renseigné)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "Les privilèges root sont nécessaires."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start n'est pas pris en charge pour les instances système."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr ""
 "Le démon s'exécute en mode système, mais --disallow-exit n'est pas défini."
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
 "Le démon s'exécute en mode système, mais --disallow-module-loading n'est pas "
 "défini."
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "Le démon s'exécute en mode système, désactivation forcée du mode SHM."
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 "Le démon s'exécute en mode système, désactivation forcée de la fermeture "
 "après délai d'inactivité."
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "Échec lors de l'acquisition de stdio."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "Échec du tube : %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "Échec de fork() : %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "Échec de read() : %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "Échec lors du démarrage du démon."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "Démarrage du démon réussi."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "Échec de read() : %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Pulseaudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Hôte de compilation : %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "CFLAGS de compilation : %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "Exécution sur l'hôte : %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "%u processeurs trouvés."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "La taille de la page est de %lu octets"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Compilé avec la prise en charge Valgrind : oui"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Compilé avec la prise en charge Valgrind : non"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "Exécution en mode valgrind : %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "Exécution sur l'hôte : %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "Construction optimisée : oui"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "Construction optimisée : non"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG défini, tous les messages d'erreur sont désactivés."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr ""
 "FASTPATH défini, seuls les messages d'erreur fastpath ont été désactivés."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "Tous les messages d'erreur sont activés."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "Échec lors de l'obtention de l'ID de la machine"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "L'ID de la machine est %s."
 
-#: ../src/daemon/main.c:773
-#, fuzzy, c-format
+#: ../src/daemon/main.c:945
+#, c-format
 msgid "Session ID is %s."
-msgstr "L'ID de la machine est %s."
+msgstr "L'ID de la session est %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "Utilisation du répertoire d'exécution %s."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "Utilisation du répertoire d'état %s."
 
-#: ../src/daemon/main.c:787
-#, fuzzy, c-format
+#: ../src/daemon/main.c:959
+#, c-format
 msgid "Using modules directory %s."
-msgstr "Utilisation du répertoire d'exécution %s."
+msgstr "Utilisation du répertoire des modules %s."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Exécution en mode système : %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -371,17 +418,23 @@ msgid ""
 "Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an "
 "explanation why system mode is usually a bad idea."
 msgstr ""
+"Vous exécutez PA dans un mode système. Sachez que vous ne devriez pas faire "
+"cela.\n"
+"Si vous choisissez malgré tout de le faire, vous êtes responsable de tout "
+"dysfonctionnement inattendu.\n"
+"Veuillez lire http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode pour "
+"comprendre pourquoi le mode système est généralement une mauvaise idée."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "Échec de pa_pid_file_create()."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr ""
 "De nouvelles horloges à haute résolution sont disponibles ! Bon appétit !"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -389,32 +442,32 @@ msgstr ""
 "Eh mec, ton noyau il pue ! La recommandation d'aujourd'hui du patron est "
 "d'activer les horloges à haute résolution sur ton Linux."
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "Échec de pa_core_new()."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "Échec lors de l'initialisation du démon"
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Démarrage du démon sans aucun module chargé : refus de fonctionner."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "Démarrage du démon effectué."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "Fermeture du démon initiée."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "Démon terminé."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -451,15 +504,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -574,15 +625,15 @@ msgstr ""
 "  -n                                    Ne pas charger les fichiers de "
 "scripts par défaut\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize requiert un paramètre booléen"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail requiert un paramètre booléen"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -590,167 +641,171 @@ msgstr ""
 "--log-level requiert un paramètre de niveau de journal (soit numérique entre "
 "0 et 4, soit de débogage : info, notice, warn , error)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority requiert un paramètre booléen"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime requiert un paramètre booléen"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading requiert un paramètre booléen"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit requiert un paramètre booléen"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file requiert un paramètre booléen"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
-msgstr "Cible du journal invalide : utilisez « syslog », « stderr » ou « auto »."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
+msgstr ""
+"Cible du journal invalide : utilisez « syslog », « stderr » ou « auto »."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time requiert un paramètre booléen"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta requiert un paramètre booléen"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Méthode de rééchantillonnage invalide « %s »."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system requiert un paramètre booléen"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit requiert un paramètre booléen"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm requiert un paramètre booléen"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Nom : %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "Aucune information de module disponible\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Version : %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Description : %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Auteur : %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Utilisation : %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "Chargement unique : %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
-msgstr ""
+msgstr "AVERTISSEMENT D'OBSOLESCENCE : %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Chemin : %s\n"
 
 # dans les lignes suivantes [%s = nom de fichier: %u = ligne dans celui-ci]
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Cible du journal « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Niveau du journal « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Méthode de rééchantillonnage « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] rlimit « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit n'est pas pris en charge sur cette plateforme."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Format d'échantillon « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Taux d'échantillonnage « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Canaux d'échantillonnage « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] Plan de canaux « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Nombre de fragments « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Taille du fragment « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Niveau de priorité (nice) « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Taux d'échantillonnage « %s » invalide."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Échec lors de l'ouverture du fichier de configuration : %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -758,15 +813,14 @@ msgstr ""
 "Le plan de canaux spécifié par défaut a un nombre de canaux différent du "
 "nombre spécifié par défaut."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Lecture à partir du fichier de configuration : %s ###\n"
 
-#: ../src/daemon/caps.c:62
-#, fuzzy
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
-msgstr "Abandon des privilèges root."
+msgstr "Nettoyage des privilèges."
 
 #: ../src/daemon/pulseaudio.desktop.in.h:1
 msgid "PulseAudio Sound System"
@@ -776,6 +830,16 @@ msgstr "Système de son PulseAudio"
 msgid "Start the PulseAudio Sound System"
 msgstr "Démarrer le système de son PulseAudio"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "Système de son PulseAudio"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "Démarrer le système de son PulseAudio"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
@@ -805,8 +869,8 @@ msgid "Rear Right"
 msgstr "Arrière droit"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Émetteur à basse fréquence"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -980,9 +1044,10 @@ msgstr "Arrière gauche haut"
 msgid "Top Rear Right"
 msgstr "Arrière droit haut"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(invalide)"
 
@@ -1010,342 +1075,354 @@ msgstr "Surround 5.1"
 msgid "Surround 7.1"
 msgstr "Surround 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "OK"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "Accès refusé"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Commande inconnue"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "Paramètre invalide"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "L'entité existe"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "Aucune entité de ce type"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "Connexion refusée"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "Erreur du protocole"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "Délai dépassé"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "Aucune clé d'autorisation"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "Erreur interne"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "Connexion terminée"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "L'entité a été tuée"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Serveur invalide"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "Échec lors de l'initialisation du module"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "État incorrect"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Aucune donnée"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "Version du protocole invalide"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "Trop grand"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "Non pris en charge"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Code d'erreur inconnu"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "Aucune extension de ce type"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "Fonctionnalité dépréciée"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "Implantation manquante"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "Le client s'est divisé (Client forked)"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
-msgstr ""
+msgstr "Erreur d'entrée/sortie"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
-msgstr ""
+msgstr "Périphérique ou ressource occupé"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f Gio"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f Mio"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f Kio"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "Échec de XOpenDisplay()"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "Échec de pa_context_connect() : %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "Échec lors de l'analyse des données du cookie"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Échec lors de l'ouverture du fichier de configuration « %s » :%s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "Aucun cookie chargé. Tentative de connexion sans celui-ci."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork() : %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid() : %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "Message reçu pour une extension inconnue « %s »"
 
-#: ../src/utils/pacat.c:108
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:112
+#, c-format
 msgid "Failed to drain stream: %s"
-msgstr "Échec lors du vidage du flux : %s\n"
+msgstr "Échec lors du vidage du flux : %s"
 
-#: ../src/utils/pacat.c:113
-#, fuzzy
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
-msgstr "Flux de lecture vidé.\n"
+msgstr "Flux de lecture vidé."
 
-#: ../src/utils/pacat.c:123
-#, fuzzy
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
-msgstr "Vidage de la connexion au serveur.\n"
+msgstr "Vidage de la connexion au serveur."
 
-#: ../src/utils/pacat.c:136
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:141
+#, c-format
 msgid "pa_stream_drain(): %s"
-msgstr "pa_stream_drain() : %s\n"
+msgstr "pa_stream_drain() : %s"
 
-#: ../src/utils/pacat.c:159
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:164
+#, c-format
 msgid "pa_stream_write() failed: %s"
-msgstr "Échec de pa_stream_write() : %s\n"
+msgstr "Échec de pa_stream_write() : %s"
 
-#: ../src/utils/pacat.c:197
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:205
+#, c-format
 msgid "pa_stream_begin_write() failed: %s"
-msgstr "Échec de pa_stream_write() : %s\n"
+msgstr "Échec de pa_stream_begin_write() : %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
+#, c-format
 msgid "pa_stream_peek() failed: %s"
-msgstr "Échec de pa_stream_peek() : %s\n"
+msgstr "Échec de pa_stream_peek() : %s"
 
-#: ../src/utils/pacat.c:307
-#, fuzzy
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
-msgstr "Création du flux réussie.\n"
+msgstr "Création du flux réussie."
 
-#: ../src/utils/pacat.c:310
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:328
+#, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
-msgstr "Échec de pa_stream_get_buffer_attr() : %s\n"
+msgstr "Échec de pa_stream_get_buffer_attr() : %s"
 
-#: ../src/utils/pacat.c:314
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:332
+#, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
-msgstr "Mesures du tampon : maxlength=%u, tlength=%u, prebuf=%u, minreq=%u\n"
+msgstr "Mesures du tampon : maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:335
+#, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
-msgstr "Mesures du tampon : maxlength=%u, fragsize=%u\n"
+msgstr "Mesures du tampon : maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:339
+#, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr ""
-"Utilisation de la spécification d'échantillon « %s », plan des canaux « %s ».\n"
+"Utilisation de la spécification d'échantillon « %s », plan des canaux « %s »."
 
 # l'espace manquant entre %s et suspended est voulu
-#: ../src/utils/pacat.c:325
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:343
+#, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
-msgstr "Connecté au périphérique %s (%u, %ssuspendu).\n"
+msgstr "Connecté au périphérique %s (%u, %ssuspendu)."
 
-#: ../src/utils/pacat.c:335
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:353
+#, c-format
 msgid "Stream error: %s"
-msgstr "Erreur du flux : %s\n"
+msgstr "Erreur du flux : %s"
 
-#: ../src/utils/pacat.c:345
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:363
+#, c-format
 msgid "Stream device suspended.%s"
-msgstr "Périphérique de flux suspendu %s \n"
+msgstr "Périphérique de flux suspendu.%s"
 
-#: ../src/utils/pacat.c:347
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:365
+#, c-format
 msgid "Stream device resumed.%s"
-msgstr "Périphérique de flux repris %s \n"
+msgstr "Périphérique de flux repris.%s"
 
-#: ../src/utils/pacat.c:355
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:373
+#, c-format
 msgid "Stream underrun.%s"
-msgstr "Flux vide %s \n"
+msgstr "Flux vide.%s"
 
-#: ../src/utils/pacat.c:362
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:380
+#, c-format
 msgid "Stream overrun.%s"
-msgstr "Flux saturé %s \n"
+msgstr "Flux saturé.%s"
 
-#: ../src/utils/pacat.c:369
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:387
+#, c-format
 msgid "Stream started.%s"
-msgstr "Flux démarré %s \n"
+msgstr "Flux démarré.%s"
 
-#: ../src/utils/pacat.c:376
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:394
+#, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
-msgstr "Flux déplacé vers le périphérique %s (%u, %ssuspendu).%s \n"
+msgstr "Flux déplacé vers le périphérique %s (%u, %ssuspendu).%s"
 
 # suspendu ou non suspendu
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "non "
 
-#: ../src/utils/pacat.c:383
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:401
+#, c-format
 msgid "Stream buffer attributes changed.%s"
-msgstr "Des attributs du tampon de flux ont changé. %s \n"
+msgstr "Des attributs du tampon de flux ont changé.%s"
 
-#: ../src/utils/pacat.c:415
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
+#, c-format
 msgid "Connection established.%s"
-msgstr "Connection établie.%s \n"
+msgstr "Connexion établie.%s"
 
-#: ../src/utils/pacat.c:418
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:454
+#, c-format
 msgid "pa_stream_new() failed: %s"
-msgstr "Échec de pa_stream_new() : %s\n"
+msgstr "Échec de pa_stream_new() : %s"
 
-#: ../src/utils/pacat.c:450
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:492
+#, c-format
 msgid "pa_stream_connect_playback() failed: %s"
-msgstr "Échec de pa_stream_connect_playback() : %s\n"
+msgstr "Échec de pa_stream_connect_playback() : %s"
 
-#: ../src/utils/pacat.c:456
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:498
+#, c-format
 msgid "pa_stream_connect_record() failed: %s"
-msgstr "Échec de pa_stream_connect_record() : %s\n"
+msgstr "Échec de pa_stream_connect_record() : %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
+#, c-format
 msgid "Connection failure: %s"
-msgstr "Échec lors de la connexion : %s\n"
+msgstr "Échec lors de la connexion : %s"
 
-#: ../src/utils/pacat.c:503
-#, fuzzy
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
-msgstr "EOF obtenu.\n"
+msgstr "EOF obtenu."
 
-#: ../src/utils/pacat.c:540
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:582
+#, c-format
 msgid "write() failed: %s"
-msgstr "Échec de write() : %s\n"
+msgstr "Échec de write() : %s"
 
-#: ../src/utils/pacat.c:561
-#, fuzzy
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
-msgstr "Signal obtenu, fermeture.\n"
+msgstr "Signal obtenu, fermeture."
 
-#: ../src/utils/pacat.c:575
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:617
+#, c-format
 msgid "Failed to get latency: %s"
-msgstr "Échec lors de l'obtention de la latence : %s\n"
+msgstr "Échec lors de l'obtention de la latence : %s"
 
-#: ../src/utils/pacat.c:580
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:622
+#, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
-msgstr "Durée : %0.3f s ; Latency : %0.0f µs.  \r"
+msgstr "Durée : %0.3f sec. ; Latence : %0.0f µsec."
 
-#: ../src/utils/pacat.c:599
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:643
+#, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
-msgstr "Échec de pa_stream_update_timing_info() : %s\n"
+msgstr "Échec de pa_stream_update_timing_info() : %s"
 
 # downmix = par ex. convertir 5 canaux en 2 canaux
 # upmixer = par ex. convertir 2 canaux en 5 canaux
 # https://bugzilla.redhat.com/show_bug.cgi?id=460798
-#: ../src/utils/pacat.c:609
+#: ../src/utils/pacat.c:653
 #, fuzzy, c-format
 msgid ""
 "%s [options]\n"
@@ -1398,10 +1475,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [options]\n"
@@ -1455,8 +1537,16 @@ msgstr ""
 "octets.\n"
 "      --process-time=OCTETS             Demande le temps de traitement "
 "indiqué par requête en octets.\n"
+"      --property=PROPRIÉTÉ=VALEUR         Attribut la propriété définie à la "
+"valeur définie.\n"
+"      --raw                             Enregistre/lit les données PCM "
+"brutes.\n"
+"      --file-format=FFORMAT             Enregistre/lit les données PCM "
+"formatées.\n"
+"      --list-file-formats               Liste les formats de fichiers "
+"disponibles.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1467,185 +1557,184 @@ msgstr ""
 "Compilé avec libpulse %s\n"
 "Lié avec libpulse %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
+#, c-format
 msgid "Invalid client name '%s'"
-msgstr "Plan des canaux invalide « %s »\n"
+msgstr "Nom du client invalide « %s »"
 
-#: ../src/utils/pacat.c:779
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:834
+#, c-format
 msgid "Invalid stream name '%s'"
-msgstr "Méthode de rééchantillonnage invalide « %s »."
+msgstr "Nom du flux invalide « %s »"
 
-#: ../src/utils/pacat.c:816
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:871
+#, c-format
 msgid "Invalid channel map '%s'"
-msgstr "Plan des canaux invalide « %s »\n"
+msgstr "Plan des canaux invalide « %s »"
 
-#: ../src/utils/pacat.c:845
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
+#, c-format
 msgid "Invalid latency specification '%s'"
-msgstr "Spécification de latence invalide « %s »\n"
+msgstr "Spécification de latence invalide « %s »"
 
-#: ../src/utils/pacat.c:852
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
+#, c-format
 msgid "Invalid process time specification '%s'"
-msgstr "Spécification de temps de traitement invalide « %s »\n"
+msgstr "Spécification de temps de traitement invalide « %s »"
 
-#: ../src/utils/pacat.c:864
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:933
+#, c-format
 msgid "Invalid property '%s'"
-msgstr "Méthode de rééchantillonnage invalide « %s »."
+msgstr "Propriété invalide « %s »"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
-msgstr ""
+msgstr "Format de fichier inconnu %s."
 
-#: ../src/utils/pacat.c:900
-#, fuzzy
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
-msgstr "Spécification d'échantillon invalide\n"
+msgstr "Spécification d'échantillon invalide"
 
-#: ../src/utils/pacat.c:910
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:981
+#, c-format
 msgid "open(): %s"
-msgstr "open() : %s\n"
+msgstr "open() : %s"
 
-#: ../src/utils/pacat.c:915
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:986
+#, c-format
 msgid "dup2(): %s"
-msgstr "dup2() : %s\n"
+msgstr "dup2() : %s"
 
-#: ../src/utils/pacat.c:922
-#, fuzzy
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
-msgstr "Trop de paramètres.\n"
+msgstr "Trop de paramètres."
 
-#: ../src/utils/pacat.c:933
-#, fuzzy
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
-msgstr "Échec lors de l'obtention des informations de l'échantillon : %s\n"
+msgstr ""
+"Échec lors de la génération des informations de l'échantillon du fichier."
 
-#: ../src/utils/pacat.c:953
-#, fuzzy
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
-msgstr "Échec lors de l'ouverture du fichier audio.\n"
+msgstr "Échec lors de l'ouverture du fichier audio."
 
-#: ../src/utils/pacat.c:959
-#, fuzzy
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
-msgstr "Ouverture d'un flux %s avec une spécification d'échantillon « %s ».\n"
+msgstr ""
+"Avertissement : les spécifications de l'échantillon spécifié seront écrasées "
+"par celles du fichier."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
-#, fuzzy
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
-msgstr "Échec lors de l'obtention des informations de l'échantillon : %s\n"
+msgstr ""
+"Échec lors de l'obtention des informations de l'échantillon du fichier."
 
-#: ../src/utils/pacat.c:971
-#, fuzzy
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
-msgstr "Ouverture d'un flux %s avec une spécification d'échantillon « %s ».\n"
+msgstr ""
+"Avertissement : échec lors de l'obtention des informations du plan des "
+"canaux du fichier."
 
-#: ../src/utils/pacat.c:982
-#, fuzzy
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
-msgstr ""
-"Le plan des canaux ne correspond pas à la spécification d'échantillon\n"
+msgstr "Le plan des canaux ne correspond pas à la spécification d'échantillon"
 
-#: ../src/utils/pacat.c:993
-#, fuzzy
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
-msgstr "Ouverture d'un flux %s avec une spécification d'échantillon « %s ».\n"
+msgstr ""
+"Avertissement : Échec lors de l'écriture du plan des canaux dans le fichier."
 
-#: ../src/utils/pacat.c:1008
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:1085
+#, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
-msgstr "Ouverture d'un flux %s avec une spécification d'échantillon « %s ».\n"
+msgstr ""
+"Ouverture d'un flux %s avec une spécification d'échantillon « %s » et un "
+"plan des canaux « %s »."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "enregistrement"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "lecture"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
 #, fuzzy
+msgid "Failed to set media name."
+msgstr "Échec lors de l'analyse de la ligne de commande"
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
-msgstr "Échec de pa_mainloop_new().\n"
+msgstr "Échec de pa_mainloop_new()."
 
-#: ../src/utils/pacat.c:1054
-#, fuzzy
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
-msgstr "Échec de io_new().\n"
+msgstr "Échec de io_new()."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
-#, fuzzy
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
-msgstr "Échec de pa_context_new().\n"
+msgstr "Échec de pa_context_new()."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "Échec de pa_context_connect() : %s"
 
-#: ../src/utils/pacat.c:1075
-#, fuzzy
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
-msgstr "Échec de pa_context_new().\n"
+msgstr "Échec de pa_context_rttime_new()."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
-#, fuzzy
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
-msgstr "Échec de pa_mainloop_run().\n"
+msgstr "Échec de pa_mainloop_run()."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork() : %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp() : %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "Échec lors de la suspension : %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "Échec lors de la reprise : %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr ""
 "AVERTISSEMENT : le serveur de son n'est pas local, suspension annulée.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Échec lors de la connexion : %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "SIGINT reçu, fermeture.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "AVERTISSEMENT : le processus fils a été terminé par le signal %u\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1690,37 +1779,48 @@ msgstr "Échec de pa_context_new().\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "Échec de pa_mainloop_run().\n"
 
-#: ../src/utils/pactl.c:135
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:150
+#, c-format
 msgid "Failed to get statistics: %s"
-msgstr "Échec lors de l'obtention des statistiques : %s\n"
+msgstr "Échec lors de l'obtention des statistiques : %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "En cours d'utilisation : %u blocs contenant au total %s octets.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr ""
 "Alloué pendant l'ensemble de la durée d'exécution : %u blocs contenant au "
 "total %s octets.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "Taille du cache de l'échantillon : %s\n"
 
-#: ../src/utils/pactl.c:156
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:171
+#, c-format
 msgid "Failed to get server information: %s"
-msgstr "Échec lors de l'obtention des informations du serveur : %s\n"
+msgstr "Échec lors de l'obtention des informations du serveur : %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1728,7 +1828,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "Nom d'utilisateur : %s\n"
 "Nom d'hôte : %s\n"
@@ -1740,14 +1840,14 @@ msgstr ""
 "Source par défaut : %s\n"
 "Cookie : %08x\n"
 
-#: ../src/utils/pactl.c:205
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
+#, c-format
 msgid "Failed to get sink information: %s"
-msgstr "Échec lors de l'obtention des informations sur la destination : %s\n"
+msgstr "Échec lors de l'obtention des informations sur la destination : %s"
 
 # demander à Lennart s'il s'agit de monitor of source
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1763,7 +1863,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1785,22 +1885,27 @@ msgstr ""
 "\tPropriétés :\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
+#, c-format
 msgid "\tPorts:\n"
-msgstr "\tProfils :\n"
+msgstr "\tPorts :\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
+#, c-format
 msgid "\tActive Port: %s\n"
-msgstr "\tProfil actif : %s\n"
+msgstr "\tPort actif : %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
 #, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tPorts :\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
+#, c-format
 msgid "Failed to get source information: %s"
-msgstr "Échec lors de l'obtention des informations sur la source : %s\n"
+msgstr "Échec lors de l'obtention des informations sur la source : %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1839,20 +1944,20 @@ msgstr ""
 "\tPropriétés :\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "n/d"
 
-#: ../src/utils/pactl.c:375
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:454
+#, c-format
 msgid "Failed to get module information: %s"
-msgstr "Échec lors de l'obtention des informations du module : %s\n"
+msgstr "Échec lors de l'obtention des informations du module : %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1869,12 +1974,12 @@ msgstr ""
 "\tPropriétés : \n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:496
+#, c-format
 msgid "Failed to get client information: %s"
-msgstr "Échec lors de l'obtention des informations du client : %s\n"
+msgstr "Échec lors de l'obtention des informations du client : %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1889,12 +1994,12 @@ msgstr ""
 "\tPropriétés :\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:539
+#, c-format
 msgid "Failed to get card information: %s"
-msgstr "Impossible d'obtenir des informations sur la carte : %s\n"
+msgstr "Impossible d'obtenir des informations sur la carte : %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1911,25 +2016,24 @@ msgstr ""
 "\tPropriétés :\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tProfils :\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tProfil actif : %s\n"
 
-#: ../src/utils/pactl.c:496
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
+#, c-format
 msgid "Failed to get sink input information: %s"
 msgstr ""
-"Échec lors de l'obtention des informations de l'entrée de la destination : %"
-"s\n"
+"Échec lors de l'obtention des informations de l'entrée de la destination : %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1938,6 +2042,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1965,14 +2070,14 @@ msgstr ""
 "\tPropriétés :\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
+#, c-format
 msgid "Failed to get source output information: %s"
 msgstr ""
-"Échec lors de l'obtention des informations de la sortie de la source : %s\n"
+"Échec lors de l'obtention des informations de la sortie de la source : %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1981,34 +2086,43 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Sortie de la source #%u\n"
+"Entrée de la destination #%u\n"
 "\tPilote : %s\n"
 "\tModule propriétaire : %s\n"
 "\tClient : %s\n"
-"\tSource : %u\n"
+"\tDestination : %u\n"
 "\tSpécification de l'échantillon : %s\n"
 "\tPlan des canaux : %s\n"
+"\tMuet : %s\n"
+"\tVolume : %s\n"
+"\t         %s\n"
+"\t         balance %0.2f\n"
 "\tLatence du tampon : %0.0f µs\n"
-"\tLatence de la source : %0.0f µs\n"
+"\tLatence de la destination : %0.0f µs\n"
 "\tMéthode de rééchantillonnage : %s\n"
 "\tPropriétés :\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:734
+#, c-format
 msgid "Failed to get sample information: %s"
-msgstr "Échec lors de l'obtention des informations de l'échantillon : %s\n"
+msgstr "Échec lors de l'obtention des informations de l'échantillon : %s"
 
 # Lazy ?
 # load-sample-lazy = Create a new entry in the sample cache, but don't load
 # the sample immediately. The sample is loaded only when it is first used
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -2039,50 +2153,164 @@ msgstr ""
 "\tPropriétés :\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
+#, c-format
 msgid "Failure: %s"
-msgstr "Échec : %s\n"
+msgstr "Échec : %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
 #, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Échec lors de l'obtention des informations sur la source : %s"
+
+#: ../src/utils/pactl.c:954
+#, c-format
 msgid "Failed to upload sample: %s"
-msgstr "Échec lors de l'envoi de l'échantillon : %s\n"
+msgstr "Échec lors de l'envoi de l'échantillon : %s"
 
-#: ../src/utils/pactl.c:704
-#, fuzzy
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
-msgstr "Fin prématurée du fichier\n"
+msgstr "Fin prématurée du fichier"
+
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr "destination"
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr "source"
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+#, fuzzy
+msgid "source-output"
+msgstr "source"
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
 #, fuzzy
+msgid "server"
+msgstr "Serveur invalide"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
-msgstr "SIGINT reçu, fermeture.\n"
+msgstr "SIGINT reçu, fermeture."
+
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "Spécification de volume invalide"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
 
-#: ../src/utils/pactl.c:869
+#: ../src/utils/pactl.c:1339
 #, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2092,29 +2320,15 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample NOMDEFICHIER [NOM]\n"
-"%s [options] play-sample NOM [DEST]\n"
-"%s [options] remove-sample NOM\n"
-"%s [options] move-sink-input ID DEST\n"
-"%s [options] move-source-output ID SOURCE\n"
-"%s [options] load-module NOM [PARAMS ...]\n"
-"%s [options] unload-module ID\n"
-"%s [options] suspend-sink [DEST] 1|0\n"
-"%s [options] suspend-source [SOURCE] 1|0\n"
-"%s·[options]·set-card-profile·[CARTE]·[PROFIL]·\n"
+"%s [options] ... \n"
 "\n"
 "  -h, --help                            Affiche cette aide\n"
 "      --version                         Affiche la version\n"
-"\n"
 "  -s, --server=SERVEUR                  Le nom du serveur auquel se "
 "connecter\n"
-"  -n, --client-name=NOM                 Définit le nom de ce client sur le "
-"serveur\n"
+"\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2125,136 +2339,146 @@ msgstr ""
 "Compilé avec libpulse %s\n"
 "Lié avec libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
-#, fuzzy
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
-msgstr "Veuillez indiquer un fichier d'échantillon à charger\n"
+msgstr "Veuillez indiquer un fichier d'échantillon à charger"
 
-#: ../src/utils/pactl.c:992
-#, fuzzy
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
-msgstr "Échec lors de l'ouverture du fichier audio.\n"
+msgstr "Échec lors de l'ouverture du fichier audio."
 
-#: ../src/utils/pactl.c:1004
-#, fuzzy
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
-msgstr "Ouverture d'un flux %s avec une spécification d'échantillon « %s ».\n"
+msgstr ""
+"Avertissement : Échec lors de l'obtention des spécifications de "
+"l'échantillon du fichier."
 
-#: ../src/utils/pactl.c:1014
-#, fuzzy
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
-msgstr "Vous devez indiquer un nom d'échantillon à lire\n"
+msgstr "Vous devez indiquer un nom d'échantillon à lire"
 
-#: ../src/utils/pactl.c:1026
-#, fuzzy
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
-msgstr "Vous devez indiquer un nom d'échantillon à supprimer\n"
+msgstr "Vous devez indiquer un nom d'échantillon à supprimer"
 
-#: ../src/utils/pactl.c:1035
-#, fuzzy
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr ""
-"Vous devez indiquer un index de sortie de destination et une destination\n"
+"Vous devez indiquer un index d'entrée de destination et une destination"
 
-#: ../src/utils/pactl.c:1045
-#, fuzzy
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
-msgstr "Vous devez indiquer un index de sortie de source et une source\n"
+msgstr "Vous devez indiquer un index de sortie de source et une source"
 
-#: ../src/utils/pactl.c:1060
-#, fuzzy
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
-msgstr "Vous devez indiquer un nom de module et des paramètres.\n"
+msgstr "Vous devez indiquer un nom de module et des paramètres."
 
-#: ../src/utils/pactl.c:1080
-#, fuzzy
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
-msgstr "Vous devez indiquer un index de module\n"
+msgstr "Vous devez indiquer un index de module"
 
-#: ../src/utils/pactl.c:1090
-#, fuzzy
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "Vous ne pouvez pas indiquer plus d'une destination. Vous devez indiquer une "
-"valeur booléenne.\n"
+"valeur booléenne."
 
-#: ../src/utils/pactl.c:1103
-#, fuzzy
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr ""
 "Vous ne pouvez pas indiquer plus d'une source. Vous devez indiquer une "
-"valeur booléenne.\n"
+"valeur booléenne."
 
-#: ../src/utils/pactl.c:1115
-#, fuzzy
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
-msgstr "Vous devez indiquer un nom/un index de carte et un nom de profil\n"
+msgstr "Vous devez indiquer un nom/un index de carte et un nom de profil"
 
-#: ../src/utils/pactl.c:1126
-#, fuzzy
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
-msgstr "Vous devez indiquer un nom/un index de carte et un nom de profil\n"
+msgstr "Vous devez indiquer un nom/un index de destination et un nom de port"
 
-#: ../src/utils/pactl.c:1137
-#, fuzzy
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
-msgstr "Vous devez indiquer un nom/un index de carte et un nom de profil\n"
+msgstr "Vous devez indiquer un nom/un index de source et un nom de port"
 
-#: ../src/utils/pactl.c:1149
-#, fuzzy
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
-msgstr "Vous devez indiquer un nom/un index de carte et un nom de profil\n"
+msgstr "Vous devez indiquer un nom/un index de destination et un volume"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-#, fuzzy
-msgid "Invalid volume specification"
-msgstr "Spécification d'échantillon invalide\n"
-
-#: ../src/utils/pactl.c:1166
-#, fuzzy
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
-msgstr "Vous devez indiquer un nom/un index de carte et un nom de profil\n"
+msgstr "Vous devez indiquer un nom/un index de source et un volume"
 
-#: ../src/utils/pactl.c:1183
-#, fuzzy
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
-msgstr ""
-"Vous devez indiquer un index de sortie de destination et une destination\n"
+msgstr "Vous devez indiquer un index d'entrée de destination et un volume"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
-msgstr ""
+msgstr "Index invalide d'entrée de la destination"
+
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "Vous devez indiquer un index de sortie de source et une source"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1665
 #, fuzzy
+msgid "Invalid source output index"
+msgstr "Index invalide d'entrée de la destination"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
-msgstr "Vous devez indiquer un nom/un index de carte et un nom de profil\n"
+msgstr "Vous devez indiquer un nom/un index de destination et un booléen muet"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
 #, fuzzy
+msgid "Invalid mute specification"
+msgstr "Spécification d'échantillon invalide"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
-msgstr "Vous devez indiquer un nom/un index de carte et un nom de profil\n"
+msgstr "Vous devez indiquer un nom/un index de source et un booléen muet"
 
-#: ../src/utils/pactl.c:1238
-#, fuzzy
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr ""
-"Vous devez indiquer un index de sortie de destination et une destination\n"
+"Vous devez indiquer un index d'entrée de destination et un booléen muet"
 
-#: ../src/utils/pactl.c:1243
-#, fuzzy
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
-msgstr "Spécification d'échantillon invalide\n"
+msgstr "Spécification d'index d'entrée de la destination invalide"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
 #, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "Vous devez indiquer un nom/un index de source et un booléen muet"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "Spécification d'index d'entrée de la destination invalide"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "Vous devez indiquer un nom/un index de destination et un booléen muet"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
-msgstr "Aucune commande valide indiquée.\n"
+msgstr "Aucune commande valide indiquée."
 
 #: ../src/utils/pax11publish.c:61
 #, c-format
@@ -2282,105 +2506,107 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "Échec lors de l'analyse de la ligne de commande.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Serveur : %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Source : %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Destination : %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Cookie : %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "Échec lors de l'analyse des données du cookie\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "Échec lors de l'enregistrement des données du cookie\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "Échec lors du chargement du fichier de configuration du client.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr ""
 "Échec lors de la lecture des données de configuration de l'environnement.\n"
 
 # Fully Qualified Domain Name
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "Échec lors de l'obtention du FQDN (« nom de domaine complet »).\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "Échec lors du chargement des données du cookie\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Pas encore implémenté.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr ""
+"Aucun démon PulseAudio en cours d'exécution, ou ne s'exécutant pas dans une "
+"session de type démon."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0) : %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect() : %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "Impossible de tuer le démon PulseAudio."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "Le démon ne répond pas."
 
-#: ../src/utils/pacmd.c:161
-#, fuzzy, c-format
+#: ../src/utils/pacmd.c:184
+#, c-format
 msgid "poll(): %s"
-msgstr "fork() : %s"
+msgstr "poll() : %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read() : %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write() : %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "Impossible d'accèder au verrou autonome."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2390,14 +2616,14 @@ msgid ""
 "We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() "
 "returned 0 or another value < min_avail."
 msgstr ""
-"ALSA nous a réveillé pour lire de nouvelles données à partir du "
+"ALSA nous a réveillé pour écrire de nouvelles données à partir du "
 "périphérique, mais il n'y avait en fait rien à écrire !\n"
 "Il s'agit très probablement d'un bogue dans le pilote ALSA « %s ». Veuillez "
-"rapporter ce problème aux développeurs d'ALSA.Nous avons été réveillés avec "
-"le jeu POLLOUT -- cependant un snd_pcm_avail() ultérieur a retourné 0 ou une "
-"autre valeur < min_avail."
+"rapporter ce problème aux développeurs d'ALSA.\n"
+"Nous avons été réveillés avec POLLOUT actif, cependant un snd_pcm_avail() "
+"ultérieur a retourné 0 ou une autre valeur < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2410,263 +2636,477 @@ msgstr ""
 "ALSA nous a réveillé pour lire de nouvelles données à partir du "
 "périphérique, mais il n'y avait en fait rien à lire !\n"
 "Il s'agit très probablement d'un bogue dans le pilote ALSA « %s ». Veuillez "
-"rapporter ce problème aux développeurs d'ALSA.Nous avons été réveillés avec "
-"le jeu POLLIN -- cependant un snd_pcm_avail() ultérieur a retourné 0 ou une "
-"autre valeur < min_avail."
+"rapporter ce problème aux développeurs d'ALSA.\n"
+"Nous avons été réveillés avec POLLIN actif, cependant un snd_pcm_avail() "
+"ultérieur a retourné 0 ou une autre valeur < min_avail."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "Éteint"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "Lecture haute fidélité (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
-#, fuzzy
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
-msgstr "Lecture haute fidélité (A2DP)"
+msgstr "Capture haute fidélité (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Telephonie en duplex (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "Serveur de son PulseAudio"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
-msgstr ""
+msgstr "Périphériques de sortie"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
-#, fuzzy
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
-msgstr "Entrée %s"
+msgstr "Périphériques d'entrée"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
-msgstr ""
+msgstr "Audio sur @HOSTNAME@"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
-msgstr "Entrée %s"
+msgstr "Entrée"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
-msgstr ""
+msgstr "Entrée de la station d'accueil"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
-msgstr ""
+msgstr "Microphone de la station d'accueil"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "Entrée de la station d'accueil"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "Entrée-ligne"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
-msgstr ""
+msgstr "Microphone"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
-msgid "External Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "Microphone de la station d'accueil"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
 #, fuzzy
+msgid "Rear Microphone"
+msgstr "Microphone"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "Microphone externe"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
-msgstr "Audio interne"
+msgstr "Microphone interne"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
-msgstr ""
+msgstr "Radio"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
-msgstr ""
+msgstr "Vidéo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
-msgstr ""
+msgstr "Contrôle automatique du gain"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
-msgstr ""
+msgstr "Pas de contrôle automatique du gain"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
-msgstr ""
+msgstr "Boost"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
-msgstr ""
+msgstr "Pas de boost"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
-msgstr ""
+msgstr "Amplificateur"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
-msgstr ""
+msgstr "Pas d'amplificateur"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
+#: ../src/modules/alsa/alsa-mixer.c:2237
 #, fuzzy
-msgid "Analog Input"
-msgstr "Mono analogique"
+msgid "Bass Boost"
+msgstr "Boost"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
+#: ../src/modules/alsa/alsa-mixer.c:2238
 #, fuzzy
-msgid "Analog Microphone"
-msgstr "Mono analogique"
+msgid "No Bass Boost"
+msgstr "Pas de boost"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-#, fuzzy
-msgid "Analog Line-In"
-msgstr "Mono analogique"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-#, fuzzy
-msgid "Analog Radio"
-msgstr "Mono analogique"
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "Casques analogiques"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-#, fuzzy
-msgid "Analog Video"
-msgstr "Stéréo analogique"
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "Entrée analogique"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "Microphone de la station d'accueil"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
-msgstr "Sortie %s"
+msgstr "Sortie analogique"
+
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "Sortie analogique (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
+#: ../src/modules/alsa/alsa-mixer.c:2313
 #, fuzzy
-msgid "Analog Headphones"
-msgstr "Mono analogique"
+msgid "Line Out"
+msgstr "Entrée-ligne"
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2314
+msgid "Analog Mono Output"
+msgstr "Sortie mono analogique"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2315
 #, fuzzy
-msgid "Analog Mono Output"
-msgstr "Mono analogique"
+msgid "Speakers"
+msgstr "Stéréo analogique"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, c-format
-msgid "%s+%s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, c-format
-msgid "%s / %s"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Stéréo numérique (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Stéréo numérique (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr "Mono analogique"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr "Stéréo analogique"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
-msgstr "Surround analogique 4.1"
+msgstr "Surround analogique 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
-msgstr "Surround analogique 4.0"
+msgstr "Surround analogique 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
-msgstr "Surround analogique 4.1"
+msgstr "Surround analogique 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr "Surround analogique 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr "Surround analogique 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr "Surround analogique 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr "Surround analogique 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
-msgstr "Surround analogique 4.0"
+msgstr "Surround analogique 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
-msgstr "Surround analogique 4.1"
+msgstr "Surround analogique 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
-msgstr "Surround analogique 4.0"
+msgstr "Surround analogique 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr "Surround analogique 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr "Stéréo numérique (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
+#: ../src/modules/alsa/alsa-mixer.c:3770
 #, fuzzy
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "Surround numérique 4.0 (IEC958/AC3)"
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Stéréo numérique (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Surround numérique 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Surround numérique 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr "Stéréo numérique (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
 #, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Surround numérique 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
-msgstr "Mono analogique"
+msgstr "Duplex Mono analogique"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
-msgstr "Stéréo analogique"
+msgstr "Duplex stéréo analogique"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
-msgstr "Stéréo numérique (IEC958)"
+msgstr "Duplex stéréo numérique (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Sortie vide"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "Entrée"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
 
+#: ../src/modules/module-equalizer-sink.c:76
 #, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<nom de la destination> sink_properties=<propriétés de la "
+"destination> master=<nom de la destination à filter> format=<format de "
+"l'échantillon> rate=<taux d'échantillonage> channels=<nombre de canaux> "
+"channel_map=<plan des canaux> plugin=<nom de l'extension ladspa> "
+"label=<étiquette de l'extension ladspa> control=<liste des valeurs de "
+"contrôle de l'entrée séparées par des virgules>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit n'est pas pris en charge sur cette plateforme."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "Échec de XOpenDisplay()"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Sortie de la source #%u\n"
+#~ "\tPilote : %s\n"
+#~ "\tModule propriétaire : %s\n"
+#~ "\tClient : %s\n"
+#~ "\tSource : %u\n"
+#~ "\tSpécification de l'échantillon : %s\n"
+#~ "\tPlan des canaux : %s\n"
+#~ "\tLatence du tampon : %0.0f µs\n"
+#~ "\tLatence de la source : %0.0f µs\n"
+#~ "\tMéthode de rééchantillonnage : %s\n"
+#~ "\tPropriétés :\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample NOMDEFICHIER [NOM]\n"
+#~ "%s [options] play-sample NOM [DEST]\n"
+#~ "%s [options] remove-sample NOM\n"
+#~ "%s [options] move-sink-input ID DEST\n"
+#~ "%s [options] move-source-output ID SOURCE\n"
+#~ "%s [options] load-module NOM [PARAMS ...]\n"
+#~ "%s [options] unload-module ID\n"
+#~ "%s [options] suspend-sink [DEST] 1|0\n"
+#~ "%s [options] suspend-source [SOURCE] 1|0\n"
+#~ "%s·[options]·set-card-profile·[CARTE]·[PROFIL]·\n"
+#~ "%s [options] set-sink-port DEST PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume DEST VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume ENTREEDEST VOLUME\n"
+#~ "%s [options] set-sink-mute DEST 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute ENTREEDEST 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Affiche cette aide\n"
+#~ "      --version                         Affiche la version\n"
+#~ "\n"
+#~ "  -s, --server=SERVEUR                  Le nom du serveur auquel se "
+#~ "connecter\n"
+#~ "  -n, --client-name=NOM                 Définit le nom de ce client sur "
+#~ "le serveur\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Surround numérique 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Émetteur à basse fréquence"
+
 #~ msgid "Invalid client name '%s'\n"
 #~ msgstr "Plan des canaux invalide « %s »\n"
 
-#, fuzzy
 #~ msgid "Failed to determine sample specification from file.\n"
 #~ msgstr "Échec lors de l'obtention des informations de l'échantillon : %s\n"
 
@@ -2713,8 +3153,8 @@ msgstr "Stéréo numérique (IEC958)"
 #~ "High-priority scheduling (negative Unix nice level) for the PulseAudio "
 #~ "daemon"
 #~ msgstr ""
-#~ "Ordonnancement haute priorité (niveau Unix « nice » négatif) pour le démon "
-#~ "PulseAudio"
+#~ "Ordonnancement haute priorité (niveau Unix « nice » négatif) pour le "
+#~ "démon PulseAudio"
 
 #~ msgid "Real-time scheduling for the PulseAudio daemon"
 #~ msgstr "Ordonnancement en temps réel pour le démon PulseAudio"
@@ -2734,7 +3174,6 @@ msgstr "Stéréo numérique (IEC958)"
 #~ msgid "read() failed: %s\n"
 #~ msgstr "Échec de read() : %s\n"
 
-#, fuzzy
 #~ msgid "pa_context_connect() failed: %s\n"
 #~ msgstr "Échec de pa_context_connect() : %s"
 
@@ -2884,7 +3323,6 @@ msgstr "Stéréo numérique (IEC958)"
 #~ msgid "Using sample spec '%s'\n"
 #~ msgstr "Utilisation de la spécification de l'échantillon « %s »\n"
 
-#, fuzzy
 #~ msgid ""
 #~ "Called SUID root and real-time and/or high-priority scheduling was "
 #~ "requested in the configuration. However, we lack the necessary "
@@ -2896,7 +3334,6 @@ msgstr "Stéréo numérique (IEC958)"
 #~ "permissions nécessaires :\n"
 #~ "nous ne somme pas dans le groupe "
 
-#, fuzzy
 #~ msgid "--log-time boolean argument"
 #~ msgstr "--disallow-exit requiert un paramètre booléen"
 
@@ -2927,12 +3364,6 @@ msgstr "Stéréo numérique (IEC958)"
 #~ "Module : %s\n"
 #~ "Paramètre : %s\n"
 
-#~ msgid "sink"
-#~ msgstr "destination"
-
-#~ msgid "source"
-#~ msgstr "source"
-
 #~ msgid ""
 #~ "' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
 #~ "For enabling real-time scheduling please acquire the appropriate "
index e174451..65374c7 100644 (file)
--- a/po/gu.po
+++ b/po/gu.po
@@ -1,28 +1,24 @@
-# translation of PulseAudio-up.po to Gujarati
+# translation of PulseAudio.po to Gujarati
 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the PACKAGE package.
+# Sweta Kothari <swkothar@redhat.com>, 2009, 2012.
 #
-# Sweta Kothari <swkothar@redhat.com>, 2009.
 msgid ""
 msgstr ""
-"Project-Id-Version: PulseAudio-up\n"
+"Project-Id-Version: PulseAudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-09-11 13:02+0530\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:53+0000\n"
 "Last-Translator: Sweta Kothari <swkothar@redhat.com>\n"
 "Language-Team: Gujarati\n"
+"Language: \n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: KBabel 1.11.4\n"
 "Plural-Forms: nplurals=2; plural=(n!=1);\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -34,11 +30,11 @@ msgstr ""
 "ALSA ડ્રાઇવર '%s' માં મોટેભાગે આ ભૂલ જેવુ છે. ALSA ડેવલ્પરોમાં આ સમસ્યાને મહેરબાની કરીને "
 "અહેવાલ કરો."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
@@ -47,7 +43,19 @@ msgstr ""
 "ALSA ડ્રાઇવર '%s' માં મોટેભાગે આ ભૂલ જેવુ છે. ALSA ડેવલ્પરોમાં આ સમસ્યાને મહેરબાની કરીને "
 "અહેવાલ કરો."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() કિંમતને પાછુ મળેલ છે કે જે અપવાદ રીતે વિશાળ છે: %lu bytes (%lu ms).\n"
+"ALSA ડ્રાઇવર '%s' માં મોટેભાગે આ ભૂલ જેવુ છે. ALSA ડેવલ્પરોમાં આ સમસ્યાને મહેરબાની કરીને "
+"અહેવાલ કરો."
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -60,303 +68,333 @@ msgstr ""
 "ALSA ડ્રાઇવર '%s' માં મોટેભાગે આ ભૂલ જેવુ છે. ALSA ડેવલ્પરોમાં આ સમસ્યાને મહેરબાની કરીને "
 "અહેવાલ કરો."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "હંમેશા ઓછામાં ઓછુ એક સિંક લોડ થયેલ રાખો જો તે શૂન્ય હોય તો પણ"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "ડમી આઉટપુટ"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "વર્ચ્યુઅલ LADSPA સિંક"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<name for the sink> sink_properties=<properties for the sink> "
 "master=<name of sink to filter> format=<sample format> rate=<sample rate> "
 "channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
+"plugin name> label=<ladspa plugin label> control=<comma separated list of "
 "input control values>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "ક્લોક થયેલ NULL સિંક"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "શૂન્ય આઉટપુટ"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "આંતરિક ઓડિયો"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "મોડેમ"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "મૂળ lt_dlopen લોડરને શોધવામાં નિષ્ફળ."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "નવા dl લોડરને ફાળવવાનું નિષ્ફળ."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "bind-now-loader ને ઉમેરવાનું નિષ્ફળ."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "સંકેત %s મળ્યુ."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "બહાર નીકળી રહ્યા છે."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "વપરાશકર્તા '%s' ને શોધવામાં નિષ્ફળ."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "જૂથ '%s' ને શોધવામાં નિષ્ફળ."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "વપરાશકર્તા '%s' (UID %lu) અને જૂથ '%s' (GID %lu) શોધાયુ."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "વપરાશકર્તા '%s' અને જૂથ '%s' ની GID બંધબેસતુ નથી."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "વપરાશકર્તાઓ '%s' ની ઘર ડિરેક્ટરી '%s' નથી, અવગણી રહ્યા છે."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "'%s' ને બનાવવામાં નિષ્ફળ: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "જૂથ યાદીને બદલવામાં નિષ્ફળ: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "GID ને બદલવામાં નિષ્ફળ: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "UID ને બદલવામાં નિષ્ફળ: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "સફળતાપૂર્વક છોડી દીધેલ રુટ અધિકારો."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "આ પ્લેટફોર્મ પર બિનઆધારભૂત સિસ્ટમ વિશાળ સ્થિતિ."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) નિષ્ફળ: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "આદેશ વાક્યને પદચ્છેદન કરવામાં નિષ્ફળ."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "ડિમન ચાલી રહ્યુ નથી"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "PID %u તરીકે ડિમન ચાલી રહ્યુ છે"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "ડિમનને મારવાનું નિષ્ફળ: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
 msgstr ""
 "આ પ્રક્રિયાને રુટ તરીકે ચલાવવા માટે વિચાર થયેલ નથી (નહિં તો --system એ સ્પષ્ટ થયેલ છે)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "રુટ અધિકારો જરૂરી છે."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start એ સિસ્ટમ ઉદાહરણો માટે આધારભૂત નથી."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "સિસ્ટમ સ્થિતિમાં ચાલી રહ્યુ છે, પરંતુ --disallow-exit સુયોજિત નથી!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr "સિસ્ટમ સ્થિતિમાં ચાલી રહ્યુ છે, પરંતુ --disallow-module-loading એ સુયોજિત નથી!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "સિસ્ટમ સ્થિતિમાં ચાલી રહ્યુ છે, SHM સ્થિતિને દબાણપૂર્વક નિષ્ક્રિય કરી રહ્યા છે!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 "સિસ્ટમ સ્થિતિમાં ચાલી રહ્યુ છે, બહાર નીકળવનાં નિષ્કાર્ય સમયને દબાણપૂર્વક નિષ્ક્રિય કરી "
 "રહ્યા છે!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "stdio ને મેળવવામાં નિષ્ફળ."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "પાઇપ નિષ્ફળ: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() નિષ્ફળ: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() નિષ્ફળ: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "ડિમન શરૂઆત નિષ્ફળ."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "ડિમન શરૂઆત કરવુ સફળ છે."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() નિષ્ફળ: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "આ PulseAudio %s છે"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "કમ્પાઇલેશન યજમાન: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "કમ્પાઇલેશન CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "યજમાન પર ચાલી રહ્યુ છે: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "%u CPUs શોધાયુ."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "પાનાંનુ માપ %lu બાઇટો છે"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Valgrind આધાર સાથે કમ્પાઇલ થયેલ છે: હા"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Valgrind આધાર સાથે કમ્પાઇલ થયેલ છે: ના"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "valgrind સ્થિતિમાં ચાલી રહ્યુ છે: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "યજમાન પર ચાલી રહ્યુ છે: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "શ્રેષ્ટ થયેલ બિલ્ડ: હા"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "શ્રેષ્ટ થયેલ બિલ્ડ: ના"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG વ્યાખ્યાયિત થયેલ છે, બધા હકો નિષ્ક્રિય થયેલ છે."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH વ્યાખ્યાયિત થયેલ છે, ફક્ત ઝડપી પાથનાં હકો નિષ્ક્રિય થયેલ છે."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "બધા હકો સક્રિય થયેલ છે."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "મશીન ID ને મેળવવામાં નિષ્ફળ"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "મશીન ID %s છે."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "સત્ર ID %s છે."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "રનટાઇમ ડિરેક્ટરી %s ને વાપરી રહ્યા છે."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "સ્થિતિ ડિરેક્ટરી %s ને વાપરી રહ્યા છે."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "ઇોડ્યુલોમ ડિરેક્ટરી %s ને વાપરી રહ્યા છે."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "સિસ્ટમ સ્થિતિમાં ચાલી રહ્યુ છે: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -371,15 +409,15 @@ msgstr ""
 "શા માટે સિસ્ટમ સ્થિતિ સામાન્ય રીતે ખરાબ વિચાર છે તે માટે વિગતવાર જાણકારી માટે મહેરબાની "
 "કરીને http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode આને વાંચો."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() નિષ્ફળ."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "તાજુ high-resolution ટાઇમરો ઉપલ્બધ છે! બોન એપેટાઇટ!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -387,32 +425,32 @@ msgstr ""
 "મિત્ર, તમારુ કર્નલમાં ગડબડ છે! રસોઇયાનું આજે ભલામણ એ સક્રિય થયેલ high-resolution "
 "ટાઇમરો સાથે Linux નું છે!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() નિષ્ફળ."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "ડિમનને શરૂ કરવામાં નિષ્ફળ."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "કોઇપણ લોડ થયેલ મોડ્યુલો વગર ડિમનને શરૂ કરો, કામ કરવા માટે ફરી શરૂ કરી રહ્યા છે."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "ડિમન પારંભ કરવાનું સમાપ્ત છે."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "ડિમનને બંધ કરવાનું પ્રારંભ થયેલ છે."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "ડિમનનો અંત આવેલ છે."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -449,15 +487,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -553,15 +589,15 @@ msgstr ""
 "\n"
 "  -n                                    મૂળભૂત સ્ક્રિપ્ટ ફાઇલને લોડ કરો નહિં\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize એ બુલિયન દલીલની ઇચ્છા રાખે છે"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail એ બુલિયન દલીલની ઇચ્છા રાખે છે"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -569,178 +605,181 @@ msgstr ""
 "--log-level એ લોગ સ્તર દલીલની ઇચ્છા રાખે છે (ક્યાંતો સીમા 0..4 માં પૂર્ણસંખ્યા છે અથવા "
 "ડિબગ, જાણકારી, સૂચના, ચેતવણી, ભૂલ નું એક)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority એ બુલિયન દલીલની ઇચ્છા રાખે છે"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime એ બુલિયન દલીલની ઇચ્છા રાખે છે"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading એ બુલિયન દલીલની ઇચ્છા રાખે છે"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit એ બુલિયન દલીલની ઇચ્છા રાખે છે"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file એ બુલિયન દલીલની ઇચ્છા રાખે છે"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr "અયોગ્ય લોગ લક્ષ્ય: ક્યાંતો 'syslog', 'stderr' અથવા 'auto' ને વાપરો."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time એ બુલિયન દલીલની ઇચ્છા રાખે છે"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta એ બુલિયન દલીલની ઇચ્છા રાખે છે"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "અયોગ્ય resample પદ્દતિ '%s'."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system એ બુલિયન દલીલની ઇચ્છા રાખે છે"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit એ બુલિયન દલીલની ઇચ્છા રાખે છે"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm એ બુલિયન દલીલની ઇચ્છા રાખે છે"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "નામ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "મોડ્યુલ જાણકારી ઉપલ્બધ નથી\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "આવૃત્તિ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "વર્ણન: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "લેખક: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "વપરાશ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "એકવાર લોડ કરો: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "DEPRECATION WARNING: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "પાથ: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] અયોગ્ય લોગ લક્ષ્ય '%s'."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] અયોગ્ય લોગ સ્તર '%s'."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] અયોગ્ય resample પદ્દતિ '%s'."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] અયોગ્ય rlimit '%s'."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit એ આ પ્લેટફોર્મ પર આધારભૂત નથી."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] અયોગ્ય નમૂના બંધારણ '%s'."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] અયોગ્ય નમૂના દર '%s'."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] અયોગ્ય નમૂના ચેનલો '%s'."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] અયોગ્ય ચેનલ મેપ '%s'."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] અયોગ્ય ફ્રેગમેન્ટોનાં નંબર '%s'."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] અયોગ્ય ફ્રેગમેન્ટ માપ '%s'."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] અયોગ્ય સારુ સ્તર '%s'."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] અયોગ્ય નમૂના દર '%s'."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "રૂપરેખાંકન ફાઇલને ખોલવાનું નિષ્ફળ: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 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:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### રૂપરેખાંકન ફાઇલમાંથી વાંચો: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "અધિકારોને છોડી રહ્યા છે."
 
@@ -752,6 +791,16 @@ msgstr "PulseAudio સાઉન્ડ સિસ્ટમ"
 msgid "Start the PulseAudio Sound System"
 msgstr "PulseAudio સાઉન્ડ સિસ્ટમને શરૂ કરો"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio સાઉન્ડ સિસ્ટમ"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "PulseAudio સાઉન્ડ સિસ્ટમને શરૂ કરો"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "મોનો"
@@ -781,8 +830,8 @@ msgid "Rear Right"
 msgstr "રિઅર જમણે"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Low Frequency Emmiter"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -956,9 +1005,10 @@ msgstr "ઉપર રિઅર ડાબે"
 msgid "Top Rear Right"
 msgstr "ઉપર રિઅર જમણે"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(અયોગ્ય)"
 
@@ -986,332 +1036,349 @@ msgstr "સરાઉન્ડ 5.1"
 msgid "Surround 7.1"
 msgstr "સરાઉન્ડ 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "બરાબર"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "પ્રવેશનો સ્વીકાર કરેલ નથી"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "અજ્ઞાત આદેશ"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "અયોગ્ય દલીલ"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "વસ્તુ અસ્તિત્વ ધરાવે છે"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "આવી વસ્તુ નથી"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "જોડાણને માન્ય ન કરવુ"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "પ્રોટોકોલ ભૂલ"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "સમય સમાપ્ત"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "સત્તાધિકરણ કી નથી"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "આંતરિક ભૂલ"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "જોડાણનો અંત થયેલ છે"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "વસ્તુને મારી નંખાયેલ છે"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "અયોગ્ય સર્વર"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "મોડ્યુલ શરૂઆત કરવાનું નિષ્ફળ"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "ખરાબ સ્થિતિ"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "માહિતી નથી"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "અસુસંગત પ્રોટોકોલ આવૃત્તિ"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "ઘણું લાંબુ છે"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "આધારભૂત નથી"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "અજ્ઞાત ભૂલ કોડ"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "આવુ એક્સટેન્શન નથી"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "અપ્રચલિત કાર્યત્મકતા"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "ગુમ થયેલ અમલીકરણ"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "ક્લાઇન્ટમાં ફાટા પડેલ છે"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "ઇનપુટ/આઉટપુટ ભૂલ"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "ઉપકરણ અથવા સ્ત્રોત વ્યસ્ત"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() નિષ્ફળ"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() નિષ્ફળ: %s"
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "કુકીની માહિતીને પદચ્છેદન કરવામાં નિષ્ફળ"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "રૂપરેખાંકન ફાઇલ '%s' ને ખોલવામાં નિષ્ફળ: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "કુકી લોડ થયેલ નથી. તેનાં વગર જોડવાનો પ્રયત્ન કરી રહ્યા છે."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "અજ્ઞાત એક્સટેન્શન '%s' માટે મળેલ સંદેશ"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "સ્ટ્રીમને નિકાલ કરવામાં નિષ્ફળ: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "પ્લેબેક સ્ટ્રીમ ને નિકાલ કરેલ છે."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "સર્વરમાં જોડાણને નિકાલ કરી રહ્યા છે."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() નિષ્ફળ: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_begin_write() નિષ્ફળ: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() નિષ્ફળ: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "સ્ટ્રીમ સફળતાપૂર્વક બનાવેલ છે."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() નિષ્ફળ: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, 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:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "બફર મેટ્રિક્સ: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "નમૂનો spec '%s' ને વાપરી રહ્યા છે, ચેનલ મેપ '%s'."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "ઉપકરણ %s (%u, %ssuspended) સાથે જોડાયેલ છે."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "સ્ટ્રીમ ભૂલ: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "સ્ટ્રીમ ઉપકરણ ને થોડા સમય માટે બંધ રાખેલ છે.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "સ્ટ્રીમ ઉપકરણને ફરી શરૂ કરેલ છે.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "સ્ટ્રીમ ચલાવવા હેઠળ છે.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "સ્ટ્રીમ ઉપર ચાલે છે.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "સ્ટ્રીમ શરૂ થયેલ છે.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "સ્ટ્રીમ એ ઉપકરણ %s (%u, %ssuspended) માં ખસેડેલ છે.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "નથી "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "સ્ટ્રીમ બફર ગુણધર્મો બદલાયેલ છે.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "જોડાણ સ્થાપિત થયેલ છે.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() નિષ્ફળ: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() નિષ્ફળ: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() નિષ્ફળ: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "જોડાણ નિષ્ફળ: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "EOF મળ્યુ."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() નિષ્ફળ: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "સંકેત મળ્યું, બહાર નીકળી રહ્યા છે."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "ગુપ્તતા મેળવવામાં નિષ્ફળતા: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Time: %0.3f sec; Latency: %0.0f usec."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() નિષ્ફળ: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1363,10 +1430,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [options]\n"
@@ -1415,7 +1487,7 @@ msgstr ""
 "      --file-format=FFORMAT             બંધારણ થયેલ માહિતીનો રેકોર્ડ કરો/વગાડો.\n"
 "      --list-file-formats               ઉપલ્બધ ફાઇલ બંધારણોની યાદી.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1426,169 +1498,174 @@ msgstr ""
 "libpulse %s સાથે કમ્પાઇલ થયેલ છે\n"
 "libpulse %s સાથે કડી થયેલ છે\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "અયોગ્ય ક્લાઇન્ટ નામ '%s'"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "અયોગ્ય સ્ટ્રીમ નામ '%s'"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "અયોગ્ય ચેનલ મેપ '%s'"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "અયોગ્ય ગુપ્તતા સ્પષ્ટીકરણ '%s'"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "અયોગ્ય પ્રક્રિયા સમય સ્પષ્ટીકરણ '%s'"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "અયોગ્ય ગુણધર્મ '%s'"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "અજ્ઞાત ફાઇલ બંધારણ %s."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "અયોગ્ય નમૂના સ્પષ્ટીકરણ"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "ઘણી બધી દલીલો છે."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "ફાઇલ માટે નમૂના સ્પષ્ટીકરણ ને ઉત્પન્ન કરવામાં નિષ્ફળ."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "સાઉન્ડ ફાઇલને ખોલવામાં નિષ્ફળતા."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
 msgstr "ચેતવણી: સ્પષ્ટ થયેલ નમૂના સ્પષ્ટીકરણ ફાઇલ માંથી સ્પષ્ટીકરણ સાથે ઉપર લખાયેલ હશે."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "ફાઇલ માંથી નમૂના સ્પષ્ટીકરણને નક્કી કરવામાં નિષ્ફળતા."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "ચેતવણી: ફાઇલમાંથી ચેનલ મેપને નક્કી કરવામાં નિષ્ફળતા."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "ચેનલ મેપ એ સ્પષ્ટીકરણ નમૂનાને બંધબેસતુ નથી"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "ચેતણી: ફાઇલમાં ચેનલ મેપને લખવામાં નિષ્ફળતા."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr "નમૂના સ્પષ્ટીકરણ '%s' અને ચેનલ નક્ષા '%s' સાથે %s સ્ટ્રીમને ખોલી રહ્યા છે."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "રેકોર્ડ કરી રહ્યા છે"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "પ્લેબેક"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "આદેશ વાક્યને પદચ્છેદન કરવામાં નિષ્ફળ."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() નિષ્ફળ."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() નિષ્ફળ."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() નિષ્ફળ."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() નિષ્ફળ: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_new() નિષ્ફળ."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() નિષ્ફળ."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "થોડા સમય માટે બંધ કરવા માટે નિષ્ફળતા: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "ફરી શરૂ કરવામાં નિષ્ફળતા: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "ચેતવણી: સાઉન્ડ સર્વર એ સ્થાનિક નથી, થોડા સમય માટે બંધ કરવામાં આવ્યુ નથી.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "જોડાણ નિષ્ફળ: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "SIGINT મળ્યુ, બહાર નીકળી રહ્યા છે.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "ચેતવણી: બાળ પ્રક્રિયાનો સંકેત %u દ્દારા અંત આવેલ છે\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1632,35 +1709,46 @@ msgstr "pa_context_new() નિષ્ફળ.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() નિષ્ફળ.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "પરિસ્થિતિઓને મેળવવામાં નિષ્ફળતા: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "હાલમાં વપરાશમાં છે: %u બ્લોકો %s કુલ બાઇટોને સમાવી રહ્યા છે.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "આખી જીંદગી દરમ્યાન ફાળવેલ છે: %u બ્લોકો %s કુલ બાઇટોને સમાવી રહ્યા છે.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "નમૂના કેશ માપ: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "સર્વર જાણકારી મેળવવામાં નિષ્ફળતા: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1668,7 +1756,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "વપરાશકર્તા નામ: %s\n"
 "યજમાન નામ: %s\n"
@@ -1680,13 +1768,13 @@ msgstr ""
 "મૂળભૂત સ્ત્રોત: %s\n"
 "કુકી: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "સિંક જાણકારી મેળવવામાં નિષ્ફળતા: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1702,7 +1790,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1724,22 +1812,27 @@ msgstr ""
 "\tગુણધર્મો:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tપોર્ટો:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tસક્રિય પોર્ટ: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tપોર્ટો:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "સ્ત્રોત જાણકારીને મેળવવામાં નિષ્ફળતા: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1778,20 +1871,20 @@ msgstr ""
 "\tગુણધર્મો:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "n/a"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "મોડ્યુલની જાણકારી મેળવવામાં નિષ્ફળતા: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1808,12 +1901,12 @@ msgstr ""
 "\tગુણધર્મો:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "ક્લાઇન્ટ જાણકારી મેળવવામાં નિષ્ફળતા: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1828,12 +1921,12 @@ msgstr ""
 "\tગુણધર્મો:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "કાર્ડ જાણકારી મેળવવામાં નિષ્ફળતા: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1850,23 +1943,23 @@ msgstr ""
 "\tગુણધર્મો:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tરૂપરેખાઓ:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tસક્રિય રૂપરેખા: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "સિંક ઇનપુટ જાણકારી મેળવવામાં નિષ્ફળતા: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1875,6 +1968,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1902,13 +1996,13 @@ msgstr ""
 "\tગુણધર્મો:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "સ્ત્રોત આઉટપુટ જાણકારી મેળવવામાં નિષ્ફળ: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1917,31 +2011,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"સà«\8dતà«\8dરà«\8bત àª\86àª\89àª\9fપુટ #%u\n"
+"સિàª\82àª\95 àª\87નપુટ #%u\n"
 "\tડ્રાઇવર: %s\n"
 "\tમાલિક મોડ્યુલ: %s\n"
 "\tક્લાઇન્ટ: %s\n"
-"\tસà«\8dતà«\8dરà«\8bત: %u\n"
+"\tસિàª\82àª\95: %u\n"
 "\tનમૂના સ્પષ્ટીકરણ: %s\n"
 "\tચેનલ મેપ %s\n"
+"\tમૂંગુ: %s\n"
+"\tવોલ્યુમ: %s\n"
+"\t        %s\n"
+"\t        સમતુલન %0.2f\n"
 "\tબફર ગુપ્તતા: %0.0f usec\n"
 "\tસિંક ગુપ્તતા: %0.0f usec\n"
 "\tResampl પદ્દતિ: %s\n"
 "\tગુણધર્મો:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "નમૂના જાણકારી મેળવવામાં નિષ્ફળ: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1972,48 +2075,163 @@ msgstr ""
 "\tગુણધર્મો:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "નિષ્ફળતા: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "સ્ત્રોત જાણકારીને મેળવવામાં નિષ્ફળતા: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "નમૂનાને અપલોડ કરવામાં નિષ્ફળ: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "ફાઇલનો નિયત સમય પહેલા અંત"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "અયોગ્ય સર્વર"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "SIGINT મળ્યુ, બહાર નીકળી રહ્યા છે."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "અયોગ્ય નમૂના સ્પષ્ટીકરણ"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2023,37 +2241,14 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+"%s [options] ... \n"
 "\n"
-"  -h, --help                            Show this help\n"
-"      --version                         Show version\n"
+"  -h, --help                            આ મદદ ને બતાવો\n"
+"      --version                         આવૃત્તિને બતાવો\n"
+"  -s, --server=SERVER                   જોડાવવા માટે સર્વરનું નામ\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect "
-"to\n"
-"  -n, --client-name=NAME                How to call this client on the "
-"server\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2064,106 +2259,138 @@ msgstr ""
 "libpulse %s સાથે કમ્પાઇલ થયેલ છે\n"
 "libpulse %s સાથે કડી થયેલ છે\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "મહેરબાની કરીને લોડ કરવા માટે નમૂના ફાઇલને સ્પષ્ટ કરો"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "સાઉન્ડ ફાઇલને ખોલવામાં નિષ્ફળ."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "ચેતવણી: ફાઇલ માંથી નમૂના સ્પષ્ટીકરણ કરવાનું નક્કી કરવામાં નિષ્ફળ."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "વગાડવા માટે તમારે નમૂના નામને સ્પષ્ટ કરવુ જ પડશે"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "દૂર કરવા માટે તમારે નમૂના નામને સ્પષ્ટ કરવુ જ પડશે"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "સિંક ઇનપુટ અનુક્રમણિકા અને સિંકને તમારે સ્પષ્ટ કરવુ જ પડશે"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "તમારે સ્ત્રોત આઉટપુટ અનુક્રમણિકા અને સ્ત્રોતને સ્પષ્ટ કરવુ જ પડશે"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "તમારે મોડ્યુલ નામ અને દલીલોને સ્પષ્ટ કરવુ જ પડશે."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "તમારે મોડ્યુલ અનુક્રમણિકાને સ્પષ્ટ કરવુ જ પડશે"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "તમે એક સિંક કરતા વધારે સ્પષ્ટ કરી શકશો નહિં. તમારે બુલિયન કિંમતને સ્પષ્ટ કરવુ જ પડશે."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr ""
 "તમે એક સ્ત્રોત કરતા વધારે સ્પષ્ટ કરી શકશો નહિં. તમારે બુલિયન કિંમતને સ્પષ્ટ કરવુ જ પડશે."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "તમારે કાર્ડ નામ/અનુક્રમણિકા અને પોર્ટ નામને સ્પષ્ટ કરવુ જ પડશે"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "તમારે કાર્ડ નામ/અનુક્રમણિકા અને પોર્ટ નામને સ્પષ્ટ કરવુ જ પડશે"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "તમારે કાર્ડ નામ/અનુક્રમણિકા અને પોર્ટ નામને સ્પષ્ટ કરવુ જ પડશે"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "તમારે કાર્ડ નામ/અનુક્રમણિકા અને વોલ્યુમને સ્પષ્ટ કરવુ જ પડશે"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "અયોગ્ય નમૂના સ્પષ્ટીકરણ"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "તમારે કાર્ડ નામ/અનુક્રમણિકા અને વોલ્યુમ સ્પષ્ટ કરવુ જ પડશે"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "સિંક ઇનપુટ અનુક્રમણિકા અને વોલ્યુમને તમારે સ્પષ્ટ કરવુ જ પડશે"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "અયોગ્ય સિંક ઇનપુટ અનુક્રમણિકા"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "તમારે સ્ત્રોત આઉટપુટ અનુક્રમણિકા અને સ્ત્રોતને સ્પષ્ટ કરવુ જ પડશે"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "અયોગ્ય સિંક ઇનપુટ અનુક્રમણિકા"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "તમારે સિંક નામ/અનુક્રમણિકા અને મૂંગા બુલિયનને સ્પષ્ટ કરવુ જ પડશે"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "અયોગ્ય નમૂના સ્પષ્ટીકરણ"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "તમારે સિંક નામ/અનુક્રમણિકા અને મૂંગા બુલિયનને સ્પષ્ટ કરવુ જ પડશે"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "સિંક ઇનપુટ અનુક્રમણિકા અને મૂંગા બુલિયનને તમારે સ્પષ્ટ કરવુ જ પડશે"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "અયોગ્ય ઇનપુટ અનુક્રમણિકા સ્પષ્ટીકરણ"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "તમારે સિંક નામ/અનુક્રમણિકા અને મૂંગા બુલિયનને સ્પષ્ટ કરવુ જ પડશે"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "અયોગ્ય ઇનપુટ અનુક્રમણિકા સ્પષ્ટીકરણ"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "તમારે સિંક નામ/અનુક્રમણિકા અને મૂંગા બુલિયનને સ્પષ્ટ કરવુ જ પડશે"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "યોગ્ય આદેશ સ્પષ્ટ થયેલ નથી."
 
@@ -2191,103 +2418,103 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "આદેશ વાક્યને પદચ્છેદન કરવામાં નિષ્ફળ.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "સર્વર: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "સ્ત્રોત: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "સિંક: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "કુકી: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "કુકી માહિતીને પદચ્છેદન કરવામાં નિષ્ફળ\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "કુકી માહિતીને સંગ્રહ કરવામાં નિષ્ફળ\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "ક્લાઇન્ટ રૂપરેખાંકન ફાઇલને લોડ કરવામાં નિષ્ફળ.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "પર્યાવરણ રૂપરેખાંકન માહિતીને વાંચવામાં નિષ્ફળ.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "FQDN ને મેળવવામાં નિષ્ફળ.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "કુકી માહિતીને લોડ કરવામાં નિષ્ફળ\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "હજુ અમલીકરણ થયેલ નથી.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr "PulseAudio ડિમન ચાલી રહ્યુ નથી, અથવા સત્ર ડિમન તરીકે ચાલી રહ્યુ નથી."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "PulseAudio ડિમનને મારવામાં નિષ્ફળ."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "ડિમન એ જવાબ આપતુ નથી."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "autospawn તાળાને દાખલ કરી શકાતુ નથી."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2304,7 +2531,7 @@ msgstr ""
 "POLLOUT સુયોજન સાથે આપણે જાગેલ હતા -- છતાંપણ ના પછીનું snd_pcm_avail() ને 0 પાછો મળે "
 "છે અથવા બીજી કિંમત < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2321,242 +2548,465 @@ msgstr ""
 "POLLOUT સુયોજન સાથે આપણે જાગેલ હતા -- છતાંપણ ના પછીનું snd_pcm_avail() ને 0 પાછો મળે "
 "છે અથવા બીજી કિંમત < min_avail."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "બંધ"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "High Fidelity Playback (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "High Fidelity Capture (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Telephony Duplex (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "PulseAudio સાઉન્ડ સર્વર"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
-msgstr ""
+msgstr "આઉટપુટ ઉપકરણો"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
-msgstr ""
+msgstr "ઇનપુટ ઉપકરણો"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
-msgstr ""
+msgstr "@HOSTNAME@ પર ઓડિયો"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
-msgstr ""
+msgstr "ઇનપુટ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
-msgstr ""
+msgstr "ડોકિંગ સ્ટેશન ઇનપુટ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
-msgstr ""
+msgstr "ડોકિંગ સ્ટેશન માઇક્રોફોન"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "ડોકિંગ સ્ટેશન ઇનપુટ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "લાઇન-ઇન"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
-msgstr ""
+msgstr "માઇક્રોફોન"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
-msgid "External Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "ડોકિંગ સ્ટેશન માઇક્રોફોન"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
 #, fuzzy
+msgid "Rear Microphone"
+msgstr "માઇક્રોફોન"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "બહારનાં માઇક્રોફોન"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
-msgstr "àª\86àª\82તરિàª\95 àª\93ડિયà«\8b"
+msgstr "àª\86àª\82તરિàª\95 àª®àª¾àª\87àª\95à«\8dરà«\8bફà«\8bન"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
-msgstr ""
+msgstr "રેડિયો"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
-msgstr ""
+msgstr "વિડિયો"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
-msgstr ""
+msgstr "Automatic Gain Control"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
-msgstr ""
+msgstr "Automatic Gain Control નથી"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
-msgstr ""
+msgstr "બુસ્ટ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
-msgstr ""
+msgstr "બુસ્ટ નથી"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
-msgstr ""
+msgstr "પરિવર્ધક"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
-msgstr ""
+msgstr "પરિવર્ધક નથી"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "બુસ્ટ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "બુસ્ટ નથી"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "ઍનલૉગ હૅડફોનો"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "ઍનલૉગ ઇનપુટ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "ડોકિંગ સ્ટેશન માઇક્રોફોન"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
-msgstr "શà«\82નà«\8dય આઉટપુટ"
+msgstr "àª\8dનલà«\89àª\97 આઉટપુટ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "ઍનલૉગ આઉટપુટ (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "લાઇન-ઇન"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
+msgstr "ઍનલૉગ મોનો આઉટપુટ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "ઍનલૉગ સ્ટેરિઓ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, fuzzy, c-format
-msgid "%s+%s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "ડિજિટલ સ્ટેરિઓ (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, fuzzy, c-format
-msgid "%s / %s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "ડિજિટલ સ્ટેરિઓ (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
-msgstr ""
+msgstr "ઍનલૉગ મોનો"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
-msgstr "સ્ટેરિઓ"
+msgstr "àª\8dનલà«\89àª\97 àª¸à«\8dàª\9fà«\87રિàª\93"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
-msgstr "સરાàª\89નà«\8dડ 4.1"
+msgstr "àª\8dનલà«\89àª\97 àª¸àª°àª¾àª\89નà«\8dડ 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
-msgstr "સરાàª\89નà«\8dડ 4.0"
+msgstr "àª\8dનલà«\89àª\97 àª¸àª°àª¾àª\89નà«\8dડ 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
-msgstr "સરાàª\89નà«\8dડ 4.1"
+msgstr "àª\8dનલà«\89àª\97 àª¸àª°àª¾àª\89નà«\8dડ 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
-msgstr "સરાઉન્ડ 4.0"
+msgstr "àª\8dનલà«\89àª\97 àª¸àª°àª¾àª\89નà«\8dડ 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
-msgstr "સરાઉન્ડ 4.1"
+msgstr "àª\8dનલà«\89àª\97 àª¸àª°àª¾àª\89નà«\8dડ 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
-msgstr "સરાઉન્ડ 5.0"
+msgstr "àª\8dનલà«\89àª\97 àª¸àª°àª¾àª\89નà«\8dડ 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
-msgstr "સરાઉન્ડ 5.1"
+msgstr "àª\8dનલà«\89àª\97 àª¸àª°àª¾àª\89નà«\8dડ 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
-msgstr "સરાàª\89નà«\8dડ 4.0"
+msgstr "àª\8dનલà«\89àª\97 àª¸àª°àª¾àª\89નà«\8dડ 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
-msgstr "સરાàª\89નà«\8dડ 4.1"
+msgstr "àª\8dનલà«\89àª\97 àª¸àª°àª¾àª\89નà«\8dડ 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
-msgstr "સરાàª\89નà«\8dડ 4.0"
+msgstr "àª\8dનલà«\89àª\97 àª¸àª°àª¾àª\89નà«\8dડ 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
-msgstr "સરાઉન્ડ 7.1"
+msgstr "àª\8dનલà«\89àª\97 àª¸àª°àª¾àª\89નà«\8dડ 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
-msgstr ""
+msgstr "ડિજિટલ સ્ટેરિઓ (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "ડિજિટલ સ્ટેરિઓ (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
-msgstr ""
+msgstr "ડિજિટલ સરાઉન્ડ 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
-msgstr ""
+msgstr "ડિજિટલ સરાઉન્ડ 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
-msgstr ""
+msgstr "ડિજિટલ સ્ટેરિઓ (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "ડિજિટલ સરાઉન્ડ 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
-msgstr ""
+msgstr "ઍનલૉગ મોનો ડુપ્લેક્ષ"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
-msgstr ""
+msgstr "ઍનલૉગ સ્ટેરિઓ ડુપ્લેક્ષ"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
+msgstr "ડિજિટલ સ્ટેરિઓ ડુપ્લેક્ષ (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "શૂન્ય આઉટપુટ"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "ઇનપુટ"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
 msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<name for the sink> sink_properties=<properties for the sink> "
+"master=<name of sink to filter> format=<sample format> rate=<sample rate> "
+"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
+"plugin name> label=<ladspa plugin label> control=<comma separated list of "
+"input control values>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit એ આ પ્લેટફોર્મ પર આધારભૂત નથી."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() નિષ્ફળ"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "સ્ત્રોત આઉટપુટ #%u\n"
+#~ "\tડ્રાઇવર: %s\n"
+#~ "\tમાલિક મોડ્યુલ: %s\n"
+#~ "\tક્લાઇન્ટ: %s\n"
+#~ "\tસ્ત્રોત: %u\n"
+#~ "\tનમૂના સ્પષ્ટીકરણ: %s\n"
+#~ "\tચેનલ મેપ %s\n"
+#~ "\tબફર ગુપ્તતા: %0.0f usec\n"
+#~ "\tસિંક ગુપ્તતા: %0.0f usec\n"
+#~ "\tResampl પદ્દતિ: %s\n"
+#~ "\tગુણધર્મો:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "ડિજિટલ સરાઉન્ડ 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Low Frequency Emmiter"
diff --git a/po/he.po b/po/he.po
new file mode 100644 (file)
index 0000000..39b9eaf
--- /dev/null
+++ b/po/he.po
@@ -0,0 +1,2601 @@
+#
+# Elad <el.il@doom.co.il>, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pulseaudio\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:53+0000\n"
+"Last-Translator: Elad <el.il@doom.co.il>\n"
+"Language-Team: Hebrew <fedora-he-list@redhat.com>\n"
+"Language: he\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Poedit-Language: Hebrew\n"
+"X-Poedit-Country: Israel\n"
+
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
+#, 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 ""
+
+#: ../src/modules/alsa/alsa-util.c:1179
+#, 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."
+msgstr ""
+
+#: ../src/modules/alsa/alsa-util.c:1220
+#, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+
+#: ../src/modules/alsa/alsa-util.c:1263
+#, 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."
+msgstr ""
+
+#: ../src/modules/module-always-sink.c:38
+msgid "Always keeps at least one sink loaded even if it's a null one"
+msgstr ""
+
+#: ../src/modules/module-always-sink.c:82
+msgid "Dummy Output"
+msgstr ""
+
+#: ../src/modules/module-ladspa-sink.c:48
+msgid "Virtual LADSPA sink"
+msgstr ""
+
+#: ../src/modules/module-ladspa-sink.c:52
+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> "
+"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> "
+msgstr ""
+
+#: ../src/modules/module-null-sink.c:49
+msgid "Clocked NULL sink"
+msgstr ""
+
+#: ../src/modules/module-null-sink.c:284
+msgid "Null Output"
+msgstr ""
+
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
+msgstr "צליל פנימי"
+
+#: ../src/pulsecore/sink.c:3354
+msgid "Modem"
+msgstr "מודם"
+
+#: ../src/daemon/ltdl-bind-now.c:127
+msgid "Failed to find original lt_dlopen loader."
+msgstr ""
+
+#: ../src/daemon/ltdl-bind-now.c:132
+msgid "Failed to allocate new dl loader."
+msgstr ""
+
+#: ../src/daemon/ltdl-bind-now.c:145
+msgid "Failed to add bind-now-loader."
+msgstr ""
+
+#: ../src/daemon/main.c:139
+#, c-format
+msgid "Got signal %s."
+msgstr ""
+
+#: ../src/daemon/main.c:166
+msgid "Exiting."
+msgstr "יוצא."
+
+#: ../src/daemon/main.c:184
+#, c-format
+msgid "Failed to find user '%s'."
+msgstr ""
+
+#: ../src/daemon/main.c:189
+#, c-format
+msgid "Failed to find group '%s'."
+msgstr ""
+
+#: ../src/daemon/main.c:193
+#, c-format
+msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
+msgstr ""
+
+#: ../src/daemon/main.c:198
+#, c-format
+msgid "GID of user '%s' and of group '%s' don't match."
+msgstr ""
+
+#: ../src/daemon/main.c:203
+#, c-format
+msgid "Home directory of user '%s' is not '%s', ignoring."
+msgstr ""
+
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
+#, c-format
+msgid "Failed to create '%s': %s"
+msgstr ""
+
+#: ../src/daemon/main.c:218
+#, c-format
+msgid "Failed to change group list: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:234
+#, c-format
+msgid "Failed to change GID: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:250
+#, c-format
+msgid "Failed to change UID: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:269
+msgid "Successfully dropped root privileges."
+msgstr ""
+
+#: ../src/daemon/main.c:277
+msgid "System wide mode unsupported on this platform."
+msgstr ""
+
+#: ../src/daemon/main.c:295
+#, c-format
+msgid "setrlimit(%s, (%u, %u)) failed: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:496
+msgid "Failed to parse command line."
+msgstr ""
+
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
+msgid "Daemon not running"
+msgstr ""
+
+#: ../src/daemon/main.c:613
+#, c-format
+msgid "Daemon running as PID %u"
+msgstr ""
+
+#: ../src/daemon/main.c:628
+#, c-format
+msgid "Failed to kill daemon: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:657
+msgid ""
+"This program is not intended to be run as root (unless --system is "
+"specified)."
+msgstr ""
+
+#: ../src/daemon/main.c:660
+msgid "Root privileges required."
+msgstr ""
+
+#: ../src/daemon/main.c:667
+msgid "--start not supported for system instances."
+msgstr ""
+
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
+msgid "Running in system mode, but --disallow-exit not set!"
+msgstr ""
+
+#: ../src/daemon/main.c:721
+msgid "Running in system mode, but --disallow-module-loading not set!"
+msgstr ""
+
+#: ../src/daemon/main.c:724
+msgid "Running in system mode, forcibly disabling SHM mode!"
+msgstr ""
+
+#: ../src/daemon/main.c:729
+msgid "Running in system mode, forcibly disabling exit idle time!"
+msgstr ""
+
+#: ../src/daemon/main.c:757
+msgid "Failed to acquire stdio."
+msgstr ""
+
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, c-format
+msgid "pipe() failed: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
+#, c-format
+msgid "fork() failed: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
+#, c-format
+msgid "read() failed: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:789
+msgid "Daemon startup failed."
+msgstr ""
+
+#: ../src/daemon/main.c:791
+msgid "Daemon startup successful."
+msgstr ""
+
+#: ../src/daemon/main.c:816
+#, c-format
+msgid "setsid() failed: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:901
+#, c-format
+msgid "This is PulseAudio %s"
+msgstr ""
+
+#: ../src/daemon/main.c:902
+#, c-format
+msgid "Compilation host: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
+#, c-format
+msgid "Compilation CFLAGS: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:906
+#, c-format
+msgid "Running on host: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:909
+#, c-format
+msgid "Found %u CPUs."
+msgstr ""
+
+#: ../src/daemon/main.c:911
+#, c-format
+msgid "Page size is %lu bytes"
+msgstr ""
+
+#: ../src/daemon/main.c:914
+msgid "Compiled with Valgrind support: yes"
+msgstr ""
+
+#: ../src/daemon/main.c:916
+msgid "Compiled with Valgrind support: no"
+msgstr ""
+
+#: ../src/daemon/main.c:919
+#, c-format
+msgid "Running in valgrind mode: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:921
+#, c-format
+msgid "Running in VM: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:924
+msgid "Optimized build: yes"
+msgstr ""
+
+#: ../src/daemon/main.c:926
+msgid "Optimized build: no"
+msgstr ""
+
+#: ../src/daemon/main.c:930
+msgid "NDEBUG defined, all asserts disabled."
+msgstr ""
+
+#: ../src/daemon/main.c:932
+msgid "FASTPATH defined, only fast path asserts disabled."
+msgstr ""
+
+#: ../src/daemon/main.c:934
+msgid "All asserts enabled."
+msgstr ""
+
+#: ../src/daemon/main.c:938
+msgid "Failed to get machine ID"
+msgstr ""
+
+#: ../src/daemon/main.c:941
+#, c-format
+msgid "Machine ID is %s."
+msgstr ""
+
+#: ../src/daemon/main.c:945
+#, c-format
+msgid "Session ID is %s."
+msgstr ""
+
+#: ../src/daemon/main.c:951
+#, c-format
+msgid "Using runtime directory %s."
+msgstr ""
+
+#: ../src/daemon/main.c:956
+#, c-format
+msgid "Using state directory %s."
+msgstr ""
+
+#: ../src/daemon/main.c:959
+#, c-format
+msgid "Using modules directory %s."
+msgstr ""
+
+#: ../src/daemon/main.c:961
+#, c-format
+msgid "Running in system mode: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:964
+msgid ""
+"OK, so you are running PA in system mode. Please note that you most likely "
+"shouldn't be doing that.\n"
+"If you do it nonetheless then it's your own fault if things don't work as "
+"expected.\n"
+"Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an "
+"explanation why system mode is usually a bad idea."
+msgstr ""
+
+#: ../src/daemon/main.c:981
+msgid "pa_pid_file_create() failed."
+msgstr ""
+
+#: ../src/daemon/main.c:991
+msgid "Fresh high-resolution timers available! Bon appetit!"
+msgstr ""
+
+#: ../src/daemon/main.c:993
+msgid ""
+"Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
+"resolution timers enabled!"
+msgstr ""
+
+#: ../src/daemon/main.c:1011
+msgid "pa_core_new() failed."
+msgstr ""
+
+#: ../src/daemon/main.c:1087
+msgid "Failed to initialize daemon."
+msgstr ""
+
+#: ../src/daemon/main.c:1092
+msgid "Daemon startup without any loaded modules, refusing to work."
+msgstr ""
+
+#: ../src/daemon/main.c:1130
+msgid "Daemon startup complete."
+msgstr ""
+
+#: ../src/daemon/main.c:1136
+msgid "Daemon shutdown initiated."
+msgstr ""
+
+#: ../src/daemon/main.c:1167
+msgid "Daemon terminated."
+msgstr ""
+
+#: ../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                                    Increase the verbosity level\n"
+"      --log-target={auto,syslog,stderr,file: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"
+"\n"
+"STARTUP SCRIPT:\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module "
+"with\n"
+"                                        the specified argument\n"
+"  -F, --file=FILENAME                   Run the specified script\n"
+"  -C                                    Open a command line on the running "
+"TTY\n"
+"                                        after startup\n"
+"\n"
+"  -n                                    Don't load default script file\n"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:244
+msgid "--daemonize expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:251
+msgid "--fail expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:261
+msgid ""
+"--log-level expects log level argument (either numeric in range 0..4 or one "
+"of debug, info, notice, warn, error)."
+msgstr ""
+
+#: ../src/daemon/cmdline.c:273
+msgid "--high-priority expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:280
+msgid "--realtime expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:287
+msgid "--disallow-module-loading expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:294
+msgid "--disallow-exit expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:301
+msgid "--use-pid-file expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:318
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
+msgstr ""
+
+#: ../src/daemon/cmdline.c:325
+msgid "--log-time expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:332
+msgid "--log-meta expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:351
+#, c-format
+msgid "Invalid resample method '%s'."
+msgstr ""
+
+#: ../src/daemon/cmdline.c:358
+msgid "--system expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:365
+msgid "--no-cpu-limit expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:372
+msgid "--disable-shm expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:59
+#, c-format
+msgid "Name: %s\n"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:62
+#, c-format
+msgid "No module information available\n"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:65
+#, c-format
+msgid "Version: %s\n"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:67
+#, c-format
+msgid "Description: %s\n"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:69
+#, c-format
+msgid "Author: %s\n"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:71
+#, c-format
+msgid "Usage: %s\n"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:72
+#, c-format
+msgid "Load Once: %s\n"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:74
+#, c-format
+msgid "DEPRECATION WARNING: %s\n"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:78
+#, c-format
+msgid "Path: %s\n"
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:275
+#, c-format
+msgid "[%s:%u] Invalid log target '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:291
+#, c-format
+msgid "[%s:%u] Invalid log level '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:307
+#, c-format
+msgid "[%s:%u] Invalid resample method '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:330
+#, c-format
+msgid "[%s:%u] Invalid rlimit '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:351
+#, c-format
+msgid "[%s:%u] Invalid sample format '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
+#, c-format
+msgid "[%s:%u] Invalid sample rate '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:413
+#, c-format
+msgid "[%s:%u] Invalid sample channels '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:431
+#, c-format
+msgid "[%s:%u] Invalid channel map '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:449
+#, c-format
+msgid "[%s:%u] Invalid number of fragments '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:467
+#, c-format
+msgid "[%s:%u] Invalid fragment size '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:485
+#, c-format
+msgid "[%s:%u] Invalid nice level '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:528
+#, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:641
+#, c-format
+msgid "Failed to open configuration file: %s"
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:657
+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:743
+#, c-format
+msgid "### Read from configuration file: %s ###\n"
+msgstr ""
+
+#: ../src/daemon/caps.c:58
+msgid "Cleaning up privileges."
+msgstr ""
+
+#: ../src/daemon/pulseaudio.desktop.in.h:1
+msgid "PulseAudio Sound System"
+msgstr "מערכת הקול PulseAudio"
+
+#: ../src/daemon/pulseaudio.desktop.in.h:2
+msgid "Start the PulseAudio Sound System"
+msgstr "התחל את מערכת הקול PulseAudio"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "מערכת הקול PulseAudio"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "התחל את מערכת הקול PulseAudio"
+
+#: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
+msgid "Mono"
+msgstr "מונו"
+
+#: ../src/pulse/channelmap.c:107
+msgid "Front Center"
+msgstr "מרכזי קדמי"
+
+#: ../src/pulse/channelmap.c:108
+msgid "Front Left"
+msgstr "שמאלי קדמי"
+
+#: ../src/pulse/channelmap.c:109
+msgid "Front Right"
+msgstr "ימני קדמי"
+
+#: ../src/pulse/channelmap.c:111
+msgid "Rear Center"
+msgstr "מרכזי אחורי"
+
+#: ../src/pulse/channelmap.c:112
+msgid "Rear Left"
+msgstr "שמאלי אחורי"
+
+#: ../src/pulse/channelmap.c:113
+msgid "Rear Right"
+msgstr "ימני אחורי"
+
+#: ../src/pulse/channelmap.c:115
+msgid "Subwoofer"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:117
+msgid "Front Left-of-center"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:118
+msgid "Front Right-of-center"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:120
+msgid "Side Left"
+msgstr "צד שמאל"
+
+#: ../src/pulse/channelmap.c:121
+msgid "Side Right"
+msgstr "צד ימין"
+
+#: ../src/pulse/channelmap.c:123
+msgid "Auxiliary 0"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:124
+msgid "Auxiliary 1"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:125
+msgid "Auxiliary 2"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:126
+msgid "Auxiliary 3"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:127
+msgid "Auxiliary 4"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:128
+msgid "Auxiliary 5"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:129
+msgid "Auxiliary 6"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:130
+msgid "Auxiliary 7"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:131
+msgid "Auxiliary 8"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:132
+msgid "Auxiliary 9"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:133
+msgid "Auxiliary 10"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:134
+msgid "Auxiliary 11"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:135
+msgid "Auxiliary 12"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:136
+msgid "Auxiliary 13"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:137
+msgid "Auxiliary 14"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:138
+msgid "Auxiliary 15"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:139
+msgid "Auxiliary 16"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:140
+msgid "Auxiliary 17"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:141
+msgid "Auxiliary 18"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:142
+msgid "Auxiliary 19"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:143
+msgid "Auxiliary 20"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:144
+msgid "Auxiliary 21"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:145
+msgid "Auxiliary 22"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:146
+msgid "Auxiliary 23"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:147
+msgid "Auxiliary 24"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:148
+msgid "Auxiliary 25"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:149
+msgid "Auxiliary 26"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:150
+msgid "Auxiliary 27"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:151
+msgid "Auxiliary 28"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:152
+msgid "Auxiliary 29"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:153
+msgid "Auxiliary 30"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:154
+msgid "Auxiliary 31"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:156
+msgid "Top Center"
+msgstr "מרכזי עליון"
+
+#: ../src/pulse/channelmap.c:158
+msgid "Top Front Center"
+msgstr "מרכזי עליון קדמי"
+
+#: ../src/pulse/channelmap.c:159
+msgid "Top Front Left"
+msgstr "עליון שמאלי קדמי"
+
+#: ../src/pulse/channelmap.c:160
+msgid "Top Front Right"
+msgstr "עליון ימני קדמי"
+
+#: ../src/pulse/channelmap.c:162
+msgid "Top Rear Center"
+msgstr "עליון מרכזי אחורי"
+
+#: ../src/pulse/channelmap.c:163
+msgid "Top Rear Left"
+msgstr "עליון שמאלי אחורי"
+
+#: ../src/pulse/channelmap.c:164
+msgid "Top Rear Right"
+msgstr "עליון ימני אחורי"
+
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
+msgid "(invalid)"
+msgstr "(לא תקף)"
+
+#: ../src/pulse/channelmap.c:761
+msgid "Stereo"
+msgstr "סטראו"
+
+#: ../src/pulse/channelmap.c:766
+msgid "Surround 4.0"
+msgstr "סראונד 4.0"
+
+#: ../src/pulse/channelmap.c:772
+msgid "Surround 4.1"
+msgstr "סראונד 4.1"
+
+#: ../src/pulse/channelmap.c:778
+msgid "Surround 5.0"
+msgstr "סראונד 5.0"
+
+#: ../src/pulse/channelmap.c:784
+msgid "Surround 5.1"
+msgstr "סראונד 5.1"
+
+#: ../src/pulse/channelmap.c:791
+msgid "Surround 7.1"
+msgstr "סראונד 7.1"
+
+#: ../src/pulse/error.c:40
+msgid "OK"
+msgstr "אישור"
+
+#: ../src/pulse/error.c:41
+msgid "Access denied"
+msgstr "הגישה נדחתה"
+
+#: ../src/pulse/error.c:42
+msgid "Unknown command"
+msgstr ""
+
+#: ../src/pulse/error.c:43
+msgid "Invalid argument"
+msgstr ""
+
+#: ../src/pulse/error.c:44
+msgid "Entity exists"
+msgstr ""
+
+#: ../src/pulse/error.c:45
+msgid "No such entity"
+msgstr ""
+
+#: ../src/pulse/error.c:46
+msgid "Connection refused"
+msgstr "החיבור נדחה"
+
+#: ../src/pulse/error.c:47
+msgid "Protocol error"
+msgstr "שגיאת פרוטוקול"
+
+#: ../src/pulse/error.c:48
+msgid "Timeout"
+msgstr ""
+
+#: ../src/pulse/error.c:49
+msgid "No authorization key"
+msgstr ""
+
+#: ../src/pulse/error.c:50
+msgid "Internal error"
+msgstr "שגיאה פנימית"
+
+#: ../src/pulse/error.c:51
+msgid "Connection terminated"
+msgstr ""
+
+#: ../src/pulse/error.c:52
+msgid "Entity killed"
+msgstr ""
+
+#: ../src/pulse/error.c:53
+msgid "Invalid server"
+msgstr ""
+
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
+msgstr ""
+
+#: ../src/pulse/error.c:55
+msgid "Bad state"
+msgstr ""
+
+#: ../src/pulse/error.c:56
+msgid "No data"
+msgstr ""
+
+#: ../src/pulse/error.c:57
+msgid "Incompatible protocol version"
+msgstr ""
+
+#: ../src/pulse/error.c:58
+msgid "Too large"
+msgstr "גדול מדי"
+
+#: ../src/pulse/error.c:59
+msgid "Not supported"
+msgstr "לא נתמך"
+
+#: ../src/pulse/error.c:60
+msgid "Unknown error code"
+msgstr "קוד שגיאה לא מוכר"
+
+#: ../src/pulse/error.c:61
+msgid "No such extension"
+msgstr ""
+
+#: ../src/pulse/error.c:62
+msgid "Obsolete functionality"
+msgstr ""
+
+#: ../src/pulse/error.c:63
+msgid "Missing implementation"
+msgstr ""
+
+#: ../src/pulse/error.c:64
+msgid "Client forked"
+msgstr ""
+
+#: ../src/pulse/error.c:65
+msgid "Input/Output error"
+msgstr "שגיאת קלט/פלט"
+
+#: ../src/pulse/error.c:66
+msgid "Device or resource busy"
+msgstr "התקן או משאב עסוקים"
+
+#: ../src/pulse/sample.c:171
+#, c-format
+msgid "%s %uch %uHz"
+msgstr ""
+
+#: ../src/pulse/sample.c:183
+#, c-format
+msgid "%0.1f GiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:185
+#, c-format
+msgid "%0.1f MiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:187
+#, c-format
+msgid "%0.1f KiB"
+msgstr ""
+
+#: ../src/pulse/sample.c:189
+#, c-format
+msgid "%u B"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+msgid "xcb_connect() failed"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:97
+msgid "Failed to parse cookie data"
+msgstr ""
+
+#: ../src/pulse/client-conf.c:117
+#, c-format
+msgid "Failed to open configuration file '%s': %s"
+msgstr ""
+
+#: ../src/pulse/context.c:528
+msgid "No cookie loaded. Attempting to connect without."
+msgstr ""
+
+#: ../src/pulse/context.c:675
+#, c-format
+msgid "fork(): %s"
+msgstr ""
+
+#: ../src/pulse/context.c:730
+#, c-format
+msgid "waitpid(): %s"
+msgstr ""
+
+#: ../src/pulse/context.c:1431
+#, c-format
+msgid "Received message for unknown extension '%s'"
+msgstr ""
+
+#: ../src/utils/pacat.c:112
+#, c-format
+msgid "Failed to drain stream: %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:117
+msgid "Playback stream drained."
+msgstr ""
+
+#: ../src/utils/pacat.c:128
+msgid "Draining connection to server."
+msgstr ""
+
+#: ../src/utils/pacat.c:141
+#, c-format
+msgid "pa_stream_drain(): %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:164
+#, c-format
+msgid "pa_stream_write() failed: %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:205
+#, c-format
+msgid "pa_stream_begin_write() failed: %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
+#, c-format
+msgid "pa_stream_peek() failed: %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:325
+msgid "Stream successfully created."
+msgstr ""
+
+#: ../src/utils/pacat.c:328
+#, c-format
+msgid "pa_stream_get_buffer_attr() failed: %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:332
+#, c-format
+msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
+msgstr ""
+
+#: ../src/utils/pacat.c:335
+#, c-format
+msgid "Buffer metrics: maxlength=%u, fragsize=%u"
+msgstr ""
+
+#: ../src/utils/pacat.c:339
+#, c-format
+msgid "Using sample spec '%s', channel map '%s'."
+msgstr ""
+
+#: ../src/utils/pacat.c:343
+#, c-format
+msgid "Connected to device %s (%u, %ssuspended)."
+msgstr ""
+
+#: ../src/utils/pacat.c:353
+#, c-format
+msgid "Stream error: %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:363
+#, c-format
+msgid "Stream device suspended.%s"
+msgstr ""
+
+#: ../src/utils/pacat.c:365
+#, c-format
+msgid "Stream device resumed.%s"
+msgstr ""
+
+#: ../src/utils/pacat.c:373
+#, c-format
+msgid "Stream underrun.%s"
+msgstr ""
+
+#: ../src/utils/pacat.c:380
+#, c-format
+msgid "Stream overrun.%s"
+msgstr ""
+
+#: ../src/utils/pacat.c:387
+#, c-format
+msgid "Stream started.%s"
+msgstr ""
+
+#: ../src/utils/pacat.c:394
+#, c-format
+msgid "Stream moved to device %s (%u, %ssuspended).%s"
+msgstr ""
+
+#: ../src/utils/pacat.c:394
+msgid "not "
+msgstr "לא"
+
+#: ../src/utils/pacat.c:401
+#, c-format
+msgid "Stream buffer attributes changed.%s"
+msgstr ""
+
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
+#, c-format
+msgid "Connection established.%s"
+msgstr ""
+
+#: ../src/utils/pacat.c:454
+#, c-format
+msgid "pa_stream_new() failed: %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:492
+#, c-format
+msgid "pa_stream_connect_playback() failed: %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:498
+#, c-format
+msgid "pa_stream_connect_record() failed: %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
+#, c-format
+msgid "Connection failure: %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:545
+msgid "Got EOF."
+msgstr ""
+
+#: ../src/utils/pacat.c:582
+#, c-format
+msgid "write() failed: %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:603
+msgid "Got signal, exiting."
+msgstr ""
+
+#: ../src/utils/pacat.c:617
+#, c-format
+msgid "Failed to get latency: %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:622
+#, c-format
+msgid "Time: %0.3f sec; Latency: %0.0f usec."
+msgstr ""
+
+#: ../src/utils/pacat.c:643
+#, c-format
+msgid "pa_stream_update_timing_info() failed: %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:653
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"\n"
+"  -r, --record                          Create a connection for recording\n"
+"  -p, --playback                        Create a connection for playback\n"
+"\n"
+"  -v, --verbose                         Enable verbose operations\n"
+"\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -d, --device=DEVICE                   The name of the sink/source to "
+"connect to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
+"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to "
+"44100)\n"
+"      --format=SAMPLEFORMAT             The sample type, one of s16le, "
+"s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be, "
+"s24le, s24be,\n"
+"                                        s24-32le, s24-32be (defaults to "
+"s16ne)\n"
+"      --channels=CHANNELS               The number of channels, 1 for mono, "
+"2 for stereo\n"
+"                                        (defaults to 2)\n"
+"      --channel-map=CHANNELMAP          Channel map to use instead of the "
+"default\n"
+"      --fix-format                      Take the sample format from the sink "
+"the stream is\n"
+"                                        being connected to.\n"
+"      --fix-rate                        Take the sampling rate from the sink "
+"the stream is\n"
+"                                        being connected to.\n"
+"      --fix-channels                    Take the number of channels and the "
+"channel map\n"
+"                                        from the sink the stream is being "
+"connected to.\n"
+"      --no-remix                        Don't upmix or downmix channels.\n"
+"      --no-remap                        Map channels by index instead of "
+"name.\n"
+"      --latency=BYTES                   Request the specified latency in "
+"bytes.\n"
+"      --process-time=BYTES              Request the specified process time "
+"per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
+"      --property=PROPERTY=VALUE         Set the specified property to the "
+"specified value.\n"
+"      --raw                             Record/play raw PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
+"      --list-file-formats               List available file formats.\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:786
+#, c-format
+msgid ""
+"pacat %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
+#, c-format
+msgid "Invalid client name '%s'"
+msgstr ""
+
+#: ../src/utils/pacat.c:834
+#, c-format
+msgid "Invalid stream name '%s'"
+msgstr ""
+
+#: ../src/utils/pacat.c:871
+#, c-format
+msgid "Invalid channel map '%s'"
+msgstr ""
+
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
+#, c-format
+msgid "Invalid latency specification '%s'"
+msgstr ""
+
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
+#, c-format
+msgid "Invalid process time specification '%s'"
+msgstr ""
+
+#: ../src/utils/pacat.c:933
+#, c-format
+msgid "Invalid property '%s'"
+msgstr ""
+
+#: ../src/utils/pacat.c:952
+#, c-format
+msgid "Unknown file format %s."
+msgstr ""
+
+#: ../src/utils/pacat.c:971
+msgid "Invalid sample specification"
+msgstr ""
+
+#: ../src/utils/pacat.c:981
+#, c-format
+msgid "open(): %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:986
+#, c-format
+msgid "dup2(): %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:993
+msgid "Too many arguments."
+msgstr ""
+
+#: ../src/utils/pacat.c:1004
+msgid "Failed to generate sample specification for file."
+msgstr ""
+
+#: ../src/utils/pacat.c:1030
+msgid "Failed to open audio file."
+msgstr ""
+
+#: ../src/utils/pacat.c:1036
+msgid ""
+"Warning: specified sample specification will be overwritten with "
+"specification from file."
+msgstr ""
+
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
+msgid "Failed to determine sample specification from file."
+msgstr ""
+
+#: ../src/utils/pacat.c:1048
+msgid "Warning: Failed to determine channel map from file."
+msgstr ""
+
+#: ../src/utils/pacat.c:1059
+msgid "Channel map doesn't match sample specification"
+msgstr ""
+
+#: ../src/utils/pacat.c:1070
+msgid "Warning: failed to write channel map to file."
+msgstr ""
+
+#: ../src/utils/pacat.c:1085
+#, c-format
+msgid ""
+"Opening a %s stream with sample specification '%s' and channel map '%s'."
+msgstr ""
+
+#: ../src/utils/pacat.c:1086
+msgid "recording"
+msgstr "מקליט"
+
+#: ../src/utils/pacat.c:1086
+msgid "playback"
+msgstr "נגינה"
+
+#: ../src/utils/pacat.c:1110
+msgid "Failed to set media name."
+msgstr ""
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
+msgid "pa_mainloop_new() failed."
+msgstr ""
+
+#: ../src/utils/pacat.c:1136
+msgid "io_new() failed."
+msgstr ""
+
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
+msgid "pa_context_new() failed."
+msgstr ""
+
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
+#, c-format
+msgid "pa_context_connect() failed: %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:1157
+msgid "pa_context_rttime_new() failed."
+msgstr ""
+
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
+msgid "pa_mainloop_run() failed."
+msgstr ""
+
+#: ../src/utils/pasuspender.c:79
+#, c-format
+msgid "fork(): %s\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:90
+#, c-format
+msgid "execvp(): %s\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:107
+#, c-format
+msgid "Failure to suspend: %s\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:122
+#, c-format
+msgid "Failure to resume: %s\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:145
+#, c-format
+msgid "WARNING: Sound server is not local, not suspending.\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:157
+#, c-format
+msgid "Connection failure: %s\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:174
+#, c-format
+msgid "Got SIGINT, exiting.\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:192
+#, c-format
+msgid "WARNING: Child process terminated by signal %u\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:210
+#, c-format
+msgid ""
+"%s [options] ... \n"
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:248
+#, c-format
+msgid ""
+"pasuspender %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:277
+#, c-format
+msgid "pa_mainloop_new() failed.\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:290
+#, c-format
+msgid "pa_context_new() failed.\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:298
+#, c-format
+msgid "pa_mainloop_run() failed.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:150
+#, c-format
+msgid "Failed to get statistics: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:156
+#, c-format
+msgid "Currently in use: %u blocks containing %s bytes total.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:159
+#, c-format
+msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:162
+#, c-format
+msgid "Sample cache size: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:171
+#, c-format
+msgid "Failed to get server information: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:176
+#, c-format
+msgid ""
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, c-format
+msgid ""
+"User Name: %s\n"
+"Host Name: %s\n"
+"Server Name: %s\n"
+"Server Version: %s\n"
+"Default Sample Specification: %s\n"
+"Default Channel Map: %s\n"
+"Default Sink: %s\n"
+"Default Source: %s\n"
+"Cookie: %04x:%04x\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
+#, c-format
+msgid "Failed to get sink information: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:270
+#, c-format
+msgid ""
+"Sink #%u\n"
+"\tState: %s\n"
+"\tName: %s\n"
+"\tDescription: %s\n"
+"\tDriver: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tOwner Module: %u\n"
+"\tMute: %s\n"
+"\tVolume: %s%s%s\n"
+"\t        balance %0.2f\n"
+"\tBase Volume: %s%s%s\n"
+"\tMonitor Source: %s\n"
+"\tLatency: %0.0f usec, configured %0.0f usec\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
+#, c-format
+msgid "\tPorts:\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
+#, c-format
+msgid "\tActive Port: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, c-format
+msgid "\tFormats:\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
+#, c-format
+msgid "Failed to get source information: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:383
+#, c-format
+msgid ""
+"Source #%u\n"
+"\tState: %s\n"
+"\tName: %s\n"
+"\tDescription: %s\n"
+"\tDriver: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tOwner Module: %u\n"
+"\tMute: %s\n"
+"\tVolume: %s%s%s\n"
+"\t        balance %0.2f\n"
+"\tBase Volume: %s%s%s\n"
+"\tMonitor of Sink: %s\n"
+"\tLatency: %0.0f usec, configured %0.0f usec\n"
+"\tFlags: %s%s%s%s%s%s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
+msgid "n/a"
+msgstr "לא זמין"
+
+#: ../src/utils/pactl.c:454
+#, c-format
+msgid "Failed to get module information: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:477
+#, c-format
+msgid ""
+"Module #%u\n"
+"\tName: %s\n"
+"\tArgument: %s\n"
+"\tUsage counter: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:496
+#, c-format
+msgid "Failed to get client information: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:522
+#, c-format
+msgid ""
+"Client #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:539
+#, c-format
+msgid "Failed to get card information: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:562
+#, c-format
+msgid ""
+"Card #%u\n"
+"\tName: %s\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:576
+#, c-format
+msgid "\tProfiles:\n"
+msgstr "\tפרופילים:\n"
+
+#: ../src/utils/pactl.c:582
+#, c-format
+msgid "\tActive Profile: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
+#, c-format
+msgid "Failed to get sink input information: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:622
+#, c-format
+msgid ""
+"Sink Input #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tClient: %s\n"
+"\tSink: %u\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
+"\tBuffer Latency: %0.0f usec\n"
+"\tSink Latency: %0.0f usec\n"
+"\tResample method: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
+#, c-format
+msgid "Failed to get source output information: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:693
+#, c-format
+msgid ""
+"Source Output #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tClient: %s\n"
+"\tSource: %u\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
+"\tBuffer Latency: %0.0f usec\n"
+"\tSource Latency: %0.0f usec\n"
+"\tResample method: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:734
+#, c-format
+msgid "Failed to get sample information: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:761
+#, c-format
+msgid ""
+"Sample #%u\n"
+"\tName: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
+"\tDuration: %0.1fs\n"
+"\tSize: %s\n"
+"\tLazy: %s\n"
+"\tFilename: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
+#, c-format
+msgid "Failure: %s"
+msgstr "כשל: %s"
+
+#: ../src/utils/pactl.c:915
+#, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:954
+#, c-format
+msgid "Failed to upload sample: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:971
+msgid "Premature end of file"
+msgstr ""
+
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+msgid "server"
+msgstr ""
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
+msgid "Got SIGINT, exiting."
+msgstr ""
+
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr ""
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, c-format
+msgid ""
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1380
+#, c-format
+msgid ""
+"pactl %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
+msgid "Please specify a sample file to load"
+msgstr ""
+
+#: ../src/utils/pactl.c:1462
+msgid "Failed to open sound file."
+msgstr ""
+
+#: ../src/utils/pactl.c:1474
+msgid "Warning: Failed to determine sample specification from file."
+msgstr ""
+
+#: ../src/utils/pactl.c:1484
+msgid "You have to specify a sample name to play"
+msgstr ""
+
+#: ../src/utils/pactl.c:1496
+msgid "You have to specify a sample name to remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1505
+msgid "You have to specify a sink input index and a sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1515
+msgid "You have to specify a source output index and a source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1530
+msgid "You have to specify a module name and arguments."
+msgstr ""
+
+#: ../src/utils/pactl.c:1550
+msgid "You have to specify a module index"
+msgstr ""
+
+#: ../src/utils/pactl.c:1560
+msgid ""
+"You may not specify more than one sink. You have to specify a boolean value."
+msgstr ""
+
+#: ../src/utils/pactl.c:1573
+msgid ""
+"You may not specify more than one source. You have to specify a boolean "
+"value."
+msgstr ""
+
+#: ../src/utils/pactl.c:1585
+msgid "You have to specify a card name/index and a profile name"
+msgstr ""
+
+#: ../src/utils/pactl.c:1596
+msgid "You have to specify a sink name/index and a port name"
+msgstr ""
+
+#: ../src/utils/pactl.c:1607
+msgid "You have to specify a source name/index and a port name"
+msgstr ""
+
+#: ../src/utils/pactl.c:1618
+msgid "You have to specify a sink name/index and a volume"
+msgstr ""
+
+#: ../src/utils/pactl.c:1631
+msgid "You have to specify a source name/index and a volume"
+msgstr ""
+
+#: ../src/utils/pactl.c:1644
+msgid "You have to specify a sink input index and a volume"
+msgstr ""
+
+#: ../src/utils/pactl.c:1649
+msgid "Invalid sink input index"
+msgstr ""
+
+#: ../src/utils/pactl.c:1660
+msgid "You have to specify a source output index and a volume"
+msgstr ""
+
+#: ../src/utils/pactl.c:1665
+msgid "Invalid source output index"
+msgstr ""
+
+#: ../src/utils/pactl.c:1677
+msgid "You have to specify a sink name/index and a mute boolean"
+msgstr ""
+
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+msgid "Invalid mute specification"
+msgstr ""
+
+#: ../src/utils/pactl.c:1694
+msgid "You have to specify a source name/index and a mute boolean"
+msgstr ""
+
+#: ../src/utils/pactl.c:1711
+msgid "You have to specify a sink input index and a mute boolean"
+msgstr ""
+
+#: ../src/utils/pactl.c:1716
+msgid "Invalid sink input index specification"
+msgstr ""
+
+#: ../src/utils/pactl.c:1732
+msgid "You have to specify a source output index and a mute boolean"
+msgstr ""
+
+#: ../src/utils/pactl.c:1737
+msgid "Invalid source output index specification"
+msgstr ""
+
+#: ../src/utils/pactl.c:1756
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr ""
+
+#: ../src/utils/pactl.c:1772
+msgid "No valid command specified."
+msgstr ""
+
+#: ../src/utils/pax11publish.c:61
+#, c-format
+msgid ""
+"%s [-D display] [-S server] [-O sink] [-I source] [-c file]  [-d|-e|-i|-r]\n"
+"\n"
+" -d    Show current PulseAudio data attached to X11 display (default)\n"
+" -e    Export local PulseAudio data to X11 display\n"
+" -i    Import PulseAudio data from X11 display to local environment "
+"variables and cookie file.\n"
+" -r    Remove PulseAudio data from X11 display\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:94
+#, c-format
+msgid "Failed to parse command line.\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:113
+#, c-format
+msgid "Server: %s\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:115
+#, c-format
+msgid "Source: %s\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:117
+#, c-format
+msgid "Sink: %s\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:119
+#, c-format
+msgid "Cookie: %s\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:137
+#, c-format
+msgid "Failed to parse cookie data\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:142
+#, c-format
+msgid "Failed to save cookie data\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:157
+#, c-format
+msgid "Failed to load client configuration file.\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:162
+#, c-format
+msgid "Failed to read environment configuration data.\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:179
+#, c-format
+msgid "Failed to get FQDN.\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:199
+#, c-format
+msgid "Failed to load cookie data\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:217
+#, c-format
+msgid "Not yet implemented.\n"
+msgstr ""
+
+#: ../src/utils/pacmd.c:66
+msgid "No PulseAudio daemon running, or not running as session daemon."
+msgstr ""
+
+#: ../src/utils/pacmd.c:71
+#, c-format
+msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
+msgstr ""
+
+#: ../src/utils/pacmd.c:88
+#, c-format
+msgid "connect(): %s"
+msgstr ""
+
+#: ../src/utils/pacmd.c:96
+msgid "Failed to kill PulseAudio daemon."
+msgstr ""
+
+#: ../src/utils/pacmd.c:104
+msgid "Daemon not responding."
+msgstr ""
+
+#: ../src/utils/pacmd.c:184
+#, c-format
+msgid "poll(): %s"
+msgstr ""
+
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
+#, c-format
+msgid "read(): %s"
+msgstr ""
+
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
+#, c-format
+msgid "write(): %s"
+msgstr ""
+
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
+msgid "Cannot access autospawn lock."
+msgstr ""
+
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
+#, 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:519 ../src/modules/alsa/alsa-source.c:672
+#, 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 ""
+
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
+msgid "Off"
+msgstr "מכובה"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
+msgid "High Fidelity Playback (A2DP)"
+msgstr ""
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
+msgid "High Fidelity Capture (A2DP)"
+msgstr ""
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
+msgid "Telephony Duplex (HSP/HFP)"
+msgstr ""
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
+#: ../src/modules/reserve-wrap.c:151
+msgid "PulseAudio Sound Server"
+msgstr "שרת הקול PulseAudio"
+
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
+msgid "Output Devices"
+msgstr "התקני פלט"
+
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
+msgid "Input Devices"
+msgstr "התקני קלט"
+
+#: ../src/modules/module-rygel-media-server.c:1056
+msgid "Audio on @HOSTNAME@"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2219
+msgid "Input"
+msgstr "פלט"
+
+#: ../src/modules/alsa/alsa-mixer.c:2220
+msgid "Docking Station Input"
+msgstr "קלט של תחנת עגינה"
+
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
+msgid "Docking Station Microphone"
+msgstr "מיקרופון של תחנת עגינה"
+
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "קלט של תחנת עגינה"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "קו נכנס"
+
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
+msgid "Microphone"
+msgstr "מיקרופון"
+
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "מיקרופון של תחנת עגינה"
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "מיקרופון"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "מיקרופון חיצוני"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
+msgid "Internal Microphone"
+msgstr "מיקרופון פנימי"
+
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
+msgid "Radio"
+msgstr "רדיו"
+
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
+msgid "Video"
+msgstr "וידאו"
+
+#: ../src/modules/alsa/alsa-mixer.c:2231
+msgid "Automatic Gain Control"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2232
+msgid "No Automatic Gain Control"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2233
+msgid "Boost"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2234
+msgid "No Boost"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2235
+msgid "Amplifier"
+msgstr "מגבר"
+
+#: ../src/modules/alsa/alsa-mixer.c:2236
+msgid "No Amplifier"
+msgstr "אין מגבר"
+
+#: ../src/modules/alsa/alsa-mixer.c:2237
+msgid "Bass Boost"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2238
+msgid "No Bass Boost"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "אוזניות אנלוגיות"
+
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "קלט אנלוגי"
+
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "מיקרופון של תחנת עגינה"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
+msgid "Analog Output"
+msgstr "פלט אנלוגי"
+
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "פלט אנלוגי (LFE)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "קו נכנס"
+
+#: ../src/modules/alsa/alsa-mixer.c:2314
+msgid "Analog Mono Output"
+msgstr "פלט מונו אנלוגי"
+
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "סטראו אנלוגי"
+
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "סטראו דיגיטלי (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "סטראו דיגיטלי (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3756
+msgid "Analog Mono"
+msgstr "מונו אנלוגי"
+
+#: ../src/modules/alsa/alsa-mixer.c:3757
+msgid "Analog Stereo"
+msgstr "סטראו אנלוגי"
+
+#: ../src/modules/alsa/alsa-mixer.c:3758
+msgid "Analog Surround 2.1"
+msgstr "סראונד אנלוגי 2.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3759
+msgid "Analog Surround 3.0"
+msgstr "סראונד אנלוגי 3.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:3760
+msgid "Analog Surround 3.1"
+msgstr "סראונד אנלוגי 3.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3761
+msgid "Analog Surround 4.0"
+msgstr "סראונד אנלוגי 4.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:3762
+msgid "Analog Surround 4.1"
+msgstr "סראונד אנלוגי 4.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3763
+msgid "Analog Surround 5.0"
+msgstr "סראונד אנלוגי 5.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:3764
+msgid "Analog Surround 5.1"
+msgstr "סראונד אנלוגי 5.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3765
+msgid "Analog Surround 6.0"
+msgstr "סראונד אנלוגי 6.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:3766
+msgid "Analog Surround 6.1"
+msgstr "סראונד אנלוגי 6.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3767
+msgid "Analog Surround 7.0"
+msgstr "סראונד אנלוגי 7.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:3768
+msgid "Analog Surround 7.1"
+msgstr "סראונד אנלוגי 7.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3769
+msgid "Digital Stereo (IEC958)"
+msgstr "סטראו דיגיטלי (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "סטראו דיגיטלי (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3771
+msgid "Digital Surround 4.0 (IEC958/AC3)"
+msgstr "סראונד דיגיטלי 4.0 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3772
+msgid "Digital Surround 5.1 (IEC958/AC3)"
+msgstr "סראונד דיגיטלי 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3773
+msgid "Digital Stereo (HDMI)"
+msgstr "סטראו דיגיטלי (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "סראונד דיגיטלי 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
+msgid "Analog Mono Duplex"
+msgstr "מונו אנלוגי משולב"
+
+#: ../src/modules/alsa/alsa-mixer.c:3896
+msgid "Analog Stereo Duplex"
+msgstr "סטראו אנלוגי משולב"
+
+#: ../src/modules/alsa/alsa-mixer.c:3897
+msgid "Digital Stereo Duplex (IEC958)"
+msgstr "סטראו דיגיטלי משולב (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "פלט אנלוגי"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "פלט"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "סראונד דיגיטלי 4.0 (IEC958)"
index 2e313ba..644c9ac 100644 (file)
--- a/po/hi.po
+++ b/po/hi.po
@@ -1,16 +1,17 @@
 # translation of pulseaudio.master-tx.po to Hindi
 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the PACKAGE package.
+# Rajesh Ranjan <rajesh672@gmail.com>, 2009, 2012.
 #
-# Rajesh Ranjan <rajesh672@gmail.com>, 2009.
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-09-21 16:29+0530\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:54+0000\n"
 "Last-Translator: Rajesh Ranjan <rajesh672@gmail.com>\n"
 "Language-Team: Hindi <hindi.sf.net>\n"
+"Language: hi\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -22,13 +23,9 @@ msgstr ""
 "\n"
 "\n"
 "\n"
+"\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -40,11 +37,11 @@ msgstr ""
 "अधिक संभव है कि यह ALSA ड्राइवर '%s' में एक बग है. इस मुद्दे को ALSA डेवलेपर को रिपोर्ट "
 "करें."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
@@ -52,7 +49,19 @@ msgstr ""
 "अधिक संभव है कि यह ALSA ड्राइवर '%s' में एक बग है. इस मुद्दे को ALSA डेवलेपर को रिपोर्ट "
 "करें."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() ने एक मान दिया जो अप्रत्याशित रूप से बड़ा है: %lu बाइट (%lu ms).\n"
+"अधिक संभव है कि यह ALSA ड्राइवर '%s' में एक बग है. इस मुद्दे को ALSA डेवलेपर को रिपोर्ट "
+"करें."
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -65,301 +74,331 @@ msgstr ""
 "अधिक संभव है कि यह ALSA ड्राइवर '%s' में एक बग है. इस मुद्दे को ALSA डेवलेपर को रिपोर्ट "
 "करें."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "हमेशा कम से मक एक सिंक को लोडेड रखें हालांकि यह एक रिक्त है"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "डमी आउटपुट"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "वर्चुअल LADSPA सिंक"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<name for the sink> sink_properties=<properties for the sink> "
 "master=<name of sink to filter> format=<sample format> rate=<sample rate> "
 "channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
+"plugin name> label=<ladspa plugin label> control=<comma separated list of "
 "input control values>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "क्लॉक्ड रिक्त सिंक"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "रिक्त आउटपुट"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "आंतरिक ऑडियो"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "मॉडेम"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "मौलिक ltdlopen लोडर ढूँढ़ने में विफल (_d)."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "नया dl लोडर आबंटित करने में विफल."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "bind-now-loader जोड़ने में विफल."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "%s संकेत पाया."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "बाहर हो रहा है."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "'%s' उपयोक्ता ढूंढ़ने में विफल."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "'%s' समूह ढूंढ़ने में विफल."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "'%s' (UID %lu) उपयोक्ता व '%s' (GID %lu) समूह पाया."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "'%s' उपयोक्ता और '%s' समूह का GID मेल नहीं खाता है"
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "'%s' उपयोक्ता की घर निर्देशिका '%s' नहीं है, अनदेखा कर रहा है."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "'%s' बनाने में विफल: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "समूह सूची पाने में विफल: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "GID बदलने में विफल: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "UID बदलने में विफल: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "रूट अधिकार सफलतापूर्वक छोड़ा."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "इस प्लैटफॉर्म पर असमर्थित तंत्र व्यापक विधि."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) विफल: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "कमांड लाइन विश्लेषण में विफल."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "डेमॉन नहीं कार्यशील"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "डेमॉन बतौर PID %u चल रहा है"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "डेमॉन हटाने में विफल: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
 msgstr ""
 "यह प्रोग्राम बतौर रूट चलाने के लिए इच्छित नहीं है (unless --system is specified)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "रूट अधिकार जरूरी."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start not supported for system instances."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "तंत्र मोड में चल रहा है, लेकिन --disallow-exit सेट नहीं!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr "तंत्र मोड में चल रहा है, लेकिन --disallow-module-loading सेट नहीं!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "तंत्र मोड में चल रहा है, SHM मोड बाध्य रूप से निष्क्रिय!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr "तंत्र मोड में चल रहा है, निकास निष्क्रिय समय बाध्य रूप से निष्क्रिय!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "stdio पाने में विफल."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "पाइप विफल: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() विफल: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() विफल: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "डेमॉन आरंभ विफल."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "डेमॉन आरंभ सफल."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() विफल: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "यह पल्सऑडियो %s है."
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Compilation host: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "Compilation CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "मेजबान पर चल रहा है: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "%u CPU पाया."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "पृष्ठ आकार %lu बाइट है."
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "वेलग्रिंड समर्थन से कंपाइल: हाँ"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "वेलग्रिंड समर्थन से कंपाइल: नहीं"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "वेलग्रिंड विधि में चल रहा है: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "मेजबान पर चल रहा है: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "अनुकूलित बिल्ड: हाँ"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "अनुकूलित बिल्ड: नहीं"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG परिभाषित, सभी निष्क्रिय."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH परिभाषित, केव तेज पथ एसर्ट निष्क्रिय."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "सभी एसर्ट सक्षम."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "मशीन ID पाने में विफल"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "मशीन ID %s है."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "सत्र ID %s है."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "रनटाइम निर्देशिका %s का प्रयोग कर रहा है."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "स्टेट निर्देशिका %s का प्रयोग कर रहा है."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "मॉड्यूल निर्देशिका %s का प्रयोग कर रहा है."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "तंत्र मोड में चल रहा है: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -373,47 +412,47 @@ msgstr ""
 "कृपया http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode को पढ़ें जानने के लिए "
 "कि क्यों तंत्र मोड एक बढ़िया विचार नहीं है."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() विफल."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "ताज़ा उच्च विभेदन टाइमर उपलब्ध! आनंद लें!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
 msgstr ""
 "आपका कर्नेल बुरी स्थिति में है! सलाह है कि उच्च विभेदन युक्त लिनक्स सक्रिय किया जाना चाहिए!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() विफल."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "डेमॉन आरंभ करने में विफल."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "बिना लोड मॉड्यूल के डेमॉन आरंभ, काम करने से अस्वीकार कर रहा है."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "डेमॉन आरंभन पूर्ण."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "डेमॉन बन्द किया जाना आरंभ."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "डेमॉन अवरोधित."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -450,15 +489,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -555,15 +592,15 @@ msgstr ""
 "\n"
 "  -n                                    Don't load default script file\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize के लिए बुलियन तर्क की आशा है"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail के लिए बुलियन तर्क की आशा है"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -571,166 +608,169 @@ msgstr ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority के लिए बुलियन तर्क की आशा है"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime के लिए बुलियन तर्क की आशा है"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading के लिए बुलियन तर्क की आशा है"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit के लिए बुलियन तर्क की आशा है"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file के लिए बुलियन तर्क की आशा है"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr "अवैध लॉग लक्ष्य: use either 'syslog', 'stderr' or 'auto'."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time के लिए बुलियन तर्क की आशा है"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta के लिए बुलियन तर्क की आशा है"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "अवैध पुनः प्रतिदर्श विधि '%s'."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system के लिए बुलियन तर्क की आशा है"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit के लिए बुलियन तर्क की आशा है"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm के लिए बुलियन तर्क की आशा है"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "नाम: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "कोई मॉड्यूल सूचना उपलब्ध नहीं\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "संस्करण: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "विवरण: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "लेखक: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "उपयोग: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "एक बार लोड करें: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "अवमूल्यन चेतावनी: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "पथ: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] अवैध लॉग लक्ष्य '%s'."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] अवैध लॉग स्तर '%s'."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] अवैध पुनः नमूना विधि '%s'."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] अवैध rlimit '%s'."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit इस प्लेटफॉर्म पर समर्थित नहीं."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] अवैध प्रतिदर्श प्रारूप '%s'."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] अवैध प्रतिदर्श दर '%s'."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] अवैध प्रतिदर्श चैनल '%s'."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] अवैध चैनल मानचित्र '%s'."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] टुकड़े '%s' की अवैध संख्या."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] अवैध खंड आकार '%s'."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] अवैध नाइस स्तर '%s'."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] अवैध प्रतिदर्श दर '%s'."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "विन्यास फ़ाइल खोलने में विफल: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -738,12 +778,12 @@ msgstr ""
 "निर्दिष्ट तयशुदा चैनल मानचित्र के पास चैनल की भिन्न संख्या है चैनल की तयशुदा निर्दिष्ट संख्या "
 "के बनिस्पत."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### विन्यास फ़ाइल से पढ़ें: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "अधिकार छोड़ रहा है."
 
@@ -755,6 +795,16 @@ msgstr "पल्सऑडियो ध्वनि तंत्र"
 msgid "Start the PulseAudio Sound System"
 msgstr "पल्सऑडियो ध्वनि तंत्र प्रारंभ करें"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "पल्सऑडियो ध्वनि तंत्र"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "पल्सऑडियो ध्वनि तंत्र प्रारंभ करें"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "मोनो"
@@ -784,8 +834,8 @@ msgid "Rear Right"
 msgstr "पश्च दाहिना"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "निम्न आवृत्ति निकासकर्ता"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -959,9 +1009,10 @@ msgstr "ऊपर पश्च बायाँ"
 msgid "Top Rear Right"
 msgstr "ऊपर पश्च दायाँ"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(अवैध)"
 
@@ -989,332 +1040,349 @@ msgstr "सर्राउंड 5.1"
 msgid "Surround 7.1"
 msgstr "सर्राउंड 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "ठीक"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "पहुँच मनाही"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "अनजान कमांड"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "अवैध तर्क"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "एंटिटी मौजूद"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "कोई ऐसी एंटिटी नहीं"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "कनेक्शन अस्वीकृत"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "प्रोटोकाल त्रुटि"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "समय ख़त्म"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "कोई प्राधिकरण कुंजी नहीं"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "आंतरिक त्रुटि"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "कनेक्शन समाप्त"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "एंटिटी मृत"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "अवैध सर्वर"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "मॉडयूल आरंभीकरण असफल"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "बुरी स्थिति"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "कोई आँकड़ा नहीं"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "बेमेल प्रोटोकॉल संस्करण"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "काफी बड़ा"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "समर्थित नहीं है"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "अज्ञात त्रुटि कोड"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "कोई ऐसा विस्तार नहीं"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "पुरानी प्रकार्यात्मकता"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "अनुपस्थित कार्यान्वयन"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "क्लाएंट विभाजित"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "इनपुट/आउटपुट त्रुटि"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "युक्ति या संसाधन व्यस्त"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() विफल"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() विफल: %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "कुकी आंकड़ा के विश्लेषण में विफल"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "विन्यास फ़ाइल '%s' खोलने में विफल: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "कोई कुकी नहीं लोड किया गया. इसके बिना कनेक्ट करने की कोशिश कर रहा हूँ."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "अज्ञात विस्तार '%s' के लिए संदेश प्राप्त"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "स्ट्रीम से खींचने में विफल: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "प्लेबैक स्ट्रीम खत्म."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "सर्वर में कनेक्शन ले जा रहा है."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() विफल: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_begin_write() विफल: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() विफल: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "स्ट्रीम सफलतापूर्वक निर्मित."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() विफल: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, 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:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "बफ़र मेट्रिक्स: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "नमूना स्पेक '%s' का प्रयोग, चैनल मैप '%s'."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "युक्ति %s (%u, %ssuspended) से कनेक्टेड."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "स्ट्रीम त्रुटि: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "स्ट्रीम युक्ति स्थगित.%s "
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "स्ट्रीम युक्ति पुनर्बहाल.%s "
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "स्ट्रीम अंडररन.%s "
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "स्ट्रीम ओवररन.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "स्ट्रीम आरंभ.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "स्ट्रीम युक्ति %s (%u, %ssuspended).%s में खिसकाया गया"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "नहीं "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "स्ट्रीम बफ़र गुण परिवर्तित.%s "
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "कनेक्शन स्थापित.%s "
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() विफल: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() विफल: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() विफल: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "कनेक्शन विफल.%s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "EOF पाया."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() विफल: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "संकेत पाया, निकल रहा है."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "लेटेंसी पाने में विफल: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "समय: %0.3f सेकेंड; लैटेंसी: %0.0f usec."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() विफल: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1366,10 +1434,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [options]\n"
@@ -1428,7 +1501,7 @@ msgstr ""
 "      --file-format=FFORMAT             Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1439,169 +1512,174 @@ msgstr ""
 "लिबपल्स %s के साथ कंपाइल\n"
 "लिबपल्स %s के साथ लिंक\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "अवैध क्लाइंट नाम '%s'"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "अवैध स्ट्रीम नाम '%s'"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "अवैध चैनल मानचित्र '%s'"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "अवैध लैटेंसी विनिर्दिष्टता '%s'"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "अवैध प्रक्रिया समय विनिर्दिष्टता '%s'"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "अवैध गुण '%s'"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "अज्ञात फ़ाइल प्रारूप %s."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "अवैध नमूना विनिर्दिष्टता"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "कई वितर्क."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "फ़ाइल के लिए नमूना विनिर्दिष्टता पाने में विफल."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "ध्वनि फ़ाइल खोलने में विफल."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
 msgstr "चेतावनी: निर्दिष्ट नमूना विनिर्दिष्टता को फ़ाइल की विनिर्दिष्टता से लिखा जाएगा."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "फ़ाइल से नमूना विनिर्दिष्टता निर्धारित करने में विफल."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "चेतावनी: फ़ाइल से चैनल मैप पाने में विफल."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "चैनल मैप नमूना विनिर्दिष्टता से मेल नहीं खाता है"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "चेतावनी: फ़ाइल में चैनल मैप लिखने में विफल."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr "किसी %s स्ट्रीम को किसी नमूना विनिर्दिष्ता '%s' और चैनल मैप '%s' से खोल रहा है."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "रिकार्डिंग"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "प्लेबैक"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "कमांड लाइन विश्लेषण में विफल."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() विफल."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() विफल."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() विफल."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() विफल: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_rttime_new() विफल."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() विफल."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "स्थगन में विफल: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "पुनर्बहाली में विफल: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "चेतावनी: ध्वनि सर्वर स्थानीय नहीं है, स्थगित नहीं कर रहा है.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "कनेक्शन विफल.%s \n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "SIGINT पाया, निकल रहा है.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "चेतावनी: संतति प्रक्रिया %u संकेत से रूका\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1646,35 +1724,46 @@ msgstr "pa_context_new() विफल.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() विफल.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "आंकड़े पाने में विफल: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "प्रयोग में मुद्रा: %u ब्लॉक %s बाइट कुल समाहित करता है.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "संपूर्ण जीवनचक्र के दौरान आबंटित: %u ब्लॉक %s बाइट कुल को समाहित करता है.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "नमूना कैश आकार: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "सर्वर सूचना पाने में विफल: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1682,7 +1771,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "उपयोक्ता नाम: %s\n"
 "मेजबान नाम: %s\n"
@@ -1694,13 +1783,13 @@ msgstr ""
 "तयशुदा स्रोत: %s\n"
 "कुकी: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "सिंक सूचना पाने में विफल: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1716,7 +1805,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1738,22 +1827,27 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tPorts:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tActive Port: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tPorts:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "स्रोत सूचना पाने में विफल: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1792,20 +1886,20 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "n/a"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "मॉड्यूल सूचना पाने में विफल: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1822,12 +1916,12 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "क्लाइंट सूचना पाने में विफल: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1842,12 +1936,12 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "कार्ड सूचना पाने में विफल: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1864,23 +1958,23 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tProfiles:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tActive Profile: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "सिंक इनपुट सूचना पाने में विफल: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1889,6 +1983,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1916,13 +2011,13 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "स्रोत आउटपुट सूचना पाने में विफल: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1931,31 +2026,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Source Output #%u\n"
+"Sink Input #%u\n"
 "\tDriver: %s\n"
 "\tOwner Module: %s\n"
 "\tClient: %s\n"
-"\tSource: %u\n"
+"\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
-"\tSource Latency: %0.0f usec\n"
+"\tSink Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "नमूना सूचना पाने में विफल: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1986,48 +2090,163 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "विफलता: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "स्रोत सूचना पाने में विफल: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "नमूना अफलोड करने में विफल: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "फ़ाइल का असामयिक अंत"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "अवैध सर्वर"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "SIGINT पाया, निकल रहा है."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "अवैध आयतन विनिर्दिष्टता"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2037,37 +2256,15 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+"%s [options] ... \n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
-"\n"
 "  -s, --server=SERVER                   The name of the server to connect "
 "to\n"
-"  -n, --client-name=NAME                How to call this client on the "
-"server\n"
+"\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2078,49 +2275,54 @@ msgstr ""
 "लिबपल्स %s से कंपाइल\n"
 "लिबपल्स %s से कड़ीबद्ध\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "लोड करने के लिए किसी नमूना फ़ाइल निर्दिष्ट करें"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "ध्वनि फ़ाइल खोलने में विफल."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "%s स्ट्रीम को किसी नमूना विनिर्दिष्टता '%s' के साथ खोल रहा है."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "आपको किसी नमूना नाम को बजाने के लिए निर्दिष्ट करना है"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "आपको किसी नमूना नाम को हटाने के लिए निर्दिष्ट करना है"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "आपको किसी सिंक इनपुट सूची और सिंक को निर्दिष्ट करना है"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "आपको किसी सिंक स्रोत आउटपुट और स्रोत को निर्दिष्ट करना है"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "आपको किसी मॉड्यूल नाम और वितर्क को निर्दिष्ट करना है"
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "आपको किसी मॉड्यूल सूची को निर्दिष्ट करना है"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "आप एक सिंक से अधिक निर्दिष्ट नहीं कर सकते हैं. आपको किसी बुलियन मान को निर्दिष्ट करना है."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
@@ -2128,57 +2330,84 @@ msgstr ""
 "आप एक स्रोत से अधिक निर्दिष्ट नहीं कर सकते हैं. आपको किसी बुलियन मान को निर्दिष्ट करना "
 "है."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "आपको किसी कार्ड नाम/सूची और प्रोफ़ाइल नाम को निर्दिष्ट करना है."
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "आपको किसी कार्ड नाम/सूची और पोर्ट नाम को निर्दिष्ट करना है."
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "आपको किसी स्रोत नाम/सूची और पोर्ट नाम को निर्दिष्ट करना है."
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "आपको किसी सिंक नाम/सूची और वाल्यूम को निर्दिष्ट करना है."
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "अवैध आयतन विनिर्दिष्टता"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "आपको किसी स्रोत नाम/सूची और आयतन को निर्दिष्ट करना है."
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "आपने किसी सिंक इनपुट सूची और आयतन को निर्दिष्ट किया है"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "अवैध सिंक इनपुट सूची"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "आपको किसी सिंक स्रोत आउटपुट और स्रोत को निर्दिष्ट करना है"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "अवैध सिंक इनपुट सूची"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "आपको किसी कार्ड नाम/सूची और मूक बुलियन नाम को निर्दिष्ट करना है."
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "अवैध नमूना विनिर्दिष्टता"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "आपको किसी स्रोत नाम/सूची और मूल बुलियन को निर्दिष्ट करना है."
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "आपने किसी सिंक इनपुट सूची और मूल बुलियन को निर्दिष्ट किया है"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "अवैध सिंक इनपुट सूची विनिर्दिष्टता"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "आपको किसी स्रोत नाम/सूची और मूल बुलियन को निर्दिष्ट करना है."
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "अवैध सिंक इनपुट सूची विनिर्दिष्टता"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "आपको किसी कार्ड नाम/सूची और मूक बुलियन नाम को निर्दिष्ट करना है."
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "कोई वैध कमांड निर्दिष्ट नहीं."
 
@@ -2206,103 +2435,103 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "कमांड लाइन के विश्लेषण में असमर्थ.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "सर्वर: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "स्रोत: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "सिंक: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "कुकी: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "कुकी आंकड़ा के विश्लेषण में विफल\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "कुकी आंकड़ा के सहेजने में विफल\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "क्लाइंट विन्यास फ़ाइल लोड करने में विफल\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "वातावरण विन्यास आंकड़ा को पढ़ने में विफल.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "FQDN पाने में विफल.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "कुकी आंकड़ा लोड करने में विफल\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "अभी तक कार्यान्वित नहीं.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr "कोई पल्सऑडियो डेमॉन चल रहा है, या चयन डेमॉन के तहत चल रहा है."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "PulseAudio डेमॉन को मारने में विफल."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "डेमॉन प्रतिक्रिया नहीं दे रहा है."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "autospawn लॉक की पहुँच नहीं ले सकता है."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2319,7 +2548,7 @@ msgstr ""
 "हमें POLLOUT सेट के साथ तैयार किया गया है  -- हालांकि परवर्ती snd_pcm_avail() ने 0 या "
 "दूसरा मान < min_avail दिया."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2336,242 +2565,465 @@ msgstr ""
 "हमें POLLIN सेट के साथ तैयार किया गया है  -- हालांकि परवर्ती snd_pcm_avail() ने 0 या "
 "दूसरा मान < min_avail दिया."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "बंद"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "उच्च विश्वसनीयतायुक्ति प्लेबैक (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "उच्च विश्वसनीयता कैप्चर (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "टेलिफोनी ड्यूप्लेक्स (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "पल्सऑडियो ध्वनि सर्वर"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
-msgstr ""
+msgstr "आउटपुट युक्ति"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
-msgstr ""
+msgstr "इनपुट युक्ति"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
-msgstr ""
+msgstr "@HOSTNAME@ पर ऑडियो"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
-msgstr ""
+msgstr "इनपुट"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
-msgstr ""
+msgstr "डॉकिंग स्टेशन इनपुट"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
-msgstr ""
+msgstr "डॉकिंग स्टेशन माइक्रोफोन"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "डॉकिंग स्टेशन इनपुट"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "लाइन इन"
+
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
-msgstr ""
+msgstr "माइक्रोफोन"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
-msgid "External Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "डॉकिंग स्टेशन माइक्रोफोन"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
 #, fuzzy
+msgid "Rear Microphone"
+msgstr "माइक्रोफोन"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "बाहरी माइक्रोफोन"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
-msgstr "à¤\86à¤\82तरिà¤\95 à¤\91डियà¥\8b"
+msgstr "à¤\86à¤\82तरिà¤\95 à¤®à¤¾à¤\87à¤\95à¥\8dरà¥\8bफà¥\8bन"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
-msgstr ""
+msgstr "रेडियो"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
-msgstr ""
+msgstr "वीडियो"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
-msgstr ""
+msgstr "स्वचालित प्राप्ति नियंत्रण"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
-msgstr ""
+msgstr "कोई स्वचालित प्राप्ति नियंत्रण नहीं"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
-msgstr ""
+msgstr "बूस्ट"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
-msgstr ""
+msgstr "कोई बढ़ावा नहीं"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
-msgstr ""
+msgstr "एंप्लीफायर"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
-msgstr ""
+msgstr "कोई एंप्लीफायर नहीं"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "बूस्ट"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "कोई बढ़ावा नहीं"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "एनालॉग हेडफोन"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "एनालॉग इनपुट"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "डॉकिंग स्टेशन माइक्रोफोन"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
-msgstr "रिà¤\95à¥\8dत आउटपुट"
+msgstr "à¤\8fनालà¥\89à¤\97 आउटपुट"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "एनालॉग आउटपुट (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "लाइन इन"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
+msgstr "एनालॉग एकल आउटपुट"
+
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "एनालॉग स्टीरियो"
+
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, fuzzy, c-format
-msgid "%s+%s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "डिजिटल सेटअप (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, fuzzy, c-format
-msgid "%s / %s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "डिजिटल सेटअप (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
-msgstr ""
+msgstr "एनालॉग मोनो"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
-msgstr "स्टीरियो"
+msgstr "à¤\8fनालà¥\89à¤\97 à¤¸à¥\8dà¤\9fà¥\80रियà¥\8b"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
-msgstr "सरà¥\8dराà¤\89à¤\82ड 4.1"
+msgstr "à¤\8fनालà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
-msgstr "सरà¥\8dराà¤\89à¤\82ड 4.0"
+msgstr "à¤\8fनालà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
-msgstr "सरà¥\8dराà¤\89à¤\82ड 4.1"
+msgstr "à¤\8fनालà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
-msgstr "सर्राउंड 4.0"
+msgstr "à¤\8fनालà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
-msgstr "सर्राउंड 4.1"
+msgstr "à¤\8fनालà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
-msgstr "सर्राउंड 5.0"
+msgstr "à¤\8fनालà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
-msgstr "सर्राउंड 5.1"
+msgstr "à¤\8fनालà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
-msgstr "सरà¥\8dराà¤\89à¤\82ड 4.0"
+msgstr "à¤\8fनालà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
-msgstr "सरà¥\8dराà¤\89à¤\82ड 4.1"
+msgstr "à¤\8fनालà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
-msgstr "सरà¥\8dराà¤\89à¤\82ड 4.0"
+msgstr "à¤\8fनालà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
-msgstr "सर्राउंड 7.1"
+msgstr "à¤\8fनालà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
-msgstr ""
+msgstr "डिजिटल स्टीरियो (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "डिजिटल स्टीरियो (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
-msgstr ""
+msgstr "डिजिटल सर्राउंड 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
-msgstr ""
+msgstr "डिजिटल सर्राउंड 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
-msgstr ""
+msgstr "डिजिटल सेटअप (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "डिजिटल सर्राउंड 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
-msgstr ""
+msgstr "एनालॉग एकल डुप्लेक्स"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
-msgstr ""
+msgstr "एनालॉग स्टीरियो डुप्लेक्स"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
+msgstr "डिजिटल स्टीरियो डुप्लेक्स (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "रिक्त आउटपुट"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "इनपुट"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
 msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<name for the sink> sink_properties=<properties for the sink> "
+"master=<name of sink to filter> format=<sample format> rate=<sample rate> "
+"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
+"plugin name> label=<ladspa plugin label> control=<comma separated list of "
+"input control values>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit इस प्लेटफॉर्म पर समर्थित नहीं."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() विफल"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "डिजिटल सर्राउंड 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "निम्न आवृत्ति निकासकर्ता"
index a6d059e..7a610e1 100644 (file)
--- a/po/hu.po
+++ b/po/hu.po
@@ -1,11 +1,15 @@
+#
+# KAMI <kami911@gmail.com>, 2012.
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-10-17 04:45+0000\n"
-"PO-Revision-Date: \n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:54+0000\n"
 "Last-Translator: KAMI <kami911@gmail.com>\n"
 "Language-Team: \n"
+"Language: \n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -14,369 +18,449 @@ msgstr ""
 "X-Poedit-SourceCharset: utf-8\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../src/modules/alsa/alsa-util.c:858
-#: ../src/pulsecore/sink.c:2629
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
-msgid "%s %s"
-msgstr "%s %s"
+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 ""
+"A „snd_pcm_avail()” függvény visszatérési értéke váratlanul nagy értékű: %lu "
+"bájt (%lu ms).\n"
+"Ez egy hiba lehet az ALSA „%s” eszközmeghajtóban. Kérem jelentse ezt a "
+"problémát az ALSA fejlesztői felé."
 
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1179
 #, 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."
+"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 ""
-"A „snd_pcm_avail()” függvény visszatérési értéke váratlanul nagy értékű: %lu bájt (%lu ms).\n"
-"Ez egy hiba lehet az ALSA „%s” eszközmeghajtóban. Kérem jelentse ezt a problémát az ALSA fejlesztői felé."
+"A „snd_pcm_delay()” függvény visszatérési értéke váratlanul nagy értékű: %li "
+"bájt (%s%lu ms).\n"
+"Ez egy hiba lehet az ALSA „%s” eszközmeghajtóban. Kérem jelentse ezt a "
+"problémát az ALSA fejlesztői felé."
 
-#: ../src/modules/alsa/alsa-util.c:1147
-#, c-format
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, 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."
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
 msgstr ""
-"A „snd_pcm_delay()” függvény visszatérési értéke váratlanul nagy értékű: %li bájt (%s%lu ms).\n"
-"Ez egy hiba lehet az ALSA „%s” eszközmeghajtóban. Kérem jelentse ezt a problémát az ALSA fejlesztői felé."
+"A „snd_pcm_avail()” függvény visszatérési értéke váratlanul nagy értékű: %lu "
+"bájt (%lu ms).\n"
+"Ez egy hiba lehet az ALSA „%s” eszközmeghajtóban. Kérem jelentse ezt a "
+"problémát az ALSA fejlesztői felé."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1263
 #, 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."
+"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 ""
-"A „snd_pcm_mmap_begin()” függvény visszatérési értéke váratlanul nagy értékű: %lu bájt (%lu ms).\n"
-"Ez egy hiba lehet az ALSA „%s” eszközmeghajtóban. Kérem jelentse ezt a problémát az ALSA fejlesztői felé."
+"A „snd_pcm_mmap_begin()” függvény visszatérési értéke váratlanul nagy "
+"értékű: %lu bájt (%lu ms).\n"
+"Ez egy hiba lehet az ALSA „%s” eszközmeghajtóban. Kérem jelentse ezt a "
+"problémát az ALSA fejlesztői felé."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "Mindig maradjon meg legalább egy nyelőt, még ha az csak az üres nyelő."
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "Látszólagos kimenet"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "Látszólagos LADSPA nyelő"
 
-#: ../src/modules/module-ladspa-sink.c:53
-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> channels=<number of channels> channel_map=<channel map> plugin=<ladspa plugin name> label=<ladspa plugin label> control=<comma seperated list of input control values>"
-msgstr "sink_name=<nyelő neve> sink_properties=<nyelő tulajdonságai> master=<szűrendő nyelő neve> format=<sample format> rate=<mintavételezési ráta> channels=<csatornák száma> channel_map=<csatornaleképzés> plugin=<ladspa bővítmény neve> label=<ladspa bővítmény címkéje> control=<bemenetszabályzó értékek vesszővel elválasztott listája>"
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
+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> "
+"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> "
+msgstr ""
+"sink_name=<nyelő neve> sink_properties=<nyelő tulajdonságai> "
+"master=<szűrendő nyelő neve> format=<sample format> rate=<mintavételezési "
+"ráta> channels=<csatornák száma> channel_map=<csatornaleképzés> "
+"plugin=<ladspa bővítmény neve> label=<ladspa bővítmény címkéje> "
+"control=<bemenetszabályzó értékek vesszővel elválasztott listája>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "Órajelezett semmis nyelő"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "Semmis kimenet"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "Belső hangforrás"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "Modem"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "Nem található az eredeti „lt_dlopen” betöltő."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "Nem foglalható le hely az új dl betöltő számára."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "Nem sikerült hozzáadni az azonnali betöltés csatolást."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "Szignál: %s."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "Kilépés."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "Nem található a(z) „%s” felhasználó."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "Nem található a(z) „%s” csoport."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "Létező felhasználó „%s” (UID: %lu) és csoport „%s” (GID: %lu)."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
-msgstr "A(z) „%s” felhasználó GID azonosítója és „%s” csoportja nem egyezik meg."
+msgstr ""
+"A(z) „%s” felhasználó GID azonosítója és „%s” csoportja nem egyezik meg."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "A(z) „%s” felhasználó Saját mappája nem „%s”. Kihagyás."
 
-#: ../src/daemon/main.c:208
-#: ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Nem sikerült létrehozni a(z) „%s” fájlt: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "Nem sikerült megváltoztatni a csoportlistát: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "Nem sikerült megváltoztatni az GID azonosítót: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "Nem sikerült megváltoztatni az UID azonosítót: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "A rendszergazdai jogosultságok sikeresen visszaadva."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "A rendszer üzemmód nem támogatott ezen az operációs rendszeren."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) meghiúsult: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "Nem sikerült feldolgozni a parancssort."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "A démon nem fut."
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "A démon a következő PID azonosítóval fut: %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "A démon kilövése nem sikerült: %s"
 
-#: ../src/daemon/main.c:571
-msgid "This program is not intended to be run as root (unless --system is specified)."
-msgstr "Ez a program nincsen felkészítve arra, hogy rendszergazdai jogosultságokkal fusson (kivéve, ha a --system paraméter megadásra kerül)."
+#: ../src/daemon/main.c:657
+msgid ""
+"This program is not intended to be run as root (unless --system is "
+"specified)."
+msgstr ""
+"Ez a program nincsen felkészítve arra, hogy rendszergazdai jogosultságokkal "
+"fusson (kivéve, ha a --system paraméter megadásra kerül)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "Rendszergazdai jogosultságok szükségesek."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start nem támogatott rendszer üzemmód használata esetén."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
-msgstr "Futtatás rendszer üzemmódban, de a --disallow-exit paraméter nincs beállítva."
+msgstr ""
+"Futtatás rendszer üzemmódban, de a --disallow-exit paraméter nincs beállítva."
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
-msgstr "Futtatás rendszer üzemmódban, de a --disallow-module-loading paraméter nincs beállítva."
+msgstr ""
+"Futtatás rendszer üzemmódban, de a --disallow-module-loading paraméter nincs "
+"beállítva."
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "Futtatás rendszer üzemmódban, az SHM üzemmód forszírozott letiltása."
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
-msgstr "Futtatás rendszer üzemmódban, kilépés üresjárati időtúllépés esetén beállítás forszírozott letiltása."
+msgstr ""
+"Futtatás rendszer üzemmódban, kilépés üresjárati időtúllépés esetén "
+"beállítás forszírozott letiltása."
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
-msgstr "Nem sikerült jogot szerezni az alapértelmezett ki- és bemenetre (stdio)."
+msgstr ""
+"Nem sikerült jogot szerezni az alapértelmezett ki- és bemenetre (stdio)."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "Cső létrehozás meghiúsult: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "Programindítás meghiúsult: %s"
 
-#: ../src/daemon/main.c:646
-#: ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "Olvasás meghiúsult: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "A démon elindítása nem sikerült."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "A démon sikeresen elindult."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "Olvasás meghiúsult: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Összeépítő számítógép: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "Összeépítési CFLAGS jelzők: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "Kiszolgáló: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "%u CPU található a rendszerben."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "Oldalméret: %lu bájt"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Összeépítés Valgrind támogatással: Igen"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Összeépítés Valgrind támogatással: Nem"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "Futás Valgrind üzemmódban: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "Kiszolgáló: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "Optimalizált összeépítés: Igen"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "Optimalizált összeépítés: Nem"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG megadva, minden érvényesítés letiltva."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH megadva, így csak a gyors útvonal-érvényesítés lesz letiltva."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "Minden érvényesítés engedélyezve."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "Nem sikerült lekérdezni a számítógép azonosítóját"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "Számítógép-azonosító: %s."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "Munkamenet-azonosító: %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "A futásidőben használt mappa: %s."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "Az állapottároló mappa: %s."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "A modulok mappája: %s."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Futás rendszer üzemmódban: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
-"OK, so you are running PA in system mode. Please note that you most likely shouldn't be doing that.\n"
-"If you do it nonetheless then it's your own fault if things don't work as expected.\n"
-"Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an explanation why system mode is usually a bad idea."
+"OK, so you are running PA in system mode. Please note that you most likely "
+"shouldn't be doing that.\n"
+"If you do it nonetheless then it's your own fault if things don't work as "
+"expected.\n"
+"Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an "
+"explanation why system mode is usually a bad idea."
 msgstr ""
-"A PulseAudio rendszer üzemmódban fut. Általánosságban ezen üzemmód használata nem ajánlott.\n"
-"Ha mindenképpen ilyen üzemmódban kívánja futtatni a PulseAudio rendszert, ne lepődjön meg, ha egyes funkciók esetleg nem az elvárások szerint működnek.\n"
-"További tájékoztatás: http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode amelyből megtudhatja miért nem tanácsos a rendszer üzemmód használata."
-
-#: ../src/daemon/main.c:809
+"A PulseAudio rendszer üzemmódban fut. Általánosságban ezen üzemmód "
+"használata nem ajánlott.\n"
+"Ha mindenképpen ilyen üzemmódban kívánja futtatni a PulseAudio rendszert, ne "
+"lepődjön meg, ha egyes funkciók esetleg nem az elvárások szerint működnek.\n"
+"További tájékoztatás: http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode "
+"amelyből megtudhatja miért nem tanácsos a rendszer üzemmód használata."
+
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
-msgstr "A „pa_pid_file_create()” függvényhívás meghiúsult: %s"
+msgstr "A „pa_pid_file_create()” függvényhívás meghiúsult."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "A nagypontosságú időzítők elérhetőek."
 
-#: ../src/daemon/main.c:821
-msgid "Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"
-msgstr "A nagypontosságú időzítők nem érhetőek el. Napjaink Linux rendszereiben érdemes engedélyezni a nagypontosságú időzítőket."
+#: ../src/daemon/main.c:993
+msgid ""
+"Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
+"resolution timers enabled!"
+msgstr ""
+"A nagypontosságú időzítők nem érhetőek el. Napjaink Linux rendszereiben "
+"érdemes engedélyezni a nagypontosságú időzítőket."
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "A „pa_core_new()” függvényhívás meghiúsult: %s"
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "Nem sikerült előkészíteni a démont."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
-msgstr "A démont noha elindult, de nem töltött be modulokat, így a hangrendszer nem üzemképes."
+msgstr ""
+"A démont noha elindult, de nem töltött be modulokat, így a hangrendszer nem "
+"üzemképes."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "A démon elindítása sikeres."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "A démon leállítása kezdeményezve."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "A démon leállítva."
 
-#: ../src/daemon/cmdline.c:115
+#: ../src/daemon/cmdline.c:113
 #, c-format
 msgid ""
 "%s [options]\n"
@@ -387,37 +471,46 @@ msgid ""
 "      --dump-conf                       Dump default configuration\n"
 "      --dump-modules                    Dump list of available modules\n"
 "      --dump-resample-methods           Dump available resample methods\n"
-"      --cleanup-shm                     Cleanup stale shared memory segments\n"
-"      --start                           Start the daemon if it is not running\n"
+"      --cleanup-shm                     Cleanup stale shared memory "
+"segments\n"
+"      --start                           Start the daemon if it is not "
+"running\n"
 "  -k  --kill                            Kill a running daemon\n"
-"      --check                           Check for a running daemon (only returns exit code)\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"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_NICE)\n"
 "      --realtime[=BOOL]                 Try to enable realtime scheduling\n"
-"                                        (only available as root, when SUID or\n"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_RTPRIO)\n"
-"      --disallow-module-loading[=BOOL]  Disallow module user requested module\n"
+"      --disallow-module-loading[=BOOL]  Disallow module user requested "
+"module\n"
 "                                        loading/unloading after startup\n"
 "      --disallow-exit[=BOOL]            Disallow user requested exit\n"
-"      --exit-idle-time=SECS             Terminate the daemon when idle and this\n"
+"      --exit-idle-time=SECS             Terminate the daemon when idle and "
+"this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle and\n"
-"                                        this time passed\n"
-"      --scache-idle-time=SECS           Unload autoloaded samples when idle and\n"
+"      --scache-idle-time=SECS           Unload autoloaded samples when idle "
+"and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
-"      --log-meta[=BOOL]                 Include code location in log messages\n"
+"      --log-target={auto,syslog,stderr,file: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"
+"  -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"
@@ -428,196 +521,212 @@ msgid ""
 "      --disable-shm[=BOOL]              Disable shared memory support.\n"
 "\n"
 "STARTUP SCRIPT:\n"
-"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module with\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module "
+"with\n"
 "                                        the specified argument\n"
 "  -F, --file=FILENAME                   Run the specified script\n"
-"  -C                                    Open a command line on the running TTY\n"
+"  -C                                    Open a command line on the running "
+"TTY\n"
 "                                        after startup\n"
 "\n"
 "  -n                                    Don't load default script file\n"
 msgstr ""
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize paraméter logikai értéket vár el"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail paraméter logikai értéket vár el"
 
-#: ../src/daemon/cmdline.c:264
-msgid "--log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error)."
-msgstr "--log-level paraméter a naplózás szintjének értékét várja el (Ez lehet a 0..4 számtartomány, vagy a következők egyike: debug, info, notice, warn, error)."
+#: ../src/daemon/cmdline.c:261
+msgid ""
+"--log-level expects log level argument (either numeric in range 0..4 or one "
+"of debug, info, notice, warn, error)."
+msgstr ""
+"--log-level paraméter a naplózás szintjének értékét várja el (Ez lehet a "
+"0..4 számtartomány, vagy a következők egyike: debug, info, notice, warn, "
+"error)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority paraméter logikai értéket vár el"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime paraméter logikai értéket vár el"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading paraméter logikai értéket vár el"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit paraméter logikai értéket vár el"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file paraméter logikai értéket vár el"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
-msgstr "Érvénytelen naplózási cél: használja a „syslog”, a „stderr” vagy az „auto” értéket."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
+msgstr ""
+"Érvénytelen naplózási cél: használja a „syslog”, a „stderr” vagy az „auto” "
+"értéket."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time paraméter logikai értéket vár el"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta paraméter logikai értéket vár el"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Érvénytelen újramintavételezési eljárás: „%s”."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system paraméter logikai értéket vár el"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit paraméter logikai értéket vár el"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm paraméter logikai értéket vár el"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Név: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "Nem áll rendelkezésre modul információ.\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Verzió: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Leírás: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Szerző: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Használat: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "Betöltve: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "VISSZAVONÁSI FIGYELMEZTETÉS: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Elérési útvonal: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Érvénytelen naplózási cél: „%s”."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Érvénytelen naplózási szint: „%s”."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Érvénytelen újramintavételezési eljárás: „%s”."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] Érvénytelen rlimit érték: „%s”."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] Az rlimit nem támogatott ezen az operációs rendszeren."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Érvénytelen mintavételi formátum: „%s”."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Érvénytelen mintavételi ráta: „%s”."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Érvénytelen minta csatornák: „%s”."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] Érvénytelen csatornaleképzés: „%s”."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Érvénytelen a részek száma: „%s”."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Érvénytelen a részek mérete: „%s”."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Érvénytelen a prioritási érték: „%s”."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Érvénytelen mintavételi ráta: „%s”."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Nem sikerült megnyitni a konfigurációs fájlt: %s"
 
-#: ../src/daemon/daemon-conf.c:562
-msgid "The specified default channel map has a different number of channels than the specified default number of channels."
-msgstr "Az alapértelmezetten megadott mintavételi leírás csatornáinak száma eltér az alapértelmezetten megadott csatornaszámtól."
+#: ../src/daemon/daemon-conf.c:657
+msgid ""
+"The specified default channel map has a different number of channels than "
+"the specified default number of channels."
+msgstr ""
+"Az alapértelmezetten megadott mintavételi leírás csatornáinak száma eltér az "
+"alapértelmezetten megadott csatornaszámtól."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Olvasás a következő konfigurációs fájlból: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "Jogosultságok letisztázása."
 
@@ -629,8 +738,17 @@ msgstr "PulseAudio hangrendszer"
 msgid "Start the PulseAudio Sound System"
 msgstr "A PulseAudio hangrendszer elindítása"
 
-#: ../src/pulse/channelmap.c:105
-#: ../src/pulse/channelmap.c:757
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio hangrendszer"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "A PulseAudio hangrendszer elindítása"
+
+#: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
 
@@ -659,8 +777,8 @@ msgid "Rear Right"
 msgstr "Hátsó jobb"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Mély-hangszóró (LFE)"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -834,12 +952,10 @@ msgstr "Felső hátsó bal"
 msgid "Top Rear Right"
 msgstr "Felső hátsó jobb"
 
-#: ../src/pulse/channelmap.c:484
-#: ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295
-#: ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341
-#: ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(Érvénytelen)"
 
@@ -867,335 +983,354 @@ msgstr "Térhatású 5.1"
 msgid "Surround 7.1"
 msgstr "Térhatású 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "OK"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "Hozzáférés megtagadva"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Ismeretlen parancs"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "Érvénytelen paraméter"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "Az egység létezik"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "Nincs ilyen egység"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "Kapcsolat elutasítva"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "Protokollhiba"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "Időtúllépés"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "Nem érhető el hitelesítőkulcs"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "Belső hiba"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "A kapcsolat megszakadt."
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "Egység kilőve"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Érvénytelen kiszolgáló"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "A modul előkészítése meghiúsult."
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "Hibás állapot"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Nincs adat"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "Inkompatibilis protokollverzió"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "Túl nagy"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "Nem támogatott"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Ismeretlen hibakód"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "Nincs ilyen kiterjesztés"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "Elavult funkcionalitás"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "Nincs megvalósítva"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "Kliens elindítva"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "Kimeneti/bemeneti hiba"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "Az eszköz vagy erőforrás foglalt"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55
-#: ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "Az XOpenDisplay() függvényhívás meghiúsult."
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "A „pa_context_connect()” függvényhívás meghiúsult: %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "Nem sikerült feldolgozni a süti adatokat."
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Nem sikerült megnyitni a(z) „%s” konfigurációs fájlt: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
-msgstr "Nincs betölthető süti. Kísérlet a kapcsolat felvételére sütik használata nélkül."
+msgstr ""
+"Nincs betölthető süti. Kísérlet a kapcsolat felvételére sütik használata "
+"nélkül."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "Programindítás: %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "Üzenet érkezett az ismeretlen „%s” kiterjesztéstől"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "Nem sikerült csatlakozni a következő adatfolyamhoz: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "A lejátszás adatfolyamához csatlakozva."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "Csatlakozás a kiszolgálóhoz kapcsolathoz."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "A „pa_stream_write()” függvényhívás meghiúsult: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "A „pa_stream_begin_write()” függvényhívás meghiúsult: %s"
 
-#: ../src/utils/pacat.c:237
-#: ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "A „pa_stream_peek()” függvényhívás meghiúsult: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "Az adatfolyam sikeresen létrejött."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "A „pa_stream_get_buffer_attr()” függvényhívás meghiúsult: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
-msgstr "Pufferméretek: maximális nagyság: %u, hossz: %u, előpufferelés: %u, minimum: %u"
+msgstr ""
+"Pufferméretek: maximális nagyság: %u, hossz: %u, előpufferelés: %u, minimum: "
+"%u"
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Pufferméretek: maximális nagyság: %u, részek mérete: %u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "Mintavételi leírás: „%s” és csatornaleképzés: „%s” használata."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "Csatlakozva a következő eszközhöz: „%s” (%u, %ssuspended)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "Adatfolyam hiba: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "Adatfolyam-eszköz készenléti állapotban: %s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "Adatfolyam-eszköz visszatért a készenléti állapotból: %s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "%s adatfolyam alulcsordulás."
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "%s adatfolyam túlcsordulás."
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "%s adatfolyam elindítva."
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
-msgstr "Az adatfolyam áthelyezve a következő eszközre: „%s” (%u, %ssuspended). %s"
+msgstr ""
+"Az adatfolyam áthelyezve a következő eszközre: „%s” (%u, %ssuspended). %s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "nem"
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "Az adatfolyam-puffer beállításai megváltoztak: %s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "Kapcsolat létrehozva. %s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "A „pa_stream_new()” függvényhívás meghiúsult: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "A „pa_stream_connect_playback()” függvényhívás meghiúsult: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "A „pa_stream_connect_record()” függvényhívás meghiúsult: %s"
 
-#: ../src/utils/pacat.c:470
-#: ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "Kapcsolódási hiba: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "A fájl vége elérve."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "Az írás sikertelen: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "Kilépés, szignál hatására…"
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "Nem sikerült lekérdezni a késleltetést: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Idő: %0.3f másodperc, késleltetés: %0.0f ezredmásodperc."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "A „pa_stream_update_timing_info()” függvényhívás meghiúsult: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1207,71 +1342,115 @@ msgid ""
 "\n"
 "  -v, --verbose                         Enable verbose operations\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -d, --device=DEVICE                   The name of the sink/source to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
-"      --stream-name=NAME                How to call this stream on the server\n"
-"      --volume=VOLUME                   Specify the initial (linear) volume in range 0...65536\n"
-"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to 44100)\n"
-"      --format=SAMPLEFORMAT             The sample type, one of s16le, s16be, u8, float32le,\n"
-"                                        float32be, ulaw, alaw, s32le, s32be, s24le, s24be,\n"
-"                                        s24-32le, s24-32be (defaults to s16ne)\n"
-"      --channels=CHANNELS               The number of channels, 1 for mono, 2 for stereo\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -d, --device=DEVICE                   The name of the sink/source to "
+"connect to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
+"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to "
+"44100)\n"
+"      --format=SAMPLEFORMAT             The sample type, one of s16le, "
+"s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be, "
+"s24le, s24be,\n"
+"                                        s24-32le, s24-32be (defaults to "
+"s16ne)\n"
+"      --channels=CHANNELS               The number of channels, 1 for mono, "
+"2 for stereo\n"
 "                                        (defaults to 2)\n"
-"      --channel-map=CHANNELMAP          Channel map to use instead of the default\n"
-"      --fix-format                      Take the sample format from the sink the stream is\n"
+"      --channel-map=CHANNELMAP          Channel map to use instead of the "
+"default\n"
+"      --fix-format                      Take the sample format from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-rate                        Take the sampling rate from the sink the stream is\n"
+"      --fix-rate                        Take the sampling rate from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-channels                    Take the number of channels and the channel map\n"
-"                                        from the sink the stream is being connected to.\n"
+"      --fix-channels                    Take the number of channels and the "
+"channel map\n"
+"                                        from the sink the stream is being "
+"connected to.\n"
 "      --no-remix                        Don't upmix or downmix channels.\n"
-"      --no-remap                        Map channels by index instead of name.\n"
-"      --latency=BYTES                   Request the specified latency in bytes.\n"
-"      --process-time=BYTES              Request the specified process time per request in bytes.\n"
-"      --property=PROPERTY=VALUE         Set the specified property to the specified value.\n"
+"      --no-remap                        Map channels by index instead of "
+"name.\n"
+"      --latency=BYTES                   Request the specified latency in "
+"bytes.\n"
+"      --process-time=BYTES              Request the specified process time "
+"per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
+"      --property=PROPERTY=VALUE         Set the specified property to the "
+"specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [KAPCSOLÓ]\n"
 "\n"
 "  -h, --help                            Ezen súgó megjelenítése\n"
-"      --version                         Az alkalmazás verziószámának megjelenítése\n"
+"      --version                         Az alkalmazás verziószámának "
+"megjelenítése\n"
 "\n"
 "  -r, --record                          Kapcsolat létrehozása felvételhez\n"
 "  -p, --playback                        Kapcsolat létrehozása lejátszáshoz\n"
 "\n"
 "  -v, --verbose                         Történések részletezése\n"
 "\n"
-"  -s, --server=KISZOLGÁLÓ                   Kapcsolódás a megadott KISZOLGÁLÓ kiszolgálóhoz\n"
-"  -d, --device=ESZKÖZ                   Kapcsolódás az ESZKÖZ nevű nyelőhöz vagy forráshoz\n"
+"  -s, --server=KISZOLGÁLÓ                   Kapcsolódás a megadott "
+"KISZOLGÁLÓ kiszolgálóhoz\n"
+"  -d, --device=ESZKÖZ                   Kapcsolódás az ESZKÖZ nevű nyelőhöz "
+"vagy forráshoz\n"
 "  -n, --client-name=NÉV                A kliens neve ezen a szerveren\n"
 "      --stream-name=NÉV                Adatfolyam neve a kiszolgálón\n"
-"      --volume=HANGERŐ                   Kezdeti (lineáris) hangerő megadása a következő tartományban: 0...65536\n"
-"      --rate=MINTAVÉTEL                 Mintavételezés érzéke Hz-ben (alapértelmezés: 44100)\n"
-"      --format=MINTAFORMÁTUM             A mintavétel típusa a következőkből: s16le, s16be, u8, float32le,\n"
-"                                        float32be, ulaw, alaw, s32le, s32be, s24le, s24be,\n"
-"                                        s24-32le, s24-32be (alapértelmezés: s16ne)\n"
-"      --channels=CSATORNÁK               Csatornák száma: 1 - mono, 2 - sztereó\n"
+"      --volume=HANGERŐ                   Kezdeti (lineáris) hangerő megadása "
+"a következő tartományban: 0...65536\n"
+"      --rate=MINTAVÉTEL                 Mintavételezés érzéke Hz-ben "
+"(alapértelmezés: 44100)\n"
+"      --format=MINTAFORMÁTUM             A mintavétel típusa a "
+"következőkből: s16le, s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be, "
+"s24le, s24be,\n"
+"                                        s24-32le, s24-32be (alapértelmezés: "
+"s16ne)\n"
+"      --channels=CSATORNÁK               Csatornák száma: 1 - mono, 2 - "
+"sztereó\n"
 "                                        (defaults to 2)\n"
-"      --channel-map=CSATORNALEKÉPZÉS          Az alapértelmezés helyett használandó csatornaleképzés\n"
-"      --fix-format                      Take the sample format from the sink the stream is\n"
+"      --channel-map=CSATORNALEKÉPZÉS          Az alapértelmezés helyett "
+"használandó csatornaleképzés\n"
+"      --fix-format                      Take the sample format from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-rate                        Take the sampling rate from the sink the stream is\n"
+"      --fix-rate                        Take the sampling rate from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-channels                    Take the number of channels and the channel map\n"
-"                                        from the sink the stream is being connected to.\n"
+"      --fix-channels                    Take the number of channels and the "
+"channel map\n"
+"                                        from the sink the stream is being "
+"connected to.\n"
 "      --no-remix                        Don't upmix or downmix channels.\n"
-"      --no-remap                        Map channels by index instead of name.\n"
-"      --latency=BYTES                   Request the specified latency in bytes.\n"
-"      --process-time=BYTES              Request the specified process time per request in bytes.\n"
-"      --property=PROPERTY=VALUE         Set the specified property to the specified value.\n"
-"      --raw                             Nyers PCM adatok felvétele vagy lejátszása.\n"
-"      --file-format=FORMÁTUM             FORMÁTUM alakú PCM adatok felvétele vagy lejátszása.\n"
+"      --no-remap                        Map channels by index instead of "
+"name.\n"
+"      --latency=BYTES                   Request the specified latency in "
+"bytes.\n"
+"      --process-time=BYTES              Request the specified process time "
+"per request in bytes.\n"
+"      --property=PROPERTY=VALUE         Set the specified property to the "
+"specified value.\n"
+"      --raw                             Nyers PCM adatok felvétele vagy "
+"lejátszása.\n"
+"      --file-format=FORMÁTUM             FORMÁTUM alakú PCM adatok felvétele "
+"vagy lejátszása.\n"
 "      --list-file-formats               Elérhető fájlformátumok listája.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1282,185 +1461,196 @@ msgstr ""
 "Összeépítve a libpulse %s programkönyvtárral\n"
 "Csatolva a libpulse %s programkönyvtárhoz\n"
 
-#: ../src/utils/pacat.c:764
-#: ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "Érvénytelen kliensnév: „%s”"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "Érvénytelen adatfolyam-név: „%s”"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "Érvénytelen csatornaleképzés: „%s”"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "Érvénytelen késleltetés leírás: „%s”"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "Érvénytelen műveleti idő leírás: „%s”"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "Érvénytelen tulajdonság: „%s”"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "Ismeretlen fájlformátum: „%s”"
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "Érvénytelen mintavételi leírás."
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "Megnyitás: %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "Túl sok paraméter."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "Nem sikerült létrehozni a mintavételi leírást a fájlhoz."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "Nem sikerült megnyitni a hangfájlt."
 
-#: ../src/utils/pacat.c:959
-msgid "Warning: specified sample specification will be overwritten with specification from file."
-msgstr "Figyelmeztetés: a megadott mintavételi leírás felül lesz írva a fájlból származó mintavételi leírással."
+#: ../src/utils/pacat.c:1036
+msgid ""
+"Warning: specified sample specification will be overwritten with "
+"specification from file."
+msgstr ""
+"Figyelmeztetés: a megadott mintavételi leírás felül lesz írva a fájlból "
+"származó mintavételi leírással."
 
-#: ../src/utils/pacat.c:962
-#: ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "Nem sikerült meghatározni a mintavételi leírást a fájlból."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
-msgstr "Figyelmeztetés: Nem sikerült meghatározni a csatornaleképzést a fájlból."
+msgstr ""
+"Figyelmeztetés: Nem sikerült meghatározni a csatornaleképzést a fájlból."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "A csatornaleképzés nem feleltethető meg a mintavételi leírásnak."
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "Hiba történt a csatornaleképzés fájlba írása közben."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
-msgid "Opening a %s stream with sample specification '%s' and channel map '%s'."
-msgstr "A(z) „%s” adatfolyam megnyitása a következő mintavételi leírás: „%s” és csatornaleképzés: „%s” használatával."
+msgid ""
+"Opening a %s stream with sample specification '%s' and channel map '%s'."
+msgstr ""
+"A(z) „%s” adatfolyam megnyitása a következő mintavételi leírás: „%s” és "
+"csatornaleképzés: „%s” használatával."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "Felvétel"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "Lejátszás"
 
-#: ../src/utils/pacat.c:1035
-#: ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "Nem sikerült feldolgozni a parancssort."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "A „pa_mainloop_new()” függvényhívás meghiúsult."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "A „io_new()” függvényhívás meghiúsult."
 
-#: ../src/utils/pacat.c:1061
-#: ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "A „pa_context_new()” függvényhívás meghiúsult."
 
-#: ../src/utils/pacat.c:1069
-#: ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "A „pa_context_connect()” függvényhívás meghiúsult: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "A „pa_context_rttime_new()” függvényhívás meghiúsult."
 
-#: ../src/utils/pacat.c:1082
-#: ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "A „pa_mainloop_run()” függvényhívás meghiúsult."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "Programindítás: %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "Hiba lépett fel a készenléti állapotba térés közben: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "Hiba lépett fel a készenléti állapotból visszatérés közben: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
-msgstr "FIGYELMEZTETÉS: A hangkiszolgáló nem helyi és nincs is felfüggesztve.\n"
+msgstr ""
+"FIGYELMEZTETÉS: A hangkiszolgáló nem helyi és nincs is felfüggesztve.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Kapcsolódási hiba: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "Kilépés, SIGINT szignál hatására…\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
-msgstr "FIGYELMEZTETÉS: A gyermek folyamat a következő szignállal fejeződött be: %u\n"
+msgstr ""
+"FIGYELMEZTETÉS: A gyermek folyamat a következő szignállal fejeződött be: %u\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
 "\n"
 msgstr ""
 "%s [KAPCSOLÓ] ... \n"
 "\n"
 "  -h, --help                            Megjeleníti ezt a súgót\n"
-"      --version                         Az alkalmazás verziószámának megjelenítése\n"
+"      --version                         Az alkalmazás verziószámának "
+"megjelenítése\n"
 "\n"
 
 #: ../src/utils/pasuspender.c:248
@@ -1489,35 +1679,49 @@ msgstr "A „pa_context_new()” függvényhívás meghiúsult.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "A „pa_mainloop_run()” függvényhívás meghiúsult.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "Nem sikerült a statisztika lekérdezése: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
-msgstr "Jelenleg lefoglalt blokkok száma: %u, amely összesen %s bájtot jelent.\n"
+msgstr ""
+"Jelenleg lefoglalt blokkok száma: %u, amely összesen %s bájtot jelent.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
-msgstr "A futás során összesen lefoglalt blokkok száma: %u, amely összesen %s bájtot jelent.\n"
+msgstr ""
+"A futás során összesen lefoglalt blokkok száma: %u, amely összesen %s bájtot "
+"jelent.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "Minta-gyorsítótár mérete: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "Nem sikerült lekérdezni a kiszolgáló adatait: „%s”"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1525,7 +1729,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "Felhasználónév: %s\n"
 "Számítógépnév: %s\n"
@@ -1537,13 +1741,13 @@ msgstr ""
 "Alapértelmezett forrás: %s\n"
 "Süti: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "Nem sikerült lekérdezni a nyelő adatait: „%s”"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1559,7 +1763,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1581,24 +1785,27 @@ msgstr ""
 "\tTulajdonságok:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268
-#: ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tPort:\n"
 
-#: ../src/utils/pactl.c:274
-#: ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tAktív Port: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tPort:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "Nem sikerült lekérdezni a forrás adatait: „%s”"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1637,28 +1844,20 @@ msgstr ""
 "\tTulajdonságok:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345
-#: ../src/utils/pactl.c:401
-#: ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473
-#: ../src/utils/pactl.c:532
-#: ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543
-#: ../src/utils/pactl.c:587
-#: ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594
-#: ../src/utils/pactl.c:637
-#: ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "ismeretlen"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "Nem sikerült lekérdezni a modul adatait: „%s”"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1675,12 +1874,12 @@ msgstr ""
 "\tTulajdonságok:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "Nem sikerült lekérdezni a kliens adatait: „%s”"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1695,12 +1894,12 @@ msgstr ""
 "\tTulajdonságok:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "Nem sikerült lekérdezni a kártya adatait: „%s”"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1717,23 +1916,23 @@ msgstr ""
 "\tTulajdonságok:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tProfil:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tAktív profil: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "Nem sikerült lekérdezni a nyelő bemeneti adatait: „%s”"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1742,6 +1941,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1769,13 +1969,13 @@ msgstr ""
 "\tTulajdonságok:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "Nem sikerült lekérdezni a forrás kimeneti adatait: „%s”"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1784,31 +1984,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Forrás kimenet #%u\n"
+"Nyelő bemenet #%u\n"
 "\tEszközmeghajtó: %s\n"
 "\tTulajdonos modul: %s\n"
 "\tKliens: %s\n"
-"\tForrás: %u\n"
+"\tNyelő: %u\n"
 "\tMintavételi leírás: %s\n"
 "\tCsatornaleképzés: %s\n"
+"\tNémítás: %s\n"
+"\tHangerő: %s\n"
+"\t        %s\n"
+"\t        egyensúly %0.2f\n"
 "\tPuffer késleltetés: %0.0f usec\n"
-"\tForrás késleltetés: %0.0f usec\n"
+"\tNyelő késleltetés: %0.0f usec\n"
 "\tÚjramintavételezési eljárás: %s\n"
 "\tTulajdonságok:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "Nem sikerült lekérdezni a mintavétel adatait: „%s”"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1839,85 +2048,180 @@ msgstr ""
 "\tTulajdonságok:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653
-#: ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "Hiba: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Nem sikerült lekérdezni a forrás adatait: „%s”"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "Nem sikerült feltölteni a mintát: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "Idő előtti fájlvége"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "Érvénytelen kiszolgáló"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "Kilépés, SIGINT szignál hatására…"
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "A hangerő megadása érvénytelen."
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
-msgstr ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FÁJLNÉV [NÉV]\n"
-"%s [options] play-sample NÉV [NYELŐ]\n"
-"%s [options] remove-sample NÉV\n"
-"%s [options] move-sink-input NYELŐBEMENET NYELŐ\n"
-"%s [options] move-source-output FORRÁSKIMENET FORRÁS\n"
-"%s [options] load-module NÉV [PARAMÉTEREK ...]\n"
-"%s [options] unload-module MODUL\n"
-"%s [options] suspend-sink NYELŐ 1|0\n"
-"%s [options] suspend-source FORRÁS 1|0\n"
-"%s [options] set-card-profile KÁRTYA PROFIL\n"
-"%s [options] set-sink-port NYELŐ PORT\n"
-"%s [options] set-source-port FORRÁS PORT\n"
-"%s [options] set-sink-volume NYELŐ HANGERŐ\n"
-"%s [options] set-source-volume FORRÁS HANGERŐ\n"
-"%s [options] set-sink-input-volume NYELŐBEMENET HANGERŐ\n"
-"%s [options] set-sink-mute NYELŐ 1|0\n"
-"%s [options] set-source-mute FORRÁS 1|0\n"
-"%s [options] set-sink-input-mute NYELŐBEMENET 1|0\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+msgstr ""
+"%s [KAPCSOLÓ] ... \n"
 "\n"
 "  -h, --help                            Megjeleníti ezt a súgót\n"
-"      --version                         Az alkalmazás verziószámának megjelenítése\n"
+"      --version                         Az alkalmazás verziószámának "
+"megjelenítése\n"
 "\n"
-"  -s, --server=KISZOLGÁLÓ                   Kapcsolódás a megadott KISZOLGÁLÓ kiszolgálóhoz\n"
-"  -n, --client-name=NÉV                A kliens neve ezen a szerveren\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -1928,104 +2232,146 @@ msgstr ""
 "Összeépítve a libpulse %s programkönyvtárral\n"
 "Csatolva a libpulse %s programkönyvtárhoz\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "Adja meg a betöltendő mintafájlt"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "Nem sikerült megnyitni az hangfájlt."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
-msgstr "Figyelmeztetés: Nem sikerült meghatározni a mintavételi leírást a fájlból."
+msgstr ""
+"Figyelmeztetés: Nem sikerült meghatározni a mintavételi leírást a fájlból."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "Meg kell adnia lejátszandó minta nevét."
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "Meg kell adnia az eltávolítandó minta nevét."
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "Meg kell adnia a nyelő bemeneti azonosítóját és a nyelőt."
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "Meg kell adnia a forrás kimeneti azonosítóját és a forrást."
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "Meg kell adnia a modul nevét és a paramétereit."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "Meg kell adnia a modul azonosítóját."
 
-#: ../src/utils/pactl.c:1090
-msgid "You may not specify more than one sink. You have to specify a boolean value."
+#: ../src/utils/pactl.c:1560
+msgid ""
+"You may not specify more than one sink. You have to specify a boolean value."
 msgstr "Nem adhat meg egynél több nyelőt. Egy logikai értéket kell megadnia."
 
-#: ../src/utils/pactl.c:1103
-msgid "You may not specify more than one source. You have to specify a boolean value."
+#: ../src/utils/pactl.c:1573
+msgid ""
+"You may not specify more than one source. You have to specify a boolean "
+"value."
 msgstr "Nem adhat meg egynél több forrást. Egy logikai értéket kell megadnia."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "Meg kell adnia a kártya nevét vagy azonosítóját és a profil nevét"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "Meg kell adnia a nyelő nevét vagy azonosítóját és a port nevét."
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "Meg kell adnia a forrás nevét vagy azonosítóját és a port nevét"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "Meg kell adnia a nyelő nevét vagy azonosítóját és a hangerejét."
 
-#: ../src/utils/pactl.c:1154
-#: ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193
-#: ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226
-#: ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "A hangerő megadása érvénytelen."
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "Meg kell adnia a forrás nevét vagy azonosítóját és a hangerejét"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "Meg kell adnia a nyelő bemenet azonosítóját és a hangerejét"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "A nyelő bemeneti azonosítója érvénytelen."
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "Meg kell adnia a forrás kimeneti azonosítóját és a forrást."
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "A nyelő bemeneti azonosítója érvénytelen."
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
-msgstr "Meg kell adnia a nyelő nevét vagy azonosítóját és a némítás logikai változóját."
+msgstr ""
+"Meg kell adnia a nyelő nevét vagy azonosítóját és a némítás logikai "
+"változóját."
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "Érvénytelen mintavételi leírás."
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
-msgstr "Meg kell adnia a forrás nevét vagy azonosítóját és a némítás logikai változóját"
+msgstr ""
+"Meg kell adnia a forrás nevét vagy azonosítóját és a némítás logikai "
+"változóját"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
-msgstr "Meg kell adnia a nyelő bemenet azonosítóját és a némítás logikai változóját"
+msgstr ""
+"Meg kell adnia a nyelő bemenet azonosítóját és a némítás logikai változóját"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "A nyelő bemeneti azonosítójának megadása érvénytelen."
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr ""
+"Meg kell adnia a forrás nevét vagy azonosítóját és a némítás logikai "
+"változóját"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "A nyelő bemeneti azonosítójának megadása érvénytelen."
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr ""
+"Meg kell adnia a nyelő nevét vagy azonosítóját és a némítás logikai "
+"változóját."
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "Érvénytelen parancs lett megadva."
 
@@ -2036,14 +2382,18 @@ msgid ""
 "\n"
 " -d    Show current PulseAudio data attached to X11 display (default)\n"
 " -e    Export local PulseAudio data to X11 display\n"
-" -i    Import PulseAudio data from X11 display to local environment variables and cookie file.\n"
+" -i    Import PulseAudio data from X11 display to local environment "
+"variables and cookie file.\n"
 " -r    Remove PulseAudio data from X11 display\n"
 msgstr ""
-"%s [-D megjelenítő] [-S kiszolgáló] [-O nyelő] [-I forrás] [-c fájl]  [-d|-e|-i|-r]\n"
+"%s [-D megjelenítő] [-S kiszolgáló] [-O nyelő] [-I forrás] [-c fájl]  [-d|-"
+"e|-i|-r]\n"
 "\n"
-" -d    Megjeleníti az aktuális X11 megjelenítőhöz csatlakoztatott PulseAudio adatokat (alapértelmezés)\n"
+" -d    Megjeleníti az aktuális X11 megjelenítőhöz csatlakoztatott PulseAudio "
+"adatokat (alapértelmezés)\n"
 " -e    Helyi PulseAudio adatok exportálása az X11 megjelenítőre\n"
-" -i    Helyi PulseAudio adatok importálása az X11 megjelenítőről helyi környezeti változókba és süti fájlokba\n"
+" -i    Helyi PulseAudio adatok importálása az X11 megjelenítőről helyi "
+"környezeti változókba és süti fájlokba\n"
 " -r    Eltávolítja a PulseAudio adatokat z X11 megjelenítőről\n"
 
 #: ../src/utils/pax11publish.c:94
@@ -2051,353 +2401,597 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "Nem sikerült feldolgozni a parancssort.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Kiszolgáló: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Forrás: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Nyelő: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Süti: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "Nem sikerült feldolgozni a süti adatokat.\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "Nem sikerült elmenteni a süti adatokat.\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "Nem sikerült betölteni a kliens konfigurációs fájlt.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "Nem sikerült elolvasni a környezetváltozó konfigurációs adatokat.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "Nem sikerült lekérdezni a teljes tartománynevet (FQDN).\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "Nem sikerült betölteni a süti adatokat.\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Még nincs elkészítve.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr "Nem fut a PulseAudio démon vagy nem fut munkamenet démonként sem."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "Kapcsolódás: %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "A PulseAudio démon kilövése nem sikerült."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "A démon nem válaszol."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "Lekérdezés: %s"
 
-#: ../src/utils/pacmd.c:171
-#: ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "Olvasás: %s"
 
-#: ../src/utils/pacmd.c:207
-#: ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "Írás: %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136
-#: ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "Nem érhető zárolás az automatikus indításhoz."
 
-#: ../src/modules/alsa/alsa-sink.c:530
-#: ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, 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."
+"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 ""
-"Az ALSA modul értesítése nyomán új adatokat kellett volna írni az eszközre, de jelenleg semmilyen írandó adat nincsen.\n"
-"Ez egy hiba lehet az ALSA „%s” eszközmeghajtóban. Kérem jelentse ezt a problémát az ALSA fejlesztői felé.\n"
-"Az értesítés a POLLOUT jelzésen keresztül érkezett – viszont a „snd_pcm_avail()” függvény visszatérési értéke 0 volt vagy a második érték kisebb volt, mint a minimum."
+"Az ALSA modul értesítése nyomán új adatokat kellett volna írni az eszközre, "
+"de jelenleg semmilyen írandó adat nincsen.\n"
+"Ez egy hiba lehet az ALSA „%s” eszközmeghajtóban. Kérem jelentse ezt a "
+"problémát az ALSA fejlesztői felé.\n"
+"Az értesítés a POLLOUT jelzésen keresztül érkezett – viszont a „snd_pcm_avail"
+"()” függvény visszatérési értéke 0 volt vagy a második érték kisebb volt, "
+"mint a minimum."
 
-#: ../src/modules/alsa/alsa-source.c:506
-#: ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, 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."
+"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 ""
-"Az ALSA modul értesítése nyomán új adatokat kellett volna olvasni az eszközről, de jelenleg semmilyen olvasandó adat nincsen.\n"
-"Ez egy hiba lehet az ALSA „%s” eszközmeghajtóban. Kérem jelentse ezt a problémát az ALSA fejlesztői felé.\n"
-"Az értesítés a POLLIN jelzésen keresztül érkezett – viszont a „snd_pcm_avail()” függvény visszatérési értéke 0 volt vagy a második érték kisebb volt, mint a minimum."
-
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+"Az ALSA modul értesítése nyomán új adatokat kellett volna olvasni az "
+"eszközről, de jelenleg semmilyen olvasandó adat nincsen.\n"
+"Ez egy hiba lehet az ALSA „%s” eszközmeghajtóban. Kérem jelentse ezt a "
+"problémát az ALSA fejlesztői felé.\n"
+"Az értesítés a POLLIN jelzésen keresztül érkezett – viszont a „snd_pcm_avail"
+"()” függvény visszatérési értéke 0 volt vagy a második érték kisebb volt, "
+"mint a minimum."
+
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "Kikapcsolva"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "HiFi lejátszás (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "HiFi felvétel (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Telefon duplex (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "PulseAudio hangkiszolgáló"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
 msgstr "Kimeneti eszközök"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
 msgstr "Bemeneti eszközök"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
 msgstr "Hangforrások a(z) @HOSTNAME@ számítógépen"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
 msgstr "Bemenet"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
 msgstr "Dokkolóállomás bemenet"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
 msgstr "Dokkolóállomás mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "Dokkolóállomás bemenet"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
 msgstr "Vonalbemenet"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
 msgstr "Mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "Dokkolóállomás mikrofon"
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "Mikrofon"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
 msgid "External Microphone"
 msgstr "Külső mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
 msgstr "Belső mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
 msgstr "Rádió"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
 msgstr "Videó"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
 msgstr "Automatikus erősítésszabályzás"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
 msgstr "Nincs automatikus erősítésszabályzás"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
 msgstr "Erősítés"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
 msgstr "Nincs erősítés"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
 msgstr "Erősítő"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
 msgstr "Nincs erősítő"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr "Analóg bemenet"
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "Erősítés"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr "Analóg mikrofon"
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "Nincs erősítés"
+
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
-msgstr "Analóg vonalbemenet"
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "Analóg fejhallgató"
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr "Analóg rádió"
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "Analóg bemenet"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr "Analóg videó"
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "Dokkolóállomás mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
 msgstr "Analóg kimenet"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr "Analóg fejhallgató"
-
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
 msgstr "Analóg kimenet (mély)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "Vonalbemenet"
+
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
 msgstr "Analóg mono kimenet"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, c-format
-msgid "%s+%s"
-msgstr "%s+%s"
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "Analóg sztereó"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984
-#: ../src/modules/alsa/alsa-mixer.c:3404
-#, c-format
-msgid "%s / %s"
-msgstr "%s / %s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Digitális térhatású (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Digitális térhatású (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr "Analóg mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr "Analóg sztereó"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
 msgstr "Analóg térhatású 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
 msgstr "Analóg térhatású 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
 msgstr "Analóg térhatású 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr "Analóg térhatású 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr "Analóg térhatású 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr "Analóg térhatású 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr "Analóg térhatású 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
 msgstr "Analóg térhatású 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
 msgstr "Analóg térhatású 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
 msgstr "Analóg térhatású 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr "Analóg térhatású 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr "Digitális sztereó (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "Digitális térhatású 4.0 (IEC958)"
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Digitális sztereó (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Digitális térhatású 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Digitális térhatású 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr "Digitális térhatású (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Digitális térhatású 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
 msgstr "Analóg mono duplex"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
 msgstr "Analóg sztereó duplex"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
 msgstr "Analóg sztereó duplex (IEC958)"
 
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Semmis kimenet"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "Bemenet"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<nyelő neve> sink_properties=<nyelő tulajdonságai> "
+"master=<szűrendő nyelő neve> format=<sample format> rate=<mintavételezési "
+"ráta> channels=<csatornák száma> channel_map=<csatornaleképzés> "
+"plugin=<ladspa bővítmény neve> label=<ladspa bővítmény címkéje> "
+"control=<bemenetszabályzó értékek vesszővel elválasztott listája>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] Az rlimit nem támogatott ezen az operációs rendszeren."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "Az XOpenDisplay() függvényhívás meghiúsult."
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Forrás kimenet #%u\n"
+#~ "\tEszközmeghajtó: %s\n"
+#~ "\tTulajdonos modul: %s\n"
+#~ "\tKliens: %s\n"
+#~ "\tForrás: %u\n"
+#~ "\tMintavételi leírás: %s\n"
+#~ "\tCsatornaleképzés: %s\n"
+#~ "\tPuffer késleltetés: %0.0f usec\n"
+#~ "\tForrás késleltetés: %0.0f usec\n"
+#~ "\tÚjramintavételezési eljárás: %s\n"
+#~ "\tTulajdonságok:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FÁJLNÉV [NÉV]\n"
+#~ "%s [options] play-sample NÉV [NYELŐ]\n"
+#~ "%s [options] remove-sample NÉV\n"
+#~ "%s [options] move-sink-input NYELŐBEMENET NYELŐ\n"
+#~ "%s [options] move-source-output FORRÁSKIMENET FORRÁS\n"
+#~ "%s [options] load-module NÉV [PARAMÉTEREK ...]\n"
+#~ "%s [options] unload-module MODUL\n"
+#~ "%s [options] suspend-sink NYELŐ 1|0\n"
+#~ "%s [options] suspend-source FORRÁS 1|0\n"
+#~ "%s [options] set-card-profile KÁRTYA PROFIL\n"
+#~ "%s [options] set-sink-port NYELŐ PORT\n"
+#~ "%s [options] set-source-port FORRÁS PORT\n"
+#~ "%s [options] set-sink-volume NYELŐ HANGERŐ\n"
+#~ "%s [options] set-source-volume FORRÁS HANGERŐ\n"
+#~ "%s [options] set-sink-input-volume NYELŐBEMENET HANGERŐ\n"
+#~ "%s [options] set-sink-mute NYELŐ 1|0\n"
+#~ "%s [options] set-source-mute FORRÁS 1|0\n"
+#~ "%s [options] set-sink-input-mute NYELŐBEMENET 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Megjeleníti ezt a súgót\n"
+#~ "      --version                         Az alkalmazás verziószámának "
+#~ "megjelenítése\n"
+#~ "\n"
+#~ "  -s, --server=KISZOLGÁLÓ                   Kapcsolódás a megadott "
+#~ "KISZOLGÁLÓ kiszolgálóhoz\n"
+#~ "  -n, --client-name=NÉV                A kliens neve ezen a szerveren\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Digitális térhatású 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Mély-hangszóró (LFE)"
diff --git a/po/id.po b/po/id.po
new file mode 100644 (file)
index 0000000..dac5f86
--- /dev/null
+++ b/po/id.po
@@ -0,0 +1,2307 @@
+# Indonesian translation of pulseaudio
+# Copyright (C) 2011 THE pulseaudio'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the pulseaudio package.
+#
+# Translators:
+# Andika Triwidada <andika@gmail.com>, 2011, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: PulseAudio\n"
+"Report-Msgid-Bugs-To: http://pulseaudio.org/wiki/Community#BugsPatchesTranslations\n"
+"POT-Creation-Date: 2010-11-27 01:08+0000\n"
+"PO-Revision-Date: 2012-09-22 04:49+0000\n"
+"Last-Translator: Andika Triwidada <andika@gmail.com>\n"
+"Language-Team: Indonesia <id@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: id\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#: ../src/modules/alsa/alsa-util.c:861 ../src/pulsecore/sink.c:2631
+#, c-format
+msgid "%s %s"
+msgstr "%s %s"
+
+#: ../src/modules/alsa/alsa-util.c:1109
+#, 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 "snd_pcm_avail() mengembalikan nilai yang luar biasa besar: %lu byte (%lu ms).\nSangat mungkin ini adalah kutu pada driver ALSA '%s'. Silakan laporkan hal ini ke para pengembang ALSA."
+
+#: ../src/modules/alsa/alsa-util.c:1150
+#, 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."
+msgstr "snd_pcm_delay() mengembalikan nilai yang luar biasa besar: %li byte (%s%lu ms).\nSangat mungkin ini adalah kutu pada driver ALSA '%s'. Silakan laporkan hal ini ke para pengembang ALSA."
+
+#: ../src/modules/alsa/alsa-util.c:1197
+#, 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."
+msgstr "snd_pcm_mmap_begin() mengembalikan nilai yang luar biasa besar: %lu byte (%lu ms).\nSangat mungkin ini adalah kutu pada driver ALSA '%s'. Silakan laporkan hal ini ke para pengembang ALSA."
+
+#: ../src/modules/module-always-sink.c:39
+msgid "Always keeps at least one sink loaded even if it's a null one"
+msgstr "Selalu jaga paling tidak satu muara bermuatan bahkan jika berupa null"
+
+#: ../src/modules/module-always-sink.c:83
+msgid "Dummy Output"
+msgstr "Keluaran Dummy"
+
+#: ../src/modules/module-ladspa-sink.c:49
+msgid "Virtual LADSPA sink"
+msgstr "Muara virtual LADSPA"
+
+#: ../src/modules/module-ladspa-sink.c:53
+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> "
+"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
+"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
+"input control values>"
+msgstr "sink_name=<nama bagi muara> sink_properties=<properti bagi muara> master=<nama muara untuk disaring> format=<format cuplikan> rate=<laju cuplikan> channels=<cacah kanal> channel_map=<peta kanal> plugin=<nama plugin ladspa> label=<label plugin ladspa> control=<daftar nilai kendali masukan yang dipisahkan dengan koma>"
+
+#: ../src/modules/module-null-sink.c:55
+msgid "Clocked NULL sink"
+msgstr "Muara NULL dengan clock"
+
+#: ../src/modules/module-null-sink.c:291
+msgid "Null Output"
+msgstr "Keluaran Null"
+
+#: ../src/pulsecore/sink.c:2615
+msgid "Internal Audio"
+msgstr "Audio Internal"
+
+#: ../src/pulsecore/sink.c:2620
+msgid "Modem"
+msgstr "Modem"
+
+#: ../src/daemon/ltdl-bind-now.c:124
+msgid "Failed to find original lt_dlopen loader."
+msgstr "Gagal menemukan pemuat lt_dlopen asli."
+
+#: ../src/daemon/ltdl-bind-now.c:129
+msgid "Failed to allocate new dl loader."
+msgstr "Gagal mengalokasikan pemuat dl baru."
+
+#: ../src/daemon/ltdl-bind-now.c:142
+msgid "Failed to add bind-now-loader."
+msgstr "Gagal menambah bind-now-loader."
+
+#: ../src/daemon/main.c:146
+#, c-format
+msgid "Got signal %s."
+msgstr "Mendapat sinyal %s."
+
+#: ../src/daemon/main.c:173
+msgid "Exiting."
+msgstr "Sedang keluar."
+
+#: ../src/daemon/main.c:191
+#, c-format
+msgid "Failed to find user '%s'."
+msgstr "Gagal mencari pengguna '%s'."
+
+#: ../src/daemon/main.c:196
+#, c-format
+msgid "Failed to find group '%s'."
+msgstr "Gagal mencari grup '%s'."
+
+#: ../src/daemon/main.c:200
+#, c-format
+msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
+msgstr "Menemukan pengguna '%s' (UID %lu) dan grup '%s' (GID %lu)."
+
+#: ../src/daemon/main.c:205
+#, c-format
+msgid "GID of user '%s' and of group '%s' don't match."
+msgstr "GID dari pengguna '%s' dan dari grup '%s' tak cocok."
+
+#: ../src/daemon/main.c:210
+#, c-format
+msgid "Home directory of user '%s' is not '%s', ignoring."
+msgstr "Direktori rumah dari pengguna '%s' bukan '%s', mengabaikan."
+
+#: ../src/daemon/main.c:213 ../src/daemon/main.c:218
+#, c-format
+msgid "Failed to create '%s': %s"
+msgstr "Gagal membuat '%s': %s"
+
+#: ../src/daemon/main.c:225
+#, c-format
+msgid "Failed to change group list: %s"
+msgstr "Gagal mengubah daftar grup: %s"
+
+#: ../src/daemon/main.c:241
+#, c-format
+msgid "Failed to change GID: %s"
+msgstr "Gagal mengubah GID: %s"
+
+#: ../src/daemon/main.c:257
+#, c-format
+msgid "Failed to change UID: %s"
+msgstr "Gagal mengubah UID: %s"
+
+#: ../src/daemon/main.c:276
+msgid "Successfully dropped root privileges."
+msgstr "Sukses melepas hak root."
+
+#: ../src/daemon/main.c:284
+msgid "System wide mode unsupported on this platform."
+msgstr "Mode seluruh-sistem tak didukung pada platform ini."
+
+#: ../src/daemon/main.c:302
+#, c-format
+msgid "setrlimit(%s, (%u, %u)) failed: %s"
+msgstr "setrlimit(%s, (%u, %u)) gagal: %s"
+
+#: ../src/daemon/main.c:502
+msgid "Failed to parse command line."
+msgstr "Gagal mengurai baris perintah."
+
+#: ../src/daemon/main.c:535
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup"
+" service."
+msgstr "Mode sistem ditolak bagi pengguna non root. Hanya memulai layanan pencarian server D-Bus."
+
+#: ../src/daemon/main.c:617
+msgid "Daemon not running"
+msgstr "Daemon tidak sedang berjalan"
+
+#: ../src/daemon/main.c:619
+#, c-format
+msgid "Daemon running as PID %u"
+msgstr "Daemon berjalan sebagai PID %u"
+
+#: ../src/daemon/main.c:634
+#, c-format
+msgid "Failed to kill daemon: %s"
+msgstr "Gagal membunuh daemon: %s"
+
+#: ../src/daemon/main.c:662
+msgid ""
+"This program is not intended to be run as root (unless --system is "
+"specified)."
+msgstr "Program ini tidak diinginkan dijalankan sebagai root (kecuali dinyatakan --system)."
+
+#: ../src/daemon/main.c:665
+msgid "Root privileges required."
+msgstr "Dibutuhkan hak root."
+
+#: ../src/daemon/main.c:671
+msgid "--start not supported for system instances."
+msgstr "--start tak didukung bagi instansi sistem."
+
+#: ../src/daemon/main.c:676
+#, c-format
+msgid "User-configured server at %s, not autospawning."
+msgstr "Server yang ditata pengguna pada %s, bukan spawn otomatis."
+
+#: ../src/daemon/main.c:683
+msgid "Running in system mode, but --disallow-exit not set!"
+msgstr "Berjalan pada mode sistem, tapi --disallow-exit tak ditata!"
+
+#: ../src/daemon/main.c:686
+msgid "Running in system mode, but --disallow-module-loading not set!"
+msgstr "Berjalan pada mode sistem, tapi --disallow-module-loading tak ditata!"
+
+#: ../src/daemon/main.c:689
+msgid "Running in system mode, forcibly disabling SHM mode!"
+msgstr "Berjalan pada mode sistem, memaksa mematikan mode SHM!"
+
+#: ../src/daemon/main.c:694
+msgid "Running in system mode, forcibly disabling exit idle time!"
+msgstr "Berjalan pada mode sistem, memaksa mematikan waktu menganggur keluar!"
+
+#: ../src/daemon/main.c:720
+msgid "Failed to acquire stdio."
+msgstr "Gagal memperoleh stdio."
+
+#: ../src/daemon/main.c:726
+#, c-format
+msgid "pipe() failed: %s"
+msgstr "pipe() gagal: %s"
+
+#: ../src/daemon/main.c:731 ../src/daemon/main.c:790
+#, c-format
+msgid "fork() failed: %s"
+msgstr "fork() gagal: %s"
+
+#: ../src/daemon/main.c:745 ../src/utils/pacat.c:529
+#, c-format
+msgid "read() failed: %s"
+msgstr "read() gagal: %s"
+
+#: ../src/daemon/main.c:751
+msgid "Daemon startup failed."
+msgstr "Gagal memulai daemon."
+
+#: ../src/daemon/main.c:753
+msgid "Daemon startup successful."
+msgstr "Sukses memulai daemon."
+
+#: ../src/daemon/main.c:778
+#, c-format
+msgid "setsid() failed: %s"
+msgstr "setsid() gagal: %s"
+
+#: ../src/daemon/main.c:830
+#, c-format
+msgid "This is PulseAudio %s"
+msgstr "Ini adalah PulseAudio %s"
+
+#: ../src/daemon/main.c:831
+#, c-format
+msgid "Compilation host: %s"
+msgstr "Host kompilasi: %s"
+
+#: ../src/daemon/main.c:832
+#, c-format
+msgid "Compilation CFLAGS: %s"
+msgstr "CFLAGS kompilasi: %s"
+
+#: ../src/daemon/main.c:835
+#, c-format
+msgid "Running on host: %s"
+msgstr "Dijalankan pada host: %s"
+
+#: ../src/daemon/main.c:838
+#, c-format
+msgid "Found %u CPUs."
+msgstr "Ditemukan %u CPU."
+
+#: ../src/daemon/main.c:840
+#, c-format
+msgid "Page size is %lu bytes"
+msgstr "Ukuran page adalah %lu byte"
+
+#: ../src/daemon/main.c:843
+msgid "Compiled with Valgrind support: yes"
+msgstr "Dikompail dengan dukungan Valgrind: ya"
+
+#: ../src/daemon/main.c:845
+msgid "Compiled with Valgrind support: no"
+msgstr "Dikompail dengan dukungan Valgrind: tidak"
+
+#: ../src/daemon/main.c:848
+#, c-format
+msgid "Running in valgrind mode: %s"
+msgstr "Berjalan pada mode valgrind: %s"
+
+#: ../src/daemon/main.c:850
+#, c-format
+msgid "Running in VM: %s"
+msgstr "Dijalankan di VM: %s"
+
+#: ../src/daemon/main.c:853
+msgid "Optimized build: yes"
+msgstr "Pembangunan teroptimasi: ya"
+
+#: ../src/daemon/main.c:855
+msgid "Optimized build: no"
+msgstr "Pembangunan teroptimasi: tidak"
+
+#: ../src/daemon/main.c:859
+msgid "NDEBUG defined, all asserts disabled."
+msgstr "NDEBUG didefinisikan, semua assert dimatikan."
+
+#: ../src/daemon/main.c:861
+msgid "FASTPATH defined, only fast path asserts disabled."
+msgstr "FASTPATH didefinisikan, hanya assert jalur cepat yang dimatikan."
+
+#: ../src/daemon/main.c:863
+msgid "All asserts enabled."
+msgstr "Semua assert diaktifkan."
+
+#: ../src/daemon/main.c:867
+msgid "Failed to get machine ID"
+msgstr "Gagal memperoleh ID mesin"
+
+#: ../src/daemon/main.c:870
+#, c-format
+msgid "Machine ID is %s."
+msgstr "ID mesin adalah %s."
+
+#: ../src/daemon/main.c:874
+#, c-format
+msgid "Session ID is %s."
+msgstr "ID sesi adalah %s."
+
+#: ../src/daemon/main.c:880
+#, c-format
+msgid "Using runtime directory %s."
+msgstr "Memakai direktori runtime %s."
+
+#: ../src/daemon/main.c:885
+#, c-format
+msgid "Using state directory %s."
+msgstr "Memakai direktori keadaan %s."
+
+#: ../src/daemon/main.c:888
+#, c-format
+msgid "Using modules directory %s."
+msgstr "Memakai direktori modul %s."
+
+#: ../src/daemon/main.c:890
+#, c-format
+msgid "Running in system mode: %s"
+msgstr "Berjalan pada mode sistem: %s"
+
+#: ../src/daemon/main.c:893
+msgid ""
+"OK, so you are running PA in system mode. Please note that you most likely shouldn't be doing that.\n"
+"If you do it nonetheless then it's your own fault if things don't work as expected.\n"
+"Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an explanation why system mode is usually a bad idea."
+msgstr "OK, jadi Anda menjalankan PA dalam mode sistem. Mohon catat bahwa sangat boleh jadi Anda tak perlu melakukan ini.\nNamun bila Anda melakukannya juga, salah Anda sendiri bila semua tak bekerja seperti yang diharapkan.\nSilakan baca http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode bagi penjelasan mengapa mode sistem biasanya adalah ide buruk."
+
+#: ../src/daemon/main.c:910
+msgid "pa_pid_file_create() failed."
+msgstr "pa_pid_file_create() gagal."
+
+#: ../src/daemon/main.c:920
+msgid "Fresh high-resolution timers available! Bon appetit!"
+msgstr "Pewaktu resolusi tinggi yang segar tersedia! Selamat makan!"
+
+#: ../src/daemon/main.c:922
+msgid ""
+"Dude, your kernel stinks! The chef's recommendation today is Linux with "
+"high-resolution timers enabled!"
+msgstr "Bung, kernel Anda bau! Saran koki hari ini adalah Linux dengan pewaktu resolusi tinggi yang diaktifkan!"
+
+#: ../src/daemon/main.c:945
+msgid "pa_core_new() failed."
+msgstr "pa_core_new() gagal."
+
+#: ../src/daemon/main.c:1008
+msgid "Failed to initialize daemon."
+msgstr "Gagal menginisialisasi daemon."
+
+#: ../src/daemon/main.c:1013
+msgid "Daemon startup without any loaded modules, refusing to work."
+msgstr "Daemon dimulai tanpa modul apapun yang dimuat, menolak bekerja."
+
+#: ../src/daemon/main.c:1051
+msgid "Daemon startup complete."
+msgstr "Memulai daemon komplit."
+
+#: ../src/daemon/main.c:1057
+msgid "Daemon shutdown initiated."
+msgstr "Mulai mematikan daemon."
+
+#: ../src/daemon/main.c:1083
+msgid "Daemon terminated."
+msgstr "Daemon diakhiri."
+
+#: ../src/daemon/cmdline.c:115
+#, 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"
+"      --module-idle-time=SECS           Unload autoloaded modules when idle and\n"
+"                                        this time passed\n"
+"      --scache-idle-time=SECS           Unload autoloaded samples when idle and\n"
+"                                        this time passed\n"
+"      --log-level[=LEVEL]               Increase or set verbosity level\n"
+"  -v                                    Increase the verbosity level\n"
+"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --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"
+"\n"
+"STARTUP SCRIPT:\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module with\n"
+"                                        the specified argument\n"
+"  -F, --file=FILENAME                   Run the specified script\n"
+"  -C                                    Open a command line on the running TTY\n"
+"                                        after startup\n"
+"\n"
+"  -n                                    Don't load default script file\n"
+msgstr "%s [opsi]\n\nPERINTAH:\n  -h, --help                            Tampilkan bantuan ini\n      --version                         Tampilkan versi\n      --dump-conf                       Semua konfigurasi baku\n      --dump-modules                    Daftar semua modul tersedia\n      --dump-resample-methods           Semua metoda cuplik ulang yang tersedia\n      --cleanup-shm                     Bersihkan segmen memori dipakai bersama yang basi\n      --start                           Mulai daemon bila tidak sedang berjalan\n  -k  --kill                            Matikan daemon yang sedang berjalan\n      --check                           Periksa apakah ada daemon yang sedang berjalan\n                                        (hanya mengembalikan kode keluar)\n\nOPSI:\n      --system[=BOOL]                   Jalankan sebagai instansi seluruh sistem\n  -D, --daemonize[=BOOL]                Jadikan daemon setelah awalan\n      --fail[=BOOL]                     Keluar ketika awalan gagal\n      --high-priority[=BOOL]            Coba tata ke aras nice tinggi\n                                        (hanya tersedia sebagai root, ketika SUID\n                                        atau RLIMIT_NICE yang dinaikkan)\n      --realtime[=BOOL]                 Coba fungsikan penjadwalan waktu-nyata\n                                        (hanya tersedia sebagai root, ketika SUID\n                                        atau RLIMIT_RTPRIO yang dinaikkan)\n      --disallow-module-loading[=BOOL]  Larang muat/bongkar modul yang diminta\n                                        pengguna setelah awalan\n      --disallow-exit[=BOOL]            Larang permintaan keluar dari pengguna\n      --exit-idle-time=SECS             Matikan daemon ketika menganggur dan\n                                        waktu ini habis\n      --module-idle-time=SECS           Bongkar modul yang dimuat sendiri ketika\n                                        menganggur dan waktu ini habis\n      --scache-idle-time=SECS           Bongkar contoh yang dimuat sendiri ketika\n                                        menganggur dan waktu ini habis\n      --log-level[=LEVEL]               Naikkan atau tata aras kerincian\n  -v                                    Naikkan aras kerincian\n      --log-target={auto,syslog,stderr} Nyatakan target log\n      --log-meta[=BOOL]                 Sertakan lokasi kode dalam pesan log\n      --log-time[=BOOL]                 Sertakan penanda waktu dalam pesan log\n      --log-backtrace=FRAMES            Sertakan suatu backtrace dalam pesan log\n  -p, --dl-search-path=PATH             Tata path pencarian bagi objek dipakai\n                                        bersama yang dinamis (plugin)\n      --resample-method=METHOD          Gunakan metoda cuplik ulang yang dinyatakan\n                                        (Lihat --dump-resample-methods untuk\n                                        nilai yang mungkin)\n      --use-pid-file[=BOOL]             Buat suatu berkas PID\n      --no-cpu-limit[=BOOL]             Jangan pasang pembatas beban CPU\n                                        pada platform yang mendukungannya.\n      --disable-shm[=BOOL]              Matikan dukungan memori bersama.\n\nSKRIP AWALAN:\n  -L, --load=\"ARGUMEN MODUL\"            Muat modul plugin yang dinyatakan\n                                        dengan argumen yang disertakan\n  -F, --file=NAMABERKAS                 Jalankan skrip yang dinyatakan\n  -C                                    Buka baris perintah pada TTY berjalan\n                                        setelah awalan\n\n  -n                                    Jangan muat berkas skrip baku\n"
+
+#: ../src/daemon/cmdline.c:247
+msgid "--daemonize expects boolean argument"
+msgstr "--daemonize mengharapkan argumen bool"
+
+#: ../src/daemon/cmdline.c:254
+msgid "--fail expects boolean argument"
+msgstr "--fail  mengharapkan argumen bool"
+
+#: ../src/daemon/cmdline.c:264
+msgid ""
+"--log-level expects log level argument (either numeric in range 0..4 or one "
+"of debug, info, notice, warn, error)."
+msgstr "--log-level mengharapkan argumen aras log (bisa berupa angka 0..4 atau salah satu dari debug, info, notice, warn, error)."
+
+#: ../src/daemon/cmdline.c:276
+msgid "--high-priority expects boolean argument"
+msgstr "--high-priority mengharapkan argumen bool"
+
+#: ../src/daemon/cmdline.c:283
+msgid "--realtime expects boolean argument"
+msgstr "--realtime mengharapkan argumen bool"
+
+#: ../src/daemon/cmdline.c:290
+msgid "--disallow-module-loading expects boolean argument"
+msgstr "--disallow-module-loading mengharapkan argumen bool"
+
+#: ../src/daemon/cmdline.c:297
+msgid "--disallow-exit expects boolean argument"
+msgstr "--disallow-exit mengharapkan argumen bool"
+
+#: ../src/daemon/cmdline.c:304
+msgid "--use-pid-file expects boolean argument"
+msgstr "--use-pid-file mengharapkan argumen bool"
+
+#: ../src/daemon/cmdline.c:321
+msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+msgstr "Tujuan log tak valid: gunakan saah satu dari 'syslog', 'stderr', atau 'auto'."
+
+#: ../src/daemon/cmdline.c:328
+msgid "--log-time expects boolean argument"
+msgstr "--log-time mengharapkan argumen bool"
+
+#: ../src/daemon/cmdline.c:335
+msgid "--log-meta expects boolean argument"
+msgstr "--log-meta mengharapkan argumen bool"
+
+#: ../src/daemon/cmdline.c:354
+#, c-format
+msgid "Invalid resample method '%s'."
+msgstr "Metode cuplik ulang tak valid '%s'."
+
+#: ../src/daemon/cmdline.c:361
+msgid "--system expects boolean argument"
+msgstr "--system mengharapkan argumen bool"
+
+#: ../src/daemon/cmdline.c:368
+msgid "--no-cpu-limit expects boolean argument"
+msgstr "--no-cpu-limit mengharapkan argumen bool"
+
+#: ../src/daemon/cmdline.c:375
+msgid "--disable-shm expects boolean argument"
+msgstr "--disable-shm mengharapkan argumen bool"
+
+#: ../src/daemon/dumpmodules.c:60
+#, c-format
+msgid "Name: %s\n"
+msgstr "Nama: %s\n"
+
+#: ../src/daemon/dumpmodules.c:63
+#, c-format
+msgid "No module information available\n"
+msgstr "Informasi modul tak tersedia\n"
+
+#: ../src/daemon/dumpmodules.c:66
+#, c-format
+msgid "Version: %s\n"
+msgstr "Versi: %s\n"
+
+#: ../src/daemon/dumpmodules.c:68
+#, c-format
+msgid "Description: %s\n"
+msgstr "Keterangan: %s\n"
+
+#: ../src/daemon/dumpmodules.c:70
+#, c-format
+msgid "Author: %s\n"
+msgstr "Penulis: %s\n"
+
+#: ../src/daemon/dumpmodules.c:72
+#, c-format
+msgid "Usage: %s\n"
+msgstr "Cara pakai: %s\n"
+
+#: ../src/daemon/dumpmodules.c:73
+#, c-format
+msgid "Load Once: %s\n"
+msgstr "Muat Sekali: %s\n"
+
+#: ../src/daemon/dumpmodules.c:75
+#, c-format
+msgid "DEPRECATION WARNING: %s\n"
+msgstr "PERINGATAN KADALUARSA: %s\n"
+
+#: ../src/daemon/dumpmodules.c:79
+#, c-format
+msgid "Path: %s\n"
+msgstr "Path: %s\n"
+
+#: ../src/daemon/daemon-conf.c:251
+#, c-format
+msgid "[%s:%u] Invalid log target '%s'."
+msgstr "[%s:%u] Tujuan log tak valid '%s'."
+
+#: ../src/daemon/daemon-conf.c:267
+#, c-format
+msgid "[%s:%u] Invalid log level '%s'."
+msgstr "[%s:%u] Aras log tak valid '%s'."
+
+#: ../src/daemon/daemon-conf.c:283
+#, c-format
+msgid "[%s:%u] Invalid resample method '%s'."
+msgstr "[%s:%u] Metoda cuplikan ulang tak valid '%s'."
+
+#: ../src/daemon/daemon-conf.c:306
+#, c-format
+msgid "[%s:%u] Invalid rlimit '%s'."
+msgstr "[%s:%u] rlimit tak valid'%s'."
+
+#: ../src/daemon/daemon-conf.c:313
+#, c-format
+msgid "[%s:%u] rlimit not supported on this platform."
+msgstr "[%s:%u] rlimit tak didukung pada platform ini."
+
+#: ../src/daemon/daemon-conf.c:329
+#, c-format
+msgid "[%s:%u] Invalid sample format '%s'."
+msgstr "[%s:%u] Bentuk cuplikan tak valid '%s'."
+
+#: ../src/daemon/daemon-conf.c:347
+#, c-format
+msgid "[%s:%u] Invalid sample rate '%s'."
+msgstr "[%s:%u] Laju cuplikan tak valid '%s'."
+
+#: ../src/daemon/daemon-conf.c:371
+#, c-format
+msgid "[%s:%u] Invalid sample channels '%s'."
+msgstr "[%s:%u] Kanal cuplikan tak valid '%s'."
+
+#: ../src/daemon/daemon-conf.c:389
+#, c-format
+msgid "[%s:%u] Invalid channel map '%s'."
+msgstr "[%s:%u] Peta kanal tak valid '%s'."
+
+#: ../src/daemon/daemon-conf.c:407
+#, c-format
+msgid "[%s:%u] Invalid number of fragments '%s'."
+msgstr "[%s:%u] Cacah fragmen tak valid '%s'."
+
+#: ../src/daemon/daemon-conf.c:425
+#, c-format
+msgid "[%s:%u] Invalid fragment size '%s'."
+msgstr "[%s:%u] Ukuran fragmen tak valid '%s'."
+
+#: ../src/daemon/daemon-conf.c:443
+#, c-format
+msgid "[%s:%u] Invalid nice level '%s'."
+msgstr "[%s:%u] Aras nice tak valid '%s'."
+
+#: ../src/daemon/daemon-conf.c:479
+#, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Tipe server '%s' tak valid."
+
+#: ../src/daemon/daemon-conf.c:586
+#, c-format
+msgid "Failed to open configuration file: %s"
+msgstr "Gagal membaca berkas konfigurasi: %s"
+
+#: ../src/daemon/daemon-conf.c:602
+msgid ""
+"The specified default channel map has a different number of channels than "
+"the specified default number of channels."
+msgstr "Peta kanal baku yang dinyatakan memiliki cacah kanal yang berbeda dengan cacah kanal baku yang dinyatakan."
+
+#: ../src/daemon/daemon-conf.c:688
+#, c-format
+msgid "### Read from configuration file: %s ###\n"
+msgstr "### Membaca dari berkas konfigurasi: %s ###\n"
+
+#: ../src/daemon/caps.c:62
+msgid "Cleaning up privileges."
+msgstr "Membersihkan hak khusus."
+
+#: ../src/daemon/pulseaudio.desktop.in.h:1
+msgid "PulseAudio Sound System"
+msgstr "Sistem Suara PulseAudio"
+
+#: ../src/daemon/pulseaudio.desktop.in.h:2
+msgid "Start the PulseAudio Sound System"
+msgstr "Memulai Sistem Suara PulseAudio"
+
+#: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
+msgid "Mono"
+msgstr "Mono"
+
+#: ../src/pulse/channelmap.c:107
+msgid "Front Center"
+msgstr "Depan Tengah"
+
+#: ../src/pulse/channelmap.c:108
+msgid "Front Left"
+msgstr "Depan Kiri"
+
+#: ../src/pulse/channelmap.c:109
+msgid "Front Right"
+msgstr "Depan Kanan"
+
+#: ../src/pulse/channelmap.c:111
+msgid "Rear Center"
+msgstr "Belakang Tengah"
+
+#: ../src/pulse/channelmap.c:112
+msgid "Rear Left"
+msgstr "Belakang Kiri"
+
+#: ../src/pulse/channelmap.c:113
+msgid "Rear Right"
+msgstr "Belakang Kanan"
+
+#: ../src/pulse/channelmap.c:115
+msgid "Subwoofer"
+msgstr "Subwoofer"
+
+#: ../src/pulse/channelmap.c:117
+msgid "Front Left-of-center"
+msgstr "Depan Tengah agak ke kiri"
+
+#: ../src/pulse/channelmap.c:118
+msgid "Front Right-of-center"
+msgstr "Depan Tengah agak ke kanan"
+
+#: ../src/pulse/channelmap.c:120
+msgid "Side Left"
+msgstr "Samping Kiri"
+
+#: ../src/pulse/channelmap.c:121
+msgid "Side Right"
+msgstr "Samping Kanan"
+
+#: ../src/pulse/channelmap.c:123
+msgid "Auxiliary 0"
+msgstr "Tambahan 0"
+
+#: ../src/pulse/channelmap.c:124
+msgid "Auxiliary 1"
+msgstr "Tambahan 1"
+
+#: ../src/pulse/channelmap.c:125
+msgid "Auxiliary 2"
+msgstr "Tambahan 2"
+
+#: ../src/pulse/channelmap.c:126
+msgid "Auxiliary 3"
+msgstr "Tambahan 3"
+
+#: ../src/pulse/channelmap.c:127
+msgid "Auxiliary 4"
+msgstr "Tambahan 4"
+
+#: ../src/pulse/channelmap.c:128
+msgid "Auxiliary 5"
+msgstr "Tambahan 5"
+
+#: ../src/pulse/channelmap.c:129
+msgid "Auxiliary 6"
+msgstr "Tambahan 6"
+
+#: ../src/pulse/channelmap.c:130
+msgid "Auxiliary 7"
+msgstr "Tambahan 7"
+
+#: ../src/pulse/channelmap.c:131
+msgid "Auxiliary 8"
+msgstr "Tambahan 8"
+
+#: ../src/pulse/channelmap.c:132
+msgid "Auxiliary 9"
+msgstr "Tambahan 9"
+
+#: ../src/pulse/channelmap.c:133
+msgid "Auxiliary 10"
+msgstr "Tambahan 10"
+
+#: ../src/pulse/channelmap.c:134
+msgid "Auxiliary 11"
+msgstr "Tambahan 11"
+
+#: ../src/pulse/channelmap.c:135
+msgid "Auxiliary 12"
+msgstr "Tambahan 12"
+
+#: ../src/pulse/channelmap.c:136
+msgid "Auxiliary 13"
+msgstr "Tambahan 13"
+
+#: ../src/pulse/channelmap.c:137
+msgid "Auxiliary 14"
+msgstr "Tambahan 14"
+
+#: ../src/pulse/channelmap.c:138
+msgid "Auxiliary 15"
+msgstr "Tambahan 15"
+
+#: ../src/pulse/channelmap.c:139
+msgid "Auxiliary 16"
+msgstr "Tambahan 16"
+
+#: ../src/pulse/channelmap.c:140
+msgid "Auxiliary 17"
+msgstr "Tambahan 17"
+
+#: ../src/pulse/channelmap.c:141
+msgid "Auxiliary 18"
+msgstr "Tambahan 18"
+
+#: ../src/pulse/channelmap.c:142
+msgid "Auxiliary 19"
+msgstr "Tambahan 19"
+
+#: ../src/pulse/channelmap.c:143
+msgid "Auxiliary 20"
+msgstr "Tambahan 20"
+
+#: ../src/pulse/channelmap.c:144
+msgid "Auxiliary 21"
+msgstr "Tambahan 21"
+
+#: ../src/pulse/channelmap.c:145
+msgid "Auxiliary 22"
+msgstr "Tambahan 22"
+
+#: ../src/pulse/channelmap.c:146
+msgid "Auxiliary 23"
+msgstr "Tambahan 23"
+
+#: ../src/pulse/channelmap.c:147
+msgid "Auxiliary 24"
+msgstr "Tambahan 24"
+
+#: ../src/pulse/channelmap.c:148
+msgid "Auxiliary 25"
+msgstr "Tambahan 25"
+
+#: ../src/pulse/channelmap.c:149
+msgid "Auxiliary 26"
+msgstr "Tambahan 26"
+
+#: ../src/pulse/channelmap.c:150
+msgid "Auxiliary 27"
+msgstr "Tambahan 27"
+
+#: ../src/pulse/channelmap.c:151
+msgid "Auxiliary 28"
+msgstr "Tambahan 28"
+
+#: ../src/pulse/channelmap.c:152
+msgid "Auxiliary 29"
+msgstr "Tambahan 29"
+
+#: ../src/pulse/channelmap.c:153
+msgid "Auxiliary 30"
+msgstr "Tambahan 30"
+
+#: ../src/pulse/channelmap.c:154
+msgid "Auxiliary 31"
+msgstr "Tambahan 31"
+
+#: ../src/pulse/channelmap.c:156
+msgid "Top Center"
+msgstr "Puncak Tengah"
+
+#: ../src/pulse/channelmap.c:158
+msgid "Top Front Center"
+msgstr "Puncak Depan Tengah"
+
+#: ../src/pulse/channelmap.c:159
+msgid "Top Front Left"
+msgstr "Puncak Depan Kiri"
+
+#: ../src/pulse/channelmap.c:160
+msgid "Top Front Right"
+msgstr "Puncak Depan Kanan"
+
+#: ../src/pulse/channelmap.c:162
+msgid "Top Rear Center"
+msgstr "Puncak Belakang Tengah"
+
+#: ../src/pulse/channelmap.c:163
+msgid "Top Rear Left"
+msgstr "Puncak Belakang Kiri"
+
+#: ../src/pulse/channelmap.c:164
+msgid "Top Rear Right"
+msgstr "Puncak Belakang Kanan"
+
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
+#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
+#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+msgid "(invalid)"
+msgstr "(tak valid)"
+
+#: ../src/pulse/channelmap.c:761
+msgid "Stereo"
+msgstr "Stereo"
+
+#: ../src/pulse/channelmap.c:766
+msgid "Surround 4.0"
+msgstr "Surround 4.0"
+
+#: ../src/pulse/channelmap.c:772
+msgid "Surround 4.1"
+msgstr "Surround 4.1"
+
+#: ../src/pulse/channelmap.c:778
+msgid "Surround 5.0"
+msgstr "Surround 5.0"
+
+#: ../src/pulse/channelmap.c:784
+msgid "Surround 5.1"
+msgstr "Surround 5.1"
+
+#: ../src/pulse/channelmap.c:791
+msgid "Surround 7.1"
+msgstr "Surround 7.1"
+
+#: ../src/pulse/error.c:43
+msgid "OK"
+msgstr "OK"
+
+#: ../src/pulse/error.c:44
+msgid "Access denied"
+msgstr "Akses ditolak"
+
+#: ../src/pulse/error.c:45
+msgid "Unknown command"
+msgstr "Perintah tak dikenal"
+
+#: ../src/pulse/error.c:46
+msgid "Invalid argument"
+msgstr "Argumen tak valid"
+
+#: ../src/pulse/error.c:47
+msgid "Entity exists"
+msgstr "Entitas ada"
+
+#: ../src/pulse/error.c:48
+msgid "No such entity"
+msgstr "Entitas tak ada"
+
+#: ../src/pulse/error.c:49
+msgid "Connection refused"
+msgstr "Koneksi ditolak"
+
+#: ../src/pulse/error.c:50
+msgid "Protocol error"
+msgstr "Galat protokol"
+
+#: ../src/pulse/error.c:51
+msgid "Timeout"
+msgstr "Habis waktu"
+
+#: ../src/pulse/error.c:52
+msgid "No authorization key"
+msgstr "Tak ada kunci otorisasi"
+
+#: ../src/pulse/error.c:53
+msgid "Internal error"
+msgstr "Galat internal"
+
+#: ../src/pulse/error.c:54
+msgid "Connection terminated"
+msgstr "Sambungan diakhiri"
+
+#: ../src/pulse/error.c:55
+msgid "Entity killed"
+msgstr "Entitas dimatikan"
+
+#: ../src/pulse/error.c:56
+msgid "Invalid server"
+msgstr "Server tak valid"
+
+#: ../src/pulse/error.c:57
+msgid "Module initalization failed"
+msgstr "Inisialisasi modul gagal"
+
+#: ../src/pulse/error.c:58
+msgid "Bad state"
+msgstr "Kondisi buruk"
+
+#: ../src/pulse/error.c:59
+msgid "No data"
+msgstr "Tak ada data"
+
+#: ../src/pulse/error.c:60
+msgid "Incompatible protocol version"
+msgstr "Versi protokol tak kompatibel"
+
+#: ../src/pulse/error.c:61
+msgid "Too large"
+msgstr "Terlalu besar"
+
+#: ../src/pulse/error.c:62
+msgid "Not supported"
+msgstr "Tak didukung"
+
+#: ../src/pulse/error.c:63
+msgid "Unknown error code"
+msgstr "Kode galat tak dikenal"
+
+#: ../src/pulse/error.c:64
+msgid "No such extension"
+msgstr "Tak ada ekstensi demikian"
+
+#: ../src/pulse/error.c:65
+msgid "Obsolete functionality"
+msgstr "Fungsionalitas yang tak berlaku lagi"
+
+#: ../src/pulse/error.c:66
+msgid "Missing implementation"
+msgstr "Tak ada implementasi"
+
+#: ../src/pulse/error.c:67
+msgid "Client forked"
+msgstr "Klien di-fork"
+
+#: ../src/pulse/error.c:68
+msgid "Input/Output error"
+msgstr "Galat masukan/keluaran"
+
+#: ../src/pulse/error.c:69
+msgid "Device or resource busy"
+msgstr "Perangkat atau sumber daya sibuk"
+
+#: ../src/pulse/sample.c:172
+#, c-format
+msgid "%s %uch %uHz"
+msgstr "%s %uch %uHz"
+
+#: ../src/pulse/sample.c:184
+#, c-format
+msgid "%0.1f GiB"
+msgstr "%0.1f GiB"
+
+#: ../src/pulse/sample.c:186
+#, c-format
+msgid "%0.1f MiB"
+msgstr "%0.1f MiB"
+
+#: ../src/pulse/sample.c:188
+#, c-format
+msgid "%0.1f KiB"
+msgstr "%0.1f KiB"
+
+#: ../src/pulse/sample.c:190
+#, c-format
+msgid "%u B"
+msgstr "%u B"
+
+#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
+msgid "XOpenDisplay() failed"
+msgstr "XOpenDisplay() gagal"
+
+#: ../src/pulse/client-conf-x11.c:93
+msgid "Failed to parse cookie data"
+msgstr "Gagal mengurai data cookie"
+
+#: ../src/pulse/client-conf.c:118
+#, c-format
+msgid "Failed to open configuration file '%s': %s"
+msgstr "Gagal membuka berkas konfigurasi '%s': %s"
+
+#: ../src/pulse/context.c:539
+msgid "No cookie loaded. Attempting to connect without."
+msgstr "Tak ada cookie yang dimuat. Mencoba menyambung tanpanya."
+
+#: ../src/pulse/context.c:682
+#, c-format
+msgid "fork(): %s"
+msgstr "fork(): %s"
+
+#: ../src/pulse/context.c:737
+#, c-format
+msgid "waitpid(): %s"
+msgstr "waitpid(): %s"
+
+#: ../src/pulse/context.c:1434
+#, c-format
+msgid "Received message for unknown extension '%s'"
+msgstr "Menerima pesan bagi pengaya tak dikenal '%s'"
+
+#: ../src/utils/pacat.c:110
+#, c-format
+msgid "Failed to drain stream: %s"
+msgstr "Gagal menguras stream: %s"
+
+#: ../src/utils/pacat.c:115
+msgid "Playback stream drained."
+msgstr "Stream main ulang terkuras."
+
+#: ../src/utils/pacat.c:125
+msgid "Draining connection to server."
+msgstr "Menguras sambungan ke server."
+
+#: ../src/utils/pacat.c:138
+#, c-format
+msgid "pa_stream_drain(): %s"
+msgstr "pa_stream_drain(): %s"
+
+#: ../src/utils/pacat.c:161
+#, c-format
+msgid "pa_stream_write() failed: %s"
+msgstr "pa_stream_write() gagal: %s"
+
+#: ../src/utils/pacat.c:202
+#, c-format
+msgid "pa_stream_begin_write() failed: %s"
+msgstr "pa_stream_begin_write() gagal: %s"
+
+#: ../src/utils/pacat.c:252 ../src/utils/pacat.c:282
+#, c-format
+msgid "pa_stream_peek() failed: %s"
+msgstr "pa_stream_peek() gagal: %s"
+
+#: ../src/utils/pacat.c:322
+msgid "Stream successfully created."
+msgstr "Stream sukses dibuat."
+
+#: ../src/utils/pacat.c:325
+#, c-format
+msgid "pa_stream_get_buffer_attr() failed: %s"
+msgstr "pa_stream_get_buffer_attr() gagal: %s"
+
+#: ../src/utils/pacat.c:329
+#, c-format
+msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
+msgstr "Metrik penyangga: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
+
+#: ../src/utils/pacat.c:332
+#, c-format
+msgid "Buffer metrics: maxlength=%u, fragsize=%u"
+msgstr "Metrik penyangga: maxlength=%u, fragsize=%u"
+
+#: ../src/utils/pacat.c:336
+#, c-format
+msgid "Using sample spec '%s', channel map '%s'."
+msgstr "Memakai spek cuplikan '%s', peta kanal '%s'."
+
+#: ../src/utils/pacat.c:340
+#, c-format
+msgid "Connected to device %s (%u, %ssuspended)."
+msgstr "Tersambung ke perangkat %s (%u, %stersuspensi)."
+
+#: ../src/utils/pacat.c:350
+#, c-format
+msgid "Stream error: %s"
+msgstr "Galat stream: %s"
+
+#: ../src/utils/pacat.c:360
+#, c-format
+msgid "Stream device suspended.%s"
+msgstr "Perangkat stream disuspensi.%s"
+
+#: ../src/utils/pacat.c:362
+#, c-format
+msgid "Stream device resumed.%s"
+msgstr "Perangkat stream dilanjutkan.%s"
+
+#: ../src/utils/pacat.c:370
+#, c-format
+msgid "Stream underrun.%s"
+msgstr "Stream underrun.%s"
+
+#: ../src/utils/pacat.c:377
+#, c-format
+msgid "Stream overrun.%s"
+msgstr "Stream tertimpa.%s"
+
+#: ../src/utils/pacat.c:384
+#, c-format
+msgid "Stream started.%s"
+msgstr "Stream dimulai.%s"
+
+#: ../src/utils/pacat.c:391
+#, c-format
+msgid "Stream moved to device %s (%u, %ssuspended).%s"
+msgstr "Stream dipindah ke perangkat %s (%u, %sdisuspensi).%s"
+
+#: ../src/utils/pacat.c:391
+msgid "not "
+msgstr "tidak"
+
+#: ../src/utils/pacat.c:398
+#, c-format
+msgid "Stream buffer attributes changed.%s"
+msgstr "Atribut penyangga stream diubah.%s"
+
+#: ../src/utils/pacat.c:430
+#, c-format
+msgid "Connection established.%s"
+msgstr "Koneksi terbentuk.%s"
+
+#: ../src/utils/pacat.c:433
+#, c-format
+msgid "pa_stream_new() failed: %s"
+msgstr "pa_stream_new() gagal: %s"
+
+#: ../src/utils/pacat.c:471
+#, c-format
+msgid "pa_stream_connect_playback() failed: %s"
+msgstr "pa_stream_connect_playback() gagal: %s"
+
+#: ../src/utils/pacat.c:477
+#, c-format
+msgid "pa_stream_connect_record() failed: %s"
+msgstr "pa_stream_connect_record() gagal: %s"
+
+#: ../src/utils/pacat.c:491 ../src/utils/pactl.c:949
+#, c-format
+msgid "Connection failure: %s"
+msgstr "Kegagalan koneksi: %s"
+
+#: ../src/utils/pacat.c:524
+msgid "Got EOF."
+msgstr "Mendapat EOF."
+
+#: ../src/utils/pacat.c:561
+#, c-format
+msgid "write() failed: %s"
+msgstr "write() gagal: %s"
+
+#: ../src/utils/pacat.c:582
+msgid "Got signal, exiting."
+msgstr "Mendapat sinyal, keluar."
+
+#: ../src/utils/pacat.c:596
+#, c-format
+msgid "Failed to get latency: %s"
+msgstr "Gagal mendapat latensi: %s"
+
+#: ../src/utils/pacat.c:601
+#, c-format
+msgid "Time: %0.3f sec; Latency: %0.0f usec."
+msgstr "Waktu: %0.3f dtk; Latensi: %0.0f udtk."
+
+#: ../src/utils/pacat.c:620
+#, c-format
+msgid "pa_stream_update_timing_info() failed: %s"
+msgstr "pa_stream_update_timing_info() gagal: %s"
+
+#: ../src/utils/pacat.c:630
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"\n"
+"  -r, --record                          Create a connection for recording\n"
+"  -p, --playback                        Create a connection for playback\n"
+"\n"
+"  -v, --verbose                         Enable verbose operations\n"
+"\n"
+"  -s, --server=SERVER                   The name of the server to connect to\n"
+"  -d, --device=DEVICE                   The name of the sink/source to connect to\n"
+"  -n, --client-name=NAME                How to call this client on the server\n"
+"      --stream-name=NAME                How to call this stream on the server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume in range 0...65536\n"
+"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to 44100)\n"
+"      --format=SAMPLEFORMAT             The sample type, one of s16le, s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be, s24le, s24be,\n"
+"                                        s24-32le, s24-32be (defaults to s16ne)\n"
+"      --channels=CHANNELS               The number of channels, 1 for mono, 2 for stereo\n"
+"                                        (defaults to 2)\n"
+"      --channel-map=CHANNELMAP          Channel map to use instead of the default\n"
+"      --fix-format                      Take the sample format from the sink the stream is\n"
+"                                        being connected to.\n"
+"      --fix-rate                        Take the sampling rate from the sink the stream is\n"
+"                                        being connected to.\n"
+"      --fix-channels                    Take the number of channels and the channel map\n"
+"                                        from the sink the stream is being connected to.\n"
+"      --no-remix                        Don't upmix or downmix channels.\n"
+"      --no-remap                        Map channels by index instead of name.\n"
+"      --latency=BYTES                   Request the specified latency in bytes.\n"
+"      --process-time=BYTES              Request the specified process time per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time per request in msec.\n"
+"      --property=PROPERTY=VALUE         Set the specified property to the specified value.\n"
+"      --raw                             Record/play raw PCM data.\n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
+"      --list-file-formats               List available file formats.\n"
+msgstr "%s [opsi]\n\n  -h, --help                            Tampilkan bantuan ini\n      --version                         Tampilkan versi\n\n  -r, --record                          Buat koneksi untuk perekaman\n  -p, --playback                        Buat koneksi untuk main ulang\n\n  -v, --verbose                         Aktifkan operasi cerewet\n\n  -s, --server=SERVER                   Nama server untuk dihubungi\n  -d, --device=DEVICE                   Nama muara/sumber untuk dihubungi\n  -n, --client-name=NAME                Bagaimana memanggil klien ini di server\n      --stream-name=NAME                Bagaimana memanggil stream ini di server\n      --volume=VOLUME                   Nyatakan volume awal (linier) dalam jangkauan 0...65536\n      --rate=SAMPLERATE                 Laju cuplikan dalam Hz (nilai baku 44100)\n      --format=SAMPLEFORMAT             Jenis cuplikan, salah satu dari s16le, s16be, u8, float32le,\n                                        float32be, ulaw, alaw, s32le, s32be, s24le, s24be,\n                                        s24-32le, s24-32be (nilai baku s16ne)\n      --channels=CHANNELS               Cacah kanal, 1 untuk mono, 2 untuk stereo\n                                        (nilai baku 2)      --channel-map=CHANNELMAP          Peta kanal yang dipakai sebagai pengganti baku\n      --fix-format                      Ambil format cuplikan dari muara stream\n                                        yang sedang tersambung.\n      --fix-rate                        Ambil laju cuplikan dari muara stream\n                                        yang sedang tersambung.\n      --fix-channels                    Ambil cacah kanal dan peta kanal dari muara stream\n                                        yang sedang tersambung.\n      --no-remix                        Jangan upmix atau downmix kanal.\n\n      --no-remap                        Petakan kanal berdasar indeks bukan nama.\n      --latency=BYTES                   Minta latensi yang dinyatakan, dalam byte.\n      --process-time=BYTES              Minta waktu proses yang dinyatakan bagi tiap permintaan\n                                        dalam byte.\n      --latency-msec=MSEC               Minta latensi yang dinyatakan, dalam milidetik.\n      --process-time-msec=MSEC          Minta waktu proses yang dinyatakan bagi tiap permintaan\n                                        dalam milidetik.\n      --property=PROPERTY=VALUE         Tata properti yang dinyatakan ke nilai yang dinyatakan.\n      --raw                             Rekam/mainkan data PCM mentah.\n      --file-format[=FFORMAT]           Rekam/mainkan data PCM terformat.\n      --list-file-formats               Tampilkan daftar format berkas yang tersedia.\n"
+
+#: ../src/utils/pacat.c:758
+#, c-format
+msgid ""
+"pacat %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr "pacat %s\nDikompail dengan libpulse %s\nDitaut dengan libpulse %s\n"
+
+#: ../src/utils/pacat.c:791 ../src/utils/pactl.c:1046
+#, c-format
+msgid "Invalid client name '%s'"
+msgstr "Nama klien '%s' tak valid"
+
+#: ../src/utils/pacat.c:806
+#, c-format
+msgid "Invalid stream name '%s'"
+msgstr "Nama stream '%s' tak valid"
+
+#: ../src/utils/pacat.c:843
+#, c-format
+msgid "Invalid channel map '%s'"
+msgstr "Peta kanal '%s' tak valid"
+
+#: ../src/utils/pacat.c:872 ../src/utils/pacat.c:886
+#, c-format
+msgid "Invalid latency specification '%s'"
+msgstr "Spesifikasi latensi '%s' tak valid"
+
+#: ../src/utils/pacat.c:879 ../src/utils/pacat.c:893
+#, c-format
+msgid "Invalid process time specification '%s'"
+msgstr "Spesifikasi waktu proses '%s' tak valid"
+
+#: ../src/utils/pacat.c:905
+#, c-format
+msgid "Invalid property '%s'"
+msgstr "Properti '%s' tak valid"
+
+#: ../src/utils/pacat.c:922
+#, c-format
+msgid "Unknown file format %s."
+msgstr "Format berkas %s tak dikenal."
+
+#: ../src/utils/pacat.c:941
+msgid "Invalid sample specification"
+msgstr "Spesifikasi cuplikan tak valid"
+
+#: ../src/utils/pacat.c:951
+#, c-format
+msgid "open(): %s"
+msgstr "open(): %s"
+
+#: ../src/utils/pacat.c:956
+#, c-format
+msgid "dup2(): %s"
+msgstr "dup2(): %s"
+
+#: ../src/utils/pacat.c:963
+msgid "Too many arguments."
+msgstr "Terlalu banyak argumen."
+
+#: ../src/utils/pacat.c:974
+msgid "Failed to generate sample specification for file."
+msgstr "Gagal menjangkitkan spesifikasi cuplikan bagi berkas."
+
+#: ../src/utils/pacat.c:994
+msgid "Failed to open audio file."
+msgstr "Gagal membuka berkas audio."
+
+#: ../src/utils/pacat.c:1000
+msgid ""
+"Warning: specified sample specification will be overwritten with "
+"specification from file."
+msgstr "Peringatan: spesifikasi cuplikan yang dinyatakan akan ditimpa oleh spesifikasi dari berkas."
+
+#: ../src/utils/pacat.c:1003 ../src/utils/pactl.c:1090
+msgid "Failed to determine sample specification from file."
+msgstr "Gagal menentukan spesifikasi cuplikan dari berkas."
+
+#: ../src/utils/pacat.c:1012
+msgid "Warning: Failed to determine channel map from file."
+msgstr "Peringatan: Gagal menentukan peta kanal dari berkas."
+
+#: ../src/utils/pacat.c:1023
+msgid "Channel map doesn't match sample specification"
+msgstr "Peta kanan tak cocok dengan spesifikasi cuplikan"
+
+#: ../src/utils/pacat.c:1034
+msgid "Warning: failed to write channel map to file."
+msgstr "Peringatan: gagal menulis peta kanal ke berkas."
+
+#: ../src/utils/pacat.c:1049
+#, c-format
+msgid ""
+"Opening a %s stream with sample specification '%s' and channel map '%s'."
+msgstr "Sedang membuka stream %s dengan spesifikasi cuplikan '%s' dan peta kanal '%s'."
+
+#: ../src/utils/pacat.c:1050
+msgid "recording"
+msgstr "merekam"
+
+#: ../src/utils/pacat.c:1050
+msgid "playback"
+msgstr "memainkan"
+
+#: ../src/utils/pacat.c:1076 ../src/utils/pactl.c:1364
+msgid "pa_mainloop_new() failed."
+msgstr "pa_mainloop_new() gagal."
+
+#: ../src/utils/pacat.c:1095
+msgid "io_new() failed."
+msgstr "io_new() gagal."
+
+#: ../src/utils/pacat.c:1102 ../src/utils/pactl.c:1376
+msgid "pa_context_new() failed."
+msgstr "pa_context_new() gagal."
+
+#: ../src/utils/pacat.c:1110 ../src/utils/pactl.c:1382
+#, c-format
+msgid "pa_context_connect() failed: %s"
+msgstr "pa_context_connect() gagal: %s"
+
+#: ../src/utils/pacat.c:1116
+msgid "pa_context_rttime_new() failed."
+msgstr "pa_context_rttime_new() gagal."
+
+#: ../src/utils/pacat.c:1123 ../src/utils/pactl.c:1387
+msgid "pa_mainloop_run() failed."
+msgstr "pa_mainloop_run() gagal."
+
+#: ../src/utils/pasuspender.c:79
+#, c-format
+msgid "fork(): %s\n"
+msgstr "fork(): %s\n"
+
+#: ../src/utils/pasuspender.c:90
+#, c-format
+msgid "execvp(): %s\n"
+msgstr "execvp(): %s\n"
+
+#: ../src/utils/pasuspender.c:107
+#, c-format
+msgid "Failure to suspend: %s\n"
+msgstr "Gagal mensuspensi: %s\n"
+
+#: ../src/utils/pasuspender.c:122
+#, c-format
+msgid "Failure to resume: %s\n"
+msgstr "Gagal melanjutkan: %s\n"
+
+#: ../src/utils/pasuspender.c:145
+#, c-format
+msgid "WARNING: Sound server is not local, not suspending.\n"
+msgstr "PERINGATAN: Server suara bukan lokal, tidak mensuspensi.\n"
+
+#: ../src/utils/pasuspender.c:157
+#, c-format
+msgid "Connection failure: %s\n"
+msgstr "Kegagalan sambungan: %s\n"
+
+#: ../src/utils/pasuspender.c:174
+#, c-format
+msgid "Got SIGINT, exiting.\n"
+msgstr "Mendapat SIGINT, keluar.\n"
+
+#: ../src/utils/pasuspender.c:192
+#, c-format
+msgid "WARNING: Child process terminated by signal %u\n"
+msgstr "PERINGATAN: Proses anak diakhiri oleh sinyal %u\n"
+
+#: ../src/utils/pasuspender.c:210
+#, c-format
+msgid ""
+"%s [options] ... \n"
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"  -s, --server=SERVER                   The name of the server to connect to\n"
+"\n"
+msgstr "%s [opsi] ... \n\n  -h, --help                            Tampilkan bantuan ini\n      --version                         Tampilkan versi\n  -s, --server=SERVER                   Nama server untuk dihubungi\n\n"
+
+#: ../src/utils/pasuspender.c:246
+#, c-format
+msgid ""
+"pasuspender %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr "pasuspender %s\nDikompail dengan libpulse %s\nDitaut dengan libpulse %s\n"
+
+#: ../src/utils/pasuspender.c:275
+#, c-format
+msgid "pa_mainloop_new() failed.\n"
+msgstr "pa_mainloop_new() gagal.\n"
+
+#: ../src/utils/pasuspender.c:288
+#, c-format
+msgid "pa_context_new() failed.\n"
+msgstr "pa_context_new() gagal.\n"
+
+#: ../src/utils/pasuspender.c:296
+#, c-format
+msgid "pa_mainloop_run() failed.\n"
+msgstr "pa_mainloop_run() gagal.\n"
+
+#: ../src/utils/pactl.c:134
+#, c-format
+msgid "Failed to get statistics: %s"
+msgstr "Gagal mendapat statistik: %s"
+
+#: ../src/utils/pactl.c:140
+#, c-format
+msgid "Currently in use: %u blocks containing %s bytes total.\n"
+msgstr "Sedang dipakai: %u blok memuat total %s byte.\n"
+
+#: ../src/utils/pactl.c:143
+#, c-format
+msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
+msgstr "Dialokasikan dalam seluruh masa hidup: %u blok memuat total %s byte.\n"
+
+#: ../src/utils/pactl.c:146
+#, c-format
+msgid "Sample cache size: %s\n"
+msgstr "Ukuran singgahan cuplikan: %s\n"
+
+#: ../src/utils/pactl.c:155
+#, c-format
+msgid "Failed to get server information: %s"
+msgstr "Gagal mendapat informasi server: %s"
+
+#: ../src/utils/pactl.c:160
+#, c-format
+msgid ""
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr "String Server: %s\nVersi Protokol Pustaka: %u\nVersi Protokol Server: %u\nDi Lokal: %s\nIndeks Klien: %u\nUkuran Ubin: %zu\n"
+
+#: ../src/utils/pactl.c:176
+#, c-format
+msgid ""
+"User Name: %s\n"
+"Host Name: %s\n"
+"Server Name: %s\n"
+"Server Version: %s\n"
+"Default Sample Specification: %s\n"
+"Default Channel Map: %s\n"
+"Default Sink: %s\n"
+"Default Source: %s\n"
+"Cookie: %04x:%04x\n"
+msgstr "Nama Pengguna: %s\nNama Host: %s\nNama Server: %s\nVersi Server: %s\nSpesifikasi Cuplikan Baku: %s\nPeta Kanal Baku: %s\nMuara Baku: %s\nSumber Baku: %s\nCookie: %04x:%04x\n"
+
+#: ../src/utils/pactl.c:218
+#, c-format
+msgid "Failed to get sink information: %s"
+msgstr "Gagal mendapat informasi muara: %s"
+
+#: ../src/utils/pactl.c:234
+#, c-format
+msgid ""
+"Sink #%u\n"
+"\tState: %s\n"
+"\tName: %s\n"
+"\tDescription: %s\n"
+"\tDriver: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tOwner Module: %u\n"
+"\tMute: %s\n"
+"\tVolume: %s%s%s\n"
+"\t        balance %0.2f\n"
+"\tBase Volume: %s%s%s\n"
+"\tMonitor Source: %s\n"
+"\tLatency: %0.0f usec, configured %0.0f usec\n"
+"\tFlags: %s%s%s%s%s%s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr "Muara #%u\n\tKeadaan: %s\n\tNama: %s\n\tKeterangan: %s\n\tDriver: %s\n\tSpesifikasi Cuplikan: %s\n\tPeta Kanal: %s\n\tModul Pemilik: %u\n\tSenyap: %s\n\tVolume: %s%s%s\n\t        balans %0.2f\n\tVolume Dasar: %s%s%s\n\tSumber Pemantau: %s\n\tLatensi: %0.0f usec, dikonfigurasi %0.0f usec\n\tBendera: %s%s%s%s%s%s\n\tProperti:\n\t\t%s\n"
+
+#: ../src/utils/pactl.c:281 ../src/utils/pactl.c:373
+#, c-format
+msgid "\tPorts:\n"
+msgstr "»Port:\n"
+
+#: ../src/utils/pactl.c:287 ../src/utils/pactl.c:379
+#, c-format
+msgid "\tActive Port: %s\n"
+msgstr "»Port Aktif: %s\n"
+
+#: ../src/utils/pactl.c:310
+#, c-format
+msgid "Failed to get source information: %s"
+msgstr "Gagal mendapat informasi sumber: %s"
+
+#: ../src/utils/pactl.c:326
+#, c-format
+msgid ""
+"Source #%u\n"
+"\tState: %s\n"
+"\tName: %s\n"
+"\tDescription: %s\n"
+"\tDriver: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tOwner Module: %u\n"
+"\tMute: %s\n"
+"\tVolume: %s%s%s\n"
+"\t        balance %0.2f\n"
+"\tBase Volume: %s%s%s\n"
+"\tMonitor of Sink: %s\n"
+"\tLatency: %0.0f usec, configured %0.0f usec\n"
+"\tFlags: %s%s%s%s%s%s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr "Sumber #%u\n\tKeadaan: %s\n\tNama: %s\n\tKeterangan: %s\n\tDriver: %s\n\tSpesifikasi Cuplikan: %s\n\tPeta Kanal: %s\n\tModul Pemilik: %u\n\tSenyap: %s\n\tVolume: %s%s%s\n\t        balans %0.2f\n\tVolume Dasar: %s%s%s\n\tPemantau Muara: %s\n\tLatensi: %0.0f usec, dikonfigurasi %0.0f usec\n\tBendera: %s%s%s%s%s%s\n\tProperti:\n\t\t%s\n"
+
+#: ../src/utils/pactl.c:358 ../src/utils/pactl.c:414 ../src/utils/pactl.c:449
+#: ../src/utils/pactl.c:486 ../src/utils/pactl.c:545 ../src/utils/pactl.c:546
+#: ../src/utils/pactl.c:556 ../src/utils/pactl.c:600 ../src/utils/pactl.c:601
+#: ../src/utils/pactl.c:607 ../src/utils/pactl.c:650 ../src/utils/pactl.c:651
+#: ../src/utils/pactl.c:658
+msgid "n/a"
+msgstr "t/t"
+
+#: ../src/utils/pactl.c:388
+#, c-format
+msgid "Failed to get module information: %s"
+msgstr "Gagal mendapat informasi modul: %s"
+
+#: ../src/utils/pactl.c:406
+#, c-format
+msgid ""
+"Module #%u\n"
+"\tName: %s\n"
+"\tArgument: %s\n"
+"\tUsage counter: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr "Modul #%u\n\tNama: %s\n\tArgumen: %s\n\tPencacah pemakaian: %s\n\tProperti:\n\t\t%s\n"
+
+#: ../src/utils/pactl.c:425
+#, c-format
+msgid "Failed to get client information: %s"
+msgstr "Gagal mendapat informasi klien: %s"
+
+#: ../src/utils/pactl.c:443
+#, c-format
+msgid ""
+"Client #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr "Klien #%u\n\tDriver: %s\n\tModul Pemilik: %s\n\tProperti:\n\t\t%s\n"
+
+#: ../src/utils/pactl.c:460
+#, c-format
+msgid "Failed to get card information: %s"
+msgstr "Gagal mendapat informasi kartu: %s"
+
+#: ../src/utils/pactl.c:478
+#, c-format
+msgid ""
+"Card #%u\n"
+"\tName: %s\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr "Kartu #%u\n\tNama: %s\n\tDriver: %s\n\tModul Pemilik: %s\n\tProperti:\n\t\t%s\n"
+
+#: ../src/utils/pactl.c:492
+#, c-format
+msgid "\tProfiles:\n"
+msgstr "\tProfil:\n"
+
+#: ../src/utils/pactl.c:498
+#, c-format
+msgid "\tActive Profile: %s\n"
+msgstr "\tProfil Aktif: %s\n"
+
+#: ../src/utils/pactl.c:509
+#, c-format
+msgid "Failed to get sink input information: %s"
+msgstr "Gagal mendapat informasi masukan muara: %s"
+
+#: ../src/utils/pactl.c:528
+#, c-format
+msgid ""
+"Sink Input #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tClient: %s\n"
+"\tSink: %u\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
+"\tBuffer Latency: %0.0f usec\n"
+"\tSink Latency: %0.0f usec\n"
+"\tResample method: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr "Masukan Muara #%u\n\tDriver: %s\n\tModul Pemilik: %s\n\tKlien: %s\n\tMuara: %u\n\tSpesifikasi Cuplikan: %s\n\tPeta Kanal: %s\n\tSenyap: %s\n\tVolume: %s\n\t        %s\n\t        balans %0.2f\n\tLatensi Penyangga: %0.0f usec\n\tLatensi Muara: %0.0f usec\n\tMetoda cuplik ulang: %s\n\tProperti:\n\t\t%s\n"
+
+#: ../src/utils/pactl.c:567
+#, c-format
+msgid "Failed to get source output information: %s"
+msgstr "Gagal mendapat informasi keluaran sumber: %s"
+
+#: ../src/utils/pactl.c:587
+#, c-format
+msgid ""
+"Source Output #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tClient: %s\n"
+"\tSource: %u\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tBuffer Latency: %0.0f usec\n"
+"\tSource Latency: %0.0f usec\n"
+"\tResample method: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr "Luaran Sumber #%u\n\tDriver: %s\n\tModul Pemilik: %s\n\tKlien: %s\n\tSumber: %u\n\tSpesifikasi Cuplikan: %s\n\tPeta Kanal: %s\n\tLatensi Penyangga: %0.0f usec\n\tLatensi Sumber: %0.0f usec\n\tMetoda cuplik ulang: %s\n\tProperti:\n\t\t%s\n"
+
+#: ../src/utils/pactl.c:618
+#, c-format
+msgid "Failed to get sample information: %s"
+msgstr "Gagal mendapat informasi cuplikan: %s"
+
+#: ../src/utils/pactl.c:636
+#, c-format
+msgid ""
+"Sample #%u\n"
+"\tName: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
+"\tDuration: %0.1fs\n"
+"\tSize: %s\n"
+"\tLazy: %s\n"
+"\tFilename: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr "Cuplikan #%u\n\tNama: %s\n\tSpesifikasi Cuplikan: %s\n\tPeta Kanal: %s\n\tVolume: %s\n\t        %s\n\t        balans %0.2f\n\tDurasi: %0.1fs\n\tUkuran: %s\n\tMalas: %s\n\tNama Berkas: %s\n\tProperti:\n\t\t%s\n"
+
+#: ../src/utils/pactl.c:666 ../src/utils/pactl.c:676
+#, c-format
+msgid "Failure: %s"
+msgstr "Kegagalan: %s"
+
+#: ../src/utils/pactl.c:700
+#, c-format
+msgid "Failed to upload sample: %s"
+msgstr "Gagal mengunggah cuplikan: %s"
+
+#: ../src/utils/pactl.c:717
+msgid "Premature end of file"
+msgstr "Akhir berkas dini"
+
+#: ../src/utils/pactl.c:737
+msgid "new"
+msgstr "baru"
+
+#: ../src/utils/pactl.c:740
+msgid "change"
+msgstr "ubah"
+
+#: ../src/utils/pactl.c:743
+msgid "remove"
+msgstr "hapus"
+
+#: ../src/utils/pactl.c:746 ../src/utils/pactl.c:781
+msgid "unknown"
+msgstr "tak dikenal"
+
+#: ../src/utils/pactl.c:754
+msgid "sink"
+msgstr "muara"
+
+#: ../src/utils/pactl.c:757
+msgid "source"
+msgstr "sumber"
+
+#: ../src/utils/pactl.c:760
+msgid "sink-input"
+msgstr "masukan-muara"
+
+#: ../src/utils/pactl.c:763
+msgid "source-output"
+msgstr "sumber-keluaran"
+
+#: ../src/utils/pactl.c:766
+msgid "module"
+msgstr "modul"
+
+#: ../src/utils/pactl.c:769
+msgid "client"
+msgstr "klien"
+
+#: ../src/utils/pactl.c:772
+msgid "sample-cache"
+msgstr "singgahan-cuplikan"
+
+#: ../src/utils/pactl.c:775 ../src/utils/pactl.c:778
+msgid "server"
+msgstr "server"
+
+#: ../src/utils/pactl.c:787
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr "Kejadian '%s' pada %s #%u\n"
+
+#: ../src/utils/pactl.c:955
+msgid "Got SIGINT, exiting."
+msgstr "Mendapat SIGINT, keluar."
+
+#: ../src/utils/pactl.c:961
+#, c-format
+msgid ""
+"%s [options] stat\n"
+"%s [options] list\n"
+"%s [options] exit\n"
+"%s [options] upload-sample FILENAME [NAME]\n"
+"%s [options] play-sample NAME [SINK]\n"
+"%s [options] remove-sample NAME\n"
+"%s [options] move-sink-input SINKINPUT SINK\n"
+"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+"%s [options] load-module NAME [ARGS ...]\n"
+"%s [options] unload-module MODULE\n"
+"%s [options] suspend-sink SINK 1|0\n"
+"%s [options] suspend-source SOURCE 1|0\n"
+"%s [options] set-card-profile CARD PROFILE\n"
+"%s [options] set-sink-port SINK PORT\n"
+"%s [options] set-source-port SOURCE PORT\n"
+"%s [options] set-sink-volume SINK VOLUME\n"
+"%s [options] set-source-volume SOURCE VOLUME\n"
+"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+"%s [options] set-sink-mute SINK 1|0\n"
+"%s [options] set-source-mute SOURCE 1|0\n"
+"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+"%s [options] subscribe\n"
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"\n"
+"  -s, --server=SERVER                   The name of the server to connect to\n"
+"  -n, --client-name=NAME                How to call this client on the server\n"
+msgstr "%s [opsi] stat\n%s [opsi] list\n%s [opsi] exit\n%s [opsi] upload-sample NAMABERKAS [NAMA]\n%s [opsi] play-sample NAMA [MUARA]\n%s [opsi] remove-sample NAMA\n%s [opsi] move-sink-input MUARAINPUT MUARA\n%s [opsi] move-source-output SUMBEROUTPUT SUMBER\n%s [opsi] load-module NAMA [ARGS ...]\n%s [opsi] unload-module MODULE\n%s [opsi] suspend-sink MUARA 1|0\n%s [opsi] suspend-source SUMBER 1|0\n%s [opsi] set-card-profile CARD PROFILE\n%s [opsi] set-sink-port MUARA PORT\n%s [opsi] set-source-port SUMBER PORT\n%s [opsi] set-sink-volume MUARA VOLUME\n%s [opsi] set-source-volume SUMBER VOLUME\n%s [opsi] set-sink-input-volume MUARAINPUT VOLUME\n%s [opsi] set-sink-mute MUARA 1|0\n%s [opsi] set-source-mute SUMBER 1|0\n%s [opsi] set-sink-input-mute MUARAINPUT 1|0\n%s [opsi] subscribe\n\n  -h, --help                            Tampilkan bantuan ini\n      --version                         Tampilkan versi\n\n  -s, --server=SERVER                   Nama server untuk dihubungi  -n, --client-name=NAMA                Bagaimana memanggil klien ini di server\n"
+
+#: ../src/utils/pactl.c:1026
+#, c-format
+msgid ""
+"pactl %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr "pactl %s\nDikompail dengan libpulse %s\nDitaut dengan libpulse %s\n"
+
+#: ../src/utils/pactl.c:1072
+msgid "Please specify a sample file to load"
+msgstr "Nyatakan berkas cuplikan untuk dimuat"
+
+#: ../src/utils/pactl.c:1085
+msgid "Failed to open sound file."
+msgstr "Gagal membuka berkas suara."
+
+#: ../src/utils/pactl.c:1097
+msgid "Warning: Failed to determine sample specification from file."
+msgstr "Peringatan: Gagal menentukan spesifikasi cuplikan dari berkas."
+
+#: ../src/utils/pactl.c:1107
+msgid "You have to specify a sample name to play"
+msgstr "Anda mesti menyatakan nama cuplikan untuk diputar"
+
+#: ../src/utils/pactl.c:1119
+msgid "You have to specify a sample name to remove"
+msgstr "Anda mesti menyatakan nama cuplikan untuk dihapus"
+
+#: ../src/utils/pactl.c:1128
+msgid "You have to specify a sink input index and a sink"
+msgstr "Anda mesti menyatakan suatu indeks masukan muara dan suatu muara"
+
+#: ../src/utils/pactl.c:1138
+msgid "You have to specify a source output index and a source"
+msgstr "Anda mesti menyatakan suatu indeks keluaran sumber dan suatu sumber"
+
+#: ../src/utils/pactl.c:1153
+msgid "You have to specify a module name and arguments."
+msgstr "Anda mesti menyatakan nama modul dan argumen."
+
+#: ../src/utils/pactl.c:1173
+msgid "You have to specify a module index"
+msgstr "Anda mesti menyatakan indeks modul"
+
+#: ../src/utils/pactl.c:1183
+msgid ""
+"You may not specify more than one sink. You have to specify a boolean value."
+msgstr "Anda tak boleh menyatakan lebih dari satu muara. Anda mesti menyatakan suatu nilai bool."
+
+#: ../src/utils/pactl.c:1196
+msgid ""
+"You may not specify more than one source. You have to specify a boolean "
+"value."
+msgstr "Anda tak boleh menyatakan lebih dari satu sumber. Anda mesti menyatakan suatu nilai bool."
+
+#: ../src/utils/pactl.c:1208
+msgid "You have to specify a card name/index and a profile name"
+msgstr "Anda mesti menyatakan suatu indeks/nama kartu dan suatu nama profil"
+
+#: ../src/utils/pactl.c:1219
+msgid "You have to specify a sink name/index and a port name"
+msgstr "Anda mesti menyatakan suatu indeks/nama muara dan suatu nama port"
+
+#: ../src/utils/pactl.c:1230
+msgid "You have to specify a source name/index and a port name"
+msgstr "Anda mesti menyatakan suatu indeks/nama sumber dan suatu nama port"
+
+#: ../src/utils/pactl.c:1242
+msgid "You have to specify a sink name/index and a volume"
+msgstr "Anda mesti menyatakan suatu indeks/nama muara dan suatu volume"
+
+#: ../src/utils/pactl.c:1247 ../src/utils/pactl.c:1264
+#: ../src/utils/pactl.c:1286 ../src/utils/pactl.c:1302
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1341
+msgid "Invalid volume specification"
+msgstr "Spesifikasi volume tak valid"
+
+#: ../src/utils/pactl.c:1259
+msgid "You have to specify a source name/index and a volume"
+msgstr "Anda mesti menyatakan suatu indeks/nama sumber dan suatu volume"
+
+#: ../src/utils/pactl.c:1276
+msgid "You have to specify a sink input index and a volume"
+msgstr "Anda mesti menyatakan suatu indeks masukan muara dan suatu volume"
+
+#: ../src/utils/pactl.c:1281
+msgid "Invalid sink input index"
+msgstr "Indeks masukan muara tak valid"
+
+#: ../src/utils/pactl.c:1297
+msgid "You have to specify a sink name/index and a mute boolean"
+msgstr "Anda mesti menyatakan suatu indeks/nama muara dan suatu bool mute"
+
+#: ../src/utils/pactl.c:1314
+msgid "You have to specify a source name/index and a mute boolean"
+msgstr "Anda mesti menyatakan suatu indeks/nama sumber dan suatu bool mute"
+
+#: ../src/utils/pactl.c:1331
+msgid "You have to specify a sink input index and a mute boolean"
+msgstr "Anda mesti menyatakan indeks masukan muara dan suatu bool mute"
+
+#: ../src/utils/pactl.c:1336
+msgid "Invalid sink input index specification"
+msgstr "Spesifikasi index masukan muara tak valid"
+
+#: ../src/utils/pactl.c:1359
+msgid "No valid command specified."
+msgstr "Tak ada perintah valid yang dinyatakan."
+
+#: ../src/utils/pax11publish.c:61
+#, c-format
+msgid ""
+"%s [-D display] [-S server] [-O sink] [-I source] [-c file]  [-d|-e|-i|-r]\n"
+"\n"
+" -d    Show current PulseAudio data attached to X11 display (default)\n"
+" -e    Export local PulseAudio data to X11 display\n"
+" -i    Import PulseAudio data from X11 display to local environment variables and cookie file.\n"
+" -r    Remove PulseAudio data from X11 display\n"
+msgstr "%s [-D display] [-S server] [-O muara] [-I sumber] [-c file]  [-d|-e|-i|-r]\n\n -d    Tampilkan data PulseAudio yang kini dicantolkan ke tampilan X11 (baku)\n -e    Ekspor data PulseAudio lokal ke tampilan X11\n -i    Impor data PulseAudio dari tampilan X11 ke variabel lingkungan lokal dan berkas cookie.\n -r    Hapus data PulseAudio dari tampilan X11\n"
+
+#: ../src/utils/pax11publish.c:94
+#, c-format
+msgid "Failed to parse command line.\n"
+msgstr "Gagal mengurai baris perintah.\n"
+
+#: ../src/utils/pax11publish.c:108
+#, c-format
+msgid "Server: %s\n"
+msgstr "Server: %s\n"
+
+#: ../src/utils/pax11publish.c:110
+#, c-format
+msgid "Source: %s\n"
+msgstr "Sumber: %s\n"
+
+#: ../src/utils/pax11publish.c:112
+#, c-format
+msgid "Sink: %s\n"
+msgstr "Muara: %s\n"
+
+#: ../src/utils/pax11publish.c:114
+#, c-format
+msgid "Cookie: %s\n"
+msgstr "Cookie: %s\n"
+
+#: ../src/utils/pax11publish.c:132
+#, c-format
+msgid "Failed to parse cookie data\n"
+msgstr "Gagal mengurai data cookie\n"
+
+#: ../src/utils/pax11publish.c:137
+#, c-format
+msgid "Failed to save cookie data\n"
+msgstr "Gagal menyimpan data cookie\n"
+
+#: ../src/utils/pax11publish.c:152
+#, c-format
+msgid "Failed to load client configuration file.\n"
+msgstr "Gagal memuat berkas konfigurasi klien.\n"
+
+#: ../src/utils/pax11publish.c:157
+#, c-format
+msgid "Failed to read environment configuration data.\n"
+msgstr "Gagal membaca data konfigurasi lingkungan.\n"
+
+#: ../src/utils/pax11publish.c:174
+#, c-format
+msgid "Failed to get FQDN.\n"
+msgstr "Gagal mendapatkan FQDN.\n"
+
+#: ../src/utils/pax11publish.c:194
+#, c-format
+msgid "Failed to load cookie data\n"
+msgstr "Gagal memuat data cookie\n"
+
+#: ../src/utils/pax11publish.c:211
+#, c-format
+msgid "Not yet implemented.\n"
+msgstr "Belum diimplementasikan.\n"
+
+#: ../src/utils/pacmd.c:65
+msgid "No PulseAudio daemon running, or not running as session daemon."
+msgstr "Tak ada daemon PulseAudio yang berjalan, atau tak dijalankan sebagai daemon sesi."
+
+#: ../src/utils/pacmd.c:70
+#, c-format
+msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
+msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
+
+#: ../src/utils/pacmd.c:87
+#, c-format
+msgid "connect(): %s"
+msgstr "connect(): %s"
+
+#: ../src/utils/pacmd.c:95
+msgid "Failed to kill PulseAudio daemon."
+msgstr "Gagal mematikan daemon PulseAudio."
+
+#: ../src/utils/pacmd.c:103
+msgid "Daemon not responding."
+msgstr "Daemon tidak merespon."
+
+#: ../src/utils/pacmd.c:178
+#, c-format
+msgid "poll(): %s"
+msgstr "poll(): %s"
+
+#: ../src/utils/pacmd.c:189 ../src/utils/pacmd.c:209
+#, c-format
+msgid "read(): %s"
+msgstr "read(): %s"
+
+#: ../src/utils/pacmd.c:231 ../src/utils/pacmd.c:249
+#, c-format
+msgid "write(): %s"
+msgstr "write(): %s"
+
+#: ../src/pulsecore/lock-autospawn.c:134 ../src/pulsecore/lock-autospawn.c:217
+msgid "Cannot access autospawn lock."
+msgstr "Tak bisa akses kunci spawn sendiri."
+
+#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#, 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 bangun untuk menulis data baru ke perangkat, tapi sebenarnya tak ada sesuatu untuk ditulis!\nSangat mungkin ini adalah kutu pada driver ALSA '%s'. Silakan laporkan masalah ini ke para pengembang ALSA.\nKami dibangunkan dengan POLLOUT diset -- namun snd_pcm_avail() setelahnya mengembalikan 0 atau nilai lain < min_avail."
+
+#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#, 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 bangun untuk membaca data baru dari perangkat, tapi sebenarnya tak ada sesuatu untuk dibaca!\nSangat mungkin ini adalah kutu pada driver ALSA '%s'. Silakan laporkan masalah ini ke para pengembang ALSA.\nKami dibangunkan dengan POLLIN diset -- namun snd_pcm_avail() setelahnya mengembalikan 0 atau nilai lain < min_avail."
+
+#: ../src/modules/alsa/module-alsa-card.c:152
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2262
+#: ../src/modules/alsa/alsa-mixer.c:2936
+msgid "Off"
+msgstr "Mati"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2204
+msgid "High Fidelity Playback (A2DP)"
+msgstr "Main Ulang High Fidelity (A2DP)"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2218
+msgid "High Fidelity Capture (A2DP)"
+msgstr "High Fidelity Capture (A2DP)"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2233
+msgid "Telephony Duplex (HSP/HFP)"
+msgstr "Dupleks Teleponi (HSP/HFP)"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2247
+msgid "Handsfree Gateway"
+msgstr "Gateway Handsfree"
+
+#: ../src/modules/reserve-wrap.c:151
+msgid "PulseAudio Sound Server"
+msgstr "Server Suara PulseAudio"
+
+#: ../src/modules/module-rygel-media-server.c:592
+#: ../src/modules/module-rygel-media-server.c:606
+msgid "Output Devices"
+msgstr "Perangkat Keluaran"
+
+#: ../src/modules/module-rygel-media-server.c:593
+#: ../src/modules/module-rygel-media-server.c:607
+msgid "Input Devices"
+msgstr "Perangkat Masukan"
+
+#: ../src/modules/module-rygel-media-server.c:797
+msgid "Audio on @HOSTNAME@"
+msgstr "Audio pada @HOSTNAME@"
+
+#: ../src/modules/alsa/alsa-mixer.c:1701
+msgid "Input"
+msgstr "Masukan"
+
+#: ../src/modules/alsa/alsa-mixer.c:1702
+msgid "Docking Station Input"
+msgstr "Masukan Docking Station"
+
+#: ../src/modules/alsa/alsa-mixer.c:1703
+msgid "Docking Station Microphone"
+msgstr "Mikrofon Docking Station"
+
+#: ../src/modules/alsa/alsa-mixer.c:1704
+msgid "Line-In"
+msgstr "Line-In"
+
+#: ../src/modules/alsa/alsa-mixer.c:1705
+msgid "Microphone"
+msgstr "Mikrofon"
+
+#: ../src/modules/alsa/alsa-mixer.c:1706
+msgid "External Microphone"
+msgstr "Mikrofon Eksternal"
+
+#: ../src/modules/alsa/alsa-mixer.c:1707
+msgid "Internal Microphone"
+msgstr "Mikrofon Internal"
+
+#: ../src/modules/alsa/alsa-mixer.c:1708
+msgid "Radio"
+msgstr "Radio"
+
+#: ../src/modules/alsa/alsa-mixer.c:1709
+msgid "Video"
+msgstr "Video"
+
+#: ../src/modules/alsa/alsa-mixer.c:1710
+msgid "Automatic Gain Control"
+msgstr "Kendali Penguatan Otomatis (AGC)"
+
+#: ../src/modules/alsa/alsa-mixer.c:1711
+msgid "No Automatic Gain Control"
+msgstr "Tanpa Kendali Penguatan Otomatis (AGC)"
+
+#: ../src/modules/alsa/alsa-mixer.c:1712
+msgid "Boost"
+msgstr "Boost"
+
+#: ../src/modules/alsa/alsa-mixer.c:1713
+msgid "No Boost"
+msgstr "Tanpa Boost"
+
+#: ../src/modules/alsa/alsa-mixer.c:1714
+msgid "Amplifier"
+msgstr "Penguat"
+
+#: ../src/modules/alsa/alsa-mixer.c:1715
+msgid "No Amplifier"
+msgstr "Tanpa Penguat"
+
+#: ../src/modules/alsa/alsa-mixer.c:1716
+msgid "Bass Boost"
+msgstr "Boost Bass"
+
+#: ../src/modules/alsa/alsa-mixer.c:1717
+msgid "No Bass Boost"
+msgstr "Tanpa Boost Bass"
+
+#: ../src/modules/alsa/alsa-mixer.c:1718
+msgid "Speaker"
+msgstr "Speaker"
+
+#: ../src/modules/alsa/alsa-mixer.c:1719
+msgid "Headphones"
+msgstr "Headphone"
+
+#: ../src/modules/alsa/alsa-mixer.c:1777
+msgid "Analog Input"
+msgstr "Masukan Analog"
+
+#: ../src/modules/alsa/alsa-mixer.c:1778
+msgid "Analog Microphone"
+msgstr "Mikrofon Analog"
+
+#: ../src/modules/alsa/alsa-mixer.c:1779
+msgid "Analog Line-In"
+msgstr "Line-In Analog"
+
+#: ../src/modules/alsa/alsa-mixer.c:1780
+msgid "Analog Radio"
+msgstr "Radio Analog"
+
+#: ../src/modules/alsa/alsa-mixer.c:1781
+msgid "Analog Video"
+msgstr "Video Analog"
+
+#: ../src/modules/alsa/alsa-mixer.c:1782
+msgid "Analog Output"
+msgstr "Keluaran Analog"
+
+#: ../src/modules/alsa/alsa-mixer.c:1783
+msgid "Analog Headphones"
+msgstr "Headphone Analog"
+
+#: ../src/modules/alsa/alsa-mixer.c:1784
+msgid "Analog Output (LFE)"
+msgstr "Keluaran Analog (LFE)"
+
+#: ../src/modules/alsa/alsa-mixer.c:1785
+msgid "Analog Mono Output"
+msgstr "Keluaran Mono Analog"
+
+#: ../src/modules/alsa/alsa-mixer.c:1786
+msgid "Analog Speakers"
+msgstr "Speaker Analog"
+
+#: ../src/modules/alsa/alsa-mixer.c:1986
+#, c-format
+msgid "%s+%s"
+msgstr "%s+%s"
+
+#: ../src/modules/alsa/alsa-mixer.c:1989 ../src/modules/alsa/alsa-mixer.c:3409
+#, c-format
+msgid "%s / %s"
+msgstr "%s / %s"
+
+#: ../src/modules/alsa/alsa-mixer.c:2795
+msgid "Analog Mono"
+msgstr "Analog Mono"
+
+#: ../src/modules/alsa/alsa-mixer.c:2796
+msgid "Analog Stereo"
+msgstr "Analog Stereo"
+
+#: ../src/modules/alsa/alsa-mixer.c:2797
+msgid "Analog Surround 2.1"
+msgstr "Analog Surround 2.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:2798
+msgid "Analog Surround 3.0"
+msgstr "Analog Surround 3.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:2799
+msgid "Analog Surround 3.1"
+msgstr "Analog Surround 3.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:2800
+msgid "Analog Surround 4.0"
+msgstr "Analog Surround 4.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:2801
+msgid "Analog Surround 4.1"
+msgstr "Analog Surround 4.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:2802
+msgid "Analog Surround 5.0"
+msgstr "Analog Surround 5.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:2803
+msgid "Analog Surround 5.1"
+msgstr "Analog Surround 5.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:2804
+msgid "Analog Surround 6.0"
+msgstr "Analog Surround 6.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:2805
+msgid "Analog Surround 6.1"
+msgstr "Analog Surround 6.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:2806
+msgid "Analog Surround 7.0"
+msgstr "Analog Surround 7.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:2807
+msgid "Analog Surround 7.1"
+msgstr "Analog Surround 7.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:2808
+msgid "Digital Stereo (IEC958)"
+msgstr "Digital Stereo (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2809
+msgid "Digital Surround 4.0 (IEC958)"
+msgstr "Digital Surround 4.0 (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2810
+msgid "Digital Surround 4.0 (IEC958/AC3)"
+msgstr "Digital Surround 4.0 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2811
+msgid "Digital Surround 5.1 (IEC958/AC3)"
+msgstr "Digital Surround 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2812
+msgid "Digital Stereo (HDMI)"
+msgstr "Digital Stereo (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2933
+msgid "Analog Mono Duplex"
+msgstr "Analog Mono Duplex"
+
+#: ../src/modules/alsa/alsa-mixer.c:2934
+msgid "Analog Stereo Duplex"
+msgstr "Analog Stereo Duplex"
+
+#: ../src/modules/alsa/alsa-mixer.c:2935
+msgid "Digital Stereo Duplex (IEC958)"
+msgstr "Digital Stereo Duplex (IEC958)"
index c0c70e4..1f769d0 100644 (file)
--- a/po/it.po
+++ b/po/it.po
@@ -4,26 +4,23 @@
 #
 # Luca Ferretti <elle.uca@libero.it>, 2008, 2009.
 # mario_santagiuliana <mario at marionline.it>, 2009.
-# Milo Casagrande <milo@ubuntu.com>, 2009.
+# Milo Casagrande <milo@ubuntu.com>, 2009, 2012.
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-10-18 05:22+0000\n"
-"PO-Revision-Date: 2009-10-18 11:46+0200\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:54+0000\n"
 "Last-Translator: Milo Casagrande <milo@ubuntu.com>\n"
 "Language-Team: Italian <tp@lists.linux.it>\n"
+"Language: it\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -35,11 +32,11 @@ msgstr ""
 "Molto probabilmente si tratta di un bug nel driver ALSA \"%s\". Segnalare "
 "questo problema agli sviluppatori ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
@@ -47,7 +44,19 @@ msgstr ""
 "Molto probabilmente si tratta di un bug nel driver ALSA \"%s\". Segnalare "
 "questo problema agli sviluppatori ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() ha restituito un valore molto grande: %lu byte (%lu ms).\n"
+"Molto probabilmente si tratta di un bug nel driver ALSA \"%s\". Segnalare "
+"questo problema agli sviluppatori ALSA."
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -60,25 +69,28 @@ msgstr ""
 "Molto probabilmente si tratta di un bug nel driver ALSA \"%s\". Segnalare "
 "questo problema agli sviluppatori ALSA."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "Mantiene sempre almeno un sink caricato anche se è nullo"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "Output dummy"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "Sink LADSPA virtuale"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<nome del sink> sink_properties=<proprietà del sink> master=<nome "
 "del sink da filtrare> format=<formato campionamento> rate=<frequenza "
@@ -86,121 +98,127 @@ msgstr ""
 "plugin=<nome plugin ladspa> label=<etichetta plugin ladspa> control=<valori "
 "di controllo separati da virgole>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "Sink NULL temporizzato"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "Output nullo"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "Audio interno"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "Modem"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "Ricerca del loader lt_dlopen originale non riuscita."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "Allocazione del nuovo loader dl non riuscita."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "Aggiunta di bind-now-loader non riuscita."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "Ottenuto il segnale %s."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "Uscita."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "Ricerca dell'utente \"%s\" non riuscita."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "Ricerca del gruppo \"%s\" non riuscita."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "Trovato l'utente \"%s\" (UID %lu) e il gruppo \"%s\" (GID %lu)."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "Il GID dell'utente \"%s\" e del gruppo \"%s\" non corrispondono."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "La directory home dell'utente \"%s\" non è \"%s\", ignorato."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Creazione di \"%s\" non riuscita: %s"
 
 # group list ????
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "Cambio dell'elenco di gruppo non riuscito: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "Cambio di GID non riuscito: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "Cambio di UID non riuscito: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "Privilegi di root abbandonati con successo."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "Modalità di sistema non supportata su questa piattaforma."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) non riuscita: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "Analisi della riga di comando non riuscita."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "Demone non in esecuzione"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "Demone in esecuzione con PID %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "Terminazione del demone non riuscita: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -208,163 +226,184 @@ msgstr ""
 "Questo programma non è pensato per essere eseguito come root (a meno di "
 "specificare --system)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "Richiesti privilegi di root."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start non supportato per le istanze di sistema."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "In esecuzione in modalità sistema, ma --disallow-exit non impostato."
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
 "In esecuzione in modalità sistema, ma --disallow-module-loading non "
 "impostato."
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr ""
 "In esecuzione in modalità sistema, disabilitata in modo forzoso la modalità "
 "SHM."
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 "In esecuzione in modalità sistema, disabilitato in modo forzoso il tempo di "
 "uscita per inattività."
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "Acquisizione di STDIO non riuscita."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "pipe non riuscita: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() non riuscita: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() non riuscita: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "Avvio del demone non riuscito."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "Avvio del demone riuscito."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() non riuscita: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Questo è PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Host di compilazione: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "CFLAGS di compilazione: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "In esecuzione sull'host: %s"
 
 # evviva il rispetto della l10n!!!
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "Trovate %u CPU."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "La dimensione di pagina è %lu byte"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Compilato con supporto a Valgrind: sì"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Compilato con supporto a Valgrind: no"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "In esecuzione in modalità valgrind: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "In esecuzione sull'host: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "Build ottimizzata: sì"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "Build ottimizzata: no"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG definito, tutte le dichiarazioni sono disabilitate."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr ""
 "FASTPATH definito, solo le dichiarazioni veloci di path sono disabilitate."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "Tutte le dichiarazioni sono abilitate."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "Recupero dell'ID della macchina non riuscito"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "L'ID della macchina è %s"
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "L'ID della sessione è %s"
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "In uso directory di runtime %s."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "In uso directory di stato %s."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "In uso directory dei moduli %s."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "In esecuzione in modalità sistema: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -380,17 +419,17 @@ msgstr ""
 "Consultare http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode per maggiori "
 "informazioni sul perché la modalità sistema è una pessima idea."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() non riuscita."
 
 # io mi domando e dico..... mah!
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "Disponibili timer high-resolution freschi freschi! Buon appetito!"
 
 # $REPEAT_PREVIOUS_COMMENT_HERE
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -398,33 +437,33 @@ msgstr ""
 "Hey, questo kernel è andato a male! Lo chef oggi raccomanda Linux con i "
 "timer high-resolution abilitati!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() non riuscita."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "Inizializzazione del demone non riuscita."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Avvio del demone senza alcun modulo caricato, rifiuta di lavorare."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "Completato l'avvio del demone."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "Iniziato l'arresto del demone."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "Demone terminato."
 
 # mamma mia che impressione
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -461,15 +500,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -595,15 +632,15 @@ msgstr ""
 "  -n                                    Non carica il file script "
 "predefinito\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize richiede un argomento booleano"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail richiede un argomento booleano"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -612,170 +649,173 @@ msgstr ""
 "nell'intervallo numerico 0..4 oppure uno tra debug, info, notice, warn, "
 "error)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority richiede un argomento booleano"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime richiede un argomento booleano"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading richiede un argomento booleano"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit richiede un argomento booleano"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file richiede un argomento booleano"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr ""
 "Destinazione del registro non valida: usare \"syslog\", \"stderr\" o \"auto"
 "\"."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time richiede un argomento booleano"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta richiede un argomento booleano"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Metodo di ricampionamento \"%s\" non valido."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system richiede un argomento booleano"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit richiede un argomento booleano"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm richiede un argomento booleano"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Nome: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "Nessuna informazione disponibile sul modulo\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Versione: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Descrizione: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Autore: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Uso: %s\n"
 
 # %s è sì/no
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "Caricato una sola volta: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "ATTENZIONE, DEPRECATI: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Percorso: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Destinazione di registro \"%s\" non valida."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Livello di registro \"%s\" non valido."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Metodo di ricampionamento \"%s\" non valido."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] rlimit \"%s\" non valido."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit non supportato su questa piattaforma."
-
 # o campionamento?? ma campionamento non è sampling?
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Formato di campionamento \"%s\" non valido."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Frequenza di campionamento '%s' non valida."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Canali di campionamento \"%s\" non validi."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] Mappa del canale \"%s\" non valida."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Numero di frammenti \"%s\" non valido."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Dimensione dei frammenti \"%s\" non valida."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Livello di nice \"%s\" non valido."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Frequenza di campionamento '%s' non valida."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Apertura del file di configurazione non riuscita: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -783,12 +823,12 @@ msgstr ""
 "La mappa del canale predefinita specificata presenta un numero diverso di "
 "canali rispetto a quello predefinito specificato."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Lettura dal file di configurazione: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "Abbandono dei privilegi."
 
@@ -800,6 +840,16 @@ msgstr "Sistema sonoro PulseAudio"
 msgid "Start the PulseAudio Sound System"
 msgstr "Avvia il sistema sonoro PulseAudio"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "Sistema sonoro PulseAudio"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "Avvia il sistema sonoro PulseAudio"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
@@ -831,8 +881,8 @@ msgid "Rear Right"
 msgstr "Posteriore destro"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Emettitore basse frequenze"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -1006,9 +1056,10 @@ msgstr "Superiore posteriore sinistro"
 msgid "Top Rear Right"
 msgstr "Superiore posteriore destro"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(non valido)"
 
@@ -1036,335 +1087,352 @@ msgstr "Surround 5.1"
 msgid "Surround 7.1"
 msgstr "Surround 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "OK"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "Accesso negato"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Comando sconosciuto"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "Argomento non valido"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "L'entità esiste"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "Entità inesistente"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "Connessione rifiutata"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "Errore di protocollo"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "Timeout"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "Nessuna chiave di autorizzazione"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "Errore interno"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "Connessione terminata"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "Entità uccisa"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Server non valido"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "Inizializzazione del modulo non riuscita"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "Stato errato"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Nessun dato"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "Versione di protocollo incompatibile"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "Troppo grande"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "Non supportato"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Codice d'errore sconosciuto"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "Estensione inesistente"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "Funzionalità obsoleta"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "Implementazione mancante"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "Fork del client"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "Errore di input/output"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "Dispositivo o risorsa occupata"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s ch %u %u Hz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() non riuscita"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() non riuscita: %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "Analisi dei dati cookie non riuscita"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Apertura del file di configurazione \"%s\" non riuscita: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "Nessun cookie caricato. Tentativo di connettersi senza."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "Ricevuto messaggio per l'estensione sconosciuta \"%s\""
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "Svuotamento dello stream non riuscito: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "Stream di riproduzione svuotato."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "Svuotamento della connessione sul server."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() non riuscita: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_begin_write() non riuscita: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() non riuscita: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "Creazione dello stream riuscita."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() non riuscita: %s"
 
 # maxlength, fragsize e gli altri non so se vanno tradotti...
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 msgstr "Metriche del buffer: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 
 # maxlength e fragsize non so se vanno tradotti...
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Metriche del buffer: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "In uso specifica di campionamento \"%s\", mappa dei canali \"%s\"."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "Connesso al device %s (%u, %ssospeso)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "Errore di stream: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "Device stream sospeso.%s "
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "Device stream ripristinato.%s "
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "Underrun dello stream.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "Overrun dello stream.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "Stream avviato.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "Stream spostato sul device %s (%u, %ssospeso).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "non "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "Attributi del buffer di stream cambiati.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "Connessione stabilita.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() non riuscita: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() non riuscita: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() non riuscita: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "Connessione non riuscita: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "Ricevuto EOF."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() non riuscita: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "Ricevuto il segnale, uscita."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "Recupero della latenza non riuscito: %s"
 
 # dubbio: tempo o durata??
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Tempo: %0.3f sec; Latenza: %0.0f microsec."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() non riuscita: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1416,10 +1484,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [OPZIONI]\n"
@@ -1489,7 +1562,7 @@ msgstr ""
 "formattati\n"
 "      --list-file-FORMATI               Elenca i formati disponibili.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1500,69 +1573,69 @@ msgstr ""
 "Compilato con libpulse %s\n"
 "Link eseguito con libpulse %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "Nome del client \"%s\" non valido"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "Nome dello stream \"%s\" non valido"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "Mappa dei canali \"%s\" non valida"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "Specifica di latenza \"%s\" non valida"
 
 # esecuzione???
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "Specifica di tempo di elaborazione \"%s\" non valida"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "Proprietà \"%s\" non valida"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "Formato file %s sconosciuto."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "Specifica di campionamento non valida"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "Troppi argomenti."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "Generazione della specifica di campionamento per il file non riuscita."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "Apertura del file audio non riuscita."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
@@ -1570,24 +1643,24 @@ msgstr ""
 "Attenzione: la specifica di campionamento indicata verrà soprascritta con "
 "quella dal file."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "Determinazione della specifica di campionamento dal file non riuscita."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr ""
 "Attenzione: determinazione della mappa dei canali dal file non riuscita."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "La mappa dei canali non corrisponde alla specifica di campionamento"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "Attenzione: scrittura della mappa dei canali su file non riuscita."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
@@ -1595,81 +1668,86 @@ msgstr ""
 "Apertura di uno stream %s con specifica di campionamento \"%s\" e mappa dei "
 "canali \"%s\"."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "registrazione"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "riproduzione"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "Analisi della riga di comando non riuscita."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() non riuscita."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() non riuscita."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() non riuscita."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() non riuscita: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_rttime_new() non riuscita."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() non riuscita."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "Sospensione non riuscita: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "Ripristino non riuscito: %s\n"
 
 # cambiato un po' la parte finale...
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "ATTENZIONE: server audio non locale, impossibile sospendere.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Connessione non riuscita: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "Ricevuto SIGINT, in uscita.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "ATTENZIONE: processo figlio terminato dal segnale %u\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1714,37 +1792,48 @@ msgstr "pa_context_new() non riuscita.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() non riuscita.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "Recupero delle statistiche non riuscito: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "Attualmente in uso: %u blocchi contenenti %s byte in totale.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr ""
 "Allocati durante l'intera esecuzione: %u blocchi contenenti %s byte in "
 "totale.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "Dimensione della cache dei campioni: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "Recupero delle informazioni del server non riuscito: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1752,7 +1841,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "Nome utente: %s\n"
 "Nome host: %s\n"
@@ -1764,7 +1853,7 @@ msgstr ""
 "Sorgente predefinita: %s\n"
 "Cookie: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "Recupero delle informazioni del sink non riuscito: %s"
@@ -1772,8 +1861,8 @@ msgstr "Recupero delle informazioni del sink non riuscito: %s"
 # nel relativo messaggio per il source
 # c'è "monitor of sink", quindi assumo che
 # qui dovesse essere "monitor of source"
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1789,7 +1878,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1811,22 +1900,27 @@ msgstr ""
 "\tProprietà:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tPorte:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tPorta attiva: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tPorte:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "Recupero delle informazioni della sorgente non riuscito: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1865,20 +1959,20 @@ msgstr ""
 "\tProprietà:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "N/D"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "Recupero delle informazioni del modulo non riuscito: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1895,12 +1989,12 @@ msgstr ""
 "\tProprietà:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "Recupero delle informazioni del client non riuscito: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1915,12 +2009,12 @@ msgstr ""
 "\tProprietà:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "Recupero delle informazioni della scheda non riuscito: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1937,12 +2031,12 @@ msgstr ""
 "\tProprietà:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tProfili:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tProfilo attivo: %s\n"
@@ -1951,13 +2045,13 @@ msgstr "\tProfilo attivo: %s\n"
 # A stream that is connected to an output device, i.e. an input for a sink.
 #
 # from http://pulseaudio.org/wiki/WritingVolumeControlUIs
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "Recupero delle informazioni dell'ingresso per il sink non riuscito: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1966,6 +2060,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1997,14 +2092,14 @@ msgstr ""
 # A stream that is connected to an input device, i.e. an output of a source.
 #
 # from http://pulseaudio.org/wiki/WritingVolumeControlUIs
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr ""
 "Recupero delle informazioni dell'uscita per la sorgente non riuscito: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -2013,32 +2108,41 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Uscita per sorgente #%u\n"
+"Ingresso per sink #%u\n"
 "\tDriver: %s\n"
 "\tModulo di appartenenza: %s\n"
 "\tClient: %s\n"
-"\tSorgente: %u\n"
+"\tSink: %u\n"
 "\tSpecifica di campionamento: %s\n"
 "\tMappa dei canali: %s\n"
+"\tMuto: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        bilanciamento %0.2f\n"
 "\tLatenza del buffer: %0.0f microsec\n"
-"\tLatenza della sorgente: %0.0f microsec\n"
+"\tLatenza del sink: %0.0f microsec\n"
 "\tMetodo di ricampionamento: %s\n"
 "\tProprietà:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "Recupero delle informazioni del campione non riuscito: %s"
 
 # campiona lazy??
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -2069,48 +2173,163 @@ msgstr ""
 "\tProprietà:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "Fallimento: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Recupero delle informazioni della sorgente non riuscito: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "Caricamento del campione non riuscito: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "Fine del file prematura"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "Server non valido"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "Ricevuto SIGINT, uscita."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "Specifica di volume non valida"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2120,35 +2339,15 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [OPZIONI] stat\n"
-"%s [OPZIONI] list\n"
-"%s [OPZIONI] exit\n"
-"%s [OPZIONI] upload-sample NOMEFILE [NOME]\n"
-"%s [OPZIONI] play-sample NOME [SINK]\n"
-"%s [OPZIONI] remove-sample NOME\n"
-"%s [OPZIONI] move-sink-input SINKINPUT SINK\n"
-"%s [OPZIONI] move-source-output SOURCEOUTPUT SORGENTE\n"
-"%s [OPZIONI] load-module NOME [ARGOMENTI...]\n"
-"%s [OPZIONI] unload-module MODULO\n"
-"%s [OPZIONI] suspend-sink SINK 1|0\n"
-"%s [OPZIONI] suspend-source SORGENTE 1|0\n"
-"%s [OPZIONI] set-card-profile SCHEDA PROFILO\n"
-"%s [OPZIONI] set-sink-port SINK PORTA\n"
-"%s [OPZIONI] set-source-port SORGENTE PORTA\n"
-"%s [OPZIONI] set-sink-volume SINK VOLUME\n"
-"%s [OPZIONI] set-source-volume SORGENTE VOLUME\n"
-"%s [OPZIONI] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [OPZIONI] set-sink-mute SINK 1|0\n"
-"%s [OPZIONI] set-source-mute SORGENTE 1|0\n"
-"%s [OPZIONI] set-sink-input-mute SINKINPUT 1|0\n"
+"%s [OPZIONI] ... \n"
 "\n"
-"  -h, --help                       Mostra questo aiuto\n"
-"      --version                    Mostra la versione\n"
+"  -h, --help                            Mostra questo aiuto\n"
+"      --version                         Mostra la versione\n"
+"  -s, --server=SERVER                   Il nome del server a cui "
+"connettersi\n"
 "\n"
-"  -s, --server=SERVER              Il nome del server a cui connettersi\n"
-"  -n, --client-name=NOME           Come chiamare questo client sul server\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2159,53 +2358,58 @@ msgstr ""
 "Compilato con libpulse %s\n"
 "Link eseguito con libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "Specificare un file campione da caricare"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "Apertura del file audio non riuscita."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr ""
 "Attenzione: determinazione della specifica di campionamento dal file non "
 "riuscita."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "È necessario specificare un nome di campione da riprodurre"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "È necessario specificare un nome di campione da rimuovere"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "È necessario specificare un indice di ingresso per sink e un sink"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr ""
 "È necessario specificare una indice di uscita per sorgente e una sorgente"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "È necessario specificare un nome di modulo e gli argomenti."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "È necessario specificare un indice di modulo"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "Non è possibile specificare più di un sink. È necessario specificare un "
 "valore booleano."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
@@ -2213,58 +2417,86 @@ msgstr ""
 "Non è possibile specificare più di una sorgente. È necessario specificare un "
 "valore booleano."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr ""
 "È necessario specificare un nome/indice di scheda e un nome di profilo."
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "È necessario specificare un nome/indice di sink e un nome di porta"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "È necessario specificare un nome/indice di sorgente e un nome di porta"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "È necessario specificare un nome/indice di sink e un nome di porta"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "Specifica di volume non valida"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "È necessario specificare un nome/indice di sorgente e un nome di porta"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "È necessario specificare un indice di ingresso per sink e un sink"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "Indice dell'input del sink non valido"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr ""
+"È necessario specificare una indice di uscita per sorgente e una sorgente"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "Indice dell'input del sink non valido"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "È necessario specificare un nome/indice di sink e un nome di porta"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "Specifica di campionamento non valida"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "È necessario specificare un nome/indice di sorgente e un nome di porta"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "È necessario specificare un indice di ingresso per sink e un sink"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "Specifica dell'indice di input del sink non valida"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "È necessario specificare un nome/indice di sorgente e un nome di porta"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "Specifica dell'indice di input del sink non valida"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "È necessario specificare un nome/indice di sink e un nome di porta"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "Nessun comando valido specificato."
 
@@ -2294,105 +2526,105 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "Analisi della riga di comando non riuscita.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Server: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Sorgente: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Sink: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Cookie: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "Analisi dei dati cookie non riuscita\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "Salvataggio dei dati cookie non riuscito\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "Caricamento del file di configurazione del client non riuscito.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "Lettura dei dati di configurazione dell'ambiente non riuscita.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "Recupero del FQDN non riuscito.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "Caricamento dei dati cookie non riuscito\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Non ancora implementato.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr ""
 "Nessun demone PulseAudio in esecuzione o non in esecuzione come demone di "
 "sessione."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "Uccisione del demone PulseAudio non riuscita."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "Il demone non sta rispondendo."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "Impossibile accedere al lock di autospawn."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2409,7 +2641,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:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2426,228 +2658,464 @@ msgstr ""
 "Attivazione avvenuta con POLLIN impostato -- tuttavia, una successiva "
 "snd_pcm_avail() ha ritornato 0 o un altro valore < min_avail."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "Spento"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "Riproduzione ad alta fedeltà (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "Cattura ad alta fedeltà (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Doppino telefonico (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "Server sonoro PulseAudio"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
 msgstr "Dispositivi di uscita"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
 msgstr "Dispositivi di ingresso"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
 msgstr "Audio su @HOSTNAME@"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
 msgstr "Ingresso"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
 msgstr "Ingresso docking station"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
 msgstr "Microfono docking station"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
-msgstr "Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "Ingresso docking station"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "Line In"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
 msgstr "Microfono"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "Microfono docking station"
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "Microfono"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
 msgid "External Microphone"
 msgstr "Microfono esterno"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
 msgstr "Microfono interno"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
 msgstr "Radio"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
 msgstr "Video"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
 msgstr "Controllo automatico del guadagno"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
 msgstr "Nessun controllo automatico del guadagno"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
 msgstr "Boost"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
 msgstr "Nessun boost"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
 msgstr "Amplificatore"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
 msgstr "Nessun amplificatore"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr "Ingresso analogico"
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "Boost"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr "Microfono analogico"
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "Nessun boost"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
-msgstr "Line-in analogico"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr "Radio analogica"
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "Cuffie analogiche"
+
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "Ingresso analogico"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr "Video analogico"
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "Microfono docking station"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
 msgstr "Uscita analogica"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr "Cuffie analogiche"
-
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
 msgstr "Uscita analogica (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "Line In"
+
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
 msgstr "Uscita mono analogica"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, c-format
-msgid "%s+%s"
-msgstr "%s+%s"
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "Stereo analogico"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, c-format
-msgid "%s / %s"
-msgstr "%s / %s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Stereo digitale (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Stereo digitale (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr "Mono analogico"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr "Stereo analogico"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
 msgstr "Surround analogico 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
 msgstr "Surround analogico 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
 msgstr "Surround analogico 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr "Surround analogico 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr "Surround analogico 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr "Surround analogico 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr "Surround analogico 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
 msgstr "Surround analogico 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
 msgstr "Surround analogico 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
 msgstr "Surround analogico 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr "Surround analogico 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr "Stereo digitale (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "Surround digitale 4.0 (IEC958)"
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Stereo digitale (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Surround digitale 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Surround digitale 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr "Stereo digitale (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Surround digitale 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
 msgstr "Duplex mono analogico"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
 msgstr "Duplex stereo analogico"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
 msgstr "Duplex stereo digitale (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Output nullo"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "Ingresso"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<nome del sink> sink_properties=<proprietà del sink> master=<nome "
+"del sink da filtrare> format=<formato campionamento> rate=<frequenza "
+"campionamento> channels=<numero di canali> channel_map=<mappa canale> "
+"plugin=<nome plugin ladspa> label=<etichetta plugin ladspa> control=<valori "
+"di controllo separati da virgole>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit non supportato su questa piattaforma."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() non riuscita"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Uscita per sorgente #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tModulo di appartenenza: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSorgente: %u\n"
+#~ "\tSpecifica di campionamento: %s\n"
+#~ "\tMappa dei canali: %s\n"
+#~ "\tLatenza del buffer: %0.0f microsec\n"
+#~ "\tLatenza della sorgente: %0.0f microsec\n"
+#~ "\tMetodo di ricampionamento: %s\n"
+#~ "\tProprietà:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [OPZIONI] stat\n"
+#~ "%s [OPZIONI] list\n"
+#~ "%s [OPZIONI] exit\n"
+#~ "%s [OPZIONI] upload-sample NOMEFILE [NOME]\n"
+#~ "%s [OPZIONI] play-sample NOME [SINK]\n"
+#~ "%s [OPZIONI] remove-sample NOME\n"
+#~ "%s [OPZIONI] move-sink-input SINKINPUT SINK\n"
+#~ "%s [OPZIONI] move-source-output SOURCEOUTPUT SORGENTE\n"
+#~ "%s [OPZIONI] load-module NOME [ARGOMENTI...]\n"
+#~ "%s [OPZIONI] unload-module MODULO\n"
+#~ "%s [OPZIONI] suspend-sink SINK 1|0\n"
+#~ "%s [OPZIONI] suspend-source SORGENTE 1|0\n"
+#~ "%s [OPZIONI] set-card-profile SCHEDA PROFILO\n"
+#~ "%s [OPZIONI] set-sink-port SINK PORTA\n"
+#~ "%s [OPZIONI] set-source-port SORGENTE PORTA\n"
+#~ "%s [OPZIONI] set-sink-volume SINK VOLUME\n"
+#~ "%s [OPZIONI] set-source-volume SORGENTE VOLUME\n"
+#~ "%s [OPZIONI] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [OPZIONI] set-sink-mute SINK 1|0\n"
+#~ "%s [OPZIONI] set-source-mute SORGENTE 1|0\n"
+#~ "%s [OPZIONI] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "\n"
+#~ "  -h, --help                       Mostra questo aiuto\n"
+#~ "      --version                    Mostra la versione\n"
+#~ "\n"
+#~ "  -s, --server=SERVER              Il nome del server a cui connettersi\n"
+#~ "  -n, --client-name=NOME           Come chiamare questo client sul "
+#~ "server\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Surround digitale 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Emettitore basse frequenze"
index de7f605..9271cd8 100644 (file)
--- a/po/ja.po
+++ b/po/ja.po
@@ -1,26 +1,28 @@
+# translation of ja.po to Japanese
 # PulseAudio
 # Copyright (C) 2009.
 # This file is distributed under the same license as the PACKAGE package.
+#
 # Hyu_gabaru Ryu_ichi <hyu_gabaru@yahoo.co.jp>, 2009.
+# Kiyoto Hashida <khashida@redhat.com>, 2009, 2012.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: 1.0\n"
+"Project-Id-Version: ja\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-09-10 21:05+0900\n"
-"Last-Translator: Hyu_gabaru Ryu_ichi <hyu_gabaru@yahoo.co.jp>\n"
-"Language-Team: Japanese <fedora-trans-ja@redhat.com>\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:54+0000\n"
+"Last-Translator: Kiyoto Hashida <khashida@redhat.com>\n"
+"Language-Team: Japanese <jp@li.org>\n"
+"Language: ja\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+"Plural-Forms: Plural-Forms: nplurals=1; plural=0;\n"
+"\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -28,17 +30,35 @@ msgid ""
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 msgstr ""
+"snd_pcm_avail() は 例外的に大きな値を返しました: %lu バイト(%lu ms)。\n"
+"これは多分、ALSA ドライバー '%s' 内のバグです。この問題は ALSA 開発者宛に 報"
+"告を提出して下さい。"
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
+"snd_pcm_delay() は 例外的に大きな値を返しました: %li バイト(%s%lu ms)。\n"
+"これは多分、ALSA ドライバー '%s' 内のバグです。この問題は ALSA 開発者宛に 報"
+"告を提出して下さい。"
+
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 msgstr ""
+"snd_pcm_avail() は 例外的に大きな値を返しました: %lu バイト(%lu ms)。\n"
+"これは多分、ALSA ドライバー '%s' 内のバグです。この問題は ALSA 開発者宛に 報"
+"告を提出して下さい。"
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -46,296 +66,341 @@ msgid ""
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 msgstr ""
+"snd_pcm_mmap_begin() は 例外的に大きな値を返しました: %lu バイト(%lu "
+"ms)。\n"
+"これは多分、ALSA ドライバー '%s' 内のバグです。この問題は ALSA 開発者宛に 報"
+"告を提出して下さい。"
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr ""
+"null である場合でも、常に最低でもシンクが1つロードされるように維持します"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
-msgstr ""
+msgstr "ダミー出力"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
-msgstr ""
+msgstr "仮想 LADSPA シンク"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
-msgstr ""
-
-#: ../src/modules/module-null-sink.c:55
+"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> "
+msgstr ""
+"sink_name=<シンクの名前> sink_properties=<シンクのプロパティ> master=<フィル"
+"タするシンク名> format=<サンプル形式> rate=<サンプルレート> channels=<チャン"
+"ネル数> channel_map=<チャンネルマップ> plugin=<ladspa plugin の名前> "
+"label=<ladspa plugin のラベル> control=<コンマで隔離した入力制御値の 一覧>"
+
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
-msgstr ""
+msgstr "クロック付き NULL シンク"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
-msgstr ""
+msgstr "Null 出力"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
-msgstr ""
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
+msgstr "内部オーディオ"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
-msgstr ""
+msgstr "モデム"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
-msgstr ""
+msgstr "オリジナルの lt_dlopen ローダーを見つけるのに失敗しました。"
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
-msgstr ""
+msgstr "新規の dl ローダーの割り当てに失敗しました。"
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
-msgstr ""
+msgstr "bind-now-loader の追加に失敗しました。"
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
-msgstr ""
+msgstr "信号 %s を得ました。"
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
-msgstr ""
+msgstr "終了しています。"
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
-msgstr ""
+msgstr "ユーザー '%s' が見付かりませんでした。"
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
-msgstr ""
+msgstr "グループ '%s' が見付かりませんでした。"
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
-msgstr ""
+msgstr "ユーザー'%s' (UID %lu) とグループ  '%s' (GID %lu) を見つけました。"
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
-msgstr ""
+msgstr "ユーザー'%s' と グループ '%s' の GID が一致しません。"
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
-msgstr ""
+msgstr "ユーザー '%s' のホームディレクトリは '%s' ではありません。無視します。"
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
-msgstr ""
+msgstr "'%s' の作成に失敗しました: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
-msgstr ""
+msgstr "グループ一覧の変更に失敗しました: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
-msgstr ""
+msgstr "GID の変更に失敗しました: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
-msgstr ""
+msgstr "UID の変更に失敗しました: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
-msgstr ""
+msgstr "root の権限を正しく破棄しました。"
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
-msgstr ""
+msgstr "このプラットフォームではシステム全域のモードはサポートがありません。"
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
-msgstr ""
+msgstr "setrlimit(%s, (%u, %u)) は失敗: %s "
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
+msgstr "コマンドラインの構文解析に失敗しました。"
+
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
 msgstr ""
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
-msgstr ""
+msgstr "デーモンは稼働していません"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
-msgstr ""
+msgstr "デーモンは PID %u として稼働していません"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
-msgstr ""
+msgstr "デーモンのキルに失敗しました: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
 msgstr ""
+"このプログラムは root として実行されるように意図されていません(--system を "
+"指定していない限り)。"
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
-msgstr ""
+msgstr "Root の権限が必要です。"
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
+msgstr "--start はシステムインスタンスではサポートがありません。"
+
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
 msgstr ""
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr ""
+"システムモードで実行中です、しかし --disallow-exit がセットされていません!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
+"システムモードで実行中です、しかし --disallow-module-loading がセットされてい"
+"ません!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
-msgstr ""
+msgstr "システムモードで実行中です、強制的に SHM モードを無効にしています!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
+"システムモードで実行中です、強制的に exit の遊び時間を無効にしています!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
-msgstr ""
+msgstr "stdio の取得に失敗しました。"
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
-msgstr ""
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
+msgstr "パイプは失敗: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
-msgstr ""
+msgstr "fork() は失敗: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
-msgstr ""
+msgstr "read() は失敗: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
-msgstr ""
+msgstr "デーモン開始に失敗しました。"
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
-msgstr ""
+msgstr "デーモンが正常に開始しました。"
+
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() は失敗: %s"
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
-msgstr ""
+msgstr "これは PulseAudio %s です。"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
-msgstr ""
+msgstr "コンパイルホスト: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
-msgstr ""
+msgstr "コンパイル CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
-msgstr ""
+msgstr "ホスト上で実行中: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
-msgstr ""
+msgstr "%u CPU を見つけました。"
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
-msgstr ""
+msgstr "ページサイズは %lu バイトです"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
-msgstr ""
+msgstr "Valgrind サポートでのコンパイル: はい"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
-msgstr ""
+msgstr "Valgrind サポートでのコンパイル: いいえ"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
-msgstr ""
+msgstr "valgrind モードで実行中: %s"
+
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "ホスト上で実行中: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
-msgstr ""
+msgstr "最適化したビルド: はい"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
-msgstr ""
+msgstr "最適化したビルド: いいえ"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
-msgstr ""
+msgstr "NDEBUG は定義済みです。アサーションは全て無効です。"
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
-msgstr ""
+msgstr "FASTPATH は定義済みです。ファーストパスアサーションのみが無効です。"
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
-msgstr ""
+msgstr "アサーションは全て有効です。"
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
-msgstr ""
+msgstr "マシン ID の取得に失敗"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
-msgstr ""
+msgstr "マシン ID は %s"
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
-msgstr ""
+msgstr "セッション ID は %s"
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
-msgstr ""
+msgstr "ランタイムディレクトリ %s を使用 "
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
-msgstr ""
+msgstr "状態ディレクトリ %s を使用"
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
-msgstr ""
+msgstr "モジュールディレクトリ %s を使用"
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
-msgstr ""
+msgstr "システムモードで実行中: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -344,47 +409,56 @@ msgid ""
 "Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an "
 "explanation why system mode is usually a bad idea."
 msgstr ""
+"そうすると、ユーザーはシステムモードで PA を実行している訳です。その場合、 実"
+"際にはそうすべきでないことに注意して下さい。\n"
+"それでも実行するのでしたら、期待どおりに機能しなくても責任はユーザー自身に あ"
+"ります。\n"
+"システムモードの使用が通常は良くない方針であることの説明については、 http://"
+"pulseaudio.org/wiki/WhatIsWrongWithSystemMode をお読み下さい。"
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
-msgstr ""
+msgstr "pa_pid_file_create() は失敗"
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
-msgstr ""
+msgstr "最新の高解像度タイマーが使用できます! 楽しんで下さい!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
 msgstr ""
+"あらあら、ユーザーのカーネルはダメですよ! 今日のシェフのお薦めは高解像度タイ"
+"マーが 有効になっている Linux です!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
-msgstr ""
+msgstr "pa_core_new() は失敗"
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
-msgstr ""
+msgstr "デーモンの初期化に失敗しました。"
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
+"デーモンはモジュールの読み込みなしで開始しており、動作を拒否しています。"
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
-msgstr ""
+msgstr "デーモンの開始が完了です。"
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
-msgstr ""
+msgstr "デーモンのシャットダウンが始まりました。"
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
-msgstr ""
+msgstr "デーモンは取り消されました。"
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -421,15 +495,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -456,763 +528,870 @@ msgid ""
 "\n"
 "  -n                                    Don't load default script file\n"
 msgstr ""
+"%s [オプション]\n"
+"\n"
+"コマンド:\n"
+"  -h, --help                            このヘルプを表示\n"
+"      --version                         バージョンを表示\n"
+"      --dump-conf                       デフォルト設定をダンプ\n"
+"      --dump-modules                    使用可能なモジュール一覧をダンプ\n"
+"      --dump-resample-methods           使用可能な再サンプル方法をダンプ\n"
+"      --cleanup-shm                     古い共有メモリーセグメントをクリーン"
+"アップ \n"
+"      --start                           実行していない場合、デーモンを開始 \n"
+"  -k  --kill                            実行中のデーモンをキル\n"
+"      --check                           実行中のデーモンをチェック (退出コー"
+"ドを返すのみ)\n"
+"\n"
+"オプション:\n"
+"      --system[=BOOL]                   システム全域インスタンスとして実行\n"
+"  -D, --daemonize[=BOOL]                開始後デーモン化\n"
+"      --fail[=BOOL]                     開始失敗なら終了\n"
+"      --high-priority[=BOOL]            高度なナイスレベルの設定を試行\n"
+"                                        (root としてのみ可能, SUID の時、又"
+"は\n"
+"                                        昇格した RLIMIT_NICE で)\n"
+"      --realtime[=BOOL]                 リアルタイムスケジュールを有効にする"
+"試行\n"
+"                                        (root としてのみ可能, SUID の時、又"
+"は\n"
+"                                        昇格した RLIMIT_RTPRIO で)\n"
+"      --disallow-module-loading[=BOOL]  起動後のユーザー要求のモジュールの "
+"ロード/アンロードを 許可しない\n"
+"\n"
+"      --disallow-exit[=BOOL]            ユーザー要求の退出を許可しない\n"
+"      --exit-idle-time=SECS             遊休時と指定時間後にデーモンを終了 \n"
+"\n"
+"      --module-idle-time=SECS           遊休時と指定時間後に自動ロードモ"
+"ジュールをアンロード \n"
+"\n"
+"      --scache-idle-time=SECS           遊休時と指定時間後に自動ロードサンプ"
+"ルをアンロード \n"
+"\n"
+"      --log-level[=LEVEL]               詳細レベルを上げるか、又はセット\n"
+"  -v                                    詳細レベルを上げる \n"
+"--log-target={auto,syslog,stderr} ログターゲットを指定 \n"
+"--log-meta[=BOOL]                 ログメッセージ内にコードの場所を含む \n"
+"      --log-time[=BOOL]                 ログメッセージ内にタイムスタンプを含"
+"む\n"
+"      --log-backtrace=FRAMES            ログメッセージ内にバックトレースを含"
+"む\n"
+"  -p, --dl-search-path=PATH             動的共有オブジェクト(plugins)用に検索"
+"パスをセット\n"
+"\n"
+"      --resample-method=METHOD          指定した再サンプリング方法を使用\n"
+"                                        (使用可能な値は --dump-resample-"
+"methods で\n"
+"                                        参照)\n"
+"      --use-pid-file[=BOOL]             PID ファイルを作成\n"
+"      --no-cpu-limit[=BOOL]             サポート元のプラットフォームに CPU\n"
+"                                         ロードリミッターをインストールしな"
+"い\n"
+"      --disable-shm[=BOOL]              共有メモリーサポートを無効にする\n"
+"\n"
+"スタートアップスクリプト:\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         指定した引数で指定したプラグインモ"
+"ジュールを ロード\n"
+"\n"
+"  -F, --file=FILENAME                   指定したスクリプトを実行\n"
+"  -C                                    スタートアップ後に実行中の TTY 上でコ"
+"マンドラインを 開く\n"
+"\n"
+"  -n                                    デフォルトのスクリプトファイルをロー"
+"ドしない\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
-msgstr ""
+msgstr "--daemonize はブーリアン引数を予期します"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
-msgstr ""
+msgstr "--fail はブーリアン引数を予期します。"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
 msgstr ""
+"--log-level はログレベル引数を予期します(数値幅0〜4、又はデバグ、情報、注"
+"記、警告、エラーの 中の1つ)"
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
-msgstr ""
+msgstr "--high-priority は ブーリアン引数を予期します"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
-msgstr ""
+msgstr "--realtime はブーリアン引数を予期します "
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
-msgstr ""
+msgstr "--disallow-module-loading はブーリアン引数を予期します "
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
-msgstr ""
+msgstr "--disallow-exit はブーリアン引数を予期します "
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
-msgstr ""
+msgstr "--use-pid-file はブーリアン引数を予期します "
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr ""
+"無効なログターゲット: 'syslog' か、 'stderr' か、'auto' を使用して下さい。"
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
-msgstr ""
+msgstr "--log-time ブーリアン引数を予期します "
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
-msgstr ""
+msgstr "--log-meta ブーリアン引数を予期します "
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
-msgstr ""
+msgstr "無効な再サンプル方法 '%s'"
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
-msgstr ""
+msgstr "--system はブーリアン引数を予期します"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
-msgstr ""
+msgstr "--no-cpu-limit はブーリアン引数を予期します"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
-msgstr ""
+msgstr "--disable-shm はブーリアン引数を予期します"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
-msgstr ""
+msgstr "名前: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
-msgstr ""
+msgstr "モジュール情報が使用できません\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
-msgstr ""
+msgstr "バージョン: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
-msgstr ""
+msgstr "説明: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
-msgstr ""
+msgstr "著者: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
-msgstr ""
+msgstr "使用法: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
-msgstr ""
+msgstr "1度だけロード: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
-msgstr ""
+msgstr "破棄の警告: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
-msgstr ""
+msgstr "パス: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
-msgstr ""
+msgstr "[%s:%u] 無効なログターゲット '%s'"
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
-msgstr ""
+msgstr "[%s:%u] 無効なログレベル '%s'"
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
-msgstr ""
+msgstr "[%s:%u] 無効な再サンプル方法 '%s'"
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
-msgstr ""
+msgstr "[%s:%u] 無効な rlimit '%s'"
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr ""
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
-msgstr ""
+msgstr "[%s:%u] 無効なサンプル形式 '%s'"
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
-msgstr ""
+msgstr "[%s:%u] 無効なサンプルレート '%s'"
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
-msgstr ""
+msgstr "[%s:%u] 無効なサンプルチャンネル '%s'"
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
-msgstr ""
+msgstr "[%s:%u] 無効なチャンネルマップ '%s'"
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
-msgstr ""
+msgstr "[%s:%u] 無効なフラグメントの数 '%s'"
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
-msgstr ""
+msgstr "[%s:%u] 無効なフラグメントサイズ '%s'"
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
-msgstr ""
+msgstr "[%s:%u] 無効なナイスレベル '%s'"
+
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] 無効なサンプルレート '%s'"
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
-msgstr ""
+msgstr "設定ファイルを開くのに失敗: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 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:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
-msgstr ""
+msgstr "### 設定ファイルから読み込み: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
-msgstr ""
+msgstr "権限をクリーンアップ"
 
 #: ../src/daemon/pulseaudio.desktop.in.h:1
 msgid "PulseAudio Sound System"
-msgstr ""
+msgstr "PulseAudio サウンドシステム"
 
 #: ../src/daemon/pulseaudio.desktop.in.h:2
 msgid "Start the PulseAudio Sound System"
-msgstr ""
+msgstr "PulseAudio サウンドシステムを開始"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio サウンドシステム"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "PulseAudio サウンドシステムを開始"
 
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
-msgstr ""
+msgstr "モノ"
 
 #: ../src/pulse/channelmap.c:107
 msgid "Front Center"
-msgstr ""
+msgstr "中央前"
 
 #: ../src/pulse/channelmap.c:108
 msgid "Front Left"
-msgstr ""
+msgstr "左前"
 
 #: ../src/pulse/channelmap.c:109
 msgid "Front Right"
-msgstr ""
+msgstr "右前"
 
 #: ../src/pulse/channelmap.c:111
 msgid "Rear Center"
-msgstr ""
+msgstr "中央後ろ"
 
 #: ../src/pulse/channelmap.c:112
 msgid "Rear Left"
-msgstr ""
+msgstr "左後ろ"
 
 #: ../src/pulse/channelmap.c:113
 msgid "Rear Right"
-msgstr ""
+msgstr "右後ろ"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
+msgid "Subwoofer"
 msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
-msgstr ""
+msgstr "中央の左前"
 
 #: ../src/pulse/channelmap.c:118
 msgid "Front Right-of-center"
-msgstr ""
+msgstr "中央の右前"
 
 #: ../src/pulse/channelmap.c:120
 msgid "Side Left"
-msgstr ""
+msgstr "左側"
 
 #: ../src/pulse/channelmap.c:121
 msgid "Side Right"
-msgstr ""
+msgstr "右側"
 
 #: ../src/pulse/channelmap.c:123
 msgid "Auxiliary 0"
-msgstr ""
+msgstr "補助 0"
 
 #: ../src/pulse/channelmap.c:124
 msgid "Auxiliary 1"
-msgstr ""
+msgstr "補助 1"
 
 #: ../src/pulse/channelmap.c:125
 msgid "Auxiliary 2"
-msgstr ""
+msgstr "補助 2"
 
 #: ../src/pulse/channelmap.c:126
 msgid "Auxiliary 3"
-msgstr ""
+msgstr "補助 3"
 
 #: ../src/pulse/channelmap.c:127
 msgid "Auxiliary 4"
-msgstr ""
+msgstr "補助 4"
 
 #: ../src/pulse/channelmap.c:128
 msgid "Auxiliary 5"
-msgstr ""
+msgstr "補助 5"
 
 #: ../src/pulse/channelmap.c:129
 msgid "Auxiliary 6"
-msgstr ""
+msgstr "補助 6"
 
 #: ../src/pulse/channelmap.c:130
 msgid "Auxiliary 7"
-msgstr ""
+msgstr "補助 7"
 
 #: ../src/pulse/channelmap.c:131
 msgid "Auxiliary 8"
-msgstr ""
+msgstr "補助 8"
 
 #: ../src/pulse/channelmap.c:132
 msgid "Auxiliary 9"
-msgstr ""
+msgstr "補助 9"
 
 #: ../src/pulse/channelmap.c:133
 msgid "Auxiliary 10"
-msgstr ""
+msgstr "補助 10"
 
 #: ../src/pulse/channelmap.c:134
 msgid "Auxiliary 11"
-msgstr ""
+msgstr "補助 11"
 
 #: ../src/pulse/channelmap.c:135
 msgid "Auxiliary 12"
-msgstr ""
+msgstr "補助 12"
 
 #: ../src/pulse/channelmap.c:136
 msgid "Auxiliary 13"
-msgstr ""
+msgstr "補助 13"
 
 #: ../src/pulse/channelmap.c:137
 msgid "Auxiliary 14"
-msgstr ""
+msgstr "補助 14"
 
 #: ../src/pulse/channelmap.c:138
 msgid "Auxiliary 15"
-msgstr ""
+msgstr "補助 15"
 
 #: ../src/pulse/channelmap.c:139
 msgid "Auxiliary 16"
-msgstr ""
+msgstr "補助 16"
 
 #: ../src/pulse/channelmap.c:140
 msgid "Auxiliary 17"
-msgstr ""
+msgstr "補助 17"
 
 #: ../src/pulse/channelmap.c:141
 msgid "Auxiliary 18"
-msgstr ""
+msgstr "補助 18"
 
 #: ../src/pulse/channelmap.c:142
 msgid "Auxiliary 19"
-msgstr ""
+msgstr "補助 19"
 
 #: ../src/pulse/channelmap.c:143
 msgid "Auxiliary 20"
-msgstr ""
+msgstr "補助 20"
 
 #: ../src/pulse/channelmap.c:144
 msgid "Auxiliary 21"
-msgstr ""
+msgstr "補助 21"
 
 #: ../src/pulse/channelmap.c:145
 msgid "Auxiliary 22"
-msgstr ""
+msgstr "補助 22"
 
 #: ../src/pulse/channelmap.c:146
 msgid "Auxiliary 23"
-msgstr ""
+msgstr "補助 23"
 
 #: ../src/pulse/channelmap.c:147
 msgid "Auxiliary 24"
-msgstr ""
+msgstr "補助 24"
 
 #: ../src/pulse/channelmap.c:148
 msgid "Auxiliary 25"
-msgstr ""
+msgstr "補助 25"
 
 #: ../src/pulse/channelmap.c:149
 msgid "Auxiliary 26"
-msgstr ""
+msgstr "補助 26"
 
 #: ../src/pulse/channelmap.c:150
 msgid "Auxiliary 27"
-msgstr ""
+msgstr "補助 27"
 
 #: ../src/pulse/channelmap.c:151
 msgid "Auxiliary 28"
-msgstr ""
+msgstr "補助 28"
 
 #: ../src/pulse/channelmap.c:152
 msgid "Auxiliary 29"
-msgstr ""
+msgstr "補助 29"
 
 #: ../src/pulse/channelmap.c:153
 msgid "Auxiliary 30"
-msgstr ""
+msgstr "補助 30"
 
 #: ../src/pulse/channelmap.c:154
 msgid "Auxiliary 31"
-msgstr ""
+msgstr "補助 31"
 
 #: ../src/pulse/channelmap.c:156
 msgid "Top Center"
-msgstr ""
+msgstr "上部中央"
 
 #: ../src/pulse/channelmap.c:158
 msgid "Top Front Center"
-msgstr ""
+msgstr "上部中央前"
 
 #: ../src/pulse/channelmap.c:159
 msgid "Top Front Left"
-msgstr ""
+msgstr "上部左前"
 
 #: ../src/pulse/channelmap.c:160
 msgid "Top Front Right"
-msgstr ""
+msgstr "上部右前"
 
 #: ../src/pulse/channelmap.c:162
 msgid "Top Rear Center"
-msgstr ""
+msgstr "上部中央後ろ"
 
 #: ../src/pulse/channelmap.c:163
 msgid "Top Rear Left"
-msgstr ""
+msgstr "上部左後ろ"
 
 #: ../src/pulse/channelmap.c:164
 msgid "Top Rear Right"
-msgstr ""
+msgstr "上部右後ろ"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
-msgstr ""
+msgstr "無効)"
 
 #: ../src/pulse/channelmap.c:761
 msgid "Stereo"
-msgstr ""
+msgstr "ステレオ"
 
 #: ../src/pulse/channelmap.c:766
 msgid "Surround 4.0"
-msgstr ""
+msgstr "サラウンド 4.0"
 
 #: ../src/pulse/channelmap.c:772
 msgid "Surround 4.1"
-msgstr ""
+msgstr "サラウンド 4.1"
 
 #: ../src/pulse/channelmap.c:778
 msgid "Surround 5.0"
-msgstr ""
+msgstr "サラウンド 5.0"
 
 #: ../src/pulse/channelmap.c:784
 msgid "Surround 5.1"
-msgstr ""
+msgstr "サラウンド 5.1"
 
 #: ../src/pulse/channelmap.c:791
 msgid "Surround 7.1"
-msgstr ""
+msgstr "サラウンド 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
-msgstr ""
+msgstr "OK"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
-msgstr ""
+msgstr "アクセス拒否"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
-msgstr ""
+msgstr "不明なコマンド"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
-msgstr ""
+msgstr "無効な引数"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
-msgstr ""
+msgstr "エンティティは存在します"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
-msgstr ""
+msgstr "そのようなエンティティはありません"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
-msgstr ""
+msgstr "接続拒否"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
-msgstr ""
+msgstr "プロトコルエラー"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
-msgstr ""
+msgstr "タイムアウト"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
-msgstr ""
+msgstr "認証キーがありません"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
-msgstr ""
+msgstr "内部エラー"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
-msgstr ""
+msgstr "接続切断"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
-msgstr ""
+msgstr "エンティティはキルされました"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
-msgstr ""
+msgstr "無効なサーバー"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
-msgstr ""
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
+msgstr "モジュール初期化失敗"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
-msgstr ""
+msgstr "悪い状態"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
-msgstr ""
+msgstr "データ無し"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
-msgstr ""
+msgstr "互換性のないプロトコルバージョン"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
-msgstr ""
+msgstr "大き過ぎます"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
-msgstr ""
+msgstr "サポートがありません"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
-msgstr ""
+msgstr "不明なエラーコード"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
-msgstr ""
+msgstr "そのような拡張子はありません"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
-msgstr ""
+msgstr "旧来の機能"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
-msgstr ""
+msgstr "実装の欠如"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
-msgstr ""
+msgstr "クライアントはフォークされています"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
-msgstr ""
+msgstr "入力/出力 エラー"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
-msgstr ""
+msgstr "デバイスか、リソースがビジー"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
-msgstr ""
+msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
-msgstr ""
+msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
-msgstr ""
+msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
-msgstr ""
+msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
-msgstr ""
+msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() は失敗: %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
 msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
-msgstr ""
+msgstr "クッキーデータの構文解析に失敗"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
-msgstr ""
+msgstr "設定ファイル'%s' を開くのに失敗: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
-msgstr ""
+msgstr "クッキーがロードされていません。無い状態で接続を試行"
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
-msgstr ""
+msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
-msgstr ""
+msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
-msgstr ""
+msgstr "不明な拡張子 '%s' のメッセージを受信"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
-msgstr ""
+msgstr "ストリームの排出に失敗: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
-msgstr ""
+msgstr "排出したストリームを再生"
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
-msgstr ""
+msgstr "サーバーへの排出接続"
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
-msgstr ""
+msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
-msgstr ""
+msgstr "pa_stream_write() は失敗: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
-msgstr ""
+msgstr "pa_stream_begin_write() は失敗: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
-msgstr ""
+msgstr "pa_stream_peek() は失敗: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
-msgstr ""
+msgstr "ストリームは正常に作成完了"
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
-msgstr ""
+msgstr "pa_stream_get_buffer_attr() は失敗: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
-msgstr ""
+msgstr "バッファメトリックス: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
-msgstr ""
+msgstr "バッファメトリックス: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
-msgstr ""
+msgstr "サンプル仕様 '%s' 、チャンネルマップ '%s' を使用。"
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
-msgstr ""
+msgstr "デバイス %s に接続 (%u, %ssuspended)"
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
-msgstr ""
+msgstr "ストリームエラー: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
-msgstr ""
+msgstr "ストリームデバイス休止 %s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
-msgstr ""
+msgstr "ストリームデバイス復帰 %s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
-msgstr ""
+msgstr "ストリームアンダーラン %s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
-msgstr ""
+msgstr "ストリームオーバーラン %s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
-msgstr ""
+msgstr "ストリーム開始 %s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
-msgstr ""
+msgstr "ストリームはデバイス %s へ移動 (%u, %ssuspended).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
-msgstr ""
+msgstr "not "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
+msgstr "ストリームバッファの属性変更 %s"
+
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
 msgstr ""
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
-msgstr ""
+msgstr "接続が確立 %s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
-msgstr ""
+msgstr "pa_stream_new() は失敗: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
-msgstr ""
+msgstr "pa_stream_connect_playback() は失敗: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
-msgstr ""
+msgstr "pa_stream_connect_record() は失敗: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
-msgstr ""
+msgstr "接続失敗: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
-msgstr ""
+msgstr "EOF 取得"
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
-msgstr ""
+msgstr "write() は失敗: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
-msgstr ""
+msgstr "信号取得、退出中"
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
-msgstr ""
+msgstr "レイテンシー取得に失敗: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
-msgstr ""
+msgstr "時間: %0.3f sec ; レイテンシー: %0.0f usec"
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
-msgstr ""
+msgstr "pa_stream_update_timing_info() は失敗: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1264,184 +1443,250 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
-
-#: ../src/utils/pacat.c:731
+"%s [options]\n"
+"\n"
+"  -h, --help                            このヘルプを表示\n"
+"      --version                         バージョンを表示\n"
+"\n"
+"  -r, --record                          録音用の接続を作成\n"
+"  -p, --playback                        再生用の接続を作成\n"
+"\n"
+"  -v, --verbose                         詳細操作を有効にする\n"
+"\n"
+"  -s, --server=SERVER                   接続先サーバーの名前 \n"
+"  -d, --device=DEVICE                   接続先シンク/ソースの名前 \n"
+"  -n, --client-name=NAME                サーバーでこのクライアントへのコール"
+"方法 \n"
+"      --stream-name=NAME                サーバー上でこのストリームへのコール"
+"方法\n"
+"      --volume=VOLUME                   初期 (リニア) ボリューム幅を指定  "
+"0...65536\n"
+"      --rate=SAMPLERATE                 サンプルレートを Hz で表示 (デフォル"
+"トは 44100)\n"
+"      --format=SAMPLEFORMAT             サンプルタイプ, 次の1つ s16le, "
+"s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be, "
+"s24le, s24be,\n"
+"                                        s24-32le, s24-32be (デフォルトは "
+"s16ne)\n"
+"      --channels=CHANNELS               チャンネルの数, モノ用に1, ステレオ"
+"用に2\n"
+"                                        (デフォルトは 2)\n"
+"      --channel-map=CHANNELMAP          デフォルトの代わりに使用するチャンネ"
+"ルマップ \n"
+"      --fix-format                      ストリームの接続先であるシンクからサ"
+"ンプル形式を取る \n"
+"\n"
+"      --fix-rate                        ストリームの接続先であるシンクからサ"
+"ンプルレートを取る \n"
+"\n"
+"      --fix-channels                    ストリームの接続先であるシンクから"
+"チャンネル数と チャンネルマップを取る\n"
+"\n"
+"      --no-remix                         チャンネルのアップミックスやダウン"
+"ミックスをしない\n"
+"      --no-remap                        名前の代わりにインデックスでチャンネ"
+"ルをマップする\n"
+"      --latency=BYTES                   指定レイテンシーをバイトで要求 \n"
+"      --process-time=BYTES              要求毎の指定プロセスタイムをバイトで"
+"要求 \n"
+"      --property=PROPERTY=VALUE         指定プロパティを指定値にセット\n"
+"      --raw                             録音/再生の生の PCM データ\n"
+"      --file-format=FFORMAT             録音/再生のフォーマットした PCM デー"
+"タ\n"
+"      --list-file-formats               利用可能なファイル形式を一覧表示\n"
+
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
 "Compiled with libpulse %s\n"
 "Linked with libpulse %s\n"
 msgstr ""
+"pacat %s\n"
+"libpulse %s でコンパイル \n"
+"libpulse %s で接続\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
-msgstr ""
+msgstr "無効なクライアント名 '%s'"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
-msgstr ""
+msgstr "無効なストリーム名 '%s'"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
-msgstr ""
+msgstr "無効なチャンネルマップ '%s'"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
-msgstr ""
+msgstr "無効なレイテンシー仕様 '%s'"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
-msgstr ""
+msgstr "無効なプロセスタイム仕様 '%s'"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
-msgstr ""
+msgstr "無効なプロパティ '%s'"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
-msgstr ""
+msgstr "不明なファイル形式 '%s'"
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
-msgstr ""
+msgstr "無効なサンプル仕様"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
-msgstr ""
+msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
-msgstr ""
+msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
-msgstr ""
+msgstr "引数が多過ぎます。"
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
-msgstr ""
+msgstr "ファイル用のサンプル仕様の生成に失敗しました。"
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
-msgstr ""
+msgstr "オーディオファイルを開くのに失敗しました。"
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
-msgstr ""
+msgstr "警告: 指定されたサンプルの仕様はファイルからの仕様で上書きされます。"
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
-msgstr ""
+msgstr "ファイルからのサンプル仕様の決定に失敗しました。"
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
-msgstr ""
+msgstr "警告: ファイルからのチャンネルマップの決定に失敗しました。"
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
-msgstr ""
+msgstr "チャンネルマップはサンプル仕様に一致しません。"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
-msgstr ""
+msgstr "警告: ファイルへのチャンネルマップ書き込みに失敗しました。"
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr ""
+"サンプル仕様 '%s' と チャンネルマップ '%s' で  %s ストリームを開いています。"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
-msgstr ""
+msgstr "録音"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
-msgstr ""
+msgstr "再生"
+
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "コマンドラインの構文解析に失敗しました。"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
-msgstr ""
+msgstr "pa_mainloop_new() は失敗"
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
-msgstr ""
+msgstr "io_new() は失敗"
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
-msgstr ""
+msgstr "pa_context_new() は失敗"
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
-msgstr ""
+msgstr "pa_context_connect() は失敗: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
-msgstr ""
+msgstr "pa_context_rttime_new() は失敗"
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
-msgstr ""
+msgstr "pa_mainloop_run() は失敗"
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
-msgstr ""
+msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
-msgstr ""
+msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
-msgstr ""
+msgstr "休止の失敗: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
-msgstr ""
+msgstr "復帰の失敗: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
-msgstr ""
+msgstr "警告: サウンドサーバーはローカルではありません。休止しません。\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
-msgstr ""
+msgstr "接続失敗 : %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
-msgstr ""
+msgstr "SIGINT 取得、退出中 \n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
-msgstr ""
+msgstr "警告: 子プロセスは信号 %u で終了しました\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1452,6 +1697,12 @@ msgid ""
 "to\n"
 "\n"
 msgstr ""
+"%s [オプション] ... \n"
+"\n"
+"  -h, --help                            このヘルプを表示\n"
+"      --version                         バージョンを表示\n"
+"  -s, --server=SERVER                   接続先サーバーの名前 \n"
+"\n"
 
 #: ../src/utils/pasuspender.c:248
 #, c-format
@@ -1460,51 +1711,65 @@ msgid ""
 "Compiled with libpulse %s\n"
 "Linked with libpulse %s\n"
 msgstr ""
+"pasuspender %s\n"
+"libpulse %s でコンパイル\n"
+"libpulse %s でリンク\n"
 
 #: ../src/utils/pasuspender.c:277
 #, c-format
 msgid "pa_mainloop_new() failed.\n"
-msgstr ""
+msgstr "pa_mainloop_new() は失敗\n"
 
 #: ../src/utils/pasuspender.c:290
 #, c-format
 msgid "pa_context_new() failed.\n"
-msgstr ""
+msgstr "pa_context_new() は失敗\n"
 
 #: ../src/utils/pasuspender.c:298
 #, c-format
 msgid "pa_mainloop_run() failed.\n"
-msgstr ""
+msgstr "pa_mainloop_run() は失敗\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
-msgstr ""
+msgstr "統計の取得に失敗しました: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
-msgstr ""
+msgstr "現在使用中: %u ブロックは合計 %s バイトを含む \n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
-msgstr ""
+msgstr "総寿命の期間中に割り当て: %u ブロックは合計  %s バイトを含む\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
-msgstr ""
+msgstr "サンプルのキャッシュサイズ: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
-msgstr ""
+msgstr "サーバー情報の取得に失敗 : %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1512,16 +1777,25 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
+"ユーザー名: %s\n"
+"ホスト名: %s\n"
+"サーバー名: %s\n"
+"サーバーバージョン: %s\n"
+"デフォルトサンプル仕様: %s\n"
+"デフォルトチャンネルマップ: %s\n"
+"デフォルトシンク: %s\n"
+"デフォルトソース: %s\n"
+"クッキー: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
-msgstr ""
+msgstr "シンク情報の取得に失敗しました: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1537,27 +1811,49 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
+"シンク #%u\n"
+"\t状態: %s\n"
+"\t名前: %s\n"
+"\t説明: %s\n"
+"\tドライバー: %s\n"
+"\tサンプル仕様: %s\n"
+"\tチャンネルマップ: %s\n"
+"\tオーナーモジュール: %u\n"
+"\tミュート: %s\n"
+"\tボリューム: %s%s%s\n"
+"\t        バランス %0.2f\n"
+"\tベースボリューム: %s%s%s\n"
+"\tモニターソース: %s\n"
+"\tレイテンシー: %0.0f usec, 設定 %0.0f usec\n"
+"\tフラグ: %s%s%s%s%s%s\n"
+"\tプロパティ:\n"
+"\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
-msgstr ""
+msgstr "\tポート:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
-msgstr ""
+msgstr "\t活動中ポート: %s\n"
+
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tポート:\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
-msgstr ""
+msgstr "ソース情報の取得に失敗しました: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1578,21 +1874,38 @@ msgid ""
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
+"ソース #%u\n"
+"\t状態: %s\n"
+"\t名前: %s\n"
+"\t説明: %s\n"
+"\tドライバー: %s\n"
+"\tサンプル仕様: %s\n"
+"\tチャンネルマップ: %s\n"
+"\tオーナーモジュール: %u\n"
+"\tミュート: %s\n"
+"\tボリューム: %s%s%s\n"
+"\t        バランス %0.2f\n"
+"\tベースボリューム: %s%s%s\n"
+"\tシンクのモニター: %s\n"
+"\tレイテンシー: %0.0f usec, 設定 %0.0f usec\n"
+"\tフラグ: %s%s%s%s%s%s\n"
+"\tプロパティ:\n"
+"\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
-msgstr ""
+msgstr "n/a"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
-msgstr ""
+msgstr "モジュール情報の取得に失敗しました: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1602,13 +1915,19 @@ msgid ""
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
+"モジュール #%u\n"
+"\t名前: %s\n"
+"\t引数: %s\n"
+"\t使用度カウンター: %s\n"
+"\tプロパティ:\n"
+"\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
-msgstr ""
+msgstr "クライアント情報の取得に失敗しました: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1617,13 +1936,18 @@ msgid ""
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
+"クライアント #%u\n"
+"\tドライバー: %s\n"
+"\tオーナーモジュール: %s\n"
+"\tプロパティ:\n"
+"\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
-msgstr ""
+msgstr "カード情報の取得に失敗しました: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1633,24 +1957,30 @@ msgid ""
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
+"カード #%u\n"
+"\t名前: %s\n"
+"\tドライバー: %s\n"
+"\tモジュール: %s\n"
+"\tプロパティ:\n"
+"\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
-msgstr ""
+msgstr "\tプロフィール:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
-msgstr ""
+msgstr "\t有効なプロフィール: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
-msgstr ""
+msgstr "シンク入力情報の取得に失敗しました: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1659,6 +1989,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1669,14 +2000,30 @@ msgid ""
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
+"シンク入力 #%u\n"
+"\tドライバー: %s\n"
+"\tオーナーモジュール: %s\n"
+"\tクライアント: %s\n"
+"\tシンク: %u\n"
+"\tサンプル仕様: %s\n"
+"\tチャンネルマップ: %s\n"
+"\tミュート: %s\n"
+"\tボリューム: %s\n"
+"\t        %s\n"
+"\t        バランス %0.2f\n"
+"\tバッファレイテンシー: %0.0f usec\n"
+"\tシンクレイテンシー: %0.0f usec\n"
+"\t再サンプル方法: %s\n"
+"\tプロパティ:\n"
+"\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
-msgstr ""
+msgstr "ソース出力情報の取得に失敗しました: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1685,19 +2032,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
+"シンク入力 #%u\n"
+"\tドライバー: %s\n"
+"\tオーナーモジュール: %s\n"
+"\tクライアント: %s\n"
+"\tシンク: %u\n"
+"\tサンプル仕様: %s\n"
+"\tチャンネルマップ: %s\n"
+"\tミュート: %s\n"
+"\tボリューム: %s\n"
+"\t        %s\n"
+"\t        バランス %0.2f\n"
+"\tバッファレイテンシー: %0.0f usec\n"
+"\tシンクレイテンシー: %0.0f usec\n"
+"\t再サンプル方法: %s\n"
+"\tプロパティ:\n"
+"\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
-msgstr ""
+msgstr "サンプル情報の取得に失敗しました: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1714,49 +2082,177 @@ msgid ""
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
+"サンプル #%u\n"
+"\t名前: %s\n"
+"\tサンプル仕様: %s\n"
+"\tチャンネルマップ: %s\n"
+"\tボリューム: %s\n"
+"\t        %s\n"
+"\t        バランス %0.2f\n"
+"\t継続期間: %0.1fs\n"
+"\tサイズ: %s\n"
+"\tレイジー: %s\n"
+"\tファイル名e: %s\n"
+"\tプロパティ:\n"
+"\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
-msgstr ""
+msgstr "失敗: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "ソース情報の取得に失敗しました: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
-msgstr ""
+msgstr "サンプルのアップロードに失敗しました: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
+msgstr "ファイルの早期終了"
+
+#: ../src/utils/pactl.c:991
+msgid "new"
 msgstr ""
 
-#: ../src/utils/pactl.c:863
-msgid "Got SIGINT, exiting."
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
 msgstr ""
 
-#: ../src/utils/pactl.c:869
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "無効なサーバー"
+
+#: ../src/utils/pactl.c:1041
 #, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
+msgid "Got SIGINT, exiting."
+msgstr "SIGINT を取得、退出中"
+
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "無効なボリューム仕様"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -1766,115 +2262,158 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
+"%s [オプション] ... \n"
+"\n"
+"  -h, --help                            このヘルプを表示\n"
+"      --version                         バージョンを表示\n"
+"  -s, --server=SERVER                   接続先サーバーの名前 \n"
+"\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
 "Compiled with libpulse %s\n"
 "Linked with libpulse %s\n"
 msgstr ""
+"pactl %s\n"
+"libpulse %s でコンパイル\n"
+"libpulse %s でリンク\n"
 
-#: ../src/utils/pactl.c:979
-msgid "Please specify a sample file to load"
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
 msgstr ""
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1449
+msgid "Please specify a sample file to load"
+msgstr "ロードするサンプルファイルを指定して下さい"
+
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
-msgstr ""
+msgstr "サウンドファイルを開くのに失敗しました。"
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
-msgstr ""
+msgstr "警告: ファイルからサンプル仕様を決定するのに失敗しました。"
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
-msgstr ""
+msgstr "再生するサンプル名を指定する必要があります"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
-msgstr ""
+msgstr "削除するサンプル名を指定する必要があります。"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
-msgstr ""
+msgstr "シンク入力インデックスとシンクを指定する必要があります"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
-msgstr ""
+msgstr "ソース出力インデックスとソースを指定する必要があります"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
-msgstr ""
+msgstr "モジュール名と引数を指定する必要があります"
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
-msgstr ""
+msgstr "モジュールインデックスを指定する必要があります"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
+"シンクは1つ以上は指定できません。ブーリアン値を1つ指定する必要があります。"
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr ""
+"ソースは1つ以上は指定できません。ブーリアン値を1つ指定する必要があります。"
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
-msgstr ""
+msgstr "カードの名前/インデックスとプロフィール名を指定する必要があります"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
-msgstr ""
+msgstr "シンクの名前/インデックスとポート名を指定する必要があります"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
-msgstr ""
+msgstr "ソースの名前/インデックスとポート名を指定する必要があります"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
-msgstr ""
+msgstr "シンクの名前/インデックスとボリュームを指定する必要があります"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr ""
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
-msgstr ""
+msgstr "ソースの名前/インデックスとボリュームを指定する必要があります"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
-msgstr ""
+msgstr "シンク入力インデックスとボリュームを指定する必要があります"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
-msgstr ""
+msgstr "無効なシンク入力インデックス"
+
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "ソース出力インデックスとソースを指定する必要があります"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "無効なシンク入力インデックス"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
-msgstr ""
+msgstr "シンクの名前/インデックスとミュートブーリアンを指定する必要があります"
+
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "無効なサンプル仕様"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
-msgstr ""
+msgstr "ソースの名前/インデックスとミュートブーリアンを指定する必要があります"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
-msgstr ""
+msgstr "シンク入力インデックスとミュートブーリアンを指定する必要があります"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
-msgstr ""
+msgstr "無効なシンク入力インデックス仕様"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "ソースの名前/インデックスとミュートブーリアンを指定する必要があります"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "無効なシンク入力インデックス仕様"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "シンクの名前/インデックスとミュートブーリアンを指定する必要があります"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
-msgstr ""
+msgstr "有効なコマンドが指定されていません"
 
 #: ../src/utils/pax11publish.c:61
 #, c-format
@@ -1887,109 +2426,119 @@ msgid ""
 "variables and cookie file.\n"
 " -r    Remove PulseAudio data from X11 display\n"
 msgstr ""
+"%s [-D display] [-S server] [-O sink] [-I source] [-c file]  [-d|-e|-i|-r]\n"
+"\n"
+" -d    X11 ディスプレイに接続した現在の PulseAudio のデータを表示 (デフォル"
+"ト)\n"
+" -e    X11 ディスプレイにローカル PulseAudio データをエキスポート\n"
+" -i    X11 ディスプレイからローカル環境変数とクッキーに PulseAudio データをイ"
+"ンポート \n"
+" -r    X11 ディスプレイから PulseAudio データを削除\n"
 
 #: ../src/utils/pax11publish.c:94
 #, c-format
 msgid "Failed to parse command line.\n"
-msgstr ""
+msgstr "コマンドラインの構文解析に失敗\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
-msgstr ""
+msgstr "サーバー: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
-msgstr ""
+msgstr "ソース: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
-msgstr ""
+msgstr "シンク: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
-msgstr ""
+msgstr "クッキー: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
-msgstr ""
+msgstr "クッキーデータの構文解析に失敗\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
-msgstr ""
+msgstr "クッキーデータの保存に失敗\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
-msgstr ""
+msgstr "クライアント設定ファイルのロードに失敗\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
-msgstr ""
+msgstr "環境設定データの読み込みに失敗 \n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
-msgstr ""
+msgstr "FQDN の取得に失敗 \n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
-msgstr ""
+msgstr "クッキーデータのロードに失敗\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
-msgstr ""
+msgstr "まだ実装されていません\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr ""
+"PulseAudio デーモン自身が稼働していないか、又はセッションデーモンとして稼働し"
+"ていません。"
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
-msgstr ""
+msgstr "ソケット (PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
-msgstr ""
+msgstr "PulseAudio のキルに失敗"
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
-msgstr ""
+msgstr "デーモンが応答しません"
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
-msgstr ""
+msgstr "autospawn ロックにアクセスできません"
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -1999,8 +2548,14 @@ msgid ""
 "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:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2010,229 +2565,470 @@ msgid ""
 "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/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "オフ"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
-msgstr ""
+msgstr "ハイファイ再生 (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
-msgstr ""
+msgstr "ハイファイキャプチャ (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
+msgstr "テレフォニーデュプレックス (HSP/HFP)"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
 msgstr ""
 
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
-msgstr ""
+msgstr "PulseAudio サウンドサーバー"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
-msgstr ""
+msgstr "出力デバイス"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
-msgstr ""
+msgstr "入力デバイス"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
-msgstr ""
+msgstr "@HOSTNAME@ 上のオーディオ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
-msgstr ""
+msgstr "入力"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
-msgstr ""
+msgstr "ドッキングステーション入力"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
-msgstr ""
+msgstr "ドッキングステーションマイクロフォン"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "ドッキングステーション入力"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "ラインイン"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
-msgstr ""
+msgstr "マイクロフォン"
+
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "ドッキングステーションマイクロフォン"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "マイクロフォン"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
 msgid "External Microphone"
-msgstr ""
+msgstr "外部マイクロフォン"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
-msgstr ""
+msgstr "内部マイクロフォン"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
-msgstr ""
+msgstr "ラジオ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
-msgstr ""
+msgstr "ビデオ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
-msgstr ""
+msgstr "自動ゲイン制御"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
-msgstr ""
+msgstr "自動ゲイン制御なし"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
-msgstr ""
+msgstr "ブースト"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
-msgstr ""
+msgstr "ブーストなし"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
-msgstr ""
+msgstr "アンプ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
-msgstr ""
+msgstr "アンプなし"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "ブースト"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "ブーストなし"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "アナログヘッドフォン"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "アナログ入力"
+
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "ドッキングステーションマイクロフォン"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
-msgstr ""
+msgstr "アナログ出力"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "アナログ出力 (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "ラインイン"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
+msgstr "アナログモノ出力"
+
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "アナログステレオ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, fuzzy, c-format
-msgid "%s+%s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "デジタルステレオ (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, fuzzy, c-format
-msgid "%s / %s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "デジタルステレオ (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
-msgstr ""
+msgstr "アナログモノ"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
-msgstr ""
+msgstr "アナログステレオ"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
-msgstr ""
+msgstr "アナログサラウンド 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
-msgstr ""
+msgstr "アナログサラウンド 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
-msgstr ""
+msgstr "アナログサラウンド 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
-msgstr ""
+msgstr "アナログサラウンド 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
-msgstr ""
+msgstr "アナログサラウンド 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
-msgstr ""
+msgstr "アナログサラウンド 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
-msgstr ""
+msgstr "アナログサラウンド 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
-msgstr ""
+msgstr "アナログサラウンド 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
-msgstr ""
+msgstr "アナログサラウンド 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
-msgstr ""
+msgstr "アナログサラウンド 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
-msgstr ""
+msgstr "アナログサラウンド 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
-msgstr ""
+msgstr "デジタルステレオ (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "デジタルステレオ (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
-msgstr ""
+msgstr "デジタルサラウンド 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
-msgstr ""
+msgstr "デジタルサラウンド 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
-msgstr ""
+msgstr "デジタルステレオ (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "デジタルサラウンド 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
-msgstr ""
+msgstr "アナログモノデュプレックス"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
-msgstr ""
+msgstr "アナログステレオデュプレックス"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
+msgstr "デジタルステレオデュプレックス (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Null 出力"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "入力"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<シンクの名前> sink_properties=<シンクのプロパティ> master=<フィル"
+"タするシンク名> format=<サンプル形式> rate=<サンプルレート> channels=<チャン"
+"ネル数> channel_map=<チャンネルマップ> plugin=<ladspa plugin の名前> "
+"label=<ladspa plugin のラベル> control=<コンマで隔離した入力制御値の 一覧>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
 msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit はこのプラットフォームではサポートがありません。"
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() は失敗"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "ソース出力 #%u\n"
+#~ "\tドライバー: %s\n"
+#~ "\tオーナーモジュール: %s\n"
+#~ "\tクライアント: %s\n"
+#~ "\tソース: %u\n"
+#~ "\tサンプル仕様: %s\n"
+#~ "\tチャンネルマップ: %s\n"
+#~ "\tバッファレイテンシー: %0.0f usec\n"
+#~ "\tソースレイテンシー: %0.0f usec\n"
+#~ "\t再サンプル方法: %s\n"
+#~ "\tプロパティ:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [オプション] stat\n"
+#~ "%s [オプション] list\n"
+#~ "%s [オプション] exit\n"
+#~ "%s [オプション] upload-sample FILENAME [NAME]\n"
+#~ "%s [オプション] play-sample NAME [SINK]\n"
+#~ "%s [オプション] remove-sample NAME\n"
+#~ "%s [オプション] move-sink-input SINKINPUT SINK\n"
+#~ "%s [オプション] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [オプション] load-module NAME [ARGS ...]\n"
+#~ "%s [オプション] unload-module MODULE\n"
+#~ "%s [オプション] suspend-sink SINK 1|0\n"
+#~ "%s [オプション] suspend-source SOURCE 1|0\n"
+#~ "%s [オプション] set-card-profile CARD PROFILE\n"
+#~ "%s [オプション] set-sink-port SINK PORT\n"
+#~ "%s [オプション] set-source-port SOURCE PORT\n"
+#~ "%s [オプション] set-sink-volume SINK VOLUME\n"
+#~ "%s [オプション] set-source-volume SOURCE VOLUME\n"
+#~ "%s [オプション] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [オプション] set-sink-mute SINK 1|0\n"
+#~ "%s [オプション] set-source-mute SOURCE 1|0\n"
+#~ "%s [オプション] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            このヘルプを表示\n"
+#~ "      --version                         バージョンを表示\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   接続先サーバーの名前 \n"
+#~ "  -n, --client-name=NAME                サーバーでこのクライアントへのコー"
+#~ "ル方法 \n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "デジタルサラウンド 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "低周波エミッタ"
index 4b2750a..e28279b 100644 (file)
--- a/po/kn.po
+++ b/po/kn.po
@@ -1,28 +1,24 @@
 # translation of pulseaudio.master-tx.kn.po to Kannada
 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the PACKAGE package.
+# Shankar Prasad <svenkate@redhat.com>, 2009, 2012.
 #
-# Shankar Prasad <svenkate@redhat.com>, 2009.
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx.kn\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-09-22 15:32+0530\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:54+0000\n"
 "Last-Translator: Shankar Prasad <svenkate@redhat.com>\n"
-"Language-Team: Kannada <en@li.org>\n"
+"Language-Team: Kannada <kde-l10n-kn@kde.org>\n"
+"Language: kn\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Generator: KBabel 1.11.4\n"
+"X-Generator: Lokalize 1.0\n"
 "Plural-Forms:  nplurals=2; plural=(n != 1);\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -34,11 +30,11 @@ msgstr ""
 "ಇದಕ್ಕೆ ALSA ಚಾಲಕ '%s' ದಲ್ಲಿನ ಒಂದು ದೋಷದ ಕಾರಣವಿರಬಹುದು. ದಯವಿಟ್ಟುಈ ತೊಂದರೆಯನ್ನು ALSA "
 "ವಿಕಸನಗಾರರ ಗಮನಕ್ಕೆ ತನ್ನಿ."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
@@ -46,7 +42,19 @@ msgstr ""
 "ಇದಕ್ಕೆ ALSA ಚಾಲಕ '%s' ದಲ್ಲಿನ ಒಂದು ದೋಷದ ಕಾರಣವಿರಬಹುದು. ದಯವಿಟ್ಟುಈ ತೊಂದರೆಯನ್ನು ALSA "
 "ವಿಕಸನಗಾರರ ಗಮನಕ್ಕೆ ತನ್ನಿ."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() ದಿಂದ ಅತ್ಯಂತ ದೊಡ್ಡದಾದ ಮೌಲ್ಯವು ಮರಳಿದೆ: %lu ಬೈಟ್‌ಗಳು (%lu ms).\n"
+"ಇದಕ್ಕೆ ALSA ಚಾಲಕ '%s' ದಲ್ಲಿನ ಒಂದು ದೋಷದ ಕಾರಣವಿರಬಹುದು. ದಯವಿಟ್ಟುಈ ತೊಂದರೆಯನ್ನು ALSA "
+"ವಿಕಸನಗಾರರ ಗಮನಕ್ಕೆ ತನ್ನಿ."
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -58,25 +66,28 @@ msgstr ""
 "ಇದಕ್ಕೆ ALSA ಚಾಲಕ '%s' ದಲ್ಲಿನ ಒಂದು ದೋಷದ ಕಾರಣವಿರಬಹುದು. ದಯವಿಟ್ಟುಈ ತೊಂದರೆಯನ್ನು ALSA "
 "ವಿಕಸನಗಾರರ ಗಮನಕ್ಕೆ ತನ್ನಿ."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "ಯಾವಾಗಲೂ ಒಂದು ಸಿಂಕ್‌ ಅನ್ನು ಲೋಡ್ ಮಾಡಿರುತ್ತದೆ, ಅದು ಶೂನ್ಯವಾಗಿದ್ದರೂ ಸಹ"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "ಡಮ್ಮಿ ಔಟ್‌ಪುಟ್"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "ವರ್ಚುವಲ್ LADSPA ಸಿಂಕ್"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<ಸಿಂಕ್‌ನ ಹೆಸರು> sink_properties=<ಸಿಂಕ್‌ನ ಗುಣಗಳು> master=<ಫಿಲ್ಟರ್ "
 "ಮಾಡಬೇಕಿರುವ ಸಿಂಕ್‌ನ ಹೆಸರು> format=<ನಮೂನೆ ವಿನ್ಯಾಸ> rate=<ನಮೂನೆ ದರ> "
@@ -84,120 +95,126 @@ msgstr ""
 "label=<ladspa ಪ್ಲಗ್‌ಇನ್ ಹೆಸರು> control=<ವಿರಾಮ ಚಿಹ್ನೆಗಳನ್ನು ಹೊಂದಿರುವ ಇನ್‌ಪುಟ್ ನಿಯಂತ್ರಣ "
 "ಮೌಲ್ಯಗಳ ಪಟ್ಟಿ>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "ಕ್ಲಾಕ್‌ ಮಾಡಲಾದ NULL ಸಿಂಕ್"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "ಶೂನ್ಯ ಔಟ್‌ಪುಟ್"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "ಆಂತರಿಕ ಆಡಿಯೊ"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "ಮಾಡೆಮ್"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "ಮೂಲ lt_dlopen loader ಅನ್ನು ಲೋಡ್ ಮಾಡುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "ಹೊಸ dl ಲೋಡರ್ ಅನ್ನು ನಿಯೋಜಿಸುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "bind-now-ಲೋಡರ್ ಅನ್ನು ಸೇರಿಸಲಾಗಿಲ್ಲ."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "%s ನಿಂದ ಸಂಕೇತವು ದೊರೆತಿದೆ."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "ನಿರ್ಗಮಿಸುತ್ತಿದೆ."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "ಬಳಕೆದಾರ '%s' ಅನ್ನು ಪತ್ತೆ ಮಾಡಲು ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "ಗುಂಪು '%s' ಅನ್ನು ಪತ್ತೆ ಮಾಡಲು ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "ಬಳಕೆದಾರ '%s' (UID %lu) ಹಾಗು ಗುಂಪು '%s' (GID %lu) ಕಂಡುಬಂದಿದೆ."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "ಬಳಕೆದಾರ '%s' ರ GID ಹಾಗು ಗುಂಪು '%s' ತಾಳೆಯಾಗುತ್ತಿಲ್ಲ."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "ಬಳಕೆದಾರ '%s' ರ ನೆಲೆ ಕೋಶವು '%s' ಆಗಿಲ್ಲ, ಆಲಕ್ಷಿಸಲಾಗುತ್ತಿದೆ."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "'%s' ಅನ್ನು ರಚಿಸುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "ಗುಂಪಿನ ಪಟ್ಟಿಯನ್ನು ಬದಲಾಯಿಸಲು ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "GID ಅನ್ನು ಬದಲಾಯಿಸಲು ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "UID ಅನ್ನು ಬದಲಾಯಿಸಲು ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "ರೂಟ್ ಸವಲತ್ತುಗಳನ್ನು ಯಶಸ್ವಿಯಾಗಿ ಬಿಡಲಾಗಿದೆ."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "ವ್ಯವಸ್ಥೆಯಾದ್ಯಂತದ ಕ್ರಮಕ್ಕೆ ಈ ಪ್ಲಾಟ್‌ಫಾರ್ಮಿನಲ್ಲಿ ಬೆಂಬಲವಿಲ್ಲ."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "ಆಜ್ಞಾ ಸಾಲನ್ನು ಪಾರ್ಸ್ ಮಾಡುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "ಡೀಮನ್ ಚಲಾಯಿತಗೊಳ್ಳುತ್ತಿದೆ"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "ಡೀಮನ್ PID %u ಯಾಗಿ ಚಲಾಯಿಗೊಳ್ಳುತ್ತಿದೆ"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "ಡೀಮನ್ ಅನ್ನು ಕೊಲ್ಲಲು ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -205,163 +222,184 @@ msgstr ""
 "ಈ ಪ್ರೋಗ್ರಾಮನ್ನು ರೂಟ್‌ ಆಗಿ ಚಲಾಯಿಸುವ ಉದ್ಧೇಶವನ್ನು ಹೊಂದಿಲ್ಲ (--system ಅನ್ನು ಸೂಚಿಸದೆ "
 "ಇದ್ದಲ್ಲಿ ಮಾತ್ರ)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "ನಿರ್ವಾಹಕ ಸವಲತ್ತುಗಳ ಅಗತ್ಯವಿದೆ."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "ವ್ಯವಸ್ಥೆಯ ಸನ್ನಿವೇಶದಿಂದ --start ಬೆಂಬಲಿತವಾಗಿಲ್ಲ."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr ""
 "ವ್ಯವಸ್ಥೆಯ ಕ್ರಮದಲ್ಲಿ ಚಲಾಯಿತಗೊಳ್ಳುತ್ತಿದೆ, ಆದರೆ --disallow-exit ಅನ್ನು ಹೊಂದಿಸಲಾಗಿಲ್ಲ!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
 "ವ್ಯವಸ್ಥೆಯ ಕ್ರಮದಲ್ಲಿ ಚಲಾಯಿತಗೊಳ್ಳುತ್ತಿದೆ, ಆದರೆ --disallow-module-loading ಅನ್ನು "
 "ಹೊಂದಿಸಲಾಗಿಲ್ಲ!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr ""
 "ವ್ಯವಸ್ಥೆಯ ಕ್ರಮದಲ್ಲಿ ಚಲಾಯಿತಗೊಳ್ಳುತ್ತಿದ್ದು, SHM ಕ್ರಮವನ್ನು ಒತ್ತಾಯಪೂರ್ವಕವಾಗಿ "
 "ಅಶಕ್ತಗೊಳಿಸುತ್ತಿದೆ!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 "ವ್ಯವಸ್ಥೆಯ ಕ್ರಮದಲ್ಲಿ ಚಲಾಯಿತಗೊಳ್ಳುತ್ತಿದ್ದು, ನಿರ್ಗಮಿಸುವ ಜಡ ಸಮಯವನ್ನು ಒತ್ತಾಯಪೂರ್ವಕವಾಗಿ "
 "ಅಶಕ್ತಗೊಳಿಸುತ್ತಿದೆ!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "stdio ಅನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "ಪೈಪ್‌ ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "ಡೀಮನ್ ಆರಂಭಗೊಳ್ಳುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "ಡೀಮನ್ ಅನ್ನು ಯಶಸ್ವಿಯಾಗಿ ಆರಂಭಿಸಲಾಗಿದೆ."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() ವಿಫಲಗೊಂಡಿದೆ: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "ಇದು PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "ಕಂಪೈಲ್ ಮಾಡುವ ಅತಿಥೇಯ: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "ಕಂಪೈಲ್ ಮಾಡುವ CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "ಅತಿಥೇಯದಲ್ಲಿ ಚಲಾಯಿತಗೊಳ್ಳುತ್ತಿದೆ: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "%u CPUಗಳು ಕಂಡುಬಂದಿವೆ."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "ಪುಟದ ಗಾತ್ರವು %lu ಬೈಟ್‌ಗಳಾಗಿವೆ"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Valgrind ಬೆಂಬಲದೊಂದಿಗೆ ಕಂಪೈಲ್ ಮಾಡಲಾಗಿದೆ: ಹೌದು"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Valgrind ಬೆಂಬಲದೊಂದಿಗೆ ಕಂಪೈಲ್ ಮಾಡಲಾಗಿದೆ: ಇಲ್ಲ"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "valgrind ಕ್ರಮದಲ್ಲಿ ಚಲಾಯಿಸಲಾಗುತ್ತಿದೆ: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "ಅತಿಥೇಯದಲ್ಲಿ ಚಲಾಯಿತಗೊಳ್ಳುತ್ತಿದೆ: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "ಪ್ರಶಸ್ತವಾದ ನಿರ್ಮಾಣ: ಹೌದು"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "ಪ್ರಶಸ್ತವಾದ ನಿರ್ಮಾಣ: ಇಲ್ಲ"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG ಅನ್ನು ಸೂಚಿಸಲಾಗಿದೆ, ಎಲ್ಲಾ ಪ್ರತಿಪಾದನೆಗಳನ್ನೂ ಅಶಕ್ತಗೊಳಿಸಲಾಗಿದೆ."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr ""
 "FASTPATH ಅನ್ನು ಸೂಚಿಸಲಾಗಿದೆ, ಕೇವಲ ವೇಗ ಮಾರ್ಗದ ಪ್ರತಿಪಾದನೆಗಳನ್ನೂ ಅಶಕ್ತಗೊಳಿಸಲಾಗಿದೆ."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "ಎಲ್ಲಾ ಪ್ರತಿಪಾದನೆಗಳನ್ನೂ ಶಕ್ತಗೊಳಿಸಲಾಗಿದೆ."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "ಮೆಶೀನ್ ID ಯನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "ಮೆಶೀನ್ ID ಯು %s ಆಗಿದೆ."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "ಅಧಿವೇಶನ ID ಯು %s ಆಗಿದೆ."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "ಚಲಾವಣಾಸಮಯ(ರನ್‌ಟೈಮ್) ಕೋಶ %s ಅನ್ನು ಬಳಸಿಕೊಂಡು."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "ಸ್ಥಿತಿ ಕೋಶ %s ಅನ್ನು ಬಳಸಿಕೊಂಡು."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "ಘಟಕಗಳ ಕೋಶ %s ಅನ್ನು ಬಳಸಿಕೊಂಡು."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "ವ್ಯವಸ್ಥೆಯ ಕ್ರಮದಲ್ಲಿ ಚಲಾಯಿಸಲಾಗುತ್ತಿದೆ: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -377,15 +415,15 @@ msgstr ""
 "ವ್ಯವಸ್ಥೆಯ ಕ್ರಮವು (ಸಿಸ್ಟಮ್ ಮೋಡ್) ಏಕೆ ಒಂದು ಸರಿಯಲ್ಲದ ಬಳಕೆ ಎಂದು ಅರಿಯಲು ದಯವಿಟ್ಟು http://"
 "pulseaudio.org/wiki/WhatIsWrongWithSystemMode ಅನ್ನು ನೋಡಿ."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "ತಾಜಾ ರೆಸಲ್ಯೂಶನ್ ಟೈಮರ್ ಲಭ್ಯವಿದೆ! Bon appetit!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -393,32 +431,32 @@ msgstr ""
 "ಮಹಾಶಯರೆ, ನಿಮ್ಮ ಕರ್ನಲ್ ಕೊಳೆತುಹೋಗಿದೆ! ಅತ್ಯುತ್ತಮ ರೆಸಲ್ಯೂಶನ್ ಟೈಮರ್ ಅನ್ನು ಶಕ್ತಗೊಳಿಸಲಾದ "
 "ಲಿನಕ್ಸನ್ನು ಬಳಸುವಂತೆ ಅಡುಗೆಯವರು ಸಲಹೆ ಮಾಡುತ್ತಿದ್ದಾರೆ!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "ಡೀಮನ್ ಅನ್ನು ಆರಂಭಿಸಲು ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "ಲೋಡ್ ಮಾಡಲಾದ ಯಾವುದೆ ಡೀಮನ್ ಇಲ್ಲದೆ ಆರಂಭಗೊಂಡಿದೆ, ಕೆಲಸ ಮಾಡಲು ನಿರಾಕರಿಸಿದೆ."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "ಡೀಮನ್ ಆರಂಭಗೊಳಿಕೆ ಪೂರ್ಣಗೊಂಡಿದೆ."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "ಡೀಮನ್ ಸ್ಥಗಿತಗೊಳಿಕೆಯನ್ನು ಆರಂಭಿಸಲಾಗಿದೆ."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "ಡೀಮನ್ ಅನ್ನು ಅಂತ್ಯಗೊಳಿಸಲಾಗಿದೆ."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -455,15 +493,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -565,15 +601,15 @@ msgstr ""
 "  -n                                    ಪೂರ್ವನಿಯೋಜಿತ ಸ್ಕ್ರಿಪ್ಟಿನ ಕಡತವನ್ನು ಲೋಡ್ "
 "ಮಾಡಬೇಡ\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize ಬೂಲಿಯನ್ ಆರ್ಗುಮೆಂಟನ್ನು ನಿರೀಕ್ಷಿಸುತ್ತದೆ"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail ಬೂಲಿಯನ್ ಆರ್ಗುಮೆಂಟನ್ನು ನಿರೀಕ್ಷಿಸುತ್ತದೆ"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -581,166 +617,169 @@ msgstr ""
 "--log-level ದಾಖಲೆ ಮಟ್ಟದ ಆರ್ಗುಮೆಂಟನ್ನು ನಿರೀಕ್ಷಿಸುತ್ತದೆ (0..4 ವ್ಯಾಪ್ತಿಯಲ್ಲಿನ ಅಂಕೆಯನ್ನು "
 "ಅಥವ debug, info, notice, warn, error ಅನ್ನು)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority ಬೂಲಿಯನ್ ಆರ್ಗುಮೆಂಟನ್ನು ನಿರೀಕ್ಷಿಸುತ್ತದೆ"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime ಬೂಲಿಯನ್ ಆರ್ಗುಮೆಂಟನ್ನು ನಿರೀಕ್ಷಿಸುತ್ತದೆ"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading ಬೂಲಿಯನ್ ಆರ್ಗುಮೆಂಟನ್ನು ನಿರೀಕ್ಷಿಸುತ್ತದೆ"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit ಬೂಲಿಯನ್ ಆರ್ಗುಮೆಂಟನ್ನು ನಿರೀಕ್ಷಿಸುತ್ತದೆ"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file ಬೂಲಿಯನ್ ಆರ್ಗುಮೆಂಟನ್ನು ನಿರೀಕ್ಷಿಸುತ್ತದೆ"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr "ಅಮಾನ್ಯವಾದ ದಾಖಲೆ ಗುರಿ: 'syslog', 'stderr' ಅಥವ 'auto' ಅನ್ನು ಬಳಸಿ."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time ಬೂಲಿಯನ್ ಆರ್ಗುಮೆಂಟನ್ನು ನಿರೀಕ್ಷಿಸುತ್ತದೆ"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta ಬೂಲಿಯನ್ ಆರ್ಗುಮೆಂಟನ್ನು ನಿರೀಕ್ಷಿಸುತ್ತದೆ"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "ಅಮಾನ್ಯವಾದ ಮರುನಮೂನೆ ವಿಧಾನ '%s'."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system ಬೂಲಿಯನ್ ಆರ್ಗುಮೆಂಟನ್ನು ನಿರೀಕ್ಷಿಸುತ್ತದೆ"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit ಬೂಲಿಯನ್ ಆರ್ಗುಮೆಂಟನ್ನು ನಿರೀಕ್ಷಿಸುತ್ತದೆ"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm ಬೂಲಿಯನ್ ಆರ್ಗುಮೆಂಟನ್ನು ನಿರೀಕ್ಷಿಸುತ್ತದೆ"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "ಹೆಸರು: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "ಯಾವುದೆ ಘಟಕ ಮಾಹಿತಿಯು ಲಭ್ಯವಿಲ್ಲ\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "ಆವೃತ್ತಿ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "ವಿವರಣೆ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "ಕತೃ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "ಬಳಕೆ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "ಒಮ್ಮೆ ಲೋಡ್ ಮಾಡು: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "DEPRECATION WARNING: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "ಮಾರ್ಗ: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] ಅಮಾನ್ಯವಾದ ದಾಖಲೆ ಗುರಿ '%s'."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] ಅಮಾನ್ಯವಾದ ದಾಖಲೆ ಮಟ್ಟ '%s'."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] ಅಮಾನ್ಯವಾದ ಮರುನಮೂನೆ ವಿಧಾನ '%s'."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] ಅಮಾನ್ಯವಾದ rlimit '%s'."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit ಗೆ ಈ ಪ್ಲಾಟ್‌ಫಾರ್ಮಿನಲ್ಲಿ ಬೆಂಬಲವಿಲ್ಲ."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] ಅಮಾನ್ಯವಾದ ನಮೂನೆ ರಚನೆ '%s'."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] ಅಮಾನ್ಯವಾದ ನಮೂನೆ ದರ '%s'."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] ಅಮಾನ್ಯವಾದ ನಮೂನೆ ಚಾನಲ್‌ಗಳು '%s'."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] ಅಮಾನ್ಯವಾದ ಚಾನಲ್ ನಕ್ಷೆ '%s'."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] ಅಮಾನ್ತವಾದ ಫ್ರಾಗ್ಮೆಂಟುಗಳ ಸಂಖ್ಯೆ '%s'."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] ಅಮಾನ್ಯವಾದ ಫ್ರಾಗ್ಮೆಂಟ್ ಗಾತ್ರ '%s'."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] ಅಮಾನ್ಯವಾದ ನೈಸ್‌ ಹಂತ '%s'."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] ಅಮಾನ್ಯವಾದ ನಮೂನೆ ದರ '%s'."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "ಸಂರಚನಾ ಕಡತವನ್ನು ತೆರೆಯಲು ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -748,12 +787,12 @@ msgstr ""
 "ಸೂಚಿಸಲಾದ ಪೂರ್ವನಿಯೋಜಿತ ಚಾನಲ್ ನಕ್ಷೆಯು ಪೂರ್ವನಿಯೋಜಿತ ಚಾನಲ್‌ಗಳ ಸಂಖ್ಯೆಗಳಿಗಿಂತ ವಿಭಿನ್ನವಾದ "
 "ಮಾರ್ಗಗಳ ಸಂಖ್ಯೆಯನ್ನು ಹೊಂದಿದೆ."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### ಸಂರಚನಾ ಕಡತದಿಂದ ಓದು: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "ಸವಲತ್ತುಗಳನ್ನು ಸ್ವಚ್ಛಗೊಳಿಸಲಾಗುತ್ತಿದೆ."
 
@@ -765,6 +804,16 @@ msgstr "PulseAudio ಧ್ವನಿ ವ್ಯವಸ್ಥೆ"
 msgid "Start the PulseAudio Sound System"
 msgstr "PulseAudio ಧ್ವನಿ ವ್ಯವಸ್ಥೆಯನ್ನು ಆರಂಭಿಸಿ"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio ಧ್ವನಿ ವ್ಯವಸ್ಥೆ"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "PulseAudio ಧ್ವನಿ ವ್ಯವಸ್ಥೆಯನ್ನು ಆರಂಭಿಸಿ"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "ಮೊನೊ"
@@ -794,8 +843,8 @@ msgid "Rear Right"
 msgstr "ಹಿಂಬದಿಯ ಬಲಭಾಗ"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "ಕೆಳಮಟ್ಟದ ಫ್ರೀಕ್ವೆನ್ಸಿ ಉತ್ಪಾದಕ"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -969,9 +1018,10 @@ msgstr "ಮೇಲಿನ ಹಿಂಬದಿಯ ಎಡಭಾಗ"
 msgid "Top Rear Right"
 msgstr "ಮೇಲಿನ ಹಿಂಬದಿಯ ಬಲಭಾಗ"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(ಅಮಾನ್ಯ)"
 
@@ -999,333 +1049,350 @@ msgstr "ಸರೌಂಡ್‌ 5.1"
 msgid "Surround 7.1"
 msgstr "ಸರೌಂಡ್‌ 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "ಸರಿ"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "ನಿಲುಕಣೆಯನ್ನು ತಿರಸ್ಕರಿಸಲಾಗಿದೆ"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "ಅಜ್ಞಾತ ಆಜ್ಞೆ"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "ಅಮಾನ್ಯವಾದ ಆರ್ಗ್ಯುಮೆಂಟ್"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "ನಮೂದು ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "ಅಂತಹ ಯಾವುದೆ ನಮೂದು ಇಲ್ಲ"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "ಸಂಪರ್ಕವನ್ನು ತಿರಸ್ಕರಿಸಲಾಗಿದೆ"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "ಪ್ರೊಟೊಕಾಲ್ ದೋಷ"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "ಕಾಲಾವಕಾಶ ಮುಗಿದಿದೆ"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "ಯಾವುದೆ ದೃಢೀಕರಣ ಕೀಲಿ ಇಲ್ಲ"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "ಆಂತರಿಕ ದೋಷ"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "ಸಂಪರ್ಕವನ್ನು ಅಂತ್ಯಗೊಳಿಸಲಾಗಿದೆ"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "ನಮೂದನ್ನು ಕೊಲ್ಲಲಾಗಿದೆ"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "ಅಮಾನ್ಯವಾದ ಪರಿಚಾರಕ"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "ಘಟಕವನ್ನು ಆರಂಭಿಸುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "ಸರಿಯಲ್ಲದ ಸ್ಥಿತಿ"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "ದತ್ತಾಂಶ ಇಲ್ಲ"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "ಸಹವರ್ತನೀಯವಲ್ಲದ ಪ್ರೊಟೋಕಾಲ್ ಆವೃತ್ತಿ"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "ಬಹಳ ದೊಡ್ಡದಾಗಿದೆ"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "ಬೆಂಬಲವಿಲ್ಲ"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "ಅಜ್ಞಾತ ದೋಷ ಸಂಜ್ಞೆ"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "ಅಂತಹ ಯಾವುದೆ ವಿಸ್ತರಣೆ ಇಲ್ಲ"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "ಪರಿಪೂರ್ಣ ಕ್ರಿಯಾಶೀಲತೆ"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "ಅನ್ವಯಿಸುವಿಕೆಯು ಕಾಣಿಸುತ್ತಿಲ್ಲ"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "ಕ್ಲೈಂಟ್ ಅನ್ನು ಫೋರ್ಕ್ ಮಾಡಲಾಗಿದೆ"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "ಇನ್‌ಪುಟ್/ಔಟ್‌ಪುಟ್ ದೋಷ"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "ಸಾಧನ ಅಥವ ಸಂಪನ್ಮೂಲವು ಕಾರ್ಯನಿರತವಾಗಿದೆ"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() ವಿಫಲಗೊಂಡಿದೆ"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() ವಿಫಲಗೊಂಡಿದೆ: %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "ಕುಕಿ ದತ್ತಾಂಶವನ್ನು ಪಾರ್ಸ್ ಮಾಡುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "ಸಂರಚನಾ ಕಡತ '%s' ಅನ್ನು ಲೋಡ್ ಮಾಡುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr ""
 "ಯಾವುದೆ ಕುಕಿಯನ್ನು ಲೋಡ್ ಮಾಡಲಾಗಿಲ್ಲ. ಕುಕಿ ಇಲ್ಲದೆ ಸಂಪರ್ಕಸಾಧಿಸಲು ಪ್ರಯತ್ನಿಸಲಾಗುತ್ತಿದೆ."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "ಫೋರ್ಕ್(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "ಅಜ್ಞಾತ ವಿಸ್ತರಣೆ '%s' ಇಂದ ಸಂದೇಶವನ್ನು ಪಡೆದುಕೊಳ್ಳಲಾಗಿದೆ"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "ಸ್ಟ್ರೀಮನ್ನು ಬರಿದಾಗಿಸುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "ಪ್ಲೇಬ್ಯಾಕ್ ಸ್ಟ್ರೀಮನ್ನು ಬರಿದಾಗಿಸಲಾಗಿದೆ."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "ಪರಿಚಾರಕಕ್ಕೆ ಬರಿದಾಗಿಸುವ ಸಂಪರ್ಕ."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_begin_write() ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "ಸ್ಟ್ರೀಮನ್ನು ಯಶಸ್ವಿಯಾಗಿ ನಿರ್ಮಿಸಲಾಗಿದೆ."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, 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:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "ಬಫರ್ ಮೆಟ್ರಿಕ್‌ಗಳು: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "ನಮೂನೆಯ ವಿವರ '%s' ಅನ್ನು, ಚಾನಲ್‌ ನಕ್ಷೆ '%s' ಅನ್ನು ಬಳಸಿಕೊಂಡು."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "ಸಾಧನ %s ಕ್ಕೆ ಸಂಪರ್ಕ ಜೋಡಿಸಲಾಗಿದೆ (%u, %ssuspended)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "ಸ್ಟ್ರೀಮ್ ದೋಷ: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "ಸ್ಟ್ರೀಮ್ ಸಾಧನವನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ತಡೆಹಿಡಿಯಲಾಗಿದೆ.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "ಸ್ಟ್ರೀಮ್ ಸಾಧನವನ್ನು ಮರಳಿ ಆರಂಭಿಸಲಾಗಿದೆ.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "ಸ್ಟ್ರೀಮ್ ಅನ್ನು ಕಡಿಮೆ ಚಲಾಯಿಸಲಾಗಿದೆ.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "ಸ್ಟ್ರೀಮ್ ಅನ್ನು ಹೆಚ್ಚು ಚಲಾಯಿಸಲಾಗಿದೆ.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "ಸ್ಟ್ರೀಮ್ ಅನ್ನು ಆರಂಭಿಸಲಾಗಿದೆ.%s "
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "ಸಾಧನ %s ಕ್ಕೆ ಸ್ಟ್ರೀಮ್‌ ಅನ್ನು ಸ್ಥಳಾಂತರಿಸಲಾಗಿದೆ (%u, %ssuspended).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "ಇಲ್ಲ "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "ಸ್ಟ್ರೀಮ್ ಬಫರ್ ಗುಣವಿಶೇಷತೆಗಳನ್ನು ಬದಲಾಯಿಸಲಾಗಿದೆ.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "ಸಂಪರ್ಕವನ್ನು ಸಾಧಿಸಲಾಗಿದೆ.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "ಸಂಪರ್ಕದ ವಿಫಲತೆ: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "EOF ಅನ್ನು ಪಡೆಯಲಾಗಿದೆ."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "ಸಂಕೇತ ದೊರೆತಿದೆ, ನಿರ್ಗಮಿಸುತ್ತಿದೆ."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "ಅಗೋಚರತೆಯನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "ಸಮಯ: %0.3f sec; ಅಗೋಚರತೆ: %0.0f usec."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1377,10 +1444,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [ಆಯ್ಕೆಗಳು]\n"
@@ -1436,7 +1508,7 @@ msgstr ""
 "ಮಾಡು/ಚಲಾಯಿಸು.\n"
 "      --list-file-formats               ಲಭ್ಯವಿರುವ ಕಡತ ವಿನ್ಯಾಸಗಳ ಪಟ್ಟಿ.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1447,91 +1519,91 @@ msgstr ""
 "libpulse %s ನೊಂದಿಗೆ ಕಂಪೈಲ್ ಮಾಡಲಾಗಿದೆ\n"
 "libpulse %s ನೊಂದಿಗೆ ಜೋಡಿಸಲಾಗಿದೆ\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "ಅಮಾನ್ಯವಾದ ಕ್ಲೈಂಟಿನ ಹೆಸರು '%s'"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "ಅಮಾನ್ಯವಾದ ಸ್ಟ್ರೀಮ್‌ನ ಹೆಸರು '%s'"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "ಅಮಾನ್ಯವಾದ ಚಾನಲ್ ನಕ್ಷೆ '%s'"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "ಅಮಾನ್ಯವಾದ ಅಗೋಚರತೆ ವಿವರಣೆ '%s'"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "ಅಮಾನ್ಯವಾದ ಪ್ರಕ್ರಿಯೆ ಸಮಯದ ವಿವರಣೆ '%s'"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "ಅಮಾನ್ಯವಾದ ಗುಣಲಕ್ಷಣ '%s'"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "ಅಮಾನ್ಯವಾದ ಕಡತ ವಿನ್ಯಾಸ %s."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "ಅಮಾನ್ಯವಾದ ನಮೂನೆ ವಿವರ"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "ಬಹಳಷ್ಟು ಆರ್ಗುಮೆಂಟ್‌ಗಳು."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "ನಮೂನೆಯ ಮಾಹಿತಿಯನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "ಧ್ವನಿ ಕಡತವನ್ನು ತೆರೆಯುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
 msgstr ""
 "ಎಚ್ಚರಿಕೆ: ಸೂಚಿಸಲಾದ ನಮೂನೆ ವಿವರಣೆಯನ್ನು ಕಡತದಲ್ಲಿನ ವಿವರಣೆಯಿಂದ ತಿದ್ದಿಬರೆಯಲಾಗುತ್ತದೆ."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "ಕಡತದಿಂದ ನಮೂನೆಯ ವಿವರಣೆಯನ್ನು ನಿರ್ಧರಿಸುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "ಎಚ್ಚರಿಕೆ: ಕಡತದಿಂದ ಚಾನಲ್ ನಕ್ಷೆಯನ್ನು ನಿರ್ಧರಿಸುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "ಚಾನಲ್ ನಕ್ಷೆಯು ನಮೂನೆಯ ವಿವರಣೆಯೊಂದಿಗೆ ತಾಳೆಯಾಗುತ್ತಿಲ್ಲ"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "ಎಚ್ಚರಿಕೆ: ಕಡತಕ್ಕೆ ಚಾನಲ್ ನಕ್ಷೆಯನ್ನು ಬರೆಯುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
@@ -1539,80 +1611,85 @@ msgstr ""
 "ಒಂದು %s ಸ್ಟ್ರೀಮ್‌ ಅನ್ನು ನಮೂನೆ ವಿವರಣೆ '%s' ಯೊಂದಿಗೆ ಹಾಗು ಚಾನಲ್ ನಕ್ಷೆ '%s' ಯೊಂದಿಗೆ "
 "ತೆರೆಯಲಾಗುತ್ತಿದೆ."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "ರೆಕಾರ್ಡಿಂಗ್"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "ಪ್ಲೇಬ್ಯಾಕ್‌"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "ಆಜ್ಞಾ ಸಾಲನ್ನು ಪಾರ್ಸ್ ಮಾಡುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_rttime_new() ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "ಫೋರ್ಕ್(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "ಸ್ಥಗಿತಗೊಳಿಸಲು ವಿಫಲಗೊಂಡಿದೆ: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "ಮರಳಿ ಆರಂಭಿಸಲು ವಿಫಲಗೊಂಡಿದೆ: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "ಎಚ್ಚರಿಕೆ: ಧ್ವನಿ ಪರಿಚಾರಕವು ಸ್ಥಳೀಯವಾಗಿಲ್ಲ, ತಾತ್ಕಾಲಿಕವಾಗಿ ತಡೆಹಿಡಿಯಲಾಗುತ್ತಿಲ್ಲ.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "ಸಂಪರ್ಕದ ವಿಫಲತೆ: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "SIGINT ದೊರೆತಿದೆ, ನಿರ್ಗಮಿಸುತ್ತಿದೆ.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "ಎಚ್ಚರಿಕೆ: ಉಪ ಪ್ರಕ್ರಿಯೆಯು %u ಸಂಕೇತದೊಂದಿಗೆ ಅಂತ್ಯಗೊಂಡಿದೆ\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1656,37 +1733,48 @@ msgstr "pa_context_new() ವಿಫಲಗೊಂಡಿದೆ.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() ವಿಫಲಗೊಂಡಿದೆ.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "ಅಂಕಿಅಂಶಗಳನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "ಪ್ರಸಕ್ತ ಬಳಕೆಯಲ್ಲಿರುವುದು: %u ಖಂಡಗಳು ಒಟ್ಟು %s ಬೈಟ್‌ಗಳನ್ನು ಹೊಂದಿದೆ.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr ""
 "ಸಂಪೂರ್ಣ ಜೀವಿತಾವಧಿಯ ಸಮಯದಲ್ಲಿ ನಿಯೋಜಿಸಲಾಗಿದ್ದು: %u ಖಂಡಗಳು ಒಟ್ಟು %s ಬೈಟ್‌ಗಳನ್ನು "
 "ಹೊಂದಿದೆ.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "ನಮೂನೆಯ ಕ್ಯಾಶೆ ಗಾತ್ರ: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "ಪರಿಚಾರಕದ ಮಾಹಿತಿಯನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1694,7 +1782,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "ಬಳಕೆದಾರ ಹೆಸರು: %s\n"
 "ಅತಿಥೇಯದ ಹೆಸರು: %s\n"
@@ -1706,13 +1794,13 @@ msgstr ""
 "ಪೂರ್ವನಿಯೋಜಿತ ಆಕರ: %s\n"
 "ಕುಕಿ: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "ಸಿಂಕ್‌ ಮಾಹಿತಿಯನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1728,7 +1816,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1750,22 +1838,27 @@ msgstr ""
 "\tಗುಣಗಳು:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tಸಂಪರ್ಕಸ್ಥಾನಗಳು:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tಸಕ್ರಿಯ ಸಂಪರ್ಕಸ್ಥಾನ: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tಸಂಪರ್ಕಸ್ಥಾನಗಳು:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "ಆಕರದ ಮಾಹಿತಿಯನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1804,20 +1897,20 @@ msgstr ""
 "\tಗುಣಗಳು:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "ಅನ್ವಯಿಸುವುದಿಲ್ಲ"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "ಘಟಕದ ಮಾಹಿತಿಯನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1834,12 +1927,12 @@ msgstr ""
 "\tಗುಣಗಳು:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "ಕ್ಲೈಂಟಿನ ಮಾಹಿತಿಯನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1854,12 +1947,12 @@ msgstr ""
 "\tಗುಣಗಳು:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "ಕಾರ್ಡಿನ ಮಾಹಿತಿಯನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1876,23 +1969,23 @@ msgstr ""
 "\tಗುಣಗಳು:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tಪ್ರೊಫೈಲುಗಳು:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tಸಕ್ರಿಯ ಪ್ರೊಫೈಲುಗಳು: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "ಸಿಂಕ್‌ ಇನ್‌ಪುಟ್ ಮಾಹಿತಿಯನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1901,6 +1994,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1928,13 +2022,13 @@ msgstr ""
 "\tಗುಣಗಳು:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "ಆಕರದ ಔಟ್‌ಪುಟ್ ಮಾಹಿತಿಯನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1943,31 +2037,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"à²\86à²\95ರ à²\94à²\9f್‌ಪುಟ್‌ #%u\n"
+"ಸಿà²\82à²\95à³\8d à²\87ನ್‌ಪುಟ್‌ #%u\n"
 "\tಚಾಲಕ: %s\n"
 "\tಮಾಲಿಕ ಘಟಕ: %s\n"
 "\tಕ್ಲೈಂಟ್‌: %s\n"
-"\tà²\86à²\95ರ: %u\n"
+"\tಸಿà²\82à²\95à³\8d: %u\n"
 "\tನಮೂನೆ ವಿವರಣೆ: %s\n"
 "\tಚಾನಲ್‌ ನಕ್ಷೆ: %s\n"
+"\tಮೂಕ: %s\n"
+"\tಧ್ವನಿ ಪ್ರಮಾಣ: %s\n"
+"\t        %s\n"
+"\t        ಸಮತೋಲನ %0.2f\n"
 "\tಬಫರಿನ ಅಗೋಚರತೆ: %0.0f usec\n"
-"\tà²\86à²\95ರದ ಅಗೋಚರತೆ: %0.0f usec\n"
+"\tಸಿà²\82à²\95à³\8dâ\80\8cನ ಅಗೋಚರತೆ: %0.0f usec\n"
 "\tಮರುನಮೂನೆ ವಿಧಾನ: %s\n"
 "\tಗುಣಗಳು:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "ನಮೂನೆಯ ಮಾಹಿತಿಯನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1998,48 +2101,163 @@ msgstr ""
 "\tಗುಣಗಳು:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "ವಿಫಲತೆ: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "ಆಕರದ ಮಾಹಿತಿಯನ್ನು ಪಡೆದುಕೊಳ್ಳುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "ನಮೂನೆಯನ್ನು ಅಪ್‌ಲೋಡ್ ಮಾಡುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "ಕಡತದ ಅಪ್ರಾಪ್ತ ಸಮಯದಲ್ಲಿ ಅಂತ್ಯ"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "ಅಮಾನ್ಯವಾದ ಪರಿಚಾರಕ"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "SIGINT ದೊರೆತಿದೆ, ನಿರ್ಗಮಿಸುತ್ತಿದೆ."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "ಅಮಾನ್ಯವಾದ ಧ್ವನಿ ಪ್ರಮಾಣದ ವಿವರ"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2049,36 +2267,14 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [ಆಯ್ಕೆಗಳು] stat\n"
-"%s [ಆಯ್ಕೆಗಳು] list\n"
-"%s [ಆಯ್ಕೆಗಳು] exit\n"
-"%s [ಆಯ್ಕೆಗಳು] upload-sample FILENAME [NAME]\n"
-"%s [ಆಯ್ಕೆಗಳು] play-sample NAME [SINK]\n"
-"%s [ಆಯ್ಕೆಗಳು] remove-sample NAME\n"
-"%s [ಆಯ್ಕೆಗಳು] move-sink-input SINKINPUT SINK\n"
-"%s [ಆಯ್ಕೆಗಳು] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [ಆಯ್ಕೆಗಳು] load-module NAME [ARGS ...]\n"
-"%s [ಆಯ್ಕೆಗಳು] unload-module MODULE\n"
-"%s [ಆಯ್ಕೆಗಳು] suspend-sink SINK 1|0\n"
-"%s [ಆಯ್ಕೆಗಳು] suspend-source SOURCE 1|0\n"
-"%s [ಆಯ್ಕೆಗಳು] set-card-profile CARD PROFILE\n"
-"%s [ಆಯ್ಕೆಗಳು] set-sink-port SINK PORT\n"
-"%s [ಆಯ್ಕೆಗಳು] set-source-port SOURCE PORT\n"
-"%s [ಆಯ್ಕೆಗಳು] set-sink-volume SINK VOLUME\n"
-"%s [ಆಯ್ಕೆಗಳು] set-source-volume SOURCE VOLUME\n"
-"%s [ಆಯ್ಕೆಗಳು] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [ಆಯ್ಕೆಗಳು] set-sink-mute SINK 1|0\n"
-"%s [ಆಯ್ಕೆಗಳು] set-source-mute SOURCE 1|0\n"
-"%s [ಆಯ್ಕೆಗಳು] set-sink-input-mute SINKINPUT 1|0\n"
+"%s [ಆಯ್ಕೆಗಳು] ... \n"
 "\n"
 "  -h, --help                            ಈ ನೆರವನ್ನು ತೋರಿಸು\n"
 "      --version                         ಆವೃತ್ತಿಯನ್ನು ತೋರಿಸು\n"
-"\n"
 "  -s, --server=SERVER                   ಸಂಪರ್ಕಸಾಧಿಸಬೇಕಿರುವ ಪರಿಚಾರಕದ ಹೆಸರು\n"
-"  -n, --client-name=NAME                ಪರಿಚಾರಕದಲ್ಲಿ ಈ ಕ್ಲೈಂಟಿನಲ್ಲಿ ಏನೆಂದು "
-"ಕರೆಯಬೇಕು\n"
+"\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2089,50 +2285,55 @@ msgstr ""
 "libpulse %s ನೊಂದಿಗೆ ಕಂಪೈಲ್ ಮಾಡಲಾಗಿದೆ\n"
 "libpulse %s ನೊಂದಿಗೆ ಜೋಡಿಸಲಾಗಿದೆ\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "ಲೋಡ್ ಮಾಡಬೇಕಿರುವ ಒಂದು ಕಡತದ ನಮೂನೆಯನ್ನು ಸೂಚಿಸಿ"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "ಧ್ವನಿ ಕಡತವನ್ನು ತೆರೆಯುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "ಎಚ್ಚರಿಕೆ: ಕಡತದಿಂದ ನಮೂನೆಯ ವಿವರವನ್ನು ನಿರ್ಧರಿಸುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "ಚಲಾಯಿಸಲು ನೀವು ಒಂದು ನಮೂನೆಯ ಹೆಸರನ್ನು ಸೂಚಿಸಬೇಕಾಗುತ್ತದೆ"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "ತೆಗೆದು ಹಾಕಲು ನೀವು ಒಂದು ನಮೂನೆಯ ಹೆಸರನ್ನು ಸೂಚಿಸಬೇಕು"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "ನೀವು ಒಂದು ಸಿಂಕ್ ಇನ್‌ಪುಟ್ ಸೂಚಿಯನ್ನು ಹಾಗು ಒಂದು ಸಿಂಕ್‌ ಅನ್ನು ಸೂಚಿಸಬೇಕು."
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "ನೀವು ಒಂದು ಆಕರ ಔಟ್‌ಪುಟ್ ಸೂಚಿಯನ್ನು ಹಾಗು ಒಂದು ಆಕರವನ್ನು ಸೂಚಿಸಬೇಕು."
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "ನೀವು ಒಂದು ಘಟಕದ ಹೆಸರನ್ನು ಹಾಗು ಆರ್ಗುಮೆಂಟುಗಳನ್ನು ಸೂಚಿಸಬೇಕು."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "ನೀವು ಒಂದು ಘಟಕ ಸೂಚಿಯನ್ನು ಸೂಚಿಸಬೇಕು"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "ನೀವು ಒಂದಕ್ಕಿಂತ ಹೆಚ್ಚಿನ ಸಿಂಕನ್ನು ಸೂಚಿಸಲಾಗುವುದಿಲ್ಲ. ನೀವು ಒಂದು ಬೂಲಿಯನ್‌ ಮೌಲ್ಯವನ್ನು "
 "ಸೂಚಿಸಬೇಕಾಗುತ್ತದೆ."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
@@ -2140,57 +2341,84 @@ msgstr ""
 "ನೀವು ಒಂದಕ್ಕಿಂತ ಹೆಚ್ಚಿನ ಆಕರವನ್ನು ಸೂಚಿಸಲಾಗುವುದಿಲ್ಲ. ನೀವು ಒಂದು ಬೂಲಿಯನ್‌ ಮೌಲ್ಯವನ್ನು "
 "ಸೂಚಿಸಬೇಕಾಗುತ್ತದೆ."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "ಒಂದು ಕಾರ್ಡಿನ ಹೆಸರು/ಸೂಚಿಯನ್ನು ಹಾಗು ಪ್ರೊಫೈಲ್‌ ಹೆಸರನ್ನು ಸೂಚಿಸಬೇಕು"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "ನೀವು ಒಂದು ಸಿಂಕಿನ ಹೆಸರು/ಸೂಚಿಯನ್ನು ಹಾಗು ಸಂಪರ್ಕಸ್ಥಾನದ ಹೆಸರನ್ನು ಸೂಚಿಸಬೇಕು"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "ನೀವು ಒಂದು ಆಕರದ ಹೆಸರು/ಸೂಚಿಯನ್ನು ಹಾಗು ಸಂಪರ್ಕಸ್ಥಾನದ ಹೆಸರನ್ನು ಸೂಚಿಸಬೇಕು"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "ನೀವು ಒಂದು ಸಿಂಕಿನ ಹೆಸರು/ಸೂಚಿಯನ್ನು ಹಾಗು ಸಂಪರ್ಕಸ್ಥಾನದ ಹೆಸರನ್ನು ಸೂಚಿಸಬೇಕು"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "ಅಮಾನ್ಯವಾದ ಧ್ವನಿ ಪ್ರಮಾಣದ ವಿವರ"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "ನೀವು ಒಂದು ಆಕರದ ಹೆಸರು/ಸೂಚಿಯನ್ನು ಹಾಗು ಸಂಪರ್ಕಸ್ಥಾನದ ಹೆಸರನ್ನು ಸೂಚಿಸಬೇಕು"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "ನೀವು ಒಂದು ಸಿಂಕ್ ಇನ್‌ಪುಟ್ ಸೂಚಿಯನ್ನು ಹಾಗು ಒಂದು ಸಿಂಕ್‌ ಅನ್ನು ಸೂಚಿಸಬೇಕು"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "ಅಮಾನ್ಯವಾದ ಸಿಂಕ್ ಇನ್‌ಪುಟ್ ಸೂಚಿ"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "ನೀವು ಒಂದು ಆಕರ ಔಟ್‌ಪುಟ್ ಸೂಚಿಯನ್ನು ಹಾಗು ಒಂದು ಆಕರವನ್ನು ಸೂಚಿಸಬೇಕು."
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "ಅಮಾನ್ಯವಾದ ಸಿಂಕ್ ಇನ್‌ಪುಟ್ ಸೂಚಿ"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "ನೀವು ಒಂದು ಸಿಂಕಿನ ಹೆಸರು/ಸೂಚಿಯನ್ನು ಹಾಗು ಸಂಪರ್ಕಸ್ಥಾನದ ಹೆಸರನ್ನು ಸೂಚಿಸಬೇಕು"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "ಅಮಾನ್ಯವಾದ ನಮೂನೆ ವಿವರ"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "ನೀವು ಒಂದು ಆಕರದ ಹೆಸರು/ಸೂಚಿಯನ್ನು ಹಾಗು ಸಂಪರ್ಕಸ್ಥಾನದ ಹೆಸರನ್ನು ಸೂಚಿಸಬೇಕು"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "ನೀವು ಒಂದು ಸಿಂಕ್ ಇನ್‌ಪುಟ್ ಸೂಚಿಯನ್ನು ಹಾಗು ಒಂದು ಸಿಂಕ್‌ ಅನ್ನು ಸೂಚಿಸಬೇಕು"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "ಅಮಾನ್ಯವಾದ ಸಿಂಕ್ ಇನ್‌ಪುಟ್ ಸೂಚಿ ವಿವರ"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "ನೀವು ಒಂದು ಆಕರದ ಹೆಸರು/ಸೂಚಿಯನ್ನು ಹಾಗು ಸಂಪರ್ಕಸ್ಥಾನದ ಹೆಸರನ್ನು ಸೂಚಿಸಬೇಕು"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "ಅಮಾನ್ಯವಾದ ಸಿಂಕ್ ಇನ್‌ಪುಟ್ ಸೂಚಿ ವಿವರ"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "ನೀವು ಒಂದು ಸಿಂಕಿನ ಹೆಸರು/ಸೂಚಿಯನ್ನು ಹಾಗು ಸಂಪರ್ಕಸ್ಥಾನದ ಹೆಸರನ್ನು ಸೂಚಿಸಬೇಕು"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "ಮಾನ್ಯವಾದ ಯಾವುದೆ ಆಜ್ಞೆಯನ್ನು ಸೂಚಿಸಲಾಗಿಲ್ಲ."
 
@@ -2219,104 +2447,104 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "ಆಜ್ಞಾ ಸಾಲನ್ನು ಪಾರ್ಸ್ ಮಾಡುವಲ್ಲಿ ವಿಫಲತೆ.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "ಪರಿಚಾರಕ: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "ಆಕರ: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "ಸಿಂಕ್: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "ಕುಕಿ: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "ಕುಕಿ ದತ್ತಾಂಶವನ್ನು ಪಾರ್ಸ್ ಮಾಡುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "ಕುಕಿ ದತ್ತಾಂಶವನ್ನು ಉಳಿಸುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "ಕ್ಲೈಂಟ್ ಸಂರಚನಾ ಕಡತವನ್ನು ಲೋಡ್ ಮಾಡುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "ಪರಿಸರ ಸಂರಚನಾ ದತ್ತಾಂಶವನ್ನು ಓದುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "FQDN ಅನ್ನು ಪಡೆಯಲು ವಿಫಲಗೊಂಡಿದೆ.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "ಕುಕಿ ದತ್ತಾಂಶವನ್ನು ಲೋಡ್ ಮಾಡುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "ಇನ್ನೂ ಸಹ ಅನ್ವಯಿಸಲಾಗಿಲ್ಲ.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr ""
 "ಯಾವುದೆ PulseAudio ಡೆಮನ್ ಚಾಲಿತಗೊಳ್ಳುತ್ತಿಲ್ಲ, ಅಥವ ಅಧಿವೇಶನ ಡೆಮನ್ ಆಗಿ ಚಾಲಿತಗೊಳ್ಳುತ್ತಿಲ್ಲ."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "ಸಾಕೆಟ್(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "ಸಂಪರ್ಕಿಸು(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "PulseAudio ಡೀಮನ್ ಅನ್ನು ಕೊಲ್ಲುವಲ್ಲಿ ವಿಫಲಗೊಂಡಿದೆ."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "ಡೀಮನ್ ಪ್ರತಿಕ್ರಿಯಿಸುತ್ತಿಲ್ಲ."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "ಪೋಲ್(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "ಓದು(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "ಬರೆ(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "ಸ್ವಯಂಹೆಚ್ಚಿಸುವಿಕೆಯ ಲಾಕ್ ಅನ್ನು ನಿಲುಕಿಸಿಕೊಳ್ಳಲು ಸಾಧ್ಯವಿಲ್ಲ."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2331,7 +2559,7 @@ msgstr ""
 "ವಿಕಸನಗಾರರ ಗಮನಕ್ಕೆ ತನ್ನಿ.POLLOUT ಸೆಟ್‌ನಿಂದ ನಾವು ಎಚ್ಚೆತ್ತುಗೊಂಡಿದ್ದೇವೆ -- ಆದರೆ ನಂತರದ "
 "snd_pcm_avail() 0 ಅಥವ min_avail ಕ್ಕಿಂತ ಚಿಕ್ಕದಾದ ಇನ್ನೊಂದು ಮೌಲ್ಯವನ್ನು ಮರಳಿಸಿದೆ."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2346,242 +2574,464 @@ msgstr ""
 "ವಿಕಸನಗಾರರ ಗಮನಕ್ಕೆ ತನ್ನಿ.POLLIN ಸೆಟ್‌ನಿಂದ ನಾವು ಎಚ್ಚೆತ್ತುಗೊಂಡಿದ್ದೇವೆ -- ಆದರೆ ನಂತರದ "
 "snd_pcm_avail() 0 ಅಥವ min_avail ಕ್ಕಿಂತ ಚಿಕ್ಕದಾದ ಇನ್ನೊಂದು ಮೌಲ್ಯವನ್ನು ಮರಳಿಸಿದೆ."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "ಜಡ"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "ಹೈ ಫಿಡಿಲಿಟಿ ಪ್ಲೇಬ್ಯಾಕ್ (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "ಹೈ ಫಿಡಿಲಿಟಿ ಕ್ಯಾಪ್ಚರ್ (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "ಟೆಲಿಫೋನಿ ಡ್ಯೂಪ್ಲೆಕ್ಸ್‌ (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "PulseAudio ಧ್ವನಿ ಪರಿಚಾರಕ"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
-msgstr ""
+msgstr "ಔಟ್‌ಪುಟ್ ಸಾಧನಗಳು"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
-msgstr ""
+msgstr "ಇನ್‌ಪುಟ್‌ ಸಾಧನಗಳು"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
-msgstr ""
+msgstr "@HOSTNAME@ ನಲ್ಲಿನ ಆಡಿಯೊ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
-msgstr ""
+msgstr "ಇನ್‌ಪುಟ್"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
-msgstr ""
+msgstr "ಡಾಕಿಂಗ್ ಸ್ಟೇಶನ್ ಇನ್‌ಪುಟ್"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
-msgstr ""
+msgstr "ಡಾಕಿಂಗ್ ಸ್ಟೇಶನ್ ಮೈಕ್ರೊಫೋನ್"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "ಡಾಕಿಂಗ್ ಸ್ಟೇಶನ್ ಇನ್‌ಪುಟ್"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "ಲೈನ್-ಇನ್"
+
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
-msgstr ""
+msgstr "ಮೈಕ್ರೊಫೋನ್"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
-msgid "External Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "ಡಾಕಿಂಗ್ ಸ್ಟೇಶನ್ ಮೈಕ್ರೊಫೋನ್"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
 #, fuzzy
+msgid "Rear Microphone"
+msgstr "ಮೈಕ್ರೊಫೋನ್"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "ಬಾಹ್ಯ ಮೈಕ್ರೊಫೋನ್"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
-msgstr "ಆಂತರಿಕ ಆಡಿಯೊ"
+msgstr "ಆಂತರಿಕ  ಮೈಕ್ರೊಫೋನ್"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
-msgstr ""
+msgstr "ರೇಡಿಯೊ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
-msgstr ""
+msgstr "ವೀಡಿಯೊ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
-msgstr ""
+msgstr "ಆಟೊಮ್ಯಾಟಿಕ್ ಗೇನ್ ಕಂಟ್ರೋಲ್"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
-msgstr ""
+msgstr "ಯಾವುದೆ ಆಟೊಮ್ಯಾಟಿಕ್ ಗೇನ್ ಕಂಟ್ರೋಲ್ ಇಲ್ಲ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
-msgstr ""
+msgstr "ಬೂಸ್ಟ್"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
-msgstr ""
+msgstr "ಯಾವುದೆ ಬೂಸ್ಟ್ ಇಲ್ಲ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
-msgstr ""
+msgstr "ಆಂಪ್ಲಿಫಯರ್"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
-msgstr ""
+msgstr "ಯಾವುದೆ ಆಂಪ್ಲಿಫಯರ್ ಇಲ್ಲ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "ಬೂಸ್ಟ್"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "ಯಾವುದೆ ಬೂಸ್ಟ್ ಇಲ್ಲ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "ಅನಲಾಗ್ ಹೆಡ್‌ಫೋನ್‌ಗಳು"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "ಅನಲಾಗ್ ಇನ್‌ಪುಟ್"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "ಡಾಕಿಂಗ್ ಸ್ಟೇಶನ್ ಮೈಕ್ರೊಫೋನ್"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
-msgstr "ಶà³\82ನà³\8dಯ ಔಟ್‌ಪುಟ್"
+msgstr "à²\85ನಲಾà²\97à³\8d ಔಟ್‌ಪುಟ್"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "ಅನಲಾಗ್ ಔಟ್‌ಪುಟ್ (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "ಲೈನ್-ಇನ್"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
+msgstr "ಅನಲಾಗ್ ಮೊನೊ ಔಟ್‌ಪುಟ್"
+
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "ಅನಲಾಗ್ ಸ್ಟೀರಿಯೋ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, fuzzy, c-format
-msgid "%s+%s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "ಡಿಜಿಟಲ್ ಸ್ಟೀರಿಯೊ (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, fuzzy, c-format
-msgid "%s / %s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "ಡಿಜಿಟಲ್ ಸ್ಟೀರಿಯೊ (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
-msgstr ""
+msgstr "ಅನಲಾಗ್ ಮೊನೊ"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
-msgstr "ಸ್ಟೀರಿಯೋ"
+msgstr "à²\85ನಲಾà²\97à³\8d à²¸à³\8dà²\9fà³\80ರಿಯà³\8b"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
-msgstr "ಸರà³\8cà²\82ಡà³\8dâ\80\8c 4.1"
+msgstr "à²\85ನಲಾà²\97à³\8d à²¸à²°à³\8cà²\82ಡà³\8dâ\80\8c 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
-msgstr "ಸರà³\8cà²\82ಡà³\8dâ\80\8c 4.0"
+msgstr "à²\85ನಲಾà²\97à³\8d à²¸à²°à³\8cà²\82ಡà³\8dâ\80\8c 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
-msgstr "ಸರà³\8cà²\82ಡà³\8dâ\80\8c 4.1"
+msgstr "à²\85ನಲಾà²\97à³\8d à²¸à²°à³\8cà²\82ಡà³\8dâ\80\8c 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
-msgstr "ಸರೌಂಡ್‌ 4.0"
+msgstr "à²\85ನಲಾà²\97à³\8d à²¸à²°à³\8cà²\82ಡà³\8dâ\80\8c 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
-msgstr "ಸರೌಂಡ್‌ 4.1"
+msgstr "à²\85ನಲಾà²\97à³\8d à²¸à²°à³\8cà²\82ಡà³\8dâ\80\8c 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
-msgstr "ಸರೌಂಡ್‌ 5.0"
+msgstr "à²\85ನಲಾà²\97à³\8d à²¸à²°à³\8cà²\82ಡà³\8dâ\80\8c 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
-msgstr "ಸರೌಂಡ್‌ 5.1"
+msgstr "à²\85ನಲಾà²\97à³\8d à²¸à²°à³\8cà²\82ಡà³\8dâ\80\8c 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
-msgstr "ಸರà³\8cà²\82ಡà³\8dâ\80\8c 4.0"
+msgstr "à²\85ನಲಾà²\97à³\8d à²¸à²°à³\8cà²\82ಡà³\8dâ\80\8c 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
-msgstr "ಸರà³\8cà²\82ಡà³\8dâ\80\8c 4.1"
+msgstr "à²\85ನಲಾà²\97à³\8d à²¸à²°à³\8cà²\82ಡà³\8dâ\80\8c 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
-msgstr "ಸರà³\8cà²\82ಡà³\8dâ\80\8c 4.0"
+msgstr "à²\85ನಲಾà²\97à³\8d à²¸à²°à³\8cà²\82ಡà³\8dâ\80\8c 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
-msgstr "ಸರೌಂಡ್‌ 7.1"
+msgstr "à²\85ನಲಾà²\97à³\8d à²¸à²°à³\8cà²\82ಡà³\8dâ\80\8c 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
-msgstr ""
+msgstr "ಡಿಜಿಟಲ್ ಸ್ಟೀರಿಯೊ (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "ಡಿಜಿಟಲ್ ಸ್ಟೀರಿಯೊ (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
-msgstr ""
+msgstr "ಡಿಜಿಟಲ್ ಸರೌಂಡ್ 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
-msgstr ""
+msgstr "ಡಿಜಿಟಲ್ ಸರೌಂಡ್ 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
-msgstr ""
+msgstr "ಡಿಜಿಟಲ್ ಸ್ಟೀರಿಯೊ (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "ಡಿಜಿಟಲ್ ಸರೌಂಡ್ 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
-msgstr ""
+msgstr "ಅನಲಾಗ್ ಮೊನೊ ಡ್ಯೂಪ್ಲೆಕ್ಸ್"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
-msgstr ""
+msgstr "ಅನಲಾಗ್ ಸ್ಟೀರಿಯೊ ಡ್ಯೂಪ್ಲೆಕ್ಸ್"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
+msgstr "ಅನಲಾಗ್ ಸ್ಟೀರಿಯೊ ಡ್ಯೂಪ್ಲೆಕ್ಸ್ (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "ಶೂನ್ಯ ಔಟ್‌ಪುಟ್"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "ಇನ್‌ಪುಟ್"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
 msgstr ""
+"sink_name=<ಸಿಂಕ್‌ನ ಹೆಸರು> sink_properties=<ಸಿಂಕ್‌ನ ಗುಣಗಳು> master=<ಫಿಲ್ಟರ್ "
+"ಮಾಡಬೇಕಿರುವ ಸಿಂಕ್‌ನ ಹೆಸರು> format=<ನಮೂನೆ ವಿನ್ಯಾಸ> rate=<ನಮೂನೆ ದರ> "
+"channels=<ಚಾನಲ್‌ಗಳ ಸಂಖ್ಯೆ> channel_map=<ಚಾನಲ್ ನಕ್ಷೆ> plugin=<ladspa ಪ್ಲಗ್‌ಇನ್ ಹೆಸರು> "
+"label=<ladspa ಪ್ಲಗ್‌ಇನ್ ಹೆಸರು> control=<ವಿರಾಮ ಚಿಹ್ನೆಗಳನ್ನು ಹೊಂದಿರುವ ಇನ್‌ಪುಟ್ ನಿಯಂತ್ರಣ "
+"ಮೌಲ್ಯಗಳ ಪಟ್ಟಿ>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit ಗೆ ಈ ಪ್ಲಾಟ್‌ಫಾರ್ಮಿನಲ್ಲಿ ಬೆಂಬಲವಿಲ್ಲ."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() ವಿಫಲಗೊಂಡಿದೆ"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "ಆಕರ ಔಟ್‌ಪುಟ್‌ #%u\n"
+#~ "\tಚಾಲಕ: %s\n"
+#~ "\tಮಾಲಿಕ ಘಟಕ: %s\n"
+#~ "\tಕ್ಲೈಂಟ್‌: %s\n"
+#~ "\tಆಕರ: %u\n"
+#~ "\tನಮೂನೆ ವಿವರಣೆ: %s\n"
+#~ "\tಚಾನಲ್‌ ನಕ್ಷೆ: %s\n"
+#~ "\tಬಫರಿನ ಅಗೋಚರತೆ: %0.0f usec\n"
+#~ "\tಆಕರದ ಅಗೋಚರತೆ: %0.0f usec\n"
+#~ "\tಮರುನಮೂನೆ ವಿಧಾನ: %s\n"
+#~ "\tಗುಣಗಳು:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [ಆಯ್ಕೆಗಳು] stat\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] list\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] exit\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] upload-sample FILENAME [NAME]\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] play-sample NAME [SINK]\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] remove-sample NAME\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] move-sink-input SINKINPUT SINK\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] load-module NAME [ARGS ...]\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] unload-module MODULE\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] suspend-sink SINK 1|0\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] suspend-source SOURCE 1|0\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] set-card-profile CARD PROFILE\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] set-sink-port SINK PORT\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] set-source-port SOURCE PORT\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] set-sink-volume SINK VOLUME\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] set-source-volume SOURCE VOLUME\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] set-sink-mute SINK 1|0\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] set-source-mute SOURCE 1|0\n"
+#~ "%s [ಆಯ್ಕೆಗಳು] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            ಈ ನೆರವನ್ನು ತೋರಿಸು\n"
+#~ "      --version                         ಆವೃತ್ತಿಯನ್ನು ತೋರಿಸು\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   ಸಂಪರ್ಕಸಾಧಿಸಬೇಕಿರುವ ಪರಿಚಾರಕದ ಹೆಸರು\n"
+#~ "  -n, --client-name=NAME                ಪರಿಚಾರಕದಲ್ಲಿ ಈ ಕ್ಲೈಂಟಿನಲ್ಲಿ ಏನೆಂದು "
+#~ "ಕರೆಯಬೇಕು\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "ಡಿಜಿಟಲ್ ಸರೌಂಡ್ 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "ಕೆಳಮಟ್ಟದ ಫ್ರೀಕ್ವೆನ್ಸಿ ಉತ್ಪಾದಕ"
index 4a5cbf9..91ff254 100644 (file)
--- a/po/ml.po
+++ b/po/ml.po
@@ -1,28 +1,21 @@
-# translation of pulseaudio.master-tx.ml.po to
-# translation of pulseaudio.master-tx.pulseaudio.ml.po to
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#  <>, YEAR,ÀÀ²\ 1, 2012.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx.ml\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-09-21 20:54+0530\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:41+0000\n"
 "Last-Translator: \n"
 "Language-Team:  <en@li.org>\n"
+"Language: \n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: KBabel 1.11.4\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -33,18 +26,29 @@ msgstr ""
 "snd_pcm_avail() നല്‍കിയ മൂല്ല്യം വളരെ വലുതാണു്: %lu ബൈറ്റുകള്‍ (%lu ms).\n"
 "ഇതു് ALSA ഡ്രൈവര്‍ '%s'-ലുള്ള ഒരു ബഗാവാം. ദയവായി ഈ പ്രശ്നം ALSA ഡവലപ്പര്‍സിനെ അറിയിക്കുക."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
 "snd_pcm_delay() നല്‍കിയ മൂല്ല്യം വളരെ വലുതാണു്: %li ബൈറ്റുകള്‍ (%s%lu ms).\n"
 "ഇതു് ALSA ഡ്രൈവര്‍ '%s'-ലുള്ള ഒരു ബഗാവാം. ദയവായി ഈ പ്രശ്നം ALSA ഡവലപ്പര്‍സിനെ അറിയിക്കുക."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() നല്‍കിയ മൂല്ല്യം വളരെ വലുതാണു്: %lu ബൈറ്റുകള്‍ (%lu ms).\n"
+"ഇതു് ALSA ഡ്രൈവര്‍ '%s'-ലുള്ള ഒരു ബഗാവാം. ദയവായി ഈ പ്രശ്നം ALSA ഡവലപ്പര്‍സിനെ അറിയിക്കുക."
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -55,146 +59,155 @@ msgstr ""
 "snd_pcm_mmap_begin() നല്‍കിയ മൂല്ല്യം വളരെ വലുതാണു്: %lu ബൈറ്റുകള്‍(%lu ms).\n"
 "ഇതു് ALSA ഡ്രൈവര്‍ '%s'-ലുള്ള ഒരു ബഗാവാം. ദയവായി ഈ പ്രശ്നം ALSA ഡവലപ്പര്‍സിനെ അറിയിക്കുക."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "നള്‍ ആണെങ്കിലും ഒരു സിങ്കെങ്കിലും എപ്പോഴും ലഭ്യമാക്കുക"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "ഡമ്മി ഔട്ട്പുട്ട്"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "വിര്‍ച്ച്വല്‍ LADSPA സിങ്ക്"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<name for the sink> sink_properties=<properties for the sink> "
 "master=<name of sink to filter> format=<sample format> rate=<sample rate> "
 "channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
+"plugin name> label=<ladspa plugin label> control=<comma separated list of "
 "input control values>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "ക്ലോക്കഡ് NULL സിങ്ക്"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "നള്‍ ഔട്ട്പുട്ട്"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "ഇന്റേര്‍ണല്‍ ഓഡിയോ"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "മോഡം"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "യഥാര്‍ത്ഥ lt_dlopen ലോഡര്‍ ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "പുതിയ dl ലോഡര്‍ അനുവദിക്കുന്നതില്‍ പരാജയപ്പെട്ടു."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "bind-now-loader ചേര്‍ക്കുന്നതില്‍ പരാജയപ്പെട്ടു."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "%s സിഗ്നല്‍ ലഭ്യമായി."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "പുറത്തു് കടക്കുന്നു."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "'%s' എന്ന ഉപയോക്താവു് ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "'%s' എന്ന ഗ്രൂപ്പ് ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "ഉപയോക്താവു് '%s' (UID %lu) , ഗ്രൂപ്പ് '%s' (GID %lu) ലഭ്യമായി."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "ഉപയോക്താവു് '%s'-ന്റെയും ഗ്രൂപ്പ് '%s'-ന്റെയും GID ചേരുന്നില്ല."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "ഉപയോക്താവു് '%s'-ന്റെ ഹോം ഡയറക്ടറി '%s' അല്ല, ഉപേക്ഷിക്കുന്നു."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "'%s' ഉണ്ടാക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "ഗ്രൂപ്പ് ലിസ്റ്റ് മാറ്റുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "GID മാറ്റുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "UID മാറ്റുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "റൂട്ട് ആനുകൂല്യങ്ങള്‍ വിജയകരമായി ഉപേക്ഷിച്ചിരിക്കുന്നു."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "ഈ പ്ലാറ്റ്ഫോമില്‍ സിസ്റ്റം വൈഡ് മോഡ് പിന്തുണയ്ക്കുന്നില്ല."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) പരാജയപ്പെട്ടു: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "കമാന്‍ഡ് ലൈന്‍ പാഴ്സ് ചെയ്യുന്നതില്‍ പരാജയപ്പെട്ടു."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "ഡെമണ്‍ പ്രവര്‍ത്തനത്തിലില്ല"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "ഡെമണ്‍ PID %u ആയി പ്രവര്‍ത്തിക്കുന്നു"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "ഡെമണ്‍ നശിപ്പിക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -202,157 +215,178 @@ msgstr ""
 "ഈ പ്രോഗ്രാം റൂട്ടായി പ്രവര്‍ത്തിപ്പിക്കേണ്ടതല്ല (--system എന്നു് പറഞ്ഞിട്ടുണ്ടെങ്കില്‍ മാത്രം റൂട്ട് "
 "ആവശ്യമുണ്ടു്)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "റൂട്ട് ആനുകൂല്യങ്ങള്‍ ആവശ്യമുണ്ടു്."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "സിസ്റ്റം ഇന്‍സ്റ്റന്‍സുകള്‍ക്ക് --start പിന്തുണയ്ക്കുന്നില്ല."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "സിസ്റ്റം മോഡില്‍ പ്രവര്‍ത്തിക്കുന്നു, പക്ഷേ --disallow-exit സജ്ജമാക്കിയിട്ടില്ല!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
 "സിസ്റ്റം മോഡില്‍ പ്രവര്‍ത്തിക്കുന്നു, പക്ഷേ --disallow-module-loading സജ്ജമാക്കിയിട്ടില്ല!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "സിസ്റ്റം മോഡില്‍ പ്രവര്‍ത്തിക്കുന്നു, നിര്‍ബന്ധമായും SHM മോഡ് പ്രവര്‍ത്ത രഹിതമാക്കുന്നു!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 "സിസ്റ്റം മോഡില്‍ പ്രവര്‍ത്തിക്കുന്നു, നിര്‍ബന്ധമായും എക്സിറ്റ് ഐഡില്‍ സമയം പ്രവര്‍ത്ത രഹിതമാക്കുന്നു!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "stdio ലഭിക്കുന്നതില്‍ പരാജയപ്പെട്ടു."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "pipe പരാജയപ്പെട്ടു: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() പരാജയപ്പെട്ടു: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() പരാജയപ്പെട്ടു: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "ഡെമണിന്റെ തുടക്കം പരാജയപ്പെട്ടു."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "ഡെമണിന്റെ തുടക്കം വിജയിച്ചു."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() പരാജയപ്പെട്ടു: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "ഇതു് PulseAudio %s ആണു്"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "കംപൈലേഷന്‍ ഹോസ്റ്റ്: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "കംപൈലേഷന്‍ CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "ഹോസ്റ്റില്‍ പ്രവര്‍ത്തിക്കുന്നു: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "%u സിപിയു ലഭ്യമായി."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "താളിന്റെ വ്യാപ്തി %lu ബൈറ്റുകളാണു്"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Valgrind പിന്തുണയോടെ കംപൈല്‍ ചെയ്തിരിക്കുന്നു: ഉവ്വു്"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Valgrind പിന്തുണയോടെ കംപൈല്‍ ചെയ്തിരിക്കുന്നു: ഇല്ല"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "valgrind മോഡില്‍ പ്രവര്‍ത്തിപ്പിക്കുന്നു: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "ഹോസ്റ്റില്‍ പ്രവര്‍ത്തിക്കുന്നു: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "ഒപ്ടിമൈസ്ഡ് ബിള്‍ഡ്: ഉവ്വു്"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "ഒപ്ടിമൈസ്ഡ് ബിള്‍ഡ്: ഇല്ല"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG നിഷ്കര്‍ഷിച്ചിരിക്കുന്നു, എല്ലാ asserts-ഉം പ്രവര്‍‌ത്ത രഹിതം."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH നിഷ്കര്‍ഷിച്ചിരിക്കുന്നു, fast path asserts മാത്രം പ്രവര്‍‌ത്ത രഹിതം."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "എല്ലാ asserts-ഉം പ്രവര്‍‌ത്ത സജ്ജം"
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "മഷീന്‍ ID ലഭ്യമാക്കുവാന്‍ സാധ്യമായില്ല"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "മഷീന്‍ ID %s ആണു്."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "സെഷന്‍ ID %s ആണു്."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "റണ്‍ടൈം ഡയറക്ടറി %s ഉപയോഗിക്കുന്നു."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "സ്റ്റേറ്റ് ഡയറക്ടറി %s ഉപയോഗിക്കുന്നു."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "മൊഡ്യൂള്‍സ് ഡയറക്ടറി %s ഉപയോഗിക്കുന്നു."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "സിസ്റ്റം മോഡില്‍ പ്രവര്‍ത്തിക്കുന്നു: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -366,15 +400,15 @@ msgstr ""
 "സിസ്റ്റം മോഡിലുള്ള പ്രവര്‍ത്തനം ഉത്തമമല്ലാത്തതിന്റെ കാരണങ്ങള്‍ക്കായിhttp://pulseaudio.org/"
 "wiki/WhatIsWrongWithSystemMode കാണുക."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() പരാജയപ്പെട്ടു."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "Fresh high-resolution timers available! Bon appetit!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -382,32 +416,32 @@ msgstr ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() പരാജയപ്പെട്ടു."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "ഡെമണ്‍ ആരംഭിക്കുന്നതില്‍ പരാജയപ്പെട്ടു."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "ഒരു ഘടകങ്ങളും ലഭ്യമാകാതെ ഡെമണ്‍ ആരംഭിച്ചിരിക്കുന്നു, പ്രവര്‍ത്തനം നിഷേധിച്ചിരിക്കുന്നു."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "ഡെമണിന്റെ തുടക്കം പൂര്‍ണ്ണമായി."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "ഡെമണ്‍ അടച്ചുപൂട്ടുന്നതു് ആരംഭിച്ചിരിക്കുന്നു."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "ഡെമണ്‍ നിര്‍ത്തിയിരിക്കുന്നു."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -444,15 +478,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -549,15 +581,15 @@ msgstr ""
 "\n"
 "  -n                                    Don't load default script file\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize-നു് ബൂളിയന്‍ ആര്‍ഗ്യുമെന്റ് ആവശ്യമുണ്ടു്"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail-നു് ബൂളിയന്‍ ആര്‍ഗ്യുമെന്റ് ആവശ്യമുണ്ടു്"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -565,166 +597,169 @@ msgstr ""
 "--log-level-നു് ലോഗ് ലവല്‍ ആര്‍ഗ്യുമെന്റ് ആവശ്യമുണ്ടു് (ഒന്നുകില്‍ 0..4 വരെയുള്ള ന്യൂമറിക് പരിധി "
 "അല്ലെങ്കില്‍ debug, info, notice, warn, error എന്നിവയില്‍ ഒന്നു്)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority-നു് ബൂളിയന്‍ ആര്‍ഗ്യുമെന്റ് ആവശ്യമുണ്ടു്"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime-നു് ബൂളിയന്‍ ആര്‍ഗ്യുമെന്റ് ആവശ്യമുണ്ടു്"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading-നു് ബൂളിയന്‍ ആര്‍ഗ്യുമെന്റ് ആവശ്യമുണ്ടു്"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit-നു് ബൂളിയന്‍ ആര്‍ഗ്യുമെന്റ് ആവശ്യമുണ്ടു്"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file-നു് ബൂളിയന്‍ ആര്‍ഗ്യുമെന്റ് ആവശ്യമുണ്ടു്"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr "തെറ്റായ ലോഗ് ടാര്‍ഗറ്റ്: 'syslog', 'stderr' അല്ലെങ്കില്‍ 'auto' ഉപയോഗിക്കുക."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time-നു് ബൂളിയന്‍ ആര്‍ഗ്യുമെന്റ് ആവശ്യമുണ്ടു്"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta-നു് ബൂളിയന്‍ ആര്‍ഗ്യുമെന്റ് ആവശ്യമുണ്ടു്"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "തെറ്റായ റീസാംപിള്‍ മാര്‍ഗ്ഗം '%s'."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system-നു് ബൂളിയന്‍ ആര്‍ഗ്യുമെന്റ് ആവശ്യമുണ്ടു്"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit-നു് ബൂളിയന്‍ ആര്‍ഗ്യുമെന്റ് ആവശ്യമുണ്ടു്"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm-നു് ബൂളിയന്‍ ആര്‍ഗ്യുമെന്റ് ആവശ്യമുണ്ടു്"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "പേരു്: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "ഘടകത്തെപ്പറ്റിയുള്ള വിവരം ലഭ്യമല്ല\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "പതിപ്പു്: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "വിവരണം: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "രചയിതാവു്: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "ഉപയോഗം: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "ഒരിക്കല്‍ ലഭ്യമാക്കുക: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "DEPRECATION WARNING: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "പാഥ്: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] തെറ്റായ ലോഗ് ടാര്‍ഗറ്റ് '%s'."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] തെറ്റായ ലോഗ് ലവല്‍ '%s'."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] തെറ്റായ റീസാംപിള്‍ മാര്‍ഗ്ഗം '%s'."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] അസാധുവായ rlimit '%s'."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] ഈ പ്ലാറ്റ്ഫോമില്‍ rlimit-നുള്ള പിന്തുണ ലഭ്യമല്ല."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] തെറ്റായ സാംപിള്‍ മാതൃക '%s'."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] തെറ്റായ സാംപിള്‍ റേറ്റ് '%s'."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] തെറ്റായ സാംപിള്‍ ചാനലുകള്‍ '%s'."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] അസാധുവായ ചാനല്‍ മാപ്പ് '%s'."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] '%s' ഫ്രാഗ്മെന്റുകളുടെ തെറ്റായ എണ്ണം."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] തെറ്റായ ഫ്രാഗ്മെന്റ് വ്യാപ്തി '%s'."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] അസാധുവായ nice സ്ഥാനം '%s'."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] തെറ്റായ സാംപിള്‍ റേറ്റ് '%s'."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "ക്രമീകരണ ഫയല്‍ തുറക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -732,12 +767,12 @@ msgstr ""
 "വ്യക്തമാക്കിയിട്ടുള്ള സ്വതവേയുള്ള ചാനല്‍ മാപ്പിനുള്ള ചാനലുകളുടെ എണ്ണം നല്‍കിയിരിക്കുന്ന സ്വതവേയുള്ള "
 "ചാനലുകളുടെ എണ്ണത്തേക്കാള്‍ വ്യത്യസ്ഥമാണു്."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### ക്രമീകരണ ഫയലില്‍ നിന്നും ലഭ്യമാക്കുക: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "അനുമതികള്‍ വെടിപ്പാക്കുന്നു."
 
@@ -749,6 +784,16 @@ msgstr "PulseAudio സൌണ്ട് സിസ്റ്റം"
 msgid "Start the PulseAudio Sound System"
 msgstr "PulseAudio സൌണ്ട് സിസ്റ്റം ആരംഭിക്കുക"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio സൌണ്ട് സിസ്റ്റം"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "PulseAudio സൌണ്ട് സിസ്റ്റം ആരംഭിക്കുക"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "മോണോ"
@@ -778,8 +823,8 @@ msgid "Rear Right"
 msgstr "വലതു് അവസാനം"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "ലോ ഫ്രീക്വന്‍സി എമ്മിറ്റര്‍"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -953,9 +998,10 @@ msgstr "മുകളില്‍ അവസാനം ഇടത്തു്"
 msgid "Top Rear Right"
 msgstr "മുകളില്‍ അവസാനം വലത്തു്"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(അസാധു)"
 
@@ -983,332 +1029,349 @@ msgstr "സറൌണ്ട് 5.1"
 msgid "Surround 7.1"
 msgstr "സറൌണ്ട് 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "ശരി"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "അനുമതി നിഷേധിച്ചിരിക്കുന്നു"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "അപരിചിതമായ കമാന്‍ഡ്"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "തെറ്റായ ആര്‍ഗ്യുമെന്റ്"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "എന്റിറ്റി നിലവിലുണ്ടു്"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "അത്തരം എന്റിറ്റിയില്ല"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "കണക്ഷന്‍ നിഷേധിച്ചിരിക്കുന്നു"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "പ്രോട്ടോക്കോളില്‍ പിശക്"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "സമയം കഴിഞ്ഞിരിക്കുന്നു"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "ഓഥറൈസേഷന്‍ കീ നിലവിലില്ല"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "ആന്തരിക പിശക്"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "കണക്ഷന്‍ വിഛേദിച്ചിരിക്കുന്നു"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "എന്റിറ്റി ഇല്ലാതാക്കിയിരിക്കുന്നു"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "തെറ്റായ സര്‍വര്‍"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "ഘടകം ആരംഭിക്കുന്നതില്‍ പരാജയപ്പെട്ടു"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "തെറ്റായ അവസ്ഥ"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "ഡേറ്റാ ലഭ്യമല്ല"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "പൊരുത്തപ്പെടാത്ത പ്രോട്ടോക്കോള്‍ പതിപ്പു്"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "വളരെ വലുതു്"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "പിന്തുണ ലഭ്യമല്ല"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "അപരിചിതമായ പിശക് കോഡ്"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "അത്തരം എക്സ്റ്റെന്‍ഷന്‍ ലഭ്യമല്ല"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "ഇല്ലാതാക്കിയ വിശേഷത"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "പ്രവര്‍ത്തനം ലഭ്യമല്ല"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "ക്ലൈന്റ് ഫോര്‍ക്ക് ചെയ്തിരിക്കുന്നു"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "ഇന്‍പുട്ട്/ഔട്ട്പുട്ട് പിശക്"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "ഉപകരണം അല്ലെങ്കില്‍ ഉറവിടം ഉപയോഗത്തില്‍"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() പരാജയപ്പെട്ടു"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() പരാജയപ്പെട്ടു: %s"
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "കുക്കി ഡേറ്റാ പാഴ്സ് ചെയ്യുന്നതില്‍ പരാജയപ്പെട്ടു"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "ക്രമീകരണ ഫയല്‍ '%s' തുറക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "ഒരു കുക്കിയും ലഭ്യമല്ല. അതില്ലാതെ കണക്ട് ചെയ്യുവാന്‍‌ ശ്രമിക്കുന്നു."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "അപരിചിതമായ എക്സ്റ്റെന്‍ഷന്‍ '%s'-നുള്ള സന്ദേശം ലഭിച്ചിരിക്കുന്നു"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "സ്ട്രീം ഡ്രെയിന്‍ ചെയ്യുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "പ്ലേബാക്ക് സ്ട്രീം ഡ്രെയിന്‍ ചെയ്തിരിക്കുന്നു."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "സര്‍വറിലേക്കുള്ള കണക്ഷന്‍ ഡ്രെയിന്‍ ചെയ്യുന്നു."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_begin_write() പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "സ്ട്രീം വിജയകരമായി ഉണ്ടാക്കിയിരിക്കുന്നു."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, 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:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "ബഫര്‍ മെട്രിക്സ്: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "സാംപിള്‍ സ്പെക് '%s', ചാനല്‍ മാപ്പ് '%s' ഉപയോഗിക്കുന്നു."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "ഡിവൈസ് %s-ലേക്ക് കണക്ട് ചെയ്തിരിക്കുന്നു (%u, %ssuspended)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "സ്ട്രീം പിശക്: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "സ്ട്രീം ഡിവൈസ് സസ്പെന്‍ഡ് ചെയ്തിരിക്കുന്നു.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "സ്ട്രീം ഡിവൈസ് വീണ്ടും ആരംഭിച്ചിരിക്കുന്നു.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "സ്ട്രീം അണ്ടര്‍റണ്‍.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "സ്ട്രീ ഓവര്‍റണ്‍.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "സ്ട്രീം ആരംഭിച്ചിരിക്കുന്നു.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "ഡിവൈസ് %s-ലേക്ക് സ്ട്രീം നീക്കം ചെയ്തിരിക്കുന്നു (%u, %ssuspended).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "അല്ല"
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "സ്ട്രീം ബഫര്‍ വിശേഷതകള്‍ മാറ്റിയിരിക്കുന്നു.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "കണക്ഷന്‍ സ്ഥാപിച്ചിരിക്കുന്നു.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "കണക്ഷനില്‍ തകരാര്‍: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "EOF ലഭ്യമായിരിക്കുന്നു"
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "സിഗ്നല്‍ ലഭ്യമായി, പുറത്തു് കടക്കുന്നു."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "ലാറ്റന്‍സി ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "സമയം: %0.3f sec; ലാറ്റന്‍സി: %0.0f usec."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1360,10 +1423,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [options]\n"
@@ -1422,7 +1490,7 @@ msgstr ""
 "      --file-format=FFORMAT             Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1433,170 +1501,175 @@ msgstr ""
 "libpulse %s-നൊപ്പം കംപൈല്‍ ചെയ്തിരിക്കുന്നു\n"
 "libpulse %s-നൊപ്പം ലിങ്ക് ചെയ്തിരിക്കുന്നു\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "തെറ്റായ ക്ലൈന്റ് നാമം '%s'"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "തെറ്റായ സ്ട്രീം നാമം '%s'"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "തെറ്റായ ചാനല്‍ മാപ്പ് '%s'"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "തെറ്റായ ലാറ്റന്‍സി വിവരണം '%s'"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "തെറ്റായ പ്രക്രിയ സമയ വിവരണം '%s'"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "തെറ്റായ വിശേഷത '%s'"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "അപരിചിതമായ ഫയല്‍ രീതി %s."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "തെറ്റായ മാതൃക വിവരണം"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "അനവധി ആര്‍ഗ്യുമെന്റുകള്‍."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "ഫയലിനുള്ള സാംപിള്‍ വിവരണം ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "ഓ‍ഡിയോ ഫയല്‍ തുറക്കുന്നതില്‍ പരാജയപ്പെട്ടു."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
 msgstr ""
 "മുന്നറിയിപ്പു്: ഫയലില്‍ നിന്നുള്ള വിവരണം വ്യക്തമാക്കിയിരിക്കുന്ന സാംപിള്‍ വിവരണം മാറ്റിയെഴുതുന്നു."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "ഫയലില്‍ നിന്നും സാംപിള്‍ വിവരണം ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "മുന്നറിയിപ്പു്: ഫയലില്‍ നിന്നും ചാനല്‍ മാപ്പ് ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "ചാനല്‍ മാപ്പ് സാംപിള്‍ വിവരണവുമായി ചേരുന്നില്ല"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "മുന്നറിയിപ്പു്: ഫയലിലേക്ക് ചാനല്‍ മാപ്പ് സൂക്ഷിക്കുന്നതില്‍ പരാജയപ്പെട്ടു."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr "%s സ്ട്രീം തുറക്കുന്നു. ഇതിന്റെ സാംപിള്‍ വിവരണം '%s'-ഉം ചാനല്‍ മാപ്പ് '%s'-ഉം ആണു്."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "റിക്കോര്‍ഡ് ചെയ്യുന്നു"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "പ്ലേബാക്ക്"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "കമാന്‍ഡ് ലൈന്‍ പാഴ്സ് ചെയ്യുന്നതില്‍ പരാജയപ്പെട്ടു."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() പരാജയപ്പെട്ടു."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() പരാജയപ്പെട്ടു."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() പരാജയപ്പെട്ടു."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_rttime_new() പരാജയപ്പെട്ടു."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() പരാജയപ്പെട്ടു."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "സസ്പെന്‍ഡ് ചെയ്യുന്നതില്‍ പരാജയപ്പെട്ടു: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "വീണ്ടും ആരംഭിക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "മുന്നറിയിപ്പു്: ശബ്ദ സര്‍വര്‍ ലോക്കലല്ല, സസ്പെന്‍ഡ് ചെയ്യുന്നില്ല.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "കണക്ഷനില്‍ തകരാര്‍: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "SIGINT ലഭിച്ചു, പുറത്തു് കടക്കുന്നു.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "മുന്നറിയിപ്പു്: %u സിഗ്നല്‍ വഴി ചൈള്‍ പ്രക്രിയ അവസാനിച്ചിരിക്കുന്നു\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1641,35 +1714,46 @@ msgstr "pa_context_new() പരാജയപ്പെട്ടു..\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() പരാജയപ്പെട്ടു.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "സ്ഥിതിവിവരക്കണക്കുകള്‍ ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "നിലവില്‍ ഉപയോഗത്തില്‍: %u ബ്ലോക്കുകള്‍, മൊത്തം %s ബൈറ്റുകള്‍ അടങ്ങുന്നു.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "കാലാവധിയ്ക്കുള്ളില്‍ അനുവദിക്കുന്നു: %u ബ്ലോക്കുകള്‍, മൊത്തം %s ബൈറ്റുകള്‍ അടങ്ങുന്നു.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "സാംപിള്‍ കാഷ് വ്യപ്തി: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "സര്‍വര്‍ വിവരങ്ങള്‍ ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1677,7 +1761,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "User name: %s\n"
 "Host Name: %s\n"
@@ -1689,13 +1773,13 @@ msgstr ""
 "Default Source: %s\n"
 "Cookie: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "സിങ്ക് വിവരം ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1711,7 +1795,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1733,22 +1817,27 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tപോര്‍ട്ടുകള്‍:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tസജീവമായ പോര്‍ട്ട്: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tപോര്‍ട്ടുകള്‍:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "സോഴ്സ് വിവരങ്ങള്‍ ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1787,20 +1876,20 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "n/a"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "ഘടക വിവരങ്ങള്‍ ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1817,12 +1906,12 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "ക്ലൈന്റ് വിവരങ്ങള്‍ ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1837,12 +1926,12 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "കാര്‍ഡ് വിവരങ്ങള്‍ ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1859,23 +1948,23 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tപ്രൊഫൈലുകള്‍:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tസജീവമായ പ്രൊഫൈല്‍: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "സിങ്ക് ഇന്‍പുട്ട് വിവരങ്ങള്‍ ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1884,6 +1973,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1911,13 +2001,13 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "സോഴ്സ് ഔട്ട്പുട്ട് വിവരം ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1926,31 +2016,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Source Output #%u\n"
+"Sink Input #%u\n"
 "\tDriver: %s\n"
 "\tOwner Module: %s\n"
 "\tClient: %s\n"
-"\tSource: %u\n"
+"\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
-"\tSource Latency: %0.0f usec\n"
+"\tSink Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "മാതൃകയുടെ വിവരങ്ങള്‍ ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1981,48 +2080,163 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "പരാജയം: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "സോഴ്സ് വിവരങ്ങള്‍ ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "മാതൃക അപ്ലോഡ് ചെയ്യുന്നതില്‍ പരാജയപ്പെട്ടു: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "ഫയല്‍ അനുചിതമായ അവസാനം"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "തെറ്റായ സര്‍വര്‍"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "SIGINT ലഭ്യമായി, പുറത്തു് കടക്കുന്നു."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "തെറ്റായ വോള്യം വിവരണങ്ങള്‍"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2032,37 +2246,15 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+"%s [options] ... \n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
-"\n"
 "  -s, --server=SERVER                   The name of the server to connect "
 "to\n"
-"  -n, --client-name=NAME                How to call this client on the "
-"server\n"
+"\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2073,106 +2265,138 @@ msgstr ""
 "libpulse %s-നൊപ്പം കംപൈല്‍ ചെയ്തിരിക്കുന്നു\n"
 "libpulse %s-നൊപ്പം ലിങ്ക് ചെയ്തിരിക്കുന്നു\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "ലഭ്യമാക്കുന്നതിലുള്ള മാതൃകാ ഫയല്‍ ദയവായി വ്യക്തമാക്കുക"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "ശബ്ദ ഫയല്‍ തുറക്കുന്നതില്‍ പരാജയപ്പെട്ടു."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "മുന്നറിയിപ്പു്: ഫയലില്‍ നിന്നും മാതൃകയുടെ വിവരണം കണ്ടുപിടിക്കുന്നതില്‍ പരാജയപ്പെട്ടു."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "പ്രവര്‍ത്തിപ്പിക്കുവാനുള്ള മാതൃകയുടെ പേരു് നല്‍കേണ്ടതുണ്ടു്"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "നീക്കം ചെയ്യുന്നതിനുള്ള മാതൃകയുടെ പേരു് നല്‍കേണ്ടതുണ്ടു്"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "ഒരു സിങ്ക് ഇന്‍പുട്ട് ഇന്‍ഡക്സും സിങ്കും നല്‍കേണ്ടതുണ്ടു്"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "ഒരു സോഴ്സ് ഔട്ട്പുട്ട് ഇന്‍ഡക്സും സോഴ്സും നല്‍കേണ്ടതുണ്ടു്"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "ഒരു മൌഡ്യൂള്‍ നാമവും ആര്‍ഗ്യുമെന്റുകളും നല്‍കേണ്ടതുണ്ടു്."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "ഒരു മൌഡ്യൂള്‍ ഇന്‍ഡക്സ് നല്‍കേണ്ടതുണ്ടു്"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "ഒരു സിങ്കില്‍ കൂടുതല്‍ നിങ്ങള്‍ നല്‍കേണ്ടതില്ല. കൂടാതെ, ഒരു ബൂളിയന്‍ മൂല്ല്യവും നിങ്ങള്‍ നല്‍കേണ്ടതാണു്."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr ""
 "ഒരു സോഴ്സില്‍ കൂടുതല്‍ നിങ്ങള്‍ നല്‍കേണ്ടതില്ല. കൂടാതെ, ഒരു ബൂളിയന്‍ മൂല്ല്യവും നിങ്ങള്‍ നല്‍കേണ്ടതാണു്."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "ഒരു കാര്‍ഡ് നാമം/ഇന്‍ഡക്സും പ്രൊഫൈല്‍ നാമവും നല്‍കേണ്ടതുണ്ടു്"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "ഒരു സിങ്ക് നാമം/ഇന്‍ഡക്സും പോര്‍ട്ട് നാമവും നല്‍കേണ്ടതുണ്ടു്"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "ഒരു സോഴ്സ് നാമം/ഇന്‍ഡക്സും പോര്‍ട്ട് നാമവും നല്‍കേണ്ടതുണ്ടു്"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "ഒരു സിങ്ക് നാമം/ഇന്‍ഡക്സും വോള്യവും നല്‍കേണ്ടതുണ്ടു്"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "തെറ്റായ വോള്യം വിവരണങ്ങള്‍"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "ഒരു സോഴ്സ് നാമം/ഇന്‍ഡക്സും വോള്യവും നല്‍കേണ്ടതുണ്ടു്"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "ഒരു സിങ്ക് ഇന്‍പുട്ട് ഇന്‍ഡക്സും വോള്യവും നല്‍കേണ്ടതുണ്ടു്"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "തെറ്റായ സിങ്ക് ഇന്‍പുട്ട് ഇന്‍ഡക്സ്"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "ഒരു സോഴ്സ് ഔട്ട്പുട്ട് ഇന്‍ഡക്സും സോഴ്സും നല്‍കേണ്ടതുണ്ടു്"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "തെറ്റായ സിങ്ക് ഇന്‍പുട്ട് ഇന്‍ഡക്സ്"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "ഒരു സിങ്ക് നാമം/ഇന്‍ഡക്സും മ്യൂട്ട് ബൂളിയനും നല്‍കേണ്ടതുണ്ടു്"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "തെറ്റായ മാതൃക വിവരണം"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "ഒരു സോഴ്സ് നാമം/ഇന്‍ഡക്സും മ്യൂട്ട് ബൂളിയനും നല്‍കേണ്ടതുണ്ടു്"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "ഒരു സിങ്ക് ഇന്‍പുട്ട് ഇന്‍ഡക്സും മ്യൂട്ട് ബൂളിയനും നല്‍കേണ്ടതുണ്ടു്"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "തെറ്റായ സിങ്ക് ഇന്‍പുട്ട് ഇന്‍ഡക്സ് സ്പെസിഫിക്കേഷന്‍"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "ഒരു സോഴ്സ് നാമം/ഇന്‍ഡക്സും മ്യൂട്ട് ബൂളിയനും നല്‍കേണ്ടതുണ്ടു്"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "തെറ്റായ സിങ്ക് ഇന്‍പുട്ട് ഇന്‍ഡക്സ് സ്പെസിഫിക്കേഷന്‍"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "ഒരു സിങ്ക് നാമം/ഇന്‍ഡക്സും മ്യൂട്ട് ബൂളിയനും നല്‍കേണ്ടതുണ്ടു്"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "ശരിയായ കമാന്‍ഡുകള്‍ നല്‍കിയിട്ടില്ല."
 
@@ -2200,103 +2424,103 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "കമാന്‍ഡ് ലൈന്‍ പാഴ്സ് ചെയ്യുന്നതില്‍ പരാജയപ്പെട്ടു.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "സര്‍വര്‍: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "സോഴ്സ്: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "സിങ്ക്: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "കുക്കി: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "കുക്കീ ഡേറ്റാ പാഴ്സ് ചെയ്യുന്നതില്‍ പരാജയപ്പെട്ടു\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "കുക്കീ ഡേറ്റാ സൂക്ഷിക്കുന്നതില്‍ പരാജയപ്പെട്ടു\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "ക്ലൈന്റ് ക്രമീകരണ ഫയല്‍ ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "എന്‍വയോണ്മെന്റ് ക്രമീകരണ ഡേറ്റാ ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "FQDN ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "കുക്കീ ഡേറ്റാ ലഭ്യമാക്കുന്നതില്‍ പരാജയപ്പെട്ടു\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "ഇതുവരെ ലഭ്യമാക്കിയിട്ടില്ല.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr "പള്‍സ്ഓഡിയോ ഡെമണ്‍ പ്രവര്‍ത്തനതിലില്ല, സെഷന്‍ ഡെമണായും പ്രവര്‍ത്തിക്കുന്നില്ല."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "പള്‍സ്ഓഡിയോ ഡെമണ്‍ ഇല്ലാതാക്കുന്നതില്‍ പരാജയപ്പെട്ടു."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "ഡെമണ്‍ മറുപടി നല്‍കുന്നില്ല."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "ഓട്ടോസ്പൌണ്‍ ലോക്ക് ലഭ്യമാക്കുവാന്‍ സാധ്യമല്ല."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2312,7 +2536,7 @@ msgstr ""
 "POLLOUT സെറ്റ് വഴി നമ്മെ അറിയിച്ചിരിക്കുന്നു -- പക്ഷേ, snd_pcm_avail() ലഭ്യമാക്കിയതു് 0 "
 "അല്ലെങ്കില്‍ മറ്റൊരു മൂല്ല്യം < min_avail ആണു്."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2328,242 +2552,465 @@ msgstr ""
 "POLLIN സെറ്റ് വഴി നമ്മെ അറിയിച്ചിരിക്കുന്നു -- പക്ഷേ, snd_pcm_avail() ലഭ്യമാക്കിയതു് 0 "
 "അല്ലെങ്കില്‍ മറ്റൊരു മൂല്ല്യം < min_avail ആണു്."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "ഓഫ്"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "ഹൈ ഫിഡലിറ്റി പ്ലേബാക്ക് (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "ഹൈ ഫിഡലിറ്റി കാപ്ചര്‍ (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "ടെലിഫോണി ഡ്യൂപ്ലെക്സ് (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "പള്‍സ്ഓഡിയോ സൌണ്ട് സര്‍വര്‍"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
-msgstr ""
+msgstr "ഔട്ട്പുട്ട് ഡിവൈസുകള്‍"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
-msgstr ""
+msgstr "ഇന്‍പുട്ട് ഡിവൈസുകള്‍"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
-msgstr ""
+msgstr "@HOSTNAME@-ലുള്ള ഓഡിയോ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
-msgstr ""
+msgstr "ഇന്‍പുട്ട്"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
-msgstr ""
+msgstr "ഡോക്കിങ് സ്റ്റേഷന്‍ ഇന്‍പുട്ട്"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
-msgstr ""
+msgstr "ഡോക്കിങ് സ്റ്റേഷന്‍ മൈക്രോഫോണ്‍"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "ഡോക്കിങ് സ്റ്റേഷന്‍ ഇന്‍പുട്ട്"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "അനലോഗ് ലൈന്‍-ഇന്‍"
+
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
-msgstr ""
+msgstr "മൈക്രോഫോണ്‍"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
-msgid "External Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "ഡോക്കിങ് സ്റ്റേഷന്‍ മൈക്രോഫോണ്‍"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
 #, fuzzy
+msgid "Rear Microphone"
+msgstr "മൈക്രോഫോണ്‍"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "എക്സ്റ്റേണല്‍ മൈക്രോഫോണ്‍"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
-msgstr "à´\87à´¨àµ\8dà´±àµ\87à´°àµ\8dâ\80\8dണലàµ\8dâ\80\8d à´\93à´¡à´¿à´¯àµ\8b"
+msgstr "à´\87à´¨àµ\8dà´±àµ\87ണലàµ\8dâ\80\8d à´®àµ\88à´\95àµ\8dà´°àµ\8bà´«àµ\8bà´£àµ\8dâ\80\8d"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
-msgstr ""
+msgstr "റേഡിയോ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
-msgstr ""
+msgstr "വീഡിയോ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
-msgstr ""
+msgstr "ഓട്ടോമാറ്റിക് ഗെയിന്‍ കണ്ട്രോള്‍"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
-msgstr ""
+msgstr "ഓട്ടോമാറ്റിക് ഗെയിന്‍ കണ്ട്രോള്‍ ലഭ്യമല്ല"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
-msgstr ""
+msgstr "ബൂസ്റ്റ്"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
-msgstr ""
+msgstr "ബൂസ്റ്റ് ലഭ്യമല്ല"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
-msgstr ""
+msgstr "ആംപ്ലിഫയര്‍"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
-msgstr ""
+msgstr "ആംപ്ലിഫയര്‍ ലഭ്യമല്ല"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "ബൂസ്റ്റ്"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "ബൂസ്റ്റ് ലഭ്യമല്ല"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "അനലോഗ് ഹെഡ്ഫോണുകള്‍"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "അനലോഗ് ഇന്‍പുട്ട്"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "ഡോക്കിങ് സ്റ്റേഷന്‍ മൈക്രോഫോണ്‍"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
-msgstr "നളàµ\8dâ\80\8d à´\94à´\9fàµ\8dà´\9fàµ\8dà´ªàµ\81à´\9fàµ\8dà´\9fàµ\8d"
+msgstr "à´\85നലàµ\8bà´\97àµ\8d à´\94à´\9fàµ\8dà´\9fàµ\8dà´ªàµ\81à´\9fàµ\8dà´\9fàµ\8d"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "അനലോഗ് ഔട്ട്പുട്ട് (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "അനലോഗ് ലൈന്‍-ഇന്‍"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
+msgstr "അനലോഗ് മോണോ ഔട്ട്പുട്ട്"
+
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "അനലോഗ് സ്റ്റീരിയോ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, fuzzy, c-format
-msgid "%s+%s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "ഡിജിറ്റല്‍ സ്റ്റീരിയോ (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, fuzzy, c-format
-msgid "%s / %s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "ഡിജിറ്റല്‍ സ്റ്റീരിയോ (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
-msgstr ""
+msgstr "അനലോഗ് മോണോ"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
-msgstr "സ്റ്റീരിയോ"
+msgstr "à´\85നലàµ\8bà´\97àµ\8d à´¸àµ\8dà´±àµ\8dà´±àµ\80à´°à´¿à´¯àµ\8b"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
-msgstr "സറàµ\8cà´£àµ\8dà´\9fàµ\8d 4.1"
+msgstr "à´\85നലàµ\8bà´\97àµ\8d à´¸à´±àµ\8cà´£àµ\8dà´\9fàµ\8d 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
-msgstr "സറàµ\8cà´£àµ\8dà´\9fàµ\8d 4.0"
+msgstr "à´\85നലàµ\8bà´\97àµ\8d à´¸à´±àµ\8cà´£àµ\8dà´\9fàµ\8d 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
-msgstr "സറàµ\8cà´£àµ\8dà´\9fàµ\8d 4.1"
+msgstr "à´\85നലàµ\8bà´\97àµ\8d à´¸à´±àµ\8cà´£àµ\8dà´\9fàµ\8d 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
-msgstr "സറൌണ്ട് 4.0"
+msgstr "à´\85നലàµ\8bà´\97àµ\8d à´¸à´±àµ\8cà´£àµ\8dà´\9fàµ\8d 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
-msgstr "സറൌണ്ട് 4.1"
+msgstr "à´\85നലàµ\8bà´\97àµ\8d à´¸à´±àµ\8cà´£àµ\8dà´\9fàµ\8d 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
-msgstr "സറൌണ്ട് 5.0"
+msgstr "à´\85നലàµ\8bà´\97àµ\8d à´¸à´±àµ\8cà´£àµ\8dà´\9fàµ\8d 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
-msgstr "സറൌണ്ട് 5.1"
+msgstr "à´\85നലàµ\8bà´\97àµ\8d à´¸à´±àµ\8cà´£àµ\8dà´\9fàµ\8d 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
-msgstr "സറàµ\8cà´£àµ\8dà´\9fàµ\8d 4.0"
+msgstr "à´\85നലàµ\8bà´\97àµ\8d à´¸à´±àµ\8cà´£àµ\8dà´\9fàµ\8d 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
-msgstr "സറàµ\8cà´£àµ\8dà´\9fàµ\8d 4.1"
+msgstr "à´\85നലàµ\8bà´\97àµ\8d à´¸à´±àµ\8cà´£àµ\8dà´\9fàµ\8d 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
-msgstr "സറàµ\8cà´£àµ\8dà´\9fàµ\8d 4.0"
+msgstr "à´\85നലàµ\8bà´\97àµ\8d à´¸à´±àµ\8cà´£àµ\8dà´\9fàµ\8d 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
-msgstr "സറൌണ്ട് 7.1"
+msgstr "à´\85നലàµ\8bà´\97àµ\8d à´¸à´±àµ\8cà´£àµ\8dà´\9fàµ\8d 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
-msgstr ""
+msgstr "ഡിജിറ്റല്‍ സ്റ്റീരിയോ (IEC958) "
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "ഡിജിറ്റല്‍ സ്റ്റീരിയോ (IEC958) "
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
-msgstr ""
+msgstr "ഡിജിറ്റല്‍ സറൌണ്ട് 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
-msgstr ""
+msgstr "ഡിജിറ്റല്‍ സറൌണ്ട് 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
-msgstr ""
+msgstr "ഡിജിറ്റല്‍ സ്റ്റീരിയോ (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "ഡിജിറ്റല്‍ സറൌണ്ട് 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
-msgstr ""
+msgstr "അനലോഗ് മോണോ ഡ്യൂപ്ലെക്സ്"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
-msgstr ""
+msgstr "അനലോഗ് സ്റ്റീരിയോ ഡ്യൂപ്ലെക്സ്"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
+msgstr "ഡിജിറ്റല്‍ സ്റ്റീരിയോ ഡ്യൂപ്ലെക്സ് (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "നള്‍ ഔട്ട്പുട്ട്"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "ഇന്‍പുട്ട്"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
 msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<name for the sink> sink_properties=<properties for the sink> "
+"master=<name of sink to filter> format=<sample format> rate=<sample rate> "
+"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
+"plugin name> label=<ladspa plugin label> control=<comma separated list of "
+"input control values>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] ഈ പ്ലാറ്റ്ഫോമില്‍ rlimit-നുള്ള പിന്തുണ ലഭ്യമല്ല."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() പരാജയപ്പെട്ടു"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "ഡിജിറ്റല്‍ സറൌണ്ട് 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "ലോ ഫ്രീക്വന്‍സി എമ്മിറ്റര്‍"
index 9f417fd..cee6b76 100644 (file)
--- a/po/mr.po
+++ b/po/mr.po
@@ -1,29 +1,24 @@
 # translation of pulseaudio.master-tx.po to Marathi
 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the PACKAGE package.
+# Sandeep Shedmake <sshedmak@redhat.com>, 2009, 2012.
 #
-# Sandeep Shedmake <sandeep.shedmake@gmail.com>, 2009.
-# Sandeep Shedmake <sshedmak@redhat.com>, 2009.
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-09-21 18:16+0530\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:54+0000\n"
 "Last-Translator: Sandeep Shedmake <sshedmak@redhat.com>\n"
 "Language-Team: Marathi <fedora-trans-mr@redhat.com>\n"
+"Language: mr\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: KBabel 1.11.4\n"
 "Plural-Forms: nplurals=2; plural=(n!=1);\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -35,11 +30,11 @@ msgstr ""
 "हे सहसा ALSA ड्राइवर '%s' अंतर्गत बग अशू शकते. कृपया या अडचणीस ALSA डेव्हलपर करीता "
 "कळवा."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
@@ -47,7 +42,19 @@ msgstr ""
 "हे सहसा ALSA ड्राइवर '%s' अंतर्गत बग अशू शकते. कृपया या अडचणीस ALSA डेव्हलपर करीता "
 "कळवा."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() ने अपेक्षा पेक्षा मोठे मूल्य पूरवले: %lu बाईटस् (%lu ms).\n"
+"हे सहसा ALSA ड्राइवर '%s' अंतर्गत बग अशू शकते. कृपया या अडचणीस ALSA डेव्हलपर करीता "
+"कळवा."
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -59,25 +66,28 @@ msgstr ""
 "हे सहसा ALSA ड्राइवर '%s' अंतर्गत बग अशू शकते. कृपया या अडचणीस ALSA डेव्हलपर करीता "
 "कळवा."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "नल्ल असल्यावरही नेहमी किमान एक सींक लोड करून ठेवा"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "डम्मी आऊटपुट"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "आभासी LADSPA सींक"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<सींक करीता नाव> sink_properties=<सींक करीता गुणधर्म> "
 "master=<फिल्टरजोगी सींकचे नाव> format=<चाचणी रूपण> rate=<चाचणी दर> "
@@ -85,275 +95,302 @@ msgstr ""
 "नाव> label=<ladspa प्लगइन लेबल> control=<इंपुट कंट्रोल मुल्यांची स्वल्पविराम विभाजीत "
 "सूची>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "क्लॉक्ड् NULL सींक"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "Null आऊटपुट"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "आंतरीक ऑडिओ"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "मोडेम"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "मूळ lt_dlopen दाखलकर्ता शोधण्यास अपयशी."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "नवीन dl दाखलकर्ता वाटप करण्यास अपयशी."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "bind-now-loader समावेष करण्यास अपयशी."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "संकेत %s प्राप्त झाले."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "बाहेर पडत आहे."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "वापरकर्ता '%s' शोधणे अशक्य."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "गट '%s' शोधण्यास अपयशी."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "वापरकर्ता '%s' (UID %lu) व गट '%s' (GID %lu) आढळले."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "वापरकर्ता '%s' व गट '%s' चे GID जुळत नाही."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "वापरकर्ता '%s' ची मुख्य डिरेक्ट्री '%s' नाही, दुर्लक्ष करत आहे."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "'%s' बनवण्यास अपयशी: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "गट यादी बदलवण्यास अपयशी: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "GID बदलवण्यास अपयशी: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "UID बदलवण्यास अपयशी: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "रूट परवानगी यशस्वीरित्या वगळले."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "प्रणाली भर पद्धत या प्लॅटफॉर्म करीता समर्थीत नाही."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) अपयशी: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "आदेश ओळ वाचण्यास अपयशी."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "डिमन कार्यरत नाही"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "डिमन PID %u नुरूप कार्यरत आहे"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "डिमन नष्ट करण्यास अपयशी: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
 msgstr "हा कार्यक्रम रूट नुरूप चालविण्याकरीता नाही (जोपर्यंत --system निश्चित नाही)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "रूट परवानगी आवश्यक."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "प्रणाली घटनांकरीता --start समर्थीत नाही."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "प्रणाली पद्धती अंतर्गत कार्यरत, परंतु --disallow-exit निश्चित केले नाही!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
 "प्रणाली पद्धती अंतर्गत कार्यरत, परंतु --disallow-module-loading निश्चित केले नाही!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "प्रणाली पद्धती अंतर्गत कार्यरत, SHM पद्धत जबरनरित्या अकार्यान्वीत करत आहे!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr "प्रणाली पद्धती अंतर्गत कार्यरत, रिकामे वेळ जबरनरित्या अकार्यान्वीत करत आहे!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "stdio प्राप्त करण्यास अपयशी."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "पाइप अपयशी: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() अपयशी: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() अपयशी: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "डिमन स्टार्टअप अपयशी."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "डिमन स्टार्टअप यशस्वी."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() अपयशी: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "हे PulseAudio %s आहे"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "कंपाइलेशन यजमान: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "कंपाइलेशन CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "यजमान वर कार्यरत: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "%u CPUs आढळले."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "पान आकार %lu बाईटस् आहे"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Valgrind समर्थनशी कंपाईल केले: होय"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Valgrind समर्थनशी कंपाईल केले: नाही"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "valgrind पद्धतीत कार्यरत: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "यजमान वर कार्यरत: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "अनुकूल बिल्ड: होय"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "अनुकूल बिल्ड: नाही"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG वर्णीकृत, सर्व asserts अकार्यान्वीत."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH वर्णीकृत, फक्त जलद मार्गीय asserts अकार्यान्वीत केले."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "सर्व asserts कार्यान्वीत केले."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "मशीन ID प्राप्त करण्यास अपयशी"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "मशीन ID %s आहे."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "सत्र ID %s आहे."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "रनटाईम डिरेक्ट्री %s वापरत आहे."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "स्थिती डिरेक्ट्री %s वापरत आहे."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "घटक डिरेक्ट्री %s वापरत आहे."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "प्रणाली पद्धतीत कार्यरत: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -369,15 +406,15 @@ msgstr ""
 "प्रणाली मोड दोकादायक आहे यासाठी कृपया http://pulseaudio.org/wiki/"
 "WhatIsWrongWithSystemMode वाचा."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() अपयशी."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "नवीन उच्च-बिंदूता टाइमर उपलब्ध! Bon appetit!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -385,32 +422,32 @@ msgstr ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() अपयशी."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "डिमन प्रारंभ करण्यास अपयशी."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "विना विभाग दाखल केल्यास डिमन प्रारंभ झाले, कार्य करण्यास नकार."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "डिमन स्टार्टअप पूर्ण झाले."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "डिमन पूर्णपणे बंद करण्यास प्रारंभ केले."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "डिमन नष्ट केले."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -447,15 +484,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -552,15 +587,15 @@ msgstr ""
 "\n"
 "  -n                                    Don't load default script file\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize यास बूलीयन बाब अपेक्षीत आहे"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail यास बूलीयन बाब अपेक्षीत आहे"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -568,166 +603,169 @@ msgstr ""
 "--log-level यास लॉग स्तरीय बाब अपेक्षीत आहे (एकतर क्षेत्र 0..4 अंतर्गत संख्यायी किंवा "
 "debug, info, notice, warn, error पैकी एक)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority यास बूलीयन बाब अपेक्षीत आहे"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime यास बूलीयन बाब अपेक्षीत आहे"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading यास बूलीयन बाब अपेक्षीत आहे"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit यास बूलीयन बाब अपेक्षीत आहे"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file यास बूलीयन बाब अपेक्षीत आहे"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr "अवैध लॉग लक्ष्य: 'syslog', 'stderr' किंवा 'auto' पैकी एक वापरा."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time यास बूलीयन बाब अपेक्षीत आहे"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta यास बूलीयन बाब अपेक्षीत आहे"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "अवैध पुन्ह सॅम्पल पद्धत '%s'."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system यास बूलीयन बाब अपेक्षीत आहे"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit यास बूलीयन बाब अपेक्षीत आहे"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm यास बूलीयन बाब अपेक्षीत आहे"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "नाव: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "घटक माहिती उपलब्ध नाही\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "आवृत्ती: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "वर्णन: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "लेखक: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "वापरणी: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "एकदा दाखल करा: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "DEPRECATION WARNING: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "मार्ग: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] अवैध लॉग लक्ष्य '%s'."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] अवैध लॉग स्तर '%s'."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] अवैध पुन्ह सॅम्पल पद्धत '%s'."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] अवैध rlimit '%s'."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit या प्लॅटफॉर्म वर समर्थीत नाही."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] अवैध सॅम्पल स्वरूप '%s'."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] अवैध सॅम्पल दर '%s'."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] अवैध सॅम्पल मार्ग '%s'."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] अवैध मार्ग मॅप '%s'."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] अवैध तुकडे '%s' यांची एकूण संख्या."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] अवैध तुकड्याचे आकार '%s'."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] अवैध nice स्तर '%s'."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] अवैध सॅम्पल दर '%s'."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "संयोजना फाइल उघडण्यास अपयशी: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -735,12 +773,12 @@ msgstr ""
 "निश्चित मुलभूत वाहिनी मॅपकडे निश्चित एकूण मुलभूत वाहिनी पेक्षा वेगळे वाहिनी संख्या "
 "समाविष्टीत आहे."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### संयोजना फाइल: %s पासून वाचा ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "परवानगी वगळत आहे."
 
@@ -752,6 +790,16 @@ msgstr "PulseAudio आवाज प्रणाली"
 msgid "Start the PulseAudio Sound System"
 msgstr "PulseAudio आवाज प्रणाली सुरू करा"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio आवाज प्रणाली"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "PulseAudio आवाज प्रणाली सुरू करा"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "मोनो"
@@ -781,8 +829,8 @@ msgid "Rear Right"
 msgstr "पाठीमागे उजवीकडे"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "कमी क्रिक्वेन्सी स्रोत"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -956,9 +1004,10 @@ msgstr "वरील पाठीमागचे डावे"
 msgid "Top Rear Right"
 msgstr "वरील पाठीमागचे उजवे"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(अवैध)"
 
@@ -986,332 +1035,349 @@ msgstr "सराऊन्ड 5.1"
 msgid "Surround 7.1"
 msgstr "सराऊन्ड 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "ठिक"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "प्रवेश नकारले"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "अपरिचीत आदेश"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "अवैध बाब"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "घटक अस्तित्वात आहे"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "घटक आढळले नाही"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "जुळवणी नकारली"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "प्रोटोकॉल त्रुटी"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "वेळसमाप्ती"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "ओळख पटवण्याकरीता कि आढळली नाही"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "आंतरीक त्रुटी"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "वेळसमाप्ती नष्ट झाली"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "घटक नष्ट झाले"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "अवैध सर्वर"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "घटक प्रारंभ अपयशी"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "अयोग्य स्तर"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "डेटा आढळला नाही"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "असहत्व प्रोटोकॉल आवृत्ती"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "खूप मोठे"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "समर्थीत नाही"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "अपरिचीत त्रुटी कोड"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "यानुरूप वाढ आढळली नाही"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "जुणी कार्यपद्धत"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "लागू केले आहे असे आढळले नाही"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "क्लाऐंट विभाजीत केले"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "इंपुट/आऊटपुट त्रुटी"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "उपकरन किंव स्रोत व्यस्थ"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() अपयशी"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() अपयशी: %s"
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "कुकी डेटा वाचण्यास अपयशी"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "संयोजना फाइल '%s' उघडण्यास अपयशी: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "कुकी दाखल केले नाही. जुळवणीचा प्रयत्न करत आहे."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "अपरिचीत वाढ '%s' करीता संदेश प्राप्त झाले"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "स्ट्रीम रिकामे करण्यास अपयशी: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "प्लेबॅक स्ट्रीम रिकामे झाले."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "सर्व्हर करीता जुळवणी ड्रेन केली."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() अपयशी: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_begin_write() अपयशी: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() अपयशी: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "स्ट्रीम यशस्वीरित्या निर्माण केले."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() अपयशी: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, 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:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "बफर मेट्रीक्स्: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "उदाहरणार्थ spec '%s', वाहिनी नकाशा '%s' वापरत आहे."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "साधन %s शी जुळले (%u, %s सस्पेंड केले)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "स्ट्रीम त्रुटी: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "स्ट्रीम साधन सस्पेंड केले.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "स्ट्रीम साधन पुनः सुरू केले.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "स्ट्रीम underrun.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "स्ट्रीम overrun.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "स्ट्रीम started.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "स्ट्रीम साधन %s कडे स्थानांतरीत केले (%u, %ssuspended).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "नाही "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "स्ट्रीम बफर गुणधर्म बदलले.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "जुळवणी स्थापीत केली.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() अपयशी: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() अपयशी: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() अपयशी: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "जुळवणी अपयशी: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "EOF प्राप्त झाले."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() अपयशी: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "संकेत प्राप्त झाले, बाहेर पडत आहे."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "विलंब प्राप्त करण्यास अपयशी: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "वेळ: %0.3f sec; विलंब: %0.0f usec."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() अपयशी: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1363,10 +1429,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [options]\n"
@@ -1425,7 +1496,7 @@ msgstr ""
 "      --file-format=FFORMAT             Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1436,169 +1507,174 @@ msgstr ""
 "libpulse %s शी कंपाई केले\n"
 "libpulse %s शी लिंक केले\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "अवैध क्लाएंटचे नाव '%s'"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "अवैध स्ट्रीमचे नाव '%s'"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "अवैध वाहिनी नकाशा '%s'"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "अवैध विलंब संयोजना '%s'"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "अवैध कार्य वेळ संयोजना '%s'"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "अवैध गुणधर्म '%s'"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "अपरिचीत फाइल रूपण %s."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "अवैध सॅम्पल संयोजना"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "खूप जास्त बाब."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "फाइलसाठी सॅम्पल माहिती प्राप्त करण्यास अपयशी."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "आवाज फाइल उघडण्यास अपयशी."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
 msgstr "सावधानता: निर्देशीत चाचणी संयोजना फाइलमधील संयोजनाशी खोडून पुनः लिहीली जाईल."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "फाइलपासून चाचणी संयोजना माहिती प्राप्त करण्यास अपयशी."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "सावधानता: फाइलपासून वाहिनी नकाशा ओळखण्यास अपयशी."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "वाहिनी नकाशा चाचणी संयोजनाशी जुळत नाही"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "सावधानता: वाहिनी नकाशा फाइलमध्ये लिहण्यास अपयशी."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr "%s स्ट्रीम चाचणी संयोजना '%s' व वाहिनी नकाशा '%s' सह उघडत आहे."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "रेकॉर्डींग"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "प्लेबॅक"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "आदेश ओळ वाचण्यास अपयशी."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() अपयशी."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() अपयशी."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() अपयशी."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() अपयशी: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_rrttime_new() अपयशी."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() अपयशी."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "सस्पेंड करण्यास अपयशी: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "पुन्हा चालू करण्यास अपयशी: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "सावधानता: आवाज सर्वर स्थानीय नाही, सस्पेंड करत नाही.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "जुळवणी अपयशी: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "SIGINT प्राप्त झाले, बाहेर पडत आहे.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "सावधानता: उप कार्य संकेत %u द्वारे नष्ट करण्यात आले\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1643,35 +1719,46 @@ msgstr "pa_context_new() अपयशी.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() अपयशी.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "आकडेवारी प्राप्त करण्यास अपयशी: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "वर्तमानक्षणी वापरणीत आहे: %2$s बाईटस् समाविष्टीत एकूण %1$u ब्लॉक्स् .\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "संपूर्ण कार्यकाळवेळी लागू केले: %2$s बाईटस् समाविष्टीत एकूण %1$u ब्लॉक्स् .\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "सॅपल कॅशे आकार: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "सर्वर माहिती प्राप्त करण्यास अपयशी: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1679,7 +1766,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "वापरकर्ता नाव: %s\n"
 "आयोजक नाव: %s\n"
@@ -1691,13 +1778,13 @@ msgstr ""
 "मुलभूत स्रोत: %s\n"
 "कुकीज: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "sink माहिती प्राप्त करण्यास अपयशी: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1713,7 +1800,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1735,22 +1822,27 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tपोर्टस्:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tसक्रीय पोर्ट: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tपोर्टस्:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "स्रोत माहिती प्राप्त करण्यास अपयशी: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1789,20 +1881,20 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "n/a"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "विभाग माहिती प्राप्त करण्यास अपयशी: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1819,12 +1911,12 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "क्लाऐंट माहिती प्राप्त करण्यास अपयशी: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1839,12 +1931,12 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "कार्ड माहिती प्राप्त करण्यास अपयशी: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1861,23 +1953,23 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tसंक्षिप्त माहिती:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tसक्रीय संक्षिप्त माहिती: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "सींक इंपुट माहिती प्राप्त करण्यास अपयशी: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1886,6 +1978,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1913,13 +2006,13 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "स्रोत आऊटपुट माहिती प्राप्त करण्यास अपयशी: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1928,31 +2021,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Source Output #%u\n"
+"Sink Input #%u\n"
 "\tDriver: %s\n"
 "\tOwner Module: %s\n"
 "\tClient: %s\n"
-"\tSource: %u\n"
+"\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
-"\tSource Latency: %0.0f usec\n"
+"\tSink Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "सॅम्पल माहिती प्राप्त करण्यास अपयशी: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1983,48 +2085,163 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "अपयशी: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "स्रोत माहिती प्राप्त करण्यास अपयशी: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "सॅम्पल अपलोड करण्यास अपयशी: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "फाइलची अयोग्य समाप्ती"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "अवैध सर्वर"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "SIGINT प्राप्त झाले, बाहेर पडत आहे."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "अवैध खंडाची संयोजना"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2034,37 +2251,15 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+"%s [options] ... \n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
-"\n"
 "  -s, --server=SERVER                   The name of the server to connect "
 "to\n"
-"  -n, --client-name=NAME                How to call this client on the "
-"server\n"
+"\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2075,106 +2270,138 @@ msgstr ""
 "libpulse %s सह कंपाईल केले\n"
 "libpulse %s सह जुळले\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "कृपया दाखल करण्याजोगी तात्पूर्ती फाइल निर्देशीत करा"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "आवाज फाइल उघडण्यास अपयशी."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "सावधानता: फाइलपासून चाचणी संयोजना ओळखण्यास अपयशी."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "चालवण्याकरीता तुम्हाला तात्पूर्ते नाव निश्चित करावे लागेल"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "काढून टाकण्याकरीता तुम्हाला तात्पूर्ते नाव निश्चित करावे लागेल"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "तुम्हाला सींक इंपुट निर्देशांक व सींक निश्चित करावे लागेल"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "तुम्हाला आऊटपुट इंडेक्स स्रोत व स्रोत निश्चित करावे लागेल"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "तुम्हाला विभागाचे नाव व बाब निश्चित करावे लागेल."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "तुम्हाला विभाग इंडेक्स् निश्चित करावे लागेल"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "तुम्ही एकापेक्षा जास्त सींक निश्चित करू शकत नाही. तुम्हाला बूलीयन मूल्य निश्चित करावे लागेल."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr ""
 "तुम्ही एकापेक्षा जास्त स्रोत निश्चित करू शकत नाही. तुम्हाला बूलीयन मूल्य निश्चित करावे लागेल."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "तुम्हाला कार्डचे नाव/इंडेक्स् व प्रोफाइल नाव निश्चित करावे लागेल"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "तुम्हाला सींक नाव/इंडेक्स् व पोर्टचे नाव निश्चित करावे लागेल"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "तुम्हाला स्रोत नाव/इंडेक्स् व पोर्टचे नाव निश्चित करावे लागेल"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "तुम्हाला सींक नाव/इंडेक्स् व पोर्टचे नाव निश्चित करावे लागेल"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "अवैध खंडाची संयोजना"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "तुम्हाला स्रोत नाव/इंडेक्स् व खंडाचे नाव निश्चित करावे लागेल"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "तुम्हाला सींक इंपुट इंडेक्स् व सींक निश्चित करावे लागेल"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "अवैध सींक इंपुट इंडेक्स्"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "तुम्हाला आऊटपुट इंडेक्स स्रोत व स्रोत निश्चित करावे लागेल"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "अवैध सींक इंपुट इंडेक्स्"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "तुम्हाला सींक नाव/इंडेक्स् व पोर्टचे नाव निश्चित करावे लागेल"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "अवैध सॅम्पल संयोजना"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "तुम्हाला स्रोत नाव/इंडेक्स् व पोर्टचे नाव निश्चित करावे लागेल"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "तुम्हाला सींक इंपुट निर्देशांक व सींक निश्चित करावे लागेल"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "अवैध सींक इंपुट इंडेक्स् संयोजना"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "तुम्हाला स्रोत नाव/इंडेक्स् व पोर्टचे नाव निश्चित करावे लागेल"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "अवैध सींक इंपुट इंडेक्स् संयोजना"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "तुम्हाला सींक नाव/इंडेक्स् व पोर्टचे नाव निश्चित करावे लागेल"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "वैध आदेश निश्चित केले नाही."
 
@@ -2202,103 +2429,103 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "आदेश ओळ वाचण्यास अपयशी.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "सर्वर: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "स्रोत: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "सींक: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "कुकीज: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "कुकीज माहिती वाचण्यास अपयशी\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "कुकी डेटा साठवण्यास अपयशी\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "क्लाऐंट संयोजना फाइल दाखल करण्यास अपयशी.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "वातावरण संयोजना डेटा वाचण्यास अपयशी.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "FQDN प्राप्त करण्यास अपयशी.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "कुकी डेटा दाखल करण्यास अपयशी\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "अजूनही लागू केले नाही.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr "PulseAudio डिमन कार्यरत नाही, किंवा सत्र डिमन नुरूप कार्यरत नाही."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "PulseAudio डिमन पूर्णपणे नष्ट करण्यास अपयशी."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "डिमन प्रतिसाद देत नाही."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "autospawn कुलूप करीता प्रवेश प्राप्य अशक्य."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2313,7 +2540,7 @@ msgstr ""
 "POLLOUT द्वारे सज्ज होणे शक्य आहे -- तरी परस्पर snd_pcm_avail() ने 0 पूरविले किंवा इतर "
 "मूल्य < min_avail असावे."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2328,242 +2555,465 @@ msgstr ""
 "POLLIN द्वारे सज्ज होणे शक्य आहे -- तरी परस्पर snd_pcm_avail() ने 0 पूरविले किंवा इतर "
 "मूल्य < min_avail असावे."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "बंद करा"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "हाय फिडेलिटी प्लेबॅक (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "हाय फिडीलीटी कॅपचर (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "टेलिफोनी ड्युप्लेक्स् (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "PulseAudio आवाज सर्वर"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
-msgstr ""
+msgstr "आऊट साधणे"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
-msgstr ""
+msgstr "इंपुट साधणे"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
-msgstr ""
+msgstr "@HOSTNAME@ वरील ऑडिओ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
-msgstr ""
+msgstr "इंपुट"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
-msgstr ""
+msgstr "डॉकिंग स्टेशन इंपुट"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
-msgstr ""
+msgstr "डॉकिंग स्टेशन माइक्रोफोन"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "डॉकिंग स्टेशन इंपुट"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "लाइन-इन"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
-msgstr ""
+msgstr "माइक्रोफोन"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
-msgid "External Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "डॉकिंग स्टेशन माइक्रोफोन"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
 #, fuzzy
+msgid "Rear Microphone"
+msgstr "माइक्रोफोन"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "बाहेरील माइक्रोफोन"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
-msgstr "à¤\86à¤\82तरà¥\80à¤\95 à¤\91डिà¤\93"
+msgstr "à¤\86à¤\82तरà¥\80à¤\95 à¤®à¤¾à¤\87à¤\95à¥\8dरà¥\8bफà¥\8bन"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
-msgstr ""
+msgstr "रेडिओ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
-msgstr ""
+msgstr "विडिओ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
-msgstr ""
+msgstr "स्वयं गैन कंट्रोल"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
-msgstr ""
+msgstr "स्वयं गैन कंट्रोल अशक्य"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
-msgstr ""
+msgstr "बूस्ट"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
-msgstr ""
+msgstr "बूस्ट अशक्य"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
-msgstr ""
+msgstr "ऍमप्लिफायर"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
-msgstr ""
+msgstr "ऍमप्लिफायर अशक्य"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "बूस्ट"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "बूस्ट अशक्य"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "ऍनलॉग हेडफोन्स्"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "ऍनलॉग इंपुट"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "डॉकिंग स्टेशन माइक्रोफोन"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
-msgstr "Null आऊटपुट"
+msgstr "ऍनलॉग आऊटपुट"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "ऍनलॉग आऊटपुट (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "लाइन-इन"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
+msgstr "ऍनलॉग मोनो आऊटपुट"
+
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "ऍनलॉग स्टिरीओ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, fuzzy, c-format
-msgid "%s+%s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "डिजीटल स्टिरीओ (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, fuzzy, c-format
-msgid "%s / %s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "डिजीटल स्टिरीओ (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
-msgstr ""
+msgstr "ऍनलॉग मोनो"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
-msgstr "स्टिरीओ"
+msgstr "à¤\8dनलà¥\89à¤\97 à¤¸à¥\8dà¤\9fिरà¥\80à¤\93"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
-msgstr "सराà¤\8aनà¥\8dड 4.1"
+msgstr "à¤\8dनलà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
-msgstr "सराà¤\8aनà¥\8dड 4.0"
+msgstr "à¤\8dनलà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
-msgstr "सराà¤\8aनà¥\8dड 4.1"
+msgstr "à¤\8dनलà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
-msgstr "सराà¤\8aनà¥\8dड 4.0"
+msgstr "à¤\8dनलà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
-msgstr "सराà¤\8aनà¥\8dड 4.1"
+msgstr "à¤\8dनलà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
-msgstr "सराà¤\8aनà¥\8dड 5.0"
+msgstr "à¤\8dनलà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
-msgstr "सराà¤\8aनà¥\8dड 5.1"
+msgstr "à¤\8dनलà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
-msgstr "सराà¤\8aनà¥\8dड 4.0"
+msgstr "à¤\8dनलà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
-msgstr "सराà¤\8aनà¥\8dड 4.1"
+msgstr "à¤\8dनलà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
-msgstr "सराà¤\8aनà¥\8dड 4.0"
+msgstr "à¤\8dनलà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
-msgstr "सराà¤\8aनà¥\8dड 7.1"
+msgstr "à¤\8dनलà¥\89à¤\97 à¤¸à¤°à¥\8dराà¤\89à¤\82ड 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
-msgstr ""
+msgstr "डिजीटल स्टिरीओ (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "डिजीटल स्टिरीओ (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
-msgstr ""
+msgstr "डिजीटल सर्राउंड 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
-msgstr ""
+msgstr "डिजीटल सर्राउंड 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
-msgstr ""
+msgstr "डिजीटल स्टिरीओ (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "डिजीटल सर्राउंड 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
-msgstr ""
+msgstr "ऍनलॉग मोनो ड्युप्लेक्स्"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
-msgstr ""
+msgstr "ऍनलॉग स्टिरीओ ड्युप्लेक्स्"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
+msgstr "डिजीटल स्टिरीओ ड्युप्लेक्स् (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Null आऊटपुट"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "इंपुट"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
 msgstr ""
+"sink_name=<सींक करीता नाव> sink_properties=<सींक करीता गुणधर्म> "
+"master=<फिल्टरजोगी सींकचे नाव> format=<चाचणी रूपण> rate=<चाचणी दर> "
+"channels=<वाहिनींची संख्या> channel_map=<वाहिनी नकाशा> plugin=<ladspa प्लगइन "
+"नाव> label=<ladspa प्लगइन लेबल> control=<इंपुट कंट्रोल मुल्यांची स्वल्पविराम विभाजीत "
+"सूची>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit या प्लॅटफॉर्म वर समर्थीत नाही."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() अपयशी"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "डिजीटल सर्राउंड 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "कमी क्रिक्वेन्सी स्रोत"
index a1c127e..2e6d57c 100644 (file)
--- a/po/nl.po
+++ b/po/nl.po
@@ -2,27 +2,22 @@
 # Copyright (C) 2009 THE pulseaudio.master-tx'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the pulseaudio.master-tx package.
 # Geert Warrink <geert.warrink@onsnet.nu>, 2009.
-# Reinout van Schouwen <reinout@gmail.com>, 2009
-#
+# Reinout van Schouwen <reinout@gmail.com>, 2009, 2012.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-10-14 04:44+0000\n"
-"PO-Revision-Date: 2009-10-14 11:00+0100\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:54+0000\n"
 "Last-Translator: Reinout van Schouwen <reinout@gmail.com>\n"
 "Language-Team: Dutch <vertaling@vrijschrift.org>\n"
+"Language: nl\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding:  \n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -30,25 +25,38 @@ msgid ""
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 msgstr ""
-"snd_pcm_avail() gaf een waarde terug die uitzonderlijk groot is: %lu bytes (%"
-"lu ms).\n"
+"snd_pcm_avail() gaf een waarde terug die uitzonderlijk groot is: %lu bytes "
+"(%lu ms).\n"
 "Waarschijnlijk is dit een fout in het ALSA-stuurprogramma ‘%s’. Meld dit "
 "probleem alstublieft aan de ALSA-ontwikkelaars."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
+"snd_pcm_delay() gaf een waarde terug die uitzonderlijk groot is: %li bytes "
+"(%s%lu ms).\n"
+"Waarschijnlijk is dit een fout in het ALSA-stuurprogramma ‘%s’. Meld dit "
+"probleem alstublieft aan de ALSA-ontwikkelaars."
+
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 msgstr ""
-"snd_pcm_delay() gaf een waarde terug die uitzonderlijk groot is: %li bytes (%"
-"s%lu ms).\n"
+"snd_pcm_avail() gaf een waarde terug die uitzonderlijk groot is: %lu bytes "
+"(%lu ms).\n"
 "Waarschijnlijk is dit een fout in het ALSA-stuurprogramma ‘%s’. Meld dit "
 "probleem alstublieft aan de ALSA-ontwikkelaars."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -61,147 +69,156 @@ msgstr ""
 "Waarschijnlijk is dit een fout in het ALSA-stuurprogramma ‘%s’. Meld dit "
 "probleem alstublieft aan de ALSA-ontwikkelaars."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr ""
 "Houdt altijd ten minste een afvoer ingeladen zelfs als het de null-afvoer is."
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "Dummy-uitvoer"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "Virtuele LADSPA afvoer"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
-"sink_name=<naam voor de afvoer> sink_properties=<eigenschappen van de afvoer> "
-"master=<naam van de te filteren afvoer> format=<sampleformaat> rate=<sample "
-"snelheid> channels=<aantal kanalen> channel_map=<kanaalkaart> plugin=<ladspa "
-"pluginnaam> label=<ladspa pluginlabel> control=<kommagescheiden "
-"lijst van invoercontrolewaarden>"
+"sink_name=<naam voor de afvoer> sink_properties=<eigenschappen van de "
+"afvoer> master=<naam van de te filteren afvoer> format=<sampleformaat> "
+"rate=<sample snelheid> channels=<aantal kanalen> channel_map=<kanaalkaart> "
+"plugin=<ladspa pluginnaam> label=<ladspa pluginlabel> "
+"control=<kommagescheiden lijst van invoercontrolewaarden>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "Geklokte NULL afvoer"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "Null-uitvoer"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "Intern geluid"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "Modem"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "Kon de originele lt_dlopen lader niet vinden."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "Kon die nieuwe dl lader niet toekennen."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "Kon bind-now-loader niet toevoegen."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "Signaal %s ontvangen."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "Afsluiten."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "Kon gebruiker '%s' niet vinden."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "Kon groep ‘%s’ niet vinden."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "Gebruiker ‘%s’ (UID %lu) en groep ‘%s’ (GID %lu) gevonden."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "GID van gebruiker ‘%s’ en van groep ‘%s’ passen niet bij elkaar."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "Persoonlijke map van gebruiker ‘%s’ is niet ‘%s’, negeer het."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Aanmaken van ‘%s’ mislukt: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "Veranderen van groepslijst mislukt: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "Veranderen van GID mislukt: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "Veranderen van UID mislukt: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "Beheerdersrechten met succes laten vervallen."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "Systeembrede modus wordt op dit platform niet ondersteund."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) mislukte: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "Analyseren van de opdrachtregel mislukte."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "Voorziening draait niet"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "Voorziening draait met PID %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "Elimineren van voorziening mislukt: ‘%s’"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -209,156 +226,177 @@ msgstr ""
 "Dit programma is niet bedoeld om als root gedraaid te worden (behalve als --"
 "system is opgegeven)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "Beheerdersrechten vereist."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start wordt niet ondersteund voor systeeminstanties"
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "Draaiend in systeemmodus, maar --disallow-exit is niet ingesteld!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
 "Draaiend in systeemmodus, maar --disallow-module-loading is niet gezet!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "Draaiend in systeemmodus, geforceerd uitzetten van SHM-modus!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr "Draaiend in systeemmodus, geforceerd uitzetten van exit idle time!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "Verkrijgen van stdio mislukte."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "pipe mislukte: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() mislukte: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() mislukte: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "Voorziening opstarten mislukt."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "Voorziening met succes opgestart."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() mislukte: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Dit is PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Compilatiehost: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "Compilatie-CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "Draaiend op host: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "%u CPU's gevonden."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "Pagina grootte is %lu bytes"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Gecompileerd met Valgrind ondersteuning: ja"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Gecompileerd met Valgrind ondersteuning: nee"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "Draaiend in valgrind-modus: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "Draaiend op host: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "Geoptimaliseerd gebouwd: ja"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "Geoptimaliseerd gebouwd: nee"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG gedefinieerd, alle asserts uitgezet."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH gedefinieerd, alleen fast path-asserts uitgezet."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "Alle asserts aangezet."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "Machine-ID verkrijgen mislukt"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "Machine-ID is: %s."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "Sessie-ID is: %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "Gebruik van runtime-map %s."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "Verbruik van state-map %s."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "Gebruik van module-map %s."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Draaiend in systeemmodus: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -367,22 +405,22 @@ msgid ""
 "Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an "
 "explanation why system mode is usually a bad idea."
 msgstr ""
-"OK, dus u draait PA in systeemmodus. Merk op dat u dit "
-"waarschijnlijk beter niet kunt doen.\n"
+"OK, dus u draait PA in systeemmodus. Merk op dat u dit waarschijnlijk beter "
+"niet kunt doen.\n"
 "Als u het toch doet dan is het uw eigen schuld als dingen niet werken zoals "
 "verwacht.\n"
-"Lees http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode voor een "
-"uitleg waarom systeemmodus gewoonlijk een slecht idee is."
+"Lees http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode voor een uitleg "
+"waarom systeemmodus gewoonlijk een slecht idee is."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() mislukte."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "Verse high-resolution timers beschikbaar! Smakelijk eten!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -390,32 +428,32 @@ msgstr ""
 "Kerel, je kernel stinkt! De aanbeveling van de chef is vandaag Linux met "
 "aangezette high-resolution timers!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() mislukte."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "Initialiseren van de voorziening mislukt."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Voorziening opgestart zonder geladen modules, dat werkt niet."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "Voorziening opstarten is klaar."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "Voorziening afsluiten is begonnen."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "Voorziening is afgesloten."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -452,15 +490,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -567,15 +603,15 @@ msgstr ""
 "  -n                                    Laad het standaard script bestand "
 "niet\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize verwacht een boolean argument"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail verwacht een boolean argument"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -583,166 +619,169 @@ msgstr ""
 "--log-level verwacht een log level argument (numeriek uit de reeks 0..4 of "
 "een van type debug, info, notice, warn, error)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority verwacht een boolean argument"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime verwacht een boolean argument"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading verwacht een boolean argument"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit verwacht een bolean argument"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file verwacht een boolean argument"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr "Ongeldig log doel: gebruik een van 'syslog', 'stderr', 'auto'."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time verwacht een boolean argument"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta verwacht een boolean argument"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Ongeldige resample methode '%s'."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system verwacht een boolean argument"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit verwacht een boolean argument"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm verwacht een boolean argument"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Naam: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "Geen module informatie beschikbaar\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Versie: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Beschrijving: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Auteur: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Gebruik: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "Laad eenmaal: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "ACHTERHAALDHEIDSWAARSCHUWING: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Pad: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Ongeldig logdoel '%s'."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Ongeldig logniveau '%s'."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Ongeldige resample-methode ‘%s’."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] Ongeldige rlimit ‘%s’."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit wordt niet ondersteund op dit platform."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Ongeldig sampleformaat ‘%s’."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Ongeldige samlperate ‘%s’."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Ongeldige sample-kanalen ‘%s’."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] Ongeldige kanalenkaart ‘%s’."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Ongeldig aantal fragmenten '%s'."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Ongeldige fragmentgrootte ‘%s’."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Ongeldig nice niveau ‘%s’."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Ongeldige samlperate ‘%s’."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Openen van configuratiebestand %s mislukt."
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -750,12 +789,12 @@ msgstr ""
 "De opgegeven standaard kanalenkaart heeft een ander aantal kanalen dan de "
 "opgegeven standaard aantal kanalen."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Lees uit het configuratiebestand: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "Rechten opschonen."
 
@@ -767,6 +806,16 @@ msgstr "PulseAudio geluidssysteem"
 msgid "Start the PulseAudio Sound System"
 msgstr "Start het PulseAudio geluidssysteem"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio geluidssysteem"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "Start het PulseAudio geluidssysteem"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
@@ -796,8 +845,8 @@ msgid "Rear Right"
 msgstr "Achter rechts"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Lage-frequentiezender"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -971,9 +1020,10 @@ msgstr "boven achter links"
 msgid "Top Rear Right"
 msgstr "boven achter rechts"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(ongeldig)"
 
@@ -1001,332 +1051,349 @@ msgstr "Surround 5.1"
 msgid "Surround 7.1"
 msgstr "Surround 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "OK"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "toegang geweigerd"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Onbekend commando"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "Ongeldige argumenten"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "Eenheid bestaat"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "Eenheid onbekend"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "Verbinding geweigerd"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "Protocolfout"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "Tijd verstreken"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "Geen autorisatiesleutel"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "Interne fout"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "Verbinding verbroken"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "Eenheid geëlimineerd"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Ongeldige server"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "Module-initialisatie mislukt"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "Slechte toestand"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Geen data"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "Protocol versie niet compatibel"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "Te groot"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "Niet ondersteund"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Onbekende fout code"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "Onbekende extentie"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "Verouderde functionaliteit"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "Implementatie ontbreekt"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "Client afgesplitst"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "Input/Output fout"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "Apparaat of hulpbron is bezig"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() mislukte"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() mislukte: %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "Analyseren van cookie-data mislukt"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Open van configuratiebestand ‘%s’ mislukte: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "Geen cookie geladen. Probeer zonder cookie te verbinden."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "Ontving boodschap voor onbekende extensie ‘%s’"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "Afvoeren stroom %s mislukte"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "Afspelen van afgevoerde stroom."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "Vervinding naar server afvoeren."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() mislukte: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_begin_write() mislukte: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() mislukte: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "Stroom met succes aangemaakt."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() mislukte: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 msgstr "Buffermetriek: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Buffermetriek: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "Gebruik sample-spec  '%s', kanaal map '%s'."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "Verbonden met apparaat %s (%u, %sopgeschort)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "Stroomfout: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "Stroomapparaat opgeschort.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "Stroomapparaat hervat.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "Te weinig data voor stroom.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "Data-overschrijding voor stroom.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "Stroom gestart.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "Stroom verplaatst naar apparaat %s (%u, %sopgeschort).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "niet "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "Stroom buffer attributen veranderden.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "Verbinding bereikt.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() mislukte: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() mislukte: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() mislukte: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "Verbindingsfout: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "Kreeg EOF."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() mislukte: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "Ontving signaal, afsluiten."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "Latentie krijgen mislukte: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Tijd: %0.3f sec; Latentie: %0.0f usec."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() mislukte: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1378,10 +1445,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [opties]\n"
@@ -1404,8 +1476,8 @@ msgstr ""
 "genoemd\n"
 "      --volume=VOLUME                   Geef het begins (lineare) volume in "
 "reeks 0...65536\n"
-"      --rate=SAMPLERATE                 De samplerate in Hz "
-"(standaard 44100)\n"
+"      --rate=SAMPLERATE                 De samplerate in Hz (standaard "
+"44100)\n"
 "      --format=SAMPLEFORMAT             Het sampletype, een van s16le, "
 "s16be, u8, float32le,\n"
 "                                        float32be, ulaw, alaw, s32le, s32be, "
@@ -1417,11 +1489,11 @@ msgstr ""
 "                                        (standaard 2)\n"
 "      --channel-map=CHANNELMAP          Kanaalkaart te gebruiken in plaats "
 "van de standaard\n"
-"      --fix-format                      Neem het sampleformaat over "
-"van de afvoer waar de stroom\n"
+"      --fix-format                      Neem het sampleformaat over van de "
+"afvoer waar de stroom\n"
 "                                        mee verbonden is.\n"
-"      --fix-rate                        Neem de samplerate over "
-"van de afvoer waar de stroom\n"
+"      --fix-rate                        Neem de samplerate over van de "
+"afvoer waar de stroom\n"
 "                                        mee verbonden is.\n"
 "      --fix-channels                    Neem het aantal kanalen en de kanaal "
 "map over\n"
@@ -1443,7 +1515,7 @@ msgstr ""
 "      --list-file-formats               Laat beschikbare bestandsformaten "
 "zien.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1454,68 +1526,68 @@ msgstr ""
 "Gecompileerd met libpulse %s\n"
 "Gelinkt met libpulse %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "Ongeldige clientnaam ‘%s’."
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "Ongeldige stroomnaam ‘%s’."
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "Ongeldige kanaalkaart ‘%s’."
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "Ongeldige latentie-specificatie ‘%s’."
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "Ongeldige procestijdspecificatie ‘%s’."
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "Ongeldige eigenschap ‘%s’."
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "Ongeldig bestandsformaat %s"
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "Ongeldige samplespecificatie"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "Te veel argumenten."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "Aanmaken van samplespecificatie voor bestand mislukt."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "Openen van geluidsbestand mislukte."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
@@ -1523,103 +1595,108 @@ msgstr ""
 "Waarschuwing: opgegeven bemonster specificatie zal overschreven worden met "
 "de specificatie van het bestand."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "Bepalen van samplespecificatie van het bestand mislukte."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "Waarschuwing: Bepalen van kanaalkaart van bestand mislukte."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "Kanaal map komt niet overeen met bemonster specificatie."
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "Waarschuwing: schrijven van kanaalkaart naar bestand mislukte."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr ""
 "Openen van een %s stroom met samplespecificatie ‘%s’ en kanaalkaart ‘%s’."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "opnemen"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "afspelen"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "Analyseren van de opdrachtregel mislukte."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() mislukte."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() mislukte."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_cotext_new() mislukte."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() mislukte: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_rttime_new() mislukte."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() mislukte."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "Opschorten mislukte: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "Vervolgen mislukte: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "WAARSCHUWING: Geluidsserver is niet lokaal, geen opschorten.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Verbonding mislukte: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "Kreeg SIGINT, verlaten.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "WAARSCHUWING: kind proces afgesloten door signaal %u\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1664,37 +1741,48 @@ msgstr "pa_context_new() mislukte.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() mislukte.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "Verkrijgen van statistiek %s mislukte"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "Op dit moment in gebruik: %u blokken bevattende in totaal %s bytes.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr ""
 "Toegewezen tijdens de gehele levensduur: %u blokken bevattende in totaal %s "
 "butes.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "Sample-buffergrootte: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "Server informatie verkrijgen mislukte: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1702,7 +1790,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "Gebruikersnaam: %s\n"
 "Hostnaam: %s\n"
@@ -1714,13 +1802,13 @@ msgstr ""
 "Standaard bron: %s\n"
 "Cookie: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "Verkrijgen afvoerinformatie mislukte: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1736,7 +1824,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1758,22 +1846,27 @@ msgstr ""
 "\tEigenschappen:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tPoorten:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tActieve poort: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tPoorten:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "Verkrijgen van broninformatie mislukt: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1812,20 +1905,20 @@ msgstr ""
 "\tEigenschappen:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "n.v.t."
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "Verkrijgen van module informatie mislukte: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1842,12 +1935,12 @@ msgstr ""
 "\tEigenschappen:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "Verkrijgen van clientinformatie mislukt: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1862,12 +1955,12 @@ msgstr ""
 "\tEigenschappen:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "Verkrijgen van kaartinformatie mislukt: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1884,23 +1977,23 @@ msgstr ""
 "\tEigenschappen:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tProfielen:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tActieve profiel: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "Verkrijgen van afvoer-invoerinformatie mislukt: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1909,6 +2002,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1936,13 +2030,13 @@ msgstr ""
 "\tEigenschappen:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "Verkrijgen van bron-uitvoerinformatie mislukt: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1951,31 +2045,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Bronuitvoer #%u\n"
-"\tDriver: %s\n"
-"\tModule-eigenaaar: %s\n"
+"Afvoer input #%u\n"
+"\tStuurprogramma: %s\n"
+"\tModule-eigenaar: %s\n"
 "\tClient: %s\n"
-"\tBron: %u\n"
+"\tAfvoer: %u\n"
 "\tSamplespecificatie: %s\n"
 "\tKanaalkaart: %s\n"
+"\tDemping: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balans %0.2f\n"
 "\tBufferlatentie: %0.0f usec\n"
-"\tBronlatentie: %0.0f usec\n"
+"\tAfvoerlatentie: %0.0f usec\n"
 "\tResample-methode: %s\n"
 "\tEigenschappen:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "Verkrijgen van sample-informatie mislukt: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -2006,48 +2109,163 @@ msgstr ""
 "\tEigenschappen:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "Mislukt: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Verkrijgen van broninformatie mislukt: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "Uploaden van monster mislukte: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "Voortijdig einde van bestand"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "Ongeldige server"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "Ontving SIGINT, afsluiten."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "Ongeldige volume-opgave"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2057,37 +2275,15 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [opties] stat\n"
-"%s [opties] list\n"
-"%s [opties] exit\n"
-"%s [opties] upload-sample BESTANDNAAM [NAAM]\n"
-"%s [opties] play-sample NAAM [AFVOER]\n"
-"%s [opties] remove-sample NAAM\n"
-"%s [opties] move-sink-input AFVOERINPUT AFVOER\n"
-"%s [opties] move-source-output BRONOUTPUT BRON\n"
-"%s [opties] load-module NAAM [ARG ...]\n"
-"%s [opties] unload-module MODULE\n"
-"%s [opties] suspend-sink AFVOER 1|0\n"
-"%s [opties] suspend-source BRON 1|0\n"
-"%s [opties] set-card-profile KAART PROFIEL\n"
-"%s [opties] set-sink-port AFVOER POORT\n"
-"%s [opties] set-source-port BRON POORT\n"
-"%s [opties] set-sink-volume AFVOER VOLUME\n"
-"%s [opties] set-source-volume BRON VOLUME\n"
-"%s [opties] set-sink-input-volume AFVOERINPUT VOLUME\n"
-"%s [opties] set-sink-mute AFVOER 1|0\n"
-"%s [opties] set-source-mute BRON 1|0\n"
-"%s [opties] set-sink-input-mute AFVOERINPUT 1|0\n"
+"%s [opties] ... \n"
 "\n"
 "  -h, --help                            Laat deze hulp zien\n"
 "      --version                         Laat versie zien\n"
+"  -s, --server=SERVER                   De naam van de server waarmee "
+"verbonden wordt\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect "
-"to\n"
-"  -n, --client-name=NAME                How to call this client on the "
-"server\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2098,107 +2294,140 @@ msgstr ""
 "Gecompileerd met libpulse %s\n"
 "Gelinkt met libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "Geef een te laden samplebestand op"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "Openen geluidsbestand mislukt."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
-msgstr ""
-"Waarschuwing: Bepalen van samplespecificatie van bestand mislukte."
+msgstr "Waarschuwing: Bepalen van samplespecificatie van bestand mislukte."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "U dient een samplenaam op te geven om af te spelen"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "U dient een samplenaam op te geven om te verwijderen"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "U dient een afvoer-invoerindex en een afvoer op te geven"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "U dient een bron-uitvoerindex en een bron op te geven"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "U dient een modulenaam en argumenten op te geven."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "U dient een module index op te geven"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
-"U kunt niet meer dan een afvoer opgeven. U dient een boolean waarde op te geven."
+"U kunt niet meer dan een afvoer opgeven. U dient een boolean waarde op te "
+"geven."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr ""
-"U kunt niet meer dan één bron opgeven. u dient een boolean waarde op te geven."
+"U kunt niet meer dan één bron opgeven. u dient een boolean waarde op te "
+"geven."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "U dient een kaartnaam/index en een profielnaam op te geven"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "U dient een afvoernaam/index en een poortnaam op te geven"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "U dient een bronnaam/index en een poortnaam op te geven"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "U dient een afvoernaam/index en een volume op te geven"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "Ongeldige volume-opgave"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "U dient een bronnaam/index en een volume op te geven"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "U dient een afvoer-invoerindex en een volume op te geven"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "Ongeldige afvoer-invoerindex"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "U dient een bron-uitvoerindex en een bron op te geven"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "Ongeldige afvoer-invoerindex"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "U dient een afvoernaam/index en een dempingsboolean op te geven"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "Ongeldige samplespecificatie"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "U dient een bronnaam/index en een dempingsboolean op te geven"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "U dient een afvoer-invoerindex en een dempingsboolean op te geven"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "Ongeldige afvoer-invoerindex opgave"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "U dient een bronnaam/index en een dempingsboolean op te geven"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "Ongeldige afvoer-invoerindex opgave"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "U dient een afvoernaam/index en een dempingsboolean op te geven"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "Geen geldige opdracht opgegeven."
 
@@ -2227,104 +2456,105 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "Opdrachtregel ontleden mislukt.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Server: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Bron: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Afvoer: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Cookie: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "Cookiedata ontleden mislukt\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "Cookiedata opslaan mislukt\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "Clientconfiguratiebestand laden mislukt.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "Omgevingsconfiguratiedata lezen mislukt.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "FQDN verkrijgen mislukte.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "Cookiedata laden mislukt\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Nog niet geïmplementeerd.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr ""
-"Er draait geen PulseAudio-voorziening, of het draait niet als sessievoorziening."
+"Er draait geen PulseAudio-voorziening, of het draait niet als "
+"sessievoorziening."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "PulseAudio-voorziening uitzetten mislukt."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "Voorziening reageert niet."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "Kan geen toegang krijgen tot autospawn blokkade."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2341,7 +2571,7 @@ msgstr ""
 "We werden gewekt met POLLOUT ingesteld -- echter een opvolgende snd_pcm_avail"
 "() gaf 0 terug of een andere waarde < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2358,232 +2588,469 @@ msgstr ""
 "We werden gewekt met POLLIN ingesteld -- echter een opvolgende snd_pcm_avail"
 "() gaf 0 terug of een andere waarde < min_avail."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "Uit"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "High Fidelity Playback (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "High Fidelity afvangen (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Telefonie duplex (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "PulseAudio-geluidsserver"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
 msgstr "Uitvoerapparaten"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
 msgstr "Invoerapparaten"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
 msgstr "Geluid op @HOSTNAME@"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
 msgstr "Invoer"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
 msgstr "Docking station-invoer"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
 msgstr "Docking station-microfoon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "Docking station-invoer"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
 msgstr "Lijn-in"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
 msgstr "Microfoon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "Docking station-microfoon"
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "Microfoon"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
 msgid "External Microphone"
 msgstr "Externe microfoon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
 msgstr "Interne microfoon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
 msgstr "Radio"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
 msgstr "Video"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
 msgstr "Automatische gain-controle"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
 msgstr "Geen automatische gain-controle"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
 msgstr "Boostversterking"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
 msgstr "Geen boostversterking"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
 msgstr "Versterker"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
 msgstr "Geen versterker"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr "Analoge invoer"
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "Boostversterking"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr "Analoge microfoon"
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "Geen boostversterking"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
-msgstr "Analoge lijn-in"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr "Analoge radio"
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "Analoge koptelefoon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr "Analoge video"
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "Analoge invoer"
+
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "Docking station-microfoon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
 msgstr "Analoge output"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr "Analoge koptelefoon"
-
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
 msgstr "Analoge output (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "Lijn-in"
+
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
 msgstr "Analoge mono-uitvoer"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, c-format
-msgid "%s+%s"
-msgstr "%s+%s"
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "Analoog stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, c-format
-msgid "%s / %s"
-msgstr "%s/%s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Digitaal stereo (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Digitaal stereo (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr "Analoog mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr "Analoog stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
 msgstr "Analoog surround 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
 msgstr "Analoog surround 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
 msgstr "Analoog surround 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr "Analoog surround 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr "Analoog surround 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr "Analoog surround 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr "Analoog surround 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
 msgstr "Analoog surround 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
 msgstr "Analoog surround 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
 msgstr "Analoog surround 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr "Analoog surround 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr "Digitaal stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "Digitaal surround 4.0 (IEC958)"
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Digitaal stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Digitaal surround 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Digitaal surround 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr "Digitaal stereo (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Digitaal surround 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
 msgstr "Analoog mono duplex"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
 msgstr "Analoog stereo duplex"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
 msgstr "Digitaal stereo duplex (IEC958)"
 
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Null-uitvoer"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "Invoer"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<naam voor de afvoer> sink_properties=<eigenschappen van de "
+"afvoer> master=<naam van de te filteren afvoer> format=<sampleformaat> "
+"rate=<sample snelheid> channels=<aantal kanalen> channel_map=<kanaalkaart> "
+"plugin=<ladspa pluginnaam> label=<ladspa pluginlabel> "
+"control=<kommagescheiden lijst van invoercontrolewaarden>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit wordt niet ondersteund op dit platform."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() mislukte"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Bronuitvoer #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tModule-eigenaaar: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tBron: %u\n"
+#~ "\tSamplespecificatie: %s\n"
+#~ "\tKanaalkaart: %s\n"
+#~ "\tBufferlatentie: %0.0f usec\n"
+#~ "\tBronlatentie: %0.0f usec\n"
+#~ "\tResample-methode: %s\n"
+#~ "\tEigenschappen:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [opties] stat\n"
+#~ "%s [opties] list\n"
+#~ "%s [opties] exit\n"
+#~ "%s [opties] upload-sample BESTANDNAAM [NAAM]\n"
+#~ "%s [opties] play-sample NAAM [AFVOER]\n"
+#~ "%s [opties] remove-sample NAAM\n"
+#~ "%s [opties] move-sink-input AFVOERINPUT AFVOER\n"
+#~ "%s [opties] move-source-output BRONOUTPUT BRON\n"
+#~ "%s [opties] load-module NAAM [ARG ...]\n"
+#~ "%s [opties] unload-module MODULE\n"
+#~ "%s [opties] suspend-sink AFVOER 1|0\n"
+#~ "%s [opties] suspend-source BRON 1|0\n"
+#~ "%s [opties] set-card-profile KAART PROFIEL\n"
+#~ "%s [opties] set-sink-port AFVOER POORT\n"
+#~ "%s [opties] set-source-port BRON POORT\n"
+#~ "%s [opties] set-sink-volume AFVOER VOLUME\n"
+#~ "%s [opties] set-source-volume BRON VOLUME\n"
+#~ "%s [opties] set-sink-input-volume AFVOERINPUT VOLUME\n"
+#~ "%s [opties] set-sink-mute AFVOER 1|0\n"
+#~ "%s [opties] set-source-mute BRON 1|0\n"
+#~ "%s [opties] set-sink-input-mute AFVOERINPUT 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Laat deze hulp zien\n"
+#~ "      --version                         Laat versie zien\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s/%s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Digitaal surround 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Lage-frequentiezender"
+
 #, fuzzy
 #~ msgid "Invalid client name '%s'\n"
 #~ msgstr "Ongeldige resample methode '%s'."
index c4a8d19..edf4ca2 100644 (file)
--- a/po/or.po
+++ b/po/or.po
@@ -1,16 +1,17 @@
 # translation of pulseaudio.master-tx.or.po to Oriya
 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the PACKAGE package.
+# Manoj Kumar Giri <mgiri@redhat.com>, 2009, 2012.
 #
-# Manoj Kumar Giri <mgiri@redhat.com>, 2009.
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx.or\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-09-11 12:56+0530\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:55+0000\n"
 "Last-Translator: Manoj Kumar Giri <mgiri@redhat.com>\n"
 "Language-Team: Oriya <oriya-it@googlegroups.com>\n"
+"Language: or\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -31,13 +32,9 @@ msgstr ""
 "\n"
 "\n"
 "\n"
+"\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -50,20 +47,33 @@ msgstr ""
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"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."
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -76,145 +86,154 @@ msgstr ""
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "ସର୍ବଦା ଅତିକମରେ ଗୋଟିଏ ସିଙ୍କକୁ ଧାରଣ କରନ୍ତୁ ଯଦିଚ ତାହା ଗୋଟିଏ ଶୂନ୍ୟ ଅଟେ"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "ପ୍ରତିରୂପି ଫଳାଫଳ"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "ଆଭାସୀ LADSPA ସିଙ୍କ"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<ସିଙ୍କର ନାମ> sink_properties=<ସିଙ୍କର ଗୁଣଧର୍ମ> master=<ସିଙ୍କ ଛାଣକର ନାମ> "
 "format=<ନମୁନା ସଜ୍ଜିକରଣ ଶୈଳୀ> rate=<ନମୁନା ହାର> channels=<ଚ୍ୟାନେଲ ସଂଖ୍ୟା> "
 "channel_map=<ଚ୍ୟାନେଲ ମ୍ୟାପ> plugin=<ladspa ପ୍ଲଗଇନ ନାମ> label=<ladspa ପ୍ଲଗଇନ "
 "ନାମପଟି> control=<କମା ଦ୍ୱାରା ପୃଥକ ନିବେଶ ନିୟନ୍ତ୍ରଣ ମୂଲ୍ୟ ତାଲିକା>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "ସମୟାନୁବର୍ତ୍ତି ଶୂନ୍ୟ ସିଙ୍କ"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "ଶୂନ୍ୟ ଫଳାଫଳ"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "ଆଭ୍ୟନ୍ତରୀଣ ଧ୍ୱନି"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "ମଡେମ"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "ପ୍ରକୃତ lt_dlopen ଧାରକକୁ ଖୋଜି ପାଇବାରେ ବିଫଳ।"
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "ନୂତନ dl ଧାରକକୁ ବଣ୍ଟନ କରିବାରେ ବିଫଳ।"
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "bind-now-loaderକୁ ଯୋଗ କରିବାରେ ବିଫଳ।"
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "ସଂକେତ %s ପାଇଲା।"
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "ଉତ୍ତେଜିତ କରୁଅଛି।"
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "ଚାଳକ '%s' କୁ ଖୋଜିବାରେ ବିଫଳ।"
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "ସମୂହ '%s' କୁ ଖୋଜି ପାଇବାରେ ବିଫଳ।"
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "ଚାଳକ '%s' (UID %lu) ଏବଂ ସମୂହ '%s' (GID %lu) ମିଳିଲା।"
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "ଚାଳକ '%s' ଏବଂ ସମୂହ '%s' ର GID ମେଳଖାଏନାହିଁ।"
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "ଚାଳକ '%s' ର ମୂଖ୍ୟ ଡିରେକ୍ଟୋରୀଟି '%s' ନୁହଁ, ଅଗ୍ରାହ୍ୟ କରୁଅଛି।"
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "'%s' ନିର୍ମାଣ କରିବାରେ ବିଫଳ: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "ସମୂହ ତାଲିକାକୁ ପରିବର୍ତ୍ତନ କରିବାରେ ବିଫଳ: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "GID କୁ ପରିବର୍ତ୍ତନ କରିବାରେ ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "UID କୁ ପରିବର୍ତ୍ତନ କରିବାରେ ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "ମୂଖ୍ୟ ଚାଳକ ଅଧିକାରକୁ ସଫଳତାର ସହିତ ପକାଯାଇଛି।"
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "ତନ୍ତ୍ରମୟ ଧାରା ଏହି ପ୍ଲାଟଫର୍ମରେ ଅସମର୍ଥିତ।"
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "ପାଠ୍ୟ ନିର୍ଦ୍ଦେଶକୁ ବିଶ୍ଳେଷଣ କରିବାରେ ବିଫଳ।"
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "ଡେମନ ଚାଲୁନାହିଁ"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "ଡେମନ PID %u ପରି ଚାଲୁଅଛି"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "ଡେମନକୁ ବନ୍ଦ କରିବାରେ ବିଫଳ: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -222,155 +241,176 @@ msgstr ""
 "ଏହି ପ୍ରଗ୍ରାମଟି ମୂଖ୍ୟ ଚାଳକ ଭାବରେ ଚଲାଇବା ପାଇଁ ନିର୍ଦ୍ଦିଷ୍ଟ ହୋଇନାହିଁ (unless --system is "
 "specified)।"
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "ମୂଖ୍ୟ ଚାଳକ ଅଧିକାର ଆବଶ୍ୟକ।"
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start ତନ୍ତ୍ର ସ୍ଥିତି ପାଇଁ ସମର୍ଥିତ ନୁହଁ।"
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "ତନ୍ତ୍ର ଧାରାରେ ଚାଲୁଅଛି, କିନ୍ତୁ --disallow-exit କୁ ସେଟ କରାଯାଇନାହିଁ!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr "ତନ୍ତ୍ର ଧାରାରେ ଚାଲୁଅଛି, କିନ୍ତୁ --disallow-module-loading କୁ ସେଟ କରାଯାଇନାହିଁ!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "ତନ୍ତ୍ର ଧାରାରେ ଚାଲୁଅଛି, SHM ଧାରାକୁ ବାଧ୍ଯତାମୁଳକ ଭାବରେ ନିଷ୍କ୍ରିୟ କରିଥାଏ!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr "ତନ୍ତ୍ର ଧାରାରେ ଚାଲୁଅଛି, ପ୍ରସ୍ଥାନ ସ୍ଥିର ସମୟକୁ ବାଧ୍ଯତାମୁଳକ ଭାବରେ ନିଷ୍କ୍ରିୟ କରିଥାଏ!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "stdio କୁ ଅଧିକାର କରିବାରେ ବିଫଳ।"
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "ପାଇପ ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "ଡେମନ ଆରମ୍ଭ ବିଫଳ ହୋଇଛି।"
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "ଡେମନ ଆରମ୍ଭ ସଫଳ ହୋଇଛି।"
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() ବିଫଳ ହୋଇଛି: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "ଏହା ହେଉଛି PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "ସଂକଳନ ଆଧାର: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "ସଂକଳନ CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "ଆଧାରରେ ଚାଲୁଅଛି: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "%u CPUs ମିଳିଛି।"
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "ପୃଷ୍ଠା ଆକାରଟି ହେଉଛି %lu ବାଇଟ"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Valgrind ସମର୍ଥନ ସହିତ ସଂକଳନ ହୋଇଛି: yes"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Valgrind ସମର୍ଥନ ସହିତ ସଂକଳନ ହୋଇଛି: no"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "valgrind ଧାରାରେ ଚାଲୁଅଛି: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "ଆଧାରରେ ଚାଲୁଅଛି: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "ଉପଯୁକ୍ତ ନିର୍ମାଣ: yes"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "ଉପଯୁକ୍ତ ନିର୍ମାଣ: no"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG କୁ ବ୍ୟାଖ୍ୟା କରାଯାଇଛି, ସମସ୍ତ ନିଶ୍ଚୟକୁ ନିଷ୍କ୍ରିୟ କରାଯାଇଛି।"
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH କୁ ବ୍ୟାଖ୍ୟା କରାଯାଇଛି, କେବଳ ତୀବ୍ର ପଥ ନିଶ୍ଚୟକୁ ନିଷ୍କ୍ରିୟ କରାଯାଇଛି।"
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "ସମସ୍ତ ନିଶ୍ଚୟକୁ ସକ୍ରିୟ କରାଯାଇଛି।"
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "ଯନ୍ତ୍ର ID ପାଇବାରେ ବିଫଳ"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "ଯନ୍ତ୍ର ID ଟି ହେଉଛି %s।"
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "ଅଧିବେଶନ ID ଟି ହେଉଛି %s।"
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "ପ୍ରଚଳିତ ଡିରେକ୍ଟୋରୀ %s କୁ ବ୍ୟବହାର କରୁଅଛି।"
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "ସ୍ଥିତି ଡିରେକ୍ଟୋରୀ %s କୁ ବ୍ୟବହାର କରି।"
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "ଏକକାଂଶ ଡିରେକ୍ଟୋରୀ %s କୁ ବ୍ୟବହାର କରି।"
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "ତନ୍ତ୍ର ଧାରାରେ ଚାଲୁଅଛି: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -385,15 +425,15 @@ msgstr ""
 "ତନ୍ତ୍ର ଧାରାଟି ସାଧାରଣତଃ କାହିଁକି ଖରାପ ତାହା ବିଷୟରେ ଜାଣିବା ପାଇଁ ଦୟାକରି http://pulseaudio."
 "org/wiki/WhatIsWrongWithSystemMode କୁ ପଢ଼ନ୍ତୁ।"
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() ବିଫଳ ହୋଇଛି।"
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "ସତେଜ ଉଚ୍ଚ-ବିଭେଦନ ସମୟ ମାପକ ଉପଲବ୍ଧ! Bon appetit!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -401,32 +441,32 @@ msgstr ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() ବିଫଳ ହୋଇଛି।"
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "ଡେମନକୁ ଆରମ୍ଭ କରିବାରେ ବିଫଳ।"
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "ଧାରଣ ହୋଇଥିବା ଏକକାଂଶଗୁଡ଼ିକ ବିନା ଡେମନ ଆରମ୍ଭ ହୋଇଛି, କାର୍ଯ୍ୟ କରିବାକୁ ବାରଣ କରୁଅଛି।"
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "ଡେମନ ଆରମ୍ଭ ସମ୍ପୂର୍ଣ୍ଣ ହୋଇଛି।"
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "ଡେମନ ବନ୍ଦକୁ ଆରମ୍ଭ କରାଯାଇଛି।"
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "ଡେମନକୁ ସମାପ୍ତ କରାଯାଇଛି।"
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -463,15 +503,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -567,15 +605,15 @@ msgstr ""
 "\n"
 "  -n                                    Don't load default script file\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize ବୁଲିଆନ ସ୍ୱତନ୍ତ୍ରଚର ଆଶା କରୁଅଛି"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail ବୁଲିଆନ ସ୍ୱତନ୍ତ୍ରଚର ଆଶା କରୁଅଛି"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -583,166 +621,169 @@ msgstr ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority ବୁଲିଆନ ସ୍ୱତନ୍ତ୍ରଚର ଆଶା କରୁଅଛି"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime ବୁଲିଆନ ସ୍ୱତନ୍ତ୍ରଚର ଆଶା କରୁଅଛି"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading ବୁଲିଆନ ସ୍ୱତନ୍ତ୍ରଚର ଆଶା କରୁଅଛି"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit ବୁଲିଆନ ସ୍ୱତନ୍ତ୍ରଚର ଆଶା କରୁଅଛି"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file ବୁଲିଆନ ସ୍ୱତନ୍ତ୍ରଚର ଆଶା କରୁଅଛି"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr "ଅବୈଧ ଲଗ ଲକ୍ଷ୍ଯସ୍ଥଳ: 'syslog', 'stderr' କିମ୍ବା 'auto' କୁ ବ୍ୟବହାର କରନ୍ତୁ।"
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time ବୁଲିଆନ ସ୍ୱତନ୍ତ୍ରଚର ଆଶା କରୁଅଛି"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta ବୁଲିଆନ ସ୍ୱତନ୍ତ୍ରଚର ଆଶା କରୁଅଛି"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "ଅବୈଧ ପୁନଃ ପ୍ରତିଦର୍ଶନ ଧାରା '%s'।"
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system ବୁଲିଆନ ସ୍ୱତନ୍ତ୍ରଚର ଆଶା କରୁଅଛି"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit ବୁଲିଆନ ସ୍ୱତନ୍ତ୍ରଚର ଆଶା କରୁଅଛି"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm ବୁଲିଆନ ସ୍ୱତନ୍ତ୍ରଚର ଆଶା କରୁଅଛି"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "ନାମ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "କୌଣସି ଏକକାଂଶ ସୂଚନା ଉପଲବ୍ଧ ନାହିଁ\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "ସଂସ୍କରଣ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "ବର୍ଣ୍ଣନା: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "ଲେଖକ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "ବ୍ୟବହାର ବିଧି: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "ଥରେ ଧାରଣ କରନ୍ତୁ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "DEPRECATION WARNING: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "ପଥ: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] ଅବୈଧ ଲଗ ଲକ୍ଷ୍ଯସ୍ଥଳ '%s'।"
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] ଅବୈଧ ଲଗ ସ୍ତର%s'."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] ଅବୈଧ ପୁନଃ ମିଶ୍ରଣ ଧାରା '%s'।"
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] ଅବୈଧ rlimit '%s'."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit ଏହି ପ୍ଲାଟଫର୍ମରେ ସମର୍ଥିତ ନୁହଁ।"
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] ଅବୈଧ ନମୁନା ଶୈଳୀ '%s'।"
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] ଅବୈଧ ନମୁନା ହାର '%s'।"
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] ଅବୈଧ ନମୁନା ଚ୍ୟାନେଲ '%s'।"
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] ଅବୈଧ ଚ୍ୟାନେଲ ମ୍ୟାପ '%s'."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] ଅବୈଧ ସଂଖ୍ୟକ ଖଣ୍ଡଗୁଡ଼ିକ '%s'."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] ଅବୈଧ ଖଣ୍ଡ ଆକାର '%s'."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] ଅବୈଧ ସୁନ୍ଦର ସ୍ତର '%s'."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] ଅବୈଧ ନମୁନା ହାର '%s'।"
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "ବିନ୍ୟାସ ଫାଇଲ ଖୋଲିବାରେ ବିଫଳ: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -750,12 +791,12 @@ msgstr ""
 "ନିର୍ଦ୍ଦିଷ୍ଟିତ ପୂର୍ବନିର୍ଦ୍ଧାରିତ ଚ୍ୟାନେଲ ମ୍ୟାପରେ ପୂର୍ବନିର୍ଦ୍ଧାରିତ ସଂଖ୍ୟକ ଚ୍ୟାନେଲ ବ୍ୟତିତ ଭିନ୍ନ ସଂଖ୍ୟକ "
 "ଚ୍ୟାନେଲ ଉଲ୍ଲେଖ ଅଛି।"
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### ବିନ୍ୟାସ ଫାଇଲରୁ ପଢ଼ନ୍ତୁ: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "ଅଧିକାରଗୁଡ଼ିକୁ ବାତିଲ କରୁଅଛି।"
 
@@ -767,6 +808,16 @@ msgstr "PulseAudio ଧ୍ୱନି ତନ୍ତ୍ର"
 msgid "Start the PulseAudio Sound System"
 msgstr "PulseAudio ଧ୍ୱନି ତନ୍ତ୍ରକୁ ଆରମ୍ଭ କରନ୍ତୁ"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio ଧ୍ୱନି ତନ୍ତ୍ର"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "PulseAudio ଧ୍ୱନି ତନ୍ତ୍ରକୁ ଆରମ୍ଭ କରନ୍ତୁ"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "ମୋନୋ"
@@ -796,8 +847,8 @@ msgid "Rear Right"
 msgstr "ପଛ ଡ଼ାହାଣ ପାଖ"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "ନିମ୍ନ ଆବୃତ୍ତି ପରିତ୍ୟାଗ କାରୀ"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -971,9 +1022,10 @@ msgstr "ଉପର ପଛ ବାମ ପାଖ"
 msgid "Top Rear Right"
 msgstr "ଉପର ପଛ ଡ଼ାହାଣ ପାଖ"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(ଅବୈଧ)"
 
@@ -1001,332 +1053,349 @@ msgstr "ଚତୁଃ ପାର୍ଶ୍ୱ 5.1"
 msgid "Surround 7.1"
 msgstr "ଚତୁଃ ପାର୍ଶ୍ୱ 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "OK"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "ଅଭିଗମ୍ୟତା ବାରଣ ହୋଇଛି"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "ଅଜଣା ନିର୍ଦ୍ଦେଶ"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "ଅବୈଧ ସ୍ୱତନ୍ତ୍ରଚର"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "ବସ୍ତୁ ଅବସ୍ଥିତ"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "ଏପରି କୌଣସି ବସ୍ତୁ ନାହିଁ"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "ସଂଯୋଗ ବାରଣ ହୋଇଛି"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "ପ୍ରୋଟୋକଲ ତ୍ରୁଟି"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "ସମୟ ସମାପ୍ତ"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "କୌଣସି ପ୍ରାଧିକରଣ କି ନାହିଁ"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "ଆଭ୍ୟନ୍ତରୀଣ ତ୍ରୁଟି"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "ସଂଯୋଗ ବନ୍ଦ ହୋଇଯାଇଛି"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "ବସ୍ତୁକୁ ବନ୍ଦକରାଯାଇଛି"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "ଅବୈଧ ସର୍ଭର"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "ଏକକାଂଶ ପ୍ରାରମ୍ଭିକରଣ ବିଫଳ ହୋଇଛି"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "ଖରାପ ସ୍ଥିତି"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "କୌଣସି ତଥ୍ୟ ନାହିଁ"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "ଅସଙ୍ଗତ ପ୍ରୋଟୋକଲ ସଂସ୍କରଣ"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "ଅତ୍ୟଧିକ ବଡ଼"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "ସମର୍ଥିତ ନୁହଁ"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "ଅଜଣା ତ୍ରୁଟି ସଂକେତ"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "ଏପରି କୌଣସି ଅନୁଲଗ୍ନ ନାହିଁ"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "ଅଚଳ କାର୍ଯ୍ୟକାରିତା"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "ଅନୁପସ୍ଥିତ ପ୍ରୟୋଗ"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "ଗ୍ରାହକ ଶାଖାଯୁକ୍ତ ହୋଇଛି"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "ନିବେଶ/ଫଳାଫଳ ତ୍ରୁଟି"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "ଉପକରଣ ଅଥବା ଉତ୍ସ ବ୍ୟସ୍ତ ଅଛି"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() ବିଫଳ ହୋଇଛି"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() ବିଫଳ ହୋଇଛି: %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "କୁକି ତଥ୍ୟକୁ ବିଶ୍ଳେଷଣ କରିବାରେ ବିଫଳ"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "ବିନ୍ୟାସ ଫାଇଲ '%s' କୁ ଖୋଲିବାରେ ବିଫଳ: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "କୌଣସି କୁକି ଧାରଣ କରାଯାଇନାହିଁ। ତାହା ବିନା ସଂଯୋଗ କରିବାକୁ ପ୍ରଚେଷ୍ଚା କରୁଅଛି।"
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "ଅଜଣା ଅନୁଲଗ୍ନ '%s' ପାଇଁ ସନ୍ଦେଶ ଗ୍ରହଣ କରିଅଛି"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "ଧାରାକୁ ବାହାର କରିବାରେ ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "ପଛଚଲା ଧାରାକୁ ବାହାର କରାଯାଇଛି।"
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "ସର୍ଭର ପ୍ରତି ଡ୍ରେନିଙ୍ଗ ସଂଯୋଗ।"
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_begin_write() ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "ଧାରା ସଫଳତାର ସହିତ ନିର୍ମାଣ ହୋଇଛି।"
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, 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:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "ବଫର ମେଟ୍ରିକସ: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "ନମୁନା spec '%s' ବ୍ୟବହାର କରି, ଚ୍ୟାନେଲ ମ୍ୟାପ '%s'।"
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "ଉପକରଣ %s ସହିତ ସଂଯୁକ୍ତ ହୋଇଛି (%u, %ssuspended)।"
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "ଧାରା ତ୍ରୁଟି: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "ଧାରା ଉପକରଣ ନିଲମ୍ବିତ ହୋଇଛି।%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "ଧାରା ଉପକରଣ ପୁନଃ ଚଳନ ହୋଇଛି।%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "ଧାରା underrun.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "ଧାରା overrun.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "ଧାରା ଆରମ୍ଭ ହୋଇଛି।%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "ଧାରା ଉପକରଣ %sକୁ ଗତି କରିଛି (%u, %ssuspended).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "not "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "ଧାରା ବଫର ଗୁଣଗୁଡ଼ିକ ପରିବର୍ତ୍ତନ ହୋଇଛି।%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "ସଂଯୋଗ ସ୍ଥାପିତ ହୋଇଛି।%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "ସଂଯୋଗ ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "EOF ପାଇଅଛି।"
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "ସଂକେତ ପାଇଲା, ପ୍ରସ୍ଥାନ କରୁଅଛି।"
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "ବିଳମ୍ବତା ପାଇବାରେ ବିଫଳ: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "ସମୟ: %0.3f ସେକଣ୍ଡ; ବିଳମ୍ବତା: %0.0f usec."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1378,10 +1447,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [ବିକଳ୍ପଗୁଡ଼ିକ]\n"
@@ -1434,7 +1508,7 @@ msgstr ""
 "      --file-format=FFORMAT             ସଜ୍ଜିକୃତ PCM ତଥ୍ୟକୁ ଲିପିବଦ୍ଧ କରନ୍ତୁ/ଚଲାନ୍ତୁ।\n"
 "      --list-file-formats               ତାଲିକା ଉପଲବ୍ଧ ଫାଇଲ ସଜ୍ଜିକରଣ ଶୈଳୀ।\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1445,169 +1519,174 @@ msgstr ""
 "libpulse %s ସହିତ ସଂକଳିତ\n"
 "libpulse %s ସହିତ ସଂଯୁକ୍ତ\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "ଅବୈଧ କ୍ଲାଏଣ୍ଟ ନାମ '%s'"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "ଅବୈଧ ଧାରା ନାମ '%s'"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "ଅବୈଧ ଚ୍ୟାନେଲ ମ୍ୟାପ '%s'"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "ଅବୈଧ ବିଳମ୍ବତା ବିଶେଷ ଲକ୍ଷଣ '%s'"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "ଅବୈଧ ପଦ୍ଧତି ସମୟ ବିଶେଷ ଲକ୍ଷଣ '%s'"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "ଅବୈଧ ଗୁଣଧର୍ମ '%s'"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "ଅଜଣା ଫାଇଲ ସଜ୍ଜିକରଣ ଶୈଳୀ %s।"
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "ଅବୈଧ ନମୁନା ବିଶେଷ ଲକ୍ଷଣ"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "ଅତ୍ୟଧିକ ସ୍ୱତନ୍ତ୍ରଚର।"
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "ଫାଇଲ ପାଇଁ ନମୁନା ସୂଚନା ସୃଷ୍ଟି କରିବାରେ ବିଫଳ।"
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "ଧ୍ୱନି ଫାଇଲ ଖୋଲିବାରେ ବିଫଳ।"
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
 msgstr "ଚେତାବନୀ: ଉଲ୍ଲିଖିତ ନମୁନା ବିଶେଷ ଲକ୍ଷଣକୁ ଫାଇଲରୁ ବିଶେଷ ଲକ୍ଷଣ ସହିତ ନବଲିଖନ କରାଯିବ।"
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "ଫାଇଲରୁ ନମୁନା ସୂଚନା ନିର୍ଦ୍ଧାରଣ କରିବାରେ ବିଫଳ।"
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "ଚେତାବନୀ: ଫାଇଲରୁ ଚ୍ୟାନେଲ ମ୍ୟାପ ନିର୍ଦ୍ଧାରଣ କରିବାରେ ବିଫଳ।"
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "ନମୁନା ବିଶେଷ ଲକ୍ଷଣ ସହିତ ଚ୍ୟାନେଲ ମ୍ୟାପ ମେଳ ଖାଉନାହିଁ"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "ଚେତାବନୀ: ଚ୍ୟାନେଲ ମ୍ୟାପକୁ ଫାଇଲରେ ଲେଖିବାରେ ବିଫଳ।"
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr "ନମୁନା ବିଶେଷ ଲକ୍ଷଣ '%s' ଏବଂ ଚ୍ୟାନେଲ ମ୍ୟାପ '%s' ସହିତ ଗୋଟିଏ %s ଧାରାକୁ ଖୋଲୁଅଛି।"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "ଅନୁଲିପି କରୁଅଛି"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "ପଛଚଲା"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "ପାଠ୍ୟ ନିର୍ଦ୍ଦେଶକୁ ବିଶ୍ଳେଷଣ କରିବାରେ ବିଫଳ।"
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() ବିଫଳ ହୋଇଛି।"
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() ବିଫଳ ହୋଇଛି।"
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() ବିଫଳ ହୋଇଛି।"
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() ବିଫଳ ହୋଇଛି: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_rttime_new() ବିଫଳ ହୋଇଛି।"
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() ବିଫଳ ହୋଇଛି।"
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "ନିଲମ୍ବନ କରିବାରେ ବିଫଳ: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "ପୁନଃ ଚଳନ କରିବାରେ ବିଫଳ: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "WARNING: ଧ୍ୱନି ସର୍ଭରଟି ସ୍ଥାନୀୟ ନୁହଁ, ନିଲମ୍ବିତ କରୁନାହିଁ।\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "ସଂଯୋଗ ବିଫଳ ହୋଇଛି: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "SIGINT ପାଇଛି, ଉତ୍ସାହିତ କରୁଅଛି।\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "WARNING: ନିମ୍ନ ସ୍ତରର ପ୍ରକ୍ରିୟାଟି ସଂକେତ %u ଦ୍ୱାରା ସମାପ୍ତ\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1651,35 +1730,46 @@ msgstr "pa_context_new() ବିଫଳ ହୋଇଛି।\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() ବିଫଳ ହୋଇଛି।\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "ପରିସଂଖ୍ୟାନ ପାଇବାରେ ବିଫଳ: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "ବର୍ତ୍ତମାନ ବ୍ୟବହାରରେ ଅଛି: %u ବ୍ଲକ ସମୁଦାୟ %s ବାଇଟ ଧାରଣ କରିଥାଏ।\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "ସମଗ୍ର ଜୀବନରେ ବଣ୍ଟିତ ହୋଇଥାଏ: %u ବ୍ଲକ ସମୁଦାୟ %s ବାଇଟ ଧାରଣ କରିଥାଏ।\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "ନମୁନା କ୍ୟାଶେ ଆକାର: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "ସର୍ଭର ସୂଚନା ପାଇବାରେ ବିଫଳ: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1687,7 +1777,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "ଚାଳକ ନାମ: %s\n"
 "ଆଧାର ନାମ: %s\n"
@@ -1699,13 +1789,13 @@ msgstr ""
 "ପୂର୍ବନିର୍ଦ୍ଧାରିତ ଉତ୍ସ: %s\n"
 "କୁକି: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "ସିଙ୍କ ସୂଚନା ପାଇବାରେ ବିଫଳ: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1721,7 +1811,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1743,22 +1833,27 @@ msgstr ""
 "\tଗୁଣଧର୍ମ:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tସଂଯୋଗିକୀଗୁଡ଼ିକ:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tସକ୍ରିୟ ସଂଯୋଗିକୀ: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tସଂଯୋଗିକୀଗୁଡ଼ିକ:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "ଉତ୍ସ ସୂଚନା ପାଇବାରେ ବିଫଳ: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1797,20 +1892,20 @@ msgstr ""
 "\tଗୁଣଧର୍ମ:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "n/a"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "ଏକକାଂଶ ସୂଚନା ପାଇବାରେ ବିଫଳ: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1827,12 +1922,12 @@ msgstr ""
 "\tଗୁଣଧର୍ମ:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "ଗ୍ରାହକ ସୂଚନା ପାଇବାରେ ବିଫଳ: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1847,12 +1942,12 @@ msgstr ""
 "\tଗୁଣଧର୍ମ:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "କାର୍ଡ ସୂଚନା ପାଇବାରେ ବିଫଳ: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1869,23 +1964,23 @@ msgstr ""
 "\tଗୁଣଧର୍ମ:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tରୂପରେଖଗୁଡ଼ିକ:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tସକ୍ରିୟ ରୂପରେଖା: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "ସିଙ୍କ ନିବେଶ ସୂଚନା ପାଇବାରେ ବିଫଳ: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1894,6 +1989,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1921,13 +2017,13 @@ msgstr ""
 "\tଗୁଣଧର୍ମ:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "ଉତ୍ସ ଫଳାଫଳ ସୂଚନା ପାଇବାରେ ବିଫଳ: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1936,31 +2032,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"à¬\89ତà­\8dସ à¬¨à¬¿à¬°à­\8dà¬\97ମ #%u\n"
+"ସିà¬\99à­\8dà¬\95 à¬¨à¬¿à¬¬à­\87ଶ #%u\n"
 "\tଡ୍ରାଇଭର: %s\n"
 "\tମାଲିକ ଏକକାଂଶ: %s\n"
 "\tଗ୍ରାହକ: %s\n"
-"\tà¬\89ତà­\8dସ: %u\n"
+"\tସିà¬\99à­\8dà¬\95: %u\n"
 "\tନମୁନା ବିଶେଷ ଲକ୍ଷଣ: %s\n"
 "\tଚ୍ୟାନେଲ ମ୍ୟାପ: %s\n"
+"\tମୁକ: %s\n"
+"\tଭଲ୍ୟୁମ: %s\n"
+"\t        %s\n"
+"\t        ସମତୁଲ %0.2f\n"
 "\tବଫର ବିଳମ୍ବତା: %0.0f usec\n"
-"\tà¬\89ତà­\8dସ ବିଳମ୍ବତା: %0.0f usec\n"
+"\tସିà¬\99à­\8dà¬\95 ବିଳମ୍ବତା: %0.0f usec\n"
 "\tପୁନଃ ମିଶ୍ରଣ ପଦ୍ଧତି: %s\n"
 "\tଗୁଣଧର୍ମ:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "ନମୁନା ସୂଚନା ପାଇବାରେ ବିଫଳ: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1991,48 +2096,163 @@ msgstr ""
 "\tଗୁଣଧର୍ମ:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "ବିଫଳତା: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "ଉତ୍ସ ସୂଚନା ପାଇବାରେ ବିଫଳ: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "ନମୁନାକୁ ଧାରଣ କରିବାରେ ବିଫଳ: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "ଫାଇଲର ସମୟ ପୂର୍ବ ସମାପ୍ତି"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "ଅବୈଧ ସର୍ଭର"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "SIGINT ପାଇଛି, ଉତ୍ସାହିତ କରୁଅଛି।"
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "ଅବୈଧ ନମୁନା ବିଶେଷ ଲକ୍ଷଣ"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2042,35 +2262,14 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] stat\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] list\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] exit\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] upload-sample FILENAME [NAME]\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] play-sample NAME [SINK]\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] remove-sample NAME\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] move-sink-input ID SINK\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] move-source-output ID SOURCE\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] load-module NAME [ARGS ...]\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] unload-module ID\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] suspend-sink [SINK] 1|0\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] suspend-source [SOURCE] 1|0\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-card-profile [CARD] [PROFILE] \n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-sink-port [SINK] [PORT] \n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-source-port [SOURCE] [PORT] \n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-sink-volume SINK VOLUME\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-source-volume SOURCE VOLUME\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-sink-mute SINK 1|0\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-source-mute SOURCE 1|0\n"
-"%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-sink-input-mute SINKINPUT 1|0\n"
+"%s [options] ... \n"
 "\n"
 "  -h, --help                            ଏହି ସହାୟତାକୁ ଦର୍ଶାନ୍ତୁ\n"
 "      --version                         ସଂସ୍କରଣ ଦର୍ଶାନ୍ତୁ\n"
-"\n"
 "  -s, --server=SERVER                   ସଂଯୋଗ କରିବା ପାଇଁ ସର୍ଭରର ନାମ\n"
-"  -n, --client-name=NAME                ସର୍ଭରରେ ଏହି କ୍ଲାଏଣ୍ଟକୁ କିପରି ଡାକିବେ\n"
+"\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2081,106 +2280,138 @@ msgstr ""
 "libpulse %s ସହିତ ସଂକଳିତ\n"
 "libpulse %s ସହିତ ସଂଯୁକ୍ତ\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "ଧାରଣ କରିବା ପାଇଁ ଗୋଟିଏ ନୁମନା ଫାଇଲ ଉଲ୍ଲେଖ କରନ୍ତୁ"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "ଧ୍ୱନି ଫାଇଲ ଖୋଲିବାରେ ବିଫଳ।"
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "ଚେତାବନୀ: ଫାଇଲରୁ ନମୁନା ବିଶେଷ ଲକ୍ଷଣକୁ ନିର୍ଦ୍ଧାରଣ କରିବାରେ ବିଫଳ।"
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "ଚଲାଇବା ପାଇଁ ଆପଣଙ୍କୁ ଗୋଟିଏ ନମୁନା ନାମ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "କାଢ଼ିବା ପାଇଁ ଆପଣଙ୍କୁ ଗୋଟିଏ ନମୁନା ନାମ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "ଆପଣଙ୍କୁ ଗୋଟିଏ ସିଙ୍କ ନିବେଶ ଅନୁକ୍ରମଣିକା ଏବଂ ଗୋଟିଏ ସିଙ୍କ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "ଆପଣଙ୍କୁ ଗୋଟିଏ ଉତ୍ସ ନିର୍ଗମ ଅନୁକ୍ରମଣିକା ଏବଂ ଗୋଟିଏ ଉତ୍ସ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "ଆପଣଙ୍କୁ ଗୋଟିଏ ଏକକାଂଶ ନାମ ଏବଂ ସ୍ୱତନ୍ତ୍ରଚରଗୁଡ଼ିକୁ ଉଲ୍ଲେଖ କରିବା ଉଚିତ।"
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "ଆପଣଙ୍କୁ ଗୋଟିଏ ଏକକାଂଶ ଅନୁକ୍ରମଣିକାକୁ ଉଲ୍ଲେଖ କରିବା ଉଚିତ ନୁହଁ"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "ଆପଣଙ୍କୁ ଗୋଟିଏରୁ ଅଧିକ ସିଙ୍କ ଉଲ୍ଲେଖ କରିବାକୁ ପଡ଼ିନପାରେ। ଆପଣଙ୍କୁ ଗୋଟିଏ ବୁଲିଆନ ମୂଲ୍ୟ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ।"
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr ""
 "ଆପଣଙ୍କୁ ଗୋଟିଏରୁ ଅଧିକ ଉତ୍ସ ଉଲ୍ଲେଖ କରିବାକୁ ପଡ଼ିନପାରେ। ଆପଣଙ୍କୁ ଗୋଟିଏ ବୁଲିଆନ ମୂଲ୍ୟ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ।"
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "ଆପଣଙ୍କୁ ଗୋଟିଏ କାର୍ଡ ନାମ/ଅନୁକ୍ରମଣିକା ଏବଂ ରୂପରେଖା ନାମ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "ଆପଣଙ୍କୁ ଗୋଟିଏ ସିଙ୍କ ନାମ/ଅନୁକ୍ରମଣିକା ଏବଂ ସଂଯୋଗିକୀ ନାମ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "ଆପଣଙ୍କୁ ଗୋଟିଏ ଉତ୍ସ ନାମ/ଅନୁକ୍ରମଣିକା ଏବଂ ସଂଯୋଗିକୀ ନାମ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "ଆପଣଙ୍କୁ ଗୋଟିଏ ସିଙ୍କ ନାମ/ଅନୁକ୍ରମଣିକା ଏବଂ ସଂଯୋଗିକୀ ନାମ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "ଅବୈଧ ନମୁନା ବିଶେଷ ଲକ୍ଷଣ"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "ଆପଣଙ୍କୁ ଗୋଟିଏ ଉତ୍ସ ନାମ/ଅନୁକ୍ରମଣିକା ଏବଂ ସଂଯୋଗିକୀ ନାମ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "ଆପଣଙ୍କୁ ଗୋଟିଏ ସିଙ୍କ ନିବେଶ ଅନୁକ୍ରମଣିକା ଏବଂ ଗୋଟିଏ ସିଙ୍କ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "ଅବୈଧ ସିଙ୍କ ନିବେଶ ଅନୁକ୍ରମଣିକା"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "ଆପଣଙ୍କୁ ଗୋଟିଏ ଉତ୍ସ ନିର୍ଗମ ଅନୁକ୍ରମଣିକା ଏବଂ ଗୋଟିଏ ଉତ୍ସ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "ଅବୈଧ ସିଙ୍କ ନିବେଶ ଅନୁକ୍ରମଣିକା"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "ଆପଣଙ୍କୁ ଗୋଟିଏ ସିଙ୍କ ନାମ/ଅନୁକ୍ରମଣିକା ଏବଂ ସଂଯୋଗିକୀ ନାମ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "ଅବୈଧ ନମୁନା ବିଶେଷ ଲକ୍ଷଣ"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "ଆପଣଙ୍କୁ ଗୋଟିଏ ଉତ୍ସ ନାମ/ଅନୁକ୍ରମଣିକା ଏବଂ ସଂଯୋଗିକୀ ନାମ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "ଆପଣଙ୍କୁ ଗୋଟିଏ ସିଙ୍କ ନିବେଶ ଅନୁକ୍ରମଣିକା ଏବଂ ଗୋଟିଏ ସିଙ୍କ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "ଅବୈଧ ସିଙ୍କ ନିବେଶ ଅନୁକ୍ରମଣିକା ବିଶେଷ ଲକ୍ଷଣ"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "ଆପଣଙ୍କୁ ଗୋଟିଏ ଉତ୍ସ ନାମ/ଅନୁକ୍ରମଣିକା ଏବଂ ସଂଯୋଗିକୀ ନାମ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "ଅବୈଧ ସିଙ୍କ ନିବେଶ ଅନୁକ୍ରମଣିକା ବିଶେଷ ଲକ୍ଷଣ"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "ଆପଣଙ୍କୁ ଗୋଟିଏ ସିଙ୍କ ନାମ/ଅନୁକ୍ରମଣିକା ଏବଂ ସଂଯୋଗିକୀ ନାମ ଉଲ୍ଲେଖ କରିବାକୁ ହେବ"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "କୌଣସି ବୈଧ ନିର୍ଦ୍ଦେଶ ଉଲ୍ଲେଖ କରାଯାଇନାହିଁ।"
 
@@ -2207,103 +2438,103 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "ପାଠ୍ୟ ନିର୍ଦ୍ଦେଶକୁ ବିଶ୍ଳେଷଣ କରିବାରେ ବିଫଳ।\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "ସର୍ଭର: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "ଉତ୍ସ: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "ସିଙ୍କ: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "କୁକି: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "କୁକି ତଥ୍ୟକୁ ବିଶ୍ଳେଷଣ କରିବାରେ ବିଫଳ\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "କୁକି ତଥ୍ୟକୁ ସଂରକ୍ଷଣ କରିବାରେ ବିଫଳ\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "ଗ୍ରାହକ ବିନ୍ୟାସ ଫାଇଲକୁ ଧାରଣ କରିବାରେ ବିଫଳ।\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "ପରିବେଶ ବିନ୍ୟାସ ତଥ୍ୟକୁ ପଢ଼ିବାରେ ବିଫଳ।\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "FQDNକୁ ପାଇବାରେ ବିଫଳ।\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "କୁକି ତଥ୍ୟ ଧାରଣ କରିବାରେ ବିଫଳ\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "ଅପର୍ଯ୍ୟନ୍ତ କାର୍ଯ୍ୟକାରୀ ହୋଇନାହିଁ।\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr "କୌଣସି PulseAudio ଡେମନ ଚାଲୁନାହିଁ, କିମ୍ବା ଅଧିବେଶନ ଡେମନ ପରି ଚାଲୁନାହିଁ।"
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "ସକେଟ(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "ସଂଯୋଗ କରନ୍ତୁ(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "PulseAudio ଡେମନକୁ ବନ୍ଦ କରିବାରେ ବିଫଳ।"
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "ଡେମନ ଉତ୍ତର ଦେଉନାହିଁ।"
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "ପଢ଼ନ୍ତୁ(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "ଲେଖନ୍ତୁ(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "autospawn ଅପରିବର୍ତ୍ତନୀୟତାକୁ ଅଭିଗମ୍ୟ କରିହେଉ ନାହିଁ"
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2320,7 +2551,7 @@ msgstr ""
 "We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() "
 "returned 0 or another value < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2337,242 +2568,462 @@ msgstr ""
 "We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() "
 "returned 0 or another value < min_avail."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "ଅଫ"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "ଉଚ୍ଚ ଫିଡିଲିଟି ପଛଚଲା (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "ଉଚ୍ଚ ଫିଡିଲିଟି ପଛଚଲା (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "ଟେଲିଫୋନି ଡ୍ୟୁପ୍ଲେକ୍ସ (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "PulseAudio ଧ୍ୱନି ସର୍ଭର"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
-msgstr ""
+msgstr "ଫଳାଫଳ ଉପକରଣ"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
-msgstr ""
+msgstr "ନିବେଶ ଉପକରଣ"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
-msgstr ""
+msgstr "@HOSTNAME@ ରେ ଧ୍ୱନି"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
-msgstr ""
+msgstr "ନିବେଶ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
-msgstr ""
+msgstr "ଡକିଙ୍ଗ ଷ୍ଟେସନ ନିବେଶ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
-msgstr ""
+msgstr "ଡକିଙ୍ଗ ଷ୍ଟେସନ ମାଇକ୍ରୋଫୋନ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "ଡକିଙ୍ଗ ଷ୍ଟେସନ ନିବେଶ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "ଲାଇନ-ଇନ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
-msgstr ""
+msgstr "ମାଇକ୍ରୋଫୋନ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
-msgid "External Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "ଡକିଙ୍ଗ ଷ୍ଟେସନ ମାଇକ୍ରୋଫୋନ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
 #, fuzzy
+msgid "Rear Microphone"
+msgstr "ମାଇକ୍ରୋଫୋନ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "ବାହ୍ୟ ମାଇକ୍ରୋଫୋନ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
-msgstr "à¬\86ଭà­\8dà­\9fନà­\8dତରà­\80ଣ à¬§à­\8dୱନି"
+msgstr "à¬\86ଭà­\8dà­\9fନà­\8dତରà­\80ଣ à¬®à¬¾à¬\87à¬\95à­\8dରà­\8bଫà­\8bନ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
-msgstr ""
+msgstr "ରେଡିଓ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
-msgstr ""
+msgstr "ଭିଡ଼ିଓ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
-msgstr ""
+msgstr "ସ୍ୱୟଂଚାଳିତ ଲାଭ ନିୟନ୍ତ୍ରଣ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
-msgstr ""
+msgstr "କୌଣସି ସ୍ୱୟଂଚାଳିତ ଲାଭ ନିୟନ୍ତ୍ରଣ ନାହିଁ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
-msgstr ""
+msgstr "ବୃଦ୍ଧି"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
-msgstr ""
+msgstr "ବୃଦ୍ଧି ନାହିଁ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
-msgstr ""
+msgstr "ଏମ୍ପ୍ଲିଫାୟର"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
-msgstr ""
+msgstr "ଏମ୍ପ୍ଲିଫାୟର ନାହିଁ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "ବୃଦ୍ଧି"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "ବୃଦ୍ଧି ନାହିଁ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "ଏନାଲୋଗ ହେଡ଼ଫୋନଗୁଡ଼ିକ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "ଏନାଲୋଗ ନିବେଶ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "ଡକିଙ୍ଗ ଷ୍ଟେସନ ମାଇକ୍ରୋଫୋନ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
-msgstr "ଶà­\82ନà­\8dà­\9f ଫଳାଫଳ"
+msgstr "à¬\8fନାଲà­\8bà¬\97 ଫଳାଫଳ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "ଏନାଲୋଗ ଫଳାଫଳ (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "ଲାଇନ-ଇନ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
+msgstr "ଏନାଲୋଗ ମୋନୋ ଫଳାଫଳ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "ଏନାଲୋଗ ଷ୍ଟେରିଓ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, fuzzy, c-format
-msgid "%s+%s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "ଡିଜିଟାଲ ଷ୍ଟେରିଓ (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, fuzzy, c-format
-msgid "%s / %s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "ଡିଜିଟାଲ ଷ୍ଟେରିଓ (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
-msgstr ""
+msgstr "ଏନାଲୋଗ ମୋନୋ"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
-msgstr "ଷ୍ଟେରିଓ"
+msgstr "à¬\8fନାଲà­\8bà¬\97 à¬·à­\8dà¬\9fà­\87ରିà¬\93"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
-msgstr "à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 4.1"
+msgstr "à¬\8fନାଲà­\8bà¬\97 à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
-msgstr "à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 4.0"
+msgstr "à¬\8fନାଲà­\8bà¬\97 à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
-msgstr "à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 4.1"
+msgstr "à¬\8fନାଲà­\8bà¬\97 à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
-msgstr "ଚତୁଃ ପାର୍ଶ୍ୱ 4.0"
+msgstr "à¬\8fନାଲà­\8bà¬\97 à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
-msgstr "ଚତୁଃ ପାର୍ଶ୍ୱ 4.1"
+msgstr "à¬\8fନାଲà­\8bà¬\97 à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
-msgstr "ଚତୁଃ ପାର୍ଶ୍ୱ 5.0"
+msgstr "à¬\8fନାଲà­\8bà¬\97 à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
-msgstr "ଚତୁଃ ପାର୍ଶ୍ୱ 5.1"
+msgstr "à¬\8fନାଲà­\8bà¬\97 à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
-msgstr "à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 4.0"
+msgstr "à¬\8fନାଲà­\8bà¬\97 à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
-msgstr "à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 4.1"
+msgstr "à¬\8fନାଲà­\8bà¬\97 à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
-msgstr "à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 4.0"
+msgstr "à¬\8fନାଲà­\8bà¬\97 à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
-msgstr "ଚତୁଃ ପାର୍ଶ୍ୱ 7.1"
+msgstr "à¬\8fନାଲà­\8bà¬\97 à¬\9aତà­\81à¬\83 à¬ªà¬¾à¬°à­\8dଶà­\8dà­± 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
-msgstr ""
+msgstr "ଡିଜିଟାଲ ଷ୍ଟେରିଓ (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "ଡିଜିଟାଲ ଷ୍ଟେରିଓ (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
-msgstr ""
+msgstr "ଡିଜିଟାଲ ଚତୁଃ ପାର୍ଶ୍ୱ 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
-msgstr ""
+msgstr "ଡିଜିଟାଲ ଚତୁଃ ପାର୍ଶ୍ୱ 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
-msgstr ""
+msgstr "ଡିଜିଟାଲ ଷ୍ଟେରିଓ (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "ଡିଜିଟାଲ ଚତୁଃ ପାର୍ଶ୍ୱ 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
-msgstr ""
+msgstr "ଏନାଲୋଗ ମୋନୋ ଡ଼ୁପ୍ଲେକ୍ସ"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
-msgstr ""
+msgstr "ଏନାଲୋଗ ଷ୍ଟେରିଓ ଡ଼ୁପ୍ଲେକ୍ସ"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
+msgstr "ଡିଜିଟାଲ ଷ୍ଟେରିଓ ଡ଼ୁପ୍ଲେକ୍ସ (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "ଶୂନ୍ୟ ଫଳାଫଳ"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "ନିବେଶ"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<ସିଙ୍କର ନାମ> sink_properties=<ସିଙ୍କର ଗୁଣଧର୍ମ> master=<ସିଙ୍କ ଛାଣକର ନାମ> "
+"format=<ନମୁନା ସଜ୍ଜିକରଣ ଶୈଳୀ> rate=<ନମୁନା ହାର> channels=<ଚ୍ୟାନେଲ ସଂଖ୍ୟା> "
+"channel_map=<ଚ୍ୟାନେଲ ମ୍ୟାପ> plugin=<ladspa ପ୍ଲଗଇନ ନାମ> label=<ladspa ପ୍ଲଗଇନ "
+"ନାମପଟି> control=<କମା ଦ୍ୱାରା ପୃଥକ ନିବେଶ ନିୟନ୍ତ୍ରଣ ମୂଲ୍ୟ ତାଲିକା>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
 msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit ଏହି ପ୍ଲାଟଫର୍ମରେ ସମର୍ଥିତ ନୁହଁ।"
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() ବିଫଳ ହୋଇଛି"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "ଉତ୍ସ ନିର୍ଗମ #%u\n"
+#~ "\tଡ୍ରାଇଭର: %s\n"
+#~ "\tମାଲିକ ଏକକାଂଶ: %s\n"
+#~ "\tଗ୍ରାହକ: %s\n"
+#~ "\tଉତ୍ସ: %u\n"
+#~ "\tନମୁନା ବିଶେଷ ଲକ୍ଷଣ: %s\n"
+#~ "\tଚ୍ୟାନେଲ ମ୍ୟାପ: %s\n"
+#~ "\tବଫର ବିଳମ୍ବତା: %0.0f usec\n"
+#~ "\tଉତ୍ସ ବିଳମ୍ବତା: %0.0f usec\n"
+#~ "\tପୁନଃ ମିଶ୍ରଣ ପଦ୍ଧତି: %s\n"
+#~ "\tଗୁଣଧର୍ମ:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] stat\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] list\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] exit\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] upload-sample FILENAME [NAME]\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] play-sample NAME [SINK]\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] remove-sample NAME\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] move-sink-input ID SINK\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] move-source-output ID SOURCE\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] load-module NAME [ARGS ...]\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] unload-module ID\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] suspend-sink [SINK] 1|0\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] suspend-source [SOURCE] 1|0\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-card-profile [CARD] [PROFILE] \n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-sink-port [SINK] [PORT] \n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-source-port [SOURCE] [PORT] \n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-sink-volume SINK VOLUME\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-source-volume SOURCE VOLUME\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-sink-mute SINK 1|0\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-source-mute SOURCE 1|0\n"
+#~ "%s [ବିକଳ୍ପଗୁଡ଼ିକ] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            ଏହି ସହାୟତାକୁ ଦର୍ଶାନ୍ତୁ\n"
+#~ "      --version                         ସଂସ୍କରଣ ଦର୍ଶାନ୍ତୁ\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   ସଂଯୋଗ କରିବା ପାଇଁ ସର୍ଭରର ନାମ\n"
+#~ "  -n, --client-name=NAME                ସର୍ଭରରେ ଏହି କ୍ଲାଏଣ୍ଟକୁ କିପରି ଡାକିବେ\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "ଡିଜିଟାଲ ଚତୁଃ ପାର୍ଶ୍ୱ 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "ନିମ୍ନ ଆବୃତ୍ତି ପରିତ୍ୟାଗ କାରୀ"
index 16c5abe..c630293 100644 (file)
--- a/po/pa.po
+++ b/po/pa.po
@@ -3,28 +3,25 @@
 # This file is distributed under the same license as the PACKAGE package.
 #
 # Amanpreet Singh Alam <aalam@users.sf.net>, 2008.
-# Jaswinder Singh <jsingh@redhat.com>, 2009.
 # A S Alam <aalam@users.sf.net>, 2009.
+# Jaswinder Singh <jsingh@redhat.com>, 2009, 2012.
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx.pa\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-09-11 12:08+0530\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:55+0000\n"
 "Last-Translator: Jaswinder Singh <jsingh@redhat.com>\n"
-"Language-Team: Punjabi <Punjabi-users@lists.sourceforge.net>\n"
+"Language-Team: Punjabi/Panjabi <kde-i18n-doc@kde.org>\n"
+"Language: \n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Generator: KBabel 1.11.4\n"
+"X-Generator: Lokalize 1.0\n"
 "Plural-Forms: nplurals=2; plural=(n != 1)\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -35,18 +32,29 @@ msgstr ""
 "snd_pcm_avail() ਤੋਂ ਇੱਕ ਮੁੱਲ ਮਿਲਿਆ ਹੈ, ਜੋ ਬਹੁਤ ਵੱਡਾ ਹੈ: %lu ਬਾਈਟ (%lu ms)।\n"
 "ਇਹ ALSA ਡਰਾਈਵਰ '%s' ਵਿਚਲਾ ਬੱਗ ਲੱਗਦਾ ਹੈ। ਇਸ ਮੁੱਦੇ ਦੀ ALSA ਡਿਵੈਲਪਰਾਂ ਨੂੰ ਰਿਪੋਰਟ ਦਿਓ ਜੀ।"
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
 "snd_pcm_delay() ਤੋਂ ਇੱਕ ਮੁੱਲ ਮਿਲਿਆ ਹੈ, ਜੋ ਬਹੁਤ ਵੱਡਾ ਹੈ: %li ਬਾਈਟ (%s%lu ms)।\n"
 "ਇਹ ALSA ਡਰਾਈਵਰ '%s' ਵਿਚਲਾ ਬੱਗ ਲੱਗਦਾ ਹੈ। ਇਸ ਮੁੱਦੇ ਦੀ ALSA ਡਿਵੈਲਪਰਾਂ ਨੂੰ ਰਿਪੋਰਟ ਦਿਓ ਜੀ।"
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() ਤੋਂ ਇੱਕ ਮੁੱਲ ਮਿਲਿਆ ਹੈ, ਜੋ ਬਹੁਤ ਵੱਡਾ ਹੈ: %lu ਬਾਈਟ (%lu ms)।\n"
+"ਇਹ ALSA ਡਰਾਈਵਰ '%s' ਵਿਚਲਾ ਬੱਗ ਲੱਗਦਾ ਹੈ। ਇਸ ਮੁੱਦੇ ਦੀ ALSA ਡਿਵੈਲਪਰਾਂ ਨੂੰ ਰਿਪੋਰਟ ਦਿਓ ਜੀ।"
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -57,300 +65,330 @@ msgstr ""
 "snd_pcm_mmap_begin() ਤੋਂ ਇੱਕ ਮੁੱਲ ਮਿਲਿਆ ਹੈ, ਜੋ ਬਹੁਤ ਵੱਡਾ ਹੈ: %lu ਬਾਈਟ (%lu ms)।\n"
 "ਇਹ ALSA ਡਰਾਈਵਰ '%s' ਵਿਚਲਾ ਬੱਗ ਲੱਗਦਾ ਹੈ। ਇਸ ਮੁੱਦੇ ਦੀ ALSA ਡਿਵੈਲਪਰਾਂ ਨੂੰ ਰਿਪੋਰਟ ਦਿਓ ਜੀ।"
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "ਹਮੇਸ਼ਾਂ ਘੱਟੋ-ਘੱਟ ਇੱਕ ਸਿੰਕ ਲੋਡ ਹੀ ਰੱਖੋ ਭਾਵੇਂ ਇਹ ਇੱਕ ਜ਼ੀਰੋ (null) ਹੇਵੋ"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "ਡੰਮੀ ਆਊਟਪੁੱਟ"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "ਵਰਚੁਅਲ LADSPA ਸਿੰਕ"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<name for the sink> sink_properties=<properties for the sink> "
 "master=<name of sink to filter> format=<sample format> rate=<sample rate> "
 "channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
+"plugin name> label=<ladspa plugin label> control=<comma separated list of "
 "input control values>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "ਕਲਾਕਡ NULL ਸਿੰਕ"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "ਜ਼ੀਰੋ (Null) ਆਉਟਪੁੱਟ"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "ਅੰਦਰੂਨੀ ਆਡੀਓ"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "ਮਾਡਮ"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "ਅਸਲੀ lt_dlopen ਲੋਡਰ ਲੱਭਣ ਵਿੱਚ ਫੇਲ੍ਹ ਹੋਇਆ।"
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "ਨਵਾਂ dl ਲੋਡਰ ਦੇਣ ਲਈ ਫੇਲ੍ਹ।"
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "ਬਾਈਂਡ-ਨਾਓ-ਲੋਡਰ ਜੋੜਨ ਵਿੱਚ ਫੇਲ੍ਹ ਹੋਇਆ।"
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "%s ਸਿਗਨਲ ਮਿਲਿਆ ਹੈ।"
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "ਬੰਦ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।"
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "'%s' ਯੂਜ਼ਰ ਲੱਭਣ ਵਿੱਚ ਫੇਲ੍ਹ ਹੋਇਆ ਹੈ।"
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "'%s' ਗਰੁੱਪ ਲੱਭਣ ਵਿੱਚ ਫੇਲ ਹੋਇਆ ਹੈ।"
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "ਯੂਜ਼ਰ '%s' (UID %lu) ਅਤੇ ਗਰੁੱਪ '%s' (GID %lu) ਲੱਭੇ ਹਨ।"
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "ਯੂਜ਼ੂ '%s' ਅਤੇ ਗਰੁੱਪ '%s' ਦਾ GID ਮੇਲ ਨਹੀਂ ਖਾਂਦੇ।"
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "ਯੂਜ਼ੂ '%s' ਦੀ ਘਰ ਡਾਇਰੈਕਟਰੀ '%s' ਨਹੀਂ, ਅਣਡਿੱਠਾ ਕਰ ਰਿਹਾ।"
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "'%s' ਬਣਾਉਣ ਵਿੱਚ ਫੇਲ੍ਹ: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "ਗਰੁੱਪ ਲਿਸਟ ਬਦਲਣ ਲਈ ਫੇਲ੍ਹ: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "GID ਬਦਲਣ ਲਈ ਫੇਲ੍ਹ: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "UID ਬਦਲਣ ਲਈ ਫੇਲ੍ਹ: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "ਰੂਟ ਅਧਿਕਾਰ ਸਫਲਤਾਪੂਰਕ ਹਟਾਏ ਗਏ।"
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "ਇਸ ਪਲੇਟਫਾਰਮ ਤੇ ਸਿਸਟਮ ਸੰਬੰਧੀ ਮੋਡ ਨੂੰ ਸਹਿਯੋਗ ਨਹੀਂ ਹੈ।"
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) ਫੇਲ੍ਹ ਹੋਇਆ: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "ਕਮਾਂਡ ਲਾਈਨ ਪਾਰਸ ਕਰਨ ਵਿੱਚ ਫੇਲ੍ਹ।"
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "ਡੈਮਨ ਚੱਲ ਨਹੀਂ ਰਿਹਾ"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "ਡੈਮਨ PID %u ਤੌਰ ਤੇ ਚੱਲ ਰਿਹਾ ਹੈ"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "ਡੈਮਨ ਖਤਮ ਕਰਨ ਵਿੱਚ ਫੇਲ੍ਹ: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
 msgstr "ਇਹ ਪਰੋਗਰਾਮ ਰੂਟ ਦੇ ਤੌਰ ਤੇ ਚਲਾਉਣ ਲਈ ਨਹੀਂ ਹੈ (ਜਦੋਂ ਤੱਕ --system ਦਿੱਤਾ ਨਹੀਂ ਜਾਂਦਾ)।"
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "ਰੂਟ ਅਧਿਕਾਰਾਂ ਦੀ ਲੋੜ ਹੈ।"
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start ਨੂੰ ਸਿਸਟਮ ਮੌਕਿਆਂ ਲਈ ਸਹਿਯੋਗ ਨਹੀਂ ਹੈ।"
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "ਸਿਸਟਮ ਮੋਡ ਵਿੱਚ ਚੱਲ ਰਿਹਾ ਹੈ, ਪਰ --disallow-exit ਸੈੱਟ ਨਹੀਂ ਕੀਤਾ!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr "ਸਿਸਟਮ ਮੋਡ ਵਿੱਚ ਚੱਲ ਰਿਹਾ ਹੈ, ਪਰ --disallow-module-loading ਸੈੱਟ ਨਹੀਂ ਕੀਤਾ!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "ਸਿਸਟਮ ਮੋਡ ਵਿੱਚ ਚੱਲ ਰਿਹਾ ਹੈ, ਜ਼ਬਰਦਸਤੀ SHM ਮੋਡ ਨੂੰ ਅਯੋਗ ਕਰ ਰਿਹਾ ਹੈ!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr "ਸਿਸਟਮ ਮੋਡ ਵਿੱਚ ਚੱਲ ਰਿਹਾ ਹੈ, ਜ਼ਬਰਦਸਤੀ idle ਟਾਈਲ ਬੰਦ ਨੂੰ ਅਯੋਗ ਕਰ ਰਿਹਾ ਹੈ!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "ਸਟੂਡੀਓ ਪ੍ਰਾਪਤ ਕਰਨ ਵਿੱਚ ਫੇਲ੍ਹ।"
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "pipe ਫੇਲ੍ਹ: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() ਫੇਲ੍ਹ ਹੈ: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() ਫੇਲ੍ਹ ਹੈ: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "ਡੈਮਨ ਸ਼ੁਰੂਆਤੀ ਫੇਲ੍ਹ ਹੋਈ।"
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "ਡੈਮਨ ਸ਼ੁਰੂਆਤੀ ਸਫ਼ਲ ਹੋਈ।"
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() ਫੇਲ੍ਹ ਹੈ: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "ਇਹ ਪਲਸਆਡੀਓ %s ਹੈ"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "ਕੰਪਾਈਲੇਸ਼ਨ ਹੋਸਟ: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "ਕੰਪਾਈਲੇਸ਼ਨ CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "ਹੋਸਟ ਤੇ ਚੱਲ ਰਿਹਾ ਹੈ: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "%u CPUs ਲੱਭੇ।"
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "ਪੇਜ਼ ਸਾਈਜ਼ %lu ਬਾਈਟ ਹੈ"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Valgrind ਸਹਿਯੋਗ ਨਾਲ ਕੰਪਾਈਲ: ਹਾਂ"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Valgrind ਸਹਿਯੋਗ ਨਾਲ ਕੰਪਾਈਲ: ਨਹੀਂ"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "Valgrind ਮੋਡ ਵਿੱਚ ਚੱਲ ਰਿਹਾ ਹੈ: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "ਹੋਸਟ ਤੇ ਚੱਲ ਰਿਹਾ ਹੈ: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "ਓਪਟੀਮਾਈਜ਼ਡ ਬਿਲਡ: ਹਾਂ"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "ਓਪਟੀਮਾਈਜ਼ਡ ਬਿਲਡ: ਨਹੀਂ"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG ਪਰਿਭਾਸ਼ਤ, ਸਭ asserts ਅਯੋਗ ਹਨ।"
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH ਪਰਿਭਾਸ਼ਤ, ਸਿਰਫ ਫਾਸਟ ਪਾਥ asserts ਅਯੋਗ ਹਨ।"
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "ਸਭ asserts ਯੋਗ ਕੀਤੇ ਹਨ।"
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "ਮਸ਼ੀਨ ID ਪ੍ਰਾਪਤ ਕਰਨ ਵਿੱਚ ਫੇਲ੍ਹ"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "ਮਸ਼ੀਨ ID %s ਹੈ।"
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "ਸ਼ੈਸ਼ਨ ID %s ਹੈ।"
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "ਰਨਟਾਈਮ ਡਾਇਰੈਕਟਰੀ %s ਦੀ ਵਰਤੋਂ।"
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "ਸਟੇਟ ਡਾਇਰੈਕਟਰੀ %s ਦੀ ਵਰਤੋਂ।"
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "ਮੈਡਿਊਲ ਡਾਇਰੈਕਟਰੀ %s ਦੀ ਵਰਤੋਂ।"
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "ਸਿਸਟਮ ਮੋਡ ਵਿੱਚ ਚੱਲ ਰਿਹਾ ਹੈ: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -365,47 +403,47 @@ msgstr ""
 "ਕਿਰਪਾ ਕਰਕੇ ਸਿਸਟਮ ਮੋਡ ਦੇ ਗਲਤ ਹੋਣ ਬਾਰੇ ਵਧੇਰੇ ਜਾਣਕਾਰੀ ਲਈ http://pulseaudio.org/wiki/"
 "WhatIsWrongWithSystemMode ਵੇਖੋ।"
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() ਫੇਲ੍ਹ ਹੈ।"
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "ਤਾਜ਼ੀ ਹਾਈ-ਰੈਜ਼ੋਲੂਸ਼ਨ ਟਾਈਮਰ ਉਪਲੱਬਧ ਹੈ! Bon appetit!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
 msgstr ""
 "ਮਿੱਤਰਾ, ਤੇਰਾ ਕਰਨਲ ਪੁਰਾਣਾ ਹੈ! ਚੀਫ ਦੀ ਅੱਜ ਦੀ ਸਿਫਾਰਸ਼ ਹਾਈ-ਰੈਜ਼ੋਲੂਸ਼ਨ ਟਾਈਮਰ ਯੋਗ ਨਾਲ ਲੀਨਕਸ ਹੈ!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() ਫੇਲ੍ਹ ਹੈ।"
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "ਡੈਮਨ ਸ਼ੁਰੂ ਕਰਨ ਵਿੱਚ ਫੇਲ੍ਹ।"
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "ਡੈਮਨ ਸ਼ੁਰੂਆਤੀ ਬਿਨਾਂ ਕਿਸੇ ਲੋਡ ਕੀਤੇ ਮੈਡਿਊਲ, ਕੰਮ ਕਰਨ ਤੋਂ ਰੋਕ ਰਿਹਾ ਹੈ।"
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "ਡੈਮਨ ਸ਼ੁਰੂਆਤੀ ਮੁਕੰਮਲ।"
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "ਡੈਮਨ ਬੰਦ ਕਰਨਾ ਸ਼ੁਰੂ ਹੋ ਗਿਆ।"
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "ਡੈਮਨ ਬੰਦ ਹੋ ਗਿਆ।"
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -442,15 +480,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -547,15 +583,15 @@ msgstr ""
 "\n"
 "  -n                                    Don't load default script file\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize ਨੂੰ ਬੁਲੀਅਨ ਆਰਗੂਮੈਂਟ ਦੀ ਲੋੜ ਹੈ"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail ਨੂੰ ਬੁਲੀਅਨ ਆਰਗੂਮੈਂਟ ਦੀ ਲੋੜ ਹੈ"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -563,177 +599,180 @@ msgstr ""
 "--log-level ਨੂੰ ਲਾਗ ਲੈਵਲ ਆਰਗੂਮੈਂਟ ਦੀ ਲੋੜ ਹੈ (ਜਾਂ ਤਾਂ ਅੰਕੀ ਰੇਂਜ 0..4 ਜਾਂ debug, info, "
 "notice, warn, error ਵਿੱਚੋਂ ਇੱਕ)।"
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority ਨੂੰ ਬੁਲੀਅਨ ਆਰਗੂਮੈਂਟ ਦੀ ਲੋੜ ਹੈ"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime ਨੂੰ ਬੁਲੀਅਨ ਆਰਗੂਮੈਂਟ ਦੀ ਲੋੜ ਹੈ"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading ਨੂੰ ਬੁਲੀਅਨ ਆਰਗੂਮੈਂਟ ਦੀ ਲੋੜ ਹੈ"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit ਨੂੰ ਬੁਲੀਅਨ ਆਰਗੂਮੈਂਟ ਦੀ ਲੋੜ ਹੈ"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file ਨੂੰ ਬੁਲੀਅਨ ਆਰਗੂਮੈਂਟ ਦੀ ਲੋੜ ਹੈ"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr "ਗਲਤ ਲਾਗ ਟਾਰਗੇਟ: 'syslog', 'stderr' ਜਾਂ 'auto' ਵਰਤੋਂ।"
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time ਨੂੰ ਬੁਲੀਅਨ ਆਰਗੂਮੈਂਟ ਦੀ ਲੋੜ ਹੈ"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta ਨੂੰ ਬੁਲੀਅਨ ਆਰਗੂਮੈਂਟ ਦੀ ਲੋੜ ਹੈ"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "ਅਢੁੱਕਵਾਂ ਰੀਸੈਂਪਲ ਢੰਗ '%s'।"
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system ਨੂੰ ਬੁਲੀਅਨ ਆਰਗੂਮੈਂਟ ਦੀ ਲੋੜ ਹੈ"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit ਨੂੰ ਬੁਲੀਅਨ ਆਰਗੂਮੈਂਟ ਦੀ ਲੋੜ ਹੈ"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm ਨੂੰ ਬੁਲੀਅਨ ਆਰਗੂਮੈਂਟ ਦੀ ਲੋੜ ਹੈ"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "ਨਾਂ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "ਕੋਈ ਮੋਡੀਊਲ ਜਾਣਕਾਰੀ ਉਪਲੱਬਧ ਨਹੀਂ\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "ਵਰਜਨ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "ਵੇਰਵਾ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "ਲੇਖਕ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "ਵਰਤੋਂ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "ਇੱਕ ਵਾਰ ਲੋਡ ਕਰੋ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "DEPRECATION WARNING: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "ਪਾਥ: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] ਗਲਤ ਲਾਗ ਟਾਰਗੇਟ '%s'।"
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] ਗਲਤੀ ਲਾਗ ਲੈਵਲ '%s'।"
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] ਅਢੁੱਕਵੀਂ ਰੀਸੈਂਪਲ ਢੰਗ '%s'।"
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] ਅਢੁੱਕਵੀਂ rlimit '%s'।"
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit ਨੂੰ ਇਸ ਪਲੇਟਫਾਰਮ ਤੇ ਸਹਿਯੋਗ ਨਹੀਂ ਹੈ।"
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] ਅਢੁੱਕਵਾਂ ਸੈਂਪਲ ਫਾਰਮੈਟ '%s'।"
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] ਅਢੁੱਕਵਾਂ ਸੈਂਪਲ ਰੇਟ '%s'।"
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] ਅਢੁੱਕਵਾਂ ਸੈਂਪਲ ਚੈਨਲ '%s'।"
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] ਅਢੁੱਕਵਾਂ ਚੈਨਲ ਮੈਪ '%s'।"
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] ਫਰੈਗਮੈਂਟਾਂ ਦਾ ਅਢੁੱਕਵਾਂ ਨੰਬਰ '%s'।"
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] ਅਢੁੱਕਵਾਂ ਫਰੈਗਮੈਂਟ ਅਕਾਰ '%s'।"
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] ਅਢੁੱਕਵਾਂ nice ਲੈਵਲ '%s'।"
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] ਅਢੁੱਕਵਾਂ ਸੈਂਪਲ ਰੇਟ '%s'।"
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "ਸੰਰਚਨਾ ਫਾਇਲ ਖੋਲ੍ਹਣ ਵਿੱਚ ਫੇਲ੍ਹ: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 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:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### ਸੰਰਚਨਾ ਫਾਇਲ ਵਿੱਚੋਂ ਪੜਿਆ: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "ਅਧਿਕਾਰ ਹਟਾ ਰਿਹਾ ਹੈ।"
 
@@ -745,6 +784,16 @@ msgstr "ਪਲਸਆਡੀਓ ਸਾਊਂਡ ਸਿਸਟਮ"
 msgid "Start the PulseAudio Sound System"
 msgstr "ਪਲਸਆਡੀਓ ਸਾਊਂਡ ਸਿਸਟਮ ਚਲਾਓ"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "ਪਲਸਆਡੀਓ ਸਾਊਂਡ ਸਿਸਟਮ"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "ਪਲਸਆਡੀਓ ਸਾਊਂਡ ਸਿਸਟਮ ਚਲਾਓ"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "ਮੋਨੋ"
@@ -774,8 +823,8 @@ msgid "Rear Right"
 msgstr "ਪਿੱਛੇ ਸੱਜਾ"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "ਘੱਟ ਫਰੀਕਿਊਂਸੀ ਇੱਮਟਰ"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -949,9 +998,10 @@ msgstr "ਉੱਤੇ ਪਿੱਛੇ ਖੱਬੇ"
 msgid "Top Rear Right"
 msgstr "ਉੱਤੇ ਪਿੱਛੇ ਸੱਜੇ"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(ਅਢੁੱਕਵਾਂ)"
 
@@ -979,332 +1029,349 @@ msgstr "ਸਰਾਊਂਡਿੰਗ 5.1"
 msgid "Surround 7.1"
 msgstr "ਸਰਾਊਂਡਿੰਗ 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "ਠੀਕ ਹੈ"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "ਅਸੈੱਸ ਪਾਬੰਦੀ ਹੈ"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "ਅਣਜਾਣ ਕਮਾਂਡ"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "ਅਢੁੱਕਵਾਂ ਆਰਗੂਮੈਂਟ"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "ਐਂਟਟੀ ਮੌਜੂਦ ਹੈ"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "ਕੋਈ ਐਂਟਟੀ ਨਹੀਂ"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "ਕੁਨੈਕਸ਼ਨ ਤੋਂ ਇਨਕਾਰ"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "ਪਰੋਟੋਕਾਲ ਗਲਤੀ"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "ਸਮਾਂ-ਸਮਾਪਤ"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "ਕੋਈ ਪ੍ਰਮਾਣਿਕਤਾ ਕੁੰਜੀ ਨਹੀਂ"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "ਅੰਦਰੂਨੀ ਗਲਤੀ"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "ਕੁਨੈਕਸ਼ਨ ਖਤਮ ਕੀਤਾ"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "ਐਂਟਟੀ ਖਤਮ ਹੋ ਗਈ"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "ਅਢੁੱਕਵਾਂ ਸਰਵਰ"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "ਮੋਡੀਊਲ ਸ਼ੁਰੂ ਕਰਨਾ ਫੇਲ੍ਹ"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "ਖਰਾਬ ਹਾਲਤ"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "ਕੋਈ ਡਾਟਾ ਨਹੀਂ"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "ਨਾ-ਅਨੁਕੂਲ ਪਰੋਟੋਕਾਲ ਵਰਜਨ"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "ਬਹੁਤ ਵੱਡਾ"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "ਸਹਾਇਕ ਨਹੀਂ"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "ਅਣਜਾਣ ਗਲਤੀ ਕੋਡ"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "ਕੋਈ ਅਜਿਹੀ ਇਕਸਟੈਂਸ਼ਨ ਨਹੀਂ"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "ਛੱਡੀ ਗਈ ਫੰਕਸ਼ਨੈਲਿਟੀ"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "ਗੈਰ-ਮੌਜੂਦ ਨਿਰਧਾਰਨ"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "ਕਲਾਇਟ ਅੱਡ ਕੀਤਾ"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "ਇੰਪੁੱਟ/ਆਊਟਪੁੱਟ ਗਲਤੀ"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "ਜਤੰਰ ਜਾਂ ਸਰੋਤ ਵਰਤੋਂ ਅਧੀਨ ਹੈ"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() ਫੇਲ੍ਹ ਹੈ"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() ਫੇਲ੍ਹ ਹੈ: %s"
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "ਕੂਕੀ ਡਾਟਾ ਪਾਰਸ ਕਰਨ ਵਿੱਚ ਫੇਲ੍ਹ"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "ਸੰਰਚਨਾ ਫਾਇਲ '%s' ਨੂੰ ਖੋਲ੍ਹਣ ਵਿੱਚ ਫੇਲ੍ਹ: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "ਕੋਈ ਕੂਕੀ ਲੋਡ ਨਹੀਂ ਕੀਤੀ। ਇਸ ਤੋਂ ਬਿਨਾਂ ਕੁਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।"
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "ਅਣਜਾਣੀ ਇਕਸਟੈਂਸ਼ਨ '%s' ਲਈ ਸੁਨੇਹਾ ਮਿਲਿਆ ਹੈ"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "ਸਟਰੀਮ ਡਰੇਨ ਫੇਲ੍ਹ ਹੋਇਆ: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "ਪਲੇਬੈਕ ਸਟਰੀਮ ਡਰੇਨ ਕੀਤੀ।"
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "ਸਰਵਰ ਨਾਲ ਕੁਨੈਕਸ਼ਨ ਡਰੇਨ ਹੋ ਰਿਹਾ ਹੈ।"
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() ਫੇਲ੍ਹ ਹੈ: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_write() ਫੇਲ੍ਹ ਹੈ: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() ਫੇਲ੍ਹ ਹੈ: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "ਸਟਰੀਮ ਸਫਲਤਾਪੂਰਕ ਬਣ ਗਈ ਹੈ।"
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() ਫੇਲ੍ਹ ਹੈ: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 msgstr "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Buffer metrics: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "ਸਧਾਰਨ spec '%s', ਚੈਨਲ ਮੈਪ '%s' ਦੀ ਵਰਤੋਂ।"
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "%s ਜੰਤਰ ਨਾਲ ਕੁਨਕੈਟ ਕੀਤਾ (%u, %ssuspended)।"
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "ਸਟਰੀਮ ਗਲਤੀ: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "ਸਟਰੀਮ ਜੰਤਰ ਸਸਪੈਂਡ ਕੀਤਾ ਹੈ।%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "ਸਟਰੀਮ ਜੰਤਰ ਮੁੜ-ਪ੍ਰਾਪਤ ਕੀਤਾ।%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "ਸਟਰੀਮ ਅੰਡਰਰਨ।%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "ਸਟਰੀਮ ਓਵਰਰਨ।%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "ਸਟਰੀਮ ਸ਼ੁਰੂ ਕੀਤੀ। %s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "ਸਟਰੀਮ ਨੂੰ ਜੰਤਰ %s ਤੋਂ ਤਬਦੀਲ ਕੀਤਾ ਗਿਆ ਹੈ (%u, %ssuspended)।%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "ਨਹੀਂ "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "ਸਟਰੀਮ ਬਫਰ ਐਟਰੀਬਿਊਟ ਤਬਦੀਲ ਕੀਤੇ ਗਏ।%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "ਕੁਨੈਕਸ਼ਨ ਬਣ ਗਿਆ।%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() ਫੇਲ੍ਹ ਹੈ: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() ਫੇਲ੍ਹ ਹੈ: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() ਫੇਲ੍ਹ ਹੈ: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "ਕੁਨੈਕਸ਼ਨ ਫੇਲ: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "EOF ਮਿਲਿਆ।"
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() ਫੇਲ੍ਹ ਹੈ: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "ਸਿਗਨਲ ਮਿਲਿਆ, ਬੰਦ ਹੋ ਰਿਹਾ ਹੈ।"
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "ਵਕਫਾ ਪ੍ਰਾਪਤੀ ਫੇਲ ਹੋਈ: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "ਟਾਈਮ: %0.3f ਸਕਿੰਟ; ਵਕਫਾ: %0.0f usec।"
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() ਫੇਲ੍ਹ ਹੈ: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1356,10 +1423,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [options]\n"
@@ -1418,7 +1490,7 @@ msgstr ""
 "      --file-format=FFORMAT             Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1429,169 +1501,174 @@ msgstr ""
 "libpulse %s ਦੇ ਕੰਪਾਇਲ\n"
 "libpulse %s ਨਾਲ ਲਿੰਕ ਕੀਤਾ\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "ਅਢੁੱਕਵਾਂ ਚੈਨਲ ਮੈਪ '%s'"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "ਅਢੁੱਕਵਾਂ ਰੀਸੈਂਪਲ ਢੰਗ '%s'"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "ਅਢੁੱਕਵਾਂ ਚੈਨਲ ਮੈਪ '%s'"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "ਅਢੁੱਕਵਾਂ ਵਕਫਾ ਹਦਾਇਤ '%s'"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "ਅਢੁੱਕਵਾਂ ਪਰੋਸੈੱਸ ਟਾਈਮ ਹਦਾਇਤ '%s'"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "ਅਢੁੱਕਵਾਂ ਰੀਸੈਂਪਲ ਢੰਗ '%s'"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "ਅਣਜਾਣ ਫਾਇਲ ਫਾਰਮੈਟ %s"
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "ਅਢੁੱਕਵਾਂ ਸੈਂਪਲ ਹਦਾਇਤ"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "ਬਹੁਤ ਵੱਧ ਆਰਗੂਮੈਂਟ।"
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "ਸੈਂਪਲ ਜਾਣਕਾਰੀ ਲੈਣ ਵਿੱਚ ਫੇਲ: %s"
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "ਸਾਊਂਡ ਫਾਇਲ ਖੋਲ੍ਹਣ ਲਈ ਫੇਲ੍ਹ ਹੈ।"
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
 msgstr "ਇੱਕ %s ਸਟਰੀਮ ਨੂੰ ਸੈਂਪਲ ਹਦਾਇਤ '%s' ਨਾਲ ਖੋਲ੍ਹਿਆ ਜਾ ਰਿਹਾ ਹੈ।"
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "ਸੈਂਪਲ ਜਾਣਕਾਰੀ ਲੈਣ ਵਿੱਚ ਫੇਲ: %s"
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "ਇੱਕ %s ਸਟਰੀਮ ਨੂੰ ਸੈਂਪਲ ਹਦਾਇਤ '%s' ਨਾਲ ਖੋਲ੍ਹਿਆ ਜਾ ਰਿਹਾ ਹੈ।"
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "ਚੈਨਲ ਮੈਪ ਸੈਂਪਲ ਹਦਾਇਤ ਨਾਲ ਨਹੀਂ ਮਿਲਦਾ"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "ਇੱਕ %s ਸਟਰੀਮ ਨੂੰ ਸੈਂਪਲ ਹਦਾਇਤ '%s' ਨਾਲ ਖੋਲ੍ਹਿਆ ਜਾ ਰਿਹਾ ਹੈ।"
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr "ਇੱਕ %s ਸਟਰੀਮ ਨੂੰ ਸੈਂਪਲ ਹਦਾਇਤ '%s' ਅਤੇ ਚੈਨਲ ਮੈਪ '%s' ਨਾਲ ਖੋਲ੍ਹਿਆ ਜਾ ਰਿਹਾ ਹੈ।"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "ਰਿਕਾਰਡਿੰਗ"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "ਪਲੇਅਬੈਕ"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "ਕਮਾਂਡ ਲਾਈਨ ਪਾਰਸ ਕਰਨ ਵਿੱਚ ਫੇਲ੍ਹ।"
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() ਫੇਲ੍ਹ ਹੈ।"
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() ਫੇਲ੍ਹ ਹੈ।"
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() ਫੇਲ੍ਹ ਹੈ।"
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() ਫੇਲ੍ਹ ਹੈ: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_new() ਫੇਲ੍ਹ ਹੈ।"
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() ਫੇਲ੍ਹ ਹੈ।"
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "ਸਸਪੈਂਡ ਕਰਨ ਵਿੱਚ ਫੇਲ: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "ਮੁੜ-ਪ੍ਰਾਪਤੀ ਫੇਲ: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "ਚੇਤਾਵਨੀ: ਸਾਊਂਡ ਸਰਵਰ ਲੋਕਲ ਨਹੀਂ ਹੈ, ਸਸਪੈਂਡ ਨਹੀਂ ਹੋ ਰਿਹਾ।\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "ਕੁਨੈਕਸ਼ਨ ਫੇਲ: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "SIGINT ਮਿਲਿਆ, ਬੰਦ ਹੋ ਰਿਹਾ ਹੈ।\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "ਚੇਤਾਵਨੀ: ਚਲਾਈਡ ਪਰੋਸੈੱਸ ਨੂੰ ਸਿਗਨਲ %u ਵਲੋਂ ਬੰਦ ਕੀਤਾ ਗਿਆ ਹੈ\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1636,35 +1713,46 @@ msgstr "pa_context_new() ਫੇਲ੍ਹ ਹੈ।\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() ਫੇਲ੍ਹ ਹੈ।\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "ਅੰਕੜੇ ਪ੍ਰਾਪਤੀ ਫੇਲ੍ਹ: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "ਹੁਣ ਵਰਤੋਂ ਵਿੱਚ ਹੈ: %u ਬਲਾਕ ਵਿੱਚ ਕੁੱਲ %s ਬਾਈਟ ਹਨ।\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "ਪੂਰੇ ਲਾਈਫਟਾਈਮ ਵਿੱਚ ਜਾਰੀ ਕੀਤਾ ਗਿਆ: %u ਬਲਾਕ ਵਿੱਚ ਕੁੱਲ %s ਬਾਈਟ ਹਨ।\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "ਸੈਂਪਲ ਕੈਸ਼ ਸਾਈਜ਼: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "ਸਰਵਰ ਜਾਣਕਾਰੀ ਪ੍ਰਾਪਤ ਕਰਨ ਵਿੱਚ ਫੇਲ ਹੋਇਆ: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1672,7 +1760,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "User name: %s\n"
 "Host Name: %s\n"
@@ -1684,13 +1772,13 @@ msgstr ""
 "Default Source: %s\n"
 "Cookie: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "ਸਿੰਕ ਜਾਣਕਾਰੀ ਲੈਣ ਵਿੱਚ ਫੇਲ੍ਹ: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1706,7 +1794,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1728,22 +1816,27 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tਪੋਰਟ:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tਸਰਗਰਮ ਪੋਰਟ: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tਪੋਰਟ:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "ਸਰੋਤ ਜਾਣਕਾਰੀ ਲੈਣ ਵਿੱਚ ਫੇਲ: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1782,20 +1875,20 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "ਉਪਲੱਬਧ ਨਹੀਂ"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "ਮੋਡੀਊਲ ਜਾਣਕਾਰੀ ਲੈਣ ਵਿੱਚ ਫੇਲ: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1812,12 +1905,12 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "ਕਲਾਇਟ ਜਾਣਕਾਰੀ ਲੈਣ ਵਿੱਚ ਫੇਲ: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1832,12 +1925,12 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "ਕਾਰਡ ਜਾਣਕਾਰੀ ਲੈਣ ਵਿੱਚ ਫੇਲ: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1854,23 +1947,23 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tਪਰੋਫਾਈਲ:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tਸਰਗਰਮ ਪਰੋਫਾਈਲ: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "ਇੰਪੁੱਟ ਜਾਣਕਾਰੀ ਲੈਣ ਵਿੱਚ ਫੇਲ੍ਹ: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1879,6 +1972,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1906,13 +2000,13 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "ਸਰੋਤ ਆਉਟਪੁੱਟ ਜਾਣਕਾਰੀ ਲੈਣ ਵਿੱਚ ਫੇਲ: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1921,31 +2015,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Source Output #%u\n"
+"Sink Input #%u\n"
 "\tDriver: %s\n"
 "\tOwner Module: %s\n"
 "\tClient: %s\n"
-"\tSource: %u\n"
+"\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
-"\tSource Latency: %0.0f usec\n"
+"\tSink Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "ਸੈਂਪਲ ਜਾਣਕਾਰੀ ਲੈਣ ਵਿੱਚ ਫੇਲ: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1976,48 +2079,163 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "ਫੇਲ੍ਹ: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "ਸਰੋਤ ਜਾਣਕਾਰੀ ਲੈਣ ਵਿੱਚ ਫੇਲ: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "ਸੈਂਪਲ ਅੱਪਲੋਡ ਕਰਨ ਵਿੱਚ ਫੇਲ: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "ਫਾਇਲ ਦਾ ਸਮੇਂ ਤੋਂ ਪਹਿਲਾਂ ਅੰਤ"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "ਅਢੁੱਕਵਾਂ ਸਰਵਰ"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "SIGINT ਮਿਲਿਆ, ਬੰਦ ਹੋ ਰਿਹਾ ਹੈ।"
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "ਅਢੁੱਕਵਾਂ ਸੈਂਪਲ ਹਦਾਇਤ"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2027,37 +2245,15 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+"%s [options] ... \n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
-"\n"
 "  -s, --server=SERVER                   The name of the server to connect "
 "to\n"
-"  -n, --client-name=NAME                How to call this client on the "
-"server\n"
+"\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2068,104 +2264,136 @@ msgstr ""
 "Compiled with libpulse %s\n"
 "Linked with libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "ਲੋਡ ਕਰਨ ਲਈ ਸੈਂਪਲ ਫਾਇਲ ਦਿਓ"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "ਸਾਊਂਡ ਫਾਇਲ ਖੋਲ੍ਹਣ ਲਈ ਫੇਲ੍ਹ ਹੈ।"
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "ਇੱਕ %s ਸਟਰੀਮ ਨੂੰ ਸੈਂਪਲ ਹਦਾਇਤ '%s' ਨਾਲ ਖੋਲ੍ਹਿਆ ਜਾ ਰਿਹਾ ਹੈ।"
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "ਖੇਡਣ ਲਈ ਤੁਹਾਨੂੰ ਸੈਂਪਲ ਨਾਂ ਦੇਣਾ ਪਵੇਗਾ"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "ਹਟਾਉਣ ਲਈ ਤੁਹਾਨੂੰ ਸੈਂਪਲ ਨਾਂ ਦੇਣਾ ਪਵੇਗਾ"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "ਤੁਹਾਨੂੰ ਇੰਪੁੱਟ ਲਿਸਟ ਅਤੇ ਇੱਕ ਸਿੰਕ ਨੂੰ ਸਿੰਕ ਕਰਨਾ ਪਵੇਗਾ"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "ਤੁਹਾਨੂੰ ਇੱਕ ਸਰੋਤ ਆਉਟਪੁੱਟ ਲਿਸਟ ਅਤੇ ਇੱਕ ਸਰੋਤ ਦੇਣਾ ਪਵੇਗਾ"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "ਤੁਹਾਨੂੰ ਇੱਕ ਮੋਡੀਊਲ ਨਾਂ ਅਤੇ ਆਰਗੂਮੈਂਟ ਦੇਣਾ ਪਵੇਗਾ।"
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "ਤੁਹਾਨੂੰ ਇੱਕ ਮੈਡੀਊਲ ਲਿਸਟ ਦੇਣੀ ਪਵੇਗੀ"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr "ਤੁਸੀਂ ਇੱਕ ਤੋਂ ਵੱਧ ਸਿੰਕ ਨਹੀਂ ਦੇ ਸਕਦੇ। ਤੁਹਾਨੂੰ ਇੱਕ ਬੁਲੀਅਨ ਮੁੱਲ ਦੇਣਾ ਪਵੇਗਾ।"
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr "ਤੁਸੀਂ ਇੱਕ ਤੋਂ ਵੱਧ ਸਰੋਤ ਨਹੀਂ ਦੇ ਸਕਦੇ। ਤੁਹਾਨੂੰ ਬੁਲੀਅਨ ਮੁੱਲ ਦੇਣਾ ਪਵੇਗਾ।"
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "ਤੁਹਾਨੂੰ ਇੱਕ ਕਾਰਡ ਨਾਂ/ਲਿਸਟ ਅਤੇ ਪਰੋਫਾਈਲ ਨਾਂ ਦੇਣਾ ਪਵੇਗਾ"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "ਤੁਹਾਨੂੰ ਇੱਕ ਕਾਰਡ ਨਾਂ/ਲਿਸਟ ਅਤੇ ਪਰੋਫਾਈਲ ਨਾਂ ਦੇਣਾ ਪਵੇਗਾ"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "ਤੁਹਾਨੂੰ ਇੱਕ ਕਾਰਡ ਨਾਂ/ਲਿਸਟ ਅਤੇ ਪਰੋਫਾਈਲ ਨਾਂ ਦੇਣਾ ਪਵੇਗਾ"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "ਤੁਹਾਨੂੰ ਇੱਕ ਕਾਰਡ ਨਾਂ/ਲਿਸਟ ਅਤੇ ਪਰੋਫਾਈਲ ਨਾਂ ਦੇਣਾ ਪਵੇਗਾ"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "ਅਢੁੱਕਵਾਂ ਸੈਂਪਲ ਹਦਾਇਤ"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "ਤੁਹਾਨੂੰ ਇੱਕ ਕਾਰਡ ਨਾਂ/ਲਿਸਟ ਅਤੇ ਪਰੋਫਾਈਲ ਨਾਂ ਦੇਣਾ ਪਵੇਗਾ"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "ਤੁਹਾਨੂੰ ਇੰਪੁੱਟ ਲਿਸਟ ਅਤੇ ਇੱਕ ਸਿੰਕ ਨੂੰ ਸਿੰਕ ਕਰਨਾ ਪਵੇਗਾ"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "ਅਢੁੱਕਵੀਂ ਸਿੰਕ ਇੰਪੁੱਟ ਸੂਚੀ"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "ਤੁਹਾਨੂੰ ਇੱਕ ਸਰੋਤ ਆਉਟਪੁੱਟ ਲਿਸਟ ਅਤੇ ਇੱਕ ਸਰੋਤ ਦੇਣਾ ਪਵੇਗਾ"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "ਅਢੁੱਕਵੀਂ ਸਿੰਕ ਇੰਪੁੱਟ ਸੂਚੀ"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "ਤੁਹਾਨੂੰ ਇੱਕ ਕਾਰਡ ਨਾਂ/ਲਿਸਟ ਅਤੇ ਪਰੋਫਾਈਲ ਨਾਂ ਦੇਣਾ ਪਵੇਗਾ"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "ਅਢੁੱਕਵਾਂ ਸੈਂਪਲ ਹਦਾਇਤ"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "ਤੁਹਾਨੂੰ ਇੱਕ ਕਾਰਡ ਨਾਂ/ਲਿਸਟ ਅਤੇ ਪਰੋਫਾਈਲ ਨਾਂ ਦੇਣਾ ਪਵੇਗਾ"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "ਤੁਹਾਨੂੰ ਇੰਪੁੱਟ ਲਿਸਟ ਅਤੇ ਇੱਕ ਸਿੰਕ ਨੂੰ ਸਿੰਕ ਕਰਨਾ ਪਵੇਗਾ"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "ਅਢੁੱਕਵਾਂ ਸੈਂਪਲ ਹਦਾਇਤ"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "ਤੁਹਾਨੂੰ ਇੱਕ ਕਾਰਡ ਨਾਂ/ਲਿਸਟ ਅਤੇ ਪਰੋਫਾਈਲ ਨਾਂ ਦੇਣਾ ਪਵੇਗਾ"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "ਅਢੁੱਕਵਾਂ ਸੈਂਪਲ ਹਦਾਇਤ"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "ਤੁਹਾਨੂੰ ਇੱਕ ਕਾਰਡ ਨਾਂ/ਲਿਸਟ ਅਤੇ ਪਰੋਫਾਈਲ ਨਾਂ ਦੇਣਾ ਪਵੇਗਾ"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "ਕੋਈ ਯੋਗ ਕਮਾਂਡ ਨਹੀਂ ਦਿੱਤੀ।"
 
@@ -2193,103 +2421,103 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "ਕਮਾਂਡ ਲਾਈਨ ਪਾਰਸ ਕਰਨ ਵਿੱਚ ਫੇਲ੍ਹ।\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "ਸਰਵਰ: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "ਸਰੋਤ: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "ਸਿੰਕ: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "ਕੂਕੀਜ਼: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "ਕੂਕੀ ਡਾਟਾ ਪਾਰਸ ਕਰਨ ਵਿੱਚ ਫੇਲ\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "ਕੂਕੀ ਡਾਟਾ ਸੰਭਾਲਣ ਵਿੱਚ ਫੇਲ\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "ਕਲਾਇਟ ਸੰਰਚਨਾ ਫਾਇਲ ਲੋਡ ਕਰਨ ਵਿੱਚ ਫੇਲ।\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "ਇੰਵਾਇਰਨਮੈਂਟ ਸੰਰਚਨਾ ਡਾਟਾ ਪੜ੍ਹਨ ਵਿੱਚ ਫੇਲ੍ਹ।\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "FQDN ਪ੍ਰਾਪਤ ਕਰਨ ਵਿੱਚ ਫੇਲ।\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "ਕੂਕੀ ਡਾਟਾ ਲੋਡ ਕਰਨ ਵਿੱਚ ਫੇਲ\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "ਹਾਲੇ ਬਣਾਇਆ ਨਹੀਂ।\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr "ਕੋਈ ਪਲਸ-ਆਡੀਓ ਡੈਮਨ ਨਹੀਂ ਚੱਲ ਰਿਹਾ, ਜਾਂ ਸ਼ੈਸ਼ਨ ਡੈਮਨ ਤੌਰ ਤੇ ਨਹੀਂ ਚੱਲ ਰਿਹਾ।"
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "ਪਲਸਆਡੀਓ ਡੈਮਨ ਬੰਦ ਕਰਨ ਵਿੱਚ ਫੇਲ।"
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "ਡੈਮਨ ਜਵਾਬ ਨਹੀਂ ਦੇ ਰਹੀ।"
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "autospawn ਲਾਕ ਵਰਤ ਨਹੀਂ ਸਕਦਾ।"
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2306,7 +2534,7 @@ msgstr ""
 "We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() "
 "returned 0 or another value < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2323,242 +2551,465 @@ msgstr ""
 "We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() "
 "returned 0 or another value < min_avail."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "ਬੰਦ"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "ਹਾਈ ਫਡੈਲਿਟੀ ਪਲੇਅਬੈਕ (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "ਹਾਈ ਫਡੈਲਿਟੀ ਪਲੇਅਬੈਕ (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "ਟੈਲੀਫੋਨੀ ਡੁਪਲੈਕਸ (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "ਪਲਸਆਡੀਓ ਸਾਊਂਡ ਡਰਾਇਵਰ"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
-msgstr ""
+msgstr "ਆਊਟਪੁੱਟ ਜੰਤਰ"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
-msgstr ""
+msgstr "ਇੰਪੁੱਟ ਜੰਤਰ"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
-msgstr ""
+msgstr "@HOSTNAME@ ਉੱਪਰ ਆਡੀਓ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
-msgstr ""
+msgstr "ਇੰਪੁੱਟ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
-msgstr ""
+msgstr "ਡੌਕਿੰਗ ਸਟੇਸ਼ਨ ਇੰਪੁੱਟ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
-msgstr ""
+msgstr "ਡੌਕਿੰਗ ਸਟੇਸ਼ਨ ਮਾਈਕਰੋਫੋਨ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "ਡੌਕਿੰਗ ਸਟੇਸ਼ਨ ਇੰਪੁੱਟ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "ਲਾਈਨ-ਇਨ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
-msgstr ""
+msgstr "ਮਾਈਕਰੋਫੋਨ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
-msgid "External Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "ਡੌਕਿੰਗ ਸਟੇਸ਼ਨ ਮਾਈਕਰੋਫੋਨ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
 #, fuzzy
+msgid "Rear Microphone"
+msgstr "ਮਾਈਕਰੋਫੋਨ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "ਬਾਹਰੀ ਮਾਈਕਰੋਫੋਨ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
-msgstr "à¨\85ੰਦਰà©\82ਨà©\80 à¨\86ਡà©\80à¨\93"
+msgstr "à¨\85ੰਦਰà©\82ਨà©\80 à¨®à¨¾à¨\88à¨\95ਰà©\8bਫà©\8bਨ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
-msgstr ""
+msgstr "ਰੇਡੀਓ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
-msgstr ""
+msgstr "ਵੀਡੀਓ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
-msgstr ""
+msgstr "ਆਟੋਮੈਟਿਕ ਗੇਨ ਕੰਟਰੋਲ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
-msgstr ""
+msgstr "ਕੋਈ ਆਟੋਮੈਟਿਕ ਗੇਨ ਕੰਟਰੋਲ ਨਹੀਂ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
-msgstr ""
+msgstr "ਬੂਸਟ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
-msgstr ""
+msgstr "ਕੋਈ ਬੂਸਟ ਨਹੀਂ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
-msgstr ""
+msgstr "ਐਂਪਲੀਫਾਇਰ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
-msgstr ""
+msgstr "ਕੋਈ ਐਂਪਲੀਫਾਇਰ ਨਹੀਂ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "ਬੂਸਟ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "ਕੋਈ ਬੂਸਟ ਨਹੀਂ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "ਐਨਾਲਾਗ ਹੈੱਡਫੋਨ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "ਐਨਾਲਾਗ ਇੰਪੁੱਟ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "ਡੌਕਿੰਗ ਸਟੇਸ਼ਨ ਮਾਈਕਰੋਫੋਨ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
-msgstr "à©\9bà©\80ਰà©\8b (Null) ਆਉਟਪੁੱਟ"
+msgstr "à¨\90ਨਾਲਾà¨\97 ਆਉਟਪੁੱਟ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "ਐਨਾਲਾਗ ਆਊਟਪੁੱਟ (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "ਲਾਈਨ-ਇਨ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
+msgstr "ਐਨਾਲਾਗ ਮੋਨੋ ਆਊਟਪੁੱਟ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "ਐਨਾਲਾਗ ਸਟੀਰੀਓ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, fuzzy, c-format
-msgid "%s+%s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "ਡਿਜ਼ੀਟਲ ਸਟੀਰੀਓ (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, fuzzy, c-format
-msgid "%s / %s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "ਡਿਜ਼ੀਟਲ ਸਟੀਰੀਓ (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
-msgstr ""
+msgstr "ਐਨਾਲਾਗ ਮੋਨੋ"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
-msgstr "ਸਟੀਰੀਓ"
+msgstr "à¨\90ਨਾਲਾà¨\97 à¨¸à¨\9fà©\80ਰà©\80à¨\93"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
-msgstr "ਸਰਾà¨\8aà¨\82ਡਿੰà¨\97 4.1"
+msgstr "à¨\90ਨਾਲਾà¨\97 à¨¸à¨°à¨¾à¨\8aà¨\82ਡ 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
-msgstr "ਸਰਾà¨\8aà¨\82ਡਿੰà¨\97 4.0"
+msgstr "à¨\90ਨਾਲਾà¨\97 à¨¸à¨°à¨¾à¨\8aà¨\82ਡ 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
-msgstr "ਸਰਾà¨\8aà¨\82ਡਿੰà¨\97 4.1"
+msgstr "à¨\90ਨਾਲਾà¨\97 à¨¸à¨°à¨¾à¨\8aà¨\82ਡ 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
-msgstr "ਸਰਾà¨\8aà¨\82ਡਿੰà¨\97 4.0"
+msgstr "à¨\90ਨਾਲਾà¨\97 à¨¸à¨°à¨¾à¨\8aà¨\82ਡ 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
-msgstr "ਸਰਾà¨\8aà¨\82ਡਿੰà¨\97 4.1"
+msgstr "à¨\90ਨਾਲਾà¨\97 à¨¸à¨°à¨¾à¨\8aà¨\82ਡ 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
-msgstr "ਸਰਾà¨\8aà¨\82ਡਿੰà¨\97 5.0"
+msgstr "à¨\90ਨਾਲਾà¨\97 à¨¸à¨°à¨¾à¨\8aà¨\82ਡ 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
-msgstr "ਸਰਾà¨\8aà¨\82ਡਿੰà¨\97 5.1"
+msgstr "à¨\90ਨਾਲਾà¨\97 à¨¸à¨°à¨¾à¨\8aà¨\82ਡ 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
-msgstr "ਸਰਾà¨\8aà¨\82ਡਿੰà¨\97 4.0"
+msgstr "à¨\90ਨਾਲਾà¨\97 à¨¸à¨°à¨¾à¨\8aà¨\82ਡ 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
-msgstr "ਸਰਾà¨\8aà¨\82ਡਿੰà¨\97 4.1"
+msgstr "à¨\90ਨਾਲਾà¨\97 à¨¸à¨°à¨¾à¨\8aà¨\82ਡ 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
-msgstr "ਸਰਾà¨\8aà¨\82ਡਿੰà¨\97 4.0"
+msgstr "à¨\90ਨਾਲਾà¨\97 à¨¸à¨°à¨¾à¨\8aà¨\82ਡ 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
-msgstr "ਸਰਾà¨\8aà¨\82ਡਿੰà¨\97 7.1"
+msgstr "à¨\90ਨਾਲਾà¨\97 à¨¸à¨°à¨¾à¨\8aà¨\82ਡ 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
-msgstr ""
+msgstr "ਡਿਜ਼ੀਟਲ ਸਟੀਰੀਓ (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "ਡਿਜ਼ੀਟਲ ਸਟੀਰੀਓ (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
-msgstr ""
+msgstr "ਡਿਜ਼ੀਟਲ ਸਰਾਊਂਡ 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
-msgstr ""
+msgstr "ਡਿਜ਼ੀਟਲ ਸਰਾਊਂਡ 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
-msgstr ""
+msgstr "ਡਿਜ਼ੀਟਲ ਸਟੀਰੀਓ (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "ਡਿਜ਼ੀਟਲ ਸਰਾਊਂਡ 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
-msgstr ""
+msgstr "ਐਨਾਲਾਗ ਮੋਨੋ ਡੁਪਲੈਕਸ"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
-msgstr ""
+msgstr "ਐਨਾਲਾਗ ਸਟੀਰੀਓ ਡੁਪਲੈਕਸ"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
+msgstr "ਡਿਜ਼ੀਟਲ ਸਟੀਰੀਓ ਡੁਪਲੈਕਸ (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "ਜ਼ੀਰੋ (Null) ਆਉਟਪੁੱਟ"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "ਇੰਪੁੱਟ"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<name for the sink> sink_properties=<properties for the sink> "
+"master=<name of sink to filter> format=<sample format> rate=<sample rate> "
+"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
+"plugin name> label=<ladspa plugin label> control=<comma separated list of "
+"input control values>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
 msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit ਨੂੰ ਇਸ ਪਲੇਟਫਾਰਮ ਤੇ ਸਹਿਯੋਗ ਨਹੀਂ ਹੈ।"
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() ਫੇਲ੍ਹ ਹੈ"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "ਡਿਜ਼ੀਟਲ ਸਰਾਊਂਡ 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "ਘੱਟ ਫਰੀਕਿਊਂਸੀ ਇੱਮਟਰ"
index 5d7f3a0..6c7edd1 100644 (file)
--- a/po/pl.po
+++ b/po/pl.po
@@ -1,24 +1,22 @@
 # translation of pl.po to Polish
-# Piotr Drąg <piotrdrag@gmail.com>, 2008.
+# Piotr Drąg <piotrdrag@gmail.com>, 2008, 2012, 2013.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: pl\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-30 09:44+0000\n"
-"PO-Revision-Date: 2009-09-30 17:04+0200\n"
+"POT-Creation-Date: 2013-04-16 20:01+0200\n"
+"PO-Revision-Date: 2013-04-16 20:02+0200\n"
 "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
-"Language-Team: Polish <fedora-trans-pl@redhat.com>\n"
+"Language-Team: Polish <trans-pl@lists.fedoraproject.org>\n"
+"Language: pl\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
+"|| n%100>=20) ? 1 : 2);\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1128 ../src/modules/alsa/alsa-util.c:1203
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -26,23 +24,36 @@ msgid ""
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 msgstr ""
-"snd_pcm_avail() zwróciło wyjątkowo dużą wartość: %lu bajty (%lu ms).\n"
+"snd_pcm_avail() zwróciło wyjątkowo dużą wartość: %lu bajtów (%lu ms).\n"
+"Prawdopodobnie jest to błąd sterownika ALSA \"%s\". Proszę zgłosić ten "
+"problem programistom usługi ALSA."
+
+#: ../src/modules/alsa/alsa-util.c:1178
+#, 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."
+msgstr ""
+"snd_pcm_delay() zwróciło wyjątkowo dużą wartość: %li bajtów (%s%lu ms).\n"
 "Prawdopodobnie jest to błąd sterownika ALSA \"%s\". Proszę zgłosić ten "
-"problem programistom ALSA."
+"problem programistom usługi ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1219
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 msgstr ""
-"snd_pcm_delay() zwróciło wyjątkowo dużą wartość: %li bajty (%s%lu ms).\n"
+"snd_pcm_avail_delay() zwróciło dziwne wartości: opóźnienie %lu jest mniejsze "
+"niż korzyść %lu.\n"
 "Prawdopodobnie jest to błąd sterownika ALSA \"%s\". Proszę zgłosić ten "
-"problem programistom ALSA."
+"problem programistom usługi ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1262
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -50,124 +61,134 @@ msgid ""
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 msgstr ""
-"snd_pcm_mmap_begin() zwróciło wyjątkowo dużą wartość: %lu bajty (%lu ms).\n"
+"snd_pcm_mmap_begin() zwróciło wyjątkowo dużą wartość: %lu bajtów (%lu ms).\n"
 "Prawdopodobnie jest to błąd sterownika ALSA \"%s\". Proszę zgłosić ten "
-"problem programistom ALSA."
+"problem programistom usługi ALSA."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr ""
 "Utrzymywanie zawsze co najmniej jednego wczytanego odpływu nawet, jeśli to "
 "pusty odpływ"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "Głuche wyjście"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:53
 msgid "Virtual LADSPA sink"
 msgstr "Wirtualny odpływ LADSPA"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:57
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<nazwa odpływu> sink_properties=<właściwości odpływu> "
 "master=<nazwa odpływu do filtrowania> format=<format próbki> "
 "rate=<częstotliwość próbki> channels=<liczba kanałów> channel_map=<mapa "
 "kanałów> plugin=<nazwa wtyczki ladspa> label=<etykieta wtyczki ladspa> "
-"control=<lista wartości kontroli wejścia oddzielona przecinkami>"
+"control=<lista wartości kontroli wejścia oddzielona przecinkami> "
+"input_ladspaport_map=<lista nazw wejściowych portów LADSPA oddzielona "
+"przecinkami> output_ladspaport_map=<lista nazw wyjściowych portów LADSPA "
+"oddzielona przecinkami> "
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "Zegarowy PUSTY odpływ"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:280
 msgid "Null Output"
 msgstr "Puste wyjście"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
-msgstr "Wewnętrzny dźwięk"
+#: ../src/pulsecore/sink.c:3469
+msgid "Built-in Audio"
+msgstr "Wbudowany dźwięk"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3474
 msgid "Modem"
 msgstr "Modem"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:77
+#, c-format
+msgid "Failed to open module %s: %s"
+msgstr "Otwarcie modułu %s się nie powiodło: %s"
+
+#: ../src/daemon/ltdl-bind-now.c:128
 msgid "Failed to find original lt_dlopen loader."
 msgstr ""
-"Znalezienie oryginalnego programu wczytującego lt_dlopen nie powiodło się."
+"Odnalezienie pierwotnego programu wczytującego lt_dlopen się nie powiodło."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:133
 msgid "Failed to allocate new dl loader."
-msgstr "Przydzielenie nowego programu wczytującego dl nie powiodło się."
+msgstr "Przydzielenie nowego programu wczytującego dl się nie powiodło."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:146
 msgid "Failed to add bind-now-loader."
-msgstr "Dodanie bind-now-loader nie powiodło się."
+msgstr "Dodanie bind-now-loader się nie powiodło."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "Otrzymano sygnał %s."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
-msgstr "Kończenie pracy."
+msgstr "Kończenie działania."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
-msgstr "Odnalezienie użytkownika \"%s\" nie powiodło się."
+msgstr "Odnalezienie użytkownika \"%s\" się nie powiodło."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
-msgstr "Odnalezienie grupy \"%s\" nie powiodło się."
+msgstr "Odnalezienie grupy \"%s\" się nie powiodło."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "Odnaleziono użytkownika \"%s\" (UID %lu) i grupę \"%s\" (GID %lu)."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
-msgstr "GID użytkownika \"%s\" i grupy \"%s\" nie zgadzają się."
+msgstr "GID użytkownika \"%s\" i grupy \"%s\" się nie zgadzają."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
-msgstr "Katalog domowy użytkownika \"%s\" nie jest \"%s\", ignorowanie."
+msgstr "Katalogiem domowym użytkownika \"%s\" nie jest \"%s\", ignorowanie."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
-msgstr "Utworzenie \"%s\" nie powiodło się: %s"
+msgstr "Utworzenie \"%s\" się nie powiodło: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
-msgstr "Zmiana listy grup nie powiodła się: %s"
+msgstr "Zmiana listy grup się nie powiodła: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
-msgstr "Zmiana GID nie powiodła się: %s"
+msgstr "Zmiana GID się nie powiodła: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
-msgstr "Zmiana UID nie powiodła się: %s"
+msgstr "Zmiana UID się nie powiodła: %s"
 
 #: ../src/daemon/main.c:271
-msgid "Successfully dropped root privileges."
-msgstr "Pomyślnie porzucono uprawnienia roota."
+msgid "Successfully changed user to \""
+msgstr "Pomyślnie zmieniono użytkownika na \""
 
 #: ../src/daemon/main.c:279
 msgid "System wide mode unsupported on this platform."
@@ -176,188 +197,221 @@ msgstr "Tryb systemowy nie jest obsługiwany na tej platformie."
 #: ../src/daemon/main.c:297
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
-msgstr "setrlimit(%s, (%u, %u)) nie powiodło się: %s"
+msgstr "setrlimit(%s, (%u, %u)) się nie powiodło: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:498
 msgid "Failed to parse command line."
-msgstr "Przetworzenie wiersza poleceń nie powiodła się."
+msgstr "Przetworzenie wiersza poleceń się nie powiodło."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:531
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+"Odmówiono trybu systemowego dla użytkownika nie będącego rootem. "
+"Uruchamianie tylko usługi wyszukiwania serwera D-Bus."
+
+#: ../src/daemon/main.c:613
 msgid "Daemon not running"
-msgstr "Demon nie jest uruchomiony"
+msgstr "Usługa nie jest uruchomiona"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:615
 #, c-format
 msgid "Daemon running as PID %u"
-msgstr "Demon jest uruchomiony jako PID %u"
+msgstr "Usługa jest uruchomiona jako PID %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:630
 #, c-format
 msgid "Failed to kill daemon: %s"
-msgstr "Zniszczenie demona nie powiodło się: %s"
+msgstr "Zniszczenie usługi się nie powiodło: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:659
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
 msgstr ""
-"Ten program nie powinien być uruchomiany jako root (chyba, że podano --"
+"Ten program nie powinien być uruchamiany jako root (chyba, że podano --"
 "system)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:662
 msgid "Root privileges required."
 msgstr "Wymagane są uprawnienia roota."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:669
 msgid "--start not supported for system instances."
 msgstr "--start nie jest obsługiwane przy uruchamianiu systemowym."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:709
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+"Serwer skonfigurowany przez użytkownika w %s, odmawianie uruchomienia/"
+"automatycznego wznowienia."
+
+#: ../src/daemon/main.c:715
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+"Serwer skonfigurowany przez użytkownika w %s, który jest lokalny. Dalsze "
+"wykrywanie."
+
+#: ../src/daemon/main.c:720
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr ""
 "Uruchamianie w trybie systemowym, ale --disallow-exit nie jest ustawione."
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:723
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
 "Uruchamianie w trybie systemowym, ale --disallow-module-loading nie jest "
 "ustawione."
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:726
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "Uruchamianie w trybie systemowym, wymuszanie wyłączenia trybu SHM."
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:731
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 "Uruchamianie w trybie systemowym, wymuszanie wyłączenia czasu oczekiwania na "
 "zakończenie."
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:759
 msgid "Failed to acquire stdio."
-msgstr "Uzyskanie standardowego wejścia/wyjścia nie powiodło się."
+msgstr "Uzyskanie standardowego wejścia/wyjścia się nie powiodło."
 
-#: ../src/daemon/main.c:627
+#: ../src/daemon/main.c:765 ../src/daemon/main.c:830
 #, c-format
-msgid "pipe failed: %s"
-msgstr "potok nie powiódł się: %s"
+msgid "pipe() failed: %s"
+msgstr "pipe() się nie powiodło: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:770 ../src/daemon/main.c:835
 #, c-format
 msgid "fork() failed: %s"
-msgstr "fork() nie powiodło się: %s"
+msgstr "fork() się nie powiodło: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:785 ../src/daemon/main.c:850 ../src/utils/pacat.c:564
 #, c-format
 msgid "read() failed: %s"
-msgstr "read() nie powiodło się: %s"
+msgstr "read() się nie powiodło: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:791
 msgid "Daemon startup failed."
-msgstr "Uruchomienie demona nie powiodło się."
+msgstr "Uruchomienie usługi się nie powiodło."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:793
 msgid "Daemon startup successful."
-msgstr "Pomyślnie uruchomiono demona."
+msgstr "Pomyślnie uruchomiono usługę."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:818
+#, c-format
+msgid "setsid() failed: %s"
+msgstr "setsid() się nie powiodło: %s"
+
+#: ../src/daemon/main.c:903
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "To jest PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:904
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Komputer kompilacji: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:905 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "CFLAGS kompilacji: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:908
 #, c-format
 msgid "Running on host: %s"
 msgstr "Uruchamianie na komputerze: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Found %u CPUs."
 msgstr "Odnaleziono %u procesorów."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:913
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "Rozmiar strony to %lu bajtów"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: yes"
 msgstr "Skompilowano z obsługą Valgrind: tak"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:918
 msgid "Compiled with Valgrind support: no"
 msgstr "Skompilowano z obsługą Valgrind: nie"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:921
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "Uruchamianie w trybie Valgrind: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:923
+#, c-format
+msgid "Running in VM: %s"
+msgstr "Uruchamianie w maszynie wirtualnej: %s"
+
+#: ../src/daemon/main.c:926
 msgid "Optimized build: yes"
 msgstr "Budowanie optymalizowane: tak"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:928
 msgid "Optimized build: no"
 msgstr "Budowanie optymalizowane: nie"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:932
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "Podano NDEBUG, wszystkie asercje zostały wyłączone."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:934
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "Podano FASTPATH, tylko szybkie asercje ścieżek zostały wyłączone."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:936
 msgid "All asserts enabled."
 msgstr "Wszystkie asercje są włączone."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:940
 msgid "Failed to get machine ID"
-msgstr "Uzyskanie identyfikatora komputera nie powiodło się"
+msgstr "Uzyskanie identyfikatora komputera się nie powiodło"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:943
 #, c-format
 msgid "Machine ID is %s."
 msgstr "Identyfikator komputera to %s."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:947
 #, c-format
 msgid "Session ID is %s."
 msgstr "Identyfikator sesji to %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:953
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "Używanie katalogu wykonywania %s."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:958
 #, c-format
 msgid "Using state directory %s."
 msgstr "Używanie katalogu stanu %s."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Using modules directory %s."
 msgstr "Używanie katalogu modułów %s."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:963
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Uruchamianie w trybie systemowym: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:966
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -373,15 +427,15 @@ msgstr ""
 "Proszę przeczytać http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode, "
 "gdzie wyjaśniono, dlaczego tryb systemowy jest zwykle złym pomysłem."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:983
 msgid "pa_pid_file_create() failed."
-msgstr "pa_pid_file_create() nie powiodło się."
+msgstr "pa_pid_file_create() się nie powiodło."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:993
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "Świeże zegary o wysokiej rozdzielczości! Smacznego!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:995
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -389,31 +443,32 @@ msgstr ""
 "Koleś, twoje jądro śmierdzi! Szef kuchni poleca dzisiaj Linuksa z włączonymi "
 "zegarami o wysokiej rozdzielczości!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1013
 msgid "pa_core_new() failed."
-msgstr "pa_core_new() nie powiodło się."
+msgstr "pa_core_new() się nie powiodło."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1091
 msgid "Failed to initialize daemon."
-msgstr "Zainicjowanie demona nie powiodło się."
+msgstr "Zainicjowanie usługi się nie powiodło."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1096
 msgid "Daemon startup without any loaded modules, refusing to work."
-msgstr "Uruchamianie demona bez żadnych wczytanych modułów, odmawianie pracy."
+msgstr ""
+"Uruchamianie usługi bez żadnych wczytanych modułów, odmawianie działania."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1134
 msgid "Daemon startup complete."
-msgstr "Ukończono uruchamianie demona."
+msgstr "Ukończono uruchamianie usługi."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1140
 msgid "Daemon shutdown initiated."
-msgstr "Zainicjowano wyłączenie demona."
+msgstr "Zainicjowano wyłączenie usługi."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1171
 msgid "Daemon terminated."
-msgstr "Demon został zniszczony."
+msgstr "Usługa została zniszczona."
 
-#: ../src/daemon/cmdline.c:115
+#: ../src/daemon/cmdline.c:113
 #, c-format
 msgid ""
 "%s [options]\n"
@@ -451,15 +506,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --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"
@@ -496,18 +549,18 @@ msgstr ""
 "      --dump-resample-methods           Zrzuca dostępne metody resamplingu\n"
 "      --cleanup-shm                     Czyści stare fragmenty pamięci\n"
 "                                        współdzielonej\n"
-"      --start                           Uruchamia demona, jeśli nie jest\n"
-"                                        uruchomiony\n"
-"  -k  --kill                            Niszczy uruchomionego demona\n"
-"      --check                           Sprawdza, czy demon jest\n"
-"                                        uruchomiony (zwraca tylko kod\n"
+"      --start                           Uruchamia usługi, jeśli nie jest\n"
+"                                        uruchomiona\n"
+"  -k  --kill                            Niszczy uruchomioną usługę\n"
+"      --check                           Sprawdza, czy usługa jest\n"
+"                                        uruchomiona (zwraca tylko kod\n"
 "                                        wyjścia)\n"
 "\n"
 "OPCJE:\n"
 "      --system[=ZMIENNALOGICZNA]        Uruchamia w trybie systemowym\n"
-"  -D, --daemonize[=ZMIENNALOGICZNA]     Tworzy demona po uruchomieniu\n"
-"      --fail[=ZMIENNALOGICZNA]          Wyłącza, kiedy uruchomienie nie\n"
-"                                        powiedzie się\n"
+"  -D, --daemonize[=ZMIENNALOGICZNA]     Tworzy usługę po uruchomieniu\n"
+"      --fail[=ZMIENNALOGICZNA]          Wyłącza, kiedy uruchomienie się nie\n"
+"                                        powiedzie\n"
 "      --high-priority[=ZMIENNALOGICZNA] Próbuje ustawić wysoki poziom nice\n"
 "                                        (dostępne tylko jako root, na SUID\n"
 "                                        lub z podniesionym RLIMIT_NICE)\n"
@@ -521,11 +574,8 @@ msgstr ""
 "                                        uruchomieniu\n"
 "      --disallow-exit[=ZMIENNALOGICZNA] Nie zezwala użytkownikowi na\n"
 "                                        żądanie wyłączenia\n"
-"      --exit-idle-time=SEKUNDY          Niszczy demona, kiedy jest zajęty i\n"
+"      --exit-idle-time=SEKUNDY          Niszczy usługę, kiedy jest zajęta i\n"
 "                                        upłynął podany czas\n"
-"      --module-idle-time=SEKUNDY        Usuwa automatycznie wczytane\n"
-"                                        moduły, kiedy jest zajęty i upłynął\n"
-"                                        podany czas\n"
 "      --scache-idle-time=SEKUNDY        Usuwa automatycznie wczytane\n"
 "                                        próbki, kiedy jest zajęty i upłynął\n"
 "                                        podany czas\n"
@@ -533,7 +583,8 @@ msgstr ""
 "                                        wyświetlanych informacji\n"
 "  -v                                    Zwiększa poziom wyświetlanych\n"
 "                                        informacji\n"
-"      --log-target={auto,syslog,stderr} Określa dziennik docelowy\n"
+"      --log-target={auto,syslog,stderr,file:ŚCIEŻKA,newfile:ŚCIEŻKA}\n"
+"                                        Określa dziennik docelowy\n"
 "      --log-meta[=ZMIENNALOGICZNA]      Dołącza położenie kodu do\n"
 "                                        komunikatów dziennika\n"
 "      --log-time[=ZMIENNALOGICZNA]      Dołącza czas w komunikatach\n"
@@ -563,11 +614,11 @@ msgstr ""
 "  -n                                    Nie wczytuje domyślnego pliku\n"
 "                                        skryptu\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:245
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize oczekuje parametru zmiennej logicznej"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:253
 msgid "--fail expects boolean argument"
 msgstr "--fail oczekuje parametru zmiennej logicznej"
 
@@ -583,164 +634,166 @@ msgstr ""
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority oczekuje parametru zmiennej logicznej"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:284
 msgid "--realtime expects boolean argument"
 msgstr "--realtime oczekuje parametru zmiennej logicznej"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:292
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading oczekuje parametru zmiennej logicznej"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:300
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit oczekuje parametru zmiennej logicznej"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:308
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file oczekuje parametru zmiennej logicznej"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:326
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>', 'newfile:<path>'."
 msgstr ""
-"Nieprawidłowy dziennik docelowy: należy użyć \"syslog\", \"stderr\" lub "
-"\"auto\"."
+"Nieprawidłowy dziennik docelowy: należy użyć \"syslog\", \"stderr\", \"auto"
+"\" lub prawidłowej nazwy pliku \"file:<ścieżka>\", \"newfile:<ścieżka>\"."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:333
 msgid "--log-time expects boolean argument"
 msgstr "--log-time oczekuje parametru zmiennej logicznej"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:341
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta oczekuje parametru zmiennej logicznej"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:361
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Nieprawidłowa metoda resamplingu \"%s\"."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:368
 msgid "--system expects boolean argument"
 msgstr "--system oczekuje parametru zmiennej logicznej"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:376
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit oczekuje parametru zmiennej logicznej"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:384
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm oczekuje parametru zmiennej logicznej"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Nazwa: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
-msgstr "Brak informacji o module\n"
+msgstr "Brak dostępnych informacji o module\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Wersja: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Opis: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Autor: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Użycie: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "Wczytanie jednorazowe: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "OSTRZEŻENIE O PRZESTARZAŁOŚCI: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Ścieżka: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Nieprawidłowy dziennik docelowy \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:322
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Nieprawidłowy poziom dziennika \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:337
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Nieprawidłowa metoda resamplingu \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:359
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] Nieprawidłowy rlimit \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit nie jest obsługiwany na tej platformie."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:379
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Nieprawidłowy format próbki \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:397 ../src/daemon/daemon-conf.c:415
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Nieprawidłowa częstotliwość próbki \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:438
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Nieprawidłowe kanały próbki \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:455
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] Nieprawidłowa mapa kanałów \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:472
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Nieprawidłowa liczba fragmentów \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:489
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Nieprawidłowy rozmiar fragmentu \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:506
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Nieprawidłowy poziom nice \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:549
+#, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Nieprawidłowy typ serwera \"%s\"."
+
+#: ../src/daemon/daemon-conf.c:662
 #, c-format
 msgid "Failed to open configuration file: %s"
-msgstr "Otwarcie pliku konfiguracji nie powiodło się: %s"
+msgstr "Otwarcie pliku konfiguracji się nie powiodło: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:678
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -748,12 +801,12 @@ msgstr ""
 "Podana domyślna mapa kanałów ma inną liczbę kanałów niż podana domyślna "
 "liczba kanałów."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:764
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Odczytano z pliku konfiguracji: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:54
 msgid "Cleaning up privileges."
 msgstr "Czyszczenie uprawnień."
 
@@ -765,6 +818,14 @@ msgstr "System dźwięku PulseAudio"
 msgid "Start the PulseAudio Sound System"
 msgstr "Uruchomienie systemu dźwięku PulseAudio"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "Polityka trasowania dla KDE systemu dźwięku PulseAudio"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "Uruchomienie systemu dźwięku PulseAudio z polityką trasowania dla KDE"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
@@ -794,7 +855,7 @@ msgid "Rear Right"
 msgstr "Tylny prawy"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
+msgid "Subwoofer"
 msgstr "Subwoofer"
 
 #: ../src/pulse/channelmap.c:117
@@ -815,131 +876,131 @@ msgstr "Boczny prawy"
 
 #: ../src/pulse/channelmap.c:123
 msgid "Auxiliary 0"
-msgstr "Pomocnicze 0"
+msgstr "Pomocniczy 0"
 
 #: ../src/pulse/channelmap.c:124
 msgid "Auxiliary 1"
-msgstr "Pomocnicze 1"
+msgstr "Pomocniczy 1"
 
 #: ../src/pulse/channelmap.c:125
 msgid "Auxiliary 2"
-msgstr "Pomocnicze 2"
+msgstr "Pomocniczy 2"
 
 #: ../src/pulse/channelmap.c:126
 msgid "Auxiliary 3"
-msgstr "Pomocnicze 3"
+msgstr "Pomocniczy 3"
 
 #: ../src/pulse/channelmap.c:127
 msgid "Auxiliary 4"
-msgstr "Pomocnicze 4"
+msgstr "Pomocniczy 4"
 
 #: ../src/pulse/channelmap.c:128
 msgid "Auxiliary 5"
-msgstr "Pomocnicze 5"
+msgstr "Pomocniczy 5"
 
 #: ../src/pulse/channelmap.c:129
 msgid "Auxiliary 6"
-msgstr "Pomocnicze 6"
+msgstr "Pomocniczy 6"
 
 #: ../src/pulse/channelmap.c:130
 msgid "Auxiliary 7"
-msgstr "Pomocnicze 7"
+msgstr "Pomocniczy 7"
 
 #: ../src/pulse/channelmap.c:131
 msgid "Auxiliary 8"
-msgstr "Pomocnicze 8"
+msgstr "Pomocniczy 8"
 
 #: ../src/pulse/channelmap.c:132
 msgid "Auxiliary 9"
-msgstr "Pomocnicze 9"
+msgstr "Pomocniczy 9"
 
 #: ../src/pulse/channelmap.c:133
 msgid "Auxiliary 10"
-msgstr "Pomocnicze 10"
+msgstr "Pomocniczy 10"
 
 #: ../src/pulse/channelmap.c:134
 msgid "Auxiliary 11"
-msgstr "Pomocnicze 11"
+msgstr "Pomocniczy 11"
 
 #: ../src/pulse/channelmap.c:135
 msgid "Auxiliary 12"
-msgstr "Pomocnicze 12"
+msgstr "Pomocniczy 12"
 
 #: ../src/pulse/channelmap.c:136
 msgid "Auxiliary 13"
-msgstr "Pomocnicze 13"
+msgstr "Pomocniczy 13"
 
 #: ../src/pulse/channelmap.c:137
 msgid "Auxiliary 14"
-msgstr "Pomocnicze 14"
+msgstr "Pomocniczy 14"
 
 #: ../src/pulse/channelmap.c:138
 msgid "Auxiliary 15"
-msgstr "Pomocnicze 15"
+msgstr "Pomocniczy 15"
 
 #: ../src/pulse/channelmap.c:139
 msgid "Auxiliary 16"
-msgstr "Pomocnicze 16"
+msgstr "Pomocniczy 16"
 
 #: ../src/pulse/channelmap.c:140
 msgid "Auxiliary 17"
-msgstr "Pomocnicze 17"
+msgstr "Pomocniczy 17"
 
 #: ../src/pulse/channelmap.c:141
 msgid "Auxiliary 18"
-msgstr "Pomocnicze 18"
+msgstr "Pomocniczy 18"
 
 #: ../src/pulse/channelmap.c:142
 msgid "Auxiliary 19"
-msgstr "Pomocnicze 19"
+msgstr "Pomocniczy 19"
 
 #: ../src/pulse/channelmap.c:143
 msgid "Auxiliary 20"
-msgstr "Pomocnicze 20"
+msgstr "Pomocniczy 20"
 
 #: ../src/pulse/channelmap.c:144
 msgid "Auxiliary 21"
-msgstr "Pomocnicze 21"
+msgstr "Pomocniczy 21"
 
 #: ../src/pulse/channelmap.c:145
 msgid "Auxiliary 22"
-msgstr "Pomocnicze 22"
+msgstr "Pomocniczy 22"
 
 #: ../src/pulse/channelmap.c:146
 msgid "Auxiliary 23"
-msgstr "Pomocnicze 23"
+msgstr "Pomocniczy 23"
 
 #: ../src/pulse/channelmap.c:147
 msgid "Auxiliary 24"
-msgstr "Pomocnicze 24"
+msgstr "Pomocniczy 24"
 
 #: ../src/pulse/channelmap.c:148
 msgid "Auxiliary 25"
-msgstr "Pomocnicze 25"
+msgstr "Pomocniczy 25"
 
 #: ../src/pulse/channelmap.c:149
 msgid "Auxiliary 26"
-msgstr "Pomocnicze 26"
+msgstr "Pomocniczy 26"
 
 #: ../src/pulse/channelmap.c:150
 msgid "Auxiliary 27"
-msgstr "Pomocnicze 27"
+msgstr "Pomocniczy 27"
 
 #: ../src/pulse/channelmap.c:151
 msgid "Auxiliary 28"
-msgstr "Pomocnicze 28"
+msgstr "Pomocniczy 28"
 
 #: ../src/pulse/channelmap.c:152
 msgid "Auxiliary 29"
-msgstr "Pomocnicze 29"
+msgstr "Pomocniczy 29"
 
 #: ../src/pulse/channelmap.c:153
 msgid "Auxiliary 30"
-msgstr "Pomocnicze 30"
+msgstr "Pomocniczy 30"
 
 #: ../src/pulse/channelmap.c:154
 msgid "Auxiliary 31"
-msgstr "Pomocnicze 31"
+msgstr "Pomocniczy 31"
 
 #: ../src/pulse/channelmap.c:156
 msgid "Top Center"
@@ -969,9 +1030,10 @@ msgstr "Górny tylny lewy"
 msgid "Top Rear Right"
 msgstr "Górny tylny prawy"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:122
 msgid "(invalid)"
 msgstr "(nieprawidłowe)"
 
@@ -999,331 +1061,347 @@ msgstr "Surround 5.1"
 msgid "Surround 7.1"
 msgstr "Surround 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "OK"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
-msgstr "Odmówiono dostępu"
+msgstr "Odmowa dostępu"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Nieznane polecenie"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "Nieprawidłowy parametr"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "Jednostka istnieje"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "Brak jednostki"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "Odrzucono połączenie"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "Błąd protokołu"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "Przekroczono czas oczekiwania"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "Brak klucza upoważnienia"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "Wewnętrzny błąd"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "Zniszczono połączenie"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "Zniszczono jednostkę"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Nieprawidłowy serwer"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
-msgstr "Zainicjowanie modułu nie powiodło się"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
+msgstr "Zainicjowanie modułu się nie powiodło"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "Błędny stan"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Brak danych"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "Niezgodna wersja protokołu"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "Za duże"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "Nieobsługiwane"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Nieznany kod błędu"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "Nie ma takiego rozszerzenia"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "Przestarzała funkcjonalność"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "Brak implementacji"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "Rozdzielono klienta"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "Błąd wejścia/wyjścia"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "Urządzenie lub zasób jest zajęty"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() nie powiodło się"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+msgid "xcb_connect() failed"
+msgstr "xcb_connect() się nie powiodło: %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr "xcb_connection_has_error() zwróciło wartość \"true\""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
-msgstr "Przetworzenie danych ciasteczka nie powiodło się"
+msgstr "Przetworzenie danych ciasteczka się nie powiodło"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
-msgstr "Otwarcie pliku konfiguracji \"%s\" nie powiodło się: %s"
+msgstr "Otwarcie pliku konfiguracji \"%s\" się nie powiodło: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "Nie wczytano ciasteczka. Próba połączenia się bez niego."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:609
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:664
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1365
 #, c-format
 msgid "Received message for unknown extension '%s'"
-msgstr "Otrzymano komunikat z nieznanego powodu \"%s\""
+msgstr "Otrzymano komunikat dla nieznanego rozszerzenia \"%s\""
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:116
 #, c-format
 msgid "Failed to drain stream: %s"
-msgstr "Opróżnienie strumienia nie powiodło się: %s"
+msgstr "Opróżnienie strumienia się nie powiodło: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:121
 msgid "Playback stream drained."
 msgstr "Opróżniono strumień odtwarzania."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:132
 msgid "Draining connection to server."
 msgstr "Opróżnianie połączenia z serwerem."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:145
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:168
 #, c-format
 msgid "pa_stream_write() failed: %s"
-msgstr "pa_stream_write() nie powiodło się: %s"
+msgstr "pa_stream_write() się nie powiodło: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:209
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
-msgstr "pa_stream_begin_write() nie powiodło się: %s"
+msgstr "pa_stream_begin_write() się nie powiodło: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:259 ../src/utils/pacat.c:289
 #, c-format
 msgid "pa_stream_peek() failed: %s"
-msgstr "pa_stream_peek() nie powiodło się: %s"
+msgstr "pa_stream_peek() się nie powiodło: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:339
 msgid "Stream successfully created."
 msgstr "Pomyślnie utworzono strumień."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:342
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
-msgstr "pa_stream_get_buffer_attr() nie powiodło się: %s"
+msgstr "pa_stream_get_buffer_attr() się nie powiodło: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:346
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 msgstr "Metryka bufora: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:349
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Metryka bufora: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "Używanie przykładowej specyfikacji \"%s\", mapa kanałów \"%s\"."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:357
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "Połączono się z urządzeniem %s (%u, %swstrzymane)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:367
 #, c-format
 msgid "Stream error: %s"
 msgstr "Błąd strumienia: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:377
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "Wstrzymano urządzenie strumienia.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:379
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "Wznowiono urządzenie strumienia.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream underrun.%s"
-msgstr "Niedopełniono strumień.%s"
+msgstr "Niedopełniony strumień.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream overrun.%s"
-msgstr "Przepełniono strumień.%s"
+msgstr "Przepełniony strumień.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream started.%s"
 msgstr "Utworzono strumień.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:408
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "Strumień został przeniesiony do urządzenia %s (%u, %swstrzymane).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:408
 msgid "not "
 msgstr "nie "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:415
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "Zmieniono atrybuty bufora strumienia.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:430
+msgid "Cork request stack is empty: corking stream"
+msgstr "Stos żądań korka jest pusty: zatykanie strumienia"
+
+#: ../src/utils/pacat.c:436
+msgid "Cork request stack is empty: uncorking stream"
+msgstr "Stos żądań korka jest pusty: odtykanie strumienia"
+
+#: ../src/utils/pacat.c:440
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr "Ostrzeżenie: otrzymano więcej żądań odetkania niż żądań zatkania."
+
+#: ../src/utils/pacat.c:465
 #, c-format
 msgid "Connection established.%s"
 msgstr "Ustanowiono połączenie.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:468
 #, c-format
 msgid "pa_stream_new() failed: %s"
-msgstr "pa_stream_new() nie powiodło się: %s"
+msgstr "pa_stream_new() się nie powiodło: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:506
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
-msgstr "pa_stream_connect_playback() nie powiodło się: %s"
+msgstr "pa_stream_connect_playback() się nie powiodło: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:512
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
-msgstr "pa_stream_connect_record() nie powiodło się: %s"
+msgstr "pa_stream_connect_record() się nie powiodło: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:526 ../src/utils/pactl.c:1406
 #, c-format
 msgid "Connection failure: %s"
-msgstr "Połączenie nie powiodło się: %s"
+msgstr "Połączenie się nie powiodło: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:559
 msgid "Got EOF."
 msgstr "Otrzymano EOF."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:596
 #, c-format
 msgid "write() failed: %s"
-msgstr "write() nie powiodło się: %s"
+msgstr "write() się nie powiodło: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:617
 msgid "Got signal, exiting."
-msgstr "Otrzymano sygnał, kończenie pracy."
+msgstr "Otrzymano sygnał, kończenie działania."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:631
 #, c-format
 msgid "Failed to get latency: %s"
-msgstr "Uzyskanie opóźnienia nie powiodło się: %s"
+msgstr "Uzyskanie opóźnienia się nie powiodło: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:636
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Czas: %0.3f sekundy; opóźnienie: %0.0f usekundy."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:657
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
-msgstr "pa_stream_update_timing_info() nie powiodło się: %s"
+msgstr "pa_stream_update_timing_info() się nie powiodło: %s"
 
-#: ../src/utils/pacat.c:609
+#: ../src/utils/pacat.c:667
 #, c-format
 msgid ""
 "%s [options]\n"
@@ -1376,10 +1454,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [opcje]\n"
@@ -1430,15 +1513,20 @@ msgstr ""
 "                                        bajtach.\n"
 "      --process-time=BAJTY              Żąda określonego czasu procesu na\n"
 "                                        żądanie w bajtach.\n"
+"      --latency-msec=MSEKUNDY           Żąda określonego opóźnienia w\n"
+"                                        milisekundach.\n"
+"      --process-time-msec=MSEKUNDY      Żąda określonego czasu procesu na\n"
+"                                        żądanie w milisekundach.\n"
 "      --property=WŁASNOŚĆ=WARTOŚĆ       Ustawia podaną własność na podaną\n"
 "                                        wartość.\n"
 "      --raw                             Nagrywa/odtwarza surowe dane PCM.\n"
-"      --file-format=FFORMAT             Nagrywa/odtwarza sformatowane dane\n"
+"      --passthrough                     Przekazuje dane.\n"
+"      --file-format=[=FFORMAT]          Nagrywa/odtwarza sformatowane dane\n"
 "                                        PCM.\n"
 "      --list-file-formats               Wyświetla listę dostępnych formatów\n"
 "                                        plików.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:802
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1449,68 +1537,68 @@ msgstr ""
 "Skompilowane za pomocą libpulse %s\n"
 "Skonsolidowane za pomocą libpulse %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:835 ../src/utils/pactl.c:1577
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "Nieprawidłowa nazwa klienta \"%s\""
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:850
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "Nieprawidłowa nazwa strumienia \"%s\""
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:887
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "Nieprawidłowa mapa kanałów \"%s\""
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:916 ../src/utils/pacat.c:930
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "Nieprawidłowe określenie opóźnienia \"%s\""
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:923 ../src/utils/pacat.c:937
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "Nieprawidłowe określenie czasu procesu \"%s\""
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:949
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "Nieprawidłowa własność \"%s\""
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:968
 #, c-format
 msgid "Unknown file format %s."
 msgstr "Nieznany format pliku %s."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:987
 msgid "Invalid sample specification"
 msgstr "Nieprawidłowe określenie próbki"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:997
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:1002
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:1009
 msgid "Too many arguments."
 msgstr "Za dużo parametrów."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1020
 msgid "Failed to generate sample specification for file."
-msgstr "Utworzenie określenia próbki dla pliku nie powiodło się."
+msgstr "Utworzenie określenia próbki dla pliku się nie powiodło."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1046
 msgid "Failed to open audio file."
-msgstr "Otwarcie pliku dźwiękowego nie powiodło się."
+msgstr "Otwarcie pliku dźwiękowego się nie powiodło."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1052
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
@@ -1518,23 +1606,23 @@ msgstr ""
 "Ostrzeżenie: podane określenie próbki zostanie zastąpione przez określenie z "
 "pliku."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1055 ../src/utils/pactl.c:1644
 msgid "Failed to determine sample specification from file."
-msgstr "Ustalenie określenia próbki z pliku nie powiodło się."
+msgstr "Ustalenie określenia próbki z pliku nie się nie powiodło."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1064
 msgid "Warning: Failed to determine channel map from file."
-msgstr "Ostrzeżenie: ustalenie mapy kanałów z pliku nie powiodło się."
+msgstr "Ostrzeżenie: ustalenie mapy kanałów z pliku się nie powiodło."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1075
 msgid "Channel map doesn't match sample specification"
 msgstr "Mapa kanałów nie zgadza się z określeniem próbki"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1086
 msgid "Warning: failed to write channel map to file."
-msgstr "Ostrzeżenie: zapisanie mapy kanałów do pliku nie powiodło się."
+msgstr "Ostrzeżenie: zapisanie mapy kanałów do pliku się nie powiodło."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1101
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
@@ -1542,81 +1630,85 @@ msgstr ""
 "Otwieranie strumienia %s za pomocą określenie próbki \"%s\" i mapy kanałów "
 "\"%s\"."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1102
 msgid "recording"
 msgstr "nagrywanie"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1102
 msgid "playback"
 msgstr "odtwarzanie"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1126
+msgid "Failed to set media name."
+msgstr "Ustawienie nazwy nośnika się nie powiodło."
+
+#: ../src/utils/pacat.c:1133 ../src/utils/pactl.c:1994
 msgid "pa_mainloop_new() failed."
-msgstr "pa_mainloop_new() nie powiodło się."
+msgstr "pa_mainloop_new() się nie powiodło."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1156
 msgid "io_new() failed."
-msgstr "io_new() nie powiodło się."
+msgstr "io_new() się nie powiodło."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1163 ../src/utils/pactl.c:2006
 msgid "pa_context_new() failed."
-msgstr "pa_context_new() nie powiodło się."
+msgstr "pa_context_new() się nie powiodło."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1171 ../src/utils/pactl.c:2012
 #, c-format
 msgid "pa_context_connect() failed: %s"
-msgstr "pa_context_connect() nie powiodło się: %s"
+msgstr "pa_context_connect() się nie powiodło: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1177
 msgid "pa_context_rttime_new() failed."
-msgstr "pa_context_rttime_new() nie powiodło się."
+msgstr "pa_context_rttime_new() się nie powiodło."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1184 ../src/utils/pactl.c:2017
 msgid "pa_mainloop_run() failed."
-msgstr "pa_mainloop_run() nie powiodło się."
+msgstr "pa_mainloop_run() się nie powiodło."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
-msgstr "Wstrzymanie nie powiodło się: %s\n"
+msgstr "Wstrzymanie się nie powiodło: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
-msgstr "Wznowienie nie powiodło się: %s\n"
+msgstr "Wznowienie się nie powiodło: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr ""
 "OSTRZEŻENIE: serwer dźwięku nie jest lokalny, nie zostanie wstrzymany.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
-msgstr "Połączenie nie powiodło się: %s\n"
+msgstr "Połączenie się nie powiodło: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
-msgstr "Otrzymano SIGINT, kończenie pracy.\n"
+msgstr "Otrzymano SIGINT, kończenie działania.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "OSTRZEŻENIE: proces potomny został zniszczony przez sygnał %u\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1648,49 +1740,66 @@ msgstr ""
 #: ../src/utils/pasuspender.c:277
 #, c-format
 msgid "pa_mainloop_new() failed.\n"
-msgstr "pa_mainloop_new() nie powiodło się.\n"
+msgstr "pa_mainloop_new() się nie powiodło.\n"
 
 #: ../src/utils/pasuspender.c:290
 #, c-format
 msgid "pa_context_new() failed.\n"
-msgstr "pa_context_new() nie powiodło się.\n"
+msgstr "pa_context_new() się nie powiodło.\n"
 
-#: ../src/utils/pasuspender.c:298
+#: ../src/utils/pasuspender.c:302
 #, c-format
 msgid "pa_mainloop_run() failed.\n"
-msgstr "pa_mainloop_run() nie powiodło się.\n"
+msgstr "pa_mainloop_run() się nie powiodło.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:161
 #, c-format
 msgid "Failed to get statistics: %s"
-msgstr "Uzyskanie statystyk nie powiodło się: %s"
+msgstr "Uzyskanie statystyk się nie powiodło: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:167
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "Obecnie używane: %u bloków zawierających razem %s bajtów.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:170
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr ""
 "Przydzielono podczas całego czasu uruchomienia: %u bloków zawierających "
 "razem %s bajtów.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:173
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "Rozmiar pamięci podręcznej próbek: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:182
 #, c-format
 msgid "Failed to get server information: %s"
-msgstr "Uzyskanie informacji o serwerze nie powiodło się: %s"
+msgstr "Uzyskanie informacji o serwerze się nie powiodło: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:187
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+"Ciąg serwera: %s\n"
+"Wersja protokołu biblioteki: %u\n"
+"Wersja protokołu serwera: %u\n"
+"Czy jest lokalny: %s\n"
+"Indeks klienta: %u\n"
+"Rozmiar kafla: %zu\n"
+
+#: ../src/utils/pactl.c:203
+#, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1698,7 +1807,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "Nazwa użytkownika: %s\n"
 "Nazwa komputera: %s\n"
@@ -1708,14 +1817,14 @@ msgstr ""
 "Domyślna mapa kanałów: %s\n"
 "Domyślny odpływ: %s\n"
 "Domyślne źródło: %s\n"
-"Ciasteczko: %08x\n"
+"Ciasteczko: %04x:%04x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:255 ../src/utils/pactl.c:897 ../src/utils/pactl.c:971
 #, c-format
 msgid "Failed to get sink information: %s"
-msgstr "Uzyskanie informacji o odpływie nie powiodło się: %s"
+msgstr "Uzyskanie informacji o odpływie się nie powiodło: %s"
 
-#: ../src/utils/pactl.c:221
+#: ../src/utils/pactl.c:281
 #, c-format
 msgid ""
 "Sink #%u\n"
@@ -1732,7 +1841,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1750,26 +1859,31 @@ msgstr ""
 "\tGłośność podstawowa: %s%s%s\n"
 "\tŹródło monitora: %s\n"
 "\tOpóźnienie: %0.0f usekundy, skonfigurowano %0.0f usekundy\n"
-"\tFlagi: %s%s%s%s%s%s\n"
+"\tFlagi: %s%s%s%s%s%s%s\n"
 "\tWłaściwości:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:329 ../src/utils/pactl.c:441 ../src/utils/pactl.c:601
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tPorty:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:336 ../src/utils/pactl.c:448
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tAktywny port: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:342 ../src/utils/pactl.c:454
+#, c-format
+msgid "\tFormats:\n"
+msgstr "\tFormaty:\n"
+
+#: ../src/utils/pactl.c:368 ../src/utils/pactl.c:916 ../src/utils/pactl.c:986
 #, c-format
 msgid "Failed to get source information: %s"
-msgstr "Uzyskanie informacji o źródle nie powiodło się: %s"
+msgstr "Uzyskanie informacji o źródle się nie powiodło: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:394
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1808,20 +1922,20 @@ msgstr ""
 "\tWłaściwości:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:426 ../src/utils/pactl.c:496 ../src/utils/pactl.c:539
+#: ../src/utils/pactl.c:581 ../src/utils/pactl.c:679 ../src/utils/pactl.c:680
+#: ../src/utils/pactl.c:692 ../src/utils/pactl.c:752 ../src/utils/pactl.c:753
+#: ../src/utils/pactl.c:765 ../src/utils/pactl.c:817 ../src/utils/pactl.c:818
+#: ../src/utils/pactl.c:825
 msgid "n/a"
 msgstr "nie dotyczy"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:465 ../src/utils/pactl.c:872
 #, c-format
 msgid "Failed to get module information: %s"
-msgstr "Uzyskanie informacji o module nie powiodło się: %s"
+msgstr "Uzyskanie informacji o module się nie powiodło: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:488
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1838,12 +1952,12 @@ msgstr ""
 "\tWłaściwości:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:507
 #, c-format
 msgid "Failed to get client information: %s"
-msgstr "Uzyskanie informacji o kliencie nie powiodło się: %s"
+msgstr "Uzyskanie informacji o kliencie się nie powiodło: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:533
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1858,12 +1972,12 @@ msgstr ""
 "\tWłaściwości:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:550
 #, c-format
 msgid "Failed to get card information: %s"
-msgstr "Uzyskanie informacji o karcie nie powiodło się: %s"
+msgstr "Uzyskanie informacji o karcie się nie powiodło: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:573
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1880,22 +1994,36 @@ msgstr ""
 "\tWłaściwości:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:589
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tProfile:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:595
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tAktywny profil: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:609
+#, c-format
+msgid ""
+"\t\t\tProperties:\n"
+"\t\t\t\t%s\n"
+msgstr ""
+"\t\t\tWłaściwości:\n"
+"\t\t\t\t%s\n"
+
+#: ../src/utils/pactl.c:614
+#, c-format
+msgid "\t\t\tPart of profile(s): %s"
+msgstr "\t\t\tCzęść profilu: %s"
+
+#: ../src/utils/pactl.c:631 ../src/utils/pactl.c:935 ../src/utils/pactl.c:1001
 #, c-format
 msgid "Failed to get sink input information: %s"
-msgstr "Uzyskanie informacji o wejściu odpływu nie powiodło się: %s"
+msgstr "Uzyskanie informacji o wejściu odpływu się nie powiodło: %s"
 
-#: ../src/utils/pactl.c:515
+#: ../src/utils/pactl.c:660
 #, c-format
 msgid ""
 "Sink Input #%u\n"
@@ -1905,6 +2033,8 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tCorked: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1922,6 +2052,8 @@ msgstr ""
 "\tOdpływ: %u\n"
 "\tOkreślenie próbki: %s\n"
 "\tMapa kanałów: %s\n"
+"\tFormat: %s\n"
+"\tZakorkowane: %s\n"
 "\tWyciszenie: %s\n"
 "\tPoziom głośności: %s\n"
 "\t                  %s\n"
@@ -1932,12 +2064,12 @@ msgstr ""
 "\tWłaściwości:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:703 ../src/utils/pactl.c:954 ../src/utils/pactl.c:1016
 #, c-format
 msgid "Failed to get source output information: %s"
-msgstr "Uzyskanie informacji o wyjściu źródła nie powiodło się: %s"
+msgstr "Uzyskanie informacji o wyjściu źródła się nie powiodło: %s"
 
-#: ../src/utils/pactl.c:574
+#: ../src/utils/pactl.c:733
 #, c-format
 msgid ""
 "Source Output #%u\n"
@@ -1947,31 +2079,43 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tCorked: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Źródło wyjścia #%u\n"
+"Odpływ wejścia #%u\n"
 "\tSterownik: %s\n"
 "\tWłaściciel modułu: %s\n"
 "\tKlient: %s\n"
-"\tŹródło: %u\n"
+"\tOdpływ: %u\n"
 "\tOkreślenie próbki: %s\n"
 "\tMapa kanałów: %s\n"
+"\tFormat: %s\n"
+"\tZakorkowane: %s\n"
+"\tWyciszenie: %s\n"
+"\tPoziom głośności: %s\n"
+"\t                  %s\n"
+"\t                  balans %0.2f\n"
 "\tOpóźnienie bufora: %0.0f usekundy\n"
-"\tOpóźnienie źródła: %0.0f usekundy\n"
+"\tOpóźnienie odpływu: %0.0f usekundy\n"
 "\tMetoda resamplingu: %s\n"
 "\tWłaściwości:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:776
 #, c-format
 msgid "Failed to get sample information: %s"
-msgstr "Uzyskanie informacji o próbce nie powiodło się: %s"
+msgstr "Uzyskanie informacji o próbce się nie powiodło: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:803
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -2002,48 +2146,189 @@ msgstr ""
 "\tWłaściwości:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:833 ../src/utils/pactl.c:843
 #, c-format
 msgid "Failure: %s"
 msgstr "Niepowodzenie: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:879
+#, c-format
+msgid "Failed to unload module: Module %s not loaded"
+msgstr ""
+"Usunięcie modułu z pamięci się nie powiodło: moduł %s nie jest wczytany"
+
+#: ../src/utils/pactl.c:1042
+#, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Ustawienie formatu się nie powiodło: nieprawidłowy ciąg formatu %s"
+
+#: ../src/utils/pactl.c:1081
 #, c-format
 msgid "Failed to upload sample: %s"
-msgstr "Wysłanie próbki nie powiodło się: %s"
+msgstr "Wysłanie próbki się nie powiodło: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:1098
 msgid "Premature end of file"
 msgstr "Przedwczesny koniec pliku"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:1118
+msgid "new"
+msgstr "nowy"
+
+#: ../src/utils/pactl.c:1121
+msgid "change"
+msgstr "zmień"
+
+#: ../src/utils/pactl.c:1124
+msgid "remove"
+msgstr "usuń"
+
+#: ../src/utils/pactl.c:1127 ../src/utils/pactl.c:1162
+msgid "unknown"
+msgstr "nieznany"
+
+#: ../src/utils/pactl.c:1135
+msgid "sink"
+msgstr "odpływ"
+
+#: ../src/utils/pactl.c:1138
+msgid "source"
+msgstr "źródło"
+
+#: ../src/utils/pactl.c:1141
+msgid "sink-input"
+msgstr "wejście-odpływu"
+
+#: ../src/utils/pactl.c:1144
+msgid "source-output"
+msgstr "wyjście-źródła"
+
+#: ../src/utils/pactl.c:1147
+msgid "module"
+msgstr "moduł"
+
+#: ../src/utils/pactl.c:1150
+msgid "client"
+msgstr "klient"
+
+#: ../src/utils/pactl.c:1153
+msgid "sample-cache"
+msgstr "bufor-próbki"
+
+#: ../src/utils/pactl.c:1156 ../src/utils/pactl.c:1159
+msgid "server"
+msgstr "serwer"
+
+#: ../src/utils/pactl.c:1168
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr "Zdarzenie \"%s\" w %s #%u\n"
+
+#: ../src/utils/pactl.c:1412
 msgid "Got SIGINT, exiting."
-msgstr "Otrzymano SIGINT, kończenie pracy."
+msgstr "Otrzymano SIGINT, kończenie działania."
+
+#: ../src/utils/pactl.c:1439
+msgid "Invalid volume specification"
+msgstr "Nieprawidłowe określenie głośności"
+
+#: ../src/utils/pactl.c:1462
+msgid "Volume outside permissible range.\n"
+msgstr "Głośność jest poza dozwolonym zakresem.\n"
+
+#: ../src/utils/pactl.c:1492 ../src/utils/pactl.c:1493
+#: ../src/utils/pactl.c:1494 ../src/utils/pactl.c:1495
+#: ../src/utils/pactl.c:1496 ../src/utils/pactl.c:1497
+#: ../src/utils/pactl.c:1498 ../src/utils/pactl.c:1499
+#: ../src/utils/pactl.c:1500 ../src/utils/pactl.c:1501
+#: ../src/utils/pactl.c:1502 ../src/utils/pactl.c:1503
+#: ../src/utils/pactl.c:1504 ../src/utils/pactl.c:1505
+#: ../src/utils/pactl.c:1506 ../src/utils/pactl.c:1507
+#: ../src/utils/pactl.c:1508 ../src/utils/pactl.c:1509
+#: ../src/utils/pactl.c:1510 ../src/utils/pactl.c:1511
+#: ../src/utils/pactl.c:1512
+msgid "[options]"
+msgstr "[opcje]"
+
+#: ../src/utils/pactl.c:1494
+msgid "[TYPE]"
+msgstr "[TYP]"
+
+#: ../src/utils/pactl.c:1496
+msgid "FILENAME [NAME]"
+msgstr "NAZWA-PLIKU [NAZWA]"
+
+#: ../src/utils/pactl.c:1497
+msgid "NAME [SINK]"
+msgstr "NAZWA [ODPŁYW]"
+
+#: ../src/utils/pactl.c:1498 ../src/utils/pactl.c:1504 ../src/utils/pacmd.c:55
+#: ../src/utils/pacmd.c:65
+msgid "NAME"
+msgstr "NAZWA"
+
+#: ../src/utils/pactl.c:1499 ../src/utils/pacmd.c:53
+msgid "NAME [ARGS ...]"
+msgstr "NAZWA [PARAMETRY...]"
+
+#: ../src/utils/pactl.c:1500 ../src/utils/pacmd.c:54 ../src/utils/pacmd.c:62
+msgid "NAME|#N"
+msgstr "NAZWA|#N"
+
+#: ../src/utils/pactl.c:1501 ../src/utils/pacmd.c:71
+msgid "#N SINK|SOURCE"
+msgstr "#N ODPŁYW|ŹRÓDŁO"
+
+#: ../src/utils/pactl.c:1502 ../src/utils/pacmd.c:58 ../src/utils/pacmd.c:72
+msgid "NAME|#N 1|0"
+msgstr "NAZWA|#N 1|0"
+
+#: ../src/utils/pactl.c:1503 ../src/utils/pacmd.c:74
+msgid "CARD PROFILE"
+msgstr "PROFIL KARTY"
+
+#: ../src/utils/pactl.c:1505 ../src/utils/pacmd.c:75
+msgid "NAME|#N PORT"
+msgstr "NAZWA|#N PORT"
+
+#: ../src/utils/pactl.c:1506 ../src/utils/pacmd.c:56
+msgid "NAME|#N VOLUME"
+msgstr "NAZWA|#N GŁOŚNOŚĆ"
+
+#: ../src/utils/pactl.c:1507 ../src/utils/pacmd.c:57
+msgid "#N VOLUME"
+msgstr "#N GŁOŚNOŚĆ"
+
+#: ../src/utils/pactl.c:1508
+msgid "NAME|#N 1|0|toggle"
+msgstr "NAZWA|#N 1|0|przełącznik"
+
+#: ../src/utils/pactl.c:1509
+msgid "#N 1|0|toggle"
+msgstr "#N 1|0|przełącznik"
+
+#: ../src/utils/pactl.c:1510
+msgid "#N FORMATS"
+msgstr "#N FORMATY"
+
+#: ../src/utils/pactl.c:1511 ../src/utils/pacmd.c:76
+msgid "CARD-NAME|CARD-#N PORT OFFSET"
+msgstr "NAZWA-KARTY|KARTA-#N PORT OFFSET"
+
+#: ../src/utils/pactl.c:1513
+#, c-format
+msgid ""
+"\n"
+"The special names @DEFAULT_SINK@, @DEFAULT_SOURCE@ and @DEFAULT_MONITOR@\n"
+"can be used to specify the default sink, source and monitor.\n"
+msgstr ""
+"\n"
+"Specjalne nazwy @DEFAULT_SINK@, @DEFAULT_SOURCE@ i @DEFAULT_MONITOR@\n"
+"mogą być używane do podania domyślnego odpływu, źródła i monitora.\n"
 
-#: ../src/utils/pactl.c:869
+#: ../src/utils/pactl.c:1516
 #, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2053,36 +2338,14 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [opcje] stat\n"
-"%s [opcje] list\n"
-"%s [opcje] exit\n"
-"%s [opcje] upload-sample NAZWAPLIKU [NAZWA]\n"
-"%s [opcje] play-sample NAZWA [ODPŁYW]\n"
-"%s [opcje] remove-sample NAZWA\n"
-"%s [opcje] move-sink-input WEJŚCIE_ODPŁYWU ODPŁYW\n"
-"%s [opcje] move-source-output WYJŚCIE_ODPŁYWU ŹRÓDŁO\n"
-"%s [opcje] load-module NAZWA [PARAMETRY...]\n"
-"%s [opcje] unload-module MODUŁ\n"
-"%s [opcje] suspend-sink SINK 1|0\n"
-"%s [opcje] suspend-source SOURCE 1|0\n"
-"%s [opcje] set-card-profile KARTA PROFIL\n"
-"%s [opcje] set-sink-port ODPŁYW PORT\n"
-"%s [opcje] set-source-port ŹRÓDŁO PORT\n"
-"%s [opcje] set-sink-volume ODPŁYW GŁOŚNOŚĆ\n"
-"%s [opcje] set-source-volume ŹRÓDŁO GŁOŚNOŚĆ\n"
-"%s [opcje] set-sink-input-volume WYJŚCIE_ODPŁYWU GŁOŚNOŚĆ\n"
-"%s [opcje] set-sink-mute ODPŁYW 1|0\n"
-"%s [opcje] set-source-mute ŹRÓDŁO 1|0\n"
-"%s [opcje] set-sink-input-mute WEJŚCIE_ODPŁYWU 1|0\n"
-"\n"
 "\n"
 "  -h, --help                            Wyświetla tę pomoc\n"
 "      --version                         Wyświetla wersję\n"
 "\n"
 "  -s, --server=SERWER                   Nazwa serwera do połączenia się\n"
-"  -n, --client-name=NAZWA               Jak nazwać tego klienta na serwerze\n"
+"  -n, --client-name=NAZWA               Jak nazwać tego klienta w serwerze\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1557
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2093,106 +2356,154 @@ msgstr ""
 "Skompilowane za pomocą libpulse %s\n"
 "Skonsolidowane za pomocą libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1616
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr "Należy podać nic lub jedno z: %s"
+
+#: ../src/utils/pactl.c:1626
 msgid "Please specify a sample file to load"
 msgstr "Proszę podać plik próbki do wczytania"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1639
 msgid "Failed to open sound file."
-msgstr "Otwarcie pliku dźwiękowego nie powiodło się."
+msgstr "Otwarcie pliku dźwiękowego się nie powiodło."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1651
 msgid "Warning: Failed to determine sample specification from file."
-msgstr "Ostrzeżenie: ustalenie określenia próbki z pliku nie powiodło się."
+msgstr "Ostrzeżenie: ustalenie określenia próbki z pliku się nie powiodło."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1661
 msgid "You have to specify a sample name to play"
 msgstr "Należy podać nazwę próbki do odtworzenia"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1673
 msgid "You have to specify a sample name to remove"
 msgstr "Należy podać nazwę próbki do usunięcia"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1682
 msgid "You have to specify a sink input index and a sink"
 msgstr "Należy podać indeks odpływu wejścia i odpływ"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1692
 msgid "You have to specify a source output index and a source"
 msgstr "Należy podać indeks źródła wyjścia i źródło"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1707
 msgid "You have to specify a module name and arguments."
 msgstr "Należy podać nazwę modułu i parametry."
 
-#: ../src/utils/pactl.c:1080
-msgid "You have to specify a module index"
-msgstr "Należy podać indeks modułu"
+#: ../src/utils/pactl.c:1727
+msgid "You have to specify a module index or name"
+msgstr "Należy podać indeks lub nazwę modułu"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1740
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "Nie można podać więcej niż jednego odpływu. Należy podać wartość logiczną."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1745 ../src/utils/pactl.c:1765
+msgid "Invalid suspend specification."
+msgstr "Nieprawidłowe określenie uśpienia."
+
+#: ../src/utils/pactl.c:1760
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr ""
 "Nie można podać więcej niż jednego źródła. Należy podać wartość logiczną."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1777
 msgid "You have to specify a card name/index and a profile name"
 msgstr "Należy podać nazwę karty/indeks i nazwę profilu"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1788
 msgid "You have to specify a sink name/index and a port name"
 msgstr "Należy podać nazwę odpływu/indeks i nazwę portu"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1799
+msgid "You have to specify a sink name"
+msgstr "Należy podać nazwę odpływu"
+
+#: ../src/utils/pactl.c:1809
 msgid "You have to specify a source name/index and a port name"
 msgstr "Należy podać nazwę źródła/indeks i nazwę portu"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1820
+msgid "You have to specify a source name"
+msgstr "Należy podać nazwę źródła"
+
+#: ../src/utils/pactl.c:1830
 msgid "You have to specify a sink name/index and a volume"
 msgstr "Należy podać nazwę odpływu/indeks i głośność"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "Nieprawidłowe określenie głośności"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1843
 msgid "You have to specify a source name/index and a volume"
 msgstr "Należy podać nazwę źródła/indeks i głośność"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1856
 msgid "You have to specify a sink input index and a volume"
 msgstr "Należy podać indeks odpływu wejścia i głośność"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1861
 msgid "Invalid sink input index"
 msgstr "Nieprawidłowy indeks wejścia odpływu"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1872
+msgid "You have to specify a source output index and a volume"
+msgstr "Należy podać indeks źródła wyjścia i głośność"
+
+#: ../src/utils/pactl.c:1877
+msgid "Invalid source output index"
+msgstr "Nieprawidłowy indeks wejścia źródła"
+
+#: ../src/utils/pactl.c:1888
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "Należy podać nazwę odpływu/indeks i zmienną logiczną wyciszenia"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1893 ../src/utils/pactl.c:1908
+#: ../src/utils/pactl.c:1928 ../src/utils/pactl.c:1946
+msgid "Invalid mute specification"
+msgstr "Nieprawidłowe określenie wyciszenia"
+
+#: ../src/utils/pactl.c:1903
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "Należy podać nazwę źródła/indeks i zmienną logiczną wyciszenia"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1918
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "Należy podać indeks odpływu wejścia i zmienną logiczną wyciszenia"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1923
 msgid "Invalid sink input index specification"
 msgstr "Nieprawidłowe określenie indeksu wejścia odpływu"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1936
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "Należy podać nazwę indeks wyjścia źródła i zmienną logiczną wyciszenia"
+
+#: ../src/utils/pactl.c:1941
+msgid "Invalid source output index specification"
+msgstr "Nieprawidłowe określenie indeksu wyjścia źródła"
+
+#: ../src/utils/pactl.c:1958
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr ""
+"Należy podać nazwę indeks odpływu listę obsługiwanych formatów oddzielonych "
+"średnikami"
+
+#: ../src/utils/pactl.c:1970
+msgid "You have to specify a card name/index, a port name and a latency offset"
+msgstr "Należy podać nazwę karty/indeks, nazwę portu i offset opóźnienia"
+
+#: ../src/utils/pactl.c:1977
+msgid "Could not parse latency offset"
+msgstr "Nie można przetworzyć offsetu opóźnienia"
+
+#: ../src/utils/pactl.c:1989
 msgid "No valid command specified."
 msgstr "Nie podano prawidłowego polecenia."
 
@@ -2218,107 +2529,180 @@ msgstr ""
 #: ../src/utils/pax11publish.c:94
 #, c-format
 msgid "Failed to parse command line.\n"
-msgstr "Przetworzenie wiersza poleceń nie powiodła się.\n"
+msgstr "Przetworzenie wiersza poleceń się nie powiodło.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Serwer: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Źródło: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Odpływ: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Ciasteczko: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
-msgstr "Przetworzenie danych ciasteczka nie powiodła się\n"
+msgstr "Przetworzenie danych ciasteczka się nie powiodło\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
-msgstr "Zapisanie danych ciasteczka nie powiodło się\n"
+msgstr "Zapisanie danych ciasteczka się nie powiodło\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
-msgstr "Wczytanie pliku konfiguracji klienta nie powiodło się.\n"
+msgstr "Wczytanie pliku konfiguracji klienta się nie powiodło.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
-msgstr "Odczytanie danych konfiguracji środowiska nie powiodło się.\n"
+msgstr "Odczytanie danych konfiguracji środowiska się nie powiodło.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
-msgstr "Uzyskanie FQDN nie powiodło się.\n"
+msgstr "Uzyskanie FQDN się nie powiodło.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
-msgstr "Wczytanie danych ciasteczka nie powiodło się\n"
+msgstr "Wczytanie danych ciasteczka się nie powiodło\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Niezaimplementowane.\n"
 
+#: ../src/utils/pacmd.c:59
+msgid "#N 1|0"
+msgstr "#N 1|0"
+
+#: ../src/utils/pacmd.c:60
+msgid "NAME|#N KEY=VALUE"
+msgstr "NAZWA|#N KLUCZ=WARTOŚĆ"
+
+#: ../src/utils/pacmd.c:61
+msgid "#N KEY=VALUE"
+msgstr "#N KLUCZ=WARTOŚĆ"
+
+#: ../src/utils/pacmd.c:63
+msgid "#N"
+msgstr "#N"
+
+#: ../src/utils/pacmd.c:64
+msgid "NAME SINK|#N"
+msgstr "NAZWA ODPŁYW|#N"
+
+#: ../src/utils/pacmd.c:66 ../src/utils/pacmd.c:67
+msgid "NAME FILENAME"
+msgstr "NAZWA NAZWA-PLIKU"
+
+#: ../src/utils/pacmd.c:68
+msgid "PATHNAME"
+msgstr "NAZWA-ŚCIEŻKI"
+
 #: ../src/utils/pacmd.c:69
+msgid "FILENAME SINK|#N"
+msgstr "NAZWA-PLIKU ODPŁYW|#N"
+
+#: ../src/utils/pacmd.c:73 ../src/utils/pacmd.c:79 ../src/utils/pacmd.c:80
+msgid "1|0"
+msgstr "1|0"
+
+#: ../src/utils/pacmd.c:77
+msgid "TARGET"
+msgstr "CEL"
+
+#: ../src/utils/pacmd.c:78
+msgid "NUMERIC LEVEL"
+msgstr "NUMERYCZNY POZIOM"
+
+#: ../src/utils/pacmd.c:81
+msgid "FRAMES"
+msgstr "RAMKI"
+
+#: ../src/utils/pacmd.c:83
+#, c-format
+msgid ""
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"When no command is given pacmd starts in the interactive mode\n"
+msgstr ""
+"\n"
+"  -h, --help                            Wyświetla tę pomoc\n"
+"      --version                         Wyświetla wersję\n"
+"Jeśli nie podano polecenia, to program pacmd zostaje uruchomiony w trybie "
+"interaktywnym\n"
+
+#: ../src/utils/pacmd.c:131
+#, c-format
+msgid ""
+"pacmd %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"pacmd %s\n"
+"Skompilowane za pomocą libpulse %s\n"
+"Skonsolidowane za pomocą libpulse %s\n"
+
+#: ../src/utils/pacmd.c:145
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr ""
-"Demon PulseAudio nie jest uruchomiony, lub nie jest uruchomiony jako demon "
+"Usługa PulseAudio nie jest uruchomiona, lub nie jest uruchomiona jako usługa "
 "sesji."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:150
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "gniazdo(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:167
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:176
 msgid "Failed to kill PulseAudio daemon."
-msgstr "Zniszczenie demona PulseAudio nie powiodło się."
+msgstr "Zniszczenie usługi PulseAudio się nie powiodło."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:184
 msgid "Daemon not responding."
-msgstr "Demon nie odpowiada."
+msgstr "Usługa nie odpowiada."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:264
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:275 ../src/utils/pacmd.c:295
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:317 ../src/utils/pacmd.c:335
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "Nie można uzyskać dostępu do blokady automatycznego wznawiania."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:567 ../src/modules/alsa/alsa-sink.c:747
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2328,14 +2712,14 @@ msgid ""
 "We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() "
 "returned 0 or another value < min_avail."
 msgstr ""
-"ALSA została wybudzona, aby zapisać nowe dane do urządzenia, ale nie było "
-"nic do zapisania.\n"
+"Usługa ALSA została wybudzona, aby zapisać nowe dane do urządzenia, ale nie "
+"było nic do zapisania.\n"
 "Prawdopodobnie jest to błąd w sterowniku ALSA \"%s\". Proszę zgłosić ten "
-"problem programistom ALSA.\n"
+"problem programistom usługi ALSA.\n"
 "Wybudzono za pomocą ustawienia POLLOUT - ale jednoczesne wywołanie "
 "snd_pcm_avail() zwróciło zero lub inną wartość < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:526 ../src/modules/alsa/alsa-source.c:679
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2345,235 +2729,461 @@ msgid ""
 "We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() "
 "returned 0 or another value < min_avail."
 msgstr ""
-"ALSA została wybudzona, aby odczytać nowe dane z urządzenia, ale nie było "
-"nic do odczytania.\n"
+"Usługa ALSA została wybudzona, aby odczytać nowe dane z urządzenia, ale nie "
+"było nic do odczytania.\n"
 "Prawdopodobnie jest to błąd w sterowniku ALSA \"%s\". Proszę zgłosić ten "
-"problem programistom ALSA.\n"
+"problem programistom usługi ALSA.\n"
 "Wybudzono za pomocą ustawienia POLLIN - ale jednoczesne wywołanie "
 "snd_pcm_avail() zwróciło zero lub inną wartość < min_avail."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:193
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2273
+#: ../src/modules/alsa/alsa-mixer.c:3922
 msgid "Off"
-msgstr "Wyłącz"
+msgstr "Wyłączone"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2087
+msgid "Headset"
+msgstr "Słuchawki z mikrofonem"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2092
+msgid "Handsfree"
+msgstr "Zestaw głośnomówiący"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2097
+#: ../src/modules/alsa/alsa-mixer.c:2256 ../src/modules/alsa/alsa-mixer.c:2334
+msgid "Microphone"
+msgstr "Mikrofon"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2102
+#: ../src/modules/alsa/alsa-mixer.c:2271
+msgid "Speaker"
+msgstr "Głośnik"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2107
+msgid "Headphone"
+msgstr "Słuchawki"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2112
+msgid "Portable"
+msgstr "Przenośne"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2117
+msgid "Car"
+msgstr "Samochód"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2122
+msgid "HiFi"
+msgstr "HiFi"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2127
+msgid "Phone"
+msgstr "Telefon"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2135
+msgid "Bluetooth Output"
+msgstr "Wyjście Bluetooth"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2138
+msgid "Bluetooth Input"
+msgstr "Wejście Bluetooth"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2162
 msgid "High Fidelity Playback (A2DP)"
 msgstr "Odtwarzanie o wysokiej dokładności (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2172
 msgid "High Fidelity Capture (A2DP)"
 msgstr "Przechwytywanie o wysokiej dokładności (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2182
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Duplex telefoniczny (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2192
+msgid "Handsfree Gateway"
+msgstr "Zestaw głośnomówiący"
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "Serwer dźwięku PulseAudio"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
 msgstr "Urządzenia wyjściowe"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
 msgstr "Urządzenia wejściowe"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
 msgstr "Dźwięk na @HOSTNAME@"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2251
 msgid "Input"
 msgstr "Wejście"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2252
 msgid "Docking Station Input"
 msgstr "Wejście stacji dokującej"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2253
 msgid "Docking Station Microphone"
 msgstr "Mikrofon stacji dokującej"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2254
+msgid "Docking Station Line In"
+msgstr "Wejście liniowe stacji dokującej"
+
+#: ../src/modules/alsa/alsa-mixer.c:2255 ../src/modules/alsa/alsa-mixer.c:2340
+msgid "Line In"
 msgstr "Wejście liniowe"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
-msgid "Microphone"
-msgstr "Mikrofon"
+#: ../src/modules/alsa/alsa-mixer.c:2257 ../src/modules/alsa/alsa-mixer.c:2335
+msgid "Front Microphone"
+msgstr "Przedni mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2258 ../src/modules/alsa/alsa-mixer.c:2336
+msgid "Rear Microphone"
+msgstr "Tylny mikrofon"
+
+#: ../src/modules/alsa/alsa-mixer.c:2259
 msgid "External Microphone"
 msgstr "Zewnętrzny mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2260 ../src/modules/alsa/alsa-mixer.c:2338
 msgid "Internal Microphone"
 msgstr "Wewnętrzny mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2261 ../src/modules/alsa/alsa-mixer.c:2341
 msgid "Radio"
 msgstr "Radio"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2262 ../src/modules/alsa/alsa-mixer.c:2342
 msgid "Video"
 msgstr "Wideo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2263
 msgid "Automatic Gain Control"
 msgstr "Automatyczna kontrola natężenia"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2264
 msgid "No Automatic Gain Control"
 msgstr "Brak automatycznej kontroli natężenia"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2265
 msgid "Boost"
 msgstr "Podbicie"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2266
 msgid "No Boost"
 msgstr "Brak podbicia"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2267
 msgid "Amplifier"
 msgstr "Amplituner"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2268
 msgid "No Amplifier"
 msgstr "Brak amplitunera"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr "Wejście analogowe"
+#: ../src/modules/alsa/alsa-mixer.c:2269
+msgid "Bass Boost"
+msgstr "Podbicie basów"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr "Mikrofon analogowy"
+#: ../src/modules/alsa/alsa-mixer.c:2270
+msgid "No Bass Boost"
+msgstr "Brak podbicia basów"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
-msgstr "Analogowe wejście liniowe"
+#: ../src/modules/alsa/alsa-mixer.c:2272 ../src/modules/alsa/alsa-mixer.c:2344
+msgid "Headphones"
+msgstr "Słuchawki"
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr "Radio analogowe"
+#: ../src/modules/alsa/alsa-mixer.c:2333
+msgid "Analog Input"
+msgstr "Wejście analogowe"
+
+#: ../src/modules/alsa/alsa-mixer.c:2337
+msgid "Dock Microphone"
+msgstr "Mikrofon stacji dokującej"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr "Wideo analogowe"
+#: ../src/modules/alsa/alsa-mixer.c:2339
+msgid "Headset Microphone"
+msgstr "Mikrofon na słuchawkach"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2343
 msgid "Analog Output"
 msgstr "Wyjście analogowe"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr "Słuchawki analogowe"
+#: ../src/modules/alsa/alsa-mixer.c:2345
+msgid "LFE on Separate Mono Output"
+msgstr "Subwoofer na oddzielnym wyjściu mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
-msgstr "Wyjście analogowe (subwoofer)"
+#: ../src/modules/alsa/alsa-mixer.c:2346
+msgid "Line Out"
+msgstr "Wyjście liniowe"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2347
 msgid "Analog Mono Output"
 msgstr "Analogowe wyjście mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, c-format
-msgid "%s+%s"
-msgstr "%s+%s"
+#: ../src/modules/alsa/alsa-mixer.c:2348
+msgid "Speakers"
+msgstr "Głośniki"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, c-format
-msgid "%s / %s"
-msgstr "%s/%s"
+#: ../src/modules/alsa/alsa-mixer.c:2349
+msgid "HDMI / DisplayPort"
+msgstr "HDMI/DisplayPort"
+
+#: ../src/modules/alsa/alsa-mixer.c:2350
+msgid "Digital Output (S/PDIF)"
+msgstr "Wyjście cyfrowe (S/PDIF)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2351
+msgid "Digital Input (S/PDIF)"
+msgstr "Wejście cyfrowe (S/PDIF)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:2352
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Cyfrowe przekazywanie (S/PDIF)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3770
 msgid "Analog Mono"
 msgstr "Analogowe mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Analog Stereo"
 msgstr "Analogowe stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Analog Surround 2.1"
 msgstr "Analogowe surround 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Analog Surround 3.0"
 msgstr "Analogowe surround 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3774
 msgid "Analog Surround 3.1"
 msgstr "Analogowe surround 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3775
 msgid "Analog Surround 4.0"
 msgstr "Analogowe surround 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3776
 msgid "Analog Surround 4.1"
 msgstr "Analogowe surround 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3777
 msgid "Analog Surround 5.0"
 msgstr "Analogowe surround 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3778
 msgid "Analog Surround 5.1"
 msgstr "Analogowe surround 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3779
 msgid "Analog Surround 6.0"
 msgstr "Analogowe surround 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3780
 msgid "Analog Surround 6.1"
 msgstr "Analogowe surround 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3781
 msgid "Analog Surround 7.0"
 msgstr "Analogowe surround 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3782
 msgid "Analog Surround 7.1"
 msgstr "Analogowe surround 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3783
+msgid "Analog 4-channel Input"
+msgstr "Czterokanałowe wejście analogowe"
+
+#: ../src/modules/alsa/alsa-mixer.c:3784
 msgid "Digital Stereo (IEC958)"
 msgstr "Cyfrowe stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "Cyfrowe surround 4.0 (IEC958)"
+#: ../src/modules/alsa/alsa-mixer.c:3785
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Cyfrowe przekazywanie (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3786
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Cyfrowe surround 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3787
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Cyfrowe surround 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3788
+msgid "Digital Surround 5.1 (IEC958/DTS)"
+msgstr "Cyfrowe surround 5.1 (IEC958/DTS)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3789
 msgid "Digital Stereo (HDMI)"
 msgstr "Cyfrowe stereo (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3790
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Cyfrowe surround 5.1 (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3919
 msgid "Analog Mono Duplex"
 msgstr "Analogowy dupleks mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3920
 msgid "Analog Stereo Duplex"
 msgstr "Analogowy dupleks stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3921
 msgid "Digital Stereo Duplex (IEC958)"
 msgstr "Cyfrowy dupleks stereo (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:4021
+#, c-format
+msgid "%s Output"
+msgstr "Wyjście %s"
+
+#: ../src/modules/alsa/alsa-mixer.c:4029
+#, c-format
+msgid "%s Input"
+msgstr "Wejście %s"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"source_name=<nazwa źródła> source_properties=<właściwości źródła> "
+"source_master=<nazwa źródła do filtrowania> sink_name=<nazwa odpływu> "
+"sink_properties=<właściwości odpływu> sink_master=<nazwa odpływu do "
+"filtrowania> adjust_time=<jak często odczytywać częstotliwości w sekundach> "
+"adjust_threshold=<jak daleko odchodzić do odczytania w milisekundach> "
+"format=<format próbki> rate=<częstotliwość próbki> channels=<liczba kanałów> "
+"channel_map=<map kanałów> aec_method=<używana implementacja> "
+"aec_args=<parametry dla mechanizmu AEC> save_aec=<zapisywanie danych AEC w /"
+"tmp> autoloaded=<należy ustawić, jeśli moduł jest automatycznie wczytywany> "
+"use_volume_sharing=<yes lub no> "
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr "Korektor graficzny ogólnego przeznaczenia"
+
+#: ../src/modules/module-equalizer-sink.c:76
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<nazwa odpływu> sink_properties=<właściwości odpływu> "
+"sink_master=<nazwa odpływu do filtrowania> format=<format próbki> "
+"rate=<częstotliwość próbki> channels=<liczba kanałów> channel_map=<mapa "
+"kanałów> autoloaded=<należy ustawić, jeśli ten moduł jest automatycznie "
+"uruchamiany> use_volume_sharing=<yes lub no> "
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr "autoclean=<automatycznie usuwać nieużywane filtry?>"
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"s24le, s24be, s24-32le, s24-32be, s32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+"%s [opcje]\n"
+"\n"
+"-h, --help                            Wyświetla tę pomoc\n"
+"-v, --verbose                         Wyświetla komunikaty debugowania\n"
+"      --from-rate=CZĘSTOTLIWOŚĆPRÓBKI Z częstotliwości próbki w Hz\n"
+"                                      (domyślnie 44100)\n"
+"      --from-format=FORMATPRÓBKI      Z typu próbki (domyślnie s16le)\n"
+"      --from-channels=KANAŁY          Z liczby kanałów (domyślnie 1)\n"
+"      --to-rate=CZĘSTOTLIWOŚĆPRÓBKI   Do częstotliwości próbki w Hz\n"
+"                                      (domyślnie 44100)\n"
+"      --to-format=FORMATPRÓBKI        Do typu próbki (domyślnie s16le)\n"
+"      --to-channels=KANAŁY            Do liczby kanałów (domyślnie 1)\n"
+"      --resample-method=METODA        Metoda resamplingu\n"
+"                                      (domyślnie automatyczna)\n"
+"      --seconds=SEKUNDY               Z długości strumienia (domyślnie 60)\n"
+"\n"
+"Jeśli nie podano formatu, to test wykona wszystkie kombinacje formatów.\n"
+"\n"
+"Typ próbki musi być jednym z s16le, s16be, u8, float32le, float32be, ulaw,\n"
+"alaw, s24le, s24be, s24-32le, s24-32be, s32le, s32be (domyślnie s16ne)\n"
+"\n"
+"Proszę zobaczyć --dump-resample-methods, aby uzyskać możliwe\n"
+"wartości metody resamplingu.\n"
+
+#: ../src/tests/resampler-test.c:356
+#, c-format
+msgid "%s %s\n"
+msgstr "%s %s\n"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr "=== %d sekundy: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+
+#: ../src/modules/module-virtual-surround-sink.c:49
+msgid "Virtual surround sink"
+msgstr "Wirtualny odpływ Surround"
+
+#: ../src/modules/module-virtual-surround-sink.c:53
+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> "
+"channels=<number of channels> channel_map=<channel map> "
+"use_volume_sharing=<yes or no> force_flat_volume=<yes or no> hrir=/path/to/"
+"left_hrir.wav "
+msgstr ""
+"sink_name=<nazwa odpływu> sink_properties=<właściwości odpływu> "
+"sink_master=<nazwa odpływu do filtrowania> format=<format próbki> "
+"rate=<częstotliwość próbki> channels=<liczba kanałów> channel_map=<mapa "
+"kanałów> use_volume_sharing=<yes lub no> force_flat_volume=<yes lub no> "
+"hrir=/ścieżka/do/pliku/left_hrir.wav"
+
+#. add on profile
+#: ../src/modules/macosx/module-coreaudio-device.c:747
+msgid "On"
+msgstr "Włączone"
index bca8d93..5d80217 100644 (file)
--- a/po/pt.po
+++ b/po/pt.po
@@ -1,23 +1,22 @@
+#
+# Rui Gouveia <rui.gouveia@globaltek.pt>, 2012.
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: \n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:55+0000\n"
 "Last-Translator: Rui Gouveia <rui.gouveia@globaltek.pt>\n"
 "Language-Team: pt <fedora-trans-pt@redhat.com>\n"
+"Language: \n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "X-Poedit-Language: Portuguese\n"
 "X-Poedit-Country: PORTUGAL\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -30,11 +29,11 @@ msgstr ""
 "Provavelmente isto é um erro no driver ALSA '%s'. Por favor, reporte este "
 "problema aos programadores do ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
@@ -43,7 +42,20 @@ msgstr ""
 "Provavelmente isto é um erro no driver ALSA '%s'. Por favor, reporte este "
 "problema aos programadores do ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() retornou um valor excepcionalmente elevado: %lu bytes (%lu "
+"ms).\n"
+"Provavelmente isto é um erro no driver ALSA '%s'. Por favor, reporte este "
+"problema aos programadores do ALSA."
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -51,30 +63,33 @@ msgid ""
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 msgstr ""
-"snd_pcm_mmap_begin() retornou um valor excepcionalmente elevado: %lu bytes (%"
-"lu ms).\n"
+"snd_pcm_mmap_begin() retornou um valor excepcionalmente elevado: %lu bytes "
+"(%lu ms).\n"
 "Provavelmente isto é um erro no driver ALSA '%s'. Por favor, reporte este "
 "problema aos programadores do ALSA."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "Mantém sempre pelo menos um depósito carregado mesmo que seja um nulo"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "Saída Dummy"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "Depósito virtual LADSPA"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<nome do depósito> sink_properties=<propriedades do depósito> "
 "master=<nome do depósito a filtrar> format=<formato exemplo> "
@@ -83,120 +98,126 @@ msgstr ""
 "do plugin ladspa> control=<Lista de valores de controlo de entrada separados "
 "por vírgulas>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr ""
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "Saída nula"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "Áudio Interno"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "Modem"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "Não foi possível encontrar o carregador \"lt_dlopen\"."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "Não foi possível alocar o novo carregador \"dl\"."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "Não foi possível adicionar \"bind-now-loader\"."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "Foi obtido o sinal %s."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "A sair."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "Falha ao procurar o utilizador '%s'."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "Falha ao procurar o grupo '%s'."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "Foi encontrado utilizador '%s' (UID %lu) e grupo '%s' (GID %lu)."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "GID do utilizador '%s' e do grupo '%s' não coincidem."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "Directório pessoal do utilizador '%s' não é '%s'. A ignorar."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Falha ao criar o '%s': %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "Falhou a alteração da lista de grupos: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "Não foi possível mudar o GID: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "Não foi possível mudar o UID: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "Privilégios de root cedidos com sucesso."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "Modo de sistema não suportado nesta plataforma."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) falhou: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "Não foi possível processar linha de comando."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "Serviço não está a executar"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "Serviço a executar como PID %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "Tentativa de matar serviço falhou: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -204,159 +225,180 @@ msgstr ""
 "Este programa não pretende ser executado como root (a não ser que a opção --"
 "system seja especificada)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "São necessários privilégios de root."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start não é suportado para instâncias do sistema."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "A executar em modo de sistema, mas --disallow-exit não está definido!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
 "A executar em modo de sistema, mas --disallow-module-loading não está "
 "definido!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "A executar em modo de sistema, a forçar a desactivação do modo SHM!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 "A executar em modo de sistema, a forçar a desactivação da saída por "
 "inactividade!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "Não foi possível adquirir o stdio."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "pipe falhou: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() falhou: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() falhou: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "Arranque do serviço falhou."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "Arranque do serviço sucedeu."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() falhou: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Isto é PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Máquina de compilação: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "CFLAGS utilizadas na compilação: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "A executar na máquina: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "Foram encontrados %u CPUs."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "Tamanho da página é %lu bytes"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Compilado com suporte para Valgrind: sim"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Compilado com suporte para Valgrind: não"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "A executar em modo \"valgrind\": %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "A executar na máquina: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "Optimizado: sim"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "Compilação optimizada: não"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG definido, todas as declarações desactivadas."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH definido, apenas as declarações \"fast path\" desactivadas."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "Todas as declarações desactivadas."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "A tentativa de ler o ID da máquina falhou"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "O ID da máquina é %s."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "O ID da sessão é %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "Execução a utilizar o directório %s"
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "A manter o estado no directório %s."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "A utilizar o directório de módulos %s"
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Execução em modo de sistema: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -372,15 +414,15 @@ msgstr ""
 "Por favor leia http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode para uma "
 "explicação de como o modo de sistema é usualmente uma má ideia."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() falhou."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "Timer \"frescos\" de alta resolução disponíveis. Bom apetite!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -388,32 +430,32 @@ msgstr ""
 "Oh pá, o teu kernel não presta! O prato do dia recomendado é Linux com "
 "timers de alta resolução activos!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() falhou."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "Falha ao inicializar serviço."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Serviço arrancou sem módulos carregados. A recusar trabalhar."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "Arranque do serviço completo."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "Encerramento do serviço iniciado."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "Serviço terminado."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -450,15 +492,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -566,15 +606,15 @@ msgstr ""
 "\n"
 "  -n                                    Não carrega o script por omissão\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize espera argumento booleano"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail espera argumento booleano"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -582,168 +622,171 @@ msgstr ""
 "--log-level espera um argumento para o nível de log (numérico no intervalo "
 "0..4 ou um dos seguintes: debug, info, notice, warn, error)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority espera argumento booleano"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime espera argumento booleano"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading espera argumento booleano"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit espera argumento booleano"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file espera argumento booleano"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr ""
 "Destino de ficheiro de registo inválido: utilize 'syslog', 'stderr' ou "
 "'auto'."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time espera argumento booleano"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta espera argumento booleano"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Método de resample inválido '%s'."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system espera argumento booleano"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit espera argumento booleano"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm espera argumento booleano"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Nome: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "Nenhuma informação de módulo disponível\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Versão: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Descrição: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Autor: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Utilização: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "Carregar Uma Vez: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "AVISO DE DESCONTINUIDADE: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Caminho: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] ficheiro registo de destino inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Nível do ficheiro de registo inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Método de reamostragem inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] rlimit inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit não é suportado nesta plataforma."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Formato da amostra inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Taxa de amostragem '%s' inválida."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Canais de amostragem inválidos '%s'."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] Mapa de canais inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Número inválido de fragmentos '%s'."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Tamanho do fragmento inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] nível nice inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Taxa de amostragem '%s' inválida."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Falha ao abrir ficheiro de configuração: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -751,12 +794,12 @@ msgstr ""
 "O mapa de canais especificado tem um número de canais diferente do número de "
 "canais definido por omissão."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Ler configuração a partir do ficheiro: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "A limpar privilégios."
 
@@ -768,6 +811,16 @@ msgstr "Sistema de Som PulseAudio"
 msgid "Start the PulseAudio Sound System"
 msgstr "Inciar o Sistema de Som PulseAudio"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "Sistema de Som PulseAudio"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "Inciar o Sistema de Som PulseAudio"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
@@ -797,8 +850,8 @@ msgid "Rear Right"
 msgstr "Traseira Direita"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Emissor de Baixa Frequência"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -972,9 +1025,10 @@ msgstr "Topo Traseira Esquerda"
 msgid "Top Rear Right"
 msgstr "Topo Traseira Direita"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(inválido)"
 
@@ -1002,332 +1056,349 @@ msgstr "Surround 5.1"
 msgid "Surround 7.1"
 msgstr "Surround 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "OK"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "Acesso negado"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Comando desconhecido"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "Argumento inválido"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "Entidade existe! "
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "Entidade não existe"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "Ligação recusada"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "Erro de protocolo"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "Tempo expirou"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "Sem chave de autorização"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "Erro interno"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "Ligação terminou"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "Entidade terminada"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Servidor Inválido"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "Inicialização do módulo falhou"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "Mau estado"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Nenhuns dados"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "Versão de protocolo incompatível"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "Demasiado Grande"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "Não suportado"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Código de erro desconhecido"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "Extensão não existe"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "Funcionalidade obsoleta"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "Implementação em falta"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "Cliente efectuou um fork"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "Erro de entrada/saída"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "Dispositivo ou recurso ocupado"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() falhou"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() falhou: %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "Não foi possível processar dados da cookie"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Falha ao abrir ficheiro de configuração '%s': %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "Nenhuma cookie carregada. A tentar ligar sem cookie."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "Recebida mensagem para extensão desconhecida '%s'"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "Falha ao esvaziar fluxo: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "Fluxo de leitura drenado."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "A drenar ligação ao servidor."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() falhou: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_write() falhou: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() falhou: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "Fluxo criado com sucesso."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() falhou: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 msgstr "Métricas do Buffer: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Métricas do Buffer: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "Utilizando especificação da amostra '%s', mapa de canal '%s'."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "Ligado ao dispositivo %s (%u, %ssuspended)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "Erro de fluxo: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "Dispositivo de fluxo suspenso.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "Dispositivo de fluxo retomado.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "Fluxo com falta de dados.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "Fluxo com excesso de dados.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "Fluxo iniciado.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "Fluxo movido para o dispositivo %s (%u, %ssuspended).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "negação"
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "Atributos do buffer de fluxo alterados.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "Ligação estabelecida.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() falhou: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() falhou: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() falhou: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "Ligação falhou: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "Obtive EOF."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() falhou: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "Recebido sinal, a sair."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "Falhou a obtenção da cadência: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Tempo: %0.3f sec; Cadência: %0.0f usec."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() falhou: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1379,10 +1450,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [opções]\n"
@@ -1440,7 +1516,7 @@ msgstr ""
 "      --list-file-formats               Lista o formato de ficheiros "
 "disponíveis.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1451,68 +1527,68 @@ msgstr ""
 "Compilado com libpulse %s\n"
 "Ligado com libpulse %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "Nome de cliente inválido '%s'"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "Nome de fluxo inválido '%s'"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "Mapa de canais inválido '%s'"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "Especificação da cadência inválida '%s'"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "Especificação de tempo de processamento inválido '%s'"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "Propriedade inválida '%s'"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "Formato de ficheiro desconhecido %s."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "Especificação de amostra inválida"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "Demasiados argumentos."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "Falha ao gerar especificação de amostra para o ficheiro."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "Falha ao abrir ficheiro de audio"
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
@@ -1520,103 +1596,108 @@ msgstr ""
 "Aviso: a especificação da amostra será sobrescrita com a especificação do "
 "ficheiro."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "Falha ao determinar a especificação da amostra a partir do ficheiro."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "Aviso: Falha a determinar o mapa de canal do ficheiro."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "Mapa de canais não corresponde à especificação da amostra"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "Aviso: falha na escrita do mapa de canais no ficheiro."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr ""
 "Abrindo um %s fluxo com especificação da amostra '%s' e mapa de canais '%s'."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "a gravar"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "reprodução"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "Não foi possível processar linha de comando."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() falhou."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() falhou."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() falhou."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() falhou: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_rttime_new() falhou."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() falhou."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "Falhou ao suspender: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "Falhou ao restaurar: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "Atenção: Servidor de Som não local, suspender ignorado.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Ligação falhou: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "Obtido SIGINT, a sair.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "Atenção: Processo filho terminado por sinal %u\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1660,36 +1741,47 @@ msgstr "pa_context_new() falhou.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() falhou.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "Falhou a obtenção de estatísticas: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "Correntemente em uso: %u blocos contendo %s bytes no total.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr ""
 "Alocado durante todo o tempo de vida: %u blocos contendo %s bytes no total.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "Tamanho cache da amostra: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "Falha ao obter informações do servidor: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1697,7 +1789,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "Nome de utilizador: %s\n"
 "Nome da máquina: %s\n"
@@ -1709,13 +1801,13 @@ msgstr ""
 "Fonte por omissão: %s\n"
 "Cookie: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "Falha ao obter informações do depósito: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1731,7 +1823,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1753,22 +1845,27 @@ msgstr ""
 "\tPropriedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tPorto:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tPorto Activo: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tPorto:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "Falha ao obter informações da fonte: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1807,20 +1904,20 @@ msgstr ""
 "\tPropriedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "n/d"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "Falha ao obter informações do módulo: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1837,12 +1934,12 @@ msgstr ""
 "\tPropriedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "Falha ao obter informações do cliente: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1857,12 +1954,12 @@ msgstr ""
 "\tPropriedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "Falha ao obter informações da carta: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1879,23 +1976,23 @@ msgstr ""
 "\tPropriedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tPrefis:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tPerfil Activo: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "Falha ao obter informação de entrada do depósito: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1904,6 +2001,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1931,13 +2029,13 @@ msgstr ""
 "\tPropriedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "Falha ao obter informações da fonte: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1946,31 +2044,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Saída fonte #%u\n"
+"Entrada de Depósito #%u\n"
 "\tDriver: %s\n"
-"\tMódulo dono: %s\n"
+"\tMódulo Dono: %s\n"
 "\tCliente: %s\n"
-"\tFonte: %u\n"
+"\tDepósito: %u\n"
 "\tEspecificação da amostra: %s\n"
-"\tMapa de Canais: %s\n"
+"\tMapa de canais: %s\n"
+"\tMudo: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balanço %0.2f\n"
 "\tCadência do Buffer: %0.0f usec\n"
-"\tCadência da Fonte: %0.0f usec\n"
+"\tCadência do Depósito: %0.0f usec\n"
 "\tMétodo de reamostragem: %s\n"
 "\tPropriedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "Falha ao obter informações da amostra: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -2001,48 +2108,163 @@ msgstr ""
 "\tPropriedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "Falha: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Falha ao obter informações da fonte: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "Falha ao enviar amostra: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "Fim prematuro do ficheiro"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "Servidor Inválido"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "Obtido SIGINT, a sair."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "Especificação de volume inválida"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2052,36 +2274,14 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [opções] stat\n"
-"%s [opções] list\n"
-"%s [opções] exit\n"
-"%s [opções] upload-sample NOME_DO_FICHEIRO [NOME]\n"
-"%s [opções] play-sample NOME [DEPÓSITO]\n"
-"%s [opções] remove-sample NOME\n"
-"%s [opções] move-sink-input ENTRADA_DO_DEPÓSITO DEPÓSITO\n"
-"%s [opções] move-source-output SAÍDA_DA_FONTE FONTE\n"
-"%s [opções] load-module NOME [ARGTOS ...]\n"
-"%s [opções] unload-module MÓDULO\n"
-"%s [opções] suspend-sink DEPÓSITO 1|0\n"
-"%s [opções] suspend-source FONTE 1|0\n"
-"%s [opções] set-card-profile PLACA PERFIL\n"
-"%s [opções] set-sink-port DEPÓSITO PORTO\n"
-"%s [opções] set-source-port FONTE PORTO\n"
-"%s [opções] set-sink-volume DEPÓSITO VOLUME\n"
-"%s [opções] set-source-volume FONTE VOLUME\n"
-"%s [opções] set-sink-input-volume VOLUME_DE_ENTRADA DEPÓSITO\n"
-"%s [opções] set-sink-mute DEPÓSITO 1|0\n"
-"%s [opções] set-source-mute FONTE 1|0\n"
-"%s [opções] set-sink-input-mute ENTRADA_DA_FONTE 1|0\n"
+"%s [opções] ... \n"
 "\n"
 "  -h, --help                            Mostra esta ajuda\n"
 "      --version                         Mostra a versão\n"
+"  -s, --server=SERVER                   Nome do servidor ao qual ligar\n"
 "\n"
-"  -s, --server=SERVER                   O nome do servidor ao qual ligar\n"
-"  -n, --client-name=NAME                Como chamar este cliente no "
-"servidor\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2092,50 +2292,55 @@ msgstr ""
 "Compilado com libpulse %s\n"
 "Linkado com libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "Por favor, especifique um ficheiro de amostra para carregar"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "Falha ao abrir ficheiro de som."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "Aviso: Falha ao determinar a especificação da amostra do ficheiro."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "Tem de especificar um nome de amostra para reproduzir"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "Tem de especificar um nome de amostra para remover"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "Tem de especificar um índice de entrada de depósito e um depósito"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "Tem de especificar um índice de saída de fonte e uma fonte"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "Tem de especificar um nome de módulo e argumentos."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "Tem de especificar um índice de módulo"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "Não pode especificar mais do que um depósito.  Tem de especificar um valor "
 "booleano."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
@@ -2143,57 +2348,84 @@ msgstr ""
 "Não pode especificar mais do que uma fonte.  Tem de especificar um valor "
 "booleano."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "Tem de especificar um nome/índice de placa e um nome de perfil"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "Tem de especificar um nome/índice de depósito e nome de um porto"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "Tem de especificar um nome/índice de fonte e nome de um porto"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "Tem de especificar um nome/índice de depósito e um volume"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "Especificação de volume inválida"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "Tem de especificar um nome/índice de fonte e um volume"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "Tem de especificar um índice de entrada de depósito e um volume"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "Índice de depósito de entrada inválido"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "Tem de especificar um índice de saída de fonte e uma fonte"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "Índice de depósito de entrada inválido"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "Tem de especificar um nome/índice de depósito e um booleano mudo"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "Especificação de amostra inválida"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "Tem de especificar um nome/índice de fonte e um booleano mudo"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "Tem de especificar um índice de entrada de depósito e um booleano mudo"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "Índice de entrada de depósito inválida"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "Tem de especificar um nome/índice de fonte e um booleano mudo"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "Índice de entrada de depósito inválida"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "Tem de especificar um nome/índice de depósito e um booleano mudo"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "O comando especificado é inválido."
 
@@ -2223,104 +2455,104 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "Não foi possível processar a linha de comando.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Servidor: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Fonte: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Sink: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Cookie: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "Não foi possível processar os dados da cookie\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "Não foi possível gravar os dados da cookie\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "Não foi possível carregar o ficheiro de configuração do cliente\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "Não foi possível ler os dados de configuração do ambiente\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "Falhou ao obter FQDN.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "Não foi possível carregar os dados da cookie\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Ainda não implementado.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr ""
 "Não existe um daemon PulseAudio a correr, ou não corre como daemon de sessão."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "Não foi possível terminar o serviço PulseAudio."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "Serviço não responde."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "Impossível aceder ao lock \"autospawn\"."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2337,7 +2569,7 @@ msgstr ""
 "Fomos acordados pelo conjunto POLLOUT -- contudo uma chamada a seguir de "
 "snd_pcm_avail() retornou 0 ou outro valor < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2354,253 +2586,484 @@ msgstr ""
 "Fomos acordados pelo conjunto POLLIN -- contudo uma chamada a seguir de "
 "snd_pcm_avail() retornou 0 ou outro valor < min_avail."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "Desligado"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "Reprodução Alta Fidelidade (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "Captação de Alta Fidelidade (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Telefonia Duplex (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "Servidor de Som PulseAudio"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
 msgstr ""
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 #, fuzzy
 msgid "Input Devices"
 msgstr "Entrada %s"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 #, fuzzy
 msgid "Input"
 msgstr "Entrada %s"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
+msgstr "Áudio Interno"
+
+#: ../src/modules/alsa/alsa-mixer.c:2222
+msgid "Docking Station Line In"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "Áudio Interno"
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "Áudio Interno"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
 msgid "External Microphone"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 #, fuzzy
 msgid "Internal Microphone"
 msgstr "Áudio Interno"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-#, fuzzy
-msgid "Analog Input"
-msgstr "Mono Analógico"
+#: ../src/modules/alsa/alsa-mixer.c:2237
+msgid "Bass Boost"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-#, fuzzy
-msgid "Analog Microphone"
-msgstr "Mono Analógico"
+#: ../src/modules/alsa/alsa-mixer.c:2238
+msgid "No Bass Boost"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
 #, fuzzy
-msgid "Analog Line-In"
+msgid "Headphones"
 msgstr "Mono Analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
+#: ../src/modules/alsa/alsa-mixer.c:2301
 #, fuzzy
-msgid "Analog Radio"
+msgid "Analog Input"
 msgstr "Mono Analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-#, fuzzy
-msgid "Analog Video"
-msgstr "Estéreo Analógico"
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2310
 #, fuzzy
 msgid "Analog Output"
 msgstr "Saída nula"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-#, fuzzy
-msgid "Analog Headphones"
-msgstr "Mono Analógico"
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
+#: ../src/modules/alsa/alsa-mixer.c:2313
+msgid "Line Out"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2314
 #, fuzzy
 msgid "Analog Mono Output"
 msgstr "Mono Analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, fuzzy, c-format
-msgid "%s+%s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "Estéreo Analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, fuzzy, c-format
-msgid "%s / %s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Estéreo Digital (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Estéreo Digital (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr "Mono Analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr "Estéreo Analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3758
 #, fuzzy
 msgid "Analog Surround 2.1"
 msgstr "Analog Surround 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3759
 #, fuzzy
 msgid "Analog Surround 3.0"
 msgstr "Analog Surround 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3760
 #, fuzzy
 msgid "Analog Surround 3.1"
 msgstr "Analog Surround 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr "Analog Surround 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr "Analog Surround 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr "Analog Surround 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr "Analog Surround 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3765
 #, fuzzy
 msgid "Analog Surround 6.0"
 msgstr "Analog Surround 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3766
 #, fuzzy
 msgid "Analog Surround 6.1"
 msgstr "Analog Surround 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3767
 #, fuzzy
 msgid "Analog Surround 7.0"
 msgstr "Analog Surround 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr "Analog Surround 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr "Estéreo Digital (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
+#: ../src/modules/alsa/alsa-mixer.c:3770
 #, fuzzy
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "Surround Digital 4.0 (IEC958/AC3)"
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Estéreo Digital (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Surround Digital 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Surround Digital 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr "Estéreo Digital (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Surround Digital 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 #, fuzzy
 msgid "Analog Mono Duplex"
 msgstr "Mono Analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 #, fuzzy
 msgid "Analog Stereo Duplex"
 msgstr "Estéreo Analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 #, fuzzy
 msgid "Digital Stereo Duplex (IEC958)"
 msgstr "Estéreo Digital (IEC958)"
 
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Saída nula"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "Entrada %s"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<nome do depósito> sink_properties=<propriedades do depósito> "
+"master=<nome do depósito a filtrar> format=<formato exemplo> "
+"rate=<frequência de amostragem> channels=<número de canais> "
+"channel_map=<mapa de canais> plugin=<nome do plugin ladspa> label=<etiqueta "
+"do plugin ladspa> control=<Lista de valores de controlo de entrada separados "
+"por vírgulas>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit não é suportado nesta plataforma."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() falhou"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Saída fonte #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tMódulo dono: %s\n"
+#~ "\tCliente: %s\n"
+#~ "\tFonte: %u\n"
+#~ "\tEspecificação da amostra: %s\n"
+#~ "\tMapa de Canais: %s\n"
+#~ "\tCadência do Buffer: %0.0f usec\n"
+#~ "\tCadência da Fonte: %0.0f usec\n"
+#~ "\tMétodo de reamostragem: %s\n"
+#~ "\tPropriedades:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [opções] stat\n"
+#~ "%s [opções] list\n"
+#~ "%s [opções] exit\n"
+#~ "%s [opções] upload-sample NOME_DO_FICHEIRO [NOME]\n"
+#~ "%s [opções] play-sample NOME [DEPÓSITO]\n"
+#~ "%s [opções] remove-sample NOME\n"
+#~ "%s [opções] move-sink-input ENTRADA_DO_DEPÓSITO DEPÓSITO\n"
+#~ "%s [opções] move-source-output SAÍDA_DA_FONTE FONTE\n"
+#~ "%s [opções] load-module NOME [ARGTOS ...]\n"
+#~ "%s [opções] unload-module MÓDULO\n"
+#~ "%s [opções] suspend-sink DEPÓSITO 1|0\n"
+#~ "%s [opções] suspend-source FONTE 1|0\n"
+#~ "%s [opções] set-card-profile PLACA PERFIL\n"
+#~ "%s [opções] set-sink-port DEPÓSITO PORTO\n"
+#~ "%s [opções] set-source-port FONTE PORTO\n"
+#~ "%s [opções] set-sink-volume DEPÓSITO VOLUME\n"
+#~ "%s [opções] set-source-volume FONTE VOLUME\n"
+#~ "%s [opções] set-sink-input-volume VOLUME_DE_ENTRADA DEPÓSITO\n"
+#~ "%s [opções] set-sink-mute DEPÓSITO 1|0\n"
+#~ "%s [opções] set-source-mute FONTE 1|0\n"
+#~ "%s [opções] set-sink-input-mute ENTRADA_DA_FONTE 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Mostra esta ajuda\n"
+#~ "      --version                         Mostra a versão\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   O nome do servidor ao qual ligar\n"
+#~ "  -n, --client-name=NAME                Como chamar este cliente no "
+#~ "servidor\n"
+
+#, fuzzy
+#~ msgid "%s+%s"
+#~ msgstr "%s %s"
+
+#, fuzzy
+#~ msgid "%s / %s"
+#~ msgstr "%s %s"
+
+#, fuzzy
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Surround Digital 4.0 (IEC958/AC3)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Emissor de Baixa Frequência"
+
 #, fuzzy
 #~ msgid "Invalid client name '%s'\n"
 #~ msgstr "Nome de máquina inválido"
index 257aa36..e86d68d 100644 (file)
@@ -2,16 +2,17 @@
 # Copyright (C) 2008,2009 pulseaudio
 # This file is distributed under the same license as the pulseaudio package.
 # Fabian Affolter <fab@fedoraproject.org>, 2008.
-# Igor Pires Soares <igor@projetofedora.org>, 2009.
+# Igor Pires Soares <igor@projetofedora.org>, 2009, 2012.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-10-23 09:53+0000\n"
-"PO-Revision-Date: 2009-10-23 14:42-0300\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:55+0000\n"
 "Last-Translator: Igor Pires Soares <igor@projetofedora.org>\n"
 "Language-Team: Brazilian-Portuguese <fedora-trans-pt_br@redhat.com>\n"
+"Language: \n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -19,370 +20,446 @@ msgstr ""
 "X-Poedit-Language: Portuguese\n"
 "X-Poedit-Country: Brazil\n"
 
-#: ../src/modules/alsa/alsa-util.c:858
-#: ../src/pulsecore/sink.c:2629
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
-msgid "%s %s"
-msgstr "%s %s"
+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 ""
+"O snd_pcm_avail() retornou um valor que é excepcionalmente grande: %lu bytes "
+"(%lu ms).\n"
+"É mais provável que isso seja um erro no driver \"%s\" do ALSA. Por favor, "
+"relate esse problema aos desenvolvedores do ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1179
 #, 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."
+"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 ""
-"O snd_pcm_avail() retornou um valor que é excepcionalmente grande: %lu bytes (%lu ms).\n"
-"É mais provável que isso seja um erro no driver \"%s\" do ALSA. Por favor, relate esse problema aos desenvolvedores do ALSA."
+"O snd_pcm_delay() retornou um valor que é excepcionalmente grande: %li bytes "
+"(%s%lu ms).\n"
+"É mais provável que isso seja um erro no driver \"%s\" do ALSA. Por favor, "
+"relate esse problema aos desenvolvedores do ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1147
-#, c-format
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, 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."
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
 msgstr ""
-"O snd_pcm_delay() retornou um valor que é excepcionalmente grande: %li bytes (%s%lu ms).\n"
-"É mais provável que isso seja um erro no driver \"%s\" do ALSA. Por favor, relate esse problema aos desenvolvedores do ALSA."
+"O snd_pcm_avail() retornou um valor que é excepcionalmente grande: %lu bytes "
+"(%lu ms).\n"
+"É mais provável que isso seja um erro no driver \"%s\" do ALSA. Por favor, "
+"relate esse problema aos desenvolvedores do ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1263
 #, 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."
+"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 ""
-"O snd_pcm_mmap_begin() retornou um valor que é excepcionalmente grande: %lu bytes (%lu ms).\n"
-"É mais provável que isso seja um erro no driver \"%s\" do ALSA. Por favor, relate esse problema aos desenvolvedores do ALSA."
+"O snd_pcm_mmap_begin() retornou um valor que é excepcionalmente grande: %lu "
+"bytes (%lu ms).\n"
+"É mais provável que isso seja um erro no driver \"%s\" do ALSA. Por favor, "
+"relate esse problema aos desenvolvedores do ALSA."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "Sempre manter pelo menos um destino carregado mesmo se for nulo"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "Saída fictícia"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "Destino Virtual LADSPA"
 
-#: ../src/modules/module-ladspa-sink.c:53
-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> channels=<number of channels> channel_map=<channel map> plugin=<ladspa plugin name> label=<ladspa plugin label> control=<comma seperated list of input control values>"
-msgstr "sink_name=<nome do destino> sink_properties=<propriedades do destino> master=<nome do destino a ser filtrado> format=<formato de amostragem> rate=<taxa da amostragem> channels=<número de canais> channel_map=<mapa dos canais> plugin=<nome do plugin ladspa> label=<rótulo do plugin ladspa> control=<lista separada por vírgulas dos valores de controle da entrada>"
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
+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> "
+"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> "
+msgstr ""
+"sink_name=<nome do destino> sink_properties=<propriedades do destino> "
+"master=<nome do destino a ser filtrado> format=<formato de amostragem> "
+"rate=<taxa da amostragem> channels=<número de canais> channel_map=<mapa dos "
+"canais> plugin=<nome do plugin ladspa> label=<rótulo do plugin ladspa> "
+"control=<lista separada por vírgulas dos valores de controle da entrada>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "Destino nulo temporizado"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "Saída nula"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "Áudio interno"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "Modem"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "Falha ao localizar o carregador original lt_dlopen."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "Falha ao alocar o novo carregador dl."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "Falha em adicionar o bind-now-loader."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "Sinal %s recebido."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "Saindo."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "Falha ao localizar o usuário \"%s\"."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "Falha ao localizar o grupo \"%s\"."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "Usuário \"%s\" (UID %lu) e grupo \"%s\" (GID %lu) localizados."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "O GID do usuário'%s' e do grupo '%s' não combinam."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "O diretório pessoal do usuário \"%s\" não é \"%s\", ignorando."
 
-#: ../src/daemon/main.c:208
-#: ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Falha ao criar \"%s\": %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "Falha ao alterar a lista de grupos: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "Falha ao alterar o GID: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "Falha ao alterar o UID: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "Os privilégios do root foram retirados com sucesso."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "O modo ampliado do sistema não tem suporte nessa plataforma."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) falhou: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "Falha em interpretar a linha de comando."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "O daemon não está em execução"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "Daemon executando como PID %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "Falha em encerrar o daemon: %s"
 
-#: ../src/daemon/main.c:571
-msgid "This program is not intended to be run as root (unless --system is specified)."
-msgstr "Este programa não é para ser executado como root (a não ser que --system seja especificado)."
+#: ../src/daemon/main.c:657
+msgid ""
+"This program is not intended to be run as root (unless --system is "
+"specified)."
+msgstr ""
+"Este programa não é para ser executado como root (a não ser que --system "
+"seja especificado)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "Privilégios de root requeridos."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start não tem suporte para instâncias de sistemas."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "Executando em no modo system, mas --disallow-exit não foi configurado!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
-msgstr "Executando no modo system, mas --disallow-module-loading não foi configurado!"
+msgstr ""
+"Executando no modo system, mas --disallow-module-loading não foi configurado!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "Executando no modo system, desabilitando forçadamente o modo SHM!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
-msgstr "Executando no modo system, desabilitando forçadamente o exit idle time!"
+msgstr ""
+"Executando no modo system, desabilitando forçadamente o exit idle time!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "Falha em adquirir o stdio."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "O pipe falhou: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "O fork() falhou: %s"
 
-#: ../src/daemon/main.c:646
-#: ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "A operação read() falhou: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "Falha na partida do daemon."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "Os daemons foram iniciados com sucesso."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "A operação read() falhou: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Este é o PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Host de compilação: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "Compilação CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "Executando no host: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "%u CPUs localizadas."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "O tamanho da página é %lu bytes"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Compilado com suporte do Valgrind: sim"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Compilado com suporte do Valgrind: não"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "Executando em modo valgrind: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "Executando no host: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "Build otimizado: sim"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "Build otimizado: não"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG definido, todas as declarações desabilitadas."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
-msgstr "FASTPATH definido, somente as declarações do \"fast path\" foram desabilitadas."
+msgstr ""
+"FASTPATH definido, somente as declarações do \"fast path\" foram "
+"desabilitadas."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "Todas as declarações habilitadas."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "Falha em obter o ID da máquina"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "A ID da máquina é %s."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "O ID da sessão é %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "Usando o diretório de runtime %s."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "Usando o diretório de estado %s."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "Usando o diretório de módulos %s."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Executando em modo do sistema: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
-"OK, so you are running PA in system mode. Please note that you most likely shouldn't be doing that.\n"
-"If you do it nonetheless then it's your own fault if things don't work as expected.\n"
-"Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an explanation why system mode is usually a bad idea."
+"OK, so you are running PA in system mode. Please note that you most likely "
+"shouldn't be doing that.\n"
+"If you do it nonetheless then it's your own fault if things don't work as "
+"expected.\n"
+"Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an "
+"explanation why system mode is usually a bad idea."
 msgstr ""
-"OK, então você está executando o PA no modo de sistema. Por favor, note que é mais provável que você não deveria estar fazendo isso.\n"
-"Todavia, se você o fizer, então a culpa será sua se as coisas não funcionarem como esperado.\n"
-"Por favor, leia o http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode para obter um explicação sobre porque o modo de sistema é uma má idéia."
-
-#: ../src/daemon/main.c:809
+"OK, então você está executando o PA no modo de sistema. Por favor, note que "
+"é mais provável que você não deveria estar fazendo isso.\n"
+"Todavia, se você o fizer, então a culpa será sua se as coisas não "
+"funcionarem como esperado.\n"
+"Por favor, leia o http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode para "
+"obter um explicação sobre porque o modo de sistema é uma má idéia."
+
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() falhou."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "Timers de alta resolução frequinhos disponíveis! Bon appetit!"
 
-#: ../src/daemon/main.c:821
-msgid "Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"
-msgstr "Cara, teu kernel fede! A recomendação do chef hoje é Linux com timers de alta resolução habilitados!"
+#: ../src/daemon/main.c:993
+msgid ""
+"Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
+"resolution timers enabled!"
+msgstr ""
+"Cara, teu kernel fede! A recomendação do chef hoje é Linux com timers de "
+"alta resolução habilitados!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() falhou."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "Falha em iniciar o daemon."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
-msgstr "O Daemon iniciou sem qualquer módulo carregado, recusando-se a trabalhar."
+msgstr ""
+"O Daemon iniciou sem qualquer módulo carregado, recusando-se a trabalhar."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "A partida dos Daemon está completa."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "O encerramento do Daemon foi iniciado."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "Daemon terminado."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -392,37 +469,46 @@ msgid ""
 "      --dump-conf                       Dump default configuration\n"
 "      --dump-modules                    Dump list of available modules\n"
 "      --dump-resample-methods           Dump available resample methods\n"
-"      --cleanup-shm                     Cleanup stale shared memory segments\n"
-"      --start                           Start the daemon if it is not running\n"
+"      --cleanup-shm                     Cleanup stale shared memory "
+"segments\n"
+"      --start                           Start the daemon if it is not "
+"running\n"
 "  -k  --kill                            Kill a running daemon\n"
-"      --check                           Check for a running daemon (only returns exit code)\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"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_NICE)\n"
 "      --realtime[=BOOL]                 Try to enable realtime scheduling\n"
-"                                        (only available as root, when SUID or\n"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_RTPRIO)\n"
-"      --disallow-module-loading[=BOOL]  Disallow module user requested module\n"
+"      --disallow-module-loading[=BOOL]  Disallow module user requested "
+"module\n"
 "                                        loading/unloading after startup\n"
 "      --disallow-exit[=BOOL]            Disallow user requested exit\n"
-"      --exit-idle-time=SECS             Terminate the daemon when idle and this\n"
+"      --exit-idle-time=SECS             Terminate the daemon when idle and "
+"this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle and\n"
-"                                        this time passed\n"
-"      --scache-idle-time=SECS           Unload autoloaded samples when idle and\n"
+"      --scache-idle-time=SECS           Unload autoloaded samples when idle "
+"and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
-"      --log-meta[=BOOL]                 Include code location in log messages\n"
+"      --log-target={auto,syslog,stderr,file: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"
+"  -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"
@@ -433,10 +519,12 @@ msgid ""
 "      --disable-shm[=BOOL]              Disable shared memory support.\n"
 "\n"
 "STARTUP SCRIPT:\n"
-"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module with\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module "
+"with\n"
 "                                        the specified argument\n"
 "  -F, --file=FILENAME                   Run the specified script\n"
-"  -C                                    Open a command line on the running TTY\n"
+"  -C                                    Open a command line on the running "
+"TTY\n"
 "                                        after startup\n"
 "\n"
 "  -n                                    Don't load default script file\n"
@@ -447,238 +535,272 @@ msgstr ""
 "  -h, --help                            Mostra esta ajuda\n"
 "      --version                        Mostra a versão\n"
 "      --dump-conf                       Descarrega a configuração padrão\n"
-"      --dump-modules                   Descarrega a lista de módulos disponíveis\n"
-"      --dump-resample-methods           Descarrega os métodos de reamostragem\n"
-"      --cleanup-shm                     Limpa os segmentos de memória compartilhados\n"
-"      --start                           Inicia o daemon se ele não estiver em execução\n"
+"      --dump-modules                   Descarrega a lista de módulos "
+"disponíveis\n"
+"      --dump-resample-methods           Descarrega os métodos de "
+"reamostragem\n"
+"      --cleanup-shm                     Limpa os segmentos de memória "
+"compartilhados\n"
+"      --start                           Inicia o daemon se ele não estiver "
+"em execução\n"
 "  -k  --kill                            Encerra um daemon em execução\n"
-"      --check                           Verifica se há um daemon em execução (somente retorna o código de saída)\n"
+"      --check                           Verifica se há um daemon em execução "
+"(somente retorna o código de saída)\n"
 "\n"
 "OPÇÕES:\n"
-"      --system[=BOOL]                   Executa como uma instância do sistema em escala ampla\n"
+"      --system[=BOOL]                   Executa como uma instância do "
+"sistema em escala ampla\n"
 "  -D, --daemonize[=BOOL]                Torna-se um daemom após o início\n"
 "      --fail[=BOOL]                     Sai quando a partida falha\n"
 "      --high-priority[=BOOL]            Tenta definir um nível alto de nice\n"
 "                                        (disponível apenas, quando SUID ou\n"
 "                                        com RLIMIT_NICE) elevado\n"
-"      --realtime[=BOOL]                 Tenta habilitar o escalonamento em tempo real\n"
-"                                        (disponível apenas como root, quando SUID ou\n"
+"      --realtime[=BOOL]                 Tenta habilitar o escalonamento em "
+"tempo real\n"
+"                                        (disponível apenas como root, quando "
+"SUID ou\n"
 "                                        com  RLIMIT_RTPRIO) elevado\n"
-"      --disallow-module-loading[=BOOL]  Não permite carga/descarga de módulo requerido pelo usuário\n"
+"      --disallow-module-loading[=BOOL]  Não permite carga/descarga de módulo "
+"requerido pelo usuário\n"
 "                                        depois da partida\n"
-"      --disallow-exit[=BOOL]            Não permite saída requisitada pelo usuário\n"
-"      --exit-idle-time=SECS             Termina um daemon quando ocioso e este\n"
+"      --disallow-exit[=BOOL]            Não permite saída requisitada pelo "
+"usuário\n"
+"      --exit-idle-time=SECS             Termina um daemon quando ocioso e "
+"este\n"
 "                                        tempo foi decorrido\n"
-"      --module-idle-time=SECS           Descarrega os módulos autocarregáveis quando ociosos e\n"
+"      --module-idle-time=SECS           Descarrega os módulos "
+"autocarregáveis quando ociosos e\n"
 "                                        este tempo foi decorrido\n"
-"      --scache-idle-time=SECS           Descarrega amostras quando ociosas e\n"
+"      --scache-idle-time=SECS           Descarrega amostras quando ociosas "
+"e\n"
 "                                        este tempo foi decorrido\n"
-"      --log-level[=LEVEL]               Aumenta ou define o grau de detalhamento\n"
+"      --log-level[=LEVEL]               Aumenta ou define o grau de "
+"detalhamento\n"
 "  -v                                    Aumenta o nível de detalhamento\n"
 "      --log-target={auto,syslog,stderr} Especifica o destino do log\n"
-"      --log-meta[=BOOL]                 Inclui a localização do código na mensagem de log\n"
-"      --log-time[=BOOL]                 Inclui carimbos de hora nas mensagens de log\n"
-"      --log-backtrace=FRAMES            Inclui um backtrace na mensagem de log\n"
-"  -p, --dl-search-path=PATH             Define o caminho de pesquisa para objetos (plugins)\n"
+"      --log-meta[=BOOL]                 Inclui a localização do código na "
+"mensagem de log\n"
+"      --log-time[=BOOL]                 Inclui carimbos de hora nas "
+"mensagens de log\n"
+"      --log-backtrace=FRAMES            Inclui um backtrace na mensagem de "
+"log\n"
+"  -p, --dl-search-path=PATH             Define o caminho de pesquisa para "
+"objetos (plugins)\n"
 "                                            dinamicamente compartilhados\n"
-"      --resample-method=METHOD         Usa o método de reamostragem especificado\n"
+"      --resample-method=METHOD         Usa o método de reamostragem "
+"especificado\n"
 "                                        (Veja --dump-resample-methods para\n"
 "                                        valores possíveis)\n"
 "      --use-pid-file[=BOOL]             Cria um arquivo PID\n"
-"      --no-cpu-limit[=BOOL]            Não instala um limitador de carga de CPU em\n"
+"      --no-cpu-limit[=BOOL]            Não instala um limitador de carga de "
+"CPU em\n"
 "                                        plataformas que o suportem.\n"
-"      --disable-shm[=BOOL]              Desabilita o suporte à memória compartilhada.\n"
+"      --disable-shm[=BOOL]              Desabilita o suporte à memória "
+"compartilhada.\n"
 "\n"
 "SCRIPT DE INÍCIO:\n"
 "  -L, --load=\"ARGUMENTOS DO MÓDULO\"    Carrega um plugin especificado com\n"
 "                                        o argumento especificado\n"
 "  -F, --file=NOME_DO_ARQUIVO          Executa o script especificado\n"
-"  -C                                    Abre uma linha de comando no TTY em execução\n"
+"  -C                                    Abre uma linha de comando no TTY em "
+"execução\n"
 "                                       depois da partida\n"
 "\n"
-"  -n                                    Não carrega o arquivo de script padrão\n"
+"  -n                                    Não carrega o arquivo de script "
+"padrão\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize espera argumento booleano"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail espera argumento booleano"
 
-#: ../src/daemon/cmdline.c:264
-msgid "--log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error)."
-msgstr "--log-level espera um argumento em nível de log  (seja numérico na faixa de 0..4 seja algum entre debug, info, notice, warn, error)."
+#: ../src/daemon/cmdline.c:261
+msgid ""
+"--log-level expects log level argument (either numeric in range 0..4 or one "
+"of debug, info, notice, warn, error)."
+msgstr ""
+"--log-level espera um argumento em nível de log  (seja numérico na faixa de "
+"0..4 seja algum entre debug, info, notice, warn, error)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority espera um argumento booleano"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime espera um argumento booleano"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading espera um argumento booleano"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit espera um argumento booleano"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file espera argumento booleano"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr "Log target inválido: use 'syslog', 'stderr' ou 'auto'."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time espera um argumento booleano"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta espera um argumento booleano"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Método de reamostragem inválido '%s'."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system espera argumento booleano"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit espera argumento booleano"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm espera argumento booleano"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Nome: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "Não há informação do módulo disponível\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Versão: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Descrição: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Autor: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Uso: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "Carrega uma vez: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "AVISO DE OBSOLESCÊNCIA: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Caminho: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Alvo do log inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Nível de log inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Método de reamostragem inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] rlimit inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit não tem suporte nessa plataforma."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Formato de amostragem inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Taxa de amostragem inválida '%s'."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Canais de amostragem inválidos'%s'."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] Mapa de canais \"%s\" inválido."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Números de fragmentos inválidos '%s'."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Tamanho de fragmentos inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Número de nice inválido'%s'."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Taxa de amostragem inválida '%s'."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Falha em abrir o arquivo de configuração: %s"
 
-#: ../src/daemon/daemon-conf.c:562
-msgid "The specified default channel map has a different number of channels than the specified default number of channels."
-msgstr "O mapa padrão dos canais especificado tem um número diferente de canais do que o número de canais padrão especificado."
+#: ../src/daemon/daemon-conf.c:657
+msgid ""
+"The specified default channel map has a different number of channels than "
+"the specified default number of channels."
+msgstr ""
+"O mapa padrão dos canais especificado tem um número diferente de canais do "
+"que o número de canais padrão especificado."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Lido do arquivo de configuração: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "Limpando privilégios."
 
@@ -690,8 +812,17 @@ msgstr "Sistema de som PulseAudio"
 msgid "Start the PulseAudio Sound System"
 msgstr "Iniciar o sistema de som PulseAudio"
 
-#: ../src/pulse/channelmap.c:105
-#: ../src/pulse/channelmap.c:757
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "Sistema de som PulseAudio"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "Iniciar o sistema de som PulseAudio"
+
+#: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
 
@@ -720,8 +851,8 @@ msgid "Rear Right"
 msgstr "Posterior direito"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Emissor de baixa freqüência"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -895,12 +1026,10 @@ msgstr "Posterior superior esquerdo"
 msgid "Top Rear Right"
 msgstr "Posterior superior direito"
 
-#: ../src/pulse/channelmap.c:484
-#: ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295
-#: ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341
-#: ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(Inválido)"
 
@@ -928,335 +1057,349 @@ msgstr "Surround 5.1"
 msgid "Surround 7.1"
 msgstr "Surround 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "OK"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "Acesso negado"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Comando desconhecido"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "Argumento inválido"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "Entidade existente"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "Não existe tal entidade"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "Conexão recusada"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "Erro de protocolo"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "Timeout"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "Não há chave para autorização"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "Erro interno"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "Conexão terminada"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "Entidade terminada"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Servidor inválido"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "A inicialização do módulo falhou"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "Mau estado"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Não há dados"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "Versão de protocolo incompatível"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "Muito grande"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "Não há suporte"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Código de erro desconhecido"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "Não existe tal extensão"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "Funcionalidade obsoleta"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "Implementação faltando"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "Cliente bifurcado"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "Erro de entrada/saída"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "Dispositivo ou recurso ocupado"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55
-#: ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() falhou"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_new() falhou: %s"
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "Falhou ao analisar os dados do cookie"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Falha em abrir o arquivo de configuração '%s': %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "Nenhum cookie foi carregado. Tentativa de conexão sem eles."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "Foi recebida uma mensagem para uma extensão desconhecida '%s'"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "Falha ao drenar o fluxo: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "Fluxo de reprodução drenado."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "Drenando conexão para o servidor."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() falhou: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_begin_write() falhou: %s"
 
-#: ../src/utils/pacat.c:237
-#: ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() falhou: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "Fluxo criado com sucesso."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() falhou: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 msgstr "Métricas do buffer: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Métricas do buffer: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "Usando especificação de amostragem \"%s\", mapa de canais \"%s\"."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "Conectado ao dispositivo %s (%u, %ssuspended)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "Erro de fluxo: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "Dispositivo de fluxo suspenso.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "O dispositivo de fluxo continuou.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "Subestimação do fluxo.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "Superestimação do fluxo.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "Fluxo iniciado.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "Fluxo movido para o dispositivo %s (%u, %ssuspended).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "não"
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "Atributos do buffer de fluxo alterados.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "Conexão estabelecida.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() falhou: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() falhou: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() falhou: %s"
 
-#: ../src/utils/pacat.c:470
-#: ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "Falha na conexão: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "Atingiu EOF."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() falhou: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "Sinal recebido, saindo."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "Falha ao obter a latência: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Tempo: %0.3f sec;; Latência: %0.0f usec."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() falhou: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1268,31 +1411,55 @@ msgid ""
 "\n"
 "  -v, --verbose                         Enable verbose operations\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -d, --device=DEVICE                   The name of the sink/source to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
-"      --stream-name=NAME                How to call this stream on the server\n"
-"      --volume=VOLUME                   Specify the initial (linear) volume in range 0...65536\n"
-"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to 44100)\n"
-"      --format=SAMPLEFORMAT             The sample type, one of s16le, s16be, u8, float32le,\n"
-"                                        float32be, ulaw, alaw, s32le, s32be, s24le, s24be,\n"
-"                                        s24-32le, s24-32be (defaults to s16ne)\n"
-"      --channels=CHANNELS               The number of channels, 1 for mono, 2 for stereo\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -d, --device=DEVICE                   The name of the sink/source to "
+"connect to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
+"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to "
+"44100)\n"
+"      --format=SAMPLEFORMAT             The sample type, one of s16le, "
+"s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be, "
+"s24le, s24be,\n"
+"                                        s24-32le, s24-32be (defaults to "
+"s16ne)\n"
+"      --channels=CHANNELS               The number of channels, 1 for mono, "
+"2 for stereo\n"
 "                                        (defaults to 2)\n"
-"      --channel-map=CHANNELMAP          Channel map to use instead of the default\n"
-"      --fix-format                      Take the sample format from the sink the stream is\n"
+"      --channel-map=CHANNELMAP          Channel map to use instead of the "
+"default\n"
+"      --fix-format                      Take the sample format from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-rate                        Take the sampling rate from the sink the stream is\n"
+"      --fix-rate                        Take the sampling rate from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-channels                    Take the number of channels and the channel map\n"
-"                                        from the sink the stream is being connected to.\n"
+"      --fix-channels                    Take the number of channels and the "
+"channel map\n"
+"                                        from the sink the stream is being "
+"connected to.\n"
 "      --no-remix                        Don't upmix or downmix channels.\n"
-"      --no-remap                        Map channels by index instead of name.\n"
-"      --latency=BYTES                   Request the specified latency in bytes.\n"
-"      --process-time=BYTES              Request the specified process time per request in bytes.\n"
-"      --property=PROPERTY=VALUE         Set the specified property to the specified value.\n"
+"      --no-remap                        Map channels by index instead of "
+"name.\n"
+"      --latency=BYTES                   Request the specified latency in "
+"bytes.\n"
+"      --process-time=BYTES              Request the specified process time "
+"per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
+"      --property=PROPERTY=VALUE         Set the specified property to the "
+"specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [opções]\n"
@@ -1303,36 +1470,58 @@ msgstr ""
 "  -r, --record                          Cria uma conexão para gravação\n"
 "  -p, --playback                        Cria uma conexão para reprodução\n"
 "\n"
-"  -v, --verbose                         Habilita operações no modo detalhado\n"
+"  -v, --verbose                         Habilita operações no modo "
+"detalhado\n"
 "\n"
 "  -s, --server=SERVIDOR                   Nome do servidor a conectar-se\n"
-"  -d, --device=DISPOSITIVO                   O nome do destino/fonte a conectar-se\n"
-"  -n, --client-name=NOME                Como chamar este cliente no servidor\n"
+"  -d, --device=DISPOSITIVO                   O nome do destino/fonte a "
+"conectar-se\n"
+"  -n, --client-name=NOME                Como chamar este cliente no "
+"servidor\n"
 "      --stream-name=NOME               Como chamar este fluxo no servidor\n"
-"      --volume=VOLUME                   Especifica a faixa (linear) inicial de volume no intervalo 0...65536\n"
-"      --rate=TAXA_DE_AMOSTRAGEM             Taxa de amostragem em Hz (o padrão é 44100)\n"
-"      --format=FORMATO_DE_AMOSTRAGEM       Tipo de amostragem, um de s16le, s16be, u8, float32le,\n"
-"                                        float32be, ulaw, alaw, s32le, s32be, s24le, s24be,\n"
-"                                        s24-32le, s24-32be (o padrão é s16ne)\n"
-"      --channels=CANAIS               O número de canais, 1 para mono, 2 para estéreo\n"
+"      --volume=VOLUME                   Especifica a faixa (linear) inicial "
+"de volume no intervalo 0...65536\n"
+"      --rate=TAXA_DE_AMOSTRAGEM             Taxa de amostragem em Hz (o "
+"padrão é 44100)\n"
+"      --format=FORMATO_DE_AMOSTRAGEM       Tipo de amostragem, um de s16le, "
+"s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be, "
+"s24le, s24be,\n"
+"                                        s24-32le, s24-32be (o padrão é "
+"s16ne)\n"
+"      --channels=CANAIS               O número de canais, 1 para mono, 2 "
+"para estéreo\n"
 "                                        (o padrão é 2)\n"
-"      --channel-map=MAPA_DE_CANAIS          Mapeamento de canais a ser usado no lugar do padrão\n"
-"      --fix-format                      Obtém o formato da amostragem do destino onde o fluxo\n"
+"      --channel-map=MAPA_DE_CANAIS          Mapeamento de canais a ser usado "
+"no lugar do padrão\n"
+"      --fix-format                      Obtém o formato da amostragem do "
+"destino onde o fluxo\n"
 "                                             está sendo conectado.\n"
-"      --fix-rate                        Obtém a taxa de amostragem do destino onde o fluxo está\n"
+"      --fix-rate                        Obtém a taxa de amostragem do "
+"destino onde o fluxo está\n"
 "                                        sendo conectado.\n"
-"      --fix-channels                    Obtém o número de canais e o mapa de canais\n"
-"                                      do destino onde o fluxo está sendo conectado.\n"
-"      --no-remix                        Não realizar upmix nem downmix dos canais.\n"
-"      --no-remap                        Mapear os canais por índice em vez de nome.\n"
-"      --latency=BYTES                   Requisitar a latência especificada em bytes.\n"
-"      --process-time=BYTES              Requisitar o tempo de processo especificado por requisições em bytes.\n"
-"      --property=PROPRIEDADE=VALOR         Define a propriedade especificada para o valor especificado.\n"
-"      --raw                             Grava/reproduz dados PCM não tratados.\n"
-"      --file-format=FORMATO_DO_ARQ.             Grava/reproduz dados PCM formatados.\n"
-"      --list-file-formats               Lista os formatos de arquivo disponíveis.\n"
-
-#: ../src/utils/pacat.c:731
+"      --fix-channels                    Obtém o número de canais e o mapa de "
+"canais\n"
+"                                      do destino onde o fluxo está sendo "
+"conectado.\n"
+"      --no-remix                        Não realizar upmix nem downmix dos "
+"canais.\n"
+"      --no-remap                        Mapear os canais por índice em vez "
+"de nome.\n"
+"      --latency=BYTES                   Requisitar a latência especificada "
+"em bytes.\n"
+"      --process-time=BYTES              Requisitar o tempo de processo "
+"especificado por requisições em bytes.\n"
+"      --property=PROPRIEDADE=VALOR         Define a propriedade especificada "
+"para o valor especificado.\n"
+"      --raw                             Grava/reproduz dados PCM não "
+"tratados.\n"
+"      --file-format=FORMATO_DO_ARQ.             Grava/reproduz dados PCM "
+"formatados.\n"
+"      --list-file-formats               Lista os formatos de arquivo "
+"disponíveis.\n"
+
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1343,179 +1532,188 @@ msgstr ""
 "Compilado com  libpulse %s\n"
 "Linkado com libpulse %s\n"
 
-#: ../src/utils/pacat.c:764
-#: ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "Nome do cliente \"%s\" inválido"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "Nome do fluxo \"%s\" inválido"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "Mapa de canais \"%s\" inválido"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "Especificação de latência inválida \"%s\""
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "Especificação do tempo de processo \"%s\" inválida"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "Propriedade \"%s\" inválida"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "Formato de arquivo %s desconhecido."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "Especificação de amostragem inválida"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "Argumentos em excesso."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "Falha ao gerar a especificação de amostragem para o arquivo."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "Falha ao abrir o arquivo de áudio."
 
-#: ../src/utils/pacat.c:959
-msgid "Warning: specified sample specification will be overwritten with specification from file."
-msgstr "Aviso: a especificação de amostragem especificada será sobrescrita pela especificação do arquivo."
+#: ../src/utils/pacat.c:1036
+msgid ""
+"Warning: specified sample specification will be overwritten with "
+"specification from file."
+msgstr ""
+"Aviso: a especificação de amostragem especificada será sobrescrita pela "
+"especificação do arquivo."
 
-#: ../src/utils/pacat.c:962
-#: ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "Falha ao determinar a especificação de amostragem a partir do arquivo."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "Aviso: falha ao determinar o mapa de canais a partir do arquivo."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "O mapa de canais não combina com a especificação da amostragem"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "Aviso: falha ao gravar o mapa de canais no arquivo."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
-msgid "Opening a %s stream with sample specification '%s' and channel map '%s'."
-msgstr "Abrindo um fluxo %s com a especificação de amostragem \"%s\" e mapeamento de canais \"%s\"."
+msgid ""
+"Opening a %s stream with sample specification '%s' and channel map '%s'."
+msgstr ""
+"Abrindo um fluxo %s com a especificação de amostragem \"%s\" e mapeamento de "
+"canais \"%s\"."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "gravando"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "playback"
 
-#: ../src/utils/pacat.c:1035
-#: ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "Falha em interpretar a linha de comando."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() falhou."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() falhou."
 
-#: ../src/utils/pacat.c:1061
-#: ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() falhou."
 
-#: ../src/utils/pacat.c:1069
-#: ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_new() falhou: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_rttime_new() falhou."
 
-#: ../src/utils/pacat.c:1082
-#: ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() falhou."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "Falha em suspender: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "Falha ao prosseguir: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
-msgstr "AVISO: O servidor de som não é local, Sound server is not local, não está em suspenso.\n"
+msgstr ""
+"AVISO: O servidor de som não é local, Sound server is not local, não está em "
+"suspenso.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Falha na conexão: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "Recebido o SIGINT, saindo.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "AVISO: O processo filho terminou pelo sinal %u \n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
 "\n"
 msgstr ""
 "%s [options] ... \n"
@@ -1551,35 +1749,46 @@ msgstr "pa_context_new() falhou.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() falhou.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "Falha ao obter estatísticas: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "Em uso no momento: %u blocos contendo %s bytes no total.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "Alocado por todo o tempo: %u blocos contendo %s bytes  no total.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "Tamanho do cache para amostragem: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "Falha ao obter informações do servidor: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1587,7 +1796,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "Nome do usuário: %s\n"
 "Nome da máquina: %s\n"
@@ -1599,13 +1808,13 @@ msgstr ""
 "Fonte padrão %s\n"
 "Cookie: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "Falha ao obter informações do destino: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1621,7 +1830,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1643,24 +1852,27 @@ msgstr ""
 "\tPropriedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268
-#: ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tPortas:\n"
 
-#: ../src/utils/pactl.c:274
-#: ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tPorta ativa: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tPortas:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "Falha ao obter informações da fonte: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1699,28 +1911,20 @@ msgstr ""
 "\tPropriedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345
-#: ../src/utils/pactl.c:401
-#: ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473
-#: ../src/utils/pactl.c:532
-#: ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543
-#: ../src/utils/pactl.c:587
-#: ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594
-#: ../src/utils/pactl.c:637
-#: ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "n/a"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "Falha ao obter informações do módulo: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1737,12 +1941,12 @@ msgstr ""
 "\tPropriedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "Falha ao obter informações do cliente: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1757,12 +1961,12 @@ msgstr ""
 "\tPropriedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "Falha ao obter informações da placa: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1779,23 +1983,23 @@ msgstr ""
 "\tPropriedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tPerfis:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tPerfil ativo: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "Falha ao obter informações da entrada do destino: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1804,6 +2008,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1831,13 +2036,13 @@ msgstr ""
 "\tPropriedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "Falha ao obter informações da saída da fonte: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1846,31 +2051,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Saída da fonte #%u\n"
+"Entrada do destino #%u\n"
 "\tDriver: %s\n"
 "\tMódulo proprietário: %s\n"
 "\tCliente: %s\n"
-"\tFonte: %u\n"
+"\tDestino: %u\n"
 "\tEspecificação da amostragem: %s\n"
 "\tMapa dos canais: %s\n"
+"\tMudo: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balanço %0.2f\n"
 "\tLatência do buffer: %0.0f usec\n"
-"\tLatência da fonte: %0.0f usec\n"
+"\tLatência do destino: %0.0f usec\n"
 "\tMétodo de reamostragem: %s\n"
 "\tPropriedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "Falha ao obter informações sobre a amostragem: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1901,85 +2115,181 @@ msgstr ""
 "\tPropriedades:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653
-#: ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "Falha: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Falha ao obter informações da fonte: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "Falha ao enviar a amostra: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "Fim prematuro do arquivo"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr "destino"
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr "fonte"
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+#, fuzzy
+msgid "source-output"
+msgstr "fonte"
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "Servidor inválido"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "SIGINT recebido, saindo."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "Especificação de volume inválida"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
-msgstr ""
-"%s [opções] stat\n"
-"%s [opções] list\n"
-"%s [opções] exit\n"
-"%s [opções] upload-sample NOME_DO_ARQUIVO [NOME]\n"
-"%s [opções] play-sample NOME [DESTINO]\n"
-"%s [opções] remove-sample NOME\n"
-"%s [opções] move-sink-input ENTRADA DESTINO\n"
-"%s [opções] move-source-output SAÍDA FONTE\n"
-"%s [opções] load-module NOME [ARGS ...]\n"
-"%s [opções] unload-module MÓDULO\n"
-"%s [opções] suspend-sink [DESTINO] 1|0\n"
-"%s [opções] suspend-source [FONTE] 1|0\n"
-"%s [opções] set-card-profile [PLACA] [PERFIL]\n"
-"%s [opções] set-sink-port [DESTINO] [PORTA]\n"
-"%s [opções] set-source-port [FONTE] [PORTA]\n"
-"%s [opções] set-sink-volume DESTINO VOLUME\n"
-"%s [opções] set-source-volume FONTE VOLUME\n"
-"%s [opções] set-sink-input-volume ENTRADA VOLUME\n"
-"%s [opções] set-sink-mute DESTINO 1|0\n"
-"%s [opções] set-source-mute FONTE 1|0\n"
-"%s [opções] set-sink-input-mute ENTRADA 1|0\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+msgstr ""
+"%s [options] ... \n"
 "\n"
-"  -h, --help                            Mostra essa ajuda\n"
-"      --version                        Mostra a versão\n"
+"  -h, --help                          Mostra esta ajuda\n"
+"      --version                         Mostra a versão\n"
+"  -s, --server=SERVER                   Nome do servidor a ser conectado\n"
 "\n"
-"  -s, --server=SERVIDOR                   O nome do servidor a ser conectado\n"
-"  -n, --client-name=NOME                Como chamar este cliente no servidor \n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -1990,104 +2300,143 @@ msgstr ""
 "Compilado com libpulse %s\n"
 "Linkado com libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "Por favor, especifique um arquivo de amostra a ser carregado"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "Falha ao abrir o arquivo de som."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
-msgstr "Aviso: falha ao determinar a especificação da amostragem a partir do arquivo."
+msgstr ""
+"Aviso: falha ao determinar a especificação da amostragem a partir do arquivo."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "Você deve especificar um nome para amostra a ser reproduzida"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "Você deve especificar um nome para a amostra a ser removida"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "Você deve especificar a entrada do destino e um destino"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "Você deve especificar um índice de saída da fonte e uma fonte"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "Você deve especificar um nome para o módulo e seus argumentos."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "Você deve especificar um índice do módulo"
 
-#: ../src/utils/pactl.c:1090
-msgid "You may not specify more than one sink. You have to specify a boolean value."
-msgstr "Você não pode especificar mais de um destino. Você deve especificar um valor booleano."
+#: ../src/utils/pactl.c:1560
+msgid ""
+"You may not specify more than one sink. You have to specify a boolean value."
+msgstr ""
+"Você não pode especificar mais de um destino. Você deve especificar um valor "
+"booleano."
 
-#: ../src/utils/pactl.c:1103
-msgid "You may not specify more than one source. You have to specify a boolean value."
-msgstr "Você não pode especificar mais de uma fonte. Você deve especificar um valor booleano."
+#: ../src/utils/pactl.c:1573
+msgid ""
+"You may not specify more than one source. You have to specify a boolean "
+"value."
+msgstr ""
+"Você não pode especificar mais de uma fonte. Você deve especificar um valor "
+"booleano."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "Você deve especificar um nome/índice para a placa e um nome de perfil"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "Você deve especificar um nome/índice do destino e o nome da porta"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "Você deve especificar um nome/índice da fonte e o nome da porta"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "Você deve especificar um nome/índice do destino e um volume"
 
-#: ../src/utils/pactl.c:1154
-#: ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193
-#: ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226
-#: ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "Especificação de volume inválida"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "Você deve especificar um nome/índice da fonte e um volume"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "Você deve especificar um índice de entrada para o destino e um volume"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "Índice de entrada de destino inválido"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "Você deve especificar um índice de saída da fonte e uma fonte"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "Índice de entrada de destino inválido"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "Você deve especificar um nome/índice do destino e um booleano do mudo"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "Especificação de amostragem inválida"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "Você deve especificar um nome/índice da fonte e um booleano do mudo"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
-msgstr "Você deve especificar um índice de entrada para o destino e um booleano do mudo"
+msgstr ""
+"Você deve especificar um índice de entrada para o destino e um booleano do "
+"mudo"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "Especificação do índice de entrada de destino inválida"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "Você deve especificar um nome/índice da fonte e um booleano do mudo"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "Especificação do índice de entrada de destino inválida"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "Você deve especificar um nome/índice do destino e um booleano do mudo"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "Nenhum comando válido especificado."
 
@@ -2098,14 +2447,17 @@ msgid ""
 "\n"
 " -d    Show current PulseAudio data attached to X11 display (default)\n"
 " -e    Export local PulseAudio data to X11 display\n"
-" -i    Import PulseAudio data from X11 display to local environment variables and cookie file.\n"
+" -i    Import PulseAudio data from X11 display to local environment "
+"variables and cookie file.\n"
 " -r    Remove PulseAudio data from X11 display\n"
 msgstr ""
 "%s [-D display] [-S server] [-O sink] [-I source] [-c file]  [-d|-e|-i|-r]\n"
 "\n"
-" -d    Mostra os dados atuais do PulseAudio associados ao display X11 (padrão)\n"
+" -d    Mostra os dados atuais do PulseAudio associados ao display X11 "
+"(padrão)\n"
 " -e    Exporta os dados locais do PulseAudio para um display X11 \n"
-" -i     Importa os dados do PulseAudio de um display X11 para as variáveis de ambiente locais e para o arquivo de cookie.\n"
+" -i     Importa os dados do PulseAudio de um display X11 para as variáveis "
+"de ambiente locais e para o arquivo de cookie.\n"
 " -r    Remove os dados do PulseAudio do display X11\n"
 
 #: ../src/utils/pax11publish.c:94
@@ -2113,449 +2465,731 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "Falha em interpretar a linha de comando.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Servidor: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Fonte: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Destino: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Cookie: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "Falha ao analisar os dados do cookie\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "Falha em salvar os dados do cookie\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "Falha em carregar o arquivo de configuração do cliente.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "Falha em ler os dados de configuração do ambiente\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "Falha na obtenção do FQDN.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "Falha em carregar os dados do cookie\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Ainda não implementado.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
-msgstr "Nenhum daemon do PulseAudio em execução ou não está em execução como daemon de sessão."
+msgstr ""
+"Nenhum daemon do PulseAudio em execução ou não está em execução como daemon "
+"de sessão."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "Falha ao matar o daemon do PulseAudio."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "O daemon não responde."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171
-#: ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207
-#: ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136
-#: ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "Não foi possível acessar a trava de autogeração."
 
-#: ../src/modules/alsa/alsa-sink.c:530
-#: ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, 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."
+"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 ""
-"O ALSA nos acordou para gravar novos dados no dispositivo, mas não há nada a ser gravado!\n"
-"É mais provável que isso seja um erro no driver \"%s\" do ALSA. Por favor, relate esse problema para os desenvolvedores do ALSA.\n"
-"Nós fomos acordados com o conjunto POLLOUT -- entretanto, a snd_pcm_avail() subseqüente retornou 0 ou outro valor < min_avail."
+"O ALSA nos acordou para gravar novos dados no dispositivo, mas não há nada a "
+"ser gravado!\n"
+"É mais provável que isso seja um erro no driver \"%s\" do ALSA. Por favor, "
+"relate esse problema para os desenvolvedores do ALSA.\n"
+"Nós fomos acordados com o conjunto POLLOUT -- entretanto, a snd_pcm_avail() "
+"subseqüente retornou 0 ou outro valor < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506
-#: ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, 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."
+"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 ""
-"O ALSA nos acordou para ler novos dados no dispositivo, mas não há nada a ser lido!\n"
-"É mais provável que isso seja um erro no driver \"%s\" do ALSA. Por favor, relate esse problema para os desenvolvedores do ALSA.\n"
-"Nós fomos acordados com o conjunto POLLIN -- entretanto, a snd_pcm_avail() subseqüente retornou 0 ou outro valor < min_avail."
-
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+"O ALSA nos acordou para ler novos dados no dispositivo, mas não há nada a "
+"ser lido!\n"
+"É mais provável que isso seja um erro no driver \"%s\" do ALSA. Por favor, "
+"relate esse problema para os desenvolvedores do ALSA.\n"
+"Nós fomos acordados com o conjunto POLLIN -- entretanto, a snd_pcm_avail() "
+"subseqüente retornou 0 ou outro valor < min_avail."
+
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "Desligado"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "Reprodução de alta fidelidade (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "Captura de alta fidelidade (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Duplex telefônico (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "Servidor de som PulseAudio"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
 msgstr "Dispositivos de saída"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
 msgstr "Dispositivos de entrada"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
 msgstr "Áudio em @HOSTNAME@"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
 msgstr "Entrada"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
 msgstr "Entrada da base de encaixe"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
 msgstr "Microfone da base de encaixe"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "Entrada da base de encaixe"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
 msgstr "Entrada de linha"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
 msgstr "Microfone"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "Microfone da base de encaixe"
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "Microfone"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
 msgid "External Microphone"
 msgstr "Microfone externo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
 msgstr "Microfone interno"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
 msgstr "Rádio"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
 msgstr "Vídeo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
 msgstr "Ganho de controle automático"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
 msgstr "Sem ganho de controle automático"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
 msgstr "Impulso"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
 msgstr "Sem impulso"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
 msgstr "Amplificador"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
 msgstr "Sem amplificador"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr "Entrada analógica"
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "Impulso"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr "Microfone analógico"
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "Sem impulso"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
-msgstr "Entrada de linha analógica"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr "Rádio analógico"
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "Fones de ouvido analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr "Vídeo analógico"
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "Entrada analógica"
+
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "Microfone da base de encaixe"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
 msgstr "Saída analógica"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr "Fones de ouvido analógico"
-
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
 msgstr "Saída analógica (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "Entrada de linha"
+
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
 msgstr "Saída analógica monofônica"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, c-format
-msgid "%s+%s"
-msgstr "%s+%s"
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "Estéreo analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984
-#: ../src/modules/alsa/alsa-mixer.c:3404
-#, c-format
-msgid "%s / %s"
-msgstr "%s / %s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Estéreo digital (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Estéreo digital (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr "Monofônico analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr "Estéreo analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
 msgstr "Surround analógico 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
 msgstr "Surround analógico 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
 msgstr "Surround analógico 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr "Surround analógico 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr "Surround analógico 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr "Surround analógico 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr "Surround analógico 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
 msgstr "Surround analógico 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
 msgstr "Surround analógico 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
 msgstr "Surround analógico 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr "Surround analógico 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr "Estéreo digital (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "Surround 4.0 digital (IEC958)"
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Estéreo digital (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Surround digital 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Surround digital 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr "Estéreo digital (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Surround digital 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
 msgstr "Duplex monofônico analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
 msgstr "Duplex estéreo analógico"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
 msgstr "Duplex estéreo digital (IEC958)"
 
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Saída nula"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "Entrada"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<nome do destino> sink_properties=<propriedades do destino> "
+"master=<nome do destino a ser filtrado> format=<formato de amostragem> "
+"rate=<taxa da amostragem> channels=<número de canais> channel_map=<mapa dos "
+"canais> plugin=<nome do plugin ladspa> label=<rótulo do plugin ladspa> "
+"control=<lista separada por vírgulas dos valores de controle da entrada>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit não tem suporte nessa plataforma."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() falhou"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Saída da fonte #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tMódulo proprietário: %s\n"
+#~ "\tCliente: %s\n"
+#~ "\tFonte: %u\n"
+#~ "\tEspecificação da amostragem: %s\n"
+#~ "\tMapa dos canais: %s\n"
+#~ "\tLatência do buffer: %0.0f usec\n"
+#~ "\tLatência da fonte: %0.0f usec\n"
+#~ "\tMétodo de reamostragem: %s\n"
+#~ "\tPropriedades:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [opções] stat\n"
+#~ "%s [opções] list\n"
+#~ "%s [opções] exit\n"
+#~ "%s [opções] upload-sample NOME_DO_ARQUIVO [NOME]\n"
+#~ "%s [opções] play-sample NOME [DESTINO]\n"
+#~ "%s [opções] remove-sample NOME\n"
+#~ "%s [opções] move-sink-input ENTRADA DESTINO\n"
+#~ "%s [opções] move-source-output SAÍDA FONTE\n"
+#~ "%s [opções] load-module NOME [ARGS ...]\n"
+#~ "%s [opções] unload-module MÓDULO\n"
+#~ "%s [opções] suspend-sink [DESTINO] 1|0\n"
+#~ "%s [opções] suspend-source [FONTE] 1|0\n"
+#~ "%s [opções] set-card-profile [PLACA] [PERFIL]\n"
+#~ "%s [opções] set-sink-port [DESTINO] [PORTA]\n"
+#~ "%s [opções] set-source-port [FONTE] [PORTA]\n"
+#~ "%s [opções] set-sink-volume DESTINO VOLUME\n"
+#~ "%s [opções] set-source-volume FONTE VOLUME\n"
+#~ "%s [opções] set-sink-input-volume ENTRADA VOLUME\n"
+#~ "%s [opções] set-sink-mute DESTINO 1|0\n"
+#~ "%s [opções] set-source-mute FONTE 1|0\n"
+#~ "%s [opções] set-sink-input-mute ENTRADA 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Mostra essa ajuda\n"
+#~ "      --version                        Mostra a versão\n"
+#~ "\n"
+#~ "  -s, --server=SERVIDOR                   O nome do servidor a ser "
+#~ "conectado\n"
+#~ "  -n, --client-name=NOME                Como chamar este cliente no "
+#~ "servidor \n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Surround 4.0 digital (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Emissor de baixa freqüência"
+
 #~ msgid "Invalid client name '%s'\n"
 #~ msgstr "Nome do cliente \"%s\" inválido\n"
+
 #~ msgid "Failed to determine sample specification from file.\n"
 #~ msgstr ""
 #~ "Falha ao determinar a especificação de amostragem a partir do arquivo.\n"
+
 #~ msgid "select(): %s"
 #~ msgstr "select(): %s"
+
 #~ msgid "Cannot connect to system bus: %s"
 #~ msgstr "Não foi possível conectar com o barramento do sistema: %s"
+
 #~ msgid "Cannot get caller from PID: %s"
 #~ msgstr "Não foi possível obter quem chamou pelo PID: %s"
+
 #~ msgid "Cannot set UID on caller object."
 #~ msgstr "Não foi possível definir o UID sobre o objeto que chamou."
+
 #~ msgid "Failed to get CK session."
 #~ msgstr "Falha em obter a sessão CK."
+
 #~ msgid "Cannot set UID on session object."
 #~ msgstr "Não foi possível definir o UID do objeto da sessão."
+
 #~ msgid "Cannot allocate PolKitAction."
 #~ msgstr "Não foi possível alocar o PolKitAction."
+
 #~ msgid "Cannot set action_id"
 #~ msgstr "Não foi possível definir a action_id"
+
 #~ msgid "Cannot allocate PolKitContext."
 #~ msgstr "Não foi possível alocar o PolKitContext."
+
 #~ msgid "Cannot initialize PolKitContext: %s"
 #~ msgstr "Não foi possível iniciar o PolKitContext: %s"
+
 #~ msgid "Could not determine whether caller is authorized: %s"
 #~ msgstr "Não foi possível determinar se o solicitante está autorizado: %s"
+
 #~ msgid "Cannot obtain auth: %s"
 #~ msgstr "Não foi possível obter auth: %s"
+
 #~ msgid "PolicyKit responded with '%s'"
 #~ msgstr "PolicyKit respondeu com '%s'"
+
 #~ msgid ""
 #~ "High-priority scheduling (negative Unix nice level) for the PulseAudio "
 #~ "daemon"
 #~ msgstr ""
 #~ "Escalonamento de alta prioridade (nível de nice Unix negativo) para o "
 #~ "daemon do PulseAudio"
+
 #~ msgid "Real-time scheduling for the PulseAudio daemon"
 #~ msgstr "Escalonamento em tempo real para o daemon do PulseAudio"
+
 #~ msgid ""
 #~ "System policy prevents PulseAudio from acquiring high-priority scheduling."
 #~ msgstr ""
 #~ "Uma política do sistema impede que o PulseAudio adquira escalonamento de "
 #~ "alta prioridade."
+
 #~ msgid ""
 #~ "System policy prevents PulseAudio from acquiring real-time scheduling."
 #~ msgstr ""
 #~ "Uma política do sistema impede que o PulseAudio adquira o escalonamento "
 #~ "em tempo real."
+
 #~ msgid "read() failed: %s\n"
 #~ msgstr "read() falhou: %s\n"
+
 #~ msgid "pa_context_connect() failed: %s\n"
 #~ msgstr "pa_context_connect() falhou: %s\n"
+
 #~ msgid "We're in the group '%s', allowing high-priority scheduling."
 #~ msgstr "Estamos no grupo '%s', permitindo escalonamento de alta prioridade."
+
 #~ msgid "We're in the group '%s', allowing real-time scheduling."
 #~ msgstr "Estamos no grupo '%s', permitindo escalonamento em tempo real."
+
 #~ msgid "PolicyKit grants us acquire-high-priority privilege."
 #~ msgstr ""
 #~ "O PolicyKit assegura-nos a aquisição de privilégio de alta prioridade."
+
 #~ msgid "PolicyKit refuses acquire-high-priority privilege."
 #~ msgstr "O PolicyKit recusa a aquisição de privilégios de alta prioridade."
+
 #~ msgid "PolicyKit grants us acquire-real-time privilege."
 #~ msgstr "O PolicyKit assegura-nos a aquisição de privilégios de tempo-real."
+
 #~ msgid "PolicyKit refuses acquire-real-time privilege."
 #~ msgstr "O PolicyKit recusa a aquisição de privilégios de tempo real."
+
 #~ msgid ""
 #~ "High-priority scheduling enabled in configuration but not allowed by "
 #~ "policy."
 #~ msgstr ""
 #~ "O escalonamento de alta prioridade foi habilitado para esta configuração, "
 #~ "mas não é permitida pela política."
+
 #~ msgid "Successfully increased RLIMIT_RTPRIO"
 #~ msgstr "RLIMIT_RTPRIO aumentado com sucesso"
+
 #~ msgid "RLIMIT_RTPRIO failed: %s"
 #~ msgstr "RLIMIT_RTPRIO falhou: %s"
+
 #~ msgid "Giving up CAP_NICE"
 #~ msgstr "Abandonando CAP_NICE"
+
 #~ msgid ""
 #~ "Real-time scheduling enabled in configuration but not allowed by policy."
 #~ msgstr ""
 #~ "O escalonamento de tempo real foi habilitado pela configuração, mas não é "
 #~ "permitido pela política."
+
 #~ msgid "Limited capabilities successfully to CAP_SYS_NICE."
 #~ msgstr "As capacidades foram limitadas com sucesso para CAP_SYS_NICE."
+
 #~ msgid "time_new() failed.\n"
 #~ msgstr "time_new() falhou.\n"
+
 #~ msgid "Stream successfully created\n"
 #~ msgstr "Fluxo criado com sucesso\n"
+
 #~ msgid "Stream errror: %s\n"
 #~ msgstr "Erro de fluxo: %s\n"
+
 #~ msgid "Connection established.\n"
 #~ msgstr "Conexão estabelecida.\n"
+
 #~ msgid ""
 #~ "%s [options] [FILE]\n"
 #~ "\n"
@@ -2594,6 +3228,7 @@ msgstr "Duplex estéreo digital (IEC958)"
 #~ "      --volume=VOLUME                   Especifica o volume inicial "
 #~ "(linear) no intervalo 0...65536\n"
 #~ "      --channel-map=CHANNELMAP          Define o mapa do canal para uso\n"
+
 #~ msgid ""
 #~ "paplay %s\n"
 #~ "Compiled with libpulse %s\n"
@@ -2602,12 +3237,16 @@ msgstr "Duplex estéreo digital (IEC958)"
 #~ "paplay %s\n"
 #~ "Compilado com libpulse %s\n"
 #~ "Linkado com  libpulse %s\n"
+
 #~ msgid "Invalid channel map\n"
 #~ msgstr "Mapa de canais inválido\n"
+
 #~ msgid "Failed to open file '%s'\n"
 #~ msgstr "Falha ao abrir o arquivo '%s'\n"
+
 #~ msgid "Channel map doesn't match file.\n"
 #~ msgstr "O mapa dos canais não coincide com o arquivo.\n"
+
 #~ msgid "Using sample spec '%s'\n"
 #~ msgstr "Usando a especificação da amostragem '%s'\n"
 
@@ -2626,14 +3265,19 @@ msgstr "Duplex estéreo digital (IEC958)"
 #, fuzzy
 #~ msgid "--log-time boolean argument"
 #~ msgstr "--disallow-exit argumento booleano"
+
 #~ msgid "Default sink name (%s) does not exist in name register."
 #~ msgstr "O nome padrão do destino (%s) não existe no registro de nomes."
+
 #~ msgid "Buffer overrun, dropping incoming data\n"
 #~ msgstr "Houve estouro de buffer, os dados que chegaram foram descartados\n"
+
 #~ msgid "pa_stream_drop() failed: %s\n"
 #~ msgstr "pa_stream_drop() falhou: %s\n"
+
 #~ msgid "muted"
 #~ msgstr "mudo"
+
 #~ msgid ""
 #~ "*** Autoload Entry #%u ***\n"
 #~ "Name: %s\n"
@@ -2646,10 +3290,7 @@ msgstr "Duplex estéreo digital (IEC958)"
 #~ "Tipo: %s\n"
 #~ "Módulo: %s\n"
 #~ "Argumento: %s\n"
-#~ msgid "sink"
-#~ msgstr "destino"
-#~ msgid "source"
-#~ msgstr "fonte"
+
 #~ msgid ""
 #~ "' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
 #~ "For enabling real-time scheduling please acquire the appropriate "
@@ -2659,12 +3300,13 @@ msgstr "Duplex estéreo digital (IEC958)"
 #~ "outra vez.\n"
 #~ " Para habilitar o escalonamento em tempo real, por favo, adquira os "
 #~ "privilégios adequados pelo PolicyKit, ou torne-se membro do'"
+
 #~ msgid ""
 #~ "', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this "
 #~ "user."
 #~ msgstr ""
 #~ "', ou eleve o RLIMIT_NICE/RLIMIT_RTPRIO dos limites do recurso para este "
 #~ "usuário."
+
 #~ msgid "socketpair(): %s"
 #~ msgstr "socketpair(): %s"
-
diff --git a/po/ru.po b/po/ru.po
new file mode 100644 (file)
index 0000000..e131e39
--- /dev/null
+++ b/po/ru.po
@@ -0,0 +1,3038 @@
+# Russian translation of pulseaudio.
+# Copyright (C) 2010 pulseaudio
+# This file is distributed under the same license as the pulseaudio package.
+# Leonid Kurbatov <llenchikk@rambler.ru>, 2010, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pulseaudio.master-tx\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:55+0000\n"
+"Last-Translator: Leonid Kurbatov <llenchikk@rambler.ru>\n"
+"Language-Team: Russian <->\n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: -\n"
+
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
+#, 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 ""
+"snd_pcm_avail() возвращает значение, которое является исключительно большим: "
+"%lu байт (%lu мс).\n"
+"Вероятно, это ошибка в драйвере ALSA '%s'. Пожалуйста, сообщите об этой "
+"проблеме разработчикам ALSA."
+
+#: ../src/modules/alsa/alsa-util.c:1179
+#, 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."
+msgstr ""
+"snd_pcm_delay() возвращает значение, которое является исключительно большим: "
+"%li байт (%s%lu мс).\n"
+"Вероятно, это ошибка в драйвере ALSA '%s'. Пожалуйста, сообщите об этой "
+"проблеме разработчикам ALSA."
+
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() возвращает значение, которое является исключительно большим: "
+"%lu байт (%lu мс).\n"
+"Вероятно, это ошибка в драйвере ALSA '%s'. Пожалуйста, сообщите об этой "
+"проблеме разработчикам ALSA."
+
+#: ../src/modules/alsa/alsa-util.c:1263
+#, 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."
+msgstr ""
+"snd_pcm_mmap_begin() возвращает значение, которое является исключительно "
+"большим: %lu байт (%lu мс).\n"
+"Вероятно, это ошибка в драйвере ALSA '%s'. Пожалуйста, сообщите об этой "
+"проблеме разработчикам ALSA."
+
+#: ../src/modules/module-always-sink.c:38
+msgid "Always keeps at least one sink loaded even if it's a null one"
+msgstr ""
+"Всегда оставлять хотя бы один аудиоприёмник загруженным, даже если он "
+"неопределён."
+
+#: ../src/modules/module-always-sink.c:82
+msgid "Dummy Output"
+msgstr "Фиктивный выход"
+
+#: ../src/modules/module-ladspa-sink.c:48
+msgid "Virtual LADSPA sink"
+msgstr "Виртуальный LADSPA аудиоприёмник"
+
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
+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> "
+"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> "
+msgstr ""
+"sink_name=<имя аудиоприёмника> sink_properties=<свойства аудиоприёмника> "
+"master=<имя аудиоприёмника для фильтрации> format=<формат> rate=<частота> "
+"channels=<число каналов> channel_map=<схема каналов> plugin=<имя плагина "
+"ladspa> label=<метка плагина ladspa> control=<список входных значений, "
+"разделённый запятыми>"
+
+#: ../src/modules/module-null-sink.c:49
+msgid "Clocked NULL sink"
+msgstr "Синхронизированный NULL аудиоприёмник"
+
+#: ../src/modules/module-null-sink.c:284
+msgid "Null Output"
+msgstr "Пустой выход"
+
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
+msgstr "Встроенное аудио"
+
+#: ../src/pulsecore/sink.c:3354
+msgid "Modem"
+msgstr "Модем"
+
+#: ../src/daemon/ltdl-bind-now.c:127
+msgid "Failed to find original lt_dlopen loader."
+msgstr "Не удалось найти оригинальный lt_dlopen загрузчик."
+
+#: ../src/daemon/ltdl-bind-now.c:132
+msgid "Failed to allocate new dl loader."
+msgstr "Не удалось выделить новый dl загрузчик."
+
+#: ../src/daemon/ltdl-bind-now.c:145
+msgid "Failed to add bind-now-loader."
+msgstr "Не удалось добавить bind-now-загрузчик."
+
+#: ../src/daemon/main.c:139
+#, c-format
+msgid "Got signal %s."
+msgstr "Получен сигнал %s."
+
+#: ../src/daemon/main.c:166
+msgid "Exiting."
+msgstr "Выход."
+
+#: ../src/daemon/main.c:184
+#, c-format
+msgid "Failed to find user '%s'."
+msgstr "Не удалось найти пользователя '%s'."
+
+#: ../src/daemon/main.c:189
+#, c-format
+msgid "Failed to find group '%s'."
+msgstr "Не удалось найти группу '%s'."
+
+#: ../src/daemon/main.c:193
+#, c-format
+msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
+msgstr "Найден пользователь '%s' (UID %lu) и группа '%s' (GID %lu)."
+
+#: ../src/daemon/main.c:198
+#, c-format
+msgid "GID of user '%s' and of group '%s' don't match."
+msgstr "Идентификаторы групп пользователя '%s' и группы '%s' не совпадают."
+
+#: ../src/daemon/main.c:203
+#, c-format
+msgid "Home directory of user '%s' is not '%s', ignoring."
+msgstr "Домашняя папка пользователя '%s' не является '%s', игнорирование."
+
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
+#, c-format
+msgid "Failed to create '%s': %s"
+msgstr "Не удалось создать '%s': %s"
+
+#: ../src/daemon/main.c:218
+#, c-format
+msgid "Failed to change group list: %s"
+msgstr "Ошибка при изменении списка групп: %s"
+
+#: ../src/daemon/main.c:234
+#, c-format
+msgid "Failed to change GID: %s"
+msgstr "Не удалось изменить идентификатор группы GID: %s"
+
+#: ../src/daemon/main.c:250
+#, c-format
+msgid "Failed to change UID: %s"
+msgstr "Не удалось изменить идентификатор пользователя UID: %s"
+
+#: ../src/daemon/main.c:269
+msgid "Successfully dropped root privileges."
+msgstr "Успешное удаление привилегий администратора."
+
+#: ../src/daemon/main.c:277
+msgid "System wide mode unsupported on this platform."
+msgstr "Расширенный системный режим не поддерживается на этой платформе."
+
+#: ../src/daemon/main.c:295
+#, c-format
+msgid "setrlimit(%s, (%u, %u)) failed: %s"
+msgstr "setrlimit(%s, (%u, %u)) не удалось: %s"
+
+#: ../src/daemon/main.c:496
+msgid "Failed to parse command line."
+msgstr "Ошибка разбора командной строки."
+
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
+msgid "Daemon not running"
+msgstr "Демон не запущен"
+
+#: ../src/daemon/main.c:613
+#, c-format
+msgid "Daemon running as PID %u"
+msgstr "Демон запущен как PID %u"
+
+#: ../src/daemon/main.c:628
+#, c-format
+msgid "Failed to kill daemon: %s"
+msgstr "Не удалось убить демон: %s"
+
+#: ../src/daemon/main.c:657
+msgid ""
+"This program is not intended to be run as root (unless --system is "
+"specified)."
+msgstr ""
+"Эта программа не предназначена для запуска с правами администратора (если не "
+"указано в системе)."
+
+#: ../src/daemon/main.c:660
+msgid "Root privileges required."
+msgstr "Необходимы права администратора."
+
+#: ../src/daemon/main.c:667
+msgid "--start not supported for system instances."
+msgstr "--start не поддерживается для системных элементов."
+
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
+msgid "Running in system mode, but --disallow-exit not set!"
+msgstr "Запущен в системном режиме, но --disallow-exit не задан!"
+
+#: ../src/daemon/main.c:721
+msgid "Running in system mode, but --disallow-module-loading not set!"
+msgstr "Запущен в системном режиме, но --disallow-module-loading не задан!"
+
+#: ../src/daemon/main.c:724
+msgid "Running in system mode, forcibly disabling SHM mode!"
+msgstr "Запущен в системном режиме с принудительным отключением режима SHM!"
+
+#: ../src/daemon/main.c:729
+msgid "Running in system mode, forcibly disabling exit idle time!"
+msgstr ""
+"Запущен в системном режиме с принудительным отключением времени выхода после "
+"простоя!"
+
+#: ../src/daemon/main.c:757
+msgid "Failed to acquire stdio."
+msgstr "Не удалось запросить stdio."
+
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
+msgstr "Канал не удался: %s"
+
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
+#, c-format
+msgid "fork() failed: %s"
+msgstr "fork() ветвь не удалась: %s"
+
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
+#, c-format
+msgid "read() failed: %s"
+msgstr "read() чтение не удалось: %s"
+
+#: ../src/daemon/main.c:789
+msgid "Daemon startup failed."
+msgstr "Запуск демона не удался."
+
+#: ../src/daemon/main.c:791
+msgid "Daemon startup successful."
+msgstr "Успешный запуск демона."
+
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() чтение не удалось: %s"
+
+#: ../src/daemon/main.c:901
+#, c-format
+msgid "This is PulseAudio %s"
+msgstr "PulseAudio %s"
+
+#: ../src/daemon/main.c:902
+#, c-format
+msgid "Compilation host: %s"
+msgstr "Хост компиляции: %s"
+
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
+#, c-format
+msgid "Compilation CFLAGS: %s"
+msgstr "Компиляция CFLAGS: %s"
+
+#: ../src/daemon/main.c:906
+#, c-format
+msgid "Running on host: %s"
+msgstr "Запущен на хосте: %s"
+
+#: ../src/daemon/main.c:909
+#, c-format
+msgid "Found %u CPUs."
+msgstr "Найдено процессоров: %u."
+
+#: ../src/daemon/main.c:911
+#, c-format
+msgid "Page size is %lu bytes"
+msgstr "Размер страницы: %lu байт"
+
+#: ../src/daemon/main.c:914
+msgid "Compiled with Valgrind support: yes"
+msgstr "Скомпилировано с поддержкой Valgrind: да"
+
+#: ../src/daemon/main.c:916
+msgid "Compiled with Valgrind support: no"
+msgstr "Скомпилировано с поддержкой Valgrind: нет"
+
+#: ../src/daemon/main.c:919
+#, c-format
+msgid "Running in valgrind mode: %s"
+msgstr "Запуск в режиме Valgrind: %s"
+
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "Запущен на хосте: %s"
+
+#: ../src/daemon/main.c:924
+msgid "Optimized build: yes"
+msgstr "Оптимизированная сборка: да"
+
+#: ../src/daemon/main.c:926
+msgid "Optimized build: no"
+msgstr "Оптимизированная сборка: нет"
+
+#: ../src/daemon/main.c:930
+msgid "NDEBUG defined, all asserts disabled."
+msgstr "NDEBUG задан, все ассерты запрещены."
+
+#: ../src/daemon/main.c:932
+msgid "FASTPATH defined, only fast path asserts disabled."
+msgstr "FASTPATH задан, запрещены только fast path ассерты."
+
+#: ../src/daemon/main.c:934
+msgid "All asserts enabled."
+msgstr "Все ассерты разрешены."
+
+#: ../src/daemon/main.c:938
+msgid "Failed to get machine ID"
+msgstr "Не удалось получить ID машины"
+
+#: ../src/daemon/main.c:941
+#, c-format
+msgid "Machine ID is %s."
+msgstr "ID машины %s."
+
+#: ../src/daemon/main.c:945
+#, c-format
+msgid "Session ID is %s."
+msgstr "ID сессии %s."
+
+#: ../src/daemon/main.c:951
+#, c-format
+msgid "Using runtime directory %s."
+msgstr "Использование каталога изолированного окружения %s."
+
+#: ../src/daemon/main.c:956
+#, c-format
+msgid "Using state directory %s."
+msgstr "Использование заданного каталога %s."
+
+#: ../src/daemon/main.c:959
+#, c-format
+msgid "Using modules directory %s."
+msgstr "Использование каталога модулей %s."
+
+#: ../src/daemon/main.c:961
+#, c-format
+msgid "Running in system mode: %s"
+msgstr "Запуск в системном режиме: %s"
+
+#: ../src/daemon/main.c:964
+msgid ""
+"OK, so you are running PA in system mode. Please note that you most likely "
+"shouldn't be doing that.\n"
+"If you do it nonetheless then it's your own fault if things don't work as "
+"expected.\n"
+"Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an "
+"explanation why system mode is usually a bad idea."
+msgstr ""
+"Итак, вы запускаете PA в системном режиме. Помните, что вам, скорее всего, "
+"не следует делать этого.\n"
+"Если вы это всё равно делаете, то ваша вина, что вещи не работают как "
+"ожидалось.\n"
+"Пожалуйста прочитайте http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode "
+"для объяснения, почему системный режим обычно является плохой идеей."
+
+#: ../src/daemon/main.c:981
+msgid "pa_pid_file_create() failed."
+msgstr "pa_pid_file_create() не удалось."
+
+#: ../src/daemon/main.c:991
+msgid "Fresh high-resolution timers available! Bon appetit!"
+msgstr "Доступен свежий таймер высокого разрешения! Приятного аппетита!"
+
+#: ../src/daemon/main.c:993
+msgid ""
+"Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
+"resolution timers enabled!"
+msgstr ""
+"Братан, твоё ядро воняет! Сегодняшняя рекомендация шефа - ядро с включенным "
+"таймером высокого разрешения!"
+
+#: ../src/daemon/main.c:1011
+msgid "pa_core_new() failed."
+msgstr "pa_core_new() не удалась."
+
+#: ../src/daemon/main.c:1087
+msgid "Failed to initialize daemon."
+msgstr "Ошибка инициализации демона."
+
+#: ../src/daemon/main.c:1092
+msgid "Daemon startup without any loaded modules, refusing to work."
+msgstr "Запуск демона без каких-либо загружаемых модулей, отказ от работы."
+
+#: ../src/daemon/main.c:1130
+msgid "Daemon startup complete."
+msgstr "Запуск демона завершён."
+
+#: ../src/daemon/main.c:1136
+msgid "Daemon shutdown initiated."
+msgstr "Завершение демона инициализировано."
+
+#: ../src/daemon/main.c:1167
+msgid "Daemon terminated."
+msgstr "Демон завершён."
+
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, 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                                    Increase the verbosity level\n"
+"      --log-target={auto,syslog,stderr,file: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"
+"\n"
+"STARTUP SCRIPT:\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module "
+"with\n"
+"                                        the specified argument\n"
+"  -F, --file=FILENAME                   Run the specified script\n"
+"  -C                                    Open a command line on the running "
+"TTY\n"
+"                                        after startup\n"
+"\n"
+"  -n                                    Don't load default script file\n"
+msgstr ""
+"%s [options]\n"
+"\n"
+"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"
+"      --module-idle-time=SECS           Unload autoloaded modules when idle "
+"and\n"
+"                                        this time passed\n"
+"      --scache-idle-time=SECS           Unload autoloaded samples when idle "
+"and\n"
+"                                        this time passed\n"
+"      --log-level[=LEVEL]               Increase or set verbosity level\n"
+"  -v                                    Increase the verbosity level\n"
+"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --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"
+"\n"
+"STARTUP SCRIPT:\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module "
+"with\n"
+"                                        the specified argument\n"
+"  -F, --file=FILENAME                   Run the specified script\n"
+"  -C                                    Open a command line on the running "
+"TTY\n"
+"                                        after startup\n"
+"\n"
+"  -n                                    Don't load default script file\n"
+
+#: ../src/daemon/cmdline.c:244
+msgid "--daemonize expects boolean argument"
+msgstr "--daemonize ожидает логический аргумент"
+
+#: ../src/daemon/cmdline.c:251
+msgid "--fail expects boolean argument"
+msgstr "--fail ожидает логический аргумент"
+
+#: ../src/daemon/cmdline.c:261
+msgid ""
+"--log-level expects log level argument (either numeric in range 0..4 or one "
+"of debug, info, notice, warn, error)."
+msgstr ""
+"--log-level ожидает аргумент протоколирования (или числовой в диапазоне 0..4 "
+"или одному из debug, info, notice, warn, error)."
+
+#: ../src/daemon/cmdline.c:273
+msgid "--high-priority expects boolean argument"
+msgstr "--high-priority ожидает логический аргумент"
+
+#: ../src/daemon/cmdline.c:280
+msgid "--realtime expects boolean argument"
+msgstr "--realtime ожидает логический аргумент"
+
+#: ../src/daemon/cmdline.c:287
+msgid "--disallow-module-loading expects boolean argument"
+msgstr "--disallow-module-loading ожидает логический аргумент"
+
+#: ../src/daemon/cmdline.c:294
+msgid "--disallow-exit expects boolean argument"
+msgstr "--disallow-exit ожидает логический аргумент"
+
+#: ../src/daemon/cmdline.c:301
+msgid "--use-pid-file expects boolean argument"
+msgstr "--use-pid-file ожидает логический аргумент"
+
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
+msgstr "Недопустимый журнал: используйте либо 'syslog', 'stderr' или 'auto'."
+
+#: ../src/daemon/cmdline.c:325
+msgid "--log-time expects boolean argument"
+msgstr "--log-time ожидает логический аргумент"
+
+#: ../src/daemon/cmdline.c:332
+msgid "--log-meta expects boolean argument"
+msgstr "--log-meta ожидает логический аргумент"
+
+#: ../src/daemon/cmdline.c:351
+#, c-format
+msgid "Invalid resample method '%s'."
+msgstr "Недопустимый метод ресэмплирования '%s'."
+
+#: ../src/daemon/cmdline.c:358
+msgid "--system expects boolean argument"
+msgstr "--system ожидает логический аргумент"
+
+#: ../src/daemon/cmdline.c:365
+msgid "--no-cpu-limit expects boolean argument"
+msgstr "--no-cpu-limit ожидает логический аргумент"
+
+#: ../src/daemon/cmdline.c:372
+msgid "--disable-shm expects boolean argument"
+msgstr "--disable-shm ожидает логический аргумент"
+
+#: ../src/daemon/dumpmodules.c:59
+#, c-format
+msgid "Name: %s\n"
+msgstr "Имя: %s\n"
+
+#: ../src/daemon/dumpmodules.c:62
+#, c-format
+msgid "No module information available\n"
+msgstr "Нет информации о модулях\n"
+
+#: ../src/daemon/dumpmodules.c:65
+#, c-format
+msgid "Version: %s\n"
+msgstr "Версия: %s\n"
+
+#: ../src/daemon/dumpmodules.c:67
+#, c-format
+msgid "Description: %s\n"
+msgstr "Описание: %s\n"
+
+#: ../src/daemon/dumpmodules.c:69
+#, c-format
+msgid "Author: %s\n"
+msgstr "Автор: %s\n"
+
+#: ../src/daemon/dumpmodules.c:71
+#, c-format
+msgid "Usage: %s\n"
+msgstr "Использование: %s\n"
+
+#: ../src/daemon/dumpmodules.c:72
+#, c-format
+msgid "Load Once: %s\n"
+msgstr "Загружен раз: %s\n"
+
+#: ../src/daemon/dumpmodules.c:74
+#, c-format
+msgid "DEPRECATION WARNING: %s\n"
+msgstr "DEPRECATION WARNING: %s\n"
+
+#: ../src/daemon/dumpmodules.c:78
+#, c-format
+msgid "Path: %s\n"
+msgstr "Путь: %s\n"
+
+#: ../src/daemon/daemon-conf.c:275
+#, c-format
+msgid "[%s:%u] Invalid log target '%s'."
+msgstr "[%s:%u] Недопустимый журнал '%s'."
+
+#: ../src/daemon/daemon-conf.c:291
+#, c-format
+msgid "[%s:%u] Invalid log level '%s'."
+msgstr "[%s:%u] Недопустимый аргумент протоколирования '%s'."
+
+#: ../src/daemon/daemon-conf.c:307
+#, c-format
+msgid "[%s:%u] Invalid resample method '%s'."
+msgstr "[%s:%u] Недопустимый метод ресэмплирования '%s'."
+
+#: ../src/daemon/daemon-conf.c:330
+#, c-format
+msgid "[%s:%u] Invalid rlimit '%s'."
+msgstr "[%s:%u] Недопустимый rlimit '%s'."
+
+#: ../src/daemon/daemon-conf.c:351
+#, c-format
+msgid "[%s:%u] Invalid sample format '%s'."
+msgstr "[%s:%u] Недопустимый формат сэмпла '%s'."
+
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
+#, c-format
+msgid "[%s:%u] Invalid sample rate '%s'."
+msgstr "[%s:%u] Неверная частота дискретизации '%s'."
+
+#: ../src/daemon/daemon-conf.c:413
+#, c-format
+msgid "[%s:%u] Invalid sample channels '%s'."
+msgstr "[%s:%u] Неверные сэмпл-каналы '%s'."
+
+#: ../src/daemon/daemon-conf.c:431
+#, c-format
+msgid "[%s:%u] Invalid channel map '%s'."
+msgstr "[%s:%u] Неверная схема каналов '%s'."
+
+#: ../src/daemon/daemon-conf.c:449
+#, c-format
+msgid "[%s:%u] Invalid number of fragments '%s'."
+msgstr "[%s:%u] Неверное число фрагментов '%s'."
+
+#: ../src/daemon/daemon-conf.c:467
+#, c-format
+msgid "[%s:%u] Invalid fragment size '%s'."
+msgstr "[%s:%u] Недопустимый размер фрагмента '%s'."
+
+#: ../src/daemon/daemon-conf.c:485
+#, c-format
+msgid "[%s:%u] Invalid nice level '%s'."
+msgstr "[%s:%u] Недопустимый точный уровень '%s'."
+
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Неверная частота дискретизации '%s'."
+
+#: ../src/daemon/daemon-conf.c:641
+#, c-format
+msgid "Failed to open configuration file: %s"
+msgstr "Не удалось открыть файл конфигурации: %s"
+
+#: ../src/daemon/daemon-conf.c:657
+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:743
+#, c-format
+msgid "### Read from configuration file: %s ###\n"
+msgstr "### Прочитать из файла конфигурации: %s ###\n"
+
+#: ../src/daemon/caps.c:58
+msgid "Cleaning up privileges."
+msgstr "Очистка привилегий."
+
+#: ../src/daemon/pulseaudio.desktop.in.h:1
+msgid "PulseAudio Sound System"
+msgstr "Звуковая система PulseAudio"
+
+#: ../src/daemon/pulseaudio.desktop.in.h:2
+msgid "Start the PulseAudio Sound System"
+msgstr "Запуск звуковой системы PulseAudio"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "Звуковая система PulseAudio"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "Запуск звуковой системы PulseAudio"
+
+#: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
+msgid "Mono"
+msgstr "Моно"
+
+#: ../src/pulse/channelmap.c:107
+msgid "Front Center"
+msgstr "Фронт центр"
+
+#: ../src/pulse/channelmap.c:108
+msgid "Front Left"
+msgstr "Фронт лево"
+
+#: ../src/pulse/channelmap.c:109
+msgid "Front Right"
+msgstr "Фронт право"
+
+#: ../src/pulse/channelmap.c:111
+msgid "Rear Center"
+msgstr "Сзади центр"
+
+#: ../src/pulse/channelmap.c:112
+msgid "Rear Left"
+msgstr "Сзади лево"
+
+#: ../src/pulse/channelmap.c:113
+msgid "Rear Right"
+msgstr "Сзади право"
+
+#: ../src/pulse/channelmap.c:115
+msgid "Subwoofer"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:117
+msgid "Front Left-of-center"
+msgstr "Фронт левее центра"
+
+#: ../src/pulse/channelmap.c:118
+msgid "Front Right-of-center"
+msgstr "Фронт правее центра"
+
+#: ../src/pulse/channelmap.c:120
+msgid "Side Left"
+msgstr "Левая сторона"
+
+#: ../src/pulse/channelmap.c:121
+msgid "Side Right"
+msgstr "Правая сторона"
+
+#: ../src/pulse/channelmap.c:123
+msgid "Auxiliary 0"
+msgstr "Дополнительный 0"
+
+#: ../src/pulse/channelmap.c:124
+msgid "Auxiliary 1"
+msgstr "Дополнительный 1"
+
+#: ../src/pulse/channelmap.c:125
+msgid "Auxiliary 2"
+msgstr "Дополнительный 2"
+
+#: ../src/pulse/channelmap.c:126
+msgid "Auxiliary 3"
+msgstr "Дополнительный 3"
+
+#: ../src/pulse/channelmap.c:127
+msgid "Auxiliary 4"
+msgstr "Дополнительный 4"
+
+#: ../src/pulse/channelmap.c:128
+msgid "Auxiliary 5"
+msgstr "Дополнительный 5"
+
+#: ../src/pulse/channelmap.c:129
+msgid "Auxiliary 6"
+msgstr "Дополнительный 6"
+
+#: ../src/pulse/channelmap.c:130
+msgid "Auxiliary 7"
+msgstr "Дополнительный 7"
+
+#: ../src/pulse/channelmap.c:131
+msgid "Auxiliary 8"
+msgstr "Дополнительный 8"
+
+#: ../src/pulse/channelmap.c:132
+msgid "Auxiliary 9"
+msgstr "Дополнительный 9"
+
+#: ../src/pulse/channelmap.c:133
+msgid "Auxiliary 10"
+msgstr "Дополнительный 10"
+
+#: ../src/pulse/channelmap.c:134
+msgid "Auxiliary 11"
+msgstr "Дополнительный 11"
+
+#: ../src/pulse/channelmap.c:135
+msgid "Auxiliary 12"
+msgstr "Дополнительный 12"
+
+#: ../src/pulse/channelmap.c:136
+msgid "Auxiliary 13"
+msgstr "Дополнительный 13"
+
+#: ../src/pulse/channelmap.c:137
+msgid "Auxiliary 14"
+msgstr "Дополнительный 14"
+
+#: ../src/pulse/channelmap.c:138
+msgid "Auxiliary 15"
+msgstr "Дополнительный 15"
+
+#: ../src/pulse/channelmap.c:139
+msgid "Auxiliary 16"
+msgstr "Дополнительный 16"
+
+#: ../src/pulse/channelmap.c:140
+msgid "Auxiliary 17"
+msgstr "Дополнительный 17"
+
+#: ../src/pulse/channelmap.c:141
+msgid "Auxiliary 18"
+msgstr "Дополнительный 18"
+
+#: ../src/pulse/channelmap.c:142
+msgid "Auxiliary 19"
+msgstr "Дополнительный 19"
+
+#: ../src/pulse/channelmap.c:143
+msgid "Auxiliary 20"
+msgstr "Дополнительный 20"
+
+#: ../src/pulse/channelmap.c:144
+msgid "Auxiliary 21"
+msgstr "Дополнительный 21"
+
+#: ../src/pulse/channelmap.c:145
+msgid "Auxiliary 22"
+msgstr "Дополнительный 22"
+
+#: ../src/pulse/channelmap.c:146
+msgid "Auxiliary 23"
+msgstr "Дополнительный 23"
+
+#: ../src/pulse/channelmap.c:147
+msgid "Auxiliary 24"
+msgstr "Дополнительный 24"
+
+#: ../src/pulse/channelmap.c:148
+msgid "Auxiliary 25"
+msgstr "Дополнительный 25"
+
+#: ../src/pulse/channelmap.c:149
+msgid "Auxiliary 26"
+msgstr "Дополнительный 26"
+
+#: ../src/pulse/channelmap.c:150
+msgid "Auxiliary 27"
+msgstr "Дополнительный 27"
+
+#: ../src/pulse/channelmap.c:151
+msgid "Auxiliary 28"
+msgstr "Дополнительный 28"
+
+#: ../src/pulse/channelmap.c:152
+msgid "Auxiliary 29"
+msgstr "Дополнительный 29"
+
+#: ../src/pulse/channelmap.c:153
+msgid "Auxiliary 30"
+msgstr "Дополнительный 30"
+
+#: ../src/pulse/channelmap.c:154
+msgid "Auxiliary 31"
+msgstr "Дополнительный 31"
+
+#: ../src/pulse/channelmap.c:156
+msgid "Top Center"
+msgstr "Верх центр"
+
+#: ../src/pulse/channelmap.c:158
+msgid "Top Front Center"
+msgstr "Верх фронт центр"
+
+#: ../src/pulse/channelmap.c:159
+msgid "Top Front Left"
+msgstr "Верх фронт лево"
+
+#: ../src/pulse/channelmap.c:160
+msgid "Top Front Right"
+msgstr "Верх фронт право"
+
+#: ../src/pulse/channelmap.c:162
+msgid "Top Rear Center"
+msgstr "Верх сзади центр"
+
+#: ../src/pulse/channelmap.c:163
+msgid "Top Rear Left"
+msgstr "Верх сзади лево"
+
+#: ../src/pulse/channelmap.c:164
+msgid "Top Rear Right"
+msgstr "Верх сзади право"
+
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
+msgid "(invalid)"
+msgstr "(недействительно)"
+
+#: ../src/pulse/channelmap.c:761
+msgid "Stereo"
+msgstr "Стерео"
+
+#: ../src/pulse/channelmap.c:766
+msgid "Surround 4.0"
+msgstr "Объёмный 4.0"
+
+#: ../src/pulse/channelmap.c:772
+msgid "Surround 4.1"
+msgstr "Объёмный 4.1"
+
+#: ../src/pulse/channelmap.c:778
+msgid "Surround 5.0"
+msgstr "Объёмный 5.0"
+
+#: ../src/pulse/channelmap.c:784
+msgid "Surround 5.1"
+msgstr "Объёмный 5.1"
+
+#: ../src/pulse/channelmap.c:791
+msgid "Surround 7.1"
+msgstr "Объёмный 7.1"
+
+#: ../src/pulse/error.c:40
+msgid "OK"
+msgstr "OK"
+
+#: ../src/pulse/error.c:41
+msgid "Access denied"
+msgstr "Нет доступа"
+
+#: ../src/pulse/error.c:42
+msgid "Unknown command"
+msgstr "Неизвестная команда"
+
+#: ../src/pulse/error.c:43
+msgid "Invalid argument"
+msgstr "Недействительный аргумент"
+
+#: ../src/pulse/error.c:44
+msgid "Entity exists"
+msgstr "Объект существует"
+
+#: ../src/pulse/error.c:45
+msgid "No such entity"
+msgstr "Нет такого объекта"
+
+#: ../src/pulse/error.c:46
+msgid "Connection refused"
+msgstr "Отказ в подключении"
+
+#: ../src/pulse/error.c:47
+msgid "Protocol error"
+msgstr "Ошибка протокола"
+
+#: ../src/pulse/error.c:48
+msgid "Timeout"
+msgstr "Тайм-аут"
+
+#: ../src/pulse/error.c:49
+msgid "No authorization key"
+msgstr "Нет ключа авторизации"
+
+#: ../src/pulse/error.c:50
+msgid "Internal error"
+msgstr "Внутренняя ошибка"
+
+#: ../src/pulse/error.c:51
+msgid "Connection terminated"
+msgstr "Соединение завершено"
+
+#: ../src/pulse/error.c:52
+msgid "Entity killed"
+msgstr "Объект уничтожен"
+
+#: ../src/pulse/error.c:53
+msgid "Invalid server"
+msgstr "Неверный сервер"
+
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
+msgstr "Инициализация модуля не удалась"
+
+#: ../src/pulse/error.c:55
+msgid "Bad state"
+msgstr "Неисправное состояние"
+
+#: ../src/pulse/error.c:56
+msgid "No data"
+msgstr "Нет данных"
+
+#: ../src/pulse/error.c:57
+msgid "Incompatible protocol version"
+msgstr "Несовместимая версия протокола"
+
+#: ../src/pulse/error.c:58
+msgid "Too large"
+msgstr "Слишком большой"
+
+#: ../src/pulse/error.c:59
+msgid "Not supported"
+msgstr "Не поддерживается"
+
+#: ../src/pulse/error.c:60
+msgid "Unknown error code"
+msgstr "Неизвестный код ошибки"
+
+#: ../src/pulse/error.c:61
+msgid "No such extension"
+msgstr "Нет такого расширения"
+
+#: ../src/pulse/error.c:62
+msgid "Obsolete functionality"
+msgstr "Устаревшая функциональность"
+
+#: ../src/pulse/error.c:63
+msgid "Missing implementation"
+msgstr "Отсутствующая реализация"
+
+#: ../src/pulse/error.c:64
+msgid "Client forked"
+msgstr "Клиент разветвлён"
+
+#: ../src/pulse/error.c:65
+msgid "Input/Output error"
+msgstr "Ошибка ввода/вывода"
+
+#: ../src/pulse/error.c:66
+msgid "Device or resource busy"
+msgstr "Устройство или ресурс занято"
+
+#: ../src/pulse/sample.c:171
+#, c-format
+msgid "%s %uch %uHz"
+msgstr "%s %uch %uГц"
+
+#: ../src/pulse/sample.c:183
+#, c-format
+msgid "%0.1f GiB"
+msgstr "%0.1f Гб"
+
+#: ../src/pulse/sample.c:185
+#, c-format
+msgid "%0.1f MiB"
+msgstr "%0.1f Мб"
+
+#: ../src/pulse/sample.c:187
+#, c-format
+msgid "%0.1f KiB"
+msgstr "%0.1f Кб"
+
+#: ../src/pulse/sample.c:189
+#, c-format
+msgid "%u B"
+msgstr "%u Б"
+
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() не удалось: %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:97
+msgid "Failed to parse cookie data"
+msgstr "Не удалось разобрать данные cookie"
+
+#: ../src/pulse/client-conf.c:117
+#, c-format
+msgid "Failed to open configuration file '%s': %s"
+msgstr "Не удалось открыть файл конфигурации '%s': %s"
+
+#: ../src/pulse/context.c:528
+msgid "No cookie loaded. Attempting to connect without."
+msgstr "Cookie не загружены. Попытка подключения без них."
+
+#: ../src/pulse/context.c:675
+#, c-format
+msgid "fork(): %s"
+msgstr "fork(): %s"
+
+#: ../src/pulse/context.c:730
+#, c-format
+msgid "waitpid(): %s"
+msgstr "waitpid(): %s"
+
+#: ../src/pulse/context.c:1431
+#, c-format
+msgid "Received message for unknown extension '%s'"
+msgstr "Получено сообщение для неизвестного расширения '%s'"
+
+#: ../src/utils/pacat.c:112
+#, c-format
+msgid "Failed to drain stream: %s"
+msgstr "Не удалось создать туннель для потока: %s"
+
+#: ../src/utils/pacat.c:117
+msgid "Playback stream drained."
+msgstr "Поток воспроизведения туннелирован."
+
+#: ../src/utils/pacat.c:128
+msgid "Draining connection to server."
+msgstr "Туннелирование соединения с сервером."
+
+#: ../src/utils/pacat.c:141
+#, c-format
+msgid "pa_stream_drain(): %s"
+msgstr "pa_stream_drain(): %s"
+
+#: ../src/utils/pacat.c:164
+#, c-format
+msgid "pa_stream_write() failed: %s"
+msgstr "pa_stream_write() не удалось: %s"
+
+#: ../src/utils/pacat.c:205
+#, c-format
+msgid "pa_stream_begin_write() failed: %s"
+msgstr "pa_stream_begin_write() не удалось: %s"
+
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
+#, c-format
+msgid "pa_stream_peek() failed: %s"
+msgstr "pa_stream_peek() не удалось: %s"
+
+#: ../src/utils/pacat.c:325
+msgid "Stream successfully created."
+msgstr "Поток успешно создан."
+
+#: ../src/utils/pacat.c:328
+#, c-format
+msgid "pa_stream_get_buffer_attr() failed: %s"
+msgstr "pa_stream_get_buffer_attr() не удалось: %s"
+
+#: ../src/utils/pacat.c:332
+#, 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:335
+#, c-format
+msgid "Buffer metrics: maxlength=%u, fragsize=%u"
+msgstr "Показатели буфера: maxlength=%u, fragsize=%u"
+
+#: ../src/utils/pacat.c:339
+#, c-format
+msgid "Using sample spec '%s', channel map '%s'."
+msgstr "Использование семплов '%s', схемы каналов '%s'."
+
+#: ../src/utils/pacat.c:343
+#, c-format
+msgid "Connected to device %s (%u, %ssuspended)."
+msgstr "Соединён с устройством %s (%u, %sожидание)."
+
+#: ../src/utils/pacat.c:353
+#, c-format
+msgid "Stream error: %s"
+msgstr "Ошибка потока: %s"
+
+#: ../src/utils/pacat.c:363
+#, c-format
+msgid "Stream device suspended.%s"
+msgstr "Поток приостановлен.%s"
+
+#: ../src/utils/pacat.c:365
+#, c-format
+msgid "Stream device resumed.%s"
+msgstr "Поток возобновлён.%s"
+
+#: ../src/utils/pacat.c:373
+#, c-format
+msgid "Stream underrun.%s"
+msgstr "Поток недогружен.%s"
+
+#: ../src/utils/pacat.c:380
+#, c-format
+msgid "Stream overrun.%s"
+msgstr "Поток переполнен.%s"
+
+#: ../src/utils/pacat.c:387
+#, c-format
+msgid "Stream started.%s"
+msgstr "Поток запущен.%s"
+
+#: ../src/utils/pacat.c:394
+#, c-format
+msgid "Stream moved to device %s (%u, %ssuspended).%s"
+msgstr "Поток перемещён на устройство %s (%u, %sожидание).%s"
+
+#: ../src/utils/pacat.c:394
+msgid "not "
+msgstr "not "
+
+#: ../src/utils/pacat.c:401
+#, c-format
+msgid "Stream buffer attributes changed.%s"
+msgstr "Атрибуты буфера потока изменены.%s"
+
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
+#, c-format
+msgid "Connection established.%s"
+msgstr "Соединение установлено.%s"
+
+#: ../src/utils/pacat.c:454
+#, c-format
+msgid "pa_stream_new() failed: %s"
+msgstr "pa_stream_new() не удалось: %s"
+
+#: ../src/utils/pacat.c:492
+#, c-format
+msgid "pa_stream_connect_playback() failed: %s"
+msgstr "pa_stream_connect_playback() не удалось: %s"
+
+#: ../src/utils/pacat.c:498
+#, c-format
+msgid "pa_stream_connect_record() failed: %s"
+msgstr "pa_stream_connect_record() не удалось: %s"
+
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
+#, c-format
+msgid "Connection failure: %s"
+msgstr "Ошибка подключения: %s"
+
+#: ../src/utils/pacat.c:545
+msgid "Got EOF."
+msgstr "Достигнут конец файла."
+
+#: ../src/utils/pacat.c:582
+#, c-format
+msgid "write() failed: %s"
+msgstr "write() не удалось: %s"
+
+#: ../src/utils/pacat.c:603
+msgid "Got signal, exiting."
+msgstr "Сигнал получен, выход."
+
+#: ../src/utils/pacat.c:617
+#, c-format
+msgid "Failed to get latency: %s"
+msgstr "Не удалось получить задержку: %s"
+
+#: ../src/utils/pacat.c:622
+#, c-format
+msgid "Time: %0.3f sec; Latency: %0.0f usec."
+msgstr "Время: %0.3f с; задержка: %0.0f мкс."
+
+#: ../src/utils/pacat.c:643
+#, c-format
+msgid "pa_stream_update_timing_info() failed: %s"
+msgstr "pa_stream_update_timing_info() не удалось: %s"
+
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"\n"
+"  -r, --record                          Create a connection for recording\n"
+"  -p, --playback                        Create a connection for playback\n"
+"\n"
+"  -v, --verbose                         Enable verbose operations\n"
+"\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -d, --device=DEVICE                   The name of the sink/source to "
+"connect to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
+"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to "
+"44100)\n"
+"      --format=SAMPLEFORMAT             The sample type, one of s16le, "
+"s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be, "
+"s24le, s24be,\n"
+"                                        s24-32le, s24-32be (defaults to "
+"s16ne)\n"
+"      --channels=CHANNELS               The number of channels, 1 for mono, "
+"2 for stereo\n"
+"                                        (defaults to 2)\n"
+"      --channel-map=CHANNELMAP          Channel map to use instead of the "
+"default\n"
+"      --fix-format                      Take the sample format from the sink "
+"the stream is\n"
+"                                        being connected to.\n"
+"      --fix-rate                        Take the sampling rate from the sink "
+"the stream is\n"
+"                                        being connected to.\n"
+"      --fix-channels                    Take the number of channels and the "
+"channel map\n"
+"                                        from the sink the stream is being "
+"connected to.\n"
+"      --no-remix                        Don't upmix or downmix channels.\n"
+"      --no-remap                        Map channels by index instead of "
+"name.\n"
+"      --latency=BYTES                   Request the specified latency in "
+"bytes.\n"
+"      --process-time=BYTES              Request the specified process time "
+"per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
+"      --property=PROPERTY=VALUE         Set the specified property to the "
+"specified value.\n"
+"      --raw                             Record/play raw PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
+"      --list-file-formats               List available file formats.\n"
+msgstr ""
+"%s [options]\n"
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"\n"
+"  -r, --record                          Create a connection for recording\n"
+"  -p, --playback                        Create a connection for playback\n"
+"\n"
+"  -v, --verbose                         Enable verbose operations\n"
+"\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -d, --device=DEVICE                   The name of the sink/source to "
+"connect to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
+"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to "
+"44100)\n"
+"      --format=SAMPLEFORMAT             The sample type, one of s16le, "
+"s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be, "
+"s24le, s24be,\n"
+"                                        s24-32le, s24-32be (defaults to "
+"s16ne)\n"
+"      --channels=CHANNELS               The number of channels, 1 for mono, "
+"2 for stereo\n"
+"                                        (defaults to 2)\n"
+"      --channel-map=CHANNELMAP          Channel map to use instead of the "
+"default\n"
+"      --fix-format                      Take the sample format from the sink "
+"the stream is\n"
+"                                        being connected to.\n"
+"      --fix-rate                        Take the sampling rate from the sink "
+"the stream is\n"
+"                                        being connected to.\n"
+"      --fix-channels                    Take the number of channels and the "
+"channel map\n"
+"                                        from the sink the stream is being "
+"connected to.\n"
+"      --no-remix                        Don't upmix or downmix channels.\n"
+"      --no-remap                        Map channels by index instead of "
+"name.\n"
+"      --latency=BYTES                   Request the specified latency in "
+"bytes.\n"
+"      --process-time=BYTES              Request the specified process time "
+"per request in bytes.\n"
+"      --property=PROPERTY=VALUE         Set the specified property to the "
+"specified value.\n"
+"      --raw                             Record/play raw PCM data.\n"
+"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --list-file-formats               List available file formats.\n"
+
+#: ../src/utils/pacat.c:786
+#, c-format
+msgid ""
+"pacat %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"pacat %s\n"
+"Скомпилировано с libpulse %s\n"
+"Связано с libpulse %s\n"
+
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
+#, c-format
+msgid "Invalid client name '%s'"
+msgstr "Неверное имя клиента '%s'"
+
+#: ../src/utils/pacat.c:834
+#, c-format
+msgid "Invalid stream name '%s'"
+msgstr "Неверное имя потока '%s'"
+
+#: ../src/utils/pacat.c:871
+#, c-format
+msgid "Invalid channel map '%s'"
+msgstr "Неверная схема каналов '%s'"
+
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
+#, c-format
+msgid "Invalid latency specification '%s'"
+msgstr "Неверное значение задержки '%s'"
+
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
+#, c-format
+msgid "Invalid process time specification '%s'"
+msgstr "Неверная спецификация времени процесса '%s'"
+
+#: ../src/utils/pacat.c:933
+#, c-format
+msgid "Invalid property '%s'"
+msgstr "Неверное свойство '%s'"
+
+#: ../src/utils/pacat.c:952
+#, c-format
+msgid "Unknown file format %s."
+msgstr "Неизвестный формат файла %s."
+
+#: ../src/utils/pacat.c:971
+msgid "Invalid sample specification"
+msgstr "Неверная спецификация сэмпла"
+
+#: ../src/utils/pacat.c:981
+#, c-format
+msgid "open(): %s"
+msgstr "open(): %s"
+
+#: ../src/utils/pacat.c:986
+#, c-format
+msgid "dup2(): %s"
+msgstr "dup2(): %s"
+
+#: ../src/utils/pacat.c:993
+msgid "Too many arguments."
+msgstr "Слишком много аргументов."
+
+#: ../src/utils/pacat.c:1004
+msgid "Failed to generate sample specification for file."
+msgstr "Ошибка создания спецификации сэмпла для файла."
+
+#: ../src/utils/pacat.c:1030
+msgid "Failed to open audio file."
+msgstr "Не удалось открыть аудио файл."
+
+#: ../src/utils/pacat.c:1036
+msgid ""
+"Warning: specified sample specification will be overwritten with "
+"specification from file."
+msgstr ""
+"Предупреждение: заданная спецификация сэмпла будет перезаписана "
+"спецификацией из файла."
+
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
+msgid "Failed to determine sample specification from file."
+msgstr "Не удалось определить спецификацию сэмпла из файла."
+
+#: ../src/utils/pacat.c:1048
+msgid "Warning: Failed to determine channel map from file."
+msgstr "Предупреждение: не удалось определить схему каналов из файла."
+
+#: ../src/utils/pacat.c:1059
+msgid "Channel map doesn't match sample specification"
+msgstr "Схема каналов не соответствует спецификации сэмпла"
+
+#: ../src/utils/pacat.c:1070
+msgid "Warning: failed to write channel map to file."
+msgstr "Предупреждение: не удалось записать схему каналов в файл."
+
+#: ../src/utils/pacat.c:1085
+#, c-format
+msgid ""
+"Opening a %s stream with sample specification '%s' and channel map '%s'."
+msgstr ""
+"Открытие потока %s со спецификацией сэмплов '%s' и схемой каналов '%s'."
+
+#: ../src/utils/pacat.c:1086
+msgid "recording"
+msgstr "запись"
+
+#: ../src/utils/pacat.c:1086
+msgid "playback"
+msgstr "воспроизведение"
+
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "Ошибка разбора командной строки."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
+msgid "pa_mainloop_new() failed."
+msgstr "pa_mainloop_new() не удалось."
+
+#: ../src/utils/pacat.c:1136
+msgid "io_new() failed."
+msgstr "io_new() не удалось."
+
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
+msgid "pa_context_new() failed."
+msgstr "pa_context_new() не удалось."
+
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
+#, c-format
+msgid "pa_context_connect() failed: %s"
+msgstr "pa_context_connect() не удалось: %s"
+
+#: ../src/utils/pacat.c:1157
+msgid "pa_context_rttime_new() failed."
+msgstr "pa_context_rttime_new() не удалось."
+
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
+msgid "pa_mainloop_run() failed."
+msgstr "pa_mainloop_run() не удалось."
+
+#: ../src/utils/pasuspender.c:79
+#, c-format
+msgid "fork(): %s\n"
+msgstr "fork(): %s\n"
+
+#: ../src/utils/pasuspender.c:90
+#, c-format
+msgid "execvp(): %s\n"
+msgstr "execvp(): %s\n"
+
+#: ../src/utils/pasuspender.c:107
+#, c-format
+msgid "Failure to suspend: %s\n"
+msgstr "Не удаётся приостановить: %s\n"
+
+#: ../src/utils/pasuspender.c:122
+#, c-format
+msgid "Failure to resume: %s\n"
+msgstr "Не удаётся возобновить: %s\n"
+
+#: ../src/utils/pasuspender.c:145
+#, c-format
+msgid "WARNING: Sound server is not local, not suspending.\n"
+msgstr ""
+"ПРЕДУПРЕЖДЕНИЕ: Аудио сервер не является локальным, не приостанавливается.\n"
+
+#: ../src/utils/pasuspender.c:157
+#, c-format
+msgid "Connection failure: %s\n"
+msgstr "Ошибка соединения: %s\n"
+
+#: ../src/utils/pasuspender.c:174
+#, c-format
+msgid "Got SIGINT, exiting.\n"
+msgstr "Получен сигнал для остановки, выход.\n"
+
+#: ../src/utils/pasuspender.c:192
+#, c-format
+msgid "WARNING: Child process terminated by signal %u\n"
+msgstr "ПРЕДУПРЕЖДЕНИЕ: Дочерний процесс отменён по сигналу %u\n"
+
+#: ../src/utils/pasuspender.c:210
+#, c-format
+msgid ""
+"%s [options] ... \n"
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"\n"
+msgstr ""
+"%s [options] ... \n"
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"\n"
+
+#: ../src/utils/pasuspender.c:248
+#, c-format
+msgid ""
+"pasuspender %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"pasuspender %s\n"
+"Скомпилировано с libpulse %s\n"
+"Связано с libpulse %s\n"
+
+#: ../src/utils/pasuspender.c:277
+#, c-format
+msgid "pa_mainloop_new() failed.\n"
+msgstr "pa_mainloop_new() не удалось.\n"
+
+#: ../src/utils/pasuspender.c:290
+#, c-format
+msgid "pa_context_new() failed.\n"
+msgstr "pa_context_new() не удалось.\n"
+
+#: ../src/utils/pasuspender.c:298
+#, c-format
+msgid "pa_mainloop_run() failed.\n"
+msgstr "pa_mainloop_run() не удалось.\n"
+
+#: ../src/utils/pactl.c:150
+#, c-format
+msgid "Failed to get statistics: %s"
+msgstr "Не удалось получить статистику: %s"
+
+#: ../src/utils/pactl.c:156
+#, c-format
+msgid "Currently in use: %u blocks containing %s bytes total.\n"
+msgstr "Сейчас используется: %u блоков содержащих всего %s байт.\n"
+
+#: ../src/utils/pactl.c:159
+#, c-format
+msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
+msgstr "Выделено за всё время: %u блоков содержащих всего %s байт.\n"
+
+#: ../src/utils/pactl.c:162
+#, c-format
+msgid "Sample cache size: %s\n"
+msgstr "Размер кэша сэмплов: %s\n"
+
+#: ../src/utils/pactl.c:171
+#, c-format
+msgid "Failed to get server information: %s"
+msgstr "Не удалось получить информацию о сервере: %s"
+
+#: ../src/utils/pactl.c:176
+#, c-format
+msgid ""
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
+"Host Name: %s\n"
+"Server Name: %s\n"
+"Server Version: %s\n"
+"Default Sample Specification: %s\n"
+"Default Channel Map: %s\n"
+"Default Sink: %s\n"
+"Default Source: %s\n"
+"Cookie: %04x:%04x\n"
+msgstr ""
+"Имя пользователя: %s\n"
+"Имя хоста: %s\n"
+"Имя сервера: %s\n"
+"Версия сервера: %s\n"
+"Спецификация сэмплов по умолчанию: %s\n"
+"Схема каналов по умолчанию: %s\n"
+"Аудиоприёмник по умолчанию: %s\n"
+"Источник по умолчанию: %s\n"
+"Cookie: %08x\n"
+
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
+#, c-format
+msgid "Failed to get sink information: %s"
+msgstr "Не удалось получить информацию об аудиоприёмнике: %s"
+
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
+msgid ""
+"Sink #%u\n"
+"\tState: %s\n"
+"\tName: %s\n"
+"\tDescription: %s\n"
+"\tDriver: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tOwner Module: %u\n"
+"\tMute: %s\n"
+"\tVolume: %s%s%s\n"
+"\t        balance %0.2f\n"
+"\tBase Volume: %s%s%s\n"
+"\tMonitor Source: %s\n"
+"\tLatency: %0.0f usec, configured %0.0f usec\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+"Аудиоприёмник #%u\n"
+"\tСостояние: %s\n"
+"\tИмя: %s\n"
+"\tОписание: %s\n"
+"\tДрайвер: %s\n"
+"\tСпецификация сэмплов: %s\n"
+"\tСхема каналов: %s\n"
+"\tРодительский модуль: %u\n"
+"\tВыключить: %s\n"
+"\tГромкость: %s%s%s\n"
+"\t        баланс %0.2f\n"
+"\tБазовая громкость: %s%s%s\n"
+"\tМонитор источника: %s\n"
+"\tЗадержка: %0.0f мкс, настроить %0.0f мкс\n"
+"\tФлаги: %s%s%s%s%s%s\n"
+"\tСвойства:\n"
+"\t\t%s\n"
+
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
+#, c-format
+msgid "\tPorts:\n"
+msgstr "\tПорты:\n"
+
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
+#, c-format
+msgid "\tActive Port: %s\n"
+msgstr "\tАктивный порт: %s\n"
+
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tПорты:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
+#, c-format
+msgid "Failed to get source information: %s"
+msgstr "Не удалось получить информацию об источнике: %s"
+
+#: ../src/utils/pactl.c:383
+#, c-format
+msgid ""
+"Source #%u\n"
+"\tState: %s\n"
+"\tName: %s\n"
+"\tDescription: %s\n"
+"\tDriver: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tOwner Module: %u\n"
+"\tMute: %s\n"
+"\tVolume: %s%s%s\n"
+"\t        balance %0.2f\n"
+"\tBase Volume: %s%s%s\n"
+"\tMonitor of Sink: %s\n"
+"\tLatency: %0.0f usec, configured %0.0f usec\n"
+"\tFlags: %s%s%s%s%s%s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+"Источник #%u\n"
+"\tСостояние: %s\n"
+"\tИмя: %s\n"
+"\tОписание: %s\n"
+"\tДрайвер: %s\n"
+"\tСпецификация сэмплов: %s\n"
+"\tСхема каналов: %s\n"
+"\tРодительский модуль: %u\n"
+"\tВыключить: %s\n"
+"\tГромкость: %s%s%s\n"
+"\t        баланс %0.2f\n"
+"\tБазовая громкость: %s%s%s\n"
+"\tМонитор аудиоприёмника: %s\n"
+"\tЗадержка: %0.0f мкс, настроить %0.0f мкс\n"
+"\tФлаги: %s%s%s%s%s%s\n"
+"\tСвойства:\n"
+"\t\t%s\n"
+
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
+msgid "n/a"
+msgstr "н/д"
+
+#: ../src/utils/pactl.c:454
+#, c-format
+msgid "Failed to get module information: %s"
+msgstr "Не удалось получить информацию о модуле: %s"
+
+#: ../src/utils/pactl.c:477
+#, c-format
+msgid ""
+"Module #%u\n"
+"\tName: %s\n"
+"\tArgument: %s\n"
+"\tUsage counter: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+"Модуль #%u\n"
+"\tИмя: %s\n"
+"\tАргумент: %s\n"
+"\tСчётчик использования: %s\n"
+"\tСвойства:\n"
+"\t\t%s\n"
+
+#: ../src/utils/pactl.c:496
+#, c-format
+msgid "Failed to get client information: %s"
+msgstr "Не удалось получить информацию о клиенте: %s"
+
+#: ../src/utils/pactl.c:522
+#, c-format
+msgid ""
+"Client #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+"Клиент #%u\n"
+"\tДрайвер: %s\n"
+"\tРодительский модуль: %s\n"
+"\tСвойства:\n"
+"\t\t%s\n"
+
+#: ../src/utils/pactl.c:539
+#, c-format
+msgid "Failed to get card information: %s"
+msgstr "Не удалось получить информацию о карте: %s"
+
+#: ../src/utils/pactl.c:562
+#, c-format
+msgid ""
+"Card #%u\n"
+"\tName: %s\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+"Карта #%u\n"
+"\tИмя: %s\n"
+"\tДрайвер: %s\n"
+"\tРодительский модуль: %s\n"
+"\tСвойства:\n"
+"\t\t%s\n"
+
+#: ../src/utils/pactl.c:576
+#, c-format
+msgid "\tProfiles:\n"
+msgstr "\tПрофили:\n"
+
+#: ../src/utils/pactl.c:582
+#, c-format
+msgid "\tActive Profile: %s\n"
+msgstr "\tАктивный профиль: %s\n"
+
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
+#, c-format
+msgid "Failed to get sink input information: %s"
+msgstr "Не удалось получить информацию о вводе аудиоприёмника: %s"
+
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
+msgid ""
+"Sink Input #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tClient: %s\n"
+"\tSink: %u\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
+"\tBuffer Latency: %0.0f usec\n"
+"\tSink Latency: %0.0f usec\n"
+"\tResample method: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+"Ввод аудиоприёмника #%u\n"
+"\tДрайвер: %s\n"
+"\tРодительский модуль: %s\n"
+"\tКлиент: %s\n"
+"\tАудиоприёмник: %u\n"
+"\tСпецификация сэмплов: %s\n"
+"\tСхема каналов: %s\n"
+"\tВыключить: %s\n"
+"\tГромкость: %s\n"
+"\t        %s\n"
+"\t        баланс %0.2f\n"
+"\tЗадержка буфера: %0.0f мкс\n"
+"\tЗадержка аудиоприёмника: %0.0f usec\n"
+"\tМетод ресэмплирования: %s\n"
+"\tСвойства:\n"
+"\t\t%s\n"
+
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
+#, c-format
+msgid "Failed to get source output information: %s"
+msgstr "Не удалось получить информацию о выходе источника: %s"
+
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
+msgid ""
+"Source Output #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tClient: %s\n"
+"\tSource: %u\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
+"\tBuffer Latency: %0.0f usec\n"
+"\tSource Latency: %0.0f usec\n"
+"\tResample method: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+"Ввод аудиоприёмника #%u\n"
+"\tДрайвер: %s\n"
+"\tРодительский модуль: %s\n"
+"\tКлиент: %s\n"
+"\tАудиоприёмник: %u\n"
+"\tСпецификация сэмплов: %s\n"
+"\tСхема каналов: %s\n"
+"\tВыключить: %s\n"
+"\tГромкость: %s\n"
+"\t        %s\n"
+"\t        баланс %0.2f\n"
+"\tЗадержка буфера: %0.0f мкс\n"
+"\tЗадержка аудиоприёмника: %0.0f usec\n"
+"\tМетод ресэмплирования: %s\n"
+"\tСвойства:\n"
+"\t\t%s\n"
+
+#: ../src/utils/pactl.c:734
+#, c-format
+msgid "Failed to get sample information: %s"
+msgstr "Не удалось получить информацию о сэмпле: %s"
+
+#: ../src/utils/pactl.c:761
+#, c-format
+msgid ""
+"Sample #%u\n"
+"\tName: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
+"\tDuration: %0.1fs\n"
+"\tSize: %s\n"
+"\tLazy: %s\n"
+"\tFilename: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+"Сэмпл #%u\n"
+"\tИмя: %s\n"
+"\tСпецификация сэмпла: %s\n"
+"\tСхема каналов: %s\n"
+"\tГромкость: %s\n"
+"\t        %s\n"
+"\t        баланс %0.2f\n"
+"\tДлительность: %0.1fs\n"
+"\tРазмер: %s\n"
+"\tОтложенный (lazy): %s\n"
+"\tИмя файла: %s\n"
+"\tСвойства:\n"
+"\t\t%s\n"
+
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
+#, c-format
+msgid "Failure: %s"
+msgstr "Не удалось: %s"
+
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Не удалось получить информацию об источнике: %s"
+
+#: ../src/utils/pactl.c:954
+#, c-format
+msgid "Failed to upload sample: %s"
+msgstr "Не удалось загрузить сэмпл: %s"
+
+#: ../src/utils/pactl.c:971
+msgid "Premature end of file"
+msgstr "Преждевременный конец файла"
+
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "Неверный сервер"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
+msgid "Got SIGINT, exiting."
+msgstr "Получен сигнал для остановки, выход."
+
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "Неверное значение громкости"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
+msgid ""
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+msgstr ""
+"%s [options] ... \n"
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"\n"
+
+#: ../src/utils/pactl.c:1380
+#, c-format
+msgid ""
+"pactl %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"pactl %s\n"
+"Скомпилировано с libpulse %s\n"
+"Связано с libpulse %s\n"
+
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
+msgid "Please specify a sample file to load"
+msgstr "Пожалуйста укажите файл сэмпла для загрузки"
+
+#: ../src/utils/pactl.c:1462
+msgid "Failed to open sound file."
+msgstr "Не удалось открыть звуковой файл."
+
+#: ../src/utils/pactl.c:1474
+msgid "Warning: Failed to determine sample specification from file."
+msgstr "Предупреждение: не удалось определить спецификации сэмплов из файла."
+
+#: ../src/utils/pactl.c:1484
+msgid "You have to specify a sample name to play"
+msgstr "Вы должны указать имя сэмпла для воспроизведения"
+
+#: ../src/utils/pactl.c:1496
+msgid "You have to specify a sample name to remove"
+msgstr "Вы должны указать имя сэмпла для удаления"
+
+#: ../src/utils/pactl.c:1505
+msgid "You have to specify a sink input index and a sink"
+msgstr "Вы должны указать индекс ввода аудиоприёмника и аудиоприёмник"
+
+#: ../src/utils/pactl.c:1515
+msgid "You have to specify a source output index and a source"
+msgstr "Вы должны указать индекс вывода источника и источник"
+
+#: ../src/utils/pactl.c:1530
+msgid "You have to specify a module name and arguments."
+msgstr "Вы должны указать имя модуля и аргументы"
+
+#: ../src/utils/pactl.c:1550
+msgid "You have to specify a module index"
+msgstr "Вы должны указать индекс модуля"
+
+#: ../src/utils/pactl.c:1560
+msgid ""
+"You may not specify more than one sink. You have to specify a boolean value."
+msgstr ""
+"Вы не можете указать более одного аудиоприёмника. Вы должны указать "
+"логическое значение."
+
+#: ../src/utils/pactl.c:1573
+msgid ""
+"You may not specify more than one source. You have to specify a boolean "
+"value."
+msgstr ""
+"Вы не можете указать более одного источника. Вы должны указать логическое "
+"значение."
+
+#: ../src/utils/pactl.c:1585
+msgid "You have to specify a card name/index and a profile name"
+msgstr "Вы должны указать имя/индекс карты и имя профиля"
+
+#: ../src/utils/pactl.c:1596
+msgid "You have to specify a sink name/index and a port name"
+msgstr "Вы должны указать имя/индекс аудиоприёмника и имя порта"
+
+#: ../src/utils/pactl.c:1607
+msgid "You have to specify a source name/index and a port name"
+msgstr "Вы должны указать имя/индекс источника и имя порта"
+
+#: ../src/utils/pactl.c:1618
+msgid "You have to specify a sink name/index and a volume"
+msgstr "Вы должны указать имя/индекс аудиоприёмника и громкость"
+
+#: ../src/utils/pactl.c:1631
+msgid "You have to specify a source name/index and a volume"
+msgstr "Вы должны указать имя/индекс источника и громкость"
+
+#: ../src/utils/pactl.c:1644
+msgid "You have to specify a sink input index and a volume"
+msgstr "Вы должны указать индекс ввода аудиоприёмника и громкость"
+
+#: ../src/utils/pactl.c:1649
+msgid "Invalid sink input index"
+msgstr "Неверный индекс ввода аудиоприёмника"
+
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "Вы должны указать индекс вывода источника и источник"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "Неверный индекс ввода аудиоприёмника"
+
+#: ../src/utils/pactl.c:1677
+msgid "You have to specify a sink name/index and a mute boolean"
+msgstr "Вы должны указать имя/индекс аудиоприёмника и выключить логический"
+
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "Неверная спецификация сэмпла"
+
+#: ../src/utils/pactl.c:1694
+msgid "You have to specify a source name/index and a mute boolean"
+msgstr "Вы должны указать имя/индекс источника и выключить логический"
+
+#: ../src/utils/pactl.c:1711
+msgid "You have to specify a sink input index and a mute boolean"
+msgstr "Вы должны указать индекс ввода аудиоприёмника и выключить логический"
+
+#: ../src/utils/pactl.c:1716
+msgid "Invalid sink input index specification"
+msgstr "Неверная спецификация индекса ввода аудиоприёмника"
+
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "Вы должны указать имя/индекс источника и выключить логический"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "Неверная спецификация индекса ввода аудиоприёмника"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "Вы должны указать имя/индекс аудиоприёмника и выключить логический"
+
+#: ../src/utils/pactl.c:1772
+msgid "No valid command specified."
+msgstr "Не указаны правильные команды."
+
+#: ../src/utils/pax11publish.c:61
+#, c-format
+msgid ""
+"%s [-D display] [-S server] [-O sink] [-I source] [-c file]  [-d|-e|-i|-r]\n"
+"\n"
+" -d    Show current PulseAudio data attached to X11 display (default)\n"
+" -e    Export local PulseAudio data to X11 display\n"
+" -i    Import PulseAudio data from X11 display to local environment "
+"variables and cookie file.\n"
+" -r    Remove PulseAudio data from X11 display\n"
+msgstr ""
+"%s [-D display] [-S server] [-O sink] [-I source] [-c file]  [-d|-e|-i|-r]\n"
+"\n"
+" -d    Show current PulseAudio data attached to X11 display (default)\n"
+" -e    Export local PulseAudio data to X11 display\n"
+" -i    Import PulseAudio data from X11 display to local environment "
+"variables and cookie file.\n"
+" -r    Remove PulseAudio data from X11 display\n"
+
+#: ../src/utils/pax11publish.c:94
+#, c-format
+msgid "Failed to parse command line.\n"
+msgstr "Ошибка разбора командной строки.\n"
+
+#: ../src/utils/pax11publish.c:113
+#, c-format
+msgid "Server: %s\n"
+msgstr "Сервер: %s\n"
+
+#: ../src/utils/pax11publish.c:115
+#, c-format
+msgid "Source: %s\n"
+msgstr "Источник: %s\n"
+
+#: ../src/utils/pax11publish.c:117
+#, c-format
+msgid "Sink: %s\n"
+msgstr "Аудиоприёмник: %s\n"
+
+#: ../src/utils/pax11publish.c:119
+#, c-format
+msgid "Cookie: %s\n"
+msgstr "Cookie: %s\n"
+
+#: ../src/utils/pax11publish.c:137
+#, c-format
+msgid "Failed to parse cookie data\n"
+msgstr "Не удалось разобрать данные cookie\n"
+
+#: ../src/utils/pax11publish.c:142
+#, c-format
+msgid "Failed to save cookie data\n"
+msgstr "Не удалось сохранить данные cookie\n"
+
+#: ../src/utils/pax11publish.c:157
+#, c-format
+msgid "Failed to load client configuration file.\n"
+msgstr "Не удалось загрузить файл конфигурации клиента.\n"
+
+#: ../src/utils/pax11publish.c:162
+#, c-format
+msgid "Failed to read environment configuration data.\n"
+msgstr "Не удалось прочитать данные конфигурации окружения.\n"
+
+#: ../src/utils/pax11publish.c:179
+#, c-format
+msgid "Failed to get FQDN.\n"
+msgstr "Не удалось получить имя домена (FQDN).\n"
+
+#: ../src/utils/pax11publish.c:199
+#, c-format
+msgid "Failed to load cookie data\n"
+msgstr "Не удалось загрузить данные cookie\n"
+
+#: ../src/utils/pax11publish.c:217
+#, c-format
+msgid "Not yet implemented.\n"
+msgstr "Ещё не выполнено.\n"
+
+#: ../src/utils/pacmd.c:66
+msgid "No PulseAudio daemon running, or not running as session daemon."
+msgstr ""
+"Нет запущенного демона PulseAudio или не запущен в качестве сессионного "
+"демона."
+
+#: ../src/utils/pacmd.c:71
+#, c-format
+msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
+msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
+
+#: ../src/utils/pacmd.c:88
+#, c-format
+msgid "connect(): %s"
+msgstr "connect(): %s"
+
+#: ../src/utils/pacmd.c:96
+msgid "Failed to kill PulseAudio daemon."
+msgstr "Не удалось убить демон PulseAudio."
+
+#: ../src/utils/pacmd.c:104
+msgid "Daemon not responding."
+msgstr "Демон не отвечает."
+
+#: ../src/utils/pacmd.c:184
+#, c-format
+msgid "poll(): %s"
+msgstr "poll(): %s"
+
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
+#, c-format
+msgid "read(): %s"
+msgstr "read(): %s"
+
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
+#, c-format
+msgid "write(): %s"
+msgstr "write(): %s"
+
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
+msgid "Cannot access autospawn lock."
+msgstr "Cannot access autospawn lock."
+
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
+#, 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 set -- однако последующее snd_pcm_avail() вернуло 0 "
+"или другое значение < min_avail."
+
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
+#, 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"
+"Мы проснулись с POLLOUT set -- однако последующее snd_pcm_avail() вернуло 0 "
+"или другое значение < min_avail."
+
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
+msgid "Off"
+msgstr "Выключено"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
+msgid "High Fidelity Playback (A2DP)"
+msgstr "Воспроизведение высокого качества (A2DP)"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
+msgid "High Fidelity Capture (A2DP)"
+msgstr "Запись высокого качества (A2DP)"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
+msgid "Telephony Duplex (HSP/HFP)"
+msgstr "Дуплексная телефония (HSP/HFP)"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
+#: ../src/modules/reserve-wrap.c:151
+msgid "PulseAudio Sound Server"
+msgstr "Звуковой сервер PulseAudio"
+
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
+msgid "Output Devices"
+msgstr "Устройства вывода"
+
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
+msgid "Input Devices"
+msgstr "Устройства ввода"
+
+#: ../src/modules/module-rygel-media-server.c:1056
+msgid "Audio on @HOSTNAME@"
+msgstr "Аудио на @HOSTNAME@"
+
+#: ../src/modules/alsa/alsa-mixer.c:2219
+msgid "Input"
+msgstr "Ввод"
+
+#: ../src/modules/alsa/alsa-mixer.c:2220
+msgid "Docking Station Input"
+msgstr "Док-станция ввода"
+
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
+msgid "Docking Station Microphone"
+msgstr "Док-станция микрофон"
+
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "Док-станция ввода"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "Линейный вход"
+
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
+msgid "Microphone"
+msgstr "Микрофон"
+
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "Док-станция микрофон"
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "Микрофон"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "Внешний микрофон"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
+msgid "Internal Microphone"
+msgstr "Встроенный микрофон"
+
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
+msgid "Radio"
+msgstr "Радио"
+
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
+msgid "Video"
+msgstr "Видео"
+
+#: ../src/modules/alsa/alsa-mixer.c:2231
+msgid "Automatic Gain Control"
+msgstr "Автоматическая регулировка усиления"
+
+#: ../src/modules/alsa/alsa-mixer.c:2232
+msgid "No Automatic Gain Control"
+msgstr "Нет автоматической регулировки усиления"
+
+#: ../src/modules/alsa/alsa-mixer.c:2233
+msgid "Boost"
+msgstr "Усиление"
+
+#: ../src/modules/alsa/alsa-mixer.c:2234
+msgid "No Boost"
+msgstr "Нет усиления"
+
+#: ../src/modules/alsa/alsa-mixer.c:2235
+msgid "Amplifier"
+msgstr "Усилитель"
+
+#: ../src/modules/alsa/alsa-mixer.c:2236
+msgid "No Amplifier"
+msgstr "Нет усилителя"
+
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "Усиление"
+
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "Нет усиления"
+
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "Аналоговые наушники"
+
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "Аналоговый ввод"
+
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "Док-станция микрофон"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
+msgid "Analog Output"
+msgstr "Аналоговый вывод"
+
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "Аналоговый вывод (LFE)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "Линейный вход"
+
+#: ../src/modules/alsa/alsa-mixer.c:2314
+msgid "Analog Mono Output"
+msgstr "Аналоговый вывод моно"
+
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "Аналоговое стерео"
+
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Цифровое стерео (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Цифровое стерео (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3756
+msgid "Analog Mono"
+msgstr "Аналоговое моно"
+
+#: ../src/modules/alsa/alsa-mixer.c:3757
+msgid "Analog Stereo"
+msgstr "Аналоговое стерео"
+
+#: ../src/modules/alsa/alsa-mixer.c:3758
+msgid "Analog Surround 2.1"
+msgstr "Аналоговый объёмный 2.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3759
+msgid "Analog Surround 3.0"
+msgstr "Аналоговый объёмный 3.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:3760
+msgid "Analog Surround 3.1"
+msgstr "Аналоговый объёмный 3.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3761
+msgid "Analog Surround 4.0"
+msgstr "Аналоговый объёмный 4.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:3762
+msgid "Analog Surround 4.1"
+msgstr "Аналоговый объёмный 4.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3763
+msgid "Analog Surround 5.0"
+msgstr "Аналоговый объёмный 5.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:3764
+msgid "Analog Surround 5.1"
+msgstr "Аналоговый объёмный 5.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3765
+msgid "Analog Surround 6.0"
+msgstr "Аналоговый объёмный 6.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:3766
+msgid "Analog Surround 6.1"
+msgstr "Аналоговый объёмный 6.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3767
+msgid "Analog Surround 7.0"
+msgstr "Аналоговый объёмный 7.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:3768
+msgid "Analog Surround 7.1"
+msgstr "Аналоговый объёмный 7.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3769
+msgid "Digital Stereo (IEC958)"
+msgstr "Цифровое стерео (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Цифровое стерео (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3771
+msgid "Digital Surround 4.0 (IEC958/AC3)"
+msgstr "Цифровой объёмный 4.0 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3772
+msgid "Digital Surround 5.1 (IEC958/AC3)"
+msgstr "Цифровой объёмный 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3773
+msgid "Digital Stereo (HDMI)"
+msgstr "Цифровое стерео (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Цифровой объёмный 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
+msgid "Analog Mono Duplex"
+msgstr "Аналоговый моно дуплекс"
+
+#: ../src/modules/alsa/alsa-mixer.c:3896
+msgid "Analog Stereo Duplex"
+msgstr "Аналоговый стерео дуплекс"
+
+#: ../src/modules/alsa/alsa-mixer.c:3897
+msgid "Digital Stereo Duplex (IEC958)"
+msgstr "Цифровой стерео дуплекс (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Пустой выход"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "Ввод"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<имя аудиоприёмника> sink_properties=<свойства аудиоприёмника> "
+"master=<имя аудиоприёмника для фильтрации> format=<формат> rate=<частота> "
+"channels=<число каналов> channel_map=<схема каналов> plugin=<имя плагина "
+"ladspa> label=<метка плагина ladspa> control=<список входных значений, "
+"разделённый запятыми>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit не поддерживается на этой платформе."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() не удалось"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Выход источника #%u\n"
+#~ "\tДрайвер: %s\n"
+#~ "\tРодительский модуль: %s\n"
+#~ "\tКлиент: %s\n"
+#~ "\tИсточник: %u\n"
+#~ "\tСпецификация сэмплов: %s\n"
+#~ "\tСхема каналов: %s\n"
+#~ "\tЗадержка буфера: %0.0f мкс\n"
+#~ "\tЗадержка источника: %0.0f мкс\n"
+#~ "\tМетод ресэмплирования: %s\n"
+#~ "\tСвойства:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Цифровой объёмный 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Сабвуфер"
index 820b14d..aad1df6 100644 (file)
--- a/po/sr.po
+++ b/po/sr.po
@@ -2,28 +2,24 @@
 # Copyright (C) 2006 Lennart Poettering
 # This file is distributed under the same license as the pulseaudio package.
 # Igor Miletic (Игор Милетић) <grejigl-gnomeprevod@yahoo.ca>, 2009.
-# Miloš Komarčević <kmilos@gmail.com>, 2009.
+# Miloš Komarčević <kmilos@gmail.com>, 2009, 2012.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-10-30 10:22+0000\n"
-"PO-Revision-Date: 2009-10-30 22:51+0100\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:55+0000\n"
 "Last-Translator: Miloš Komarčević <kmilos@gmail.com>\n"
 "Language-Team: Serbian (sr) <fedora-trans-sr@redhat.com>\n"
+"Language: \n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
-"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -36,20 +32,33 @@ msgstr ""
 "Ово је највероватније грешка у „%s“ ALSA управљачком програму. Пријавите "
 "овај проблем ALSA програмерима."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
+"snd_pcm_delay() је вратио вредност која је необично велика: %li бајтова (%s"
+"%lu ms).\n"
+"Ово је највероватније грешка у „%s“ ALSA управљачком програму. Пријавите "
+"овај проблем ALSA програмерима."
+
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 msgstr ""
-"snd_pcm_delay() је вратио вредност која је необично велика: %li бајтова (%s%"
-"lu ms).\n"
+"snd_pcm_avail() је вратио вредност која је необично велика: %lu бајтова (%lu "
+"ms).\n"
 "Ово је највероватније грешка у „%s“ ALSA управљачком програму. Пријавите "
 "овај проблем ALSA програмерима."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -62,25 +71,28 @@ msgstr ""
 "Ово је највероватније грешка у „%s“ ALSA управљачком програму. Пријавите "
 "овај проблем ALSA програмерима."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "Увек одржава барем један сливник оптерећеним чак и када је празан"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "Лажан излаз"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "Виртуелни LADSPA сливник"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<име сливника> sink_properties=<својства сливника> master=<име "
 "сливника за филтрирање> format=<формат узорка> rate=<учестаност "
@@ -88,120 +100,126 @@ msgstr ""
 "ladspa додатка> label=<ознака ladspa додатка> control=<списак улазних "
 "контролних вредности раздвојених зарезом>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "Узорак NULL сливника"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "Празан излаз"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "Унутрашњи звук"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "Модем"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "Неуспешна претрага за оригиналним lt_dlopen учитавачем."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "Неуспешно смештање новог dl учитавача."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "Неуспешно додавање „повежи одмах“ учитавача."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "Добих сигнал %s."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "Напуштам."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "Не могу наћи корисника „%s“."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "Не могу наћи групу „%s“."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "Нађени су корисник „%s“ (UID %lu) и група „%s“ (GID %lu)."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "GID корисника „%s“ се не поклапа са групом „%s“."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "Лични директоријум корисника „%s“ није „%s“, занемарујем."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Неуспешно прављење „%s“: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "Неуспешна промена групног списка: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "Неуспешна промена GID-а: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "Неуспешна промена UID-а: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "Успешно одбачена root овлашћења."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "Режим за читав систем није подржан на овој платформи."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) није успело: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "Неуспешно тумачење командне линије."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "Демон није покренут"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "Демон је покренут са PID-ом %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "Неуспешно убијање демона: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -209,158 +227,179 @@ msgstr ""
 "Није намеравано да се овај програм покреће из root налога (осим у случају "
 "када је --system наведено)"
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "Потребна су root овлашћења."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start није подржано за системске примерке."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "Покренуто у системском режиму, али --disallow-exit није постављено!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
 "Покренуто у системском режиму, али --disallow-module-loading није постављено!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "Покренуто у системском режиму, присилно онемогућујем SHM режим!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 "Покренуто у системском режиму, присилно онемогућујем гашење после одређеног "
 "времена мировања!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "Неуспешно проналажење стандардног улаза/излаза."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "Неуспешно пуштање података кроз цев: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "Неуспела функција fork(): %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "Неуспела функција read(): %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "Неуспешно покретање демона."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "Демон успешно покренут."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "Неуспела функција read(): %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Ово је PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Домаћин компајлирања: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "CFLAGS компајлирања: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "Покренут на домаћину: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "Нашао %u процесор(а)"
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "Величина странице је %lu бајтова"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Компајлирано са подршком за Valgrind: да"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Компајлирано са подршком за Valgrind: не"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "Покренут у Valgrind режиму: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "Покренут на домаћину: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "Оптимизована изградња: да"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "Оптимизована изградња: не"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG дефинисан, сва обавештења искључена."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH дефинисан, само обавештења брзе путање искључена."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "Сва обавештења омогућена."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "Неуспешно добављање ИБ машине"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "ИБ машине је %s."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "ИБ сесије је %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "Користи се %s извршни директоријум."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "Користи се %s директоријум стања."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "Користи се %s директоријум модула."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Покренуто у системском режиму: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -376,15 +415,15 @@ msgstr ""
 "Прочитајте http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode ради "
 "објашњења зашто је системски режим обично лоша идеја."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "Неуспела функција pa_pid_file_create()."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "Доступни су нови бројачи високе резолуције! Пријатно!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -392,32 +431,32 @@ msgstr ""
 "Ваше језгро није добро подешено за pulseaudio! Препоручује Вам се да "
 "користите Linux језгро са омогућеним бројачима високе резолуције."
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "Неуспела функција pa_core_new()."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "Неуспешно покретање демона."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Демон је покренут без иједног учитаног модула, одбија да ради."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "Покретање демона успешно."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "Покренуто гашење демона."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "Рад демона је прекинут."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -454,15 +493,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -567,15 +604,15 @@ msgstr ""
 "  -n                                    Не учитавај подразумевану датотеку "
 "скрипте.\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize очекује логички аргумент"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail очекује логички аргумент"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -583,167 +620,170 @@ msgstr ""
 "--log-level очекује аргумент за ниво записа (или нумеричка вредност у опсегу "
 "0..4 или једно од debug, info, notice, warn, error)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority очекује логички аргумент"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime очекује логички аргумент"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading очекује логички аргумент"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit очекује логички аргумент"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file очекује логички аргумент"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr ""
 "Неисправан циљни дневник: користите једно од „syslog“, „stderr“ или „auto“."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time очекује логички аргумент"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta очекује логички аргумент"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Неисправан начин дискретизације „%s“."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system очекује логички аргумент"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit очекује логички аргумент"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm очекује логички аргумент"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Име: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "Подаци о модулу нису доступни\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Верзија: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Опис: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Аутор: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Употреба: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "Учитај једном: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "УПОЗОРЕЊЕ О ПРЕВАЗИЛАЖЕЊУ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Путања: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Неисправан циљни дневник „%s“."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Неисправан ниво опширности у дневнику „%s“."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Неисправан начин дискретизације „%s“."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] Неисправан rlimit „%s“."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit није подржан на овој платформи."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Неисправан формат узорка „%s“."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Неисправна учестаност дискретизације „%s“."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Неисправни канали узорка „%s“."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] Неисправна мапа канала „%s“."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Неисправан број одломака „%s“."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Неисправна величина одломка „%s“."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Неисправан ниво приоритета „%s“."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Неисправна учестаност дискретизације „%s“."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Неуспело отварање датотеке подешавања: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -751,12 +791,12 @@ msgstr ""
 "Наведена мапа канала има нема исти број канала као што је наведено у "
 "подразумеваном броју канала."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Прочитај из датотеке подешавања: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "Чистим повластице."
 
@@ -768,6 +808,16 @@ msgstr "PulseAudio звучни систем"
 msgid "Start the PulseAudio Sound System"
 msgstr "Покрени PulseAudio звучни систем"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio звучни систем"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "Покрени PulseAudio звучни систем"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Моно"
@@ -797,8 +847,8 @@ msgid "Rear Right"
 msgstr "Позадински десни"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Звучник за ниске фреквенције"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -972,9 +1022,10 @@ msgstr "Горњи позадински леви"
 msgid "Top Rear Right"
 msgstr "Горњи позадински десни"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(неисправно)"
 
@@ -1002,332 +1053,349 @@ msgstr "Окружујући 5.1"
 msgid "Surround 7.1"
 msgstr "Окружујући 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "У реду"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "Забрањен приступ"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Непозната наредба"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "Неисправан аргумент"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "Ентитет постоји"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "Не постоји такав ентитет"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "Веза одбијена"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "Грешка у протоколу"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "Време истекло"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "Нема кључа за овлашћење"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "Интерна грешка"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "Веза прекинута"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "Ентитет убијен"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Сервер неисправан"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "Иницијализација модула није успела"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "Лоше стање"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Нема података"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "Неусаглашена верзија протокола"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "Превелико"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "Није подржано"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Ко̑д грешке је непознат"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "Не постоји такво проширење"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "Избачена функционалност"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "Није одрађено"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "Клијент је израчван"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "Улазна/излазна грешка"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "Уређај или ресурс је заузет"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "Неуспела функција XOpenDisplay()"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "Неуспела функција pa_context_connect(): %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "Неуспешно тумачење података из колачића"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Неуспешно отварање датотеке подешавања „%s“: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "Колачић није учитан. Покушавам се повезати без колачића."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "Примио поруку за непознати локал „%s“"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "Неуспешно исушивање тока: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "Репродукциони ток је исушен."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "Веза до сервера се исушује."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "Неуспела функција pa_stream_write(): %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "Неуспела функција pa_stream_write(): %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "Неуспела функција pa_stream_peek(): %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "Ток је успешно направљен."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "Неуспела функција pa_stream_get_buffer_attr(): %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, 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:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Мере бафера: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "Користим следеће параметре узорка „%s“ и мапу канала „%s“."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "Прикључен на уређај %s (%u, %s обустављено)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "Грешка тока: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "Уређај тока обустављен.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "Уређај тока настављен.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "Ток није попуњен.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "Ток се прелива.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "Ток је покренут.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "Ток пребачен на уређај %s (%u, %s обустављено).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "није"
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "Параметри бафера тока су промењени.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "Веза успостављена.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "Неуспела функција pa_stream_new(): %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "Неуспела функција pa_stream_connect_playback(): %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "Неуспела функција pa_stream_connect_record(): %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "Неуспешно повезивање: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "Добих EOF."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "Неуспела функција write(): %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "Добих сигнал, излазим."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "Не могу добити вредност кашњења: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Време: %0.3f s; Кашњење: %0.0f us."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "Неуспела функција pa_stream_update_timing_info(): %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1379,10 +1447,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [опције]\n"
@@ -1440,7 +1513,7 @@ msgstr ""
 "      --list-file-formats               Испиши све доступне формате "
 "података.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1451,68 +1524,68 @@ msgstr ""
 "Компајлирано са libpulse %s\n"
 "Повезано са libpulse %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "Неисправно име клијента „%s“"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "Неисправно име тока „%s“"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "Неисправна мапа канала „%s“"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "Неисправан параметар кашњења „%s“"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "Неисправан параметар за време процеса „%s“"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "Неисправно својство „%s“"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "Непознат %s формат датотеке."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "Неисправан параметар узорка"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "Превише аргумената."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "Није успело прављење параметара узорка за датотеку."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "Није успело отварање звучне датотеке."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
@@ -1520,102 +1593,107 @@ msgstr ""
 "Упозорење: наведени параметри узорка ће бити пребрисани параметрима из "
 "датотеке."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "Неуспешно утврђивање параметара узорка из датотеке."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "Упозорење: Неуспешно утврђивање мапе канала из датотеке."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "Мапа канала се не поклапа са параметрима узорка"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "Упозорење: Неуспешно записивање мапе канала у датотеку."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr "Отварам ток %s са параметрима узорка „%s“ и мапом канала „%s“."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "снима"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "пушта"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "Неуспешно тумачење командне линије."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "Неуспела функција pa_mainloop_new()."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "Неуспела функција io_new()."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "Неуспела функција pa_context_new()."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "Неуспела функција pa_context_connect(): %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "Неуспела функција pa_context_new()."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "Неуспела функција pa_mainloop_run()."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "Неуспешно заустављање: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "Неуспешно настављање: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "УПОЗОРЕЊЕ: Звучни сервер није локални, не заустављам.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Неуспешно повезивање: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "Добих SIGINT, излазим.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "УПОЗОРЕЊЕ: Потлачени процес је прекинут сигналом %u\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1660,35 +1738,46 @@ msgstr "Неуспела функција pa_context_new().\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "Неуспела функција pa_mainloop_run().\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "Неуспешно добављање статистике: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "Тренутно у употреби: %u блокова садржи укупно %s бајтова.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "Смештено од покретања: %u блокова садржи укупно %s бајтова.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "Величина кеш меморије узорка: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "Неуспешно добављање података о серверу: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1696,7 +1785,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "Корисничко име: %s\n"
 "Име домаћина: %s\n"
@@ -1708,13 +1797,13 @@ msgstr ""
 "Подразумевани извор: %s\n"
 "Колачић: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "Неуспешно добављање података о сливнику: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1730,7 +1819,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1752,22 +1841,27 @@ msgstr ""
 "\tСвојства:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tПортови:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tАктивни порт: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tПортови:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "Неуспешно добављање података о извору: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1806,20 +1900,20 @@ msgstr ""
 "\tСвојства:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "непознато"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "Неуспешно добављање података о модулу: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1836,12 +1930,12 @@ msgstr ""
 "\tСвојства:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "Неуспешно добављање података о клијенту: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1856,12 +1950,12 @@ msgstr ""
 "\tСвојства:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "Неуспешно добављање података о картици: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1878,23 +1972,23 @@ msgstr ""
 "\tСвојства:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tПрофили:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tАктивни профил: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "Неуспешно добављање података о улазу сливника: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1903,6 +1997,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1930,13 +2025,13 @@ msgstr ""
 "\tСвојства:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "Неуспешно добављање података о излазу извора: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1945,31 +2040,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Ð\98злаз Ð¸Ð·Ð²Ð¾Ñ\80а #%u\n"
+"Улаз Ñ\83 Ñ\81ливник #%u\n"
 "\tУправљачки програм: %s\n"
 "\tПрипада модулу: %s\n"
 "\tКлијент: %s\n"
-"\tÐ\98звоÑ\80: %u\n"
+"\tСливник: %u\n"
 "\tПараметри узорка: %s\n"
 "\tМапа канала: %s\n"
+"\tИскључен тон: %s\n"
+"\tЈачина звука: %s\n"
+"\t        %s\n"
+"\t        баланс %0.2f\n"
 "\tКашњење бафера: %0.0f μs\n"
-"\tКашњење извора: %0.0f μs\n"
+"\tКашњење сливника: %0.0f μs\n"
 "\tНачин дискретизације: %s\n"
 "\tСвојства:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "Неуспешно добављање података о узорку: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -2000,48 +2104,163 @@ msgstr ""
 "\tСвојства:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "Неуспех: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Неуспешно добављање података о извору: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "Није успело постављање узорка: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "Прерани крај датотеке"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "Сервер неисправан"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "Добих SIGINT, излазим."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "Неисправан параметар јачине"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2051,37 +2270,15 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [опције] stat\n"
-"%s [опције] list\n"
-"%s [опције] exit\n"
-"%s [опције] upload-sample ИМЕДАТОТЕКЕ [ИМЕ]\n"
-"%s [опције] play-sample ИМЕ [СЛИВНИК]\n"
-"%s [опције] remove-sample ИМЕ\n"
-"%s [опције] move-sink-input УЛАЗСЛИВНИКА СЛИВНИК\n"
-"%s [опције] move-source-output ИЗЛАЗИЗВОРА ИЗВОР\n"
-"%s [опције] load-module ИМЕ [АРГ ...]\n"
-"%s [опције] unload-module МОДУЛ\n"
-"%s [опције] suspend-sink СЛИВНИК 1|0\n"
-"%s [опције] suspend-source ИЗВОР 1|0\n"
-"%s [опције] set-card-profile КАРТИЦА ПРОФИЛ\n"
-"%s [опције] set-sink-port СЛИВНИК ПОРТ\n"
-"%s [опције] set-source-port ИЗВОР ПОРТ\n"
-"%s [опције] set-sink-volume СЛИВНИК ЈАЧИНА\n"
-"%s [опције] set-source-volume ИЗВОР ЈАЧИНА\n"
-"%s [опције] set-sink-input-volume УЛАЗСЛИВНИКА ЈАЧИНА\n"
-"%s [опције] set-sink-mute СЛИВНИК 1|0\n"
-"%s [опције] set-source-mute ИЗВОР 1|0\n"
-"%s [опције] set-sink-input-mute УЛАЗСЛИВНИКА 1|0\n"
+"%s [опције] ... \n"
 "\n"
 "  -h, --help                            Прикажи ову помоћ\n"
 "      --version                         Прикажи верзију\n"
-"\n"
 "  -s, --server=СЕРВЕР                   Име сервера на који се треба "
 "повезати\n"
-"  -n, --client-name=ИМЕ                 Како назвати овог клијента на "
-"серверу\n"
+"\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2092,106 +2289,138 @@ msgstr ""
 "Компајлирано са libpulse %s\n"
 "Повезано са libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "Наведите датотеку узорка коју треба учитати"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "Није успело отварање звучне датотеке."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "Упозорење: Неуспешно утврђивање параметара узорка из датотеке."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "Морате навести име узорка којег желите репродуковати"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "Морате навести име узорка којег желите уклонити"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "Морате навести индекс улаза сливника и сливник"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "Морате навести индекс излаза извора и извор"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "Морате навести име и аргументе модула."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "Морате навести индекс модула"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "Не можете навести више од једног сливника. Морате навести логичку вредност."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr ""
 "Не можете навести више од једног извора. Морате навести логичку вредност."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "Морате навести име/индекс картице и име профила"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "Морате навести име/индекс сливника и име порта"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "Морате навести име/индекс извора и име порта"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "Морате навести име/индекс сливника и јачину"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "Неисправан параметар јачине"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "Морате навести име/индекс извора и јачину"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "Морате навести индекс улаза сливника и јачину"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "Неисправан индекс улаза сливника"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "Морате навести индекс излаза извора и извор"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "Неисправан индекс улаза сливника"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "Морате навести име/индекс сливника и логичку вредност за искључивање"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "Неисправан параметар узорка"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "Морате навести име/индекс извора и логичку вредност за искључивање"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "Морате навести индекс улаза сливника и логичку вредност за искључивање"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "Неисправан параметар индекса улаза сливника"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "Морате навести име/индекс извора и логичку вредност за искључивање"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "Неисправан параметар индекса улаза сливника"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "Морате навести име/индекс сливника и логичку вредност за искључивање"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "Није наведена исправна наредба."
 
@@ -2221,104 +2450,104 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "Неуспешно тумачење командне линије.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Сервер: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Извор: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Сливник: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Колачић: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "Неуспешно тумачење података из колачића\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "Неуспешно записивање података колачића\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "Неуспешно учитавање клијентове датотеке подешавања.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "Неуспешно читање података подешавања за окружење.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "Неуспешно добијање FQDN-а.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "Неуспешно учитавање датотека колачића\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Није још имплементирано.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr ""
 "Нема покренутог PulseAudio демона, или се не извршава као демон сесије."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "Није успело убијање PulseAudio демона."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "Демон се не одазива."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "Није могуће приступити датотеци закључавања за самоумножавање."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2335,7 +2564,7 @@ msgstr ""
 "Пробуђени смо са постављеним POLLOUT-ом -- али следећи snd_pcm_avail() је "
 "вратио 0 или неку другу вредност мању од min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2352,228 +2581,465 @@ msgstr ""
 "Пробуђени смо са постављеним POLLIN-ом -- али следећи snd_pcm_avail() је "
 "вратио 0 или неку другу вредност мању од min_avail."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "Искључено"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "Репродукција високе тачности (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "Снимање високе тачности (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Двосмерно телефонирање (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "PulseAudio звучни систем"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
 msgstr "Излазни уређаји"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
 msgstr "Улазни уређаји"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
 msgstr "Аудио на @HOSTNAME@"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
 msgstr "Улаз"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
 msgstr "Улаз прикључне станице"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
 msgstr "Микрофон прикључне станице"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "Улаз прикључне станице"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
 msgstr "Линија у"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
 msgstr "Микрофон"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "Микрофон прикључне станице"
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "Микрофон"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
 msgid "External Microphone"
 msgstr "Спољни микрофон"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
 msgstr "Унутрашњи микрофон"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
 msgstr "Радио"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
 msgstr "Видео"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
 msgstr "Самостална контрола појачања"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
 msgstr "Без самосталне контроле појачања"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
 msgstr "Подизање"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
 msgstr "Без подизања"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
 msgstr "Појачало"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
 msgstr "Без појачала"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr "Аналогни улаз"
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "Подизање"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr "Аналогни микрофон"
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "Без подизања"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
-msgstr "Аналогна линија у"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "Аналогне слушалице"
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr "Ð\90налогни Ñ\80адио"
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "Ð\90налогни Ñ\83лаз"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr "Ð\90налогни Ð²Ð¸Ð´ÐµÐ¾"
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "Ð\9cикÑ\80оÑ\84он Ð¿Ñ\80икÑ\99Ñ\83Ñ\87не Ñ\81Ñ\82аниÑ\86е"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
 msgstr "Аналогни излаз"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr "Аналогне слушалице"
-
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
 msgstr "Аналогни излаз (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "Линија у"
+
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
 msgstr "Аналогни моно излаз"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, c-format
-msgid "%s+%s"
-msgstr "%s+%s"
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "Аналогни стерео"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, c-format
-msgid "%s / %s"
-msgstr "%s / %s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Дигитални стерео (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Дигитални стерео (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr "Аналогни моно"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr "Аналогни стерео"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
 msgstr "Аналогни окружујући 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
 msgstr "Аналогни окружујући 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
 msgstr "Аналогни окружујући 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr "Аналогни окружујући 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr "Аналогни окружујући 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr "Аналогни окружујући 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr "Аналогни окружујући 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
 msgstr "Аналогни окружујући 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
 msgstr "Аналогни окружујући 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
 msgstr "Аналогни окружујући 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr "Аналогни окружујући 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr "Дигитални стерео (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "Дигитални окружујући 4.0 (IEC958)"
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Дигитални стерео (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Дигитални окружујући 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Дигитални окружујући 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr "Дигитални стерео (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Дигитални окружујући 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
 msgstr "Двосмерни аналогни моно"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
 msgstr "Двосмерни аналогни стерео"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
 msgstr "Двосмерни дигитални стерео (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Празан излаз"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "Улаз"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<име сливника> sink_properties=<својства сливника> master=<име "
+"сливника за филтрирање> format=<формат узорка> rate=<учестаност "
+"дискретизације> channels=<број канала> channel_map=<мапа канала> plugin=<име "
+"ladspa додатка> label=<ознака ladspa додатка> control=<списак улазних "
+"контролних вредности раздвојених зарезом>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit није подржан на овој платформи."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "Неуспела функција XOpenDisplay()"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Излаз извора #%u\n"
+#~ "\tУправљачки програм: %s\n"
+#~ "\tПрипада модулу: %s\n"
+#~ "\tКлијент: %s\n"
+#~ "\tИзвор: %u\n"
+#~ "\tПараметри узорка: %s\n"
+#~ "\tМапа канала: %s\n"
+#~ "\tКашњење бафера: %0.0f μs\n"
+#~ "\tКашњење извора: %0.0f μs\n"
+#~ "\tНачин дискретизације: %s\n"
+#~ "\tСвојства:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [опције] stat\n"
+#~ "%s [опције] list\n"
+#~ "%s [опције] exit\n"
+#~ "%s [опције] upload-sample ИМЕДАТОТЕКЕ [ИМЕ]\n"
+#~ "%s [опције] play-sample ИМЕ [СЛИВНИК]\n"
+#~ "%s [опције] remove-sample ИМЕ\n"
+#~ "%s [опције] move-sink-input УЛАЗСЛИВНИКА СЛИВНИК\n"
+#~ "%s [опције] move-source-output ИЗЛАЗИЗВОРА ИЗВОР\n"
+#~ "%s [опције] load-module ИМЕ [АРГ ...]\n"
+#~ "%s [опције] unload-module МОДУЛ\n"
+#~ "%s [опције] suspend-sink СЛИВНИК 1|0\n"
+#~ "%s [опције] suspend-source ИЗВОР 1|0\n"
+#~ "%s [опције] set-card-profile КАРТИЦА ПРОФИЛ\n"
+#~ "%s [опције] set-sink-port СЛИВНИК ПОРТ\n"
+#~ "%s [опције] set-source-port ИЗВОР ПОРТ\n"
+#~ "%s [опције] set-sink-volume СЛИВНИК ЈАЧИНА\n"
+#~ "%s [опције] set-source-volume ИЗВОР ЈАЧИНА\n"
+#~ "%s [опције] set-sink-input-volume УЛАЗСЛИВНИКА ЈАЧИНА\n"
+#~ "%s [опције] set-sink-mute СЛИВНИК 1|0\n"
+#~ "%s [опције] set-source-mute ИЗВОР 1|0\n"
+#~ "%s [опције] set-sink-input-mute УЛАЗСЛИВНИКА 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Прикажи ову помоћ\n"
+#~ "      --version                         Прикажи верзију\n"
+#~ "\n"
+#~ "  -s, --server=СЕРВЕР                   Име сервера на који се треба "
+#~ "повезати\n"
+#~ "  -n, --client-name=ИМЕ                 Како назвати овог клијента на "
+#~ "серверу\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Дигитални окружујући 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Звучник за ниске фреквенције"
index 45e83d6..59945fc 100644 (file)
@@ -2,28 +2,24 @@
 # Copyright (C) 2006 Lennart Poettering
 # This file is distributed under the same license as the pulseaudio package.
 # Igor Miletic (Igor Miletić) <grejigl-gnomeprevod@yahoo.ca>, 2009.
-# Miloš Komarčević <kmilos@gmail.com>, 2009.
+# Miloš Komarčević <kmilos@gmail.com>, 2009, 2012.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-10-30 10:22+0000\n"
-"PO-Revision-Date: 2009-10-30 22:51+0100\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:55+0000\n"
 "Last-Translator: Miloš Komarčević <kmilos@gmail.com>\n"
 "Language-Team: Serbian (sr) <fedora-trans-sr@redhat.com>\n"
+"Language: \n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
-"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -36,20 +32,33 @@ msgstr ""
 "Ovo je najverovatnije greška u „%s“ ALSA upravljačkom programu. Prijavite "
 "ovaj problem ALSA programerima."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
+"snd_pcm_delay() je vratio vrednost koja je neobično velika: %li bajtova (%s"
+"%lu ms).\n"
+"Ovo je najverovatnije greška u „%s“ ALSA upravljačkom programu. Prijavite "
+"ovaj problem ALSA programerima."
+
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 msgstr ""
-"snd_pcm_delay() je vratio vrednost koja je neobično velika: %li bajtova (%s%"
-"lu ms).\n"
+"snd_pcm_avail() je vratio vrednost koja je neobično velika: %lu bajtova (%lu "
+"ms).\n"
 "Ovo je najverovatnije greška u „%s“ ALSA upravljačkom programu. Prijavite "
 "ovaj problem ALSA programerima."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -62,25 +71,28 @@ msgstr ""
 "Ovo je najverovatnije greška u „%s“ ALSA upravljačkom programu. Prijavite "
 "ovaj problem ALSA programerima."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "Uvek održava barem jedan slivnik opterećenim čak i kada je prazan"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "Lažan izlaz"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "Virtuelni LADSPA slivnik"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<ime slivnika> sink_properties=<svojstva slivnika> master=<ime "
 "slivnika za filtriranje> format=<format uzorka> rate=<učestanost "
@@ -88,120 +100,126 @@ msgstr ""
 "ladspa dodatka> label=<oznaka ladspa dodatka> control=<spisak ulaznih "
 "kontrolnih vrednosti razdvojenih zarezom>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "Uzorak NULL slivnika"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "Prazan izlaz"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "Unutrašnji zvuk"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "Modem"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "Neuspešna pretraga za originalnim lt_dlopen učitavačem."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "Neuspešno smeštanje novog dl učitavača."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "Neuspešno dodavanje „poveži odmah“ učitavača."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "Dobih signal %s."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "Napuštam."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "Ne mogu naći korisnika „%s“."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "Ne mogu naći grupu „%s“."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "Nađeni su korisnik „%s“ (UID %lu) i grupa „%s“ (GID %lu)."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "GID korisnika „%s“ se ne poklapa sa grupom „%s“."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "Lični direktorijum korisnika „%s“ nije „%s“, zanemarujem."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Neuspešno pravljenje „%s“: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "Neuspešna promena grupnog spiska: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "Neuspešna promena GID-a: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "Neuspešna promena UID-a: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "Uspešno odbačena root ovlašćenja."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "Režim za čitav sistem nije podržan na ovoj platformi."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) nije uspelo: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "Neuspešno tumačenje komandne linije."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "Demon nije pokrenut"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "Demon je pokrenut sa PID-om %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "Neuspešno ubijanje demona: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -209,159 +227,180 @@ msgstr ""
 "Nije nameravano da se ovaj program pokreće iz root naloga (osim u slučaju "
 "kada je --system navedeno)"
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "Potrebna su root ovlašćenja."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start nije podržano za sistemske primerke."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "Pokrenuto u sistemskom režimu, ali --disallow-exit nije postavljeno!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
 "Pokrenuto u sistemskom režimu, ali --disallow-module-loading nije "
 "postavljeno!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "Pokrenuto u sistemskom režimu, prisilno onemogućujem SHM režim!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 "Pokrenuto u sistemskom režimu, prisilno onemogućujem gašenje posle određenog "
 "vremena mirovanja!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "Neuspešno pronalaženje standardnog ulaza/izlaza."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "Neuspešno puštanje podataka kroz cev: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "Neuspela funkcija fork(): %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "Neuspela funkcija read(): %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "Neuspešno pokretanje demona."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "Demon uspešno pokrenut."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "Neuspela funkcija read(): %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Ovo je PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Domaćin kompajliranja: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "CFLAGS kompajliranja: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "Pokrenut na domaćinu: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "Našao %u procesor(a)"
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "Veličina stranice je %lu bajtova"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Kompajlirano sa podrškom za Valgrind: da"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Kompajlirano sa podrškom za Valgrind: ne"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "Pokrenut u Valgrind režimu: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "Pokrenut na domaćinu: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "Optimizovana izgradnja: da"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "Optimizovana izgradnja: ne"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG definisan, sva obaveštenja isključena."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH definisan, samo obaveštenja brze putanje isključena."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "Sva obaveštenja omogućena."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "Neuspešno dobavljanje IB mašine"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "IB mašine je %s."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "IB sesije je %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "Koristi se %s izvršni direktorijum."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "Koristi se %s direktorijum stanja."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "Koristi se %s direktorijum modula."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Pokrenuto u sistemskom režimu: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -377,15 +416,15 @@ msgstr ""
 "Pročitajte http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode radi "
 "objašnjenja zašto je sistemski režim obično loša ideja."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "Neuspela funkcija pa_pid_file_create()."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "Dostupni su novi brojači visoke rezolucije! Prijatno!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -393,32 +432,32 @@ msgstr ""
 "Vaše jezgro nije dobro podešeno za pulseaudio! Preporučuje Vam se da "
 "koristite Linux jezgro sa omogućenim brojačima visoke rezolucije."
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "Neuspela funkcija pa_core_new()."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "Neuspešno pokretanje demona."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Demon je pokrenut bez ijednog učitanog modula, odbija da radi."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "Pokretanje demona uspešno."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "Pokrenuto gašenje demona."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "Rad demona je prekinut."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -455,15 +494,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -568,15 +605,15 @@ msgstr ""
 "  -n                                    Ne učitavaj podrazumevanu datoteku "
 "skripte.\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize očekuje logički argument"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail očekuje logički argument"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -584,167 +621,170 @@ msgstr ""
 "--log-level očekuje argument za nivo zapisa (ili numerička vrednost u opsegu "
 "0..4 ili jedno od debug, info, notice, warn, error)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority očekuje logički argument"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime očekuje logički argument"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading očekuje logički argument"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit očekuje logički argument"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file očekuje logički argument"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr ""
 "Neispravan ciljni dnevnik: koristite jedno od „syslog“, „stderr“ ili „auto“."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time očekuje logički argument"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta očekuje logički argument"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Neispravan način diskretizacije „%s“."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system očekuje logički argument"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit očekuje logički argument"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm očekuje logički argument"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Ime: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "Podaci o modulu nisu dostupni\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Verzija: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Opis: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Autor: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Upotreba: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "Učitaj jednom: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "UPOZORENJE O PREVAZILAŽENJU: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Putanja: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Neispravan ciljni dnevnik „%s“."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Neispravan nivo opširnosti u dnevniku „%s“."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Neispravan način diskretizacije „%s“."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] Neispravan rlimit „%s“."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit nije podržan na ovoj platformi."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Neispravan format uzorka „%s“."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Neispravna učestanost diskretizacije „%s“."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Neispravni kanali uzorka „%s“."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] Neispravna mapa kanala „%s“."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Neispravan broj odlomaka „%s“."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Neispravna veličina odlomka „%s“."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Neispravan nivo prioriteta „%s“."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Neispravna učestanost diskretizacije „%s“."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Neuspelo otvaranje datoteke podešavanja: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -752,12 +792,12 @@ msgstr ""
 "Navedena mapa kanala ima nema isti broj kanala kao što je navedeno u "
 "podrazumevanom broju kanala."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Pročitaj iz datoteke podešavanja: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "Čistim povlastice."
 
@@ -769,6 +809,16 @@ msgstr "PulseAudio zvučni sistem"
 msgid "Start the PulseAudio Sound System"
 msgstr "Pokreni PulseAudio zvučni sistem"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio zvučni sistem"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "Pokreni PulseAudio zvučni sistem"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
@@ -798,8 +848,8 @@ msgid "Rear Right"
 msgstr "Pozadinski desni"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Zvučnik za niske frekvencije"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -973,9 +1023,10 @@ msgstr "Gornji pozadinski levi"
 msgid "Top Rear Right"
 msgstr "Gornji pozadinski desni"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(neispravno)"
 
@@ -1003,332 +1054,349 @@ msgstr "Okružujući 5.1"
 msgid "Surround 7.1"
 msgstr "Okružujući 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "U redu"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "Zabranjen pristup"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Nepoznata naredba"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "Neispravan argument"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "Entitet postoji"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "Ne postoji takav entitet"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "Veza odbijena"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "Greška u protokolu"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "Vreme isteklo"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "Nema ključa za ovlašćenje"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "Interna greška"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "Veza prekinuta"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "Entitet ubijen"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Server neispravan"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "Inicijalizacija modula nije uspela"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "Loše stanje"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Nema podataka"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "Neusaglašena verzija protokola"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "Preveliko"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "Nije podržano"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Kȏd greške je nepoznat"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "Ne postoji takvo proširenje"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "Izbačena funkcionalnost"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "Nije odrađeno"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "Klijent je izračvan"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "Ulazna/izlazna greška"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "Uređaj ili resurs je zauzet"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "Neuspela funkcija XOpenDisplay()"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "Neuspela funkcija pa_context_connect(): %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "Neuspešno tumačenje podataka iz kolačića"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Neuspešno otvaranje datoteke podešavanja „%s“: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "Kolačić nije učitan. Pokušavam se povezati bez kolačića."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "Primio poruku za nepoznati lokal „%s“"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "Neuspešno isušivanje toka: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "Reprodukcioni tok je isušen."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "Veza do servera se isušuje."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "Neuspela funkcija pa_stream_write(): %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "Neuspela funkcija pa_stream_write(): %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "Neuspela funkcija pa_stream_peek(): %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "Tok je uspešno napravljen."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "Neuspela funkcija pa_stream_get_buffer_attr(): %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 msgstr "Mere bafera: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Mere bafera: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "Koristim sledeće parametre uzorka „%s“ i mapu kanala „%s“."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "Priključen na uređaj %s (%u, %s obustavljeno)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "Greška toka: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "Uređaj toka obustavljen.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "Uređaj toka nastavljen.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "Tok nije popunjen.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "Tok se preliva.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "Tok je pokrenut.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "Tok prebačen na uređaj %s (%u, %s obustavljeno).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "nije"
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "Parametri bafera toka su promenjeni.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "Veza uspostavljena.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "Neuspela funkcija pa_stream_new(): %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "Neuspela funkcija pa_stream_connect_playback(): %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "Neuspela funkcija pa_stream_connect_record(): %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "Neuspešno povezivanje: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "Dobih EOF."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "Neuspela funkcija write(): %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "Dobih signal, izlazim."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "Ne mogu dobiti vrednost kašnjenja: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Vreme: %0.3f s; Kašnjenje: %0.0f us."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "Neuspela funkcija pa_stream_update_timing_info(): %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1380,10 +1448,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [opcije]\n"
@@ -1442,7 +1515,7 @@ msgstr ""
 "      --list-file-formats               Ispiši sve dostupne formate "
 "podataka.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1453,68 +1526,68 @@ msgstr ""
 "Kompajlirano sa libpulse %s\n"
 "Povezano sa libpulse %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "Neispravno ime klijenta „%s“"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "Neispravno ime toka „%s“"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "Neispravna mapa kanala „%s“"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "Neispravan parametar kašnjenja „%s“"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "Neispravan parametar za vreme procesa „%s“"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "Neispravno svojstvo „%s“"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "Nepoznat %s format datoteke."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "Neispravan parametar uzorka"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "Previše argumenata."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "Nije uspelo pravljenje parametara uzorka za datoteku."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "Nije uspelo otvaranje zvučne datoteke."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
@@ -1522,102 +1595,107 @@ msgstr ""
 "Upozorenje: navedeni parametri uzorka će biti prebrisani parametrima iz "
 "datoteke."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "Neuspešno utvrđivanje parametara uzorka iz datoteke."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "Upozorenje: Neuspešno utvrđivanje mape kanala iz datoteke."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "Mapa kanala se ne poklapa sa parametrima uzorka"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "Upozorenje: Neuspešno zapisivanje mape kanala u datoteku."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr "Otvaram tok %s sa parametrima uzorka „%s“ i mapom kanala „%s“."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "snima"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "pušta"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "Neuspešno tumačenje komandne linije."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "Neuspela funkcija pa_mainloop_new()."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "Neuspela funkcija io_new()."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "Neuspela funkcija pa_context_new()."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "Neuspela funkcija pa_context_connect(): %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "Neuspela funkcija pa_context_new()."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "Neuspela funkcija pa_mainloop_run()."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "Neuspešno zaustavljanje: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "Neuspešno nastavljanje: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "UPOZORENJE: Zvučni server nije lokalni, ne zaustavljam.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Neuspešno povezivanje: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "Dobih SIGINT, izlazim.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "UPOZORENJE: Potlačeni proces je prekinut signalom %u\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1662,35 +1740,46 @@ msgstr "Neuspela funkcija pa_context_new().\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "Neuspela funkcija pa_mainloop_run().\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "Neuspešno dobavljanje statistike: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "Trenutno u upotrebi: %u blokova sadrži ukupno %s bajtova.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "Smešteno od pokretanja: %u blokova sadrži ukupno %s bajtova.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "Veličina keš memorije uzorka: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "Neuspešno dobavljanje podataka o serveru: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1698,7 +1787,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "Korisničko ime: %s\n"
 "Ime domaćina: %s\n"
@@ -1710,13 +1799,13 @@ msgstr ""
 "Podrazumevani izvor: %s\n"
 "Kolačić: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "Neuspešno dobavljanje podataka o slivniku: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1732,7 +1821,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1754,22 +1843,27 @@ msgstr ""
 "\tSvojstva:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tPortovi:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tAktivni port: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tPortovi:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "Neuspešno dobavljanje podataka o izvoru: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1808,20 +1902,20 @@ msgstr ""
 "\tSvojstva:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "nepoznato"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "Neuspešno dobavljanje podataka o modulu: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1838,12 +1932,12 @@ msgstr ""
 "\tSvojstva:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "Neuspešno dobavljanje podataka o klijentu: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1858,12 +1952,12 @@ msgstr ""
 "\tSvojstva:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "Neuspešno dobavljanje podataka o kartici: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1880,23 +1974,23 @@ msgstr ""
 "\tSvojstva:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tProfili:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tAktivni profil: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "Neuspešno dobavljanje podataka o ulazu slivnika: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1905,6 +1999,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1932,13 +2027,13 @@ msgstr ""
 "\tSvojstva:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "Neuspešno dobavljanje podataka o izlazu izvora: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1947,31 +2042,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Izlaz izvora #%u\n"
+"Ulaz u slivnik #%u\n"
 "\tUpravljački program: %s\n"
 "\tPripada modulu: %s\n"
 "\tKlijent: %s\n"
-"\tIzvor: %u\n"
+"\tSlivnik: %u\n"
 "\tParametri uzorka: %s\n"
 "\tMapa kanala: %s\n"
+"\tIsključen ton: %s\n"
+"\tJačina zvuka: %s\n"
+"\t        %s\n"
+"\t        balans %0.2f\n"
 "\tKašnjenje bafera: %0.0f μs\n"
-"\tKašnjenje izvora: %0.0f μs\n"
+"\tKašnjenje slivnika: %0.0f μs\n"
 "\tNačin diskretizacije: %s\n"
 "\tSvojstva:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "Neuspešno dobavljanje podataka o uzorku: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -2002,48 +2106,163 @@ msgstr ""
 "\tSvojstva:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "Neuspeh: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Neuspešno dobavljanje podataka o izvoru: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "Nije uspelo postavljanje uzorka: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "Prerani kraj datoteke"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "Server neispravan"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "Dobih SIGINT, izlazim."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "Neispravan parametar jačine"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2053,37 +2272,15 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [opcije] stat\n"
-"%s [opcije] list\n"
-"%s [opcije] exit\n"
-"%s [opcije] upload-sample IMEDATOTEKE [IME]\n"
-"%s [opcije] play-sample IME [SLIVNIK]\n"
-"%s [opcije] remove-sample IME\n"
-"%s [opcije] move-sink-input ULAZSLIVNIKA SLIVNIK\n"
-"%s [opcije] move-source-output IZLAZIZVORA IZVOR\n"
-"%s [opcije] load-module IME [ARG ...]\n"
-"%s [opcije] unload-module MODUL\n"
-"%s [opcije] suspend-sink SLIVNIK 1|0\n"
-"%s [opcije] suspend-source IZVOR 1|0\n"
-"%s [opcije] set-card-profile KARTICA PROFIL\n"
-"%s [opcije] set-sink-port SLIVNIK PORT\n"
-"%s [opcije] set-source-port IZVOR PORT\n"
-"%s [opcije] set-sink-volume SLIVNIK JAČINA\n"
-"%s [opcije] set-source-volume IZVOR JAČINA\n"
-"%s [opcije] set-sink-input-volume ULAZSLIVNIKA JAČINA\n"
-"%s [opcije] set-sink-mute SLIVNIK 1|0\n"
-"%s [opcije] set-source-mute IZVOR 1|0\n"
-"%s [opcije] set-sink-input-mute ULAZSLIVNIKA 1|0\n"
+"%s [opcije] ... \n"
 "\n"
 "  -h, --help                            Prikaži ovu pomoć\n"
 "      --version                         Prikaži verziju\n"
-"\n"
 "  -s, --server=SERVER                   Ime servera na koji se treba "
 "povezati\n"
-"  -n, --client-name=IME                 Kako nazvati ovog klijenta na "
-"serveru\n"
+"\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2094,107 +2291,139 @@ msgstr ""
 "Kompajlirano sa libpulse %s\n"
 "Povezano sa libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "Navedite datoteku uzorka koju treba učitati"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "Nije uspelo otvaranje zvučne datoteke."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "Upozorenje: Neuspešno utvrđivanje parametara uzorka iz datoteke."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "Morate navesti ime uzorka kojeg želite reprodukovati"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "Morate navesti ime uzorka kojeg želite ukloniti"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "Morate navesti indeks ulaza slivnika i slivnik"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "Morate navesti indeks izlaza izvora i izvor"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "Morate navesti ime i argumente modula."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "Morate navesti indeks modula"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "Ne možete navesti više od jednog slivnika. Morate navesti logičku vrednost."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr ""
 "Ne možete navesti više od jednog izvora. Morate navesti logičku vrednost."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "Morate navesti ime/indeks kartice i ime profila"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "Morate navesti ime/indeks slivnika i ime porta"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "Morate navesti ime/indeks izvora i ime porta"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "Morate navesti ime/indeks slivnika i jačinu"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "Neispravan parametar jačine"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "Morate navesti ime/indeks izvora i jačinu"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "Morate navesti indeks ulaza slivnika i jačinu"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "Neispravan indeks ulaza slivnika"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "Morate navesti indeks izlaza izvora i izvor"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "Neispravan indeks ulaza slivnika"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "Morate navesti ime/indeks slivnika i logičku vrednost za isključivanje"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "Neispravan parametar uzorka"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "Morate navesti ime/indeks izvora i logičku vrednost za isključivanje"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr ""
 "Morate navesti indeks ulaza slivnika i logičku vrednost za isključivanje"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "Neispravan parametar indeksa ulaza slivnika"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "Morate navesti ime/indeks izvora i logičku vrednost za isključivanje"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "Neispravan parametar indeksa ulaza slivnika"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "Morate navesti ime/indeks slivnika i logičku vrednost za isključivanje"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "Nije navedena ispravna naredba."
 
@@ -2224,104 +2453,104 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "Neuspešno tumačenje komandne linije.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Server: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Izvor: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Slivnik: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Kolačić: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "Neuspešno tumačenje podataka iz kolačića\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "Neuspešno zapisivanje podataka kolačića\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "Neuspešno učitavanje klijentove datoteke podešavanja.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "Neuspešno čitanje podataka podešavanja za okruženje.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "Neuspešno dobijanje FQDN-a.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "Neuspešno učitavanje datoteka kolačića\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Nije još implementirano.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr ""
 "Nema pokrenutog PulseAudio demona, ili se ne izvršava kao demon sesije."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "Nije uspelo ubijanje PulseAudio demona."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "Demon se ne odaziva."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "Nije moguće pristupiti datoteci zaključavanja za samoumnožavanje."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2338,7 +2567,7 @@ msgstr ""
 "Probuđeni smo sa postavljenim POLLOUT-om -- ali sledeći snd_pcm_avail() je "
 "vratio 0 ili neku drugu vrednost manju od min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2355,228 +2584,465 @@ msgstr ""
 "Probuđeni smo sa postavljenim POLLIN-om -- ali sledeći snd_pcm_avail() je "
 "vratio 0 ili neku drugu vrednost manju od min_avail."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "Isključeno"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "Reprodukcija visoke tačnosti (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "Snimanje visoke tačnosti (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Dvosmerno telefoniranje (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "PulseAudio zvučni sistem"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
 msgstr "Izlazni uređaji"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
 msgstr "Ulazni uređaji"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
 msgstr "Audio na @HOSTNAME@"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
 msgstr "Ulaz"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
 msgstr "Ulaz priključne stanice"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
 msgstr "Mikrofon priključne stanice"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "Ulaz priključne stanice"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
 msgstr "Linija u"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
 msgstr "Mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "Mikrofon priključne stanice"
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "Mikrofon"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
 msgid "External Microphone"
 msgstr "Spoljni mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
 msgstr "Unutrašnji mikrofon"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
 msgstr "Radio"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
 msgstr "Video"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
 msgstr "Samostalna kontrola pojačanja"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
 msgstr "Bez samostalne kontrole pojačanja"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
 msgstr "Podizanje"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
 msgstr "Bez podizanja"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
 msgstr "Pojačalo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
 msgstr "Bez pojačala"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr "Analogni ulaz"
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "Podizanje"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr "Analogni mikrofon"
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "Bez podizanja"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
-msgstr "Analogna linija u"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "Analogne slušalice"
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr "Analogni radio"
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "Analogni ulaz"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr "Analogni video"
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "Mikrofon priključne stanice"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
 msgstr "Analogni izlaz"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr "Analogne slušalice"
-
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
 msgstr "Analogni izlaz (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "Linija u"
+
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
 msgstr "Analogni mono izlaz"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, c-format
-msgid "%s+%s"
-msgstr "%s+%s"
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "Analogni stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, c-format
-msgid "%s / %s"
-msgstr "%s / %s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Digitalni stereo (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Digitalni stereo (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr "Analogni mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr "Analogni stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
 msgstr "Analogni okružujući 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
 msgstr "Analogni okružujući 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
 msgstr "Analogni okružujući 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr "Analogni okružujući 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr "Analogni okružujući 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr "Analogni okružujući 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr "Analogni okružujući 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
 msgstr "Analogni okružujući 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
 msgstr "Analogni okružujući 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
 msgstr "Analogni okružujući 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr "Analogni okružujući 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr "Digitalni stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "Digitalni okružujući 4.0 (IEC958)"
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Digitalni stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Digitalni okružujući 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Digitalni okružujući 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr "Digitalni stereo (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Digitalni okružujući 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
 msgstr "Dvosmerni analogni mono"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
 msgstr "Dvosmerni analogni stereo"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
 msgstr "Dvosmerni digitalni stereo (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Prazan izlaz"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "Ulaz"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<ime slivnika> sink_properties=<svojstva slivnika> master=<ime "
+"slivnika za filtriranje> format=<format uzorka> rate=<učestanost "
+"diskretizacije> channels=<broj kanala> channel_map=<mapa kanala> plugin=<ime "
+"ladspa dodatka> label=<oznaka ladspa dodatka> control=<spisak ulaznih "
+"kontrolnih vrednosti razdvojenih zarezom>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit nije podržan na ovoj platformi."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "Neuspela funkcija XOpenDisplay()"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Izlaz izvora #%u\n"
+#~ "\tUpravljački program: %s\n"
+#~ "\tPripada modulu: %s\n"
+#~ "\tKlijent: %s\n"
+#~ "\tIzvor: %u\n"
+#~ "\tParametri uzorka: %s\n"
+#~ "\tMapa kanala: %s\n"
+#~ "\tKašnjenje bafera: %0.0f μs\n"
+#~ "\tKašnjenje izvora: %0.0f μs\n"
+#~ "\tNačin diskretizacije: %s\n"
+#~ "\tSvojstva:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [opcije] stat\n"
+#~ "%s [opcije] list\n"
+#~ "%s [opcije] exit\n"
+#~ "%s [opcije] upload-sample IMEDATOTEKE [IME]\n"
+#~ "%s [opcije] play-sample IME [SLIVNIK]\n"
+#~ "%s [opcije] remove-sample IME\n"
+#~ "%s [opcije] move-sink-input ULAZSLIVNIKA SLIVNIK\n"
+#~ "%s [opcije] move-source-output IZLAZIZVORA IZVOR\n"
+#~ "%s [opcije] load-module IME [ARG ...]\n"
+#~ "%s [opcije] unload-module MODUL\n"
+#~ "%s [opcije] suspend-sink SLIVNIK 1|0\n"
+#~ "%s [opcije] suspend-source IZVOR 1|0\n"
+#~ "%s [opcije] set-card-profile KARTICA PROFIL\n"
+#~ "%s [opcije] set-sink-port SLIVNIK PORT\n"
+#~ "%s [opcije] set-source-port IZVOR PORT\n"
+#~ "%s [opcije] set-sink-volume SLIVNIK JAČINA\n"
+#~ "%s [opcije] set-source-volume IZVOR JAČINA\n"
+#~ "%s [opcije] set-sink-input-volume ULAZSLIVNIKA JAČINA\n"
+#~ "%s [opcije] set-sink-mute SLIVNIK 1|0\n"
+#~ "%s [opcije] set-source-mute IZVOR 1|0\n"
+#~ "%s [opcije] set-sink-input-mute ULAZSLIVNIKA 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Prikaži ovu pomoć\n"
+#~ "      --version                         Prikaži verziju\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   Ime servera na koji se treba "
+#~ "povezati\n"
+#~ "  -n, --client-name=IME                 Kako nazvati ovog klijenta na "
+#~ "serveru\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Digitalni okružujući 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Zvučnik za niske frekvencije"
index d08b30e..9740d7e 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -1,44 +1,49 @@
 # Swedish translation for pulseaudio.
 # Copyright (C) 2008 Free Software Foundation, Inc.
 # This file is distributed under the same license as the pulseaudio package.
-# Daniel Nylander <po@danielnylander.se>, 2008.
+# Daniel Nylander <po@danielnylander.se>, 2008, 2012.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2008-09-05 18:24+0100\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:56+0000\n"
 "Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
+"Language: sv\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
-msgid "%s %s"
+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 ""
 
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
-"ms).\n"
+"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 ""
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1220
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -47,143 +52,151 @@ msgid ""
 "to the ALSA developers."
 msgstr ""
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr ""
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr ""
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr ""
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr ""
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr ""
 
-#: ../src/pulsecore/sink.c:2613
+#: ../src/pulsecore/sink.c:3349
 #, fuzzy
-msgid "Internal Audio"
+msgid "Built-in Audio"
 msgstr "Internt fel"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr ""
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr ""
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 #, fuzzy
 msgid "Failed to allocate new dl loader."
 msgstr "Misslyckades med att öppna ljudfil.\n"
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr ""
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "Fick signal %s."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "Avslutar."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "Misslyckades med att hitta användaren \"%s\"."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "Misslyckades med att hitta gruppen \"%s\"."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr ""
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr ""
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "Hemkatalogen för användaren \"%s\" är inte \"%s\", ignorerar."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Misslyckades med att skapa \"%s\": %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr ""
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr ""
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) misslyckades: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr ""
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr ""
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr ""
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -191,156 +204,177 @@ msgstr ""
 "Detta program är inte tänkt att köras som root (såvida inte --system har "
 "angivits)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 #, fuzzy
 msgid "Root privileges required."
 msgstr "Root-behörighet krävs."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start stöds inte för systeminstanser."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr ""
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr ""
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr ""
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "pipe misslyckades: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() misslyckades: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() misslyckades: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr ""
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr ""
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() misslyckades: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Detta är PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr ""
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr ""
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr ""
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr ""
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, c-format
+msgid "Running in VM: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr ""
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr ""
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr ""
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr ""
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr ""
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr ""
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr ""
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr ""
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr ""
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr ""
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr ""
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -350,45 +384,45 @@ msgid ""
 "explanation why system mode is usually a bad idea."
 msgstr ""
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() misslyckades."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr ""
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
 msgstr ""
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() misslyckades."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr ""
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr ""
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr ""
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr ""
 
-#: ../src/daemon/cmdline.c:115
+#: ../src/daemon/cmdline.c:113
 #, c-format
 msgid ""
 "%s [options]\n"
@@ -426,15 +460,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -462,194 +494,196 @@ msgid ""
 "  -n                                    Don't load default script file\n"
 msgstr ""
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize förväntar sig ett booleskt argument"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail förväntar sig ett booleskt argument"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
 msgstr ""
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority förväntar sig ett booleskt argument"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime förväntar sig ett booleskt argument"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading förväntar sig ett booleskt argument"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 #, fuzzy
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit booleskt argument"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file förväntar sig ett booleskt argument"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr ""
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 #, fuzzy
 msgid "--log-time expects boolean argument"
 msgstr "--realtime förväntar sig ett booleskt argument"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 #, fuzzy
 msgid "--log-meta expects boolean argument"
 msgstr "--disallow-exit booleskt argument"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr ""
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system förväntar sig ett booleskt argument"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit förväntar sig ett booleskt argument"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm förväntar sig ett booleskt argument"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Namn: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr ""
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Version: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Beskrivning: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Upphovsman: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Användning: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr ""
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr ""
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Sökväg: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr ""
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "Ogiltig server"
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Misslyckades med att öppna konfigurationsfil: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 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:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr ""
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 #, fuzzy
 msgid "Cleaning up privileges."
 msgstr "Släpper root-behörighet."
@@ -662,6 +696,14 @@ msgstr ""
 msgid "Start the PulseAudio Sound System"
 msgstr ""
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr ""
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr ""
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Mono"
@@ -691,7 +733,7 @@ msgid "Rear Right"
 msgstr "Höger bak"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
+msgid "Subwoofer"
 msgstr ""
 
 #: ../src/pulse/channelmap.c:117
@@ -866,9 +908,10 @@ msgstr ""
 msgid "Top Rear Right"
 msgstr ""
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 #, fuzzy
 msgid "(invalid)"
 msgstr "Ogiltig"
@@ -897,333 +940,350 @@ msgstr ""
 msgid "Surround 7.1"
 msgstr ""
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "OK"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "Åtkomst nekad"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Okänt kommando"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "Ogiltigt argument"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "Entiteten finns"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "Ingen sådan entitet"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "Anslutning nekades"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "Protokollfel"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "Tidsgräns nåddes"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr ""
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "Internt fel"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "Anslutningen terminerad"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr ""
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Ogiltig server"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr ""
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "Felaktigt tillstånd"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Inget data"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr ""
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "För stor"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "Stöds inte"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Okänd felkod"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr ""
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr ""
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr ""
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr ""
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr ""
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr ""
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr ""
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr ""
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr ""
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr ""
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() misslyckades"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_new() misslyckades.\n"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr ""
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Misslyckades med att öppna konfigurationsfilen \"%s\": %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr ""
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr ""
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, fuzzy, c-format
 msgid "Failed to drain stream: %s"
 msgstr "Misslyckades med att hitta användaren \"%s\"."
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr ""
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr ""
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, fuzzy, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s\n"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, fuzzy, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() misslyckades: %s\n"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, fuzzy, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_write() misslyckades: %s\n"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, fuzzy, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() misslyckades: %s\n"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr ""
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, fuzzy, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() misslyckades: %s\n"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 msgstr ""
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr ""
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr ""
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr ""
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, fuzzy, c-format
 msgid "Stream error: %s"
 msgstr "Strömfel: %s\n"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr ""
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr ""
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, fuzzy, c-format
 msgid "Stream underrun.%s"
 msgstr "Strömfel: %s\n"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, fuzzy, c-format
 msgid "Stream overrun.%s"
 msgstr "Strömfel: %s\n"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr ""
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr ""
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "inte "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr ""
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, fuzzy, c-format
 msgid "Connection established.%s"
 msgstr "Anslutning etablerad.\n"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, fuzzy, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() misslyckades: %s\n"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, fuzzy, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() misslyckades: %s\n"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, fuzzy, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() misslyckades: %s\n"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, fuzzy, c-format
 msgid "Connection failure: %s"
 msgstr "Anslutningsfel: %s\n"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 #, fuzzy
 msgid "Got EOF."
 msgstr "Fick filslut.\n"
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, fuzzy, c-format
 msgid "write() failed: %s"
 msgstr "write() misslyckades: %s\n"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 #, fuzzy
 msgid "Got signal, exiting."
 msgstr "Fick signal %s."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, fuzzy, c-format
 msgid "Failed to get latency: %s"
 msgstr "Misslyckades med att få statistik: %s\n"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, fuzzy, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Tid: %0.3f sec; Latens: %0.0f ms  \r"
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, fuzzy, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() misslyckades: %s\n"
 
-#: ../src/utils/pacat.c:609
+#: ../src/utils/pacat.c:653
 #, c-format
 msgid ""
 "%s [options]\n"
@@ -1276,14 +1336,19 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1291,180 +1356,185 @@ msgid ""
 "Linked with libpulse %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, fuzzy, c-format
 msgid "Invalid client name '%s'"
 msgstr "Ogiltig server"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, fuzzy, c-format
 msgid "Invalid stream name '%s'"
 msgstr "Ogiltig server"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, fuzzy, c-format
 msgid "Invalid channel map '%s'"
 msgstr "Ogiltig server"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr ""
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, fuzzy, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "Ogiltig server"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, fuzzy, c-format
 msgid "Invalid property '%s'"
 msgstr "Ogiltig server"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr ""
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 #, fuzzy
 msgid "Invalid sample specification"
 msgstr "Misslyckades med att få modulinformation: %s\n"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, fuzzy, c-format
 msgid "open(): %s"
 msgstr "open(): %s\n"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, fuzzy, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s\n"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 #, fuzzy
 msgid "Too many arguments."
 msgstr "För många argument.\n"
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 #, fuzzy
 msgid "Failed to generate sample specification for file."
 msgstr "Misslyckades med att få modulinformation: %s\n"
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 #, fuzzy
 msgid "Failed to open audio file."
 msgstr "Misslyckades med att öppna ljudfil.\n"
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
 msgstr ""
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 #, fuzzy
 msgid "Failed to determine sample specification from file."
 msgstr "Misslyckades med att få modulinformation: %s\n"
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr ""
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 #, fuzzy
 msgid "Channel map doesn't match sample specification"
 msgstr "Misslyckades med att få modulinformation: %s\n"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr ""
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr ""
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr ""
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr ""
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "Misslyckades med att tolka kommandorad.\n"
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 #, fuzzy
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() misslyckades.\n"
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 #, fuzzy
 msgid "io_new() failed."
 msgstr "io_new() misslyckades.\n"
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 #, fuzzy
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() misslyckades.\n"
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, fuzzy, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_new() misslyckades.\n"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 #, fuzzy
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_new() misslyckades.\n"
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 #, fuzzy
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() misslyckades.\n"
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr ""
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr ""
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr ""
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Anslutningsfel: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr ""
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr ""
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1502,35 +1572,46 @@ msgstr "pa_context_new() misslyckades.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() misslyckades.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, fuzzy, c-format
 msgid "Failed to get statistics: %s"
 msgstr "Misslyckades med att få statistik: %s\n"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, fuzzy, c-format
 msgid "Failed to get server information: %s"
 msgstr "Misslyckades med att få modulinformation: %s\n"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1538,15 +1619,15 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, fuzzy, c-format
 msgid "Failed to get sink information: %s"
 msgstr "Misslyckades med att få klientinformation: %s\n"
 
-#: ../src/utils/pactl.c:221
+#: ../src/utils/pactl.c:270
 #, c-format
 msgid ""
 "Sink #%u\n"
@@ -1563,27 +1644,32 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, fuzzy, c-format
 msgid "\tActive Port: %s\n"
 msgstr "pipe misslyckades: %s"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, c-format
+msgid "\tFormats:\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, fuzzy, c-format
 msgid "Failed to get source information: %s"
 msgstr "Misslyckades med att få modulinformation: %s\n"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1605,20 +1691,20 @@ msgid ""
 "\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr ""
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, fuzzy, c-format
 msgid "Failed to get module information: %s"
 msgstr "Misslyckades med att få modulinformation: %s\n"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1629,12 +1715,12 @@ msgid ""
 "\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, fuzzy, c-format
 msgid "Failed to get client information: %s"
 msgstr "Misslyckades med att få klientinformation: %s\n"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1644,12 +1730,12 @@ msgid ""
 "\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, fuzzy, c-format
 msgid "Failed to get card information: %s"
 msgstr "Misslyckades med att få modulinformation: %s\n"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1660,22 +1746,22 @@ msgid ""
 "\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, fuzzy, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "pipe misslyckades: %s"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, fuzzy, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "Misslyckades med att få klientinformation: %s\n"
 
-#: ../src/utils/pactl.c:515
+#: ../src/utils/pactl.c:622
 #, c-format
 msgid ""
 "Sink Input #%u\n"
@@ -1685,6 +1771,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1696,12 +1783,12 @@ msgid ""
 "\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, fuzzy, c-format
 msgid "Failed to get source output information: %s"
 msgstr "Misslyckades med att få modulinformation: %s\n"
 
-#: ../src/utils/pactl.c:574
+#: ../src/utils/pactl.c:693
 #, c-format
 msgid ""
 "Source Output #%u\n"
@@ -1711,6 +1798,11 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
@@ -1718,12 +1810,12 @@ msgid ""
 "\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, fuzzy, c-format
 msgid "Failed to get sample information: %s"
 msgstr "Misslyckades med att få modulinformation: %s\n"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1741,49 +1833,166 @@ msgid ""
 "\t\t%s\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, fuzzy, c-format
 msgid "Failure: %s"
 msgstr "Fel: %s\n"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Misslyckades med att få modulinformation: %s\n"
+
+#: ../src/utils/pactl.c:954
 #, fuzzy, c-format
 msgid "Failed to upload sample: %s"
 msgstr "Misslyckades med att hitta användaren \"%s\"."
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr ""
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr "sink"
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr "källa"
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+#, fuzzy
+msgid "source-output"
+msgstr "källa"
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "Ogiltig server"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 #, fuzzy
 msgid "Got SIGINT, exiting."
 msgstr "Fick signal %s."
 
-#: ../src/utils/pactl.c:869
+#: ../src/utils/pactl.c:1285
+#, fuzzy
+msgid "Invalid volume specification"
+msgstr "Misslyckades med att få modulinformation: %s\n"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
 #, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -1794,7 +2003,7 @@ msgid ""
 "server\n"
 msgstr ""
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -1805,108 +2014,136 @@ msgstr ""
 "Kompilerad med libpulse %s\n"
 "Länkad med libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr ""
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 #, fuzzy
 msgid "Failed to open sound file."
 msgstr "Misslyckades med att öppna ljudfil.\n"
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 #, fuzzy
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "Misslyckades med att få modulinformation: %s\n"
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr ""
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr ""
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr ""
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr ""
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr ""
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr ""
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr ""
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr ""
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr ""
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr ""
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr ""
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-#, fuzzy
-msgid "Invalid volume specification"
-msgstr "Misslyckades med att få modulinformation: %s\n"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr ""
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr ""
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr ""
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+msgid "You have to specify a source output index and a volume"
+msgstr ""
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "källa"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr ""
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "Misslyckades med att få modulinformation: %s\n"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr ""
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr ""
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 #, fuzzy
 msgid "Invalid sink input index specification"
 msgstr "Misslyckades med att få modulinformation: %s\n"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+msgid "You have to specify a source output index and a mute boolean"
+msgstr ""
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "Misslyckades med att få modulinformation: %s\n"
+
+#: ../src/utils/pactl.c:1756
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr ""
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr ""
 
@@ -1927,103 +2164,103 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "Misslyckades med att tolka kommandorad.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Server: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Källa: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Sink: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Kaka: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr ""
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Ännu inte implementerad.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr ""
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr ""
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr ""
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr ""
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, fuzzy, c-format
 msgid "poll(): %s"
 msgstr "fork(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2034,7 +2271,7 @@ msgid ""
 "returned 0 or another value < min_avail."
 msgstr ""
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2045,233 +2282,350 @@ msgid ""
 "returned 0 or another value < min_avail."
 msgstr ""
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr ""
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr ""
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr ""
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr ""
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr ""
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
 msgstr ""
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
 msgstr ""
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
+msgstr "Internt fel"
+
+#: ../src/modules/alsa/alsa-mixer.c:2222
+msgid "Docking Station Line In"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "Internt fel"
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "Internt fel"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
 msgid "External Microphone"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 #, fuzzy
 msgid "Internal Microphone"
 msgstr "Internt fel"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
+#: ../src/modules/alsa/alsa-mixer.c:2237
+msgid "Bass Boost"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2238
+msgid "No Bass Boost"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
+#: ../src/modules/alsa/alsa-mixer.c:2313
+msgid "Line Out"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, c-format
-msgid "%s+%s"
+#: ../src/modules/alsa/alsa-mixer.c:2315
+msgid "Speakers"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, c-format
-msgid "%s / %s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2317
+msgid "Digital Output (S/PDIF)"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:2318
+msgid "Digital Passthrough (S/PDIF)"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
+#: ../src/modules/alsa/alsa-mixer.c:3770
+msgid "Digital Passthrough  (IEC958)"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
 msgstr ""
 
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, c-format
+msgid "%s Output"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, c-format
+msgid "%s Input"
+msgstr ""
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "Användning: %s\n"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() misslyckades"
+
 #~ msgid "select(): %s"
 #~ msgstr "select(): %s"
 
@@ -2313,11 +2667,5 @@ msgstr ""
 #~ msgid "muted"
 #~ msgstr "tystad"
 
-#~ msgid "sink"
-#~ msgstr "sink"
-
-#~ msgid "source"
-#~ msgstr "källa"
-
 #~ msgid "socketpair(): %s"
 #~ msgstr "socketpair(): %s"
index 000b559..d8c8363 100644 (file)
--- a/po/ta.po
+++ b/po/ta.po
@@ -1,16 +1,17 @@
 # translation of pulseaudio.master-tx.ta.po to Tamil
 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the PACKAGE package.
+# I. Felix <ifelix@redhat.com>, 2009, 2012.
 #
-# I. Felix <ifelix@redhat.com>, 2009.
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx.ta\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-09-18 13:43+0530\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:56+0000\n"
 "Last-Translator: I. Felix <ifelix@redhat.com>\n"
 "Language-Team: Tamil <fedora-trans-ta@redhat.com>\n"
+"Language: ta\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -37,13 +38,9 @@ msgstr ""
 "\n"
 "\n"
 "\n"
+"\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -56,20 +53,33 @@ msgstr ""
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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."
+
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"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."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -82,301 +92,331 @@ msgstr ""
 "Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
 "to the ALSA developers."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "ஒரு பூஜ்ஜியம் இருந்தாலும் குறைந்தது ஒன்றை மட்டும் வைத்திருக்கவும்"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "டம்மி வெளிப்பாடு"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "மெய்நிகர் LADSPA சின்க்"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<name for the sink> sink_properties=<properties for the sink> "
 "master=<name of sink to filter> format=<sample format> rate=<sample rate> "
 "channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
+"plugin name> label=<ladspa plugin label> control=<comma separated list of "
 "input control values>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "கடிகார பூஜ்ஜிய சிங்"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "பூஜ்ஜிய வெளிப்பாடு"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "உட்புற ஆடியோ"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "மாதிரி"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "அசல் lt_dlopen ஏற்றியை காண முடியவில்லை."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "புதிய dl ஏற்றுபவரை ஒதுக்கிருவதில் தோல்வி."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "இப்போது பிணைக்கும் ஏற்பியை சேர்ப்பதில் தோல்வி."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "%sக்கு சிக்னல் கிடைத்துவிட்டது."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "வெளியேறுதல்."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "'%s' பயனரை கண்டுபிடிப்பதில் தோல்வி."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "'%s' குழுவை கண்டுபிடிப்பதில் தோல்வி."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "'%s'பயனர் கண்டுபிடிக்கப்பட்டார் (UID %lu) மற்றும் குழு '%s' (GID %lu)."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "GID ன் பயனர் '%s' மற்றும் '%s' குழுவுடன் ஒத்து போகவில்லை."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "முகப்பு அடைவு பயனரான'%s' '%s'ஆல், புறக்கணிக்கப்படவில்லை."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "'%s'ஐ உருவாக்க முடியவில்லை: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "குழுப் பட்டியலை மாற்ற முடியவில்லை: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "GIDக்கு மாற்றுவதில் தோல்வி: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "UIDக்கு மாற்றுவதில் தோல்வி: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "ரூட் முன்னுரிமைகள் வெற்றிகரமாக விடப்பட்டது."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "இந்த தளத்தில் கணினியின் திறந்த முறைமை துணைபுரியவில்லை."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) தோல்வியுற்றது: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "கட்டளை வரியை மாற்றுவதில் தோல்வி."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "டோமோன் இயங்கவில்லை"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "PID %uவாக டோமோன் இயங்குகிறது"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "டோமோனுக்கு முடிவு கட்டுவதில் தோல்வி: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
 msgstr "இந்த நிரல் ரூட்டாக இயங்க முடியவில்லை (--system குறிப்பிடாத வரை)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "ரூட் முன்னுரிமைகள் தேவைப்படுகிறது."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start கணினி நிகழ்வில் துணைபுரியவில்லை."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "கணினி முறைமையில் இயங்குகிறது, ஆனால் --disallow-exit அமைக்கப்படவில்லை!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
 "கணினி முறைமையில் இயங்குகிறது, ஆனால் --disallow-module-loading அமைக்கப்படவில்லை!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "கணினி முறைமையில் இயங்குகிறது, SHM முறைமை செயல்நீக்குதல் கட்டாயப்படுத்துகிறது!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr "கணினி முறைமையில் இயங்குகிறது, வெறுமை நேரத்தை செயல்நீக்க கட்டாயப்படுத்துகிறது!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "stdioஐ பெற முடியவில்லை."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "பைப் தோல்வியுற்றது: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() தோல்வியுற்றது: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "வாசிப்பதில்() தோல்வியுற்றது: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "டோமோனை துவக்குவதில் தோல்வியுற்றது."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "டோமோனை வெற்றிகரமாக துவக்ககப்பட்டது."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "வாசிப்பதில்() தோல்வியுற்றது: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "இது தான் பள்ஸ் ஆடியோ %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "தொகுக்கப்பட்ட புரவலன்: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "தொகுப்பு CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "புரவலனாக இயங்குகிறத: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "CPUs %uவில் காணப்படுகிறது ."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "பக்க அளவுகள் %lu பைட்ஸ்"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Compiled with Valgrind support: yes"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Compiled with Valgrind support: no"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "valgrind முறைமையில் இயங்குகிறது: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "புரவலனாக இயங்குகிறத: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "Optimized build: yes"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "சுருக்கமான உருவாக்கம்: இல்லை"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG வரையறுக்கப்பட்டது, அனைத்தும் உறுதியாக செயல்நீக்கப்பட்டது."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH வரையறுக்கப்பட்டது, விரைவு பாதை மட்டும் உறுதியாக செயல்நீக்கப்பட்டது."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "அனைத்து உறுதியாக செயல்படுகிறது."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "கணினி குறியீடை பெறுவதில் தோல்வி"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "கணினி குறியீடு %s."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "அமர்வு குறியீடு %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "ஓடும்நேரம்  %s அடைவை பயன்படுத்துகிறது."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "%s நிலை அடைவினை பயன்படுத்துகிறது."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "தொகுதி %s அடைவை பயன்படுத்துகிறது."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "கணினியின் முறைமையில் இயங்குகிறது: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -392,15 +432,15 @@ msgstr ""
 "Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an "
 "explanation why system mode is usually a bad idea."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() தோல்வியுற்றது."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "உயர்ந்த திரைத்திறன் நேரம்காட்டி கிடைக்கிளது! Bon appetit!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -408,32 +448,32 @@ msgstr ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() தோல்வியுற்றது."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "டோமோனை ஆரம்பிப்பதில் தோல்வி."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "டீமான் துவக்கம் எந்த தொகுதிகளும் ஏற்றப்படாமல், வேலையை நிராகரிக்கிறது."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "டோமோன் துவக்குவது முடிவடைந்தது."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "டோமோன் பணிநிறுத்தம் முனைகிறது."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "டோமோன் நீக்கப்பட்டுது."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -470,15 +510,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -575,15 +613,15 @@ msgstr ""
 "\n"
 "  -n                                    Don't load default script file\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize பூலியன் அளவுரு எதிர்பார்க்கிறது"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail பூலியன் அளவுரு எதிர்பார்க்கிறது"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -591,166 +629,169 @@ msgstr ""
 "--log-level பதிவு நிலை அளவுருவை எதிர்பார்க்கிறது (எண் 0..4 அல்லது debug, info, "
 "notice, warn, errorஇல் ஒன்று)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority பூலியன் அளவுரு எதிர்பார்க்கிறது"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime பூலியன் அளவுரு எதிர்பார்க்கிறது"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading பூலியன் அளவுரு எதிர்பார்க்கிறது"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit பூலியன் அளவுரு எதிர்பார்க்கிறது"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file பூலியன் அளவுரு எதிர்பார்க்கிறது"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr "தவறான பதிவு இலக்கு: 'syslog', 'stderr' அல்லது 'auto'ஐ பயன்படுத்தவும்."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time பூலியன் அளவுரு எதிர்பார்க்கிறது"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta பூலியன் அளவுரு எதிர்பார்க்கிறது"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "தவறான மறுமாதிரி முறை '%s'."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system பூலியன் அளவுரு எதிர்பார்க்கிறது"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit பூலியன் அளவுரு எதிர்பார்க்கிறது"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm பூலியன் அளவுரு எதிர்பார்க்கிறது"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "பெயர்: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "தொகுதி தகவல் கிடைக்கப் பெறவில்லை\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "பதிப்பு: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "விளக்கம்: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "ஆசிரியர்: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "பயன்பாடு: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "ஒருமுறை ஏற்றப்பட்டது: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "DEPRECATION WARNING: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "பாதை: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] தவறான பதிவு இலக்கு '%s'."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] தவறான பதிவு இலக்கு '%s'."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] தவறான மறுமாதிரி முறை '%s'."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] தவறான rlimit '%s'."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit இந்த தளத்தில் துணைபுரியவில்லை."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] தவறான மாதிரி முறை '%s'."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] தவறான மாதிரி விலை '%s'."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] தவறான மாதிரி சேனல்கள் '%s'."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] தவறான சேனல் படம் '%s'."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] பகுப்பு '%s'க்கு தவறான எண்"
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] தவறான பகுப்பு அளவு '%s'."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] தவறான நல்ல நிலை '%s'."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] தவறான மாதிரி விலை '%s'."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "கட்டமைக்கப்பட்ட கோப்பினை திறப்பதில் தோல்வி: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -758,12 +799,12 @@ msgstr ""
 "குறிப்பிட்ட முன்னிருப்பு சேனல் மேப் வேறுபட்ட சேனல்களின் எண்ணிக்கையை குறிப்பிட்ட "
 "முன்னிருப்பு சேனல்களின் எண்ணிக்கையை விட கொண்டுள்ளது"
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### கட்டமைப்பு கோப்பிலிருந்து வாசிக்கவும்: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "முன்னுரிமைகளை துடைக்கிறது."
 
@@ -775,6 +816,16 @@ msgstr "பள்ஸ் ஆடியோ ஒலி கணினி"
 msgid "Start the PulseAudio Sound System"
 msgstr "பள்ஸ் ஆடியோ ஒலி கணினியை துவக்கவும"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "பள்ஸ் ஆடியோ ஒலி கணினி"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "பள்ஸ் ஆடியோ ஒலி கணினியை துவக்கவும"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "மோனோ"
@@ -804,8 +855,8 @@ msgid "Rear Right"
 msgstr "பின் வலது"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "குறைந்த அலைவரிசை எம்மிட்டர்"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -979,9 +1030,10 @@ msgstr "மேலே பின் இடது"
 msgid "Top Rear Right"
 msgstr "மேலே பின் வலது"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(தவறான)"
 
@@ -1009,332 +1061,349 @@ msgstr "Surround 5.1"
 msgid "Surround 7.1"
 msgstr "Surround 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "சரி"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "அணுகல் மறுக்கப்பட்டது"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "தெரியாத கட்டளை"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "தவறான விவாதம்"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "உருப்படி உள்ளது"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "உருப்படி எதுவும் இல்லை"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "இணைப்பு மறுக்கப்பட்டது"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "அறிக்கை பிழை"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "நேரம் முடிவுற்றது"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "அங்கீகார விசை இல்லை"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "உட்புற பிழை"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "இணைப்பு துண்டிக்கப்பட்டது"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "உருப்படி நீக்கப்பட்டது"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "தவறான புரவலன்"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "தொகுதியை துவக்க முடியவில்லை"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "தவறான நிலை"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "தரவு இல்லை"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "நெறிமுறை பதிப்பு உகந்ததல்ல"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "மிகப் பெரியது"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "துணைப்புரியாத"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "தெரியாத பிழைக் குறியீடு"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "இது போன்ற தொடர்ச்சி இல்லை"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "நீக்கப்படும் செயல்பாடு"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "விடுபட்ட செயல்பாடு"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "கிளையன் நீக்கப்பட்டது"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "உள்ளீடு/வெளிப்பாடு பிழை"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "சாதனம் அல்லது மூலம் பணிமிகுதியில்"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenகாட்சி() தோல்வியுற்றது"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() தோல்வி: %s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "குக்கீ தரவை மாற்றுவதில் தோல்வியுற்றது"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "'%s'கட்டமைக்கப்பட்ட கோப்பினை திறக்க முடியவில்லை: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "குக்கி ஏற்றப்படவில்லை. இணைப்பில்லாமல் முயற்சிக்கிறது."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "தெரியாத தொடரிச்சியிலிருந்து '%s'க்கு செய்திகள் பெறப்பட்டன"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "ஸ்டீரிமை இழக்க முடியவில்லை: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "பின்னணி ஸ்டீரிம் இழக்கப்படுகிறது."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "சேவையகத்திற்கு இணைப்பு இழக்கப்படுகிறது."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() தோல்வியுற்றது: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_write() தோல்வியுற்றது: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() தோல்வியுற்றது: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "ஸ்டிரீம் வெற்றிகரமாக உருவாக்கப்பட்டது."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() தோல்வியுற்றது: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 msgstr "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Buffer metrics: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "குறிப்பிட்ட குறிப்பு '%s', சேனல் வரைபடத்தை '%s'ஐ பயன்படுத்துகிறது."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "%s சாதனத்துடன் இணைக்கப்பட்டது (%u, %ssuspended)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "ஸ்டிரீம் பிழை: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "ஸ்டீரிம் சாதனம் இடைநீக்கப்பட்டது.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "ஸ்டீரிம் சாதனம் தொடர்கிறது.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "ஸ்டீரிம் இயங்குகிறது.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "ஸ்டீரிம் அதிகளவு இயங்கியது.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "ஸ்டிரீம் %s துவக்கப்பட்டது"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "ஸ்டிரீம் %s சாதனத்திற்கு நகர்ந்தது (%u, %ssuspended).%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "இல்லை"
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "ஸ்டீரிம் ஃபப்பர் பண்புகளை மாற்றப்பட்டது.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "இணைப்பு துவக்கப்பட்டது.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() தோல்வியுற்றது: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() தோல்வியுற்றது: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() தோல்வியுற்றது: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "இணைப்பதில் தோல்வி: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "EOF கிடைக்கப் பெற்றது"
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "எழுதுவதில் () தோல்வியுற்றது: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "சிக்னல் கிடைத்தது, வெளியேறுகிறது."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "லடன்சியை பெற முடியவில்லை: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Time: %0.3f sec; Latency: %0.0f usec."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() தோல்வி: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1386,10 +1455,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [options]\n"
@@ -1448,7 +1522,7 @@ msgstr ""
 "      --file-format=FFORMAT             Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1459,171 +1533,176 @@ msgstr ""
 "Compiled with libpulse %s\n"
 "Linked with libpulse %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "தவறான கிளையன் பெயர் '%s'"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "தவறான ஸ்டீரீம் பெயர் '%s'."
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "தவறான சேனல் வரைபடம் '%s'"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "தவறான லேடன்சி குறிப்பீடு '%s'"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "தவறான செயல் நேர குறிப்பீடு '%s'"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "தவறான தன்மை '%s'."
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "தெரியாத கோப்பு வடிவம் %s."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "தவறான மாதிரி குறிப்பீடு"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "நிறைய விவாதங்கள்."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "மாதிரி தகவலை பெற முடியவில்லை.: %s"
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "ஒலி கோப்பினை திறக்க முடியவில்லை."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
 msgstr ""
 "எச்சரிக்கை: கோப்பிலிருந்து குறிப்பீட்டுடன் குறிக்கிட்ட மாதிரி குறிப்பீடு மேலெழுதப்படலாம்."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "கோப்பிலிருந்து மாதிரி குறிப்பீட்டை  வரையறுக்க முடியவில்லை."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "எச்சரிக்கை: கோப்பிலிருந்து சேனல் வரைபடத்தை வரையறுக்க முடியவில்லை."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "சேனல் வரைபடம் மாதிரி குறிப்பீட்டுடன் பொருந்தவில்லை"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "எச்சரிக்கை: கோப்புக்கு சேனல் வரைபடத்தை எழுத முடியவில்லை."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr ""
 "ஒரு %s ஸ்டீரம் மாதிரி குறிப்பீட்டை '%s' மற்றும் சேனல் வரைபட்டம் '%s' உடன் திறக்கிறது."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "ஒலிப்பதிவு"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "பிண்ணனி"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "கட்டளை வரியை மாற்றுவதில் தோல்வி."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() தோல்வி."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() தோல்வியுற்றது."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() தோல்வி."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() தோல்வி: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_rttime_new() தோல்வியுற்றது."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() தோல்வி."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "நீக்க முடியவில்லை: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "தொடர முடியவில்லை: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "எச்சரிக்கை: ஒலி சேவையம் உள்ளமைவாக இல்லை, இடைநிறுத்தப்படவில்லை.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "இணைப்பதில் தோல்வி: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "SIGINT பெறப்பட்டது, வெளியேறுகிறது.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "எச்சரிக்கை: சேய் செயல் சிக்னல் %uஆல் முடிக்கப்பட்டது\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1667,36 +1746,47 @@ msgstr "pa_context_new() தோல்வி.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() தோல்வி.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "புள்ளிவிவரத்தை பெற முடியவில்லை: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "தற்போது பயனிலுள்ளது: %u தொகுதிகள் %s பைட்களை மொத்தமாக கொண்டுள்ளது.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr ""
 "வாழ்க்கை முழுவதும் ஒதுக்கப்பட்டது: %u தொகுதிகள் %s பைட்களை மொத்தமாக கொண்டுள்ளது.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "மாதிரி இடையக அளவு: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "சேவையகத்தின் தகவலை பெற முடியவில்லை: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1704,7 +1794,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "பயனர் பெயர்: %s\n"
 "புரவலன் பெயர்: %s\n"
@@ -1716,13 +1806,13 @@ msgstr ""
 "முன்னிருப்பு மூலங்கள்: %s\n"
 "கூக்கி: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "சுருக்கமான தகவலை பெறு முடியவில்லை: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1738,7 +1828,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1760,22 +1850,27 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tPorts:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tசெயல்பாட்டிலுள்ள விவரக்குறிப்புகள்: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tPorts:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "மூலத்தின் தகவலை பெற இயலவில்லை: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1814,20 +1909,20 @@ msgstr ""
 "\tபண்புகள்:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "n/a"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "தொகுதி தகவலை பெற முடியவில்லை: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1844,12 +1939,12 @@ msgstr ""
 "\tபண்புகள்:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "கிளையன்ட் தகவலை பெற முடியவில்லை: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1864,12 +1959,12 @@ msgstr ""
 "\tபண்புகள்:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "அட்டை தகவலை பெற முடியவில்லை: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1886,23 +1981,23 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tவிவரக்குறிப்புகள்:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tசெயல்பாட்டிலுள்ள விவரக்குறிப்புகள்: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "சிங்க் தகவலை பெற முடியவில்லை: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1911,6 +2006,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1938,13 +2034,13 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "மூல வெளிப்பாடு தகவலை பெற முடியவில்லை: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1953,31 +2049,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Source Output #%u\n"
+"Sink Input #%u\n"
 "\tDriver: %s\n"
 "\tOwner Module: %s\n"
 "\tClient: %s\n"
-"\tSource: %u\n"
+"\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
-"\tSource Latency: %0.0f usec\n"
+"\tSink Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "மாதிரி தகவலை பெற முடியவில்லை.: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -2008,48 +2113,163 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "தோல்வி: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "மூலத்தின் தகவலை பெற இயலவில்லை: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "மாதிரியை மேம்படுத்த முடியவில்லை: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "முன்னாக கோப்பு முடித்தல்"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "தவறான புரவலன்"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "SIGINT பெறப்பட்டது, வெளியேறுகிறது."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "தவறான தொகுதி குறிப்பீடு"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2059,37 +2279,14 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+"%s [விருப்பங்கள்] ... \n"
 "\n"
-"  -h, --help                            Show this help\n"
-"      --version                         Show version\n"
+"  -h, --உதவி                            இந்த உதவியை காட்டு\n"
+"      --பதிப்பு                         பதிப்பினைக் காட்டு\n"
+"  -s, --சேவையகம்=SERVER                   பெயரிடப்பட்ட சேவையகம் இணைக்கப்பட வேண்டும்\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect "
-"to\n"
-"  -n, --client-name=NAME                How to call this client on the "
-"server\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2100,106 +2297,138 @@ msgstr ""
 "Compiled with libpulse %s\n"
 "Linked with libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "ஏற்றுவதற்கு ஒரு மாதிரி கோப்பினை குறிப்பிடவும்"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "ஒலி கோப்பினை திறக்க முடியவில்லை."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "எச்சரிக்கை: கோப்பிலிருந்து மாதிரி குறிப்பீட்டை வரையறுக்க முடியவில்லை."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "இயக்கிவதற்கு நீங்கள் ஒரு மாதிரி பெயர் குறிப்பிட வேண்டும்"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "நீக்குவதற்கு நீங்கள் ஒரு மாதிரி பெயர் குறிப்பிட வேண்டும்"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "நீங்கள் ஒரு சிங்க் உள்ளீடு சுட்டி மற்றும் ஒரு சிங்கை குறிப்பிட வேண்டும்"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "நீங்கள் ஒரு மூல வெளிப்பாடு சுட்டி மற்றும் ஒரு மூலத்தை குறிப்பிட வேண்டும்"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "தொகுதி பெயர் மற்றும் விவாதங்களை நீங்கள் குறிப்பிட வேண்டும்."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "தொகுதி அட்டவணையை நீங்கள் குறிப்பிட வேண்டும்"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "ஒரு சிங்கிற்கு மேல் நீங்கள் குறிப்பிடக் கூடாது. பூலியன் மதிப்பை நீங்கள் குறிப்பிட வேண்டும்."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr ""
 "ஒரு மூலத்திற்கு மேல் நீங்கள் குறிப்பிடக் கூடாது. பூலியன் மதிப்பை நீங்கள் குறிப்பிட வேண்டும்."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "ஒரு அட்டை பெயர்/ முன்பக்கம் மற்றும் ஒரு விவரச்சீட்டு பெயர் நீங்கள் குறிப்பிட வேண்டும்"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "நீங்கள் ஒரு சிங்க் பெயர்/ முன்பக்கம் மற்றும் ஒரு துறைப் பெயரை குறிப்பிட வேண்டும்"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "ஒரு மூலப் பெயர்/ முன்பக்கம் மற்றும் ஒரு துறைப் பெயர் நீங்கள் குறிப்பிட வேண்டும்"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "நீங்கள் ஒரு சிங்க் பெயர்/ முன்பக்கம் மற்றும் ஒரு துறைப் பெயரை குறிப்பிட வேண்டும்"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "தவறான தொகுதி குறிப்பீடு"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "ஒரு மூலப் பெயர்/ முன்பக்கம் மற்றும் ஒரு துறைப் பெயர் நீங்கள் குறிப்பிட வேண்டும்"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "நீங்கள் ஒரு சிங்க் உள்ளீடு சுட்டி மற்றும் ஒரு சிங்கை குறிப்பிட வேண்டும்"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "தவறான சுருக்க உள்ளீடு அட்டவணை"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "நீங்கள் ஒரு மூல வெளிப்பாடு சுட்டி மற்றும் ஒரு மூலத்தை குறிப்பிட வேண்டும்"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "தவறான சுருக்க உள்ளீடு அட்டவணை"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "நீங்கள் ஒரு சிங்க் பெயர்/ முன்பக்கம் மற்றும் ஒரு துறைப் பெயரை குறிப்பிட வேண்டும்"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "தவறான மாதிரி குறிப்பீடு"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "ஒரு மூலப் பெயர்/ முன்பக்கம் மற்றும் ஒரு துறைப் பெயர் நீங்கள் குறிப்பிட வேண்டும்"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "நீங்கள் ஒரு சிங்க் உள்ளீடு சுட்டி மற்றும் ஒரு சிங்கை குறிப்பிட வேண்டும்"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "தவறான சுருக்க உள்ளீடு அட்டவணை குறிப்பீடு"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "ஒரு மூலப் பெயர்/ முன்பக்கம் மற்றும் ஒரு துறைப் பெயர் நீங்கள் குறிப்பிட வேண்டும்"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "தவறான சுருக்க உள்ளீடு அட்டவணை குறிப்பீடு"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "நீங்கள் ஒரு சிங்க் பெயர்/ முன்பக்கம் மற்றும் ஒரு துறைப் பெயரை குறிப்பிட வேண்டும்"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "சரியான கட்டளை குறிப்பிடபடவில்லை"
 
@@ -2227,103 +2456,103 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "கட்டளை வரியை மாற்ற முடியவில்லை \n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "சேவையகம்: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "மூலம்: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "சுருங்குதல்: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "கூக்கீ: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "குக்கீ தரவை மாற்ற முடியவில்லை\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "குக்கீ தரவை சேமிக்க முடியவில்லை\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "கிளையன்ட் கட்டமைப்பு கோப்பினை ஏற்ற முடியவில்லை.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "சுற்றுப்புற கட்டமைப்பு தரவினை வாணிக்க முடியவில்லை.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "FQDNஐ பெற முடியவில்லை.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "குக்கீ தரவை ஏற்ற முடியவில்லை\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "இன்னும் செயல்படுத்தபடவில்லை.\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr "PulseAudio டீமான் இயங்கவில்லை, அல்லது அமர்வு டீமானாக இயங்கவில்லை."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "PulseAudio daemonஐ நிறுத்த முடியவில்லை."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "டோமோன் பதிலளிக்க மறுக்கிறது."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "autospawn பூட்டை அணுக முடியவில்லை."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2340,7 +2569,7 @@ msgstr ""
 "POLLOUT அமைவுடன் நாங்கள் எழுந்திருந்தோம்-- எப்படியிருந்தும் அடுத்தடுத்து snd_pcm_avail"
 "() r0 அல்லது வேறொரு மதிப்பு < min_avail திரும்பியது."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2357,242 +2586,465 @@ msgstr ""
 "POLLOUT அமைவுடன் நாங்கள் எழுந்திருந்தோம்-- எப்படியிருந்தும் அடுத்தடுத்து snd_pcm_avail"
 "() 0 அல்லது வேறொரு மதிப்பு < min_avail திரும்பியது."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "ஆஃப்"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "High Fidelity Playback (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "High Fidelity Capture (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Telephony Duplex (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "PulseAudio ஒலி சேவையகம்"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
-msgstr ""
+msgstr "வெளிப்பாடு சாதனங்கள்"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
-msgstr ""
+msgstr "உள்ளீடு சாதனங்கள்"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
-msgstr ""
+msgstr "@HOSTNAME@இல் ஆடியோ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
-msgstr ""
+msgstr "உள்ளீடு"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
-msgstr ""
+msgstr "டாக்கிங் ஸ்டேஷன் உள்ளீடு"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
-msgstr ""
+msgstr "டாக்கிங் ஸ்டேஷன் மைக்ரோஃபோன்"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "டாக்கிங் ஸ்டேஷன் உள்ளீடு"
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "லைன்இன்"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
-msgstr ""
+msgstr "மைக்ரோஃபோன்"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
-msgid "External Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "டாக்கிங் ஸ்டேஷன் மைக்ரோஃபோன்"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
 #, fuzzy
+msgid "Rear Microphone"
+msgstr "மைக்ரோஃபோன்"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "வெளியார்ந்த மைக்ரோஃபோன்"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
-msgstr "à®\89à®\9fà¯\8dபà¯\81à®± à®\86à®\9fியà¯\8b"
+msgstr "à®\89à®\9fà¯\8dபà¯\81à®± à®®à¯\88à®\95à¯\8dà®°à¯\8bà®\83பà¯\8bனà¯\8d"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
-msgstr ""
+msgstr "ரேடியோ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
-msgstr ""
+msgstr "வீடியோ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
-msgstr ""
+msgstr "தானியக்க லாப கட்டுப்பாடு"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
-msgstr ""
+msgstr "தானியக்க லாப கட்டுப்பாடு எதுவுமில்லை"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
-msgstr ""
+msgstr "பூஸ்ட்"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
-msgstr ""
+msgstr "பூஸ்ட் இல்லை"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
-msgstr ""
+msgstr "ஆம்பிளிஃபையர்"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
-msgstr ""
+msgstr "ஆம்ப்ளிஃபையர் இல்லை"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "பூஸ்ட்"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "பூஸ்ட் இல்லை"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "அனலாக் ஹெட்ஃபோன்கள்"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "அனலாக் உள்ளிடு"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "டாக்கிங் ஸ்டேஷன் மைக்ரோஃபோன்"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
-msgstr "பà¯\82à®\9cà¯\8dà®\9cிய வெளிப்பாடு"
+msgstr "à®\85னலாà®\95à¯\8d வெளிப்பாடு"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "அனலாக் வெளிப்பாடு (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "லைன்இன்"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
+msgstr "அனலாக் மோனோ வெளிப்பாடு"
+
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "அனலாக் ஸ்டிரியோ"
+
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, fuzzy, c-format
-msgid "%s+%s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "Digital Stereo (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, fuzzy, c-format
-msgid "%s / %s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Digital Stereo (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
-msgstr ""
+msgstr "அனலாக் மோனோ"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
-msgstr "ஸ்டிரியோ"
+msgstr "à®\85னலாà®\95à¯\8d à®¸à¯\8dà®\9fிரியà¯\8b"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
-msgstr "Surround 4.1"
+msgstr "Analog Surround 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
-msgstr "Surround 4.0"
+msgstr "Analog Surround 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
-msgstr "Surround 4.1"
+msgstr "Analog Surround 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
-msgstr "Surround 4.0"
+msgstr "Analog Surround 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
-msgstr "Surround 4.1"
+msgstr "Analog Surround 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
-msgstr "Surround 5.0"
+msgstr "Analog Surround 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
-msgstr "Surround 5.1"
+msgstr "Analog Surround 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
-msgstr "Surround 4.0"
+msgstr "Analog Surround 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
-msgstr "Surround 4.1"
+msgstr "Analog Surround 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
-msgstr "Surround 4.0"
+msgstr "Analog Surround 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
-msgstr "Surround 7.1"
+msgstr "Analog Surround 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
-msgstr ""
+msgstr "Digital Stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "Digital Stereo (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
-msgstr ""
+msgstr "Digital Surround 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
-msgstr ""
+msgstr "Digital Surround 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
-msgstr ""
+msgstr "Digital Stereo (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Digital Surround 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
-msgstr ""
+msgstr "Analog Mono Duplex"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
-msgstr ""
+msgstr "Analog Stereo Duplex"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
+msgstr "Digital Stereo Duplex (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "பூஜ்ஜிய வெளிப்பாடு"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "உள்ளீடு"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
 msgstr ""
+"sink_name=<name for the sink> sink_properties=<properties for the sink> "
+"master=<name of sink to filter> format=<sample format> rate=<sample rate> "
+"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
+"plugin name> label=<ladspa plugin label> control=<comma separated list of "
+"input control values>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit இந்த தளத்தில் துணைபுரியவில்லை."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenகாட்சி() தோல்வியுற்றது"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Digital Surround 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "குறைந்த அலைவரிசை எம்மிட்டர்"
index 31fa09a..dc27706 100644 (file)
--- a/po/te.po
+++ b/po/te.po
@@ -1,16 +1,17 @@
 # translation of pulseaudio.master-tx.te.po to Telugu
 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the PACKAGE package.
+# Krishna Babu K <kkrothap@redhat.com>, 2009, 2012.
 #
-# Krishna Babu K <kkrothap@redhat.com>, 2009.
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx.te\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-09-21 17:28+0530\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:56+0000\n"
 "Last-Translator: Krishna Babu K <kkrothap@redhat.com>\n"
 "Language-Team: Telugu <en@li.org>\n"
+"Language: te\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -23,13 +24,9 @@ msgstr ""
 "\n"
 "\n"
 "\n"
+"\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -41,11 +38,11 @@ msgstr ""
 "సాదారణంగా యిది ALSA డ్రైవర్ '%s' నందలి బగ్ కావచ్చును. దయచేసి దీనిని ALSA అభివృద్ది కారులకు "
 "నివేదించుము."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
@@ -53,7 +50,19 @@ msgstr ""
 "సాదారణంగా యిది ALSA డ్రైవర్ '%s' నందు బగ్ కావచ్చును . దయచేసి దీనిని ALSA అభివృద్దికారులక "
 "నివేదించుము."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() అనునది పెద్ద విలువను యిచ్చినది: %lu bytes (%lu ms).\n"
+"సాదారణంగా యిది ALSA డ్రైవర్ '%s' నందలి బగ్ కావచ్చును. దయచేసి దీనిని ALSA అభివృద్ది కారులకు "
+"నివేదించుము."
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -64,299 +73,329 @@ msgstr ""
 "snd_pcm_mmap_begin() అనునది పెద్ద విలువను యిచ్చినది: %lu bytes (%lu ms).\n"
 "సాదారణంగా యిది ALSA డ్రైవర్ '%s'నందలి బగ్ కావచ్చును. దయచేసి దీనిని ALSA అభివృద్దికారులను నివేదించండి."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr "ఒకవేళ అది null అయినా కూడా యెల్లప్పుడూ కనీసం వొక సింకు లోడైనట్లు వుంచుతుంది"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "డమ్మీ అవుట్పుట్"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
 msgstr "వర్చ్యువల్ LADSPA సింకు"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<సింక్ నామము> sink_properties=<సింకు లక్షణములు> master=<ఫిల్టర్‌కు సింకు "
 "నామము> format=<మాదిరి ఫార్మాట్> rate=<మాదిరి రేటు> channels=<చానల్సు సంఖ్య> "
 "channel_map=<చానల్ మాప్> plugin=<ladspa ప్లగిన్ నామము> label=<ladspa ప్లగిన్ లేబుల్> "
 "control=<ఇన్పుట్ నియంత్రణ విలువలయొక్క జాబితా>"
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "NULL సింక్ క్లాక్‌చేయబడింది"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
 msgstr "Null అవుట్పుట్"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "అంతర్గత ఆడియో"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "మోడెమ్"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "వాస్తవ lt_dlopen లోడర్ కనుగొనుటలో విఫలమైంది."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "కొత్త dl లోడర్ కేటాయించుటలో విఫలమైంది."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "bind-now-loader జతచేయుటకు విఫలమైంది."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "సంకేతము %s పొందినది."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "నిష్క్రమించుచున్నది."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "వినియోగదారి '%s'ను కనుగొనుటకు విఫలమైంది."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "సమూహం '%s' కనుగొనుటకు విఫలమైంది."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "వినియోగదారి '%s' (UID %lu) మరియు సమూహము '%s' (GID %lu) కనబడినవి."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "వినియోగదారి '%s' మరియు సమూహము '%s' యొక్క GID సరితూగలేదు."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "వినియోగదారి '%s' యొక్క నివాస డైరెక్టరీ '%s' కాదు, వదిలివేయుచున్నది."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "'%s' సృష్టించుటకు విఫలమైంది: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "సమూహ జాబితా మార్చుటకు విఫలమైంది: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "GID మార్చుటకు విఫలమైంది: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "UID మార్చటకు విఫలమైంది: %s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "root అనుమతులు విజయవంతంగా తిసివేయబడినాయి."
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "ఈ ప్లాట్‌ఫాం నందు సిస్టమ్ తరహా రీతి మద్దతీయబడదు."
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) విఫలమైంది: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "ఆదేశ వరుసను పార్శ్ చేయుటకు విఫలమైంది."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "డెమోన్ నడుచుట లేదు"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "డెమోన్ PID %u వలె నడుచుచున్నది"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "డెమోన్ చంపుటకు విఫలమైంది: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
 msgstr "ఈ ప్రోగ్రామ్ root లా నడుపవలసింది కాదు (--system తెలిపితే తప్ప)"
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "Root అనుమతులు అవసరము."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "--start సిస్టమ్ సంభవాల ద్వారా మద్దతీయబడదు."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "సిస్టమ్ మోడ్ నందు నడుపుతోంది, అయితే --disallow-exit అమర్చలేదు!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr "సిస్టమ్ రీతినందు నడుచుచున్నది, అయితే --disallow-module-loading అమర్చలేదు!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "సిస్టమ్ రీతినందు నడుపుచున్నది, బలవంతంగా SHM రీతిని అచేతనము చేస్తోంది!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr "సిస్టమ్ రీతినందు నడుచుచున్నది, బలవంతంగా నిష్క్రమణ వృధా సమయాన్ని అచేతనము చేయుచున్నది!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "stdio పొందుటకు విఫలమైంది."
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "పైర్ విఫలమైంది: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork() విఫలమైంది: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read() విఫలమైంది: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "డెమోన్ ప్రారంభం విఫలమైంది."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "డెమోన్ ప్రారంభము సఫలమైంది."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() విఫలమైంది: %s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "ఇది PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "నిర్వర్తన హోస్టు: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "నిర్వర్తన CFLAGS: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "హోస్టును నడుపుచున్నది: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "%u CPUలను కనుగొన్నది."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "పేజీ పరిమాణము %lu బైట్లు"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "Valgrind మద్దతుతో నిర్వర్తించబడింది: అవును"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "Valgrind మద్దతుతో నిర్వర్తించబడింది: లేదు"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "valgrind రీతినందు నడుపుచున్నది: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "హోస్టును నడుపుచున్నది: %s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "ఆప్టిమైజ్డు బుల్డు: అవును"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "ఆప్టిమైజ్డు బుల్డు: కాదు"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "NDEBUG నిర్వచించబడింది, అన్ని స్థిరరాశులు అచేతనమైనవి."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "FASTPATH నిర్వచించబడింది, ఫాస్ట్ పాత్ స్థిరరాశులు మాత్రమే అచేతనమైనవి."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "అన్ని స్థిరరాశులు చేతనమైనవి."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "మిషన్ ID పొందుటకు విఫలమైంది"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "మిషన్ ID %s."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:945
 #, c-format
 msgid "Session ID is %s."
 msgstr "సెషన్ ID %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "రన్‌టైమ్ డైరెక్టరీను వుపయోగించుచున్నది %s."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "స్థితి డైరెక్టరీను వుపయోగించుచున్నది %s."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:959
 #, c-format
 msgid "Using modules directory %s."
 msgstr "మాడ్యూళ్ళ డైరెక్టరీ %s వుపయోగిస్తోంది."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "సిస్టమ్ రీతినందు వుపయోగించుచున్నది: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -370,46 +409,46 @@ msgstr ""
 "సిస్టమ్ రీతి అనునది సరైనటువంటిది యెందుకు కాదో వివరణ కొరకు దయచేసి యిక్కడ చదవండి http://"
 "pulseaudio.org/wiki/WhatIsWrongWithSystemMode"
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() విఫలమైంది."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "తాజా అధిక-తీవ్రత కాలసూచికలు అందుబాటులో వున్నాయి! బాన్ ఎపటైట్!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
 msgstr "మిత్రమా, నీ కెర్నల్ చెడిపోయింది! అధిక-తీవ్రత కాలసూచకిలను చేతనము చేయమని సూచించడమైనది!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() విఫలమైంది."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "డెమోన్ సిద్దముచేయుటకు విఫలమైంది."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "ఏవిధమైన మాడ్యూళ్ళు లోడవకుండా డెమోన్ ప్రారంభము, పనిచేయుటకు తిరస్కరించబడింది."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "డెమోన్ ప్రారంభము పూర్తైనది."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "డెమోన్ మూసివేత సిద్దముచేయబడింది."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "డెమోన్ అంతముచేయబడింది."
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -446,15 +485,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -551,15 +588,15 @@ msgstr ""
 "\n"
 "  -n                                    Don't load default script file\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize బూలియన్ ఆర్గుమెంటును కోరుకుంటుంది"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail బూలియన్ ఆర్గుమెంటును కోరుకుంటుంది"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -567,166 +604,169 @@ msgstr ""
 "--log-level లాగ్ స్థాయి ఆర్గుమెంట్‌ను కోరుకుంటోంది (సహజసంఖ్యను 0..4 విస్తృతిలో కాని లేదా డీబగ్‌, "
 "సమాచారము, నోటీసు, హెచ్చరిక, దోషము వీటిలో వొకటికాని)."
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority బూలియన్ ఆర్గుమెంటును కోరుకుంటుంది"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime బూలియన్ ఆర్గుమెంటును కోరుకుంటుంది"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading బూలియన్ ఆర్గుమెంటును కోరుకుంటుంది"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit బూలియన్ ఆర్గుమెంటును కోరుకుంటుంది"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file బూలియన్ ఆర్గుమెంటును కోరుకుంటుంది"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr "చెల్లని లాగ్ టార్గెట్: 'syslog', 'stderr' లేదా 'auto' వుపయోగించుము."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time బూలియన్ ఆర్గుమెంటును కోరుకుంటుంది"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta బూలియన్ ఆర్గుమెంటును కోరుకుంటుంది"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "చెల్లని పునఃవుదాహరణ పద్దతి '%s'."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system బూలియన్ ఆర్గుమెంటును కోరుకుంటుంది"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit బూలియన్ ఆర్గుమెంటును కోరుకుంటుంది"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm బూలియన్ ఆర్గుమెంటును కోరుకుంటుంది"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "నామము: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "ఎటువంటి మాడ్యూల్ సమాచారము అందుబాటులోలేదు\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "వర్షన్: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "వివరణ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "మూలకర్త: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "వాడుక: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "ఒకసారి లోడుచేయుము: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "తీసివేత హెచ్చరిక: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "పాత్: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] చెల్లని లాగ్ లక్ష్యము '%s'."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] చెల్లని లాగ్ స్థాయి '%s'."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] చెల్లని పునఃవుదాహరణ పద్దతి '%s'."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] చెల్లని rlimit '%s'."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit అనునది ఈ ప్లాట్‌ఫాం నందు మద్దతివ్వబడదు."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] చెల్లని మాదిరి ఫార్మాట్ '%s'."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] చెల్లని మాదిరి రేటు '%s'."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] చెల్లని మాదిరి చానళ్ళు '%s'."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] చెల్లని ఛానల్ మాప్ '%s'."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] చెల్లని ముక్కలు సంఖ్య '%s'."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] చెల్లని ముక్క పరిమాణము '%s'."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] చెల్లని సాదా స్థాయి '%s'."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] చెల్లని మాదిరి రేటు '%s'."
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "ఆకృతీకరణ దస్త్రమును తెరుచుటకు విఫలమైంది: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -734,12 +774,12 @@ msgstr ""
 "తెలుపబడిన అప్రమేయ ప్రాసారమార్గం మాప్ తెలుపబడిన అప్రమేయ ప్రసారమార్గముల కన్నా విభిన్న ప్రసారమార్గముల "
 "సంఖ్యను కలిగివుంది."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### ఆకృతీకరణ దస్త్రమునుండి చదువుము: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
 msgstr "అనుమతులను శుభ్రపరచుచున్నది."
 
@@ -751,6 +791,16 @@ msgstr "PulseAudio శబ్దపు సిస్టమ్"
 msgid "Start the PulseAudio Sound System"
 msgstr "PulseAudio శబ్దపు సిస్టమ్‌ను ప్రారంభించుము"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio శబ్దపు సిస్టమ్"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "PulseAudio శబ్దపు సిస్టమ్‌ను ప్రారంభించుము"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "మోనో"
@@ -780,8 +830,8 @@ msgid "Rear Right"
 msgstr "వెనుక కుడివైపు"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "తక్కువ తరచుదనం వెలువరించునది"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -955,9 +1005,10 @@ msgstr "పైన వెనుక ఎడమవైపు"
 msgid "Top Rear Right"
 msgstr "పైన వెనుక కుడివైపున"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(చెల్లని)"
 
@@ -985,332 +1036,349 @@ msgstr "సరౌండ్ 5.1"
 msgid "Surround 7.1"
 msgstr "సరౌండ్ 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "సరే"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "సాంగత్యం తిరస్కరించబడినది"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "తెలియని ఆదేశము"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "నిస్సారమైన క్రమానుగత సంకేతం"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "ఎంటిటి నిష్క్రమించినది"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "అటువంటి యెంటిటి లేదు"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "కనెక్షన్ తిరస్కరించబడింది"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "నియమం దోషం"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "సమయంముగిసింది"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "ఎటువంటి ధృవీకృత కీ లేదు"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "అంతర్గత దోషము"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "అనుసంధానము అంతముచేయబడింది"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "ఎంటిటి నాశనంచేయబడింది"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "చెల్లని సేవిక"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "మాడ్యూల్ సిద్దీకరణ విఫలమైంది"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "చెడ్డ స్థితి"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "దత్తాంశం లేదు"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "సారూప్యతలేని ప్రోటోకాల్ వర్షన్"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "మరీ పెద్దది"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "మద్దతీయబడదు"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "తెలియని దోషము కోడ్"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "అటువంటి పొడిగింపు లేదు"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "పనితీరు తీసివేయి"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "తప్పిపోయిన యింప్లిమెంటేషన్"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "కక్షిదారి పోర్క్ చేసిన"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "ఇన్పుట్/అవుట్పుట్ దోషము"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "పరికరము లేదా వనరు రద్దీగావుంది"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay() విఫలమైంది"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() విఫలమైంది: %s"
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "కుకీ డాటా పార్శ్ చేయుటకు విఫలమైంది"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "ఆకృతీకరణ దస్త్రము '%s' తెరువుటకు విఫలమైంది: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "ఏ కుకీ లోడవలేదు. లేకుండా అనుసంధానమగుటకు ప్రయత్నిస్తోంది."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "తెలియని పొడిగింపు కొరకు సందేశము స్వీకరించింది '%s'"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:112
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "స్ట్రీమ్‌ను డ్రైయిన్ చేయుటకు విఫలమైంది: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
 msgstr "ప్లేబ్యాక్ స్ట్రీమ్ డ్రెయిన్ అయినది."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
 msgstr "సేవికకు అనుసంధానమును ఎండగట్టుచున్నది."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:141
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:164
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "pa_stream_write() విఫలమైంది: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:205
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "pa_stream_begin_write() విఫలమైంది: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "pa_stream_peek() విఫలమైంది: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
 msgstr "స్ట్రీమ్ సమర్ధవంతంగా సృష్టించబడింది."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:328
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "pa_stream_get_buffer_attr() విఫలమైంది: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:332
 #, 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:317
+#: ../src/utils/pacat.c:335
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "బఫర్ ప్రమాణాలు: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:339
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "సాదారణ విశదీకరణ(స్పెక్) '%s' వుపయోగిస్తోంది, ప్రసారమార్గం మాప్ '%s'."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:343
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "పరికరము %s (%u, %ssuspended) కు అనుసంధానించబడింది."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Stream error: %s"
 msgstr "స్ట్రీమ్ దోషము: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:363
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "స్ట్రీమ్ పరికరము అర్దాంతరముగా నిలిపివేయబడింది.%s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:365
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "స్ట్రీమ్ పరికరము తిరిగికొనసాగించబడింది.%s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:373
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "స్ట్రీమ్ తక్కువగానడుచుచున్నది.%s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:380
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "స్ట్రీమ్ మించినడుచుచున్నది.%s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream started.%s"
 msgstr "స్ట్రీమ్ ప్రారంభమైంది.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "స్ట్రీమ్ పరికరము %s (%u, %ssuspended) కు కదుపబడింది.%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "కాదు "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "స్ట్రీమ్ బఫర్ యాట్రిబ్యూట్లు మార్చబడినవి.%s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
 #, c-format
 msgid "Connection established.%s"
 msgstr "అనుసంధానము ఏర్పడినది.%s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:454
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "pa_stream_new() విఫలమైంది: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:492
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "pa_stream_connect_playback() విఫలమైంది: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:498
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "pa_stream_connect_record() విఫలమైంది: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
 #, c-format
 msgid "Connection failure: %s"
 msgstr "అనుసంధానము వైఫల్యము: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
 msgstr "EOF పొందింది."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:582
 #, c-format
 msgid "write() failed: %s"
 msgstr "write() విఫలమైంది: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
 msgstr "సంకేతము పొందినది, నిష్క్రమించుచున్నది."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:617
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "లేటెన్సీని పొందుటలో విఫలమైంది: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:622
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "సమయం: %0.3f సెకను; లెటెన్సీ: %0.0f usec."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:643
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
 msgstr "pa_stream_update_timing_info() విఫలమైంది: %s"
 
-#: ../src/utils/pacat.c:609
-#, c-format
+#: ../src/utils/pacat.c:653
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1362,10 +1430,15 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [options]\n"
@@ -1424,7 +1497,7 @@ msgstr ""
 "      --file-format=FFORMAT             Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1435,169 +1508,174 @@ msgstr ""
 "libpulse తో నిర్వర్తించబడింది %s\n"
 "libpulse లింకైనది %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "చెల్లని కక్షిదారి నామము '%s'"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:834
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "చెల్లని స్ట్రీమ్ నామము '%s'"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:871
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "చెల్లని ప్రసారమార్గ మాప్ '%s'"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "చెల్లని లేటెన్సీ విశదీకరణము '%s'"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "చెల్లని కార్యక్రమము సమయ విశదీకరణ '%s'"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:933
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "చెల్లని లక్షణము '%s'"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
 msgstr "తెలియని ఫైలు ఫార్మాట్ %s."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
 msgstr "చెల్లనటువంటి మాదిరి విశదీకరణ"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:981
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:986
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
 msgstr "చాలా యెక్కువ ఆర్గుమెంట్లు."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
 msgstr "దస్త్రము కొరకు మాదిరి సమాచారము జనియింపచేయుటలో విఫలమైంది."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
 msgstr "ఆడియో ఫైలును తెరువుటకు విఫలమైంది."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
 msgstr "హెచ్చరిక: తెలుపబడిన మాదిరి విశదీకరణ దస్త్రమునుండి వచ్చు విశదీకరణతో తిరిగివ్రాయబడుతుంది."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
 msgstr "దస్త్రమునుండి మాదిరి విశదీకరణను నిర్ధారించుటలో విఫలమైంది."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
 msgstr "హెచ్చరిక: దస్త్రమునుండి ప్రసారమార్గ మాప్ నిర్ధారించుటలో విఫలమైంది."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
 msgstr "ప్రసారమార్గ మాప్ మాదిరి విశదీకరణితో సరిపోలుటలేదు"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
 msgstr "హెచ్చరిక: ప్రసారమార్గ మాప్‌ను దస్త్రముకు వ్రాయుటలో విఫలమైంది."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1085
 #, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
 msgstr "%s స్ట్రీమ్‌ను మాదిరి విశదీకరణ '%s' మరియు ప్రసారమార్గ మాప్ '%s'తో తెరుచుచున్నది."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "రికార్డింగు"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "ప్లేబాక్"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "ఆదేశ వరుసను పార్శ్ చేయుటకు విఫలమైంది."
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
 msgstr "pa_mainloop_new() విఫలమైంది."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
 msgstr "io_new() విఫలమైంది."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
 msgstr "pa_context_new() విఫలమైంది."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect() విఫలమైంది: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
 msgstr "pa_context_rttime_new() విఫలమైంది."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
 msgstr "pa_mainloop_run() విఫలమైంది."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "అర్ధాంతరనిలుపుదల వైఫల్యం: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "తిరిగికొనసాగింపు వైఫల్యము: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "హెచ్చరిక: శబ్ధపు సేవిక స్థానికం కాదు, అర్ధాంతరనిలుపుదల కావడంలేదు.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "అనుసంధానము వైఫల్యము: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "SIGINT పొందింది, నిష్క్రమించుచున్నది.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "హెచ్చరిక: చైల్డు కార్యక్రమము సంకేతము %u ద్వారా అంతముచేయబడింది\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1642,35 +1720,46 @@ msgstr "pa_context_new() విఫలమైంది.\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() విఫలమైంది.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:150
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "గణాంకాలను పొందుటకు విఫలమైంది: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "ప్రస్తుతం వుపయోగంలోవుంది: %u బ్లాక్‌లు %s బైట్లను మొత్తంగా కలిగి వున్నాయి.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "మొత్తం లైఫ్‌టైములో కేటాయించబడింది: %u బ్లాకులు %s బైట్లను మొత్తంగా కలిగివున్నాయి.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "మాదిరి క్యాచి పరిమాణము: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:171
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "సేవిక సమాచారమును పొందుటకు విఫలమైంది: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1678,7 +1767,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "వినియోగదారి నామము: %s\n"
 "హోస్టు నామము: %s\n"
@@ -1690,13 +1779,13 @@ msgstr ""
 "అప్రమేయ మూలము: %s\n"
 "కుకీ: %08x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "సింక్ సమాచారమును పొందుటకు విఫలమైంది: %s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1712,7 +1801,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1734,22 +1823,27 @@ msgstr ""
 "\tలక్షణాలు:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tపోర్టులు:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tక్రియాశీల పోర్టు: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tపోర్టులు:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "మూలము సమాచారము పొందుటకు విఫలమైంది: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1788,20 +1882,20 @@ msgstr ""
 "\tలక్షణాలు:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "వర్తించదు"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:454
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "మాడ్యూల్ సమాచారము పొందుటకు విఫలమైంది: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1818,12 +1912,12 @@ msgstr ""
 "\tలక్షణాలు:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:496
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "కక్షిదారి సమాచారము పొందుటలో విఫలమైంది: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1838,12 +1932,12 @@ msgstr ""
 "\tలక్షణాలు:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:539
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "కార్డు సమాచారము పొందుటకు విఫలమైంది: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1860,23 +1954,23 @@ msgstr ""
 "\tలక్షణాలు:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tప్రోఫైల్సు:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tక్రియాశీల ప్రొఫైల్: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "సింక్ ఇన్పుట్ సమాచారము పొందుటకు విఫలమైంది: %s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1885,6 +1979,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1912,13 +2007,13 @@ msgstr ""
 "\tలక్షణాలు:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "మూలపు అవుట్పుట్ సమాచారము పొందుటకు విఫలమైంది: %s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1927,31 +2022,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"à°®à±\82లమà±\81 à°\85à°µà±\81à°\9f్పుట్ #%u\n"
+"సిà°\82à°\95à±\8d à°\87à°¨్పుట్ #%u\n"
 "\tడ్రైవర్: %s\n"
 "\tయజమాని మాడ్యూల్: %s\n"
 "\tకక్షిదారి: %s\n"
-"\tà°®à±\82లమà±\81: %u\n"
-"\tమాదిరి విశదీకరణ: %s\n"
+"\tసిà°\82à°\95à±\8d: %u\n"
+"\tమాదిరి విశదీకరణము: %s\n"
 "\tప్రసారమార్గ మాప్: %s\n"
+"\tనిశ్శబ్ధము: %s\n"
+"\tవాల్యూమ్: %s\n"
+"\t        %s\n"
+"\t        సమతుల్యత %0.2f\n"
 "\tబఫర్ క్రియాహీనత: %0.0f usec\n"
-"\tà°®à±\82లమà±\81 క్రియాహీనత: %0.0f usec\n"
-"\tà°ªà±\81à°¨à°\83à°µà±\81దాహరణ à°µà°¿à°¶à°¦à±\80à°\95à°°à°£: %s\n"
+"\tసిà°\82à°\95à±\8d క్రియాహీనత: %0.0f usec\n"
+"\tà°ªà±\81à°¨à°\83à°µà±\81దాహరణ à°ªà°¦à±\8dదతి: %s\n"
 "\tలక్షణాలు:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:734
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "మాదిరి సమాచారము పొందుటకు విఫలమైంది: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1982,48 +2086,163 @@ msgstr ""
 "\tలక్షణాలు:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
 #, c-format
 msgid "Failure: %s"
 msgstr "వైఫైల్యము: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "మూలము సమాచారము పొందుటకు విఫలమైంది: %s"
+
+#: ../src/utils/pactl.c:954
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "మాదిరి అప్‌లోడు చేయుటకు విఫలమైంది: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
 msgstr "దస్త్రము యొక్క అపరిపక్వ ముగింపు"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "చెల్లని సేవిక"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
 msgstr "SIGINT పొందింది, నిష్క్రమించుచున్నది."
 
-#: ../src/utils/pactl.c:869
-#, c-format
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "చెల్లనటువంటి వాల్యూమ్ విశదీకరణ"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2033,37 +2252,15 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+"%s [options] ... \n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
-"\n"
 "  -s, --server=SERVER                   The name of the server to connect "
 "to\n"
-"  -n, --client-name=NAME                How to call this client on the "
-"server\n"
+"\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2074,106 +2271,138 @@ msgstr ""
 "libpulse తో నిర్వర్తించబడింది%s\n"
 "libpulse తో లింకుచేయబడింది %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
 msgstr "లోడువ్వుటకు దయచేసి మాదిరి దస్త్రమును తెలుపుము"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
 msgstr "శబ్దపు దస్త్రమును తెరువుటకు విఫలమైంది."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
 msgstr "హెచ్చరిక: దస్త్రమునుండి మాదిరి విశదీకరణను నిర్ణయించుటకు విఫలమైంది."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
 msgstr "ప్లే చేయుటకు మీరు మాదిరి నామమును తెలుపవలసి వుంది"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
 msgstr "తొలగించుటకు మీరు మాదిరి నామమును తెలుపవలసి వుంది"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
 msgstr "మీరు సింక్ ఇన్పుట్ విషయసూచిక మరియు సింక్ తెలుపవలసి వుంది"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
 msgstr "మీరు మూలము అవుట్పుట్ విషయసూచిక మరియు మూలము తెలుపవలసి వుంది"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
 msgstr "మీరు మాడ్యూల్ నామము మరియు ఆర్గుమెంట్లు తెలుపవలసి వుంది."
 
-#: ../src/utils/pactl.c:1080
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
 msgstr "మీరు మాడ్యూల్ విషయసూచిక తెలుపవలసి వుంది"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "మీరు వొక సింకు కన్నా యెక్కువ తెలుపవలసి వుండకపోవచ్చు. మీరు బూలియన్ విలువను తెలుపవలసి వుంది."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
 msgstr ""
 "మీరు వొక మూలము కన్నా యెక్కువ తెలుపవలసి వుండకపోవచ్చు. మీరు బూలియన్ విలువను తెలుపవలసి వుంది."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
 msgstr "మీరు కార్డ్ నామము/విషయసూచిక మరియు ప్రొఫైల్ నామము తెలుపవలసి వుంది"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
 msgstr "మీరు సింక్‌ నామము/విషయసూచిక మరియు ప్రొఫైల్ నామము తెలుపవలసి వుంది"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
 msgstr "మీరు మూలము నామము/విషయసూచిక మరియు ప్రొఫైల్ నామము తెలుపవలసి వుంది"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
 msgstr "మీరు సింక్ నామము/విషయసూచిక మరియు ప్రొఫైల్ నామము తెలుపవలసి వుంది"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "చెల్లనటువంటి వాల్యూమ్ విశదీకరణ"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
 msgstr "మీరు మూలము నామము/విషయసూచిక మరియు ప్రొఫైల్ నామము తెలుపవలసి వుంది"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
 msgstr "మీరు సింక్ ఇన్పుట్ విషయసూచిక మరియు వాల్యూమ్ తెలుపవలసి వుంది"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
 msgstr "చెల్లని సింకు యిన్పుట్ విషయసూచిక"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "మీరు మూలము అవుట్పుట్ విషయసూచిక మరియు మూలము తెలుపవలసి వుంది"
+
+#: ../src/utils/pactl.c:1665
+#, fuzzy
+msgid "Invalid source output index"
+msgstr "చెల్లని సింకు యిన్పుట్ విషయసూచిక"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
 msgstr "మీరు సింక్‌ నామము/విషయసూచిక మరియు మ్యూట్ బూలియన్ తెలుపవలసి వుంది"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "చెల్లనటువంటి మాదిరి విశదీకరణ"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
 msgstr "మీరు మూలపు నామము/విషయసూచిక మరియు మ్యూట్ బూలియన్ తెలుపవలసివుంది"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
 msgstr "మీరు సింక్ ఇన్పుట్ విషయసూచిక మరియు మ్యూట్ బూలియన్ తెలుపవలసివుంది"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
 msgstr "చెల్లనటువంటి సింకు యిన్పుట్ విషయసూచిక విశదీకరణ"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
+#, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "మీరు మూలపు నామము/విషయసూచిక మరియు మ్యూట్ బూలియన్ తెలుపవలసివుంది"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "చెల్లనటువంటి సింకు యిన్పుట్ విషయసూచిక విశదీకరణ"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "మీరు సింక్‌ నామము/విషయసూచిక మరియు మ్యూట్ బూలియన్ తెలుపవలసి వుంది"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
 msgstr "ఎటువంటి విలువైన ఆదేశము తెలుపబడలేదు."
 
@@ -2201,103 +2430,103 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "ఆదేశ వరుసను పార్శ్ చేయుటకు విఫలమైంది.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "సేవిక: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "మూలము: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "సింక్: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "కుకీ: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "కుకీ డాటా పార్శ్ చేయుటకు విఫలమైంది\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "కుకీ డాటా దాయుటకు విఫలమైంది\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "కక్షిదారి ఆకృతీకరణ దస్త్రమును లోడు చేయుటకు విఫలమైంది.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "ఎన్విరాన్మెంట్ ఆకృతీకరణ డాటాను చదువుటకు విఫలమైంది.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "FQDN పొందుటకు విఫలమైంది.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "కుకీ డాటా లోడు చేయుటకు విఫలమైంది\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "ఇంకా యింప్లిమెంట్ చేయలేదు\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr "PulseAudio డెమోన్ నడుచుటలేదు, లేదా సెషన్ డెమోన్ వలె నడుచుటలేదు."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "PulseAudio డెమోన్ నాశనం చేయుటలో విఫలమైంది."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "డెమోన్ స్పందించుటలేదు."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:184
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "ఆటోస్పాన్ తాళంను యాక్సిస్ చేయలేదు."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2313,7 +2542,7 @@ msgstr ""
 "మనము POLLOUT అమర్పు ద్వారా జాగరూక పరచబడినాము -- ఏమైనప్పటికి snd_pcm_avail() అనునది 0 ను "
 "యిస్తుంది లేదా వేరొక విలువ < min_avail యిస్తుంది."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2329,242 +2558,464 @@ msgstr ""
 "మనము POLLOUT అమర్పు ద్వారా జాగరూక పరచబడినాము -- ఏమైనప్పటికి snd_pcm_avail() అనునది 0 ను "
 "యిస్తుంది లేదా వేరొక విలువ < min_avail యిస్తుంది."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "ఆఫ్"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "హై ఫెడిలిటి ప్లేబ్యాక్ (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
 msgstr "హై ఫెడిలిటి కాప్చర్ (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "టెలిఫోనీ డూప్లెక్స్ (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "పల్స్ ఆడియో సౌండ్ సేవిక"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
-msgstr ""
+msgstr "అవుట్పుట్ పరికరములు"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
-msgstr ""
+msgstr "ఇన్పుట్ పరికరములు"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
-msgstr ""
+msgstr "@HOSTNAME@ పై ఆడియో"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
-msgstr ""
+msgstr "ఇన్పుట్"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
-msgstr ""
+msgstr "డాకింగ్ స్టేషన్ ఇన్పుట్"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
-msgstr ""
+msgstr "డాకింగ్ స్టేషన్ మైక్రోఫోన్"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "డాకింగ్ స్టేషన్ ఇన్పుట్"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "లైన్-యిన్"
+
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
-msgstr ""
+msgstr "మైక్రోఫోన్"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
-msgid "External Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "డాకింగ్ స్టేషన్ మైక్రోఫోన్"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
 #, fuzzy
+msgid "Rear Microphone"
+msgstr "మైక్రోఫోన్"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "బహిర్గత మైక్రోఫోన్"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
-msgstr "à°\85à°\82తరà±\8dà°\97à°¤ à°\86à°¡à°¿à°¯à±\8b"
+msgstr "à°\85à°\82తరà±\8dà°\97à°¤ à°®à±\88à°\95à±\8dà°°à±\8bà°«à±\8bà°¨à±\8d"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
-msgstr ""
+msgstr "రేడియో"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
-msgstr ""
+msgstr "వీడియో"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
-msgstr ""
+msgstr "స్వయంచాలకంగా పొందు నియంత్రణ"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
-msgstr ""
+msgstr "స్వయంచాలకంగా పొందు ఏ నియంత్రణ లేదు"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
-msgstr ""
+msgstr "బూస్ట్"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
-msgstr ""
+msgstr "బూస్ట్ లేదు"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
-msgstr ""
+msgstr "ఎంప్లిఫైర్"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
-msgstr ""
+msgstr "ఎంప్లిఫైర్ లేదు"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "బూస్ట్"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "బూస్ట్ లేదు"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "ఎనలాగ్ హెడ్‌ఫోన్స్"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "ఎనలాగ్ యిన్పుట్"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "డాకింగ్ స్టేషన్ మైక్రోఫోన్"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
-msgstr "Null అవుట్పుట్"
+msgstr "ఎనలాగ్ అవుట్పుట్"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "ఎనలాగ్ అవుట్పుట్ (LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "లైన్-యిన్"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2314
 msgid "Analog Mono Output"
+msgstr "ఎనలాగ్ మోనో అవుట్పుట్"
+
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "ఎనలాగ్ స్టీరియో"
+
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, fuzzy, c-format
-msgid "%s+%s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "డిజిటల్ స్టీరియో (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, fuzzy, c-format
-msgid "%s / %s"
-msgstr "%s %s"
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "డిజిటల్ స్టీరియో (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
-msgstr ""
+msgstr "ఎనలాగ్ మోనో"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
-msgstr "స్టీరియో"
+msgstr "à°\8eనలాà°\97à±\8d à°¸à±\8dà°\9fà±\80à°°à°¿à°¯à±\8b"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
-msgstr "సరà±\8cà°\82à°¡à±\8d 4.1"
+msgstr "à°\8eనలాà°\97à±\8d à°¸à°°à±\8cà°\82à°¡à±\8d 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
-msgstr "సరà±\8cà°\82à°¡à±\8d 4.0"
+msgstr "à°\8eనలాà°\97à±\8d à°¸à°°à±\8cà°\82à°¡à±\8d 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
-msgstr "సరà±\8cà°\82à°¡à±\8d 4.1"
+msgstr "à°\8eనలాà°\97à±\8d à°¸à°°à±\8cà°\82à°¡à±\8d 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
-msgstr "సరౌండ్ 4.0"
+msgstr "à°\8eనలాà°\97à±\8d à°¸à°°à±\8cà°\82à°¡à±\8d 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
-msgstr "సరౌండ్ 4.1"
+msgstr "à°\8eనలాà°\97à±\8d à°¸à°°à±\8cà°\82à°¡à±\8d 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
-msgstr "సరౌండ్ 5.0"
+msgstr "à°\8eనలాà°\97à±\8d à°¸à°°à±\8cà°\82à°¡à±\8d 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
-msgstr "సరౌండ్ 5.1"
+msgstr "à°\8eనలాà°\97à±\8d à°¸à°°à±\8cà°\82à°¡à±\8d 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
-msgstr "సరà±\8cà°\82à°¡à±\8d 4.0"
+msgstr "à°\8eనలాà°\97à±\8d à°¸à°°à±\8cà°\82à°¡à±\8d 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
-msgstr "సరà±\8cà°\82à°¡à±\8d 4.1"
+msgstr "à°\8eనలాà°\97à±\8d à°¸à°°à±\8cà°\82à°¡à±\8d 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
-msgstr "సరà±\8cà°\82à°¡à±\8d 4.0"
+msgstr "à°\8eనలాà°\97à±\8d à°¸à°°à±\8cà°\82à°¡à±\8d 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
-msgstr "సరౌండ్ 7.1"
+msgstr "à°\8eనలాà°\97à±\8d à°¸à°°à±\8cà°\82à°¡à±\8d 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
-msgstr ""
+msgstr "డిజిటల్ స్టీరియో (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "డిజిటల్ స్టీరియో (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
-msgstr ""
+msgstr "డిజిటల్ సరౌండ్ 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
-msgstr ""
+msgstr "డిజిటల్ సరౌండ్ 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
-msgstr ""
+msgstr "డిజిటల్ స్టీరియో (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "డిజిటల్ సరౌండ్ 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
-msgstr ""
+msgstr "ఎనలాగ్ మోనో డుప్లెక్స్"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
-msgstr ""
+msgstr "ఎనలాగ్ స్టీరియో డుప్లెక్స్"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
+msgstr "డిజిటల్ స్టీరియో డుప్లెక్స్ (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Null అవుట్పుట్"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "ఇన్పుట్"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
 msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+#, fuzzy
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<సింక్ నామము> sink_properties=<సింకు లక్షణములు> master=<ఫిల్టర్‌కు సింకు "
+"నామము> format=<మాదిరి ఫార్మాట్> rate=<మాదిరి రేటు> channels=<చానల్సు సంఖ్య> "
+"channel_map=<చానల్ మాప్> plugin=<ladspa ప్లగిన్ నామము> label=<ladspa ప్లగిన్ లేబుల్> "
+"control=<ఇన్పుట్ నియంత్రణ విలువలయొక్క జాబితా>"
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit అనునది ఈ ప్లాట్‌ఫాం నందు మద్దతివ్వబడదు."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() విఫలమైంది"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "మూలము అవుట్పుట్ #%u\n"
+#~ "\tడ్రైవర్: %s\n"
+#~ "\tయజమాని మాడ్యూల్: %s\n"
+#~ "\tకక్షిదారి: %s\n"
+#~ "\tమూలము: %u\n"
+#~ "\tమాదిరి విశదీకరణ: %s\n"
+#~ "\tప్రసారమార్గ మాప్: %s\n"
+#~ "\tబఫర్ క్రియాహీనత: %0.0f usec\n"
+#~ "\tమూలము క్రియాహీనత: %0.0f usec\n"
+#~ "\tపునఃవుదాహరణ విశదీకరణ: %s\n"
+#~ "\tలక్షణాలు:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "డిజిటల్ సరౌండ్ 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "తక్కువ తరచుదనం వెలువరించునది"
index aacdf94..b76df78 100644 (file)
--- a/po/uk.po
+++ b/po/uk.po
@@ -1,28 +1,24 @@
 # Copyright (C) 2009 Free Software Foundation, Inc.
 # This file is distributed under the same license as the pulseaudio.master-tx package.
 #
-# Yuri Chornoivan <yurchor@ukr.net>, 2009.
+# Yuri Chornoivan <yurchor@ukr.net>, 2009, 2012, 2013.
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-10-03 10:02+0000\n"
-"PO-Revision-Date: 2009-10-03 19:28+0300\n"
+"POT-Creation-Date: 2013-03-23 15:06+0200\n"
+"PO-Revision-Date: 2013-03-23 16:01+0200\n"
 "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
 "Language-Team: Ukrainian <translation@linux.org.ua>\n"
+"Language: uk\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: Lokalize 0.3\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 "
-"&& (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Generator: Lokalize 1.5\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr "%s %s"
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1128 ../src/modules/alsa/alsa-util.c:1203
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -35,20 +31,33 @@ msgstr ""
 "Ймовірно, ви натрапили на ваду у драйвері ALSA «%s». Будь ласка, повідомте "
 "про цю ваду розробникам ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1178
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
-"Функція snd_pcm_delay() повернула винятково велике значення: %li байтів (%s%"
-"lu мс).\n"
+"Функція snd_pcm_delay() повернула винятково велике значення: %li байтів (%s"
+"%lu мс).\n"
 "Ймовірно, ви натрапили на ваду у драйвері ALSA «%s». Будь ласка, повідомте "
 "про цю ваду розробникам ALSA."
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1219
+#, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail_delay() повернуто дивні значення: затримка %lu є меншою за "
+"доступну, %lu.\n"
+"Ймовірно, це пов’язано з вадою у драйвері ALSA «%s». Будь ласка, повідомте "
+"про цю ваду розробникам ALSA."
+
+#: ../src/modules/alsa/alsa-util.c:1262
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -61,122 +70,132 @@ msgstr ""
 "Ймовірно, ви натрапили на ваду у драйвері ALSA «%s». Будь ласка, повідомте "
 "про цю ваду розробникам ALSA."
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
 msgstr ""
 "Завжди підтримувати принаймні один завантажений приймач, навіть якщо він "
 "буде нульовим"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
 msgstr "Тестове відтворення"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:53
 msgid "Virtual LADSPA sink"
 msgstr "Віртуальний приймач LADSPA"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:57
 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> "
-"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
-"input control values>"
+"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> "
 msgstr ""
 "sink_name=<назва приймача> sink_properties=<властивості приймача> "
 "master=<назва приймача для фільтрування> format=<формат семплу> "
 "rate=<частота вибірки> channels=<кількість каналів> channel_map=<карта "
-"каналів> plugin=<назва додатка ladspa> label=<мітка додатка ladspa> "
-"control=<розділений комами список значень вхідних параметрів>"
+"каналів вхідних даних> plugin=<назва додатка ladspa> label=<мітка додатка "
+"ladspa> control=<розділений комами список значень вхідних параметрів> "
+"input_ladspaport_map=<список назв портів вхідних даних LADSPA, відокремлених "
+"комами> output_ladspaport_map=<список назв портів вихідних даних LADSPA, "
+"відокремлених комами> "
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
 msgstr "NULL-приймач з годинником"
 
-#: ../src/modules/module-null-sink.c:291
+#: ../src/modules/module-null-sink.c:280
 msgid "Null Output"
 msgstr "Нуль-відтворення"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3443
+msgid "Built-in Audio"
 msgstr "Вбудоване аудіо"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3448
 msgid "Modem"
 msgstr "Модем"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:77
+#, c-format
+msgid "Failed to open module %s: %s"
+msgstr "Не вдалося відкрити модуль %s: %s"
+
+#: ../src/daemon/ltdl-bind-now.c:128
 msgid "Failed to find original lt_dlopen loader."
 msgstr ""
 "Спроба знайти початковий інструмент завантаження lt_dlopen зазнала невдачі."
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:133
 msgid "Failed to allocate new dl loader."
 msgstr ""
 "Спроба виділення пам’яті для нового інструменту завантаження dl зазнала "
 "невдачі."
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:146
 msgid "Failed to add bind-now-loader."
 msgstr "Не вдалося додати bind-now-loader."
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "Отримано сигнал %s."
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "Завершення роботи."
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "Не вдалося знайти користувача «%s»."
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "Не вдалося знайти групу «%s»."
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "Знайдено користувача «%s» (UID %lu) і групу «%s» (GID %lu)."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "GID користувача «%s» і групи «%s» не збігаються."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "Домашнім каталогом користувача «%s» не є «%s», дані проігноровано."
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Не вдалося створити «%s»: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "Не вдалося змінити список груп: %s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "Не вдалося змінити GID: %s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "Не вдалося змінити UID: %s"
 
 #: ../src/daemon/main.c:271
-msgid "Successfully dropped root privileges."
-msgstr "Ð\9fÑ\80огÑ\80ама Ñ\83Ñ\81пÑ\96Ñ\88но Ð¿Ð¾Ð·Ð±Ñ\83лаÑ\81Ñ\8f Ð¿Ñ\80ав Ð´Ð¾Ñ\81Ñ\82Ñ\83пÑ\83 ÐºÐ¾Ñ\80иÑ\81Ñ\82Ñ\83ваÑ\87а root."
+msgid "Successfully changed user to \""
+msgstr "Ð\9aоÑ\80иÑ\81Ñ\82Ñ\83ваÑ\87а Ñ\83Ñ\81пÑ\96Ñ\88но Ð·Ð¼Ñ\96нено Ð½Ð° Â«"
 
 #: ../src/daemon/main.c:279
 msgid "System wide mode unsupported on this platform."
@@ -187,25 +206,33 @@ msgstr "Загальносистемний режим не підтримуєт
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "Спроба виконати setrlimit(%s, (%u, %u)) була невдалою: %s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:498
 msgid "Failed to parse command line."
 msgstr "Не вдалося обробити рядок команди."
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:531
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+"Запуск у системному режимі для неадміністративного користувача неможливий. "
+"Буде запущено лише службу виявлення пристроїв сервера D-Bus."
+
+#: ../src/daemon/main.c:613
 msgid "Daemon not running"
 msgstr "Фонову службу не запущено"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:615
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "Фонову службу запущено як PID %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:630
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "Не вдалося завершити роботу фонової служби: %s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:659
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
@@ -213,160 +240,186 @@ msgstr ""
 "Цю програму не призначено для запуску від імені користувача root (якщо не "
 "вказано параметра --system)."
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:662
 msgid "Root privileges required."
 msgstr "Потрібні права доступу користувача root."
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:669
 msgid "--start not supported for system instances."
 msgstr ""
 "Параметр --start не підтримується для загальносистемних екземплярів програми."
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:709
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+"Налаштований користувачем сервер на %s, не вдалося запустити/автоматично "
+"відновити роботу."
+
+#: ../src/daemon/main.c:715
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+"Налаштований користувачем сервер на %s, який, здається, є локальним. "
+"Виконуємо докладнішу діагностику."
+
+#: ../src/daemon/main.c:720
 msgid "Running in system mode, but --disallow-exit not set!"
-msgstr "Запуск у загальносистемному режимі, але не встановлено --disallow-exit!"
+msgstr ""
+"Запуск у загальносистемному режимі, але не встановлено --disallow-exit!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:723
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr ""
 "Запуск у загальносистемному режимі, але не встановлено --disallow-module-"
 "loading!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:726
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "Запуск у загальносистемному режимі, примусове вимикання режиму SHM!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:731
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 "Запуск у загальносистемному режимі, примусове вимикання режиму параметрів "
 "часу виходу за відсутності активності!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:759
 msgid "Failed to acquire stdio."
 msgstr "Не вдалося отримати stdio."
 
-#: ../src/daemon/main.c:627
+#: ../src/daemon/main.c:765 ../src/daemon/main.c:830
 #, c-format
-msgid "pipe failed: %s"
-msgstr "Спроба створення каналу завершилася невдало: %s"
+msgid "pipe() failed: %s"
+msgstr "Спроба виконання pipe() завершилася невдало: %s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:770 ../src/daemon/main.c:835
 #, c-format
 msgid "fork() failed: %s"
 msgstr "Спроба виконання fork() завершилася невдало: %s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:785 ../src/daemon/main.c:850 ../src/utils/pacat.c:564
 #, c-format
 msgid "read() failed: %s"
 msgstr "Спроба виконання read() завершилася невдало: %s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:791
 msgid "Daemon startup failed."
 msgstr "Спроба запуску фонової служби завершилася невдало."
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:793
 msgid "Daemon startup successful."
 msgstr "Фонову службу успішно запущено."
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:818
+#, c-format
+msgid "setsid() failed: %s"
+msgstr "Спроба виконання setsid() завершилася невдало: %s"
+
+#: ../src/daemon/main.c:903
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "Це PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:904
 #, c-format
 msgid "Compilation host: %s"
 msgstr "Вузол збирання: %s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:905 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "CFLAGS збирання: %s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:908
 #, c-format
 msgid "Running on host: %s"
 msgstr "Запущено на вузлі: %s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Found %u CPUs."
 msgstr "Знайдено %u процесорів."
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:913
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "Розмір сторінки дорівнює %lu байтам"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: yes"
 msgstr "Зібрано з підтримкою Valgrind: так"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:918
 msgid "Compiled with Valgrind support: no"
 msgstr "Зібрано з підтримкою Valgrind: ні"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:921
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "Запуск у режимі valgrind: %s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:923
+#, c-format
+msgid "Running in VM: %s"
+msgstr "Запущено у віртуальній машині: %s"
+
+#: ../src/daemon/main.c:926
 msgid "Optimized build: yes"
 msgstr "Зібрано з оптимізацією: так"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:928
 msgid "Optimized build: no"
 msgstr "Зібрано з оптимізацією: ні"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:932
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "Визначено NDEBUG, всі додавання вимкнено."
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:934
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "Визначено FASTPATH, вимкнено лише додавання швидких шляхів."
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:936
 msgid "All asserts enabled."
 msgstr "Увімкнено всі додавання."
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:940
 msgid "Failed to get machine ID"
 msgstr "Спроба отримати ідентифікатор системи завершилася невдало"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:943
 #, c-format
 msgid "Machine ID is %s."
 msgstr "Ідентифікатор системи %s."
 
-#: ../src/daemon/main.c:773
+#: ../src/daemon/main.c:947
 #, c-format
 msgid "Session ID is %s."
 msgstr "Ідентифікатор сеансу — %s."
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:953
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "Каталог запуску: %s."
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:958
 #, c-format
 msgid "Using state directory %s."
 msgstr "Каталог стану: %s."
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Using modules directory %s."
 msgstr "Каталог модулів: %s."
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:963
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Запуску у загальносистемному режимі: %s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:966
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -383,15 +436,15 @@ msgstr ""
 "WhatIsWrongWithSystemMode, щоб дізнатися про те, чому не варто "
 "використовувати системний режим."
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:983
 msgid "pa_pid_file_create() failed."
 msgstr "Спроба виконання pa_pid_file_create() зазнала невдачі."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:993
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "Доступні свіжі високоточні таймери! Смачного!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:995
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -399,33 +452,33 @@ msgstr ""
 "Чувак, твоє ядро — лайно! Круті пацани рекомендують Linux з увімкненими "
 "високоточними таймерами!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1013
 msgid "pa_core_new() failed."
 msgstr "Спроба виконання pa_core_new() зазнала невдачі."
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1091
 msgid "Failed to initialize daemon."
 msgstr "Не вдалося ініціалізувати фонову службу."
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1096
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 "Запуск фонової служби без жодного завантаженого модуля, служба не буде "
 "працездатною."
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1134
 msgid "Daemon startup complete."
 msgstr "Запуск фонової служби завершено."
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1140
 msgid "Daemon shutdown initiated."
 msgstr "Ініційовано завершення роботи фонової служби."
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1171
 msgid "Daemon terminated."
 msgstr "Виконання фонової служби перервано."
 
-#: ../src/daemon/cmdline.c:115
+#: ../src/daemon/cmdline.c:113
 #, c-format
 msgid ""
 "%s [options]\n"
@@ -463,15 +516,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --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"
@@ -500,7 +551,7 @@ msgid ""
 msgstr ""
 "%s [параметри]\n"
 "\n"
-"COMMANDS:\n"
+"КОМАНДИ:\n"
 "  -h, --help                            Показати цю довідку\n"
 "      --version                         Показати дані щодо версії\n"
 "      --dump-conf                       Створити знімок поточних "
@@ -540,16 +591,14 @@ msgstr ""
 "      --exit-idle-time=СЕК.             Перервати виконання фонової служби, "
 "якщо не спостерігатиметься\n"
 "                                        активності протягом вказаного часу\n"
-"      --module-idle-time=СЕК.           Вивантажити автоматично завантажені "
-"модулі, якщо не спостерігатиметься\n"
-"                                        активності протягом вказаного часу\n"
 "      --scache-idle-time=СЕК.           Вивантажити автоматично завантажені "
 "фрагменти, якщо не спостерігатиметься\n"
 "                                        активності протягом вказаного часу\n"
 "      --log-level[=РІВЕНЬ]              Підвищити або встановити рівень "
 "докладності виводу\n"
 "  -v                                    Підвищити рівень докладності виводу\n"
-"      --log-target={auto,syslog,stderr} Вказати журнал\n"
+"      --log-target={auto,syslog,stderr,file:ШЛЯХ,newfile:ШЛЯХ}\n"
+"                                        Вказати журнал\n"
 "      --log-meta[=BOOL]                 Додати повідомлення про місце у коді "
 "до повідомлень журналу\n"
 "      --log-time[=BOOL]                 Додати час до повідомлень журналу\n"
@@ -583,11 +632,11 @@ msgstr ""
 "  -n                                    Не завантажувати типовий файл "
 "скрипту\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:245
 msgid "--daemonize expects boolean argument"
 msgstr "Для параметра --daemonize слід вказувати булівський аргумент"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:253
 msgid "--fail expects boolean argument"
 msgstr "Для параметра --fail слід вказувати булівський аргумент"
 
@@ -604,163 +653,167 @@ msgstr ""
 msgid "--high-priority expects boolean argument"
 msgstr "Для параметра --high-priority слід вказувати булівський аргумент"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:284
 msgid "--realtime expects boolean argument"
 msgstr "Для параметра --realtime слід вказувати булівський аргумент"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:292
 msgid "--disallow-module-loading expects boolean argument"
 msgstr ""
 "Для параметра --disallow-module-loading слід вказувати булівський аргумент"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:300
 msgid "--disallow-exit expects boolean argument"
 msgstr "Для параметра --disallow-exit слід вказувати булівський аргумент"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:308
 msgid "--use-pid-file expects boolean argument"
 msgstr "Для параметра --use-pid-file слід вказувати булівський аргумент"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
-msgstr "Журнал вказано неправильно: можливі варіанти «syslog», «stderr» і «auto»."
+#: ../src/daemon/cmdline.c:326
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>', 'newfile:<path>'."
+msgstr ""
+"Журнал вказано неправильно: можливі варіанти «syslog», «stderr», «auto» і "
+"чинна назва файла «file:<шлях>» або «newfile:<шлях>»."
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:333
 msgid "--log-time expects boolean argument"
 msgstr "Для параметра --log-time слід вказувати булівський аргумент"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:341
 msgid "--log-meta expects boolean argument"
 msgstr "Для параметра --log-meta слід вказувати булівський аргумент"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:361
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "Некоректний метод зміни частотних характеристик «%s»."
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:368
 msgid "--system expects boolean argument"
 msgstr "Для параметра --system слід вказувати булівський аргумент"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:376
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "Для параметра --no-cpu-limit слід вказувати булівський аргумент"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:384
 msgid "--disable-shm expects boolean argument"
 msgstr "Для параметра --disable-shm слід вказувати булівський аргумент"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "Назва: %s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "Дані щодо модуля недоступні\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "Версія: %s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "Опис: %s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "Автор: %s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "Використання: %s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "Завантаження при: %s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
 msgstr "ПОПЕРЕДЖЕННЯ ПРО ЗАСТАРІЛІСТЬ: %s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "Шлях: %s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Некоректний журнал «%s»."
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:322
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Некоректний рівень журналювання «%s»."
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:337
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Некоректний метод зміни частотних характеристик «%s»."
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:359
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] Некоректне значення rlimit «%s»."
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] rlimit не підтримується на цій платформі."
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:379
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Некоректний формат фрагмента «%s»."
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:397 ../src/daemon/daemon-conf.c:415
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Некоректна частота вибірки «%s»."
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:438
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Некоректні канали фрагмента «%s»."
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:455
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] Некоректна карта каналів «%s»'."
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:472
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Некоректна кількість фрагментів «%s»."
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:489
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Некоректний розмір фрагмента «%s»."
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:506
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Некоректний рівень nice «%s»."
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:549
+#, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] Некоректний тип сервера «%s»."
+
+#: ../src/daemon/daemon-conf.c:662
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Не вдалося відкрити файл налаштувань: %s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:678
 msgid ""
 "The specified default channel map has a different number of channels than "
 "the specified default number of channels."
@@ -768,12 +821,12 @@ msgstr ""
 "У вказаній типовій карті каналів визначається інша кількість каналів, ніж "
 "типова кількість каналів."
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:764
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Прочитано з файла налаштувань: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:54
 msgid "Cleaning up privileges."
 msgstr "Позбуваємося прав доступу."
 
@@ -785,6 +838,14 @@ msgstr "Звукова система PulseAudio"
 msgid "Start the PulseAudio Sound System"
 msgstr "Запустити звукову систему PulseAudio"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "Правила маршрутизації звукової системи PulseAudio у KDE"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "Запустити звукову систему PulseAudio з правилами маршрутизації KDE"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "Моно"
@@ -814,8 +875,8 @@ msgid "Rear Right"
 msgstr "Задній правий"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "Ð\94жеÑ\80ело Ð½Ð¸Ð·Ñ\8cкиÑ\85 Ñ\87аÑ\81Ñ\82оÑ\82"
+msgid "Subwoofer"
+msgstr "Ð\9dизÑ\8cкоÑ\87аÑ\81Ñ\82оÑ\82ний Ð´Ð¸Ð½Ð°Ð¼Ñ\96к"
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -989,9 +1050,10 @@ msgstr "Верхній задній лівий"
 msgid "Top Rear Right"
 msgstr "Верхній задній правий"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:122
 msgid "(invalid)"
 msgstr "(некоректний)"
 
@@ -1019,331 +1081,351 @@ msgstr "Об'ємний 5.1"
 msgid "Surround 7.1"
 msgstr "Об'ємний 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "Гаразд"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "Доступ заборонено"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "Невідома команда"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "Некоректний аргумент"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "Об’єкт існує"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "Такого об’єкта не існує"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "У з'єднанні відмовлено"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "Помилка протоколу"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "Перевищення часу очікування"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "Не вказано ключа розпізнавання"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "Внутрішня помилка"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "З’єднання перервано"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "Об’єкт вилучено"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "Некоректний сервер"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "Спроба ініціалізації модуля завершилася невдало"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "Стан помилки"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "Немає даних"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "Несумісна версія протоколу"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "Завеликий"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "Не підтримується"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "Помилка з невідомим кодом"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "Такого додатка немає"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "Застарілі функціональні можливості"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "Відсутня реалізація"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "Клієнт розгалужено"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
 msgstr "Помилка вводу/виводу"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
 msgstr "Пристрій або ресурс зайнято"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uкан. %uГц"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f ГБ"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f МБ"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f кБ"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u Б"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "Спроба виконання XOpenDisplay() завершилася невдало"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+msgid "xcb_connect() failed"
+msgstr "помилка xcb_connect()"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr "xcb_connection_has_error() повернуто true"
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "Не вдалося обробити дані куки"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Не вдалося відкрити файл налаштування «%s»: %s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
-msgstr "Куків не завантажено. Буде виконано спробу з’єднання за їх відсутності."
+msgstr ""
+"Куків не завантажено. Буде виконано спробу з’єднання за їх відсутності."
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:609
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:664
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1365
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "Отримано повідомлення про невідомий додаток «%s»"
 
-#: ../src/utils/pacat.c:108
+#: ../src/utils/pacat.c:116
 #, c-format
 msgid "Failed to drain stream: %s"
 msgstr "Не вдалося створити тунель для потоку: %s"
 
-#: ../src/utils/pacat.c:113
+#: ../src/utils/pacat.c:121
 msgid "Playback stream drained."
 msgstr "Потік відтворення тунельовано."
 
-#: ../src/utils/pacat.c:123
+#: ../src/utils/pacat.c:132
 msgid "Draining connection to server."
 msgstr "Тунельне з’єднання з сервером."
 
-#: ../src/utils/pacat.c:136
+#: ../src/utils/pacat.c:145
 #, c-format
 msgid "pa_stream_drain(): %s"
 msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
+#: ../src/utils/pacat.c:168
 #, c-format
 msgid "pa_stream_write() failed: %s"
 msgstr "Спроба виконання pa_stream_write() завершилася невдало: %s"
 
-#: ../src/utils/pacat.c:197
+#: ../src/utils/pacat.c:209
 #, c-format
 msgid "pa_stream_begin_write() failed: %s"
 msgstr "Спроба виконання pa_stream_write() завершилася невдало: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
+#: ../src/utils/pacat.c:259 ../src/utils/pacat.c:289
 #, c-format
 msgid "pa_stream_peek() failed: %s"
 msgstr "Спроба виконання pa_stream_peek() завершилася невдало: %s"
 
-#: ../src/utils/pacat.c:307
+#: ../src/utils/pacat.c:339
 msgid "Stream successfully created."
 msgstr "Потік було успішно створено."
 
-#: ../src/utils/pacat.c:310
+#: ../src/utils/pacat.c:342
 #, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
 msgstr "Спроба виконання pa_stream_get_buffer_attr() завершилася невдало: %s"
 
-#: ../src/utils/pacat.c:314
+#: ../src/utils/pacat.c:346
 #, 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:317
+#: ../src/utils/pacat.c:349
 #, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
 msgstr "Метрика буфера: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
+#: ../src/utils/pacat.c:353
 #, c-format
 msgid "Using sample spec '%s', channel map '%s'."
 msgstr "Використання частотної специфікації «%s», карта каналів «%s»."
 
-#: ../src/utils/pacat.c:325
+#: ../src/utils/pacat.c:357
 #, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
 msgstr "З’єднано з пристроєм %s (%u, %s призупинено)."
 
-#: ../src/utils/pacat.c:335
+#: ../src/utils/pacat.c:367
 #, c-format
 msgid "Stream error: %s"
 msgstr "Помилка потоку: %s"
 
-#: ../src/utils/pacat.c:345
+#: ../src/utils/pacat.c:377
 #, c-format
 msgid "Stream device suspended.%s"
 msgstr "Призупинено пристрій потоку. %s"
 
-#: ../src/utils/pacat.c:347
+#: ../src/utils/pacat.c:379
 #, c-format
 msgid "Stream device resumed.%s"
 msgstr "Відновлено пристрій потоку. %s"
 
-#: ../src/utils/pacat.c:355
+#: ../src/utils/pacat.c:387
 #, c-format
 msgid "Stream underrun.%s"
 msgstr "Недовантаження потоку. %s"
 
-#: ../src/utils/pacat.c:362
+#: ../src/utils/pacat.c:394
 #, c-format
 msgid "Stream overrun.%s"
 msgstr "Перевантаження потоку. %s"
 
-#: ../src/utils/pacat.c:369
+#: ../src/utils/pacat.c:401
 #, c-format
 msgid "Stream started.%s"
 msgstr "Потік запущено. %s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:408
 #, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
 msgstr "Потік пересунуто на пристрій %s (%u, %s призупинено). %s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:408
 msgid "not "
 msgstr "не "
 
-#: ../src/utils/pacat.c:383
+#: ../src/utils/pacat.c:415
 #, c-format
 msgid "Stream buffer attributes changed.%s"
 msgstr "Недовантаження потоку. %s"
 
-#: ../src/utils/pacat.c:415
+#: ../src/utils/pacat.c:430
+msgid "Cork request stack is empty: corking stream"
+msgstr "Стос запитів щодо блокування порожній: блокуємо потік"
+
+#: ../src/utils/pacat.c:436
+msgid "Cork request stack is empty: uncorking stream"
+msgstr "Стос запитів щодо блокування порожній: розблоковуємо потік"
+
+#: ../src/utils/pacat.c:440
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+"Попередження: отримано більше запитів щодо розблокування, ніж запитів щодо "
+"блокування!"
+
+#: ../src/utils/pacat.c:465
 #, c-format
 msgid "Connection established.%s"
 msgstr "Встановлено з’єднання. %s"
 
-#: ../src/utils/pacat.c:418
+#: ../src/utils/pacat.c:468
 #, c-format
 msgid "pa_stream_new() failed: %s"
 msgstr "Спроба виконання pa_stream_new() зазнала невдачі: %s"
 
-#: ../src/utils/pacat.c:450
+#: ../src/utils/pacat.c:506
 #, c-format
 msgid "pa_stream_connect_playback() failed: %s"
 msgstr "Спроба виконання pa_stream_connect_playback() зазнала невдачі: %s"
 
-#: ../src/utils/pacat.c:456
+#: ../src/utils/pacat.c:512
 #, c-format
 msgid "pa_stream_connect_record() failed: %s"
 msgstr "Спроба виконання pa_stream_connect_record() зазнала невдачі: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
+#: ../src/utils/pacat.c:526 ../src/utils/pactl.c:1406
 #, c-format
 msgid "Connection failure: %s"
 msgstr "Спроба встановлення з’єднання зазнала невдачі: %s"
 
-#: ../src/utils/pacat.c:503
+#: ../src/utils/pacat.c:559
 msgid "Got EOF."
 msgstr "Отримано EOF."
 
-#: ../src/utils/pacat.c:540
+#: ../src/utils/pacat.c:596
 #, c-format
 msgid "write() failed: %s"
 msgstr "Спроба виконання write() завершилася невдало: %s"
 
-#: ../src/utils/pacat.c:561
+#: ../src/utils/pacat.c:617
 msgid "Got signal, exiting."
 msgstr "Отримано сигнал, завершення роботи."
 
-#: ../src/utils/pacat.c:575
+#: ../src/utils/pacat.c:631
 #, c-format
 msgid "Failed to get latency: %s"
 msgstr "Не вдалося отримати латентність: %s"
 
-#: ../src/utils/pacat.c:580
+#: ../src/utils/pacat.c:636
 #, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
 msgstr "Час: %0.3f сек.; Латентність: %0.0f мкс."
 
-#: ../src/utils/pacat.c:599
+#: ../src/utils/pacat.c:657
 #, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
-msgstr "Спроба виконання pa_stream_update_timing_info() завершилася невдало: %s"
+msgstr ""
+"Спроба виконання pa_stream_update_timing_info() завершилася невдало: %s"
 
-#: ../src/utils/pacat.c:609
+#: ../src/utils/pacat.c:667
 #, c-format
 msgid ""
 "%s [options]\n"
@@ -1396,68 +1478,81 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
-"%s [параметри]\n"
+"%s [options]\n"
 "\n"
 "  -h, --help                            Показати цю довідку\n"
 "      --version                         Показати дані щодо версії\n"
 "\n"
-"  -r, --record                          Створити з’єднання для запису\n"
-"  -p, --playback                        Створити з’єднання для відтворення\n"
+"  -r, --record                          Встановити з’єднання для запису\n"
+"  -p, --playback                        Встановити з’єднання для "
+"відтворення\n"
 "\n"
-"  -v, --verbose                         Увімкнути докладні повідомлення\n"
+"  -v, --verbose                         Увімкнути докладний режим\n"
 "\n"
 "  -s, --server=СЕРВЕР                   Назва сервера, з яким слід "
 "встановити з’єднання\n"
-"  -d, --device=ПРИСТРІЙ                  Назва пристрою приймача/джерела, з "
+"  -d, --device=ПРИСТРІЙ                 Назва приймача або джерела даних, з "
 "яким слід встановити з’єднання\n"
-"  -n, --client-name=Ð\9dÐ\90Ð\97Ð\92Ð\90               Ð¡Ð¿Ð¾Ñ\81Ñ\96б Ð²Ð¸ÐºÐ»Ð¸ÐºÑ\83 клієнта на сервері\n"
-"      --stream-name=Ð\9dÐ\90Ð\97Ð\92Ð\90               Ð¡Ð¿Ð¾Ñ\81Ñ\96б Ð²Ð¸ÐºÐ»Ð¸ÐºÑ\83 потоку на сервері\n"
+"  -n, --client-name=Ð\9dÐ\90Ð\97Ð\92Ð\90               Ð\9dазва Ñ\86Ñ\8cого клієнта на сервері\n"
+"      --stream-name=Ð\9dÐ\90Ð\97Ð\92Ð\90               Ð\9dазва Ñ\86Ñ\8cого потоку на сервері\n"
 "      --volume=ГУЧНІСТЬ                 Вказати початкову (лінійну) гучність "
-"у діапазоні 0..65536\n"
-"      --rate=ЧАСТОТА_ВИБІРКИ             Частота вибірки у Гц (типовим є "
-"значення 44100)\n"
-"      --format=ФОРМАТ                   Тип вибірки, можливі значення: "
-"s16le, s16be, u8, float32le,\n"
-"                                        float32be, ulaw, alaw, s32le, s32be "
-"(типовим є значення s16ne)\n"
-"      --channels=КАНАЛИ              Кількість каналів, 1 — моно, 2 — "
+"у діапазоні 0...65536\n"
+"      --rate=ЧАСТОТА ДИСКРЕТИЗАЦІЇ      Частота дискретизації у Гц (типовою "
+"є 44100)\n"
+"      --format=ФОРМАТ ДАНИХ             Тип даних, варіанти: s16le, s16be, "
+"u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be, "
+"s24le, s24be,\n"
+"                                        s24-32le, s24-32be (типовим є "
+"s16ne)\n"
+"      --channels=КІЛЬКІСТЬ КАНАЛІВ      Кількість каналів, 1 — моно, 2 — "
 "стерео\n"
-"                                        (Ñ\82иповим Ñ\94 Ð·Ð½Ð°Ñ\87еннÑ\8f 2)\n"
-"      --channel-map=КАРТА_КАНАЛІВ       Карта каналів, яку слід "
+"                                        (Ñ\82ипове Ð·Ð½Ð°Ñ\87еннÑ\8f â\80\94 2)\n"
+"      --channel-map=КАРТА КАНАЛІВ       Карта каналів, яку слід "
 "використовувати замість типової\n"
-"      --fix-format                      Визначити формат за даними приймача, "
-"з яким буде з’єднано\n"
+"      --fix-format                      Запозичити формат даних з приймача, "
+"з яким з’єднано\n"
+"                                        потік.\n"
+"      --fix-rate                        Запозичити дані щодо частоти "
+"дискретизації з приймача, з яким з’єднано\n"
 "                                        потік.\n"
-"      --fix-rate                        Визначити частоту вибірки за даними "
-"з приймача, з яким буде\n"
-"                                        з’єднано потік.\n"
-"      --fix-channels                    Визначити кількість каналів і карту "
-"каналів\n"
-"                                        за даними з приймача, з яким буде "
-"з’єднано потік.\n"
-"      --no-remix                        Не мікшувати канали.\n"
-"      --no-remap                        Розподіляти канали за індексом, а не "
-"за назвою.\n"
-"      --latency=БАЙТИ                   Надіслати запит на вказану "
-"латентність у байтах.\n"
-"      --process-time=БАЙТИ              Надіслати запит щодо вказаного часу "
-"обробки на запит у байтах.\n"
+"      --fix-channels                    Запозичити дані щодо кількості "
+"каналів та карти каналів\n"
+"                                        з приймача, з яким з’єднано потік.\n"
+"      --no-remix                        Не збільшувати і не зменшувати "
+"кількість каналів.\n"
+"      --no-remap                        Встановлювати відповідність каналів "
+"за номером, а не за назвою.\n"
+"      --latency=БАЙТИ                   Вимагати вказаної латентності у "
+"байтах.\n"
+"      --process-time=БАЙТИ              Вимагати вказаного часу обробки на "
+"запит у байтах.\n"
+"      --latency-msec=МС                 Вимагати вказаної латентності у "
+"мілісекундах.\n"
+"      --process-time-msec=МС            Вимагати вказаного часу обробки "
+"запиту у мілісекундах.\n"
 "      --property=ВЛАСТИВІСТЬ=ЗНАЧЕННЯ   Встановити для вказаної властивості "
 "вказане значення.\n"
-"      --raw                             Записати/Відтворити не оброблені "
-"дані PCM.\n"
-"      --file-format=ФОРМАТ              Записати/Відтворити форматовані дані "
-"PCM.\n"
+"      --raw                             Записувати і відтворювати "
+"неформатовані дані PCM.\n"
+"      --passthrough                     Передати дані без обробки.\n"
+"      --file-format[=FFORMAT]           Записувати і відтворювати "
+"форматовані дані PCM.\n"
 "      --list-file-formats               Показати список можливих форматів "
-"файлів.\n"
+"даних.\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:802
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1468,68 +1563,68 @@ msgstr ""
 "Зібрано з libpulse %s\n"
 "З’єднано з libpulse %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
+#: ../src/utils/pacat.c:835 ../src/utils/pactl.c:1577
 #, c-format
 msgid "Invalid client name '%s'"
 msgstr "Некоректна назва клієнта «%s»"
 
-#: ../src/utils/pacat.c:779
+#: ../src/utils/pacat.c:850
 #, c-format
 msgid "Invalid stream name '%s'"
 msgstr "Некоректна назва потоку «%s»"
 
-#: ../src/utils/pacat.c:816
+#: ../src/utils/pacat.c:887
 #, c-format
 msgid "Invalid channel map '%s'"
 msgstr "Некоректна карта каналів «%s»"
 
-#: ../src/utils/pacat.c:845
+#: ../src/utils/pacat.c:916 ../src/utils/pacat.c:930
 #, c-format
 msgid "Invalid latency specification '%s'"
 msgstr "Некоректна специфікація латентності «%s»"
 
-#: ../src/utils/pacat.c:852
+#: ../src/utils/pacat.c:923 ../src/utils/pacat.c:937
 #, c-format
 msgid "Invalid process time specification '%s'"
 msgstr "Некоректна часова специфікація «%s»"
 
-#: ../src/utils/pacat.c:864
+#: ../src/utils/pacat.c:949
 #, c-format
 msgid "Invalid property '%s'"
 msgstr "Некоректна властивість «%s»"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:968
 #, c-format
 msgid "Unknown file format %s."
 msgstr "Невідомий формат файлів %s."
 
-#: ../src/utils/pacat.c:900
+#: ../src/utils/pacat.c:987
 msgid "Invalid sample specification"
 msgstr "Некоректна частотна специфікація"
 
-#: ../src/utils/pacat.c:910
+#: ../src/utils/pacat.c:997
 #, c-format
 msgid "open(): %s"
 msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
+#: ../src/utils/pacat.c:1002
 #, c-format
 msgid "dup2(): %s"
 msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
+#: ../src/utils/pacat.c:1009
 msgid "Too many arguments."
 msgstr "Забагато аргументів."
 
-#: ../src/utils/pacat.c:933
+#: ../src/utils/pacat.c:1020
 msgid "Failed to generate sample specification for file."
 msgstr "Не вдалося створити частотну специфікацію для файла."
 
-#: ../src/utils/pacat.c:953
+#: ../src/utils/pacat.c:1046
 msgid "Failed to open audio file."
 msgstr "Не вдалося відкрити звуковий файл."
 
-#: ../src/utils/pacat.c:959
+#: ../src/utils/pacat.c:1052
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
@@ -1537,102 +1632,109 @@ msgstr ""
 "Попередження: вказану частотну специфікацію буде перезаписано специфікацією "
 "з файла."
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
+#: ../src/utils/pacat.c:1055 ../src/utils/pactl.c:1644
 msgid "Failed to determine sample specification from file."
 msgstr "Не вдалося отримати дані щодо частотної специфікації з файла."
 
-#: ../src/utils/pacat.c:971
+#: ../src/utils/pacat.c:1064
 msgid "Warning: Failed to determine channel map from file."
 msgstr "Попередження: не вдалося отримати дані щодо карти каналів з файла."
 
-#: ../src/utils/pacat.c:982
+#: ../src/utils/pacat.c:1075
 msgid "Channel map doesn't match sample specification"
 msgstr "Карта каналів не відповідає частотній специфікації"
 
-#: ../src/utils/pacat.c:993
+#: ../src/utils/pacat.c:1086
 msgid "Warning: failed to write channel map to file."
 msgstr "Попередження: не вдалося записати карту каналів до файла."
 
-#: ../src/utils/pacat.c:1008
+#: ../src/utils/pacat.c:1101
 #, c-format
-msgid "Opening a %s stream with sample specification '%s' and channel map '%s'."
-msgstr "Відкриття потоку %s з частотною специфікацією «%s» і картою каналів «%s»."
+msgid ""
+"Opening a %s stream with sample specification '%s' and channel map '%s'."
+msgstr ""
+"Відкриття потоку %s з частотною специфікацією «%s» і картою каналів «%s»."
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1102
 msgid "recording"
 msgstr "запис"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1102
 msgid "playback"
 msgstr "відтворення"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1126
+msgid "Failed to set media name."
+msgstr "Не вдалося встановити назву носія даних."
+
+#: ../src/utils/pacat.c:1133 ../src/utils/pactl.c:1994
 msgid "pa_mainloop_new() failed."
 msgstr "Спроба виконання pa_mainloop_new() завершилася невдало."
 
-#: ../src/utils/pacat.c:1054
+#: ../src/utils/pacat.c:1156
 msgid "io_new() failed."
 msgstr "Спроба виконання io_new() завершилася невдало."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
+#: ../src/utils/pacat.c:1163 ../src/utils/pactl.c:2006
 msgid "pa_context_new() failed."
 msgstr "Спроба виконання pa_context_new() завершилася невдало."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1171 ../src/utils/pactl.c:2012
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "Спроба виконання pa_context_connect() завершилася невдало: %s"
 
-#: ../src/utils/pacat.c:1075
+#: ../src/utils/pacat.c:1177
 msgid "pa_context_rttime_new() failed."
 msgstr "Спроба виконання pa_context_new() завершилася невдало."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
+#: ../src/utils/pacat.c:1184 ../src/utils/pactl.c:2017
 msgid "pa_mainloop_run() failed."
 msgstr "Спроба виконання pa_mainloop_run() завершилася невдало."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork(): %s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp(): %s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "Невдала спроба призупинки: %s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "Невдала спроба відновлення: %s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr ""
 "ПОПЕРЕДЖЕННЯ: звуковий сервер не є локальним, його не можна призупинити.\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Спроба встановлення з’єднання зазнала невдачі: %s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "Отримано сигнал SIGINT, завершення роботи.\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
-msgstr "ПОПЕРЕДЖЕННЯ: виконання дочірнього процесу було перервано з сигналом %u\n"
+msgstr ""
+"ПОПЕРЕДЖЕННЯ: виконання дочірнього процесу було перервано з сигналом %u\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1672,40 +1774,58 @@ msgstr "Спроба виконання pa_mainloop_new() завершилася
 msgid "pa_context_new() failed.\n"
 msgstr "Спроба виконання pa_context_new() завершилася невдало.\n"
 
-#: ../src/utils/pasuspender.c:298
+#: ../src/utils/pasuspender.c:302
 #, c-format
 msgid "pa_mainloop_run() failed.\n"
 msgstr "Спроба виконання pa_mainloop_run() завершилася невдало.\n"
 
-#: ../src/utils/pactl.c:135
+#: ../src/utils/pactl.c:161
 #, c-format
 msgid "Failed to get statistics: %s"
 msgstr "Не вдалося отримати статистичні дані: %s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:167
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "Зараз використано: %u блоків, що містять загалом %s байтів.\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:170
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
-msgstr "Виділено протягом виконання загалом: %u блоків, що містять %s байтів.\n"
+msgstr ""
+"Виділено протягом виконання загалом: %u блоків, що містять %s байтів.\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:173
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "Розмір кешу фрагментів: %s\n"
 
-#: ../src/utils/pactl.c:156
+#: ../src/utils/pactl.c:182
 #, c-format
 msgid "Failed to get server information: %s"
 msgstr "Не вдалося отримати дані щодо сервера: %s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:187
 #, c-format
 msgid ""
-"User name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+"Рядок сервера: %s\n"
+"Версія протоколу бібліотеки: %u\n"
+"Версія протоколу сервера: %u\n"
+"Локальний: %s\n"
+"Номер клієнта: %u\n"
+"Розмір фрагмента: %zu\n"
+
+#: ../src/utils/pactl.c:203
+#, c-format
+msgid ""
+"User Name: %s\n"
 "Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
@@ -1713,7 +1833,7 @@ msgid ""
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "Користувач: %s\n"
 "Назва вузла: %s\n"
@@ -1723,14 +1843,14 @@ msgstr ""
 "Типова карта каналів: %s\n"
 "Типовий приймач: %s\n"
 "Типове джерело: %s\n"
-"Кука: %08x\n"
+"Кука: %04x:%04x\n"
 
-#: ../src/utils/pactl.c:205
+#: ../src/utils/pactl.c:255 ../src/utils/pactl.c:897 ../src/utils/pactl.c:971
 #, c-format
 msgid "Failed to get sink information: %s"
 msgstr "Не вдалося отримати дані щодо приймача: %s"
 
-#: ../src/utils/pactl.c:221
+#: ../src/utils/pactl.c:281
 #, c-format
 msgid ""
 "Sink #%u\n"
@@ -1747,7 +1867,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1765,26 +1885,31 @@ msgstr ""
 "\tБазова гучність: %s%s%s\n"
 "\tСпостереження: %s\n"
 "\tЛатентність: %0.0f мкс, налаштовано %0.0f мкс\n"
-"\tПрапорці: %s%s%s%s%s%s\n"
+"\tПрапорці: %s%s%s%s%s%s%s\n"
 "\tВластивості:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
+#: ../src/utils/pactl.c:329 ../src/utils/pactl.c:441 ../src/utils/pactl.c:601
 #, c-format
 msgid "\tPorts:\n"
 msgstr "\tПорти:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
+#: ../src/utils/pactl.c:336 ../src/utils/pactl.c:448
 #, c-format
 msgid "\tActive Port: %s\n"
 msgstr "\tАктивний порт: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:342 ../src/utils/pactl.c:454
+#, c-format
+msgid "\tFormats:\n"
+msgstr "\tФормати:\n"
+
+#: ../src/utils/pactl.c:368 ../src/utils/pactl.c:916 ../src/utils/pactl.c:986
 #, c-format
 msgid "Failed to get source information: %s"
 msgstr "Не вдалося отримати дані щодо джерела: %s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:394
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1823,20 +1948,20 @@ msgstr ""
 "\tВластивості:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:426 ../src/utils/pactl.c:496 ../src/utils/pactl.c:539
+#: ../src/utils/pactl.c:581 ../src/utils/pactl.c:679 ../src/utils/pactl.c:680
+#: ../src/utils/pactl.c:692 ../src/utils/pactl.c:752 ../src/utils/pactl.c:753
+#: ../src/utils/pactl.c:765 ../src/utils/pactl.c:817 ../src/utils/pactl.c:818
+#: ../src/utils/pactl.c:825
 msgid "n/a"
 msgstr "н/д"
 
-#: ../src/utils/pactl.c:375
+#: ../src/utils/pactl.c:465 ../src/utils/pactl.c:872
 #, c-format
 msgid "Failed to get module information: %s"
 msgstr "Не вдалося отримати дані щодо модуля: %s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:488
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1853,12 +1978,12 @@ msgstr ""
 "\tВластивості:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
+#: ../src/utils/pactl.c:507
 #, c-format
 msgid "Failed to get client information: %s"
 msgstr "Не вдалося отримати дані щодо клієнта: %s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:533
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1873,12 +1998,12 @@ msgstr ""
 "\tВластивості:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
+#: ../src/utils/pactl.c:550
 #, c-format
 msgid "Failed to get card information: %s"
 msgstr "Не вдалося отримати дані щодо карти: %s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:573
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1895,22 +2020,36 @@ msgstr ""
 "\tВластивості:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:589
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tПрофілі:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:595
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tАктивний профіль: %s\n"
 
-#: ../src/utils/pactl.c:496
+#: ../src/utils/pactl.c:609
+#, c-format
+msgid ""
+"\t\t\tProperties:\n"
+"\t\t\t\t%s\n"
+msgstr ""
+"\t\t\tВластивості:\n"
+"\t\t\t\t%s\n"
+
+#: ../src/utils/pactl.c:614
+#, c-format
+msgid "\t\t\tPart of profile(s): %s"
+msgstr "\t\t\tЧастина профілів: %s"
+
+#: ../src/utils/pactl.c:631 ../src/utils/pactl.c:935 ../src/utils/pactl.c:1001
 #, c-format
 msgid "Failed to get sink input information: %s"
 msgstr "Не вдалося отримати відомостей щодо приймача: %s"
 
-#: ../src/utils/pactl.c:515
+#: ../src/utils/pactl.c:660
 #, c-format
 msgid ""
 "Sink Input #%u\n"
@@ -1920,6 +2059,8 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tCorked: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1937,6 +2078,8 @@ msgstr ""
 "\tПриймач: %u\n"
 "\tЧастотна специфікація: %s\n"
 "\tКарта каналів: %s\n"
+"\tФормат: %s\n"
+"\tСтан призупинення: %s\n"
 "\tСтан вимикання: %s\n"
 "\tГучність: %s\n"
 "\t        %s\n"
@@ -1947,12 +2090,12 @@ msgstr ""
 "\tВластивості:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
+#: ../src/utils/pactl.c:703 ../src/utils/pactl.c:954 ../src/utils/pactl.c:1016
 #, c-format
 msgid "Failed to get source output information: %s"
 msgstr "Не вдалося отримати дані щодо відтворення джерела: %s"
 
-#: ../src/utils/pactl.c:574
+#: ../src/utils/pactl.c:733
 #, c-format
 msgid ""
 "Source Output #%u\n"
@@ -1962,6 +2105,12 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tCorked: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
@@ -1975,18 +2124,24 @@ msgstr ""
 "\tДжерело: %u\n"
 "\tЧастотна специфікація: %s\n"
 "\tКарта каналів: %s\n"
+"\tФормат: %s\n"
+"\tСтан призупинення: %s\n"
+"\tСтан вимикання: %s\n"
+"\tГучність: %s\n"
+"\t %s\n"
+"\t баланс %0.2f\n"
 "\tЛатентність буфера: %0.0f мкс\n"
 "\tЛатентність джерела: %0.0f мкс\n"
 "\tСпосіб зміни частоти: %s\n"
 "\tВластивості:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
+#: ../src/utils/pactl.c:776
 #, c-format
 msgid "Failed to get sample information: %s"
 msgstr "Не вдалося отримати дані щодо фрагмента: %s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:803
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -2017,48 +2172,188 @@ msgstr ""
 "\tВластивості:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
+#: ../src/utils/pactl.c:833 ../src/utils/pactl.c:843
 #, c-format
 msgid "Failure: %s"
 msgstr "Помилка: %s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:879
+#, c-format
+msgid "Failed to unload module: Module %s not loaded"
+msgstr "Не вдалося вивантажити модуль: модуль %s не завантажено"
+
+#: ../src/utils/pactl.c:1042
+#, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "Не вдалося встановити формат: некоректний рядок формату %s"
+
+#: ../src/utils/pactl.c:1081
 #, c-format
 msgid "Failed to upload sample: %s"
 msgstr "Не вдалося вивантажити зразок: %s"
 
-#: ../src/utils/pactl.c:704
+#: ../src/utils/pactl.c:1098
 msgid "Premature end of file"
 msgstr "Передчасне завершення файла"
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:1118
+msgid "new"
+msgstr "створити"
+
+#: ../src/utils/pactl.c:1121
+msgid "change"
+msgstr "змінити"
+
+#: ../src/utils/pactl.c:1124
+msgid "remove"
+msgstr "вилучити"
+
+#: ../src/utils/pactl.c:1127 ../src/utils/pactl.c:1162
+msgid "unknown"
+msgstr "невідомий"
+
+#: ../src/utils/pactl.c:1135
+msgid "sink"
+msgstr "приймач"
+
+#: ../src/utils/pactl.c:1138
+msgid "source"
+msgstr "джерело"
+
+#: ../src/utils/pactl.c:1141
+msgid "sink-input"
+msgstr "вхід приймача"
+
+#: ../src/utils/pactl.c:1144
+msgid "source-output"
+msgstr "відтворення джерела"
+
+#: ../src/utils/pactl.c:1147
+msgid "module"
+msgstr "модуль"
+
+#: ../src/utils/pactl.c:1150
+msgid "client"
+msgstr "клієнт"
+
+#: ../src/utils/pactl.c:1153
+msgid "sample-cache"
+msgstr "кеш семплів"
+
+#: ../src/utils/pactl.c:1156 ../src/utils/pactl.c:1159
+msgid "server"
+msgstr "сервер"
+
+#: ../src/utils/pactl.c:1168
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr "Подія «%s» на %s №%u\n"
+
+#: ../src/utils/pactl.c:1412
 msgid "Got SIGINT, exiting."
 msgstr "Отримано сигнал SIGINT, завершення роботи."
 
-#: ../src/utils/pactl.c:869
+#: ../src/utils/pactl.c:1439
+msgid "Invalid volume specification"
+msgstr "Некоректна специфікація гучності"
+
+#: ../src/utils/pactl.c:1462
+msgid "Volume outside permissible range.\n"
+msgstr "Гучність поза межами дозволеного діапазону.\n"
+
+#: ../src/utils/pactl.c:1492 ../src/utils/pactl.c:1493
+#: ../src/utils/pactl.c:1494 ../src/utils/pactl.c:1495
+#: ../src/utils/pactl.c:1496 ../src/utils/pactl.c:1497
+#: ../src/utils/pactl.c:1498 ../src/utils/pactl.c:1499
+#: ../src/utils/pactl.c:1500 ../src/utils/pactl.c:1501
+#: ../src/utils/pactl.c:1502 ../src/utils/pactl.c:1503
+#: ../src/utils/pactl.c:1504 ../src/utils/pactl.c:1505
+#: ../src/utils/pactl.c:1506 ../src/utils/pactl.c:1507
+#: ../src/utils/pactl.c:1508 ../src/utils/pactl.c:1509
+#: ../src/utils/pactl.c:1510 ../src/utils/pactl.c:1511
+#: ../src/utils/pactl.c:1512
+msgid "[options]"
+msgstr "[параметри]"
+
+#: ../src/utils/pactl.c:1494
+msgid "[TYPE]"
+msgstr "[ТИП]"
+
+#: ../src/utils/pactl.c:1496
+msgid "FILENAME [NAME]"
+msgstr "НАЗВА_ФАЙЛА [НАЗВА]"
+
+#: ../src/utils/pactl.c:1497
+msgid "NAME [SINK]"
+msgstr "НАЗВА [ПРИЙМАЧ]"
+
+#: ../src/utils/pactl.c:1498 ../src/utils/pactl.c:1504 ../src/utils/pacmd.c:55
+#: ../src/utils/pacmd.c:65
+msgid "NAME"
+msgstr "НАЗВА"
+
+#: ../src/utils/pactl.c:1499 ../src/utils/pacmd.c:53
+msgid "NAME [ARGS ...]"
+msgstr "НАЗВА [АРГУМЕНТИ...]"
+
+#: ../src/utils/pactl.c:1500 ../src/utils/pacmd.c:54 ../src/utils/pacmd.c:62
+msgid "NAME|#N"
+msgstr "НАЗВА|НОМЕР"
+
+#: ../src/utils/pactl.c:1501 ../src/utils/pacmd.c:71
+msgid "#N SINK|SOURCE"
+msgstr "НОМЕР ПРИЙМАЧ|ДЖЕРЕЛО"
+
+#: ../src/utils/pactl.c:1502 ../src/utils/pacmd.c:58 ../src/utils/pacmd.c:72
+msgid "NAME|#N 1|0"
+msgstr "НАЗВА|НОМЕР 1|0"
+
+#: ../src/utils/pactl.c:1503 ../src/utils/pacmd.c:74
+msgid "CARD PROFILE"
+msgstr "ПРОФІЛЬ КАРТКИ"
+
+#: ../src/utils/pactl.c:1505 ../src/utils/pacmd.c:75
+msgid "NAME|#N PORT"
+msgstr "НАЗВА|НОМЕР ПОРТУ"
+
+#: ../src/utils/pactl.c:1506 ../src/utils/pacmd.c:56
+msgid "NAME|#N VOLUME"
+msgstr "НАЗВА|НОМЕР ГУЧНІСТЬ"
+
+#: ../src/utils/pactl.c:1507 ../src/utils/pacmd.c:57
+msgid "#N VOLUME"
+msgstr "НОМЕР ГУЧНІСТЬ"
+
+#: ../src/utils/pactl.c:1508
+msgid "NAME|#N 1|0|toggle"
+msgstr "НАЗВА|НОМЕР 1|0|toggle"
+
+#: ../src/utils/pactl.c:1509
+msgid "#N 1|0|toggle"
+msgstr "НОМЕР 1|0|toggle"
+
+#: ../src/utils/pactl.c:1510
+msgid "#N FORMATS"
+msgstr "НОМЕР ФОРМАТИ"
+
+#: ../src/utils/pactl.c:1511 ../src/utils/pacmd.c:76
+msgid "CARD-NAME|CARD-#N PORT OFFSET"
+msgstr "НАЗВА-КАРТКИ|№КАРТКИ ПОРТ ЗСУВ"
+
+#: ../src/utils/pactl.c:1513
+#, c-format
+msgid ""
+"\n"
+"The special names @DEFAULT_SINK@, @DEFAULT_SOURCE@ and @DEFAULT_MONITOR@\n"
+"can be used to specify the default sink, source and monitor.\n"
+msgstr ""
+"\n"
+"Спеціальними назвами, @DEFAULT_SINK@, @DEFAULT_SOURCE@ та @DEFAULT_MONITOR@,\n"
+"можна скористатися для визначення типового приймача, джерела та монітора.\n"
+
+#: ../src/utils/pactl.c:1516
 #, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2068,36 +2363,14 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [параметри] stat\n"
-"%s [параметри] list\n"
-"%s [параметри] exit\n"
-"%s [параметри] upload-sample НАЗВА_ФАЙЛА [НАЗВА]\n"
-"%s [параметри] play-sample НАЗВА [ПРИЙМАЧ]\n"
-"%s [параметри] remove-sample НАЗВА\n"
-"%s [параметри] move-sink-input ІДЕНТИФІКАТОР ПРИЙМАЧ\n"
-"%s [параметри] move-source-output ІДЕНТИФІКАТОР ДЖЕРЕЛО\n"
-"%s [параметри] load-module НАЗВА [АРГУМЕНТИ ...]\n"
-"%s [параметри] unload-module ІДЕНТИФІКАТОР\n"
-"%s [параметри] suspend-sink ПРИЙМАЧ 1|0\n"
-"%s [параметри] suspend-source ДЖЕРЕЛО 1|0\n"
-"%s [параметри] set-card-profile КАРТА ПРОФІЛЬ \n"
-"%s [параметри] set-sink-port ПРИЙМАЧ ПОРТ \n"
-"%s [параметри] set-source-port ДЖЕРЕЛО ПОРТ\n"
-"%s [параметри] set-sink-volume ПРИЙМАЧ ГУЧНІСТЬ\n"
-"%s [параметри] set-source-volume ДЖЕРЕЛО ГУЧНІСТЬ\n"
-"%s [параметри] set-sink-input-volume ВХІДПРИЙМАЧА ГУЧНІСТЬ\n"
-"%s [параметри] set-sink-mute ПРИЙМАЧ 1|0\n"
-"%s [параметри] set-source-mute ДЖЕРЕЛО 1|0\n"
-"%s [параметри] set-sink-input-mute ВХІДПРИЙМАЧА 1|0\n"
 "\n"
 "  -h, --help                            Показати цю довідку\n"
-"      --version                         Показати дані щодо версії\n"
-"\n"
+"      --version                         Показати відомості щодо версії\n"
 "  -s, --server=СЕРВЕР                   Назва сервера, з яким слід "
 "з’єднатися\n"
-"  -n, --client-name=Ð\9dÐ\90Ð\97Ð\92Ð\90               Ð¡Ð¿Ð¾Ñ\81Ñ\96б Ð²Ð¸ÐºÐ»Ð¸ÐºÑ\83 клієнта на сервері\n"
+"  -n, --client-name=Ð\9dÐ\90Ð\97Ð\92Ð\90               Ð\9dазва Ñ\86Ñ\8cого клієнта на сервері\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1557
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2108,51 +2381,60 @@ msgstr ""
 "Зібрано з libpulse %s\n"
 "З’єднано з libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
+#: ../src/utils/pactl.c:1616
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr "Нічого не вказуйте або вкажіть один з варіантів: %s"
+
+#: ../src/utils/pactl.c:1626
 msgid "Please specify a sample file to load"
 msgstr "Будь ласка, вкажіть зразковий файл для завантаження"
 
-#: ../src/utils/pactl.c:992
+#: ../src/utils/pactl.c:1639
 msgid "Failed to open sound file."
 msgstr "Не вдалося відкрити звуковий файл."
 
-#: ../src/utils/pactl.c:1004
+#: ../src/utils/pactl.c:1651
 msgid "Warning: Failed to determine sample specification from file."
 msgstr ""
 "Попередження: не вдалося отримати дані щодо частотної специфікації з файла."
 
-#: ../src/utils/pactl.c:1014
+#: ../src/utils/pactl.c:1661
 msgid "You have to specify a sample name to play"
 msgstr "Вам слід вказати назву зразкового файла, який слід відтворити"
 
-#: ../src/utils/pactl.c:1026
+#: ../src/utils/pactl.c:1673
 msgid "You have to specify a sample name to remove"
 msgstr "Вам слід вказати назву зразкового файла, який слід вилучити"
 
-#: ../src/utils/pactl.c:1035
+#: ../src/utils/pactl.c:1682
 msgid "You have to specify a sink input index and a sink"
 msgstr "Вам слід вказати індекс приймача даних і приймач"
 
-#: ../src/utils/pactl.c:1045
+#: ../src/utils/pactl.c:1692
 msgid "You have to specify a source output index and a source"
 msgstr "Вам слід вказати індекс джерела відтворення і джерело"
 
-#: ../src/utils/pactl.c:1060
+#: ../src/utils/pactl.c:1707
 msgid "You have to specify a module name and arguments."
 msgstr "Вам слід вказати назву модуля і аргументи."
 
-#: ../src/utils/pactl.c:1080
-msgid "You have to specify a module index"
-msgstr "Вам слід вказати індекс модуля"
+#: ../src/utils/pactl.c:1727
+msgid "You have to specify a module index or name"
+msgstr "Ð\92ам Ñ\81лÑ\96д Ð²ÐºÐ°Ð·Ð°Ñ\82и Ñ\96ндекÑ\81 Ð°Ð±Ð¾ Ð½Ð°Ð·Ð²Ñ\83 Ð¼Ð¾Ð´Ñ\83лÑ\8f"
 
-#: ../src/utils/pactl.c:1090
+#: ../src/utils/pactl.c:1740
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
 msgstr ""
 "Не можна вказувати більше одного приймача. Вам слід вказати булівське "
 "значення."
 
-#: ../src/utils/pactl.c:1103
+#: ../src/utils/pactl.c:1745 ../src/utils/pactl.c:1765
+msgid "Invalid suspend specification."
+msgstr "Некоректна специфікація призупинення."
+
+#: ../src/utils/pactl.c:1760
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
@@ -2160,57 +2442,100 @@ msgstr ""
 "Не можна вказувати більше одного джерела. Вам слід вказати булівське "
 "значення."
 
-#: ../src/utils/pactl.c:1115
+#: ../src/utils/pactl.c:1777
 msgid "You have to specify a card name/index and a profile name"
 msgstr "Вам слід вказати назву/індекс карти і назву профілю"
 
-#: ../src/utils/pactl.c:1126
+#: ../src/utils/pactl.c:1788
 msgid "You have to specify a sink name/index and a port name"
 msgstr "Вам слід вказати назву/індекс приймача і назву порту"
 
-#: ../src/utils/pactl.c:1137
+#: ../src/utils/pactl.c:1799
+msgid "You have to specify a sink name"
+msgstr "Вам слід вказати назву приймача"
+
+#: ../src/utils/pactl.c:1809
 msgid "You have to specify a source name/index and a port name"
 msgstr "Вам слід вказати назву/індекс джерела і назву порту"
 
-#: ../src/utils/pactl.c:1149
+#: ../src/utils/pactl.c:1820
+msgid "You have to specify a source name"
+msgstr "Вам слід вказати назву джерела"
+
+#: ../src/utils/pactl.c:1830
 msgid "You have to specify a sink name/index and a volume"
 msgstr "Вам слід вказати назву/індекс приймача і гучність"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-msgid "Invalid volume specification"
-msgstr "Некоректна специфікація гучності"
-
-#: ../src/utils/pactl.c:1166
+#: ../src/utils/pactl.c:1843
 msgid "You have to specify a source name/index and a volume"
 msgstr "Вам слід вказати назву/індекс джерела і гучність"
 
-#: ../src/utils/pactl.c:1183
+#: ../src/utils/pactl.c:1856
 msgid "You have to specify a sink input index and a volume"
 msgstr "Вам слід вказати індекс приймача даних і гучність"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1861
 msgid "Invalid sink input index"
 msgstr "Некоректний індекс вхідних даних приймача"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1872
+msgid "You have to specify a source output index and a volume"
+msgstr "Вам слід вказати номер каналу відтворення і гучність"
+
+#: ../src/utils/pactl.c:1877
+msgid "Invalid source output index"
+msgstr "Некоректний номер джерела відтворення"
+
+#: ../src/utils/pactl.c:1888
 msgid "You have to specify a sink name/index and a mute boolean"
-msgstr "Вам слід вказати назву/індекс приймача і булеве значення вимикання звуку"
+msgstr ""
+"Вам слід вказати назву/індекс приймача і булеве значення вимикання звуку"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1893 ../src/utils/pactl.c:1908
+#: ../src/utils/pactl.c:1928 ../src/utils/pactl.c:1946
+msgid "Invalid mute specification"
+msgstr "Некоректна специфікація вимикання звуку"
+
+#: ../src/utils/pactl.c:1903
 msgid "You have to specify a source name/index and a mute boolean"
-msgstr "Вам слід вказати назву/індекс джерела і булеве значення вимикання звуку"
+msgstr ""
+"Вам слід вказати назву/індекс джерела і булеве значення вимикання звуку"
 
-#: ../src/utils/pactl.c:1238
+#: ../src/utils/pactl.c:1918
 msgid "You have to specify a sink input index and a mute boolean"
-msgstr "Вам слід вказати індекс приймача даних і булеве значення вимикання звуку"
+msgstr ""
+"Вам слід вказати індекс приймача даних і булеве значення вимикання звуку"
 
-#: ../src/utils/pactl.c:1243
+#: ../src/utils/pactl.c:1923
 msgid "Invalid sink input index specification"
 msgstr "Некоректна специфікація індексу приймача даних"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1936
+msgid "You have to specify a source output index and a mute boolean"
+msgstr ""
+"Вам слід вказати номер джерела відтворення і булеве значення вимикання звуку"
+
+#: ../src/utils/pactl.c:1941
+msgid "Invalid source output index specification"
+msgstr "Некоректна специфікація номера джерела відтворення"
+
+#: ../src/utils/pactl.c:1958
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr ""
+"Вам слід вказати номер приймача та список підтримуваних каналів, "
+"відокремлених комами"
+
+#: ../src/utils/pactl.c:1970
+msgid "You have to specify a card name/index, a port name and a latency offset"
+msgstr "Вам слід вказати назву/індекс карти, назву порту і зсув латентності"
+
+#: ../src/utils/pactl.c:1977
+msgid "Could not parse latency offset"
+msgstr "Не вдалося обробити дані щодо зсуву латентності"
+
+#: ../src/utils/pactl.c:1989
 msgid "No valid command specified."
 msgstr "Не вказано коректної команди."
 
@@ -2240,105 +2565,178 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "Не вдалося обробити рядок команди.\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "Сервер: %s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "Джерело: %s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "Приймач: %s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Кука: %s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "Не вдалося обробити дані куки\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "Не вдалося зберегти дані куки\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "Не вдалося завантажити файл налаштувань клієнта.\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "Не вдалося прочитати дані налаштування середовища.\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "Не вдалося отримати FQDN.\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "Не вдалося завантажити дані куки\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "Ще не реалізовано.\n"
 
+#: ../src/utils/pacmd.c:59
+msgid "#N 1|0"
+msgstr "НОМЕР 1|0"
+
+#: ../src/utils/pacmd.c:60
+msgid "NAME|#N KEY=VALUE"
+msgstr "НАЗВА|НОМЕР КЛЮЧ=ЗНАЧЕННЯ"
+
+#: ../src/utils/pacmd.c:61
+msgid "#N KEY=VALUE"
+msgstr "НОМЕР КЛЮЧ=ЗНАЧЕННЯ"
+
+#: ../src/utils/pacmd.c:63
+msgid "#N"
+msgstr "НОМЕР"
+
+#: ../src/utils/pacmd.c:64
+msgid "NAME SINK|#N"
+msgstr "НАЗВА ПРИЙМАЧ|НОМЕР"
+
+#: ../src/utils/pacmd.c:66 ../src/utils/pacmd.c:67
+msgid "NAME FILENAME"
+msgstr "НАЗВА ФАЙЛ"
+
+#: ../src/utils/pacmd.c:68
+msgid "PATHNAME"
+msgstr "ШЛЯХ"
+
 #: ../src/utils/pacmd.c:69
+msgid "FILENAME SINK|#N"
+msgstr "НАЗВА_ФАЙЛА ПРИЙМАЧ|#N"
+
+#: ../src/utils/pacmd.c:73 ../src/utils/pacmd.c:79 ../src/utils/pacmd.c:80
+msgid "1|0"
+msgstr "1|0"
+
+#: ../src/utils/pacmd.c:77
+msgid "TARGET"
+msgstr "ПРИЗНАЧЕННЯ"
+
+#: ../src/utils/pacmd.c:78
+msgid "NUMERIC LEVEL"
+msgstr "ЧИСЛОВИЙ РІВЕНЬ"
+
+#: ../src/utils/pacmd.c:81
+msgid "FRAMES"
+msgstr "БЛОКИ"
+
+#: ../src/utils/pacmd.c:83
+#, c-format
+msgid ""
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"When no command is given pacmd starts in the interactive mode\n"
+msgstr ""
+"\n"
+"  -h, --help                            Показати цю довідку\n"
+"      --version                         Показати відомості щодо версії\n"
+"Якщо команду не буде вказано, pacmd буде запущено у інтерактивному режимі\n"
+
+#: ../src/utils/pacmd.c:131
+#, c-format
+msgid ""
+"pacmd %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"pacmd %s\n"
+"Зібрано з libpulse %s\n"
+"З’єднано з libpulse %s\n"
+
+#: ../src/utils/pacmd.c:145
 msgid "No PulseAudio daemon running, or not running as session daemon."
 msgstr ""
 "Фонову службу PulseAudio не запущено, або цю службу не запущено як фонову "
 "службу сеансу."
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:150
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:167
 #, c-format
 msgid "connect(): %s"
 msgstr "connect(): %s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:176
 msgid "Failed to kill PulseAudio daemon."
-msgstr "Спроба завершення роботи фонової служби PulseAudio завершилася невдало."
+msgstr ""
+"Спроба завершення роботи фонової служби PulseAudio завершилася невдало."
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:184
 msgid "Daemon not responding."
 msgstr "Фонова служба не відповідає."
 
-#: ../src/utils/pacmd.c:161
+#: ../src/utils/pacmd.c:264
 #, c-format
 msgid "poll(): %s"
 msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:275 ../src/utils/pacmd.c:295
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:317 ../src/utils/pacmd.c:335
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "Не вдалося зняти блокування автоматичного розгалуження."
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:567 ../src/modules/alsa/alsa-sink.c:747
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2355,7 +2753,7 @@ msgstr ""
 "Службу було викликано зі встановленим POLLOUT, але наступний виклик "
 "snd_pcm_avail() повернув 0 або інше значення < min_avail."
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:526 ../src/modules/alsa/alsa-source.c:679
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2372,227 +2770,567 @@ msgstr ""
 "Службу було викликано зі встановленим POLLIN, але наступний виклик "
 "snd_pcm_avail() повернув 0 або інше значення < min_avail."
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:193
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2273
+#: ../src/modules/alsa/alsa-mixer.c:3922
 msgid "Off"
 msgstr "Вимкнено"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2087
+msgid "Headset"
+msgstr "Гарнітура"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2092
+msgid "Handsfree"
+msgstr "Пристрій гучного зв’язку"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2097
+#: ../src/modules/alsa/alsa-mixer.c:2256 ../src/modules/alsa/alsa-mixer.c:2334
+msgid "Microphone"
+msgstr "Мікрофон"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2102
+#: ../src/modules/alsa/alsa-mixer.c:2271
+msgid "Speaker"
+msgstr "Гучномовець"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2107
+msgid "Headphone"
+msgstr "Навушники"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2112
+msgid "Portable"
+msgstr "Портативна система"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2117
+msgid "Car"
+msgstr "Автомобільна система"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2122
+msgid "HiFi"
+msgstr "HiFi"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2127
+msgid "Phone"
+msgstr "Телефон"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2135
+msgid "Bluetooth Output"
+msgstr "Bluetooth (відтворення)"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2138
+msgid "Bluetooth Input"
+msgstr "Bluetooth (вхід)"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2162
 msgid "High Fidelity Playback (A2DP)"
 msgstr "Високоточне відтворення (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2172
 msgid "High Fidelity Capture (A2DP)"
 msgstr "Високоточне захоплення (A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2182
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "Телефонний дуплекс (HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2192
+msgid "Handsfree Gateway"
+msgstr "Пристрій гучного зв’язку"
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "Звуковий сервер PulseAudio"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
 msgstr "Пристрої відтворення"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
 msgstr "Пристрої отримання"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
 msgstr "Звук на @НАЗВАВУЗЛА@"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
+#: ../src/modules/alsa/alsa-mixer.c:2251
 msgid "Input"
 msgstr "Вхід"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2252
 msgid "Docking Station Input"
 msgstr "Вхідний канал стикувальної станції"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2253
 msgid "Docking Station Microphone"
 msgstr "Мікрофон стикувальної станції"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
+#: ../src/modules/alsa/alsa-mixer.c:2254
+msgid "Docking Station Line In"
+msgstr "Вхід зарядної станції"
+
+#: ../src/modules/alsa/alsa-mixer.c:2255 ../src/modules/alsa/alsa-mixer.c:2339
+msgid "Line In"
 msgstr "Лінійний вхід"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
-msgid "Microphone"
-msgstr "Мікрофон"
+#: ../src/modules/alsa/alsa-mixer.c:2257 ../src/modules/alsa/alsa-mixer.c:2335
+msgid "Front Microphone"
+msgstr "Передній мікрофон"
+
+#: ../src/modules/alsa/alsa-mixer.c:2258 ../src/modules/alsa/alsa-mixer.c:2336
+msgid "Rear Microphone"
+msgstr "Задній мікрофон"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
+#: ../src/modules/alsa/alsa-mixer.c:2259
 msgid "External Microphone"
 msgstr "Зовнішній мікрофон"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2260 ../src/modules/alsa/alsa-mixer.c:2338
 msgid "Internal Microphone"
 msgstr "Вбудований мікрофон"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2261 ../src/modules/alsa/alsa-mixer.c:2340
 msgid "Radio"
 msgstr "Радіо"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2262 ../src/modules/alsa/alsa-mixer.c:2341
 msgid "Video"
 msgstr "Відео"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2263
 msgid "Automatic Gain Control"
 msgstr "Автоматичне керування підсиленням"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2264
 msgid "No Automatic Gain Control"
 msgstr "Без автоматичного керування підсиленням"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2265
 msgid "Boost"
 msgstr "Підсилення"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2266
 msgid "No Boost"
 msgstr "Без пісилення"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2267
 msgid "Amplifier"
 msgstr "Підсилювач"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2268
 msgid "No Amplifier"
 msgstr "Без підсилювача"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
-msgid "Analog Input"
-msgstr "Ð\90налоговиÑ\85 Ð²Ñ\85Ñ\96д"
+#: ../src/modules/alsa/alsa-mixer.c:2269
+msgid "Bass Boost"
+msgstr "Ð\9fÑ\96дÑ\81иленнÑ\8f Ð±Ð°Ñ\81Ñ\96в"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
-msgid "Analog Microphone"
-msgstr "Ð\90налоговий Ð¼Ñ\96кÑ\80оÑ\84он"
+#: ../src/modules/alsa/alsa-mixer.c:2270
+msgid "No Bass Boost"
+msgstr "Ð\91ез Ð¿Ñ\96дÑ\81иленнÑ\8f"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-msgid "Analog Line-In"
-msgstr "Аналоговий лінійний вхід"
+#: ../src/modules/alsa/alsa-mixer.c:2272 ../src/modules/alsa/alsa-mixer.c:2343
+msgid "Headphones"
+msgstr "Аналогові навушники"
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-msgid "Analog Radio"
-msgstr "Ð\90налогове Ñ\80адÑ\96о"
+#: ../src/modules/alsa/alsa-mixer.c:2333
+msgid "Analog Input"
+msgstr "Ð\90налоговиÑ\85 Ð²Ñ\85Ñ\96д"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-msgid "Analog Video"
-msgstr "Ð\90налогове Ð²Ñ\96део"
+#: ../src/modules/alsa/alsa-mixer.c:2337
+msgid "Dock Microphone"
+msgstr "Ð\9cÑ\96кÑ\80оÑ\84он Ñ\81Ñ\82икÑ\83валÑ\8cноÑ\97 Ñ\81Ñ\82анÑ\86Ñ\96Ñ\97"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
+#: ../src/modules/alsa/alsa-mixer.c:2342
 msgid "Analog Output"
 msgstr "Аналогове відтворення"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
-msgid "Analog Headphones"
-msgstr "Аналогові навушники"
-
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
+#: ../src/modules/alsa/alsa-mixer.c:2344
+msgid "LFE on Separate Mono Output"
 msgstr "Аналоговий вихід (сабвуфер)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2345
+msgid "Line Out"
+msgstr "Лінійний вихід"
+
+#: ../src/modules/alsa/alsa-mixer.c:2346
 msgid "Analog Mono Output"
 msgstr "Аналоговий моно-вихід"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981, c-format
-msgid "%s+%s"
-msgstr "%s+%s"
+#: ../src/modules/alsa/alsa-mixer.c:2347
+msgid "Speakers"
+msgstr "Гучномовці"
+
+#: ../src/modules/alsa/alsa-mixer.c:2348
+msgid "HDMI / DisplayPort"
+msgstr "HDMI / DisplayPort"
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404, c-format
-msgid "%s / %s"
-msgstr "%s / %s"
+#: ../src/modules/alsa/alsa-mixer.c:2349
+msgid "Digital Output (S/PDIF)"
+msgstr "Цифровий вихід (S/PDIF)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:2350
+msgid "Digital Input (S/PDIF)"
+msgstr "Цифровий вхід (S/PDIF)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2351
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "Цифрове передавання (S/PDIF)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3770
 msgid "Analog Mono"
 msgstr "Аналогове моно"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Analog Stereo"
 msgstr "Аналогове стерео"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Analog Surround 2.1"
 msgstr "Аналоговий об'ємний 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Analog Surround 3.0"
 msgstr "Аналоговий об'ємний 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
+#: ../src/modules/alsa/alsa-mixer.c:3774
 msgid "Analog Surround 3.1"
 msgstr "Аналоговий об'ємний 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3775
 msgid "Analog Surround 4.0"
 msgstr "Аналоговий об'ємний 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3776
 msgid "Analog Surround 4.1"
 msgstr "Аналоговий об'ємний 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3777
 msgid "Analog Surround 5.0"
 msgstr "Аналоговий об'ємний 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3778
 msgid "Analog Surround 5.1"
 msgstr "Аналоговий об'ємний 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
+#: ../src/modules/alsa/alsa-mixer.c:3779
 msgid "Analog Surround 6.0"
 msgstr "Аналоговий об'ємний 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
+#: ../src/modules/alsa/alsa-mixer.c:3780
 msgid "Analog Surround 6.1"
 msgstr "Аналоговий об'ємний 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
+#: ../src/modules/alsa/alsa-mixer.c:3781
 msgid "Analog Surround 7.0"
 msgstr "Аналоговий об'ємний 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3782
 msgid "Analog Surround 7.1"
 msgstr "Аналоговий об'ємний 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3783
+msgid "Analog 4-channel Input"
+msgstr "Аналогових 4-канальний вхід"
+
+#: ../src/modules/alsa/alsa-mixer.c:3784
 msgid "Digital Stereo (IEC958)"
 msgstr "Цифрове стерео (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "ЦиÑ\84Ñ\80овий Ð¾Ð±â\80\99Ñ\94мний 4.0 (IEC958)"
+#: ../src/modules/alsa/alsa-mixer.c:3785
+msgid "Digital Passthrough  (IEC958)"
+msgstr "ЦиÑ\84Ñ\80ове Ð¿ÐµÑ\80едаваннÑ\8f (IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3786
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "Цифровий об’ємний 4.0 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3787
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "Цифровий об’ємний 5.1 (IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3788
+msgid "Digital Surround 5.1 (IEC958/DTS)"
+msgstr "Цифровий об’ємний 5.1 (IEC958/DTS)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3789
 msgid "Digital Stereo (HDMI)"
 msgstr "Цифровий стерео (HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3790
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "Цифровий об’ємний 5.1 (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3919
 msgid "Analog Mono Duplex"
 msgstr "Аналогове двобічне моно"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
+#: ../src/modules/alsa/alsa-mixer.c:3920
 msgid "Analog Stereo Duplex"
 msgstr "Аналогове двобічне стерео"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
+#: ../src/modules/alsa/alsa-mixer.c:3921
 msgid "Digital Stereo Duplex (IEC958)"
 msgstr "Цифрове двобічне стерео (IEC958)"
 
+#: ../src/modules/alsa/alsa-mixer.c:4021
+#, c-format
+msgid "%s Output"
+msgstr "вихід %s"
+
+#: ../src/modules/alsa/alsa-mixer.c:4029
+#, c-format
+msgid "%s Input"
+msgstr "вхід %s"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"source_name=<назва джерела> source_properties=<властивості джерела> "
+"source_master=<назва джерелад для фільтрування> sink_name=<назва приймача> "
+"sink_properties=<властивості приймача> sink_master=<назва приймача для "
+"фільтрування> adjust_time=<частота коригування швидкостей у секундах> "
+"adjust_threshold=<тривалість зсуву у мс, яку слід узгодити> format=<формат "
+"даних> rate=<частота дискретизації> channels=<кількість каналів> "
+"channel_map=<карта каналів> aec_method=<реалізація обробки> "
+"aec_args=<параметри рушія AEC> save_aec=<чи слід зберігати дані AEC у /tmp> "
+"autoloaded=<визначити, чи слід завантажувати модуль у автоматичному режимі> "
+"use_volume_sharing=<yes або no> "
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr "Еквалайзер загального призначення"
+
+#: ../src/modules/module-equalizer-sink.c:76
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<назва приймача> sink_properties=<властивості приймача> "
+"sink_master=<назва приймача, з яким слід встановти з’єднання> format=<формат "
+"семплу> rate=<частота вибірки> channels=<кількість каналів> "
+"channel_map=<карта каналів> autoloaded=<визначити, чи слід завантажувати цей "
+"модуль у автоматичному режимі> use_volume_sharing=<yes або no> "
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr "autoclean=<чи слід автоматично вивантажувати невикористані фільтри?>"
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"s24le, s24be, s24-32le, s24-32be, s32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+"%s [параметри]\n"
+"\n"
+"-h, --help                            Показати цю довідку\n"
+"-v, --verbose                         Показувати діагностичні повідомлення\n"
+"      --from-rate=ЧАСТОТА ДИСКР.      Початкова частота дискретизації у Гц "
+"(типовою є 44100)\n"
+"      --from-format=ФОРМАТ ДАНИХ      Початковий формат даних (типовим є "
+"s16le)\n"
+"      --from-channels=КТЬ КАНАЛІВ     Початкова кількість каналів (типовою є "
+"1)\n"
+"      --to-rate=ЧАСТОТА ДИСКР.        Частота дискретизації після обробки у "
+"Гц (типовою є 44100)\n"
+"      --to-format=ФОРМАТ ДАНИХ        Формат даних після обробки (типовим є "
+"s16le)\n"
+"      --to-channels=КТЬ КАНАЛІВ       Кількість каналів після обробки "
+"(типовою є 1)\n"
+"      --resample-method=СПОСІБ        Спосіб зміни частоти (типовим є auto)\n"
+"      --seconds=КТЬ СЕКУНД            Початкова тривалість потоку (типовою є "
+"60)\n"
+"\n"
+"Якщо формати не буде вказано, перевірка виконуватиметься для всіх комбінацій "
+"форматів,\n"
+"у обох напрямках.\n"
+"\n"
+"Можливі формати даних: s16le, s16be, u8, float32le, float32be, ulaw, alaw,\n"
+"s24le, s24be, s24-32le, s24-32be, s32le, s32be (типовим є s16ne)\n"
+"\n"
+"Перелік можливих значень способів зміни частоти можна отримати за допомогою "
+"параметра--dump-resample-methods.\n"
+
+#: ../src/tests/resampler-test.c:356
+#, c-format
+msgid "%s %s\n"
+msgstr "%s %s\n"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr "=== %d секунд: %d Гц %d кан. (%s) -> %d Гц %d кан. (%s)"
+
+#: ../src/modules/module-virtual-surround-sink.c:49
+msgid "Virtual surround sink"
+msgstr "Віртуальний навколишній приймач"
+
+#: ../src/modules/module-virtual-surround-sink.c:53
+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> "
+"channels=<number of channels> channel_map=<channel map> "
+"use_volume_sharing=<yes or no> force_flat_volume=<yes or no> hrir=/path/to/"
+"left_hrir.wav "
+msgstr ""
+"sink_name=<назва приймача> sink_properties=<властивості приймача> "
+"master=<назва приймача для фільтрування> format=<формат семплу> rate=<частота "
+"вибірки> channels=<кількість каналів> "
+"channel_map=<карта каналів> use_volume_sharing=<yes або no> "
+"force_flat_volume=<yes або no> hrir=/шлях/до/лівого_hrir.wav "
+
+#. add on profile
+#: ../src/modules/macosx/module-coreaudio-device.c:747
+msgid "On"
+msgstr "Увімкнено"
+
+#~ msgid "Successfully dropped root privileges."
+#~ msgstr "Програма успішно позбулася прав доступу користувача root."
+
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] rlimit не підтримується на цій платформі."
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "Спроба виконання XOpenDisplay() завершилася невдало"
+
+#~ msgid ""
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
+#~ msgstr ""
+#~ "Відтворення джерела #%u\n"
+#~ "\tДрайвер: %s\n"
+#~ "\tМодуль власника: %s\n"
+#~ "\tКлієнт: %s\n"
+#~ "\tДжерело: %u\n"
+#~ "\tЧастотна специфікація: %s\n"
+#~ "\tКарта каналів: %s\n"
+#~ "\tЛатентність буфера: %0.0f мкс\n"
+#~ "\tЛатентність джерела: %0.0f мкс\n"
+#~ "\tСпосіб зміни частоти: %s\n"
+#~ "\tВластивості:\n"
+#~ "\t\t%s\n"
+
+#, fuzzy
+#~ msgid ""
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
+#~ "\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
+#~ "\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
+#~ msgstr ""
+#~ "%s [параметри] stat\n"
+#~ "%s [параметри] list\n"
+#~ "%s [параметри] exit\n"
+#~ "%s [параметри] upload-sample НАЗВА_ФАЙЛА [НАЗВА]\n"
+#~ "%s [параметри] play-sample НАЗВА [ПРИЙМАЧ]\n"
+#~ "%s [параметри] remove-sample НАЗВА\n"
+#~ "%s [параметри] move-sink-input ІДЕНТИФІКАТОР ПРИЙМАЧ\n"
+#~ "%s [параметри] move-source-output ІДЕНТИФІКАТОР ДЖЕРЕЛО\n"
+#~ "%s [параметри] load-module НАЗВА [АРГУМЕНТИ ...]\n"
+#~ "%s [параметри] unload-module ІДЕНТИФІКАТОР\n"
+#~ "%s [параметри] suspend-sink ПРИЙМАЧ 1|0\n"
+#~ "%s [параметри] suspend-source ДЖЕРЕЛО 1|0\n"
+#~ "%s [параметри] set-card-profile КАРТА ПРОФІЛЬ \n"
+#~ "%s [параметри] set-sink-port ПРИЙМАЧ ПОРТ \n"
+#~ "%s [параметри] set-source-port ДЖЕРЕЛО ПОРТ\n"
+#~ "%s [параметри] set-sink-volume ПРИЙМАЧ ГУЧНІСТЬ\n"
+#~ "%s [параметри] set-source-volume ДЖЕРЕЛО ГУЧНІСТЬ\n"
+#~ "%s [параметри] set-sink-input-volume ВХІДПРИЙМАЧА ГУЧНІСТЬ\n"
+#~ "%s [параметри] set-sink-mute ПРИЙМАЧ 1|0\n"
+#~ "%s [параметри] set-source-mute ДЖЕРЕЛО 1|0\n"
+#~ "%s [параметри] set-sink-input-mute ВХІДПРИЙМАЧА 1|0\n"
+#~ "\n"
+#~ "  -h, --help                            Показати цю довідку\n"
+#~ "      --version                         Показати дані щодо версії\n"
+#~ "\n"
+#~ "  -s, --server=СЕРВЕР                   Назва сервера, з яким слід "
+#~ "з’єднатися\n"
+#~ "  -n, --client-name=НАЗВА               Спосіб виклику клієнта на "
+#~ "сервері\n"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "Цифровий об’ємний 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "Джерело низьких частот"
index a273066..2971a35 100644 (file)
@@ -6,26 +6,23 @@
 #
 #
 # 闫丰刚 <sainry@gmail.com>, 2009.
-# Leah Liu <lliu@redhat.com>, 2009.
+# Leah Liu <lliu@redhat.com>, 2009, 2012.
+#
 msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio.master-tx\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-29 23:47+0200\n"
-"PO-Revision-Date: 2009-04-06 10:26+1000\n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:56+0000\n"
 "Last-Translator: Leah Liu <lliu@redhat.com>\n"
 "Language-Team: Simplified Chinese <zh@li.org>\n"
+"Language: \n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: KBabel 1.11.4\n"
 
-#: ../src/modules/alsa/alsa-util.c:858 ../src/pulsecore/sink.c:2629
-#, c-format
-msgid "%s %s"
-msgstr ""
-
-#: ../src/modules/alsa/alsa-util.c:1106
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
 #, c-format
 msgid ""
 "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
@@ -36,18 +33,29 @@ msgstr ""
 "snd_pcm_avail() 返回的值非常大:%lu 字节(%lu ms)。\n"
 "很可能是 ALSA 驱动程序 '%s' 中的 bug。请向 ALSA 开发者举报这个问题。"
 
-#: ../src/modules/alsa/alsa-util.c:1147
+#: ../src/modules/alsa/alsa-util.c:1179
 #, c-format
 msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s%"
-"lu ms).\n"
+"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 ""
 "snd_pcm_delay() 返回的值非常大:%li 字节(%s%lu ms)。\n"
 "很可能是 ALSA 驱动程序 '%s' 中的 bug。请向 ALSA 开发者举报这个问题。"
 
-#: ../src/modules/alsa/alsa-util.c:1194
+#: ../src/modules/alsa/alsa-util.c:1220
+#, fuzzy, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+"snd_pcm_avail() 返回的值非常大:%lu 字节(%lu ms)。\n"
+"很可能是 ALSA 驱动程序 '%s' 中的 bug。请向 ALSA 开发者举报这个问题。"
+
+#: ../src/modules/alsa/alsa-util.c:1263
 #, c-format
 msgid ""
 "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
@@ -58,296 +66,330 @@ msgstr ""
 "snd_pcm_mmap_begin() 返回的值非常大:%lu 字节(%lu ms)。\n"
 "很可能是 ALSA 驱动程序 '%s' 中的 bug。请向 ALSA 开发者举报这个问题。"
 
-#: ../src/modules/module-always-sink.c:39
+#: ../src/modules/module-always-sink.c:38
 msgid "Always keeps at least one sink loaded even if it's a null one"
-msgstr ""
+msgstr "总是保持至少载入一个漏,即使它是空的"
 
-#: ../src/modules/module-always-sink.c:83
+#: ../src/modules/module-always-sink.c:82
 msgid "Dummy Output"
-msgstr ""
+msgstr "假输出"
 
-#: ../src/modules/module-ladspa-sink.c:49
+#: ../src/modules/module-ladspa-sink.c:48
 msgid "Virtual LADSPA sink"
-msgstr ""
+msgstr "虚拟 LDASPA 漏"
 
-#: ../src/modules/module-ladspa-sink.c:53
+#: ../src/modules/module-ladspa-sink.c:52
+#, fuzzy
 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> "
+"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> "
+msgstr ""
+"sink_name=<name for the sink> sink_properties=<properties for the sink> "
+"master=<name of sink to filter> format=<sample format> rate=<sample rate> "
 "channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
-"plugin name> label=<ladspa plugin label> control=<comma seperated list of "
+"plugin name> label=<ladspa plugin label> control=<comma separated list of "
 "input control values>"
-msgstr ""
 
-#: ../src/modules/module-null-sink.c:55
+#: ../src/modules/module-null-sink.c:49
 msgid "Clocked NULL sink"
-msgstr ""
+msgstr "定时的空漏"
 
-#: ../src/modules/module-null-sink.c:291
-#, fuzzy
+#: ../src/modules/module-null-sink.c:284
 msgid "Null Output"
-msgstr "输出 %s"
+msgstr "空输出"
 
-#: ../src/pulsecore/sink.c:2613
-msgid "Internal Audio"
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
 msgstr "内部音频"
 
-#: ../src/pulsecore/sink.c:2618
+#: ../src/pulsecore/sink.c:3354
 msgid "Modem"
 msgstr "调制解调器"
 
-#: ../src/daemon/ltdl-bind-now.c:124
+#: ../src/daemon/ltdl-bind-now.c:127
 msgid "Failed to find original lt_dlopen loader."
 msgstr "查找原始 lt_dlopen 加载器失败。"
 
-#: ../src/daemon/ltdl-bind-now.c:129
+#: ../src/daemon/ltdl-bind-now.c:132
 msgid "Failed to allocate new dl loader."
 msgstr "分配新的 dl 加载器失败。"
 
-#: ../src/daemon/ltdl-bind-now.c:142
+#: ../src/daemon/ltdl-bind-now.c:145
 msgid "Failed to add bind-now-loader."
 msgstr "添加 bind-now-loader 失败。"
 
-#: ../src/daemon/main.c:141
+#: ../src/daemon/main.c:139
 #, c-format
 msgid "Got signal %s."
 msgstr "获得信号%s"
 
-#: ../src/daemon/main.c:168
+#: ../src/daemon/main.c:166
 msgid "Exiting."
 msgstr "退出"
 
-#: ../src/daemon/main.c:186
+#: ../src/daemon/main.c:184
 #, c-format
 msgid "Failed to find user '%s'."
 msgstr "找不到用户 `%s' "
 
-#: ../src/daemon/main.c:191
+#: ../src/daemon/main.c:189
 #, c-format
 msgid "Failed to find group '%s'."
 msgstr "找不到用户组 `%s'"
 
-#: ../src/daemon/main.c:195
+#: ../src/daemon/main.c:193
 #, c-format
 msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
 msgstr "发现用户'%s' (UID %lu)和组'%s' (GID %lu)."
 
-#: ../src/daemon/main.c:200
+#: ../src/daemon/main.c:198
 #, c-format
 msgid "GID of user '%s' and of group '%s' don't match."
 msgstr "用户'%s'与组'%s'的GID不匹配."
 
-#: ../src/daemon/main.c:205
+#: ../src/daemon/main.c:203
 #, c-format
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "用户'%s'的主文件夹不是'%s',忽略。"
 
-#: ../src/daemon/main.c:208 ../src/daemon/main.c:213
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "创建'%s'失败: %s"
 
-#: ../src/daemon/main.c:220
+#: ../src/daemon/main.c:218
 #, c-format
 msgid "Failed to change group list: %s"
 msgstr "更改组列表失败:%s"
 
-#: ../src/daemon/main.c:236
+#: ../src/daemon/main.c:234
 #, c-format
 msgid "Failed to change GID: %s"
 msgstr "更改GID失败:%s"
 
-#: ../src/daemon/main.c:252
+#: ../src/daemon/main.c:250
 #, c-format
 msgid "Failed to change UID: %s"
 msgstr "更改UID失败:%s"
 
-#: ../src/daemon/main.c:271
+#: ../src/daemon/main.c:269
 msgid "Successfully dropped root privileges."
 msgstr "成功放弃root权限。"
 
-#: ../src/daemon/main.c:279
+#: ../src/daemon/main.c:277
 msgid "System wide mode unsupported on this platform."
 msgstr "此平台不支持system-wide模式。"
 
-#: ../src/daemon/main.c:297
+#: ../src/daemon/main.c:295
 #, c-format
 msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) 失败:%s"
 
-#: ../src/daemon/main.c:474
+#: ../src/daemon/main.c:496
 msgid "Failed to parse command line."
 msgstr "分析命令行失败。"
 
-#: ../src/daemon/main.c:541
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
 msgid "Daemon not running"
 msgstr "后台程序没有运行"
 
-#: ../src/daemon/main.c:543
+#: ../src/daemon/main.c:613
 #, c-format
 msgid "Daemon running as PID %u"
 msgstr "后台程序正在运行,PID %u"
 
-#: ../src/daemon/main.c:553
+#: ../src/daemon/main.c:628
 #, c-format
 msgid "Failed to kill daemon: %s"
 msgstr "杀死后台程序失败:%s"
 
-#: ../src/daemon/main.c:571
+#: ../src/daemon/main.c:657
 msgid ""
 "This program is not intended to be run as root (unless --system is "
 "specified)."
 msgstr "不应以root身份运行本程序(除非指定 --system)。"
 
-#: ../src/daemon/main.c:573
+#: ../src/daemon/main.c:660
 msgid "Root privileges required."
 msgstr "需要 root 权限。"
 
-#: ../src/daemon/main.c:578
+#: ../src/daemon/main.c:667
 msgid "--start not supported for system instances."
 msgstr "系统实例不支持 --start。"
 
-#: ../src/daemon/main.c:583
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
 msgid "Running in system mode, but --disallow-exit not set!"
 msgstr "正在以系统模式运行,但是 --disallow-exit 未设定!"
 
-#: ../src/daemon/main.c:586
+#: ../src/daemon/main.c:721
 msgid "Running in system mode, but --disallow-module-loading not set!"
 msgstr "正在以系统模式运行,但是 --disallow-module-loading 未设定!"
 
-#: ../src/daemon/main.c:589
+#: ../src/daemon/main.c:724
 msgid "Running in system mode, forcibly disabling SHM mode!"
 msgstr "正在以系统模式运行,强制禁用SHM模式!"
 
-#: ../src/daemon/main.c:594
+#: ../src/daemon/main.c:729
 msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr "正在以系统模式运行,强制禁用退出空闲时间!"
 
-#: ../src/daemon/main.c:621
+#: ../src/daemon/main.c:757
 msgid "Failed to acquire stdio."
 msgstr "获取stdio失败。"
 
-#: ../src/daemon/main.c:627
-#, c-format
-msgid "pipe failed: %s"
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
 msgstr "管道失败:%s"
 
-#: ../src/daemon/main.c:632
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
 #, c-format
 msgid "fork() failed: %s"
 msgstr "fork()失败:%s"
 
-#: ../src/daemon/main.c:646 ../src/utils/pacat.c:508
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
 #, c-format
 msgid "read() failed: %s"
 msgstr "read()失败:%s"
 
-#: ../src/daemon/main.c:652
+#: ../src/daemon/main.c:789
 msgid "Daemon startup failed."
 msgstr "后台程序启动失败。"
 
-#: ../src/daemon/main.c:654
+#: ../src/daemon/main.c:791
 msgid "Daemon startup successful."
 msgstr "后台程序启动成功。"
 
-#: ../src/daemon/main.c:731
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read()失败:%s"
+
+#: ../src/daemon/main.c:901
 #, c-format
 msgid "This is PulseAudio %s"
 msgstr "这是 PulseAudio %s"
 
-#: ../src/daemon/main.c:732
+#: ../src/daemon/main.c:902
 #, c-format
 msgid "Compilation host: %s"
 msgstr "编译主机:%s"
 
-#: ../src/daemon/main.c:733
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "编译CFLAGS:%s"
 
-#: ../src/daemon/main.c:736
+#: ../src/daemon/main.c:906
 #, c-format
 msgid "Running on host: %s"
 msgstr "正在主机上运行:%s"
 
-#: ../src/daemon/main.c:739
+#: ../src/daemon/main.c:909
 #, c-format
 msgid "Found %u CPUs."
 msgstr "找到 %u CPU。"
 
-#: ../src/daemon/main.c:741
+#: ../src/daemon/main.c:911
 #, c-format
 msgid "Page size is %lu bytes"
 msgstr "页面大小为%lu字节"
 
-#: ../src/daemon/main.c:744
+#: ../src/daemon/main.c:914
 msgid "Compiled with Valgrind support: yes"
 msgstr "编译启用Valgrind支持:是"
 
-#: ../src/daemon/main.c:746
+#: ../src/daemon/main.c:916
 msgid "Compiled with Valgrind support: no"
 msgstr "编译启用Valgrind支持:否"
 
-#: ../src/daemon/main.c:749
+#: ../src/daemon/main.c:919
 #, c-format
 msgid "Running in valgrind mode: %s"
 msgstr "正在以valgrind模式运行:%s"
 
-#: ../src/daemon/main.c:752
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "正在主机上运行:%s"
+
+#: ../src/daemon/main.c:924
 msgid "Optimized build: yes"
 msgstr "优化生成:是"
 
-#: ../src/daemon/main.c:754
+#: ../src/daemon/main.c:926
 msgid "Optimized build: no"
 msgstr "优化生成:否"
 
-#: ../src/daemon/main.c:758
+#: ../src/daemon/main.c:930
 msgid "NDEBUG defined, all asserts disabled."
 msgstr "拒绝 NDEBUG,禁用所有 assert"
 
-#: ../src/daemon/main.c:760
+#: ../src/daemon/main.c:932
 msgid "FASTPATH defined, only fast path asserts disabled."
 msgstr "拒绝 FASTPATH,只禁用快速路径 assert。"
 
-#: ../src/daemon/main.c:762
+#: ../src/daemon/main.c:934
 msgid "All asserts enabled."
 msgstr "启用所有 assert。"
 
-#: ../src/daemon/main.c:766
+#: ../src/daemon/main.c:938
 msgid "Failed to get machine ID"
 msgstr "获取machine ID失败"
 
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:941
 #, c-format
 msgid "Machine ID is %s."
 msgstr "machine ID是%s。"
 
-#: ../src/daemon/main.c:773
-#, fuzzy, c-format
+#: ../src/daemon/main.c:945
+#, c-format
 msgid "Session ID is %s."
-msgstr "machine ID是%s。"
+msgstr "会话 ID %s。"
 
-#: ../src/daemon/main.c:779
+#: ../src/daemon/main.c:951
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "正在使用运行时文件夹%s。"
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:956
 #, c-format
 msgid "Using state directory %s."
 msgstr "正在使用状态文件夹%s。"
 
-#: ../src/daemon/main.c:787
-#, fuzzy, c-format
+#: ../src/daemon/main.c:959
+#, c-format
 msgid "Using modules directory %s."
-msgstr "正在使用运行时文件夹%s。"
+msgstr "正在使用模块目录 %s。"
 
-#: ../src/daemon/main.c:789
+#: ../src/daemon/main.c:961
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "正在以系统模式运行:%s"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:964
 msgid ""
 "OK, so you are running PA in system mode. Please note that you most likely "
 "shouldn't be doing that.\n"
@@ -356,47 +398,51 @@ msgid ""
 "Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an "
 "explanation why system mode is usually a bad idea."
 msgstr ""
+"确定,那么您正在系统模式中运行 PA。请注意:您很可能不应该这样做。\n"
+"如果您无论如何都这样做了,那么出现意外情况就是您的问题。\n"
+"在文章 http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode 中解释了为什么系"
+"统模式通常不是个好主意。"
 
-#: ../src/daemon/main.c:809
+#: ../src/daemon/main.c:981
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create()失败。"
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:991
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "新鲜的高分辨率计时器开锅了!吃个饱!"
 
-#: ../src/daemon/main.c:821
+#: ../src/daemon/main.c:993
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
-msgstr "老兄,的内核真臭!现在流行的是启用了高分辩率计分器的Linux!"
+msgstr "老兄,的内核真臭!现在流行的是启用了高分辩率计分器的Linux!"
 
-#: ../src/daemon/main.c:844
+#: ../src/daemon/main.c:1011
 msgid "pa_core_new() failed."
 msgstr "pa_core_new()失败。"
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:1087
 msgid "Failed to initialize daemon."
 msgstr "后台程序初始化失败。"
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:1092
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "后台程序启动未加载任何模块,拒绝工作。"
 
-#: ../src/daemon/main.c:926
+#: ../src/daemon/main.c:1130
 msgid "Daemon startup complete."
 msgstr "后台程序启动完成。"
 
-#: ../src/daemon/main.c:932
+#: ../src/daemon/main.c:1136
 msgid "Daemon shutdown initiated."
 msgstr "开始关闭后台程序。"
 
-#: ../src/daemon/main.c:954
+#: ../src/daemon/main.c:1167
 msgid "Daemon terminated."
 msgstr "后台程序已终止。"
 
-#: ../src/daemon/cmdline.c:115
-#, c-format
+#: ../src/daemon/cmdline.c:113
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -433,15 +479,13 @@ msgid ""
 "      --exit-idle-time=SECS             Terminate the daemon when idle and "
 "this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle "
-"and\n"
-"                                        this time passed\n"
 "      --scache-idle-time=SECS           Unload autoloaded samples when idle "
 "and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
-"      --log-target={auto,syslog,stderr} Specify the log target\n"
+"      --log-target={auto,syslog,stderr,file: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"
@@ -522,15 +566,15 @@ msgstr ""
 "\n"
 "  -n                                    不加载默认的脚本文件\n"
 
-#: ../src/daemon/cmdline.c:247
+#: ../src/daemon/cmdline.c:244
 msgid "--daemonize expects boolean argument"
 msgstr "--daemonize 期待布尔参数"
 
-#: ../src/daemon/cmdline.c:254
+#: ../src/daemon/cmdline.c:251
 msgid "--fail expects boolean argument"
 msgstr "--fail 期待布尔参数"
 
-#: ../src/daemon/cmdline.c:264
+#: ../src/daemon/cmdline.c:261
 msgid ""
 "--log-level expects log level argument (either numeric in range 0..4 or one "
 "of debug, info, notice, warn, error)."
@@ -538,180 +582,182 @@ msgstr ""
 "--log-level 期待日志级别参数(可以是数字0~4或者debug,info,notice,warn,"
 "error中的一个)"
 
-#: ../src/daemon/cmdline.c:276
+#: ../src/daemon/cmdline.c:273
 msgid "--high-priority expects boolean argument"
 msgstr "--high-priority 期待布尔参数"
 
-#: ../src/daemon/cmdline.c:283
+#: ../src/daemon/cmdline.c:280
 msgid "--realtime expects boolean argument"
 msgstr "--realtime 期待布尔参数"
 
-#: ../src/daemon/cmdline.c:290
+#: ../src/daemon/cmdline.c:287
 msgid "--disallow-module-loading expects boolean argument"
 msgstr "--disallow-module-loading 期待布尔参数"
 
-#: ../src/daemon/cmdline.c:297
+#: ../src/daemon/cmdline.c:294
 msgid "--disallow-exit expects boolean argument"
 msgstr "--disallow-exit 需要布尔值参数"
 
-#: ../src/daemon/cmdline.c:304
+#: ../src/daemon/cmdline.c:301
 msgid "--use-pid-file expects boolean argument"
 msgstr "--use-pid-file 期待布尔参数"
 
-#: ../src/daemon/cmdline.c:321
-msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+#: ../src/daemon/cmdline.c:318
+#, fuzzy
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
 msgstr "无效的日志目标:从syslog,stderr和auto中选取一个"
 
-#: ../src/daemon/cmdline.c:328
+#: ../src/daemon/cmdline.c:325
 msgid "--log-time expects boolean argument"
 msgstr "--log-time 需要布尔值参数"
 
-#: ../src/daemon/cmdline.c:335
+#: ../src/daemon/cmdline.c:332
 msgid "--log-meta expects boolean argument"
 msgstr "--log-meta 需要布尔值参数"
 
-#: ../src/daemon/cmdline.c:354
+#: ../src/daemon/cmdline.c:351
 #, c-format
 msgid "Invalid resample method '%s'."
 msgstr "无效的重采样方法'%s'。"
 
-#: ../src/daemon/cmdline.c:361
+#: ../src/daemon/cmdline.c:358
 msgid "--system expects boolean argument"
 msgstr "--system 期待布尔参数"
 
-#: ../src/daemon/cmdline.c:368
+#: ../src/daemon/cmdline.c:365
 msgid "--no-cpu-limit expects boolean argument"
 msgstr "--no-cpu-limit 期待布尔参数"
 
-#: ../src/daemon/cmdline.c:375
+#: ../src/daemon/cmdline.c:372
 msgid "--disable-shm expects boolean argument"
 msgstr "--disable-shm 期待布尔参数"
 
-#: ../src/daemon/dumpmodules.c:60
+#: ../src/daemon/dumpmodules.c:59
 #, c-format
 msgid "Name: %s\n"
 msgstr "名称:%s\n"
 
-#: ../src/daemon/dumpmodules.c:63
+#: ../src/daemon/dumpmodules.c:62
 #, c-format
 msgid "No module information available\n"
 msgstr "没有可用的模块信息\n"
 
-#: ../src/daemon/dumpmodules.c:66
+#: ../src/daemon/dumpmodules.c:65
 #, c-format
 msgid "Version: %s\n"
 msgstr "版本号:%s\n"
 
-#: ../src/daemon/dumpmodules.c:68
+#: ../src/daemon/dumpmodules.c:67
 #, c-format
 msgid "Description: %s\n"
 msgstr "描述:%s\n"
 
-#: ../src/daemon/dumpmodules.c:70
+#: ../src/daemon/dumpmodules.c:69
 #, c-format
 msgid "Author: %s\n"
 msgstr "作者:%s\n"
 
-#: ../src/daemon/dumpmodules.c:72
+#: ../src/daemon/dumpmodules.c:71
 #, c-format
 msgid "Usage: %s\n"
 msgstr "用法:%s\n"
 
-#: ../src/daemon/dumpmodules.c:73
+#: ../src/daemon/dumpmodules.c:72
 #, c-format
 msgid "Load Once: %s\n"
 msgstr "加载一次:%s\n"
 
-#: ../src/daemon/dumpmodules.c:75
+#: ../src/daemon/dumpmodules.c:74
 #, c-format
 msgid "DEPRECATION WARNING: %s\n"
-msgstr ""
+msgstr "反对警告:%s\n"
 
-#: ../src/daemon/dumpmodules.c:79
+#: ../src/daemon/dumpmodules.c:78
 #, c-format
 msgid "Path: %s\n"
 msgstr "路径:%s\n"
 
-#: ../src/daemon/daemon-conf.c:232
+#: ../src/daemon/daemon-conf.c:275
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] 无效的日志目标'%s'。"
 
-#: ../src/daemon/daemon-conf.c:248
+#: ../src/daemon/daemon-conf.c:291
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] 无效的日志级别'%s'。"
 
-#: ../src/daemon/daemon-conf.c:264
+#: ../src/daemon/daemon-conf.c:307
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] 无效的重采样方法'%s'。"
 
-#: ../src/daemon/daemon-conf.c:287
+#: ../src/daemon/daemon-conf.c:330
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] 无效的rlimit '%s'。"
 
-#: ../src/daemon/daemon-conf.c:294
-#, c-format
-msgid "[%s:%u] rlimit not supported on this platform."
-msgstr "[%s:%u] 此平台不支持rlimit。"
-
-#: ../src/daemon/daemon-conf.c:310
+#: ../src/daemon/daemon-conf.c:351
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] 无效的样品格式'%s'。"
 
-#: ../src/daemon/daemon-conf.c:328
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] 无效的样品率'%s'。"
 
-#: ../src/daemon/daemon-conf.c:352
+#: ../src/daemon/daemon-conf.c:413
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] 无效的样品通道'%s'。"
 
-#: ../src/daemon/daemon-conf.c:370
+#: ../src/daemon/daemon-conf.c:431
 #, c-format
 msgid "[%s:%u] Invalid channel map '%s'."
 msgstr "[%s:%u] 无效频道地图 '%s'。"
 
-#: ../src/daemon/daemon-conf.c:388
+#: ../src/daemon/daemon-conf.c:449
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] 无效的分段数'%s'。"
 
-#: ../src/daemon/daemon-conf.c:406
+#: ../src/daemon/daemon-conf.c:467
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] 无效的分段大小'%s'。"
 
-#: ../src/daemon/daemon-conf.c:424
+#: ../src/daemon/daemon-conf.c:485
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] 无效的nice level '%s'。"
 
-#: ../src/daemon/daemon-conf.c:546
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] 无效的样品率'%s'。"
+
+#: ../src/daemon/daemon-conf.c:641
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "打开配置文件失败:%s"
 
-#: ../src/daemon/daemon-conf.c:562
+#: ../src/daemon/daemon-conf.c:657
 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:638
+#: ../src/daemon/daemon-conf.c:743
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### 从配置文件读取:%s ###\n"
 
-#: ../src/daemon/caps.c:62
-#, fuzzy
+#: ../src/daemon/caps.c:58
 msgid "Cleaning up privileges."
-msgstr "正在取消 root 特权。"
+msgstr "取消特权。"
 
 #: ../src/daemon/pulseaudio.desktop.in.h:1
 msgid "PulseAudio Sound System"
@@ -721,6 +767,16 @@ msgstr "PulseAudio 声音系统"
 msgid "Start the PulseAudio Sound System"
 msgstr "启动 PulseAudio 声音系统"
 
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio 声音系统"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "启动 PulseAudio 声音系统"
+
 #: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
 msgid "Mono"
 msgstr "单声道"
@@ -750,8 +806,8 @@ msgid "Rear Right"
 msgstr "右后"
 
 #: ../src/pulse/channelmap.c:115
-msgid "Low Frequency Emmiter"
-msgstr "低频脉冲"
+msgid "Subwoofer"
+msgstr ""
 
 #: ../src/pulse/channelmap.c:117
 msgid "Front Left-of-center"
@@ -925,9 +981,10 @@ msgstr "上左后"
 msgid "Top Rear Right"
 msgstr "上右后"
 
-#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:170
-#: ../src/pulse/volume.c:295 ../src/pulse/volume.c:321
-#: ../src/pulse/volume.c:341 ../src/pulse/volume.c:371
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
 msgid "(invalid)"
 msgstr "(无效)"
 
@@ -955,336 +1012,348 @@ msgstr "环绕 5.1"
 msgid "Surround 7.1"
 msgstr "环绕 7.1"
 
-#: ../src/pulse/error.c:43
+#: ../src/pulse/error.c:40
 msgid "OK"
 msgstr "确定"
 
-#: ../src/pulse/error.c:44
+#: ../src/pulse/error.c:41
 msgid "Access denied"
 msgstr "拒绝访问"
 
-#: ../src/pulse/error.c:45
+#: ../src/pulse/error.c:42
 msgid "Unknown command"
 msgstr "未知命令"
 
-#: ../src/pulse/error.c:46
+#: ../src/pulse/error.c:43
 msgid "Invalid argument"
 msgstr "无效参数"
 
-#: ../src/pulse/error.c:47
+#: ../src/pulse/error.c:44
 msgid "Entity exists"
 msgstr "实体存在"
 
-#: ../src/pulse/error.c:48
+#: ../src/pulse/error.c:45
 msgid "No such entity"
 msgstr "没有该实体"
 
-#: ../src/pulse/error.c:49
+#: ../src/pulse/error.c:46
 msgid "Connection refused"
 msgstr "拒绝连接"
 
-#: ../src/pulse/error.c:50
+#: ../src/pulse/error.c:47
 msgid "Protocol error"
 msgstr "协议错误"
 
-#: ../src/pulse/error.c:51
+#: ../src/pulse/error.c:48
 msgid "Timeout"
 msgstr "超时"
 
-#: ../src/pulse/error.c:52
+#: ../src/pulse/error.c:49
 msgid "No authorization key"
 msgstr "没有授权密钥"
 
-#: ../src/pulse/error.c:53
+#: ../src/pulse/error.c:50
 msgid "Internal error"
 msgstr "内部错误"
 
-#: ../src/pulse/error.c:54
+#: ../src/pulse/error.c:51
 msgid "Connection terminated"
 msgstr "连接终止"
 
-#: ../src/pulse/error.c:55
+#: ../src/pulse/error.c:52
 msgid "Entity killed"
 msgstr "实体已杀死"
 
-#: ../src/pulse/error.c:56
+#: ../src/pulse/error.c:53
 msgid "Invalid server"
 msgstr "无效服务器"
 
-#: ../src/pulse/error.c:57
-msgid "Module initalization failed"
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
 msgstr "模块初始化失败"
 
-#: ../src/pulse/error.c:58
+#: ../src/pulse/error.c:55
 msgid "Bad state"
 msgstr "坏状态"
 
-#: ../src/pulse/error.c:59
+#: ../src/pulse/error.c:56
 msgid "No data"
 msgstr "没有数据"
 
-#: ../src/pulse/error.c:60
+#: ../src/pulse/error.c:57
 msgid "Incompatible protocol version"
 msgstr "不兼容的协议版本"
 
-#: ../src/pulse/error.c:61
+#: ../src/pulse/error.c:58
 msgid "Too large"
 msgstr "太大"
 
-#: ../src/pulse/error.c:62
+#: ../src/pulse/error.c:59
 msgid "Not supported"
 msgstr "不支持"
 
-#: ../src/pulse/error.c:63
+#: ../src/pulse/error.c:60
 msgid "Unknown error code"
 msgstr "未知错误码"
 
-#: ../src/pulse/error.c:64
+#: ../src/pulse/error.c:61
 msgid "No such extension"
 msgstr "没有该扩展"
 
-#: ../src/pulse/error.c:65
+#: ../src/pulse/error.c:62
 msgid "Obsolete functionality"
 msgstr "废弃的功能性"
 
-#: ../src/pulse/error.c:66
+#: ../src/pulse/error.c:63
 msgid "Missing implementation"
 msgstr "缺少部署"
 
-#: ../src/pulse/error.c:67
+#: ../src/pulse/error.c:64
 msgid "Client forked"
 msgstr "客户端分支"
 
-#: ../src/pulse/error.c:68
+#: ../src/pulse/error.c:65
 msgid "Input/Output error"
-msgstr ""
+msgstr "输入/输出错误"
 
-#: ../src/pulse/error.c:69
+#: ../src/pulse/error.c:66
 msgid "Device or resource busy"
-msgstr ""
+msgstr "设备或者资源忙"
 
-#: ../src/pulse/sample.c:172
+#: ../src/pulse/sample.c:171
 #, c-format
 msgid "%s %uch %uHz"
 msgstr "%s %uch %uHz"
 
-#: ../src/pulse/sample.c:184
+#: ../src/pulse/sample.c:183
 #, c-format
 msgid "%0.1f GiB"
 msgstr "%0.1f GiB"
 
-#: ../src/pulse/sample.c:186
+#: ../src/pulse/sample.c:185
 #, c-format
 msgid "%0.1f MiB"
 msgstr "%0.1f MiB"
 
-#: ../src/pulse/sample.c:188
+#: ../src/pulse/sample.c:187
 #, c-format
 msgid "%0.1f KiB"
 msgstr "%0.1f KiB"
 
-#: ../src/pulse/sample.c:190
+#: ../src/pulse/sample.c:189
 #, c-format
 msgid "%u B"
 msgstr "%u B"
 
-#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
-msgid "XOpenDisplay() failed"
-msgstr "XOpenDisplay()失败"
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect()失败:%s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
 
-#: ../src/pulse/client-conf-x11.c:93
+#: ../src/pulse/client-conf-x11.c:97
 msgid "Failed to parse cookie data"
 msgstr "cookie数据分析失败"
 
-#: ../src/pulse/client-conf.c:111
+#: ../src/pulse/client-conf.c:117
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "打开配置文件'%s'失败:%s"
 
-#: ../src/pulse/context.c:550
+#: ../src/pulse/context.c:528
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "没有加载cookie。尝试不加载cookie进行连接。"
 
-#: ../src/pulse/context.c:693
+#: ../src/pulse/context.c:675
 #, c-format
 msgid "fork(): %s"
 msgstr "fork():%s"
 
-#: ../src/pulse/context.c:748
+#: ../src/pulse/context.c:730
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid():%s"
 
-#: ../src/pulse/context.c:1438
+#: ../src/pulse/context.c:1431
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "收到未知扩展'%s'的信息"
 
-#: ../src/utils/pacat.c:108
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:112
+#, c-format
 msgid "Failed to drain stream: %s"
-msgstr "排出流失败:%s\n"
+msgstr "排出流失败:%s"
 
-#: ../src/utils/pacat.c:113
-#, fuzzy
+#: ../src/utils/pacat.c:117
 msgid "Playback stream drained."
-msgstr "流播放完毕。\n"
+msgstr "回放流枯竭。"
 
-#: ../src/utils/pacat.c:123
-#, fuzzy
+#: ../src/utils/pacat.c:128
 msgid "Draining connection to server."
-msgstr "Draining 连接到服务器。\n"
+msgstr "到服务器的 Draining 连接。"
 
-#: ../src/utils/pacat.c:136
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:141
+#, c-format
 msgid "pa_stream_drain(): %s"
-msgstr "pa_stream_drain():%s\n"
+msgstr "pa_stream_drain(): %s"
 
-#: ../src/utils/pacat.c:159
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:164
+#, c-format
 msgid "pa_stream_write() failed: %s"
-msgstr "pa_stream_write()失败:%s\n"
+msgstr "pa_stream_write() failed: %s"
 
-#: ../src/utils/pacat.c:197
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:205
+#, c-format
 msgid "pa_stream_begin_write() failed: %s"
-msgstr "pa_stream_write()失败:%s\n"
+msgstr "pa_stream_begin_write() failed: %s"
 
-#: ../src/utils/pacat.c:237 ../src/utils/pacat.c:267
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
+#, c-format
 msgid "pa_stream_peek() failed: %s"
-msgstr "pa_stream_peek()失败:%s\n"
+msgstr "pa_stream_peek() failed: %s"
 
-#: ../src/utils/pacat.c:307
-#, fuzzy
+#: ../src/utils/pacat.c:325
 msgid "Stream successfully created."
-msgstr "流创建成功。\n"
+msgstr "流创建成功。"
 
-#: ../src/utils/pacat.c:310
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:328
+#, c-format
 msgid "pa_stream_get_buffer_attr() failed: %s"
-msgstr "pa_stream_get_buffer_attr()失败:%s\n"
+msgstr "pa_stream_get_buffer_attr() failed: %s"
 
-#: ../src/utils/pacat.c:314
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:332
+#, c-format
 msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
-msgstr "缓冲计量:maxlength=%u,tlength=%u,prebuf=%u,minreq=%u\n"
+msgstr "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
 
-#: ../src/utils/pacat.c:317
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:335
+#, c-format
 msgid "Buffer metrics: maxlength=%u, fragsize=%u"
-msgstr "缓冲计量:maxlength=%u,fragsize=%u\n"
+msgstr "Buffer metrics: maxlength=%u, fragsize=%u"
 
-#: ../src/utils/pacat.c:321
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:339
+#, c-format
 msgid "Using sample spec '%s', channel map '%s'."
-msgstr "正在使用样品规格'%s',通道映射'%s'。\n"
+msgstr "正在使用样品规格 '%s',通道映射 '%s'。"
 
-#: ../src/utils/pacat.c:325
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:343
+#, c-format
 msgid "Connected to device %s (%u, %ssuspended)."
-msgstr "已连接至设备%s (%u,%s挂起)。\n"
+msgstr "已连接至设备 %s (%u,%s 挂起)。"
 
-#: ../src/utils/pacat.c:335
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:353
+#, c-format
 msgid "Stream error: %s"
-msgstr "流错误:%s\n"
+msgstr "流错误:%s"
 
-#: ../src/utils/pacat.c:345
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:363
+#, c-format
 msgid "Stream device suspended.%s"
-msgstr "流设备挂起。%s\n"
+msgstr "流设备挂起。%s"
 
-#: ../src/utils/pacat.c:347
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:365
+#, c-format
 msgid "Stream device resumed.%s"
-msgstr "流设备恢复。%s\n"
+msgstr "流设备恢复。%s"
 
-#: ../src/utils/pacat.c:355
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:373
+#, c-format
 msgid "Stream underrun.%s"
-msgstr "流欠载运行。%s\n"
+msgstr "流欠载运行。%s"
 
-#: ../src/utils/pacat.c:362
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:380
+#, c-format
 msgid "Stream overrun.%s"
-msgstr "流超限运行。%s\n"
+msgstr "流超限运行。%s"
 
-#: ../src/utils/pacat.c:369
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:387
+#, c-format
 msgid "Stream started.%s"
-msgstr "流已启动。%s\n"
+msgstr "流已启动。%s"
 
-#: ../src/utils/pacat.c:376
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:394
+#, c-format
 msgid "Stream moved to device %s (%u, %ssuspended).%s"
-msgstr "流移至设备%s (%u,%s挂起)。%s\n"
+msgstr "流移至设备 %s (%u,%s 挂起)。%s"
 
-#: ../src/utils/pacat.c:376
+#: ../src/utils/pacat.c:394
 msgid "not "
 msgstr "not "
 
-#: ../src/utils/pacat.c:383
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:401
+#, c-format
 msgid "Stream buffer attributes changed.%s"
-msgstr "更改流换出属性。%s\n"
+msgstr "更改流缓冲属性。%s"
 
-#: ../src/utils/pacat.c:415
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
+#, c-format
 msgid "Connection established.%s"
-msgstr "连接已建立。%s \n"
+msgstr "连接已建立。%s "
 
-#: ../src/utils/pacat.c:418
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:454
+#, c-format
 msgid "pa_stream_new() failed: %s"
-msgstr "pa_stream_new()失败:%s\n"
+msgstr "pa_stream_new() failed: %s"
 
-#: ../src/utils/pacat.c:450
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:492
+#, c-format
 msgid "pa_stream_connect_playback() failed: %s"
-msgstr "pa_stream_connect_playback()失败:%s\n"
+msgstr "pa_stream_connect_playback() failed: %s"
 
-#: ../src/utils/pacat.c:456
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:498
+#, c-format
 msgid "pa_stream_connect_record() failed: %s"
-msgstr "pa_stream_connect_playback()失败:%s\n"
+msgstr "pa_stream_connect_record() failed: %s"
 
-#: ../src/utils/pacat.c:470 ../src/utils/pactl.c:857
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
+#, c-format
 msgid "Connection failure: %s"
-msgstr "连接失败:%s\n"
+msgstr "连接失败:%s"
 
-#: ../src/utils/pacat.c:503
-#, fuzzy
+#: ../src/utils/pacat.c:545
 msgid "Got EOF."
-msgstr "收到EOF。\n"
+msgstr "获得 EOF。"
 
-#: ../src/utils/pacat.c:540
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:582
+#, c-format
 msgid "write() failed: %s"
-msgstr "write()失败:%s\n"
+msgstr "写入()失败:%s"
 
-#: ../src/utils/pacat.c:561
-#, fuzzy
+#: ../src/utils/pacat.c:603
 msgid "Got signal, exiting."
-msgstr "收到信号,正在退出。\n"
+msgstr "收到信号,正在退出。"
 
-#: ../src/utils/pacat.c:575
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:617
+#, c-format
 msgid "Failed to get latency: %s"
-msgstr "获取传输延迟失败:%s\n"
+msgstr "获取传输延迟失败:%s"
 
-#: ../src/utils/pacat.c:580
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:622
+#, c-format
 msgid "Time: %0.3f sec; Latency: %0.0f usec."
-msgstr "时间:%0.3f秒;延迟:%0.0f 微秒。  \r"
+msgstr "时间:%0.3f 秒;延迟:%0.0f 微秒。"
 
-#: ../src/utils/pacat.c:599
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:643
+#, c-format
 msgid "pa_stream_update_timing_info() failed: %s"
-msgstr "pa_stream_update_timing_info()失败:%s\n"
+msgstr "pa_stream_update_timing_info() failed: %s"
 
-#: ../src/utils/pacat.c:609
+#: ../src/utils/pacat.c:653
 #, fuzzy, c-format
 msgid ""
 "%s [options]\n"
@@ -1337,16 +1406,21 @@ msgid ""
 "bytes.\n"
 "      --process-time=BYTES              Request the specified process time "
 "per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
 "      --property=PROPERTY=VALUE         Set the specified property to the "
 "specified value.\n"
 "      --raw                             Record/play raw PCM data.\n"
-"      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
 "      --list-file-formats               List available file formats.\n"
 msgstr ""
 "%s [options]\n"
 "\n"
 "  -h, --help                            显示此帮助\n"
-"      --version                         显示版本\n"
+"      --version                         显示版本\n"
 "\n"
 "  -r, --record                          为录制创建连接\n"
 "  -p, --playback                        为回放创建连接\n"
@@ -1354,29 +1428,30 @@ msgstr ""
 "  -v, --verbose                         启用详述操作\n"
 "\n"
 "  -s, --server=SERVER                   要连接的服务器名\n"
-"  -d, --device=DEVICE                   要连接的sink/source名\n"
-"  -n, --client-name=NAME                指定客户端在服务器上的名称\n"
-"      --stream-name=NAME                指定流在服务器上的名称\n"
+"  -d, --device=DEVICE                   要连接的漏/源名称\n"
+"  -n, --client-name=NAME                如何在服务器中调用此客户端\n"
+"      --stream-name=NAME                如何在服务器中调用这个流\n"
 "      --volume=VOLUME                   指定初始(线性)音量,取值在0...65536"
 "之间\n"
-"      --rate=SAMPLERATE                 采样频率(单位Hz,默认为44100)\n"
-"      --format=SAMPLEFORMAT             采样类型,从s16le,s16be,u8,"
-"float32le\n"
-"                                        float32be,ulaw,alaw,s32le,s32be中"
-"取(默认为s16ne)\n"
+"      --rate=SAMPLERATE                 采样频率(单位 Hz,默认为44100)\n"
+"      --format=SAMPLEFORMAT             采样类型,s16le、s16be、u8、"
+"float32le 之一\n"
+"                                        float32be、ulaw、alaw、s32le、s32be "
+"中取(默认为 s16ne)\n"
 "      --channels=CHANNELS               通道数,1为单声道,2为立体声(默认为"
 "2)\n"
 "      --channel-map=CHANNELMAP          取代默认值的通道映射表\n"
-"      --fix-format                      从流连接的音频出口处取采样格式。\n"
-"      --fix-rate                        从流连接的音频出口处取采样率。\n"
-"      --fix-channels                    从流连接的音频出口处取通道数和通道映"
-"射表。\n"
-"      --no-remix                        Don't upmix or downmix channels.\n"
+"      --fix-format                      从流连接的漏中提取采样格式。\n"
+"      --fix-rate                        从流连接的漏中提取采样率。\n"
+"      --fix-channels                    从流连接的漏中提取通道数和通道映射"
+"表。\n"
+"      --no-remix                        不要对通道进行 upmix 或者 downmix 操"
+"作。\n"
 "      --no-remap                        根据下标而非名称来映射通道。\n"
 "      --latency=BYTES                   请求指定字节数的延迟。\n"
 "      --process-time=BYTES              每次请求指定字节数的处理时间。\n"
 
-#: ../src/utils/pacat.c:731
+#: ../src/utils/pacat.c:786
 #, c-format
 msgid ""
 "pacat %s\n"
@@ -1387,183 +1462,174 @@ msgstr ""
 "Compiled with libpulse %s\n"
 "Linked with libpulse %s\n"
 
-#: ../src/utils/pacat.c:764 ../src/utils/pactl.c:953
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
+#, c-format
 msgid "Invalid client name '%s'"
-msgstr "无效的通道映射描述'%s'\n"
+msgstr "无效客户端名称 '%s'"
 
-#: ../src/utils/pacat.c:779
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:834
+#, c-format
 msgid "Invalid stream name '%s'"
-msgstr "无效的重采样方法'%s'。"
+msgstr "无效流名称 '%s'"
 
-#: ../src/utils/pacat.c:816
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:871
+#, c-format
 msgid "Invalid channel map '%s'"
-msgstr "无效的通道映射描述'%s'\n"
+msgstr "无效通道映射 '%s'"
 
-#: ../src/utils/pacat.c:845
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
+#, c-format
 msgid "Invalid latency specification '%s'"
-msgstr "无效的延迟规格描述 %s'\n"
+msgstr "无效延迟说明 %s'"
 
-#: ../src/utils/pacat.c:852
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
+#, c-format
 msgid "Invalid process time specification '%s'"
-msgstr "无效的处理时间描述 '%s'\n"
+msgstr "无效处理时间说明 '%s'"
 
-#: ../src/utils/pacat.c:864
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:933
+#, c-format
 msgid "Invalid property '%s'"
-msgstr "无效的重采样方法'%s'。"
+msgstr "无效性能 '%s'"
 
-#: ../src/utils/pacat.c:881
+#: ../src/utils/pacat.c:952
 #, c-format
 msgid "Unknown file format %s."
-msgstr ""
+msgstr "未知文件格式 %s。"
 
-#: ../src/utils/pacat.c:900
-#, fuzzy
+#: ../src/utils/pacat.c:971
 msgid "Invalid sample specification"
-msgstr "无效的采样描述\n"
+msgstr "无效采样说明"
 
-#: ../src/utils/pacat.c:910
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:981
+#, c-format
 msgid "open(): %s"
-msgstr "open():%s\n"
+msgstr "open(): %s"
 
-#: ../src/utils/pacat.c:915
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:986
+#, c-format
 msgid "dup2(): %s"
-msgstr "dup2():%s\n"
+msgstr "dup2(): %s"
 
-#: ../src/utils/pacat.c:922
-#, fuzzy
+#: ../src/utils/pacat.c:993
 msgid "Too many arguments."
-msgstr "参数过多。\n"
+msgstr "参数过多。"
 
-#: ../src/utils/pacat.c:933
-#, fuzzy
+#: ../src/utils/pacat.c:1004
 msgid "Failed to generate sample specification for file."
-msgstr "获取采样信息失败:%s\n"
+msgstr "为文件获取采样说明失败。"
 
-#: ../src/utils/pacat.c:953
-#, fuzzy
+#: ../src/utils/pacat.c:1030
 msgid "Failed to open audio file."
-msgstr "打开声音文件失败。\n"
+msgstr "打开声音文件失败。"
 
-#: ../src/utils/pacat.c:959
-#, fuzzy
+#: ../src/utils/pacat.c:1036
 msgid ""
 "Warning: specified sample specification will be overwritten with "
 "specification from file."
-msgstr "以采样规格'%s'打开%s流。\n"
+msgstr "警告:指定的采样说明将覆盖文件中的说明。"
 
-#: ../src/utils/pacat.c:962 ../src/utils/pactl.c:997
-#, fuzzy
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
 msgid "Failed to determine sample specification from file."
-msgstr "获取采样信息失败:%s\n"
+msgstr "从文件中确定采样说明失败。"
 
-#: ../src/utils/pacat.c:971
-#, fuzzy
+#: ../src/utils/pacat.c:1048
 msgid "Warning: Failed to determine channel map from file."
-msgstr "以采样规格'%s'打开%s流。\n"
+msgstr "警告:从文件中确定通道映射失败。"
 
-#: ../src/utils/pacat.c:982
-#, fuzzy
+#: ../src/utils/pacat.c:1059
 msgid "Channel map doesn't match sample specification"
-msgstr "通道映射与采样描述不匹配\n"
+msgstr "通道映射与采样说明不匹配"
 
-#: ../src/utils/pacat.c:993
-#, fuzzy
+#: ../src/utils/pacat.c:1070
 msgid "Warning: failed to write channel map to file."
-msgstr "以采样规格'%s'打开%s流。\n"
+msgstr "警告:在文件中写入通道映射失败。"
 
-#: ../src/utils/pacat.c:1008
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:1085
+#, c-format
 msgid ""
 "Opening a %s stream with sample specification '%s' and channel map '%s'."
-msgstr "以é\87\87æ ·è§\84æ ¼'%s'æ\89\93å¼\80%sæµ\81ã\80\82\n"
+msgstr "使ç\94¨é\87\87样说æ\98\8e '%s' å\92\8cé\80\9aé\81\93æ\98 å°\84 '%s' æ\89\93å¼\80 %s æµ\81ã\80\82"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "recording"
 msgstr "正在录制"
 
-#: ../src/utils/pacat.c:1009
+#: ../src/utils/pacat.c:1086
 msgid "playback"
 msgstr "回放"
 
-#: ../src/utils/pacat.c:1035 ../src/utils/pactl.c:1267
+#: ../src/utils/pacat.c:1110
 #, fuzzy
+msgid "Failed to set media name."
+msgstr "分析命令行失败。"
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
 msgid "pa_mainloop_new() failed."
-msgstr "pa_mainloop_new()失败。\n"
+msgstr "pa_mainloop_new() failed."
 
-#: ../src/utils/pacat.c:1054
-#, fuzzy
+#: ../src/utils/pacat.c:1136
 msgid "io_new() failed."
-msgstr "io_new()失败。\n"
+msgstr "io_new() failed."
 
-#: ../src/utils/pacat.c:1061 ../src/utils/pactl.c:1279
-#, fuzzy
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
 msgid "pa_context_new() failed."
-msgstr "pa_context_new()失败。\n"
+msgstr "pa_context_new() failed."
 
-#: ../src/utils/pacat.c:1069 ../src/utils/pactl.c:1285
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
 #, c-format
 msgid "pa_context_connect() failed: %s"
 msgstr "pa_context_connect()失败:%s"
 
-#: ../src/utils/pacat.c:1075
-#, fuzzy
+#: ../src/utils/pacat.c:1157
 msgid "pa_context_rttime_new() failed."
-msgstr "pa_context_new()失败。\n"
+msgstr "pa_context_rttime_new() failed."
 
-#: ../src/utils/pacat.c:1082 ../src/utils/pactl.c:1290
-#, fuzzy
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
 msgid "pa_mainloop_run() failed."
-msgstr "pa_mainloop_run()失败。\n"
+msgstr "pa_mainloop_run() failed."
 
-#: ../src/utils/pasuspender.c:81
+#: ../src/utils/pasuspender.c:79
 #, c-format
 msgid "fork(): %s\n"
 msgstr "fork():%s\n"
 
-#: ../src/utils/pasuspender.c:92
+#: ../src/utils/pasuspender.c:90
 #, c-format
 msgid "execvp(): %s\n"
 msgstr "execvp():%s\n"
 
-#: ../src/utils/pasuspender.c:109
+#: ../src/utils/pasuspender.c:107
 #, c-format
 msgid "Failure to suspend: %s\n"
 msgstr "挂起失败:%s\n"
 
-#: ../src/utils/pasuspender.c:124
+#: ../src/utils/pasuspender.c:122
 #, c-format
 msgid "Failure to resume: %s\n"
 msgstr "恢复失败:%s\n"
 
-#: ../src/utils/pasuspender.c:147
+#: ../src/utils/pasuspender.c:145
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr "警告:非本地声音服务器,不会挂起。\n"
 
-#: ../src/utils/pasuspender.c:159
+#: ../src/utils/pasuspender.c:157
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "连接失败:%s\n"
 
-#: ../src/utils/pasuspender.c:176
+#: ../src/utils/pasuspender.c:174
 #, c-format
 msgid "Got SIGINT, exiting.\n"
 msgstr "收到SIGINT,正在退出。\n"
 
-#: ../src/utils/pasuspender.c:194
+#: ../src/utils/pasuspender.c:192
 #, c-format
 msgid "WARNING: Child process terminated by signal %u\n"
 msgstr "警告:子进程被信号%u终止\n"
 
-#: ../src/utils/pasuspender.c:212
+#: ../src/utils/pasuspender.c:210
 #, c-format
 msgid ""
 "%s [options] ... \n"
@@ -1607,43 +1673,54 @@ msgstr "pa_context_new()失败。\n"
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run()失败。\n"
 
-#: ../src/utils/pactl.c:135
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:150
+#, c-format
 msgid "Failed to get statistics: %s"
-msgstr "获取统计数据失败:%s\n"
+msgstr "获取统计数据失败:%s"
 
-#: ../src/utils/pactl.c:141
+#: ../src/utils/pactl.c:156
 #, c-format
 msgid "Currently in use: %u blocks containing %s bytes total.\n"
 msgstr "当前使用:%u块,总共%s字节。\n"
 
-#: ../src/utils/pactl.c:144
+#: ../src/utils/pactl.c:159
 #, c-format
 msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
 msgstr "整个生命周期所得分配:%u块,总共%s字节。\n"
 
-#: ../src/utils/pactl.c:147
+#: ../src/utils/pactl.c:162
 #, c-format
 msgid "Sample cache size: %s\n"
 msgstr "采样缓存大小:%s\n"
 
-#: ../src/utils/pactl.c:156
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:171
+#, c-format
 msgid "Failed to get server information: %s"
-msgstr "获取服务器信息失败:%s\n"
+msgstr "获取服务器信息失败:%s"
 
-#: ../src/utils/pactl.c:164
+#: ../src/utils/pactl.c:176
 #, c-format
 msgid ""
-"User name: %s\n"
-"Host Name: %s\n"
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, fuzzy, c-format
+msgid ""
+"User Name: %s\n"
+"Host Name: %s\n"
 "Server Name: %s\n"
 "Server Version: %s\n"
 "Default Sample Specification: %s\n"
 "Default Channel Map: %s\n"
 "Default Sink: %s\n"
 "Default Source: %s\n"
-"Cookie: %08x\n"
+"Cookie: %04x:%04x\n"
 msgstr ""
 "用户名:%s\n"
 "主机名:%s\n"
@@ -1655,13 +1732,13 @@ msgstr ""
 "默认源: %s\n"
 "Cookie:%08x\n"
 
-#: ../src/utils/pactl.c:205
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
+#, c-format
 msgid "Failed to get sink information: %s"
-msgstr "获取音频出口信息失败:%s\n"
+msgstr "获取音频出口信息失败:%s"
 
-#: ../src/utils/pactl.c:221
-#, c-format
+#: ../src/utils/pactl.c:270
+#, fuzzy, c-format
 msgid ""
 "Sink #%u\n"
 "\tState: %s\n"
@@ -1677,7 +1754,7 @@ msgid ""
 "\tBase Volume: %s%s%s\n"
 "\tMonitor Source: %s\n"
 "\tLatency: %0.0f usec, configured %0.0f usec\n"
-"\tFlags: %s%s%s%s%s%s\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
@@ -1699,22 +1776,27 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:268 ../src/utils/pactl.c:360
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
+#, c-format
 msgid "\tPorts:\n"
-msgstr "\tProfiles:\n"
+msgstr "\tPorts:\n"
 
-#: ../src/utils/pactl.c:274 ../src/utils/pactl.c:366
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
+#, c-format
 msgid "\tActive Port: %s\n"
-msgstr "\tActive Profile: %s\n"
+msgstr "\tActive Port: %s\n"
 
-#: ../src/utils/pactl.c:297
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
 #, fuzzy, c-format
+msgid "\tFormats:\n"
+msgstr "\tPorts:\n"
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
+#, c-format
 msgid "Failed to get source information: %s"
-msgstr "获取音频入口信息失败:%s\n"
+msgstr "获取音频入口信息失败:%s"
 
-#: ../src/utils/pactl.c:313
+#: ../src/utils/pactl.c:383
 #, c-format
 msgid ""
 "Source #%u\n"
@@ -1753,20 +1835,20 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:345 ../src/utils/pactl.c:401 ../src/utils/pactl.c:436
-#: ../src/utils/pactl.c:473 ../src/utils/pactl.c:532 ../src/utils/pactl.c:533
-#: ../src/utils/pactl.c:543 ../src/utils/pactl.c:587 ../src/utils/pactl.c:588
-#: ../src/utils/pactl.c:594 ../src/utils/pactl.c:637 ../src/utils/pactl.c:638
-#: ../src/utils/pactl.c:645
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
 msgid "n/a"
 msgstr "n/a"
 
-#: ../src/utils/pactl.c:375
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:454
+#, c-format
 msgid "Failed to get module information: %s"
-msgstr "获取模块信息失败:%s\n"
+msgstr "获取模块信息失败:%s"
 
-#: ../src/utils/pactl.c:393
+#: ../src/utils/pactl.c:477
 #, c-format
 msgid ""
 "Module #%u\n"
@@ -1783,12 +1865,12 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:412
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:496
+#, c-format
 msgid "Failed to get client information: %s"
-msgstr "获取客户端信息失败:%s\n"
+msgstr "获取客户端信息失败:%s"
 
-#: ../src/utils/pactl.c:430
+#: ../src/utils/pactl.c:522
 #, c-format
 msgid ""
 "Client #%u\n"
@@ -1803,12 +1885,12 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:447
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:539
+#, c-format
 msgid "Failed to get card information: %s"
-msgstr "获取声卡信息失败:%s\n"
+msgstr "获取声卡信息失败:%s"
 
-#: ../src/utils/pactl.c:465
+#: ../src/utils/pactl.c:562
 #, c-format
 msgid ""
 "Card #%u\n"
@@ -1825,23 +1907,23 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:479
+#: ../src/utils/pactl.c:576
 #, c-format
 msgid "\tProfiles:\n"
 msgstr "\tProfiles:\n"
 
-#: ../src/utils/pactl.c:485
+#: ../src/utils/pactl.c:582
 #, c-format
 msgid "\tActive Profile: %s\n"
 msgstr "\tActive Profile: %s\n"
 
-#: ../src/utils/pactl.c:496
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
+#, c-format
 msgid "Failed to get sink input information: %s"
-msgstr "获取音频出口输入信息失败:%s\n"
+msgstr "获取音频出口输入信息失败:%s"
 
-#: ../src/utils/pactl.c:515
-#, c-format
+#: ../src/utils/pactl.c:622
+#, fuzzy, c-format
 msgid ""
 "Sink Input #%u\n"
 "\tDriver: %s\n"
@@ -1850,6 +1932,7 @@ msgid ""
 "\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
 "\tMute: %s\n"
 "\tVolume: %s\n"
 "\t        %s\n"
@@ -1877,13 +1960,13 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:554
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
+#, c-format
 msgid "Failed to get source output information: %s"
-msgstr "获取音频入口输出信息失败:%s\n"
+msgstr "获取音频入口输出信息失败:%s"
 
-#: ../src/utils/pactl.c:574
-#, c-format
+#: ../src/utils/pactl.c:693
+#, fuzzy, c-format
 msgid ""
 "Source Output #%u\n"
 "\tDriver: %s\n"
@@ -1892,31 +1975,40 @@ msgid ""
 "\tSource: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
 "\tSource Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 msgstr ""
-"Source Output #%u\n"
+"Sink Input #%u\n"
 "\tDriver: %s\n"
 "\tOwner Module: %s\n"
 "\tClient: %s\n"
-"\tSource: %u\n"
+"\tSink: %u\n"
 "\tSample Specification: %s\n"
 "\tChannel Map: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
 "\tBuffer Latency: %0.0f usec\n"
-"\tSource Latency: %0.0f usec\n"
+"\tSink Latency: %0.0f usec\n"
 "\tResample method: %s\n"
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:605
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:734
+#, c-format
 msgid "Failed to get sample information: %s"
-msgstr "获取采样信息失败:%s\n"
+msgstr "获取采样信息失败:%s"
 
-#: ../src/utils/pactl.c:623
+#: ../src/utils/pactl.c:761
 #, c-format
 msgid ""
 "Sample #%u\n"
@@ -1947,50 +2039,163 @@ msgstr ""
 "\tProperties:\n"
 "\t\t%s\n"
 
-#: ../src/utils/pactl.c:653 ../src/utils/pactl.c:663
-#, fuzzy, c-format
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
+#, c-format
 msgid "Failure: %s"
-msgstr "失败:%s\n"
+msgstr "失败:%s"
 
-#: ../src/utils/pactl.c:687
+#: ../src/utils/pactl.c:915
 #, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "获取音频入口信息失败:%s"
+
+#: ../src/utils/pactl.c:954
+#, c-format
 msgid "Failed to upload sample: %s"
-msgstr "上传采样失败:%s\n"
+msgstr "上传采样失败:%s"
 
-#: ../src/utils/pactl.c:704
-#, fuzzy
+#: ../src/utils/pactl.c:971
 msgid "Premature end of file"
-msgstr "文件过早结束\n"
+msgstr "文件过早结束"
+
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
 
-#: ../src/utils/pactl.c:863
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
 #, fuzzy
+msgid "server"
+msgstr "无效服务器"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
 msgid "Got SIGINT, exiting."
-msgstr "收到SIGINT,正在退出。\n"
+msgstr "收到 SIGINT,正在退出。"
+
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr "无效采样说明"
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
 
-#: ../src/utils/pactl.c:869
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
 #, fuzzy, c-format
 msgid ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input SINKINPUT SINK\n"
-"%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module MODULE\n"
-"%s [options] suspend-sink SINK 1|0\n"
-"%s [options] suspend-source SOURCE 1|0\n"
-"%s [options] set-card-profile CARD PROFILE\n"
-"%s [options] set-sink-port SINK PORT\n"
-"%s [options] set-source-port SOURCE PORT\n"
-"%s [options] set-sink-volume SINK VOLUME\n"
-"%s [options] set-source-volume SOURCE VOLUME\n"
-"%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-"%s [options] set-sink-mute SINK 1|0\n"
-"%s [options] set-source-mute SOURCE 1|0\n"
-"%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
@@ -2000,29 +2205,14 @@ msgid ""
 "  -n, --client-name=NAME                How to call this client on the "
 "server\n"
 msgstr ""
-"%s [options] stat\n"
-"%s [options] list\n"
-"%s [options] exit\n"
-"%s [options] upload-sample FILENAME [NAME]\n"
-"%s [options] play-sample NAME [SINK]\n"
-"%s [options] remove-sample NAME\n"
-"%s [options] move-sink-input ID SINK\n"
-"%s [options] move-source-output ID SOURCE\n"
-"%s [options] load-module NAME [ARGS ...]\n"
-"%s [options] unload-module ID\n"
-"%s [options] suspend-sink [SINK] 1|0\n"
-"%s [options] suspend-source [SOURCE] 1|0\n"
-"%s [options] set-card-profile [CARD] [PROFILE] \n"
+"%s [options] ... \n"
 "\n"
-"  -h, --help                            Show this help\n"
-"      --version                         Show version\n"
+"  -h, --help                            显示此帮助\n"
+"      --version                         显示版本\n"
+"  -s, --server=SERVER                   要连接的服务器名\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect "
-"to\n"
-"  -n, --client-name=NAME                How to call this client on the "
-"server\n"
 
-#: ../src/utils/pactl.c:933
+#: ../src/utils/pactl.c:1380
 #, c-format
 msgid ""
 "pactl %s\n"
@@ -2033,129 +2223,138 @@ msgstr ""
 "Compiled with libpulse %s\n"
 "Linked with libpulse %s\n"
 
-#: ../src/utils/pactl.c:979
-#, fuzzy
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
 msgid "Please specify a sample file to load"
-msgstr "请指定要加载的采样文件\n"
+msgstr "请指定要加载的采样文件"
 
-#: ../src/utils/pactl.c:992
-#, fuzzy
+#: ../src/utils/pactl.c:1462
 msgid "Failed to open sound file."
-msgstr "打开声音文件失败。\n"
+msgstr "打开声音文件失败。"
 
-#: ../src/utils/pactl.c:1004
-#, fuzzy
+#: ../src/utils/pactl.c:1474
 msgid "Warning: Failed to determine sample specification from file."
-msgstr "以采样规格'%s'打开%s流。\n"
+msgstr "警告:从文件中确定采样说明失败。"
 
-#: ../src/utils/pactl.c:1014
-#, fuzzy
+#: ../src/utils/pactl.c:1484
 msgid "You have to specify a sample name to play"
-msgstr "你必须指定要播放的采样名\n"
+msgstr "您必须指定要播放的采样名"
 
-#: ../src/utils/pactl.c:1026
-#, fuzzy
+#: ../src/utils/pactl.c:1496
 msgid "You have to specify a sample name to remove"
-msgstr "你必须指定要删除的采样名\n"
+msgstr "您必须指定要删除的采样名"
 
-#: ../src/utils/pactl.c:1035
-#, fuzzy
+#: ../src/utils/pactl.c:1505
 msgid "You have to specify a sink input index and a sink"
-msgstr "你必须指定音频出口索引和音频出口\n"
+msgstr "您必须指定漏输入索引和漏"
 
-#: ../src/utils/pactl.c:1045
-#, fuzzy
+#: ../src/utils/pactl.c:1515
 msgid "You have to specify a source output index and a source"
-msgstr "你必须指定音频入口输出索引和音频入口\n"
+msgstr "您必须指定源输出索引和源"
 
-#: ../src/utils/pactl.c:1060
-#, fuzzy
+#: ../src/utils/pactl.c:1530
 msgid "You have to specify a module name and arguments."
-msgstr "必须指定模块名和参数。\n"
+msgstr "必须指定模块名和参数。"
 
-#: ../src/utils/pactl.c:1080
-#, fuzzy
+#: ../src/utils/pactl.c:1550
 msgid "You have to specify a module index"
-msgstr "必须指定模块索引\n"
+msgstr "必须指定模块索引"
 
-#: ../src/utils/pactl.c:1090
-#, fuzzy
+#: ../src/utils/pactl.c:1560
 msgid ""
 "You may not specify more than one sink. You have to specify a boolean value."
-msgstr "不可指定多个音频出口。必须指定一个布尔值。\n"
+msgstr "不可指定多个漏。必须指定一个布尔值。"
 
-#: ../src/utils/pactl.c:1103
-#, fuzzy
+#: ../src/utils/pactl.c:1573
 msgid ""
 "You may not specify more than one source. You have to specify a boolean "
 "value."
-msgstr "不可指定多个源。必须指定一个布尔值。\n"
+msgstr "不可指定多个源。必须指定一个布尔值。"
 
-#: ../src/utils/pactl.c:1115
-#, fuzzy
+#: ../src/utils/pactl.c:1585
 msgid "You have to specify a card name/index and a profile name"
-msgstr "你必须指定声卡名称/索引和侧写名称\n"
+msgstr "您必须指定声卡名称/索引和侧写名称"
 
-#: ../src/utils/pactl.c:1126
-#, fuzzy
+#: ../src/utils/pactl.c:1596
 msgid "You have to specify a sink name/index and a port name"
-msgstr "你必须指定声卡名称/索引和侧写名称\n"
+msgstr "您必须指定漏名称/索引和端口名称"
 
-#: ../src/utils/pactl.c:1137
-#, fuzzy
+#: ../src/utils/pactl.c:1607
 msgid "You have to specify a source name/index and a port name"
-msgstr "你必须指定声卡名称/索引和侧写名称\n"
+msgstr "您必须指定源名称/索引和端口名称"
 
-#: ../src/utils/pactl.c:1149
-#, fuzzy
+#: ../src/utils/pactl.c:1618
 msgid "You have to specify a sink name/index and a volume"
-msgstr "你必须指定声卡名称/索引和侧写名称\n"
+msgstr "您必须指定漏名称/索引和卷"
 
-#: ../src/utils/pactl.c:1154 ../src/utils/pactl.c:1171
-#: ../src/utils/pactl.c:1193 ../src/utils/pactl.c:1209
-#: ../src/utils/pactl.c:1226 ../src/utils/pactl.c:1248
-#, fuzzy
-msgid "Invalid volume specification"
-msgstr "无效的采样描述\n"
-
-#: ../src/utils/pactl.c:1166
-#, fuzzy
+#: ../src/utils/pactl.c:1631
 msgid "You have to specify a source name/index and a volume"
-msgstr "你必须指定声卡名称/索引和侧写名称\n"
+msgstr "您必须指定源名称/索引和卷"
 
-#: ../src/utils/pactl.c:1183
-#, fuzzy
+#: ../src/utils/pactl.c:1644
 msgid "You have to specify a sink input index and a volume"
-msgstr "你必须指定音频出口索引和音频出口\n"
+msgstr "您必须指定漏输入索引和卷"
 
-#: ../src/utils/pactl.c:1188
+#: ../src/utils/pactl.c:1649
 msgid "Invalid sink input index"
-msgstr ""
+msgstr "无效露输入索引"
+
+#: ../src/utils/pactl.c:1660
+#, fuzzy
+msgid "You have to specify a source output index and a volume"
+msgstr "您必须指定源输出索引和源"
 
-#: ../src/utils/pactl.c:1204
+#: ../src/utils/pactl.c:1665
 #, fuzzy
+msgid "Invalid source output index"
+msgstr "无效露输入索引"
+
+#: ../src/utils/pactl.c:1677
 msgid "You have to specify a sink name/index and a mute boolean"
-msgstr "你必须指定声卡名称/索引和侧写名称\n"
+msgstr "您必须指定漏名称/索引和静音布尔值"
 
-#: ../src/utils/pactl.c:1221
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
 #, fuzzy
+msgid "Invalid mute specification"
+msgstr "无效采样说明"
+
+#: ../src/utils/pactl.c:1694
 msgid "You have to specify a source name/index and a mute boolean"
-msgstr "你必须指定声卡名称/索引和侧写名称\n"
+msgstr "您必须指定源名称/索引和静音布尔值"
 
-#: ../src/utils/pactl.c:1238
-#, fuzzy
+#: ../src/utils/pactl.c:1711
 msgid "You have to specify a sink input index and a mute boolean"
-msgstr "你必须指定音频出口索引和音频出口\n"
+msgstr "您必须指定露输入索引和静音布尔值"
 
-#: ../src/utils/pactl.c:1243
-#, fuzzy
+#: ../src/utils/pactl.c:1716
 msgid "Invalid sink input index specification"
-msgstr "无效的采样描述\n"
+msgstr "无效漏输入索引说明"
 
-#: ../src/utils/pactl.c:1262
+#: ../src/utils/pactl.c:1732
 #, fuzzy
+msgid "You have to specify a source output index and a mute boolean"
+msgstr "您必须指定源名称/索引和静音布尔值"
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "无效漏输入索引说明"
+
+#: ../src/utils/pactl.c:1756
+#, fuzzy
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr "您必须指定漏名称/索引和静音布尔值"
+
+#: ../src/utils/pactl.c:1772
 msgid "No valid command specified."
-msgstr "未指定有效的命令。\n"
+msgstr "未指定有效的命令。"
 
 #: ../src/utils/pax11publish.c:61
 #, c-format
@@ -2180,103 +2379,103 @@ msgstr ""
 msgid "Failed to parse command line.\n"
 msgstr "分析命令行失败。\n"
 
-#: ../src/utils/pax11publish.c:108
+#: ../src/utils/pax11publish.c:113
 #, c-format
 msgid "Server: %s\n"
 msgstr "服务器:%s\n"
 
-#: ../src/utils/pax11publish.c:110
+#: ../src/utils/pax11publish.c:115
 #, c-format
 msgid "Source: %s\n"
 msgstr "音频入口:%s\n"
 
-#: ../src/utils/pax11publish.c:112
+#: ../src/utils/pax11publish.c:117
 #, c-format
 msgid "Sink: %s\n"
 msgstr "音频出口:%s\n"
 
-#: ../src/utils/pax11publish.c:114
+#: ../src/utils/pax11publish.c:119
 #, c-format
 msgid "Cookie: %s\n"
 msgstr "Cookie:%s\n"
 
-#: ../src/utils/pax11publish.c:132
+#: ../src/utils/pax11publish.c:137
 #, c-format
 msgid "Failed to parse cookie data\n"
 msgstr "分析cookie数据失败\n"
 
-#: ../src/utils/pax11publish.c:137
+#: ../src/utils/pax11publish.c:142
 #, c-format
 msgid "Failed to save cookie data\n"
 msgstr "保存cookie数据失败\n"
 
-#: ../src/utils/pax11publish.c:152
+#: ../src/utils/pax11publish.c:157
 #, c-format
 msgid "Failed to load client configuration file.\n"
 msgstr "加载客户端配置文件失败。\n"
 
-#: ../src/utils/pax11publish.c:157
+#: ../src/utils/pax11publish.c:162
 #, c-format
 msgid "Failed to read environment configuration data.\n"
 msgstr "读取环境配置数据失败。\n"
 
-#: ../src/utils/pax11publish.c:174
+#: ../src/utils/pax11publish.c:179
 #, c-format
 msgid "Failed to get FQDN.\n"
 msgstr "获取FQDN失败。\n"
 
-#: ../src/utils/pax11publish.c:194
+#: ../src/utils/pax11publish.c:199
 #, c-format
 msgid "Failed to load cookie data\n"
 msgstr "加载cookie数据失败\n"
 
-#: ../src/utils/pax11publish.c:211
+#: ../src/utils/pax11publish.c:217
 #, c-format
 msgid "Not yet implemented.\n"
 msgstr "尚未实现。\n"
 
-#: ../src/utils/pacmd.c:69
+#: ../src/utils/pacmd.c:66
 msgid "No PulseAudio daemon running, or not running as session daemon."
-msgstr ""
+msgstr "没有 PulseAudio 守护进程在运行,或者没有作为会话守护进程运行。"
 
-#: ../src/utils/pacmd.c:74
+#: ../src/utils/pacmd.c:71
 #, c-format
 msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
 msgstr "socket(PF_UNIX, SOCK_STREAM, 0):%s"
 
-#: ../src/utils/pacmd.c:91
+#: ../src/utils/pacmd.c:88
 #, c-format
 msgid "connect(): %s"
 msgstr "connect():%s"
 
-#: ../src/utils/pacmd.c:99
+#: ../src/utils/pacmd.c:96
 msgid "Failed to kill PulseAudio daemon."
 msgstr "杀死PulseAudio后台程序失败。"
 
-#: ../src/utils/pacmd.c:107
+#: ../src/utils/pacmd.c:104
 msgid "Daemon not responding."
 msgstr "后台程序未响应。"
 
-#: ../src/utils/pacmd.c:161
-#, fuzzy, c-format
+#: ../src/utils/pacmd.c:184
+#, c-format
 msgid "poll(): %s"
-msgstr "fork():%s"
+msgstr "poll(): %s"
 
-#: ../src/utils/pacmd.c:171 ../src/utils/pacmd.c:188
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
 #, c-format
 msgid "read(): %s"
 msgstr "read():%s"
 
-#: ../src/utils/pacmd.c:207 ../src/utils/pacmd.c:223
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
 #, c-format
 msgid "write(): %s"
 msgstr "write():%s"
 
-#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:219
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
 msgid "Cannot access autospawn lock."
 msgstr "不能访问autospawn锁。"
 
-#: ../src/modules/alsa/alsa-sink.c:530 ../src/modules/alsa/alsa-sink.c:689
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
 #, c-format
 msgid ""
 "ALSA woke us up to write new data to the device, but there was actually "
@@ -2292,7 +2491,7 @@ msgstr ""
 "提醒我们设置 POLLOUT -- 但结果是 snd_pcm_avail() 返回 0 或者另一个小于最小可"
 "用值的数值。"
 
-#: ../src/modules/alsa/alsa-source.c:506 ../src/modules/alsa/alsa-source.c:656
+#: ../src/modules/alsa/alsa-source.c:519 ../src/modules/alsa/alsa-source.c:672
 #, c-format
 msgid ""
 "ALSA woke us up to read new data from the device, but there was actually "
@@ -2308,448 +2507,465 @@ msgstr ""
 "提醒我们设置 POLLOUT -- 但结果是 snd_pcm_avail() 返回 0 或者另一个小于最小可"
 "用值的数值。"
 
-#: ../src/modules/alsa/module-alsa-card.c:152
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2228
-#: ../src/modules/alsa/alsa-mixer.c:2931
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
 msgid "Off"
 msgstr "关闭"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2184
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
 msgid "High Fidelity Playback (A2DP)"
 msgstr "高保真回放(A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2198
-#, fuzzy
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
 msgid "High Fidelity Capture (A2DP)"
-msgstr "高保真回放(A2DP)"
+msgstr "高保真采集(A2DP)"
 
-#: ../src/modules/bluetooth/module-bluetooth-device.c:2213
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
 msgid "Telephony Duplex (HSP/HFP)"
 msgstr "双工电话(HSP/HFP)"
 
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
 #: ../src/modules/reserve-wrap.c:151
 msgid "PulseAudio Sound Server"
 msgstr "PulseAudio 声音服务器"
 
-#: ../src/modules/module-rygel-media-server.c:569
-#: ../src/modules/module-rygel-media-server.c:583
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
 msgid "Output Devices"
-msgstr ""
+msgstr "输出设备"
 
-#: ../src/modules/module-rygel-media-server.c:570
-#: ../src/modules/module-rygel-media-server.c:584
-#, fuzzy
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
 msgid "Input Devices"
-msgstr "输入 %s"
+msgstr "输入设备"
 
-#: ../src/modules/module-rygel-media-server.c:774
+#: ../src/modules/module-rygel-media-server.c:1056
 msgid "Audio on @HOSTNAME@"
-msgstr ""
+msgstr "@HOSTNAME@ 中的音频"
 
-#: ../src/modules/alsa/alsa-mixer.c:1701
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:2219
 msgid "Input"
-msgstr "输入 %s"
+msgstr "输入"
 
-#: ../src/modules/alsa/alsa-mixer.c:1702
+#: ../src/modules/alsa/alsa-mixer.c:2220
 msgid "Docking Station Input"
-msgstr ""
+msgstr "扩展坞输入"
 
-#: ../src/modules/alsa/alsa-mixer.c:1703
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
 msgid "Docking Station Microphone"
-msgstr ""
+msgstr "扩展坞麦克风"
 
-#: ../src/modules/alsa/alsa-mixer.c:1704
-msgid "Line-In"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2222
+#, fuzzy
+msgid "Docking Station Line In"
+msgstr "扩展坞输入"
 
-#: ../src/modules/alsa/alsa-mixer.c:1705
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "Line In"
+
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
 msgid "Microphone"
-msgstr ""
+msgstr "麦克风"
 
-#: ../src/modules/alsa/alsa-mixer.c:1706
-msgid "External Microphone"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "扩展坞麦克风"
 
-#: ../src/modules/alsa/alsa-mixer.c:1707
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
 #, fuzzy
+msgid "Rear Microphone"
+msgstr "麦克风"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "外部麦克风"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
 msgid "Internal Microphone"
-msgstr "å\86\85é\83¨é\9f³é¢\91"
+msgstr "å\86\85é\83¨éº¦å\85\8bé£\8e"
 
-#: ../src/modules/alsa/alsa-mixer.c:1708
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
 msgid "Radio"
-msgstr ""
+msgstr "无线电"
 
-#: ../src/modules/alsa/alsa-mixer.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
 msgid "Video"
-msgstr ""
+msgstr "视频"
 
-#: ../src/modules/alsa/alsa-mixer.c:1710
+#: ../src/modules/alsa/alsa-mixer.c:2231
 msgid "Automatic Gain Control"
-msgstr ""
+msgstr "自动增益控制"
 
-#: ../src/modules/alsa/alsa-mixer.c:1711
+#: ../src/modules/alsa/alsa-mixer.c:2232
 msgid "No Automatic Gain Control"
-msgstr ""
+msgstr "无自动增益控制"
 
-#: ../src/modules/alsa/alsa-mixer.c:1712
+#: ../src/modules/alsa/alsa-mixer.c:2233
 msgid "Boost"
-msgstr ""
+msgstr "加速器"
 
-#: ../src/modules/alsa/alsa-mixer.c:1713
+#: ../src/modules/alsa/alsa-mixer.c:2234
 msgid "No Boost"
-msgstr ""
+msgstr "无加速器"
 
-#: ../src/modules/alsa/alsa-mixer.c:1714
+#: ../src/modules/alsa/alsa-mixer.c:2235
 msgid "Amplifier"
-msgstr ""
+msgstr "均衡器"
 
-#: ../src/modules/alsa/alsa-mixer.c:1715
+#: ../src/modules/alsa/alsa-mixer.c:2236
 msgid "No Amplifier"
-msgstr ""
+msgstr "无均衡器"
 
-#: ../src/modules/alsa/alsa-mixer.c:1773
+#: ../src/modules/alsa/alsa-mixer.c:2237
 #, fuzzy
-msgid "Analog Input"
-msgstr "模拟单声道"
+msgid "Bass Boost"
+msgstr "加速器"
 
-#: ../src/modules/alsa/alsa-mixer.c:1774
+#: ../src/modules/alsa/alsa-mixer.c:2238
 #, fuzzy
-msgid "Analog Microphone"
-msgstr "模æ\8b\9få\8d\95声é\81\93"
+msgid "No Bass Boost"
+msgstr "æ\97 å\8a é\80\9få\99¨"
 
-#: ../src/modules/alsa/alsa-mixer.c:1775
-#, fuzzy
-msgid "Analog Line-In"
-msgstr "模拟单声道"
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1776
-#, fuzzy
-msgid "Analog Radio"
-msgstr "模拟单声道"
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "模拟耳机"
 
-#: ../src/modules/alsa/alsa-mixer.c:1777
-#, fuzzy
-msgid "Analog Video"
-msgstr "模拟立体声"
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "模拟输入"
 
-#: ../src/modules/alsa/alsa-mixer.c:1778
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr "扩展坞麦克风"
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
 msgid "Analog Output"
-msgstr "输出 %s"
+msgstr "模拟输出 "
+
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "模拟输出(LFE)"
 
-#: ../src/modules/alsa/alsa-mixer.c:1779
+#: ../src/modules/alsa/alsa-mixer.c:2313
 #, fuzzy
-msgid "Analog Headphones"
-msgstr "模拟单声道"
+msgid "Line Out"
+msgstr "Line In"
 
-#: ../src/modules/alsa/alsa-mixer.c:1780
-msgid "Analog Output (LFE)"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2314
+msgid "Analog Mono Output"
+msgstr "模拟单声道输出"
 
-#: ../src/modules/alsa/alsa-mixer.c:1781
+#: ../src/modules/alsa/alsa-mixer.c:2315
 #, fuzzy
-msgid "Analog Mono Output"
-msgstr "模拟单声道"
+msgid "Speakers"
+msgstr "模拟立体声"
 
-#: ../src/modules/alsa/alsa-mixer.c:1981
-#, c-format
-msgid "%s+%s"
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
 msgstr ""
 
-#: ../src/modules/alsa/alsa-mixer.c:1984 ../src/modules/alsa/alsa-mixer.c:3404
-#, c-format
-msgid "%s / %s"
-msgstr ""
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "数字立体声(HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "数字立体声(HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2790
+#: ../src/modules/alsa/alsa-mixer.c:3756
 msgid "Analog Mono"
 msgstr "模拟单声道"
 
-#: ../src/modules/alsa/alsa-mixer.c:2791
+#: ../src/modules/alsa/alsa-mixer.c:3757
 msgid "Analog Stereo"
 msgstr "模拟立体声"
 
-#: ../src/modules/alsa/alsa-mixer.c:2792
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3758
 msgid "Analog Surround 2.1"
-msgstr "模拟环绕 4.1"
+msgstr "模拟环绕 2.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2793
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3759
 msgid "Analog Surround 3.0"
-msgstr "模拟环绕 4.0"
+msgstr "模拟环绕 3.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2794
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3760
 msgid "Analog Surround 3.1"
-msgstr "模拟环绕 4.1"
+msgstr "模拟环绕 3.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2795
+#: ../src/modules/alsa/alsa-mixer.c:3761
 msgid "Analog Surround 4.0"
 msgstr "模拟环绕 4.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3762
 msgid "Analog Surround 4.1"
 msgstr "模拟环绕 4.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2797
+#: ../src/modules/alsa/alsa-mixer.c:3763
 msgid "Analog Surround 5.0"
 msgstr "模拟环绕 5.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2798
+#: ../src/modules/alsa/alsa-mixer.c:3764
 msgid "Analog Surround 5.1"
 msgstr "模拟环绕 5.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2799
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3765
 msgid "Analog Surround 6.0"
-msgstr "模拟环绕 4.0"
+msgstr "模拟环绕 6.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2800
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3766
 msgid "Analog Surround 6.1"
-msgstr "模拟环绕 4.1"
+msgstr "模拟环绕 6.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2801
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3767
 msgid "Analog Surround 7.0"
-msgstr "模拟环绕 4.0"
+msgstr "模拟环绕 7.0"
 
-#: ../src/modules/alsa/alsa-mixer.c:2802
+#: ../src/modules/alsa/alsa-mixer.c:3768
 msgid "Analog Surround 7.1"
 msgstr "模拟环绕 7.1"
 
-#: ../src/modules/alsa/alsa-mixer.c:2803
+#: ../src/modules/alsa/alsa-mixer.c:3769
 msgid "Digital Stereo (IEC958)"
 msgstr "数字立体声(IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2804
+#: ../src/modules/alsa/alsa-mixer.c:3770
 #, fuzzy
-msgid "Digital Surround 4.0 (IEC958)"
-msgstr "æ\95°å­\97ç\8e¯ç»\95 4.0ï¼\88IEC958/AC3)"
+msgid "Digital Passthrough  (IEC958)"
+msgstr "æ\95°å­\97ç«\8bä½\93声ï¼\88IEC958)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2805
+#: ../src/modules/alsa/alsa-mixer.c:3771
 msgid "Digital Surround 4.0 (IEC958/AC3)"
 msgstr "数字环绕 4.0(IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2806
+#: ../src/modules/alsa/alsa-mixer.c:3772
 msgid "Digital Surround 5.1 (IEC958/AC3)"
 msgstr "数字环绕 5.1(IEC958/AC3)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2807
+#: ../src/modules/alsa/alsa-mixer.c:3773
 msgid "Digital Stereo (HDMI)"
 msgstr "数字立体声(HDMI)"
 
-#: ../src/modules/alsa/alsa-mixer.c:2928
+#: ../src/modules/alsa/alsa-mixer.c:3774
 #, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "数字环绕 5.1(IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
 msgid "Analog Mono Duplex"
-msgstr "模拟单声道"
+msgstr "模拟单声道双工"
 
-#: ../src/modules/alsa/alsa-mixer.c:2929
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3896
 msgid "Analog Stereo Duplex"
-msgstr "模拟立体声"
+msgstr "模拟立体声双工"
 
-#: ../src/modules/alsa/alsa-mixer.c:2930
-#, fuzzy
+#: ../src/modules/alsa/alsa-mixer.c:3897
 msgid "Digital Stereo Duplex (IEC958)"
-msgstr "数字立体声(IEC958)"
-
-#, fuzzy
-#~ msgid "Invalid client name '%s'\n"
-#~ msgstr "无效的通道映射描述'%s'\n"
-
-#, fuzzy
-#~ msgid "Failed to determine sample specification from file.\n"
-#~ msgstr "获取采样信息失败:%s\n"
-
-#~ msgid "select(): %s"
-#~ msgstr "select():%s"
-
-#~ msgid "Cannot connect to system bus: %s"
-#~ msgstr "无法连接到系统总线:%s"
-
-#~ msgid "Cannot get caller from PID: %s"
-#~ msgstr "无法从PID获取调用者:%s"
-
-#~ msgid "Cannot set UID on caller object."
-#~ msgstr "无法为调用者设定UID。"
-
-#~ msgid "Failed to get CK session."
-#~ msgstr "获取CK会话失败。"
-
-#~ msgid "Cannot set UID on session object."
-#~ msgstr "无法为会话对象设定UID。"
-
-#~ msgid "Cannot allocate PolKitAction."
-#~ msgstr "不能分配PolKitAction。"
-
-#~ msgid "Cannot set action_id"
-#~ msgstr "无法设定action_id"
-
-#~ msgid "Cannot allocate PolKitContext."
-#~ msgstr "无法分配PolKitContext。"
+msgstr "数字立体声双工(IEC958)"
 
-#~ msgid "Cannot initialize PolKitContext: %s"
-#~ msgstr "无法初使化PolKitContext: %s"
-
-#~ msgid "Could not determine whether caller is authorized: %s"
-#~ msgstr "无法判断调用者是否已获得授权: %s"
-
-#~ msgid "Cannot obtain auth: %s"
-#~ msgstr "无法获取授权: %s"
-
-#~ msgid "PolicyKit responded with '%s'"
-#~ msgstr "PolicyKit回复'%s'"
-
-#~ msgid ""
-#~ "High-priority scheduling (negative Unix nice level) for the PulseAudio "
-#~ "daemon"
-#~ msgstr "PulseAudio 守护进程的高优先调度(负的 Unix nic 等级)"
-
-#~ msgid "Real-time scheduling for the PulseAudio daemon"
-#~ msgstr "PulseAudio 守护进程的实时调度。"
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "空输出"
 
-#~ msgid ""
-#~ "System policy prevents PulseAudio from acquiring high-priority scheduling."
-#~ msgstr "系统策略防止 PulseAudio 获得高优先调度。"
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "输入"
 
-#~ msgid ""
-#~ "System policy prevents PulseAudio from acquiring real-time scheduling."
-#~ msgstr "系统策略防止 PulseAudio 获得实时调度。"
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
 
-#~ msgid "read() failed: %s\n"
-#~ msgstr "read()失败:%s\n"
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
 
+#: ../src/modules/module-equalizer-sink.c:76
 #, fuzzy
-#~ msgid "pa_context_connect() failed: %s\n"
-#~ msgstr "pa_context_connect()失败:%s"
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+"sink_name=<name for the sink> sink_properties=<properties for the sink> "
+"master=<name of sink to filter> format=<sample format> rate=<sample rate> "
+"channels=<number of channels> channel_map=<channel map> plugin=<ladspa "
+"plugin name> label=<ladspa plugin label> control=<comma separated list of "
+"input control values>"
 
-#~ msgid "We're in the group '%s', allowing high-priority scheduling."
-#~ msgstr "我们在'%s'组中,允许高优先级调度。"
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
 
-#~ msgid "We're in the group '%s', allowing real-time scheduling."
-#~ msgstr "我们在'%s'组中,允许实时调度。"
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
 
-#~ msgid "PolicyKit grants us acquire-high-priority privilege."
-#~ msgstr "PolicyKit授予我们“获取高优先级”权限。"
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
 
-#~ msgid "PolicyKit refuses acquire-high-priority privilege."
-#~ msgstr "PolicyKit拒绝“获取高优先级”权限。"
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
 
-#~ msgid "PolicyKit grants us acquire-real-time privilege."
-#~ msgstr "PolicyKit授予我们“获取实时”权限。"
+#~ msgid "[%s:%u] rlimit not supported on this platform."
+#~ msgstr "[%s:%u] 此平台不支持rlimit。"
 
-#~ msgid "PolicyKit refuses acquire-real-time privilege."
-#~ msgstr "PolicyKit拒绝我们“获取实时”权限。"
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay()失败"
 
 #~ msgid ""
-#~ "Called SUID root and real-time and/or high-priority scheduling was "
-#~ "requested in the configuration. However, we lack the necessary "
-#~ "privileges:\n"
-#~ "We are not in group '%s', PolicyKit refuse to grant us the requested "
-#~ "privileges and we have no increase RLIMIT_NICE/RLIMIT_RTPRIO resource "
-#~ "limits.\n"
-#~ "For enabling real-time/high-priority scheduling please acquire the "
-#~ "appropriate PolicyKit privileges, or become a member of '%s', or increase "
-#~ "the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
 #~ msgstr ""
-#~ "配置中需要调用 SUID root、实时和/或者高优先调度。但是我们缺少必要的特"
-#~ "权:\n"
-#~ "我们不属于组群 '%s',PolicyKit 拒绝赋予我们要求的特权,而我们无法增加 "
-#~ "RLIMIT_NICE/RLIMIT_RTPRIO 资源限制。\n"
-#~ "要启用实时/高优先调度,请获得适当的 PolicyKit 特权,或者成为 '%s' 成员,也"
-#~ "可以为这个用户增加 RLIMIT_NICE/RLIMIT_RTPRIO 资源限制。"
-
-#~ msgid ""
-#~ "High-priority scheduling enabled in configuration but not allowed by "
-#~ "policy."
-#~ msgstr "配置中已启用高优先级调度,但策略未允许。"
-
-#~ msgid "Successfully increased RLIMIT_RTPRIO"
-#~ msgstr "提高RLIMIT_RTPRIO成功。"
-
-#~ msgid "RLIMIT_RTPRIO failed: %s"
-#~ msgstr "RLIMIT_RTPRIO失败:%s"
-
-#~ msgid "Giving up CAP_NICE"
-#~ msgstr "正在放弃CAP_NICE"
-
-#~ msgid ""
-#~ "Real-time scheduling enabled in configuration but not allowed by policy."
-#~ msgstr "配置中已启用实时调度,但策略未允许。"
-
-#~ msgid "Limited capabilities successfully to CAP_SYS_NICE."
-#~ msgstr "性能成功限制到CAP_SYS_NICE。"
-
-#~ msgid "time_new() failed.\n"
-#~ msgstr "time_new()失败。\n"
-
-#~ msgid "Output %s + Input %s"
-#~ msgstr "输出 %s + 输入 %s"
-
-#~ msgid "Stream successfully created\n"
-#~ msgstr "成功创建流\n"
-
-#~ msgid "Stream errror: %s\n"
-#~ msgstr "流错误:%s\n"
-
-#~ msgid "Connection established.\n"
-#~ msgstr "连接已建立。\n"
+#~ "Source Output #%u\n"
+#~ "\tDriver: %s\n"
+#~ "\tOwner Module: %s\n"
+#~ "\tClient: %s\n"
+#~ "\tSource: %u\n"
+#~ "\tSample Specification: %s\n"
+#~ "\tChannel Map: %s\n"
+#~ "\tBuffer Latency: %0.0f usec\n"
+#~ "\tSource Latency: %0.0f usec\n"
+#~ "\tResample method: %s\n"
+#~ "\tProperties:\n"
+#~ "\t\t%s\n"
 
+#, fuzzy
 #~ msgid ""
-#~ "%s [options] [FILE]\n"
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
+#~ "%s [options] subscribe\n"
 #~ "\n"
 #~ "  -h, --help                            Show this help\n"
 #~ "      --version                         Show version\n"
 #~ "\n"
-#~ "  -v, --verbose                         Enable verbose operation\n"
-#~ "\n"
 #~ "  -s, --server=SERVER                   The name of the server to connect "
 #~ "to\n"
-#~ "  -d, --device=DEVICE                   The name of the sink to connect "
-#~ "to\n"
 #~ "  -n, --client-name=NAME                How to call this client on the "
 #~ "server\n"
-#~ "      --stream-name=NAME                How to call this stream on the "
-#~ "server\n"
-#~ "      --volume=VOLUME                   Specify the initial (linear) "
-#~ "volume in range 0...65536\n"
-#~ "      --channel-map=CHANNELMAP          Set the channel map to the use\n"
 #~ msgstr ""
-#~ "%s [options] [FILE]\n"
+#~ "%s [options] stat\n"
+#~ "%s [options] list\n"
+#~ "%s [options] exit\n"
+#~ "%s [options] upload-sample FILENAME [NAME]\n"
+#~ "%s [options] play-sample NAME [SINK]\n"
+#~ "%s [options] remove-sample NAME\n"
+#~ "%s [options] move-sink-input SINKINPUT SINK\n"
+#~ "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
+#~ "%s [options] load-module NAME [ARGS ...]\n"
+#~ "%s [options] unload-module MODULE\n"
+#~ "%s [options] suspend-sink SINK 1|0\n"
+#~ "%s [options] suspend-source SOURCE 1|0\n"
+#~ "%s [options] set-card-profile CARD PROFILE\n"
+#~ "%s [options] set-sink-port SINK PORT\n"
+#~ "%s [options] set-source-port SOURCE PORT\n"
+#~ "%s [options] set-sink-volume SINK VOLUME\n"
+#~ "%s [options] set-source-volume SOURCE VOLUME\n"
+#~ "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
+#~ "%s [options] set-sink-mute SINK 1|0\n"
+#~ "%s [options] set-source-mute SOURCE 1|0\n"
+#~ "%s [options] set-sink-input-mute SINKINPUT 1|0\n"
 #~ "\n"
-#~ "  -h, --help                            显示此帮助\n"
-#~ "      --version                         显示版本\n"
-#~ "\n"
-#~ "  -v, --verbose                         启用详述操作\n"
+#~ "  -h, --help                            Show this help\n"
+#~ "      --version                         Show version\n"
 #~ "\n"
-#~ "  -s, --server=SERVER                   要连接的服务器名\n"
-#~ "  -d, --device=DEVICE                   要连接的音频出口名\n"
-#~ "  -n, --client-name=NAME                此客户端在服务器上的名称\n"
-#~ "      --stream-name=NAME                此流在服务器上的名称\n"
-#~ "      --volume=VOLUME                   指定初始(线性)音量,取值在"
-#~ "0...65536之间\n"
-#~ "      --channel-map=CHANNELMAP          设定使用的通道映射表\n"
-
-#~ msgid ""
-#~ "paplay %s\n"
-#~ "Compiled with libpulse %s\n"
-#~ "Linked with libpulse %s\n"
-#~ msgstr ""
-#~ "paplay %s\n"
-#~ "Compiled with libpulse %s\n"
-#~ "Linked with libpulse %s\n"
+#~ "  -s, --server=SERVER                   The name of the server to connect "
+#~ "to\n"
+#~ "  -n, --client-name=NAME                How to call this client on the "
+#~ "server\n"
 
-#~ msgid "Invalid channel map\n"
-#~ msgstr "无效的通道映射表\n"
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
 
-#~ msgid "Failed to open file '%s'\n"
-#~ msgstr "打开文件'%s'失败\n"
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
 
-#~ msgid "Channel map doesn't match file.\n"
-#~ msgstr "通道映射表与文件不匹配。\n"
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "数字环绕 4.0(IEC958)"
 
-#~ msgid "Using sample spec '%s'\n"
-#~ msgstr "正在使用采样规格'%s'\n"
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "低频脉冲"
diff --git a/po/zh_TW.po b/po/zh_TW.po
new file mode 100644 (file)
index 0000000..701498a
--- /dev/null
@@ -0,0 +1,2614 @@
+# 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.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PulseAudio Volume Control\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2012-01-30 10:10+0000\n"
+"PO-Revision-Date: 2012-01-30 09:56+0000\n"
+"Last-Translator: Cheng-Chia Tseng <pswo10680@gmail.com>\n"
+"Language-Team: zh_TW\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Chinese\n"
+"X-Poedit-Country: TAIWAN\n"
+
+#: ../src/modules/alsa/alsa-util.c:1136 ../src/modules/alsa/alsa-util.c:1204
+#, 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 ""
+
+#: ../src/modules/alsa/alsa-util.c:1179
+#, 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."
+msgstr ""
+
+#: ../src/modules/alsa/alsa-util.c:1220
+#, c-format
+msgid ""
+"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
+"%lu.\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgstr ""
+
+#: ../src/modules/alsa/alsa-util.c:1263
+#, 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."
+msgstr ""
+
+#: ../src/modules/module-always-sink.c:38
+msgid "Always keeps at least one sink loaded even if it's a null one"
+msgstr ""
+
+#: ../src/modules/module-always-sink.c:82
+msgid "Dummy Output"
+msgstr "Dummy Output"
+
+#: ../src/modules/module-ladspa-sink.c:48
+msgid "Virtual LADSPA sink"
+msgstr ""
+
+#: ../src/modules/module-ladspa-sink.c:52
+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> "
+"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> "
+msgstr ""
+
+#: ../src/modules/module-null-sink.c:49
+msgid "Clocked NULL sink"
+msgstr "Clocked Null sink"
+
+#: ../src/modules/module-null-sink.c:284
+msgid "Null Output"
+msgstr "Null Output"
+
+#: ../src/pulsecore/sink.c:3349
+msgid "Built-in Audio"
+msgstr "內部音效"
+
+#: ../src/pulsecore/sink.c:3354
+msgid "Modem"
+msgstr "數據機"
+
+#: ../src/daemon/ltdl-bind-now.c:127
+msgid "Failed to find original lt_dlopen loader."
+msgstr "找不到 original lt_dlopen loader。"
+
+#: ../src/daemon/ltdl-bind-now.c:132
+msgid "Failed to allocate new dl loader."
+msgstr "未能分配新的 dl loader。"
+
+#: ../src/daemon/ltdl-bind-now.c:145
+msgid "Failed to add bind-now-loader."
+msgstr "未能加入 bind-now-loader。"
+
+#: ../src/daemon/main.c:139
+#, c-format
+msgid "Got signal %s."
+msgstr "取得信號 %s。"
+
+#: ../src/daemon/main.c:166
+msgid "Exiting."
+msgstr "正在退出。"
+
+#: ../src/daemon/main.c:184
+#, c-format
+msgid "Failed to find user '%s'."
+msgstr "找不到使用者「%s」。"
+
+#: ../src/daemon/main.c:189
+#, c-format
+msgid "Failed to find group '%s'."
+msgstr "找不到群組「%s」。"
+
+#: ../src/daemon/main.c:193
+#, c-format
+msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
+msgstr "找到使用者「%s」(UID %lu) 與群組「%s」(GID %lu)。"
+
+#: ../src/daemon/main.c:198
+#, c-format
+msgid "GID of user '%s' and of group '%s' don't match."
+msgstr "使用者「%s」的 GID 與群組「%s」的 GID 不相符。"
+
+#: ../src/daemon/main.c:203
+#, c-format
+msgid "Home directory of user '%s' is not '%s', ignoring."
+msgstr "使用者「%s」的家目錄不是「%s」,忽略中。"
+
+#: ../src/daemon/main.c:206 ../src/daemon/main.c:211
+#, c-format
+msgid "Failed to create '%s': %s"
+msgstr "未能建立「%s」:%s"
+
+#: ../src/daemon/main.c:218
+#, c-format
+msgid "Failed to change group list: %s"
+msgstr "未能變更群組清單:%s"
+
+#: ../src/daemon/main.c:234
+#, c-format
+msgid "Failed to change GID: %s"
+msgstr "未能變更 GIC:%s"
+
+#: ../src/daemon/main.c:250
+#, c-format
+msgid "Failed to change UID: %s"
+msgstr "未能變更 UID:%s"
+
+#: ../src/daemon/main.c:269
+msgid "Successfully dropped root privileges."
+msgstr "成功地放下 root 特權。"
+
+#: ../src/daemon/main.c:277
+msgid "System wide mode unsupported on this platform."
+msgstr "本平台不支援 system wide 模式。"
+
+#: ../src/daemon/main.c:295
+#, c-format
+msgid "setrlimit(%s, (%u, %u)) failed: %s"
+msgstr "setrlimit(%s, (%u, %u)) 失敗:%s"
+
+#: ../src/daemon/main.c:496
+msgid "Failed to parse command line."
+msgstr "未能解析命令列。"
+
+#: ../src/daemon/main.c:529
+msgid ""
+"System mode refused for non-root user. Only starting the D-Bus server lookup "
+"service."
+msgstr ""
+
+#: ../src/daemon/main.c:611
+msgid "Daemon not running"
+msgstr "幕後程式沒有在執行中"
+
+#: ../src/daemon/main.c:613
+#, c-format
+msgid "Daemon running as PID %u"
+msgstr "幕後程式正在執行中,PID 為 %u "
+
+#: ../src/daemon/main.c:628
+#, c-format
+msgid "Failed to kill daemon: %s"
+msgstr "未能結束幕後程式:%s"
+
+#: ../src/daemon/main.c:657
+msgid ""
+"This program is not intended to be run as root (unless --system is "
+"specified)."
+msgstr "本程式不預期以 root 身份執行(除非有指定 --system)。"
+
+#: ../src/daemon/main.c:660
+msgid "Root privileges required."
+msgstr "需要 root 特權。"
+
+#: ../src/daemon/main.c:667
+msgid "--start not supported for system instances."
+msgstr ""
+
+#: ../src/daemon/main.c:707
+#, c-format
+msgid "User-configured server at %s, refusing to start/autospawn."
+msgstr ""
+
+#: ../src/daemon/main.c:713
+#, c-format
+msgid ""
+"User-configured server at %s, which appears to be local. Probing deeper."
+msgstr ""
+
+#: ../src/daemon/main.c:718
+msgid "Running in system mode, but --disallow-exit not set!"
+msgstr ""
+
+#: ../src/daemon/main.c:721
+msgid "Running in system mode, but --disallow-module-loading not set!"
+msgstr ""
+
+#: ../src/daemon/main.c:724
+msgid "Running in system mode, forcibly disabling SHM mode!"
+msgstr ""
+
+#: ../src/daemon/main.c:729
+msgid "Running in system mode, forcibly disabling exit idle time!"
+msgstr ""
+
+#: ../src/daemon/main.c:757
+msgid "Failed to acquire stdio."
+msgstr "未能獲取 stdio。"
+
+#: ../src/daemon/main.c:763 ../src/daemon/main.c:828
+#, fuzzy, c-format
+msgid "pipe() failed: %s"
+msgstr "pipe 失敗: %s"
+
+#: ../src/daemon/main.c:768 ../src/daemon/main.c:833
+#, c-format
+msgid "fork() failed: %s"
+msgstr "fork() 失敗: %s"
+
+#: ../src/daemon/main.c:783 ../src/daemon/main.c:848 ../src/utils/pacat.c:550
+#, c-format
+msgid "read() failed: %s"
+msgstr "read() 失敗: %s"
+
+#: ../src/daemon/main.c:789
+msgid "Daemon startup failed."
+msgstr "幕後程式啟動失敗。"
+
+#: ../src/daemon/main.c:791
+msgid "Daemon startup successful."
+msgstr "幕後程式啟動成功。"
+
+#: ../src/daemon/main.c:816
+#, fuzzy, c-format
+msgid "setsid() failed: %s"
+msgstr "read() 失敗: %s"
+
+#: ../src/daemon/main.c:901
+#, c-format
+msgid "This is PulseAudio %s"
+msgstr "這是 PulseAudio %s"
+
+#: ../src/daemon/main.c:902
+#, c-format
+msgid "Compilation host: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:903 ../src/tests/resampler-test.c:418
+#, c-format
+msgid "Compilation CFLAGS: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:906
+#, c-format
+msgid "Running on host: %s"
+msgstr "正在執行於此主機上:%s"
+
+#: ../src/daemon/main.c:909
+#, c-format
+msgid "Found %u CPUs."
+msgstr "找到 %u 個 CPU。"
+
+#: ../src/daemon/main.c:911
+#, c-format
+msgid "Page size is %lu bytes"
+msgstr "分頁大小為 %lu bytes"
+
+#: ../src/daemon/main.c:914
+msgid "Compiled with Valgrind support: yes"
+msgstr "以 Valgrind 支援進行編譯:是"
+
+#: ../src/daemon/main.c:916
+msgid "Compiled with Valgrind support: no"
+msgstr "以 Valgrind 支援進行編譯:否"
+
+#: ../src/daemon/main.c:919
+#, c-format
+msgid "Running in valgrind mode: %s"
+msgstr "正在以 valgrind 模式執行中:%s"
+
+#: ../src/daemon/main.c:921
+#, fuzzy, c-format
+msgid "Running in VM: %s"
+msgstr "正在執行於此主機上:%s"
+
+#: ../src/daemon/main.c:924
+msgid "Optimized build: yes"
+msgstr "最佳化的建構版本:是"
+
+#: ../src/daemon/main.c:926
+msgid "Optimized build: no"
+msgstr "最佳化的建構版本:否"
+
+#: ../src/daemon/main.c:930
+msgid "NDEBUG defined, all asserts disabled."
+msgstr ""
+
+#: ../src/daemon/main.c:932
+msgid "FASTPATH defined, only fast path asserts disabled."
+msgstr ""
+
+#: ../src/daemon/main.c:934
+msgid "All asserts enabled."
+msgstr ""
+
+#: ../src/daemon/main.c:938
+msgid "Failed to get machine ID"
+msgstr "未能取得機器 ID"
+
+#: ../src/daemon/main.c:941
+#, c-format
+msgid "Machine ID is %s."
+msgstr "機器 ID 為 %s。"
+
+#: ../src/daemon/main.c:945
+#, c-format
+msgid "Session ID is %s."
+msgstr "工作階段 ID 為 %s。"
+
+#: ../src/daemon/main.c:951
+#, c-format
+msgid "Using runtime directory %s."
+msgstr ""
+
+#: ../src/daemon/main.c:956
+#, c-format
+msgid "Using state directory %s."
+msgstr ""
+
+#: ../src/daemon/main.c:959
+#, c-format
+msgid "Using modules directory %s."
+msgstr "使用模組目錄 %s。"
+
+#: ../src/daemon/main.c:961
+#, c-format
+msgid "Running in system mode: %s"
+msgstr "以系統模式執行中:%s"
+
+#: ../src/daemon/main.c:964
+msgid ""
+"OK, so you are running PA in system mode. Please note that you most likely "
+"shouldn't be doing that.\n"
+"If you do it nonetheless then it's your own fault if things don't work as "
+"expected.\n"
+"Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an "
+"explanation why system mode is usually a bad idea."
+msgstr ""
+
+#: ../src/daemon/main.c:981
+msgid "pa_pid_file_create() failed."
+msgstr "pa_pid_file_create() 失敗。"
+
+#: ../src/daemon/main.c:991
+msgid "Fresh high-resolution timers available! Bon appetit!"
+msgstr "有新鮮的高解析度計時器可用!期望您有個好食慾!"
+
+#: ../src/daemon/main.c:993
+msgid ""
+"Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
+"resolution timers enabled!"
+msgstr "先生,您的核心糟透了!今日主廚推薦是啟用高解析度計時器的 Linux!"
+
+#: ../src/daemon/main.c:1011
+msgid "pa_core_new() failed."
+msgstr "pa_core_new() 失敗。"
+
+#: ../src/daemon/main.c:1087
+msgid "Failed to initialize daemon."
+msgstr "未能初始化幕後程式。"
+
+#: ../src/daemon/main.c:1092
+msgid "Daemon startup without any loaded modules, refusing to work."
+msgstr "幕後程式啟動而沒有任何載入的模組,拒絕運作。"
+
+#: ../src/daemon/main.c:1130
+msgid "Daemon startup complete."
+msgstr "幕後程式啟動完成。"
+
+#: ../src/daemon/main.c:1136
+msgid "Daemon shutdown initiated."
+msgstr "幕後程式已開始關閉。"
+
+#: ../src/daemon/main.c:1167
+msgid "Daemon terminated."
+msgstr "幕後程式已終止。"
+
+#: ../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                                    Increase the verbosity level\n"
+"      --log-target={auto,syslog,stderr,file: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"
+"\n"
+"STARTUP SCRIPT:\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module "
+"with\n"
+"                                        the specified argument\n"
+"  -F, --file=FILENAME                   Run the specified script\n"
+"  -C                                    Open a command line on the running "
+"TTY\n"
+"                                        after startup\n"
+"\n"
+"  -n                                    Don't load default script file\n"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:244
+msgid "--daemonize expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:251
+msgid "--fail expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:261
+msgid ""
+"--log-level expects log level argument (either numeric in range 0..4 or one "
+"of debug, info, notice, warn, error)."
+msgstr ""
+
+#: ../src/daemon/cmdline.c:273
+msgid "--high-priority expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:280
+msgid "--realtime expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:287
+msgid "--disallow-module-loading expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:294
+msgid "--disallow-exit expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:301
+msgid "--use-pid-file expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:318
+msgid ""
+"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
+"name 'file:<path>'."
+msgstr ""
+
+#: ../src/daemon/cmdline.c:325
+msgid "--log-time expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:332
+msgid "--log-meta expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:351
+#, c-format
+msgid "Invalid resample method '%s'."
+msgstr "無效的重新取樣方法「%s」"
+
+#: ../src/daemon/cmdline.c:358
+msgid "--system expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:365
+msgid "--no-cpu-limit expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:372
+msgid "--disable-shm expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:59
+#, c-format
+msgid "Name: %s\n"
+msgstr "名稱:%s\n"
+
+#: ../src/daemon/dumpmodules.c:62
+#, c-format
+msgid "No module information available\n"
+msgstr "沒有可用的模組資訊\n"
+
+#: ../src/daemon/dumpmodules.c:65
+#, c-format
+msgid "Version: %s\n"
+msgstr "版本:%s\n"
+
+#: ../src/daemon/dumpmodules.c:67
+#, c-format
+msgid "Description: %s\n"
+msgstr "描述:%s\n"
+
+#: ../src/daemon/dumpmodules.c:69
+#, c-format
+msgid "Author: %s\n"
+msgstr "作者:%s\n"
+
+#: ../src/daemon/dumpmodules.c:71
+#, c-format
+msgid "Usage: %s\n"
+msgstr "用法:%s\n"
+
+#: ../src/daemon/dumpmodules.c:72
+#, c-format
+msgid "Load Once: %s\n"
+msgstr "載入一次:%s\n"
+
+#: ../src/daemon/dumpmodules.c:74
+#, c-format
+msgid "DEPRECATION WARNING: %s\n"
+msgstr "反對警告:%s\n"
+
+#: ../src/daemon/dumpmodules.c:78
+#, c-format
+msgid "Path: %s\n"
+msgstr "路徑:%s\n"
+
+#: ../src/daemon/daemon-conf.c:275
+#, c-format
+msgid "[%s:%u] Invalid log target '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:291
+#, c-format
+msgid "[%s:%u] Invalid log level '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:307
+#, c-format
+msgid "[%s:%u] Invalid resample method '%s'."
+msgstr "[%s:%u] 無效的重新取樣方法「%s」。"
+
+#: ../src/daemon/daemon-conf.c:330
+#, c-format
+msgid "[%s:%u] Invalid rlimit '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:351
+#, c-format
+msgid "[%s:%u] Invalid sample format '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:370 ../src/daemon/daemon-conf.c:389
+#, c-format
+msgid "[%s:%u] Invalid sample rate '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:413
+#, c-format
+msgid "[%s:%u] Invalid sample channels '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:431
+#, c-format
+msgid "[%s:%u] Invalid channel map '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:449
+#, c-format
+msgid "[%s:%u] Invalid number of fragments '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:467
+#, c-format
+msgid "[%s:%u] Invalid fragment size '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:485
+#, c-format
+msgid "[%s:%u] Invalid nice level '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:528
+#, fuzzy, c-format
+msgid "[%s:%u] Invalid server type '%s'."
+msgstr "[%s:%u] 無效的重新取樣方法「%s」。"
+
+#: ../src/daemon/daemon-conf.c:641
+#, c-format
+msgid "Failed to open configuration file: %s"
+msgstr "未能開啟配置檔:%s"
+
+#: ../src/daemon/daemon-conf.c:657
+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:743
+#, c-format
+msgid "### Read from configuration file: %s ###\n"
+msgstr "### 從此配置檔讀取:%s ###\n"
+
+#: ../src/daemon/caps.c:58
+msgid "Cleaning up privileges."
+msgstr "正在清除特權。"
+
+#: ../src/daemon/pulseaudio.desktop.in.h:1
+msgid "PulseAudio Sound System"
+msgstr "PulseAudio 音效系統"
+
+#: ../src/daemon/pulseaudio.desktop.in.h:2
+msgid "Start the PulseAudio Sound System"
+msgstr "啟動 PulseAudio 音效系統"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:1
+#, fuzzy
+msgid "PulseAudio Sound System KDE Routing Policy"
+msgstr "PulseAudio 音效系統"
+
+#: ../src/daemon/pulseaudio-kde.desktop.in.h:2
+#, fuzzy
+msgid "Start the PulseAudio Sound System with KDE Routing Policy"
+msgstr "啟動 PulseAudio 音效系統"
+
+#: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:757
+msgid "Mono"
+msgstr "單聲道"
+
+#: ../src/pulse/channelmap.c:107
+msgid "Front Center"
+msgstr "正前方"
+
+#: ../src/pulse/channelmap.c:108
+msgid "Front Left"
+msgstr "左前方"
+
+#: ../src/pulse/channelmap.c:109
+msgid "Front Right"
+msgstr "右前方"
+
+#: ../src/pulse/channelmap.c:111
+msgid "Rear Center"
+msgstr "正後方"
+
+#: ../src/pulse/channelmap.c:112
+msgid "Rear Left"
+msgstr "左後方"
+
+#: ../src/pulse/channelmap.c:113
+msgid "Rear Right"
+msgstr "右後方"
+
+#: ../src/pulse/channelmap.c:115
+msgid "Subwoofer"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:117
+msgid "Front Left-of-center"
+msgstr "前方中央偏左"
+
+#: ../src/pulse/channelmap.c:118
+msgid "Front Right-of-center"
+msgstr "前方中央偏右"
+
+#: ../src/pulse/channelmap.c:120
+msgid "Side Left"
+msgstr "左側"
+
+#: ../src/pulse/channelmap.c:121
+msgid "Side Right"
+msgstr "右側"
+
+#: ../src/pulse/channelmap.c:123
+msgid "Auxiliary 0"
+msgstr "輔助 0"
+
+#: ../src/pulse/channelmap.c:124
+msgid "Auxiliary 1"
+msgstr "輔助 1"
+
+#: ../src/pulse/channelmap.c:125
+msgid "Auxiliary 2"
+msgstr "輔助 2"
+
+#: ../src/pulse/channelmap.c:126
+msgid "Auxiliary 3"
+msgstr "輔助 3"
+
+#: ../src/pulse/channelmap.c:127
+msgid "Auxiliary 4"
+msgstr "輔助 4"
+
+#: ../src/pulse/channelmap.c:128
+msgid "Auxiliary 5"
+msgstr "輔助 5"
+
+#: ../src/pulse/channelmap.c:129
+msgid "Auxiliary 6"
+msgstr "輔助 6"
+
+#: ../src/pulse/channelmap.c:130
+msgid "Auxiliary 7"
+msgstr "輔助 7"
+
+#: ../src/pulse/channelmap.c:131
+msgid "Auxiliary 8"
+msgstr "輔助 8"
+
+#: ../src/pulse/channelmap.c:132
+msgid "Auxiliary 9"
+msgstr "輔助 9"
+
+#: ../src/pulse/channelmap.c:133
+msgid "Auxiliary 10"
+msgstr "輔助 10"
+
+#: ../src/pulse/channelmap.c:134
+msgid "Auxiliary 11"
+msgstr "輔助 11"
+
+#: ../src/pulse/channelmap.c:135
+msgid "Auxiliary 12"
+msgstr "輔助 12"
+
+#: ../src/pulse/channelmap.c:136
+msgid "Auxiliary 13"
+msgstr "輔助 13"
+
+#: ../src/pulse/channelmap.c:137
+msgid "Auxiliary 14"
+msgstr "輔助 14"
+
+#: ../src/pulse/channelmap.c:138
+msgid "Auxiliary 15"
+msgstr "輔助 15"
+
+#: ../src/pulse/channelmap.c:139
+msgid "Auxiliary 16"
+msgstr "輔助 16"
+
+#: ../src/pulse/channelmap.c:140
+msgid "Auxiliary 17"
+msgstr "輔助 17"
+
+#: ../src/pulse/channelmap.c:141
+msgid "Auxiliary 18"
+msgstr "輔助 18"
+
+#: ../src/pulse/channelmap.c:142
+msgid "Auxiliary 19"
+msgstr "輔助 19"
+
+#: ../src/pulse/channelmap.c:143
+msgid "Auxiliary 20"
+msgstr "輔助 20"
+
+#: ../src/pulse/channelmap.c:144
+msgid "Auxiliary 21"
+msgstr "輔助 21"
+
+#: ../src/pulse/channelmap.c:145
+msgid "Auxiliary 22"
+msgstr "輔助 22"
+
+#: ../src/pulse/channelmap.c:146
+msgid "Auxiliary 23"
+msgstr "輔助 23"
+
+#: ../src/pulse/channelmap.c:147
+msgid "Auxiliary 24"
+msgstr "輔助 24"
+
+#: ../src/pulse/channelmap.c:148
+msgid "Auxiliary 25"
+msgstr "輔助 25"
+
+#: ../src/pulse/channelmap.c:149
+msgid "Auxiliary 26"
+msgstr "輔助 26"
+
+#: ../src/pulse/channelmap.c:150
+msgid "Auxiliary 27"
+msgstr "輔助 27"
+
+#: ../src/pulse/channelmap.c:151
+msgid "Auxiliary 28"
+msgstr "輔助 28"
+
+#: ../src/pulse/channelmap.c:152
+msgid "Auxiliary 29"
+msgstr "輔助 29"
+
+#: ../src/pulse/channelmap.c:153
+msgid "Auxiliary 30"
+msgstr "輔助 30"
+
+#: ../src/pulse/channelmap.c:154
+msgid "Auxiliary 31"
+msgstr "輔助 31"
+
+#: ../src/pulse/channelmap.c:156
+msgid "Top Center"
+msgstr "正上方"
+
+#: ../src/pulse/channelmap.c:158
+msgid "Top Front Center"
+msgstr "頂端正上方"
+
+#: ../src/pulse/channelmap.c:159
+msgid "Top Front Left"
+msgstr "頂端左前方"
+
+#: ../src/pulse/channelmap.c:160
+msgid "Top Front Right"
+msgstr "頂端右前方"
+
+#: ../src/pulse/channelmap.c:162
+msgid "Top Rear Center"
+msgstr "頂端正後方"
+
+#: ../src/pulse/channelmap.c:163
+msgid "Top Rear Left"
+msgstr "頂端左後方"
+
+#: ../src/pulse/channelmap.c:164
+msgid "Top Rear Right"
+msgstr "頂端右後方"
+
+#: ../src/pulse/channelmap.c:484 ../src/pulse/sample.c:169
+#: ../src/pulse/volume.c:297 ../src/pulse/volume.c:323
+#: ../src/pulse/volume.c:343 ../src/pulse/volume.c:373
+#: ../src/pulse/format.c:125
+msgid "(invalid)"
+msgstr "(無效)"
+
+#: ../src/pulse/channelmap.c:761
+msgid "Stereo"
+msgstr "立體聲"
+
+#: ../src/pulse/channelmap.c:766
+msgid "Surround 4.0"
+msgstr "環繞聲 4.0"
+
+#: ../src/pulse/channelmap.c:772
+msgid "Surround 4.1"
+msgstr "環繞聲 4.1"
+
+#: ../src/pulse/channelmap.c:778
+msgid "Surround 5.0"
+msgstr "環繞聲 5.0"
+
+#: ../src/pulse/channelmap.c:784
+msgid "Surround 5.1"
+msgstr "環繞聲 5.1"
+
+#: ../src/pulse/channelmap.c:791
+msgid "Surround 7.1"
+msgstr "環繞聲 7.1"
+
+#: ../src/pulse/error.c:40
+msgid "OK"
+msgstr "確定"
+
+#: ../src/pulse/error.c:41
+msgid "Access denied"
+msgstr "拒絕存取"
+
+#: ../src/pulse/error.c:42
+msgid "Unknown command"
+msgstr "未知指令"
+
+#: ../src/pulse/error.c:43
+msgid "Invalid argument"
+msgstr "無效的參數"
+
+#: ../src/pulse/error.c:44
+msgid "Entity exists"
+msgstr "實體存在"
+
+#: ../src/pulse/error.c:45
+msgid "No such entity"
+msgstr "無此實體"
+
+#: ../src/pulse/error.c:46
+msgid "Connection refused"
+msgstr "拒絕連線"
+
+#: ../src/pulse/error.c:47
+msgid "Protocol error"
+msgstr "協定錯誤"
+
+#: ../src/pulse/error.c:48
+msgid "Timeout"
+msgstr "逾時"
+
+#: ../src/pulse/error.c:49
+msgid "No authorization key"
+msgstr "沒有認證金鑰"
+
+#: ../src/pulse/error.c:50
+msgid "Internal error"
+msgstr "內部錯誤"
+
+#: ../src/pulse/error.c:51
+msgid "Connection terminated"
+msgstr "連線已終止"
+
+#: ../src/pulse/error.c:52
+msgid "Entity killed"
+msgstr "實體已結束"
+
+#: ../src/pulse/error.c:53
+msgid "Invalid server"
+msgstr "無效的伺服器"
+
+#: ../src/pulse/error.c:54
+msgid "Module initialization failed"
+msgstr "模組初始化失敗"
+
+#: ../src/pulse/error.c:55
+msgid "Bad state"
+msgstr "不良狀態"
+
+#: ../src/pulse/error.c:56
+msgid "No data"
+msgstr "無資料"
+
+#: ../src/pulse/error.c:57
+msgid "Incompatible protocol version"
+msgstr "不相容的協定版本"
+
+#: ../src/pulse/error.c:58
+msgid "Too large"
+msgstr "過大"
+
+#: ../src/pulse/error.c:59
+msgid "Not supported"
+msgstr "不支援"
+
+#: ../src/pulse/error.c:60
+msgid "Unknown error code"
+msgstr "未知的錯誤碼"
+
+#: ../src/pulse/error.c:61
+msgid "No such extension"
+msgstr "無此擴展功能"
+
+#: ../src/pulse/error.c:62
+msgid "Obsolete functionality"
+msgstr "淘汰的功能"
+
+#: ../src/pulse/error.c:63
+msgid "Missing implementation"
+msgstr "遺失的實作"
+
+#: ../src/pulse/error.c:64
+msgid "Client forked"
+msgstr "客戶端已分支"
+
+#: ../src/pulse/error.c:65
+msgid "Input/Output error"
+msgstr "輸入/輸出 錯誤"
+
+#: ../src/pulse/error.c:66
+msgid "Device or resource busy"
+msgstr "裝置或資源忙碌"
+
+#: ../src/pulse/sample.c:171
+#, c-format
+msgid "%s %uch %uHz"
+msgstr "%s %uch %uHz"
+
+#: ../src/pulse/sample.c:183
+#, c-format
+msgid "%0.1f GiB"
+msgstr "%0.1f GiB"
+
+#: ../src/pulse/sample.c:185
+#, c-format
+msgid "%0.1f MiB"
+msgstr "%0.1f MiB"
+
+#: ../src/pulse/sample.c:187
+#, c-format
+msgid "%0.1f KiB"
+msgstr "%0.1f KiB"
+
+#: ../src/pulse/sample.c:189
+#, c-format
+msgid "%u B"
+msgstr "%u B"
+
+#: ../src/pulse/client-conf-x11.c:54 ../src/utils/pax11publish.c:100
+#, fuzzy
+msgid "xcb_connect() failed"
+msgstr "pa_context_connect() 失敗:%s"
+
+#: ../src/pulse/client-conf-x11.c:59 ../src/utils/pax11publish.c:105
+msgid "xcb_connection_has_error() returned true"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:97
+msgid "Failed to parse cookie data"
+msgstr "未能解析 cookie 資料"
+
+#: ../src/pulse/client-conf.c:117
+#, c-format
+msgid "Failed to open configuration file '%s': %s"
+msgstr "未能開啟配置檔「%s」:%s"
+
+#: ../src/pulse/context.c:528
+msgid "No cookie loaded. Attempting to connect without."
+msgstr "沒有載入 cookie。試圖連接而不用 cookie。"
+
+#: ../src/pulse/context.c:675
+#, c-format
+msgid "fork(): %s"
+msgstr "fork(): %s"
+
+#: ../src/pulse/context.c:730
+#, c-format
+msgid "waitpid(): %s"
+msgstr "waitpid(): %s"
+
+#: ../src/pulse/context.c:1431
+#, c-format
+msgid "Received message for unknown extension '%s'"
+msgstr "已接收到未知擴展功能的訊息「%s」"
+
+#: ../src/utils/pacat.c:112
+#, c-format
+msgid "Failed to drain stream: %s"
+msgstr "未能排出串流:%s"
+
+#: ../src/utils/pacat.c:117
+msgid "Playback stream drained."
+msgstr "播放控制串流已排出。"
+
+#: ../src/utils/pacat.c:128
+msgid "Draining connection to server."
+msgstr "正在排出連線到伺服器。"
+
+#: ../src/utils/pacat.c:141
+#, c-format
+msgid "pa_stream_drain(): %s"
+msgstr "pa_stream_drain(): %s"
+
+#: ../src/utils/pacat.c:164
+#, c-format
+msgid "pa_stream_write() failed: %s"
+msgstr "pa_stream_write() failed: %s"
+
+#: ../src/utils/pacat.c:205
+#, c-format
+msgid "pa_stream_begin_write() failed: %s"
+msgstr "pa_stream_begin_write() 失敗: %s"
+
+#: ../src/utils/pacat.c:255 ../src/utils/pacat.c:285
+#, c-format
+msgid "pa_stream_peek() failed: %s"
+msgstr "pa_stream_peek() 失敗: %s"
+
+#: ../src/utils/pacat.c:325
+msgid "Stream successfully created."
+msgstr "已成功建立串流。"
+
+#: ../src/utils/pacat.c:328
+#, c-format
+msgid "pa_stream_get_buffer_attr() failed: %s"
+msgstr "pa_stream_get_buffer_attr() 失敗: %s"
+
+#: ../src/utils/pacat.c:332
+#, c-format
+msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
+msgstr ""
+
+#: ../src/utils/pacat.c:335
+#, c-format
+msgid "Buffer metrics: maxlength=%u, fragsize=%u"
+msgstr ""
+
+#: ../src/utils/pacat.c:339
+#, c-format
+msgid "Using sample spec '%s', channel map '%s'."
+msgstr "使用取樣規格「%s」,聲道對應表「%s」"
+
+#: ../src/utils/pacat.c:343
+#, c-format
+msgid "Connected to device %s (%u, %ssuspended)."
+msgstr "正在連接到裝置 %s (%u, %ssuspended)。"
+
+#: ../src/utils/pacat.c:353
+#, c-format
+msgid "Stream error: %s"
+msgstr "串流錯誤:%s"
+
+#: ../src/utils/pacat.c:363
+#, c-format
+msgid "Stream device suspended.%s"
+msgstr "串流裝置已暫停。%s"
+
+#: ../src/utils/pacat.c:365
+#, c-format
+msgid "Stream device resumed.%s"
+msgstr "串流裝置已恢復:%s"
+
+#: ../src/utils/pacat.c:373
+#, c-format
+msgid "Stream underrun.%s"
+msgstr "串流欠載運行。%s"
+
+#: ../src/utils/pacat.c:380
+#, c-format
+msgid "Stream overrun.%s"
+msgstr "串流超載運行。%s"
+
+#: ../src/utils/pacat.c:387
+#, c-format
+msgid "Stream started.%s"
+msgstr "串流已開始。%s"
+
+#: ../src/utils/pacat.c:394
+#, c-format
+msgid "Stream moved to device %s (%u, %ssuspended).%s"
+msgstr "串流移至裝置 %s (%u, %ssuspended)。%s"
+
+#: ../src/utils/pacat.c:394
+msgid "not "
+msgstr "不是"
+
+#: ../src/utils/pacat.c:401
+#, c-format
+msgid "Stream buffer attributes changed.%s"
+msgstr "串流緩衝特徵已變更。%s"
+
+#: ../src/utils/pacat.c:416
+msgid "Cork request stack is empty: corking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:422
+msgid "Cork request stack is empty: uncorking stream"
+msgstr ""
+
+#: ../src/utils/pacat.c:426
+msgid "Warning: Received more uncork requests than cork requests!"
+msgstr ""
+
+#: ../src/utils/pacat.c:451
+#, c-format
+msgid "Connection established.%s"
+msgstr "連線已建立。%s"
+
+#: ../src/utils/pacat.c:454
+#, c-format
+msgid "pa_stream_new() failed: %s"
+msgstr "pa_stream_new() 失敗:%s"
+
+#: ../src/utils/pacat.c:492
+#, c-format
+msgid "pa_stream_connect_playback() failed: %s"
+msgstr "pa_stream_connect_playback() 失敗:%s"
+
+#: ../src/utils/pacat.c:498
+#, c-format
+msgid "pa_stream_connect_record() failed: %s"
+msgstr "pa_stream_connect_record() 失敗:%s"
+
+#: ../src/utils/pacat.c:512 ../src/utils/pactl.c:1252
+#, c-format
+msgid "Connection failure: %s"
+msgstr "連線失敗:%s"
+
+#: ../src/utils/pacat.c:545
+msgid "Got EOF."
+msgstr "取得檔案結尾 (EOF)。"
+
+#: ../src/utils/pacat.c:582
+#, c-format
+msgid "write() failed: %s"
+msgstr "write() 失敗:%s"
+
+#: ../src/utils/pacat.c:603
+msgid "Got signal, exiting."
+msgstr "取得訊號,正在退出。"
+
+#: ../src/utils/pacat.c:617
+#, c-format
+msgid "Failed to get latency: %s"
+msgstr "未能取得傳輸延遲:%s"
+
+#: ../src/utils/pacat.c:622
+#, c-format
+msgid "Time: %0.3f sec; Latency: %0.0f usec."
+msgstr "時間:%0.3f 秒;延遲:%0.0f 微秒。"
+
+#: ../src/utils/pacat.c:643
+#, c-format
+msgid "pa_stream_update_timing_info() failed: %s"
+msgstr "pa_stream_update_timing_info() 失敗:%s"
+
+#: ../src/utils/pacat.c:653
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"\n"
+"  -r, --record                          Create a connection for recording\n"
+"  -p, --playback                        Create a connection for playback\n"
+"\n"
+"  -v, --verbose                         Enable verbose operations\n"
+"\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -d, --device=DEVICE                   The name of the sink/source to "
+"connect to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
+"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to "
+"44100)\n"
+"      --format=SAMPLEFORMAT             The sample type, one of s16le, "
+"s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be, "
+"s24le, s24be,\n"
+"                                        s24-32le, s24-32be (defaults to "
+"s16ne)\n"
+"      --channels=CHANNELS               The number of channels, 1 for mono, "
+"2 for stereo\n"
+"                                        (defaults to 2)\n"
+"      --channel-map=CHANNELMAP          Channel map to use instead of the "
+"default\n"
+"      --fix-format                      Take the sample format from the sink "
+"the stream is\n"
+"                                        being connected to.\n"
+"      --fix-rate                        Take the sampling rate from the sink "
+"the stream is\n"
+"                                        being connected to.\n"
+"      --fix-channels                    Take the number of channels and the "
+"channel map\n"
+"                                        from the sink the stream is being "
+"connected to.\n"
+"      --no-remix                        Don't upmix or downmix channels.\n"
+"      --no-remap                        Map channels by index instead of "
+"name.\n"
+"      --latency=BYTES                   Request the specified latency in "
+"bytes.\n"
+"      --process-time=BYTES              Request the specified process time "
+"per request in bytes.\n"
+"      --latency-msec=MSEC               Request the specified latency in "
+"msec.\n"
+"      --process-time-msec=MSEC          Request the specified process time "
+"per request in msec.\n"
+"      --property=PROPERTY=VALUE         Set the specified property to the "
+"specified value.\n"
+"      --raw                             Record/play raw PCM data.\n"
+"      --passthrough                     passthrough data \n"
+"      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
+"      --list-file-formats               List available file formats.\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:786
+#, c-format
+msgid ""
+"pacat %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:819 ../src/utils/pactl.c:1400
+#, c-format
+msgid "Invalid client name '%s'"
+msgstr "無效的客戶端名稱「%s」"
+
+#: ../src/utils/pacat.c:834
+#, c-format
+msgid "Invalid stream name '%s'"
+msgstr "無效的串流名稱「%s」"
+
+#: ../src/utils/pacat.c:871
+#, c-format
+msgid "Invalid channel map '%s'"
+msgstr "無效的聲道對應表「%s」"
+
+#: ../src/utils/pacat.c:900 ../src/utils/pacat.c:914
+#, c-format
+msgid "Invalid latency specification '%s'"
+msgstr "無效的延遲規格「%s」"
+
+#: ../src/utils/pacat.c:907 ../src/utils/pacat.c:921
+#, c-format
+msgid "Invalid process time specification '%s'"
+msgstr "無效的程序時間規格「%s」"
+
+#: ../src/utils/pacat.c:933
+#, c-format
+msgid "Invalid property '%s'"
+msgstr "無效的屬性「%s」"
+
+#: ../src/utils/pacat.c:952
+#, c-format
+msgid "Unknown file format %s."
+msgstr "未知檔案格式 %s。"
+
+#: ../src/utils/pacat.c:971
+msgid "Invalid sample specification"
+msgstr "無效的取樣規格"
+
+#: ../src/utils/pacat.c:981
+#, c-format
+msgid "open(): %s"
+msgstr "open(): %s"
+
+#: ../src/utils/pacat.c:986
+#, c-format
+msgid "dup2(): %s"
+msgstr "dup2(): %s"
+
+#: ../src/utils/pacat.c:993
+msgid "Too many arguments."
+msgstr "太多參數。"
+
+#: ../src/utils/pacat.c:1004
+msgid "Failed to generate sample specification for file."
+msgstr "未能替檔案產生取樣規格。"
+
+#: ../src/utils/pacat.c:1030
+msgid "Failed to open audio file."
+msgstr "未能開啟音效檔。"
+
+#: ../src/utils/pacat.c:1036
+msgid ""
+"Warning: specified sample specification will be overwritten with "
+"specification from file."
+msgstr "警告:指定的取樣規格將會覆寫從檔案得到的規格。"
+
+#: ../src/utils/pacat.c:1039 ../src/utils/pactl.c:1467
+msgid "Failed to determine sample specification from file."
+msgstr "未能從檔案得知取樣規格。"
+
+#: ../src/utils/pacat.c:1048
+msgid "Warning: Failed to determine channel map from file."
+msgstr "警告:未能從檔案取得聲道對應表。"
+
+#: ../src/utils/pacat.c:1059
+msgid "Channel map doesn't match sample specification"
+msgstr "聲道對應表與取樣規格不符"
+
+#: ../src/utils/pacat.c:1070
+msgid "Warning: failed to write channel map to file."
+msgstr "警告:未能將聲道對應表寫入檔案。"
+
+#: ../src/utils/pacat.c:1085
+#, c-format
+msgid ""
+"Opening a %s stream with sample specification '%s' and channel map '%s'."
+msgstr "正在開啟一道 %s 串流,取樣規格為「%s」,聲道對應表為「%s」。"
+
+#: ../src/utils/pacat.c:1086
+msgid "recording"
+msgstr "錄製"
+
+#: ../src/utils/pacat.c:1086
+msgid "playback"
+msgstr "播放控制"
+
+#: ../src/utils/pacat.c:1110
+#, fuzzy
+msgid "Failed to set media name."
+msgstr "未能解析命令列。"
+
+#: ../src/utils/pacat.c:1117 ../src/utils/pactl.c:1777
+msgid "pa_mainloop_new() failed."
+msgstr "pa_mainloop_new() 失敗。"
+
+#: ../src/utils/pacat.c:1136
+msgid "io_new() failed."
+msgstr "io_new() 失敗。"
+
+#: ../src/utils/pacat.c:1143 ../src/utils/pactl.c:1789
+msgid "pa_context_new() failed."
+msgstr "pa_context_new() 失敗。"
+
+#: ../src/utils/pacat.c:1151 ../src/utils/pactl.c:1795
+#, c-format
+msgid "pa_context_connect() failed: %s"
+msgstr "pa_context_connect() 失敗:%s"
+
+#: ../src/utils/pacat.c:1157
+msgid "pa_context_rttime_new() failed."
+msgstr "pa_context_rttime_new() 失敗。"
+
+#: ../src/utils/pacat.c:1164 ../src/utils/pactl.c:1800
+msgid "pa_mainloop_run() failed."
+msgstr "pa_mainloop_run() 失敗。"
+
+#: ../src/utils/pasuspender.c:79
+#, c-format
+msgid "fork(): %s\n"
+msgstr "fork(): %s\n"
+
+#: ../src/utils/pasuspender.c:90
+#, c-format
+msgid "execvp(): %s\n"
+msgstr "execvp(): %s\n"
+
+#: ../src/utils/pasuspender.c:107
+#, c-format
+msgid "Failure to suspend: %s\n"
+msgstr "未能暫停:%s\n"
+
+#: ../src/utils/pasuspender.c:122
+#, c-format
+msgid "Failure to resume: %s\n"
+msgstr "未能恢復:%s\n"
+
+#: ../src/utils/pasuspender.c:145
+#, c-format
+msgid "WARNING: Sound server is not local, not suspending.\n"
+msgstr "警告:音效伺服器並非本機,不會暫停。\n"
+
+#: ../src/utils/pasuspender.c:157
+#, c-format
+msgid "Connection failure: %s\n"
+msgstr "連線失敗:%s\n"
+
+#: ../src/utils/pasuspender.c:174
+#, c-format
+msgid "Got SIGINT, exiting.\n"
+msgstr "取得 SIGINT,正在退出。\n"
+
+#: ../src/utils/pasuspender.c:192
+#, c-format
+msgid "WARNING: Child process terminated by signal %u\n"
+msgstr "警告:子程序已被訊號 %u 所終止\n"
+
+#: ../src/utils/pasuspender.c:210
+#, c-format
+msgid ""
+"%s [options] ... \n"
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:248
+#, c-format
+msgid ""
+"pasuspender %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:277
+#, c-format
+msgid "pa_mainloop_new() failed.\n"
+msgstr "pa_mainloop_new() 失敗。\n"
+
+#: ../src/utils/pasuspender.c:290
+#, c-format
+msgid "pa_context_new() failed.\n"
+msgstr "pa_context_new() 失敗。\n"
+
+#: ../src/utils/pasuspender.c:298
+#, c-format
+msgid "pa_mainloop_run() failed.\n"
+msgstr "pa_mainloop_run() 失敗。\n"
+
+#: ../src/utils/pactl.c:150
+#, c-format
+msgid "Failed to get statistics: %s"
+msgstr "未能取得統計:%s"
+
+#: ../src/utils/pactl.c:156
+#, c-format
+msgid "Currently in use: %u blocks containing %s bytes total.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:159
+#, c-format
+msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:162
+#, c-format
+msgid "Sample cache size: %s\n"
+msgstr "取樣快取大小:%s\n"
+
+#: ../src/utils/pactl.c:171
+#, c-format
+msgid "Failed to get server information: %s"
+msgstr "未能取得伺服器資訊:%s"
+
+#: ../src/utils/pactl.c:176
+#, c-format
+msgid ""
+"Server String: %s\n"
+"Library Protocol Version: %u\n"
+"Server Protocol Version: %u\n"
+"Is Local: %s\n"
+"Client Index: %u\n"
+"Tile Size: %zu\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:192
+#, c-format
+msgid ""
+"User Name: %s\n"
+"Host Name: %s\n"
+"Server Name: %s\n"
+"Server Version: %s\n"
+"Default Sample Specification: %s\n"
+"Default Channel Map: %s\n"
+"Default Sink: %s\n"
+"Default Source: %s\n"
+"Cookie: %04x:%04x\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:244 ../src/utils/pactl.c:830
+#, c-format
+msgid "Failed to get sink information: %s"
+msgstr "未能取得 sink 資訊:%s"
+
+#: ../src/utils/pactl.c:270
+#, c-format
+msgid ""
+"Sink #%u\n"
+"\tState: %s\n"
+"\tName: %s\n"
+"\tDescription: %s\n"
+"\tDriver: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tOwner Module: %u\n"
+"\tMute: %s\n"
+"\tVolume: %s%s%s\n"
+"\t        balance %0.2f\n"
+"\tBase Volume: %s%s%s\n"
+"\tMonitor Source: %s\n"
+"\tLatency: %0.0f usec, configured %0.0f usec\n"
+"\tFlags: %s%s%s%s%s%s%s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:318 ../src/utils/pactl.c:430
+#, c-format
+msgid "\tPorts:\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:437
+#, c-format
+msgid "\tActive Port: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:331 ../src/utils/pactl.c:443
+#, c-format
+msgid "\tFormats:\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:357 ../src/utils/pactl.c:849
+#, c-format
+msgid "Failed to get source information: %s"
+msgstr "未能取得來源資訊:%s"
+
+#: ../src/utils/pactl.c:383
+#, c-format
+msgid ""
+"Source #%u\n"
+"\tState: %s\n"
+"\tName: %s\n"
+"\tDescription: %s\n"
+"\tDriver: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tOwner Module: %u\n"
+"\tMute: %s\n"
+"\tVolume: %s%s%s\n"
+"\t        balance %0.2f\n"
+"\tBase Volume: %s%s%s\n"
+"\tMonitor of Sink: %s\n"
+"\tLatency: %0.0f usec, configured %0.0f usec\n"
+"\tFlags: %s%s%s%s%s%s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:415 ../src/utils/pactl.c:485 ../src/utils/pactl.c:528
+#: ../src/utils/pactl.c:570 ../src/utils/pactl.c:640 ../src/utils/pactl.c:641
+#: ../src/utils/pactl.c:652 ../src/utils/pactl.c:711 ../src/utils/pactl.c:712
+#: ../src/utils/pactl.c:723 ../src/utils/pactl.c:775 ../src/utils/pactl.c:776
+#: ../src/utils/pactl.c:783
+msgid "n/a"
+msgstr "n/a"
+
+#: ../src/utils/pactl.c:454
+#, c-format
+msgid "Failed to get module information: %s"
+msgstr "未能取得模組資訊:%s"
+
+#: ../src/utils/pactl.c:477
+#, c-format
+msgid ""
+"Module #%u\n"
+"\tName: %s\n"
+"\tArgument: %s\n"
+"\tUsage counter: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:496
+#, c-format
+msgid "Failed to get client information: %s"
+msgstr "未能取得客戶端資訊:%s"
+
+#: ../src/utils/pactl.c:522
+#, c-format
+msgid ""
+"Client #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:539
+#, c-format
+msgid "Failed to get card information: %s"
+msgstr "未能取得音效卡資訊:%s"
+
+#: ../src/utils/pactl.c:562
+#, c-format
+msgid ""
+"Card #%u\n"
+"\tName: %s\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:576
+#, c-format
+msgid "\tProfiles:\n"
+msgstr "\t個人設定檔:\n"
+
+#: ../src/utils/pactl.c:582
+#, c-format
+msgid "\tActive Profile: %s\n"
+msgstr "\t啟用的個人設定檔:%s\n"
+
+#: ../src/utils/pactl.c:593 ../src/utils/pactl.c:868
+#, c-format
+msgid "Failed to get sink input information: %s"
+msgstr "未能取得 sink 輸入資訊:%s"
+
+#: ../src/utils/pactl.c:622
+#, c-format
+msgid ""
+"Sink Input #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tClient: %s\n"
+"\tSink: %u\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
+"\tBuffer Latency: %0.0f usec\n"
+"\tSink Latency: %0.0f usec\n"
+"\tResample method: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:663 ../src/utils/pactl.c:887
+#, c-format
+msgid "Failed to get source output information: %s"
+msgstr "未能取得來源輸出資訊:%s"
+
+#: ../src/utils/pactl.c:693
+#, c-format
+msgid ""
+"Source Output #%u\n"
+"\tDriver: %s\n"
+"\tOwner Module: %s\n"
+"\tClient: %s\n"
+"\tSource: %u\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tFormat: %s\n"
+"\tMute: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
+"\tBuffer Latency: %0.0f usec\n"
+"\tSource Latency: %0.0f usec\n"
+"\tResample method: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:734
+#, c-format
+msgid "Failed to get sample information: %s"
+msgstr "未能取得取樣資訊:%s"
+
+#: ../src/utils/pactl.c:761
+#, c-format
+msgid ""
+"Sample #%u\n"
+"\tName: %s\n"
+"\tSample Specification: %s\n"
+"\tChannel Map: %s\n"
+"\tVolume: %s\n"
+"\t        %s\n"
+"\t        balance %0.2f\n"
+"\tDuration: %0.1fs\n"
+"\tSize: %s\n"
+"\tLazy: %s\n"
+"\tFilename: %s\n"
+"\tProperties:\n"
+"\t\t%s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:791 ../src/utils/pactl.c:801
+#, c-format
+msgid "Failure: %s"
+msgstr "失敗:%s"
+
+#: ../src/utils/pactl.c:915
+#, fuzzy, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "未能取得來源資訊:%s"
+
+#: ../src/utils/pactl.c:954
+#, c-format
+msgid "Failed to upload sample: %s"
+msgstr "未能上傳樣本:%s"
+
+#: ../src/utils/pactl.c:971
+msgid "Premature end of file"
+msgstr "未完成的檔案結尾"
+
+#: ../src/utils/pactl.c:991
+msgid "new"
+msgstr ""
+
+#: ../src/utils/pactl.c:994
+msgid "change"
+msgstr ""
+
+#: ../src/utils/pactl.c:997
+msgid "remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1000 ../src/utils/pactl.c:1035
+msgid "unknown"
+msgstr ""
+
+#: ../src/utils/pactl.c:1008
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1011
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1014
+msgid "sink-input"
+msgstr ""
+
+#: ../src/utils/pactl.c:1017
+msgid "source-output"
+msgstr ""
+
+#: ../src/utils/pactl.c:1020
+msgid "module"
+msgstr ""
+
+#: ../src/utils/pactl.c:1023
+msgid "client"
+msgstr ""
+
+#: ../src/utils/pactl.c:1026
+msgid "sample-cache"
+msgstr ""
+
+#: ../src/utils/pactl.c:1029 ../src/utils/pactl.c:1032
+#, fuzzy
+msgid "server"
+msgstr "無效的伺服器"
+
+#: ../src/utils/pactl.c:1041
+#, c-format
+msgid "Event '%s' on %s #%u\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1258
+msgid "Got SIGINT, exiting."
+msgstr "取得 SIGINT,正在退出。"
+
+#: ../src/utils/pactl.c:1285
+msgid "Invalid volume specification"
+msgstr ""
+
+#: ../src/utils/pactl.c:1308
+msgid "Volume outside permissible range.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1319 ../src/utils/pactl.c:1320
+#: ../src/utils/pactl.c:1321 ../src/utils/pactl.c:1322
+#: ../src/utils/pactl.c:1323 ../src/utils/pactl.c:1324
+#: ../src/utils/pactl.c:1325 ../src/utils/pactl.c:1326
+#: ../src/utils/pactl.c:1327 ../src/utils/pactl.c:1328
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1330
+#: ../src/utils/pactl.c:1331 ../src/utils/pactl.c:1332
+#: ../src/utils/pactl.c:1333 ../src/utils/pactl.c:1334
+#: ../src/utils/pactl.c:1335 ../src/utils/pactl.c:1336
+#: ../src/utils/pactl.c:1337
+msgid "[options]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1321
+msgid "[TYPE]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1323
+msgid "FILENAME [NAME]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1324
+msgid "NAME [SINK]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1325
+msgid "NAME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1326
+msgid "NAME [ARGS ...]"
+msgstr ""
+
+#: ../src/utils/pactl.c:1327
+msgid "#N"
+msgstr ""
+
+#: ../src/utils/pactl.c:1328
+msgid "#N SINK|SOURCE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1329 ../src/utils/pactl.c:1334
+msgid "NAME|#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1330
+msgid "CARD PROFILE"
+msgstr ""
+
+#: ../src/utils/pactl.c:1331
+msgid "NAME|#N PORT"
+msgstr ""
+
+#: ../src/utils/pactl.c:1332
+msgid "NAME|#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1333
+msgid "#N VOLUME"
+msgstr ""
+
+#: ../src/utils/pactl.c:1335
+msgid "#N 1|0"
+msgstr ""
+
+#: ../src/utils/pactl.c:1336
+msgid "#N FORMATS"
+msgstr ""
+
+#: ../src/utils/pactl.c:1339
+#, c-format
+msgid ""
+"\n"
+"  -h, --help                            Show this help\n"
+"      --version                         Show version\n"
+"\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1380
+#, c-format
+msgid ""
+"pactl %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:1439
+#, c-format
+msgid "Specify nothing, or one of: %s"
+msgstr ""
+
+#: ../src/utils/pactl.c:1449
+msgid "Please specify a sample file to load"
+msgstr "請旨定要載入的取樣檔"
+
+#: ../src/utils/pactl.c:1462
+msgid "Failed to open sound file."
+msgstr "未能開啟音效檔。"
+
+#: ../src/utils/pactl.c:1474
+msgid "Warning: Failed to determine sample specification from file."
+msgstr "警告:未能從檔案得知取樣規格。"
+
+#: ../src/utils/pactl.c:1484
+msgid "You have to specify a sample name to play"
+msgstr ""
+
+#: ../src/utils/pactl.c:1496
+msgid "You have to specify a sample name to remove"
+msgstr ""
+
+#: ../src/utils/pactl.c:1505
+msgid "You have to specify a sink input index and a sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:1515
+msgid "You have to specify a source output index and a source"
+msgstr ""
+
+#: ../src/utils/pactl.c:1530
+msgid "You have to specify a module name and arguments."
+msgstr ""
+
+#: ../src/utils/pactl.c:1550
+msgid "You have to specify a module index"
+msgstr ""
+
+#: ../src/utils/pactl.c:1560
+msgid ""
+"You may not specify more than one sink. You have to specify a boolean value."
+msgstr ""
+
+#: ../src/utils/pactl.c:1573
+msgid ""
+"You may not specify more than one source. You have to specify a boolean "
+"value."
+msgstr ""
+
+#: ../src/utils/pactl.c:1585
+msgid "You have to specify a card name/index and a profile name"
+msgstr ""
+
+#: ../src/utils/pactl.c:1596
+msgid "You have to specify a sink name/index and a port name"
+msgstr ""
+
+#: ../src/utils/pactl.c:1607
+msgid "You have to specify a source name/index and a port name"
+msgstr ""
+
+#: ../src/utils/pactl.c:1618
+msgid "You have to specify a sink name/index and a volume"
+msgstr ""
+
+#: ../src/utils/pactl.c:1631
+msgid "You have to specify a source name/index and a volume"
+msgstr ""
+
+#: ../src/utils/pactl.c:1644
+msgid "You have to specify a sink input index and a volume"
+msgstr ""
+
+#: ../src/utils/pactl.c:1649
+msgid "Invalid sink input index"
+msgstr ""
+
+#: ../src/utils/pactl.c:1660
+msgid "You have to specify a source output index and a volume"
+msgstr ""
+
+#: ../src/utils/pactl.c:1665
+msgid "Invalid source output index"
+msgstr ""
+
+#: ../src/utils/pactl.c:1677
+msgid "You have to specify a sink name/index and a mute boolean"
+msgstr ""
+
+#: ../src/utils/pactl.c:1682 ../src/utils/pactl.c:1699
+#: ../src/utils/pactl.c:1721 ../src/utils/pactl.c:1742
+#, fuzzy
+msgid "Invalid mute specification"
+msgstr "無效的取樣規格"
+
+#: ../src/utils/pactl.c:1694
+msgid "You have to specify a source name/index and a mute boolean"
+msgstr ""
+
+#: ../src/utils/pactl.c:1711
+msgid "You have to specify a sink input index and a mute boolean"
+msgstr ""
+
+#: ../src/utils/pactl.c:1716
+msgid "Invalid sink input index specification"
+msgstr ""
+
+#: ../src/utils/pactl.c:1732
+msgid "You have to specify a source output index and a mute boolean"
+msgstr ""
+
+#: ../src/utils/pactl.c:1737
+#, fuzzy
+msgid "Invalid source output index specification"
+msgstr "無效的程序時間規格「%s」"
+
+#: ../src/utils/pactl.c:1756
+msgid ""
+"You have to specify a sink index and a semicolon-separated list of supported "
+"formats"
+msgstr ""
+
+#: ../src/utils/pactl.c:1772
+msgid "No valid command specified."
+msgstr "沒有指定有效的命令。"
+
+#: ../src/utils/pax11publish.c:61
+#, c-format
+msgid ""
+"%s [-D display] [-S server] [-O sink] [-I source] [-c file]  [-d|-e|-i|-r]\n"
+"\n"
+" -d    Show current PulseAudio data attached to X11 display (default)\n"
+" -e    Export local PulseAudio data to X11 display\n"
+" -i    Import PulseAudio data from X11 display to local environment "
+"variables and cookie file.\n"
+" -r    Remove PulseAudio data from X11 display\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:94
+#, c-format
+msgid "Failed to parse command line.\n"
+msgstr "未能解析命令列。\n"
+
+#: ../src/utils/pax11publish.c:113
+#, c-format
+msgid "Server: %s\n"
+msgstr "伺服器:%s\n"
+
+#: ../src/utils/pax11publish.c:115
+#, c-format
+msgid "Source: %s\n"
+msgstr "來源:%s\n"
+
+#: ../src/utils/pax11publish.c:117
+#, c-format
+msgid "Sink: %s\n"
+msgstr "Sink: %s\n"
+
+#: ../src/utils/pax11publish.c:119
+#, c-format
+msgid "Cookie: %s\n"
+msgstr "Cookie: %s\n"
+
+#: ../src/utils/pax11publish.c:137
+#, c-format
+msgid "Failed to parse cookie data\n"
+msgstr "未能解析 cookie 資料\n"
+
+#: ../src/utils/pax11publish.c:142
+#, c-format
+msgid "Failed to save cookie data\n"
+msgstr "未能儲存 cookie 資料\n"
+
+#: ../src/utils/pax11publish.c:157
+#, c-format
+msgid "Failed to load client configuration file.\n"
+msgstr "未能載入客戶端配置檔。\n"
+
+#: ../src/utils/pax11publish.c:162
+#, c-format
+msgid "Failed to read environment configuration data.\n"
+msgstr "未能讀取環境配置資料。\n"
+
+#: ../src/utils/pax11publish.c:179
+#, c-format
+msgid "Failed to get FQDN.\n"
+msgstr "未能取得 FQDN。\n"
+
+#: ../src/utils/pax11publish.c:199
+#, c-format
+msgid "Failed to load cookie data\n"
+msgstr "未能載入 cookie 資料\n"
+
+#: ../src/utils/pax11publish.c:217
+#, c-format
+msgid "Not yet implemented.\n"
+msgstr "尚未實作。\n"
+
+#: ../src/utils/pacmd.c:66
+msgid "No PulseAudio daemon running, or not running as session daemon."
+msgstr ""
+
+#: ../src/utils/pacmd.c:71
+#, c-format
+msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
+msgstr ""
+
+#: ../src/utils/pacmd.c:88
+#, c-format
+msgid "connect(): %s"
+msgstr "connect(): %s"
+
+#: ../src/utils/pacmd.c:96
+msgid "Failed to kill PulseAudio daemon."
+msgstr "未能結束 PulseAudio 幕後程式。"
+
+#: ../src/utils/pacmd.c:104
+msgid "Daemon not responding."
+msgstr "幕後程式沒有回應。"
+
+#: ../src/utils/pacmd.c:184
+#, c-format
+msgid "poll(): %s"
+msgstr "poll(): %s"
+
+#: ../src/utils/pacmd.c:195 ../src/utils/pacmd.c:215
+#, c-format
+msgid "read(): %s"
+msgstr "read(): %s"
+
+#: ../src/utils/pacmd.c:237 ../src/utils/pacmd.c:255
+#, c-format
+msgid "write(): %s"
+msgstr "write(): %s"
+
+#: ../src/pulsecore/lock-autospawn.c:136 ../src/pulsecore/lock-autospawn.c:222
+msgid "Cannot access autospawn lock."
+msgstr ""
+
+#: ../src/modules/alsa/alsa-sink.c:560 ../src/modules/alsa/alsa-sink.c:726
+#, 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:519 ../src/modules/alsa/alsa-source.c:672
+#, 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 ""
+
+#: ../src/modules/alsa/module-alsa-card.c:167
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2796
+#: ../src/modules/alsa/alsa-mixer.c:3898
+msgid "Off"
+msgstr "關閉"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2738
+msgid "High Fidelity Playback (A2DP)"
+msgstr "高傳真播放裝置 (A2DP)"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2752
+msgid "High Fidelity Capture (A2DP)"
+msgstr "高傳真擷取裝置 (A2DP)"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2767
+msgid "Telephony Duplex (HSP/HFP)"
+msgstr "電話雙工 (HSP/HFP)"
+
+#: ../src/modules/bluetooth/module-bluetooth-device.c:2781
+msgid "Handsfree Gateway"
+msgstr ""
+
+#: ../src/modules/reserve-wrap.c:151
+msgid "PulseAudio Sound Server"
+msgstr "PulseAudio 音效伺服器"
+
+#: ../src/modules/module-rygel-media-server.c:510
+#: ../src/modules/module-rygel-media-server.c:548
+#: ../src/modules/module-rygel-media-server.c:903
+msgid "Output Devices"
+msgstr "輸出裝置"
+
+#: ../src/modules/module-rygel-media-server.c:511
+#: ../src/modules/module-rygel-media-server.c:549
+#: ../src/modules/module-rygel-media-server.c:904
+msgid "Input Devices"
+msgstr "輸入裝置"
+
+#: ../src/modules/module-rygel-media-server.c:1056
+msgid "Audio on @HOSTNAME@"
+msgstr "音效位於 @HOSTNAME@"
+
+#: ../src/modules/alsa/alsa-mixer.c:2219
+msgid "Input"
+msgstr "輸入"
+
+#: ../src/modules/alsa/alsa-mixer.c:2220
+msgid "Docking Station Input"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2221
+#, fuzzy
+msgid "Docking Station Microphone"
+msgstr "內建麥克風"
+
+#: ../src/modules/alsa/alsa-mixer.c:2222
+msgid "Docking Station Line In"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2223 ../src/modules/alsa/alsa-mixer.c:2307
+msgid "Line In"
+msgstr "線路輸入"
+
+#: ../src/modules/alsa/alsa-mixer.c:2224 ../src/modules/alsa/alsa-mixer.c:2302
+msgid "Microphone"
+msgstr "麥克風"
+
+#: ../src/modules/alsa/alsa-mixer.c:2225 ../src/modules/alsa/alsa-mixer.c:2303
+#, fuzzy
+msgid "Front Microphone"
+msgstr "麥克風"
+
+#: ../src/modules/alsa/alsa-mixer.c:2226 ../src/modules/alsa/alsa-mixer.c:2304
+#, fuzzy
+msgid "Rear Microphone"
+msgstr "麥克風"
+
+#: ../src/modules/alsa/alsa-mixer.c:2227
+msgid "External Microphone"
+msgstr "外接麥克風"
+
+#: ../src/modules/alsa/alsa-mixer.c:2228 ../src/modules/alsa/alsa-mixer.c:2306
+msgid "Internal Microphone"
+msgstr "內建麥克風"
+
+#: ../src/modules/alsa/alsa-mixer.c:2229 ../src/modules/alsa/alsa-mixer.c:2308
+msgid "Radio"
+msgstr "無線電"
+
+#: ../src/modules/alsa/alsa-mixer.c:2230 ../src/modules/alsa/alsa-mixer.c:2309
+msgid "Video"
+msgstr "視訊"
+
+#: ../src/modules/alsa/alsa-mixer.c:2231
+msgid "Automatic Gain Control"
+msgstr "自動增益控制"
+
+#: ../src/modules/alsa/alsa-mixer.c:2232
+msgid "No Automatic Gain Control"
+msgstr "無自動增益控制"
+
+#: ../src/modules/alsa/alsa-mixer.c:2233
+msgid "Boost"
+msgstr "加速器"
+
+#: ../src/modules/alsa/alsa-mixer.c:2234
+msgid "No Boost"
+msgstr "無加速器"
+
+#: ../src/modules/alsa/alsa-mixer.c:2235
+msgid "Amplifier"
+msgstr "揚聲器"
+
+#: ../src/modules/alsa/alsa-mixer.c:2236
+msgid "No Amplifier"
+msgstr "無揚聲器"
+
+#: ../src/modules/alsa/alsa-mixer.c:2237
+#, fuzzy
+msgid "Bass Boost"
+msgstr "加速器"
+
+#: ../src/modules/alsa/alsa-mixer.c:2238
+#, fuzzy
+msgid "No Bass Boost"
+msgstr "無加速器"
+
+#: ../src/modules/alsa/alsa-mixer.c:2239
+msgid "Speaker"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2240 ../src/modules/alsa/alsa-mixer.c:2311
+msgid "Headphones"
+msgstr "類比頭戴式麥克風"
+
+#: ../src/modules/alsa/alsa-mixer.c:2301
+msgid "Analog Input"
+msgstr "類比輸入"
+
+#: ../src/modules/alsa/alsa-mixer.c:2305
+msgid "Dock Microphone"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2310
+msgid "Analog Output"
+msgstr "類比輸出"
+
+#: ../src/modules/alsa/alsa-mixer.c:2312
+msgid "LFE on Separate Mono Output"
+msgstr "類比輸出 (LFE)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2313
+#, fuzzy
+msgid "Line Out"
+msgstr "線路輸入"
+
+#: ../src/modules/alsa/alsa-mixer.c:2314
+msgid "Analog Mono Output"
+msgstr "類比單聲道輸出"
+
+#: ../src/modules/alsa/alsa-mixer.c:2315
+#, fuzzy
+msgid "Speakers"
+msgstr "類比立體聲"
+
+#: ../src/modules/alsa/alsa-mixer.c:2316
+msgid "HDMI / DisplayPort"
+msgstr ""
+
+#: ../src/modules/alsa/alsa-mixer.c:2317
+#, fuzzy
+msgid "Digital Output (S/PDIF)"
+msgstr "數位立體聲 (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:2318
+#, fuzzy
+msgid "Digital Passthrough (S/PDIF)"
+msgstr "數位立體聲 (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3756
+msgid "Analog Mono"
+msgstr "類比單聲道"
+
+#: ../src/modules/alsa/alsa-mixer.c:3757
+msgid "Analog Stereo"
+msgstr "類比立體聲"
+
+#: ../src/modules/alsa/alsa-mixer.c:3758
+msgid "Analog Surround 2.1"
+msgstr "類比環繞聲 2.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3759
+msgid "Analog Surround 3.0"
+msgstr "類比環繞聲 3.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:3760
+msgid "Analog Surround 3.1"
+msgstr "類比環繞聲 3.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3761
+msgid "Analog Surround 4.0"
+msgstr "類比環繞聲 4.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:3762
+msgid "Analog Surround 4.1"
+msgstr "類比環繞聲 4.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3763
+msgid "Analog Surround 5.0"
+msgstr "類比環繞聲 5.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:3764
+msgid "Analog Surround 5.1"
+msgstr "類比環繞聲 5.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3765
+msgid "Analog Surround 6.0"
+msgstr "類比環繞聲 6.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:3766
+msgid "Analog Surround 6.1"
+msgstr "類比環繞聲 6.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3767
+msgid "Analog Surround 7.0"
+msgstr "類比環繞聲 7.0"
+
+#: ../src/modules/alsa/alsa-mixer.c:3768
+msgid "Analog Surround 7.1"
+msgstr "類比環繞聲 7.1"
+
+#: ../src/modules/alsa/alsa-mixer.c:3769
+msgid "Digital Stereo (IEC958)"
+msgstr "數位立體聲 (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3770
+#, fuzzy
+msgid "Digital Passthrough  (IEC958)"
+msgstr "數位立體聲 (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3771
+msgid "Digital Surround 4.0 (IEC958/AC3)"
+msgstr "數位環繞聲 4.0 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3772
+msgid "Digital Surround 5.1 (IEC958/AC3)"
+msgstr "數位環繞聲 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3773
+msgid "Digital Stereo (HDMI)"
+msgstr "數位立體聲 (HDMI)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3774
+#, fuzzy
+msgid "Digital Surround 5.1 (HDMI)"
+msgstr "數位環繞聲 5.1 (IEC958/AC3)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3895
+msgid "Analog Mono Duplex"
+msgstr "類比單聲道雙工"
+
+#: ../src/modules/alsa/alsa-mixer.c:3896
+msgid "Analog Stereo Duplex"
+msgstr "類比立體聲雙工"
+
+#: ../src/modules/alsa/alsa-mixer.c:3897
+msgid "Digital Stereo Duplex (IEC958)"
+msgstr "數位立體聲雙工 (IEC958)"
+
+#: ../src/modules/alsa/alsa-mixer.c:3997
+#, fuzzy, c-format
+msgid "%s Output"
+msgstr "Null Output"
+
+#: ../src/modules/alsa/alsa-mixer.c:4005
+#, fuzzy, c-format
+msgid "%s Input"
+msgstr "輸入"
+
+#: ../src/modules/echo-cancel/module-echo-cancel.c:63
+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 "
+"sink> sink_properties=<properties for the sink> sink_master=<name of sink to "
+"filter> adjust_time=<how often to readjust rates in s> adjust_threshold=<how "
+"much drift to readjust after in ms> format=<sample format> rate=<sample "
+"rate> channels=<number of channels> channel_map=<channel map> "
+"aec_method=<implementation to use> aec_args=<parameters for the AEC engine> "
+"save_aec=<save AEC data in /tmp> autoloaded=<set if this module is being "
+"loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:72
+msgid "General Purpose Equalizer"
+msgstr ""
+
+#: ../src/modules/module-equalizer-sink.c:76
+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> "
+"channels=<number of channels> channel_map=<channel map> autoloaded=<set if "
+"this module is being loaded automatically> use_volume_sharing=<yes or no> "
+msgstr ""
+
+#: ../src/modules/module-filter-apply.c:48
+msgid "autoclean=<automatically unload unused filters?>"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:257
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"-h, --help                            Show this help\n"
+"-v, --verbose                         Print debug messages\n"
+"      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to "
+"44100)\n"
+"      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+"      --from-channels=CHANNELS        From number of channels (defaults to "
+"1)\n"
+"      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to "
+"44100)\n"
+"      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+"      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+"      --resample-method=METHOD        Resample method (defaults to auto)\n"
+"      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+"\n"
+"If the formats are not specified, the test performs all formats "
+"combinations,\n"
+"back and forth.\n"
+"\n"
+"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, "
+"alaw,\n"
+"32le, s32be (defaults to s16ne)\n"
+"\n"
+"See --dump-resample-methods for possible values of resample methods.\n"
+msgstr ""
+
+#: ../src/tests/resampler-test.c:356
+#, fuzzy, c-format
+msgid "%s %s\n"
+msgstr "%s %s"
+
+#: ../src/tests/resampler-test.c:419
+#, c-format
+msgid "=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"
+msgstr ""
+
+#~ msgid "XOpenDisplay() failed"
+#~ msgstr "XOpenDisplay() 失敗"
+
+#~ msgid "%s+%s"
+#~ msgstr "%s+%s"
+
+#~ msgid "%s / %s"
+#~ msgstr "%s / %s"
+
+#~ msgid "Digital Surround 4.0 (IEC958)"
+#~ msgstr "數位環繞聲 4.0 (IEC958)"
+
+#~ msgid "Low Frequency Emmiter"
+#~ msgstr "低頻率揚聲器"
diff --git a/pulseaudio.manifest b/pulseaudio.manifest
new file mode 100755 (executable)
index 0000000..b940f06
--- /dev/null
@@ -0,0 +1,35 @@
+<manifest>
+       <define>
+               <domain name="pulseaudio"/>
+               <request>
+                       <smack request="dbus" type="rw"/>
+                       <smack request="system::vconf" type="arwxt"/>
+                       <smack request="system::vconf_multimedia" type="arwxt"/>
+                       <smack request="system::vconf_setting" type="rw"/>
+                       <smack request="system::share" type="-rwx-"/>
+                       <smack request="system::homedir" type="arwxt"/>
+                       <smack request="deviced::display" type="rw"/>
+                       <smack request="device::audio" type="arwxt"/>
+                       <smack request="device::recording" type="rw"/>
+                       <smack request="bluez" type="rw"/>
+                       <smack request="sys-assert::core" type="arwxt"/>
+                       <smack request="syslogd" type="w"/>
+                       <smack request="com.samsung.audio-tuning" type="r"/>
+                       <smack request="security-server::api-privilege-by-pid" type="w"/>
+                       <smack request="svi-data" type="rx"/>
+                       <smack request="org.tizen.setting::default-resources" type="arwxt"/>
+               </request>
+               <permit>
+                       <smack permit="dbus" type="rw"/>
+               </permit>
+               <provide>
+                       <label name="pulseaudio::record"/>
+               </provide>
+       </define>
+       <assign>
+               <filesystem path="/usr/bin/pulseaudio" label="pulseaudio" exec_label="pulseaudio"/>
+       </assign>
+       <request>
+               <domain name="_"/>
+       </request>
+</manifest>
index 623504e..2e8ff44 100755 (executable)
@@ -1,5 +1,13 @@
 #!/bin/sh
 if [ -x /usr/bin/pulseaudio ]; then         
-        /usr/bin/pulseaudio --log-level=4 --system -D
+       # create directory
+       mkdir /tmp/pulseaudio
+       chmod 777 /tmp/pulseaudio
+       # directorty labeling
+       chsmack -a 'pulseaudio' /tmp/pulseaudio
+       # transmute
+       chsmack -t /tmp/pulseaudio
+
+       /usr/bin/pulseaudio --log-level=4 --system -D
        touch /tmp/hibernation/pulseaudio_ready
 fi
diff --git a/pulseaudio_shared.manifest b/pulseaudio_shared.manifest
new file mode 100644 (file)
index 0000000..653fac6
--- /dev/null
@@ -0,0 +1,11 @@
+<manifest>
+       <request>
+               <domain name="_"/>
+       </request>
+       <assign>
+               <filesystem path="/usr/bin/pacat" label="_" exec_label="none"/>
+               <filesystem path="/usr/bin/pacat-simple" label="_" exec_label="none"/>
+               <filesystem path="/usr/bin/pacmd" label="_" exec_label="none"/>
+               <filesystem path="/usr/bin/pactl" label="_" exec_label="none"/>
+       </assign>
+</manifest>
diff --git a/pulsecore.pc.in b/pulsecore.pc.in
new file mode 100644 (file)
index 0000000..086a5da
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+libdir=@libdir@
+includedir=${prefix}/include
+libexecdir=@libexecdir@
+pulsetestdir=${libexecdir}/pulse-tests
+
+Name: pulsecore
+Description: Module building interface for pulseaudio
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -L${libdir}/pulseaudio -L${libdir}/pulse-@PA_MAJORMINOR@/modules -lpulsecore-@PA_MAJORMINOR@ -lpulsecommon-@PA_MAJORMINOR@ -lpulse @PTHREAD_LIBS@
+Cflags: -D_REENTRANT -D__INCLUDED_FROM_PULSE_AUDIO -DPA_DEFAULT_CONFIG_DIR=\"@PA_DEFAULT_CONFIG_DIR@\" -I${includedir}
diff --git a/shell-completion/pulseaudio-bash-completion.sh b/shell-completion/pulseaudio-bash-completion.sh
new file mode 100644 (file)
index 0000000..a82b10e
--- /dev/null
@@ -0,0 +1,564 @@
+#!/bin/bash
+
+__cards () {
+    while IFS=$'\t' read idx name _; do
+        printf "%s %s\n" "$idx" "$name"
+    done < <(pactl list cards short 2> /dev/null)
+}
+
+__sinks () {
+    while IFS=$'\t' read _ name _ _ _; do
+        printf "%s\n" "$name"
+    done < <(pactl list sinks short 2> /dev/null)
+}
+
+__sinks_idx () {
+    while IFS=$'\t' read idx _ _ _ _; do
+        printf "%s\n" "$idx"
+    done < <(pactl list sinks short 2> /dev/null)
+}
+
+__sources () {
+    while IFS=$'\t' read _ name _ _ _; do
+        printf "%s\n" "$name"
+    done < <(pactl list sources short 2> /dev/null)
+}
+
+__sink_inputs () {
+    while IFS=$'\t' read idx _ _ _ _; do
+        printf "%s\n" "$idx"
+    done < <(pactl list sink-inputs short 2> /dev/null)
+}
+
+__source_outputs () {
+    while IFS=$'\t' read idx _ _ _ _; do
+        printf "%s\n" "$idx"
+    done < <(pactl list source-outputs short 2> /dev/null)
+}
+
+__ports () {
+    pactl list cards 2> /dev/null | awk -e \
+        '/^\tPorts:/ {
+            flag=1; next
+         }
+
+         /^\t[A-Za-z]/ {
+             flag=0
+         }
+
+         flag {
+             if (/^\t\t[A-Za-z]/)
+                 ports = ports substr($0, 3, index($0, ":")-3) " "
+         }
+
+         END {
+             print ports
+         }'
+}
+
+__profiles () {
+    pactl list cards 2> /dev/null | awk -e \
+        '/^\tProfiles:/ {
+            flag=1; next
+        }
+
+        /^\t[A-Za-z]/ {
+            flag=0
+        }
+
+        flag {
+            if (/^\t\t[A-Za-z]/)
+                profiles = profiles substr($0, 3, index($0, ": ")-3) " "
+        }
+
+        END {
+            print profiles
+        }'
+}
+
+__all_modules () {
+    while read name; do
+        name=${name%% *}
+        printf "%s\n" "$name"
+    done < <(pulseaudio --dump-modules 2> /dev/null)
+}
+
+__loaded_modules () {
+    while IFS=$'\t' read idx name _; do
+        printf "%s %s\n" "$idx" "$name"
+    done < <(pactl list modules short 2> /dev/null)
+}
+
+__resample_methods () {
+    while read name; do
+        printf "%s\n" "$name"
+    done < <(pulseaudio --dump-resample-methods 2> /dev/null)
+}
+
+_pacat_file_formats () {
+    while IFS=$'\t' read name _; do
+        printf "%s\n" "$name"
+    done < <(pacat --list-file-formats 2> /dev/null)
+}
+
+in_array() {
+    local i
+    for i in "${@:2}"; do
+        [[ $1 = "$i" ]] && return
+    done
+}
+
+_pactl() {
+    local cur prev words cword preprev command
+    local comps
+    local flags='-h --help --version -s --server= --client-name='
+    local list_types='short sinks sources sink-inputs source outputs cards
+                    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)
+
+    _init_completion -n = || return
+    preprev=${words[$cword-2]}
+
+    for word in "${COMP_WORDS[@]}"; do
+        if in_array "$word" "${commands[@]}"; then
+            command=$word
+            break
+        fi
+    done
+
+    case $preprev in
+        list) COMPREPLY=($(compgen -W 'short' -- "$cur")) ;;
+
+        play-sample)
+            comps=$(__sinks)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        move-sink-input)
+            comps=$(__sinks)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        move-source-output)
+            comps=$(__sources)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        set-card-profile)
+            comps=$(__profiles)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        set-*-port)
+            comps=$(__ports)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        set-*-mute) COMPREPLY=($(compgen -W 'true false toggle' -- "$cur")) ;;
+
+        set-sink-formats)
+            ;; #TODO
+
+        set-port-*)
+            comps=$(__ports)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+        --server)
+            compopt +o nospace
+            _known_hosts_real "$cur"
+            ;;
+    esac
+    [[ $COMPREPLY ]] && return 0
+
+    case $prev in
+        list) COMPREPLY=($(compgen -W '${list_types[*]}' -- "$cur")) ;;
+
+        stat) COMPREPLY=($(compgen -W 'short' -- "$cur")) ;;
+
+        upload-sample) _filedir ;;
+
+        play-sample) ;; # TODO
+
+        remove-sample) ;; # TODO
+
+        load-module)
+            comps=$(__all_modules)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        unload-module)
+            comps=$(__loaded_modules)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        set-card*)
+            comps=$(__cards)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        *sink-input*)
+            comps=$(__sink_inputs)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        *source-output*)
+            comps=$(__source_outputs)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        set-sink-formats)
+            comps=$(__sinks_idx)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        *sink*)
+            comps=$(__sinks)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        *source*)
+            comps=$(__sources)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        set-port*)
+            comps=$(__cards)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        -s)
+            _known_hosts_real "$cur" ;;
+    esac
+    [[ $COMPREPLY ]] && return 0
+
+    case $cur in
+        --server=*)
+            cur=${cur#*=}
+            _known_hosts_real "$cur"
+            ;;
+
+        -*)
+            COMPREPLY=($(compgen -W '${flags[*]}' -- "$cur"))
+            [[ $COMPREPLY == *= ]] && compopt -o nospace
+            ;;
+
+        *)
+            [[ -z $command ]] && COMPREPLY=($(compgen -W '${commands[*]}' -- "$cur"))
+            ;;
+    esac
+}
+complete -F _pactl pactl
+
+_pacmd() {
+    local cur prev words cword preprev command
+    local comps
+    local flags='-h --help --version'
+    local commands=(exit help list-modules list-sinks list-sources list-clients
+                    list-samples list-sink-inputs list-source-outputs stat info
+                    load-module unload-module describe-module set-sink-volume
+                    set-source-volume set-sink-input-volume set-source-output-volume
+                    set-sink-mute set-source-mut set-sink-input-mute
+                    set-source-output-mute update-sink-proplist update-source-proplist
+                    update-sink-input-proplist update-source-output-proplist
+                    set-default-sink set-default-source kill-client kill-sink-input
+                    kill-source-output play-sample remove-sample load-sample
+                    load-sample-lazy load-sample-dir-lazy play-file dump
+                    move-sink-input move-source-output suspend-sink suspend-source
+                    suspend set-card-profile set-sink-port set-source-port
+                    set-port-latency-offset set-log-target set-log-level set-log-meta
+                    set-log-time set-log-backtrace)
+    _init_completion -n = || return
+    preprev=${words[$cword-2]}
+
+    for word in "${COMP_WORDS[@]}"; do
+        if in_array "$word" "${commands[@]}"; then
+            command=$word
+            break
+        fi
+    done
+
+    case $preprev in
+        play-sample|play-file)
+            comps=$(__sinks)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        load-sample*) _filedir ;;
+
+        move-sink-input)
+            comps=$(__sinks)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        move-source-output)
+            comps=$(__sources)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        set-card-profile)
+            comps=$(__profiles)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        set-*port*)
+            comps=$(__ports)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        set-*-mute) COMPREPLY=($(compgen -W 'true false' -- "$cur"));;
+
+        set-sink-formats)
+            ;; #TODO
+    esac
+
+    case $prev in
+        list-*) ;;
+        describe-module|load-module)
+            comps=$(__all_modules)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        unload-module)
+            comps=$(__loaded_modules)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        load-sample-dir-lazy) _filedir -d ;;
+        play-file) _filedir ;;
+
+        *sink-input*)
+            comps=$(__sink_inputs)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        *source-output*)
+            comps=$(__source_outputs)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        *sink*)
+            comps=$(__sinks)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        *source*)
+            comps=$(__sources)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        set-card*)
+            comps=$(__cards)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        set-port-*)
+            comps=$(__cards)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        set-log-target)
+            COMPREPLY=($(compgen -W 'auto syslog stderr file: newfile:' -- "$cur"))
+            ;;
+
+        set-log-level)
+            COMPREPLY=($(compgen -W '{0..4}' -- "$cur"))
+            ;;
+
+        set-log-meta|set-log-time|suspend)
+            COMPREPLY=($(compgen -W 'true false' -- "$cur"))
+            ;;
+    esac
+
+    case $cur in
+        -*) COMPREPLY=($(compgen -W '${flags[*]}' -- "$cur")) ;;
+        suspend)
+            COMPREPLY=($(compgen -W 'suspend suspend-sink suspend-source' -- "$cur"))
+            ;;
+
+        load-sample)
+            COMPREPLY=($(compgen -W 'load-sample load-sample-lazy load-sample-dir-lazy' -- "$cur"))
+            ;;
+
+        *)
+            [[ -z $command ]] && COMPREPLY=($(compgen -W '${commands[*]}' -- "$cur"))
+            ;;
+    esac
+}
+complete -F _pacmd pacmd
+
+_pasuspender () {
+    local cur prev
+    local flags='-h --help --version -s --server='
+
+    _init_completion -n = || return
+
+    case $cur in
+        --server=*)
+            cur=${cur#*=}
+            _known_hosts_real "$cur"
+            ;;
+
+        -*)
+            COMPREPLY=($(compgen -W '${flags[*]}' -- "$cur"))
+            [[ $COMPREPLY == *= ]] && compopt -o nospace
+            ;;
+    esac
+
+    case $prev in
+        -s) _known_hosts_real "$cur" ;;
+    esac
+}
+complete -F _pasuspender pasuspender
+
+_padsp () {
+    local cur prev
+    local flags='-h -s -n -m -M -S -D -d'
+
+    _get_comp_words_by_ref cur prev
+
+    case $cur in
+        -*) COMPREPLY=($(compgen -W '${flags[*]}' -- "$cur")) ;;
+    esac
+
+    case $prev in
+        -s) _known_hosts_real "$cur" ;;
+    esac
+}
+complete -F _padsp padsp
+
+_pacat () {
+    local cur prev comps
+    local flags='-h --help --version -r --record -p --playback -v --verbose -s
+                --server= -d --device= -n --client-name= --stream-name= --volume=
+                --rate= --format= --channels= --channel-map= --fix-format --fix-rate
+                --fix-channels --no-remix --no-remap --latency= --process-time=
+                --latency-msec= --process-time-msec= --property= --raw --passthrough
+                --file-format= --list-file-formats'
+
+    _init_completion -n = || return
+
+    case $cur in
+        --server=*)
+            cur=${cur#*=}
+            _known_hosts_real "$cur"
+            ;;
+
+        --device=*)
+            cur=${cur#*=}
+            comps=$(__sinks)
+            comps+=$(__sources)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        --rate=*)
+            cur=${cur#*=}
+            COMPREPLY=($(compgen -W '32000 44100 48000 9600 192000' -- "$cur"))
+            ;;
+
+        --file-format=*)
+            cur=${cur#*=}
+            comps=$(_pacat_file_formats)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        --*=*)
+            ;;
+
+        -*)
+            COMPREPLY=($(compgen -W '${flags[*]}' -- "$cur"))
+            [[ $COMPREPLY == *= ]] && compopt -o nospace
+            ;;
+        *) _filedir ;;
+    esac
+
+    case $prev in
+        -s) _known_hosts_real "$cur" ;;
+        -d)
+            comps=$(__sinks)
+            comps+=$(__sources)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+    esac
+}
+complete -F _pacat pacat paplay parecord
+
+_pulseaudio()
+{
+    local cur prev words cword
+    local flags='-h --help --version --dump-conf --dump-resample-methods --cleanup-shm
+                --start -k --kill --check --system= -D --daemonize= --fail= --high-priority=
+                --realtime= --disallow-module-loading= --disallow-exit= --exit-idle-time=
+                --scache-idle-time= --log-level= -v --log-target= --log-meta= --log-time=
+                --log-backtrace= -p --dl-search-path= --resample-method= --use-pit-file=
+                --no-cpu-limit= --disable-shm= -L --load= -F --file= -C -n'
+    _init_completion -n = || return
+
+    case $cur in
+        --system=*|--daemonize=*|--fail=*|--high-priority=*|--realtime=*| \
+            --disallow-*=*|--log-meta=*|--log-time=*|--use-pid-file=*| \
+            --no-cpu-limit=*|--disable-shm=*)
+            cur=${cur#*=}
+            COMPREPLY=($(compgen -W 'true false' -- "$cur"))
+            ;;
+
+        --log-target=*)
+            cur=${cur#*=}
+            COMPREPLY=($(compgen -W 'auto syslog stderr file: newfile:' -- "$cur"))
+            ;;
+
+        --log-level=*)
+            cur=${cur#*=}
+            COMPREPLY=($(compgen -W '{0..4}' -- "$cur"))
+            ;;
+
+        --dl-search-path=*)
+            cur=${cur#*=}
+            _filedir -d
+            ;;
+
+        --file=*)
+            cur=${cur#*=}
+            _filedir
+            ;;
+
+        --resample-method=*)
+            cur=${cur#*=}
+            comps=$(__resample_methods)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        --load=*)
+            cur=${cur#*=}
+            comps=$(__all_modules)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+
+        --*=*)
+            ;;
+
+        -*)
+            COMPREPLY=($(compgen -W '${flags[*]}' -- "$cur"))
+            [[ $COMPREPLY == *= ]] && compopt -o nospace
+            ;;
+    esac
+
+    case $prev in
+        -D) COMPREPLY=($(compgen -W 'true false' -- "$cur")) ;;
+        -p) _filedir -d ;;
+        -F) _filedir ;;
+        -L)
+            cur=${cur#*=}
+            comps=$(__all_modules)
+            COMPREPLY=($(compgen -W '${comps[*]}' -- "$cur"))
+            ;;
+    esac
+}
+complete -F _pulseaudio pulseaudio
+
+#vim: set ft=zsh sw=4 ts=4 noet
diff --git a/shell-completion/pulseaudio-zsh-completion.zsh b/shell-completion/pulseaudio-zsh-completion.zsh
new file mode 100644 (file)
index 0000000..d73b74d
--- /dev/null
@@ -0,0 +1,534 @@
+#compdef pulseaudio pactl pacmd pacat paplay parecord padsp pasuspender
+
+_devices() {
+    local -a _device_list
+    local cmd _device _device_description _remote_cmd
+
+    if [[ $service == pactl  || $service == pacmd ]]; then
+        case $words[$((CURRENT - 1))] in
+            set-sink-input-*) cmd=('sink-inputs');;
+            set-sink-*) cmd=('sinks');;
+            set-source-output-*) cmd=('source-outputs');;
+            set-source-*) cmd=('sources');;
+            suspend-sink) cmd=('sinks');;
+            suspend-source) cmd=('sources');;
+            move-sink-input) cmd=('sink-inputs');;
+            move-source-output) cmd=('source-outputs');;
+            kill-sink-input) cmd=('sink-inputs');;
+            kill-source-output) cmd=('source-outputs');;
+        esac
+
+        case $words[$((CURRENT - 2))] in
+            move-sink-input) cmd=('sinks');;
+            move-source-output) cmd=('sources');;
+        esac
+
+    elif [[ $service == (pacat|paplay|parecord) ]]; then
+        if [[ $words == *-r[[:space:]]* ]]; then
+            cmd=('sources')
+        elif [[ $words == *-p[[:space:]]* ]]; then
+            cmd=('sinks')
+        else
+            cmd=('sinks' 'sources')
+        fi
+
+    elif [[ $service == paplay ]]; then
+        cmd=('sinks')
+    elif [[ $service == parecord ]]; then
+        cmd=('sources')
+    fi
+
+    for (( i = 0; i < ${#words[@]}; i++ )) do
+        if [[ ${words[$i]} == -s ]]; then
+            _remote_cmd="-s ${words[$i+1]}"
+            break;
+        fi
+    done
+
+    for target in $cmd; do
+        for device_info in ${(ps:\n\n:)"$(_call_program device_tag "pactl $_remote_cmd list $target 2> /dev/null")"}; do
+            for line in ${(f)device_info}; do
+                if [[ $target == (sink-inputs|source-outputs) ]]; then
+                    if [[ $line == (Sink*Input|Source*Output)* ]]; then
+                        _device=${line#*\#}
+                    elif [[ $line == *application.name* ]]; then
+                        _device_description=${line#*= }
+                    fi
+
+                else
+                    if [[ $words[$((CURRENT - 1))] == *set-sink-formats* ]]; then
+                        if [[ $line == Sink* ]]; then
+                            _device=${line#*\#}
+                        elif [[ $line == *Description:* ]]; then
+                            _device_description=${line#*: }
+                        fi
+
+                    else
+                        if [[ $line == *Name:* ]]; then
+                            _device=${line#*: }
+                        elif [[ $line == *Description:* ]]; then
+                            _device_description=${line#*: }
+                        fi
+                    fi
+                fi
+            done
+            _device_list+=($_device:$_device_description)
+        done
+    done
+
+    _describe 'device list' _device_list
+}
+
+_profiles() {
+    local -a _profile_list
+    local _current_card _raw_profiles _profile_name _profile_description _remote_cmd
+
+    _current_card=$words[$((CURRENT - 1))]
+
+    for (( i = 0; i < ${#words[@]}; i++ )) do
+        if [[ ${words[$i]} == -s ]]; then
+            _remote_cmd="-s ${words[$i+1]}"
+            break;
+        fi
+    done
+
+    for card in ${(ps:\n\n:)"$(_call_program profiles_tag "pactl $_remote_cmd list cards 2> /dev/null")"}; do
+        if [[ $card == *$_current_card* ]]; then
+            _raw_profiles=${card##*Profiles:}
+            _raw_profiles=${_raw_profiles%%Active Profile:*}
+            for profile in ${(f)_raw_profiles}; do
+                if [[ $profile != [[:blank:]] ]]; then
+                    _profile_name=${profile%%: *}
+                    _profile_name=${_profile_name//[[:blank:]]/}
+                    _profile_name=${_profile_name//:/\\:}
+                    _profile_description=${profile#*: }
+                    _profile_list+=($_profile_name:$_profile_description)
+                fi
+            done
+        fi
+    done
+
+    _describe 'profile list' _profile_list
+}
+
+_ports() {
+    local -a _port_list
+    local _raw_ports _port_name _port_description _current_device _remote_cmd
+
+    case $words[$((CURRENT - 2))] in
+        set-sink-port) cmd="sinks";;
+        set-source-port) cmd="sources";;
+        set-port-latency-offset) cmd="cards";;
+    esac
+
+    _current_device=$words[$((CURRENT - 1))]
+
+    for (( i = 0; i < ${#words[@]}; i++ )) do
+        if [[ ${words[$i]} == -s ]]; then
+            _remote_cmd="-s ${words[$i+1]}"
+            break;
+        fi
+    done
+
+    for device in ${(ps:\n\n:)"$(_call_program port_tag "pactl $_remote_cmd list $cmd 2> /dev/null")"}; do
+        if [[ $device == *Ports:* && $device == *$_current_device* ]]; then
+            _raw_ports=${device##*Ports:}
+            _raw_ports=${_raw_ports%%Active Port:*}
+            for line in ${(f)_raw_ports}; do
+                if [[ $line != [[:blank:]] &&
+                    $line != (*Part?of*|*Properties:*|*device.icon_name*) ]]; then
+                    _port_name=${line%%: *}
+                    _port_name=${_port_name//[[:blank:]]/}
+                    _port_description=${line#*: }
+                    _port_list+=($_port_name:$_port_description)
+                fi
+            done
+        fi
+    done
+
+    _describe 'port list' _port_list
+}
+
+_cards(){
+    local -a _card_list
+    local _card _cad_name _remote_cmd
+
+    for (( i = 0; i < ${#words[@]}; i++ )) do
+        if [[ ${words[$i]} == -s ]]; then
+            _remote_cmd="-s ${words[$i+1]}"
+            break;
+        fi
+    done
+
+    for card_info in ${(ps:\n\n:)"$(_call_program card_tag "pactl $_remote_cmd list cards 2> /dev/null")"}; do
+        for line in ${(f)card_info}; do
+            if [[ $line == *Name:* ]]; then
+                _card=${line#*: }
+            elif [[ $line == *alsa.long_card_name* ]]; then
+                _card_name=${line#*= \"}
+                _card_name=${_card_name%at*}
+            fi
+        done
+        _card_list+=($_card:$_card_name)
+    done
+
+    _describe 'card list' _card_list
+}
+
+_all_modules(){
+    local -a _all_modules_list
+    for module in ${(f)"$(_call_program modules_tag "pulseaudio --dump-modules 2> /dev/null")"}; do
+        _all_modules_list+=${module%% *}
+    done
+    _describe 'module list' _all_modules_list
+}
+
+_loaded_modules(){
+    local -a _loaded_modules_list _remote_cmd
+
+    for (( i = 0; i < ${#words[@]}; i++ )) do
+        if [[ ${words[$i]} == -s ]]; then
+            _remote_cmd="-s ${words[$i+1]}"
+            break;
+        fi
+    done
+
+    for module in ${(f)"$(_call_program modules_tag "pactl $_remote_cmd list modules short 2> /dev/null")"}; do
+        _loaded_modules_list+=(${${(ps:\t:)module}[1]}:${${(ps:\t:)module}[2]})
+    done
+    _describe 'module list' _loaded_modules_list
+}
+
+_resample_methods() {
+    local -a _resample_method_list
+    for method in ${(f)"$(_call_program modules_tag "pulseaudio --dump-resample-methods 2> /dev/null")"}; do
+        _resample_method_list+=$method
+    done
+    _describe 'resample method list' _resample_method_list
+}
+
+_clients() {
+    local -a _client_list
+    local _client _client_description _remote_cmd
+
+    for (( i = 0; i < ${#words[@]}; i++ )) do
+        if [[ ${words[$i]} == -s ]]; then
+            _remote_cmd="-s ${words[$i+1]}"
+            break;
+        fi
+    done
+
+    for client_info in ${(ps:\n\n:)"$(_call_program clients_tag "pactl $_remote_cmd list clients 2> /dev/null")"}; do
+        for line in ${(f)client_info}; do
+            if [[ $line == Client[[:space:]]#* ]]; then
+                _client=${line#*\#}
+            elif [[ $line == *application.name* ]]; then
+                _client_description=${line#*=}
+            fi
+        done
+        _client_list+=($_client:$_client_description)
+    done
+    _describe 'client list' _client_list
+}
+
+_pacat_file_formats() {
+    local -a _file_format_list
+    for format in ${(f)"$(_call_program fformats_tag "pacat --list-file-formats")"}; do
+        _file_format_list+=(${${(ps:\t:)format}[1]}:${${(ps:\t:)format}[2]})
+    done
+    _describe 'file format list' _file_format_list
+}
+
+_pactl_completion() {
+    _pactl_command(){
+        _pactl_commands=(
+            'help: show help and exit'
+            'stat: dump statistics about the PulseAudio daemon'
+            'info: dump info about the PulseAudio daemon'
+            'list: list modules/sources/streams/cards etc...'
+            'exit: ask the PulseAudio daemon to exit'
+            'upload-sample: upload a sound from a file into the sample cache'
+            'play-sample: play the specified sample from the sample cache'
+            'remove-sample: remove the specified sample from the sample cache'
+            'load-module: load a module'
+            'unload-module: unload a module'
+            'move-sink-input: move a stream to a sink'
+            'move-source-output: move a recording stream to a source'
+            'suspend-sink: suspend or resume a sink'
+            'suspend-source: suspend or resume a source'
+            'set-card-profile: set a card profile:cards:_cards'
+            'set-sink-default: set the default sink'
+            'set-source-default: set the default source'
+            'set-sink-port: set the sink port of a sink'
+            'set-source-port: set the source port of a source'
+            'set-port-latency-offset: set a latency offset on a port'
+            'set-sink-volume: set the volume of a sink'
+            'set-source-volume: set the volume of a source'
+            'set-sink-input-volume: set the volume of a stream'
+            'set-source-output-volume: set the volume of a recording stream'
+            'set-sink-mute: mute a sink'
+            'set-source-mute: mute a source'
+            'set-sink-input-mute: mute a stream'
+            'set-source-output-mute: mute a recording stream'
+            'set-sink-formats: set supported formats of a sink'
+            'subscribe: subscribe to events'
+        )
+        _describe 'pactl commands' _pactl_commands
+    }
+
+    _pactl_list_commands=(
+        'modules: list loaded modules'
+        'sinks: list available sinks'
+        'sources: list available sources'
+        'sink-inputs: list connected sink inputs'
+        'source-outputs: list connected source outputs'
+        'clients: list connected clients'
+        'samples: list samples'
+        'cards: list available cards'
+    )
+
+    _arguments -C \
+        - '(help)' \
+            {-h,--help}'[display this help and exit]' \
+        '--version[show version and exit]' \
+        - '(server)' \
+            {-s,--server}'[name of server to connect to]:host:_hosts' \
+        - '(name)' \
+            {-n,--client-name}'[client name to use]:name' \
+        '::pactl commands:_pactl_command' \
+
+    case $words[$((CURRENT - 1))] in
+        list) _describe 'pactl list commands' _pactl_list_commands;;
+        stat) compadd short;;
+        set-card-profile) _cards;;
+        set-sink-*) _devices;;
+        set-source-*) _devices;;
+        upload-sample) _files;;
+        load-module) _all_modules;;
+        unload-module) _loaded_modules;;
+        suspend-*) _devices;;
+        move-*) _devices;;
+        set-port-latency-offset) _cards;;
+    esac
+
+    case $words[$((CURRENT - 2))] in
+        set-card-profile) _profiles;;
+        set-(sink|source)-port) _ports;;
+        set-port-latency-offset) _ports;;
+        set-*-mute) compadd true false toggle;;
+        suspend-*) compadd true false;;
+        list) compadd short;;
+        move-*) _devices;;
+        '-s' | '-n') _pactl_command;;
+        --server | --client-*) _pactl_command;;
+    esac
+}
+
+_pacmd_completion() {
+    _pacmd_command(){
+        _pacmd_commands=(
+            'help: show help and exit'
+            'list-modules: list modules'
+            'list-sinks: list sinks'
+            'list-sources: list sources'
+            'list-clients: list clients'
+            'list-sink-inputs: list sink-inputs'
+            'list-source-outputs: list source-outputs'
+            'stat: dump statistics about the PulseAudio daemon'
+            'info: dump info about the PulseAudio daemon'
+            'load-module: load a module'
+            'unload-module: unload a module'
+            'describe-module: print info for a module'
+            'set-sink-volume: set the volume of a sink'
+            'set-source-volume: set the volume of a source'
+            'set-sink-mute: mute a sink'
+            'set-source-mute: mute a source'
+            'set-sink-input-volume: set the volume of a stream'
+            'set-source-output-volume: set the volume of a recording stream'
+            'set-sink-input-mute: mute a stream'
+            'set-source-output-mute: mute a recording stream'
+            'set-default-sink: set the default sink'
+            'set-default-source: set the default source'
+            'set-card-profile: set a card profile'
+            'set-sink-port: set the sink port of a sink'
+            'set-source-port: set the source port of a source'
+            'set-port-latency-offset: set a latency offset on a port'
+            'suspend-sink: suspend or resume a sink'
+            'suspend-source: suspend or resume a source'
+            'suspend: suspend all sinks and sources'
+            'move-sink-input: move a stream to a sink'
+            'move-source-output: move a recording stream to a source'
+            'update-sink-proplist: update the properties of a sink'
+            'update-source-proplist: update the properties of a source'
+            'update-sink-input-proplist: update the properties of a sink-input'
+            'update-source-output-proplist: update the properties of a source-output'
+            'list-samples: list samples'
+            'play-sample: play the specified sample from the sample cache' # TODO
+            'remove-sample: remove the specified sample from the sample cache' # TODO
+            'load-sample: upload a sound from a file into the sample cache'
+            'load-sample-lazy: lazily upload a sound file into the sample cache'
+            'load-sample-dir-lazy: lazily upload all sound files in a directory into the sample cache'
+            'kill-client: kill a client'
+            'kill-sink-input: kill a sink input'
+            'kill-source-output: kill a source output'
+            'set-log-target: change the log target'
+            'set-log-level: change the log level'
+            'set-log-meta: show source code location in log messages'
+            'set-log-time: show timestamps in log messages'
+            'set-log-backtrace: show backtrace in log messages'
+            'play-file: play a sound file'
+            'dump: show daemon configuration'
+            'dump-volumes: show the state of all volumes'
+            'shared: show shared properties'
+            'exit: ask the PulseAudio daemon to exit'
+        )
+        _describe 'pacmd commands' _pacmd_commands
+    }
+
+    _arguments -C \
+        - '(help)' \
+            {-h,--help}'[display this help and exit]' \
+        '--version[show version and exit]' \
+        '::pacmd commands:_pacmd_command' \
+
+    case $words[$((CURRENT - 1))] in
+        set-card-profile) _cards;;
+        set-sink-*) _devices;;
+        set-source-*) _devices;;
+        load-module) _all_modules;;
+        describe-module) _all_modules;;
+        unload-module) _loaded_modules;;
+        suspend-*) _devices;;
+        move-*) _devices;;
+        set-port-latency-offset) _cards;;
+        load-sample*) _files;;
+        kill-client) _clients;;
+        kill-(sink|source)-*) _devices;;
+        set-log-target) compadd null auto syslog stderr file:;;
+        set-log-*) compadd true false;;
+        play-file) _files;;
+    esac
+
+    case $words[$((CURRENT - 2))] in
+        set-card-profile) _profiles;;
+        set-(sink|source)-port) _ports;;
+        set-port-latency-offset) _ports;;
+        set-*-mute) compadd true false;;
+        suspend-*) compadd true false;;
+        move-*) _devices;;
+    esac
+}
+
+_pasuspender_completion() {
+    _arguments -C \
+        {-h,--help}'[display this help and exit]' \
+        '--version[show version and exit]' \
+        {-s,--server}'[name of server to connect to]:host:_hosts' \
+}
+
+_padsp_completion() {
+    _arguments -C \
+        '-h[display this help and exit]' \
+        '-s[name of server to connect to]:host:_hosts' \
+        '-n[client name to use]:name:' \
+        '-m[stream name to use]:name:' \
+        '-M[disable /dev/mixer emulation]' \
+        '-S[disable /dev/sndstat emulation]' \
+        '-D[disable /dev/dsp emulation]' \
+        '-d[enable debug output]' \
+        '--[disable further command line parsing]' \
+}
+
+# TODO channel map completion
+_pacat_completion() {
+    _pacat_sample_formats=('s16le' 's16be' 'u8' 'float32le' 'float32be'
+        'ulaw' 'alaw' 's32le' 's32be' 's24le' 's24-32le' 's24-32be')
+
+    _arguments -C \
+        {-h,--help}'[display this help and exit]' \
+        '--version[show version and exit]' \
+        {-r,--record}'[create a connection for recording]' \
+        {-p,--playback}'[create a connection for playback]' \
+        {-s,--server=}'[name of server to connect to]:host:_hosts' \
+        {-d,--device=}'[name of sink/source to connect to]:device:_devices' \
+        {-n,--client-name=}'[client name to use]:name' \
+        '--stream-name=[how to call this stream]:name' \
+        '--volume=[initial volume to use]:volume' \
+        '--rate=[sample rate to use]:rate:(44100 48000 96000)' \
+        '--format=[sample type to use]:format:((${(q)_pacat_sample_formats}))' \
+        '--channels=[number of channels to use]:number:(1 2)' \
+        '--channel-map=[channel map to use]:map' \
+        '--fix-format[use the sample format of the sink]' \
+        '--fix-rate[use the rate of the sink]' \
+        '--fix-channels[channel map of the sink]' \
+        '--no-remix[do not upmix or downmix channels]' \
+        '--no-remap[map channels by index instead of name]' \
+        '--latency=[request the specified latency]:bytes' \
+        '--process-time=[request the specified process time]:bytes' \
+        '--latency-msec=[request the specified latency in msec]:msec' \
+        '--process-time-msec=[request the specified process time in msec]:msec' \
+        '--property=[set the specified property]:property' \
+        '--raw[record/play raw PCM data]' \
+        '--passthrough[passtrough data]' \
+        '--file-format=[record/play formatted PCM data]:format:_pacat_file_formats' \
+        '--list-file-formats[list available formats]' \
+        '::files:_files' \
+}
+
+# TODO log-target file completion
+_pulseaudio_completion() {
+    _arguments -C \
+        {-h,--help}'[display this help and exit]' \
+        '--version[show version and exit]' \
+        '--dump-conf[show default configuration]' \
+        '--dump-modules[show available modules]' \
+        '--dump-resample-methods[show available resample methods]' \
+        '--cleanup-shm[cleanup shared memory]' \
+        '--start[start the daemon]' \
+        {-k,--kill}'[kill a running daemon]' \
+        '--check[check for a running daemon]' \
+        '--system=[run as systemd-wide daemon]:bool:(true false)' \
+        {-D,--daemonize=}'[daemonize after startup]:bool:(true false)' \
+        '--fail=[quit when startup fails]:bool:(true false)' \
+        '--high-priority=[try to set high nice level]:bool:(true false)' \
+        '--realtime=[try to enable rt scheduling]:bool:(true false)' \
+        '--disallow-module-loading=[disallow module loading]:bool:(true false)' \
+        '--disallow-exit=[disallow user requested exit]' \
+        '--exit-idle-time=[terminate the daemon on passed idle time]:time' \
+        '--scache-idle-time=[unload autoloaded samples on passed idle time]:time' \
+        '--log-level=[set the verbosity level]:level' \
+        '-v[increase the verbosity level]' \
+        '--log-target=[set the log target]:target:(auto syslog stderr file\: new_file\:):file' \
+        '--log-meta=[include code location in log messages]:bool:(true false)' \
+        '--log-time=[include timestamps in log messages]:bool:(true false)' \
+        '--log-backtrace=[include backtrace in log messages]:frames' \
+        {-p,--dl-search-path=}'[set the search path for plugins]:dir:_files' \
+        '--resample-method=[set the resample method]:method:_resample_methods' \
+        '--use-pid-file=[create a PID file]:bool:(true false)' \
+        '--no-cpu-limit=[do not install CPU load limiter]:bool:(true false)' \
+        '--disable-shm=[disable shared memory support]:bool:(true false)' \
+        {-L,--load=}'[load the specified module]:modules:_all_modules' \
+        {-F,--file=}'[run the specified script]:file:_files' \
+        '-C[open a command line on the running tty]' \
+        '-n[do not load the default script file]' \
+}
+
+_pulseaudio() {
+    local state line curcontext="$curcontext"
+
+    case $service in
+        pulseaudio) _pulseaudio_completion;;
+        pactl) _pactl_completion;;
+        pacmd) _pacmd_completion;;
+        pacat) _pacat_completion;;
+        paplay)_pacat_completion;;
+        parecord)_pacat_completion;;
+        padsp) _padsp_completion;;
+        pasuspender) _pasuspender_completion;;
+        *) _message "Err";;
+    esac
+}
+
+_pulseaudio "$@"
+
+#vim: set ft=zsh sw=4 ts=4 noet
diff --git a/src/.gitignore b/src/.gitignore
new file mode 100644 (file)
index 0000000..cd9c51a
--- /dev/null
@@ -0,0 +1,76 @@
+TAGS
+*.lo
+*.o
+*.la
+.deps
+.libs
+/Makefile
+/Makefile.in
+proximity-helper
+client.conf
+daemon.conf
+default.pa
+echo-cancel-test
+esdcompat
+gconf-helper
+pacat
+pacmd
+pactl
+padsp
+paplay
+pasuspender
+pax11publish
+pulseaudio
+start-pulseaudio-x11
+start-pulseaudio-kde
+*-symdef.h
+*-orc-gen.[ch]
+# tests
+alsa-mixer-path-test
+alsa-time-test
+asyncmsgq-test
+asyncq-test
+channelmap-test
+close-test
+connect-stress
+cpulimit-test
+cpulimit-test2
+cpu-test
+extended-test
+flist-test
+format-test
+get-binary-name-test
+gtk-test
+hook-list-test
+interpol-test
+ipacl-test
+lock-autospawn-test
+mainloop-test
+mainloop-test-glib
+mcalign-test
+memblockq-test
+memblock-test
+mix-special-test
+mix-test
+once-test
+pacat-simple
+parec-simple
+proplist-test
+queue-test
+remix-test
+resampler-test
+rtpoll-test
+rtstutter
+sig2str-test
+sigbus-test
+smoother-test
+stripnul
+strlist-test
+sync-playback
+system.pa
+thread-mainloop-test
+thread-test
+usergroup-test
+utf8-test
+volume-test
+mult-s16-test
index 8ebf2b9..a07c560 100644 (file)
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 # USA.
 
-
 ###################################
 #       Extra directories         #
 ###################################
 
 pulseincludedir=$(includedir)/pulse
 pulsecoreincludedir=$(includedir)/pulsecore
-pulseconfdir=$(sysconfdir)/pulse
 pulselibexecdir=$(libexecdir)/pulse
+if HAVE_X11
 xdgautostartdir=$(sysconfdir)/xdg/autostart
+endif
+if HAVE_ALSA
 alsaprofilesetsdir=$(datadir)/pulseaudio/alsa-mixer/profile-sets
 alsapathsdir=$(datadir)/pulseaudio/alsa-mixer/paths
-udevrulesdir=/lib/udev/rules.d
+endif
+if HAVE_DBUS
 dbuspolicydir=$(sysconfdir)/dbus-1/system.d
-
-###################################
-#            Defines              #
-###################################
-
-PA_BINARY=$(bindir)/pulseaudio$(EXEEXT)
-if OS_IS_WIN32
-PA_DEFAULT_CONFIG_DIR=%PULSE_ROOT%
-else
-PA_DEFAULT_CONFIG_DIR=$(pulseconfdir)
 endif
 
 ###################################
 #     Compiler/linker flags       #
 ###################################
 
-AM_CFLAGS = \
+AM_CPPFLAGS = \
        -I$(top_srcdir)/src \
-       -I$(top_builddir)/src \
        -I$(top_srcdir)/src/modules \
        -I$(top_builddir)/src/modules \
-       -I$(top_srcdir)/src/modules/rtp \
-       -I$(top_builddir)/src/modules/rtp \
-       -I$(top_srcdir)/src/modules/gconf \
-       -I$(top_builddir)/src/modules/gconf \
-       -I$(top_srcdir)/src/modules/bluetooth \
-       -I$(top_builddir)/src/modules/bluetooth \
-       -I$(top_srcdir)/src/modules/oss \
-       -I$(top_builddir)/src/modules/oss \
-       -I$(top_srcdir)/src/modules/alsa \
-       -I$(top_builddir)/src/modules/alsa \
-       -I$(top_srcdir)/src/modules/raop \
-       -I$(top_builddir)/src/modules/raop \
-       -I$(top_srcdir)/src/modules/x11 \
-       -I$(top_builddir)/src/modules/x11 \
-       -I$(top_srcdir)/src/modules/jack \
-       -I$(top_builddir)/src/modules/jack \
-       $(PTHREAD_CFLAGS) -D_POSIX_PTHREAD_SEMANTICS \
-       $(LIBSAMPLERATE_CFLAGS) \
-       $(LIBSNDFILE_CFLAGS) \
-       $(LIBSPEEX_CFLAGS) \
-       -DPA_BUILDDIR=\"$(abs_builddir)\" \
-       -DPA_DLSEARCHPATH=\"$(modlibexecdir)\" \
-       -DPA_DEFAULT_CONFIG_DIR=\"$(PA_DEFAULT_CONFIG_DIR)\" \
-       -DPA_BINARY=\"$(PA_BINARY)\" \
-       -DPA_SYSTEM_RUNTIME_PATH=\"$(PA_SYSTEM_RUNTIME_PATH)\" \
-       -DPA_SYSTEM_CONFIG_PATH=\"$(PA_SYSTEM_CONFIG_PATH)\" \
-       -DPA_SYSTEM_STATE_PATH=\"$(PA_SYSTEM_STATE_PATH)\" \
-       -DAO_REQUIRE_CAS \
-       -DPULSE_LOCALEDIR=\"$(pulselocaledir)\" \
-       -DPA_MACHINE_ID=\"$(localstatedir)/lib/dbus/machine-id\" \
-        -DPA_ALSA_PATHS_DIR=\"$(alsapathsdir)\" \
-        -DPA_ALSA_PROFILE_SETS_DIR=\"$(alsaprofilesetsdir)\" \
-       $(LTDLINCL)
+       -DPA_ALSA_PATHS_DIR=\"$(alsapathsdir)\" \
+       -DPA_ALSA_PROFILE_SETS_DIR=\"$(alsaprofilesetsdir)\"
+AM_CFLAGS = \
+       $(PTHREAD_CFLAGS) \
+       -DPA_SRCDIR=\"$(abs_srcdir)\" \
+       -DPA_BUILDDIR=\"$(abs_builddir)\"
+AM_CXXFLAGS = $(AM_CFLAGS)
+SERVER_CFLAGS = -D__INCLUDED_FROM_PULSE_AUDIO
 
 AM_LIBADD = $(PTHREAD_LIBS) $(INTLLIBS)
 AM_LDADD = $(PTHREAD_LIBS) $(INTLLIBS)
-AM_LDFLAGS = $(NODELETE_LDFLAGS) -Wl,-rpath-link,$(top_srcdir)/src/.libs -Wl,-rpath-link,$(libdir)
+AM_LDFLAGS = $(NODELETE_LDFLAGS)
+
+if HAVE_GCOV
+AM_CFLAGS+=$(GCOV_CFLAGS)
+AM_CXXFLAGS+=$(GCOV_CFLAGS)
+AM_LDFLAGS+=$(GCOV_LIBS)
+endif
 
 if STATIC_BINS
 BINLDFLAGS = -static
 endif
 
 if OS_IS_WIN32
-AM_LDFLAGS+=-Wl,--export-all-symbols
+AM_LDFLAGS+=-Wl,--export-all-symbols,--enable-auto-import -no-undefined
 WINSOCK_LIBS=-lwsock32 -lws2_32 -lwininet
 endif
 
+if OS_IS_DARWIN
+AM_LDFLAGS+=-Wl,-headerpad_max_install_names -headerpad_max_install_names
+endif
+
 FOREIGN_CFLAGS = -w
-MODULE_LDFLAGS = -module -disable-static -avoid-version $(LDFLAGS_NOUNDEFINED)
+
+MODULE_LDFLAGS = $(AM_LDFLAGS) -module -disable-static -avoid-version $(NOUNDEFINED_LDFLAGS)
+MODULE_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
 
 ###################################
 #          Extra files            #
 ###################################
 
-ALSA_PROFILES = \
-               modules/alsa/mixer/profile-sets/default.conf \
-               modules/alsa/mixer/profile-sets/native-instruments-audio4dj.conf \
-               modules/alsa/mixer/profile-sets/native-instruments-audio8dj.conf
-
-ALSA_PATHS = \
-               modules/alsa/mixer/paths/analog-input-aux.conf \
-               modules/alsa/mixer/paths/analog-input.conf \
-               modules/alsa/mixer/paths/analog-input.conf.common \
-               modules/alsa/mixer/paths/analog-input-fm.conf \
-               modules/alsa/mixer/paths/analog-input-linein.conf \
-               modules/alsa/mixer/paths/analog-input-mic.conf \
-               modules/alsa/mixer/paths/analog-input-mic.conf.common \
-               modules/alsa/mixer/paths/analog-input-mic-line.conf \
-               modules/alsa/mixer/paths/analog-input-tvtuner.conf \
-               modules/alsa/mixer/paths/analog-input-video.conf \
-               modules/alsa/mixer/paths/analog-output.conf \
-               modules/alsa/mixer/paths/analog-output-speaker.conf \
-               modules/alsa/mixer/paths/analog-output.conf.common \
-               modules/alsa/mixer/paths/analog-output-headphones.conf \
-               modules/alsa/mixer/paths/analog-output-headphones-2.conf \
-               modules/alsa/mixer/paths/analog-output-lfe-on-mono.conf \
-               modules/alsa/mixer/paths/analog-output-mono.conf
-
 EXTRA_DIST = \
                pulse/client.conf.in \
                pulse/version.h.in \
                daemon/daemon.conf.in \
                daemon/default.pa.in \
                daemon/system.pa.in \
-               daemon/default.pa.win32 \
                depmod.py \
                daemon/esdcompat.in \
                daemon/start-pulseaudio-x11.in \
                daemon/start-pulseaudio-kde.in \
-               utils/padsp \
+               utils/padsp.in \
+               utils/qpaeq \
                modules/module-defs.h.m4 \
                daemon/pulseaudio.desktop.in \
                daemon/pulseaudio-kde.desktop.in \
                map-file \
                daemon/pulseaudio-system.conf \
                modules/echo-cancel/adrian-license.txt
-               modules/alsa/mixer/profile-sets/90-pulseaudio.rules \
-               ${ALSA_PROFILES} \
-               ${ALSA_PATHS}
 
 pulseconf_DATA = \
                default.pa \
@@ -160,21 +111,28 @@ pulseconf_DATA = \
                daemon.conf \
                client.conf
 
-
+if HAVE_DBUS
 dbuspolicy_DATA = \
                daemon/pulseaudio-system.conf
+endif
 
 if HAVE_X11
 xdgautostart_in_files = \
                daemon/pulseaudio.desktop.in \
                daemon/pulseaudio-kde.desktop.in
-endif
 xdgautostart_DATA = $(xdgautostart_in_files:.desktop.in=.desktop)
 @INTLTOOL_DESKTOP_RULE@
+endif
+
 
+###################################
+#          Includes               #
+###################################
 
-BUILT_SOURCES = \
-               pulse/version.h
+BUILT_SOURCES =
+CLEANFILES =
+include $(top_srcdir)/orc.mak
+ORC_SOURCE =
 
 ###################################
 #          Main daemon            #
@@ -183,18 +141,23 @@ BUILT_SOURCES = \
 bin_PROGRAMS = pulseaudio
 
 pulseaudio_SOURCES = \
-               daemon/caps.h daemon/caps.c \
+               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 daemon/dumpmodules.h \
                daemon/ltdl-bind-now.c daemon/ltdl-bind-now.h \
                daemon/main.c
 
-pulseaudio_CFLAGS = $(AM_CFLAGS) $(LIBSAMPLERATE_CFLAGS) $(LIBSPEEX_CFLAGS) $(LIBSNDFILE_CFLAGS) $(CAP_CFLAGS) $(DBUS_CFLAGS)
-pulseaudio_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSPEEX_LIBS) $(LIBSNDFILE_LIBS) $(CAP_LIBS) $(DBUS_LIBS)
+pulseaudio_CFLAGS = $(AM_CFLAGS) $(CAP_CFLAGS) -fPIC -pie
+pulseaudio_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la $(LIBLTDL) $(CAP_LIBS)
 # This is needed because automake doesn't properly expand the foreach below
-pulseaudio_DEPENDENCIES = libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la $(PREOPEN_LIBS) $(LTDLDEPS)
+pulseaudio_DEPENDENCIES = libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la $(PREOPEN_LIBS)
+
+if HAVE_DBUS
+pulseaudio_CFLAGS += $(DBUS_CFLAGS)
+pulseaudio_SOURCES += daemon/server-lookup.c daemon/server-lookup.h
+pulseaudio_LDADD += $(DBUS_LIBS)
+endif
 
 if PREOPEN_MODS
 PREOPEN_LIBS = $(PREOPEN_MODS)
@@ -203,13 +166,14 @@ PREOPEN_LIBS = $(modlibexec_LTLIBRARIES)
 endif
 
 if FORCE_PREOPEN
-pulseaudio_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(IMMEDIATE_LDFLAGS) -dlpreopen force $(foreach f,$(PREOPEN_LIBS),-dlpreopen $(f)) -export-dynamic
+pulseaudio_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(IMMEDIATE_LDFLAGS) -dlpreopen force $(foreach f,$(PREOPEN_LIBS),-dlpreopen $(f))
 else
-pulseaudio_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(IMMEDIATE_LDFLAGS) -dlopen force $(foreach f,$(PREOPEN_LIBS),-dlopen $(f)) -export-dynamic
+pulseaudio_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(IMMEDIATE_LDFLAGS) -dlopen force $(foreach f,$(PREOPEN_LIBS),-dlopen $(f))
 endif
 
 if USE_DLOG
-pulseaudio_CFLAGS += -DUSE_DLOG
+pulseaudio_CFLAGS += $(DLOG_CFLAGS) -DUSE_DLOG
+pulseaudio_LDADD += $(DLOG_LIBS)
 endif
 
 
@@ -217,10 +181,16 @@ endif
 #       Utility programs          #
 ###################################
 
+bin_SCRIPTS = esdcompat
+
 bin_PROGRAMS += \
                pacat \
-               pactl \
-               pasuspender
+               pacat-simple \
+               pactl
+
+if !OS_IS_WIN32
+bin_PROGRAMS += pasuspender
+endif
 
 if HAVE_AF_UNIX
 bin_PROGRAMS += pacmd
@@ -228,372 +198,412 @@ endif
 
 if HAVE_X11
 bin_PROGRAMS += pax11publish
+bin_SCRIPTS += start-pulseaudio-x11 start-pulseaudio-kde
 endif
 
-if HAVE_AVAHI
-bin_PROGRAMS += pabrowse
-endif
-
-bin_SCRIPTS = esdcompat start-pulseaudio-x11 start-pulseaudio-kde
-
 pacat_SOURCES = utils/pacat.c
-pacat_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la $(LIBSNDFILE_LIBS)
-pacat_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS)
+pacat_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINOR@.la $(LIBSNDFILE_LIBS)
+pacat_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS) -fPIC -pie
 pacat_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
 pactl_SOURCES = utils/pactl.c
-pactl_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la $(LIBSNDFILE_LIBS)
-pactl_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS)
+pactl_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINOR@.la $(LIBSNDFILE_LIBS)
+pactl_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS) -fPIC -pie
 pactl_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
 pasuspender_SOURCES = utils/pasuspender.c
-pasuspender_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la
+pasuspender_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
 pasuspender_CFLAGS = $(AM_CFLAGS)
 pasuspender_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
 pacmd_SOURCES = utils/pacmd.c
-pacmd_CFLAGS = $(AM_CFLAGS)
-pacmd_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la
+pacmd_CFLAGS = $(AM_CFLAGS) -fPIC -pie
+pacmd_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
 pacmd_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
 pax11publish_SOURCES = utils/pax11publish.c
 pax11publish_CFLAGS = $(AM_CFLAGS) $(X11_CFLAGS)
-pax11publish_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la $(X11_LIBS)
+pax11publish_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINOR@.la $(X11_LIBS)
 pax11publish_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
-pabrowse_SOURCES = utils/pabrowse.c
-pabrowse_LDADD = $(AM_LDADD) libpulse.la libpulse-browse.la libpulsecommon-@PA_MAJORMINORMICRO@.la
-pabrowse_CFLAGS = $(AM_CFLAGS)
-pabrowse_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
-
 ###################################
 #         Test programs           #
 ###################################
 
-# missing: mcalign-test flist-test pacat-simple parec-simple sync-playback rtstutter stripnul interpol-test thread-test
-
-TESTS = \
+TESTS_default = \
                mainloop-test \
                strlist-test \
                close-test \
-               voltest \
-               vector-test \
                memblockq-test \
                channelmap-test \
                thread-mainloop-test \
                utf8-test \
+               format-test \
                get-binary-name-test \
-               ipacl-test \
                hook-list-test \
                memblock-test \
                asyncq-test \
                asyncmsgq-test \
                queue-test \
                rtpoll-test \
-               sig2str-test \
                resampler-test \
                smoother-test \
+               thread-test \
+               volume-test \
                mix-test \
-               remix-test \
-               envelope-test \
                proplist-test \
+               cpu-test \
                lock-autospawn-test \
-               prioq-test \
-               sigbus-test \
-               usergroup-test
+               mult-s16-test \
+               mix-special-test
 
-TESTS_BINARIES = \
-               mainloop-test \
+TESTS_norun = \
+               ipacl-test \
                mcalign-test \
                pacat-simple \
                parec-simple \
-               strlist-test \
-               close-test \
-               voltest \
-               vector-test \
-               memblockq-test \
-               sync-playback \
-               interpol-test \
-               channelmap-test \
-               thread-mainloop-test \
-               utf8-test \
-               get-binary-name-test \
-               ipacl-test \
-               hook-list-test \
-               memblock-test \
-               thread-test \
                flist-test \
-               asyncq-test \
-               asyncmsgq-test \
-               queue-test \
-               rtpoll-test \
-               sig2str-test \
-               resampler-test \
-               smoother-test \
-               mix-test \
                remix-test \
-               envelope-test \
-               proplist-test \
                rtstutter \
+               sig2str-test \
                stripnul \
-               lock-autospawn-test \
-               prioq-test \
+               echo-cancel-test
+
+# These tests need a running pulseaudio daemon
+TESTS_daemon = \
+               connect-stress \
+               extended-test \
+               interpol-test \
+               sync-playback
+
+if !OS_IS_WIN32
+TESTS_default += \
                sigbus-test \
                usergroup-test
+endif
+
+if !OS_IS_DARWIN
+TESTS_default += \
+               once-test
+endif
 
 if HAVE_SIGXCPU
-#TESTS += \
-#              cpulimit-test \
-#              cpulimit-test2
-TESTS_BINARIES += \
+TESTS_norun += \
                cpulimit-test \
                cpulimit-test2
 endif
 
 if HAVE_GLIB20
-TESTS += \
-               mainloop-test-glib
-TESTS_BINARIES += \
+TESTS_default += \
                mainloop-test-glib
 endif
 
-if HAVE_GTK20
-TESTS_BINARIES += \
+if HAVE_GTK30
+TESTS_norun += \
                gtk-test
 endif
 
 if HAVE_ALSA
-TESTS_BINARIES += \
+TESTS_norun += \
                alsa-time-test
+TESTS_default += \
+               alsa-mixer-path-test
 endif
 
+if HAVE_TESTS
+TESTS_ENVIRONMENT=MAKE_CHECK=1
+TESTS = $(TESTS_default)
+
 if BUILD_TESTS_DEFAULT
-noinst_PROGRAMS = $(TESTS_BINARIES)
+noinst_PROGRAMS = $(TESTS_default) $(TESTS_norun) $(TESTS_daemon)
+else
+check_PROGRAMS = $(TESTS_default) $(TESTS_norun)
+endif
+
+check-daemon: $(TESTS_daemon)
+       PATH=$(builddir):${PATH} $(top_srcdir)/src/tests/test-daemon.sh $(TESTS_daemon)
+
 else
-check_PROGRAMS = $(TESTS_BINARIES)
+TESTS_ENVIRONMENT=
+TESTS =
+noinst_PROGRAMS =
+check_PROGRAMS =
+
+check-daemon:
+       @echo "Tests are disabled!"
+       @echo "Pass option \"--enable-tests\" to configure and install \"check\" library properly!"
+       false
+
 endif
 
 mainloop_test_SOURCES = tests/mainloop-test.c
-mainloop_test_CFLAGS = $(AM_CFLAGS)
-mainloop_test_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la
-mainloop_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+mainloop_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+mainloop_test_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+mainloop_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 thread_mainloop_test_SOURCES = tests/thread-mainloop-test.c
-thread_mainloop_test_CFLAGS = $(AM_CFLAGS)
-thread_mainloop_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la
-thread_mainloop_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+thread_mainloop_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+thread_mainloop_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+thread_mainloop_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 utf8_test_SOURCES = tests/utf8-test.c
-utf8_test_CFLAGS = $(AM_CFLAGS)
-utf8_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-utf8_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+utf8_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+utf8_test_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+utf8_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
+
+format_test_SOURCES = tests/format-test.c
+format_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+format_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+format_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 get_binary_name_test_SOURCES = tests/get-binary-name-test.c
-get_binary_name_test_CFLAGS = $(AM_CFLAGS)
-get_binary_name_test_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la
-get_binary_name_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+get_binary_name_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+get_binary_name_test_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+get_binary_name_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 ipacl_test_SOURCES = tests/ipacl-test.c
-ipacl_test_CFLAGS = $(AM_CFLAGS)
-ipacl_test_LDADD = $(AM_LDADD) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la libpulsecore-@PA_MAJORMINORMICRO@.la
-ipacl_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+ipacl_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+ipacl_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+ipacl_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 hook_list_test_SOURCES = tests/hook-list-test.c
-hook_list_test_CFLAGS = $(AM_CFLAGS)
-hook_list_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
-hook_list_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+hook_list_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+hook_list_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+hook_list_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 memblock_test_SOURCES = tests/memblock-test.c
-memblock_test_CFLAGS = $(AM_CFLAGS)
-memblock_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-memblock_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+memblock_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+memblock_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+memblock_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 thread_test_SOURCES = tests/thread-test.c
-thread_test_CFLAGS = $(AM_CFLAGS)
-thread_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-thread_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+thread_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+thread_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+thread_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
+
+once_test_SOURCES = tests/once-test.c
+once_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+once_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+once_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 flist_test_SOURCES = tests/flist-test.c
 flist_test_CFLAGS = $(AM_CFLAGS)
-flist_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+flist_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
 flist_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
 asyncq_test_SOURCES = tests/asyncq-test.c
-asyncq_test_CFLAGS = $(AM_CFLAGS)
-asyncq_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
-asyncq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+asyncq_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+asyncq_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+asyncq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 asyncmsgq_test_SOURCES = tests/asyncmsgq-test.c
-asyncmsgq_test_CFLAGS = $(AM_CFLAGS)
-asyncmsgq_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
-asyncmsgq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+asyncmsgq_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+asyncmsgq_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+asyncmsgq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 queue_test_SOURCES = tests/queue-test.c
-queue_test_CFLAGS = $(AM_CFLAGS)
-queue_test_LDADD = $(AM_LDADD) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la libpulsecore-@PA_MAJORMINORMICRO@.la
-queue_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+queue_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+queue_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+queue_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 rtpoll_test_SOURCES = tests/rtpoll-test.c
-rtpoll_test_CFLAGS = $(AM_CFLAGS)
-rtpoll_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
-rtpoll_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+rtpoll_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+rtpoll_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+rtpoll_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 mcalign_test_SOURCES = tests/mcalign-test.c
 mcalign_test_CFLAGS = $(AM_CFLAGS)
-mcalign_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la libpulsecore-@PA_MAJORMINORMICRO@.la
+mcalign_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
 mcalign_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
 pacat_simple_SOURCES = tests/pacat-simple.c
-pacat_simple_LDADD = $(AM_LDADD) libpulse.la libpulse-simple.la libpulsecommon-@PA_MAJORMINORMICRO@.la
-pacat_simple_CFLAGS = $(AM_CFLAGS)
+pacat_simple_LDADD = $(AM_LDADD) libpulse.la libpulse-simple.la
+pacat_simple_CFLAGS = $(AM_CFLAGS) -fPIC -pie
 pacat_simple_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
 parec_simple_SOURCES = tests/parec-simple.c
-parec_simple_LDADD = $(AM_LDADD) libpulse.la libpulse-simple.la libpulsecommon-@PA_MAJORMINORMICRO@.la
+parec_simple_LDADD = $(AM_LDADD) libpulse.la libpulse-simple.la
 parec_simple_CFLAGS = $(AM_CFLAGS)
 parec_simple_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
+extended_test_SOURCES = tests/extended-test.c
+extended_test_LDADD = $(AM_LDADD) libpulse.la
+extended_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+extended_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
+
 strlist_test_SOURCES = tests/strlist-test.c
-strlist_test_CFLAGS = $(AM_CFLAGS)
-strlist_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-strlist_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+strlist_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+strlist_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+strlist_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 close_test_SOURCES = tests/close-test.c
 close_test_CFLAGS = $(AM_CFLAGS)
-close_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la libpulsecore-@PA_MAJORMINORMICRO@.la
+close_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
 close_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
-voltest_SOURCES = tests/voltest.c
-voltest_CFLAGS = $(AM_CFLAGS)
-voltest_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la
-voltest_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
-
-vector_test_SOURCES = tests/vector-test.c
-vector_test_CFLAGS = $(AM_CFLAGS)
-vector_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
-vector_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+volume_test_SOURCES = tests/volume-test.c
+volume_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+volume_test_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+volume_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 channelmap_test_SOURCES = tests/channelmap-test.c
-channelmap_test_CFLAGS = $(AM_CFLAGS)
-channelmap_test_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la
-channelmap_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+channelmap_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+channelmap_test_LDADD = $(AM_LDADD) libpulse.la
+channelmap_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 cpulimit_test_SOURCES = tests/cpulimit-test.c daemon/cpulimit.c daemon/cpulimit.h
-cpulimit_test_CFLAGS = $(AM_CFLAGS)
-cpulimit_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-cpulimit_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+cpulimit_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+cpulimit_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+cpulimit_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 cpulimit_test2_SOURCES = tests/cpulimit-test.c daemon/cpulimit.c daemon/cpulimit.h
-cpulimit_test2_CFLAGS = $(AM_CFLAGS) -DTEST2
-cpulimit_test2_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-cpulimit_test2_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+cpulimit_test2_CFLAGS = $(AM_CFLAGS) -DTEST2 $(LIBCHECK_CFLAGS)
+cpulimit_test2_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+cpulimit_test2_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 mainloop_test_glib_SOURCES = $(mainloop_test_SOURCES)
-mainloop_test_glib_CFLAGS = $(mainloop_test_CFLAGS) $(GLIB20_CFLAGS) -DGLIB_MAIN_LOOP
+mainloop_test_glib_CFLAGS = $(mainloop_test_CFLAGS) $(LIBCHECK_CFLAGS) $(GLIB20_CFLAGS) -DGLIB_MAIN_LOOP
 mainloop_test_glib_LDADD = $(mainloop_test_LDADD) $(GLIB20_LIBS) libpulse-mainloop-glib.la
-mainloop_test_glib_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+mainloop_test_glib_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 memblockq_test_SOURCES = tests/memblockq-test.c
-memblockq_test_CFLAGS = $(AM_CFLAGS)
-memblockq_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la libpulsecore-@PA_MAJORMINORMICRO@.la
-memblockq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+memblockq_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+memblockq_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+memblockq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 sync_playback_SOURCES = tests/sync-playback.c
-sync_playback_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la
-sync_playback_CFLAGS = $(AM_CFLAGS)
-sync_playback_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+sync_playback_LDADD = $(AM_LDADD) libpulse.la
+sync_playback_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+sync_playback_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 interpol_test_SOURCES = tests/interpol-test.c
-interpol_test_LDADD = $(AM_LDADD) libpulse.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
-interpol_test_CFLAGS = $(AM_CFLAGS)
-interpol_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+interpol_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+interpol_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+interpol_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 sig2str_test_SOURCES = tests/sig2str-test.c
-sig2str_test_LDADD = $(AM_LDADD) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la libpulsecore-@PA_MAJORMINORMICRO@.la
-sig2str_test_CFLAGS = $(AM_CFLAGS)
-sig2str_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+sig2str_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+sig2str_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+sig2str_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 resampler_test_SOURCES = tests/resampler-test.c
-resampler_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+resampler_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
 resampler_test_CFLAGS = $(AM_CFLAGS)
 resampler_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
 mix_test_SOURCES = tests/mix-test.c
-mix_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-mix_test_CFLAGS = $(AM_CFLAGS)
-mix_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+mix_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+mix_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+mix_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 remix_test_SOURCES = tests/remix-test.c
-remix_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+remix_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
 remix_test_CFLAGS = $(AM_CFLAGS)
 remix_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
 smoother_test_SOURCES = tests/smoother-test.c
-smoother_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
-smoother_test_CFLAGS = $(AM_CFLAGS)
-smoother_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
-
-envelope_test_SOURCES = tests/envelope-test.c
-envelope_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-envelope_test_CFLAGS = $(AM_CFLAGS)
-envelope_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+smoother_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+smoother_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+smoother_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 proplist_test_SOURCES = tests/proplist-test.c
-proplist_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-proplist_test_CFLAGS = $(AM_CFLAGS)
-proplist_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+proplist_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+proplist_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+proplist_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
+
+cpu_test_SOURCES = tests/cpu-test.c
+cpu_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+cpu_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+cpu_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
+
+mult_s16_test_SOURCES = tests/mult-s16-test.c
+mult_s16_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+mult_s16_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+mult_s16_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
+
+mix_special_test_SOURCES = tests/mix-special-test.c
+mix_special_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+mix_special_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+mix_special_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 rtstutter_SOURCES = tests/rtstutter.c
-rtstutter_LDADD = $(AM_LDADD) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la libpulsecore-@PA_MAJORMINORMICRO@.la
+rtstutter_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
 rtstutter_CFLAGS = $(AM_CFLAGS)
 rtstutter_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
 stripnul_SOURCES = tests/stripnul.c
-stripnul_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+stripnul_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
 stripnul_CFLAGS = $(AM_CFLAGS)
 stripnul_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
 lock_autospawn_test_SOURCES = tests/lock-autospawn-test.c
-lock_autospawn_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-lock_autospawn_test_CFLAGS = $(AM_CFLAGS)
-lock_autospawn_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
-
-prioq_test_SOURCES = tests/prioq-test.c
-prioq_test_LDADD = $(AM_LDADD) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la libpulsecore-@PA_MAJORMINORMICRO@.la
-prioq_test_CFLAGS = $(AM_CFLAGS)
-prioq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+lock_autospawn_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+lock_autospawn_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+lock_autospawn_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 sigbus_test_SOURCES = tests/sigbus-test.c
-sigbus_test_LDADD = $(AM_LDADD) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la libpulsecore-@PA_MAJORMINORMICRO@.la
-sigbus_test_CFLAGS = $(AM_CFLAGS)
-sigbus_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+sigbus_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+sigbus_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+sigbus_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 gtk_test_SOURCES = tests/gtk-test.c
-gtk_test_LDADD = $(AM_LDADD) libpulse.la libpulse-mainloop-glib.la libpulsecommon-@PA_MAJORMINORMICRO@.la
-gtk_test_CFLAGS = $(AM_CFLAGS) $(GTK20_CFLAGS)
-gtk_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(GTK20_LIBS)
+gtk_test_LDADD = $(AM_LDADD) $(GTK30_LIBS) libpulse-mainloop-glib.la libpulse.la
+gtk_test_CFLAGS = $(AM_CFLAGS) $(GTK30_CFLAGS)
+gtk_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
 alsa_time_test_SOURCES = tests/alsa-time-test.c
-alsa_time_test_LDADD = $(AM_LDADD)
+alsa_time_test_LDADD = $(AM_LDADD) $(ASOUNDLIB_LIBS)
 alsa_time_test_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS)
-alsa_time_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(ASOUNDLIB_LIBS)
+alsa_time_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+
+alsa_mixer_path_test_SOURCES = tests/alsa-mixer-path-test.c
+alsa_mixer_path_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS) $(ASOUNDLIB_CFLAGS)
+alsa_mixer_path_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la libalsa-util.la
+alsa_mixer_path_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
 
 usergroup_test_SOURCES = tests/usergroup-test.c
-usergroup_test_LDADD = $(AM_LDADD) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la libpulsecore-@PA_MAJORMINORMICRO@.la
-usergroup_test_CFLAGS = $(AM_CFLAGS)
-usergroup_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+usergroup_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
+usergroup_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+usergroup_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
+
+connect_stress_SOURCES = tests/connect-stress.c
+connect_stress_LDADD = $(AM_LDADD) libpulse.la
+connect_stress_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
+connect_stress_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
+
+echo_cancel_test_SOURCES = $(module_echo_cancel_la_SOURCES)
+nodist_echo_cancel_test_SOURCES = $(nodist_module_echo_cancel_la_SOURCES)
+echo_cancel_test_LDADD = $(module_echo_cancel_la_LIBADD)
+echo_cancel_test_CFLAGS = $(module_echo_cancel_la_CFLAGS) -DECHO_CANCEL_TEST=1
+if HAVE_WEBRTC
+echo_cancel_test_CXXFLAGS = $(module_echo_cancel_la_CXXFLAGS) -DECHO_CANCEL_TEST=1
+endif
+echo_cancel_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
 ###################################
 #         Common library          #
 ###################################
 
-lib_LTLIBRARIES = \
-               libpulsecommon-@PA_MAJORMINORMICRO@.la
+pkglib_LTLIBRARIES = \
+               libpulsecommon-@PA_MAJORMINOR@.la
 
-libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES = \
+# We duplicate files from pulse/ in this to allow as-needed linking. If we did
+# not do this, in situations where code in libpulsecommon uses code in
+# libpulse, we would then need to link libpulsecommon to libpulse (in addition
+# to the existing libpulse being linked to libpulsecommon). Duplicating the
+# code allows us to prevent this circular linking.
+libpulsecommon_@PA_MAJORMINOR@_la_SOURCES = \
                pulse/client-conf.c pulse/client-conf.h \
-               pulse/i18n.c pulse/i18n.h \
                pulse/fork-detect.c pulse/fork-detect.h \
+               pulse/xmalloc.c pulse/xmalloc.h \
+               pulse/proplist.c pulse/proplist.h \
+               pulse/utf8.c pulse/utf8.h \
+               pulse/channelmap.c pulse/channelmap.h \
+               pulse/sample.c pulse/sample.h \
+               pulse/util.c pulse/util.h \
+               pulse/timeval.c pulse/timeval.h \
+               pulse/rtclock.c pulse/rtclock.h \
+               pulse/volume.c pulse/volume.h \
                pulsecore/atomic.h \
                pulsecore/authkey.c pulsecore/authkey.h \
                pulsecore/conf-parser.c pulsecore/conf-parser.h \
@@ -604,18 +614,19 @@ libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES = \
                pulsecore/dynarray.c pulsecore/dynarray.h \
                pulsecore/endianmacros.h \
                pulsecore/flist.c pulsecore/flist.h \
+               pulsecore/g711.c pulsecore/g711.h \
                pulsecore/hashmap.c pulsecore/hashmap.h \
+               pulsecore/i18n.c pulsecore/i18n.h \
                pulsecore/idxset.c pulsecore/idxset.h \
-               pulsecore/inet_ntop.c pulsecore/inet_ntop.h \
-               pulsecore/inet_pton.c pulsecore/inet_pton.h \
+               pulsecore/arpa-inet.c pulsecore/arpa-inet.h \
                pulsecore/iochannel.c pulsecore/iochannel.h \
                pulsecore/ioline.c pulsecore/ioline.h \
-               pulsecore/ipacl.h pulsecore/ipacl.c \
+               pulsecore/ipacl.c pulsecore/ipacl.h \
                pulsecore/llist.h \
                pulsecore/lock-autospawn.c pulsecore/lock-autospawn.h \
                pulsecore/log.c pulsecore/log.h \
                pulsecore/ratelimit.c pulsecore/ratelimit.h \
-               pulsecore/macro.h pulsecore/vector.h \
+               pulsecore/macro.h \
                pulsecore/mcalign.c pulsecore/mcalign.h \
                pulsecore/memblock.c pulsecore/memblock.h \
                pulsecore/memblockq.c pulsecore/memblockq.h \
@@ -627,8 +638,6 @@ libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES = \
                pulsecore/pdispatch.c pulsecore/pdispatch.h \
                pulsecore/pid.c pulsecore/pid.h \
                pulsecore/pipe.c pulsecore/pipe.h \
-               pulsecore/poll.c pulsecore/poll.h \
-               pulsecore/prioq.c pulsecore/prioq.h \
                pulsecore/memtrap.c pulsecore/memtrap.h \
                pulsecore/aupdate.c pulsecore/aupdate.h \
                pulsecore/proplist-util.c pulsecore/proplist-util.h \
@@ -637,6 +646,7 @@ libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES = \
                pulsecore/queue.c pulsecore/queue.h \
                pulsecore/random.c pulsecore/random.h \
                pulsecore/refcnt.h \
+               pulsecore/sample-util.c pulsecore/sample-util.h \
                pulsecore/shm.c pulsecore/shm.h \
                pulsecore/bitset.c pulsecore/bitset.h \
                pulsecore/socket-client.c pulsecore/socket-client.h \
@@ -644,19 +654,35 @@ libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES = \
                pulsecore/socket-util.c pulsecore/socket-util.h \
                pulsecore/strbuf.c pulsecore/strbuf.h \
                pulsecore/strlist.c pulsecore/strlist.h \
+               pulsecore/svolume_c.c pulsecore/svolume_arm.c \
+               pulsecore/svolume_mmx.c pulsecore/svolume_sse.c \
                pulsecore/tagstruct.c pulsecore/tagstruct.h \
                pulsecore/time-smoother.c pulsecore/time-smoother.h \
                pulsecore/tokenizer.c pulsecore/tokenizer.h \
                pulsecore/usergroup.c pulsecore/usergroup.h \
                pulsecore/sndfile-util.c pulsecore/sndfile-util.h \
-               pulsecore/winsock.h
+               pulsecore/socket.h
 
-libpulsecommon_@PA_MAJORMINORMICRO@_la_CFLAGS = $(AM_CFLAGS)
-libpulsecommon_@PA_MAJORMINORMICRO@_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
-libpulsecommon_@PA_MAJORMINORMICRO@_la_LIBADD = $(AM_LIBADD) $(LIBWRAP_LIBS) $(WINSOCK_LIBS) $(LTLIBICONV) $(LIBSNDFILE_LIBS)
+if OS_IS_WIN32
+libpulsecommon_@PA_MAJORMINOR@_la_SOURCES += pulsecore/poll-win32.c pulsecore/poll.h
+else
+libpulsecommon_@PA_MAJORMINOR@_la_SOURCES += pulsecore/poll-posix.c pulsecore/poll.h
+endif
+
+libpulsecommon_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS)
+libpulsecommon_@PA_MAJORMINOR@_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
+libpulsecommon_@PA_MAJORMINOR@_la_LIBADD = $(AM_LIBADD) $(LIBWRAP_LIBS) $(WINSOCK_LIBS) $(LTLIBICONV) $(LIBSNDFILE_LIBS)
+
+if HAVE_X11
+libpulsecommon_@PA_MAJORMINOR@_la_SOURCES += \
+               pulse/client-conf-x11.c pulse/client-conf-x11.h \
+               pulsecore/x11prop.c pulsecore/x11prop.h
+libpulsecommon_@PA_MAJORMINOR@_la_CFLAGS += $(X11_CFLAGS)
+libpulsecommon_@PA_MAJORMINOR@_la_LDFLAGS += $(X11_LIBS)
+endif
 
 # proplist-util.h uses these header files, but not the library itself!
-libpulsecommon_@PA_MAJORMINORMICRO@_la_CFLAGS += $(GLIB20_CFLAGS) $(GTK20_CFLAGS)
+libpulsecommon_@PA_MAJORMINOR@_la_CFLAGS += $(GLIB20_CFLAGS) $(GTK30_CFLAGS)
 
 ## Please note that libpulsecommon implicitly also depends on<
 ## libpulse! i.e. we have a cyclic dependancy here. Which is intended
@@ -664,45 +690,177 @@ libpulsecommon_@PA_MAJORMINORMICRO@_la_CFLAGS += $(GLIB20_CFLAGS) $(GTK20_CFLAGS
 ## libpulsecommon only includes unofficial APIs.
 
 if OS_IS_WIN32
-libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES += \
+libpulsecommon_@PA_MAJORMINOR@_la_SOURCES += \
                pulsecore/mutex-win32.c pulsecore/mutex.h \
                pulsecore/thread-win32.c pulsecore/thread.h \
                pulsecore/semaphore-win32.c pulsecore/semaphore.h
-else
-libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES += \
+else !OS_IS_WIN32
+if OS_IS_DARWIN
+libpulsecommon_@PA_MAJORMINOR@_la_SOURCES += \
+               pulsecore/mutex-posix.c pulsecore/mutex.h \
+               pulsecore/thread-posix.c pulsecore/thread.h \
+               pulsecore/semaphore-osx.c pulsecore/semaphore.h
+libpulsecommon_@PA_MAJORMINOR@_la_CFLAGS += "-I/Developer/Headers/FlatCarbon/"
+#libpulsecommon_@PA_MAJORMINOR@_la_LDFLAGS += "-framework CoreServices"
+else !OS_IS_DARWIN
+libpulsecommon_@PA_MAJORMINOR@_la_SOURCES += \
                pulsecore/mutex-posix.c pulsecore/mutex.h \
                pulsecore/thread-posix.c pulsecore/thread.h \
                pulsecore/semaphore-posix.c pulsecore/semaphore.h
-endif
-
-if HAVE_X11
-libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES += pulsecore/x11prop.c pulsecore/x11prop.h
-libpulsecommon_@PA_MAJORMINORMICRO@_la_CFLAGS += $(X11_CFLAGS)
-libpulsecommon_@PA_MAJORMINORMICRO@_la_LDFLAGS += $(X11_LIBS)
-endif
+endif !OS_IS_DARWIN
+endif !OS_IS_WIN32
 
 if HAVE_LIBASYNCNS
-libpulsecommon_@PA_MAJORMINORMICRO@_la_CFLAGS += $(LIBASYNCNS_CFLAGS)
-libpulsecommon_@PA_MAJORMINORMICRO@_la_LIBADD += $(LIBASYNCNS_LIBS)
+libpulsecommon_@PA_MAJORMINOR@_la_CFLAGS += $(LIBASYNCNS_CFLAGS)
+libpulsecommon_@PA_MAJORMINOR@_la_LIBADD += $(LIBASYNCNS_LIBS)
 endif
 
 if OS_IS_WIN32
-libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES += pulsecore/dllmain.c
+libpulsecommon_@PA_MAJORMINOR@_la_SOURCES += pulsecore/dllmain.c
 endif
 
 if HAVE_DBUS
-libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES += \
+libpulsecommon_@PA_MAJORMINOR@_la_SOURCES += \
                pulsecore/dbus-util.c pulsecore/dbus-util.h \
                pulsecore/rtkit.c pulsecore/rtkit.h
-libpulsecommon_@PA_MAJORMINORMICRO@_la_CFLAGS += $(DBUS_CFLAGS)
-libpulsecommon_@PA_MAJORMINORMICRO@_la_LIBADD += $(DBUS_LIBS)
+libpulsecommon_@PA_MAJORMINOR@_la_CFLAGS += $(DBUS_CFLAGS)
+libpulsecommon_@PA_MAJORMINOR@_la_LIBADD += $(DBUS_LIBS)
 endif
 
 if USE_DLOG
-libpulsecommon_@PA_MAJORMINORMICRO@_la_CFLAGS += $(DLOG_CFLAGS) -DUSE_DLOG
-libpulsecommon_@PA_MAJORMINORMICRO@_la_LIBADD += $(DLOG_LIBS)
+libpulsecommon_@PA_MAJORMINOR@_la_CFLAGS += $(DLOG_CFLAGS) -DUSE_DLOG
+libpulsecommon_@PA_MAJORMINOR@_la_LIBADD += $(DLOG_LIBS)
+endif
+
+if USE_SECURITY
+libpulsecommon_@PA_MAJORMINOR@_la_CFLAGS += $(SECURITY_CFLAGS) -DUSE_SECURITY
+libpulsecommon_@PA_MAJORMINOR@_la_LIBADD += $(SECURITY_LIBS)
 endif
 
+###################################
+#         Pulsecore headers       #
+###################################
+
+pulsecoreinclude_HEADERS = \
+               pulsecore/arpa-inet.h \
+               pulsecore/asyncmsgq.h \
+               pulsecore/asyncq.h \
+               pulsecore/atomic.h \
+               pulsecore/aupdate.h \
+               pulsecore/auth-cookie.h \
+               pulsecore/authkey.h \
+               pulsecore/avahi-wrap.h \
+               pulsecore/bitset.h \
+               pulsecore/card.h \
+               pulsecore/cli-command.h \
+               pulsecore/client.h \
+               pulsecore/cli.h \
+               pulsecore/cli-text.h \
+               pulsecore/conf-parser.h \
+               pulsecore/core-error.h \
+               pulsecore/core.h \
+               pulsecore/core-rtclock.h \
+               pulsecore/core-scache.h \
+               pulsecore/core-subscribe.h \
+               pulsecore/core-util.h \
+               pulsecore/cpu-arm.h \
+               pulsecore/cpu.h \
+               pulsecore/cpu-orc.h \
+               pulsecore/cpu-x86.h \
+               pulsecore/creds.h \
+               pulsecore/database.h \
+               pulsecore/dbus-shared.h \
+               pulsecore/dbus-util.h \
+               pulsecore/device-port.h \
+               pulsecore/dynarray.h \
+               pulsecore/endianmacros.h \
+               pulsecore/esound.h \
+               pulsecore/fdsem.h \
+               pulsecore/flist.h \
+               pulsecore/g711.h \
+               pulsecore/hashmap.h \
+               pulsecore/hook-list.h \
+               pulsecore/i18n.h \
+               pulsecore/idxset.h \
+               pulsecore/iochannel.h \
+               pulsecore/ioline.h \
+               pulsecore/ipacl.h \
+               pulsecore/llist.h \
+               pulsecore/lock-autospawn.h \
+               pulsecore/log.h \
+               pulsecore/ltdl-helper.h \
+               pulsecore/macro.h \
+               pulsecore/mcalign.h \
+               pulsecore/memblock.h \
+               pulsecore/memblockq.h \
+               pulsecore/memchunk.h \
+               pulsecore/memtrap.h \
+               pulsecore/mime-type.h \
+               pulsecore/mix.h \
+               pulsecore/modargs.h \
+               pulsecore/modinfo.h \
+               pulsecore/module.h \
+               pulsecore/msgobject.h \
+               pulsecore/mutex.h \
+               pulsecore/namereg.h \
+               pulsecore/native-common.h \
+               pulsecore/object.h \
+               pulsecore/once.h \
+               pulsecore/packet.h \
+               pulsecore/parseaddr.h \
+               pulsecore/pdispatch.h \
+               pulsecore/pid.h \
+               pulsecore/pipe.h \
+               pulsecore/play-memblockq.h \
+               pulsecore/play-memchunk.h \
+               pulsecore/poll.h \
+               pulsecore/proplist-util.h \
+               pulsecore/protocol-cli.h \
+               pulsecore/protocol-dbus.h \
+               pulsecore/protocol-esound.h \
+               pulsecore/protocol-http.h \
+               pulsecore/protocol-native.h \
+               pulsecore/protocol-simple.h \
+               pulsecore/pstream.h \
+               pulsecore/pstream-util.h \
+               pulsecore/queue.h \
+               pulsecore/random.h \
+               pulsecore/ratelimit.h \
+               pulsecore/refcnt.h \
+               pulsecore/remap.h \
+               pulsecore/resampler.h \
+               pulsecore/rtkit.h \
+               pulsecore/rtpoll.h \
+               pulsecore/sample-util.h \
+               pulsecore/sconv.h \
+               pulsecore/sconv-s16be.h \
+               pulsecore/sconv-s16le.h \
+               pulsecore/semaphore.h \
+               pulsecore/shared.h \
+               pulsecore/shm.h \
+               pulsecore/sink.h \
+               pulsecore/sink-input.h \
+               pulsecore/sioman.h \
+               pulsecore/sndfile-util.h \
+               pulsecore/socket-client.h \
+               pulsecore/socket.h \
+               pulsecore/socket-server.h \
+               pulsecore/socket-util.h \
+               pulsecore/sound-file.h \
+               pulsecore/sound-file-stream.h \
+               pulsecore/source.h \
+               pulsecore/source-output.h \
+               pulsecore/start-child.h \
+               pulsecore/strbuf.h \
+               pulsecore/strlist.h \
+               pulsecore/tagstruct.h \
+               pulsecore/thread.h \
+               pulsecore/thread-mq.h \
+               pulsecore/time-smoother.h \
+               pulsecore/tokenizer.h \
+               pulsecore/usergroup.h \
+               pulsecore/x11prop.h \
+               pulsecore/x11wrap.h
 
 ###################################
 #         Client library          #
@@ -715,8 +873,12 @@ pulseinclude_HEADERS = \
                pulse/def.h \
                pulse/error.h \
                pulse/ext-device-manager.h \
+               pulse/ext-device-restore.h \
                pulse/ext-stream-restore.h \
                pulse/ext-policy.h \
+               pulse/ext-echo-cancel.h \
+               pulse/ext-suspend-on-idle.h \
+               pulse/format.h \
                pulse/gccmacro.h \
                pulse/introspect.h \
                pulse/mainloop-api.h \
@@ -739,18 +901,10 @@ pulseinclude_HEADERS = \
                pulse/volume.h \
                pulse/xmalloc.h
 
-lib_LTLIBRARIES += \
+lib_LTLIBRARIES = \
                libpulse.la \
                libpulse-simple.la
 
-if HAVE_AVAHI
-pulseinclude_HEADERS += \
-               pulse/browser.h
-
-lib_LTLIBRARIES += \
-               libpulse-browse.la
-endif
-
 if HAVE_GLIB20
 pulseinclude_HEADERS += \
                pulse/glib-mainloop.h
@@ -767,8 +921,12 @@ libpulse_la_SOURCES = \
                pulse/def.h \
                pulse/error.c pulse/error.h \
                pulse/ext-device-manager.c pulse/ext-device-manager.h \
+               pulse/ext-device-restore.c pulse/ext-device-restore.h \
                pulse/ext-stream-restore.c pulse/ext-stream-restore.h \
                pulse/ext-policy.c pulse/ext-policy.h \
+               pulse/ext-echo-cancel.c pulse/ext-echo-cancel.h \
+               pulse/ext-suspend-on-idle.c pulse/ext-suspend-on-idle.h \
+               pulse/format.c pulse/format.h \
                pulse/gccmacro.h \
                pulse/internal.h \
                pulse/introspect.c pulse/introspect.h \
@@ -790,29 +948,27 @@ libpulse_la_SOURCES = \
                pulse/volume.c pulse/volume.h \
                pulse/xmalloc.c pulse/xmalloc.h
 
-libpulse_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
-libpulse_la_LIBADD = $(AM_LIBADD) $(WINSOCK_LIBS) $(LTLIBICONV) libpulsecommon-@PA_MAJORMINORMICRO@.la
+libpulse_la_CFLAGS = $(AM_CFLAGS) $(LIBJSON_CFLAGS)
+libpulse_la_LIBADD = $(AM_LIBADD) $(WINSOCK_LIBS) $(LTLIBICONV) $(LIBJSON_LIBS) libpulsecommon-@PA_MAJORMINOR@.la
 libpulse_la_LDFLAGS = $(AM_LDFLAGS) $(VERSIONING_LDFLAGS) -version-info $(LIBPULSE_VERSION_INFO)
 
-if HAVE_X11
-libpulse_la_SOURCES += pulse/client-conf-x11.c pulse/client-conf-x11.h
-libpulse_la_CFLAGS += $(X11_CFLAGS)
-libpulse_la_LDFLAGS += $(X11_LIBS)
+if HAVE_DBUS
+libpulse_la_CFLAGS += $(DBUS_CFLAGS)
+libpulse_la_LIBADD += $(DBUS_LIBS)
+endif
+if USE_DLOG
+libpulse_la_CFLAGS += $(DLOG_CFLAGS) -DUSE_DLOG
+libpulse_la_LIBADD += $(DLOG_LIBS)
 endif
 
 libpulse_simple_la_SOURCES = pulse/simple.c pulse/simple.h
 libpulse_simple_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
-libpulse_simple_la_LIBADD = $(AM_LIBADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la
+libpulse_simple_la_LIBADD = $(AM_LIBADD) libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
 libpulse_simple_la_LDFLAGS = $(AM_LDFLAGS) $(VERSIONING_LDFLAGS) -version-info $(LIBPULSE_SIMPLE_VERSION_INFO)
 
-libpulse_browse_la_SOURCES = pulse/browser.c pulse/browser.h pulsecore/avahi-wrap.c pulsecore/avahi-wrap.h
-libpulse_browse_la_CFLAGS = $(AM_CFLAGS) $(AVAHI_CFLAGS)
-libpulse_browse_la_LIBADD = $(AM_LIBADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la $(AVAHI_LIBS)
-libpulse_browse_la_LDFLAGS = $(AM_LDFLAGS) $(VERSIONING_LDFLAGS) -version-info $(LIBPULSE_BROWSE_VERSION_INFO)
-
 libpulse_mainloop_glib_la_SOURCES = pulse/glib-mainloop.h pulse/glib-mainloop.c
 libpulse_mainloop_glib_la_CFLAGS = $(AM_CFLAGS) $(GLIB20_CFLAGS)
-libpulse_mainloop_glib_la_LIBADD = $(AM_LIBADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la $(GLIB20_LIBS)
+libpulse_mainloop_glib_la_LIBADD = $(AM_LIBADD) libpulse.la libpulsecommon-@PA_MAJORMINOR@.la $(GLIB20_LIBS)
 libpulse_mainloop_glib_la_LDFLAGS = $(AM_LDFLAGS) $(VERSIONING_LDFLAGS) -version-info $(LIBPULSE_MAINLOOP_GLIB_VERSION_INFO)
 
 ###################################
@@ -820,23 +976,34 @@ libpulse_mainloop_glib_la_LDFLAGS = $(AM_LDFLAGS) $(VERSIONING_LDFLAGS) -version
 ###################################
 
 if HAVE_OSS_WRAPPER
-lib_LTLIBRARIES += libpulsedsp.la
-bin_SCRIPTS += utils/padsp
+padsplibdir = $(pkglibdir)
+padsplib_LTLIBRARIES = libpulsedsp.la
+bin_SCRIPTS += padsp
+
+edit = @SED@ \
+       -e "s|@pkglibdir[@]|$(pkglibdir)|g"
+
+padsp: utils/padsp.in
+       $(edit) $< > $@
+
+CLEANFILES += padsp
+
 endif
 
 libpulsedsp_la_SOURCES = utils/padsp.c
 libpulsedsp_la_CFLAGS = $(AM_CFLAGS)
-libpulsedsp_la_LIBADD = $(AM_LIBADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la
+libpulsedsp_la_LIBADD = $(AM_LIBADD) libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
 libpulsedsp_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version -disable-static
 
 ###################################
 #      Daemon core library        #
 ###################################
 
-lib_LTLIBRARIES += libpulsecore-@PA_MAJORMINORMICRO@.la
+lib_LTLIBRARIES += libpulsecore-@PA_MAJORMINOR@.la
+noinst_LTLIBRARIES =
 
 # Pure core stuff
-libpulsecore_@PA_MAJORMINORMICRO@_la_SOURCES = \
+libpulsecore_@PA_MAJORMINOR@_la_SOURCES = \
                pulsecore/asyncmsgq.c pulsecore/asyncmsgq.h \
                pulsecore/asyncq.c pulsecore/asyncq.h \
                pulsecore/auth-cookie.c pulsecore/auth-cookie.h \
@@ -847,9 +1014,7 @@ libpulsecore_@PA_MAJORMINORMICRO@_la_SOURCES = \
                pulsecore/core-scache.c pulsecore/core-scache.h \
                pulsecore/core-subscribe.c pulsecore/core-subscribe.h \
                pulsecore/core.c pulsecore/core.h \
-               pulsecore/envelope.c pulsecore/envelope.h \
                pulsecore/fdsem.c pulsecore/fdsem.h \
-               pulsecore/g711.c pulsecore/g711.h \
                pulsecore/hook-list.c pulsecore/hook-list.h \
                pulsecore/ltdl-helper.c pulsecore/ltdl-helper.h \
                pulsecore/modargs.c pulsecore/modargs.h \
@@ -864,19 +1029,19 @@ libpulsecore_@PA_MAJORMINORMICRO@_la_SOURCES = \
                pulsecore/remap_mmx.c pulsecore/remap_sse.c \
                pulsecore/resampler.c pulsecore/resampler.h \
                pulsecore/rtpoll.c pulsecore/rtpoll.h \
-               pulsecore/sample-util.c pulsecore/sample-util.h \
+               pulsecore/mix.c pulsecore/mix.h \
+               pulsecore/cpu.h \
                pulsecore/cpu-arm.c pulsecore/cpu-arm.h \
                pulsecore/cpu-x86.c pulsecore/cpu-x86.h \
-               pulsecore/svolume_c.c pulsecore/svolume_arm.c \
-               pulsecore/svolume_mmx.c pulsecore/svolume_sse.c \
+               pulsecore/cpu-orc.c pulsecore/cpu-orc.h \
                pulsecore/sconv-s16be.c pulsecore/sconv-s16be.h \
                pulsecore/sconv-s16le.c pulsecore/sconv-s16le.h \
                pulsecore/sconv_sse.c \
                pulsecore/sconv.c pulsecore/sconv.h \
                pulsecore/shared.c pulsecore/shared.h \
-               pulsecore/shm.c pulsecore/shm.h \
                pulsecore/sink-input.c pulsecore/sink-input.h \
                pulsecore/sink.c pulsecore/sink.h \
+               pulsecore/device-port.c pulsecore/device-port.h \
                pulsecore/sioman.c pulsecore/sioman.h \
                pulsecore/sound-file-stream.c pulsecore/sound-file-stream.h \
                pulsecore/sound-file.c pulsecore/sound-file.h \
@@ -884,43 +1049,71 @@ libpulsecore_@PA_MAJORMINORMICRO@_la_SOURCES = \
                pulsecore/source.c pulsecore/source.h \
                pulsecore/start-child.c pulsecore/start-child.h \
                pulsecore/thread-mq.c pulsecore/thread-mq.h \
-               pulsecore/time-smoother.c pulsecore/time-smoother.h \
                pulsecore/database.h
 
-libpulsecore_@PA_MAJORMINORMICRO@_la_CFLAGS = $(AM_CFLAGS) $(LIBSAMPLERATE_CFLAGS) $(LIBSPEEX_CFLAGS) $(WINSOCK_CFLAGS)
-libpulsecore_@PA_MAJORMINORMICRO@_la_LDFLAGS = -avoid-version
-libpulsecore_@PA_MAJORMINORMICRO@_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSPEEX_LIBS) $(WINSOCK_LIBS) $(LTLIBICONV) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la libpulsecore-foreign.la
+libpulsecore_@PA_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) $(SERVER_CFLAGS) $(LIBSAMPLERATE_CFLAGS) $(LIBSNDFILE_CFLAGS) $(WINSOCK_CFLAGS)
+libpulsecore_@PA_MAJORMINOR@_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
+libpulsecore_@PA_MAJORMINOR@_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) $(WINSOCK_LIBS) $(LTLIBICONV) libpulsecommon-@PA_MAJORMINOR@.la libpulse.la libpulsecore-foreign.la
+
+if HAVE_SPEEX
+libpulsecore_@PA_MAJORMINOR@_la_CFLAGS += $(LIBSPEEX_CFLAGS)
+libpulsecore_@PA_MAJORMINOR@_la_LIBADD += $(LIBSPEEX_LIBS)
+endif
+
+if HAVE_NEON
+noinst_LTLIBRARIES += libpulsecore_sconv_neon.la libpulsecore_mix_neon.la
+libpulsecore_sconv_neon_la_SOURCES = pulsecore/sconv_neon.c
+libpulsecore_sconv_neon_la_CFLAGS = $(AM_CFLAGS) $(NEON_CFLAGS)
+libpulsecore_mix_neon_la_SOURCES = pulsecore/mix_neon.c
+libpulsecore_mix_neon_la_CFLAGS = $(AM_CFLAGS) $(NEON_CFLAGS)
+libpulsecore_@PA_MAJORMINOR@_la_LIBADD += libpulsecore_sconv_neon.la libpulsecore_mix_neon.la
+endif
+
+if HAVE_ORC
+ORC_SOURCE += pulsecore/svolume
+libpulsecore_@PA_MAJORMINOR@_la_SOURCES += pulsecore/svolume_orc.c
+nodist_libpulsecore_@PA_MAJORMINOR@_la_SOURCES = pulsecore/svolume-orc-gen.c pulsecore/svolume-orc-gen.h
+libpulsecore_@PA_MAJORMINOR@_la_CFLAGS += $(ORC_CFLAGS)
+libpulsecore_@PA_MAJORMINOR@_la_LIBADD += $(ORC_LIBS)
+endif
 
 if HAVE_X11
-libpulsecore_@PA_MAJORMINORMICRO@_la_SOURCES += pulsecore/x11wrap.c pulsecore/x11wrap.h
-libpulsecore_@PA_MAJORMINORMICRO@_la_CFLAGS += $(X11_CFLAGS)
-libpulsecore_@PA_MAJORMINORMICRO@_la_LDFLAGS += $(X11_LIBS)
+libpulsecore_@PA_MAJORMINOR@_la_SOURCES += pulsecore/x11wrap.c pulsecore/x11wrap.h
+libpulsecore_@PA_MAJORMINOR@_la_CFLAGS += $(X11_CFLAGS)
+libpulsecore_@PA_MAJORMINOR@_la_LDFLAGS += $(X11_LIBS)
 endif
 
 if HAVE_DBUS
-libpulsecore_@PA_MAJORMINORMICRO@_la_SOURCES += pulsecore/dbus-shared.c pulsecore/dbus-shared.h
-libpulsecore_@PA_MAJORMINORMICRO@_la_CFLAGS += $(DBUS_CFLAGS)
-libpulsecore_@PA_MAJORMINORMICRO@_la_LIBADD += $(DBUS_LIBS)
+libpulsecore_@PA_MAJORMINOR@_la_SOURCES += \
+               pulsecore/dbus-shared.c pulsecore/dbus-shared.h \
+               pulsecore/protocol-dbus.c pulsecore/protocol-dbus.h
+libpulsecore_@PA_MAJORMINOR@_la_CFLAGS += $(DBUS_CFLAGS)
+libpulsecore_@PA_MAJORMINOR@_la_LIBADD += $(DBUS_LIBS)
 endif
 
 if HAVE_GDBM
-libpulsecore_@PA_MAJORMINORMICRO@_la_SOURCES += pulsecore/database-gdbm.c
-libpulsecore_@PA_MAJORMINORMICRO@_la_CFLAGS += $(GDBM_CFLAGS)
-libpulsecore_@PA_MAJORMINORMICRO@_la_LIBADD += $(GDBM_LIBS)
+libpulsecore_@PA_MAJORMINOR@_la_SOURCES += pulsecore/database-gdbm.c
+libpulsecore_@PA_MAJORMINOR@_la_CFLAGS += $(GDBM_CFLAGS)
+libpulsecore_@PA_MAJORMINOR@_la_LIBADD += $(GDBM_LIBS)
 endif
 
 if HAVE_TDB
-libpulsecore_@PA_MAJORMINORMICRO@_la_SOURCES += pulsecore/database-tdb.c
-libpulsecore_@PA_MAJORMINORMICRO@_la_CFLAGS += $(TDB_CFLAGS)
-libpulsecore_@PA_MAJORMINORMICRO@_la_LIBADD += $(TDB_LIBS)
+libpulsecore_@PA_MAJORMINOR@_la_SOURCES += pulsecore/database-tdb.c
+libpulsecore_@PA_MAJORMINOR@_la_CFLAGS += $(TDB_CFLAGS)
+libpulsecore_@PA_MAJORMINOR@_la_LIBADD += $(TDB_LIBS)
 endif
 
 if HAVE_SIMPLEDB
-libpulsecore_@PA_MAJORMINORMICRO@_la_SOURCES += pulsecore/database-simple.c
+libpulsecore_@PA_MAJORMINOR@_la_SOURCES += pulsecore/database-simple.c
+endif
+
+if USE_DLOG
+libpulsecore_@PA_MAJORMINOR@_la_CFLAGS += $(DLOG_CFLAGS) -DUSE_DLOG
+libpulsecore_@PA_MAJORMINOR@_la_LIBADD += $(DLOG_LIBS)
 endif
 
 # We split the foreign code off to not be annoyed by warnings we don't care about
-noinst_LTLIBRARIES = libpulsecore-foreign.la
+noinst_LTLIBRARIES += libpulsecore-foreign.la
 
 libpulsecore_foreign_la_SOURCES = \
                pulsecore/ffmpeg/resample2.c pulsecore/ffmpeg/avcodec.h pulsecore/ffmpeg/dsputil.h
@@ -941,8 +1134,16 @@ modlibexec_LTLIBRARIES = \
                libprotocol-cli.la \
                libprotocol-simple.la \
                libprotocol-http.la \
-               libprotocol-native.la \
+               libprotocol-native.la
+
+if HAVE_WEBRTC
+modlibexec_LTLIBRARIES += libwebrtc-util.la
+endif
+
+if HAVE_ESOUND
+modlibexec_LTLIBRARIES += \
                libprotocol-esound.la
+endif
 
 # We need to emulate sendmsg/recvmsg to support this on Win32
 if !OS_IS_WIN32
@@ -956,28 +1157,38 @@ modlibexec_LTLIBRARIES += \
 endif
 
 libprotocol_simple_la_SOURCES = pulsecore/protocol-simple.c pulsecore/protocol-simple.h
-libprotocol_simple_la_LDFLAGS = -avoid-version
-libprotocol_simple_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+libprotocol_simple_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
+libprotocol_simple_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
 
 libcli_la_SOURCES = pulsecore/cli.c pulsecore/cli.h
-libcli_la_LDFLAGS = -avoid-version
-libcli_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+libcli_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
+libcli_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
 
 libprotocol_cli_la_SOURCES = pulsecore/protocol-cli.c pulsecore/protocol-cli.h
-libprotocol_cli_la_LDFLAGS = -avoid-version
-libprotocol_cli_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la libcli.la
+libprotocol_cli_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
+libprotocol_cli_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la libcli.la
 
 libprotocol_http_la_SOURCES = pulsecore/protocol-http.c pulsecore/protocol-http.h pulsecore/mime-type.c pulsecore/mime-type.h
-libprotocol_http_la_LDFLAGS = -avoid-version
-libprotocol_http_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+libprotocol_http_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
+libprotocol_http_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
 
 libprotocol_native_la_SOURCES = pulsecore/protocol-native.c pulsecore/protocol-native.h pulsecore/native-common.h
-libprotocol_native_la_LDFLAGS = -avoid-version
-libprotocol_native_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+libprotocol_native_la_CFLAGS = $(AM_CFLAGS) $(SERVER_CFLAGS)
+libprotocol_native_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
+libprotocol_native_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
+if HAVE_DBUS
+libprotocol_native_la_CFLAGS += $(DBUS_CFLAGS)
+libprotocol_native_la_LIBADD += $(DBUS_LIBS)
+endif
+if USE_SECURITY
+libprotocol_native_la_CFLAGS += -DUSE_SECURITY
+endif
 
+if HAVE_ESOUND
 libprotocol_esound_la_SOURCES = pulsecore/protocol-esound.c pulsecore/protocol-esound.h pulsecore/esound.h
-libprotocol_esound_la_LDFLAGS = -avoid-version
-libprotocol_esound_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+libprotocol_esound_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
+libprotocol_esound_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
+endif
 
 librtp_la_SOURCES = \
                modules/rtp/rtp.c modules/rtp/rtp.h \
@@ -985,21 +1196,21 @@ librtp_la_SOURCES = \
                modules/rtp/sap.c modules/rtp/sap.h \
                modules/rtp/rtsp_client.c modules/rtp/rtsp_client.h \
                modules/rtp/headerlist.c modules/rtp/headerlist.h
-librtp_la_LDFLAGS = -avoid-version
-librtp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+librtp_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
+librtp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
 
 libraop_la_SOURCES = \
         modules/raop/raop_client.c modules/raop/raop_client.h \
         modules/raop/base64.c modules/raop/base64.h
-libraop_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_CFLAGS)
-libraop_la_LDFLAGS = -avoid-version
-libraop_la_LIBADD = $(AM_LIBADD) $(OPENSSL_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la librtp.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+libraop_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_CFLAGS) -I$(top_srcdir)/src/modules/rtp
+libraop_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
+libraop_la_LIBADD = $(AM_LIBADD) $(OPENSSL_LIBS) libpulsecore-@PA_MAJORMINOR@.la librtp.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
 
 # Avahi
 libavahi_wrap_la_SOURCES = pulsecore/avahi-wrap.c pulsecore/avahi-wrap.h
-libavahi_wrap_la_LDFLAGS = -avoid-version
+libavahi_wrap_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
 libavahi_wrap_la_CFLAGS = $(AM_CFLAGS) $(AVAHI_CFLAGS)
-libavahi_wrap_la_LIBADD = $(AM_LIBADD) $(AVAHI_CFLAGS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+libavahi_wrap_la_LIBADD = $(AM_LIBADD) $(AVAHI_CFLAGS) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
 
 ###################################
 #        Plug-in libraries        #
@@ -1009,7 +1220,8 @@ if HAVE_DBUS
 # Serveral module (e.g. libalsa-util.la)
 modlibexec_LTLIBRARIES += \
                module-console-kit.la \
-               module-policy.la
+               module-policy.la \
+               module-stream-mgr.la
 endif
 
 modlibexec_LTLIBRARIES += \
@@ -1017,6 +1229,7 @@ modlibexec_LTLIBRARIES += \
                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 \
                module-volume-restore.la \
@@ -1034,19 +1247,31 @@ modlibexec_LTLIBRARIES += \
                module-sine.la \
                module-native-protocol-tcp.la \
                module-native-protocol-fd.la \
-               module-esound-protocol-tcp.la \
                module-combine.la \
+               module-combine-sink.la \
                module-remap-sink.la \
+               module-remap-source.la \
                module-ladspa-sink.la \
-               module-esound-sink.la \
                module-tunnel-sink.la \
                module-tunnel-source.la \
                module-position-event-sounds.la \
                module-augment-properties.la \
-               module-cork-music-on-phone.la \
+               module-role-cork.la \
                module-loopback.la \
                module-virtual-sink.la \
-               module-virtual-source.la
+               module-virtual-source.la \
+               module-virtual-surround-sink.la \
+               module-switch-on-connect.la \
+               module-switch-on-port-available.la \
+               module-filter-apply.la \
+               module-filter-heuristics.la \
+               module-role-ducking.la
+
+if HAVE_ESOUND
+modlibexec_LTLIBRARIES += \
+               module-esound-protocol-tcp.la \
+               module-esound-sink.la
+endif
 
 # See comment at librtp.la above
 if !OS_IS_WIN32
@@ -1060,9 +1285,12 @@ modlibexec_LTLIBRARIES += \
                module-cli-protocol-unix.la \
                module-simple-protocol-unix.la \
                module-http-protocol-unix.la \
-               module-native-protocol-unix.la \
+               module-native-protocol-unix.la
+if HAVE_ESOUND
+modlibexec_LTLIBRARIES += \
                module-esound-protocol-unix.la
 endif
+endif
 
 if HAVE_MKFIFO
 modlibexec_LTLIBRARIES += \
@@ -1071,10 +1299,12 @@ modlibexec_LTLIBRARIES += \
 endif
 
 if !OS_IS_WIN32
+if HAVE_ESOUND
 modlibexec_LTLIBRARIES += \
                module-esound-compat-spawnfd.la \
                module-esound-compat-spawnpid.la
 endif
+endif
 
 if HAVE_REGEX
 modlibexec_LTLIBRARIES += \
@@ -1095,6 +1325,12 @@ modlibexec_LTLIBRARIES += \
                module-oss.la
 endif
 
+if HAVE_COREAUDIO
+modlibexec_LTLIBRARIES += \
+               module-coreaudio-detect.la \
+               module-coreaudio-device.la
+endif
+
 pulselibexec_PROGRAMS =
 
 if HAVE_ALSA
@@ -1104,14 +1340,56 @@ modlibexec_LTLIBRARIES += \
                module-alsa-source.la \
                module-alsa-card.la
 
-alsaprofilesets_DATA = ${ALSA_PROFILES}
+dist_alsaprofilesets_DATA = \
+               modules/alsa/mixer/profile-sets/default.conf \
+               modules/alsa/mixer/profile-sets/extra-hdmi.conf \
+               modules/alsa/mixer/profile-sets/force-speaker.conf \
+               modules/alsa/mixer/profile-sets/force-speaker-and-int-mic.conf \
+               modules/alsa/mixer/profile-sets/maudio-fasttrack-pro.conf \
+               modules/alsa/mixer/profile-sets/native-instruments-audio4dj.conf \
+               modules/alsa/mixer/profile-sets/native-instruments-audio8dj.conf \
+               modules/alsa/mixer/profile-sets/native-instruments-traktor-audio6.conf \
+               modules/alsa/mixer/profile-sets/native-instruments-traktor-audio10.conf \
+               modules/alsa/mixer/profile-sets/native-instruments-traktorkontrol-s4.conf \
+               modules/alsa/mixer/profile-sets/native-instruments-korecontroller.conf \
+               modules/alsa/mixer/profile-sets/kinect-audio.conf
 
 if HAVE_UDEV
-udevrules_DATA = \
+dist_udevrules_DATA = \
                modules/alsa/mixer/profile-sets/90-pulseaudio.rules
 endif
 
-alsapaths_DATA = ${ALSA_PATHS}
+dist_alsapaths_DATA = \
+               modules/alsa/mixer/paths/analog-input-aux.conf \
+               modules/alsa/mixer/paths/analog-input.conf \
+               modules/alsa/mixer/paths/analog-input.conf.common \
+               modules/alsa/mixer/paths/analog-input-fm.conf \
+               modules/alsa/mixer/paths/analog-input-linein.conf \
+               modules/alsa/mixer/paths/analog-input-mic.conf \
+               modules/alsa/mixer/paths/analog-input-dock-mic.conf \
+               modules/alsa/mixer/paths/analog-input-front-mic.conf \
+               modules/alsa/mixer/paths/analog-input-headphone-mic.conf \
+               modules/alsa/mixer/paths/analog-input-headset-mic.conf \
+               modules/alsa/mixer/paths/analog-input-internal-mic.conf \
+               modules/alsa/mixer/paths/analog-input-internal-mic-always.conf \
+               modules/alsa/mixer/paths/analog-input-rear-mic.conf \
+               modules/alsa/mixer/paths/analog-input-mic.conf.common \
+               modules/alsa/mixer/paths/analog-input-mic-line.conf \
+               modules/alsa/mixer/paths/analog-input-tvtuner.conf \
+               modules/alsa/mixer/paths/analog-input-video.conf \
+               modules/alsa/mixer/paths/analog-output.conf \
+               modules/alsa/mixer/paths/analog-output-speaker.conf \
+               modules/alsa/mixer/paths/analog-output-speaker-always.conf \
+               modules/alsa/mixer/paths/analog-output.conf.common \
+               modules/alsa/mixer/paths/analog-output-desktop-speaker.conf \
+               modules/alsa/mixer/paths/analog-output-headphones.conf \
+               modules/alsa/mixer/paths/analog-output-headphones-2.conf \
+               modules/alsa/mixer/paths/analog-output-mono.conf \
+               modules/alsa/mixer/paths/iec958-stereo-output.conf \
+               modules/alsa/mixer/paths/hdmi-output-0.conf \
+               modules/alsa/mixer/paths/hdmi-output-1.conf \
+               modules/alsa/mixer/paths/hdmi-output-2.conf \
+               modules/alsa/mixer/paths/hdmi-output-3.conf
 
 endif
 
@@ -1126,11 +1404,22 @@ modlibexec_LTLIBRARIES += \
                module-zeroconf-discover.la
 endif
 
+if HAVE_BONJOUR
+modlibexec_LTLIBRARIES += \
+               module-bonjour-publish.la
+endif
+
 if HAVE_LIRC
 modlibexec_LTLIBRARIES += \
                module-lirc.la
 endif
 
+if HAVE_XEN
+modlibexec_LTLIBRARIES += \
+               module-xenpv-sink.la
+endif
+
+
 if HAVE_EVDEV
 modlibexec_LTLIBRARIES += \
                module-mmkbd-evdev.la
@@ -1140,6 +1429,12 @@ if HAVE_JACK
 modlibexec_LTLIBRARIES += \
                module-jack-sink.la \
                module-jack-source.la
+
+if HAVE_DBUS
+modlibexec_LTLIBRARIES += \
+               module-jackdbus-detect.la
+endif
+
 endif
 
 if HAVE_GCONF
@@ -1150,14 +1445,9 @@ pulselibexec_PROGRAMS += \
                gconf-helper
 endif
 
-#if OS_IS_WIN32
-#modlibexec_LTLIBRARIES += \
-#              module-waveout.la
-#endif
-
-if HAVE_HAL
+if HAVE_WAVEOUT
 modlibexec_LTLIBRARIES += \
-               module-hal-detect.la
+               module-waveout.la
 endif
 
 if HAVE_HAL_COMPAT
@@ -1170,22 +1460,35 @@ modlibexec_LTLIBRARIES += \
                module-udev-detect.la
 endif
 
+if HAVE_SYSTEMD
+modlibexec_LTLIBRARIES += \
+               module-systemd-login.la
+endif
+
 if HAVE_DBUS
 modlibexec_LTLIBRARIES += \
-               module-rygel-media-server.la
+               module-rygel-media-server.la \
+               module-dbus-protocol.la
 endif
 
 if HAVE_BLUEZ
 modlibexec_LTLIBRARIES += \
-               libbluetooth-util.la \
-               module-bluetooth-proximity.la \
                module-bluetooth-discover.la \
-               libbluetooth-ipc.la \
-               libbluetooth-sbc.la \
-               module-bluetooth-device.la
+               module-bluetooth-policy.la
+endif
 
-pulselibexec_PROGRAMS += \
-               proximity-helper
+if HAVE_BLUEZ_4
+modlibexec_LTLIBRARIES += \
+               libbluez4-util.la \
+               module-bluez4-discover.la \
+               module-bluez4-device.la
+endif
+
+if HAVE_BLUEZ_5
+modlibexec_LTLIBRARIES += \
+               libbluez5-util.la \
+               module-bluez5-discover.la \
+               module-bluez5-device.la
 endif
 
 if HAVE_OPENSSL
@@ -1198,278 +1501,395 @@ modlibexec_LTLIBRARIES += \
 endif
 endif
 
+if HAVE_DBUS
+if HAVE_FFTW
+modlibexec_LTLIBRARIES += \
+               module-equalizer-sink.la
+bin_SCRIPTS += utils/qpaeq
+endif
+endif
+
 # These are generated by an M4 script
 SYMDEF_FILES = \
-               modules/module-cli-symdef.h \
-               modules/module-cli-protocol-tcp-symdef.h \
-               modules/module-cli-protocol-unix-symdef.h \
-               modules/module-pipe-sink-symdef.h \
-               modules/module-pipe-source-symdef.h \
-               modules/module-simple-protocol-tcp-symdef.h \
-               modules/module-simple-protocol-unix-symdef.h \
-               modules/module-esound-protocol-tcp-symdef.h \
-               modules/module-esound-protocol-unix-symdef.h \
-               modules/module-native-protocol-tcp-symdef.h \
-               modules/module-native-protocol-unix-symdef.h \
-               modules/module-native-protocol-fd-symdef.h \
-               modules/module-sine-symdef.h \
-               modules/module-combine-symdef.h \
-               modules/module-remap-sink-symdef.h \
-               modules/module-ladspa-sink-symdef.h \
-               modules/module-esound-compat-spawnfd-symdef.h \
-               modules/module-esound-compat-spawnpid-symdef.h \
-               modules/module-match-symdef.h \
-               modules/module-tunnel-sink-symdef.h \
-               modules/module-tunnel-source-symdef.h \
-               modules/module-null-sink-symdef.h \
-               modules/module-sine-source-symdef.h \
-               modules/module-esound-sink-symdef.h \
-               modules/module-zeroconf-publish-symdef.h \
-               modules/module-zeroconf-discover-symdef.h \
-               modules/module-lirc-symdef.h \
-               modules/module-mmkbd-evdev-symdef.h \
-               modules/module-http-protocol-tcp-symdef.h \
-               modules/module-http-protocol-unix-symdef.h \
-               modules/module-rygel-media-server-symdef.h \
-               modules/x11/module-x11-bell-symdef.h \
-               modules/x11/module-x11-publish-symdef.h \
-               modules/x11/module-x11-xsmp-symdef.h \
-               modules/x11/module-x11-cork-request-symdef.h \
-               modules/oss/module-oss-symdef.h \
-               modules/alsa/module-alsa-sink-symdef.h \
-               modules/alsa/module-alsa-source-symdef.h \
-               modules/alsa/module-alsa-card-symdef.h \
-               modules/module-solaris-symdef.h \
-               modules/module-waveout-symdef.h \
-               modules/module-detect-symdef.h \
-               modules/rtp/module-rtp-send-symdef.h \
-               modules/rtp/module-rtp-recv-symdef.h \
-               modules/jack/module-jack-sink-symdef.h \
-               modules/jack/module-jack-source-symdef.h \
-               modules/module-volume-restore-symdef.h \
-               modules/module-device-manager-symdef.h \
-               modules/module-device-restore-symdef.h \
-               modules/module-stream-restore-symdef.h \
-               modules/module-card-restore-symdef.h \
-               modules/module-default-device-restore-symdef.h \
-               modules/module-always-sink-symdef.h \
-               modules/module-rescue-streams-symdef.h \
-               modules/module-intended-roles-symdef.h \
-               modules/module-suspend-on-idle-symdef.h \
-               modules/echo-cancel/module-echo-cancel-symdef.h \
-               modules/module-hal-detect-symdef.h \
-               modules/module-udev-detect-symdef.h \
-               modules/bluetooth/module-bluetooth-proximity-symdef.h \
-               modules/bluetooth/module-bluetooth-discover-symdef.h \
-               modules/bluetooth/module-bluetooth-device-symdef.h \
-               modules/raop/module-raop-sink-symdef.h \
-               modules/raop/module-raop-discover-symdef.h \
-               modules/gconf/module-gconf-symdef.h \
-               modules/module-position-event-sounds-symdef.h \
-               modules/module-augment-properties-symdef.h \
-               modules/module-cork-music-on-phone-symdef.h \
-               modules/module-console-kit-symdef.h \
-               modules/module-loopback-symdef.h \
-               modules/module-policy-symdef.h \
-               modules/module-virtual-sink-symdef.h \
-               modules/module-virtual-source-symdef.h
+               module-cli-symdef.h \
+               module-cli-protocol-tcp-symdef.h \
+               module-cli-protocol-unix-symdef.h \
+               module-pipe-sink-symdef.h \
+               module-pipe-source-symdef.h \
+               module-simple-protocol-tcp-symdef.h \
+               module-simple-protocol-unix-symdef.h \
+               module-native-protocol-tcp-symdef.h \
+               module-native-protocol-unix-symdef.h \
+               module-native-protocol-fd-symdef.h \
+               module-sine-symdef.h \
+               module-combine-symdef.h \
+               module-combine-sink-symdef.h \
+               module-remap-sink-symdef.h \
+               module-remap-source-symdef.h \
+               module-ladspa-sink-symdef.h \
+               module-equalizer-sink-symdef.h \
+               module-match-symdef.h \
+               module-tunnel-sink-symdef.h \
+               module-tunnel-source-symdef.h \
+               module-null-sink-symdef.h \
+               module-null-source-symdef.h \
+               module-sine-source-symdef.h \
+               module-zeroconf-publish-symdef.h \
+               module-zeroconf-discover-symdef.h \
+               module-bonjour-publish-symdef.h \
+               module-lirc-symdef.h \
+               module-xenpv-sink-symdef.h \
+               module-mmkbd-evdev-symdef.h \
+               module-http-protocol-tcp-symdef.h \
+               module-http-protocol-unix-symdef.h \
+               module-rygel-media-server-symdef.h \
+               module-x11-bell-symdef.h \
+               module-x11-publish-symdef.h \
+               module-x11-xsmp-symdef.h \
+               module-x11-cork-request-symdef.h \
+               module-oss-symdef.h \
+               module-alsa-sink-symdef.h \
+               module-alsa-source-symdef.h \
+               module-alsa-card-symdef.h \
+               module-coreaudio-detect-symdef.h \
+               module-coreaudio-device-symdef.h \
+               module-solaris-symdef.h \
+               module-waveout-symdef.h \
+               module-detect-symdef.h \
+               module-rtp-send-symdef.h \
+               module-rtp-recv-symdef.h \
+               module-jackdbus-detect-symdef.h \
+               module-jack-sink-symdef.h \
+               module-jack-source-symdef.h \
+               module-volume-restore-symdef.h \
+               module-device-manager-symdef.h \
+               module-device-restore-symdef.h \
+               module-stream-restore-symdef.h \
+               module-card-restore-symdef.h \
+               module-default-device-restore-symdef.h \
+               module-always-sink-symdef.h \
+               module-rescue-streams-symdef.h \
+               module-intended-roles-symdef.h \
+               module-suspend-on-idle-symdef.h \
+               module-echo-cancel-symdef.h \
+               module-hal-detect-symdef.h \
+               module-udev-detect-symdef.h \
+               module-systemd-login-symdef.h \
+               module-bluetooth-discover-symdef.h \
+               module-bluetooth-policy-symdef.h \
+               module-bluez4-discover-symdef.h \
+               module-bluez4-device-symdef.h \
+               module-bluez5-discover-symdef.h \
+               module-bluez5-device-symdef.h \
+               module-bluetooth-device-symdef.h \
+               module-raop-sink-symdef.h \
+               module-raop-discover-symdef.h \
+               module-gconf-symdef.h \
+               module-position-event-sounds-symdef.h \
+               module-role-ducking-symdef.h \
+               module-augment-properties-symdef.h \
+               module-role-cork-symdef.h \
+               module-console-kit-symdef.h \
+               module-dbus-protocol-symdef.h \
+               module-loopback-symdef.h \
+               module-virtual-sink-symdef.h \
+               module-virtual-source-symdef.h \
+               module-virtual-surround-sink-symdef.h \
+               module-switch-on-connect-symdef.h \
+               module-switch-on-port-available-symdef.h \
+               module-filter-apply-symdef.h \
+               module-filter-heuristics-symdef.h \
+               module-policy-symdef.h \
+               module-stream-mgr-symdef.h
+
+if HAVE_ESOUND
+SYMDEF_FILES += \
+               module-esound-protocol-tcp-symdef.h \
+               module-esound-protocol-unix-symdef.h \
+               module-esound-compat-spawnfd-symdef.h \
+               module-esound-compat-spawnpid-symdef.h \
+               module-esound-sink-symdef.h
+endif
 
 EXTRA_DIST += $(SYMDEF_FILES)
-BUILT_SOURCES += $(SYMDEF_FILES)
+BUILT_SOURCES += $(SYMDEF_FILES) builddirs
 
 $(SYMDEF_FILES): modules/module-defs.h.m4
-       $(MKDIR_P) $(dir $@)
-       $(M4) -Dfname="$@" $< > $@
+       $(AM_V_at)$(MKDIR_P) modules
+       $(AM_V_GEN)$(M4) -Dfname="$@" $< > $@
+
+.PHONY: builddirs
+builddirs:
+       $(AM_V_at)$(MKDIR_P) daemon modules
 
 # Simple protocol
 
 module_simple_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c
 module_simple_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_SIMPLE $(AM_CFLAGS)
 module_simple_protocol_tcp_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_simple_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-simple.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_simple_protocol_tcp_la_LIBADD = $(MODULE_LIBADD) libprotocol-simple.la
 
 module_simple_protocol_unix_la_SOURCES = modules/module-protocol-stub.c
 module_simple_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_SIMPLE $(AM_CFLAGS)
 module_simple_protocol_unix_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_simple_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-simple.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_simple_protocol_unix_la_LIBADD = $(MODULE_LIBADD) libprotocol-simple.la
 
 # CLI protocol
 
 module_cli_la_SOURCES = modules/module-cli.c
 module_cli_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_cli_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libcli.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_cli_la_LIBADD = $(MODULE_LIBADD) libcli.la
 
 module_cli_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c
 module_cli_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_CLI $(AM_CFLAGS)
 module_cli_protocol_tcp_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_cli_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-cli.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_cli_protocol_tcp_la_LIBADD = $(MODULE_LIBADD) libprotocol-cli.la
 
 module_cli_protocol_unix_la_SOURCES = modules/module-protocol-stub.c
 module_cli_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_CLI $(AM_CFLAGS)
 module_cli_protocol_unix_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_cli_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-cli.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_cli_protocol_unix_la_LIBADD = $(MODULE_LIBADD) libprotocol-cli.la
 
 # HTTP protocol
 
 module_http_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c
 module_http_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_HTTP $(AM_CFLAGS)
 module_http_protocol_tcp_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_http_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-http.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_http_protocol_tcp_la_LIBADD = $(MODULE_LIBADD) libprotocol-http.la
 
 module_http_protocol_unix_la_SOURCES = modules/module-protocol-stub.c
 module_http_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_HTTP $(AM_CFLAGS)
 module_http_protocol_unix_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_http_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-http.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_http_protocol_unix_la_LIBADD = $(MODULE_LIBADD) libprotocol-http.la
+
+# D-Bus protocol
+
+module_dbus_protocol_la_SOURCES = \
+               modules/dbus/iface-card.c modules/dbus/iface-card.h \
+               modules/dbus/iface-card-profile.c modules/dbus/iface-card-profile.h \
+               modules/dbus/iface-client.c modules/dbus/iface-client.h \
+               modules/dbus/iface-core.c modules/dbus/iface-core.h \
+               modules/dbus/iface-device.c modules/dbus/iface-device.h \
+               modules/dbus/iface-device-port.c modules/dbus/iface-device-port.h \
+               modules/dbus/iface-memstats.c modules/dbus/iface-memstats.h \
+               modules/dbus/iface-module.c modules/dbus/iface-module.h \
+               modules/dbus/iface-sample.c modules/dbus/iface-sample.h \
+               modules/dbus/iface-stream.c modules/dbus/iface-stream.h \
+               modules/dbus/module-dbus-protocol.c
+module_dbus_protocol_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
+module_dbus_protocol_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_dbus_protocol_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS)
 
 # Native protocol
 
 module_native_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c
 module_native_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_NATIVE $(AM_CFLAGS)
 module_native_protocol_tcp_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_native_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-native.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_native_protocol_tcp_la_LIBADD = $(MODULE_LIBADD) libprotocol-native.la
 
 module_native_protocol_unix_la_SOURCES = modules/module-protocol-stub.c
 module_native_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_NATIVE $(AM_CFLAGS)
 module_native_protocol_unix_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_native_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-native.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_native_protocol_unix_la_LIBADD = $(MODULE_LIBADD) libprotocol-native.la
 
 module_native_protocol_fd_la_SOURCES = modules/module-native-protocol-fd.c
 module_native_protocol_fd_la_CFLAGS = $(AM_CFLAGS)
 module_native_protocol_fd_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_native_protocol_fd_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-native.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_native_protocol_fd_la_LIBADD = $(MODULE_LIBADD) libprotocol-native.la
 
 # EsounD protocol
 
+if HAVE_ESOUND
 module_esound_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c
 module_esound_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_ESOUND $(AM_CFLAGS)
 module_esound_protocol_tcp_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_esound_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-esound.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_esound_protocol_tcp_la_LIBADD = $(MODULE_LIBADD) libprotocol-esound.la
 
 module_esound_protocol_unix_la_SOURCES = modules/module-protocol-stub.c
 module_esound_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_ESOUND $(AM_CFLAGS)
 module_esound_protocol_unix_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_esound_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-esound.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_esound_protocol_unix_la_LIBADD = $(MODULE_LIBADD) libprotocol-esound.la
 
 module_esound_compat_spawnfd_la_SOURCES = modules/module-esound-compat-spawnfd.c
 module_esound_compat_spawnfd_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_esound_compat_spawnfd_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_esound_compat_spawnfd_la_LIBADD = $(MODULE_LIBADD)
 
 module_esound_compat_spawnpid_la_SOURCES = modules/module-esound-compat-spawnpid.c
 module_esound_compat_spawnpid_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_esound_compat_spawnpid_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_esound_compat_spawnpid_la_LIBADD = $(MODULE_LIBADD)
 
 module_esound_sink_la_SOURCES = modules/module-esound-sink.c
-module_esound_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_esound_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_esound_sink_la_LDFLAGS = $(MODULE_LDFLAGS) $(WINSOCK_LIBS)
+module_esound_sink_la_LIBADD = $(MODULE_LIBADD)
+endif
 
 # Pipes
 
 module_pipe_sink_la_SOURCES = modules/module-pipe-sink.c
 module_pipe_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_pipe_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_pipe_sink_la_LIBADD = $(MODULE_LIBADD)
 
 module_pipe_source_la_SOURCES = modules/module-pipe-source.c
 module_pipe_source_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_pipe_source_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_pipe_source_la_LIBADD = $(MODULE_LIBADD)
 
 # Fake sources/sinks
 
 module_sine_la_SOURCES = modules/module-sine.c
 module_sine_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_sine_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_sine_la_LIBADD = $(MODULE_LIBADD)
 
 module_null_sink_la_SOURCES = modules/module-null-sink.c
 module_null_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_null_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_null_sink_la_LIBADD = $(MODULE_LIBADD)
+
+module_null_source_la_SOURCES = modules/module-null-source.c
+module_null_source_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_null_source_la_LIBADD = $(MODULE_LIBADD)
 
 module_sine_source_la_SOURCES = modules/module-sine-source.c
-module_sine_source_la_LDFLAGS = -module -avoid-version
-module_sine_source_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_sine_source_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_sine_source_la_LIBADD = $(MODULE_LIBADD)
 
 # Couplings
 
 module_combine_la_SOURCES = modules/module-combine.c
 module_combine_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_combine_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_combine_la_LIBADD = $(MODULE_LIBADD)
+
+module_combine_sink_la_SOURCES = modules/module-combine-sink.c
+module_combine_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_combine_sink_la_LIBADD = $(MODULE_LIBADD)
+
+module_switch_on_connect_la_SOURCES = modules/module-switch-on-connect.c
+module_switch_on_connect_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_switch_on_connect_la_LIBADD = $(MODULE_LIBADD)
+
+module_switch_on_port_available_la_SOURCES = modules/module-switch-on-port-available.c
+module_switch_on_port_available_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_switch_on_port_available_la_LIBADD = $(MODULE_LIBADD)
+
+module_filter_apply_la_SOURCES = modules/module-filter-apply.c
+module_filter_apply_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_filter_apply_la_LIBADD = $(MODULE_LIBADD)
+
+module_filter_heuristics_la_SOURCES = modules/module-filter-heuristics.c
+module_filter_heuristics_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_filter_heuristics_la_LIBADD = $(MODULE_LIBADD)
 
 module_remap_sink_la_SOURCES = modules/module-remap-sink.c
 module_remap_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_remap_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_remap_sink_la_LIBADD = $(MODULE_LIBADD)
+
+module_remap_source_la_SOURCES = modules/module-remap-source.c
+module_remap_source_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_remap_source_la_LIBADD = $(MODULE_LIBADD)
 
 module_ladspa_sink_la_SOURCES = modules/module-ladspa-sink.c modules/ladspa.h
-module_ladspa_sink_la_CFLAGS = -DLADSPA_PATH=\"$(libdir)/ladspa:/usr/local/lib/ladspa:/usr/lib/ladspa:/usr/local/lib64/ladspa:/usr/lib64/ladspa\" $(AM_CFLAGS)
+module_ladspa_sink_la_CFLAGS = -DLADSPA_PATH=\"$(libdir)/ladspa:/usr/local/lib/ladspa:/usr/lib/ladspa:/usr/local/lib64/ladspa:/usr/lib64/ladspa\" $(AM_CFLAGS) $(SERVER_CFLAGS)
 module_ladspa_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_ladspa_sink_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_ladspa_sink_la_LIBADD = $(MODULE_LIBADD) $(LIBLTDL)
+
+if HAVE_DBUS
+module_ladspa_sink_la_CFLAGS += $(DBUS_CFLAGS)
+module_ladspa_sink_la_LIBADD += $(DBUS_LIBS)
+endif
+
+module_equalizer_sink_la_SOURCES = modules/module-equalizer-sink.c
+module_equalizer_sink_la_CFLAGS = $(AM_CFLAGS) $(SERVER_CFLAGS) $(DBUS_CFLAGS) $(FFTW_CFLAGS)
+module_equalizer_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_equalizer_sink_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) $(FFTW_LIBS)
 
 module_match_la_SOURCES = modules/module-match.c
 module_match_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_match_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_match_la_LIBADD = $(MODULE_LIBADD)
 
 module_tunnel_sink_la_SOURCES = modules/module-tunnel.c
 module_tunnel_sink_la_CFLAGS = -DTUNNEL_SINK=1 $(AM_CFLAGS)
 module_tunnel_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_tunnel_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_tunnel_sink_la_LIBADD = $(MODULE_LIBADD)
 
 module_tunnel_source_la_SOURCES = modules/module-tunnel.c
 module_tunnel_source_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_tunnel_source_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_tunnel_source_la_LIBADD = $(MODULE_LIBADD)
 
 module_loopback_la_SOURCES = modules/module-loopback.c
 module_loopback_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_loopback_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_loopback_la_LIBADD = $(MODULE_LIBADD)
 
 module_virtual_sink_la_SOURCES = modules/module-virtual-sink.c
+module_virtual_sink_la_CFLAGS = $(AM_CFLAGS) $(SERVER_CFLAGS)
 module_virtual_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_virtual_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_virtual_sink_la_LIBADD = $(MODULE_LIBADD)
 
 module_virtual_source_la_SOURCES = modules/module-virtual-source.c
+module_virtual_source_la_CFLAGS = $(AM_CFLAGS) $(SERVER_CFLAGS)
 module_virtual_source_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_virtual_source_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_virtual_source_la_LIBADD = $(MODULE_LIBADD)
+
+module_virtual_surround_sink_la_SOURCES = modules/module-virtual-surround-sink.c
+module_virtual_surround_sink_la_CFLAGS = $(AM_CFLAGS) $(SERVER_CFLAGS)
+module_virtual_surround_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_virtual_surround_sink_la_LIBADD = $(MODULE_LIBADD)
 
 # X11
 
 module_x11_bell_la_SOURCES = modules/x11/module-x11-bell.c
 module_x11_bell_la_CFLAGS = $(AM_CFLAGS) $(X11_CFLAGS)
 module_x11_bell_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_x11_bell_la_LIBADD = $(AM_LIBADD) $(X11_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_x11_bell_la_LIBADD = $(MODULE_LIBADD) $(X11_LIBS)
 
 module_x11_publish_la_SOURCES = modules/x11/module-x11-publish.c
 module_x11_publish_la_CFLAGS = $(AM_CFLAGS) $(X11_CFLAGS)
 module_x11_publish_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_x11_publish_la_LIBADD = $(AM_LIBADD) $(X11_LIBS) libprotocol-native.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_x11_publish_la_LIBADD = $(MODULE_LIBADD) libprotocol-native.la $(X11_LIBS)
 
 module_x11_xsmp_la_SOURCES = modules/x11/module-x11-xsmp.c
 module_x11_xsmp_la_CFLAGS = $(AM_CFLAGS) $(X11_CFLAGS)
 module_x11_xsmp_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_x11_xsmp_la_LIBADD = $(AM_LIBADD) $(X11_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_x11_xsmp_la_LIBADD = $(MODULE_LIBADD) $(X11_LIBS)
 
 module_x11_cork_request_la_SOURCES = modules/x11/module-x11-cork-request.c
 module_x11_cork_request_la_CFLAGS = $(AM_CFLAGS) $(X11_CFLAGS)
 module_x11_cork_request_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_x11_cork_request_la_LIBADD = $(AM_LIBADD) $(X11_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_x11_cork_request_la_LIBADD = $(MODULE_LIBADD) $(X11_LIBS)
 
 # OSS
 
 liboss_util_la_SOURCES = modules/oss/oss-util.c modules/oss/oss-util.h
 liboss_util_la_LDFLAGS = -avoid-version
-liboss_util_la_LIBADD = libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+liboss_util_la_LIBADD = $(MODULE_LIBADD)
 
 module_oss_la_SOURCES = modules/oss/module-oss.c
 module_oss_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_oss_la_LIBADD = $(AM_LIBADD) liboss-util.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_oss_la_LIBADD = $(MODULE_LIBADD) liboss-util.la
+
+# COREAUDIO
+
+module_coreaudio_detect_la_SOURCES = modules/macosx/module-coreaudio-detect.c
+module_coreaudio_detect_la_LDFLAGS = $(MODULE_LDFLAGS) \
+               -Wl,-framework -Wl,Cocoa -framework CoreAudio \
+               -Wl,-framework -Wl,AudioUnit -framework AudioUnit
+module_coreaudio_detect_la_LIBADD = $(MODULE_LIBADD)
+
+module_coreaudio_device_la_SOURCES = modules/macosx/module-coreaudio-device.c
+module_coreaudio_device_la_LDFLAGS = $(MODULE_LDFLAGS) \
+               -Wl,-framework -Wl,Cocoa -framework CoreAudio \
+               -Wl,-framework -Wl,AudioUnit -framework AudioUnit
+module_coreaudio_device_la_LIBADD = $(MODULE_LIBADD)
 
 # ALSA
 
-libalsa_util_la_SOURCES = modules/alsa/alsa-util.c modules/alsa/alsa-util.h modules/alsa/alsa-mixer.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
+libalsa_util_la_SOURCES = \
+               modules/alsa/alsa-util.c modules/alsa/alsa-util.h \
+               modules/alsa/alsa-ucm.c modules/alsa/alsa-ucm.h \
+               modules/alsa/alsa-mixer.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
 libalsa_util_la_LDFLAGS = -avoid-version
-libalsa_util_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-libalsa_util_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS)
-
-if HAVE_HAL
-libalsa_util_la_SOURCES += modules/hal-util.h modules/hal-util.c
-libalsa_util_la_LIBADD += $(HAL_LIBS)
-libalsa_util_la_CFLAGS += $(HAL_CFLAGS)
-endif
+libalsa_util_la_LIBADD = $(MODULE_LIBADD) $(ASOUNDLIB_LIBS)
+libalsa_util_la_CFLAGS = $(AM_CFLAGS) $(SERVER_CFLAGS) $(ASOUNDLIB_CFLAGS)
 
 if HAVE_UDEV
 libalsa_util_la_SOURCES += modules/udev-util.h modules/udev-util.c
@@ -1485,356 +1905,380 @@ endif
 
 module_alsa_sink_la_SOURCES = modules/alsa/module-alsa-sink.c
 module_alsa_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_alsa_sink_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_alsa_sink_la_LIBADD = $(MODULE_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la
 module_alsa_sink_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS)
 
 module_alsa_source_la_SOURCES = modules/alsa/module-alsa-source.c
 module_alsa_source_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_alsa_source_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_alsa_source_la_LIBADD = $(MODULE_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la
 module_alsa_source_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS)
 
 module_alsa_card_la_SOURCES = modules/alsa/module-alsa-card.c
 module_alsa_card_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_alsa_card_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_alsa_card_la_LIBADD = $(MODULE_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la
 module_alsa_card_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS)
 
 # Solaris
 
 module_solaris_la_SOURCES = modules/module-solaris.c
 module_solaris_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_solaris_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_solaris_la_LIBADD = $(MODULE_LIBADD)
 
 # Avahi
 
 module_zeroconf_publish_la_SOURCES = modules/module-zeroconf-publish.c
 module_zeroconf_publish_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_zeroconf_publish_la_LIBADD = $(AM_LIBADD) $(AVAHI_LIBS) libavahi-wrap.la libprotocol-native.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_zeroconf_publish_la_LIBADD = $(MODULE_LIBADD) $(AVAHI_LIBS) libavahi-wrap.la libprotocol-native.la
 module_zeroconf_publish_la_CFLAGS = $(AM_CFLAGS) $(AVAHI_CFLAGS)
 
 module_zeroconf_discover_la_SOURCES = modules/module-zeroconf-discover.c
 module_zeroconf_discover_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_zeroconf_discover_la_LIBADD = $(AM_LIBADD) $(AVAHI_LIBS) libavahi-wrap.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_zeroconf_discover_la_LIBADD = $(MODULE_LIBADD) $(AVAHI_LIBS) libavahi-wrap.la
 module_zeroconf_discover_la_CFLAGS = $(AM_CFLAGS) $(AVAHI_CFLAGS)
 
+# Bonjour
+
+module_bonjour_publish_la_SOURCES = modules/macosx/module-bonjour-publish.c
+module_bonjour_publish_la_LDFLAGS = $(MODULE_LDFLAGS) \
+                       -Wl,-framework -Wl,CoreFoundation -framework CoreFoundation
+module_bonjour_publish_la_LIBADD = $(MODULE_LIBADD) libprotocol-native.la
+
 # LIRC
 
 module_lirc_la_SOURCES = modules/module-lirc.c
 module_lirc_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_lirc_la_LIBADD = $(AM_LIBADD) $(LIRC_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_lirc_la_LIBADD = $(MODULE_LIBADD) $(LIRC_LIBS)
 module_lirc_la_CFLAGS = $(AM_CFLAGS) $(LIRC_CFLAGS)
 
+
+# Xen PV driver
+
+module_xenpv_sink_la_SOURCES = modules/xen/module-xenpv-sink.c modules/xen/gntalloc.h modules/xen/gntdev.h
+module_xenpv_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_xenpv_sink_la_LIBADD = $(MODULE_LIBADD) $(XEN_LIBS)
+module_xenpv_sink_la_CFLAGS = $(AM_CFLAGS) $(XEN_CFLAGS) -I$(top_srcdir)/src/modules/xen
+
+
 # Linux evdev
 
 module_mmkbd_evdev_la_SOURCES = modules/module-mmkbd-evdev.c
 module_mmkbd_evdev_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_mmkbd_evdev_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_mmkbd_evdev_la_LIBADD = $(MODULE_LIBADD)
 module_mmkbd_evdev_la_CFLAGS = $(AM_CFLAGS)
 
 # Windows waveout
-
-#module_waveout_la_SOURCES = modules/module-waveout.c
-#module_waveout_la_LDFLAGS = $(MODULE_LDFLAGS)
-#module_waveout_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la -lwinmm libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-#module_waveout_la_CFLAGS = $(AM_CFLAGS)
+module_waveout_la_SOURCES = modules/module-waveout.c
+module_waveout_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_waveout_la_LIBADD = $(MODULE_LIBADD) -lwinmm
+module_waveout_la_CFLAGS = $(AM_CFLAGS)
 
 # Hardware autodetection module
 module_detect_la_SOURCES = modules/module-detect.c
 module_detect_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_detect_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_detect_la_LIBADD = $(MODULE_LIBADD)
 module_detect_la_CFLAGS = $(AM_CFLAGS)
 
 # Volume restore module
 module_volume_restore_la_SOURCES = modules/module-volume-restore.c
 module_volume_restore_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_volume_restore_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_volume_restore_la_LIBADD = $(MODULE_LIBADD)
 module_volume_restore_la_CFLAGS = $(AM_CFLAGS)
 
 # Position event sounds in space
 module_position_event_sounds_la_SOURCES = modules/module-position-event-sounds.c
 module_position_event_sounds_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_position_event_sounds_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_position_event_sounds_la_LIBADD = $(MODULE_LIBADD)
 module_position_event_sounds_la_CFLAGS = $(AM_CFLAGS)
 
+# Ducking effect based on stream roles
+module_role_ducking_la_SOURCES = modules/module-role-ducking.c
+module_role_ducking_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_role_ducking_la_LIBADD = $(MODULE_LIBADD)
+module_role_ducking_la_CFLAGS = $(AM_CFLAGS)
+
 # Augment properties from XDG .desktop files
 module_augment_properties_la_SOURCES = modules/module-augment-properties.c
 module_augment_properties_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_augment_properties_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_augment_properties_la_LIBADD = $(MODULE_LIBADD)
 #module_augment_properties_la_CFLAGS = $(AM_CFLAGS) -DDESKTOPFILEDIR=\"$(datadir)/applications\"
 module_augment_properties_la_CFLAGS = $(AM_CFLAGS) -DDESKTOPFILEDIR=\"/usr/share/applications\"
 
-# Cork music streams while a phone stream is active
-module_cork_music_on_phone_la_SOURCES = modules/module-cork-music-on-phone.c
-module_cork_music_on_phone_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_cork_music_on_phone_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-module_cork_music_on_phone_la_CFLAGS = $(AM_CFLAGS)
+# Cork certain streams while others are active (e.g. cork music when phone streams appear)
+module_role_cork_la_SOURCES = modules/module-role-cork.c
+module_role_cork_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_role_cork_la_LIBADD = $(MODULE_LIBADD)
+module_role_cork_la_CFLAGS = $(AM_CFLAGS)
 
 # Device description restore module
 module_device_manager_la_SOURCES = modules/module-device-manager.c
 module_device_manager_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_device_manager_la_LIBADD = $(AM_LIBADD) libprotocol-native.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_device_manager_la_LIBADD = $(MODULE_LIBADD) libprotocol-native.la
 module_device_manager_la_CFLAGS = $(AM_CFLAGS)
 
 # Device volume/muted restore module
 module_device_restore_la_SOURCES = modules/module-device-restore.c
 module_device_restore_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_device_restore_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_device_restore_la_LIBADD = $(MODULE_LIBADD) libprotocol-native.la
 module_device_restore_la_CFLAGS = $(AM_CFLAGS)
 
+if HAVE_DBUS
+module_device_restore_la_LIBADD += $(DBUS_LIBS)
+module_device_restore_la_CFLAGS += $(DBUS_CFLAGS)
+endif
+
 # 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 = $(AM_LIBADD) libprotocol-native.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_stream_restore_la_LIBADD = $(MODULE_LIBADD) libprotocol-native.la
 module_stream_restore_la_CFLAGS = $(AM_CFLAGS)
 
+if HAVE_DBUS
+module_stream_restore_la_LIBADD += $(DBUS_LIBS)
+module_stream_restore_la_CFLAGS += $(DBUS_CFLAGS)
+endif
+
 # Card profile restore module
 module_card_restore_la_SOURCES = modules/module-card-restore.c
 module_card_restore_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_card_restore_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_card_restore_la_LIBADD = $(MODULE_LIBADD)
 module_card_restore_la_CFLAGS = $(AM_CFLAGS)
 
 # Default sink/source restore module
 module_default_device_restore_la_SOURCES = modules/module-default-device-restore.c
 module_default_device_restore_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_default_device_restore_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_default_device_restore_la_LIBADD = $(MODULE_LIBADD)
 module_default_device_restore_la_CFLAGS = $(AM_CFLAGS)
 
 # Always Sink module
 module_always_sink_la_SOURCES = modules/module-always-sink.c
 module_always_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_always_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_always_sink_la_LIBADD = $(MODULE_LIBADD)
 module_always_sink_la_CFLAGS = $(AM_CFLAGS)
 
 # Rescue streams module
 module_rescue_streams_la_SOURCES = modules/module-rescue-streams.c
 module_rescue_streams_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_rescue_streams_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_rescue_streams_la_LIBADD = $(MODULE_LIBADD)
 module_rescue_streams_la_CFLAGS = $(AM_CFLAGS)
 
 # Automatically move streams to devices that are intended for their roles
 module_intended_roles_la_SOURCES = modules/module-intended-roles.c
 module_intended_roles_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_intended_roles_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_intended_roles_la_LIBADD = $(MODULE_LIBADD)
 module_intended_roles_la_CFLAGS = $(AM_CFLAGS)
 
 # Suspend-on-idle module
-module_suspend_on_idle_la_SOURCES = modules/module-suspend-on-idle.c
+module_suspend_on_idle_la_SOURCES = modules/module-suspend-on-idle.c modules/pm-util.c
 module_suspend_on_idle_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_suspend_on_idle_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_suspend_on_idle_la_LIBADD = $(MODULE_LIBADD) libprotocol-native.la libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
 module_suspend_on_idle_la_CFLAGS = $(AM_CFLAGS)
 
-module_suspend_on_idle_la_LDFLAGS += $(PMAPI_LIBS)
-module_suspend_on_idle_la_CFLAGS += $(PMAPI_CFLAGS)
+module_suspend_on_idle_la_LDFLAGS += $(DBUS_LIBS)
+module_suspend_on_idle_la_CFLAGS += $(DBUS_CFLAGS)
 
 # echo-cancel module
-ORC_SOURCE=modules/echo-cancel/adrian-aec-orc
-include $(top_srcdir)/build/orc.mak
-module_echo_cancel_la_SOURCES = modules/echo-cancel/module-echo-cancel.c modules/echo-cancel/echo-cancel.h \
-                               modules/echo-cancel/speex.c \
-                               modules/echo-cancel/adrian-aec.c modules/echo-cancel/adrian-aec.h \
-                               modules/echo-cancel/adrian.c modules/echo-cancel/adrian.h \
-                               $(ORC_SOURCE).orc
-nodist_module_echo_cancel_la_SOURCES = $(ORC_NODIST_SOURCES)
+module_echo_cancel_la_SOURCES = \
+               modules/echo-cancel/module-echo-cancel.c \
+               modules/echo-cancel/null.c \
+               modules/echo-cancel/echo-cancel.h
 module_echo_cancel_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_echo_cancel_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la $(LIBSPEEX_LIBS) $(ORC_LIBS)
-module_echo_cancel_la_CFLAGS = $(AM_CFLAGS) $(LIBSPEEX_CFLAGS) $(ORC_CFLAGS) -DDISABLE_ORC
+module_echo_cancel_la_LIBADD = $(MODULE_LIBADD) libprotocol-native.la libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
+module_echo_cancel_la_CFLAGS = $(AM_CFLAGS) $(SERVER_CFLAGS)
+if HAVE_ADRIAN_EC
+module_echo_cancel_la_SOURCES += \
+               modules/echo-cancel/adrian-aec.c modules/echo-cancel/adrian-aec.h \
+               modules/echo-cancel/adrian.c modules/echo-cancel/adrian.h
+module_echo_cancel_la_CFLAGS += -DHAVE_ADRIAN_EC=1
+if HAVE_ORC
+ORC_SOURCE += modules/echo-cancel/adrian-aec
+nodist_module_echo_cancel_la_SOURCES = \
+               modules/echo-cancel/adrian-aec-orc-gen.c \
+               modules/echo-cancel/adrian-aec-orc-gen.h
+module_echo_cancel_la_LIBADD += $(ORC_LIBS)
+module_echo_cancel_la_CFLAGS += $(ORC_CFLAGS) -I$(top_builddir)/src/modules/echo-cancel
+endif
+endif
+if HAVE_SPEEX
+module_echo_cancel_la_LIBADD += $(LIBSPEEX_LIBS)
+module_echo_cancel_la_CFLAGS += $(LIBSPEEX_CFLAGS)
+module_echo_cancel_la_SOURCES += modules/echo-cancel/speex.c
+endif
+if HAVE_WEBRTC
+# The webrtc code is split off into a helper library to avoid having automake
+# link module-echo-cancel with C++ (which it does if there are any C++ deps,
+# even conditional ones).
+
+libwebrtc_util_la_SOURCES = modules/echo-cancel/webrtc.cc
+libwebrtc_util_la_CXXFLAGS = $(AM_CXXFLAGS) $(SERVER_CFLAGS) $(WEBRTC_CFLAGS) -DHAVE_WEBRTC=1
+libwebrtc_util_la_LIBADD = $(WEBRTC_LIBS)
+libwebrtc_util_la_LDFLAGS = -avoid-version
+
+module_echo_cancel_la_CFLAGS += -DHAVE_WEBRTC=1
+module_echo_cancel_la_LIBADD += libwebrtc-util.la
+endif
 
 # RTP modules
 module_rtp_send_la_SOURCES = modules/rtp/module-rtp-send.c
 module_rtp_send_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_rtp_send_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la librtp.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_rtp_send_la_LIBADD = $(MODULE_LIBADD) librtp.la
 module_rtp_send_la_CFLAGS = $(AM_CFLAGS)
 
 module_rtp_recv_la_SOURCES = modules/rtp/module-rtp-recv.c
 module_rtp_recv_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_rtp_recv_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la librtp.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_rtp_recv_la_LIBADD = $(MODULE_LIBADD) librtp.la
 module_rtp_recv_la_CFLAGS = $(AM_CFLAGS)
 
 # JACK
 
+module_jackdbus_detect_la_SOURCES = modules/jack/module-jackdbus-detect.c
+module_jackdbus_detect_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_jackdbus_detect_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) $(JACK_LIBS)
+module_jackdbus_detect_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) $(JACK_CFLAGS)
+
 module_jack_sink_la_SOURCES = modules/jack/module-jack-sink.c
 module_jack_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_jack_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la $(JACK_LIBS) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_jack_sink_la_LIBADD = $(MODULE_LIBADD) $(JACK_LIBS)
 module_jack_sink_la_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS)
 
 module_jack_source_la_SOURCES = modules/jack/module-jack-source.c
 module_jack_source_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_jack_source_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la $(JACK_LIBS) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_jack_source_la_LIBADD = $(MODULE_LIBADD) $(JACK_LIBS)
 module_jack_source_la_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS)
 
-if HAVE_HAL_COMPAT
 module_hal_detect_la_SOURCES = modules/module-hal-detect-compat.c
-module_hal_detect_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_hal_detect_la_LIBADD = $(MODULE_LIBADD)
 module_hal_detect_la_CFLAGS = $(AM_CFLAGS)
-else
-module_hal_detect_la_SOURCES = modules/module-hal-detect.c
-module_hal_detect_la_LIBADD = $(AM_LIBADD) $(HAL_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-module_hal_detect_la_CFLAGS = $(AM_CFLAGS) $(HAL_CFLAGS)
-endif
 module_hal_detect_la_LDFLAGS = $(MODULE_LDFLAGS)
 
 module_udev_detect_la_SOURCES = modules/module-udev-detect.c
 module_udev_detect_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_udev_detect_la_LIBADD = $(AM_LIBADD) $(UDEV_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_udev_detect_la_LIBADD = $(MODULE_LIBADD) $(UDEV_LIBS)
 module_udev_detect_la_CFLAGS = $(AM_CFLAGS) $(UDEV_CFLAGS)
 
 module_console_kit_la_SOURCES = modules/module-console-kit.c
 module_console_kit_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_console_kit_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_console_kit_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS)
 module_console_kit_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
 
+module_systemd_login_la_SOURCES = modules/module-systemd-login.c
+module_systemd_login_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_systemd_login_la_LIBADD = $(MODULE_LIBADD) $(SYSTEMD_LIBS)
+module_systemd_login_la_CFLAGS = $(AM_CFLAGS) $(SYSTEMD_CFLAGS)
+
 # GConf support
 module_gconf_la_SOURCES = modules/gconf/module-gconf.c
 module_gconf_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_gconf_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_gconf_la_LIBADD = $(MODULE_LIBADD)
 module_gconf_la_CFLAGS = $(AM_CFLAGS) -DPA_GCONF_HELPER=\"$(pulselibexecdir)/gconf-helper\"
 
 gconf_helper_SOURCES = modules/gconf/gconf-helper.c
-gconf_helper_LDADD = $(AM_LDADD) $(GCONF_LIBS) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la libpulsecore-@PA_MAJORMINORMICRO@.la
+gconf_helper_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la $(GCONF_LIBS)
 gconf_helper_CFLAGS = $(AM_CFLAGS) $(GCONF_CFLAGS)
 gconf_helper_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
-# Bluetooth proximity
-module_bluetooth_proximity_la_SOURCES = modules/bluetooth/module-bluetooth-proximity.c
-module_bluetooth_proximity_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_bluetooth_proximity_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-module_bluetooth_proximity_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) -DPA_BT_PROXIMITY_HELPER=\"$(pulselibexecdir)/proximity-helper\"
+# Bluetooth policy
+module_bluetooth_policy_la_SOURCES = modules/bluetooth/module-bluetooth-policy.c
+module_bluetooth_policy_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_bluetooth_policy_la_LIBADD = $(MODULE_LIBADD)
+module_bluetooth_policy_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
 
-proximity_helper_SOURCES = modules/bluetooth/proximity-helper.c
-proximity_helper_LDADD = $(AM_LDADD) $(BLUEZ_LIBS)
-proximity_helper_CFLAGS = $(AM_CFLAGS) $(BLUEZ_CFLAGS)
-proximity_helper_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
-
-# Bluetooth sink / source
+# Bluetooth discover
 module_bluetooth_discover_la_SOURCES = modules/bluetooth/module-bluetooth-discover.c
 module_bluetooth_discover_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_bluetooth_discover_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libbluetooth-util.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-if HAVE_BT_A2DP_APTX
-module_bluetooth_discover_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) -DUSE_APTX
-else
-module_bluetooth_discover_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
-endif
-
-libbluetooth_sbc_la_SOURCES = \
-               modules/bluetooth/sbc/sbc.c modules/bluetooth/sbc/sbc.h \
-               modules/bluetooth/sbc/sbc_primitives.c modules/bluetooth/sbc/sbc_primitives.h \
-               modules/bluetooth/sbc/sbc_primitives_armv6.h modules/bluetooth/sbc/sbc_primitives_armv6.c \
-               modules/bluetooth/sbc/sbc_primitives_iwmmxt.h modules/bluetooth/sbc/sbc_primitives_iwmmxt.c \
-               modules/bluetooth/sbc/sbc_primitives_mmx.c modules/bluetooth/sbc/sbc_primitives_mmx.h \
-               modules/bluetooth/sbc/sbc_primitives_neon.c modules/bluetooth/sbc/sbc_primitives_neon.h \
-               modules/bluetooth/sbc/sbc_math.h \
-               modules/bluetooth/sbc/sbc_tables.h
-libbluetooth_sbc_la_LDFLAGS = -avoid-version
-libbluetooth_sbc_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-libbluetooth_sbc_la_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/src/modules/bluetooth/sbc
-BLUETOOTH_SBC_FILES = $(subst modules/bluetooth/,,$(libbluetooth_sbc_la_SOURCES))
-
-libbluetooth_ipc_la_SOURCES = \
-              modules/bluetooth/a2dp-codecs.h \
-               modules/bluetooth/ipc.c modules/bluetooth/ipc.h
-libbluetooth_ipc_la_LDFLAGS = -avoid-version
-libbluetooth_ipc_la_LIBADD = $(AM_LIBADD)libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-libbluetooth_ipc_la_CFLAGS = $(AM_CFLAGS)
-BLUETOOTH_IPC_FILES = $(subst modules/bluetooth/,,$(libbluetooth_ipc_la_SOURCES)) rtp.h
-
-libbluetooth_util_la_SOURCES = modules/bluetooth/bluetooth-util.c modules/bluetooth/bluetooth-util.h
-libbluetooth_util_la_LDFLAGS = -avoid-version
-libbluetooth_util_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-libbluetooth_util_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
-
-module_bluetooth_device_la_SOURCES = modules/bluetooth/module-bluetooth-device.c modules/bluetooth/rtp.h
-if HAVE_BT_A2DP_APTX
-module_bluetooth_device_la_LDFLAGS = $(MODULE_LDFLAGS) -Lmodules/bluetooth -lbtaptx-armv6L
-module_bluetooth_device_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) -DUSE_APTX
-
-bluetooth_aptxdir=$(modlibexecdir)
-bluetooth_aptx_DATA = modules/bluetooth/libbtaptx-armv6L.so
-else
-module_bluetooth_device_la_LDFLAGS = $(MODULE_LDFLAGS) -Lmodules/bluetooth 
-module_bluetooth_device_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) -I$(top_srcdir)/src/modules/bluetooth/sbc
-endif
-module_bluetooth_device_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libbluetooth-util.la libbluetooth-ipc.la libbluetooth-sbc.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_bluetooth_discover_la_LIBADD = $(MODULE_LIBADD)
+module_bluetooth_discover_la_CFLAGS = $(AM_CFLAGS)
+
+# Bluetooth BlueZ 4 sink / source
+module_bluez4_discover_la_SOURCES = modules/bluetooth/module-bluez4-discover.c
+module_bluez4_discover_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_bluez4_discover_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) libbluez4-util.la
+module_bluez4_discover_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
+
+libbluez4_util_la_SOURCES = \
+               modules/bluetooth/a2dp-codecs.h \
+               modules/bluetooth/bluez4-util.c \
+               modules/bluetooth/bluez4-util.h
+libbluez4_util_la_LDFLAGS = -avoid-version
+libbluez4_util_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS)
+libbluez4_util_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
+
+module_bluez4_device_la_SOURCES = modules/bluetooth/module-bluez4-device.c modules/bluetooth/rtp.h
+module_bluez4_device_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_bluez4_device_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) $(SBC_LIBS) libbluez4-util.la
+module_bluez4_device_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) $(SBC_CFLAGS)
+
+# Bluetooth BlueZ 5 sink / source
+libbluez5_util_la_SOURCES = \
+               modules/bluetooth/bluez5-util.c \
+               modules/bluetooth/bluez5-util.h \
+               modules/bluetooth/a2dp-codecs.h \
+               modules/bluetooth/hfaudioagent.h
+libbluez5_util_la_LDFLAGS = -avoid-version
+libbluez5_util_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS)
+libbluez5_util_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
+
+module_bluez5_discover_la_SOURCES = modules/bluetooth/module-bluez5-discover.c
+module_bluez5_discover_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_bluez5_discover_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) libbluez5-util.la
+module_bluez5_discover_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
+
+module_bluez5_device_la_SOURCES = modules/bluetooth/module-bluez5-device.c
+module_bluez5_device_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_bluez5_device_la_LIBADD = $(MODULE_LIBADD) $(SBC_LIBS) libbluez5-util.la
+module_bluez5_device_la_CFLAGS = $(AM_CFLAGS) $(SBC_CFLAGS)
 
 # Apple Airtunes/RAOP
 module_raop_sink_la_SOURCES = modules/raop/module-raop-sink.c
 module_raop_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_raop_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la librtp.la libraop.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_raop_sink_la_LIBADD = $(MODULE_LIBADD) librtp.la libraop.la
+module_raop_sink_la_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/src/modules/rtp
 
 module_raop_discover_la_SOURCES = modules/raop/module-raop-discover.c
 module_raop_discover_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_raop_discover_la_LIBADD = $(AM_LIBADD) $(AVAHI_LIBS) libavahi-wrap.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_raop_discover_la_LIBADD = $(MODULE_LIBADD) $(AVAHI_LIBS) libavahi-wrap.la
 module_raop_discover_la_CFLAGS = $(AM_CFLAGS) $(AVAHI_CFLAGS)
 
 # Rygel
 module_rygel_media_server_la_SOURCES = modules/module-rygel-media-server.c
 module_rygel_media_server_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_rygel_media_server_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la libprotocol-http.la
+module_rygel_media_server_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) libprotocol-http.la
 module_rygel_media_server_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
 
 module_policy_la_SOURCES = modules/module-policy.c
 module_policy_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_policy_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) $(VCONF_LIBS) libprotocol-native.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-module_policy_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) $(VCONF_CFLAGS)
+module_policy_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) $(VCONF_LIBS) $(INIPARSER_LIBS) $(ASOUNDLIB_LIBS) libprotocol-native.la libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
+module_policy_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) $(VCONF_CFLAGS) $(INIPARSER_CFLAGS) $(ASOUNDLIB_CFLAGS)
+
+module_stream_mgr_la_SOURCES = modules/module-stream-mgr.c
+module_stream_mgr_la_LDFLAGS = $(MODULE_LDFLAGS)
+module_stream_mgr_la_LIBADD = $(MODULE_LIBADD) $(AM_LIBADD) $(DBUS_LIBS)
+module_stream_mgr_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
 
 ###################################
 #        Some minor stuff         #
 ###################################
 
-CLEANFILES = esdcompat client.conf default.pa system.pa daemon.conf start-pulseaudio-x11 start-pulseaudio-kde daemon/pulseaudio.desktop daemon/pulseaudio-kde.desktop
-
-esdcompat: daemon/esdcompat.in Makefile
-       sed -e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \
-               -e 's,@PACKAGE_NAME\@,$(PACKAGE_NAME),g' \
-               -e 's,@PA_BINARY\@,$(PA_BINARY),g' < $< > $@
-       chmod +x esdcompat
-
-start-pulseaudio-x11: daemon/start-pulseaudio-x11.in Makefile
-       sed -e 's,@PA_BINARY\@,$(PA_BINARY),g' \
-               -e 's,@PACTL_BINARY\@,$(bindir)/pactl,g' < $< > $@
-       chmod +x start-pulseaudio-x11
-
-start-pulseaudio-kde: daemon/start-pulseaudio-kde.in Makefile
-       sed -e 's,@PA_BINARY\@,$(PA_BINARY),g' \
-               -e 's,@PACTL_BINARY\@,$(bindir)/pactl,g' < $< > $@
-       chmod +x start-pulseaudio-kde
-
-client.conf: pulse/client.conf.in Makefile
-       sed -e 's,@PA_BINARY\@,$(PA_BINARY),g' < $< > $@
+CLEANFILES += daemon/pulseaudio.desktop daemon/pulseaudio-kde.desktop
+DISTCLEANFILES = esdcompat client.conf default.pa system.pa daemon.conf start-pulseaudio-x11 start-pulseaudio-kde
 
 if OS_IS_WIN32
-default.pa: daemon/default.pa.win32
-       cp $< $@
-system.pa: daemon/default.pa.win32
-       cp $< $@
+SYMLINK_PROGRAM=cd $(DESTDIR)$(bindir) && cp
 else
-default.pa: daemon/default.pa.in Makefile
-       sed -e 's,@PA_BINARY\@,$(PA_BINARY),g' \
-            -e 's,@PA_DLSEARCHPATH\@,$(modlibexecdir),g' \
-           -e 's,@PA_SOEXT\@,.so,g' < $< > $@
-system.pa: daemon/system.pa.in Makefile
-       sed -e 's,@PA_BINARY\@,$(PA_BINARY),g' \
-            -e 's,@PA_DLSEARCHPATH\@,$(modlibexecdir),g' \
-           -e 's,@PA_SOEXT\@,.so,g' < $< > $@
+SYMLINK_PROGRAM=ln -sf
 endif
-
-daemon.conf: daemon/daemon.conf.in Makefile
-       sed -e 's,@PA_DLSEARCHPATH\@,$(modlibexecdir),g' \
-               -e 's,@PA_DEFAULT_CONFIG_FILE\@,$(DEFAULT_CONFIG_DIR),g' < $< > $@
-
 install-exec-hook:
-       -chown root $(DESTDIR)$(pulselibexecdir)/proximity-helper
-       -chmod u+s $(DESTDIR)$(pulselibexecdir)/proximity-helper
-       ln -sf pacat $(DESTDIR)$(bindir)/parec
-       ln -sf pacat $(DESTDIR)$(bindir)/pamon
-       ln -sf pacat $(DESTDIR)$(bindir)/paplay
-       ln -sf pacat $(DESTDIR)$(bindir)/parecord
+       $(SYMLINK_PROGRAM) pacat$(EXEEXT) $(DESTDIR)$(bindir)/parec$(EXEEXT)
+       $(SYMLINK_PROGRAM) pacat$(EXEEXT) $(DESTDIR)$(bindir)/pamon$(EXEEXT)
+       $(SYMLINK_PROGRAM) pacat$(EXEEXT) $(DESTDIR)$(bindir)/paplay$(EXEEXT)
+       $(SYMLINK_PROGRAM) pacat$(EXEEXT) $(DESTDIR)$(bindir)/parecord$(EXEEXT)
        rm -f $(DESTDIR)$(libdir)/libpulsedsp.la
        rm -f $(DESTDIR)$(modlibexecdir)/*.la
 
 uninstall-hook:
-       rm -f $(DESTDIR)$(bindir)/parec
-       rm -f $(DESTDIR)$(bindir)/pamon
-       rm -f $(DESTDIR)$(bindir)/paplay
-       rm -f $(DESTDIR)$(bindir)/parecord
+       rm -f $(DESTDIR)$(bindir)/parec$(EXEEXT)
+       rm -f $(DESTDIR)$(bindir)/pamon$(EXEEXT)
+       rm -f $(DESTDIR)$(bindir)/paplay$(EXEEXT)
+       rm -f $(DESTDIR)$(bindir)/parecord$(EXEEXT)
        rm -f $(DESTDIR)$(libdir)/libpulsedsp.*
        rm -f $(DESTDIR)$(modlibexecdir)/*.so
 
@@ -1844,25 +2288,14 @@ massif: pulseaudio
 update-ffmpeg:
        wget -O pulsecore/ffmpeg/resample2.c http://svn.mplayerhq.hu/ffmpeg/trunk/libavcodec/resample2.c?view=co
 
-# We get things twice here, because sometimes gitweb will us just give a "Generating..." otherwise.
-update-sbc:
-       for i in $(BLUETOOTH_SBC_FILES) ; do \
-               wget -O /dev/null http://git.kernel.org/\?p=bluetooth/bluez.git\;a=blob_plain\;f=sbc/$$i ; \
-               wget -O modules/bluetooth/$$i http://git.kernel.org/\?p=bluetooth/bluez.git\;a=blob_plain\;f=sbc/$$i ; \
-       done
-       for i in $(BLUETOOTH_IPC_FILES); do \
-               wget -O /dev/null http://git.kernel.org/\?p=bluetooth/bluez.git\;a=blob_plain\;f=audio/$$i ; \
-               wget -O modules/bluetooth/$$i http://git.kernel.org/\?p=bluetooth/bluez.git\;a=blob_plain\;f=audio/$$i ; \
-       done
-
 update-reserve:
        for i in reserve.c reserve.h reserve-monitor.c reserve-monitor.h ; do \
-               wget -O modules/$$i http://git.0pointer.de/\?p=reserve.git\;a=blob_plain\;f=$$i\;hb=master ; \
+               wget -O $(top_srcdir)/src/modules/$$i http://git.0pointer.de/\?p=reserve.git\;a=blob_plain\;f=$$i\;hb=master ; \
        done
 
 update-rtkit:
        for i in rtkit.c rtkit.h ; do \
-               wget -O pulsecore/$$i http://git.0pointer.de/\?p=rtkit.git\;a=blob_plain\;f=$$i\;hb=master ; \
+               wget -O $(top_srcdir)/src/pulsecore/$$i http://git.0pointer.de/\?p=rtkit.git\;a=blob_plain\;f=$$i\;hb=master ; \
        done
 
 # Automatically generate linker version script. We use the same one for all public .sos
@@ -1874,6 +2307,43 @@ update-map-file:
          echo "*;" ; \
          echo "};" ) > $(srcdir)/map-file
 
-update-all: update-ffmpeg update-sbc update-map-file
+update-all: update-ffmpeg update-map-file
+
+# Force installation order of libraries. libtool relinks on install time, in
+# which case libpulsecommon has to be installed before others, but the padsp
+# preload library has to be done after the normal libraries (e.g. libpulse)
+# ...
+# Unfortunately automake behaviour means that rules without commands also
+# override build-in rules, so it's not trivial to add dependencies.
+# See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=7328 for the workaround
+# ...
+# Isn't libtool/autotools fun!
+
+installlibLTLIBRARIES = install-libLTLIBRARIES
+$(installlibLTLIBRARIES): install-pkglibLTLIBRARIES
+
+installmodlibexecLTLIBRARIES = install-modlibexecLTLIBRARIES
+$(installmodlibexecLTLIBRARIES): install-pkglibLTLIBRARIES
+
+installpadsplibLTLIBRARIES = install-padsplibLTLIBRARIES
+$(installpadsplibLTLIBRARIES): install-libLTLIBRARIES
+
+if HAVE_GCOV
+coverage:
+       @echo ""
+       @echo "Don't forget to run 'make check' before generating coverage stats."
+       @echo ""
+       lcov --capture --directory . --output-file $(builddir)/gcov-all.info
+       -rm -r $(builddir)/coverage
+       genhtml --output-directory $(builddir)/coverage gcov-all.info
+       @echo ""
+       @echo "Coverage data now available at: $(abs_builddir)/coverage/index.html"
+else
+coverage:
+       @echo ""
+       @echo "To generate coverage stats, rerun configure with '--enable-gcov',"
+       @echo "and don't forget to disable it again for regular builds."
+       @echo ""
+endif
 
-.PHONY: utils/padsp massif update-all update-ffmpeg update-sbc update-map-file
+.PHONY: massif update-all update-ffmpeg update-map-file coverage
diff --git a/src/daemon/.gitignore b/src/daemon/.gitignore
new file mode 100644 (file)
index 0000000..54e4299
--- /dev/null
@@ -0,0 +1,3 @@
+org.pulseaudio.policy
+pulseaudio.desktop
+pulseaudio-kde.desktop
index 76b62e0..36b76a9 100644 (file)
 
 #include <unistd.h>
 #include <errno.h>
-#include <string.h>
 #include <sys/types.h>
 
-#include <pulse/i18n.h>
-
+#include <pulsecore/i18n.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/core-error.h>
 #include <pulsecore/log.h>
-#include <pulsecore/core-util.h>
 
 #ifdef HAVE_SYS_CAPABILITY_H
 #include <sys/capability.h>
 #endif
 
-#ifdef HAVE_SYS_PRCTL_H
-#include <sys/prctl.h>
-#endif
-
 #include "caps.h"
 
 /* Glibc <= 2.2 has broken unistd.h */
@@ -82,17 +74,20 @@ void pa_drop_root(void) {
     pa_assert_se(getegid() == gid);
 #endif
 
-#ifdef HAVE_SYS_PRCTL_H
-    pa_assert_se(prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) == 0);
-#endif
+    if (uid != 0)
+        pa_drop_caps();
+}
 
+void pa_drop_caps(void) {
 #ifdef HAVE_SYS_CAPABILITY_H
-    if (uid != 0) {
-        cap_t caps;
-        pa_assert_se(caps = cap_init());
-        pa_assert_se(cap_clear(caps) == 0);
-        pa_assert_se(cap_set_proc(caps) == 0);
-        pa_assert_se(cap_free(caps) == 0);
-    }
+    cap_t caps;
+    pa_assert_se(caps = cap_init());
+    pa_assert_se(cap_clear(caps) == 0);
+    pa_assert_se(cap_set_proc(caps) == 0);
+    pa_assert_se(cap_free(caps) == 0);
+#else
+    pa_log_warn("Normally all extra capabilities would be dropped now, but "
+                "that's impossible because this Pulseaudio was built without "
+                "libcap support.");
 #endif
 }
index 5d0ee62..e9cd7cb 100644 (file)
@@ -26,4 +26,6 @@
 
 void pa_drop_root(void);
 
+void pa_drop_caps(void);
+
 #endif
index f6cdcdc..a6ceb8b 100644 (file)
 #include <config.h>
 #endif
 
-#include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <getopt.h>
-#include <sys/stat.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/i18n.h>
 #include <pulse/util.h>
 
 #include <pulsecore/core-util.h>
+#include <pulsecore/i18n.h>
 #include <pulsecore/strbuf.h>
 #include <pulsecore/macro.h>
 
@@ -73,7 +71,7 @@ enum {
     ARG_START
 };
 
-/* Tabel for getopt_long() */
+/* Table for getopt_long() */
 static const struct option long_options[] = {
     {"help",                        0, 0, ARG_HELP},
     {"version",                     0, 0, ARG_VERSION},
@@ -87,8 +85,8 @@ static const struct option long_options[] = {
     {"realtime",                    2, 0, ARG_REALTIME},
     {"disallow-module-loading",     2, 0, ARG_DISALLOW_MODULE_LOADING},
     {"disallow-exit",               2, 0, ARG_DISALLOW_EXIT},
-    {"exit-idle-time",              2, 0, ARG_EXIT_IDLE_TIME},
-    {"scache-idle-time",            2, 0, ARG_SCACHE_IDLE_TIME},
+    {"exit-idle-time",              1, 0, ARG_EXIT_IDLE_TIME},
+    {"scache-idle-time",            1, 0, ARG_SCACHE_IDLE_TIME},
     {"log-target",                  1, 0, ARG_LOG_TARGET},
     {"log-meta",                    2, 0, ARG_LOG_META},
     {"log-time",                    2, 0, ARG_LOG_TIME},
@@ -139,13 +137,12 @@ void pa_cmdline_help(const char *argv0) {
            "      --disallow-exit[=BOOL]            Disallow user requested exit\n"
            "      --exit-idle-time=SECS             Terminate the daemon when idle and this\n"
            "                                        time passed\n"
-           "      --module-idle-time=SECS           Unload autoloaded modules when idle and\n"
-           "                                        this time passed\n"
            "      --scache-idle-time=SECS           Unload autoloaded samples when idle and\n"
            "                                        this time passed\n"
            "      --log-level[=LEVEL]               Increase or set verbosity level\n"
            "  -v                                    Increase the verbosity level\n"
-           "      --log-target={auto,syslog,stderr} Specify the log target\n"
+           "      --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"
@@ -173,6 +170,7 @@ void pa_cmdline_help(const char *argv0) {
 int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d) {
     pa_strbuf *buf = NULL;
     int c;
+    int b;
 
     pa_assert(conf);
     pa_assert(argc > 0);
@@ -243,17 +241,19 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
 
             case ARG_DAEMONIZE:
             case 'D':
-                if ((conf->daemonize = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
+                if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) {
                     pa_log(_("--daemonize expects boolean argument"));
                     goto fail;
                 }
+                conf->daemonize = !!b;
                 break;
 
             case ARG_FAIL:
-                if ((conf->fail = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
+                if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) {
                     pa_log(_("--fail expects boolean argument"));
                     goto fail;
                 }
+                conf->fail = !!b;
                 break;
 
             case 'v':
@@ -272,38 +272,43 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
                 break;
 
             case ARG_HIGH_PRIORITY:
-                if ((conf->high_priority = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
+                if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) {
                     pa_log(_("--high-priority expects boolean argument"));
                     goto fail;
                 }
+                conf->high_priority = !!b;
                 break;
 
             case ARG_REALTIME:
-                if ((conf->realtime_scheduling = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
+                if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) {
                     pa_log(_("--realtime expects boolean argument"));
                     goto fail;
                 }
+                conf->realtime_scheduling = !!b;
                 break;
 
             case ARG_DISALLOW_MODULE_LOADING:
-                if ((conf->disallow_module_loading = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
+                if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) {
                     pa_log(_("--disallow-module-loading expects boolean argument"));
                     goto fail;
                 }
+                conf->disallow_module_loading = !!b;
                 break;
 
             case ARG_DISALLOW_EXIT:
-                if ((conf->disallow_exit = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
+                if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) {
                     pa_log(_("--disallow-exit expects boolean argument"));
                     goto fail;
                 }
+                conf->disallow_exit = !!b;
                 break;
 
             case ARG_USE_PID_FILE:
-                if ((conf->use_pid_file = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
+                if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) {
                     pa_log(_("--use-pid-file expects boolean argument"));
                     goto fail;
                 }
+                conf->use_pid_file = !!b;
                 break;
 
             case 'p':
@@ -318,23 +323,25 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
 
             case ARG_LOG_TARGET:
                 if (pa_daemon_conf_set_log_target(conf, optarg) < 0) {
-                    pa_log(_("Invalid log target: use either 'syslog', 'stderr' or 'auto'."));
+                    pa_log(_("Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file name 'file:<path>', 'newfile:<path>'."));
                     goto fail;
                 }
                 break;
 
             case ARG_LOG_TIME:
-                if ((conf->log_time = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
+                if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) {
                     pa_log(_("--log-time expects boolean argument"));
                     goto fail;
                 }
+                conf->log_time = !!b;
                 break;
 
             case ARG_LOG_META:
-                if ((conf->log_meta = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
+                if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) {
                     pa_log(_("--log-meta expects boolean argument"));
                     goto fail;
                 }
+                conf->log_meta = !!b;
                 break;
 
             case ARG_LOG_BACKTRACE:
@@ -357,24 +364,27 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
                 break;
 
             case ARG_SYSTEM:
-                if ((conf->system_instance = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
+                if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) {
                     pa_log(_("--system expects boolean argument"));
                     goto fail;
                 }
+                conf->system_instance = !!b;
                 break;
 
             case ARG_NO_CPU_LIMIT:
-                if ((conf->no_cpu_limit = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
+                if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) {
                     pa_log(_("--no-cpu-limit expects boolean argument"));
                     goto fail;
                 }
+                conf->no_cpu_limit = !!b;
                 break;
 
             case ARG_DISABLE_SHM:
-                if ((conf->disable_shm = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
+                if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) {
                     pa_log(_("--disable-shm expects boolean argument"));
                     goto fail;
                 }
+                conf->disable_shm = !!b;
                 break;
 
             default:
index e34d7f5..4f02804 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "daemon-conf.h"
 
-/* Parese the command line and store its data in *c. Return the index
+/* Parse the command line and store its data in *c. Return the index
  * of the first unparsed argument in *d. */
 int pa_cmdline_parse(pa_daemon_conf*c, int argc, char *const argv [], int *d);
 
index c2877ec..0abbac0 100644 (file)
 #include <config.h>
 #endif
 
-#include <pulse/error.h>
 #include <pulse/rtclock.h>
 #include <pulse/timeval.h>
 
-#include <pulsecore/core-rtclock.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/core-error.h>
 #include <pulsecore/log.h>
@@ -40,7 +38,6 @@
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
-#include <sys/time.h>
 #include <unistd.h>
 #include <signal.h>
 
@@ -86,7 +83,7 @@ static struct sigaction sigaction_prev;
 static pa_bool_t installed = FALSE;
 
 /* The current state of operation */
-static enum  {
+static enum {
     PHASE_IDLE,   /* Normal state */
     PHASE_SOFT    /* After CPU overload has been detected */
 } phase = PHASE_IDLE;
@@ -140,7 +137,7 @@ static void signal_handler(int sig) {
             write_err("Soft CPU time limit exhausted, terminating.\n");
 
             /* Try a soft cleanup */
-            (void) write(the_pipe[1], &c, sizeof(c));
+            (void) pa_write(the_pipe[1], &c, sizeof(c), NULL);
             phase = PHASE_SOFT;
             reset_cpu_time(CPUTIME_INTERVAL_HARD);
 
@@ -170,7 +167,7 @@ static void callback(pa_mainloop_api*m, pa_io_event*e, int fd, pa_io_event_flags
 
     pa_log("Received request to terminate due to CPU overload.");
 
-    pa_read(the_pipe[0], &c, sizeof(c), NULL);
+    (void) pa_read(the_pipe[0], &c, sizeof(c), NULL);
     m->quit(m, 1); /* Quit the main loop */
 }
 
@@ -188,15 +185,13 @@ int pa_cpu_limit_init(pa_mainloop_api *m) {
     last_time = pa_rtclock_now();
 
     /* Prepare the main loop pipe */
-    if (pipe(the_pipe) < 0) {
+    if (pa_pipe_cloexec(the_pipe) < 0) {
         pa_log("pipe() failed: %s", pa_cstrerror(errno));
         return -1;
     }
 
     pa_make_fd_nonblock(the_pipe[0]);
     pa_make_fd_nonblock(the_pipe[1]);
-    pa_make_fd_cloexec(the_pipe[0]);
-    pa_make_fd_cloexec(the_pipe[1]);
 
     api = m;
     io_event = api->io_new(m, the_pipe[0], PA_IO_EVENT_INPUT, callback, NULL);
index 5ca8a4a..7d2fcba 100644 (file)
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_SCHED_H
 #include <sched.h>
+#endif
 
 #include <pulse/xmalloc.h>
 #include <pulse/timeval.h>
-#include <pulse/i18n.h>
+#include <pulse/version.h>
 
 #include <pulsecore/core-error.h>
 #include <pulsecore/core-util.h>
+#include <pulsecore/i18n.h>
 #include <pulsecore/strbuf.h>
 #include <pulsecore/conf-parser.h>
 #include <pulsecore/resampler.h>
@@ -83,12 +89,19 @@ static const pa_daemon_conf default_conf = {
     .config_file = NULL,
     .use_pid_file = TRUE,
     .system_instance = FALSE,
+#ifdef HAVE_DBUS
+    .local_server_type = PA_SERVER_TYPE_UNSET, /* The actual default is _USER, but we have to detect when the user doesn't specify this option. */
+#endif
     .no_cpu_limit = TRUE,
     .disable_shm = FALSE,
     .lock_memory = FALSE,
+    .deferred_volume = TRUE,
     .default_n_fragments = 4,
     .default_fragment_size_msec = 25,
+    .deferred_volume_safety_margin_usec = 8000,
+    .deferred_volume_extra_delay_usec = 0,
     .default_sample_spec = { .format = PA_SAMPLE_S16NE, .rate = 44100, .channels = 2 },
+    .alternate_sample_rate = 48000,
     .default_channel_map = { .channels = 2, .map = { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } },
     .shm_size = 0
 #ifdef HAVE_SYS_RESOURCE_H
@@ -132,31 +145,30 @@ static const pa_daemon_conf default_conf = {
 #endif
 };
 
-pa_daemon_confpa_daemon_conf_new(void) {
+pa_daemon_conf *pa_daemon_conf_new(void) {
     pa_daemon_conf *c;
 
     c = pa_xnewdup(pa_daemon_conf, &default_conf, 1);
 
-#if defined(__linux__) && !defined(__OPTIMIZE__)
-
-    /* We abuse __OPTIMIZE__ as a check whether we are a debug build
-     * or not. If we are and are run from the build tree then we
-     * override the search path to point to our build tree */
-
+#ifdef OS_IS_WIN32
+    c->dl_search_path = pa_sprintf_malloc("%s" PA_PATH_SEP "lib" PA_PATH_SEP "pulse-%d.%d" PA_PATH_SEP "modules",
+                                          pa_win32_get_toplevel(NULL), PA_MAJOR, PA_MINOR);
+#else
     if (pa_run_from_build_tree()) {
         pa_log_notice("Detected that we are run from the build tree, fixing search path.");
-        c->dl_search_path = pa_xstrdup(PA_BUILDDIR "/.libs/");
-
+        c->dl_search_path = pa_xstrdup(PA_BUILDDIR);
     } else
-
-#endif
         c->dl_search_path = pa_xstrdup(PA_DLSEARCHPATH);
+#endif
 
     return c;
 }
 
 void pa_daemon_conf_free(pa_daemon_conf *c) {
     pa_assert(c);
+
+    pa_log_set_fd(-1);
+
     pa_xfree(c->script_commands);
     pa_xfree(c->dl_search_path);
     pa_xfree(c->default_script_file);
@@ -164,18 +176,66 @@ void pa_daemon_conf_free(pa_daemon_conf *c) {
     pa_xfree(c);
 }
 
+#define PA_LOG_MAX_SUFFIX_NUMBER 100
+
 int pa_daemon_conf_set_log_target(pa_daemon_conf *c, const char *string) {
     pa_assert(c);
     pa_assert(string);
 
-    if (!strcmp(string, "auto"))
+    if (pa_streq(string, "auto"))
         c->auto_log_target = 1;
-    else if (!strcmp(string, "syslog")) {
+    else if (pa_streq(string, "syslog")) {
         c->auto_log_target = 0;
         c->log_target = PA_LOG_SYSLOG;
-    } else if (!strcmp(string, "stderr")) {
+    } else if (pa_streq(string, "stderr")) {
         c->auto_log_target = 0;
         c->log_target = PA_LOG_STDERR;
+    } else if (pa_startswith(string, "file:")) {
+        char file_path[512];
+        int log_fd;
+
+        pa_strlcpy(file_path, string + 5, sizeof(file_path));
+
+        /* Open target file with user rights */
+        if ((log_fd = open(file_path, O_RDWR|O_TRUNC|O_CREAT, S_IRUSR | S_IWUSR)) >= 0) {
+             c->auto_log_target = 0;
+             c->log_target = PA_LOG_FD;
+             pa_log_set_fd(log_fd);
+        } else {
+            printf("Failed to open target file %s, error : %s\n", file_path, pa_cstrerror(errno));
+            return -1;
+        }
+    } else if (pa_startswith(string, "newfile:")) {
+        char file_path[512];
+        int log_fd;
+        int version = 0;
+        int left_size;
+        char *p;
+
+        pa_strlcpy(file_path, string + 8, sizeof(file_path));
+
+        left_size = sizeof(file_path) - strlen(file_path);
+        p = file_path + strlen(file_path);
+
+        do {
+            memset(p, 0, left_size);
+
+            if (version > 0)
+                pa_snprintf(p, left_size, ".%d", version);
+        } while (++version <= PA_LOG_MAX_SUFFIX_NUMBER &&
+                 (log_fd = open(file_path, O_RDWR|O_TRUNC|O_CREAT|O_EXCL, S_IRUSR | S_IWUSR)) < 0);
+
+        if (version > PA_LOG_MAX_SUFFIX_NUMBER) {
+            memset(p, 0, left_size);
+            printf("Tried to open target files '%s', '%s.1', '%s.2' ... '%s.%d', but all failed.\n",
+                   file_path, file_path, file_path, file_path, PA_LOG_MAX_SUFFIX_NUMBER - 1);
+            return -1;
+        } else {
+            printf("Opened target file %s\n", file_path);
+            c->auto_log_target = 0;
+            c->log_target = PA_LOG_FD;
+            pa_log_set_fd(log_fd);
+        }
 #ifdef USE_DLOG
     } else if (!strcmp(string, "dlog")) {
         c->auto_log_target = 0;
@@ -210,6 +270,10 @@ int pa_daemon_conf_set_log_level(pa_daemon_conf *c, const char *string) {
         c->log_level = PA_LOG_WARN;
     else if (pa_startswith(string, "err"))
         c->log_level = PA_LOG_ERROR;
+#ifdef __TIZEN_LOG__
+    else if (pa_startswith(string, "verbose"))
+        c->log_level = PA_LOG_VERBOSE;
+#endif
     else
         return -1;
 
@@ -228,94 +292,103 @@ int pa_daemon_conf_set_resample_method(pa_daemon_conf *c, const char *string) {
     return 0;
 }
 
-static int parse_log_target(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+int pa_daemon_conf_set_local_server_type(pa_daemon_conf *c, const char *string) {
+    pa_assert(c);
+    pa_assert(string);
+
+    if (pa_streq(string, "user"))
+        c->local_server_type = PA_SERVER_TYPE_USER;
+    else if (pa_streq(string, "system")) {
+        c->local_server_type = PA_SERVER_TYPE_SYSTEM;
+    } else if (pa_streq(string, "none")) {
+        c->local_server_type = PA_SERVER_TYPE_NONE;
+    } else
+        return -1;
+
+    return 0;
+}
+
+static int parse_log_target(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
+
+    pa_assert(state);
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    c = state->data;
 
-    if (pa_daemon_conf_set_log_target(c, rvalue) < 0) {
-        pa_log(_("[%s:%u] Invalid log target '%s'."), filename, line, rvalue);
+    if (pa_daemon_conf_set_log_target(c, state->rvalue) < 0) {
+        pa_log(_("[%s:%u] Invalid log target '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
     return 0;
 }
 
-static int parse_log_level(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_log_level(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
+
+    pa_assert(state);
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    c = state->data;
 
-    if (pa_daemon_conf_set_log_level(c, rvalue) < 0) {
-        pa_log(_("[%s:%u] Invalid log level '%s'."), filename, line, rvalue);
+    if (pa_daemon_conf_set_log_level(c, state->rvalue) < 0) {
+        pa_log(_("[%s:%u] Invalid log level '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
     return 0;
 }
 
-static int parse_resample_method(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_resample_method(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
+
+    pa_assert(state);
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    c = state->data;
 
-    if (pa_daemon_conf_set_resample_method(c, rvalue) < 0) {
-        pa_log(_("[%s:%u] Invalid resample method '%s'."), filename, line, rvalue);
+    if (pa_daemon_conf_set_resample_method(c, state->rvalue) < 0) {
+        pa_log(_("[%s:%u] Invalid resample method '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
     return 0;
 }
 
-static int parse_rlimit(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
 #ifdef HAVE_SYS_RESOURCE_H
-    struct pa_rlimit *r = data;
+static int parse_rlimit(pa_config_parser_state *state) {
+    struct pa_rlimit *r;
+
+    pa_assert(state);
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(r);
+    r = state->data;
 
-    if (rvalue[strspn(rvalue, "\t ")] == 0) {
+    if (state->rvalue[strspn(state->rvalue, "\t ")] == 0) {
         /* Empty string */
         r->is_set = 0;
         r->value = 0;
     } else {
         int32_t k;
-        if (pa_atoi(rvalue, &k) < 0) {
-            pa_log(_("[%s:%u] Invalid rlimit '%s'."), filename, line, rvalue);
+        if (pa_atoi(state->rvalue, &k) < 0) {
+            pa_log(_("[%s:%u] Invalid rlimit '%s'."), state->filename, state->lineno, state->rvalue);
             return -1;
         }
         r->is_set = k >= 0;
         r->value = k >= 0 ? (rlim_t) k : 0;
     }
-#else
-    pa_log_warn(_("[%s:%u] rlimit not supported on this platform."), filename, line);
-#endif
 
     return 0;
 }
+#endif
 
-static int parse_sample_format(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_sample_format(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
     pa_sample_format_t f;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
+
+    c = state->data;
 
-    if ((f = pa_parse_sample_format(rvalue)) < 0) {
-        pa_log(_("[%s:%u] Invalid sample format '%s'."), filename, line, rvalue);
+    if ((f = pa_parse_sample_format(state->rvalue)) < 0) {
+        pa_log(_("[%s:%u] Invalid sample format '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -323,17 +396,17 @@ static int parse_sample_format(const char *filename, unsigned line, const char *
     return 0;
 }
 
-static int parse_sample_rate(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_sample_rate(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
     uint32_t r;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
+
+    c = state->data;
 
-    if (pa_atou(rvalue, &r) < 0 || r > (uint32_t) PA_RATE_MAX || r <= 0) {
-        pa_log(_("[%s:%u] Invalid sample rate '%s'."), filename, line, rvalue);
+    if (pa_atou(state->rvalue, &r) < 0 || r > (uint32_t) PA_RATE_MAX || r <= 0 ||
+        !((r % 4000 == 0) || (r % 11025 == 0))) {
+        pa_log(_("[%s:%u] Invalid sample rate '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -341,23 +414,40 @@ static int parse_sample_rate(const char *filename, unsigned line, const char *se
     return 0;
 }
 
+static int parse_alternate_sample_rate(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
+    uint32_t r;
+
+    pa_assert(state);
+
+    c = state->data;
+
+    if (pa_atou(state->rvalue, &r) < 0 || r > (uint32_t) PA_RATE_MAX || r <= 0 ||
+        !((r % 4000==0) || (r % 11025 == 0))) {
+        pa_log(_("[%s:%u] Invalid sample rate '%s'."), state->filename, state->lineno, state->rvalue);
+        return -1;
+    }
+
+    c->alternate_sample_rate = r;
+    return 0;
+}
+
 struct channel_conf_info {
     pa_daemon_conf *conf;
     pa_bool_t default_sample_spec_set;
     pa_bool_t default_channel_map_set;
 };
 
-static int parse_sample_channels(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    struct channel_conf_info *i = data;
+static int parse_sample_channels(pa_config_parser_state *state) {
+    struct channel_conf_info *i;
     int32_t n;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
 
-    if (pa_atoi(rvalue, &n) < 0 || n > (int32_t) PA_CHANNELS_MAX || n <= 0) {
-        pa_log(_("[%s:%u] Invalid sample channels '%s'."), filename, line, rvalue);
+    i = state->data;
+
+    if (pa_atoi(state->rvalue, &n) < 0 || n > (int32_t) PA_CHANNELS_MAX || n <= 0) {
+        pa_log(_("[%s:%u] Invalid sample channels '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -366,16 +456,15 @@ static int parse_sample_channels(const char *filename, unsigned line, const char
     return 0;
 }
 
-static int parse_channel_map(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    struct channel_conf_info *i = data;
+static int parse_channel_map(pa_config_parser_state *state) {
+    struct channel_conf_info *i;
+
+    pa_assert(state);
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    i = state->data;
 
-    if (!pa_channel_map_parse(&i->conf->default_channel_map, rvalue)) {
-        pa_log(_("[%s:%u] Invalid channel map '%s'."), filename, line, rvalue);
+    if (!pa_channel_map_parse(&i->conf->default_channel_map, state->rvalue)) {
+        pa_log(_("[%s:%u] Invalid channel map '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -383,17 +472,16 @@ static int parse_channel_map(const char *filename, unsigned line, const char *se
     return 0;
 }
 
-static int parse_fragments(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_fragments(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
     int32_t n;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
 
-    if (pa_atoi(rvalue, &n) < 0 || n < 2) {
-        pa_log(_("[%s:%u] Invalid number of fragments '%s'."), filename, line, rvalue);
+    c = state->data;
+
+    if (pa_atoi(state->rvalue, &n) < 0 || n < 2) {
+        pa_log(_("[%s:%u] Invalid number of fragments '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -401,17 +489,16 @@ static int parse_fragments(const char *filename, unsigned line, const char *sect
     return 0;
 }
 
-static int parse_fragment_size_msec(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_fragment_size_msec(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
     int32_t n;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
 
-    if (pa_atoi(rvalue, &n) < 0 || n < 1) {
-        pa_log(_("[%s:%u] Invalid fragment size '%s'."), filename, line, rvalue);
+    c = state->data;
+
+    if (pa_atoi(state->rvalue, &n) < 0 || n < 1) {
+        pa_log(_("[%s:%u] Invalid fragment size '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -419,17 +506,16 @@ static int parse_fragment_size_msec(const char *filename, unsigned line, const c
     return 0;
 }
 
-static int parse_nice_level(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_nice_level(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
     int32_t level;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
+
+    c = state->data;
 
-    if (pa_atoi(rvalue, &level) < 0 || level < -20 || level > 19) {
-        pa_log(_("[%s:%u] Invalid nice level '%s'."), filename, line, rvalue);
+    if (pa_atoi(state->rvalue, &level) < 0 || level < -20 || level > 19) {
+        pa_log(_("[%s:%u] Invalid nice level '%s'."), state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -437,24 +523,49 @@ static int parse_nice_level(const char *filename, unsigned line, const char *sec
     return 0;
 }
 
-static int parse_rtprio(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    pa_daemon_conf *c = data;
+static int parse_rtprio(pa_config_parser_state *state) {
+#if !defined(OS_IS_WIN32) && defined(HAVE_SCHED_H)
+    pa_daemon_conf *c;
     int32_t rtprio;
+#endif
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
 
-    if (pa_atoi(rvalue, &rtprio) < 0 || rtprio < sched_get_priority_min(SCHED_FIFO) || rtprio > sched_get_priority_max(SCHED_FIFO)) {
-        pa_log("[%s:%u] Invalid realtime priority '%s'.", filename, line, rvalue);
+#ifdef OS_IS_WIN32
+    pa_log("[%s:%u] Realtime priority not available on win32.", state->filename, state->lineno);
+#else
+# ifdef HAVE_SCHED_H
+    c = state->data;
+
+    if (pa_atoi(state->rvalue, &rtprio) < 0 || rtprio < sched_get_priority_min(SCHED_FIFO) || rtprio > sched_get_priority_max(SCHED_FIFO)) {
+        pa_log("[%s:%u] Invalid realtime priority '%s'.", state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
     c->realtime_priority = (int) rtprio;
+# endif
+#endif /* OS_IS_WIN32 */
+
     return 0;
 }
 
+#ifdef HAVE_DBUS
+static int parse_server_type(pa_config_parser_state *state) {
+    pa_daemon_conf *c;
+
+    pa_assert(state);
+
+    c = state->data;
+
+    if (pa_daemon_conf_set_local_server_type(c, state->rvalue) < 0) {
+        pa_log(_("[%s:%u] Invalid server type '%s'."), state->filename, state->lineno, state->rvalue);
+        return -1;
+    }
+
+    return 0;
+}
+#endif
+
 int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
     int r = -1;
     FILE *f = NULL;
@@ -470,12 +581,16 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
         { "allow-exit",                 pa_config_parse_not_bool, &c->disallow_exit, NULL },
         { "use-pid-file",               pa_config_parse_bool,     &c->use_pid_file, NULL },
         { "system-instance",            pa_config_parse_bool,     &c->system_instance, NULL },
+#ifdef HAVE_DBUS
+        { "local-server-type",          parse_server_type,        c, NULL },
+#endif
         { "no-cpu-limit",               pa_config_parse_bool,     &c->no_cpu_limit, NULL },
         { "cpu-limit",                  pa_config_parse_not_bool, &c->no_cpu_limit, NULL },
         { "disable-shm",                pa_config_parse_bool,     &c->disable_shm, NULL },
         { "enable-shm",                 pa_config_parse_not_bool, &c->disable_shm, NULL },
         { "flat-volumes",               pa_config_parse_bool,     &c->flat_volumes, 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 },
         { "scache-idle-time",           pa_config_parse_int,      &c->scache_idle_time, NULL },
         { "realtime-priority",          parse_rtprio,             c, NULL },
@@ -487,10 +602,15 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
         { "resample-method",            parse_resample_method,    c, NULL },
         { "default-sample-format",      parse_sample_format,      c, NULL },
         { "default-sample-rate",        parse_sample_rate,        c, NULL },
+        { "alternate-sample-rate",      parse_alternate_sample_rate, c, NULL },
         { "default-sample-channels",    parse_sample_channels,    &ci,  NULL },
         { "default-channel-map",        parse_channel_map,        &ci,  NULL },
         { "default-fragments",          parse_fragments,          c, NULL },
         { "default-fragment-size-msec", parse_fragment_size_msec, c, NULL },
+        { "deferred-volume-safety-margin-usec",
+                                        pa_config_parse_unsigned, &c->deferred_volume_safety_margin_usec, NULL },
+        { "deferred-volume-extra-delay-usec",
+                                        pa_config_parse_int,      &c->deferred_volume_extra_delay_usec, NULL },
         { "nice-level",                 parse_nice_level,         c, NULL },
         { "disable-remixing",           pa_config_parse_bool,     &c->disable_remixing, NULL },
         { "enable-remixing",            pa_config_parse_not_bool, &c->disable_remixing, NULL },
@@ -547,7 +667,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
     c->config_file = NULL;
 
     f = filename ?
-        fopen(c->config_file = pa_xstrdup(filename), "r") :
+        pa_fopen_cloexec(c->config_file = pa_xstrdup(filename), "r") :
         pa_open_config_file(DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_FILE_USER, ENV_CONFIG_FILE, &c->config_file);
 
     if (!f && errno != ENOENT) {
@@ -558,7 +678,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
     ci.default_channel_map_set = ci.default_sample_spec_set = FALSE;
     ci.conf = c;
 
-    r = f ? pa_config_parse(c->config_file, f, table, NULL) : 0;
+    r = f ? pa_config_parse(c->config_file, f, table, NULL, NULL) : 0;
 
     if (r >= 0) {
 
@@ -622,19 +742,32 @@ FILE *pa_daemon_conf_open_default_script_file(pa_daemon_conf *c) {
         else
             f = pa_open_config_file(DEFAULT_SCRIPT_FILE, DEFAULT_SCRIPT_FILE_USER, ENV_SCRIPT_FILE, &c->default_script_file);
     } else
-        f = fopen(c->default_script_file, "r");
+        f = pa_fopen_cloexec(c->default_script_file, "r");
 
     return f;
 }
 
 char *pa_daemon_conf_dump(pa_daemon_conf *c) {
     static const char* const log_level_to_string[] = {
+#ifdef __TIZEN_LOG__
+        [PA_LOG_VERBOSE] = "verbose",
+#endif
         [PA_LOG_DEBUG] = "debug",
         [PA_LOG_INFO] = "info",
         [PA_LOG_NOTICE] = "notice",
         [PA_LOG_WARN] = "warning",
         [PA_LOG_ERROR] = "error"
     };
+
+#ifdef HAVE_DBUS
+    static const char* const server_type_to_string[] = {
+        [PA_SERVER_TYPE_UNSET] = "!!UNSET!!",
+        [PA_SERVER_TYPE_USER] = "user",
+        [PA_SERVER_TYPE_SYSTEM] = "system",
+        [PA_SERVER_TYPE_NONE] = "none"
+    };
+#endif
+
     pa_strbuf *s;
     char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
 
@@ -657,6 +790,9 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
     pa_strbuf_printf(s, "allow-exit = %s\n", pa_yes_no(!c->disallow_exit));
     pa_strbuf_printf(s, "use-pid-file = %s\n", pa_yes_no(c->use_pid_file));
     pa_strbuf_printf(s, "system-instance = %s\n", pa_yes_no(c->system_instance));
+#ifdef HAVE_DBUS
+    pa_strbuf_printf(s, "local-server-type = %s\n", server_type_to_string[c->local_server_type]);
+#endif
     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));
@@ -673,10 +809,14 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
     pa_strbuf_printf(s, "enable-lfe-remixing = %s\n", pa_yes_no(!c->disable_lfe_remixing));
     pa_strbuf_printf(s, "default-sample-format = %s\n", pa_sample_format_to_string(c->default_sample_spec.format));
     pa_strbuf_printf(s, "default-sample-rate = %u\n", c->default_sample_spec.rate);
+    pa_strbuf_printf(s, "alternate-sample-rate = %u\n", c->alternate_sample_rate);
     pa_strbuf_printf(s, "default-sample-channels = %u\n", c->default_sample_spec.channels);
     pa_strbuf_printf(s, "default-channel-map = %s\n", pa_channel_map_snprint(cm, sizeof(cm), &c->default_channel_map));
     pa_strbuf_printf(s, "default-fragments = %u\n", c->default_n_fragments);
     pa_strbuf_printf(s, "default-fragment-size-msec = %u\n", c->default_fragment_size_msec);
+    pa_strbuf_printf(s, "enable-deferred-volume = %s\n", pa_yes_no(c->deferred_volume));
+    pa_strbuf_printf(s, "deferred-volume-safety-margin-usec = %u\n", c->deferred_volume_safety_margin_usec);
+    pa_strbuf_printf(s, "deferred-volume-extra-delay-usec = %d\n", c->deferred_volume_extra_delay_usec);
     pa_strbuf_printf(s, "shm-size-bytes = %lu\n", (unsigned long) c->shm_size);
     pa_strbuf_printf(s, "log-meta = %s\n", pa_yes_no(c->log_meta));
     pa_strbuf_printf(s, "log-time = %s\n", pa_yes_no(c->log_time));
index dd69e04..faf2540 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
+#include <pulsecore/core.h>
 #include <pulsecore/core-util.h>
 
 #ifdef HAVE_SYS_RESOURCE_H
@@ -74,7 +75,9 @@ typedef struct pa_daemon_conf {
         log_meta,
         log_time,
         flat_volumes,
-        lock_memory;
+        lock_memory,
+        deferred_volume;
+    pa_server_type_t local_server_type;
     int exit_idle_time,
         scache_idle_time,
         auto_log_target,
@@ -125,7 +128,10 @@ typedef struct pa_daemon_conf {
 #endif
 
     unsigned default_n_fragments, default_fragment_size_msec;
+    unsigned deferred_volume_safety_margin_usec;
+    int deferred_volume_extra_delay_usec;
     pa_sample_spec default_sample_spec;
+    uint32_t alternate_sample_rate;
     pa_channel_map default_channel_map;
     size_t shm_size;
 } pa_daemon_conf;
@@ -152,6 +158,7 @@ int pa_daemon_conf_env(pa_daemon_conf *c);
 int pa_daemon_conf_set_log_target(pa_daemon_conf *c, const char *string);
 int pa_daemon_conf_set_log_level(pa_daemon_conf *c, const char *string);
 int pa_daemon_conf_set_resample_method(pa_daemon_conf *c, const char *string);
+int pa_daemon_conf_set_local_server_type(pa_daemon_conf *c, const char *string);
 
 const char *pa_daemon_conf_get_default_script_file(pa_daemon_conf *c);
 FILE *pa_daemon_conf_open_default_script_file(pa_daemon_conf *c);
index d4ffe49..dff97ae 100644 (file)
@@ -16,8 +16,9 @@
 # USA.
 
 ## Configuration file for the PulseAudio daemon. See pulse-daemon.conf(5) for
-## more information. Default values a commented out.  Use either ; or # for
+## more information. Default values are commented out.  Use either ; or # for
 ## commenting.
+changequote(`[', `]')dnl Set up m4 quoting
 
 ; daemonize = no
 ; fail = yes
@@ -25,6 +26,9 @@
 ; allow-exit = yes
 ; use-pid-file = yes
 ; system-instance = no
+ifelse(@HAVE_DBUS@, 1, [dnl
+; local-server-type = user
+])dnl
 ; enable-shm = yes
 ; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
 ; lock-memory = no
@@ -33,8 +37,8 @@
 ; high-priority = yes
 ; nice-level = -11
 
-realtime-scheduling = yes
-realtime-priority = 5
+realtime-scheduling = yes
+realtime-priority = 5
 
 ; exit-idle-time = 20
 ; scache-idle-time = 20
@@ -42,20 +46,21 @@ realtime-priority = 5
 ; dl-search-path = (depends on architecture)
 
 ; load-default-script-file = yes
-; default-script-file = @PA_DEFAULT_CONFIG_FILE@
+; default-script-file = @PA_DEFAULT_CONFIG_DIR@/default.pa
 
-log-target = dlog-color
+; log-target = auto
 ; log-level = notice
 ; log-meta = no
 ; log-time = no
 ; log-backtrace = 0
 
-resample-method = ffmpeg
+; resample-method = speex-float-3
 ; enable-remixing = yes
 ; enable-lfe-remixing = no
 
 ; flat-volumes = yes
 
+ifelse(@HAVE_SYS_RESOURCE_H@, 1, [dnl
 ; rlimit-fsize = -1
 ; rlimit-data = -1
 ; rlimit-stack = -1
@@ -71,11 +76,17 @@ resample-method = ffmpeg
 ; rlimit-nice = 31
 ; rlimit-rtprio = 9
 ; rlimit-rttime = 1000000
+])dnl
 
 ; default-sample-format = s16le
 ; default-sample-rate = 44100
+; alternate-sample-rate = 48000
 ; default-sample-channels = 2
 ; default-channel-map = front-left,front-right
 
 ; default-fragments = 4
 ; default-fragment-size-msec = 25
+
+; enable-deferred-volume = yes
+; deferred-volume-safety-margin-usec = 8000
+; deferred-volume-extra-delay-usec = 0
index 35bd48a..f50d929 100755 (executable)
 
 # This startup script is used only if PulseAudio is started per-user
 # (i.e. not in system mode)
+changequote(`[', `]')dnl Set up m4 quoting
 
 .nofail
 
 ### Load something into the sample cache
+ifelse(@OS_IS_WIN32@, 1, [dnl
+load-sample x11-bell %WINDIR%\Media\ding.wav
+load-sample-dir-lazy %WINDIR%\Media\*.wav
+], [dnl
 #load-sample-lazy x11-bell /usr/share/sounds/gtk-events/activate.wav
 #load-sample-lazy pulse-hotplug /usr/share/sounds/startup3.wav
 #load-sample-lazy pulse-coldplug /usr/share/sounds/startup3.wav
 #load-sample-lazy pulse-access /usr/share/sounds/generic.wav
+])dnl
 
 .fail
 
@@ -38,47 +44,80 @@ load-module module-card-restore
 ### stored in /usr/share/application
 load-module module-augment-properties
 
-### Load audio drivers statically (it's probably better to not load
-### these drivers manually, but instead use module-hal-detect --
-### see below -- for doing this automatically)
+### Should be after module-*-restore but before module-*-detect
+load-module module-switch-on-port-available
+
+### Load audio drivers statically
+### (it's probably better to not load these drivers manually, but instead
+### use module-udev-detect -- see below -- for doing this automatically)
+ifelse(@HAVE_ALSA@, 1, [dnl
 #load-module module-alsa-sink
 #load-module module-alsa-source device=hw:1,0
+])dnl
+ifelse(@HAVE_OSS_OUTPUT@, 1, [dnl
 #load-module module-oss device="/dev/dsp" sink_name=output source_name=input
 #load-module module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
+])dnl
+ifelse(@HAVE_WAVEOUT@, 1, [dnl
+load-module module-waveout sink_name=output source_name=input
+])dnl
 #load-module module-null-sink
+ifelse(@HAVE_MKFIFO@, 1, [dnl
 #load-module module-pipe-sink
+])dnl
 
 ### Automatically load driver modules depending on the hardware available
+ifelse(@HAVE_UDEV@, 1, [dnl
 .ifexists module-udev-detect@PA_SOEXT@
-#load-module module-udev-detect
+load-module module-udev-detect
 .else
-### Alternatively use the static hardware detection module (for systems that
-### lack udev support)
-#load-module module-detect
+], [dnl
+.ifexists module-detect@PA_SOEXT@
+])dnl
+### Use the static hardware detection module (for systems that lack udev support)
+load-module module-detect
+.endif
+
+### Automatically connect sink and source if JACK server is present
+.ifexists module-jackdbus-detect@PA_SOEXT@
+.nofail
+load-module module-jackdbus-detect channels=2
+.fail
 .endif
 
+ifelse(@HAVE_BLUEZ@, 1, [dnl
 ### Automatically load driver modules for Bluetooth hardware
+.ifexists module-bluetooth-policy@PA_SOEXT@
+load-module module-bluetooth-policy
+.endif
+
 .ifexists module-bluetooth-discover@PA_SOEXT@
 load-module module-bluetooth-discover
 .endif
+])dnl
 
+ifelse(@HAVE_AF_UNIX@, 1, [dnl
 ### Load several protocols
 .ifexists module-esound-protocol-unix@PA_SOEXT@
 load-module module-esound-protocol-unix
 .endif
 load-module module-native-protocol-unix
+])dnl
 
 ### Network access (may be configured with paprefs, so leave this commented
 ### here if you plan to use paprefs)
 #load-module module-esound-protocol-tcp
 #load-module module-native-protocol-tcp
+ifelse(@HAVE_AVAHI@, 1, [dnl
 #load-module module-zeroconf-publish
+])dnl
 
-### Load the RTP reciever module (also configured via paprefs, see above)
+ifelse(@OS_IS_WIN32@, 0, [dnl
+### Load the RTP receiver module (also configured via paprefs, see above)
 #load-module module-rtp-recv
 
 ### Load the RTP sender module (also configured via paprefs, see above)
-#load-module module-null-sink sink_name=rtp format=s16be channels=2 rate=44100 description="RTP Multicast Sink"
+#load-module module-null-sink sink_name=rtp format=s16be channels=2 rate=44100 sink_properties="device.description='RTP Multicast Sink'"
 #load-module module-rtp-send source=rtp.monitor
 
 ### Load additional modules from GConf settings. This can be configured with the paprefs tool.
@@ -90,7 +129,10 @@ load-module module-gconf
 .fail
 .endif
 
-### Automatically restore the default sink/source when changed by the user during runtime
+### Automatically restore the default sink/source when changed by the user
+### during runtime
+### NOTE: This should be loaded as early as possible so that subsequent modules
+### 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
@@ -108,14 +150,35 @@ load-module module-suspend-on-idle
 
 ### If autoexit on idle is enabled we want to make sure we only quit
 ### when no local session needs us anymore.
+.ifexists module-console-kit@PA_SOEXT@
 load-module module-console-kit
+.endif
+.ifexists module-systemd-login@PA_SOEXT@
+load-module module-systemd-login
+.endif
 
 ### Enable positioned event sounds
 load-module module-position-event-sounds
 
-### Cork music streams when a phone stream is active
-load-module module-cork-music-on-phone
+### Cork music/video streams when a phone stream is active
+load-module module-role-cork
+
+### Modules to allow autoloading of filters (such as echo cancellation)
+### on demand. module-filter-heuristics tries to determine what filters
+### make sense, and module-filter-apply does the heavy-lifting of
+### loading modules and rerouting streams.
+load-module module-filter-heuristics
+load-module module-filter-apply
+])dnl
+
+ifelse(@HAVE_DBUS@, 1, [dnl
+### Load DBus protocol
+.ifexists module-dbus-protocol@PA_SOEXT@
+load-module module-dbus-protocol
+.endif
+])dnl
 
+ifelse(@HAVE_X11@, 1, [dnl
 # X11 modules should not be started from default.pa so that one daemon
 # can be shared by multiple sessions.
 
@@ -131,6 +194,7 @@ load-module module-cork-music-on-phone
 #load-module module-x11-publish
 #.fail
 #.endif
+])dnl
 
 ### Make some devices default
 #set-default-sink output
diff --git a/src/daemon/default.pa.win32 b/src/daemon/default.pa.win32
deleted file mode 100644 (file)
index d5a1e18..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#\r
-# This file is part of PulseAudio.\r
-#\r
-# PulseAudio is free software; you can redistribute it and/or modify it\r
-# under the terms of the GNU Lesser General Public License as published by\r
-# the Free Software Foundation; either version 2 of the License, or\r
-# (at your option) any later version.\r
-#\r
-# PulseAudio is distributed in the hope that it will be useful, but\r
-# WITHOUT ANY WARRANTY; without even the implied warranty of\r
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
-# General Public License for more details.\r
-#\r
-# You should have received a copy of the GNU Lesser General Public License\r
-# along with PulseAudio; if not, write to the Free Software Foundation,\r
-# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.\r
-\r
-\r
-# Load audio drivers statically\r
-\r
-load-module module-waveout sink_name=output source_name=input\r
-load-module module-null-sink\r
-\r
-# Load audio drivers automatically on access\r
-\r
-#add-autoload-sink output module-waveout sink_name=output source_name=input\r
-#add-autoload-source input module-waveout sink_name=output source_name=input\r
-\r
-# Load several protocols\r
-#load-module module-esound-protocol-tcp\r
-#load-module module-native-protocol-tcp\r
-#load-module module-simple-protocol-tcp\r
-#load-module module-cli-protocol-tcp\r
-\r
-# Make some devices default\r
-set-default-sink output\r
-set-default-source input\r
-\r
-.nofail\r
-\r
-# Load something to the sample cache\r
-load-sample x11-bell %WINDIR%\Media\ding.wav\r
-load-sample-dir-lazy %WINDIR%\Media\*.wav\r
index 92470b4..0529e04 100644 (file)
 #endif
 
 #include <string.h>
-#include <getopt.h>
 #include <stdio.h>
 #include <ltdl.h>
 
 #include <pulse/util.h>
-#include <pulse/i18n.h>
 
-#include <pulsecore/modinfo.h>
 #include <pulsecore/core-util.h>
+#include <pulsecore/i18n.h>
 #include <pulsecore/macro.h>
+#include <pulsecore/modinfo.h>
 
 #include "dumpmodules.h"
 
@@ -90,8 +89,6 @@ static void show_info(const char *name, const char *path, void (*info)(const cha
     }
 }
 
-extern const lt_dlsymlist lt_preloaded_symbols[];
-
 static int is_preloaded(const char *name) {
     const lt_dlsymlist *l;
 
@@ -105,7 +102,7 @@ static int is_preloaded(const char *name) {
         if ((e = strrchr(buf, '.')))
             *e = 0;
 
-        if (!strcmp(name, buf))
+        if (pa_streq(name, buf))
             return 1;
     }
 
index 6650180..41a12a0 100755 (executable)
@@ -59,7 +59,7 @@ Ignored directives:
   -terminate    terminate esd daemone after last client exits
   -nobeeps      disable startup beeps
   -trust        start esd even if use of /tmp/.esd can be insecure
-  -port PORT   listen for connections at PORT (only for tcp/ip)
+  -port PORT    listen for connections at PORT (only for tcp/ip)
   -bind ADDRESS binds to ADDRESS (only for tcp/ip)
 EOF
             exit 0
index 276b2a0..6fd66e9 100644 (file)
@@ -36,8 +36,7 @@
 
 #include <ltdl.h>
 
-#include <pulse/i18n.h>
-
+#include <pulsecore/i18n.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/log.h>
 
 #undef PA_BIND_NOW
 #endif
 
+#ifdef OS_IS_WIN32
+#undef PA_BIND_NOW
+#endif
+
 #ifdef PA_BIND_NOW
 
 /*
@@ -62,7 +65,7 @@
   relocations on any libraries that are already loaded into our
   process, i.e. because the pulseaudio binary links directly to
   them. To disable lazy relocations for those libraries it is possible
-  to set $LT_BIND_NOW before starting the pulsaudio binary.
+  to set $LT_BIND_NOW before starting the pulseaudio binary.
 */
 
 static lt_module bind_now_open(lt_user_data d, const char *fname, lt_dladvise advise) {
@@ -71,6 +74,7 @@ static lt_module bind_now_open(lt_user_data d, const char *fname, lt_dladvise ad
     pa_assert(fname);
 
     if (!(m = dlopen(fname, PA_BIND_NOW))) {
+        pa_log(_("Failed to open module %s: %s"), fname, dlerror());
         lt_dlseterror(LT_ERROR_CANNOT_OPEN);
         return NULL;
     }
index 1d28737..ed1bd4b 100644 (file)
@@ -33,7 +33,6 @@
 #include <stddef.h>
 #include <ltdl.h>
 #include <limits.h>
-#include <fcntl.h>
 #include <unistd.h>
 #include <locale.h>
 #include <sys/types.h>
 #include <sys/mman.h>
 #endif
 
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-
 #ifdef HAVE_PWD_H
 #include <pwd.h>
 #endif
 #include <dbus/dbus.h>
 #endif
 
+#include <pulse/client-conf.h>
+#ifdef HAVE_X11
+#include <pulse/client-conf-x11.h>
+#endif
 #include <pulse/mainloop.h>
 #include <pulse/mainloop-signal.h>
 #include <pulse/timeval.h>
 #include <pulse/xmalloc.h>
-#include <pulse/i18n.h>
 
+#include <pulsecore/i18n.h>
 #include <pulsecore/lock-autospawn.h>
-#include <pulsecore/winsock.h>
+#include <pulsecore/socket.h>
 #include <pulsecore/core-error.h>
 #include <pulsecore/core-rtclock.h>
+#include <pulsecore/core-scache.h>
 #include <pulsecore/core.h>
-#include <pulsecore/memblock.h>
 #include <pulsecore/module.h>
 #include <pulsecore/cli-command.h>
 #include <pulsecore/log.h>
 #include <pulsecore/sioman.h>
 #include <pulsecore/cli-text.h>
 #include <pulsecore/pid.h>
-#include <pulsecore/namereg.h>
 #include <pulsecore/random.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/mutex.h>
-#include <pulsecore/thread.h>
-#include <pulsecore/once.h>
 #include <pulsecore/shm.h>
 #include <pulsecore/memtrap.h>
+#include <pulsecore/strlist.h>
 #ifdef HAVE_DBUS
 #include <pulsecore/dbus-shared.h>
 #endif
 #include <pulsecore/cpu-arm.h>
 #include <pulsecore/cpu-x86.h>
+#include <pulsecore/cpu-orc.h>
 
 #include "cmdline.h"
 #include "cpulimit.h"
 #include "daemon-conf.h"
-#include "dumpmodules.h"
+// #include "dumpmodules.h" for libtool 2.2
 #include "caps.h"
 #include "ltdl-bind-now.h"
+#include "server-lookup.h"
+
+#define PA_READY "/tmp/.pa_ready"
 
 #ifdef HAVE_LIBWRAP
 /* Only one instance of these variables */
@@ -132,13 +132,13 @@ static void message_cb(pa_mainloop_api*a, pa_time_event*e, const struct timeval
     }
 
     pa_timeval_add(pa_gettimeofday(&tvnext), 100000);
-    a->rtclock_time_restart(e, &tvnext);
+    a->time_restart(e, &tvnext);
 }
 
 #endif
 
 static void signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void *userdata) {
-    pa_log_info(_("Got signal %s."), pa_sig2str(sig));
+    pa_log_error("Got signal %s.", pa_sig2str(sig));
 
     switch (sig) {
 #ifdef SIGUSR1
@@ -162,8 +162,12 @@ static void signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void
         }
 #endif
 
-        case SIGINT:
         case SIGTERM:
+#ifndef TIZEN_MICRO
+            break;
+#endif
+
+        case SIGINT:
         default:
             pa_log_info(_("Exiting."));
             m->quit(m, 1);
@@ -201,15 +205,15 @@ static int change_user(void) {
         return -1;
     }
 
-    if (strcmp(pw->pw_dir, PA_SYSTEM_RUNTIME_PATH) != 0)
+    if (!pa_streq(pw->pw_dir, PA_SYSTEM_RUNTIME_PATH))
         pa_log_warn(_("Home directory of user '%s' is not '%s', ignoring."), PA_SYSTEM_USER, PA_SYSTEM_RUNTIME_PATH);
 
-    if (pa_make_secure_dir(PA_SYSTEM_RUNTIME_PATH, 0755, pw->pw_uid, gr->gr_gid) < 0) {
+    if (pa_make_secure_dir(PA_SYSTEM_RUNTIME_PATH, 0755, pw->pw_uid, gr->gr_gid, TRUE) < 0) {
         pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_RUNTIME_PATH, pa_cstrerror(errno));
         return -1;
     }
 
-    if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH, 0700, pw->pw_uid, gr->gr_gid) < 0) {
+    if (pa_make_secure_dir(PA_SYSTEM_STATE_PATH, 0700, pw->pw_uid, gr->gr_gid, TRUE) < 0) {
         pa_log(_("Failed to create '%s': %s"), PA_SYSTEM_STATE_PATH, pa_cstrerror(errno));
         return -1;
     }
@@ -253,6 +257,8 @@ static int change_user(void) {
         return -1;
     }
 
+    pa_drop_caps();
+
     pa_set_env("USER", PA_SYSTEM_USER);
     pa_set_env("USERNAME", PA_SYSTEM_USER);
     pa_set_env("LOGNAME", PA_SYSTEM_USER);
@@ -268,7 +274,7 @@ static int change_user(void) {
     if (!getenv("PULSE_STATE_PATH"))
         pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH);
 
-    pa_log_info(_("Successfully dropped root privileges."));
+    pa_log_info(_("Successfully changed user to \"" PA_SYSTEM_USER "\"."));
 
     return 0;
 }
@@ -342,34 +348,50 @@ static void set_all_rlimits(const pa_daemon_conf *conf) {
 }
 #endif
 
+static char *check_configured_address(void) {
+    char *default_server = NULL;
+    pa_client_conf *c = pa_client_conf_new();
+
+    pa_client_conf_load(c, NULL);
+#ifdef HAVE_X11
+    pa_client_conf_from_x11(c, NULL);
+#endif
+    pa_client_conf_env(c);
+
+    if (c->default_server && *c->default_server)
+        default_server = pa_xstrdup(c->default_server);
+
+    pa_client_conf_free(c);
+
+    return default_server;
+}
+
 #ifdef HAVE_DBUS
-static pa_dbus_connection *register_dbus(pa_core *c) {
+static pa_dbus_connection *register_dbus_name(pa_core *c, DBusBusType bus, const char* name) {
     DBusError error;
     pa_dbus_connection *conn;
 
     dbus_error_init(&error);
 
-    if (!(conn = pa_dbus_bus_get(c, pa_in_system_mode() ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, &error)) || dbus_error_is_set(&error)) {
+    if (!(conn = pa_dbus_bus_get(c, bus, &error)) || dbus_error_is_set(&error)) {
         pa_log_warn("Unable to contact D-Bus: %s: %s", error.name, error.message);
         goto fail;
     }
 
-    if (dbus_bus_request_name(pa_dbus_connection_get(conn), "org.pulseaudio.Server", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error) == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
-        pa_log_debug("Got org.pulseaudio.Server!");
+    if (dbus_bus_request_name(pa_dbus_connection_get(conn), name, DBUS_NAME_FLAG_DO_NOT_QUEUE, &error) == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+        pa_log_debug("Got %s!", name);
         return conn;
     }
 
     if (dbus_error_is_set(&error))
-        pa_log_warn("Failed to acquire org.pulseaudio.Server: %s: %s", error.name, error.message);
+        pa_log_error("Failed to acquire %s: %s: %s", name, error.name, error.message);
     else
-        pa_log_warn("D-Bus name org.pulseaudio.Server already taken. Weird shit!");
+        pa_log_error("D-Bus name %s already taken.", name);
 
     /* PA cannot be started twice by the same user and hence we can
-     * ignore mostly the case that org.pulseaudio.Server is already
-     * taken. */
+     * ignore mostly the case that a name is already taken. */
 
 fail:
-
     if (conn)
         pa_dbus_connection_unref(conn);
 
@@ -384,6 +406,7 @@ int main(int argc, char *argv[]) {
     pa_daemon_conf *conf = NULL;
     pa_mainloop *mainloop = NULL;
     char *s;
+    char *configured_address;
     int r = 0, retval = 1, d = 0;
     pa_bool_t valid_pid_file = FALSE;
     pa_bool_t ltdl_init = FALSE;
@@ -391,6 +414,7 @@ int main(int argc, char *argv[]) {
     const char *e;
 #ifdef HAVE_FORK
     int daemon_pipe[2] = { -1, -1 };
+    int daemon_pipe2[2] = { -1, -1 };
 #endif
 #ifdef OS_IS_WIN32
     pa_time_event *win32_timer;
@@ -399,8 +423,14 @@ int main(int argc, char *argv[]) {
     int autospawn_fd = -1;
     pa_bool_t autospawn_locked = FALSE;
 #ifdef HAVE_DBUS
-    pa_dbus_connection *dbus = NULL;
+    pa_dbusobj_server_lookup *server_lookup = NULL; /* /org/pulseaudio/server_lookup */
+    pa_dbus_connection *lookup_service_bus = NULL; /* Always the user bus. */
+    pa_dbus_connection *server_bus = NULL; /* The bus where we reserve org.pulseaudio.Server, either the user or the system bus. */
+    pa_bool_t start_server;
 #endif
+    int fd = -1;
+
+    pa_log_warn("pulseaudio daemon start.");
 
     pa_log_set_ident("pulseaudio");
     pa_log_set_level(PA_LOG_NOTICE);
@@ -458,6 +488,9 @@ int main(int argc, char *argv[]) {
     pa_reset_personality();
     pa_drop_root();
     pa_close_all(passed_fd, -1);
+#ifndef __TIZEN__
+    pa_reset_sigs(-1);
+#endif
     pa_unblock_sigs(-1);
     pa_reset_priority();
 
@@ -485,6 +518,32 @@ int main(int argc, char *argv[]) {
         pa_log_set_flags(PA_LOG_PRINT_TIME, PA_LOG_SET);
     pa_log_set_show_backtrace(conf->log_backtrace);
 
+#ifdef HAVE_DBUS
+    /* conf->system_instance and conf->local_server_type control almost the
+     * same thing; make them agree about what is requested. */
+    switch (conf->local_server_type) {
+        case PA_SERVER_TYPE_UNSET:
+            conf->local_server_type = conf->system_instance ? PA_SERVER_TYPE_SYSTEM : PA_SERVER_TYPE_USER;
+            break;
+        case PA_SERVER_TYPE_USER:
+        case PA_SERVER_TYPE_NONE:
+            conf->system_instance = FALSE;
+            break;
+        case PA_SERVER_TYPE_SYSTEM:
+            conf->system_instance = TRUE;
+            break;
+        default:
+            pa_assert_not_reached();
+    }
+
+    start_server = conf->local_server_type == PA_SERVER_TYPE_USER || (getuid() == 0 && conf->local_server_type == PA_SERVER_TYPE_SYSTEM);
+
+    if (!start_server && conf->local_server_type == PA_SERVER_TYPE_SYSTEM) {
+        pa_log_notice(_("System mode refused for non-root user. Only starting the D-Bus server lookup service."));
+        conf->system_instance = FALSE;
+    }
+#endif
+
     LTDL_SET_PRELOADED_SYMBOLS();
     pa_ltdl_init();
     ltdl_init = TRUE;
@@ -503,7 +562,7 @@ int main(int argc, char *argv[]) {
 
     switch (conf->cmd) {
         case PA_CMD_DUMP_MODULES:
-            pa_dump_modules(conf, argc-d, argv+d);
+            // pa_dump_modules(conf, argc-d, argv+d); //for libtool 2.2
             retval = 0;
             goto finish;
 
@@ -606,18 +665,68 @@ int main(int argc, char *argv[]) {
         goto finish;
     }
 
+#ifdef HAVE_GETUID
     if (getuid() == 0 && !conf->system_instance)
         pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
+#ifndef HAVE_DBUS /* A similar, only a notice worthy check was done earlier, if D-Bus is enabled. */
     else if (getuid() != 0 && conf->system_instance) {
         pa_log(_("Root privileges required."));
         goto finish;
     }
+#endif
+#endif  /* HAVE_GETUID */
 
     if (conf->cmd == PA_CMD_START && conf->system_instance) {
         pa_log(_("--start not supported for system instances."));
         goto finish;
     }
 
+    if (conf->cmd == PA_CMD_START && (configured_address = check_configured_address())) {
+        /* There is an server address in our config, but where did it come from?
+         * By default a standard X11 login will load module-x11-publish which will
+         * inject PULSE_SERVER X11 property. If the PA daemon crashes, we will end
+         * up hitting this code path. So we have to check to see if our configured_address
+         * is the same as the value that would go into this property so that we can
+         * recover (i.e. autospawn) from a crash.
+         */
+        char *ufn;
+        pa_bool_t start_anyway = FALSE;
+
+        if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
+            char *id;
+
+            if ((id = pa_machine_id())) {
+                pa_strlist *server_list;
+                char formatted_ufn[256];
+
+                pa_snprintf(formatted_ufn, sizeof(formatted_ufn), "{%s}unix:%s", id, ufn);
+                pa_xfree(id);
+
+                if ((server_list = pa_strlist_parse(configured_address))) {
+                    char *u = NULL;
+
+                    /* We only need to check the first server */
+                    server_list = pa_strlist_pop(server_list, &u);
+                    pa_strlist_free(server_list);
+
+                    start_anyway = (u && pa_streq(formatted_ufn, u));
+                    pa_xfree(u);
+                }
+            }
+            pa_xfree(ufn);
+        }
+
+        if (!start_anyway) {
+            pa_log_notice(_("User-configured server at %s, refusing to start/autospawn."), configured_address);
+            pa_xfree(configured_address);
+            retval = 0;
+            goto finish;
+        }
+
+        pa_log_notice(_("User-configured server at %s, which appears to be local. Probing deeper."), configured_address);
+        pa_xfree(configured_address);
+    }
+
     if (conf->system_instance && !conf->disallow_exit)
         pa_log_warn(_("Running in system mode, but --disallow-exit not set!"));
 
@@ -653,8 +762,9 @@ int main(int argc, char *argv[]) {
     }
 
     if (conf->daemonize) {
+#ifdef HAVE_FORK
         pid_t child;
-        int tty_fd;
+#endif
 
         if (pa_stdio_acquire() < 0) {
             pa_log(_("Failed to acquire stdio."));
@@ -663,12 +773,13 @@ int main(int argc, char *argv[]) {
 
 #ifdef HAVE_FORK
         if (pipe(daemon_pipe) < 0) {
-            pa_log(_("pipe failed: %s"), pa_cstrerror(errno));
+            pa_log(_("pipe() failed: %s"), pa_cstrerror(errno));
             goto finish;
         }
 
         if ((child = fork()) < 0) {
             pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
+            pa_close_pipe(daemon_pipe);
             goto finish;
         }
 
@@ -714,22 +825,60 @@ int main(int argc, char *argv[]) {
             pa_log_set_target(PA_LOG_SYSLOG);
 
 #ifdef HAVE_SETSID
-        setsid();
-#endif
-#ifdef HAVE_SETPGID
-        setpgid(0,0);
+        if (setsid() < 0) {
+            pa_log(_("setsid() failed: %s"), pa_cstrerror(errno));
+            goto finish;
+        }
 #endif
 
-#ifndef OS_IS_WIN32
-        pa_close(0);
-        pa_close(1);
-        pa_close(2);
+#ifdef HAVE_FORK
+        /* We now are a session and process group leader. Let's fork
+         * again and let the father die, so that we'll become a
+         * process that can never acquire a TTY again, in a session and
+         * process group without leader */
 
-        pa_assert_se(open("/dev/null", O_RDONLY) == 0);
-        pa_assert_se(open("/dev/null", O_WRONLY) == 1);
-        pa_assert_se(open("/dev/null", O_WRONLY) == 2);
-#else
-        FreeConsole();
+        if (pipe(daemon_pipe2) < 0) {
+            pa_log(_("pipe() failed: %s"), pa_cstrerror(errno));
+            goto finish;
+        }
+
+        if ((child = fork()) < 0) {
+            pa_log(_("fork() failed: %s"), pa_cstrerror(errno));
+            pa_close_pipe(daemon_pipe2);
+            goto finish;
+        }
+
+        if (child != 0) {
+            ssize_t n;
+            /* Father */
+
+            pa_assert_se(pa_close(daemon_pipe2[1]) == 0);
+            daemon_pipe2[1] = -1;
+
+            if ((n = pa_loop_read(daemon_pipe2[0], &retval, sizeof(retval), NULL)) != sizeof(retval)) {
+
+                if (n < 0)
+                    pa_log(_("read() failed: %s"), pa_cstrerror(errno));
+
+                retval = 1;
+            }
+
+            /* We now have to take care of signalling the first fork with
+             * the return value we've received from this fork... */
+            pa_assert(daemon_pipe[1] >= 0);
+
+            pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
+            pa_close(daemon_pipe[1]);
+            daemon_pipe[1] = -1;
+
+            goto finish;
+        }
+
+        pa_assert_se(pa_close(daemon_pipe2[0]) == 0);
+        daemon_pipe2[0] = -1;
+
+        /* We no longer need the (first) daemon_pipe as it's handled in our child above */
+        pa_close_pipe(daemon_pipe);
 #endif
 
 #ifdef SIGTTOU
@@ -742,12 +891,7 @@ int main(int argc, char *argv[]) {
         signal(SIGTSTP, SIG_IGN);
 #endif
 
-#ifdef TIOCNOTTY
-        if ((tty_fd = open("/dev/tty", O_RDWR)) >= 0) {
-            ioctl(tty_fd, TIOCNOTTY, (char*) 0);
-            pa_assert_se(pa_close(tty_fd) == 0);
-        }
-#endif
+        pa_nullify_stdfds();
     }
 
     pa_set_env_and_record("PULSE_INTERNAL", "1");
@@ -866,7 +1010,7 @@ int main(int argc, char *argv[]) {
         if (mlockall(MCL_FUTURE) < 0)
             pa_log_warn("mlockall() failed: %s", pa_cstrerror(errno));
         else
-            pa_log_info("Sucessfully locked process into memory.");
+            pa_log_info("Successfully locked process into memory.");
 #else
         pa_log_warn("Memory locking requested but not supported on platform.");
 #endif
@@ -874,11 +1018,6 @@ int main(int argc, char *argv[]) {
 
     pa_memtrap_install();
 
-    if (!getenv("PULSE_NO_SIMD")) {
-        pa_cpu_init_x86();
-        pa_cpu_init_arm();
-    }
-
     pa_assert_se(mainloop = pa_mainloop_new());
 
     if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm, conf->shm_size))) {
@@ -887,9 +1026,12 @@ int main(int argc, char *argv[]) {
     }
 
     c->default_sample_spec = conf->default_sample_spec;
+    c->alternate_sample_rate = conf->alternate_sample_rate;
     c->default_channel_map = conf->default_channel_map;
     c->default_n_fragments = conf->default_n_fragments;
     c->default_fragment_size_msec = conf->default_fragment_size_msec;
+    c->deferred_volume_safety_margin_usec = conf->deferred_volume_safety_margin_usec;
+    c->deferred_volume_extra_delay_usec = conf->deferred_volume_extra_delay_usec;
     c->exit_idle_time = conf->exit_idle_time;
     c->scache_idle_time = conf->scache_idle_time;
     c->resample_method = conf->resample_method;
@@ -897,9 +1039,22 @@ int main(int argc, char *argv[]) {
     c->realtime_scheduling = !!conf->realtime_scheduling;
     c->disable_remixing = !!conf->disable_remixing;
     c->disable_lfe_remixing = !!conf->disable_lfe_remixing;
+    c->deferred_volume = !!conf->deferred_volume;
     c->running_as_daemon = !!conf->daemonize;
     c->disallow_exit = conf->disallow_exit;
     c->flat_volumes = conf->flat_volumes;
+#ifdef HAVE_DBUS
+    c->server_type = conf->local_server_type;
+#endif
+
+    c->cpu_info.cpu_type = PA_CPU_UNDEFINED;
+    if (!getenv("PULSE_NO_SIMD")) {
+        if (pa_cpu_init_x86(&(c->cpu_info.flags.x86)))
+            c->cpu_info.cpu_type = PA_CPU_X86;
+        if (pa_cpu_init_arm(&(c->cpu_info.flags.arm)))
+            c->cpu_info.cpu_type = PA_CPU_ARM;
+       pa_cpu_init_orc(c->cpu_info);
+    }
 
     pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0);
     pa_signal_new(SIGINT, signal_callback, c);
@@ -915,67 +1070,102 @@ int main(int argc, char *argv[]) {
 #endif
 
 #ifdef OS_IS_WIN32
-    win32_timer = pa_mainloop_get_api(mainloop)->rtclock_time_new(pa_mainloop_get_api(mainloop), pa_gettimeofday(&win32_tv), message_cb, NULL);
+    win32_timer = pa_mainloop_get_api(mainloop)->time_new(pa_mainloop_get_api(mainloop), pa_gettimeofday(&win32_tv), message_cb, NULL);
 #endif
 
     if (!conf->no_cpu_limit)
         pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop)) == 0);
 
     buf = pa_strbuf_new();
-    if (conf->load_default_script_file) {
-        FILE *f;
 
-        if ((f = pa_daemon_conf_open_default_script_file(conf))) {
-            r = pa_cli_command_execute_file_stream(c, f, buf, &conf->fail);
-            fclose(f);
+#ifdef HAVE_DBUS
+    pa_assert_se(dbus_threads_init_default());
+
+    if (start_server) {
+#endif
+        if (conf->load_default_script_file) {
+            FILE *f;
+
+            if ((f = pa_daemon_conf_open_default_script_file(conf))) {
+                r = pa_cli_command_execute_file_stream(c, f, buf, &conf->fail);
+                fclose(f);
+            }
         }
-    }
 
-    if (r >= 0)
-        r = pa_cli_command_execute(c, conf->script_commands, buf, &conf->fail);
+        if (r >= 0)
+            r = pa_cli_command_execute(c, conf->script_commands, buf, &conf->fail);
 
-    pa_log_error("%s", s = pa_strbuf_tostring_free(buf));
-    pa_xfree(s);
+        pa_log_error("%s", s = pa_strbuf_tostring_free(buf));
+        pa_xfree(s);
+
+        if (r < 0 && conf->fail) {
+            pa_log(_("Failed to initialize daemon."));
+            goto finish;
+        }
+
+        if (!c->modules || pa_idxset_size(c->modules) == 0) {
+            pa_log(_("Daemon startup without any loaded modules, refusing to work."));
+            goto finish;
+        }
+#ifdef HAVE_DBUS
+    } else {
+        /* When we just provide the D-Bus server lookup service, we don't want
+         * any modules to be loaded. We haven't loaded any so far, so one might
+         * think there's no way to contact the server, but receiving certain
+         * signals could still cause modules to load. */
+        conf->disallow_module_loading = TRUE;
+    }
+#endif
 
     /* We completed the initial module loading, so let's disable it
      * from now on, if requested */
     c->disallow_module_loading = !!conf->disallow_module_loading;
 
-    if (r < 0 && conf->fail) {
-        pa_log(_("Failed to initialize daemon."));
-        goto finish;
+#ifdef HAVE_DBUS
+    if (!conf->system_instance) {
+        if ((server_lookup = pa_dbusobj_server_lookup_new(c))) {
+            if (!(lookup_service_bus = register_dbus_name(c, DBUS_BUS_SESSION, "org.PulseAudio1")))
+                goto finish;
+        }
     }
 
-    if (!c->modules || pa_idxset_size(c->modules) == 0) {
-        pa_log(_("Daemon startup without any loaded modules, refusing to work."));
-        goto finish;
-    }
+    if (start_server)
+        server_bus = register_dbus_name(c, conf->system_instance ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, "org.pulseaudio.Server");
+#endif
 
 #ifdef HAVE_FORK
-    if (daemon_pipe[1] >= 0) {
+    if (daemon_pipe2[1] >= 0) {
         int ok = 0;
-        pa_loop_write(daemon_pipe[1], &ok, sizeof(ok), NULL);
-        pa_close(daemon_pipe[1]);
-        daemon_pipe[1] = -1;
+        pa_loop_write(daemon_pipe2[1], &ok, sizeof(ok), NULL);
+        pa_close(daemon_pipe2[1]);
+        daemon_pipe2[1] = -1;
     }
 #endif
 
-#ifdef HAVE_DBUS
-    dbus = register_dbus(c);
-#endif
+    pa_log_warn("Daemon startup complete.");
 
-    pa_log_info(_("Daemon startup complete."));
+    /* broadcast if we're ready */
+    if ((fd = creat(PA_READY, 0644)) != -1) {
+        close (fd);
+        pa_log_warn("PA_READY(/tmp/.pa_ready) file was created");
+    }
 
     retval = 0;
-    if (pa_mainloop_run(mainloop, &retval) < 0)
+    if (pa_mainloop_run(mainloop, &retval) < 0) {
+        pa_log_error("pulseaudio daemon mainloop crash.");
         goto finish;
+    }
 
-    pa_log_info(_("Daemon shutdown initiated."));
+    pa_log_error("Daemon shutdown initiated.");
 
 finish:
 #ifdef HAVE_DBUS
-    if (dbus)
-        pa_dbus_connection_unref(dbus);
+    if (server_bus)
+        pa_dbus_connection_unref(server_bus);
+    if (lookup_service_bus)
+        pa_dbus_connection_unref(lookup_service_bus);
+    if (server_lookup)
+        pa_dbusobj_server_lookup_free(server_lookup);
 #endif
 
     if (autospawn_fd >= 0) {
@@ -986,11 +1176,16 @@ finish:
     }
 
 #ifdef OS_IS_WIN32
-    if (win32_timer)
+    if (mainloop && win32_timer)
         pa_mainloop_get_api(mainloop)->time_free(win32_timer);
 #endif
 
     if (c) {
+        /* Ensure all the modules/samples are unloaded when the core is still ref'ed,
+         * as unlink callback hooks in modules may need the core to be ref'ed */
+        pa_module_unload_all(c);
+        pa_scache_free_all(c);
+
         pa_core_unref(c);
         pa_log_info(_("Daemon terminated."));
     }
@@ -1001,9 +1196,14 @@ finish:
     pa_signal_done();
 
 #ifdef HAVE_FORK
+    /* If we have daemon_pipe[1] still open, this means we've failed after
+     * the first fork, but before the second. Therefore just write to it. */
     if (daemon_pipe[1] >= 0)
         pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL);
+    else if (daemon_pipe2[1] >= 0)
+        pa_loop_write(daemon_pipe2[1], &retval, sizeof(retval), NULL);
 
+    pa_close_pipe(daemon_pipe2);
     pa_close_pipe(daemon_pipe);
 #endif
 
index edddaf9..1eee879 100644 (file)
@@ -28,10 +28,6 @@ USA.
 
   <policy user="pulse">
     <allow own="org.pulseaudio.Server"/>
-
-    <!-- Allow pulseaudio to talk to HAL for device detection -->
-    <allow send_destination="org.freedesktop.Hal" send_interface="org.freedesktop.Hal.Manager"/>
-    <allow send_destination="org.freedesktop.Hal" send_interface="org.freedesktop.Hal.Device"/>
   </policy>
 
 </busconfig>
index 99bdbd0..b75b378 100644 (file)
@@ -8,3 +8,4 @@ Terminal=false
 Type=Application
 Categories=
 GenericName=
+X-GNOME-Autostart-Phase=Initialization
diff --git a/src/daemon/server-lookup.c b/src/daemon/server-lookup.c
new file mode 100644 (file)
index 0000000..9bdc699
--- /dev/null
@@ -0,0 +1,522 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dbus/dbus.h>
+
+#include <pulse/client-conf.h>
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/core.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-shared.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/protocol-dbus.h>
+
+#include "server-lookup.h"
+
+#define OBJECT_PATH "/org/pulseaudio/server_lookup1"
+#define INTERFACE "org.PulseAudio.ServerLookup1"
+
+struct pa_dbusobj_server_lookup {
+    pa_core *core;
+    pa_dbus_connection *conn;
+    pa_bool_t path_registered;
+};
+
+static const char introspection[] =
+    DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
+    "<node>"
+    " <!-- If you are looking for documentation make sure to check out\n"
+    "      http://pulseaudio.org/wiki/DBusInterface -->\n"
+    " <interface name=\"" INTERFACE "\">\n"
+    "  <property name=\"Address\" type=\"s\" access=\"read\"/>\n"
+    " </interface>\n"
+    " <interface name=\"" DBUS_INTERFACE_INTROSPECTABLE "\">\n"
+    "  <method name=\"Introspect\">\n"
+    "   <arg name=\"data\" type=\"s\" direction=\"out\"/>\n"
+    "  </method>\n"
+    " </interface>\n"
+    " <interface name=\"" DBUS_INTERFACE_PROPERTIES "\">\n"
+    "  <method name=\"Get\">\n"
+    "   <arg name=\"interface_name\" type=\"s\" direction=\"in\"/>\n"
+    "   <arg name=\"property_name\" type=\"s\" direction=\"in\"/>\n"
+    "   <arg name=\"value\" type=\"v\" direction=\"out\"/>\n"
+    "  </method>\n"
+    "  <method name=\"Set\">\n"
+    "   <arg name=\"interface_name\" type=\"s\" direction=\"in\"/>\n"
+    "   <arg name=\"property_name\" type=\"s\" direction=\"in\"/>\n"
+    "   <arg name=\"value\" type=\"v\" direction=\"in\"/>\n"
+    "  </method>\n"
+    "  <method name=\"GetAll\">\n"
+    "   <arg name=\"interface_name\" type=\"s\" direction=\"in\"/>\n"
+    "   <arg name=\"props\" type=\"a{sv}\" direction=\"out\"/>\n"
+    "  </method>\n"
+    " </interface>\n"
+    "</node>\n";
+
+static void unregister_cb(DBusConnection *conn, void *user_data) {
+    pa_dbusobj_server_lookup *sl = user_data;
+
+    pa_assert(sl);
+    pa_assert(sl->path_registered);
+
+    sl->path_registered = FALSE;
+}
+
+static DBusHandlerResult handle_introspect(DBusConnection *conn, DBusMessage *msg, pa_dbusobj_server_lookup *sl) {
+    DBusHandlerResult r = DBUS_HANDLER_RESULT_HANDLED;
+    const char *i = introspection;
+    DBusMessage *reply = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+
+    if (!(reply = dbus_message_new_method_return(msg))) {
+        r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+        goto finish;
+    }
+    if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &i, DBUS_TYPE_INVALID)) {
+        r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+        goto finish;
+    }
+    if (!dbus_connection_send(conn, reply, NULL)) {
+        r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+        goto finish;
+    }
+
+finish:
+    if (reply)
+        dbus_message_unref(reply);
+
+    return r;
+}
+
+enum get_address_result_t {
+    SUCCESS,
+    FAILED_TO_LOAD_CLIENT_CONF,
+    SERVER_FROM_TYPE_FAILED
+};
+
+/* Caller frees the returned address. */
+static enum get_address_result_t get_address(pa_server_type_t server_type, char **address) {
+    enum get_address_result_t r = SUCCESS;
+    pa_client_conf *conf = pa_client_conf_new();
+
+    *address = NULL;
+
+    if (pa_client_conf_load(conf, NULL) < 0) {
+        r = FAILED_TO_LOAD_CLIENT_CONF;
+        goto finish;
+    }
+
+    if (conf->default_dbus_server)
+        *address = pa_xstrdup(conf->default_dbus_server);
+    else if (!(*address = pa_get_dbus_address_from_server_type(server_type))) {
+        r = SERVER_FROM_TYPE_FAILED;
+        goto finish;
+    }
+
+finish:
+    pa_client_conf_free(conf);
+    return r;
+}
+
+static DBusHandlerResult handle_get_address(DBusConnection *conn, DBusMessage *msg, pa_dbusobj_server_lookup *sl) {
+    DBusHandlerResult r = DBUS_HANDLER_RESULT_HANDLED;
+    DBusMessage *reply = NULL;
+    char *address = NULL;
+    DBusMessageIter msg_iter;
+    DBusMessageIter variant_iter;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(sl);
+
+    switch (get_address(sl->core->server_type, &address)) {
+        case SUCCESS:
+            if (!(reply = dbus_message_new_method_return(msg))) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            dbus_message_iter_init_append(reply, &msg_iter);
+            if (!dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_VARIANT, "s", &variant_iter)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            if (!dbus_message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &address)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            if (!dbus_message_iter_close_container(&msg_iter, &variant_iter)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            if (!dbus_connection_send(conn, reply, NULL)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            r = DBUS_HANDLER_RESULT_HANDLED;
+            goto finish;
+
+        case FAILED_TO_LOAD_CLIENT_CONF:
+            if (!(reply = dbus_message_new_error(msg, "org.pulseaudio.ClientConfLoadError", "Failed to load client.conf."))) {
+                r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+                goto finish;
+            }
+            if (!dbus_connection_send(conn, reply, NULL)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            r = DBUS_HANDLER_RESULT_HANDLED;
+            goto finish;
+
+        case SERVER_FROM_TYPE_FAILED:
+            if (!(reply = dbus_message_new_error(msg, DBUS_ERROR_FAILED, "PulseAudio internal error: get_dbus_server_from_type() failed."))) {
+                r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+                goto finish;
+            }
+            if (!dbus_connection_send(conn, reply, NULL)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            r = DBUS_HANDLER_RESULT_HANDLED;
+            goto finish;
+
+        default:
+            pa_assert_not_reached();
+    }
+
+finish:
+    pa_xfree(address);
+    if (reply)
+        dbus_message_unref(reply);
+
+    return r;
+}
+
+static DBusHandlerResult handle_get(DBusConnection *conn, DBusMessage *msg, pa_dbusobj_server_lookup *sl) {
+    DBusHandlerResult r = DBUS_HANDLER_RESULT_HANDLED;
+    const char* interface;
+    const char* property;
+    DBusMessage *reply = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(sl);
+
+    if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID)) {
+        if (!(reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, "Invalid arguments"))) {
+            r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+            goto finish;
+        }
+        if (!dbus_connection_send(conn, reply, NULL)) {
+            r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+            goto finish;
+        }
+        r = DBUS_HANDLER_RESULT_HANDLED;
+        goto finish;
+    }
+
+    if (*interface && !pa_streq(interface, INTERFACE)) {
+        r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+        goto finish;
+    }
+
+    if (!pa_streq(property, "Address")) {
+        if (!(reply = dbus_message_new_error_printf(msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "%s: No such property", property))) {
+            r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+            goto finish;
+        }
+        if (!dbus_connection_send(conn, reply, NULL)) {
+            r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+            goto finish;
+        }
+        r = DBUS_HANDLER_RESULT_HANDLED;
+        goto finish;
+    }
+
+    r = handle_get_address(conn, msg, sl);
+
+finish:
+    if (reply)
+        dbus_message_unref(reply);
+
+    return r;
+}
+
+static DBusHandlerResult handle_set(DBusConnection *conn, DBusMessage *msg, pa_dbusobj_server_lookup *sl) {
+    DBusHandlerResult r = DBUS_HANDLER_RESULT_HANDLED;
+    const char* interface;
+    const char* property;
+    DBusMessage *reply = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(sl);
+
+    if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID)) {
+        if (!(reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, "Invalid arguments"))) {
+            r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+            goto finish;
+        }
+        if (!dbus_connection_send(conn, reply, NULL)) {
+            r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+            goto finish;
+        }
+        r = DBUS_HANDLER_RESULT_HANDLED;
+        goto finish;
+    }
+
+    if (*interface && !pa_streq(interface, INTERFACE)) {
+        r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+        goto finish;
+    }
+
+    if (!pa_streq(property, "Address")) {
+        if (!(reply = dbus_message_new_error_printf(msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "%s: No such property", property))) {
+            r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+            goto finish;
+        }
+        if (!dbus_connection_send(conn, reply, NULL)) {
+            r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+            goto finish;
+        }
+        r = DBUS_HANDLER_RESULT_HANDLED;
+        goto finish;
+    }
+
+    if (!(reply = dbus_message_new_error_printf(msg, DBUS_ERROR_ACCESS_DENIED, "%s: Property not settable", property))) {
+        r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+        goto finish;
+    }
+    if (!dbus_connection_send(conn, reply, NULL)) {
+        r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+        goto finish;
+    }
+    r = DBUS_HANDLER_RESULT_HANDLED;
+
+finish:
+    if (reply)
+        dbus_message_unref(reply);
+
+    return r;
+}
+
+static DBusHandlerResult handle_get_all(DBusConnection *conn, DBusMessage *msg, pa_dbusobj_server_lookup *sl) {
+    DBusHandlerResult r = DBUS_HANDLER_RESULT_HANDLED;
+    DBusMessage *reply = NULL;
+    const char *property = "Address";
+    char *interface = NULL;
+    char *address = NULL;
+    DBusMessageIter msg_iter;
+    DBusMessageIter dict_iter;
+    DBusMessageIter dict_entry_iter;
+    DBusMessageIter variant_iter;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(sl);
+
+    if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &interface, DBUS_TYPE_INVALID)) {
+        if (!(reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, "Invalid arguments"))) {
+            r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+            goto finish;
+        }
+        if (!dbus_connection_send(conn, reply, NULL)) {
+            r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+            goto finish;
+        }
+        r = DBUS_HANDLER_RESULT_HANDLED;
+        goto finish;
+    }
+
+    switch (get_address(sl->core->server_type, &address)) {
+        case SUCCESS:
+            if (!(reply = dbus_message_new_method_return(msg))) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            dbus_message_iter_init_append(reply, &msg_iter);
+            if (!dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            if (!dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            if (!dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &property)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            if (!dbus_message_iter_open_container(&dict_entry_iter, DBUS_TYPE_VARIANT, "s", &variant_iter)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            if (!dbus_message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &address)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            if (!dbus_message_iter_close_container(&dict_entry_iter, &variant_iter)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            if (!dbus_message_iter_close_container(&dict_iter, &dict_entry_iter)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            if (!dbus_message_iter_close_container(&msg_iter, &dict_iter)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            if (!dbus_connection_send(conn, reply, NULL)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            r = DBUS_HANDLER_RESULT_HANDLED;
+            goto finish;
+
+        case FAILED_TO_LOAD_CLIENT_CONF:
+            if (!(reply = dbus_message_new_error(msg, "org.pulseaudio.ClientConfLoadError", "Failed to load client.conf."))) {
+                r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+                goto finish;
+            }
+            if (!dbus_connection_send(conn, reply, NULL)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            r = DBUS_HANDLER_RESULT_HANDLED;
+            goto finish;
+
+        case SERVER_FROM_TYPE_FAILED:
+            if (!(reply = dbus_message_new_error(msg, DBUS_ERROR_FAILED, "PulseAudio internal error: get_dbus_server_from_type() failed."))) {
+                r = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+                goto finish;
+            }
+            if (!dbus_connection_send(conn, reply, NULL)) {
+                r = DBUS_HANDLER_RESULT_NEED_MEMORY;
+                goto finish;
+            }
+            r = DBUS_HANDLER_RESULT_HANDLED;
+            goto finish;
+
+        default:
+            pa_assert_not_reached();
+    }
+
+finish:
+    pa_xfree(address);
+    if (reply)
+        dbus_message_unref(reply);
+
+    return r;
+}
+
+static DBusHandlerResult message_cb(DBusConnection *conn, DBusMessage *msg, void *user_data) {
+    pa_dbusobj_server_lookup *sl = user_data;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(sl);
+
+    /* pa_log("Got message! type = %s   path = %s   iface = %s   member = %s   dest = %s", dbus_message_type_to_string(dbus_message_get_type(msg)), dbus_message_get_path(msg), dbus_message_get_interface(msg), dbus_message_get_member(msg), dbus_message_get_destination(msg)); */
+
+    if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_METHOD_CALL)
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    if (dbus_message_is_method_call(msg, DBUS_INTERFACE_INTROSPECTABLE, "Introspect") ||
+        (!dbus_message_get_interface(msg) && dbus_message_has_member(msg, "Introspect")))
+        return handle_introspect(conn, msg, sl);
+
+    if (dbus_message_is_method_call(msg, DBUS_INTERFACE_PROPERTIES, "Get") ||
+        (!dbus_message_get_interface(msg) && dbus_message_has_member(msg, "Get")))
+        return handle_get(conn, msg, sl);
+
+    if (dbus_message_is_method_call(msg, DBUS_INTERFACE_PROPERTIES, "Set") ||
+        (!dbus_message_get_interface(msg) && dbus_message_has_member(msg, "Set")))
+        return handle_set(conn, msg, sl);
+
+    if (dbus_message_is_method_call(msg, DBUS_INTERFACE_PROPERTIES, "GetAll") ||
+        (!dbus_message_get_interface(msg) && dbus_message_has_member(msg, "GetAll")))
+        return handle_get_all(conn, msg, sl);
+
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static DBusObjectPathVTable vtable = {
+    .unregister_function = unregister_cb,
+    .message_function = message_cb,
+    .dbus_internal_pad1 = NULL,
+    .dbus_internal_pad2 = NULL,
+    .dbus_internal_pad3 = NULL,
+    .dbus_internal_pad4 = NULL
+};
+
+pa_dbusobj_server_lookup *pa_dbusobj_server_lookup_new(pa_core *c) {
+    pa_dbusobj_server_lookup *sl;
+    DBusError error;
+
+    dbus_error_init(&error);
+
+    sl = pa_xnew(pa_dbusobj_server_lookup, 1);
+    sl->core = c;
+    sl->path_registered = FALSE;
+
+    if (!(sl->conn = pa_dbus_bus_get(c, DBUS_BUS_SESSION, &error)) || dbus_error_is_set(&error)) {
+        pa_log_warn("Unable to contact D-Bus: %s: %s", error.name, error.message);
+        goto fail;
+    }
+
+    if (!dbus_connection_register_object_path(pa_dbus_connection_get(sl->conn), OBJECT_PATH, &vtable, sl)) {
+        pa_log("dbus_connection_register_object_path() failed for " OBJECT_PATH ".");
+        goto fail;
+    }
+
+    sl->path_registered = TRUE;
+
+    return sl;
+
+fail:
+    dbus_error_free(&error);
+
+    pa_dbusobj_server_lookup_free(sl);
+
+    return NULL;
+}
+
+void pa_dbusobj_server_lookup_free(pa_dbusobj_server_lookup *sl) {
+    pa_assert(sl);
+
+    if (sl->path_registered) {
+        pa_assert(sl->conn);
+        if (!dbus_connection_unregister_object_path(pa_dbus_connection_get(sl->conn), OBJECT_PATH))
+            pa_log_debug("dbus_connection_unregister_object_path() failed for " OBJECT_PATH ".");
+    }
+
+    if (sl->conn)
+        pa_dbus_connection_unref(sl->conn);
+
+    pa_xfree(sl);
+}
diff --git a/src/daemon/server-lookup.h b/src/daemon/server-lookup.h
new file mode 100644 (file)
index 0000000..c930d5b
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef fooserverlookuphfoo
+#define fooserverlookuphfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+/* This object implements the D-Bus object at path
+ * /org/pulseaudio/server_lookup. Implemented interfaces
+ * are org.pulseaudio.ServerLookup and org.freedesktop.DBus.Introspectable.
+ *
+ * See http://pulseaudio.org/wiki/DBusInterface for the ServerLookup interface
+ * documentation.
+ */
+
+#include <pulsecore/core.h>
+
+typedef struct pa_dbusobj_server_lookup pa_dbusobj_server_lookup;
+
+pa_dbusobj_server_lookup *pa_dbusobj_server_lookup_new(pa_core *c);
+void pa_dbusobj_server_lookup_free(pa_dbusobj_server_lookup *sl);
+
+#endif
index c57c489..391a6d3 100755 (executable)
@@ -19,8 +19,6 @@
 
 set -e
 
-[ -z "$PULSE_SERVER" ]
-
 @PA_BINARY@ --start "$@"
 
 if [ x"$DISPLAY" != x ] ; then
index 4485ef9..e881a12 100755 (executable)
 
 # This startup script is used only if PulseAudio is started in system
 # mode.
+changequote(`[', `]')dnl Set up m4 quoting
 
 ### Automatically load driver modules depending on the hardware available
+ifelse(@HAVE_UDEV@, 1, [dnl
+.ifexists module-udev-detect@PA_SOEXT@
+load-module module-udev-detect
+.else
+], @HAVE_HAL@, 1, [dnl
 .ifexists module-hal-detect@PA_SOEXT@
-#load-module module-hal-detect
+load-module module-hal-detect
 .else
-### Alternatively use the static hardware detection module (for systems that
-### lack HAL support)
+], [dnl
+.ifexists module-detect@PA_SOEXT@
+])dnl
+### Use the static hardware detection module (for systems that lack udev/hal support)
 load-module module-detect
 .endif
 
@@ -34,18 +42,21 @@ load-module module-esound-protocol-unix
 .endif
 load-module module-native-protocol-unix
 
-load-module module-bluetooth-discover
-
-### Custom policy module to route between bt<=speaker
-load-module module-policy
-
 ### Automatically restore the volume of streams and devices
-#load-module module-stream-restore
-#load-module module-device-restore
+load-module module-stream-restore
+load-module module-device-restore
 
-### Automatically restore the default sink/source when changed by the user during runtime
+### Automatically restore the default sink/source when changed by the user
+### during runtime
+### NOTE: This should be loaded as early as possible so that subsequent modules
+### that look up the default sink/source get the right value
 load-module module-default-device-restore
 
+.ifexists module-dbus-protocol@PA_SOEXT@
+### If you want to allow TCP connections, set access to "remote" or "local,remote".
+load-module module-dbus-protocol access=local
+.endif
+
 ### Automatically move streams to the default sink if the sink they are
 ### connected to dies, similar for sources
 load-module module-rescue-streams
@@ -57,9 +68,4 @@ load-module module-always-sink
 load-module module-suspend-on-idle
 
 ### Enable positioned event sounds
-#load-module module-position-event-sounds
-
-### Set default source (not to use alsa_sink monitor which is index 0)
-set-default-source alsa_input.0.analog-stereo
-
-load-module module-remap-sink sink_name=mono_alsa master=alsa_output.0.analog-stereo channels=1
+load-module module-position-event-sounds
index 537024d..acd2d14 100644 (file)
@@ -65,7 +65,9 @@ pa_context_get_source_info_by_name;
 pa_context_get_source_info_list;
 pa_context_get_source_output_info;
 pa_context_get_source_output_info_list;
+pa_context_set_port_latency_offset;
 pa_context_get_state;
+pa_context_get_tile_size;
 pa_context_is_local;
 pa_context_is_pending;
 pa_context_kill_client;
@@ -91,6 +93,9 @@ pa_context_rttime_restart;
 pa_context_set_card_profile_by_index;
 pa_context_set_card_profile_by_name;
 pa_context_set_default_sink;
+pa_context_set_cork_all;
+pa_context_set_default_sink_by_api_bus;
+pa_context_set_default_sink_for_usb;
 pa_context_set_default_source;
 pa_context_set_event_callback;
 pa_context_set_name;
@@ -102,6 +107,8 @@ pa_context_set_sink_port_by_index;
 pa_context_set_sink_port_by_name;
 pa_context_set_sink_volume_by_index;
 pa_context_set_sink_volume_by_name;
+pa_context_set_source_output_mute;
+pa_context_set_source_output_volume;
 pa_context_set_source_mute_by_index;
 pa_context_set_source_mute_by_name;
 pa_context_set_source_port_by_index;
@@ -129,6 +136,7 @@ pa_cvolume_get_balance;
 pa_cvolume_get_fade;
 pa_cvolume_get_position;
 pa_cvolume_inc;
+pa_cvolume_inc_clamp;
 pa_cvolume_init;
 pa_cvolume_max;
 pa_cvolume_max_mask;
@@ -144,6 +152,7 @@ pa_cvolume_set_fade;
 pa_cvolume_set_position;
 pa_cvolume_snprint;
 pa_cvolume_valid;
+pa_encoding_to_string;
 pa_ext_device_manager_delete;
 pa_ext_device_manager_enable_role_device_priority_routing;
 pa_ext_device_manager_read;
@@ -152,6 +161,12 @@ pa_ext_device_manager_set_device_description;
 pa_ext_device_manager_set_subscribe_cb;
 pa_ext_device_manager_subscribe;
 pa_ext_device_manager_test;
+pa_ext_device_restore_read_formats;
+pa_ext_device_restore_read_formats_all;
+pa_ext_device_restore_save_formats;
+pa_ext_device_restore_set_subscribe_cb;
+pa_ext_device_restore_subscribe;
+pa_ext_device_restore_test;
 pa_ext_stream_restore_delete;
 pa_ext_stream_restore_read;
 pa_ext_stream_restore_set_subscribe_cb;
@@ -160,6 +175,51 @@ pa_ext_stream_restore_test;
 pa_ext_stream_restore_write;
 pa_ext_policy_test;
 pa_ext_policy_set_mono;
+pa_ext_policy_set_surround_sound;
+pa_ext_policy_unload_hdmi;
+pa_ext_echo_cancel_set_volume;
+pa_ext_echo_cancel_set_device;
+pa_ext_policy_set_balance;
+pa_ext_policy_set_muteall;
+pa_ext_policy_set_use_case;
+pa_ext_policy_set_session;
+pa_ext_policy_set_subsession;
+pa_ext_policy_set_active_device;
+pa_ext_policy_reset;
+pa_ext_policy_get_volume_level_max;
+pa_ext_policy_get_volume_level;
+pa_ext_policy_set_volume_level;
+pa_ext_policy_update_volume;
+pa_ext_policy_get_mute
+pa_ext_policy_set_mute;
+pa_ext_suspend_on_idle_set_info;
+pa_ext_suspend_on_idle_update_scn;
+pa_format_info_copy;
+pa_format_info_free;
+pa_format_info_from_string;
+pa_format_info_from_sample_spec;
+pa_format_info_get_prop_type;
+pa_format_info_get_prop_int;
+pa_format_info_get_prop_int_range;
+pa_format_info_get_prop_int_array;
+pa_format_info_get_prop_string;
+pa_format_info_get_prop_string_array;
+pa_format_info_free_string_array;
+pa_format_info_is_compatible;
+pa_format_info_is_pcm;
+pa_format_info_new;
+pa_format_info_set_channel_map;
+pa_format_info_set_channels;
+pa_format_info_set_prop_int;
+pa_format_info_set_prop_int_array;
+pa_format_info_set_prop_int_range;
+pa_format_info_set_prop_string;
+pa_format_info_set_prop_string_array;
+pa_format_info_set_rate;
+pa_format_info_set_sample_format;
+pa_format_info_snprint;
+pa_format_info_to_sample_spec;
+pa_format_info_valid;
 pa_frame_size;
 pa_get_binary_name;
 pa_get_fqdn;
@@ -189,18 +249,21 @@ pa_msleep;
 pa_operation_cancel;
 pa_operation_get_state;
 pa_operation_ref;
+pa_operation_set_state_callback;
 pa_operation_unref;
 pa_parse_sample_format;
 pa_path_get_filename;
 pa_proplist_clear;
 pa_proplist_contains;
 pa_proplist_copy;
+pa_proplist_equal;
 pa_proplist_free;
 pa_proplist_from_string;
 pa_proplist_get;
 pa_proplist_gets;
 pa_proplist_isempty;
 pa_proplist_iterate;
+pa_proplist_key_valid;
 pa_proplist_new;
 pa_proplist_set;
 pa_proplist_setf;
@@ -232,6 +295,7 @@ pa_simple_flush;
 pa_simple_mute;
 pa_simple_free;
 pa_simple_get_latency;
+pa_simple_get_final_latency;
 pa_simple_new;
 pa_simple_new_proplist;
 pa_simple_read;
@@ -256,6 +320,7 @@ pa_stream_get_channel_map;
 pa_stream_get_context;
 pa_stream_get_device_index;
 pa_stream_get_device_name;
+pa_stream_get_format_info;
 pa_stream_get_index;
 pa_stream_get_latency;
 pa_stream_get_monitor_stream;
@@ -263,9 +328,11 @@ pa_stream_get_sample_spec;
 pa_stream_get_state;
 pa_stream_get_time;
 pa_stream_get_timing_info;
+pa_stream_get_underflow_index;
 pa_stream_is_corked;
 pa_stream_is_suspended;
 pa_stream_new;
+pa_stream_new_extended;
 pa_stream_new_with_proplist;
 pa_stream_peek;
 pa_stream_prebuf;
@@ -306,6 +373,10 @@ pa_sw_volume_multiply;
 pa_sw_volume_snprint_dB;
 pa_sw_volume_to_dB;
 pa_sw_volume_to_linear;
+pa_cvolume_fading_set;
+pa_cvolume_fading_unset;
+pa_cvolume_fading_valid;
+pa_cvolume_fading_update;
 pa_threaded_mainloop_accept;
 pa_threaded_mainloop_free;
 pa_threaded_mainloop_get_api;
old mode 100644 (file)
new mode 100755 (executable)
index 8b13239..d91bf48
 #endif
 
 #include <sys/types.h>
-#include <limits.h>
 #include <asoundlib.h>
+#include <math.h>
 
 #ifdef HAVE_VALGRIND_MEMCHECK_H
 #include <valgrind/memcheck.h>
 #endif
 
+#include <pulse/mainloop-api.h>
 #include <pulse/sample.h>
-#include <pulse/xmalloc.h>
 #include <pulse/timeval.h>
 #include <pulse/util.h>
-#include <pulse/i18n.h>
+#include <pulse/volume.h>
+#include <pulse/xmalloc.h>
 #include <pulse/utf8.h>
 
+#include <pulsecore/i18n.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
-#include <pulsecore/atomic.h>
-#include <pulsecore/core-error.h>
-#include <pulsecore/once.h>
-#include <pulsecore/thread.h>
 #include <pulsecore/conf-parser.h>
 #include <pulsecore/strbuf.h>
 
 #include "alsa-mixer.h"
 #include "alsa-util.h"
 
+static int setting_select(pa_alsa_setting *s, snd_mixer_t *m);
+
 struct description_map {
     const char *name;
     const char *description;
@@ -62,7 +62,7 @@ static const char *lookup_description(const char *name, const struct description
 
     for (i = 0; i < n; i++)
         if (pa_streq(dm[i].name, name))
-            return dm[i].description;
+            return _(dm[i].description);
 
     return NULL;
 }
@@ -74,6 +74,7 @@ struct pa_alsa_fdlist {
     struct pollfd *work_fds;
 
     snd_mixer_t *mixer;
+    snd_hctl_t *hctl;
 
     pa_mainloop_api *m;
     pa_defer_event *defer;
@@ -85,7 +86,7 @@ struct pa_alsa_fdlist {
     void *userdata;
 };
 
-static void io_cb(pa_mainloop_api*a, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) {
+static void io_cb(pa_mainloop_api *a, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
 
     struct pa_alsa_fdlist *fdl = userdata;
     int err;
@@ -94,7 +95,7 @@ static void io_cb(pa_mainloop_api*a, pa_io_event* e, int fd, pa_io_event_flags_t
 
     pa_assert(a);
     pa_assert(fdl);
-    pa_assert(fdl->mixer);
+    pa_assert(fdl->mixer || fdl->hctl);
     pa_assert(fdl->fds);
     pa_assert(fdl->work_fds);
 
@@ -121,18 +122,27 @@ static void io_cb(pa_mainloop_api*a, pa_io_event* e, int fd, pa_io_event_flags_t
 
     pa_assert(i != fdl->num_fds);
 
-    if ((err = snd_mixer_poll_descriptors_revents(fdl->mixer, fdl->work_fds, fdl->num_fds, &revents)) < 0) {
+    if (fdl->hctl)
+        err = snd_hctl_poll_descriptors_revents(fdl->hctl, fdl->work_fds, fdl->num_fds, &revents);
+    else
+        err = snd_mixer_poll_descriptors_revents(fdl->mixer, fdl->work_fds, fdl->num_fds, &revents);
+
+    if (err < 0) {
         pa_log_error("Unable to get poll revent: %s", pa_alsa_strerror(err));
         return;
     }
 
     a->defer_enable(fdl->defer, 1);
 
-    if (revents)
-        snd_mixer_handle_events(fdl->mixer);
+    if (revents) {
+        if (fdl->hctl)
+            snd_hctl_handle_events(fdl->hctl);
+        else
+            snd_mixer_handle_events(fdl->mixer);
+    }
 }
 
-static void defer_cb(pa_mainloop_api*a, pa_defer_event* e, void *userdata) {
+static void defer_cb(pa_mainloop_api *a, pa_defer_event *e, void *userdata) {
     struct pa_alsa_fdlist *fdl = userdata;
     unsigned num_fds, i;
     int err, n;
@@ -140,11 +150,16 @@ static void defer_cb(pa_mainloop_api*a, pa_defer_event* e, void *userdata) {
 
     pa_assert(a);
     pa_assert(fdl);
-    pa_assert(fdl->mixer);
+    pa_assert(fdl->mixer || fdl->hctl);
 
     a->defer_enable(fdl->defer, 0);
 
-    if ((n = snd_mixer_poll_descriptors_count(fdl->mixer)) < 0) {
+    if (fdl->hctl)
+        n = snd_hctl_poll_descriptors_count(fdl->hctl);
+    else
+        n = snd_mixer_poll_descriptors_count(fdl->mixer);
+
+    if (n < 0) {
         pa_log("snd_mixer_poll_descriptors_count() failed: %s", pa_alsa_strerror(n));
         return;
     }
@@ -161,7 +176,12 @@ static void defer_cb(pa_mainloop_api*a, pa_defer_event* e, void *userdata) {
 
     memset(fdl->work_fds, 0, sizeof(struct pollfd) * num_fds);
 
-    if ((err = snd_mixer_poll_descriptors(fdl->mixer, fdl->work_fds, num_fds)) < 0) {
+    if (fdl->hctl)
+        err = snd_hctl_poll_descriptors(fdl->hctl, fdl->work_fds, num_fds);
+    else
+        err = snd_mixer_poll_descriptors(fdl->mixer, fdl->work_fds, num_fds);
+
+    if (err < 0) {
         pa_log_error("Unable to get poll descriptors: %s", pa_alsa_strerror(err));
         return;
     }
@@ -230,12 +250,15 @@ void pa_alsa_fdlist_free(struct pa_alsa_fdlist *fdl) {
     pa_xfree(fdl);
 }
 
-int pa_alsa_fdlist_set_mixer(struct pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, pa_mainloop_api* m) {
+/* We can listen to either a snd_hctl_t or a snd_mixer_t, but not both */
+int pa_alsa_fdlist_set_handle(struct pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, snd_hctl_t *hctl_handle, pa_mainloop_api *m) {
     pa_assert(fdl);
-    pa_assert(mixer_handle);
+    pa_assert(hctl_handle || mixer_handle);
+    pa_assert(!(hctl_handle && mixer_handle));
     pa_assert(m);
     pa_assert(!fdl->m);
 
+    fdl->hctl = hctl_handle;
     fdl->mixer = mixer_handle;
     fdl->m = m;
     fdl->defer = m->defer_new(m, defer_cb, fdl);
@@ -243,82 +266,122 @@ int pa_alsa_fdlist_set_mixer(struct pa_alsa_fdlist *fdl, snd_mixer_t *mixer_hand
     return 0;
 }
 
-static int prepare_mixer(snd_mixer_t *mixer, const char *dev) {
-    int err;
+struct pa_alsa_mixer_pdata {
+    pa_rtpoll *rtpoll;
+    pa_rtpoll_item *poll_item;
+    snd_mixer_t *mixer;
+};
 
-    pa_assert(mixer);
-    pa_assert(dev);
 
-    if ((err = snd_mixer_attach(mixer, dev)) < 0) {
-        pa_log_info("Unable to attach to mixer %s: %s", dev, pa_alsa_strerror(err));
-        return -1;
-    }
+struct pa_alsa_mixer_pdata *pa_alsa_mixer_pdata_new(void) {
+    struct pa_alsa_mixer_pdata *pd;
 
-    if ((err = snd_mixer_selem_register(mixer, NULL, NULL)) < 0) {
-        pa_log_warn("Unable to register mixer: %s", pa_alsa_strerror(err));
-        return -1;
-    }
+    pd = pa_xnew0(struct pa_alsa_mixer_pdata, 1);
 
-    if ((err = snd_mixer_load(mixer)) < 0) {
-        pa_log_warn("Unable to load mixer: %s", pa_alsa_strerror(err));
-        return -1;
+    return pd;
+}
+
+void pa_alsa_mixer_pdata_free(struct pa_alsa_mixer_pdata *pd) {
+    pa_assert(pd);
+
+    if (pd->poll_item) {
+        pa_rtpoll_item_free(pd->poll_item);
     }
 
-    pa_log_info("Successfully attached to mixer '%s'", dev);
-    return 0;
+    pa_xfree(pd);
 }
 
-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_pcm_info_t* info;
-    snd_pcm_info_alloca(&info);
+static int rtpoll_work_cb(pa_rtpoll_item *i) {
+    struct pa_alsa_mixer_pdata *pd;
+    struct pollfd *p;
+    unsigned n_fds;
+    unsigned short revents = 0;
+    int err, ret = 0;
 
-    pa_assert(pcm);
+    pd = pa_rtpoll_item_get_userdata(i);
+    pa_assert_fp(pd);
+    pa_assert_fp(i == pd->poll_item);
 
-    if ((err = snd_mixer_open(&m, 0)) < 0) {
-        pa_log("Error opening mixer: %s", pa_alsa_strerror(err));
-        return NULL;
+    p = pa_rtpoll_item_get_pollfd(i, &n_fds);
+
+    if ((err = snd_mixer_poll_descriptors_revents(pd->mixer, p, n_fds, &revents)) < 0) {
+        pa_log_error("Unable to get poll revent: %s", pa_alsa_strerror(err));
+        ret = -1;
+        goto fail;
     }
 
-    /* First, try by name */
-    if ((dev = snd_pcm_name(pcm)))
-        if (prepare_mixer(m, dev) >= 0) {
-            if (ctl_device)
-                *ctl_device = pa_xstrdup(dev);
+    if (revents) {
+        if (revents & (POLLNVAL | POLLERR)) {
+            pa_log_debug("Device disconnected, stopping poll on mixer");
+            goto fail;
+        } else if (revents & POLLERR) {
+            /* This shouldn't happen. */
+            pa_log_error("Got a POLLERR (revents = %04x), stopping poll on mixer", revents);
+            goto fail;
+        }
+
+        err = snd_mixer_handle_events(pd->mixer);
 
-            return m;
+        if (PA_LIKELY(err >= 0)) {
+            pa_rtpoll_item_free(i);
+            pa_alsa_set_mixer_rtpoll(pd, pd->mixer, pd->rtpoll);
+        } else {
+            pa_log_error("Error handling mixer event: %s", pa_alsa_strerror(err));
+            ret = -1;
+            goto fail;
         }
+    }
 
-    /* Then, try by card index */
-    if (snd_pcm_info(pcm, info) >= 0) {
-        char *md;
-        int card_idx;
+    return ret;
 
-        if ((card_idx = snd_pcm_info_get_card(info)) >= 0) {
+fail:
+    pa_rtpoll_item_free(i);
 
-            md = pa_sprintf_malloc("hw:%i", card_idx);
+    pd->poll_item = NULL;
+    pd->rtpoll = NULL;
+    pd->mixer = NULL;
 
-            if (!dev || !pa_streq(dev, md))
-                if (prepare_mixer(m, md) >= 0) {
+    return ret;
+}
 
-                    if (ctl_device)
-                        *ctl_device = md;
-                    else
-                        pa_xfree(md);
+int pa_alsa_set_mixer_rtpoll(struct pa_alsa_mixer_pdata *pd, snd_mixer_t *mixer, pa_rtpoll *rtp) {
+    pa_rtpoll_item *i;
+    struct pollfd *p;
+    int err, n;
 
-                    return m;
-                }
+    pa_assert(pd);
+    pa_assert(mixer);
+    pa_assert(rtp);
 
-            pa_xfree(md);
-        }
+    if ((n = snd_mixer_poll_descriptors_count(mixer)) < 0) {
+        pa_log("snd_mixer_poll_descriptors_count() failed: %s", pa_alsa_strerror(n));
+        return -1;
     }
 
-    snd_mixer_close(m);
-    return NULL;
+    i = pa_rtpoll_item_new(rtp, PA_RTPOLL_LATE, (unsigned) n);
+
+    p = pa_rtpoll_item_get_pollfd(i, NULL);
+
+    memset(p, 0, sizeof(struct pollfd) * n);
+
+    if ((err = snd_mixer_poll_descriptors(mixer, p, (unsigned) n)) < 0) {
+        pa_log_error("Unable to get poll descriptors: %s", pa_alsa_strerror(err));
+        pa_rtpoll_item_free(i);
+        return -1;
+    }
+
+    pd->rtpoll = rtp;
+    pd->poll_item = i;
+    pd->mixer = mixer;
+
+    pa_rtpoll_item_set_userdata(i, pd);
+    pa_rtpoll_item_set_work_callback(i, rtpoll_work_cb);
+
+    return 0;
 }
 
+
+
 static const snd_mixer_selem_channel_id_t alsa_channel_ids[PA_CHANNEL_POSITION_MAX] = {
     [PA_CHANNEL_POSITION_MONO] = SND_MIXER_SCHN_MONO, /* The ALSA name is just an alias! */
 
@@ -386,7 +449,7 @@ static void setting_free(pa_alsa_setting *s) {
     pa_assert(s);
 
     if (s->options)
-        pa_idxset_free(s->options, NULL, NULL);
+        pa_idxset_free(s->options, NULL);
 
     pa_xfree(s->name);
     pa_xfree(s->description);
@@ -402,6 +465,23 @@ static void option_free(pa_alsa_option *o) {
     pa_xfree(o);
 }
 
+static void decibel_fix_free(pa_alsa_decibel_fix *db_fix) {
+    pa_assert(db_fix);
+
+    pa_xfree(db_fix->name);
+    pa_xfree(db_fix->db_values);
+
+    pa_xfree(db_fix);
+}
+
+static void jack_free(pa_alsa_jack *j) {
+    pa_assert(j);
+
+    pa_xfree(j->alsa_name);
+    pa_xfree(j->name);
+    pa_xfree(j);
+}
+
 static void element_free(pa_alsa_element *e) {
     pa_alsa_option *o;
     pa_assert(e);
@@ -411,16 +491,25 @@ static void element_free(pa_alsa_element *e) {
         option_free(o);
     }
 
+    if (e->db_fix)
+        decibel_fix_free(e->db_fix);
+
     pa_xfree(e->alsa_name);
     pa_xfree(e);
 }
 
 void pa_alsa_path_free(pa_alsa_path *p) {
+    pa_alsa_jack *j;
     pa_alsa_element *e;
     pa_alsa_setting *s;
 
     pa_assert(p);
 
+    while ((j = p->jacks)) {
+        PA_LLIST_REMOVE(pa_alsa_jack, p->jacks, j);
+        jack_free(j);
+    }
+
     while ((e = p->elements)) {
         PA_LLIST_REMOVE(pa_alsa_element, p->elements, e);
         element_free(e);
@@ -431,19 +520,17 @@ void pa_alsa_path_free(pa_alsa_path *p) {
         setting_free(s);
     }
 
+    pa_proplist_free(p->proplist);
     pa_xfree(p->name);
     pa_xfree(p->description);
     pa_xfree(p);
 }
 
 void pa_alsa_path_set_free(pa_alsa_path_set *ps) {
-    pa_alsa_path *p;
     pa_assert(ps);
 
-    while ((p = ps->paths)) {
-        PA_LLIST_REMOVE(pa_alsa_path, ps->paths, p);
-        pa_alsa_path_free(p);
-    }
+    if (ps->paths)
+        pa_hashmap_free(ps->paths, NULL);
 
     pa_xfree(ps);
 }
@@ -504,14 +591,60 @@ static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
             long value = 0;
 
             if (e->direction == PA_ALSA_DIRECTION_OUTPUT) {
-                if (snd_mixer_selem_has_playback_channel(me, c))
-                    r = snd_mixer_selem_get_playback_dB(me, c, &value);
-                else
+                if (snd_mixer_selem_has_playback_channel(me, c)) {
+                    if (e->db_fix) {
+                        if ((r = snd_mixer_selem_get_playback_volume(me, c, &value)) >= 0) {
+                            /* If the channel volume is outside the limits set
+                             * by the dB fix, we clamp the hw volume to be
+                             * within the limits. */
+                            if (value < e->db_fix->min_step) {
+                                value = e->db_fix->min_step;
+                                snd_mixer_selem_set_playback_volume(me, c, value);
+                                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,
+                                             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);
+                                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,
+                                             e->db_fix->db_values[value - e->db_fix->min_step] / 100.0);
+                            }
+
+                            /* Volume step -> dB value conversion. */
+                            value = e->db_fix->db_values[value - e->db_fix->min_step];
+                        }
+                    } else
+                        r = snd_mixer_selem_get_playback_dB(me, c, &value);
+                } else
                     r = -1;
             } else {
-                if (snd_mixer_selem_has_capture_channel(me, c))
-                    r = snd_mixer_selem_get_capture_dB(me, c, &value);
-                else
+                if (snd_mixer_selem_has_capture_channel(me, c)) {
+                    if (e->db_fix) {
+                        if ((r = snd_mixer_selem_get_capture_volume(me, c, &value)) >= 0) {
+                            /* If the channel volume is outside the limits set
+                             * by the dB fix, we clamp the hw volume to be
+                             * within the limits. */
+                            if (value < e->db_fix->min_step) {
+                                value = e->db_fix->min_step;
+                                snd_mixer_selem_set_capture_volume(me, c, value);
+                                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,
+                                             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);
+                                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,
+                                             e->db_fix->db_values[value - e->db_fix->min_step] / 100.0);
+                            }
+
+                            /* Volume step -> dB value conversion. */
+                            value = e->db_fix->db_values[value - e->db_fix->min_step];
+                        }
+                    } else
+                        r = snd_mixer_selem_get_capture_dB(me, c, &value);
+                } else
                     r = -1;
             }
 
@@ -671,7 +804,91 @@ int pa_alsa_path_get_mute(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t *muted) {
     return 0;
 }
 
-static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v) {
+/* Finds the closest item in db_fix->db_values and returns the corresponding
+ * step. *db_value is replaced with the value from the db_values table.
+ * Rounding is done based on the rounding parameter: -1 means rounding down and
+ * +1 means rounding up. */
+static long decibel_fix_get_step(pa_alsa_decibel_fix *db_fix, long *db_value, int rounding) {
+    unsigned i = 0;
+    unsigned max_i = 0;
+
+    pa_assert(db_fix);
+    pa_assert(db_value);
+    pa_assert(rounding != 0);
+
+    max_i = db_fix->max_step - db_fix->min_step;
+
+    if (rounding > 0) {
+        for (i = 0; i < max_i; i++) {
+            if (db_fix->db_values[i] >= *db_value)
+                break;
+        }
+    } else {
+        for (i = 0; i < max_i; i++) {
+            if (db_fix->db_values[i + 1] > *db_value)
+                break;
+        }
+    }
+
+    *db_value = db_fix->db_values[i];
+
+    return i + db_fix->min_step;
+}
+
+/* Alsa lib documentation says for snd_mixer_selem_set_playback_dB() direction argument,
+ * that "-1 = accurate or first below, 0 = accurate, 1 = accurate or first above".
+ * But even with accurate nearest dB volume step is not selected, so that is why we need
+ * this function. Returns 0 and nearest selectable volume in *value_dB on success or
+ * negative error code if fails. */
+static int element_get_nearest_alsa_dB(snd_mixer_elem_t *me, snd_mixer_selem_channel_id_t c, pa_alsa_direction_t d, long *value_dB) {
+
+    long alsa_val;
+    long value_high;
+    long value_low;
+    int r = -1;
+
+    pa_assert(me);
+    pa_assert(value_dB);
+
+    if (d == PA_ALSA_DIRECTION_OUTPUT) {
+        if ((r = snd_mixer_selem_ask_playback_dB_vol(me, *value_dB, +1, &alsa_val)) >= 0)
+            r = snd_mixer_selem_ask_playback_vol_dB(me, alsa_val, &value_high);
+
+        if (r < 0)
+            return r;
+
+        if (value_high == *value_dB)
+            return r;
+
+        if ((r = snd_mixer_selem_ask_playback_dB_vol(me, *value_dB, -1, &alsa_val)) >= 0)
+            r = snd_mixer_selem_ask_playback_vol_dB(me, alsa_val, &value_low);
+    } else {
+        if ((r = snd_mixer_selem_ask_capture_dB_vol(me, *value_dB, +1, &alsa_val)) >= 0)
+            r = snd_mixer_selem_ask_capture_vol_dB(me, alsa_val, &value_high);
+
+        if (r < 0)
+            return r;
+
+        if (value_high == *value_dB)
+            return r;
+
+        if ((r = snd_mixer_selem_ask_capture_dB_vol(me, *value_dB, -1, &alsa_val)) >= 0)
+            r = snd_mixer_selem_ask_capture_vol_dB(me, alsa_val, &value_low);
+    }
+
+    if (r < 0)
+        return r;
+
+    if (labs(value_high - *value_dB) < labs(value_low - *value_dB))
+        *value_dB = value_high;
+    else
+        *value_dB = value_low;
+
+    return r;
+}
+
+static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v, pa_bool_t deferred_volume, pa_bool_t write_to_hw) {
+
     snd_mixer_selem_id_t *sid;
     pa_cvolume rv;
     snd_mixer_elem_t *me;
@@ -714,20 +931,68 @@ static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
 
         if (e->has_dB) {
             long value = to_alsa_dB(f);
+            int rounding;
+
+            if (e->volume_limit >= 0 && value > (e->max_dB * 100))
+                value = e->max_dB * 100;
 
             if (e->direction == PA_ALSA_DIRECTION_OUTPUT) {
-                /* If we call set_play_volume() without checking first
-                 * if the channel is available, ALSA behaves ver
+                /* If we call set_playback_volume() without checking first
+                 * if the channel is available, ALSA behaves very
                  * strangely and doesn't fail the call */
                 if (snd_mixer_selem_has_playback_channel(me, c)) {
-                    if ((r = snd_mixer_selem_set_playback_dB(me, c, value, +1)) >= 0)
-                        r = snd_mixer_selem_get_playback_dB(me, c, &value);
+                    rounding = +1;
+                    if (e->db_fix) {
+                        if (write_to_hw)
+                            r = snd_mixer_selem_set_playback_volume(me, c, decibel_fix_get_step(e->db_fix, &value, rounding));
+                        else {
+                            decibel_fix_get_step(e->db_fix, &value, rounding);
+                            r = 0;
+                        }
+
+                    } else {
+                        if (write_to_hw) {
+                            if (deferred_volume) {
+                                if ((r = element_get_nearest_alsa_dB(me, c, PA_ALSA_DIRECTION_OUTPUT, &value)) >= 0)
+                                    r = snd_mixer_selem_set_playback_dB(me, c, value, 0);
+                            } else {
+                                if ((r = snd_mixer_selem_set_playback_dB(me, c, value, rounding)) >= 0)
+                                    r = snd_mixer_selem_get_playback_dB(me, c, &value);
+                           }
+                        } else {
+                            long alsa_val;
+                            if ((r = snd_mixer_selem_ask_playback_dB_vol(me, value, rounding, &alsa_val)) >= 0)
+                                r = snd_mixer_selem_ask_playback_vol_dB(me, alsa_val, &value);
+                        }
+                    }
                 } else
                     r = -1;
             } else {
                 if (snd_mixer_selem_has_capture_channel(me, c)) {
-                    if ((r = snd_mixer_selem_set_capture_dB(me, c, value, +1)) >= 0)
-                        r = snd_mixer_selem_get_capture_dB(me, c, &value);
+                    rounding = -1;
+                    if (e->db_fix) {
+                        if (write_to_hw)
+                            r = snd_mixer_selem_set_capture_volume(me, c, decibel_fix_get_step(e->db_fix, &value, rounding));
+                        else {
+                            decibel_fix_get_step(e->db_fix, &value, rounding);
+                            r = 0;
+                        }
+
+                    } else {
+                        if (write_to_hw) {
+                            if (deferred_volume) {
+                                if ((r = element_get_nearest_alsa_dB(me, c, PA_ALSA_DIRECTION_INPUT, &value)) >= 0)
+                                    r = snd_mixer_selem_set_capture_dB(me, c, value, 0);
+                            } else {
+                                if ((r = snd_mixer_selem_set_capture_dB(me, c, value, rounding)) >= 0)
+                                    r = snd_mixer_selem_get_capture_dB(me, c, &value);
+                            }
+                        } else {
+                            long alsa_val;
+                            if ((r = snd_mixer_selem_ask_capture_dB_vol(me, value, rounding, &alsa_val)) >= 0)
+                                r = snd_mixer_selem_ask_capture_vol_dB(me, alsa_val, &value);
+                        }
+                    }
                 } else
                     r = -1;
             }
@@ -782,7 +1047,8 @@ static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
     return 0;
 }
 
-int pa_alsa_path_set_volume(pa_alsa_path *p, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v) {
+int pa_alsa_path_set_volume(pa_alsa_path *p, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v, pa_bool_t deferred_volume, pa_bool_t write_to_hw) {
+
     pa_alsa_element *e;
     pa_cvolume rv;
 
@@ -807,7 +1073,7 @@ int pa_alsa_path_set_volume(pa_alsa_path *p, snd_mixer_t *m, const pa_channel_ma
         pa_assert(!p->has_dB || e->has_dB);
 
         ev = rv;
-        if (element_set_volume(e, m, cm, &ev) < 0)
+        if (element_set_volume(e, m, cm, &ev, deferred_volume, write_to_hw) < 0)
             return -1;
 
         if (!p->has_dB) {
@@ -868,10 +1134,15 @@ int pa_alsa_path_set_mute(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t muted) {
     return 0;
 }
 
-static int element_mute_volume(pa_alsa_element *e, snd_mixer_t *m) {
-    snd_mixer_elem_t *me;
-    snd_mixer_selem_id_t *sid;
-    int r;
+/* Depending on whether e->volume_use is _OFF, _ZERO or _CONSTANT, this
+ * function sets all channels of the volume element to e->min_volume, 0 dB or
+ * e->constant_volume. */
+static int element_set_constant_volume(pa_alsa_element *e, snd_mixer_t *m) {
+    snd_mixer_elem_t *me = NULL;
+    snd_mixer_selem_id_t *sid = NULL;
+    int r = 0;
+    long volume = -1;
+    pa_bool_t volume_set = FALSE;
 
     pa_assert(m);
     pa_assert(e);
@@ -882,44 +1153,52 @@ static int element_mute_volume(pa_alsa_element *e, snd_mixer_t *m) {
         return -1;
     }
 
-    if (e->direction == PA_ALSA_DIRECTION_OUTPUT)
-        r = snd_mixer_selem_set_playback_volume_all(me, e->min_volume);
-    else
-        r = snd_mixer_selem_set_capture_volume_all(me, e->min_volume);
-
-    if (r < 0)
-        pa_log_warn("Faile to set volume to muted of %s: %s", e->alsa_name, pa_alsa_strerror(errno));
+    switch (e->volume_use) {
+        case PA_ALSA_VOLUME_OFF:
+            volume = e->min_volume;
+            volume_set = TRUE;
+            break;
 
-    return r;
-}
+        case PA_ALSA_VOLUME_ZERO:
+            if (e->db_fix) {
+                long dB = 0;
 
-/* The volume to 0dB */
-static int element_zero_volume(pa_alsa_element *e, snd_mixer_t *m) {
-    snd_mixer_elem_t *me;
-    snd_mixer_selem_id_t *sid;
-    int r;
+                volume = decibel_fix_get_step(e->db_fix, &dB, (e->direction == PA_ALSA_DIRECTION_OUTPUT ? +1 : -1));
+                volume_set = TRUE;
+            }
+            break;
 
-    pa_assert(m);
-    pa_assert(e);
+        case PA_ALSA_VOLUME_CONSTANT:
+            volume = e->constant_volume;
+            volume_set = TRUE;
+            break;
 
-    SELEM_INIT(sid, e->alsa_name);
-    if (!(me = snd_mixer_find_selem(m, sid))) {
-        pa_log_warn("Element %s seems to have disappeared.", e->alsa_name);
-        return -1;
+        default:
+            pa_assert_not_reached();
     }
 
-    if (e->direction == PA_ALSA_DIRECTION_OUTPUT)
-        r = snd_mixer_selem_set_playback_dB_all(me, 0, +1);
-    else
-        r = snd_mixer_selem_set_capture_dB_all(me, 0, +1);
+    if (volume_set) {
+        if (e->direction == PA_ALSA_DIRECTION_OUTPUT)
+            r = snd_mixer_selem_set_playback_volume_all(me, volume);
+        else
+            r = snd_mixer_selem_set_capture_volume_all(me, volume);
+    } else {
+        pa_assert(e->volume_use == PA_ALSA_VOLUME_ZERO);
+        pa_assert(!e->db_fix);
+
+        if (e->direction == PA_ALSA_DIRECTION_OUTPUT)
+            r = snd_mixer_selem_set_playback_dB_all(me, 0, +1);
+        else
+            r = snd_mixer_selem_set_capture_dB_all(me, 0, -1);
+    }
 
     if (r < 0)
-        pa_log_warn("Faile to set volume to 0dB of %s: %s", e->alsa_name, pa_alsa_strerror(errno));
+        pa_log_warn("Failed to set volume of %s: %s", e->alsa_name, pa_alsa_strerror(errno));
 
     return r;
 }
 
-int pa_alsa_path_select(pa_alsa_path *p, snd_mixer_t *m) {
+int pa_alsa_path_select(pa_alsa_path *p, pa_alsa_setting *s, snd_mixer_t *m, bool device_is_muted) {
     pa_alsa_element *e;
     int r = 0;
 
@@ -929,6 +1208,19 @@ int pa_alsa_path_select(pa_alsa_path *p, snd_mixer_t *m) {
     pa_log_debug("Activating path %s", p->name);
     pa_alsa_path_dump(p);
 
+    /* First turn on hw mute if available, to avoid noise
+     * when setting the mixer controls. */
+    if (p->mute_during_activation) {
+        PA_LLIST_FOREACH(e, p->elements) {
+            if (e->switch_use == PA_ALSA_SWITCH_MUTE)
+                /* If the muting fails here, that's not a critical problem for
+                 * selecting a path, so we ignore the return value.
+                 * element_set_switch() will print a warning anyway, so this
+                 * won't be a silent failure either. */
+                (void) element_set_switch(e, m, FALSE);
+        }
+    }
+
     PA_LLIST_FOREACH(e, p->elements) {
 
         switch (e->switch_use) {
@@ -952,11 +1244,9 @@ int pa_alsa_path_select(pa_alsa_path *p, snd_mixer_t *m) {
 
         switch (e->volume_use) {
             case PA_ALSA_VOLUME_OFF:
-                r = element_mute_volume(e, m);
-                break;
-
             case PA_ALSA_VOLUME_ZERO:
-                r = element_zero_volume(e, m);
+            case PA_ALSA_VOLUME_CONSTANT:
+                r = element_set_constant_volume(e, m);
                 break;
 
             case PA_ALSA_VOLUME_MERGE:
@@ -969,6 +1259,19 @@ int pa_alsa_path_select(pa_alsa_path *p, snd_mixer_t *m) {
             return -1;
     }
 
+    if (s)
+        setting_select(s, m);
+
+    /* Finally restore hw mute to the device mute status. */
+    if (p->mute_during_activation) {
+        PA_LLIST_FOREACH(e, p->elements) {
+            if (e->switch_use == PA_ALSA_SWITCH_MUTE) {
+                if (element_set_switch(e, m, !device_is_muted) < 0)
+                    return -1;
+            }
+        }
+    }
+
     return 0;
 }
 
@@ -1018,6 +1321,40 @@ static int check_required(pa_alsa_element *e, snd_mixer_elem_t *me) {
     if (e->required_absent == PA_ALSA_REQUIRED_ANY && (has_switch || has_volume || has_enumeration))
         return -1;
 
+    if (e->required_any != PA_ALSA_REQUIRED_IGNORE) {
+        switch (e->required_any) {
+            case PA_ALSA_REQUIRED_VOLUME:
+                e->path->req_any_present |= (e->volume_use != PA_ALSA_VOLUME_IGNORE);
+                break;
+            case PA_ALSA_REQUIRED_SWITCH:
+                e->path->req_any_present |= (e->switch_use != PA_ALSA_SWITCH_IGNORE);
+                break;
+            case PA_ALSA_REQUIRED_ENUMERATION:
+                e->path->req_any_present |= (e->enumeration_use != PA_ALSA_ENUMERATION_IGNORE);
+                break;
+            case PA_ALSA_REQUIRED_ANY:
+                e->path->req_any_present |=
+                    (e->volume_use != PA_ALSA_VOLUME_IGNORE) ||
+                    (e->switch_use != PA_ALSA_SWITCH_IGNORE) ||
+                    (e->enumeration_use != PA_ALSA_ENUMERATION_IGNORE);
+                break;
+            default:
+                pa_assert_not_reached();
+        }
+    }
+
+    if (e->enumeration_use == PA_ALSA_ENUMERATION_SELECT) {
+        pa_alsa_option *o;
+        PA_LLIST_FOREACH(o, e->options) {
+            e->path->req_any_present |= (o->required_any != PA_ALSA_REQUIRED_IGNORE) &&
+                (o->alsa_idx >= 0);
+            if (o->required != PA_ALSA_REQUIRED_IGNORE && o->alsa_idx < 0)
+                return -1;
+            if (o->required_absent != PA_ALSA_REQUIRED_IGNORE && o->alsa_idx >= 0)
+                return -1;
+        }
+    }
+
     return 0;
 }
 
@@ -1027,6 +1364,7 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) {
 
     pa_assert(m);
     pa_assert(e);
+    pa_assert(e->path);
 
     SELEM_INIT(sid, e->alsa_name);
 
@@ -1037,7 +1375,7 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) {
 
         e->switch_use = PA_ALSA_SWITCH_IGNORE;
         e->volume_use = PA_ALSA_VOLUME_IGNORE;
-        e->enumeration_use = PA_ALSA_VOLUME_IGNORE;
+        e->enumeration_use = PA_ALSA_ENUMERATION_IGNORE;
 
         return 0;
     }
@@ -1094,26 +1432,6 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) {
             e->direction_try_other = FALSE;
 
             if (e->direction == PA_ALSA_DIRECTION_OUTPUT)
-                e->has_dB = snd_mixer_selem_get_playback_dB_range(me, &min_dB, &max_dB) >= 0;
-            else
-                e->has_dB = snd_mixer_selem_get_capture_dB_range(me, &min_dB, &max_dB) >= 0;
-
-            if (e->has_dB) {
-#ifdef HAVE_VALGRIND_MEMCHECK_H
-                VALGRIND_MAKE_MEM_DEFINED(&min_dB, sizeof(min_dB));
-                VALGRIND_MAKE_MEM_DEFINED(&max_dB, sizeof(max_dB));
-#endif
-
-                e->min_dB = ((double) min_dB) / 100.0;
-                e->max_dB = ((double) max_dB) / 100.0;
-
-                if (min_dB >= max_dB) {
-                    pa_log_warn("Your kernel driver is broken: it reports a volume range from %0.2f dB to %0.2f dB which makes no sense.", e->min_dB, e->max_dB);
-                    e->has_dB = FALSE;
-                }
-            }
-
-            if (e->direction == PA_ALSA_DIRECTION_OUTPUT)
                 r = snd_mixer_selem_get_playback_volume_range(me, &e->min_volume, &e->max_volume);
             else
                 r = snd_mixer_selem_get_capture_volume_range(me, &e->min_volume, &e->max_volume);
@@ -1123,15 +1441,126 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) {
                 return -1;
             }
 
-
             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);
                 e->volume_use = PA_ALSA_VOLUME_IGNORE;
 
+            } else if (e->volume_use == PA_ALSA_VOLUME_CONSTANT &&
+                       (e->min_volume > e->constant_volume || e->max_volume < e->constant_volume)) {
+                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->volume_use = PA_ALSA_VOLUME_IGNORE;
+
             } else {
                 pa_bool_t is_mono;
                 pa_channel_position_t p;
 
+                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);
+
+                    decibel_fix_free(e->db_fix);
+                    e->db_fix = NULL;
+                }
+
+                if (e->db_fix) {
+                    e->has_dB = TRUE;
+                    e->min_volume = e->db_fix->min_step;
+                    e->max_volume = e->db_fix->max_step;
+                    min_dB = e->db_fix->db_values[0];
+                    max_dB = e->db_fix->db_values[e->db_fix->max_step - e->db_fix->min_step];
+                } else if (e->direction == PA_ALSA_DIRECTION_OUTPUT)
+                    e->has_dB = snd_mixer_selem_get_playback_dB_range(me, &min_dB, &max_dB) >= 0;
+                else
+                    e->has_dB = snd_mixer_selem_get_capture_dB_range(me, &min_dB, &max_dB) >= 0;
+
+                /* Check that the kernel driver returns consistent limits with
+                 * both _get_*_dB_range() and _ask_*_vol_dB(). */
+                if (e->has_dB && !e->db_fix) {
+                    long min_dB_checked = 0;
+                    long max_dB_checked = 0;
+
+                    if (e->direction == PA_ALSA_DIRECTION_OUTPUT)
+                        r = snd_mixer_selem_ask_playback_vol_dB(me, e->min_volume, &min_dB_checked);
+                    else
+                        r = snd_mixer_selem_ask_capture_vol_dB(me, e->min_volume, &min_dB_checked);
+
+                    if (r < 0) {
+                        pa_log_warn("Failed to query the dB value for %s at volume level %li", e->alsa_name, e->min_volume);
+                        return -1;
+                    }
+
+                    if (e->direction == PA_ALSA_DIRECTION_OUTPUT)
+                        r = snd_mixer_selem_ask_playback_vol_dB(me, e->max_volume, &max_dB_checked);
+                    else
+                        r = snd_mixer_selem_ask_capture_vol_dB(me, e->max_volume, &max_dB_checked);
+
+                    if (r < 0) {
+                        pa_log_warn("Failed to query the dB value for %s at volume level %li", e->alsa_name, e->max_volume);
+                        return -1;
+                    }
+
+                    if (min_dB != min_dB_checked || max_dB != max_dB_checked) {
+                        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,
+                                    min_dB_checked / 100.0, e->min_volume, max_dB_checked / 100.0, e->max_volume);
+                        return -1;
+                    }
+                }
+
+                if (e->has_dB) {
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+                    VALGRIND_MAKE_MEM_DEFINED(&min_dB, sizeof(min_dB));
+                    VALGRIND_MAKE_MEM_DEFINED(&max_dB, sizeof(max_dB));
+#endif
+
+                    e->min_dB = ((double) min_dB) / 100.0;
+                    e->max_dB = ((double) max_dB) / 100.0;
+
+                    if (min_dB >= max_dB) {
+                        pa_assert(!e->db_fix);
+                        pa_log_warn("Your kernel driver is broken: it reports a volume range from %0.2f dB to %0.2f dB which makes no sense.", e->min_dB, e->max_dB);
+                        e->has_dB = FALSE;
+                    }
+                }
+
+                if (e->volume_limit >= 0) {
+                    if (e->volume_limit <= e->min_volume || e->volume_limit > e->max_volume)
+                        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 {
+                        e->max_volume = e->volume_limit;
+
+                        if (e->has_dB) {
+                            if (e->db_fix) {
+                                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 (e->direction == PA_ALSA_DIRECTION_OUTPUT)
+                                    r = snd_mixer_selem_ask_playback_vol_dB(me, e->max_volume, &max_dB);
+                                else
+                                    r = snd_mixer_selem_ask_capture_vol_dB(me, e->max_volume, &max_dB);
+
+                                if (r < 0) {
+                                    pa_log_warn("Failed to get dB value of %s: %s", e->alsa_name, pa_alsa_strerror(r));
+                                    e->has_dB = FALSE;
+                                } else
+                                    e->max_dB = ((double) max_dB) / 100.0;
+                            }
+                        }
+                    }
+                }
+
                 if (e->direction == PA_ALSA_DIRECTION_OUTPUT)
                     is_mono = snd_mixer_selem_is_playback_mono(me) > 0;
                 else
@@ -1141,8 +1570,13 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) {
                     e->n_channels = 1;
 
                     if (!e->override_map) {
-                        for (p = PA_CHANNEL_POSITION_FRONT_LEFT; p < PA_CHANNEL_POSITION_MAX; p++)
+                        for (p = PA_CHANNEL_POSITION_FRONT_LEFT; p < PA_CHANNEL_POSITION_MAX; p++) {
+                            if (alsa_channel_ids[p] == SND_MIXER_SCHN_UNKNOWN)
+                                continue;
+
                             e->masks[alsa_channel_ids[p]][e->n_channels-1] = 0;
+                        }
+
                         e->masks[SND_MIXER_SCHN_MONO][e->n_channels-1] = PA_CHANNEL_POSITION_MASK_ALL;
                     }
 
@@ -1165,6 +1599,22 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) {
                         return -1;
                     }
 
+                    if (e->n_channels > 2) {
+                        /* FIXME: In some places code like this is used:
+                         *
+                         *     e->masks[alsa_channel_ids[p]][e->n_channels-1]
+                         *
+                         * The definition of e->masks is
+                         *
+                         *     pa_channel_position_mask_t masks[SND_MIXER_SCHN_LAST + 1][2];
+                         *
+                         * 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);
+                        return -1;
+                    }
+
                     if (!e->override_map) {
                         for (p = PA_CHANNEL_POSITION_FRONT_LEFT; p < PA_CHANNEL_POSITION_MAX; p++) {
                             pa_bool_t has_channel;
@@ -1182,17 +1632,18 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) {
                     }
 
                     e->merged_mask = 0;
-                    for (p = PA_CHANNEL_POSITION_FRONT_LEFT; p < PA_CHANNEL_POSITION_MAX; p++)
+                    for (p = PA_CHANNEL_POSITION_FRONT_LEFT; p < PA_CHANNEL_POSITION_MAX; p++) {
+                        if (alsa_channel_ids[p] == SND_MIXER_SCHN_UNKNOWN)
+                            continue;
+
                         e->merged_mask |= e->masks[alsa_channel_ids[p]][e->n_channels-1];
+                    }
                 }
             }
         }
 
     }
 
-    if (check_required(e, me) < 0)
-        return -1;
-
     if (e->switch_use == PA_ALSA_SWITCH_SELECT) {
         pa_alsa_option *o;
 
@@ -1224,6 +1675,29 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) {
         }
     }
 
+    if (check_required(e, me) < 0)
+        return -1;
+
+    return 0;
+}
+
+static int jack_probe(pa_alsa_jack *j, snd_hctl_t *h) {
+    pa_assert(h);
+    pa_assert(j);
+    pa_assert(j->path);
+
+    j->has_control = pa_alsa_find_jack(h, j->alsa_name) != NULL;
+
+    if (j->has_control) {
+        if (j->required_absent != PA_ALSA_REQUIRED_IGNORE)
+            return -1;
+        if (j->required_any != PA_ALSA_REQUIRED_IGNORE)
+            j->path->req_any_present = TRUE;
+    } else {
+        if (j->required != PA_ALSA_REQUIRED_IGNORE)
+            return -1;
+    }
+
     return 0;
 }
 
@@ -1255,6 +1729,7 @@ static pa_alsa_element* element_get(pa_alsa_path *p, const char *section, pa_boo
     e->path = p;
     e->alsa_name = pa_xstrdup(section);
     e->direction = p->direction;
+    e->volume_limit = -1;
 
     PA_LLIST_INSERT_AFTER(pa_alsa_element, p->elements, p->last_element, e);
 
@@ -1263,6 +1738,34 @@ finish:
     return e;
 }
 
+static pa_alsa_jack* jack_get(pa_alsa_path *p, const char *section) {
+    pa_alsa_jack *j;
+
+    if (!pa_startswith(section, "Jack "))
+        return NULL;
+    section += 5;
+
+    if (p->last_jack && pa_streq(p->last_jack->name, section))
+        return p->last_jack;
+
+    PA_LLIST_FOREACH(j, p->jacks)
+        if (pa_streq(j->name, section))
+            goto finish;
+
+    j = pa_xnew0(pa_alsa_jack, 1);
+    j->state_unplugged = PA_AVAILABLE_NO;
+    j->state_plugged = PA_AVAILABLE_YES;
+    j->path = p;
+    j->name = pa_xstrdup(section);
+    j->alsa_name = pa_sprintf_malloc("%s Jack", section);
+    PA_LLIST_INSERT_AFTER(pa_alsa_jack, p->jacks, p->last_jack, j);
+
+finish:
+    p->last_jack = j;
+    return j;
+}
+
+
 static pa_alsa_option* option_get(pa_alsa_path *p, const char *section) {
     char *en;
     const char *on;
@@ -1310,131 +1813,114 @@ finish:
     return o;
 }
 
-static int element_parse_switch(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int element_parse_switch(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_element *e;
 
-    pa_assert(p);
+    pa_assert(state);
+
+    p = state->userdata;
 
-    if (!(e = element_get(p, section, TRUE))) {
-        pa_log("[%s:%u] Switch makes no sense in '%s'", filename, line, section);
+    if (!(e = element_get(p, state->section, TRUE))) {
+        pa_log("[%s:%u] Switch makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_streq(rvalue, "ignore"))
+    if (pa_streq(state->rvalue, "ignore"))
         e->switch_use = PA_ALSA_SWITCH_IGNORE;
-    else if (pa_streq(rvalue, "mute"))
+    else if (pa_streq(state->rvalue, "mute"))
         e->switch_use = PA_ALSA_SWITCH_MUTE;
-    else if (pa_streq(rvalue, "off"))
+    else if (pa_streq(state->rvalue, "off"))
         e->switch_use = PA_ALSA_SWITCH_OFF;
-    else if (pa_streq(rvalue, "on"))
+    else if (pa_streq(state->rvalue, "on"))
         e->switch_use = PA_ALSA_SWITCH_ON;
-    else if (pa_streq(rvalue, "select"))
+    else if (pa_streq(state->rvalue, "select"))
         e->switch_use = PA_ALSA_SWITCH_SELECT;
     else {
-        pa_log("[%s:%u] Switch invalid of '%s'", filename, line, section);
+        pa_log("[%s:%u] Switch invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
     return 0;
 }
 
-static int element_parse_volume(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int element_parse_volume(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_element *e;
 
-    pa_assert(p);
+    pa_assert(state);
+
+    p = state->userdata;
 
-    if (!(e = element_get(p, section, TRUE))) {
-        pa_log("[%s:%u] Volume makes no sense in '%s'", filename, line, section);
+    if (!(e = element_get(p, state->section, TRUE))) {
+        pa_log("[%s:%u] Volume makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_streq(rvalue, "ignore"))
+    if (pa_streq(state->rvalue, "ignore"))
         e->volume_use = PA_ALSA_VOLUME_IGNORE;
-    else if (pa_streq(rvalue, "merge"))
+    else if (pa_streq(state->rvalue, "merge"))
         e->volume_use = PA_ALSA_VOLUME_MERGE;
-    else if (pa_streq(rvalue, "off"))
+    else if (pa_streq(state->rvalue, "off"))
         e->volume_use = PA_ALSA_VOLUME_OFF;
-    else if (pa_streq(rvalue, "zero"))
+    else if (pa_streq(state->rvalue, "zero"))
         e->volume_use = PA_ALSA_VOLUME_ZERO;
     else {
-        pa_log("[%s:%u] Volume invalid of '%s'", filename, line, section);
-        return -1;
+        uint32_t constant;
+
+        if (pa_atou(state->rvalue, &constant) >= 0) {
+            e->volume_use = PA_ALSA_VOLUME_CONSTANT;
+            e->constant_volume = constant;
+        } else {
+            pa_log("[%s:%u] Volume invalid of '%s'", state->filename, state->lineno, state->section);
+            return -1;
+        }
     }
 
     return 0;
 }
 
-static int element_parse_enumeration(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int element_parse_enumeration(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_element *e;
 
-    pa_assert(p);
+    pa_assert(state);
 
-    if (!(e = element_get(p, section, TRUE))) {
-        pa_log("[%s:%u] Enumeration makes no sense in '%s'", filename, line, section);
+    p = state->userdata;
+
+    if (!(e = element_get(p, state->section, TRUE))) {
+        pa_log("[%s:%u] Enumeration makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_streq(rvalue, "ignore"))
+    if (pa_streq(state->rvalue, "ignore"))
         e->enumeration_use = PA_ALSA_ENUMERATION_IGNORE;
-    else if (pa_streq(rvalue, "select"))
+    else if (pa_streq(state->rvalue, "select"))
         e->enumeration_use = PA_ALSA_ENUMERATION_SELECT;
     else {
-        pa_log("[%s:%u] Enumeration invalid of '%s'", filename, line, section);
+        pa_log("[%s:%u] Enumeration invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
     return 0;
 }
 
-static int option_parse_priority(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int option_parse_priority(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_option *o;
     uint32_t prio;
 
-    pa_assert(p);
+    pa_assert(state);
 
-    if (!(o = option_get(p, section))) {
-        pa_log("[%s:%u] Priority makes no sense in '%s'", filename, line, section);
+    p = state->userdata;
+
+    if (!(o = option_get(p, state->section))) {
+        pa_log("[%s:%u] Priority makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_atou(rvalue, &prio) < 0) {
-        pa_log("[%s:%u] Priority invalid of '%s'", filename, line, section);
+    if (pa_atou(state->rvalue, &prio) < 0) {
+        pa_log("[%s:%u] Priority invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
@@ -1442,125 +1928,135 @@ static int option_parse_priority(
     return 0;
 }
 
-static int option_parse_name(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int option_parse_name(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_option *o;
 
-    pa_assert(p);
+    pa_assert(state);
 
-    if (!(o = option_get(p, section))) {
-        pa_log("[%s:%u] Name makes no sense in '%s'", filename, line, section);
+    p = state->userdata;
+
+    if (!(o = option_get(p, state->section))) {
+        pa_log("[%s:%u] Name makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
     pa_xfree(o->name);
-    o->name = pa_xstrdup(rvalue);
+    o->name = pa_xstrdup(state->rvalue);
 
     return 0;
 }
 
-static int element_parse_required(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int element_parse_required(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_element *e;
+    pa_alsa_option *o;
+    pa_alsa_jack *j;
     pa_alsa_required_t req;
 
-    pa_assert(p);
+    pa_assert(state);
+
+    p = state->userdata;
 
-    if (!(e = element_get(p, section, TRUE))) {
-        pa_log("[%s:%u] Required makes no sense in '%s'", filename, line, section);
+    e = element_get(p, state->section, TRUE);
+    o = option_get(p, state->section);
+    j = jack_get(p, state->section);
+    if (!e && !o && !j) {
+        pa_log("[%s:%u] Required makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_streq(rvalue, "ignore"))
+    if (pa_streq(state->rvalue, "ignore"))
         req = PA_ALSA_REQUIRED_IGNORE;
-    else if (pa_streq(rvalue, "switch"))
+    else if (pa_streq(state->rvalue, "switch") && e)
         req = PA_ALSA_REQUIRED_SWITCH;
-    else if (pa_streq(rvalue, "volume"))
+    else if (pa_streq(state->rvalue, "volume") && e)
         req = PA_ALSA_REQUIRED_VOLUME;
-    else if (pa_streq(rvalue, "enumeration"))
+    else if (pa_streq(state->rvalue, "enumeration"))
         req = PA_ALSA_REQUIRED_ENUMERATION;
-    else if (pa_streq(rvalue, "any"))
+    else if (pa_streq(state->rvalue, "any"))
         req = PA_ALSA_REQUIRED_ANY;
     else {
-        pa_log("[%s:%u] Required invalid of '%s'", filename, line, section);
+        pa_log("[%s:%u] Required invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_streq(lvalue, "required-absent"))
-        e->required_absent = req;
-    else
-        e->required = req;
+    if (pa_streq(state->lvalue, "required-absent")) {
+        if (e)
+            e->required_absent = req;
+        if (o)
+            o->required_absent = req;
+        if (j)
+            j->required_absent = req;
+    }
+    else if (pa_streq(state->lvalue, "required-any")) {
+        if (e) {
+            e->required_any = req;
+            e->path->has_req_any |= (req != PA_ALSA_REQUIRED_IGNORE);
+        }
+        if (o) {
+            o->required_any = req;
+            o->element->path->has_req_any |= (req != PA_ALSA_REQUIRED_IGNORE);
+        }
+        if (j) {
+            j->required_any = req;
+            j->path->has_req_any |= (req != PA_ALSA_REQUIRED_IGNORE);
+        }
+
+    }
+    else {
+        if (e)
+            e->required = req;
+        if (o)
+            o->required = req;
+        if (j)
+            j->required = req;
+    }
 
     return 0;
 }
 
-static int element_parse_direction(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int element_parse_direction(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_element *e;
 
-    pa_assert(p);
+    pa_assert(state);
 
-    if (!(e = element_get(p, section, TRUE))) {
-        pa_log("[%s:%u] Direction makes no sense in '%s'", filename, line, section);
+    p = state->userdata;
+
+    if (!(e = element_get(p, state->section, TRUE))) {
+        pa_log("[%s:%u] Direction makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_streq(rvalue, "playback"))
+    if (pa_streq(state->rvalue, "playback"))
         e->direction = PA_ALSA_DIRECTION_OUTPUT;
-    else if (pa_streq(rvalue, "capture"))
+    else if (pa_streq(state->rvalue, "capture"))
         e->direction = PA_ALSA_DIRECTION_INPUT;
     else {
-        pa_log("[%s:%u] Direction invalid of '%s'", filename, line, section);
+        pa_log("[%s:%u] Direction invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
     return 0;
 }
 
-static int element_parse_direction_try_other(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int element_parse_direction_try_other(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_element *e;
     int yes;
 
-    if (!(e = element_get(p, section, TRUE))) {
-        pa_log("[%s:%u] Direction makes no sense in '%s'", filename, line, section);
+    pa_assert(state);
+
+    p = state->userdata;
+
+    if (!(e = element_get(p, state->section, TRUE))) {
+        pa_log("[%s:%u] Direction makes no sense in '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if ((yes = pa_parse_boolean(rvalue)) < 0) {
-        pa_log("[%s:%u] Direction invalid of '%s'", filename, line, section);
+    if ((yes = pa_parse_boolean(state->rvalue)) < 0) {
+        pa_log("[%s:%u] Direction invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
@@ -1568,6 +2064,29 @@ static int element_parse_direction_try_other(
     return 0;
 }
 
+static int element_parse_volume_limit(pa_config_parser_state *state) {
+    pa_alsa_path *p;
+    pa_alsa_element *e;
+    long volume_limit;
+
+    pa_assert(state);
+
+    p = state->userdata;
+
+    if (!(e = 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;
+    }
+
+    if (pa_atol(state->rvalue, &volume_limit) < 0 || volume_limit < 0) {
+        pa_log("[%s:%u] Invalid value for volume-limit", state->filename, state->lineno);
+        return -1;
+    }
+
+    e->volume_limit = volume_limit;
+    return 0;
+}
+
 static pa_channel_position_mask_t parse_mask(const char *m) {
     pa_channel_position_mask_t v;
 
@@ -1601,40 +2120,36 @@ static pa_channel_position_mask_t parse_mask(const char *m) {
     return v;
 }
 
-static int element_parse_override_map(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_path *p = userdata;
+static int element_parse_override_map(pa_config_parser_state *state) {
+    pa_alsa_path *p;
     pa_alsa_element *e;
-    const char *state = NULL;
+    const char *split_state = NULL;
     unsigned i = 0;
     char *n;
 
-    if (!(e = element_get(p, section, TRUE))) {
-        pa_log("[%s:%u] Override map makes no sense in '%s'", filename, line, section);
+    pa_assert(state);
+
+    p = state->userdata;
+
+    if (!(e = 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;
     }
 
-    while ((n = pa_split(rvalue, ",", &state))) {
+    while ((n = pa_split(state->rvalue, ",", &split_state))) {
         pa_channel_position_mask_t m;
 
         if (!*n)
             m = 0;
         else {
             if ((m = parse_mask(n)) == 0) {
-                pa_log("[%s:%u] Override map '%s' invalid in '%s'", filename, line, n, section);
+                pa_log("[%s:%u] Override map '%s' invalid in '%s'", state->filename, state->lineno, n, state->section);
                 pa_xfree(n);
                 return -1;
             }
         }
 
-        if (pa_streq(lvalue, "override-map.1"))
+        if (pa_streq(state->lvalue, "override-map.1"))
             e->masks[i++][0] = m;
         else
             e->masks[i++][1] = m;
@@ -1649,6 +2164,41 @@ static int element_parse_override_map(
     return 0;
 }
 
+static int jack_parse_state(pa_config_parser_state *state) {
+    pa_alsa_path *p;
+    pa_alsa_jack *j;
+    pa_available_t pa;
+
+    pa_assert(state);
+
+    p = state->userdata;
+
+    if (!(j = jack_get(p, state->section))) {
+        pa_log("[%s:%u] state makes no sense in '%s'", state->filename, state->lineno, state->section);
+        return -1;
+    }
+
+    if (pa_streq(state->rvalue, "yes"))
+       pa = PA_AVAILABLE_YES;
+    else if (pa_streq(state->rvalue, "no"))
+       pa = PA_AVAILABLE_NO;
+    else if (pa_streq(state->rvalue, "unknown"))
+       pa = PA_AVAILABLE_UNKNOWN;
+    else {
+        pa_log("[%s:%u] state must be 'yes', 'no' or 'unknown' in '%s'", state->filename, state->lineno, state->section);
+        return -1;
+    }
+
+    if (pa_streq(state->lvalue, "state.unplugged"))
+        j->state_unplugged = pa;
+    else {
+        j->state_plugged = pa;
+        pa_assert(pa_streq(state->lvalue, "state.plugged"));
+    }
+
+    return 0;
+}
+
 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;
@@ -1671,19 +2221,19 @@ static int element_set_option(pa_alsa_element *e, snd_mixer_t *m, int alsa_idx)
             r = snd_mixer_selem_set_capture_switch_all(me, alsa_idx);
 
         if (r < 0)
-            pa_log_warn("Faile to set switch of %s: %s", e->alsa_name, pa_alsa_strerror(errno));
+            pa_log_warn("Failed to set switch of %s: %s", e->alsa_name, 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("Faile to set enumeration of %s: %s", e->alsa_name, pa_alsa_strerror(errno));
+            pa_log_warn("Failed to set enumeration of %s: %s", e->alsa_name, pa_alsa_strerror(errno));
     }
 
     return r;
 }
 
-int pa_alsa_setting_select(pa_alsa_setting *s, snd_mixer_t *m) {
+static int setting_select(pa_alsa_setting *s, snd_mixer_t *m) {
     pa_alsa_option *o;
     uint32_t idx;
 
@@ -1701,8 +2251,11 @@ static int option_verify(pa_alsa_option *o) {
         { "input",                     N_("Input") },
         { "input-docking",             N_("Docking Station Input") },
         { "input-docking-microphone",  N_("Docking Station Microphone") },
-        { "input-linein",              N_("Line-In") },
+        { "input-docking-linein",      N_("Docking Station Line In") },
+        { "input-linein",              N_("Line In") },
         { "input-microphone",          N_("Microphone") },
+        { "input-microphone-front",    N_("Front Microphone") },
+        { "input-microphone-rear",     N_("Rear Microphone") },
         { "input-microphone-external", N_("External Microphone") },
         { "input-microphone-internal", N_("Internal Microphone") },
         { "input-radio",               N_("Radio") },
@@ -1713,6 +2266,8 @@ static int option_verify(pa_alsa_option *o) {
         { "input-boost-off",           N_("No Boost") },
         { "output-amplifier-on",       N_("Amplifier") },
         { "output-amplifier-off",      N_("No Amplifier") },
+        { "output-bass-boost-on",      N_("Bass Boost") },
+        { "output-bass-boost-off",     N_("No Bass Boost") },
         { "output-speaker",            N_("Speaker") },
         { "output-headphones",         N_("Headphones") }
     };
@@ -1752,7 +2307,10 @@ static int element_verify(pa_alsa_element *e) {
 
     pa_assert(e);
 
+//    pa_log_debug("Element %s, path %s: r=%d, r-any=%d, r-abs=%d", e->alsa_name, e->path->name, e->required, e->required_any, e->required_absent);
     if ((e->required != PA_ALSA_REQUIRED_IGNORE && e->required == e->required_absent) ||
+        (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);
         return -1;
@@ -1773,16 +2331,25 @@ static int element_verify(pa_alsa_element *e) {
 static int path_verify(pa_alsa_path *p) {
     static const struct description_map well_known_descriptions[] = {
         { "analog-input",               N_("Analog Input") },
-        { "analog-input-microphone",    N_("Analog Microphone") },
-        { "analog-input-linein",        N_("Analog Line-In") },
-        { "analog-input-radio",         N_("Analog Radio") },
-        { "analog-input-video",         N_("Analog Video") },
+        { "analog-input-microphone",    N_("Microphone") },
+        { "analog-input-microphone-front",    N_("Front Microphone") },
+        { "analog-input-microphone-rear",     N_("Rear Microphone") },
+        { "analog-input-microphone-dock",     N_("Dock Microphone") },
+        { "analog-input-microphone-internal", N_("Internal Microphone") },
+        { "analog-input-microphone-headset",  N_("Headset Microphone") },
+        { "analog-input-linein",        N_("Line In") },
+        { "analog-input-radio",         N_("Radio") },
+        { "analog-input-video",         N_("Video") },
         { "analog-output",              N_("Analog Output") },
-        { "analog-output-headphones",   N_("Analog Headphones") },
-        { "analog-output-lfe-on-mono",  N_("Analog Output (LFE)") },
+        { "analog-output-headphones",   N_("Headphones") },
+        { "analog-output-lfe-on-mono",  N_("LFE on Separate Mono Output") },
+        { "analog-output-lineout",      N_("Line Out") },
         { "analog-output-mono",         N_("Analog Mono Output") },
-        { "analog-output-headphones-2", N_("Analog Headphones 2") },
-        { "analog-output-speaker",      N_("Analog Speaker") }
+        { "analog-output-speaker",      N_("Speakers") },
+        { "hdmi-output",                N_("HDMI / DisplayPort") },
+        { "iec958-stereo-output",       N_("Digital Output (S/PDIF)") },
+        { "iec958-stereo-input",        N_("Digital Input (S/PDIF)") },
+        { "iec958-passthrough-output",  N_("Digital Passthrough (S/PDIF)") }
     };
 
     pa_alsa_element *e;
@@ -1804,22 +2371,36 @@ static int path_verify(pa_alsa_path *p) {
     return 0;
 }
 
-pa_alsa_path* pa_alsa_path_new(const char *fname, pa_alsa_direction_t direction) {
+static const char *get_default_paths_dir(void) {
+    if (pa_run_from_build_tree())
+        return PA_SRCDIR "/modules/alsa/mixer/paths/";
+    else
+        return PA_ALSA_PATHS_DIR;
+}
+
+pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa_direction_t direction) {
     pa_alsa_path *p;
     char *fn;
     int r;
     const char *n;
+    bool mute_during_activation = false;
 
     pa_config_item items[] = {
         /* [General] */
         { "priority",            pa_config_parse_unsigned,          NULL, "General" },
         { "description",         pa_config_parse_string,            NULL, "General" },
         { "name",                pa_config_parse_string,            NULL, "General" },
+        { "mute-during-activation", pa_config_parse_bool,           NULL, "General" },
+        { "eld-device",          pa_config_parse_int,               NULL, "General" },
 
         /* [Option ...] */
         { "priority",            option_parse_priority,             NULL, NULL },
         { "name",                option_parse_name,                 NULL, NULL },
 
+        /* [Jack ...] */
+        { "state.plugged",       jack_parse_state,                  NULL, NULL },
+        { "state.unplugged",     jack_parse_state,                  NULL, NULL },
+
         /* [Element ...] */
         { "switch",              element_parse_switch,              NULL, NULL },
         { "volume",              element_parse_volume,              NULL, NULL },
@@ -1828,9 +2409,11 @@ pa_alsa_path* pa_alsa_path_new(const char *fname, pa_alsa_direction_t direction)
         { "override-map.2",      element_parse_override_map,        NULL, NULL },
         /* ... later on we might add override-map.3 and so on here ... */
         { "required",            element_parse_required,            NULL, NULL },
+        { "required-any",        element_parse_required,            NULL, NULL },
         { "required-absent",     element_parse_required,            NULL, NULL },
         { "direction",           element_parse_direction,           NULL, NULL },
         { "direction-try-other", element_parse_direction_try_other, NULL, NULL },
+        { "volume-limit",        element_parse_volume_limit,        NULL, NULL },
         { NULL, NULL, NULL, NULL }
     };
 
@@ -1839,24 +2422,29 @@ pa_alsa_path* pa_alsa_path_new(const char *fname, pa_alsa_direction_t direction)
     p = pa_xnew0(pa_alsa_path, 1);
     n = pa_path_get_filename(fname);
     p->name = pa_xstrndup(n, strcspn(n, "."));
+    p->proplist = pa_proplist_new();
     p->direction = direction;
+    p->eld_device = -1;
 
     items[0].data = &p->priority;
     items[1].data = &p->description;
     items[2].data = &p->name;
+    items[3].data = &mute_during_activation;
+    items[4].data = &p->eld_device;
 
-    fn = pa_maybe_prefix_path(fname,
-#if defined(__linux__) && !defined(__OPTIMIZE__)
-                              pa_run_from_build_tree() ? PA_BUILDDIR "/modules/alsa/mixer/paths/" :
-#endif
-                              PA_ALSA_PATHS_DIR);
+    if (!paths_dir)
+        paths_dir = get_default_paths_dir();
 
-    r = pa_config_parse(fn, NULL, items, p);
+    fn = pa_maybe_prefix_path(fname, paths_dir);
+
+    r = pa_config_parse(fn, NULL, items, p->proplist, p);
     pa_xfree(fn);
 
     if (r < 0)
         goto fail;
 
+    p->mute_during_activation = mute_during_activation;
+
     if (path_verify(p) < 0)
         goto fail;
 
@@ -1867,7 +2455,7 @@ fail:
     return NULL;
 }
 
-pa_alsa_path* pa_alsa_path_synthesize(const char*element, pa_alsa_direction_t direction) {
+pa_alsa_path *pa_alsa_path_synthesize(const char *element, pa_alsa_direction_t direction) {
     pa_alsa_path *p;
     pa_alsa_element *e;
 
@@ -1881,11 +2469,13 @@ pa_alsa_path* pa_alsa_path_synthesize(const char*element, pa_alsa_direction_t di
     e->path = p;
     e->alsa_name = pa_xstrdup(element);
     e->direction = direction;
+    e->volume_limit = -1;
 
     e->switch_use = PA_ALSA_SWITCH_MUTE;
     e->volume_use = PA_ALSA_VOLUME_MERGE;
 
     PA_LLIST_PREPEND(pa_alsa_element, p->elements, e);
+    p->last_element = e;
     return p;
 }
 
@@ -1982,10 +2572,10 @@ static pa_bool_t element_create_settings(pa_alsa_element *e, pa_alsa_setting *te
         if (template) {
             s = pa_xnewdup(pa_alsa_setting, template, 1);
             s->options = pa_idxset_copy(template->options);
-            s->name = pa_sprintf_malloc(_("%s+%s"), template->name, o->name);
+            s->name = pa_sprintf_malloc("%s+%s", template->name, o->name);
             s->description =
                 (template->description[0] && o->description[0])
-                ? pa_sprintf_malloc(_("%s / %s"), template->description, o->description)
+                ? pa_sprintf_malloc("%s / %s", template->description, o->description)
                 : (template->description[0]
                    ? pa_xstrdup(template->description)
                    : pa_xstrdup(o->description));
@@ -2021,28 +2611,41 @@ static void path_create_settings(pa_alsa_path *p) {
     element_create_settings(p->elements, NULL);
 }
 
-int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB) {
+int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, snd_hctl_t *hctl, pa_bool_t ignore_dB) {
     pa_alsa_element *e;
+    pa_alsa_jack *j;
     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;
 
     pa_assert(p);
     pa_assert(m);
 
     if (p->probed)
-        return 0;
+        return p->supported ? 0 : -1;
+    p->probed = TRUE;
 
     pa_zero(min_dB);
     pa_zero(max_dB);
 
     pa_log_debug("Probing path '%s'", p->name);
 
+    PA_LLIST_FOREACH(j, p->jacks) {
+        if (jack_probe(j, hctl) < 0) {
+            p->supported = FALSE;
+            pa_log_debug("Probe of jack '%s' failed.", j->alsa_name);
+            return -1;
+        }
+        pa_log_debug("Probe of jack '%s' succeeded (%s)", j->alsa_name, j->has_control ? "found!" : "not found");
+    }
+
     PA_LLIST_FOREACH(e, p->elements) {
         if (element_probe(e, m) < 0) {
             p->supported = FALSE;
             pa_log_debug("Probe of element '%s' failed.", e->alsa_name);
             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);
 
         if (ignore_dB)
             e->has_dB = FALSE;
@@ -2060,6 +2663,7 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB) {
                         if (PA_CHANNEL_POSITION_MASK(t) & e->merged_mask) {
                             min_dB[t] = e->min_dB;
                             max_dB[t] = e->max_dB;
+                            path_volume_channels |= PA_CHANNEL_POSITION_MASK(t);
                         }
 
                     p->has_dB = TRUE;
@@ -2070,17 +2674,21 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB) {
                             if (PA_CHANNEL_POSITION_MASK(t) & e->merged_mask) {
                                 min_dB[t] += e->min_dB;
                                 max_dB[t] += e->max_dB;
+                                path_volume_channels |= PA_CHANNEL_POSITION_MASK(t);
                             }
-                    } else
+                    } else {
                         /* Hmm, there's another element before us
                          * 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);
+                    }
                 }
-            } else if (p->has_volume)
+            } 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);
+            }
             p->has_volume = TRUE;
         }
 
@@ -2088,22 +2696,29 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB) {
             p->has_mute = TRUE;
     }
 
+    if (p->has_req_any && !p->req_any_present) {
+        p->supported = FALSE;
+        pa_log_debug("Skipping path '%s', none of required-any elements preset.", p->name);
+        return -1;
+    }
+
     path_drop_unsupported(p);
     path_make_options_unique(p);
     path_create_settings(p);
 
     p->supported = TRUE;
-    p->probed = TRUE;
 
     p->min_dB = INFINITY;
     p->max_dB = -INFINITY;
 
     for (t = 0; t < PA_CHANNEL_POSITION_MAX; t++) {
-        if (p->min_dB > min_dB[t])
-            p->min_dB = min_dB[t];
+        if (path_volume_channels & PA_CHANNEL_POSITION_MASK(t)) {
+            if (p->min_dB > min_dB[t])
+                p->min_dB = min_dB[t];
 
-        if (p->max_dB < max_dB[t])
-            p->max_dB = max_dB[t];
+            if (p->max_dB < max_dB[t])
+                p->max_dB = max_dB[t];
+        }
     }
 
     return 0;
@@ -2118,6 +2733,12 @@ void pa_alsa_setting_dump(pa_alsa_setting *s) {
                  s->priority);
 }
 
+void pa_alsa_jack_dump(pa_alsa_jack *j) {
+    pa_assert(j);
+
+    pa_log_debug("Jack %s, alsa_name='%s', detection %s", j->name, j->alsa_name, j->has_control ? "possible" : "unavailable");
+}
+
 void pa_alsa_option_dump(pa_alsa_option *o) {
     pa_assert(o);
 
@@ -2133,13 +2754,15 @@ void pa_alsa_element_dump(pa_alsa_element *e) {
     pa_alsa_option *o;
     pa_assert(e);
 
-    pa_log_debug("Element %s, direction=%i, switch=%i, volume=%i, enumeration=%i, required=%i, required_absent=%i, mask=0x%llx, n_channels=%u, override_map=%s",
+    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,
                  e->direction,
                  e->switch_use,
                  e->volume_use,
+                 e->volume_limit,
                  e->enumeration_use,
                  e->required,
+                 e->required_any,
                  e->required_absent,
                  (long long unsigned) e->merged_mask,
                  e->n_channels,
@@ -2151,6 +2774,7 @@ void pa_alsa_element_dump(pa_alsa_element *e) {
 
 void pa_alsa_path_dump(pa_alsa_path *p) {
     pa_alsa_element *e;
+    pa_alsa_jack *j;
     pa_alsa_setting *s;
     pa_assert(p);
 
@@ -2171,6 +2795,9 @@ void pa_alsa_path_dump(pa_alsa_path *p) {
     PA_LLIST_FOREACH(e, p->elements)
         pa_alsa_element_dump(e);
 
+    PA_LLIST_FOREACH(j, p->jacks)
+        pa_alsa_jack_dump(j);
+
     PA_LLIST_FOREACH(s, p->settings)
         pa_alsa_setting_dump(s);
 }
@@ -2206,20 +2833,26 @@ void pa_alsa_path_set_callback(pa_alsa_path *p, snd_mixer_t *m, snd_mixer_elem_c
 
 void pa_alsa_path_set_set_callback(pa_alsa_path_set *ps, snd_mixer_t *m, snd_mixer_elem_callback_t cb, void *userdata) {
     pa_alsa_path *p;
+    void *state;
 
     pa_assert(ps);
     pa_assert(m);
     pa_assert(cb);
 
-    PA_LLIST_FOREACH(p, ps->paths)
+    PA_HASHMAP_FOREACH(p, ps->paths, state)
         pa_alsa_path_set_callback(p, m, cb, userdata);
 }
 
-pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t direction) {
+pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t direction, const char *paths_dir) {
     pa_alsa_path_set *ps;
     char **pn = NULL, **en = NULL, **ie;
+    pa_alsa_decibel_fix *db_fix;
+    void *state, *state2;
+    pa_hashmap *cache;
 
     pa_assert(m);
+    pa_assert(m->profile_set);
+    pa_assert(m->profile_set->decibel_fixes);
     pa_assert(direction == PA_ALSA_DIRECTION_OUTPUT || direction == PA_ALSA_DIRECTION_INPUT);
 
     if (m->direction != PA_ALSA_DIRECTION_ANY && m->direction != direction)
@@ -2227,21 +2860,26 @@ pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t d
 
     ps = pa_xnew0(pa_alsa_path_set, 1);
     ps->direction = direction;
+    ps->paths = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
 
-    if (direction == PA_ALSA_DIRECTION_OUTPUT)
+    if (direction == PA_ALSA_DIRECTION_OUTPUT) {
         pn = m->output_path_names;
-    else if (direction == PA_ALSA_DIRECTION_INPUT)
+        cache = m->profile_set->output_paths;
+    }
+    else if (direction == PA_ALSA_DIRECTION_INPUT) {
         pn = m->input_path_names;
+        cache = m->profile_set->input_paths;
+    }
 
     if (pn) {
         char **in;
 
         for (in = pn; *in; in++) {
-            pa_alsa_path *p;
+            pa_alsa_path *p = NULL;
             pa_bool_t duplicate = FALSE;
-            char **kn, *fn;
+            char **kn;
 
-            for (kn = pn; kn != in; kn++)
+            for (kn = pn; kn < in; kn++)
                 if (pa_streq(*kn, *in)) {
                     duplicate = TRUE;
                     break;
@@ -2250,18 +2888,21 @@ pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t d
             if (duplicate)
                 continue;
 
-            fn = pa_sprintf_malloc("%s.conf", *in);
-
-            if ((p = pa_alsa_path_new(fn, direction))) {
-                p->path_set = ps;
-                PA_LLIST_INSERT_AFTER(pa_alsa_path, ps->paths, ps->last_path, p);
-                ps->last_path = p;
+            p = pa_hashmap_get(cache, *in);
+            if (!p) {
+                char *fn = pa_sprintf_malloc("%s.conf", *in);
+                p = pa_alsa_path_new(paths_dir, fn, direction);
+                pa_xfree(fn);
+                if (p)
+                    pa_hashmap_put(cache, *in, p);
             }
+            pa_assert(pa_hashmap_get(cache, *in) == p);
+            if (p)
+                pa_hashmap_put(ps->paths, p, p);
 
-            pa_xfree(fn);
         }
 
-        return ps;
+        goto finish;
     }
 
     if (direction == PA_ALSA_DIRECTION_OUTPUT)
@@ -2279,23 +2920,48 @@ pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t d
         pa_alsa_path *p;
 
         p = pa_alsa_path_synthesize(*ie, direction);
-        p->path_set = ps;
 
         /* Mark all other passed elements for require-absent */
         for (je = en; *je; je++) {
             pa_alsa_element *e;
+
+            if (je == ie)
+                continue;
+
             e = pa_xnew0(pa_alsa_element, 1);
             e->path = p;
             e->alsa_name = pa_xstrdup(*je);
             e->direction = direction;
             e->required_absent = PA_ALSA_REQUIRED_ANY;
+            e->volume_limit = -1;
 
             PA_LLIST_INSERT_AFTER(pa_alsa_element, p->elements, p->last_element, e);
             p->last_element = e;
         }
 
-        PA_LLIST_INSERT_AFTER(pa_alsa_path, ps->paths, ps->last_path, p);
-        ps->last_path = p;
+        pa_hashmap_put(ps->paths, *ie, p);
+    }
+
+finish:
+    /* Assign decibel fixes to elements. */
+    PA_HASHMAP_FOREACH(db_fix, m->profile_set->decibel_fixes, state) {
+        pa_alsa_path *p;
+
+        PA_HASHMAP_FOREACH(p, ps->paths, state2) {
+            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)) {
+                    /* The profile set that contains the dB fix may be freed
+                     * before the element, so we have to copy the dB fix
+                     * object. */
+                    e->db_fix = pa_xnewdup(pa_alsa_decibel_fix, db_fix, 1);
+                    e->db_fix->profile_set = NULL;
+                    e->db_fix->name = pa_xstrdup(db_fix->name);
+                    e->db_fix->db_values = pa_xmemdup(db_fix->db_values, (db_fix->max_step - db_fix->min_step + 1) * sizeof(long));
+                }
+            }
+        }
     }
 
     return ps;
@@ -2303,70 +2969,264 @@ 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 *ps) {
     pa_alsa_path *p;
+    void *state;
     pa_assert(ps);
 
-    pa_log_debug("Path Set %p, direction=%i, probed=%s",
+    pa_log_debug("Path Set %p, direction=%i",
                  (void*) ps,
-                 ps->direction,
-                 pa_yes_no(ps->probed));
+                 ps->direction);
 
-    PA_LLIST_FOREACH(p, ps->paths)
+    PA_HASHMAP_FOREACH(p, ps->paths, state)
         pa_alsa_path_dump(p);
 }
 
-static void path_set_unify(pa_alsa_path_set *ps) {
+
+static pa_bool_t options_have_option(pa_alsa_option *options, const char *alsa_name) {
+    pa_alsa_option *o;
+
+    pa_assert(options);
+    pa_assert(alsa_name);
+
+    PA_LLIST_FOREACH(o, options) {
+        if (pa_streq(o->alsa_name, alsa_name))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+static pa_bool_t enumeration_is_subset(pa_alsa_option *a_options, pa_alsa_option *b_options) {
+    pa_alsa_option *oa, *ob;
+
+    if (!a_options) return TRUE;
+    if (!b_options) return FALSE;
+
+    /* If there is an option A offers that B does not, then A is not a subset of B. */
+    PA_LLIST_FOREACH(oa, a_options) {
+        pa_bool_t found = FALSE;
+        PA_LLIST_FOREACH(ob, b_options) {
+            if (pa_streq(oa->alsa_name, ob->alsa_name)) {
+                found = TRUE;
+                break;
+            }
+        }
+        if (!found)
+            return FALSE;
+    }
+    return TRUE;
+}
+
+/**
+ *  Compares two elements to see if a is a subset of b
+ */
+static pa_bool_t element_is_subset(pa_alsa_element *a, pa_alsa_element *b, snd_mixer_t *m) {
+    pa_assert(a);
+    pa_assert(b);
+    pa_assert(m);
+
+    /* General rules:
+     * Every state is a subset of itself (with caveats for volume_limits and options)
+     * IGNORE is a subset of every other state */
+
+    /* Check the volume_use */
+    if (a->volume_use != PA_ALSA_VOLUME_IGNORE) {
+
+        /* "Constant" is subset of "Constant" only when their constant values are equal */
+        if (a->volume_use == PA_ALSA_VOLUME_CONSTANT && b->volume_use == PA_ALSA_VOLUME_CONSTANT && a->constant_volume != b->constant_volume)
+            return FALSE;
+
+        /* Different volume uses when b is not "Merge" means we are definitely not a subset */
+        if (a->volume_use != b->volume_use && b->volume_use != PA_ALSA_VOLUME_MERGE)
+            return FALSE;
+
+        /* "Constant" is a subset of "Merge", if there is not a "volume-limit" in "Merge" below the actual constant.
+         * "Zero" and "Off" are just special cases of "Constant" when comparing to "Merge"
+         * "Merge" with a "volume-limit" is a subset of "Merge" without a "volume-limit" or with a higher "volume-limit" */
+        if (b->volume_use == PA_ALSA_VOLUME_MERGE && b->volume_limit >= 0) {
+            long a_limit;
+
+            if (a->volume_use == PA_ALSA_VOLUME_CONSTANT)
+                a_limit = a->constant_volume;
+            else if (a->volume_use == PA_ALSA_VOLUME_ZERO) {
+                long dB = 0;
+
+                if (a->db_fix) {
+                    int rounding = (a->direction == PA_ALSA_DIRECTION_OUTPUT ? +1 : -1);
+                    a_limit = decibel_fix_get_step(a->db_fix, &dB, rounding);
+                } else {
+                    snd_mixer_selem_id_t *sid;
+                    snd_mixer_elem_t *me;
+
+                    SELEM_INIT(sid, a->alsa_name);
+                    if (!(me = snd_mixer_find_selem(m, sid))) {
+                        pa_log_warn("Element %s seems to have disappeared.", a->alsa_name);
+                        return FALSE;
+                    }
+
+                    if (a->direction == PA_ALSA_DIRECTION_OUTPUT) {
+                        if (snd_mixer_selem_ask_playback_dB_vol(me, dB, +1, &a_limit) < 0)
+                            return FALSE;
+                    } else {
+                        if (snd_mixer_selem_ask_capture_dB_vol(me, dB, -1, &a_limit) < 0)
+                            return FALSE;
+                    }
+                }
+            } else if (a->volume_use == PA_ALSA_VOLUME_OFF)
+                a_limit = a->min_volume;
+            else if (a->volume_use == PA_ALSA_VOLUME_MERGE)
+                a_limit = a->volume_limit;
+            else
+                /* This should never be reached */
+                pa_assert(FALSE);
+
+            if (a_limit > b->volume_limit)
+                return FALSE;
+        }
+
+        if (a->volume_use == PA_ALSA_VOLUME_MERGE) {
+            int s;
+            /* If override-maps are different, they're not subsets */
+            if (a->n_channels != b->n_channels)
+                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]) {
+                    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);
+                    return FALSE;
+               }
+        }
+    }
+
+    if (a->switch_use != PA_ALSA_SWITCH_IGNORE) {
+        /* "On" is a subset of "Mute".
+         * "Off" is a subset of "Mute".
+         * "On" is a subset of "Select", if there is an "Option:On" in B.
+         * "Off" is a subset of "Select", if there is an "Option:Off" in B.
+         * "Select" is a subset of "Select", if they have the same options (is this always true?). */
+
+        if (a->switch_use != b->switch_use) {
+
+            if (a->switch_use == PA_ALSA_SWITCH_SELECT || a->switch_use == PA_ALSA_SWITCH_MUTE
+                || b->switch_use == PA_ALSA_SWITCH_OFF || b->switch_use == PA_ALSA_SWITCH_ON)
+                return FALSE;
+
+            if (b->switch_use == PA_ALSA_SWITCH_SELECT) {
+                if (a->switch_use == PA_ALSA_SWITCH_ON) {
+                    if (!options_have_option(b->options, "on"))
+                        return FALSE;
+                } else if (a->switch_use == PA_ALSA_SWITCH_OFF) {
+                    if (!options_have_option(b->options, "off"))
+                        return FALSE;
+                }
+            }
+        } else if (a->switch_use == PA_ALSA_SWITCH_SELECT) {
+            if (!enumeration_is_subset(a->options, b->options))
+                return FALSE;
+        }
+    }
+
+    if (a->enumeration_use != PA_ALSA_ENUMERATION_IGNORE) {
+        if (b->enumeration_use == PA_ALSA_ENUMERATION_IGNORE)
+            return FALSE;
+        if (!enumeration_is_subset(a->options, b->options))
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+static void path_set_condense(pa_alsa_path_set *ps, snd_mixer_t *m) {
     pa_alsa_path *p;
-    pa_bool_t has_dB = TRUE, has_volume = TRUE, has_mute = TRUE;
+    void *state;
+
     pa_assert(ps);
+    pa_assert(m);
+
+    /* If we only have one path, then don't bother */
+    if (pa_hashmap_size(ps->paths) < 2)
+        return;
+
+    PA_HASHMAP_FOREACH(p, ps->paths, state) {
+        pa_alsa_path *p2;
+        void *state2;
 
-    /* We have issues dealing with paths that vary too wildly. That
-     * means for now we have to have all paths support volume/mute/dB
-     * or none. */
+        PA_HASHMAP_FOREACH(p2, ps->paths, state2) {
+            pa_alsa_element *ea, *eb;
+            pa_alsa_jack *ja, *jb;
+            bool is_subset = true;
 
-    PA_LLIST_FOREACH(p, ps->paths) {
-        pa_assert(p->probed);
+            if (p == p2)
+                continue;
 
-        if (!p->has_volume)
-            has_volume = FALSE;
-        else if (!p->has_dB)
-            has_dB = FALSE;
+            /* If a has a jack that b does not have, a is not a subset */
+            PA_LLIST_FOREACH(ja, p->jacks) {
+                bool exists = false;
 
-        if (!p->has_mute)
-            has_mute = FALSE;
-    }
+                if (!ja->has_control)
+                    continue;
 
-    if (!has_volume || !has_dB || !has_mute) {
+                PA_LLIST_FOREACH(jb, p2->jacks) {
+                    if (jb->has_control && pa_streq(jb->alsa_name, ja->alsa_name) &&
+                       (ja->state_plugged == jb->state_plugged) &&
+                       (ja->state_unplugged == jb->state_unplugged)) {
+                        exists = true;
+                        break;
+                    }
+                }
 
-        if (!has_volume)
-            pa_log_debug("Some paths of the device lack hardware volume control, disabling hardware control altogether.");
-        else if (!has_dB)
-            pa_log_debug("Some paths of the device lack dB information, disabling dB logic altogether.");
+                if (!exists) {
+                    is_subset = false;
+                    break;
+                }
+            }
 
-        if (!has_mute)
-            pa_log_debug("Some paths of the device lack hardware mute control, disabling hardware control altogether.");
+            /* Compare the elements of each set... */
+            ea = p->elements;
+            eb = p2->elements;
 
-        PA_LLIST_FOREACH(p, ps->paths) {
-            if (!has_volume)
-                p->has_volume = FALSE;
-            else if (!has_dB)
-                p->has_dB = FALSE;
+            while (is_subset) {
+                if (!ea && !eb)
+                    break;
+                else if ((ea && !eb) || (!ea && eb))
+                    is_subset = false;
+                else if (pa_streq(ea->alsa_name, eb->alsa_name)) {
+                    if (element_is_subset(ea, eb, m)) {
+                        ea = ea->next;
+                        eb = eb->next;
+                    } else
+                        is_subset = false;
+                } else
+                    is_subset = false;
+            }
 
-            if (!has_mute)
-                p->has_mute = FALSE;
+            if (is_subset) {
+                pa_log_debug("Removing path '%s' as it is a subset of '%s'.", p->name, p2->name);
+                pa_hashmap_remove(ps->paths, p);
+                break;
+            }
         }
     }
 }
 
+static pa_alsa_path* path_set_find_path_by_name(pa_alsa_path_set *ps, const char* name, pa_alsa_path *ignore)
+{
+    pa_alsa_path* p;
+    void *state;
+
+    PA_HASHMAP_FOREACH(p, ps->paths, state)
+        if (p != ignore && pa_streq(p->name, name))
+            return p;
+    return NULL;
+}
+
 static void path_set_make_paths_unique(pa_alsa_path_set *ps) {
     pa_alsa_path *p, *q;
+    void *state, *state2;
 
-    PA_LLIST_FOREACH(p, ps->paths) {
+    PA_HASHMAP_FOREACH(p, ps->paths, state) {
         unsigned i;
         char *m;
 
-        for (q = p->next; q; q = q->next)
-            if (pa_streq(q->name, p->name))
-                break;
+        q = path_set_find_path_by_name(ps, p->name, p);
 
         if (!q)
             continue;
@@ -2374,7 +3234,8 @@ static void path_set_make_paths_unique(pa_alsa_path_set *ps) {
         m = pa_xstrdup(p->name);
 
         /* OK, this name is not unique, hence let's rename */
-        for (i = 1, q = p; q; q = q->next) {
+        i = 1;
+        PA_HASHMAP_FOREACH(q, ps->paths, state2) {
             char *nn, *nd;
 
             if (!pa_streq(q->name, m))
@@ -2395,43 +3256,29 @@ static void path_set_make_paths_unique(pa_alsa_path_set *ps) {
     }
 }
 
-void pa_alsa_path_set_probe(pa_alsa_path_set *ps, snd_mixer_t *m, pa_bool_t ignore_dB) {
-    pa_alsa_path *p, *n;
-
-    pa_assert(ps);
-
-    if (ps->probed)
-        return;
-
-    for (p = ps->paths; p; p = n) {
-        n = p->next;
-
-        if (pa_alsa_path_probe(p, m, ignore_dB) < 0) {
-            PA_LLIST_REMOVE(pa_alsa_path, ps->paths, p);
-            pa_alsa_path_free(p);
-        }
-    }
-
-    path_set_unify(ps);
-    path_set_make_paths_unique(ps);
-    ps->probed = TRUE;
-}
-
 static void mapping_free(pa_alsa_mapping *m) {
     pa_assert(m);
 
     pa_xfree(m->name);
     pa_xfree(m->description);
 
+    pa_proplist_free(m->proplist);
+
     pa_xstrfreev(m->device_strings);
     pa_xstrfreev(m->input_path_names);
     pa_xstrfreev(m->output_path_names);
     pa_xstrfreev(m->input_element);
     pa_xstrfreev(m->output_element);
+    if (m->input_path_set)
+        pa_alsa_path_set_free(m->input_path_set);
+    if (m->output_path_set)
+        pa_alsa_path_set_free(m->output_path_set);
 
     pa_assert(!m->input_pcm);
     pa_assert(!m->output_pcm);
 
+    pa_alsa_ucm_mapping_context_free(&m->ucm_context);
+
     pa_xfree(m);
 }
 
@@ -2445,10 +3292,10 @@ static void profile_free(pa_alsa_profile *p) {
     pa_xstrfreev(p->output_mapping_names);
 
     if (p->input_mappings)
-        pa_idxset_free(p->input_mappings, NULL, NULL);
+        pa_idxset_free(p->input_mappings, NULL);
 
     if (p->output_mappings)
-        pa_idxset_free(p->output_mappings, NULL, NULL);
+        pa_idxset_free(p->output_mappings, NULL);
 
     pa_xfree(p);
 }
@@ -2456,28 +3303,25 @@ static void profile_free(pa_alsa_profile *p) {
 void pa_alsa_profile_set_free(pa_alsa_profile_set *ps) {
     pa_assert(ps);
 
-    if (ps->profiles) {
-        pa_alsa_profile *p;
+    if (ps->input_paths)
+        pa_hashmap_free(ps->input_paths, (pa_free_cb_t) pa_alsa_path_free);
 
-        while ((p = pa_hashmap_steal_first(ps->profiles)))
-            profile_free(p);
+    if (ps->output_paths)
+        pa_hashmap_free(ps->output_paths, (pa_free_cb_t) pa_alsa_path_free);
 
-        pa_hashmap_free(ps->profiles, NULL, NULL);
-    }
+    if (ps->profiles)
+        pa_hashmap_free(ps->profiles, (pa_free_cb_t) profile_free);
 
-    if (ps->mappings) {
-        pa_alsa_mapping *m;
+    if (ps->mappings)
+        pa_hashmap_free(ps->mappings, (pa_free_cb_t) mapping_free);
 
-        while ((m = pa_hashmap_steal_first(ps->mappings)))
-            mapping_free(m);
-
-        pa_hashmap_free(ps->mappings, NULL, NULL);
-    }
+    if (ps->decibel_fixes)
+        pa_hashmap_free(ps->decibel_fixes, (pa_free_cb_t) decibel_fix_free);
 
     pa_xfree(ps);
 }
 
-static pa_alsa_mapping *mapping_get(pa_alsa_profile_set *ps, const char *name) {
+pa_alsa_mapping *pa_alsa_mapping_get(pa_alsa_profile_set *ps, const char *name) {
     pa_alsa_mapping *m;
 
     if (!pa_startswith(name, "Mapping "))
@@ -2492,6 +3336,7 @@ static pa_alsa_mapping *mapping_get(pa_alsa_profile_set *ps, const char *name) {
     m->profile_set = ps;
     m->name = pa_xstrdup(name);
     pa_channel_map_init(&m->channel_map);
+    m->proplist = pa_proplist_new();
 
     pa_hashmap_put(ps->mappings, m->name, m);
 
@@ -2518,268 +3363,234 @@ static pa_alsa_profile *profile_get(pa_alsa_profile_set *ps, const char *name) {
     return p;
 }
 
-static int mapping_parse_device_strings(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
+static pa_alsa_decibel_fix *decibel_fix_get(pa_alsa_profile_set *ps, const char *name) {
+    pa_alsa_decibel_fix *db_fix;
+
+    if (!pa_startswith(name, "DecibelFix "))
+        return NULL;
+
+    name += 11;
+
+    if ((db_fix = pa_hashmap_get(ps->decibel_fixes, name)))
+        return db_fix;
+
+    db_fix = pa_xnew0(pa_alsa_decibel_fix, 1);
+    db_fix->profile_set = ps;
+    db_fix->name = pa_xstrdup(name);
+
+    pa_hashmap_put(ps->decibel_fixes, db_fix->name, db_fix);
+
+    return db_fix;
+}
 
-    pa_alsa_profile_set *ps = userdata;
+static int mapping_parse_device_strings(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_mapping *m;
 
-    pa_assert(ps);
+    pa_assert(state);
+
+    ps = state->userdata;
 
-    if (!(m = mapping_get(ps, section))) {
-        pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
+    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_xstrfreev(m->device_strings);
-    if (!(m->device_strings = pa_split_spaces_strv(rvalue))) {
-        pa_log("[%s:%u] Device string list empty of '%s'", filename, line, section);
+    if (!(m->device_strings = pa_split_spaces_strv(state->rvalue))) {
+        pa_log("[%s:%u] Device string list empty of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
     return 0;
 }
 
-static int mapping_parse_channel_map(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int mapping_parse_channel_map(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_mapping *m;
 
-    pa_assert(ps);
+    pa_assert(state);
+
+    ps = state->userdata;
 
-    if (!(m = mapping_get(ps, section))) {
-        pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
+    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;
     }
 
-    if (!(pa_channel_map_parse(&m->channel_map, rvalue))) {
-        pa_log("[%s:%u] Channel map invalid of '%s'", filename, line, section);
+    if (!(pa_channel_map_parse(&m->channel_map, state->rvalue))) {
+        pa_log("[%s:%u] Channel map invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
     return 0;
 }
 
-static int mapping_parse_paths(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int mapping_parse_paths(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_mapping *m;
 
-    pa_assert(ps);
+    pa_assert(state);
+
+    ps = state->userdata;
 
-    if (!(m = mapping_get(ps, section))) {
-        pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
+    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;
     }
 
-    if (pa_streq(lvalue, "paths-input")) {
+    if (pa_streq(state->lvalue, "paths-input")) {
         pa_xstrfreev(m->input_path_names);
-        m->input_path_names = pa_split_spaces_strv(rvalue);
+        m->input_path_names = pa_split_spaces_strv(state->rvalue);
     } else {
         pa_xstrfreev(m->output_path_names);
-        m->output_path_names = pa_split_spaces_strv(rvalue);
+        m->output_path_names = pa_split_spaces_strv(state->rvalue);
     }
 
     return 0;
 }
 
-static int mapping_parse_element(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int mapping_parse_element(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_mapping *m;
 
-    pa_assert(ps);
+    pa_assert(state);
 
-    if (!(m = mapping_get(ps, section))) {
-        pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
+    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;
     }
 
-    if (pa_streq(lvalue, "element-input")) {
+    if (pa_streq(state->lvalue, "element-input")) {
         pa_xstrfreev(m->input_element);
-        m->input_element = pa_split_spaces_strv(rvalue);
+        m->input_element = pa_split_spaces_strv(state->rvalue);
     } else {
         pa_xstrfreev(m->output_element);
-        m->output_element = pa_split_spaces_strv(rvalue);
+        m->output_element = pa_split_spaces_strv(state->rvalue);
     }
 
     return 0;
 }
 
-static int mapping_parse_direction(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int mapping_parse_direction(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_mapping *m;
 
-    pa_assert(ps);
+    pa_assert(state);
 
-    if (!(m = mapping_get(ps, section))) {
-        pa_log("[%s:%u] Section name %s invalid.", filename, line, section);
+    ps = state->userdata;
+
+    if (!(m = pa_alsa_mapping_get(ps, state->section))) {
+        pa_log("[%s:%u] Section name %s invalid.", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if (pa_streq(rvalue, "input"))
+    if (pa_streq(state->rvalue, "input"))
         m->direction = PA_ALSA_DIRECTION_INPUT;
-    else if (pa_streq(rvalue, "output"))
+    else if (pa_streq(state->rvalue, "output"))
         m->direction = PA_ALSA_DIRECTION_OUTPUT;
-    else if (pa_streq(rvalue, "any"))
+    else if (pa_streq(state->rvalue, "any"))
         m->direction = PA_ALSA_DIRECTION_ANY;
     else {
-        pa_log("[%s:%u] Direction %s invalid.", filename, line, rvalue);
+        pa_log("[%s:%u] Direction %s invalid.", state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
     return 0;
 }
 
-static int mapping_parse_description(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int mapping_parse_description(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_profile *p;
     pa_alsa_mapping *m;
 
-    pa_assert(ps);
+    pa_assert(state);
+
+    ps = state->userdata;
 
-    if ((m = mapping_get(ps, section))) {
-        pa_xstrdup(m->description);
-        m->description = pa_xstrdup(rvalue);
-    } else if ((p = profile_get(ps, section))) {
+    if ((m = pa_alsa_mapping_get(ps, state->section))) {
+        pa_xfree(m->description);
+        m->description = pa_xstrdup(state->rvalue);
+    } else if ((p = profile_get(ps, state->section))) {
         pa_xfree(p->description);
-        p->description = pa_xstrdup(rvalue);
+        p->description = pa_xstrdup(state->rvalue);
     } else {
-        pa_log("[%s:%u] Section name %s invalid.", filename, line, section);
+        pa_log("[%s:%u] Section name %s invalid.", state->filename, state->lineno, state->section);
         return -1;
     }
 
     return 0;
 }
 
-static int mapping_parse_priority(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int mapping_parse_priority(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_profile *p;
     pa_alsa_mapping *m;
     uint32_t prio;
 
-    pa_assert(ps);
+    pa_assert(state);
+
+    ps = state->userdata;
 
-    if (pa_atou(rvalue, &prio) < 0) {
-        pa_log("[%s:%u] Priority invalid of '%s'", filename, line, section);
+    if (pa_atou(state->rvalue, &prio) < 0) {
+        pa_log("[%s:%u] Priority invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
-    if ((m = mapping_get(ps, section)))
+    if ((m = pa_alsa_mapping_get(ps, state->section)))
         m->priority = prio;
-    else if ((p = profile_get(ps, section)))
+    else if ((p = profile_get(ps, state->section)))
         p->priority = prio;
     else {
-        pa_log("[%s:%u] Section name %s invalid.", filename, line, section);
+        pa_log("[%s:%u] Section name %s invalid.", state->filename, state->lineno, state->section);
         return -1;
     }
 
     return 0;
 }
 
-static int profile_parse_mappings(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int profile_parse_mappings(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_profile *p;
 
-    pa_assert(ps);
+    pa_assert(state);
 
-    if (!(p = profile_get(ps, section))) {
-        pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
+    ps = state->userdata;
+
+    if (!(p = profile_get(ps, state->section))) {
+        pa_log("[%s:%u] %s invalid in section %s", state->filename, state->lineno, state->lvalue, state->section);
         return -1;
     }
 
-    if (pa_streq(lvalue, "input-mappings")) {
+    if (pa_streq(state->lvalue, "input-mappings")) {
         pa_xstrfreev(p->input_mapping_names);
-        p->input_mapping_names = pa_split_spaces_strv(rvalue);
+        p->input_mapping_names = pa_split_spaces_strv(state->rvalue);
     } else {
         pa_xstrfreev(p->output_mapping_names);
-        p->output_mapping_names = pa_split_spaces_strv(rvalue);
+        p->output_mapping_names = pa_split_spaces_strv(state->rvalue);
     }
 
     return 0;
 }
 
-static int profile_parse_skip_probe(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    pa_alsa_profile_set *ps = userdata;
+static int profile_parse_skip_probe(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
     pa_alsa_profile *p;
     int b;
 
-    pa_assert(ps);
+    pa_assert(state);
 
-    if (!(p = profile_get(ps, section))) {
-        pa_log("[%s:%u] %s invalid in section %s", filename, line, lvalue, section);
+    ps = state->userdata;
+
+    if (!(p = profile_get(ps, state->section))) {
+        pa_log("[%s:%u] %s invalid in section %s", state->filename, state->lineno, state->lvalue, state->section);
         return -1;
     }
 
-    if ((b = pa_parse_boolean(rvalue)) < 0) {
-        pa_log("[%s:%u] Skip probe invalid of '%s'", filename, line, section);
+    if ((b = pa_parse_boolean(state->rvalue)) < 0) {
+        pa_log("[%s:%u] Skip probe invalid of '%s'", state->filename, state->lineno, state->section);
         return -1;
     }
 
@@ -2788,6 +3599,171 @@ static int profile_parse_skip_probe(
     return 0;
 }
 
+static int decibel_fix_parse_db_values(pa_config_parser_state *state) {
+    pa_alsa_profile_set *ps;
+    pa_alsa_decibel_fix *db_fix;
+    char **items;
+    char *item;
+    long *db_values;
+    unsigned n = 8; /* Current size of the db_values table. */
+    unsigned min_step = 0;
+    unsigned max_step = 0;
+    unsigned i = 0; /* Index to the items table. */
+    unsigned prev_step = 0;
+    double prev_db = 0;
+
+    pa_assert(state);
+
+    ps = state->userdata;
+
+    if (!(db_fix = decibel_fix_get(ps, state->section))) {
+        pa_log("[%s:%u] %s invalid in section %s", state->filename, state->lineno, state->lvalue, state->section);
+        return -1;
+    }
+
+    if (!(items = pa_split_spaces_strv(state->rvalue))) {
+        pa_log("[%s:%u] Value missing", state->filename, state->lineno);
+        return -1;
+    }
+
+    db_values = pa_xnew(long, n);
+
+    while ((item = items[i++])) {
+        char *s = item; /* Step value string. */
+        char *d = item; /* dB value string. */
+        uint32_t step;
+        double db;
+
+        /* Move d forward until it points to a colon or to the end of the item. */
+        for (; *d && *d != ':'; ++d);
+
+        if (d == s) {
+            /* item started with colon. */
+            pa_log("[%s:%u] No step value found in %s", state->filename, state->lineno, item);
+            goto fail;
+        }
+
+        if (!*d || !*(d + 1)) {
+            /* No colon found, or it was the last character in item. */
+            pa_log("[%s:%u] No dB value found in %s", state->filename, state->lineno, item);
+            goto fail;
+        }
+
+        /* pa_atou() needs a null-terminating string. Let's replace the colon
+         * with a zero byte. */
+        *d++ = '\0';
+
+        if (pa_atou(s, &step) < 0) {
+            pa_log("[%s:%u] Invalid step value: %s", state->filename, state->lineno, s);
+            goto fail;
+        }
+
+        if (pa_atod(d, &db) < 0) {
+            pa_log("[%s:%u] Invalid dB value: %s", state->filename, state->lineno, d);
+            goto fail;
+        }
+
+        if (step <= prev_step && i != 1) {
+            pa_log("[%s:%u] Step value %u not greater than the previous value %u", state->filename, state->lineno, step, prev_step);
+            goto fail;
+        }
+
+        if (db < prev_db && i != 1) {
+            pa_log("[%s:%u] Decibel value %0.2f less than the previous value %0.2f", state->filename, state->lineno, db, prev_db);
+            goto fail;
+        }
+
+        if (i == 1) {
+            min_step = step;
+            db_values[0] = (long) (db * 100.0);
+            prev_step = step;
+            prev_db = db;
+        } else {
+            /* Interpolate linearly. */
+            double db_increment = (db - prev_db) / (step - prev_step);
+
+            for (; prev_step < step; ++prev_step, prev_db += db_increment) {
+
+                /* Reallocate the db_values table if it's about to overflow. */
+                if (prev_step + 1 - min_step == n) {
+                    n *= 2;
+                    db_values = pa_xrenew(long, db_values, n);
+                }
+
+                db_values[prev_step + 1 - min_step] = (long) ((prev_db + db_increment) * 100.0);
+            }
+        }
+
+        max_step = step;
+    }
+
+    db_fix->min_step = min_step;
+    db_fix->max_step = max_step;
+    pa_xfree(db_fix->db_values);
+    db_fix->db_values = db_values;
+
+    pa_xstrfreev(items);
+
+    return 0;
+
+fail:
+    pa_xstrfreev(items);
+    pa_xfree(db_values);
+
+    return -1;
+}
+
+static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile,
+                                pa_alsa_direction_t direction) {
+
+    pa_alsa_path *p;
+    void *state;
+    snd_pcm_t *pcm_handle;
+    pa_alsa_path_set *ps;
+    snd_mixer_t *mixer_handle;
+    snd_hctl_t *hctl_handle;
+
+    if (direction == PA_ALSA_DIRECTION_OUTPUT) {
+        if (m->output_path_set)
+            return; /* Already probed */
+        m->output_path_set = ps = pa_alsa_path_set_new(m, direction, NULL); /* FIXME: Handle paths_dir */
+        pcm_handle = m->output_pcm;
+    } else {
+        if (m->input_path_set)
+            return; /* Already probed */
+        m->input_path_set = ps = pa_alsa_path_set_new(m, direction, NULL); /* FIXME: Handle paths_dir */
+        pcm_handle = m->input_pcm;
+    }
+
+    if (!ps)
+        return; /* No paths */
+
+    pa_assert(pcm_handle);
+
+    mixer_handle = pa_alsa_open_mixer_for_pcm(pcm_handle, NULL, &hctl_handle);
+    if (!mixer_handle || !hctl_handle) {
+         /* Cannot open mixer, remove all entries */
+        pa_hashmap_remove_all(ps->paths, NULL);
+        return;
+    }
+
+
+    PA_HASHMAP_FOREACH(p, ps->paths, state) {
+        if (pa_alsa_path_probe(p, mixer_handle, hctl_handle, m->profile_set->ignore_dB) < 0) {
+            pa_hashmap_remove(ps->paths, p);
+        }
+    }
+
+    path_set_condense(ps, mixer_handle);
+    path_set_make_paths_unique(ps);
+
+    if (mixer_handle)
+        snd_mixer_close(mixer_handle);
+
+    pa_log_debug("Available mixer paths (after tidying):");
+    pa_alsa_path_set_dump(ps);
+}
+
 static int mapping_verify(pa_alsa_mapping *m, const pa_channel_map *bonus) {
 
     static const struct description_map well_known_descriptions[] = {
@@ -2804,11 +3780,14 @@ static int mapping_verify(pa_alsa_mapping *m, const pa_channel_map *bonus) {
         { "analog-surround-61",     N_("Analog Surround 6.1") },
         { "analog-surround-70",     N_("Analog Surround 7.0") },
         { "analog-surround-71",     N_("Analog Surround 7.1") },
+        { "analog-4-channel-input", N_("Analog 4-channel Input") },
         { "iec958-stereo",          N_("Digital Stereo (IEC958)") },
-        { "iec958-surround-40",     N_("Digital Surround 4.0 (IEC958)") },
+        { "iec958-passthrough",     N_("Digital Passthrough  (IEC958)") },
         { "iec958-ac3-surround-40", N_("Digital Surround 4.0 (IEC958/AC3)") },
         { "iec958-ac3-surround-51", N_("Digital Surround 5.1 (IEC958/AC3)") },
-        { "hdmi-stereo",            N_("Digital Stereo (HDMI)") }
+        { "iec958-dts-surround-51", N_("Digital Surround 5.1 (IEC958/DTS)") },
+        { "hdmi-stereo",            N_("Digital Stereo (HDMI)") },
+        { "hdmi-surround-51",       N_("Digital Surround 5.1 (HDMI)") }
     };
 
     pa_assert(m);
@@ -2825,7 +3804,7 @@ static int mapping_verify(pa_alsa_mapping *m, const pa_channel_map *bonus) {
 
     if ((m->input_path_names && m->input_element) ||
         (m->output_path_names && m->output_element)) {
-        pa_log("Mapping %s must have either mixer path or mixer elment, not both.", m->name);
+        pa_log("Mapping %s must have either mixer path or mixer element, not both.", m->name);
         return -1;
     }
 
@@ -2915,6 +3894,16 @@ static void profile_set_add_auto(pa_alsa_profile_set *ps) {
 
     pa_assert(ps);
 
+    /* The order is important here:
+       1) try single inputs and outputs before trying their
+          combination, because if the half-duplex test failed, we don't have
+          to try full duplex.
+       2) try the output right before the input combinations with
+          that output, because then the output_pcm is not closed between tests.
+    */
+    PA_HASHMAP_FOREACH(n, ps->mappings, n_state)
+        profile_set_add_auto_pair(ps, NULL, n);
+
     PA_HASHMAP_FOREACH(m, ps->mappings, m_state) {
         profile_set_add_auto_pair(ps, m, NULL);
 
@@ -2922,8 +3911,6 @@ static void profile_set_add_auto(pa_alsa_profile_set *ps) {
             profile_set_add_auto_pair(ps, m, n);
     }
 
-    PA_HASHMAP_FOREACH(n, ps->mappings, n_state)
-        profile_set_add_auto_pair(ps, NULL, n);
 }
 
 static int profile_verify(pa_alsa_profile *p) {
@@ -2931,7 +3918,7 @@ static int profile_verify(pa_alsa_profile *p) {
     static const struct description_map well_known_descriptions[] = {
         { "output:analog-mono+input:analog-mono",     N_("Analog Mono Duplex") },
         { "output:analog-stereo+input:analog-stereo", N_("Analog Stereo Duplex") },
-        { "output:iec958-stereo",                     N_("Digital Stereo Duplex (IEC958)") },
+        { "output:iec958-stereo+input:iec958-stereo", N_("Digital Stereo Duplex (IEC958)") },
         { "off",                                      N_("Off") }
     };
 
@@ -2959,7 +3946,7 @@ static int profile_verify(pa_alsa_profile *p) {
                 continue;
 
             if (!(m = pa_hashmap_get(p->profile_set->mappings, *name)) || m->direction == PA_ALSA_DIRECTION_INPUT) {
-                pa_log("Profile '%s' refers to unexistant mapping '%s'.", p->name, *name);
+                pa_log("Profile '%s' refers to nonexistent mapping '%s'.", p->name, *name);
                 return -1;
             }
 
@@ -2995,7 +3982,7 @@ static int profile_verify(pa_alsa_profile *p) {
                 continue;
 
             if (!(m = pa_hashmap_get(p->profile_set->mappings, *name)) || m->direction == PA_ALSA_DIRECTION_OUTPUT) {
-                pa_log("Profile '%s' refers to unexistant mapping '%s'.", p->name, *name);
+                pa_log("Profile '%s' refers to nonexistent mapping '%s'.", p->name, *name);
                 return -1;
             }
 
@@ -3031,7 +4018,7 @@ static int profile_verify(pa_alsa_profile *p) {
                 if (!pa_strbuf_isempty(sb))
                     pa_strbuf_puts(sb, " + ");
 
-                pa_strbuf_printf(sb, "%s Output", m->description);
+                pa_strbuf_printf(sb, _("%s Output"), m->description);
             }
 
         if (p->input_mappings)
@@ -3039,7 +4026,7 @@ static int profile_verify(pa_alsa_profile *p) {
                 if (!pa_strbuf_isempty(sb))
                     pa_strbuf_puts(sb, " + ");
 
-                pa_strbuf_printf(sb, "%s Input", m->description);
+                pa_strbuf_printf(sb, _("%s Input"), m->description);
             }
 
         p->description = pa_strbuf_tostring_free(sb);
@@ -3070,10 +4057,52 @@ void pa_alsa_profile_dump(pa_alsa_profile *p) {
             pa_log_debug("Output %s", m->name);
 }
 
+static int decibel_fix_verify(pa_alsa_decibel_fix *db_fix) {
+    pa_assert(db_fix);
+
+    /* Check that the dB mapping has been configured. Since "db-values" is
+     * currently the only option in the DecibelFix section, and decibel fix
+     * objects don't get created if a DecibelFix section is empty, this is
+     * actually a redundant check. Having this may prevent future bugs,
+     * however. */
+    if (!db_fix->db_values) {
+        pa_log("Decibel fix for element %s lacks the dB values.", db_fix->name);
+        return -1;
+    }
+
+    return 0;
+}
+
+void pa_alsa_decibel_fix_dump(pa_alsa_decibel_fix *db_fix) {
+    char *db_values = NULL;
+
+    pa_assert(db_fix);
+
+    if (db_fix->db_values) {
+        pa_strbuf *buf;
+        unsigned long i, nsteps;
+
+        pa_assert(db_fix->min_step <= db_fix->max_step);
+        nsteps = db_fix->max_step - db_fix->min_step + 1;
+
+        buf = pa_strbuf_new();
+        for (i = 0; i < nsteps; ++i)
+            pa_strbuf_printf(buf, "[%li]:%0.2f ", i + db_fix->min_step, db_fix->db_values[i] / 100.0);
+
+        db_values = pa_strbuf_tostring_free(buf);
+    }
+
+    pa_log_debug("Decibel fix %s, min_step=%li, max_step=%li, db_values=%s",
+                 db_fix->name, db_fix->min_step, db_fix->max_step, pa_strnull(db_values));
+
+    pa_xfree(db_values);
+}
+
 pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel_map *bonus) {
     pa_alsa_profile_set *ps;
     pa_alsa_profile *p;
     pa_alsa_mapping *m;
+    pa_alsa_decibel_fix *db_fix;
     char *fn;
     int r;
     void *state;
@@ -3099,12 +4128,18 @@ pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel
         { "input-mappings",         profile_parse_mappings,       NULL, NULL },
         { "output-mappings",        profile_parse_mappings,       NULL, NULL },
         { "skip-probe",             profile_parse_skip_probe,     NULL, NULL },
+
+        /* [DecibelFix ...] */
+        { "db-values",              decibel_fix_parse_db_values,  NULL, NULL },
         { NULL, NULL, NULL, NULL }
     };
 
     ps = pa_xnew0(pa_alsa_profile_set, 1);
     ps->mappings = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
     ps->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    ps->decibel_fixes = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    ps->input_paths = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    ps->output_paths = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
 
     items[0].data = &ps->auto_profiles;
 
@@ -3112,12 +4147,10 @@ pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel
         fname = "default.conf";
 
     fn = pa_maybe_prefix_path(fname,
-#if defined(__linux__) && !defined(__OPTIMIZE__)
-                              pa_run_from_build_tree() ? PA_BUILDDIR "/modules/alsa/mixer/profile-sets/" :
-#endif
+                              pa_run_from_build_tree() ? PA_SRCDIR "/modules/alsa/mixer/profile-sets/" :
                               PA_ALSA_PROFILE_SETS_DIR);
 
-    r = pa_config_parse(fn, NULL, items, ps);
+    r = pa_config_parse(fn, NULL, items, NULL, ps);
     pa_xfree(fn);
 
     if (r < 0)
@@ -3134,6 +4167,10 @@ pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel
         if (profile_verify(p) < 0)
             goto fail;
 
+    PA_HASHMAP_FOREACH(db_fix, ps->decibel_fixes, state)
+        if (decibel_fix_verify(db_fix) < 0)
+            goto fail;
+
     return ps;
 
 fail:
@@ -3141,6 +4178,96 @@ fail:
     return NULL;
 }
 
+static void profile_finalize_probing(pa_alsa_profile *to_be_finalized, pa_alsa_profile *next) {
+    pa_alsa_mapping *m;
+    uint32_t idx;
+
+    if (!to_be_finalized)
+        return;
+
+    if (to_be_finalized->output_mappings)
+        PA_IDXSET_FOREACH(m, to_be_finalized->output_mappings, idx) {
+
+            if (!m->output_pcm)
+                continue;
+
+            if (to_be_finalized->supported)
+                m->supported++;
+
+            /* If this mapping is also in the next profile, we won't close the
+             * pcm handle here, because it would get immediately reopened
+             * anyway. */
+            if (next && next->output_mappings && pa_idxset_get_by_data(next->output_mappings, m, NULL))
+                continue;
+
+            snd_pcm_close(m->output_pcm);
+            m->output_pcm = NULL;
+        }
+
+    if (to_be_finalized->input_mappings)
+        PA_IDXSET_FOREACH(m, to_be_finalized->input_mappings, idx) {
+
+            if (!m->input_pcm)
+                continue;
+
+            if (to_be_finalized->supported)
+                m->supported++;
+
+            /* If this mapping is also in the next profile, we won't close the
+             * pcm handle here, because it would get immediately reopened
+             * anyway. */
+            if (next && next->input_mappings && pa_idxset_get_by_data(next->input_mappings, m, NULL))
+                continue;
+
+            snd_pcm_close(m->input_pcm);
+            m->input_pcm = NULL;
+        }
+}
+
+static snd_pcm_t* mapping_open_pcm(pa_alsa_mapping *m,
+                                   const pa_sample_spec *ss,
+                                   const char *dev_id,
+                                   int mode,
+                                   unsigned default_n_fragments,
+                                   unsigned default_fragment_size_msec) {
+
+    pa_sample_spec try_ss = *ss;
+    pa_channel_map try_map = m->channel_map;
+    snd_pcm_uframes_t try_period_size, try_buffer_size;
+
+    try_ss.channels = try_map.channels;
+
+    try_period_size =
+        pa_usec_to_bytes(default_fragment_size_msec * PA_USEC_PER_MSEC, &try_ss) /
+        pa_frame_size(&try_ss);
+    try_buffer_size = default_n_fragments * try_period_size;
+
+    return pa_alsa_open_by_template(
+#ifdef __TIZEN__
+                              m->ucm_context.ucm->core,
+#endif
+                              m->device_strings, dev_id, NULL, &try_ss,
+                              &try_map, mode, &try_period_size,
+                              &try_buffer_size, 0, NULL, NULL, TRUE);
+}
+
+static void paths_drop_unsupported(pa_hashmap* h) {
+
+    void* state = NULL;
+    const void* key;
+    pa_alsa_path* p;
+
+    pa_assert(h);
+    p = pa_hashmap_iterate(h, &state, &key);
+    while (p) {
+        if (p->supported <= 0) {
+            pa_hashmap_remove(h, key);
+            pa_alsa_path_free(p);
+        }
+        p = pa_hashmap_iterate(h, &state, &key);
+    }
+}
+
 void pa_alsa_profile_set_probe(
         pa_alsa_profile_set *ps,
         const char *dev_id,
@@ -3151,6 +4278,7 @@ void pa_alsa_profile_set_probe(
     void *state;
     pa_alsa_profile *p, *last = NULL;
     pa_alsa_mapping *m;
+    pa_hashmap *broken_inputs, *broken_outputs;
 
     pa_assert(ps);
     pa_assert(dev_id);
@@ -3159,154 +4287,112 @@ void pa_alsa_profile_set_probe(
     if (ps->probed)
         return;
 
+    broken_inputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+    broken_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+
     PA_HASHMAP_FOREACH(p, ps->profiles, state) {
-        pa_sample_spec try_ss;
-        pa_channel_map try_map;
-        snd_pcm_uframes_t try_period_size, try_buffer_size;
         uint32_t idx;
 
-        /* Is this already marked that it is supported? (i.e. from the config file) */
-        if (p->supported)
-            continue;
-
-        pa_log_debug("Looking at profile %s", p->name);
-
-        /* Close PCMs from the last iteration we don't need anymore */
-        if (last && last->output_mappings)
-            PA_IDXSET_FOREACH(m, last->output_mappings, idx) {
-
-                if (!m->output_pcm)
-                    break;
+        /* Skip if this is already marked that it is supported (i.e. from the config file) */
+        if (!p->supported) {
 
-                if (last->supported)
-                    m->supported++;
+            profile_finalize_probing(last, p);
+            p->supported = TRUE;
 
-                if (!p->output_mappings || !pa_idxset_get_by_data(p->output_mappings, m, NULL)) {
-                    snd_pcm_close(m->output_pcm);
-                    m->output_pcm = NULL;
+            if (p->output_mappings) {
+                PA_IDXSET_FOREACH(m, p->output_mappings, idx) {
+                    if (pa_hashmap_get(broken_outputs, m) == m) {
+                        pa_log_debug("Skipping profile %s - will not be able to open output:%s", p->name, m->name);
+                        p->supported = FALSE;
+                        break;
+                    }
                 }
             }
 
-        if (last && last->input_mappings)
-            PA_IDXSET_FOREACH(m, last->input_mappings, idx) {
-
-                if (!m->input_pcm)
-                    break;
-
-                if (last->supported)
-                    m->supported++;
-
-                if (!p->input_mappings || !pa_idxset_get_by_data(p->input_mappings, m, NULL)) {
-                    snd_pcm_close(m->input_pcm);
-                    m->input_pcm = NULL;
+            if (p->input_mappings && p->supported) {
+                PA_IDXSET_FOREACH(m, p->input_mappings, idx) {
+                    if (pa_hashmap_get(broken_inputs, m) == m) {
+                        pa_log_debug("Skipping profile %s - will not be able to open input:%s", p->name, m->name);
+                        p->supported = FALSE;
+                        break;
+                    }
                 }
             }
 
-        p->supported = TRUE;
-
-        /* Check if we can open all new ones */
-        if (p->output_mappings)
-            PA_IDXSET_FOREACH(m, p->output_mappings, idx) {
-
-                if (m->output_pcm)
-                    continue;
+            if (p->supported)
+                pa_log_debug("Looking at profile %s", p->name);
+
+            /* Check if we can open all new ones */
+            if (p->output_mappings && p->supported)
+                PA_IDXSET_FOREACH(m, p->output_mappings, idx) {
+
+                    if (m->output_pcm)
+                        continue;
+
+                    pa_log_debug("Checking for playback on %s (%s)", m->description, m->name);
+                    if (!(m->output_pcm = mapping_open_pcm(m, ss, dev_id,
+                                                           SND_PCM_STREAM_PLAYBACK,
+                                                           default_n_fragments,
+                                                           default_fragment_size_msec))) {
+                        p->supported = FALSE;
+                        if (pa_idxset_size(p->output_mappings) == 1 &&
+                            ((!p->input_mappings) || pa_idxset_size(p->input_mappings) == 0)) {
+                            pa_log_debug("Caching failure to open output:%s", m->name);
+                            pa_hashmap_put(broken_outputs, m, m);
+                        }
+                        break;
+                    }
+                }
 
-                pa_log_debug("Checking for playback on %s (%s)", m->description, m->name);
-                try_map = m->channel_map;
-                try_ss = *ss;
-                try_ss.channels = try_map.channels;
-
-                try_period_size =
-                    pa_usec_to_bytes(default_fragment_size_msec * PA_USEC_PER_MSEC, &try_ss) /
-                    pa_frame_size(&try_ss);
-                try_buffer_size = default_n_fragments * try_period_size;
-
-                if (!(m ->output_pcm = pa_alsa_open_by_template(
-                              m->device_strings,
-                              dev_id,
-                              NULL,
-                              &try_ss, &try_map,
-                              SND_PCM_STREAM_PLAYBACK,
-                              &try_period_size, &try_buffer_size, 0, NULL, NULL,
-                              TRUE))) {
-                    p->supported = FALSE;
-                    break;
+            if (p->input_mappings && p->supported)
+                PA_IDXSET_FOREACH(m, p->input_mappings, idx) {
+
+                    if (m->input_pcm)
+                        continue;
+
+                    pa_log_debug("Checking for recording on %s (%s)", m->description, m->name);
+                    if (!(m->input_pcm = mapping_open_pcm(m, ss, dev_id,
+                                                          SND_PCM_STREAM_CAPTURE,
+                                                          default_n_fragments,
+                                                          default_fragment_size_msec))) {
+                        p->supported = FALSE;
+                        if (pa_idxset_size(p->input_mappings) == 1 &&
+                            ((!p->output_mappings) || pa_idxset_size(p->output_mappings) == 0)) {
+                            pa_log_debug("Caching failure to open input:%s", m->name);
+                            pa_hashmap_put(broken_inputs, m, m);
+                        }
+                        break;
+                    }
                 }
-            }
 
-        if (p->input_mappings && p->supported)
-            PA_IDXSET_FOREACH(m, p->input_mappings, idx) {
+            last = p;
 
-                if (m->input_pcm)
-                    continue;
+            if (!p->supported)
+                continue;
+        }
 
-                pa_log_debug("Checking for recording on %s (%s)", m->description, m->name);
-                try_map = m->channel_map;
-                try_ss = *ss;
-                try_ss.channels = try_map.channels;
-
-                try_period_size =
-                    pa_usec_to_bytes(default_fragment_size_msec*PA_USEC_PER_MSEC, &try_ss) /
-                    pa_frame_size(&try_ss);
-                try_buffer_size = default_n_fragments * try_period_size;
-
-                if (!(m ->input_pcm = pa_alsa_open_by_template(
-                              m->device_strings,
-                              dev_id,
-                              NULL,
-                              &try_ss, &try_map,
-                              SND_PCM_STREAM_CAPTURE,
-                              &try_period_size, &try_buffer_size, 0, NULL, NULL,
-                              TRUE))) {
-                    p->supported = FALSE;
-                    break;
-                }
-            }
+        pa_log_debug("Profile %s supported.", p->name);
 
-        last = p;
+        if (p->output_mappings)
+            PA_IDXSET_FOREACH(m, p->output_mappings, idx)
+                if (m->output_pcm)
+                    mapping_paths_probe(m, p, PA_ALSA_DIRECTION_OUTPUT);
 
-        if (p->supported)
-            pa_log_debug("Profile %s supported.", p->name);
+        if (p->input_mappings)
+            PA_IDXSET_FOREACH(m, p->input_mappings, idx)
+                if (m->input_pcm)
+                    mapping_paths_probe(m, p, PA_ALSA_DIRECTION_INPUT);
     }
 
     /* Clean up */
-    if (last) {
-        uint32_t idx;
-
-        if (last->output_mappings)
-            PA_IDXSET_FOREACH(m, last->output_mappings, idx)
-                if (m->output_pcm) {
-
-                    if (last->supported)
-                        m->supported++;
-
-                    snd_pcm_close(m->output_pcm);
-                    m->output_pcm = NULL;
-                }
-
-        if (last->input_mappings)
-            PA_IDXSET_FOREACH(m, last->input_mappings, idx)
-                if (m->input_pcm) {
-
-                    if (last->supported)
-                        m->supported++;
+    profile_finalize_probing(last, NULL);
 
-                    snd_pcm_close(m->input_pcm);
-                    m->input_pcm = NULL;
-                }
-    }
+    pa_alsa_profile_set_drop_unsupported(ps);
 
-    PA_HASHMAP_FOREACH(p, ps->profiles, state)
-        if (!p->supported) {
-            pa_hashmap_remove(ps->profiles, p->name);
-            profile_free(p);
-        }
-
-    PA_HASHMAP_FOREACH(m, ps->mappings, state)
-        if (m->supported <= 0) {
-            pa_hashmap_remove(ps->mappings, m->name);
-            mapping_free(m);
-        }
+    paths_drop_unsupported(ps->input_paths);
+    paths_drop_unsupported(ps->output_paths);
+    pa_hashmap_free(broken_inputs, NULL);
+    pa_hashmap_free(broken_outputs, NULL);
 
     ps->probed = TRUE;
 }
@@ -3314,116 +4400,154 @@ void pa_alsa_profile_set_probe(
 void pa_alsa_profile_set_dump(pa_alsa_profile_set *ps) {
     pa_alsa_profile *p;
     pa_alsa_mapping *m;
+    pa_alsa_decibel_fix *db_fix;
     void *state;
 
     pa_assert(ps);
 
-    pa_log_debug("Profile set %p, auto_profiles=%s, probed=%s, n_mappings=%u, n_profiles=%u",
+    pa_log_debug("Profile set %p, auto_profiles=%s, probed=%s, n_mappings=%u, n_profiles=%u, n_decibel_fixes=%u",
                  (void*)
                  ps,
                  pa_yes_no(ps->auto_profiles),
                  pa_yes_no(ps->probed),
                  pa_hashmap_size(ps->mappings),
-                 pa_hashmap_size(ps->profiles));
+                 pa_hashmap_size(ps->profiles),
+                 pa_hashmap_size(ps->decibel_fixes));
 
     PA_HASHMAP_FOREACH(m, ps->mappings, state)
         pa_alsa_mapping_dump(m);
 
     PA_HASHMAP_FOREACH(p, ps->profiles, state)
         pa_alsa_profile_dump(p);
-}
 
-void pa_alsa_add_ports(pa_hashmap **p, pa_alsa_path_set *ps) {
-    pa_alsa_path *path;
-
-    pa_assert(p);
-    pa_assert(!*p);
-    pa_assert(ps);
+    PA_HASHMAP_FOREACH(db_fix, ps->decibel_fixes, state)
+        pa_alsa_decibel_fix_dump(db_fix);
+}
 
-    /* if there is no path, we don't want a port list */
-    if (!ps->paths)
-        return;
+void pa_alsa_profile_set_drop_unsupported(pa_alsa_profile_set *ps) {
+    pa_alsa_profile *p;
+    pa_alsa_mapping *m;
+    void *state;
 
-    if (!ps->paths->next){
-        pa_alsa_setting *s;
+    PA_HASHMAP_FOREACH(p, ps->profiles, state) {
+        if (!p->supported) {
+            pa_hashmap_remove(ps->profiles, p->name);
+            profile_free(p);
+        }
+    }
 
-        /* If there is only one path, but no or only one setting, then
-         * we want a port list either */
-        if (!ps->paths->settings || !ps->paths->settings->next)
-            return;
+    PA_HASHMAP_FOREACH(m, ps->mappings, state) {
+        if (m->supported <= 0) {
+            pa_hashmap_remove(ps->mappings, m->name);
+            mapping_free(m);
+        }
+    }
+}
 
-        /* Ok, there is only one path, however with multiple settings,
-         * so let's create a port for each setting */
-        *p = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+static pa_device_port* device_port_alsa_init(pa_hashmap *ports,
+    const char* name,
+    const char* description,
+    pa_alsa_path *path,
+    pa_alsa_setting *setting,
+    pa_card_profile *cp,
+    pa_hashmap *extra,
+    pa_core *core) {
 
-        PA_LLIST_FOREACH(s, ps->paths->settings) {
-            pa_device_port *port;
-            pa_alsa_port_data *data;
+    pa_device_port *p;
 
-            port = pa_device_port_new(s->name, s->description, sizeof(pa_alsa_port_data));
-            port->priority = s->priority;
+    pa_assert(path);
 
-            data = PA_DEVICE_PORT_DATA(port);
-            data->path = ps->paths;
-            data->setting = s;
+    p = pa_hashmap_get(ports, name);
 
-            pa_hashmap_put(*p, port->name, port);
-        }
+    if (!p) {
+        pa_alsa_port_data *data;
 
-    } else {
+        p = pa_device_port_new(core, name, description, sizeof(pa_alsa_port_data));
+        pa_assert(p);
+        pa_hashmap_put(ports, p->name, p);
+        pa_proplist_update(p->proplist, PA_UPDATE_REPLACE, path->proplist);
 
-        /* We have multiple paths, so let's create a port for each
-         * one, and each of each settings */
-        *p = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+        data = PA_DEVICE_PORT_DATA(p);
+        data->path = path;
+        data->setting = setting;
+        path->port = p;
+    }
 
-        PA_LLIST_FOREACH(path, ps->paths) {
+    p->is_input |= path->direction == PA_ALSA_DIRECTION_ANY || path->direction == PA_ALSA_DIRECTION_INPUT;
+    p->is_output |= path->direction == PA_ALSA_DIRECTION_ANY || path->direction == PA_ALSA_DIRECTION_OUTPUT;
 
-            if (!path->settings || !path->settings->next) {
-                pa_device_port *port;
-                pa_alsa_port_data *data;
+    if (cp)
+        pa_hashmap_put(p->profiles, cp->name, cp);
 
-                /* If there is no or just one setting we only need a
-                 * single entry */
+    if (extra) {
+        pa_hashmap_put(extra, p->name, p);
+        pa_device_port_ref(p);
+    }
 
-                port = pa_device_port_new(path->name, path->description, sizeof(pa_alsa_port_data));
-                port->priority = path->priority * 100;
+    return p;
+}
 
+void pa_alsa_path_set_add_ports(
+        pa_alsa_path_set *ps,
+        pa_card_profile *cp,
+        pa_hashmap *ports,
+        pa_hashmap *extra,
+        pa_core *core) {
 
-                data = PA_DEVICE_PORT_DATA(port);
-                data->path = path;
-                data->setting = path->settings;
+    pa_alsa_path *path;
+    void *state;
 
-                pa_hashmap_put(*p, port->name, port);
-            } else {
-                pa_alsa_setting *s;
+    pa_assert(ports);
 
-                PA_LLIST_FOREACH(s, path->settings) {
-                    pa_device_port *port;
-                    pa_alsa_port_data *data;
-                    char *n, *d;
+    if (!ps)
+        return;
 
-                    n = pa_sprintf_malloc("%s;%s", path->name, s->name);
+    PA_HASHMAP_FOREACH(path, ps->paths, state) {
+        if (!path->settings || !path->settings->next) {
+            /* If there is no or just one setting we only need a
+             * single entry */
+            pa_device_port *port = device_port_alsa_init(ports, path->name,
+                path->description, path, path->settings, cp, extra, core);
+            port->priority = path->priority * 100;
 
-                    if (s->description[0])
-                        d = pa_sprintf_malloc(_("%s / %s"), path->description, s->description);
-                    else
-                        d = pa_xstrdup(path->description);
+        } else {
+            pa_alsa_setting *s;
+            PA_LLIST_FOREACH(s, path->settings) {
+                pa_device_port *port;
+                char *n, *d;
 
-                    port = pa_device_port_new(n, d, sizeof(pa_alsa_port_data));
-                    port->priority = path->priority * 100 + s->priority;
+                n = pa_sprintf_malloc("%s;%s", path->name, s->name);
 
-                    pa_xfree(n);
-                    pa_xfree(d);
+                if (s->description[0])
+                    d = pa_sprintf_malloc("%s / %s", path->description, s->description);
+                else
+                    d = pa_xstrdup(path->description);
 
-                    data = PA_DEVICE_PORT_DATA(port);
-                    data->path = path;
-                    data->setting = s;
+                port = device_port_alsa_init(ports, n, d, path, s, cp, extra, core);
+                port->priority = path->priority * 100 + s->priority;
 
-                    pa_hashmap_put(*p, port->name, port);
-                }
+                pa_xfree(n);
+                pa_xfree(d);
             }
         }
     }
+}
+
+void pa_alsa_add_ports(void *sink_or_source_new_data, pa_alsa_path_set *ps, pa_card *card) {
+    pa_hashmap *ports;
+
+    pa_assert(sink_or_source_new_data);
+    pa_assert(ps);
+
+    if (ps->direction == PA_ALSA_DIRECTION_OUTPUT)
+        ports = ((pa_sink_new_data *) sink_or_source_new_data)->ports;
+    else
+        ports = ((pa_source_new_data *) sink_or_source_new_data)->ports;
+
+    if (ps->paths && pa_hashmap_size(ps->paths) > 0) {
+        pa_assert(card);
+        pa_alsa_path_set_add_ports(ps, NULL, card->ports, ports, card->core);
+    }
 
-    pa_log_debug("Added %u ports", pa_hashmap_size(*p));
+    pa_log_debug("Added %u ports", pa_hashmap_size(ports));
 }
index a0d4fcb..b3f7455 100644 (file)
 #include <asoundlib.h>
 
 #include <pulse/sample.h>
-#include <pulse/volume.h>
 #include <pulse/mainloop-api.h>
 #include <pulse/channelmap.h>
-#include <pulse/proplist.h>
 #include <pulse/volume.h>
 
 #include <pulsecore/llist.h>
 #include <pulsecore/rtpoll.h>
-#include <pulsecore/core.h>
-#include <pulsecore/log.h>
 
 typedef struct pa_alsa_fdlist pa_alsa_fdlist;
+typedef struct pa_alsa_mixer_pdata pa_alsa_mixer_pdata;
 typedef struct pa_alsa_setting pa_alsa_setting;
 typedef struct pa_alsa_option pa_alsa_option;
 typedef struct pa_alsa_element pa_alsa_element;
+typedef struct pa_alsa_jack pa_alsa_jack;
 typedef struct pa_alsa_path pa_alsa_path;
 typedef struct pa_alsa_path_set pa_alsa_path_set;
 typedef struct pa_alsa_mapping pa_alsa_mapping;
 typedef struct pa_alsa_profile pa_alsa_profile;
+typedef struct pa_alsa_decibel_fix pa_alsa_decibel_fix;
 typedef struct pa_alsa_profile_set pa_alsa_profile_set;
 typedef struct pa_alsa_port_data pa_alsa_port_data;
 
 #include "alsa-util.h"
+#include "alsa-ucm.h"
 
 typedef enum pa_alsa_switch_use {
     PA_ALSA_SWITCH_IGNORE,
@@ -60,9 +60,10 @@ typedef enum pa_alsa_switch_use {
 
 typedef enum pa_alsa_volume_use {
     PA_ALSA_VOLUME_IGNORE,
-    PA_ALSA_VOLUME_MERGE,  /* merge this volume slider into the global volume slider */
-    PA_ALSA_VOLUME_OFF,    /* set this volume to minimal unconditionally */
-    PA_ALSA_VOLUME_ZERO    /* set this volume to 0dB unconditionally */
+    PA_ALSA_VOLUME_MERGE,   /* merge this volume slider into the global volume slider */
+    PA_ALSA_VOLUME_OFF,     /* set this volume to minimal unconditionally */
+    PA_ALSA_VOLUME_ZERO,    /* set this volume to 0dB unconditionally */
+    PA_ALSA_VOLUME_CONSTANT /* set this volume to a constant value unconditionally */
 } pa_alsa_volume_use_t;
 
 typedef enum pa_alsa_enumeration_use {
@@ -111,11 +112,15 @@ struct pa_alsa_option {
     char *name;
     char *description;
     unsigned priority;
+
+    pa_alsa_required_t required;
+    pa_alsa_required_t required_any;
+    pa_alsa_required_t required_absent;
 };
 
-/* And element wraps one specific ALSA element. A series of elements *
-make up a path (see below). If the element is an enumeration or switch
-* element it may includes a list of options. */
+/* An element wraps one specific ALSA element. A series of elements
+ * make up a path (see below). If the element is an enumeration or switch
+ * element it may include a list of options. */
 struct pa_alsa_element {
     pa_alsa_path *path;
     PA_LLIST_FIELDS(pa_alsa_element);
@@ -128,41 +133,67 @@ struct pa_alsa_element {
     pa_alsa_enumeration_use_t enumeration_use;
 
     pa_alsa_required_t required;
+    pa_alsa_required_t required_any;
     pa_alsa_required_t required_absent;
 
+    long constant_volume;
+
     pa_bool_t override_map:1;
     pa_bool_t direction_try_other:1;
 
     pa_bool_t has_dB:1;
     long min_volume, max_volume;
+    long volume_limit; /* -1 for no configured limit */
     double min_dB, max_dB;
 
-    pa_channel_position_mask_t masks[SND_MIXER_SCHN_LAST][2];
+    pa_channel_position_mask_t masks[SND_MIXER_SCHN_LAST + 1][2];
     unsigned n_channels;
 
     pa_channel_position_mask_t merged_mask;
 
     PA_LLIST_HEAD(pa_alsa_option, options);
+
+    pa_alsa_decibel_fix *db_fix;
+};
+
+struct pa_alsa_jack {
+    pa_alsa_path *path;
+    PA_LLIST_FIELDS(pa_alsa_jack);
+
+    char *name; /* E g "Headphone" */
+    char *alsa_name; /* E g "Headphone Jack" */
+    pa_bool_t has_control; /* is the jack itself present? */
+    pa_bool_t plugged_in; /* is this jack currently plugged in? */
+    snd_hctl_elem_t *hctl_elem; /* Jack detection handle */
+    pa_available_t state_unplugged, state_plugged;
+
+    pa_alsa_required_t required;
+    pa_alsa_required_t required_any;
+    pa_alsa_required_t required_absent;
 };
 
 /* A path wraps a series of elements into a single entity which can be
  * used to control it as if it had a single volume slider, a single
  * mute switch and a single list of selectable options. */
 struct pa_alsa_path {
-    pa_alsa_path_set *path_set;
-    PA_LLIST_FIELDS(pa_alsa_path);
-
     pa_alsa_direction_t direction;
+    pa_device_port* port;
 
     char *name;
     char *description;
     unsigned priority;
+    int eld_device;
+    pa_proplist *proplist;
 
     pa_bool_t probed:1;
     pa_bool_t supported:1;
     pa_bool_t has_mute:1;
     pa_bool_t has_volume:1;
     pa_bool_t has_dB:1;
+    bool mute_during_activation:1;
+    /* These two are used during probing only */
+    pa_bool_t has_req_any:1;
+    pa_bool_t req_any_present:1;
 
     long min_volume, max_volume;
     double min_dB, max_dB;
@@ -172,44 +203,39 @@ struct pa_alsa_path {
     pa_alsa_element *last_element;
     pa_alsa_option *last_option;
     pa_alsa_setting *last_setting;
+    pa_alsa_jack *last_jack;
 
     PA_LLIST_HEAD(pa_alsa_element, elements);
     PA_LLIST_HEAD(pa_alsa_setting, settings);
+    PA_LLIST_HEAD(pa_alsa_jack, jacks);
 };
 
 /* A path set is simply a set of paths that are applicable to a
  * device */
 struct pa_alsa_path_set {
-    PA_LLIST_HEAD(pa_alsa_path, paths);
+    pa_hashmap *paths;
     pa_alsa_direction_t direction;
-    pa_bool_t probed:1;
-
-    /* This is used during parsing only, as a shortcut so that we
-     * don't have to iterate the list all the time */
-    pa_alsa_path *last_path;
 };
 
-int pa_alsa_setting_select(pa_alsa_setting *s, snd_mixer_t *m);
 void pa_alsa_setting_dump(pa_alsa_setting *s);
 
 void pa_alsa_option_dump(pa_alsa_option *o);
-
+void pa_alsa_jack_dump(pa_alsa_jack *j);
 void pa_alsa_element_dump(pa_alsa_element *e);
 
-pa_alsa_path *pa_alsa_path_new(const char *fname, pa_alsa_direction_t direction);
+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);
-int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, pa_bool_t ignore_dB);
+int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, snd_hctl_t *hctl, pa_bool_t 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);
 int pa_alsa_path_get_mute(pa_alsa_path *path, snd_mixer_t *m, pa_bool_t *muted);
-int pa_alsa_path_set_volume(pa_alsa_path *path, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v);
+int pa_alsa_path_set_volume(pa_alsa_path *path, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v, pa_bool_t deferred_volume, pa_bool_t write_to_hw);
 int pa_alsa_path_set_mute(pa_alsa_path *path, snd_mixer_t *m, pa_bool_t muted);
-int pa_alsa_path_select(pa_alsa_path *p, snd_mixer_t *m);
+int pa_alsa_path_select(pa_alsa_path *p, pa_alsa_setting *s, snd_mixer_t *m, bool device_is_muted);
 void pa_alsa_path_set_callback(pa_alsa_path *p, snd_mixer_t *m, snd_mixer_elem_callback_t cb, void *userdata);
 void pa_alsa_path_free(pa_alsa_path *p);
 
-pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t direction);
-void pa_alsa_path_set_probe(pa_alsa_path_set *s, snd_mixer_t *m, pa_bool_t ignore_dB);
+pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t direction, const char *paths_dir);
 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);
@@ -221,6 +247,8 @@ struct pa_alsa_mapping {
     char *description;
     unsigned priority;
     pa_alsa_direction_t direction;
+    /* These are copied over to the resultant sink/source */
+    pa_proplist *proplist;
 
     pa_channel_map channel_map;
 
@@ -230,6 +258,8 @@ struct pa_alsa_mapping {
     char **output_path_names;
     char **input_element; /* list of fallbacks */
     char **output_element;
+    pa_alsa_path_set *input_path_set;
+    pa_alsa_path_set *output_path_set;
 
     unsigned supported;
 
@@ -239,6 +269,9 @@ struct pa_alsa_mapping {
 
     pa_sink *sink;
     pa_source *source;
+
+    /* ucm device context*/
+    pa_alsa_ucm_mapping_context ucm_context;
 };
 
 struct pa_alsa_profile {
@@ -257,27 +290,56 @@ struct pa_alsa_profile {
     pa_idxset *output_mappings;
 };
 
+struct pa_alsa_decibel_fix {
+    pa_alsa_profile_set *profile_set;
+
+    char *name; /* Alsa volume element name. */
+    long min_step;
+    long max_step;
+
+    /* An array that maps alsa volume element steps to decibels. The steps can
+     * be used as indices to this array, after subtracting min_step from the
+     * real value.
+     *
+     * The values are actually stored as integers representing millibels,
+     * because that's the format the alsa API uses. */
+    long *db_values;
+};
+
 struct pa_alsa_profile_set {
     pa_hashmap *mappings;
     pa_hashmap *profiles;
+    pa_hashmap *decibel_fixes;
+    pa_hashmap *input_paths;
+    pa_hashmap *output_paths;
 
     pa_bool_t auto_profiles;
+    pa_bool_t ignore_dB:1;
     pa_bool_t probed:1;
 };
 
 void pa_alsa_mapping_dump(pa_alsa_mapping *m);
 void pa_alsa_profile_dump(pa_alsa_profile *p);
+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_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);
+snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device, snd_hctl_t **hctl);
 
 pa_alsa_fdlist *pa_alsa_fdlist_new(void);
 void pa_alsa_fdlist_free(pa_alsa_fdlist *fdl);
-int pa_alsa_fdlist_set_mixer(pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, pa_mainloop_api* m);
+int pa_alsa_fdlist_set_handle(pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, snd_hctl_t *hctl_handle, pa_mainloop_api* m);
+
+/* Alternative for handling alsa mixer events in io-thread. */
+
+pa_alsa_mixer_pdata *pa_alsa_mixer_pdata_new(void);
+void pa_alsa_mixer_pdata_free(pa_alsa_mixer_pdata *pd);
+int pa_alsa_set_mixer_rtpoll(struct pa_alsa_mixer_pdata *pd, snd_mixer_t *mixer, pa_rtpoll *rtp);
 
 /* Data structure for inclusion in pa_device_port for alsa
  * sinks/sources. This contains nothing that needs to be freed
@@ -287,6 +349,7 @@ struct pa_alsa_port_data {
     pa_alsa_setting *setting;
 };
 
-void pa_alsa_add_ports(pa_hashmap **p, pa_alsa_path_set *ps);
+void pa_alsa_add_ports(void *sink_or_source_new_data, pa_alsa_path_set *ps, pa_card *card);
+void pa_alsa_path_set_add_ports(pa_alsa_path_set *ps, pa_card_profile *cp, pa_hashmap *ports, pa_hashmap *extra, pa_core *core);
 
 #endif
old mode 100644 (file)
new mode 100755 (executable)
index 1ab8d84..5e0504b
@@ -24,6 +24,7 @@
 #include <config.h>
 #endif
 
+#include <signal.h>
 #include <stdio.h>
 
 #include <asoundlib.h>
 #include <valgrind/memcheck.h>
 #endif
 
-#include <pulse/i18n.h>
 #include <pulse/rtclock.h>
 #include <pulse/timeval.h>
-#include <pulse/util.h>
+#include <pulse/volume.h>
 #include <pulse/xmalloc.h>
+#include <pulse/internal.h>
 
 #include <pulsecore/core.h>
+#include <pulsecore/i18n.h>
 #include <pulsecore/module.h>
 #include <pulsecore/memchunk.h>
 #include <pulsecore/sink.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/thread.h>
-#include <pulsecore/core-error.h>
 #include <pulsecore/thread-mq.h>
 #include <pulsecore/rtpoll.h>
 #include <pulsecore/time-smoother.h>
+#ifdef __TIZEN__
+#include <pulsecore/shared.h>
+#endif
 
 #include <modules/reserve-wrap.h>
 
 #include "alsa-util.h"
 #include "alsa-sink.h"
 
-#define ALSA_SUSPEND_ON_IDLE_TIMEOUT   "0"
-
-//#define DEBUG_TIMING
-
-#ifdef DEBUG_TIMING
-#include <signal.h>
+#ifdef __TIZEN__
+#include "tizen-audio.h"
 #endif
 
+/* #define DEBUG_TIMING */
+
 #define DEFAULT_DEVICE "default"
 
 #define DEFAULT_TSCHED_BUFFER_USEC (2*PA_USEC_PER_SEC)             /* 2s    -- Overall buffer size */
 #define TSCHED_WATERMARK_INC_STEP_USEC (10*PA_USEC_PER_MSEC)       /* 10ms  -- On underrun, increase watermark by this */
 #define TSCHED_WATERMARK_DEC_STEP_USEC (5*PA_USEC_PER_MSEC)        /* 5ms   -- When everything's great, decrease watermark by this */
 #define TSCHED_WATERMARK_VERIFY_AFTER_USEC (20*PA_USEC_PER_SEC)    /* 20s   -- How long after a drop out recheck if things are good now */
-#define TSCHED_WATERMARK_INC_THRESHOLD_USEC (0*PA_USEC_PER_MSEC)   /* 0ms   -- If the buffer level ever below this theshold, increase the watermark */
-#define TSCHED_WATERMARK_DEC_THRESHOLD_USEC (100*PA_USEC_PER_MSEC) /* 100ms -- If the buffer level didn't drop below this theshold in the verification time, decrease the watermark */
+#define TSCHED_WATERMARK_INC_THRESHOLD_USEC (0*PA_USEC_PER_MSEC)   /* 0ms   -- If the buffer level ever below this threshold, increase the watermark */
+#define TSCHED_WATERMARK_DEC_THRESHOLD_USEC (100*PA_USEC_PER_MSEC) /* 100ms -- If the buffer level didn't drop below this threshold in the verification time, decrease the watermark */
 
-/* Note that TSCHED_WATERMARK_INC_THRESHOLD_USEC == 0 means tht we
+/* Note that TSCHED_WATERMARK_INC_THRESHOLD_USEC == 0 means that we
  * will increase the watermark only if we hit a real underrun. */
 
 #define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC)                /* 10ms  -- Sleep at least 10ms on each iteration */
 #define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC)                /* 4ms   -- Wakeup at least this long before the buffer runs empty*/
 
+#define SMOOTHER_WINDOW_USEC  (10*PA_USEC_PER_SEC)                 /* 10s   -- smoother windows size */
+#define SMOOTHER_ADJUST_USEC  (1*PA_USEC_PER_SEC)                  /* 1s    -- smoother adjust time */
+
 #define SMOOTHER_MIN_INTERVAL (2*PA_USEC_PER_MSEC)                 /* 2ms   -- min smoother update interval */
-#define SMOOTHER_MAX_INTERVAL (200*PA_USEC_PER_MSEC)               /* 200ms -- max smoother update inteval */
+#define SMOOTHER_MAX_INTERVAL (200*PA_USEC_PER_MSEC)               /* 200ms -- max smoother update interval */
 
 #define VOLUME_ACCURACY (PA_VOLUME_NORM/100)  /* don't require volume adjustments to be perfectly correct. don't necessarily extend granularity in software unless the differences get greater than this level */
 
+#define DEFAULT_REWIND_SAFEGUARD_BYTES (256U) /* 1.33ms @48kHz, we'll never rewind less than this */
+#define DEFAULT_REWIND_SAFEGUARD_USEC (1330) /* 1.33ms, depending on channels/rate/sample we may rewind more than 256 above */
+
+#ifdef __TIZEN__
+#define VOIP_MIN_WB_PERIOD_BYTES 640
+#define VOIP_MIN_NB_PERIOD_BYTES 320
+#define VOIP_WIDE_BAND 16000
+#endif
+
 struct userdata {
     pa_core *core;
     pa_module *module;
@@ -100,59 +114,87 @@ struct userdata {
 
     snd_pcm_t *pcm_handle;
 
+    char *paths_dir;
     pa_alsa_fdlist *mixer_fdl;
+    pa_alsa_mixer_pdata *mixer_pd;
     snd_mixer_t *mixer_handle;
     pa_alsa_path_set *mixer_path_set;
     pa_alsa_path *mixer_path;
 
     pa_cvolume hardware_volume;
 
+    unsigned int *rates;
+
     size_t
         frame_size,
         fragment_size,
         hwbuf_size,
         tsched_watermark,
+        tsched_watermark_ref,
         hwbuf_unused,
         min_sleep,
         min_wakeup,
         watermark_inc_step,
         watermark_dec_step,
         watermark_inc_threshold,
-        watermark_dec_threshold;
+        watermark_dec_threshold,
+        rewind_safeguard;
 
     pa_usec_t watermark_dec_not_before;
+    pa_usec_t min_latency_ref;
 
     pa_memchunk memchunk;
 
     char *device_name;  /* name of the PCM device */
     char *control_device; /* name of the control device */
 
-    pa_bool_t use_mmap:1, use_tsched:1;
+    pa_bool_t use_mmap:1, use_tsched:1, deferred_volume:1, fixed_latency_range:1;
 
     pa_bool_t first, after_rewind;
 
     pa_rtpoll_item *alsa_rtpoll_item;
 
-    snd_mixer_selem_channel_id_t mixer_map[SND_MIXER_SCHN_LAST];
-
     pa_smoother *smoother;
+#ifdef TIZEN_DEBUG_ENABLE
+    uint32_t log_count;
+#endif
     uint64_t write_count;
     uint64_t since_start;
     pa_usec_t smoother_interval;
     pa_usec_t last_smoother_update;
 
+    pa_idxset *formats;
+
     pa_reserve_wrapper *reserve;
     pa_hook_slot *reserve_slot;
     pa_reserve_monitor_wrapper *monitor;
     pa_hook_slot *monitor_slot;
+
+    /* ucm context */
+    pa_alsa_ucm_mapping_context *ucm_context;
+#ifdef __TIZEN__
+    /* Start threshold */
+    int start_threshold;
+#endif
 };
 
 static void userdata_free(struct userdata *u);
 
+/* FIXME: Is there a better way to do this than device names? */
+static pa_bool_t is_iec958(struct userdata *u) {
+    return (strncmp("iec958", u->device_name, 6) == 0);
+}
+
+static pa_bool_t is_hdmi(struct userdata *u) {
+    return (strncmp("hdmi", u->device_name, 4) == 0);
+}
+
 static pa_hook_result_t reserve_cb(pa_reserve_wrapper *r, void *forced, struct userdata *u) {
     pa_assert(r);
     pa_assert(u);
 
+    pa_log_debug("Suspending sink %s, because another application requested us to release the device.", u->sink->name);
+
     if (pa_sink_suspend(u->sink, TRUE, PA_SUSPEND_APPLICATION) < 0)
         return PA_HOOK_CANCEL;
 
@@ -215,14 +257,17 @@ static int reserve_init(struct userdata *u, const char *dname) {
 }
 
 static pa_hook_result_t monitor_cb(pa_reserve_monitor_wrapper *w, void* busy, struct userdata *u) {
-    pa_bool_t b;
-
     pa_assert(w);
     pa_assert(u);
 
-    b = PA_PTR_TO_UINT(busy) && !u->reserve;
+    if (PA_PTR_TO_UINT(busy) && !u->reserve) {
+        pa_log_debug("Suspending sink %s, because another application is blocking the access to the device.", u->sink->name);
+        pa_sink_suspend(u->sink, true, PA_SUSPEND_APPLICATION);
+    } else {
+        pa_log_debug("Resuming sink %s, because other applications aren't blocking access to the device any more.", u->sink->name);
+        pa_sink_suspend(u->sink, false, PA_SUSPEND_APPLICATION);
+    }
 
-    pa_sink_suspend(u->sink, b, PA_SUSPEND_APPLICATION);
     return PA_HOOK_OK;
 }
 
@@ -252,6 +297,7 @@ static int reserve_monitor_init(struct userdata *u, const char *dname) {
     if (!(rname = pa_alsa_get_reserve_name(dname)))
         return 0;
 
+    /* We are resuming, try to lock the device */
     u->monitor = pa_reserve_monitor_wrapper_get(u->core, rname);
     pa_xfree(rname);
 
@@ -312,13 +358,18 @@ static void increase_watermark(struct userdata *u) {
         return;
     }
 
-    /* Hmm, we cannot increase the watermark any further, hence let's raise the latency */
+    /* Hmm, we cannot increase the watermark any further, hence let's
+       raise the latency, unless doing so was disabled in
+       configuration */
+    if (u->fixed_latency_range)
+        return;
+
     old_min_latency = u->sink->thread_info.min_latency;
     new_min_latency = PA_MIN(old_min_latency * 2, old_min_latency + TSCHED_WATERMARK_INC_STEP_USEC);
     new_min_latency = PA_MIN(new_min_latency, u->sink->thread_info.max_latency);
 
     if (old_min_latency != new_min_latency) {
-        pa_log_info("Increasing minimal latency to %0.2f ms",
+        pa_log_info_verbose("Increasing minimal latency to %0.2f ms",
                     (double) new_min_latency / PA_USEC_PER_MSEC);
 
         pa_sink_set_latency_range_within_thread(u->sink, new_min_latency, u->sink->thread_info.max_latency);
@@ -352,7 +403,7 @@ static void decrease_watermark(struct userdata *u) {
     fix_tsched_watermark(u);
 
     if (old_watermark != u->tsched_watermark)
-        pa_log_info("Decreasing wakeup watermark to %0.2f ms",
+        pa_log_info_verbose("Decreasing wakeup watermark to %0.2f ms",
                     (double) pa_bytes_to_usec(u->tsched_watermark, &u->sink->sample_spec) / PA_USEC_PER_MSEC);
 
     /* We don't change the latency range*/
@@ -433,12 +484,12 @@ static size_t check_left_to_play(struct userdata *u, size_t n_bytes, pa_bool_t o
         left_to_play = 0;
         underrun = TRUE;
 
-#ifdef DEBUG_TIMING
+#if 0
         PA_DEBUG_TRAP;
 #endif
 
         if (!u->first && !u->after_rewind)
-            if (pa_log_ratelimit())
+            if (pa_log_ratelimit(PA_LOG_INFO))
                 pa_log_info("Underrun!");
     }
 
@@ -474,11 +525,19 @@ static size_t check_left_to_play(struct userdata *u, size_t n_bytes, pa_bool_t o
     return left_to_play;
 }
 
+#ifdef __TIZEN__
+/* FIXME : for temporal checking */
+#define MAX_RETRY 1000
+#endif
+
 static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled, pa_bool_t on_timeout) {
-    pa_bool_t work_done = TRUE;
+    pa_bool_t work_done = FALSE;
     pa_usec_t max_sleep_usec = 0, process_usec = 0;
-    size_t left_to_play;
+    size_t left_to_play, input_underrun;
     unsigned j = 0;
+#ifdef __TIZEN__
+    static unsigned k = 0;
+#endif
 
     pa_assert(u);
     pa_sink_assert_ref(u->sink);
@@ -522,9 +581,21 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle
 
             if (!polled &&
                 pa_bytes_to_usec(left_to_play, &u->sink->sample_spec) > process_usec+max_sleep_usec/2) {
+#ifdef __TIZEN__
+#ifdef DEBUG_TIMING
+                pa_log_debug("[%d][%d] Not filling up, because too early. [n:%d, n_bytes:%d, left_to_play:%d, process_usec:%lld, max_sleep_usec:%lld, hwbuf_unused:%d]",
+                            k, j, n, n_bytes, left_to_play, process_usec, max_sleep_usec, u->hwbuf_unused);
+#endif
+                if (k++>MAX_RETRY) {
+                    pa_log_error("[%d][%d] Not filling up, because too early. [n:%d, n_bytes:%d, left_to_play:%d, process_usec:%lld, max_sleep_usec:%lld, hwbuf_unused:%d]",
+                            k, j, n, n_bytes, left_to_play, process_usec, max_sleep_usec, u->hwbuf_unused);
+                    k = 0;
+                }
+#else
 #ifdef DEBUG_TIMING
                 pa_log_debug("Not filling up, because too early.");
 #endif
+#endif
                 break;
             }
 
@@ -569,6 +640,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle
             const snd_pcm_channel_area_t *areas;
             snd_pcm_uframes_t offset, frames;
             snd_pcm_sframes_t sframes;
+            size_t written;
 
             frames = (snd_pcm_uframes_t) (n_bytes / u->frame_size);
 /*             pa_log_debug("%lu frames to write", (unsigned long) frames); */
@@ -585,8 +657,8 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle
             }
 
             /* Make sure that if these memblocks need to be copied they will fit into one slot */
-            if (frames > pa_mempool_block_size_max(u->sink->core->mempool)/u->frame_size)
-                frames = pa_mempool_block_size_max(u->sink->core->mempool)/u->frame_size;
+            if (frames > pa_mempool_block_size_max(u->core->mempool)/u->frame_size)
+                frames = pa_mempool_block_size_max(u->core->mempool)/u->frame_size;
 
             if (!after_avail && frames == 0)
                 break;
@@ -604,7 +676,8 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle
 
             p = (uint8_t*) areas[0].addr + (offset * u->frame_size);
 
-            chunk.memblock = pa_memblock_new_fixed(u->core->mempool, p, frames * u->frame_size, TRUE);
+            written = frames * u->frame_size;
+            chunk.memblock = pa_memblock_new_fixed(u->core->mempool, p, written, TRUE);
             chunk.length = pa_memblock_get_length(chunk.memblock);
             chunk.index = 0;
 
@@ -613,33 +686,59 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle
 
             if (PA_UNLIKELY((sframes = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) {
 
+                if (!after_avail && (int) sframes == -EAGAIN)
+                    break;
+
                 if ((r = try_recover(u, "snd_pcm_mmap_commit", (int) sframes)) == 0)
                     continue;
 
                 return r;
             }
 
+#ifdef __TIZEN__
+            k = 0;
+#endif
             work_done = TRUE;
 
-            u->write_count += frames * u->frame_size;
-            u->since_start += frames * u->frame_size;
+            u->write_count += written;
+            u->since_start += written;
 
 #ifdef DEBUG_TIMING
-            pa_log_debug("Wrote %lu bytes (of possible %lu bytes)", (unsigned long) (frames * u->frame_size), (unsigned long) n_bytes);
+            pa_log_debug("Wrote %lu bytes (of possible %lu bytes)", (unsigned long) written, (unsigned long) n_bytes);
+#elif TIZEN_DEBUG_ENABLE
+            {
+                const uint32_t interval = 35;
+                if(u->log_count == 0 || u->log_count > interval) {
+                    pa_log_debug("ALSA-SINK : Wrote %lu bytes (of possible %lu bytes), total(%llu)", (unsigned long) written, (unsigned long) n_bytes, u->write_count);
+                    if(u->log_count > interval)
+                        u->log_count = 0;
+                }
+                u->log_count++;
+            }
 #endif
 
-            if ((size_t) frames * u->frame_size >= n_bytes)
+            if (written >= n_bytes)
                 break;
 
-            n_bytes -= (size_t) frames * u->frame_size;
+            n_bytes -= written;
         }
     }
 
-    *sleep_usec = pa_bytes_to_usec(left_to_play, &u->sink->sample_spec);
+    input_underrun = pa_sink_process_input_underruns(u->sink, left_to_play);
 
-    if (*sleep_usec > process_usec)
-        *sleep_usec -= process_usec;
-    else
+    if (u->use_tsched) {
+        pa_usec_t underrun_sleep = pa_bytes_to_usec_round_up(input_underrun, &u->sink->sample_spec);
+
+        *sleep_usec = pa_bytes_to_usec(left_to_play, &u->sink->sample_spec);
+        process_usec = pa_bytes_to_usec(u->tsched_watermark, &u->sink->sample_spec);
+
+        if (*sleep_usec > process_usec)
+            *sleep_usec -= process_usec;
+        else
+            *sleep_usec = 0;
+
+        *sleep_usec = PA_MIN(*sleep_usec, underrun_sleep);
+    } else
         *sleep_usec = 0;
 
     return work_done ? 1 : 0;
@@ -648,7 +747,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle
 static int unix_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled, pa_bool_t on_timeout) {
     pa_bool_t work_done = FALSE;
     pa_usec_t max_sleep_usec = 0, process_usec = 0;
-    size_t left_to_play;
+    size_t left_to_play, input_underrun;
     unsigned j = 0;
 
     pa_assert(u);
@@ -672,8 +771,23 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle
         }
 
         n_bytes = (size_t) n * u->frame_size;
+
+
+#ifdef DEBUG_TIMING
+        pa_log_debug("avail: %lu", (unsigned long) n_bytes);
+#endif
+
         left_to_play = check_left_to_play(u, n_bytes, on_timeout);
         on_timeout = FALSE;
+#ifdef __TIZEN__
+        if (pa_alsa_pcm_is_voip(u->pcm_handle))
+        {
+            size_t actual_n_bytes;
+            actual_n_bytes = (u->sink->sample_spec.rate == VOIP_WIDE_BAND) ? VOIP_MIN_WB_PERIOD_BYTES :VOIP_MIN_NB_PERIOD_BYTES;
+            if(n_bytes > actual_n_bytes)
+               n_bytes = actual_n_bytes;
+        }
+#endif
 
         if (u->use_tsched)
 
@@ -716,6 +830,7 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle
         for (;;) {
             snd_pcm_sframes_t frames;
             void *p;
+            size_t written;
 
 /*         pa_log_debug("%lu frames to write", (unsigned long) frames); */
 
@@ -750,8 +865,9 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle
             pa_assert(frames > 0);
             after_avail = FALSE;
 
-            u->memchunk.index += (size_t) frames * u->frame_size;
-            u->memchunk.length -= (size_t) frames * u->frame_size;
+            written = frames * u->frame_size;
+            u->memchunk.index += written;
+            u->memchunk.length -= written;
 
             if (u->memchunk.length <= 0) {
                 pa_memblock_unref(u->memchunk.memblock);
@@ -760,23 +876,37 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle
 
             work_done = TRUE;
 
-            u->write_count += frames * u->frame_size;
-            u->since_start += frames * u->frame_size;
+            u->write_count += written;
+            u->since_start += written;
 
 /*         pa_log_debug("wrote %lu frames", (unsigned long) frames); */
 
-            if ((size_t) frames * u->frame_size >= n_bytes)
+            if (written >= n_bytes)
                 break;
 
-            n_bytes -= (size_t) frames * u->frame_size;
+            n_bytes -= written;
         }
+#ifdef __TIZEN__
+        if (pa_alsa_pcm_is_voip(u->pcm_handle))
+            break;
+#endif
     }
 
-    *sleep_usec = pa_bytes_to_usec(left_to_play, &u->sink->sample_spec);
+    input_underrun = pa_sink_process_input_underruns(u->sink, left_to_play);
 
-    if (*sleep_usec > process_usec)
-        *sleep_usec -= process_usec;
-    else
+    if (u->use_tsched) {
+        pa_usec_t underrun_sleep = pa_bytes_to_usec_round_up(input_underrun, &u->sink->sample_spec);
+
+        *sleep_usec = pa_bytes_to_usec(left_to_play, &u->sink->sample_spec);
+        process_usec = pa_bytes_to_usec(u->tsched_watermark, &u->sink->sample_spec);
+
+        if (*sleep_usec > process_usec)
+            *sleep_usec -= process_usec;
+        else
+            *sleep_usec = 0;
+
+        *sleep_usec = PA_MIN(*sleep_usec, underrun_sleep);
+    } else
         *sleep_usec = 0;
 
     return work_done ? 1 : 0;
@@ -788,6 +918,7 @@ static void update_smoother(struct userdata *u) {
     int err;
     pa_usec_t now1 = 0, now2;
     snd_pcm_status_t *status;
+    snd_htimestamp_t htstamp = { 0, 0 };
 
     snd_pcm_status_alloca(&status);
 
@@ -796,18 +927,13 @@ static void update_smoother(struct userdata *u) {
 
     /* Let's update the time smoother */
 
-    if (PA_UNLIKELY((err = pa_alsa_safe_delay(u->pcm_handle, &delay, u->hwbuf_size, &u->sink->sample_spec)) < 0)) {
+    if (PA_UNLIKELY((err = pa_alsa_safe_delay(u->pcm_handle, status, &delay, u->hwbuf_size, &u->sink->sample_spec, FALSE)) < 0)) {
         pa_log_warn("Failed to query DSP status data: %s", pa_alsa_strerror(err));
         return;
     }
 
-    if (PA_UNLIKELY((err = snd_pcm_status(u->pcm_handle, status)) < 0))
-        pa_log_warn("Failed to get timestamp: %s", pa_alsa_strerror(err));
-    else {
-        snd_htimestamp_t htstamp = { 0, 0 };
-        snd_pcm_status_get_htstamp(status, &htstamp);
-        now1 = pa_timespec_load(&htstamp);
-    }
+    snd_pcm_status_get_htstamp(status, &htstamp);
+    now1 = pa_timespec_load(&htstamp);
 
     /* Hmm, if the timestamp is 0, then it wasn't set and we take the current time */
     if (now1 <= 0)
@@ -867,13 +993,24 @@ static int build_pollfd(struct userdata *u) {
 
 /* Called from IO context */
 static int suspend(struct userdata *u) {
+#ifdef __TIZEN__
+    void *audio_data = pa_shared_get(u->core, "tizen-audio-data");
+    audio_interface_t *audio_intf = pa_shared_get(u->core, "tizen-audio-interface");
+#endif
+
     pa_assert(u);
     pa_assert(u->pcm_handle);
 
     pa_smoother_pause(u->smoother, pa_rtclock_now());
 
+
     /* Let's suspend -- we don't call snd_pcm_drain() here since that might
      * take awfully long with our long buffer sizes today. */
+#ifdef __TIZEN__
+    if (audio_intf && audio_intf->alsa_pcm_close) {
+        audio_intf->alsa_pcm_close(audio_data, u->pcm_handle);
+    } else
+#endif
     snd_pcm_close(u->pcm_handle);
     u->pcm_handle = NULL;
 
@@ -882,7 +1019,15 @@ static int suspend(struct userdata *u) {
         u->alsa_rtpoll_item = NULL;
     }
 
-    pa_log_info("Device suspended...");
+    /* We reset max_rewind/max_request here to make sure that while we
+     * are suspended the old max_request/max_rewind values set before
+     * the suspend can influence the per-stream buffer of newly
+     * created streams, without their requirements having any
+     * influence on them. */
+    pa_sink_set_max_rewind_within_thread(u->sink, 0);
+    pa_sink_set_max_request_within_thread(u->sink, 0);
+
+    pa_log_debug_verbose("Device suspended...[%s]", u->device_name);
 
     return 0;
 }
@@ -891,19 +1036,26 @@ static int suspend(struct userdata *u) {
 static int update_sw_params(struct userdata *u) {
     snd_pcm_uframes_t avail_min;
     int err;
+#ifdef __TIZEN_LOG__
+    pa_usec_t latency;
+#endif
 
     pa_assert(u);
 
-    /* Use the full buffer if noone asked us for anything specific */
+    /* Use the full buffer if no one asked us for anything specific */
     u->hwbuf_unused = 0;
 
     if (u->use_tsched) {
+#ifndef __TIZEN_LOG__
         pa_usec_t latency;
+#endif
 
         if ((latency = pa_sink_get_requested_latency_within_thread(u->sink)) != (pa_usec_t) -1) {
             size_t b;
 
+#ifndef __TIZEN_LOG__
             pa_log_debug("Latency set to %0.2fms", (double) latency / PA_USEC_PER_MSEC);
+#endif
 
             b = pa_usec_to_bytes(latency, &u->sink->sample_spec);
 
@@ -919,7 +1071,9 @@ static int update_sw_params(struct userdata *u) {
         fix_tsched_watermark(u);
     }
 
+#ifndef __TIZEN_LOG__
     pa_log_debug("hwbuf_unused=%lu", (unsigned long) u->hwbuf_unused);
+#endif
 
     /* We need at last one frame in the used part of the buffer */
     avail_min = (snd_pcm_uframes_t) u->hwbuf_unused / u->frame_size + 1;
@@ -931,31 +1085,113 @@ static int update_sw_params(struct userdata *u) {
         avail_min += pa_usec_to_bytes(sleep_usec, &u->sink->sample_spec) / u->frame_size;
     }
 
+#ifdef __TIZEN_LOG__
+    if (u->use_tsched && latency != (pa_usec_t) -1) {
+        pa_log_debug_verbose("latency:%0.2fms hwbuf_unused=%lu avail_min=%lu", (double) latency / PA_USEC_PER_MSEC, (unsigned long) u->hwbuf_unused, (unsigned long) avail_min);
+    } else {
+        pa_log_debug_verbose("hwbuf_unused=%lu avail_min=%lu", (unsigned long) u->hwbuf_unused, (unsigned long) avail_min);
+    }
+#else
     pa_log_debug("setting avail_min=%lu", (unsigned long) avail_min);
+#endif
 
+#ifdef __TIZEN__
+    if ((err = pa_alsa_set_sw_params(u->pcm_handle, avail_min, !u->use_tsched, u->start_threshold,u->sink->sample_spec.rate)) < 0) {
+        pa_log("Failed to set software parameters: %s", pa_alsa_strerror(err));
+        return err;
+    }
+#else
     if ((err = pa_alsa_set_sw_params(u->pcm_handle, avail_min, !u->use_tsched)) < 0) {
         pa_log("Failed to set software parameters: %s", pa_alsa_strerror(err));
         return err;
     }
+#endif
 
     pa_sink_set_max_request_within_thread(u->sink, u->hwbuf_size - u->hwbuf_unused);
+     if (pa_alsa_pcm_is_hw(u->pcm_handle))
+         pa_sink_set_max_rewind_within_thread(u->sink, u->hwbuf_size);
+    else {
+        pa_log_info("Disabling rewind_within_thread for device %s", u->device_name);
+        pa_sink_set_max_rewind_within_thread(u->sink, 0);
+    }
 
     return 0;
 }
 
+/* Called from IO Context on unsuspend or from main thread when creating sink */
+static void reset_watermark(struct userdata *u, size_t tsched_watermark, pa_sample_spec *ss,
+                            pa_bool_t in_thread)
+{
+    u->tsched_watermark = pa_usec_to_bytes_round_up(pa_bytes_to_usec_round_up(tsched_watermark, ss),
+                                                    &u->sink->sample_spec);
+
+    u->watermark_inc_step = pa_usec_to_bytes(TSCHED_WATERMARK_INC_STEP_USEC, &u->sink->sample_spec);
+    u->watermark_dec_step = pa_usec_to_bytes(TSCHED_WATERMARK_DEC_STEP_USEC, &u->sink->sample_spec);
+
+    u->watermark_inc_threshold = pa_usec_to_bytes_round_up(TSCHED_WATERMARK_INC_THRESHOLD_USEC, &u->sink->sample_spec);
+    u->watermark_dec_threshold = pa_usec_to_bytes_round_up(TSCHED_WATERMARK_DEC_THRESHOLD_USEC, &u->sink->sample_spec);
+
+    fix_min_sleep_wakeup(u);
+    fix_tsched_watermark(u);
+
+    if (in_thread)
+        pa_sink_set_latency_range_within_thread(u->sink,
+                                                u->min_latency_ref,
+                                                pa_bytes_to_usec(u->hwbuf_size, ss));
+    else {
+        pa_sink_set_latency_range(u->sink,
+                                  0,
+                                  pa_bytes_to_usec(u->hwbuf_size, ss));
+
+        /* work-around assert in pa_sink_set_latency_within_thead,
+           keep track of min_latency and reuse it when
+           this routine is called from IO context */
+        u->min_latency_ref = u->sink->thread_info.min_latency;
+    }
+
+    pa_log_debug_verbose("Time scheduling watermark is %0.2fms",
+                (double) pa_bytes_to_usec(u->tsched_watermark, ss) / PA_USEC_PER_MSEC);
+}
+
 /* Called from IO context */
 static int unsuspend(struct userdata *u) {
     pa_sample_spec ss;
     int err;
     pa_bool_t b, d;
     snd_pcm_uframes_t period_size, buffer_size;
+    char *device_name = NULL;
+#ifdef __TIZEN__
+    int ret = 0;
+    int hdmi_ch_enum_val = 0;
+    void *audio_data = pa_shared_get(u->core, "tizen-audio-data");
+    audio_interface_t *audio_intf = pa_shared_get(u->core, "tizen-audio-interface");
+#endif
 
     pa_assert(u);
     pa_assert(!u->pcm_handle);
 
-    pa_log_info("Trying resume...");
+    pa_log_debug_verbose("Trying resume...[%s]", u->device_name);
+
+    if ((is_iec958(u) || is_hdmi(u)) && pa_sink_is_passthrough(u->sink)) {
+        /* Need to open device in NONAUDIO mode */
+        int len = strlen(u->device_name) + 8;
+
+        device_name = pa_xmalloc(len);
+        pa_snprintf(device_name, len, "%s,AES0=6", u->device_name);
+    }
+
+#ifdef __TIZEN__
+    if (audio_intf && audio_intf->alsa_pcm_open) {
+        audio_return_t audio_ret = AUDIO_RET_OK;
 
-    if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_PLAYBACK,
+        if (AUDIO_IS_ERROR((audio_ret = audio_intf->alsa_pcm_open(audio_data, (void **)&u->pcm_handle, device_name ? device_name : u->device_name, AUDIO_DIRECTION_OUT,
+            SND_PCM_NONBLOCK | SND_PCM_NO_AUTO_RESAMPLE | SND_PCM_NO_AUTO_CHANNELS | SND_PCM_NO_AUTO_FORMAT)))) {
+            pa_log("Error opening PCM device %s: %x", u->device_name, audio_ret);
+            goto fail;
+        }
+    } else
+#endif
+    if ((err = snd_pcm_open(&u->pcm_handle, device_name ? device_name : u->device_name, SND_PCM_STREAM_PLAYBACK,
                             SND_PCM_NONBLOCK|
                             SND_PCM_NO_AUTO_RESAMPLE|
                             SND_PCM_NO_AUTO_CHANNELS|
@@ -970,6 +1206,14 @@ static int unsuspend(struct userdata *u) {
     b = u->use_mmap;
     d = u->use_tsched;
 
+#ifdef __TIZEN__
+    if (pa_streq (u->device_name, "hw:0,1")) {
+        hdmi_ch_enum_val = ss.channels - 2;
+        ret = pa_alsa_set_mixer_control("HDMI_RX Channels", hdmi_ch_enum_val);
+        pa_log_warn("This is HDMI(%s) device, set channelinfo(%d) mixer, ret=%d", u->device_name, hdmi_ch_enum_val, ret);
+    }
+#endif
+
     if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &period_size, &buffer_size, 0, &b, &d, TRUE)) < 0) {
         pa_log("Failed to set hardware parameters: %s", pa_alsa_strerror(err));
         goto fail;
@@ -999,6 +1243,9 @@ static int unsuspend(struct userdata *u) {
     if (build_pollfd(u) < 0)
         goto fail;
 
+#ifdef TIZEN_DEBUG_ENABLE
+    u->log_count = 0;
+#endif
     u->write_count = 0;
     pa_smoother_reset(u->smoother, pa_rtclock_now(), TRUE);
     u->smoother_interval = SMOOTHER_MIN_INTERVAL;
@@ -1007,16 +1254,28 @@ static int unsuspend(struct userdata *u) {
     u->first = TRUE;
     u->since_start = 0;
 
-    pa_log_info("Resumed successfully...");
+    /* reset the watermark to the value defined when sink was created */
+    if (u->use_tsched)
+        reset_watermark(u, u->tsched_watermark_ref, &u->sink->sample_spec, TRUE);
+
+    pa_log_debug_verbose("Resumed successfully...[%s]", u->device_name);
 
+    pa_xfree(device_name);
     return 0;
 
 fail:
     if (u->pcm_handle) {
+#ifdef __TIZEN__
+        if (audio_intf && audio_intf->alsa_pcm_close) {
+            audio_intf->alsa_pcm_close(audio_data, u->pcm_handle);
+        } else
+#endif
         snd_pcm_close(u->pcm_handle);
         u->pcm_handle = NULL;
     }
 
+    pa_xfree(device_name);
+
     return -PA_ERR_IO;
 }
 
@@ -1100,7 +1359,7 @@ static int sink_set_state_cb(pa_sink *s, pa_sink_state_t new_state) {
     return 0;
 }
 
-static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
+static int ctl_mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
     struct userdata *u = snd_mixer_elem_get_callback_private(elem);
 
     pa_assert(u);
@@ -1109,6 +1368,14 @@ static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
     if (mask == SND_CTL_EVENT_MASK_REMOVE)
         return 0;
 
+    if (!PA_SINK_IS_LINKED(u->sink->state))
+        return 0;
+
+    if (u->sink->suspend_cause & PA_SUSPEND_SESSION) {
+        pa_sink_set_mixer_dirty(u->sink, TRUE);
+        return 0;
+    }
+
     if (mask & SND_CTL_EVENT_MASK_VALUE) {
         pa_sink_get_volume(u->sink, TRUE);
         pa_sink_get_mute(u->sink, TRUE);
@@ -1117,10 +1384,30 @@ static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
     return 0;
 }
 
+static int io_mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
+    struct userdata *u = snd_mixer_elem_get_callback_private(elem);
+
+    pa_assert(u);
+    pa_assert(u->mixer_handle);
+
+    if (mask == SND_CTL_EVENT_MASK_REMOVE)
+        return 0;
+
+    if (u->sink->suspend_cause & PA_SUSPEND_SESSION) {
+        pa_sink_set_mixer_dirty(u->sink, TRUE);
+        return 0;
+    }
+
+    if (mask & SND_CTL_EVENT_MASK_VALUE)
+        pa_sink_update_volume_and_mute(u->sink);
+
+    return 0;
+}
+
 static void sink_get_volume_cb(pa_sink *s) {
     struct userdata *u = s->userdata;
     pa_cvolume r;
-    char t[PA_CVOLUME_SNPRINT_MAX];
+    char vol_str_pcnt[PA_CVOLUME_SNPRINT_MAX];
 
     pa_assert(u);
     pa_assert(u->mixer_path);
@@ -1132,7 +1419,13 @@ static void sink_get_volume_cb(pa_sink *s) {
     /* Shift down by the base volume, so that 0dB becomes maximum volume */
     pa_sw_cvolume_multiply_scalar(&r, &r, s->base_volume);
 
-    pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
+    pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(vol_str_pcnt, sizeof(vol_str_pcnt), &r));
+
+    if (u->mixer_path->has_dB) {
+        char vol_str_db[PA_SW_CVOLUME_SNPRINT_DB_MAX];
+
+        pa_log_debug("               in dB: %s", pa_sw_cvolume_snprint_dB(vol_str_db, sizeof(vol_str_db), &r));
+    }
 
     if (pa_cvolume_equal(&u->hardware_volume, &r))
         return;
@@ -1147,7 +1440,8 @@ static void sink_get_volume_cb(pa_sink *s) {
 static void sink_set_volume_cb(pa_sink *s) {
     struct userdata *u = s->userdata;
     pa_cvolume r;
-    char t[PA_CVOLUME_SNPRINT_MAX];
+    char vol_str_pcnt[PA_CVOLUME_SNPRINT_MAX];
+    pa_bool_t deferred_volume = !!(s->flags & PA_SINK_DEFERRED_VOLUME);
 
     pa_assert(u);
     pa_assert(u->mixer_path);
@@ -1156,7 +1450,7 @@ static void sink_set_volume_cb(pa_sink *s) {
     /* Shift up by the base volume */
     pa_sw_cvolume_divide_scalar(&r, &s->real_volume, s->base_volume);
 
-    if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r) < 0)
+    if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r, deferred_volume, !deferred_volume) < 0)
         return;
 
     /* Shift down by the base volume, so that 0dB becomes maximum volume */
@@ -1167,6 +1461,7 @@ static void sink_set_volume_cb(pa_sink *s) {
     if (u->mixer_path->has_dB) {
         pa_cvolume new_soft_volume;
         pa_bool_t accurate_enough;
+        char vol_str_db[PA_SW_CVOLUME_SNPRINT_DB_MAX];
 
         /* Match exactly what the user requested by software */
         pa_sw_cvolume_divide(&new_soft_volume, &s->real_volume, &u->hardware_volume);
@@ -1178,16 +1473,20 @@ static void sink_set_volume_cb(pa_sink *s) {
             (pa_cvolume_min(&new_soft_volume) >= (PA_VOLUME_NORM - VOLUME_ACCURACY)) &&
             (pa_cvolume_max(&new_soft_volume) <= (PA_VOLUME_NORM + VOLUME_ACCURACY));
 
-        pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->real_volume));
-        pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &u->hardware_volume));
-        pa_log_debug("Calculated software volume: %s (accurate-enough=%s)", pa_cvolume_snprint(t, sizeof(t), &new_soft_volume),
+        pa_log_debug("Requested volume: %s", pa_cvolume_snprint(vol_str_pcnt, sizeof(vol_str_pcnt), &s->real_volume));
+        pa_log_debug("           in dB: %s", pa_sw_cvolume_snprint_dB(vol_str_db, sizeof(vol_str_db), &s->real_volume));
+        pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(vol_str_pcnt, sizeof(vol_str_pcnt), &u->hardware_volume));
+        pa_log_debug("              in dB: %s", pa_sw_cvolume_snprint_dB(vol_str_db, sizeof(vol_str_db), &u->hardware_volume));
+        pa_log_debug("Calculated software volume: %s (accurate-enough=%s)",
+                     pa_cvolume_snprint(vol_str_pcnt, sizeof(vol_str_pcnt), &new_soft_volume),
                      pa_yes_no(accurate_enough));
+        pa_log_debug("                     in dB: %s", pa_sw_cvolume_snprint_dB(vol_str_db, sizeof(vol_str_db), &new_soft_volume));
 
         if (!accurate_enough)
             s->soft_volume = new_soft_volume;
 
     } else {
-        pa_log_debug("Wrote hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
+        pa_log_debug("Wrote hardware volume: %s", pa_cvolume_snprint(vol_str_pcnt, sizeof(vol_str_pcnt), &r));
 
         /* We can't match exactly what the user requested, hence let's
          * at least tell the user about it */
@@ -1196,6 +1495,48 @@ static void sink_set_volume_cb(pa_sink *s) {
     }
 }
 
+static void sink_write_volume_cb(pa_sink *s) {
+    struct userdata *u = s->userdata;
+    pa_cvolume hw_vol = s->thread_info.current_hw_volume;
+
+    pa_assert(u);
+    pa_assert(u->mixer_path);
+    pa_assert(u->mixer_handle);
+    pa_assert(s->flags & PA_SINK_DEFERRED_VOLUME);
+
+    /* Shift up by the base volume */
+    pa_sw_cvolume_divide_scalar(&hw_vol, &hw_vol, s->base_volume);
+
+    if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &hw_vol, TRUE, TRUE) < 0)
+        pa_log_error("Writing HW volume failed");
+    else {
+        pa_cvolume tmp_vol;
+        pa_bool_t accurate_enough;
+
+        /* Shift down by the base volume, so that 0dB becomes maximum volume */
+        pa_sw_cvolume_multiply_scalar(&hw_vol, &hw_vol, s->base_volume);
+
+        pa_sw_cvolume_divide(&tmp_vol, &hw_vol, &s->thread_info.current_hw_volume);
+        accurate_enough =
+            (pa_cvolume_min(&tmp_vol) >= (PA_VOLUME_NORM - VOLUME_ACCURACY)) &&
+            (pa_cvolume_max(&tmp_vol) <= (PA_VOLUME_NORM + VOLUME_ACCURACY));
+
+        if (!accurate_enough) {
+            union {
+                char db[2][PA_SW_CVOLUME_SNPRINT_DB_MAX];
+                char pcnt[2][PA_CVOLUME_SNPRINT_MAX];
+            } vol;
+
+            pa_log_debug("Written HW volume did not match with the request: %s (request) != %s",
+                         pa_cvolume_snprint(vol.pcnt[0], sizeof(vol.pcnt[0]), &s->thread_info.current_hw_volume),
+                         pa_cvolume_snprint(vol.pcnt[1], sizeof(vol.pcnt[1]), &hw_vol));
+            pa_log_debug("                                           in dB: %s (request) != %s",
+                         pa_sw_cvolume_snprint_dB(vol.db[0], sizeof(vol.db[0]), &s->thread_info.current_hw_volume),
+                         pa_sw_cvolume_snprint_dB(vol.db[1], sizeof(vol.db[1]), &hw_vol));
+        }
+    }
+}
+
 static void sink_get_mute_cb(pa_sink *s) {
     struct userdata *u = s->userdata;
     pa_bool_t b;
@@ -1220,6 +1561,65 @@ static void sink_set_mute_cb(pa_sink *s) {
     pa_alsa_path_set_mute(u->mixer_path, u->mixer_handle, s->muted);
 }
 
+static void mixer_volume_init(struct userdata *u) {
+    pa_assert(u);
+
+    if (!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);
+
+        pa_log_info("Driver does not support hardware volume control, falling back to software volume control.");
+    } else {
+        pa_sink_set_get_volume_callback(u->sink, sink_get_volume_cb);
+        pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
+
+        if (u->mixer_path->has_dB && u->deferred_volume) {
+            pa_sink_set_write_volume_callback(u->sink, sink_write_volume_cb);
+            pa_log_info("Successfully enabled deferred volume.");
+        } else
+            pa_sink_set_write_volume_callback(u->sink, NULL);
+
+        if (u->mixer_path->has_dB) {
+            pa_sink_enable_decibel_volume(u->sink, TRUE);
+            pa_log_info("Hardware volume ranges from %0.2f dB to %0.2f dB.", u->mixer_path->min_dB, u->mixer_path->max_dB);
+
+            u->sink->base_volume = pa_sw_volume_from_dB(-u->mixer_path->max_dB);
+            u->sink->n_volume_steps = PA_VOLUME_NORM+1;
+
+            pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(u->sink->base_volume));
+        } else {
+            pa_sink_enable_decibel_volume(u->sink, FALSE);
+            pa_log_info("Hardware volume ranges from %li to %li.", u->mixer_path->min_volume, u->mixer_path->max_volume);
+
+            u->sink->base_volume = PA_VOLUME_NORM;
+            u->sink->n_volume_steps = u->mixer_path->max_volume - u->mixer_path->min_volume + 1;
+        }
+
+        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) {
+        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.");
+    } else {
+        pa_sink_set_get_mute_callback(u->sink, sink_get_mute_cb);
+        pa_sink_set_set_mute_callback(u->sink, sink_set_mute_cb);
+        pa_log_info("Using hardware mute control.");
+    }
+}
+
+static int sink_set_port_ucm_cb(pa_sink *s, pa_device_port *p) {
+    struct userdata *u = s->userdata;
+
+    pa_assert(u);
+    pa_assert(p);
+    pa_assert(u->ucm_context);
+
+    return pa_alsa_ucm_set_port(u->ucm_context, p, TRUE);
+}
+
 static int sink_set_port_cb(pa_sink *s, pa_device_port *p) {
     struct userdata *u = s->userdata;
     pa_alsa_port_data *data;
@@ -1231,28 +1631,19 @@ static int sink_set_port_cb(pa_sink *s, pa_device_port *p) {
     data = PA_DEVICE_PORT_DATA(p);
 
     pa_assert_se(u->mixer_path = data->path);
-    pa_alsa_path_select(u->mixer_path, u->mixer_handle);
-
-    if (u->mixer_path->has_volume && u->mixer_path->has_dB) {
-        s->base_volume = pa_sw_volume_from_dB(-u->mixer_path->max_dB);
-        s->n_volume_steps = PA_VOLUME_NORM+1;
-
-        if (u->mixer_path->max_dB > 0.0)
-            pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(s->base_volume));
-        else
-            pa_log_info("No particular base volume set, fixing to 0 dB");
-    } else {
-        s->base_volume = PA_VOLUME_NORM;
-        s->n_volume_steps = u->mixer_path->max_volume - u->mixer_path->min_volume + 1;
-    }
+    pa_alsa_path_select(u->mixer_path, data->setting, u->mixer_handle, s->muted);
 
-    if (data->setting)
-        pa_alsa_setting_select(data->setting, u->mixer_handle);
+    mixer_volume_init(u);
 
     if (s->set_mute)
         s->set_mute(s);
-    if (s->set_volume)
-        s->set_volume(s);
+    if (s->flags & PA_SINK_DEFERRED_VOLUME) {
+        if (s->write_volume)
+            s->write_volume(s);
+    } else {
+        if (s->set_volume)
+            s->set_volume(s);
+    }
 
     return 0;
 }
@@ -1261,6 +1652,9 @@ static void sink_update_requested_latency_cb(pa_sink *s) {
     struct userdata *u = s->userdata;
     size_t before;
     pa_assert(u);
+    pa_assert(u->use_tsched); /* only when timer scheduling is used
+                               * we can dynamically adjust the
+                               * latency */
 
     if (!u->pcm_handle)
         return;
@@ -1275,51 +1669,127 @@ static void sink_update_requested_latency_cb(pa_sink *s) {
     things up. */
 
     if (u->hwbuf_unused > before) {
-        pa_log_debug("Requesting rewind due to latency change.");
+        pa_log_debug_verbose("Requesting rewind due to latency change.");
         pa_sink_request_rewind(s, (size_t) -1);
     }
 }
 
-static int process_rewind(struct userdata *u) {
-    snd_pcm_sframes_t unused;
-    size_t rewind_nbytes, unused_nbytes, limit_nbytes;
+static pa_idxset* sink_get_formats(pa_sink *s) {
+    struct userdata *u = s->userdata;
+    pa_idxset *ret = pa_idxset_new(NULL, NULL);
+    pa_format_info *f;
+    uint32_t idx;
+
     pa_assert(u);
 
-#if 1
-    /* Figure out how much we shall rewind and reset the counter */
-    rewind_nbytes = u->sink->thread_info.rewind_nbytes;
-    u->sink->thread_info.rewind_nbytes = 0;
+    PA_IDXSET_FOREACH(f, u->formats, idx) {
+        pa_idxset_put(ret, pa_format_info_copy(f), NULL);
+    }
 
-    if (rewind_nbytes > 0) {
-        pa_log_debug("Requested to rewind %lu bytes.", (unsigned long) rewind_nbytes);
-        rewind_nbytes = PA_MIN(u->memchunk.length, rewind_nbytes);
-        u->memchunk.length -= rewind_nbytes;
-        if (u->memchunk.length <= 0 && u->memchunk.memblock) {
-            pa_memblock_unref(u->memchunk.memblock);
-            pa_memchunk_reset(&u->memchunk);
+    return ret;
+}
+
+static pa_bool_t sink_set_formats(pa_sink *s, pa_idxset *formats) {
+    struct userdata *u = s->userdata;
+    pa_format_info *f, *g;
+    uint32_t idx, n;
+
+    pa_assert(u);
+
+    /* FIXME: also validate sample rates against what the device supports */
+    PA_IDXSET_FOREACH(f, formats, idx) {
+        if (is_iec958(u) && f->encoding == PA_ENCODING_EAC3_IEC61937)
+            /* EAC3 cannot be sent over over S/PDIF */
+            return FALSE;
+    }
+
+    pa_idxset_free(u->formats, (pa_free_cb_t) pa_format_info_free);
+    u->formats = pa_idxset_new(NULL, NULL);
+
+    /* Note: the logic below won't apply if we're using software encoding.
+     * This is fine for now since we don't support that via the passthrough
+     * framework, but this must be changed if we do. */
+
+    /* Count how many sample rates we support */
+    for (idx = 0, n = 0; u->rates[idx]; idx++)
+        n++;
+
+    /* First insert non-PCM formats since we prefer those. */
+    PA_IDXSET_FOREACH(f, formats, idx) {
+        if (!pa_format_info_is_pcm(f)) {
+            g = pa_format_info_copy(f);
+            pa_format_info_set_prop_int_array(g, PA_PROP_FORMAT_RATE, (int *) u->rates, n);
+            pa_idxset_put(u->formats, g, NULL);
         }
-        pa_log_debug("Rewound %lu bytes.", (unsigned long) rewind_nbytes);
     }
 
-    u->write_count -= rewind_nbytes;
-    pa_sink_process_rewind(u->sink, rewind_nbytes);
-    if (rewind_nbytes)
-        u->after_rewind = TRUE;
+    /* Now add any PCM formats */
+    PA_IDXSET_FOREACH(f, formats, idx) {
+        if (pa_format_info_is_pcm(f)) {
+            /* We don't set rates here since we'll just tack on a resampler for
+             * unsupported rates */
+            pa_idxset_put(u->formats, pa_format_info_copy(f), NULL);
+        }
+    }
 
-    return 0;
+    return TRUE;
+}
+
+static pa_bool_t sink_update_rate_cb(pa_sink *s, uint32_t rate)
+{
+    struct userdata *u = s->userdata;
+    int i;
+    pa_bool_t supported = FALSE;
+
+    pa_assert(u);
+
+    for (i = 0; u->rates[i]; i++) {
+        if (u->rates[i] == rate) {
+            supported = TRUE;
+            break;
+        }
+    }
+
+    if (!supported) {
+        pa_log_info("Sink does not support sample rate of %d Hz", rate);
+        return FALSE;
+    }
+
+    if (!PA_SINK_IS_OPENED(s->state)) {
+        pa_log_info("Updating rate for device %s, new rate is %d",u->device_name, rate);
+        u->sink->sample_spec.rate = rate;
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+static int process_rewind(struct userdata *u) {
+    snd_pcm_sframes_t unused;
+    size_t rewind_nbytes, unused_nbytes, limit_nbytes;
+    pa_assert(u);
+
+    if (!PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
+        pa_sink_process_rewind(u->sink, 0);
+        return 0;
+    }
 
-#else
     /* Figure out how much we shall rewind and reset the counter */
     rewind_nbytes = u->sink->thread_info.rewind_nbytes;
 
+#ifndef __TIZEN__
     pa_log_debug("Requested to rewind %lu bytes.", (unsigned long) rewind_nbytes);
+#endif
 
     if (PA_UNLIKELY((unused = pa_alsa_safe_avail(u->pcm_handle, u->hwbuf_size, &u->sink->sample_spec)) < 0)) {
         pa_log("snd_pcm_avail() failed: %s", pa_alsa_strerror((int) unused));
         return -1;
     }
 
-    unused_nbytes = u->tsched_watermark + (size_t) unused * u->frame_size;
+    unused_nbytes = (size_t) unused * u->frame_size;
+
+    /* make sure rewind doesn't go too far, can cause issues with DMAs */
+    unused_nbytes += u->rewind_safeguard;
 
     if (u->hwbuf_size > unused_nbytes)
         limit_nbytes = u->hwbuf_size - unused_nbytes;
@@ -1332,18 +1802,30 @@ static int process_rewind(struct userdata *u) {
     if (rewind_nbytes > 0) {
         snd_pcm_sframes_t in_frames, out_frames;
 
+#ifdef __TIZEN__
+        limit_nbytes = rewind_nbytes;
+#else
         pa_log_debug("Limited to %lu bytes.", (unsigned long) rewind_nbytes);
+#endif
 
         in_frames = (snd_pcm_sframes_t) (rewind_nbytes / u->frame_size);
+#ifndef __TIZEN__
         pa_log_debug("before: %lu", (unsigned long) in_frames);
-        if ((out_frames = snd_pcm_rewind(u->pcm_handle, (snd_pcm_uframes_t) in_frames)) < 0) {
-            pa_log("snd_pcm_rewind() failed: %s", pa_alsa_strerror((int) out_frames));
-            if (try_recover(u, "process_rewind", out_frames) < 0)
-                return -1;
+#endif
+        /* FIXME: This check added because if rewind is called for 192khz audio pop up noise observed. This is temporary fix*/
+        if (u->sink->sample_spec.rate != 192000) {
+            if ((out_frames = snd_pcm_rewind(u->pcm_handle, (snd_pcm_uframes_t) in_frames)) < 0) {
+                pa_log("snd_pcm_rewind() failed: %s", pa_alsa_strerror((int) out_frames));
+                if (try_recover(u, "process_rewind", out_frames) < 0)
+                    return -1;
+                out_frames = 0;
+            }
+        } else {
             out_frames = 0;
         }
-
+#ifndef __TIZEN__
         pa_log_debug("after: %lu", (unsigned long) out_frames);
+#endif
 
         rewind_nbytes = (size_t) out_frames * u->frame_size;
 
@@ -1351,19 +1833,23 @@ static int process_rewind(struct userdata *u) {
             pa_log_info("Tried rewind, but was apparently not possible.");
         else {
             u->write_count -= rewind_nbytes;
+#ifdef __TIZEN__
+            pa_log_debug_verbose("Requested to rewind %lu bytes, Limited to %lu bytes, Rewound %lu bytes(before:%lu after:%lu).",
+                    (unsigned long)u->sink->thread_info.rewind_nbytes, (unsigned long)limit_nbytes,
+                    (unsigned long) rewind_nbytes, in_frames, out_frames);
+#else
             pa_log_debug("Rewound %lu bytes.", (unsigned long) rewind_nbytes);
+#endif
             pa_sink_process_rewind(u->sink, rewind_nbytes);
 
             u->after_rewind = TRUE;
             return 0;
         }
     } else
-        pa_log_debug("Mhmm, actually there is nothing to rewind.");
+        pa_log_debug_verbose("Mhmm, actually there is nothing to rewind.");
 
     pa_sink_process_rewind(u->sink, 0);
     return 0;
-#endif
-
 }
 
 static void thread_func(void *userdata) {
@@ -1381,21 +1867,23 @@ static void thread_func(void *userdata) {
 
     for (;;) {
         int ret;
+        pa_usec_t rtpoll_sleep = 0, real_sleep;
 
 #ifdef DEBUG_TIMING
         pa_log_debug("Loop");
 #endif
 
+        if (PA_UNLIKELY(u->sink->thread_info.rewind_requested)) {
+            if (process_rewind(u) < 0)
+                goto fail;
+        }
+
         /* Render some data and write it to the dsp */
         if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
             int work_done;
             pa_usec_t sleep_usec = 0;
             pa_bool_t on_timeout = pa_rtpoll_timer_elapsed(u->rtpoll);
 
-            if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
-                if (process_rewind(u) < 0)
-                        goto fail;
-
             if (u->use_mmap)
                 work_done = mmap_write(u, &sleep_usec, revents & POLLOUT, on_timeout);
             else
@@ -1409,10 +1897,15 @@ static void thread_func(void *userdata) {
             if (work_done) {
 
                 if (u->first) {
-                    pa_log_info("Starting playback.");
-                    snd_pcm_start(u->pcm_handle);
+                    pa_log_info_verbose("Starting playback.");
+#ifdef __TIZEN__
+                    if (SND_PCM_STATE_PREPARED == snd_pcm_state(u->pcm_handle))
+#endif
+                        snd_pcm_start(u->pcm_handle);
 
                     pa_smoother_resume(u->smoother, pa_rtclock_now(), TRUE);
+
+                    u->first = FALSE;
                 }
 
                 update_smoother(u);
@@ -1431,37 +1924,75 @@ static void thread_func(void *userdata) {
                      * we have filled the buffer at least once
                      * completely.*/
 
-                    if (pa_log_ratelimit())
-                        pa_log_debug("Cutting sleep time for the initial iterations by half.");
+#ifdef __TIZEN_LOG__
+                    if (pa_log_ratelimit(PA_LOG_VERBOSE))
+#else
+                    if (pa_log_ratelimit(PA_LOG_DEBUG))
+#endif
+                        pa_log_debug_verbose("Cutting sleep time for the initial iterations by half.");
                     sleep_usec /= 2;
                 }
 
                 /* OK, the playback buffer is now full, let's
                  * calculate when to wake up next */
-/*                 pa_log_debug("Waking up in %0.2fms (sound card clock).", (double) sleep_usec / PA_USEC_PER_MSEC); */
+#ifdef DEBUG_TIMING
+                pa_log_debug("Waking up in %0.2fms (sound card clock).", (double) sleep_usec / PA_USEC_PER_MSEC);
+#endif
 
                 /* Convert from the sound card time domain to the
                  * system time domain */
                 cusec = pa_smoother_translate(u->smoother, pa_rtclock_now(), sleep_usec);
 
-/*                 pa_log_debug("Waking up in %0.2fms (system clock).", (double) cusec / PA_USEC_PER_MSEC); */
+#ifdef DEBUG_TIMING
+                pa_log_debug("Waking up in %0.2fms (system clock).", (double) cusec / PA_USEC_PER_MSEC);
+#endif
 
                 /* We don't trust the conversion, so we wake up whatever comes first */
-                pa_rtpoll_set_timer_relative(u->rtpoll, PA_MIN(sleep_usec, cusec));
+                rtpoll_sleep = PA_MIN(sleep_usec, cusec);
             }
 
-            u->first = FALSE;
             u->after_rewind = FALSE;
 
-        } else if (u->use_tsched)
+        }
+
+        if (u->sink->flags & PA_SINK_DEFERRED_VOLUME) {
+            pa_usec_t volume_sleep;
+            pa_sink_volume_change_apply(u->sink, &volume_sleep);
+            if (volume_sleep > 0) {
+                if (rtpoll_sleep > 0)
+                    rtpoll_sleep = PA_MIN(volume_sleep, rtpoll_sleep);
+                else
+                    rtpoll_sleep = volume_sleep;
+            }
+        }
 
-            /* OK, we're in an invalid state, let's disable our timers */
+        if (rtpoll_sleep > 0) {
+            pa_rtpoll_set_timer_relative(u->rtpoll, rtpoll_sleep);
+            real_sleep = pa_rtclock_now();
+        }
+        else
             pa_rtpoll_set_timer_disabled(u->rtpoll);
 
         /* Hmm, nothing to do. Let's sleep */
         if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
             goto fail;
 
+        if (rtpoll_sleep > 0) {
+            real_sleep = pa_rtclock_now() - real_sleep;
+#ifdef DEBUG_TIMING
+            pa_log_debug("Expected sleep: %0.2fms, real sleep: %0.2fms (diff %0.2f ms)",
+                (double) rtpoll_sleep / PA_USEC_PER_MSEC, (double) real_sleep / PA_USEC_PER_MSEC,
+                (double) ((int64_t) real_sleep - (int64_t) rtpoll_sleep) / PA_USEC_PER_MSEC);
+#endif
+            if (u->use_tsched && real_sleep > rtpoll_sleep + u->tsched_watermark)
+                pa_log_debug("Scheduling delay of %0.2fms > %0.2fms, you might want to investigate this to improve latency...",
+                    (double) (real_sleep - rtpoll_sleep) / PA_USEC_PER_MSEC,
+                    (double) (u->tsched_watermark) / PA_USEC_PER_MSEC);
+        }
+
+        if (u->sink->flags & PA_SINK_DEFERRED_VOLUME)
+            pa_sink_volume_change_apply(u->sink, NULL);
+
         if (ret == 0)
             goto finish;
 
@@ -1484,7 +2015,8 @@ static void thread_func(void *userdata) {
 
                 u->first = TRUE;
                 u->since_start = 0;
-            } else if (revents && u->use_tsched && pa_log_ratelimit())
+                revents = 0;
+            } else if (revents && u->use_tsched && pa_log_ratelimit(PA_LOG_DEBUG))
                 pa_log_debug("Wakeup from ALSA!");
 
         } else
@@ -1532,11 +2064,12 @@ 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, pa_bool_t ignore_dB) {
+    snd_hctl_t *hctl;
 
     if (!mapping && !element)
         return;
 
-    if (!(u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device))) {
+    if (!(u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device, &hctl))) {
         pa_log_info("Failed to find a working mixer device.");
         return;
     }
@@ -1546,30 +2079,19 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char
         if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_OUTPUT)))
             goto fail;
 
-        if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, ignore_dB) < 0)
+        if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, hctl, ignore_dB) < 0)
             goto fail;
 
         pa_log_debug("Probed mixer path %s:", u->mixer_path->name);
         pa_alsa_path_dump(u->mixer_path);
-    } else {
-
-        if (!(u->mixer_path_set = pa_alsa_path_set_new(mapping, PA_ALSA_DIRECTION_OUTPUT)))
-            goto fail;
-
-        pa_alsa_path_set_probe(u->mixer_path_set, u->mixer_handle, ignore_dB);
-
-        pa_log_debug("Probed mixer paths:");
-        pa_alsa_path_set_dump(u->mixer_path_set);
-    }
+    } else if (!(u->mixer_path_set = mapping->output_path_set))
+        goto fail;
 
     return;
 
 fail:
 
-    if (u->mixer_path_set) {
-        pa_alsa_path_set_free(u->mixer_path_set);
-        u->mixer_path_set = NULL;
-    } else if (u->mixer_path) {
+    if (u->mixer_path) {
         pa_alsa_path_free(u->mixer_path);
         u->mixer_path = NULL;
     }
@@ -1581,6 +2103,8 @@ fail:
 }
 
 static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
+    pa_bool_t need_mixer_callback = FALSE;
+
     pa_assert(u);
 
     if (!u->mixer_handle)
@@ -1595,75 +2119,62 @@ static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
         data = PA_DEVICE_PORT_DATA(u->sink->active_port);
         u->mixer_path = data->path;
 
-        pa_alsa_path_select(data->path, u->mixer_handle);
-
-        if (data->setting)
-            pa_alsa_setting_select(data->setting, u->mixer_handle);
+        pa_alsa_path_select(data->path, data->setting, u->mixer_handle, u->sink->muted);
 
     } else {
 
         if (!u->mixer_path && u->mixer_path_set)
-            u->mixer_path = u->mixer_path_set->paths;
+            u->mixer_path = pa_hashmap_first(u->mixer_path_set->paths);
 
         if (u->mixer_path) {
             /* Hmm, we have only a single path, then let's activate it */
 
-            pa_alsa_path_select(u->mixer_path, u->mixer_handle);
+            pa_alsa_path_select(u->mixer_path, u->mixer_path->settings, u->mixer_handle, u->sink->muted);
 
-            if (u->mixer_path->settings)
-                pa_alsa_setting_select(u->mixer_path->settings, u->mixer_handle);
         } else
             return 0;
     }
 
-    if (!u->mixer_path->has_volume)
-        pa_log_info("Driver does not support hardware volume control, falling back to software volume control.");
-    else {
+    mixer_volume_init(u);
 
-        if (u->mixer_path->has_dB) {
-            pa_log_info("Hardware volume ranges from %0.2f dB to %0.2f dB.", u->mixer_path->min_dB, u->mixer_path->max_dB);
-
-            u->sink->base_volume = pa_sw_volume_from_dB(-u->mixer_path->max_dB);
-            u->sink->n_volume_steps = PA_VOLUME_NORM+1;
+    /* Will we need to register callbacks? */
+    if (u->mixer_path_set && u->mixer_path_set->paths) {
+        pa_alsa_path *p;
+        void *state;
 
-            if (u->mixer_path->max_dB > 0.0)
-                pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(u->sink->base_volume));
-            else
-                pa_log_info("No particular base volume set, fixing to 0 dB");
-
-        } else {
-            pa_log_info("Hardware volume ranges from %li to %li.", u->mixer_path->min_volume, u->mixer_path->max_volume);
-            u->sink->base_volume = PA_VOLUME_NORM;
-            u->sink->n_volume_steps = u->mixer_path->max_volume - u->mixer_path->min_volume + 1;
+        PA_HASHMAP_FOREACH(p, u->mixer_path_set->paths, state) {
+            if (p->has_volume || p->has_mute)
+                need_mixer_callback = TRUE;
         }
-
-        u->sink->get_volume = sink_get_volume_cb;
-        u->sink->set_volume = sink_set_volume_cb;
-
-        u->sink->flags |= PA_SINK_HW_VOLUME_CTRL | (u->mixer_path->has_dB ? PA_SINK_DECIBEL_VOLUME : 0);
-        pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->mixer_path->has_dB ? "supported" : "not supported");
     }
+    else if (u->mixer_path)
+        need_mixer_callback = u->mixer_path->has_volume || u->mixer_path->has_mute;
 
-    if (!u->mixer_path->has_mute) {
-        pa_log_info("Driver does not support hardware mute control, falling back to software mute control.");
-    } else {
-        u->sink->get_mute = sink_get_mute_cb;
-        u->sink->set_mute = sink_set_mute_cb;
-        u->sink->flags |= PA_SINK_HW_MUTE_CTRL;
-        pa_log_info("Using hardware mute control.");
-    }
+    if (need_mixer_callback) {
+        int (*mixer_callback)(snd_mixer_elem_t *, unsigned int);
+        if (u->sink->flags & PA_SINK_DEFERRED_VOLUME) {
+            u->mixer_pd = pa_alsa_mixer_pdata_new();
+            mixer_callback = io_mixer_callback;
 
-    u->mixer_fdl = pa_alsa_fdlist_new();
+            if (pa_alsa_set_mixer_rtpoll(u->mixer_pd, u->mixer_handle, u->rtpoll) < 0) {
+                pa_log("Failed to initialize file descriptor monitoring");
+                return -1;
+            }
+        } else {
+            u->mixer_fdl = pa_alsa_fdlist_new();
+            mixer_callback = ctl_mixer_callback;
 
-    if (pa_alsa_fdlist_set_mixer(u->mixer_fdl, u->mixer_handle, u->core->mainloop) < 0) {
-        pa_log("Failed to initialize file descriptor monitoring");
-        return -1;
-    }
+            if (pa_alsa_fdlist_set_handle(u->mixer_fdl, u->mixer_handle, NULL, u->core->mainloop) < 0) {
+                pa_log("Failed to initialize file descriptor monitoring");
+                return -1;
+            }
+        }
 
-    if (u->mixer_path_set)
-        pa_alsa_path_set_set_callback(u->mixer_path_set, u->mixer_handle, mixer_callback, u);
-    else
-        pa_alsa_path_set_callback(u->mixer_path, u->mixer_handle, mixer_callback, u);
+        if (u->mixer_path_set)
+            pa_alsa_path_set_set_callback(u->mixer_path_set, u->mixer_handle, mixer_callback, u);
+        else
+            pa_alsa_path_set_callback(u->mixer_path, u->mixer_handle, mixer_callback, u);
+    }
 
     return 0;
 }
@@ -1671,15 +2182,21 @@ static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
 pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_card *card, pa_alsa_mapping *mapping) {
 
     struct userdata *u = NULL;
-    const char *dev_id = NULL;
-    pa_sample_spec ss, requested_ss;
+    const char *dev_id = NULL, *key, *mod_name;
+    pa_sample_spec ss;
+    char *thread_name = NULL;
+    uint32_t alternate_sample_rate;
     pa_channel_map map;
-    uint32_t nfrags, frag_size, buffer_size, tsched_size, tsched_watermark;
+    uint32_t nfrags, frag_size, buffer_size, tsched_size, tsched_watermark, rewind_safeguard;
     snd_pcm_uframes_t period_frames, buffer_frames, tsched_frames;
     size_t frame_size;
-    pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, ignore_dB = FALSE;
+    pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, ignore_dB = FALSE, namereg_fail = FALSE, deferred_volume = FALSE, set_formats = FALSE, fixed_latency_range = FALSE;
     pa_sink_new_data data;
     pa_alsa_profile_set *profile_set = NULL;
+    void *state = NULL;
+#ifdef __TIZEN__
+    int start_threshold;
+#endif
 
     pa_assert(m);
     pa_assert(ma);
@@ -1691,7 +2208,12 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
         goto fail;
     }
 
-    requested_ss = ss;
+    alternate_sample_rate = m->core->alternate_sample_rate;
+    if (pa_modargs_get_alternate_sample_rate(ma, &alternate_sample_rate) < 0) {
+        pa_log("Failed to parse alternate sample rate");
+        goto fail;
+    }
+
     frame_size = pa_frame_size(&ss);
 
     nfrags = m->core->default_n_fragments;
@@ -1715,6 +2237,13 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
     buffer_frames = buffer_size/frame_size;
     tsched_frames = tsched_size/frame_size;
 
+#ifdef __TIZEN__
+    if(pa_modargs_get_value_s32(ma, "start_threshold", &start_threshold) < 0){
+       pa_log("Failed to parse start_threshold argument.");
+       goto fail;
+    }
+#endif
+
     if (pa_modargs_get_value_boolean(ma, "mmap", &use_mmap) < 0) {
         pa_log("Failed to parse mmap argument.");
         goto fail;
@@ -1730,6 +2259,23 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
         goto fail;
     }
 
+    rewind_safeguard = PA_MAX(DEFAULT_REWIND_SAFEGUARD_BYTES, pa_usec_to_bytes(DEFAULT_REWIND_SAFEGUARD_USEC, &ss));
+    if (pa_modargs_get_value_u32(ma, "rewind_safeguard", &rewind_safeguard) < 0) {
+        pa_log("Failed to parse rewind_safeguard argument");
+        goto fail;
+    }
+
+    deferred_volume = m->core->deferred_volume;
+    if (pa_modargs_get_value_boolean(ma, "deferred_volume", &deferred_volume) < 0) {
+        pa_log("Failed to parse deferred_volume argument.");
+        goto fail;
+    }
+
+    if (pa_modargs_get_value_boolean(ma, "fixed_latency_range", &fixed_latency_range) < 0) {
+        pa_log("Failed to parse fixed_latency_range argument.");
+        goto fail;
+    }
+
     use_tsched = pa_alsa_may_tsched(use_tsched);
 
     u = pa_xnew0(struct userdata, 1);
@@ -1737,13 +2283,16 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
     u->module = m;
     u->use_mmap = use_mmap;
     u->use_tsched = use_tsched;
+    u->deferred_volume = deferred_volume;
+    u->fixed_latency_range = fixed_latency_range;
     u->first = TRUE;
+    u->rewind_safeguard = rewind_safeguard;
     u->rtpoll = pa_rtpoll_new();
     pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
 
     u->smoother = pa_smoother_new(
-            DEFAULT_TSCHED_BUFFER_USEC*2,
-            DEFAULT_TSCHED_BUFFER_USEC*2,
+            SMOOTHER_ADJUST_USEC,
+            SMOOTHER_WINDOW_USEC,
             TRUE,
             TRUE,
             5,
@@ -1751,10 +2300,16 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
             TRUE);
     u->smoother_interval = SMOOTHER_MIN_INTERVAL;
 
+    /* use ucm */
+    if (mapping && mapping->ucm_context.ucm)
+        u->ucm_context = &mapping->ucm_context;
+
     dev_id = pa_modargs_get_value(
             ma, "device_id",
             pa_modargs_get_value(ma, "device", DEFAULT_DEVICE));
 
+    u->paths_dir = pa_xstrdup(pa_modargs_get_value(ma, "paths_dir", NULL));
+
     if (reserve_init(u, dev_id) < 0)
         goto fail;
 
@@ -1771,14 +2326,23 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
             goto fail;
         }
 
+        if ((mod_name = pa_proplist_gets(mapping->proplist, PA_ALSA_PROP_UCM_MODIFIER))) {
+            if (snd_use_case_set(u->ucm_context->ucm->ucm_mgr, "_enamod", mod_name) < 0)
+                pa_log("Failed to enable ucm modifier %s", mod_name);
+            else
+                pa_log_debug("Enabled ucm modifier %s", mod_name);
+        }
+
         if (!(u->pcm_handle = pa_alsa_open_by_device_id_mapping(
+#ifdef __TIZEN__
+                      u->core,
+#endif
                       dev_id,
                       &u->device_name,
                       &ss, &map,
                       SND_PCM_STREAM_PLAYBACK,
                       &period_frames, &buffer_frames, tsched_frames,
                       &b, &d, mapping)))
-
             goto fail;
 
     } else if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
@@ -1787,18 +2351,23 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
             goto fail;
 
         if (!(u->pcm_handle = pa_alsa_open_by_device_id_auto(
+#ifdef __TIZEN__
+                      u->core,
+#endif
                       dev_id,
                       &u->device_name,
                       &ss, &map,
                       SND_PCM_STREAM_PLAYBACK,
                       &period_frames, &buffer_frames, tsched_frames,
                       &b, &d, profile_set, &mapping)))
-
             goto fail;
 
     } else {
 
         if (!(u->pcm_handle = pa_alsa_open_by_device_string(
+#ifdef __TIZEN__
+                      u->core,
+#endif
                       pa_modargs_get_value(ma, "device", DEFAULT_DEVICE),
                       &u->device_name,
                       &ss, &map,
@@ -1832,21 +2401,49 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
     if (u->use_mmap)
         pa_log_info("Successfully enabled mmap() mode.");
 
-    if (u->use_tsched)
+    if (u->use_tsched) {
         pa_log_info("Successfully enabled timer-based scheduling mode.");
 
+        if (u->fixed_latency_range)
+            pa_log_info("Disabling latency range changes on underrun");
+    }
+
+    if (is_iec958(u) || is_hdmi(u))
+        set_formats = TRUE;
+
+    u->rates = pa_alsa_get_supported_rates(u->pcm_handle, ss.rate);
+    if (!u->rates) {
+        pa_log_error("Failed to find any supported sample rates.");
+        goto fail;
+    }
+
     /* ALSA might tweak the sample spec, so recalculate the frame size */
     frame_size = pa_frame_size(&ss);
 
-    find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB);
+    if (!u->ucm_context)
+        find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB);
 
     pa_sink_new_data_init(&data);
     data.driver = driver;
     data.module = m;
     data.card = card;
     set_sink_name(&data, ma, dev_id, u->device_name, mapping);
+
+    /* We need to give pa_modargs_get_value_boolean() a pointer to a local
+     * variable instead of using &data.namereg_fail directly, because
+     * data.namereg_fail is a bitfield and taking the address of a bitfield
+     * variable is impossible. */
+    namereg_fail = data.namereg_fail;
+    if (pa_modargs_get_value_boolean(ma, "namereg_fail", &namereg_fail) < 0) {
+        pa_log("Failed to parse namereg_fail argument.");
+        pa_sink_new_data_done(&data);
+        goto fail;
+    }
+    data.namereg_fail = namereg_fail;
+
     pa_sink_new_data_set_sample_spec(&data, &ss);
     pa_sink_new_data_set_channel_map(&data, &map);
+    pa_sink_new_data_set_alternate_sample_rate(&data, alternate_sample_rate);
 
     pa_alsa_init_proplist_pcm(m->core, data.proplist, u->pcm_handle);
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device_name);
@@ -1854,13 +2451,12 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
     pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE, "%lu", (unsigned long) (period_frames * frame_size));
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_ACCESS_MODE, u->use_tsched ? "mmap+timer" : (u->use_mmap ? "mmap" : "serial"));
 
-    /* Set Suspend timeout to ZERO to avoid noise */
-    pa_log_info("Set suspend-on-idle timeout to ZERO to avoid noise");
-    pa_proplist_sets(data.proplist, "module-suspend-on-idle.timeout", ALSA_SUSPEND_ON_IDLE_TIMEOUT);
-
     if (mapping) {
         pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_NAME, mapping->name);
         pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, mapping->description);
+
+        while ((key = pa_proplist_iterate(mapping->proplist, &state)))
+            pa_proplist_sets(data.proplist, key, pa_proplist_gets(mapping->proplist, key));
     }
 
     pa_alsa_init_description(data.proplist);
@@ -1874,10 +2470,13 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
         goto fail;
     }
 
-    if (u->mixer_path_set)
-        pa_alsa_add_ports(&data.ports, u->mixer_path_set);
+    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);
 
-    u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY|(u->use_tsched ? PA_SINK_DYNAMIC_LATENCY : 0));
+    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));
     pa_sink_new_data_done(&data);
 
     if (!u->sink) {
@@ -1885,10 +2484,28 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
         goto fail;
     }
 
+    if (pa_modargs_get_value_u32(ma, "deferred_volume_safety_margin",
+                                 &u->sink->thread_info.volume_change_safety_margin) < 0) {
+        pa_log("Failed to parse deferred_volume_safety_margin parameter");
+        goto fail;
+    }
+
+    if (pa_modargs_get_value_s32(ma, "deferred_volume_extra_delay",
+                                 &u->sink->thread_info.volume_change_extra_delay) < 0) {
+        pa_log("Failed to parse deferred_volume_extra_delay parameter");
+        goto fail;
+    }
+
     u->sink->parent.process_msg = sink_process_msg;
-    u->sink->update_requested_latency = sink_update_requested_latency_cb;
+    if (u->use_tsched)
+        u->sink->update_requested_latency = sink_update_requested_latency_cb;
     u->sink->set_state = sink_set_state_cb;
-    u->sink->set_port = sink_set_port_cb;
+    if (u->ucm_context)
+        u->sink->set_port = sink_set_port_ucm_cb;
+    else
+        u->sink->set_port = sink_set_port_cb;
+    if (u->sink->alternate_sample_rate)
+        u->sink->update_rate = sink_update_rate_cb;
     u->sink->userdata = u;
 
     pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
@@ -1907,44 +2524,44 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
                 (double) pa_bytes_to_usec(u->hwbuf_size, &ss) / PA_USEC_PER_MSEC);
 
     pa_sink_set_max_request(u->sink, u->hwbuf_size);
-    pa_sink_set_max_rewind(u->sink, u->hwbuf_size);
+    if (pa_alsa_pcm_is_hw(u->pcm_handle))
+        pa_sink_set_max_rewind(u->sink, u->hwbuf_size);
+    else {
+        pa_log_info("Disabling rewind for device %s", u->device_name);
+        pa_sink_set_max_rewind(u->sink, 0);
+    }
 
     if (u->use_tsched) {
-        u->tsched_watermark = pa_usec_to_bytes_round_up(pa_bytes_to_usec_round_up(tsched_watermark, &requested_ss), &u->sink->sample_spec);
-
-        u->watermark_inc_step = pa_usec_to_bytes(TSCHED_WATERMARK_INC_STEP_USEC, &u->sink->sample_spec);
-        u->watermark_dec_step = pa_usec_to_bytes(TSCHED_WATERMARK_DEC_STEP_USEC, &u->sink->sample_spec);
-
-        u->watermark_inc_threshold = pa_usec_to_bytes_round_up(TSCHED_WATERMARK_INC_THRESHOLD_USEC, &u->sink->sample_spec);
-        u->watermark_dec_threshold = pa_usec_to_bytes_round_up(TSCHED_WATERMARK_DEC_THRESHOLD_USEC, &u->sink->sample_spec);
-
-        fix_min_sleep_wakeup(u);
-        fix_tsched_watermark(u);
-
-        pa_sink_set_latency_range(u->sink,
-                                  0,
-                                  pa_bytes_to_usec(u->hwbuf_size, &ss));
-
-        pa_log_info("Time scheduling watermark is %0.2fms",
-                    (double) pa_bytes_to_usec(u->tsched_watermark, &ss) / PA_USEC_PER_MSEC);
+        u->tsched_watermark_ref = tsched_watermark;
+        reset_watermark(u, u->tsched_watermark_ref, &ss, FALSE);
     } else
         pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(u->hwbuf_size, &ss));
 
-
     reserve_update(u);
 
+#ifdef __TIZEN__
+    /*Set start Threshold*/
+    u->start_threshold = start_threshold;
+#endif
+
     if (update_sw_params(u) < 0)
         goto fail;
 
-    if (setup_mixer(u, ignore_dB) < 0)
+    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)
         goto fail;
 
     pa_alsa_dump(PA_LOG_DEBUG, u->pcm_handle);
 
-    if (!(u->thread = pa_thread_new(thread_func, u))) {
+    thread_name = pa_sprintf_malloc("alsa-sink-%s", pa_strnull(pa_proplist_gets(u->sink->proplist, "alsa.id")));
+    if (!(u->thread = pa_thread_new(thread_name, thread_func, u))) {
         pa_log("Failed to create thread.");
         goto fail;
     }
+    pa_xfree(thread_name);
+    thread_name = NULL;
 
     /* Get initial mixer settings */
     if (data.volume_is_set) {
@@ -1963,6 +2580,24 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
             u->sink->get_mute(u->sink);
     }
 
+    if ((data.volume_is_set || data.muted_is_set) && u->sink->write_volume)
+        u->sink->write_volume(u->sink);
+
+    if (set_formats) {
+        /* For S/PDIF and HDMI, allow getting/setting custom formats */
+        pa_format_info *format;
+
+        /* To start with, we only support PCM formats. Other formats may be added
+         * with pa_sink_set_formats().*/
+        format = pa_format_info_new();
+        format->encoding = PA_ENCODING_PCM;
+        u->formats = pa_idxset_new(NULL, NULL);
+        pa_idxset_put(u->formats, format, NULL);
+
+        u->sink->get_formats = sink_get_formats;
+        u->sink->set_formats = sink_set_formats;
+    }
+
     pa_sink_put(u->sink);
 
     if (profile_set)
@@ -1971,6 +2606,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
     return u->sink;
 
 fail:
+    pa_xfree(thread_name);
 
     if (u)
         userdata_free(u);
@@ -1982,6 +2618,11 @@ fail:
 }
 
 static void userdata_free(struct userdata *u) {
+#ifdef __TIZEN__
+    void *audio_data = pa_shared_get(u->core, "tizen-audio-data");
+    audio_interface_t *audio_intf = pa_shared_get(u->core, "tizen-audio-interface");
+#endif
+
     pa_assert(u);
 
     if (u->sink)
@@ -2000,6 +2641,9 @@ static void userdata_free(struct userdata *u) {
     if (u->memchunk.memblock)
         pa_memblock_unref(u->memchunk.memblock);
 
+    if (u->mixer_pd)
+        pa_alsa_mixer_pdata_free(u->mixer_pd);
+
     if (u->alsa_rtpoll_item)
         pa_rtpoll_item_free(u->alsa_rtpoll_item);
 
@@ -2008,15 +2652,18 @@ static void userdata_free(struct userdata *u) {
 
     if (u->pcm_handle) {
         snd_pcm_drop(u->pcm_handle);
+#ifdef __TIZEN__
+        if (audio_intf && audio_intf->alsa_pcm_close) {
+            audio_intf->alsa_pcm_close(audio_data, u->pcm_handle);
+        } else
+#endif
         snd_pcm_close(u->pcm_handle);
     }
 
     if (u->mixer_fdl)
         pa_alsa_fdlist_free(u->mixer_fdl);
 
-    if (u->mixer_path_set)
-        pa_alsa_path_set_free(u->mixer_path_set);
-    else if (u->mixer_path)
+    if (u->mixer_path && !u->mixer_path_set)
         pa_alsa_path_free(u->mixer_path);
 
     if (u->mixer_handle)
@@ -2025,11 +2672,18 @@ static void userdata_free(struct userdata *u) {
     if (u->smoother)
         pa_smoother_free(u->smoother);
 
+    if (u->formats)
+        pa_idxset_free(u->formats, (pa_free_cb_t) pa_format_info_free);
+
+    if (u->rates)
+        pa_xfree(u->rates);
+
     reserve_done(u);
     monitor_done(u);
 
     pa_xfree(u->device_name);
     pa_xfree(u->control_device);
+    pa_xfree(u->paths_dir);
     pa_xfree(u);
 }
 
index b9a4ac2..e640b62 100644 (file)
@@ -28,7 +28,6 @@
 #include <pulsecore/sink.h>
 
 #include "alsa-util.h"
-#include "alsa-mixer.h"
 
 pa_sink* pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_card *card, pa_alsa_mapping *mapping);
 
old mode 100644 (file)
new mode 100755 (executable)
index 157698e..2c6cbfc
 #include <config.h>
 #endif
 
+#include <signal.h>
 #include <stdio.h>
 
 #include <asoundlib.h>
 
-#include <pulse/i18n.h>
 #include <pulse/rtclock.h>
 #include <pulse/timeval.h>
-#include <pulse/util.h>
+#include <pulse/volume.h>
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/core-error.h>
 #include <pulsecore/core.h>
+#include <pulsecore/i18n.h>
 #include <pulsecore/module.h>
 #include <pulsecore/memchunk.h>
 #include <pulsecore/sink.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/thread.h>
-#include <pulsecore/core-error.h>
 #include <pulsecore/thread-mq.h>
 #include <pulsecore/rtpoll.h>
 #include <pulsecore/time-smoother.h>
+#ifdef __TIZEN__
+#include <pulsecore/shared.h>
+#endif
 
 #include <modules/reserve-wrap.h>
 
 #include "alsa-util.h"
 #include "alsa-source.h"
 
+#ifdef __TIZEN__
+#include "tizen-audio.h"
+#endif
+
 /* #define DEBUG_TIMING */
 
 #define DEFAULT_DEVICE "default"
 #define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC)                /* 10ms */
 #define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC)                /* 4ms */
 
+#define SMOOTHER_WINDOW_USEC  (10*PA_USEC_PER_SEC)                 /* 10s */
+#define SMOOTHER_ADJUST_USEC  (1*PA_USEC_PER_SEC)                  /* 1s */
+
 #define SMOOTHER_MIN_INTERVAL (2*PA_USEC_PER_MSEC)                 /* 2ms */
 #define SMOOTHER_MAX_INTERVAL (200*PA_USEC_PER_MSEC)               /* 200ms */
 
 #define VOLUME_ACCURACY (PA_VOLUME_NORM/100)
 
+#ifdef __TIZEN__
+#define VOIP_MIN_WB_PERIOD_BYTES 640
+#define VOIP_MIN_NB_PERIOD_BYTES 320
+#define VOIP_WIDE_BAND 16000
+#endif
+
 struct userdata {
     pa_core *core;
     pa_module *module;
@@ -89,18 +104,23 @@ struct userdata {
 
     snd_pcm_t *pcm_handle;
 
+    char *paths_dir;
     pa_alsa_fdlist *mixer_fdl;
+    pa_alsa_mixer_pdata *mixer_pd;
     snd_mixer_t *mixer_handle;
     pa_alsa_path_set *mixer_path_set;
     pa_alsa_path *mixer_path;
 
     pa_cvolume hardware_volume;
 
+    unsigned int *rates;
+
     size_t
         frame_size,
         fragment_size,
         hwbuf_size,
         tsched_watermark,
+        tsched_watermark_ref,
         hwbuf_unused,
         min_sleep,
         min_wakeup,
@@ -110,15 +130,16 @@ struct userdata {
         watermark_dec_threshold;
 
     pa_usec_t watermark_dec_not_before;
+    pa_usec_t min_latency_ref;
 
-    char *device_name;
-    char *control_device;
+    char *device_name;  /* name of the PCM device */
+    char *control_device; /* name of the control device */
 
-    pa_bool_t use_mmap:1, use_tsched:1;
+    pa_bool_t use_mmap:1, use_tsched:1, deferred_volume:1, fixed_latency_range:1;
 
-    pa_rtpoll_item *alsa_rtpoll_item;
+    pa_bool_t first;
 
-    snd_mixer_selem_channel_id_t mixer_map[SND_MIXER_SCHN_LAST];
+    pa_rtpoll_item *alsa_rtpoll_item;
 
     pa_smoother *smoother;
     uint64_t read_count;
@@ -129,6 +150,17 @@ struct userdata {
     pa_hook_slot *reserve_slot;
     pa_reserve_monitor_wrapper *monitor;
     pa_hook_slot *monitor_slot;
+
+    /* ucm context */
+    pa_alsa_ucm_mapping_context *ucm_context;
+#ifdef __TIZEN__
+    /* Start threshold */
+    int start_threshold;
+#ifdef TIZEN_DEBUG_ENABLE
+    uint32_t log_count;
+#endif
+
+#endif
 };
 
 static void userdata_free(struct userdata *u);
@@ -137,6 +169,8 @@ static pa_hook_result_t reserve_cb(pa_reserve_wrapper *r, void *forced, struct u
     pa_assert(r);
     pa_assert(u);
 
+    pa_log_debug("Suspending source %s, because another application requested us to release the device.", u->source->name);
+
     if (pa_source_suspend(u->source, TRUE, PA_SUSPEND_APPLICATION) < 0)
         return PA_HOOK_CANCEL;
 
@@ -180,10 +214,10 @@ static int reserve_init(struct userdata *u, const char *dname) {
     if (pa_in_system_mode())
         return 0;
 
-    /* We are resuming, try to lock the device */
     if (!(rname = pa_alsa_get_reserve_name(dname)))
         return 0;
 
+    /* We are resuming, try to lock the device */
     u->reserve = pa_reserve_wrapper_get(u->core, rname);
     pa_xfree(rname);
 
@@ -199,14 +233,17 @@ static int reserve_init(struct userdata *u, const char *dname) {
 }
 
 static pa_hook_result_t monitor_cb(pa_reserve_monitor_wrapper *w, void* busy, struct userdata *u) {
-    pa_bool_t b;
-
     pa_assert(w);
     pa_assert(u);
 
-    b = PA_PTR_TO_UINT(busy) && !u->reserve;
+    if (PA_PTR_TO_UINT(busy) && !u->reserve) {
+        pa_log_debug("Suspending source %s, because another application is blocking the access to the device.", u->source->name);
+        pa_source_suspend(u->source, true, PA_SUSPEND_APPLICATION);
+    } else {
+        pa_log_debug("Resuming source %s, because other applications aren't blocking access to the device any more.", u->source->name);
+        pa_source_suspend(u->source, false, PA_SUSPEND_APPLICATION);
+    }
 
-    pa_source_suspend(u->source, b, PA_SUSPEND_APPLICATION);
     return PA_HOOK_OK;
 }
 
@@ -233,10 +270,10 @@ static int reserve_monitor_init(struct userdata *u, const char *dname) {
     if (pa_in_system_mode())
         return 0;
 
-    /* We are resuming, try to lock the device */
     if (!(rname = pa_alsa_get_reserve_name(dname)))
         return 0;
 
+    /* We are resuming, try to lock the device */
     u->monitor = pa_reserve_monitor_wrapper_get(u->core, rname);
     pa_xfree(rname);
 
@@ -251,6 +288,7 @@ static int reserve_monitor_init(struct userdata *u, const char *dname) {
 
 static void fix_min_sleep_wakeup(struct userdata *u) {
     size_t max_use, max_use_2;
+
     pa_assert(u);
     pa_assert(u->use_tsched);
 
@@ -296,7 +334,12 @@ static void increase_watermark(struct userdata *u) {
         return;
     }
 
-    /* Hmm, we cannot increase the watermark any further, hence let's raise the latency */
+    /* Hmm, we cannot increase the watermark any further, hence let's
+     raise the latency unless doing so was disabled in
+     configuration */
+    if (u->fixed_latency_range)
+        return;
+
     old_min_latency = u->source->thread_info.min_latency;
     new_min_latency = PA_MIN(old_min_latency * 2, old_min_latency + TSCHED_WATERMARK_INC_STEP_USEC);
     new_min_latency = PA_MIN(new_min_latency, u->source->thread_info.max_latency);
@@ -345,7 +388,7 @@ restart:
     u->watermark_dec_not_before = now + TSCHED_WATERMARK_VERIFY_AFTER_USEC;
 }
 
-static pa_usec_t hw_sleep_time(struct userdata *u, pa_usec_t *sleep_usec, pa_usec_t*process_usec) {
+static void hw_sleep_time(struct userdata *u, pa_usec_t *sleep_usec, pa_usec_t*process_usec) {
     pa_usec_t wm, usec;
 
     pa_assert(sleep_usec);
@@ -373,8 +416,6 @@ static pa_usec_t hw_sleep_time(struct userdata *u, pa_usec_t *sleep_usec, pa_use
                  (unsigned long) (*sleep_usec / PA_USEC_PER_MSEC),
                  (unsigned long) (*process_usec / PA_USEC_PER_MSEC));
 #endif
-
-    return usec;
 }
 
 static int try_recover(struct userdata *u, const char *call, int err) {
@@ -397,7 +438,7 @@ static int try_recover(struct userdata *u, const char *call, int err) {
         return -1;
     }
 
-    snd_pcm_start(u->pcm_handle);
+    u->first = TRUE;
     return 0;
 }
 
@@ -423,7 +464,7 @@ static size_t check_left_to_record(struct userdata *u, size_t n_bytes, pa_bool_t
         PA_DEBUG_TRAP;
 #endif
 
-        if (pa_log_ratelimit())
+        if (pa_log_ratelimit(PA_LOG_INFO))
             pa_log_info("Overrun!");
     }
 
@@ -439,9 +480,9 @@ static size_t check_left_to_record(struct userdata *u, size_t n_bytes, pa_bool_t
         else if (left_to_record > u->watermark_dec_threshold) {
             reset_not_before = FALSE;
 
-            /* We decrease the watermark only if have actually been
-             * woken up by a timeout. If something else woke us up
-             * it's too easy to fulfill the deadlines... */
+            /* We decrease the watermark only if have actually
+             * been woken up by a timeout. If something else woke
+             * us up it's too easy to fulfill the deadlines... */
 
             if (on_timeout)
                 decrease_watermark(u);
@@ -516,6 +557,7 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
             break;
         }
 
+
         if (++j > 10) {
 #ifdef DEBUG_TIMING
             pa_log_debug("Not filling up, because already too many iterations.");
@@ -531,15 +573,14 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
 #endif
 
         for (;;) {
+            pa_memchunk chunk;
+            void *p;
             int err;
             const snd_pcm_channel_area_t *areas;
             snd_pcm_uframes_t offset, frames;
-            pa_memchunk chunk;
-            void *p;
             snd_pcm_sframes_t sframes;
 
             frames = (snd_pcm_uframes_t) (n_bytes / u->frame_size);
-
 /*             pa_log_debug("%lu frames to read", (unsigned long) frames); */
 
             if (PA_UNLIKELY((err = pa_alsa_safe_mmap_begin(u->pcm_handle, &areas, &offset, &frames, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
@@ -554,8 +595,8 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
             }
 
             /* Make sure that if these memblocks need to be copied they will fit into one slot */
-            if (frames > pa_mempool_block_size_max(u->source->core->mempool)/u->frame_size)
-                frames = pa_mempool_block_size_max(u->source->core->mempool)/u->frame_size;
+            if (frames > pa_mempool_block_size_max(u->core->mempool)/u->frame_size)
+                frames = pa_mempool_block_size_max(u->core->mempool)/u->frame_size;
 
             if (!after_avail && frames == 0)
                 break;
@@ -594,6 +635,16 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
 
 #ifdef DEBUG_TIMING
             pa_log_debug("Read %lu bytes (of possible %lu bytes)", (unsigned long) (frames * u->frame_size), (unsigned long) n_bytes);
+#elif TIZEN_DEBUG_ENABLE
+            {
+                const uint32_t interval = 35;
+                if(u->log_count == 0 || u->log_count > interval) {
+                    pa_log_debug("ALSA-SOURCE : Read %lu bytes (of possible %lu bytes), total(%llu)", (unsigned long)(frames * u->frame_size), (unsigned long) n_bytes, u->read_count);
+                    if(u->log_count > interval)
+                        u->log_count = 0;
+                    }
+                    u->log_count++;
+            }
 #endif
 
             if ((size_t) frames * u->frame_size >= n_bytes)
@@ -603,12 +654,15 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
         }
     }
 
-    *sleep_usec = pa_bytes_to_usec(left_to_record, &u->source->sample_spec);
+    if (u->use_tsched) {
+        *sleep_usec = pa_bytes_to_usec(left_to_record, &u->source->sample_spec);
+        process_usec = pa_bytes_to_usec(u->tsched_watermark, &u->source->sample_spec);
 
-    if (*sleep_usec > process_usec)
-        *sleep_usec -= process_usec;
-    else
-        *sleep_usec = 0;
+        if (*sleep_usec > process_usec)
+            *sleep_usec -= process_usec;
+        else
+            *sleep_usec = 0;
+    }
 
     return work_done ? 1 : 0;
 }
@@ -640,6 +694,16 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
         }
 
         n_bytes = (size_t) n * u->frame_size;
+
+#ifdef __TIZEN__
+        if (pa_alsa_pcm_is_voip(u->pcm_handle))
+        {
+            size_t actual_n_bytes;
+            actual_n_bytes = (u->source->sample_spec.rate == VOIP_WIDE_BAND) ? VOIP_MIN_WB_PERIOD_BYTES :VOIP_MIN_NB_PERIOD_BYTES;
+            if(n_bytes > actual_n_bytes)
+               n_bytes = actual_n_bytes;
+        }
+#endif
         left_to_record = check_left_to_record(u, n_bytes, on_timeout);
         on_timeout = FALSE;
 
@@ -723,6 +787,19 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
 
 /*             pa_log_debug("read %lu frames", (unsigned long) frames); */
 
+#ifdef TIZEN_DEBUG_ENABLE
+            {
+                const uint32_t interval = 25;
+                if(u->log_count == 0 || u->log_count > interval) {
+                    pa_log_debug("ALSA-SOURCE : Read %lu bytes (of possible %lu bytes), total(%llu)", (unsigned long)(frames * u->frame_size), (unsigned long) n_bytes, u->read_count);
+                    if(u->log_count > interval)
+                        u->log_count = 0;
+                }
+                u->log_count++;
+            }
+#endif
+
+
             if ((size_t) frames * u->frame_size >= n_bytes)
                 break;
 
@@ -730,12 +807,15 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
         }
     }
 
-    *sleep_usec = pa_bytes_to_usec(left_to_record, &u->source->sample_spec);
+    if (u->use_tsched) {
+        *sleep_usec = pa_bytes_to_usec(left_to_record, &u->source->sample_spec);
+        process_usec = pa_bytes_to_usec(u->tsched_watermark, &u->source->sample_spec);
 
-    if (*sleep_usec > process_usec)
-        *sleep_usec -= process_usec;
-    else
-        *sleep_usec = 0;
+        if (*sleep_usec > process_usec)
+            *sleep_usec -= process_usec;
+        else
+            *sleep_usec = 0;
+    }
 
     return work_done ? 1 : 0;
 }
@@ -746,6 +826,7 @@ static void update_smoother(struct userdata *u) {
     int err;
     pa_usec_t now1 = 0, now2;
     snd_pcm_status_t *status;
+    snd_htimestamp_t htstamp = { 0, 0 };
 
     snd_pcm_status_alloca(&status);
 
@@ -754,18 +835,13 @@ static void update_smoother(struct userdata *u) {
 
     /* Let's update the time smoother */
 
-    if (PA_UNLIKELY((err = pa_alsa_safe_delay(u->pcm_handle, &delay, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
+    if (PA_UNLIKELY((err = pa_alsa_safe_delay(u->pcm_handle, status, &delay, u->hwbuf_size, &u->source->sample_spec, TRUE)) < 0)) {
         pa_log_warn("Failed to get delay: %s", pa_alsa_strerror(err));
         return;
     }
 
-    if (PA_UNLIKELY((err = snd_pcm_status(u->pcm_handle, status)) < 0))
-        pa_log_warn("Failed to get timestamp: %s", pa_alsa_strerror(err));
-    else {
-        snd_htimestamp_t htstamp = { 0, 0 };
-        snd_pcm_status_get_htstamp(status, &htstamp);
-        now1 = pa_timespec_load(&htstamp);
-    }
+    snd_pcm_status_get_htstamp(status, &htstamp);
+    now1 = pa_timespec_load(&htstamp);
 
     /* Hmm, if the timestamp is 0, then it wasn't set and we take the current time */
     if (now1 <= 0)
@@ -787,7 +863,7 @@ static void update_smoother(struct userdata *u) {
 }
 
 static pa_usec_t source_get_latency(struct userdata *u) {
-   int64_t delay;
+    int64_t delay;
     pa_usec_t now1, now2;
 
     pa_assert(u);
@@ -813,13 +889,24 @@ static int build_pollfd(struct userdata *u) {
     return 0;
 }
 
+/* Called from IO context */
 static int suspend(struct userdata *u) {
+#ifdef __TIZEN__
+    void *audio_data = pa_shared_get(u->core, "tizen-audio-data");
+    audio_interface_t *audio_intf = pa_shared_get(u->core, "tizen-audio-interface");
+#endif
+
     pa_assert(u);
     pa_assert(u->pcm_handle);
 
     pa_smoother_pause(u->smoother, pa_rtclock_now());
 
     /* Let's suspend */
+#ifdef __TIZEN__
+    if (audio_intf && audio_intf->alsa_pcm_close) {
+        audio_intf->alsa_pcm_close(audio_data, u->pcm_handle);
+    } else
+#endif
     snd_pcm_close(u->pcm_handle);
     u->pcm_handle = NULL;
 
@@ -828,18 +915,20 @@ static int suspend(struct userdata *u) {
         u->alsa_rtpoll_item = NULL;
     }
 
-    pa_log_info("Device suspended...");
+    /* FIXME : Need to adjust log level later */
+    pa_log_info("Device suspended...[%s]", u->device_name);
 
     return 0;
 }
 
+/* Called from IO context */
 static int update_sw_params(struct userdata *u) {
     snd_pcm_uframes_t avail_min;
     int err;
 
     pa_assert(u);
 
-    /* Use the full buffer if noone asked us for anything specific */
+    /* Use the full buffer if no one asked us for anything specific */
     u->hwbuf_unused = 0;
 
     if (u->use_tsched) {
@@ -877,25 +966,84 @@ static int update_sw_params(struct userdata *u) {
 
     pa_log_debug("setting avail_min=%lu", (unsigned long) avail_min);
 
+#ifdef __TIZEN__
+    if ((err = pa_alsa_set_sw_params(u->pcm_handle, avail_min, !u->use_tsched, u->start_threshold,u->source->sample_spec.rate)) < 0) {
+        pa_log("Failed to set software parameters: %s", pa_alsa_strerror(err));
+        return err;
+    }
+#else
     if ((err = pa_alsa_set_sw_params(u->pcm_handle, avail_min, !u->use_tsched)) < 0) {
         pa_log("Failed to set software parameters: %s", pa_alsa_strerror(err));
         return err;
     }
+#endif
 
     return 0;
 }
 
+/* Called from IO Context on unsuspend or from main thread when creating source */
+static void reset_watermark(struct userdata *u, size_t tsched_watermark, pa_sample_spec *ss,
+                            pa_bool_t in_thread)
+{
+    u->tsched_watermark = pa_usec_to_bytes_round_up(pa_bytes_to_usec_round_up(tsched_watermark, ss),
+                                                    &u->source->sample_spec);
+
+    u->watermark_inc_step = pa_usec_to_bytes(TSCHED_WATERMARK_INC_STEP_USEC, &u->source->sample_spec);
+    u->watermark_dec_step = pa_usec_to_bytes(TSCHED_WATERMARK_DEC_STEP_USEC, &u->source->sample_spec);
+
+    u->watermark_inc_threshold = pa_usec_to_bytes_round_up(TSCHED_WATERMARK_INC_THRESHOLD_USEC, &u->source->sample_spec);
+    u->watermark_dec_threshold = pa_usec_to_bytes_round_up(TSCHED_WATERMARK_DEC_THRESHOLD_USEC, &u->source->sample_spec);
+
+    fix_min_sleep_wakeup(u);
+    fix_tsched_watermark(u);
+
+    if (in_thread)
+        pa_source_set_latency_range_within_thread(u->source,
+                                                  u->min_latency_ref,
+                                                  pa_bytes_to_usec(u->hwbuf_size, ss));
+    else {
+        pa_source_set_latency_range(u->source,
+                                    0,
+                                    pa_bytes_to_usec(u->hwbuf_size, ss));
+
+        /* work-around assert in pa_source_set_latency_within_thead,
+           keep track of min_latency and reuse it when
+           this routine is called from IO context */
+        u->min_latency_ref = u->source->thread_info.min_latency;
+    }
+
+    pa_log_info("Time scheduling watermark is %0.2fms",
+                (double) pa_bytes_to_usec(u->tsched_watermark, ss) / PA_USEC_PER_MSEC);
+}
+
+/* Called from IO context */
 static int unsuspend(struct userdata *u) {
     pa_sample_spec ss;
     int err;
     pa_bool_t b, d;
     snd_pcm_uframes_t period_size, buffer_size;
+#ifdef __TIZEN__
+    void *audio_data = pa_shared_get(u->core, "tizen-audio-data");
+    audio_interface_t *audio_intf = pa_shared_get(u->core, "tizen-audio-interface");
+#endif
 
     pa_assert(u);
     pa_assert(!u->pcm_handle);
 
-    pa_log_info("Trying resume...");
+    /* FIXME : Need to adjust log level later */
+    pa_log_warn("Trying resume...[%s]", u->device_name);
 
+#ifdef __TIZEN__
+    if (audio_intf && audio_intf->alsa_pcm_open) {
+        audio_return_t audio_ret = AUDIO_RET_OK;
+
+        if (AUDIO_IS_ERROR((audio_ret = audio_intf->alsa_pcm_open(audio_data, (void **)&u->pcm_handle, u->device_name, AUDIO_DIRECTION_IN,
+            SND_PCM_NONBLOCK | SND_PCM_NO_AUTO_RESAMPLE | SND_PCM_NO_AUTO_CHANNELS | SND_PCM_NO_AUTO_FORMAT)))) {
+            pa_log("Error opening PCM device %s: %x", u->device_name, audio_ret);
+            goto fail;
+        }
+    } else
+#endif
     if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_CAPTURE,
                             SND_PCM_NONBLOCK|
                             SND_PCM_NO_AUTO_RESAMPLE|
@@ -941,20 +1089,32 @@ static int unsuspend(struct userdata *u) {
         goto fail;
 
     /* FIXME: We need to reload the volume somehow */
-
-    snd_pcm_start(u->pcm_handle);
-
+#ifdef TIZEN_DEBUG_ENABLE
+    u->log_count = 0;
+#endif
     u->read_count = 0;
     pa_smoother_reset(u->smoother, pa_rtclock_now(), TRUE);
     u->smoother_interval = SMOOTHER_MIN_INTERVAL;
     u->last_smoother_update = 0;
 
-    pa_log_info("Resumed successfully...");
+    u->first = TRUE;
+
+    /* reset the watermark to the value defined when source was created */
+    if (u->use_tsched)
+        reset_watermark(u, u->tsched_watermark_ref, &u->source->sample_spec, TRUE);
+
+    /* FIXME : Need to adjust log level later */
+    pa_log_info("Resumed successfully...[%s]", u->device_name);
 
     return 0;
 
 fail:
     if (u->pcm_handle) {
+#ifdef __TIZEN__
+        if (audio_intf && audio_intf->alsa_pcm_close) {
+            audio_intf->alsa_pcm_close(audio_data, u->pcm_handle);
+        } else
+#endif
         snd_pcm_close(u->pcm_handle);
         u->pcm_handle = NULL;
     }
@@ -962,6 +1122,7 @@ fail:
     return -PA_ERR_IO;
 }
 
+/* Called from IO context */
 static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
     struct userdata *u = PA_SOURCE(o)->userdata;
 
@@ -984,6 +1145,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
 
                 case PA_SOURCE_SUSPENDED: {
                     int r;
+
                     pa_assert(PA_SOURCE_IS_OPENED(u->source->thread_info.state));
 
                     if ((r = suspend(u)) < 0)
@@ -999,8 +1161,6 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
                     if (u->source->thread_info.state == PA_SOURCE_INIT) {
                         if (build_pollfd(u) < 0)
                             return -PA_ERR_IO;
-
-                        snd_pcm_start(u->pcm_handle);
                     }
 
                     if (u->source->thread_info.state == PA_SOURCE_SUSPENDED) {
@@ -1033,16 +1193,16 @@ static int source_set_state_cb(pa_source *s, pa_source_state_t new_state) {
 
     old_state = pa_source_get_state(u->source);
 
-    if (PA_SINK_IS_OPENED(old_state) && new_state == PA_SINK_SUSPENDED)
+    if (PA_SOURCE_IS_OPENED(old_state) && new_state == PA_SOURCE_SUSPENDED)
         reserve_done(u);
-    else if (old_state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(new_state))
+    else if (old_state == PA_SOURCE_SUSPENDED && PA_SOURCE_IS_OPENED(new_state))
         if (reserve_init(u, u->device_name) < 0)
             return -PA_ERR_BUSY;
 
     return 0;
 }
 
-static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
+static int ctl_mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
     struct userdata *u = snd_mixer_elem_get_callback_private(elem);
 
     pa_assert(u);
@@ -1051,6 +1211,14 @@ static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
     if (mask == SND_CTL_EVENT_MASK_REMOVE)
         return 0;
 
+    if (!PA_SOURCE_IS_LINKED(u->source->state))
+        return 0;
+
+    if (u->source->suspend_cause & PA_SUSPEND_SESSION) {
+        pa_source_set_mixer_dirty(u->source, TRUE);
+        return 0;
+    }
+
     if (mask & SND_CTL_EVENT_MASK_VALUE) {
         pa_source_get_volume(u->source, TRUE);
         pa_source_get_mute(u->source, TRUE);
@@ -1059,10 +1227,30 @@ static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
     return 0;
 }
 
+static int io_mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
+    struct userdata *u = snd_mixer_elem_get_callback_private(elem);
+
+    pa_assert(u);
+    pa_assert(u->mixer_handle);
+
+    if (mask == SND_CTL_EVENT_MASK_REMOVE)
+        return 0;
+
+    if (u->source->suspend_cause & PA_SUSPEND_SESSION) {
+        pa_source_set_mixer_dirty(u->source, TRUE);
+        return 0;
+    }
+
+    if (mask & SND_CTL_EVENT_MASK_VALUE)
+        pa_source_update_volume_and_mute(u->source);
+
+    return 0;
+}
+
 static void source_get_volume_cb(pa_source *s) {
     struct userdata *u = s->userdata;
     pa_cvolume r;
-    char t[PA_CVOLUME_SNPRINT_MAX];
+    char vol_str_pcnt[PA_CVOLUME_SNPRINT_MAX];
 
     pa_assert(u);
     pa_assert(u->mixer_path);
@@ -1074,12 +1262,18 @@ static void source_get_volume_cb(pa_source *s) {
     /* Shift down by the base volume, so that 0dB becomes maximum volume */
     pa_sw_cvolume_multiply_scalar(&r, &r, s->base_volume);
 
-    pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
+    pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(vol_str_pcnt, sizeof(vol_str_pcnt), &r));
+
+    if (u->mixer_path->has_dB) {
+        char vol_str_db[PA_SW_CVOLUME_SNPRINT_DB_MAX];
+
+        pa_log_debug("               in dB: %s", pa_sw_cvolume_snprint_dB(vol_str_db, sizeof(vol_str_db), &r));
+    }
 
     if (pa_cvolume_equal(&u->hardware_volume, &r))
         return;
 
-    s->volume = u->hardware_volume = r;
+    s->real_volume = u->hardware_volume = r;
 
     /* Hmm, so the hardware volume changed, let's reset our software volume */
     if (u->mixer_path->has_dB)
@@ -1089,16 +1283,17 @@ static void source_get_volume_cb(pa_source *s) {
 static void source_set_volume_cb(pa_source *s) {
     struct userdata *u = s->userdata;
     pa_cvolume r;
-    char t[PA_CVOLUME_SNPRINT_MAX];
+    char vol_str_pcnt[PA_CVOLUME_SNPRINT_MAX];
+    pa_bool_t deferred_volume = !!(s->flags & PA_SOURCE_DEFERRED_VOLUME);
 
     pa_assert(u);
     pa_assert(u->mixer_path);
     pa_assert(u->mixer_handle);
 
     /* Shift up by the base volume */
-    pa_sw_cvolume_divide_scalar(&r, &s->volume, s->base_volume);
+    pa_sw_cvolume_divide_scalar(&r, &s->real_volume, s->base_volume);
 
-    if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r) < 0)
+    if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &r, deferred_volume, !deferred_volume) < 0)
         return;
 
     /* Shift down by the base volume, so that 0dB becomes maximum volume */
@@ -1109,9 +1304,10 @@ static void source_set_volume_cb(pa_source *s) {
     if (u->mixer_path->has_dB) {
         pa_cvolume new_soft_volume;
         pa_bool_t accurate_enough;
+        char vol_str_db[PA_SW_CVOLUME_SNPRINT_DB_MAX];
 
         /* Match exactly what the user requested by software */
-        pa_sw_cvolume_divide(&new_soft_volume, &s->volume, &u->hardware_volume);
+        pa_sw_cvolume_divide(&new_soft_volume, &s->real_volume, &u->hardware_volume);
 
         /* If the adjustment to do in software is only minimal we
          * can skip it. That saves us CPU at the expense of a bit of
@@ -1120,21 +1316,67 @@ static void source_set_volume_cb(pa_source *s) {
             (pa_cvolume_min(&new_soft_volume) >= (PA_VOLUME_NORM - VOLUME_ACCURACY)) &&
             (pa_cvolume_max(&new_soft_volume) <= (PA_VOLUME_NORM + VOLUME_ACCURACY));
 
-        pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->volume));
-        pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &u->hardware_volume));
-        pa_log_debug("Calculated software volume: %s (accurate-enough=%s)", pa_cvolume_snprint(t, sizeof(t), &new_soft_volume),
+        pa_log_debug("Requested volume: %s", pa_cvolume_snprint(vol_str_pcnt, sizeof(vol_str_pcnt), &s->real_volume));
+        pa_log_debug("           in dB: %s", pa_sw_cvolume_snprint_dB(vol_str_db, sizeof(vol_str_db), &s->real_volume));
+        pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(vol_str_pcnt, sizeof(vol_str_pcnt), &u->hardware_volume));
+        pa_log_debug("              in dB: %s", pa_sw_cvolume_snprint_dB(vol_str_db, sizeof(vol_str_db), &u->hardware_volume));
+        pa_log_debug("Calculated software volume: %s (accurate-enough=%s)",
+                     pa_cvolume_snprint(vol_str_pcnt, sizeof(vol_str_pcnt), &new_soft_volume),
                      pa_yes_no(accurate_enough));
+        pa_log_debug("                     in dB: %s", pa_sw_cvolume_snprint_dB(vol_str_db, sizeof(vol_str_db), &new_soft_volume));
 
         if (!accurate_enough)
             s->soft_volume = new_soft_volume;
 
     } else {
-        pa_log_debug("Wrote hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
+        pa_log_debug("Wrote hardware volume: %s", pa_cvolume_snprint(vol_str_pcnt, sizeof(vol_str_pcnt), &r));
 
         /* We can't match exactly what the user requested, hence let's
          * at least tell the user about it */
 
-        s->volume = r;
+        s->real_volume = r;
+    }
+}
+
+static void source_write_volume_cb(pa_source *s) {
+    struct userdata *u = s->userdata;
+    pa_cvolume hw_vol = s->thread_info.current_hw_volume;
+
+    pa_assert(u);
+    pa_assert(u->mixer_path);
+    pa_assert(u->mixer_handle);
+    pa_assert(s->flags & PA_SOURCE_DEFERRED_VOLUME);
+
+    /* Shift up by the base volume */
+    pa_sw_cvolume_divide_scalar(&hw_vol, &hw_vol, s->base_volume);
+
+    if (pa_alsa_path_set_volume(u->mixer_path, u->mixer_handle, &s->channel_map, &hw_vol, TRUE, TRUE) < 0)
+        pa_log_error("Writing HW volume failed");
+    else {
+        pa_cvolume tmp_vol;
+        pa_bool_t accurate_enough;
+
+        /* Shift down by the base volume, so that 0dB becomes maximum volume */
+        pa_sw_cvolume_multiply_scalar(&hw_vol, &hw_vol, s->base_volume);
+
+        pa_sw_cvolume_divide(&tmp_vol, &hw_vol, &s->thread_info.current_hw_volume);
+        accurate_enough =
+            (pa_cvolume_min(&tmp_vol) >= (PA_VOLUME_NORM - VOLUME_ACCURACY)) &&
+            (pa_cvolume_max(&tmp_vol) <= (PA_VOLUME_NORM + VOLUME_ACCURACY));
+
+        if (!accurate_enough) {
+            union {
+                char db[2][PA_SW_CVOLUME_SNPRINT_DB_MAX];
+                char pcnt[2][PA_CVOLUME_SNPRINT_MAX];
+            } vol;
+
+            pa_log_debug("Written HW volume did not match with the request: %s (request) != %s",
+                         pa_cvolume_snprint(vol.pcnt[0], sizeof(vol.pcnt[0]), &s->thread_info.current_hw_volume),
+                         pa_cvolume_snprint(vol.pcnt[1], sizeof(vol.pcnt[1]), &hw_vol));
+            pa_log_debug("                                           in dB: %s (request) != %s",
+                         pa_sw_cvolume_snprint_dB(vol.db[0], sizeof(vol.db[0]), &s->thread_info.current_hw_volume),
+                         pa_sw_cvolume_snprint_dB(vol.db[1], sizeof(vol.db[1]), &hw_vol));
+        }
     }
 }
 
@@ -1162,6 +1404,65 @@ static void source_set_mute_cb(pa_source *s) {
     pa_alsa_path_set_mute(u->mixer_path, u->mixer_handle, s->muted);
 }
 
+static void mixer_volume_init(struct userdata *u) {
+    pa_assert(u);
+
+    if (!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);
+
+        pa_log_info("Driver does not support hardware volume control, falling back to software volume control.");
+    } else {
+        pa_source_set_get_volume_callback(u->source, source_get_volume_cb);
+        pa_source_set_set_volume_callback(u->source, source_set_volume_cb);
+
+        if (u->mixer_path->has_dB && u->deferred_volume) {
+            pa_source_set_write_volume_callback(u->source, source_write_volume_cb);
+            pa_log_info("Successfully enabled deferred volume.");
+        } else
+            pa_source_set_write_volume_callback(u->source, NULL);
+
+        if (u->mixer_path->has_dB) {
+            pa_source_enable_decibel_volume(u->source, TRUE);
+            pa_log_info("Hardware volume ranges from %0.2f dB to %0.2f dB.", u->mixer_path->min_dB, u->mixer_path->max_dB);
+
+            u->source->base_volume = pa_sw_volume_from_dB(-u->mixer_path->max_dB);
+            u->source->n_volume_steps = PA_VOLUME_NORM+1;
+
+            pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(u->source->base_volume));
+        } else {
+            pa_source_enable_decibel_volume(u->source, FALSE);
+            pa_log_info("Hardware volume ranges from %li to %li.", u->mixer_path->min_volume, u->mixer_path->max_volume);
+
+            u->source->base_volume = PA_VOLUME_NORM;
+            u->source->n_volume_steps = u->mixer_path->max_volume - u->mixer_path->min_volume + 1;
+        }
+
+        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) {
+        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.");
+    } else {
+        pa_source_set_get_mute_callback(u->source, source_get_mute_cb);
+        pa_source_set_set_mute_callback(u->source, source_set_mute_cb);
+        pa_log_info("Using hardware mute control.");
+    }
+}
+
+static int source_set_port_ucm_cb(pa_source *s, pa_device_port *p) {
+    struct userdata *u = s->userdata;
+
+    pa_assert(u);
+    pa_assert(p);
+    pa_assert(u->ucm_context);
+
+    return pa_alsa_ucm_set_port(u->ucm_context, p, FALSE);
+}
+
 static int source_set_port_cb(pa_source *s, pa_device_port *p) {
     struct userdata *u = s->userdata;
     pa_alsa_port_data *data;
@@ -1173,28 +1474,19 @@ static int source_set_port_cb(pa_source *s, pa_device_port *p) {
     data = PA_DEVICE_PORT_DATA(p);
 
     pa_assert_se(u->mixer_path = data->path);
-    pa_alsa_path_select(u->mixer_path, u->mixer_handle);
-
-    if (u->mixer_path->has_volume && u->mixer_path->has_dB) {
-        s->base_volume = pa_sw_volume_from_dB(-u->mixer_path->max_dB);
-        s->n_volume_steps = PA_VOLUME_NORM+1;
-
-        if (u->mixer_path->max_dB > 0.0)
-            pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(s->base_volume));
-        else
-            pa_log_info("No particular base volume set, fixing to 0 dB");
-    } else {
-        s->base_volume = PA_VOLUME_NORM;
-        s->n_volume_steps = u->mixer_path->max_volume - u->mixer_path->min_volume + 1;
-    }
+    pa_alsa_path_select(u->mixer_path, data->setting, u->mixer_handle, s->muted);
 
-    if (data->setting)
-        pa_alsa_setting_select(data->setting, u->mixer_handle);
+    mixer_volume_init(u);
 
     if (s->set_mute)
         s->set_mute(s);
-    if (s->set_volume)
-        s->set_volume(s);
+    if (s->flags & PA_SOURCE_DEFERRED_VOLUME) {
+        if (s->write_volume)
+            s->write_volume(s);
+    } else {
+        if (s->set_volume)
+            s->set_volume(s);
+    }
 
     return 0;
 }
@@ -1202,6 +1494,9 @@ static int source_set_port_cb(pa_source *s, pa_device_port *p) {
 static void source_update_requested_latency_cb(pa_source *s) {
     struct userdata *u = s->userdata;
     pa_assert(u);
+    pa_assert(u->use_tsched); /* only when timer scheduling is used
+                               * we can dynamically adjust the
+                               * latency */
 
     if (!u->pcm_handle)
         return;
@@ -1209,6 +1504,35 @@ static void source_update_requested_latency_cb(pa_source *s) {
     update_sw_params(u);
 }
 
+static pa_bool_t source_update_rate_cb(pa_source *s, uint32_t rate)
+{
+    struct userdata *u = s->userdata;
+    int i;
+    pa_bool_t supported = FALSE;
+
+    pa_assert(u);
+
+    for (i = 0; u->rates[i]; i++) {
+        if (u->rates[i] == rate) {
+            supported = TRUE;
+            break;
+        }
+    }
+
+    if (!supported) {
+        pa_log_info("Source does not support sample rate of %d Hz", rate);
+        return FALSE;
+    }
+
+    if (!PA_SOURCE_IS_OPENED(s->state)) {
+        pa_log_info("Updating rate for device %s, new rate is %d", u->device_name, rate);
+        u->source->sample_spec.rate = rate;
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
 static void thread_func(void *userdata) {
     struct userdata *u = userdata;
     unsigned short revents = 0;
@@ -1224,6 +1548,7 @@ static void thread_func(void *userdata) {
 
     for (;;) {
         int ret;
+        pa_usec_t rtpoll_sleep = 0, real_sleep;
 
 #ifdef DEBUG_TIMING
         pa_log_debug("Loop");
@@ -1235,6 +1560,18 @@ static void thread_func(void *userdata) {
             pa_usec_t sleep_usec = 0;
             pa_bool_t on_timeout = pa_rtpoll_timer_elapsed(u->rtpoll);
 
+            if (u->first) {
+                pa_log_info("Starting capture.");
+#ifdef __TIZEN__
+                if (SND_PCM_STATE_PREPARED == snd_pcm_state(u->pcm_handle))
+#endif
+                    snd_pcm_start(u->pcm_handle);
+
+                pa_smoother_resume(u->smoother, pa_rtclock_now(), TRUE);
+
+                u->first = FALSE;
+            }
+
             if (u->use_mmap)
                 work_done = mmap_read(u, &sleep_usec, revents & POLLIN, on_timeout);
             else
@@ -1263,17 +1600,47 @@ static void thread_func(void *userdata) {
 /*                 pa_log_debug("Waking up in %0.2fms (system clock).", (double) cusec / PA_USEC_PER_MSEC); */
 
                 /* We don't trust the conversion, so we wake up whatever comes first */
-                pa_rtpoll_set_timer_relative(u->rtpoll, PA_MIN(sleep_usec, cusec));
+                rtpoll_sleep = PA_MIN(sleep_usec, cusec);
+            }
+        }
+
+        if (u->source->flags & PA_SOURCE_DEFERRED_VOLUME) {
+            pa_usec_t volume_sleep;
+            pa_source_volume_change_apply(u->source, &volume_sleep);
+            if (volume_sleep > 0) {
+                if (rtpoll_sleep > 0)
+                    rtpoll_sleep = PA_MIN(volume_sleep, rtpoll_sleep);
+                else
+                    rtpoll_sleep = volume_sleep;
             }
-        } else if (u->use_tsched)
+        }
 
-            /* OK, we're in an invalid state, let's disable our timers */
+        if (rtpoll_sleep > 0) {
+            pa_rtpoll_set_timer_relative(u->rtpoll, rtpoll_sleep);
+            real_sleep = pa_rtclock_now();
+        }
+        else
             pa_rtpoll_set_timer_disabled(u->rtpoll);
 
         /* Hmm, nothing to do. Let's sleep */
         if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
             goto fail;
 
+        if (rtpoll_sleep > 0) {
+            real_sleep = pa_rtclock_now() - real_sleep;
+#ifdef DEBUG_TIMING
+            pa_log_debug("Expected sleep: %0.2fms, real sleep: %0.2fms (diff %0.2f ms)",
+                (double) rtpoll_sleep / PA_USEC_PER_MSEC, (double) real_sleep / PA_USEC_PER_MSEC,
+                (double) ((int64_t) real_sleep - (int64_t) rtpoll_sleep) / PA_USEC_PER_MSEC);
+#endif
+            if (u->use_tsched && real_sleep > rtpoll_sleep + u->tsched_watermark)
+                pa_log_info("Scheduling delay of %0.2fms, you might want to investigate this to improve latency...",
+                    (double) (real_sleep - rtpoll_sleep) / PA_USEC_PER_MSEC);
+        }
+
+        if (u->source->flags & PA_SOURCE_DEFERRED_VOLUME)
+            pa_source_volume_change_apply(u->source, NULL);
+
         if (ret == 0)
             goto finish;
 
@@ -1294,8 +1661,9 @@ static void thread_func(void *userdata) {
                 if (pa_alsa_recover_from_poll(u->pcm_handle, revents) < 0)
                     goto fail;
 
-                snd_pcm_start(u->pcm_handle);
-            } else if (revents && u->use_tsched && pa_log_ratelimit())
+                u->first = TRUE;
+                revents = 0;
+            } else if (revents && u->use_tsched && pa_log_ratelimit(PA_LOG_DEBUG))
                 pa_log_debug("Wakeup from ALSA!");
 
         } else
@@ -1343,11 +1711,12 @@ 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, pa_bool_t ignore_dB) {
+    snd_hctl_t *hctl;
 
     if (!mapping && !element)
         return;
 
-    if (!(u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device))) {
+    if (!(u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device, &hctl))) {
         pa_log_info("Failed to find a working mixer device.");
         return;
     }
@@ -1357,30 +1726,19 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char
         if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_INPUT)))
             goto fail;
 
-        if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, ignore_dB) < 0)
+        if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, hctl, ignore_dB) < 0)
             goto fail;
 
         pa_log_debug("Probed mixer path %s:", u->mixer_path->name);
         pa_alsa_path_dump(u->mixer_path);
-    } else {
-
-        if (!(u->mixer_path_set = pa_alsa_path_set_new(mapping, PA_ALSA_DIRECTION_INPUT)))
-            goto fail;
-
-        pa_alsa_path_set_probe(u->mixer_path_set, u->mixer_handle, ignore_dB);
-
-        pa_log_debug("Probed mixer paths:");
-        pa_alsa_path_set_dump(u->mixer_path_set);
-    }
+    } else if (!(u->mixer_path_set = mapping->input_path_set))
+        goto fail;
 
     return;
 
 fail:
 
-    if (u->mixer_path_set) {
-        pa_alsa_path_set_free(u->mixer_path_set);
-        u->mixer_path_set = NULL;
-    } else if (u->mixer_path) {
+    if (u->mixer_path) {
         pa_alsa_path_free(u->mixer_path);
         u->mixer_path = NULL;
     }
@@ -1392,6 +1750,8 @@ fail:
 }
 
 static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
+    pa_bool_t need_mixer_callback = FALSE;
+
     pa_assert(u);
 
     if (!u->mixer_handle)
@@ -1406,75 +1766,61 @@ static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
         data = PA_DEVICE_PORT_DATA(u->source->active_port);
         u->mixer_path = data->path;
 
-        pa_alsa_path_select(data->path, u->mixer_handle);
-
-        if (data->setting)
-            pa_alsa_setting_select(data->setting, u->mixer_handle);
+        pa_alsa_path_select(data->path, data->setting, u->mixer_handle, u->source->muted);
 
     } else {
 
         if (!u->mixer_path && u->mixer_path_set)
-            u->mixer_path = u->mixer_path_set->paths;
+            u->mixer_path = pa_hashmap_first(u->mixer_path_set->paths);
 
         if (u->mixer_path) {
             /* Hmm, we have only a single path, then let's activate it */
 
-            pa_alsa_path_select(u->mixer_path, u->mixer_handle);
-
-            if (u->mixer_path->settings)
-                pa_alsa_setting_select(u->mixer_path->settings, u->mixer_handle);
+            pa_alsa_path_select(u->mixer_path, u->mixer_path->settings, u->mixer_handle, u->source->muted);
         } else
             return 0;
     }
 
-    if (!u->mixer_path->has_volume)
-        pa_log_info("Driver does not support hardware volume control, falling back to software volume control.");
-    else {
-
-        if (u->mixer_path->has_dB) {
-            pa_log_info("Hardware volume ranges from %0.2f dB to %0.2f dB.", u->mixer_path->min_dB, u->mixer_path->max_dB);
+    mixer_volume_init(u);
 
-            u->source->base_volume = pa_sw_volume_from_dB(-u->mixer_path->max_dB);
-            u->source->n_volume_steps = PA_VOLUME_NORM+1;
+    /* Will we need to register callbacks? */
+    if (u->mixer_path_set && u->mixer_path_set->paths) {
+        pa_alsa_path *p;
+        void *state;
 
-            if (u->mixer_path->max_dB > 0.0)
-                pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(u->source->base_volume));
-            else
-                pa_log_info("No particular base volume set, fixing to 0 dB");
-
-        } else {
-            pa_log_info("Hardware volume ranges from %li to %li.", u->mixer_path->min_volume, u->mixer_path->max_volume);
-            u->source->base_volume = PA_VOLUME_NORM;
-            u->source->n_volume_steps = u->mixer_path->max_volume - u->mixer_path->min_volume + 1;
+        PA_HASHMAP_FOREACH(p, u->mixer_path_set->paths, state) {
+            if (p->has_volume || p->has_mute)
+                need_mixer_callback = TRUE;
         }
-
-        u->source->get_volume = source_get_volume_cb;
-        u->source->set_volume = source_set_volume_cb;
-
-        u->source->flags |= PA_SOURCE_HW_VOLUME_CTRL | (u->mixer_path->has_dB ? PA_SOURCE_DECIBEL_VOLUME : 0);
-        pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->mixer_path->has_dB ? "supported" : "not supported");
     }
+    else if (u->mixer_path)
+        need_mixer_callback = u->mixer_path->has_volume || u->mixer_path->has_mute;
 
-    if (!u->mixer_path->has_mute) {
-        pa_log_info("Driver does not support hardware mute control, falling back to software mute control.");
-    } else {
-        u->source->get_mute = source_get_mute_cb;
-        u->source->set_mute = source_set_mute_cb;
-        u->source->flags |= PA_SOURCE_HW_MUTE_CTRL;
-        pa_log_info("Using hardware mute control.");
-    }
+    if (need_mixer_callback) {
+        int (*mixer_callback)(snd_mixer_elem_t *, unsigned int);
+        if (u->source->flags & PA_SOURCE_DEFERRED_VOLUME) {
+            u->mixer_pd = pa_alsa_mixer_pdata_new();
+            mixer_callback = io_mixer_callback;
 
-    u->mixer_fdl = pa_alsa_fdlist_new();
+            if (pa_alsa_set_mixer_rtpoll(u->mixer_pd, u->mixer_handle, u->rtpoll) < 0) {
+                pa_log("Failed to initialize file descriptor monitoring");
+                return -1;
+            }
+        } else {
+            u->mixer_fdl = pa_alsa_fdlist_new();
+            mixer_callback = ctl_mixer_callback;
 
-    if (pa_alsa_fdlist_set_mixer(u->mixer_fdl, u->mixer_handle, u->core->mainloop) < 0) {
-        pa_log("Failed to initialize file descriptor monitoring");
-        return -1;
-    }
+            if (pa_alsa_fdlist_set_handle(u->mixer_fdl, u->mixer_handle, NULL, u->core->mainloop) < 0) {
+                pa_log("Failed to initialize file descriptor monitoring");
+                return -1;
+            }
+        }
 
-    if (u->mixer_path_set)
-        pa_alsa_path_set_set_callback(u->mixer_path_set, u->mixer_handle, mixer_callback, u);
-    else
-        pa_alsa_path_set_callback(u->mixer_path, u->mixer_handle, mixer_callback, u);
+        if (u->mixer_path_set)
+            pa_alsa_path_set_set_callback(u->mixer_path_set, u->mixer_handle, mixer_callback, u);
+        else
+            pa_alsa_path_set_callback(u->mixer_path, u->mixer_handle, mixer_callback, u);
+    }
 
     return 0;
 }
@@ -1482,15 +1828,21 @@ static int setup_mixer(struct userdata *u, pa_bool_t ignore_dB) {
 pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, pa_card *card, pa_alsa_mapping *mapping) {
 
     struct userdata *u = NULL;
-    const char *dev_id = NULL;
-    pa_sample_spec ss, requested_ss;
+    const char *dev_id = NULL, *key, *mod_name;
+    pa_sample_spec ss;
+    char *thread_name = NULL;
+    uint32_t alternate_sample_rate;
     pa_channel_map map;
     uint32_t nfrags, frag_size, buffer_size, tsched_size, tsched_watermark;
     snd_pcm_uframes_t period_frames, buffer_frames, tsched_frames;
     size_t frame_size;
-    pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, ignore_dB = FALSE;
+    pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, ignore_dB = FALSE, namereg_fail = FALSE, deferred_volume = FALSE, fixed_latency_range = FALSE;
     pa_source_new_data data;
     pa_alsa_profile_set *profile_set = NULL;
+    void *state = NULL;
+#ifdef __TIZEN__
+    int start_threshold;
+#endif
 
     pa_assert(m);
     pa_assert(ma);
@@ -1498,11 +1850,16 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
     ss = m->core->default_sample_spec;
     map = m->core->default_channel_map;
     if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_ALSA) < 0) {
-        pa_log("Failed to parse sample specification");
+        pa_log("Failed to parse sample specification and channel map");
+        goto fail;
+    }
+
+    alternate_sample_rate = m->core->alternate_sample_rate;
+    if (pa_modargs_get_alternate_sample_rate(ma, &alternate_sample_rate) < 0) {
+        pa_log("Failed to parse alternate sample rate");
         goto fail;
     }
 
-    requested_ss = ss;
     frame_size = pa_frame_size(&ss);
 
     nfrags = m->core->default_n_fragments;
@@ -1526,13 +1883,20 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
     buffer_frames = buffer_size/frame_size;
     tsched_frames = tsched_size/frame_size;
 
+#ifdef __TIZEN__
+    if(pa_modargs_get_value_s32(ma, "start_threshold", &start_threshold) < 0){
+       pa_log("Failed to parse start_threshold argument.");
+       goto fail;
+    }
+#endif
+
     if (pa_modargs_get_value_boolean(ma, "mmap", &use_mmap) < 0) {
         pa_log("Failed to parse mmap argument.");
         goto fail;
     }
 
     if (pa_modargs_get_value_boolean(ma, "tsched", &use_tsched) < 0) {
-        pa_log("Failed to parse timer_scheduling argument.");
+        pa_log("Failed to parse tsched argument.");
         goto fail;
     }
 
@@ -1541,6 +1905,17 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
         goto fail;
     }
 
+    deferred_volume = m->core->deferred_volume;
+    if (pa_modargs_get_value_boolean(ma, "deferred_volume", &deferred_volume) < 0) {
+        pa_log("Failed to parse deferred_volume argument.");
+        goto fail;
+    }
+
+    if (pa_modargs_get_value_boolean(ma, "fixed_latency_range", &fixed_latency_range) < 0) {
+        pa_log("Failed to parse fixed_latency_range argument.");
+        goto fail;
+    }
+
     use_tsched = pa_alsa_may_tsched(use_tsched);
 
     u = pa_xnew0(struct userdata, 1);
@@ -1548,23 +1923,32 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
     u->module = m;
     u->use_mmap = use_mmap;
     u->use_tsched = use_tsched;
+    u->deferred_volume = deferred_volume;
+    u->fixed_latency_range = fixed_latency_range;
+    u->first = TRUE;
     u->rtpoll = pa_rtpoll_new();
     pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
 
     u->smoother = pa_smoother_new(
-            DEFAULT_TSCHED_WATERMARK_USEC*2,
-            DEFAULT_TSCHED_WATERMARK_USEC*2,
+            SMOOTHER_ADJUST_USEC,
+            SMOOTHER_WINDOW_USEC,
             TRUE,
             TRUE,
             5,
             pa_rtclock_now(),
-            FALSE);
+            TRUE);
     u->smoother_interval = SMOOTHER_MIN_INTERVAL;
 
+    /* use ucm */
+    if (mapping && mapping->ucm_context.ucm)
+        u->ucm_context = &mapping->ucm_context;
+
     dev_id = pa_modargs_get_value(
             ma, "device_id",
             pa_modargs_get_value(ma, "device", DEFAULT_DEVICE));
 
+    u->paths_dir = pa_xstrdup(pa_modargs_get_value(ma, "paths_dir", NULL));
+
     if (reserve_init(u, dev_id) < 0)
         goto fail;
 
@@ -1581,7 +1965,17 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
             goto fail;
         }
 
+        if ((mod_name = pa_proplist_gets(mapping->proplist, PA_ALSA_PROP_UCM_MODIFIER))) {
+            if (snd_use_case_set(u->ucm_context->ucm->ucm_mgr, "_enamod", mod_name) < 0)
+                pa_log("Failed to enable ucm modifier %s", mod_name);
+            else
+                pa_log_debug("Enabled ucm modifier %s", mod_name);
+        }
+
         if (!(u->pcm_handle = pa_alsa_open_by_device_id_mapping(
+#ifdef __TIZEN__
+                      u->core,
+#endif
                       dev_id,
                       &u->device_name,
                       &ss, &map,
@@ -1596,6 +1990,9 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
             goto fail;
 
         if (!(u->pcm_handle = pa_alsa_open_by_device_id_auto(
+#ifdef __TIZEN__
+                      u->core,
+#endif
                       dev_id,
                       &u->device_name,
                       &ss, &map,
@@ -1607,6 +2004,9 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
     } else {
 
         if (!(u->pcm_handle = pa_alsa_open_by_device_string(
+#ifdef __TIZEN__
+                      u->core,
+#endif
                       pa_modargs_get_value(ma, "device", DEFAULT_DEVICE),
                       &u->device_name,
                       &ss, &map,
@@ -1640,21 +2040,45 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
     if (u->use_mmap)
         pa_log_info("Successfully enabled mmap() mode.");
 
-    if (u->use_tsched)
+    if (u->use_tsched) {
         pa_log_info("Successfully enabled timer-based scheduling mode.");
+        if (u->fixed_latency_range)
+            pa_log_info("Disabling latency range changes on overrun");
+    }
+
+    u->rates = pa_alsa_get_supported_rates(u->pcm_handle, ss.rate);
+    if (!u->rates) {
+        pa_log_error("Failed to find any supported sample rates.");
+        goto fail;
+    }
 
     /* ALSA might tweak the sample spec, so recalculate the frame size */
     frame_size = pa_frame_size(&ss);
 
-    find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB);
+    if (!u->ucm_context)
+        find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB);
 
     pa_source_new_data_init(&data);
     data.driver = driver;
     data.module = m;
     data.card = card;
     set_source_name(&data, ma, dev_id, u->device_name, mapping);
+
+    /* We need to give pa_modargs_get_value_boolean() a pointer to a local
+     * variable instead of using &data.namereg_fail directly, because
+     * data.namereg_fail is a bitfield and taking the address of a bitfield
+     * variable is impossible. */
+    namereg_fail = data.namereg_fail;
+    if (pa_modargs_get_value_boolean(ma, "namereg_fail", &namereg_fail) < 0) {
+        pa_log("Failed to parse namereg_fail argument.");
+        pa_source_new_data_done(&data);
+        goto fail;
+    }
+    data.namereg_fail = namereg_fail;
+
     pa_source_new_data_set_sample_spec(&data, &ss);
     pa_source_new_data_set_channel_map(&data, &map);
+    pa_source_new_data_set_alternate_sample_rate(&data, alternate_sample_rate);
 
     pa_alsa_init_proplist_pcm(m->core, data.proplist, u->pcm_handle);
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device_name);
@@ -1665,6 +2089,9 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
     if (mapping) {
         pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_NAME, mapping->name);
         pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, mapping->description);
+
+        while ((key = pa_proplist_iterate(mapping->proplist, &state)))
+            pa_proplist_sets(data.proplist, key, pa_proplist_gets(mapping->proplist, key));
     }
 
     pa_alsa_init_description(data.proplist);
@@ -1678,8 +2105,10 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
         goto fail;
     }
 
-    if (u->mixer_path_set)
-        pa_alsa_add_ports(&data.ports, u->mixer_path_set);
+    if (u->ucm_context)
+        pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, FALSE, card);
+    else if (u->mixer_path_set)
+        pa_alsa_add_ports(&data, u->mixer_path_set, card);
 
     u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY|(u->use_tsched ? PA_SOURCE_DYNAMIC_LATENCY : 0));
     pa_source_new_data_done(&data);
@@ -1689,10 +2118,28 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
         goto fail;
     }
 
+    if (pa_modargs_get_value_u32(ma, "deferred_volume_safety_margin",
+                                 &u->source->thread_info.volume_change_safety_margin) < 0) {
+        pa_log("Failed to parse deferred_volume_safety_margin parameter");
+        goto fail;
+    }
+
+    if (pa_modargs_get_value_s32(ma, "deferred_volume_extra_delay",
+                                 &u->source->thread_info.volume_change_extra_delay) < 0) {
+        pa_log("Failed to parse deferred_volume_extra_delay parameter");
+        goto fail;
+    }
+
     u->source->parent.process_msg = source_process_msg;
-    u->source->update_requested_latency = source_update_requested_latency_cb;
+    if (u->use_tsched)
+        u->source->update_requested_latency = source_update_requested_latency_cb;
     u->source->set_state = source_set_state_cb;
-    u->source->set_port = source_set_port_cb;
+    if (u->ucm_context)
+        u->source->set_port = source_set_port_ucm_cb;
+    else
+        u->source->set_port = source_set_port_cb;
+    if (u->source->alternate_sample_rate)
+        u->source->update_rate = source_update_rate_cb;
     u->source->userdata = u;
 
     pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
@@ -1711,40 +2158,38 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
                 (double) pa_bytes_to_usec(u->hwbuf_size, &ss) / PA_USEC_PER_MSEC);
 
     if (u->use_tsched) {
-        u->tsched_watermark = pa_usec_to_bytes_round_up(pa_bytes_to_usec_round_up(tsched_watermark, &requested_ss), &u->source->sample_spec);
-
-        u->watermark_inc_step = pa_usec_to_bytes(TSCHED_WATERMARK_INC_STEP_USEC, &u->source->sample_spec);
-        u->watermark_dec_step = pa_usec_to_bytes(TSCHED_WATERMARK_DEC_STEP_USEC, &u->source->sample_spec);
-
-        u->watermark_inc_threshold = pa_usec_to_bytes_round_up(TSCHED_WATERMARK_INC_THRESHOLD_USEC, &u->source->sample_spec);
-        u->watermark_dec_threshold = pa_usec_to_bytes_round_up(TSCHED_WATERMARK_DEC_THRESHOLD_USEC, &u->source->sample_spec);
-
-        fix_min_sleep_wakeup(u);
-        fix_tsched_watermark(u);
-
-        pa_source_set_latency_range(u->source,
-                                    0,
-                                    pa_bytes_to_usec(u->hwbuf_size, &ss));
-
-        pa_log_info("Time scheduling watermark is %0.2fms",
-                    (double) pa_bytes_to_usec(u->tsched_watermark, &ss) / PA_USEC_PER_MSEC);
-    } else
+        u->tsched_watermark_ref = tsched_watermark;
+        reset_watermark(u, u->tsched_watermark_ref, &ss, FALSE);
+    }
+    else
         pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->hwbuf_size, &ss));
 
     reserve_update(u);
 
+#ifdef __TIZEN__
+    /*Set start Threshold*/
+    u->start_threshold = start_threshold;
+#endif
+
     if (update_sw_params(u) < 0)
         goto fail;
 
-    if (setup_mixer(u, ignore_dB) < 0)
+    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)
         goto fail;
 
     pa_alsa_dump(PA_LOG_DEBUG, u->pcm_handle);
 
-    if (!(u->thread = pa_thread_new(thread_func, u))) {
+    thread_name = pa_sprintf_malloc("alsa-source-%s", pa_strnull(pa_proplist_gets(u->source->proplist, "alsa.id")));
+    if (!(u->thread = pa_thread_new(thread_name, thread_func, u))) {
         pa_log("Failed to create thread.");
         goto fail;
     }
+    pa_xfree(thread_name);
+    thread_name = NULL;
+
     /* Get initial mixer settings */
     if (data.volume_is_set) {
         if (u->source->set_volume)
@@ -1762,6 +2207,9 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
             u->source->get_mute(u->source);
     }
 
+    if ((data.volume_is_set || data.muted_is_set) && u->source->write_volume)
+        u->source->write_volume(u->source);
+
     pa_source_put(u->source);
 
     if (profile_set)
@@ -1770,6 +2218,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
     return u->source;
 
 fail:
+    pa_xfree(thread_name);
 
     if (u)
         userdata_free(u);
@@ -1781,6 +2230,11 @@ fail:
 }
 
 static void userdata_free(struct userdata *u) {
+#ifdef __TIZEN__
+    void *audio_data = pa_shared_get(u->core, "tizen-audio-data");
+    audio_interface_t *audio_intf = pa_shared_get(u->core, "tizen-audio-interface");
+#endif
+
     pa_assert(u);
 
     if (u->source)
@@ -1796,6 +2250,9 @@ static void userdata_free(struct userdata *u) {
     if (u->source)
         pa_source_unref(u->source);
 
+    if (u->mixer_pd)
+        pa_alsa_mixer_pdata_free(u->mixer_pd);
+
     if (u->alsa_rtpoll_item)
         pa_rtpoll_item_free(u->alsa_rtpoll_item);
 
@@ -1804,15 +2261,18 @@ static void userdata_free(struct userdata *u) {
 
     if (u->pcm_handle) {
         snd_pcm_drop(u->pcm_handle);
+#ifdef __TIZEN__
+        if (audio_intf && audio_intf->alsa_pcm_close) {
+            audio_intf->alsa_pcm_close(audio_data, u->pcm_handle);
+        } else
+#endif
         snd_pcm_close(u->pcm_handle);
     }
 
     if (u->mixer_fdl)
         pa_alsa_fdlist_free(u->mixer_fdl);
 
-    if (u->mixer_path_set)
-        pa_alsa_path_set_free(u->mixer_path_set);
-    else if (u->mixer_path)
+    if (u->mixer_path && !u->mixer_path_set)
         pa_alsa_path_free(u->mixer_path);
 
     if (u->mixer_handle)
@@ -1821,11 +2281,15 @@ static void userdata_free(struct userdata *u) {
     if (u->smoother)
         pa_smoother_free(u->smoother);
 
+    if (u->rates)
+        pa_xfree(u->rates);
+
     reserve_done(u);
     monitor_done(u);
 
     pa_xfree(u->device_name);
     pa_xfree(u->control_device);
+    pa_xfree(u->paths_dir);
     pa_xfree(u);
 }
 
diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c
new file mode 100755 (executable)
index 0000000..eccbcf2
--- /dev/null
@@ -0,0 +1,1621 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2011 Wolfson Microelectronics PLC
+ Author Margarita Olaya <magi@slimlogic.co.uk>
+ Copyright 2012 Feng Wei <wei.feng@freescale.com>, Freescale Ltd.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <sys/types.h>
+#include <limits.h>
+#include <asoundlib.h>
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+#include <valgrind/memcheck.h>
+#endif
+
+#include <pulse/sample.h>
+#include <pulse/xmalloc.h>
+#include <pulse/timeval.h>
+#include <pulse/util.h>
+
+#include <pulsecore/log.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/atomic.h>
+#include <pulsecore/core-error.h>
+#include <pulsecore/once.h>
+#include <pulsecore/thread.h>
+#include <pulsecore/conf-parser.h>
+#include <pulsecore/strbuf.h>
+
+#include "alsa-mixer.h"
+#include "alsa-util.h"
+#include "alsa-ucm.h"
+
+#define PA_UCM_PRE_TAG_OUTPUT                       "[Out] "
+#define PA_UCM_PRE_TAG_INPUT                        "[In] "
+
+#define PA_UCM_PLAYBACK_PRIORITY_UNSET(device)      ((device)->playback_channels && !(device)->playback_priority)
+#define PA_UCM_CAPTURE_PRIORITY_UNSET(device)       ((device)->capture_channels && !(device)->capture_priority)
+#define PA_UCM_DEVICE_PRIORITY_SET(device, priority) \
+    do { \
+        if (PA_UCM_PLAYBACK_PRIORITY_UNSET(device)) (device)->playback_priority = (priority);   \
+        if (PA_UCM_CAPTURE_PRIORITY_UNSET(device))  (device)->capture_priority = (priority);    \
+    } while (0)
+#define PA_UCM_IS_MODIFIER_MAPPING(m) ((pa_proplist_gets((m)->proplist, PA_ALSA_PROP_UCM_MODIFIER)) != NULL)
+
+struct ucm_items {
+    const char *id;
+    const char *property;
+};
+
+struct ucm_info {
+    const char *id;
+    unsigned priority;
+};
+
+static struct ucm_items item[] = {
+    {"PlaybackPCM", PA_ALSA_PROP_UCM_SINK},
+    {"CapturePCM", PA_ALSA_PROP_UCM_SOURCE},
+    {"PlaybackVolume", PA_ALSA_PROP_UCM_PLAYBACK_VOLUME},
+    {"PlaybackSwitch", PA_ALSA_PROP_UCM_PLAYBACK_SWITCH},
+    {"PlaybackPriority", PA_ALSA_PROP_UCM_PLAYBACK_PRIORITY},
+    {"PlaybackChannels", PA_ALSA_PROP_UCM_PLAYBACK_CHANNELS},
+    {"CaptureVolume", PA_ALSA_PROP_UCM_CAPTURE_VOLUME},
+    {"CaptureSwitch", PA_ALSA_PROP_UCM_CAPTURE_SWITCH},
+    {"CapturePriority", PA_ALSA_PROP_UCM_CAPTURE_PRIORITY},
+    {"CaptureChannels", PA_ALSA_PROP_UCM_CAPTURE_CHANNELS},
+    {"TQ", PA_ALSA_PROP_UCM_QOS},
+    {NULL, NULL},
+};
+
+/* UCM verb info - this should eventually be part of policy manangement */
+static struct ucm_info verb_info[] = {
+    {SND_USE_CASE_VERB_INACTIVE, 0},
+    {SND_USE_CASE_VERB_HIFI, 8000},
+    {SND_USE_CASE_VERB_HIFI_LOW_POWER, 7000},
+    {SND_USE_CASE_VERB_VOICE, 6000},
+    {SND_USE_CASE_VERB_VOICE_LOW_POWER, 5000},
+    {SND_USE_CASE_VERB_VOICECALL, 4000},
+    {SND_USE_CASE_VERB_IP_VOICECALL, 4000},
+    {SND_USE_CASE_VERB_ANALOG_RADIO, 3000},
+    {SND_USE_CASE_VERB_DIGITAL_RADIO, 3000},
+    {NULL, 0}
+};
+
+/* UCM device info - should be overwritten by ucm property */
+static struct ucm_info dev_info[] = {
+    {SND_USE_CASE_DEV_SPEAKER, 100},
+    {SND_USE_CASE_DEV_LINE, 100},
+    {SND_USE_CASE_DEV_HEADPHONES, 100},
+    {SND_USE_CASE_DEV_HEADSET, 300},
+    {SND_USE_CASE_DEV_HANDSET, 200},
+    {SND_USE_CASE_DEV_BLUETOOTH, 400},
+    {SND_USE_CASE_DEV_EARPIECE, 100},
+    {SND_USE_CASE_DEV_SPDIF, 100},
+    {SND_USE_CASE_DEV_HDMI, 100},
+    {SND_USE_CASE_DEV_NONE, 100},
+    {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);
+    }
+
+    return 0;
+};
+
+static int ucm_device_exists(pa_idxset *idxset, pa_alsa_ucm_device *dev) {
+    pa_alsa_ucm_device *d;
+    uint32_t idx;
+
+    PA_IDXSET_FOREACH(d, idxset, idx)
+        if (d == dev)
+            return 1;
+
+    return 0;
+}
+
+static void ucm_add_devices_to_idxset(
+        pa_idxset *idxset,
+        pa_alsa_ucm_device *me,
+        pa_alsa_ucm_device *devices,
+        const char **dev_names,
+        int n) {
+
+    pa_alsa_ucm_device *d;
+
+    PA_LLIST_FOREACH(d, devices) {
+        const char *name;
+        int i;
+
+        if (d == me)
+            continue;
+
+        name = pa_proplist_gets(d->proplist, PA_ALSA_PROP_UCM_NAME);
+
+        for (i = 0; i < n; i++)
+            if (pa_streq(dev_names[i], name))
+                pa_idxset_put(idxset, d, NULL);
+    }
+}
+
+/* Create a property list for this ucm device */
+static int ucm_get_device_property(
+        pa_alsa_ucm_device *device,
+        snd_use_case_mgr_t *uc_mgr,
+        pa_alsa_ucm_verb *verb,
+        const char *device_name) {
+
+    const char *value;
+    const char **devices;
+    char *id;
+    int i;
+    int err;
+    uint32_t ui;
+    int n_confdev, n_suppdev;
+
+    for (i = 0; item[i].id; i++) {
+        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)
+            continue;
+
+        pa_log_debug("Got %s for device %s: %s", item[i].id, device_name, value);
+        pa_proplist_sets(device->proplist, item[i].property, value);
+        free((void*)value);
+    }
+
+    /* get direction and channels */
+    value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_PLAYBACK_CHANNELS);
+    if (value) { /* output */
+        /* get channels */
+        if (pa_atou(value, &ui) == 0 && ui < PA_CHANNELS_MAX)
+            device->playback_channels = ui;
+        else
+            pa_log("UCM playback channels %s for device %s out of range", value, device_name);
+
+        /* 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);
+        }
+    }
+
+    value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_CAPTURE_CHANNELS);
+    if (value) { /* input */
+        /* get channels */
+        if (pa_atou(value, &ui) == 0 && ui < PA_CHANNELS_MAX)
+            device->capture_channels = ui;
+        else
+            pa_log("UCM capture channels %s for device %s out of range", value, device_name);
+
+        /* 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 (device->playback_channels == 0 && device->capture_channels == 0) {
+        pa_log_warn("UCM file does not specify 'PlaybackChannels' or 'CaptureChannels'"
+                    "for device %s, assuming stereo duplex.", device_name);
+        device->playback_channels = 2;
+        device->capture_channels = 2;
+    }
+
+    /* get priority of device */
+    if (device->playback_channels) { /* sink device */
+        value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_PLAYBACK_PRIORITY);
+        if (value) {
+            /* get priority from ucm config */
+            if (pa_atou(value, &ui) == 0)
+                device->playback_priority = ui;
+            else
+                pa_log_debug("UCM playback priority %s for device %s error", value, device_name);
+        }
+    }
+
+    if (device->capture_channels) { /* source device */
+        value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_CAPTURE_PRIORITY);
+        if (value) {
+            /* get priority from ucm config */
+            if (pa_atou(value, &ui) == 0)
+                device->capture_priority = ui;
+            else
+                pa_log_debug("UCM capture priority %s for device %s error", value, device_name);
+        }
+    }
+
+    if (PA_UCM_PLAYBACK_PRIORITY_UNSET(device) || PA_UCM_CAPTURE_PRIORITY_UNSET(device)) {
+        /* get priority from static table */
+        for (i = 0; dev_info[i].id; i++) {
+            if (strcasecmp(dev_info[i].id, device_name) == 0) {
+                PA_UCM_DEVICE_PRIORITY_SET(device, dev_info[i].priority);
+                break;
+            }
+        }
+    }
+
+    if (PA_UCM_PLAYBACK_PRIORITY_UNSET(device)) {
+        /* fall through to default priority */
+        device->playback_priority = 100;
+    }
+
+    if (PA_UCM_CAPTURE_PRIORITY_UNSET(device)) {
+        /* fall through to default priority */
+        device->capture_priority = 100;
+    }
+
+    id = pa_sprintf_malloc("%s/%s", "_conflictingdevs", device_name);
+    n_confdev = snd_use_case_get_list(uc_mgr, id, &devices);
+    pa_xfree(id);
+
+    if (n_confdev <= 0)
+        pa_log_debug("No %s for device %s", "_conflictingdevs", device_name);
+    else {
+        device->conflicting_devices = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+        ucm_add_devices_to_idxset(device->conflicting_devices, device, verb->devices, devices, n_confdev);
+        snd_use_case_free_list(devices, n_confdev);
+    }
+
+    id = pa_sprintf_malloc("%s/%s", "_supporteddevs", device_name);
+    n_suppdev = snd_use_case_get_list(uc_mgr, id, &devices);
+    pa_xfree(id);
+
+    if (n_suppdev <= 0)
+        pa_log_debug("No %s for device %s", "_supporteddevs", device_name);
+    else {
+        device->supported_devices = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+        ucm_add_devices_to_idxset(device->supported_devices, device, verb->devices, devices, n_suppdev);
+        snd_use_case_free_list(devices, n_suppdev);
+    }
+
+    return 0;
+};
+
+/* Create a property list for this ucm modifier */
+static int ucm_get_modifier_property(pa_alsa_ucm_modifier *modifier, snd_use_case_mgr_t *uc_mgr, const char *modifier_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, modifier_name);
+        err = snd_use_case_get(uc_mgr, id, &value);
+        pa_xfree(id);
+        if (err < 0 )
+            continue;
+
+        pa_log_debug("Got %s for modifier %s: %s", item[i].id, modifier_name, value);
+        pa_proplist_sets(modifier->proplist, item[i].property, value);
+        free((void*)value);
+    }
+
+    id = pa_sprintf_malloc("%s/%s", "_conflictingdevs", modifier_name);
+    modifier->n_confdev = snd_use_case_get_list(uc_mgr, id, &modifier->conflicting_devices);
+    pa_xfree(id);
+    if (modifier->n_confdev < 0)
+        pa_log_debug("No %s for modifier %s", "_conflictingdevs", modifier_name);
+
+    id = pa_sprintf_malloc("%s/%s", "_supporteddevs", modifier_name);
+    modifier->n_suppdev = snd_use_case_get_list(uc_mgr, id, &modifier->supported_devices);
+    pa_xfree(id);
+    if (modifier->n_suppdev < 0)
+        pa_log_debug("No %s for modifier %s", "_supporteddevs", modifier_name);
+
+    return 0;
+};
+
+/* Create a list of devices for this verb */
+static int ucm_get_devices(pa_alsa_ucm_verb *verb, snd_use_case_mgr_t *uc_mgr) {
+    const char **dev_list;
+    int num_dev, i;
+
+    num_dev = snd_use_case_get_list(uc_mgr, "_devices", &dev_list);
+    if (num_dev < 0)
+        return num_dev;
+
+    for (i = 0; i < num_dev; i += 2) {
+        pa_alsa_ucm_device *d = pa_xnew0(pa_alsa_ucm_device, 1);
+
+        d->proplist = pa_proplist_new();
+        pa_proplist_sets(d->proplist, PA_ALSA_PROP_UCM_NAME, pa_strnull(dev_list[i]));
+        pa_proplist_sets(d->proplist, PA_ALSA_PROP_UCM_DESCRIPTION, pa_strna(dev_list[i + 1]));
+
+        PA_LLIST_PREPEND(pa_alsa_ucm_device, verb->devices, d);
+    }
+
+    snd_use_case_free_list(dev_list, num_dev);
+
+    return 0;
+};
+
+static int ucm_get_modifiers(pa_alsa_ucm_verb *verb, snd_use_case_mgr_t *uc_mgr) {
+    const char **mod_list;
+    int num_mod, i;
+
+    num_mod = snd_use_case_get_list(uc_mgr, "_modifiers", &mod_list);
+    if (num_mod < 0)
+        return num_mod;
+
+    for (i = 0; i < num_mod; i += 2) {
+        pa_alsa_ucm_modifier *m;
+
+        if (!mod_list[i]) {
+            pa_log_warn("Got a modifier with a null name. Skipping.");
+            continue;
+        }
+
+        m = pa_xnew0(pa_alsa_ucm_modifier, 1);
+        m->proplist = pa_proplist_new();
+
+        pa_proplist_sets(m->proplist, PA_ALSA_PROP_UCM_NAME, mod_list[i]);
+        pa_proplist_sets(m->proplist, PA_ALSA_PROP_UCM_DESCRIPTION, pa_strna(mod_list[i + 1]));
+
+        PA_LLIST_PREPEND(pa_alsa_ucm_modifier, verb->modifiers, m);
+    }
+
+    snd_use_case_free_list(mod_list, num_mod);
+
+    return 0;
+};
+
+static void add_role_to_device(pa_alsa_ucm_device *dev, const char *dev_name, const char *role_name, const char *role) {
+    const char *cur = pa_proplist_gets(dev->proplist, role_name);
+
+    if (!cur)
+        pa_proplist_sets(dev->proplist, role_name, role);
+    else if (!pa_str_in_list_spaces(cur, role)) { /* does not exist */
+        char *value = pa_sprintf_malloc("%s %s", cur, role);
+
+        pa_proplist_sets(dev->proplist, role_name, value);
+        pa_xfree(value);
+    }
+
+    pa_log_info("Add role %s to device %s(%s), result %s", role, dev_name, role_name, pa_proplist_gets(dev->proplist,
+                role_name));
+}
+
+static void add_media_role(const char *name, pa_alsa_ucm_device *list, const char *role_name, const char *role, bool is_sink) {
+    pa_alsa_ucm_device *d;
+
+    PA_LLIST_FOREACH(d, list) {
+        const char *dev_name = pa_proplist_gets(d->proplist, PA_ALSA_PROP_UCM_NAME);
+
+        if (pa_streq(dev_name, name)) {
+            const char *sink = pa_proplist_gets(d->proplist, PA_ALSA_PROP_UCM_SINK);
+            const char *source = pa_proplist_gets(d->proplist, PA_ALSA_PROP_UCM_SOURCE);
+
+            if (is_sink && sink)
+                add_role_to_device(d, dev_name, role_name, role);
+            else if (!is_sink && source)
+                add_role_to_device(d, dev_name, role_name, role);
+            break;
+        }
+    }
+}
+
+static char *modifier_name_to_role(const char *mod_name, bool *is_sink) {
+    char *sub = NULL, *tmp;
+
+    *is_sink = FALSE;
+
+    if (pa_startswith(mod_name, "Play")) {
+        *is_sink = TRUE;
+        sub = pa_xstrdup(mod_name + 4);
+    } else if (pa_startswith(mod_name, "Capture"))
+        sub = pa_xstrdup(mod_name + 7);
+
+    if (!sub || !*sub) {
+        pa_xfree(sub);
+        pa_log_warn("Can't match media roles for modifer %s", mod_name);
+        return NULL;
+    }
+
+    tmp = sub;
+
+    do {
+        *tmp = tolower(*tmp);
+    } while (*(++tmp));
+
+    return sub;
+}
+
+static void ucm_set_media_roles(pa_alsa_ucm_modifier *modifier, pa_alsa_ucm_device *list, const char *mod_name) {
+    int i;
+    bool is_sink = FALSE;
+    char *sub = NULL;
+    const char *role_name;
+
+    sub = modifier_name_to_role(mod_name, &is_sink);
+    if (!sub)
+        return;
+
+    modifier->action_direction = is_sink ? PA_DIRECTION_OUTPUT : PA_DIRECTION_INPUT;
+    modifier->media_role = sub;
+
+    role_name = is_sink ? PA_ALSA_PROP_UCM_PLAYBACK_ROLES : PA_ALSA_PROP_UCM_CAPTURE_ROLES;
+    for (i = 0; i < modifier->n_suppdev; i++) {
+        /* if modifier has no specific pcm, we add role intent to its supported devices */
+        if (!pa_proplist_gets(modifier->proplist, PA_ALSA_PROP_UCM_SINK) &&
+                !pa_proplist_gets(modifier->proplist, PA_ALSA_PROP_UCM_SOURCE))
+            add_media_role(modifier->supported_devices[i], list, role_name, sub, is_sink);
+    }
+}
+
+static void append_lost_relationship(pa_alsa_ucm_device *dev) {
+    uint32_t idx;
+    pa_alsa_ucm_device *d;
+
+    if (dev->conflicting_devices) {
+        PA_IDXSET_FOREACH(d, dev->conflicting_devices, idx) {
+            if (!d->conflicting_devices)
+                d->conflicting_devices = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+
+            if (pa_idxset_put(d->conflicting_devices, dev, NULL) == 0)
+                pa_log_warn("Add lost conflicting device %s to %s",
+                        pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME),
+                        pa_proplist_gets(d->proplist, PA_ALSA_PROP_UCM_NAME));
+        }
+    }
+
+    if (dev->supported_devices) {
+        PA_IDXSET_FOREACH(d, dev->supported_devices, idx) {
+            if (!d->supported_devices)
+                d->supported_devices = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+
+            if (pa_idxset_put(d->supported_devices, dev, NULL) == 0)
+                pa_log_warn("Add lost supported device %s to %s",
+                        pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME),
+                        pa_proplist_gets(d->proplist, PA_ALSA_PROP_UCM_NAME));
+        }
+    }
+}
+
+int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index)
+{
+    char *card_name;
+    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;
+    }
+
+    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);
+
+    /* get a list of all UCM verbs (profiles) for this card */
+    num_verbs = snd_use_case_verb_list(ucm->ucm_mgr, &verb_list);
+    if (num_verbs < 0) {
+        pa_log("UCM verb list not found for %s", card_name);
+        goto ucm_verb_fail;
+    }
+
+    /* get the properties of each UCM verb */
+    for (i = 0; i < num_verbs; i += 2) {
+        pa_alsa_ucm_verb *verb;
+
+        /* Get devices and modifiers for each verb */
+        err = pa_alsa_ucm_get_verb(ucm->ucm_mgr, verb_list[i], verb_list[i+1], &verb);
+        if (err < 0) {
+            pa_log("Failed to get the verb %s", verb_list[i]);
+            continue;
+        }
+
+        PA_LLIST_PREPEND(pa_alsa_ucm_verb, ucm->verbs, verb);
+    }
+
+    if (!ucm->verbs) {
+        pa_log("No UCM verb is valid for %s", card_name);
+        err = -1;
+    }
+
+    snd_use_case_free_list(verb_list, num_verbs);
+
+ucm_verb_fail:
+    if (err < 0) {
+        snd_use_case_mgr_close(ucm->ucm_mgr);
+        ucm->ucm_mgr = NULL;
+    }
+
+ucm_mgr_fail:
+    free(card_name);
+
+name_fail:
+    return err;
+}
+
+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) {
+    pa_alsa_ucm_device *d;
+    pa_alsa_ucm_modifier *mod;
+    pa_alsa_ucm_verb *verb;
+    int err = 0;
+
+    *p_verb = NULL;
+    pa_log_info("Set UCM verb to %s", verb_name);
+    err = snd_use_case_set(uc_mgr, "_verb", verb_name);
+    if (err < 0)
+        return err;
+
+    verb = pa_xnew0(pa_alsa_ucm_verb, 1);
+    verb->proplist = pa_proplist_new();
+
+    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));
+
+    err = ucm_get_devices(verb, uc_mgr);
+    if (err < 0)
+        pa_log("No UCM devices for verb %s", verb_name);
+
+    err = ucm_get_modifiers(verb, uc_mgr);
+    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);
+
+        /* Devices properties */
+        ucm_get_device_property(d, uc_mgr, verb, dev_name);
+    }
+    /* make conflicting or supported device mutual */
+    PA_LLIST_FOREACH(d, verb->devices)
+        append_lost_relationship(d);
+
+    PA_LLIST_FOREACH(mod, verb->modifiers) {
+        const char *mod_name = pa_proplist_gets(mod->proplist, PA_ALSA_PROP_UCM_NAME);
+
+        /* Modifier properties */
+        ucm_get_modifier_property(mod, uc_mgr, mod_name);
+
+        /* Set PA_PROP_DEVICE_INTENDED_ROLES property to devices */
+        pa_log_debug("Set media roles for verb %s, modifier %s", verb_name, mod_name);
+        ucm_set_media_roles(mod, verb->devices, mod_name);
+    }
+
+    *p_verb = verb;
+    return 0;
+}
+
+static void ucm_add_port_combination(
+        pa_hashmap *hash,
+        pa_alsa_ucm_mapping_context *context,
+        bool is_sink,
+        pa_alsa_ucm_device **pdevices,
+        int num,
+        pa_hashmap *ports,
+        pa_card_profile *cp,
+        pa_core *core) {
+
+    pa_device_port *port;
+    int i;
+    unsigned priority;
+    char *name, *desc;
+    const char *dev_name;
+    const char *direction;
+    pa_alsa_ucm_device *dev;
+
+    dev = pdevices[0];
+    dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME);
+
+    name = pa_sprintf_malloc("%s%s", is_sink ? PA_UCM_PRE_TAG_OUTPUT : PA_UCM_PRE_TAG_INPUT, dev_name);
+    desc = num == 1 ? pa_xstrdup(pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_DESCRIPTION))
+            : pa_sprintf_malloc("Combination port for %s", dev_name);
+
+    priority = is_sink ? dev->playback_priority : dev->capture_priority;
+
+    for (i = 1; i < num; i++) {
+        char *tmp;
+
+        dev = pdevices[i];
+        dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME);
+
+        tmp = pa_sprintf_malloc("%s+%s", name, dev_name);
+        pa_xfree(name);
+        name = tmp;
+
+        tmp = pa_sprintf_malloc("%s,%s", desc, dev_name);
+        pa_xfree(desc);
+        desc = tmp;
+
+        /* FIXME: Is this true? */
+        priority += (is_sink ? dev->playback_priority : dev->capture_priority);
+    }
+
+    port = pa_hashmap_get(ports, name);
+    if (!port) {
+        port = pa_device_port_new(core, pa_strna(name), desc, 0);
+        pa_assert(port);
+
+        pa_hashmap_put(ports, port->name, port);
+        pa_log_debug("Add port %s: %s", port->name, port->description);
+        port->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    }
+
+    port->priority = priority;
+    if (is_sink)
+        port->is_output = TRUE;
+    else
+        port->is_input = TRUE;
+
+    pa_xfree(name);
+    pa_xfree(desc);
+
+    direction = is_sink ? "output" : "input";
+    pa_log_debug("Port %s direction %s, priority %d", port->name, direction, priority);
+
+    if (cp) {
+        pa_log_debug("Adding port %s to profile %s", port->name, cp->name);
+        pa_hashmap_put(port->profiles, cp->name, cp);
+    }
+
+    if (hash) {
+        pa_hashmap_put(hash, port->name, port);
+        pa_device_port_ref(port);
+    }
+}
+
+static int ucm_port_contains(const char *port_name, const char *dev_name, bool is_sink) {
+    int ret = 0;
+    const char *r;
+    const char *state = NULL;
+    int len;
+
+    if (!port_name || !dev_name)
+        return FALSE;
+
+    port_name += is_sink ? strlen(PA_UCM_PRE_TAG_OUTPUT) : strlen(PA_UCM_PRE_TAG_INPUT);
+
+    while ((r = pa_split_in_place(port_name, "+", &len, &state))) {
+        if (!strncmp(r, dev_name, len)) {
+            ret = 1;
+            break;
+        }
+    }
+
+    return ret;
+}
+
+static int ucm_check_conformance(
+        pa_alsa_ucm_mapping_context *context,
+        pa_alsa_ucm_device **pdevices,
+        int dev_num,
+        pa_alsa_ucm_device *dev) {
+
+    uint32_t idx;
+    pa_alsa_ucm_device *d;
+    int i;
+
+    pa_assert(dev);
+
+    pa_log_debug("Check device %s conformance with %d other devices",
+            pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME), dev_num);
+    if (dev_num == 0) {
+        pa_log_debug("First device in combination, number 1");
+        return 1;
+    }
+
+    if (dev->conflicting_devices) { /* the device defines conflicting devices */
+        PA_IDXSET_FOREACH(d, dev->conflicting_devices, idx) {
+            for (i = 0; i < dev_num; i++) {
+                if (pdevices[i] == d) {
+                    pa_log_debug("Conflicting device found");
+                    return 0;
+                }
+            }
+        }
+    } else if (dev->supported_devices) { /* the device defines supported devices */
+        for (i = 0; i < dev_num; i++) {
+            if (!ucm_device_exists(dev->supported_devices, pdevices[i])) {
+                pa_log_debug("Supported device not found");
+                return 0;
+            }
+        }
+    } else { /* not support any other devices */
+        pa_log_debug("Not support any other devices");
+        return 0;
+    }
+
+    pa_log_debug("Device added to combination, number %d", dev_num + 1);
+    return 1;
+}
+
+static inline pa_alsa_ucm_device *get_next_device(pa_idxset *idxset, uint32_t *idx) {
+    pa_alsa_ucm_device *dev;
+
+    if (*idx == PA_IDXSET_INVALID)
+        dev = pa_idxset_first(idxset, idx);
+    else
+        dev = pa_idxset_next(idxset, idx);
+
+    return dev;
+}
+
+static void ucm_add_ports_combination(
+        pa_hashmap *hash,
+        pa_alsa_ucm_mapping_context *context,
+        bool is_sink,
+        pa_alsa_ucm_device **pdevices,
+        int dev_num,
+        uint32_t map_index,
+        pa_hashmap *ports,
+        pa_card_profile *cp,
+        pa_core *core) {
+
+    pa_alsa_ucm_device *dev;
+    uint32_t idx = map_index;
+
+    if ((dev = get_next_device(context->ucm_devices, &idx)) == NULL)
+        return;
+
+    /* check if device at map_index can combine with existing devices combination */
+    if (ucm_check_conformance(context, pdevices, dev_num, dev)) {
+        /* add device at map_index to devices combination */
+        pdevices[dev_num] = dev;
+        /* add current devices combination as a new port */
+        ucm_add_port_combination(hash, context, is_sink, pdevices, dev_num + 1, ports, cp, core);
+        /* try more elements combination */
+        ucm_add_ports_combination(hash, context, is_sink, pdevices, dev_num + 1, idx, ports, cp, core);
+    }
+
+    /* try other device with current elements number */
+    ucm_add_ports_combination(hash, context, is_sink, pdevices, dev_num, idx, ports, cp, core);
+}
+
+static char* merge_roles(const char *cur, const char *add) {
+    char *r, *ret;
+    const char *state = NULL;
+
+    if (add == NULL)
+        return pa_xstrdup(cur);
+    else if (cur == NULL)
+        return pa_xstrdup(add);
+
+    ret = pa_xstrdup(cur);
+
+    while ((r = pa_split_spaces(add, &state))) {
+        char *value;
+
+        if (!pa_str_in_list_spaces(ret, r))
+            value = pa_sprintf_malloc("%s %s", ret, r);
+        else {
+            pa_xfree(r);
+            continue;
+        }
+
+        pa_xfree(ret);
+        ret = value;
+        pa_xfree(r);
+    }
+
+    return ret;
+}
+
+void pa_alsa_ucm_add_ports_combination(
+        pa_hashmap *p,
+        pa_alsa_ucm_mapping_context *context,
+        bool is_sink,
+        pa_hashmap *ports,
+        pa_card_profile *cp,
+        pa_core *core) {
+
+    pa_alsa_ucm_device **pdevices;
+
+    pa_assert(context->ucm_devices);
+
+    if (pa_idxset_size(context->ucm_devices) > 0) {
+        pdevices = pa_xnew(pa_alsa_ucm_device *, pa_idxset_size(context->ucm_devices));
+        ucm_add_ports_combination(p, context, is_sink, pdevices, 0, PA_IDXSET_INVALID, ports, cp, core);
+        pa_xfree(pdevices);
+    }
+}
+
+void pa_alsa_ucm_add_ports(
+        pa_hashmap **p,
+        pa_proplist *proplist,
+        pa_alsa_ucm_mapping_context *context,
+        bool is_sink,
+        pa_card *card) {
+
+    uint32_t idx;
+    char *merged_roles;
+    const char *role_name = is_sink ? PA_ALSA_PROP_UCM_PLAYBACK_ROLES : PA_ALSA_PROP_UCM_CAPTURE_ROLES;
+    pa_alsa_ucm_device *dev;
+    pa_alsa_ucm_modifier *mod;
+    char *tmp;
+
+    pa_assert(p);
+    pa_assert(*p);
+
+    /* add ports first */
+    pa_alsa_ucm_add_ports_combination(*p, context, is_sink, card->ports, NULL, card->core);
+
+    /* 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) {
+        const char *roles = pa_proplist_gets(dev->proplist, role_name);
+        tmp = merge_roles(merged_roles, roles);
+        pa_xfree(merged_roles);
+        merged_roles = tmp;
+    }
+
+    if (context->ucm_modifiers)
+        PA_IDXSET_FOREACH(mod, context->ucm_modifiers, idx) {
+            tmp = merge_roles(merged_roles, mod->media_role);
+            pa_xfree(merged_roles);
+            merged_roles = tmp;
+        }
+
+    if (merged_roles)
+        pa_proplist_sets(proplist, PA_PROP_DEVICE_INTENDED_ROLES, merged_roles);
+
+    pa_log_info("ALSA device %s roles: %s", pa_proplist_gets(proplist, PA_PROP_DEVICE_STRING), pa_strnull(merged_roles));
+    pa_xfree(merged_roles);
+}
+
+/* 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 ret = 0;
+    const char *profile;
+    pa_alsa_ucm_verb *verb;
+
+    if (new_profile == old_profile)
+        return ret;
+    else if (new_profile == NULL || old_profile == NULL)
+        profile = new_profile ? new_profile : SND_USE_CASE_VERB_INACTIVE;
+    else if (!pa_streq(new_profile, old_profile))
+        profile = new_profile;
+    else
+        return ret;
+
+    /* change verb */
+    pa_log_info("Set UCM verb to %s", profile);
+    if ((snd_use_case_set(ucm->ucm_mgr, "_verb", profile)) < 0) {
+        pa_log("Failed to set verb %s", profile);
+        ret = -1;
+    }
+
+    /* find active verb */
+    ucm->active_verb = NULL;
+    PA_LLIST_FOREACH(verb, ucm->verbs) {
+        const char *verb_name;
+        verb_name = pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME);
+        if (pa_streq(verb_name, profile)) {
+            ucm->active_verb = verb;
+            break;
+        }
+    }
+
+    return ret;
+}
+
+int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port, bool is_sink) {
+    int i;
+    int ret = 0;
+    pa_alsa_ucm_config *ucm;
+    const char **enable_devs;
+    int enable_num = 0;
+    uint32_t idx;
+    pa_alsa_ucm_device *dev;
+
+    pa_assert(context && context->ucm);
+
+    ucm = context->ucm;
+    pa_assert(ucm->ucm_mgr);
+
+    enable_devs = pa_xnew(const char *, pa_idxset_size(context->ucm_devices));
+
+    /* first disable then enable */
+    PA_IDXSET_FOREACH(dev, context->ucm_devices, idx) {
+        const char *dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME);
+
+        if (ucm_port_contains(port->name, dev_name, is_sink))
+            enable_devs[enable_num++] = dev_name;
+        else {
+            pa_log_debug("Disable ucm device %s", dev_name);
+            if (snd_use_case_set(ucm->ucm_mgr, "_disdev", dev_name) > 0) {
+                pa_log("Failed to disable ucm device %s", dev_name);
+                ret = -1;
+                break;
+            }
+        }
+    }
+
+    for (i = 0; i < enable_num; i++) {
+        pa_log_debug("Enable ucm device %s", enable_devs[i]);
+        if (snd_use_case_set(ucm->ucm_mgr, "_enadev", enable_devs[i]) < 0) {
+            pa_log("Failed to enable ucm device %s", enable_devs[i]);
+            ret = -1;
+            break;
+        }
+    }
+
+    pa_xfree(enable_devs);
+
+    return ret;
+}
+
+static void ucm_add_mapping(pa_alsa_profile *p, pa_alsa_mapping *m) {
+
+    switch (m->direction) {
+        case PA_ALSA_DIRECTION_ANY:
+            pa_idxset_put(p->output_mappings, m, NULL);
+            pa_idxset_put(p->input_mappings, m, NULL);
+            break;
+        case PA_ALSA_DIRECTION_OUTPUT:
+            pa_idxset_put(p->output_mappings, m, NULL);
+            break;
+        case PA_ALSA_DIRECTION_INPUT:
+            pa_idxset_put(p->input_mappings, m, NULL);
+            break;
+    }
+}
+
+static void alsa_mapping_add_ucm_device(pa_alsa_mapping *m, pa_alsa_ucm_device *device) {
+    char *cur_desc;
+    const char *new_desc;
+
+    pa_idxset_put(m->ucm_context.ucm_devices, device, NULL);
+
+    new_desc = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_DESCRIPTION);
+    cur_desc = m->description;
+    if (cur_desc)
+        m->description = pa_sprintf_malloc("%s + %s", cur_desc, new_desc);
+    else
+        m->description = pa_xstrdup(new_desc);
+    pa_xfree(cur_desc);
+
+    /* walk around null case */
+    m->description = m->description ? m->description : pa_xstrdup("");
+
+    /* save mapping to ucm device */
+    if (m->direction == PA_ALSA_DIRECTION_OUTPUT)
+        device->playback_mapping = m;
+    else
+        device->capture_mapping = m;
+}
+
+static void alsa_mapping_add_ucm_modifier(pa_alsa_mapping *m, pa_alsa_ucm_modifier *modifier) {
+    char *cur_desc;
+    const char *new_desc, *mod_name, *channel_str;
+    uint32_t channels = 0;
+
+    pa_idxset_put(m->ucm_context.ucm_modifiers, modifier, NULL);
+
+    new_desc = pa_proplist_gets(modifier->proplist, PA_ALSA_PROP_UCM_DESCRIPTION);
+    cur_desc = m->description;
+    if (cur_desc)
+        m->description = pa_sprintf_malloc("%s + %s", cur_desc, new_desc);
+    else
+        m->description = pa_xstrdup(new_desc);
+    pa_xfree(cur_desc);
+
+    if (!m->description)
+        pa_xstrdup("");
+
+    /* Modifier sinks should not be routed to by default */
+    m->priority = 0;
+
+    mod_name = pa_proplist_gets(modifier->proplist, PA_ALSA_PROP_UCM_NAME);
+    pa_proplist_sets(m->proplist, PA_ALSA_PROP_UCM_MODIFIER, mod_name);
+
+    /* save mapping to ucm modifier */
+    if (m->direction == PA_ALSA_DIRECTION_OUTPUT) {
+        modifier->playback_mapping = m;
+        channel_str = pa_proplist_gets(modifier->proplist, PA_ALSA_PROP_UCM_PLAYBACK_CHANNELS);
+    } else {
+        modifier->capture_mapping = m;
+        channel_str = pa_proplist_gets(modifier->proplist, PA_ALSA_PROP_UCM_CAPTURE_CHANNELS);
+    }
+
+    if (channel_str) {
+        pa_assert_se(pa_atou(channel_str, &channels) == 0 && channels < PA_CHANNELS_MAX);
+        pa_log_debug("Got channel count %" PRIu32 " for modifier", channels);
+    }
+
+    if (channels)
+        pa_channel_map_init_extend(&m->channel_map, channels, PA_CHANNEL_MAP_ALSA);
+    else
+        pa_channel_map_init(&m->channel_map);
+}
+
+static int ucm_create_mapping_direction(
+        pa_alsa_ucm_config *ucm,
+        pa_alsa_profile_set *ps,
+        pa_alsa_profile *p,
+        pa_alsa_ucm_device *device,
+        const char *verb_name,
+        const char *device_name,
+        const char *device_str,
+        bool is_sink) {
+
+    pa_alsa_mapping *m;
+    char *mapping_name;
+    unsigned priority, channels;
+
+    mapping_name = pa_sprintf_malloc("Mapping %s: %s: %s", verb_name, device_str, is_sink ? "sink" : "source");
+
+    m = pa_alsa_mapping_get(ps, mapping_name);
+    if (!m) {
+        pa_log("No mapping for %s", mapping_name);
+        pa_xfree(mapping_name);
+        return -1;
+    }
+    pa_log_debug("UCM mapping: %s dev %s", mapping_name, device_name);
+    pa_xfree(mapping_name);
+
+    priority = is_sink ? device->playback_priority : device->capture_priority;
+    channels = is_sink ? device->playback_channels : device->capture_channels;
+
+    if (!m->ucm_context.ucm_devices) {   /* new mapping */
+        m->ucm_context.ucm_devices = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+        m->ucm_context.ucm = ucm;
+        m->ucm_context.direction = is_sink ? PA_DIRECTION_OUTPUT : PA_DIRECTION_INPUT;
+
+        m->device_strings = pa_xnew0(char*, 2);
+        m->device_strings[0] = pa_xstrdup(device_str);
+        m->direction = is_sink ? PA_ALSA_DIRECTION_OUTPUT : PA_ALSA_DIRECTION_INPUT;
+
+        ucm_add_mapping(p, m);
+        pa_channel_map_init_extend(&m->channel_map, channels, PA_CHANNEL_MAP_ALSA);
+    }
+
+    /* mapping priority is the highest one of ucm devices */
+    if (priority > m->priority)
+        m->priority = priority;
+
+    /* mapping channels is the lowest one of ucm devices */
+    if (channels < m->channel_map.channels)
+        pa_channel_map_init_extend(&m->channel_map, channels, PA_CHANNEL_MAP_ALSA);
+
+    alsa_mapping_add_ucm_device(m, device);
+
+    return 0;
+}
+
+static int ucm_create_mapping_for_modifier(
+        pa_alsa_ucm_config *ucm,
+        pa_alsa_profile_set *ps,
+        pa_alsa_profile *p,
+        pa_alsa_ucm_modifier *modifier,
+        const char *verb_name,
+        const char *mod_name,
+        const char *device_str,
+        bool is_sink) {
+
+    pa_alsa_mapping *m;
+    char *mapping_name;
+
+    mapping_name = pa_sprintf_malloc("Mapping %s: %s: %s", verb_name, device_str, is_sink ? "sink" : "source");
+
+    m = pa_alsa_mapping_get(ps, mapping_name);
+    if (!m) {
+        pa_log("no mapping for %s", mapping_name);
+        pa_xfree(mapping_name);
+        return -1;
+    }
+    pa_log_info("ucm mapping: %s modifier %s", mapping_name, mod_name);
+    pa_xfree(mapping_name);
+
+    if (!m->ucm_context.ucm_devices && !m->ucm_context.ucm_modifiers) {   /* new mapping */
+        m->ucm_context.ucm_devices = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+        m->ucm_context.ucm_modifiers = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+        m->ucm_context.ucm = ucm;
+        m->ucm_context.direction = is_sink ? PA_DIRECTION_OUTPUT : PA_DIRECTION_INPUT;
+
+        m->device_strings = pa_xnew0(char*, 2);
+        m->device_strings[0] = pa_xstrdup(device_str);
+        m->direction = is_sink ? PA_ALSA_DIRECTION_OUTPUT : PA_ALSA_DIRECTION_INPUT;
+        /* Modifier sinks should not be routed to by default */
+        m->priority = 0;
+
+        ucm_add_mapping(p, m);
+    } else if (!m->ucm_context.ucm_modifiers) /* share pcm with device */
+        m->ucm_context.ucm_modifiers = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+
+    alsa_mapping_add_ucm_modifier(m, modifier);
+
+    return 0;
+}
+
+static int ucm_create_mapping(
+        pa_alsa_ucm_config *ucm,
+        pa_alsa_profile_set *ps,
+        pa_alsa_profile *p,
+        pa_alsa_ucm_device *device,
+        const char *verb_name,
+        const char *device_name,
+        const char *sink,
+        const char *source) {
+
+    int ret = 0;
+
+    if (!sink && !source) {
+        pa_log("No sink and source at %s: %s", verb_name, device_name);
+        return -1;
+    }
+
+    if (sink)
+        ret = ucm_create_mapping_direction(ucm, ps, p, device, verb_name, device_name, sink, TRUE);
+    if (ret == 0 && source)
+        ret = ucm_create_mapping_direction(ucm, ps, p, device, verb_name, device_name, source, FALSE);
+
+    return ret;
+}
+
+static pa_alsa_jack* ucm_get_jack(pa_alsa_ucm_config *ucm, const char *dev_name, const char *pre_tag) {
+    pa_alsa_jack *j;
+    char *name = pa_sprintf_malloc("%s%s", pre_tag, dev_name);
+
+    PA_LLIST_FOREACH(j, ucm->jacks)
+        if (pa_streq(j->name, name))
+            goto out;
+
+    j = pa_xnew0(pa_alsa_jack, 1);
+    j->state_unplugged = PA_AVAILABLE_NO;
+    j->state_plugged = PA_AVAILABLE_YES;
+    j->name = pa_xstrdup(name);
+    j->alsa_name = pa_sprintf_malloc("%s Jack", dev_name);
+
+    PA_LLIST_PREPEND(pa_alsa_jack, ucm->jacks, j);
+
+out:
+    pa_xfree(name);
+    return j;
+}
+
+static int ucm_create_profile(
+        pa_alsa_ucm_config *ucm,
+        pa_alsa_profile_set *ps,
+        pa_alsa_ucm_verb *verb,
+        const char *verb_name,
+        const char *verb_desc) {
+
+    pa_alsa_profile *p;
+    pa_alsa_ucm_device *dev;
+    pa_alsa_ucm_modifier *mod;
+    int i = 0;
+    const char *name, *sink, *source;
+    char *verb_cmp, *c;
+
+    pa_assert(ps);
+
+    if (pa_hashmap_get(ps->profiles, verb_name)) {
+        pa_log("Verb %s already exists", verb_name);
+        return -1;
+    }
+
+    p = pa_xnew0(pa_alsa_profile, 1);
+    p->profile_set = ps;
+    p->name = pa_xstrdup(verb_name);
+    p->description = pa_xstrdup(verb_desc);
+
+    p->output_mappings = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+    p->input_mappings = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+
+    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++;
+    }
+
+    for (i = 0; verb_info[i].id; i++) {
+        if (strcasecmp(verb_info[i].id, verb_cmp) == 0) {
+            p->priority = verb_info[i].priority;
+            break;
+        }
+    }
+
+    pa_xfree(verb_cmp);
+
+    if (verb_info[i].id == NULL)
+        p->priority = 1000;
+
+    PA_LLIST_FOREACH(dev, verb->devices) {
+        name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME);
+
+        sink = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_SINK);
+        source = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_SOURCE);
+
+        ucm_create_mapping(ucm, ps, p, dev, verb_name, name, sink, source);
+
+        if (sink)
+            dev->output_jack = ucm_get_jack(ucm, name, PA_UCM_PRE_TAG_OUTPUT);
+        if (source)
+            dev->input_jack = ucm_get_jack(ucm, name, PA_UCM_PRE_TAG_INPUT);
+    }
+
+    /* Now find modifiers that have their own PlaybackPCM and create
+     * separate sinks for them. */
+    PA_LLIST_FOREACH(mod, verb->modifiers) {
+        name = pa_proplist_gets(mod->proplist, PA_ALSA_PROP_UCM_NAME);
+
+        sink = pa_proplist_gets(mod->proplist, PA_ALSA_PROP_UCM_SINK);
+        source = pa_proplist_gets(mod->proplist, PA_ALSA_PROP_UCM_SOURCE);
+
+        if (sink)
+            ucm_create_mapping_for_modifier(ucm, ps, p, mod, verb_name, name, sink, TRUE);
+        else if (source)
+            ucm_create_mapping_for_modifier(ucm, ps, p, mod, verb_name, name, source, FALSE);
+    }
+
+    pa_alsa_profile_dump(p);
+
+    return 0;
+}
+
+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;
+    pa_channel_map try_map;
+    snd_pcm_uframes_t try_period_size, try_buffer_size;
+    bool exact_channels = m->channel_map.channels > 0;
+
+    if (exact_channels) {
+        try_map = m->channel_map;
+        try_ss.channels = try_map.channels;
+    } else
+        pa_channel_map_init_extend(&try_map, try_ss.channels, PA_CHANNEL_MAP_ALSA);
+
+    try_period_size =
+        pa_usec_to_bytes(ucm->core->default_fragment_size_msec * PA_USEC_PER_MSEC, &try_ss) /
+        pa_frame_size(&try_ss);
+    try_buffer_size = ucm->core->default_n_fragments * try_period_size;
+
+    pcm = pa_alsa_open_by_device_string(
+#ifdef __TIZEN__
+            ucm->core,
+#endif
+            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;
+
+    return pcm;
+}
+
+static void profile_finalize_probing(pa_alsa_profile *p) {
+    pa_alsa_mapping *m;
+    uint32_t idx;
+
+    PA_IDXSET_FOREACH(m, p->output_mappings, idx) {
+        if (p->supported)
+            m->supported++;
+
+        if (!m->output_pcm)
+            continue;
+
+        snd_pcm_close(m->output_pcm);
+        m->output_pcm = NULL;
+    }
+
+    PA_IDXSET_FOREACH(m, p->input_mappings, idx) {
+        if (p->supported)
+            m->supported++;
+
+        if (!m->input_pcm)
+            continue;
+
+        snd_pcm_close(m->input_pcm);
+        m->input_pcm = NULL;
+    }
+}
+
+static void ucm_mapping_jack_probe(pa_alsa_mapping *m) {
+    snd_pcm_t *pcm_handle;
+    snd_mixer_t *mixer_handle;
+    snd_hctl_t *hctl_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, &hctl_handle);
+    if (!mixer_handle || !hctl_handle)
+        return;
+
+    PA_IDXSET_FOREACH(dev, context->ucm_devices, idx) {
+        pa_alsa_jack *jack;
+        jack = m->direction == PA_ALSA_DIRECTION_OUTPUT ? dev->output_jack : dev->input_jack;
+        pa_assert (jack);
+        jack->has_control = pa_alsa_find_jack(hctl_handle, jack->alsa_name) != NULL;
+        pa_log_info("UCM jack %s has_control=%d", jack->name, jack->has_control);
+    }
+
+    snd_mixer_close(mixer_handle);
+}
+
+static void ucm_probe_profile_set(pa_alsa_ucm_config *ucm, pa_alsa_profile_set *ps) {
+    void *state;
+    pa_alsa_profile *p;
+    pa_alsa_mapping *m;
+    uint32_t idx;
+
+    PA_HASHMAP_FOREACH(p, ps->profiles, state) {
+        /* change verb */
+        pa_log_info("Set ucm verb to %s", p->name);
+
+        if ((snd_use_case_set(ucm->ucm_mgr, "_verb", p->name)) < 0) {
+            pa_log("Failed to set verb %s", p->name);
+            p->supported = FALSE;
+            continue;
+        }
+
+        PA_IDXSET_FOREACH(m, p->output_mappings, idx) {
+            if (PA_UCM_IS_MODIFIER_MAPPING(m)) {
+                /* Skip jack probing on modifier PCMs since we expect this to
+                 * only be controlled on the main device/verb PCM. */
+                continue;
+            }
+
+            m->output_pcm = mapping_open_pcm(ucm, m, SND_PCM_STREAM_PLAYBACK);
+            if (!m->output_pcm) {
+                p->supported = FALSE;
+                break;
+            }
+        }
+
+        if (p->supported) {
+            PA_IDXSET_FOREACH(m, p->input_mappings, idx) {
+                if (PA_UCM_IS_MODIFIER_MAPPING(m)) {
+                    /* Skip jack probing on modifier PCMs since we expect this to
+                     * only be controlled on the main device/verb PCM. */
+                    continue;
+                }
+
+                m->input_pcm = mapping_open_pcm(ucm, m, SND_PCM_STREAM_CAPTURE);
+                if (!m->input_pcm) {
+                    p->supported = FALSE;
+                    break;
+                }
+            }
+        }
+
+        if (!p->supported) {
+            profile_finalize_probing(p);
+            continue;
+        }
+
+        pa_log_debug("Profile %s supported.", p->name);
+
+        PA_IDXSET_FOREACH(m, p->output_mappings, idx)
+            if (!PA_UCM_IS_MODIFIER_MAPPING(m))
+                ucm_mapping_jack_probe(m);
+
+        PA_IDXSET_FOREACH(m, p->input_mappings, idx)
+            if (!PA_UCM_IS_MODIFIER_MAPPING(m))
+                ucm_mapping_jack_probe(m);
+
+        profile_finalize_probing(p);
+    }
+
+    /* restore ucm state */
+    snd_use_case_set(ucm->ucm_mgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
+
+    pa_alsa_profile_set_drop_unsupported(ps);
+}
+
+pa_alsa_profile_set* pa_alsa_ucm_add_profile_set(pa_alsa_ucm_config *ucm, pa_channel_map *default_channel_map) {
+    pa_alsa_ucm_verb *verb;
+    pa_alsa_profile_set *ps;
+
+    ps = pa_xnew0(pa_alsa_profile_set, 1);
+    ps->mappings = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    ps->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    ps->decibel_fixes = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+
+    /* create a profile for each verb */
+    PA_LLIST_FOREACH(verb, ucm->verbs) {
+        const char *verb_name;
+        const char *verb_desc;
+
+        verb_name = pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME);
+        verb_desc = pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_DESCRIPTION);
+        if (verb_name == NULL) {
+            pa_log("Verb with no name");
+            continue;
+        }
+
+           ucm_create_profile(ucm, ps, verb, verb_name, verb_desc);
+    }
+
+    ucm_probe_profile_set(ucm, ps);
+    ps->probed = TRUE;
+
+    return ps;
+}
+
+static void free_verb(pa_alsa_ucm_verb *verb) {
+    pa_alsa_ucm_device *di, *dn;
+    pa_alsa_ucm_modifier *mi, *mn;
+
+    PA_LLIST_FOREACH_SAFE(di, dn, verb->devices) {
+        PA_LLIST_REMOVE(pa_alsa_ucm_device, verb->devices, di);
+        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);
+    }
+
+    PA_LLIST_FOREACH_SAFE(mi, mn, verb->modifiers) {
+        PA_LLIST_REMOVE(pa_alsa_ucm_modifier, verb->modifiers, mi);
+        pa_proplist_free(mi->proplist);
+        if (mi->n_suppdev > 0)
+            snd_use_case_free_list(mi->supported_devices, mi->n_suppdev);
+        if (mi->n_confdev > 0)
+            snd_use_case_free_list(mi->conflicting_devices, mi->n_confdev);
+        pa_xfree(mi->media_role);
+        pa_xfree(mi);
+    }
+    pa_proplist_free(verb->proplist);
+    pa_xfree(verb);
+}
+
+void pa_alsa_ucm_free(pa_alsa_ucm_config *ucm) {
+    pa_alsa_ucm_verb *vi, *vn;
+    pa_alsa_jack *ji, *jn;
+
+    PA_LLIST_FOREACH_SAFE(vi, vn, ucm->verbs) {
+        PA_LLIST_REMOVE(pa_alsa_ucm_verb, ucm->verbs, vi);
+        free_verb(vi);
+    }
+    PA_LLIST_FOREACH_SAFE(ji, jn, ucm->jacks) {
+        PA_LLIST_REMOVE(pa_alsa_jack, ucm->jacks, ji);
+        pa_xfree(ji->alsa_name);
+        pa_xfree(ji->name);
+        pa_xfree(ji);
+    }
+    if (ucm->ucm_mgr) {
+        snd_use_case_mgr_close(ucm->ucm_mgr);
+        ucm->ucm_mgr = NULL;
+    }
+}
+
+void pa_alsa_ucm_mapping_context_free(pa_alsa_ucm_mapping_context *context) {
+    pa_alsa_ucm_device *dev;
+    pa_alsa_ucm_modifier *mod;
+    uint32_t idx;
+
+    if (context->ucm_devices) {
+        /* clear ucm device pointer to mapping */
+        PA_IDXSET_FOREACH(dev, context->ucm_devices, idx) {
+            if (context->direction == PA_DIRECTION_OUTPUT)
+                dev->playback_mapping = NULL;
+            else
+                dev->capture_mapping = NULL;
+        }
+
+        pa_idxset_free(context->ucm_devices, NULL);
+    }
+
+    if (context->ucm_modifiers) {
+        PA_IDXSET_FOREACH(mod, context->ucm_modifiers, idx) {
+            if (context->direction == PA_DIRECTION_OUTPUT)
+                mod->playback_mapping = NULL;
+            else
+                mod->capture_mapping = NULL;
+        }
+
+        pa_idxset_free(context->ucm_modifiers, NULL);
+    }
+}
+
+/* Enable the modifier when the first stream with matched role starts */
+void pa_alsa_ucm_roled_stream_begin(pa_alsa_ucm_config *ucm, const char *role, pa_direction_t dir) {
+    pa_alsa_ucm_modifier *mod;
+
+    if (!ucm->active_verb)
+        return;
+
+    PA_LLIST_FOREACH(mod, ucm->active_verb->modifiers) {
+        if ((mod->action_direction == dir) && (pa_streq(mod->media_role, role))) {
+            if (mod->enabled_counter == 0) {
+                const char *mod_name = pa_proplist_gets(mod->proplist, PA_ALSA_PROP_UCM_NAME);
+
+                pa_log_info("Enable ucm modifier %s", mod_name);
+                if (snd_use_case_set(ucm->ucm_mgr, "_enamod", mod_name) < 0) {
+                    pa_log("Failed to enable ucm modifier %s", mod_name);
+                }
+            }
+
+            mod->enabled_counter++;
+            break;
+        }
+    }
+}
+
+/* Disable the modifier when the last stream with matched role ends */
+void pa_alsa_ucm_roled_stream_end(pa_alsa_ucm_config *ucm, const char *role, pa_direction_t dir) {
+    pa_alsa_ucm_modifier *mod;
+
+    if (!ucm->active_verb)
+        return;
+
+    PA_LLIST_FOREACH(mod, ucm->active_verb->modifiers) {
+        if ((mod->action_direction == dir) && (pa_streq(mod->media_role, role))) {
+
+            mod->enabled_counter--;
+            if (mod->enabled_counter == 0) {
+                const char *mod_name = pa_proplist_gets(mod->proplist, PA_ALSA_PROP_UCM_NAME);
+
+                pa_log_info("Disable ucm modifier %s", mod_name);
+                if (snd_use_case_set(ucm->ucm_mgr, "_dismod", mod_name) < 0) {
+                    pa_log("Failed to disable ucm modifier %s", mod_name);
+                }
+            }
+
+            break;
+        }
+    }
+}
diff --git a/src/modules/alsa/alsa-ucm.h b/src/modules/alsa/alsa-ucm.h
new file mode 100644 (file)
index 0000000..cdeb469
--- /dev/null
@@ -0,0 +1,184 @@
+#ifndef fooalsaucmhfoo
+#define fooalsaucmhfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2011 Wolfson Microelectronics PLC
+  Author Margarita Olaya <magi@slimlogic.co.uk>
+  Copyright 2012 Feng Wei <wei.feng@freescale.com>, Freescale Ltd.
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <use-case.h>
+
+#include "alsa-mixer.h"
+
+/** For devices: List of verbs, devices or modifiers available */
+#define PA_ALSA_PROP_UCM_NAME                       "alsa.ucm.name"
+
+/** For devices: List of supported devices per verb*/
+#define PA_ALSA_PROP_UCM_DESCRIPTION                "alsa.ucm.description"
+
+/** For devices: Playback device name e.g PlaybackPCM */
+#define PA_ALSA_PROP_UCM_SINK                       "alsa.ucm.sink"
+
+/** For devices: Capture device name e.g CapturePCM*/
+#define PA_ALSA_PROP_UCM_SOURCE                     "alsa.ucm.source"
+
+/** For devices: Playback roles */
+#define PA_ALSA_PROP_UCM_PLAYBACK_ROLES             "alsa.ucm.playback.roles"
+
+/** 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 priority */
+#define PA_ALSA_PROP_UCM_PLAYBACK_PRIORITY          "alsa.ucm.playback.priority"
+
+/** For devices: Playback channels */
+#define PA_ALSA_PROP_UCM_PLAYBACK_CHANNELS          "alsa.ucm.playback.channels"
+
+/** For devices: Capture roles */
+#define PA_ALSA_PROP_UCM_CAPTURE_ROLES              "alsa.ucm.capture.roles"
+
+/** 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 priority */
+#define PA_ALSA_PROP_UCM_CAPTURE_PRIORITY           "alsa.ucm.capture.priority"
+
+/** For devices: Capture channels */
+#define PA_ALSA_PROP_UCM_CAPTURE_CHANNELS           "alsa.ucm.capture.channels"
+
+/** For devices: Quality of Service */
+#define PA_ALSA_PROP_UCM_QOS                        "alsa.ucm.qos"
+
+/** For devices: The modifier (if any) that this device corresponds to */
+#define PA_ALSA_PROP_UCM_MODIFIER "alsa.ucm.modifier"
+
+typedef struct pa_alsa_ucm_verb pa_alsa_ucm_verb;
+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;
+
+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_get_verb(snd_use_case_mgr_t *uc_mgr, const char *verb_name, const char *verb_desc, pa_alsa_ucm_verb **p_verb);
+
+void pa_alsa_ucm_add_ports(
+        pa_hashmap **hash,
+        pa_proplist *proplist,
+        pa_alsa_ucm_mapping_context *context,
+        bool is_sink,
+        pa_card *card);
+void pa_alsa_ucm_add_ports_combination(
+        pa_hashmap *hash,
+        pa_alsa_ucm_mapping_context *context,
+        bool is_sink,
+        pa_hashmap *ports,
+        pa_card_profile *cp,
+        pa_core *core);
+int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *port, bool is_sink);
+
+void pa_alsa_ucm_free(pa_alsa_ucm_config *ucm);
+void pa_alsa_ucm_mapping_context_free(pa_alsa_ucm_mapping_context *context);
+
+void pa_alsa_ucm_roled_stream_begin(pa_alsa_ucm_config *ucm, const char *role, pa_direction_t dir);
+void pa_alsa_ucm_roled_stream_end(pa_alsa_ucm_config *ucm, const char *role, pa_direction_t dir);
+
+/* UCM - Use Case Manager is available on some audio cards */
+
+struct pa_alsa_ucm_device {
+    PA_LLIST_FIELDS(pa_alsa_ucm_device);
+
+    pa_proplist *proplist;
+
+    unsigned playback_priority;
+    unsigned capture_priority;
+
+    unsigned playback_channels;
+    unsigned capture_channels;
+
+    pa_alsa_mapping *playback_mapping;
+    pa_alsa_mapping *capture_mapping;
+
+    pa_idxset *conflicting_devices;
+    pa_idxset *supported_devices;
+
+    pa_alsa_jack *input_jack;
+    pa_alsa_jack *output_jack;
+};
+
+struct pa_alsa_ucm_modifier {
+    PA_LLIST_FIELDS(pa_alsa_ucm_modifier);
+
+    pa_proplist *proplist;
+
+    int n_confdev;
+    int n_suppdev;
+
+    const char **conflicting_devices;
+    const char **supported_devices;
+
+    pa_direction_t action_direction;
+
+    char *media_role;
+
+    /* Non-NULL if the modifier has its own PlaybackPCM/CapturePCM */
+    pa_alsa_mapping *playback_mapping;
+    pa_alsa_mapping *capture_mapping;
+
+    /* Count how many role matched streams are running */
+    int enabled_counter;
+};
+
+struct pa_alsa_ucm_verb {
+    PA_LLIST_FIELDS(pa_alsa_ucm_verb);
+
+    pa_proplist *proplist;
+
+    PA_LLIST_HEAD(pa_alsa_ucm_device, devices);
+    PA_LLIST_HEAD(pa_alsa_ucm_modifier, modifiers);
+};
+
+struct pa_alsa_ucm_config {
+    pa_core *core;
+    snd_use_case_mgr_t *ucm_mgr;
+    pa_alsa_ucm_verb *active_verb;
+
+    PA_LLIST_HEAD(pa_alsa_ucm_verb, verbs);
+    PA_LLIST_HEAD(pa_alsa_jack, jacks);
+};
+
+struct pa_alsa_ucm_mapping_context {
+    pa_alsa_ucm_config *ucm;
+    pa_direction_t direction;
+
+    pa_idxset *ucm_devices;
+    pa_idxset *ucm_modifiers;
+};
+
+#endif
old mode 100644 (file)
new mode 100755 (executable)
index 002e09b..f372851
 #endif
 
 #include <sys/types.h>
-#include <limits.h>
 #include <asoundlib.h>
 
 #include <pulse/sample.h>
 #include <pulse/xmalloc.h>
 #include <pulse/timeval.h>
 #include <pulse/util.h>
-#include <pulse/i18n.h>
 #include <pulse/utf8.h>
 
+#include <pulsecore/i18n.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/atomic.h>
 #include <pulsecore/core-error.h>
-#include <pulsecore/once.h>
 #include <pulsecore/thread.h>
 #include <pulsecore/conf-parser.h>
 #include <pulsecore/core-rtclock.h>
+#ifdef __TIZEN__
+#include <pulsecore/shared.h>
+#endif
 
 #include "alsa-util.h"
 #include "alsa-mixer.h"
 
-#ifdef HAVE_HAL
-#include "hal-util.h"
-#endif
-
 #ifdef HAVE_UDEV
 #include "udev-util.h"
 #endif
 
-#define CUSTOM_BUFFER_MANAGEMENT
-#define CUSTOM_PERIOD_SIZE     1024
+#ifdef __TIZEN__
+#include "tizen-audio.h"
+#endif
 
 static int set_format(snd_pcm_t *pcm_handle, snd_pcm_hw_params_t *hwparams, pa_sample_format_t *f) {
 
@@ -254,6 +252,22 @@ int pa_alsa_set_hw_params(
     if (!pa_alsa_pcm_is_hw(pcm_handle))
         _use_tsched = FALSE;
 
+#if (SND_LIB_VERSION >= ((1<<16)|(0<<8)|24)) /* API additions in 1.0.24 */
+    if (_use_tsched) {
+
+        /* try to disable period wakeups if hardware can do so */
+        if (snd_pcm_hw_params_can_disable_period_wakeup(hwparams)) {
+
+            if ((ret = snd_pcm_hw_params_set_period_wakeup(pcm_handle, hwparams, FALSE)) < 0)
+                /* don't bail, keep going with default mode with period wakeups */
+                pa_log_debug("snd_pcm_hw_params_set_period_wakeup() failed: %s", pa_alsa_strerror(ret));
+            else
+                pa_log_info_verbose("Trying to disable ALSA period wakeups, using timers only");
+        } else
+            pa_log_debug_verbose("cannot disable ALSA period wakeups");
+    }
+#endif
+
     if ((ret = set_format(pcm_handle, hwparams, &_ss.format)) < 0)
         goto finish;
 
@@ -283,29 +297,25 @@ int pa_alsa_set_hw_params(
     }
 
     if (_use_tsched && tsched_size > 0) {
-#ifdef CUSTOM_BUFFER_MANAGEMENT
-        _period_size = CUSTOM_PERIOD_SIZE;
-        _buffer_size = _period_size * 4;
-#else
         _buffer_size = (snd_pcm_uframes_t) (((uint64_t) tsched_size * _ss.rate) / ss->rate);
         _period_size = _buffer_size;
-#endif
     } else {
         _period_size = (snd_pcm_uframes_t) (((uint64_t) _period_size * _ss.rate) / ss->rate);
         _buffer_size = (snd_pcm_uframes_t) (((uint64_t) _buffer_size * _ss.rate) / ss->rate);
     }
 
+    // FIXME : Fix added for VT avsync issue + Reducing voip HW buff size
     if (_buffer_size > 0 || _period_size > 0) {
         snd_pcm_uframes_t max_frames = 0;
 
         if ((ret = snd_pcm_hw_params_get_buffer_size_max(hwparams, &max_frames)) < 0)
             pa_log_warn("snd_pcm_hw_params_get_buffer_size_max() failed: %s", pa_alsa_strerror(ret));
         else
-            pa_log_debug("Maximum hw buffer size is %lu ms", (long unsigned) (max_frames * PA_MSEC_PER_SEC / _ss.rate));
+            pa_log_debug_verbose("Maximum hw buffer size is %lu ms", (long unsigned) (max_frames * PA_MSEC_PER_SEC / _ss.rate));
 
         /* Some ALSA drivers really don't like if we set the buffer
-         * size first and the number of periods second. (which would
-         * make a lot more sense to me) So, try a few combinations
+         * size first and the number of periods second (which would
+         * make a lot more sense to me). So, try a few combinations
          * before we give up. */
 
         if (_buffer_size > 0 && _period_size > 0) {
@@ -315,7 +325,7 @@ int pa_alsa_set_hw_params(
             if (set_buffer_size(pcm_handle, hwparams_copy, _buffer_size) >= 0 &&
                 set_period_size(pcm_handle, hwparams_copy, _period_size) >= 0 &&
                 snd_pcm_hw_params(pcm_handle, hwparams_copy) >= 0) {
-                pa_log_debug("Set buffer size first (to %lu samples), period size second (to %lu samples).", (unsigned long) _buffer_size, (unsigned long) _period_size);
+                pa_log_debug_verbose("Set buffer size first (to %lu samples), period size second (to %lu samples).", (unsigned long) _buffer_size, (unsigned long) _period_size);
                 goto success;
             }
 
@@ -323,7 +333,7 @@ int pa_alsa_set_hw_params(
             if (set_period_size(pcm_handle, hwparams_copy, _period_size) >= 0 &&
                 set_buffer_size(pcm_handle, hwparams_copy, _buffer_size) >= 0 &&
                 snd_pcm_hw_params(pcm_handle, hwparams_copy) >= 0) {
-                pa_log_debug("Set period size first (to %lu samples), buffer size second (to %lu samples).", (unsigned long) _period_size, (unsigned long) _buffer_size);
+                pa_log_debug_verbose("Set period size first (to %lu samples), buffer size second (to %lu samples).", (unsigned long) _period_size, (unsigned long) _buffer_size);
                 goto success;
             }
         }
@@ -334,7 +344,7 @@ int pa_alsa_set_hw_params(
             /* Third try: set only buffer size */
             if (set_buffer_size(pcm_handle, hwparams_copy, _buffer_size) >= 0 &&
                 snd_pcm_hw_params(pcm_handle, hwparams_copy) >= 0) {
-                pa_log_debug("Set only buffer size (to %lu samples).", (unsigned long) _buffer_size);
+                pa_log_debug_verbose("Set only buffer size (to %lu samples).", (unsigned long) _buffer_size);
                 goto success;
             }
         }
@@ -345,7 +355,7 @@ int pa_alsa_set_hw_params(
             /* Fourth try: set only period size */
             if (set_period_size(pcm_handle, hwparams_copy, _period_size) >= 0 &&
                 snd_pcm_hw_params(pcm_handle, hwparams_copy) >= 0) {
-                pa_log_debug("Set only period size (to %lu samples).", (unsigned long) _period_size);
+                pa_log_debug_verbose("Set only period size (to %lu samples).", (unsigned long) _period_size);
                 goto success;
             }
         }
@@ -354,7 +364,7 @@ int pa_alsa_set_hw_params(
     pa_log_debug("Set neither period nor buffer size.");
 
     /* Last chance, set nothing */
-    if  ((ret = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) {
+    if ((ret = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) {
         pa_log_info("snd_pcm_hw_params failed: %s", pa_alsa_strerror(ret));
         goto finish;
     }
@@ -386,6 +396,18 @@ success:
         goto finish;
     }
 
+#if (SND_LIB_VERSION >= ((1<<16)|(0<<8)|24)) /* API additions in 1.0.24 */
+    if (_use_tsched) {
+        unsigned int no_wakeup;
+        /* see if period wakeups were disabled */
+        snd_pcm_hw_params_get_period_wakeup(pcm_handle, hwparams, &no_wakeup);
+        if (no_wakeup == 0)
+            pa_log_debug_verbose("ALSA period wakeups disabled");
+        else
+            pa_log_debug_verbose("ALSA period wakeups were not disabled");
+    }
+#endif
+
     ss->rate = _ss.rate;
     ss->channels = _ss.channels;
     ss->format = _ss.format;
@@ -407,20 +429,42 @@ success:
 
     ret = 0;
 
-    snd_pcm_nonblock(pcm_handle, 1);
-
 finish:
 
     return ret;
 }
 
+#ifdef __TIZEN__
+    // FIXME : Fix added for VT avsync issue + Reducing voip HW buff size
+#define VOIP_WIDE_BAND 16000
+#define VOIP_WB_AVAIL_MIN 160
+#define VOIP_NB_AVAIL_MIN 80
+#endif
+
+#ifdef __TIZEN__
+int pa_alsa_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min, pa_bool_t period_event, int start_threshold,int sampling_rate) {
+#else
 int pa_alsa_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min, pa_bool_t period_event) {
+#endif
     snd_pcm_sw_params_t *swparams;
     snd_pcm_uframes_t boundary;
     int err;
+#ifdef __TIZEN__
+    snd_pcm_uframes_t stop_threshold = 0;
+#endif
 
     pa_assert(pcm);
 
+#ifdef __TIZEN__
+    if (start_threshold > 0) {
+        avail_min = start_threshold;
+    }
+
+    if (pa_alsa_pcm_is_voip(pcm)) {
+    // FIXME : Fix added for VT avsync issue + Reducing voip HW buff size
+        avail_min = (sampling_rate == VOIP_WIDE_BAND) ? VOIP_WB_AVAIL_MIN :VOIP_NB_AVAIL_MIN;
+    }
+#endif
     snd_pcm_sw_params_alloca(&swparams);
 
     if ((err = snd_pcm_sw_params_current(pcm, swparams) < 0)) {
@@ -433,16 +477,35 @@ int pa_alsa_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min, pa_bool_t
         return err;
     }
 
+/* For Qualcomm chipset only. Sometimes, snd_pcm_avail is not changed during playback(e.g.shutter), so we adjust parameters */
+#ifdef __TIZEN__
+    if ((err = snd_pcm_sw_params_set_tstamp_mode(pcm, swparams, SND_PCM_TSTAMP_NONE)) < 0) {
+        pa_log_warn("Unable to enable time stamping: %s\n", pa_alsa_strerror(err));
+        return err;
+    }
+#else
     if ((err = snd_pcm_sw_params_set_tstamp_mode(pcm, swparams, SND_PCM_TSTAMP_ENABLE)) < 0) {
         pa_log_warn("Unable to enable time stamping: %s\n", pa_alsa_strerror(err));
         return err;
     }
+#endif
 
     if ((err = snd_pcm_sw_params_get_boundary(swparams, &boundary)) < 0) {
         pa_log_warn("Unable to get boundary: %s\n", pa_alsa_strerror(err));
         return err;
     }
 
+#ifdef __TIZEN__
+    if ((err = snd_pcm_sw_params_set_stop_threshold(pcm, swparams, (stop_threshold)? stop_threshold:boundary)) < 0) {
+        pa_log_warn("Unable to set stop threshold: %s\n", pa_alsa_strerror(err));
+        return err;
+    }
+
+    if ((err = snd_pcm_sw_params_set_start_threshold(pcm, swparams, (start_threshold > 0)? (snd_pcm_uframes_t)start_threshold : avail_min)) < 0) {
+        pa_log_warn("Unable to set start threshold: %s\n", pa_alsa_strerror(err));
+        return err;
+    }
+#else
     if ((err = snd_pcm_sw_params_set_stop_threshold(pcm, swparams, boundary)) < 0) {
         pa_log_warn("Unable to set stop threshold: %s\n", pa_alsa_strerror(err));
         return err;
@@ -452,6 +515,7 @@ int pa_alsa_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min, pa_bool_t
         pa_log_warn("Unable to set start threshold: %s\n", pa_alsa_strerror(err));
         return err;
     }
+#endif
 
     if ((err = snd_pcm_sw_params_set_avail_min(pcm, swparams, avail_min)) < 0) {
         pa_log_error("snd_pcm_sw_params_set_avail_min() failed: %s", pa_alsa_strerror(err));
@@ -467,6 +531,9 @@ int pa_alsa_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min, pa_bool_t
 }
 
 snd_pcm_t *pa_alsa_open_by_device_id_auto(
+#ifdef __TIZEN__
+        pa_core *c,
+#endif
         const char *dev_id,
         char **dev,
         pa_sample_spec *ss,
@@ -505,6 +572,9 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto(
         pa_log_debug("Checking for superset %s (%s)", m->name, m->device_strings[0]);
 
         pcm_handle = pa_alsa_open_by_device_id_mapping(
+#ifdef __TIZEN__
+                c,
+#endif
                 dev_id,
                 dev,
                 ss,
@@ -532,6 +602,9 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto(
         pa_log_debug("Checking for subset %s (%s)", m->name, m->device_strings[0]);
 
         pcm_handle = pa_alsa_open_by_device_id_mapping(
+#ifdef __TIZEN__
+                c,
+#endif
                 dev_id,
                 dev,
                 ss,
@@ -556,6 +629,9 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto(
     d = pa_sprintf_malloc("hw:%s", dev_id);
     pa_log_debug("Trying %s as last resort...", d);
     pcm_handle = pa_alsa_open_by_device_string(
+#ifdef __TIZEN__
+            c,
+#endif
             d,
             dev,
             ss,
@@ -576,6 +652,9 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto(
 }
 
 snd_pcm_t *pa_alsa_open_by_device_id_mapping(
+#ifdef __TIZEN__
+        pa_core *c,
+#endif
         const char *dev_id,
         char **dev,
         pa_sample_spec *ss,
@@ -604,6 +683,9 @@ snd_pcm_t *pa_alsa_open_by_device_id_mapping(
     try_map = m->channel_map;
 
     pcm_handle = pa_alsa_open_by_template(
+#ifdef __TIZEN__
+            c,
+#endif
             m->device_strings,
             dev_id,
             dev,
@@ -615,7 +697,7 @@ snd_pcm_t *pa_alsa_open_by_device_id_mapping(
             tsched_size,
             use_mmap,
             use_tsched,
-            TRUE);
+            pa_channel_map_valid(&m->channel_map) /* Query the channel count if we don't know what we want */);
 
     if (!pcm_handle)
         return NULL;
@@ -628,6 +710,9 @@ snd_pcm_t *pa_alsa_open_by_device_id_mapping(
 }
 
 snd_pcm_t *pa_alsa_open_by_device_string(
+#ifdef __TIZEN__
+        pa_core *c,
+#endif
         const char *device,
         char **dev,
         pa_sample_spec *ss,
@@ -644,6 +729,12 @@ snd_pcm_t *pa_alsa_open_by_device_string(
     char *d;
     snd_pcm_t *pcm_handle;
     pa_bool_t reformat = FALSE;
+#ifdef __TIZEN__
+    int ret = 0;
+    int hdmi_ch_enum_val = 0;
+    void *audio_data = NULL;
+    audio_interface_t *audio_intf = NULL;
+#endif
 
     pa_assert(device);
     pa_assert(ss);
@@ -654,6 +745,19 @@ snd_pcm_t *pa_alsa_open_by_device_string(
     for (;;) {
         pa_log_debug("Trying %s %s SND_PCM_NO_AUTO_FORMAT ...", d, reformat ? "without" : "with");
 
+#ifdef __TIZEN__
+        audio_data = pa_shared_get(c, "tizen-audio-data");
+        audio_intf = pa_shared_get(c, "tizen-audio-interface");
+        if (audio_intf && audio_intf->alsa_pcm_open) {
+            audio_return_t audio_ret = AUDIO_RET_OK;
+
+            if (AUDIO_IS_ERROR((audio_ret = audio_intf->alsa_pcm_open(audio_data, (void **)&pcm_handle, d, (mode == SND_PCM_STREAM_PLAYBACK) ? AUDIO_DIRECTION_OUT : AUDIO_DIRECTION_IN,
+                SND_PCM_NONBLOCK | SND_PCM_NO_AUTO_RESAMPLE | SND_PCM_NO_AUTO_CHANNELS | (reformat ? 0 : SND_PCM_NO_AUTO_FORMAT))))) {
+                pa_log("Error opening PCM device %s: %x", d, audio_ret);
+                goto fail;
+            }
+        } else
+#endif
         if ((err = snd_pcm_open(&pcm_handle, d, mode,
                                 SND_PCM_NONBLOCK|
                                 SND_PCM_NO_AUTO_RESAMPLE|
@@ -665,6 +769,31 @@ snd_pcm_t *pa_alsa_open_by_device_string(
 
         pa_log_debug("Managed to open %s", d);
 
+#if 0
+#ifdef __TIZEN__
+        if (pa_streq (d, "hw:0,1")) {
+            hdmi_ch_enum_val = ss->channels - 2;
+            ret = pa_alsa_set_mixer_control("HDMI_RX Channels", hdmi_ch_enum_val);
+            pa_log_warn("This is HDMI(%s) device, set channelinfo(%d) mixer, ret=%d", d, hdmi_ch_enum_val, ret);
+        }
+#ifndef TIZEN_MICRO
+        if(pa_streq(d, "hw:0,0") || pa_streq(d, "hw:0,4")) {
+            if (ss->rate >= 192000 && ss->format == PA_SAMPLE_S24_32LE) {
+                ret = pa_alsa_set_mixer_control("SLIM_0_RX FormatSLIM_0_RX Format", 1);
+                pa_log_warn("ret(%d), device(%s), SLIM_0_RX Format(%d:%s)", ret, d, 1, "S24_LE");
+                ret = pa_alsa_set_mixer_control("SLIM_0_RX SampleRate", 2);
+                pa_log_warn("ret(%d), device(%s), SLIM_0_RX SampleRate(%d:%s)", ret, d, 2, "KHZ_192");
+            } else {
+                ret = pa_alsa_set_mixer_control("SLIM_0_RX Format", 0);
+                pa_log_warn("ret(%d), device(%s), SLIM_0_RX Format(%d:%s)", ret, d, 0, "S16_LE");
+                ret = pa_alsa_set_mixer_control("SLIM_0_RX SampleRate", 0);
+                pa_log_warn("ret(%d), device(%s), SLIM_0_RX SampleRate(%d:%s)", ret, d, 0, "KHZ_48");
+            }
+        }
+#endif
+#endif
+#endif
+
         if ((err = pa_alsa_set_hw_params(
                      pcm_handle,
                      ss,
@@ -678,6 +807,11 @@ snd_pcm_t *pa_alsa_open_by_device_string(
             if (!reformat) {
                 reformat = TRUE;
 
+#ifdef __TIZEN__
+                if (audio_data && audio_intf && audio_intf->alsa_pcm_close) {
+                    audio_intf->alsa_pcm_close(audio_data, pcm_handle);
+                } else
+#endif
                 snd_pcm_close(pcm_handle);
                 continue;
             }
@@ -692,11 +826,21 @@ snd_pcm_t *pa_alsa_open_by_device_string(
 
                 reformat = FALSE;
 
+#ifdef __TIZEN__
+                if (audio_data && audio_intf && audio_intf->alsa_pcm_close) {
+                    audio_intf->alsa_pcm_close(audio_data, pcm_handle);
+                } else
+#endif
                 snd_pcm_close(pcm_handle);
                 continue;
             }
 
             pa_log_info("Failed to set hardware parameters on %s: %s", d, pa_alsa_strerror(err));
+#ifdef __TIZEN__
+            if (audio_data && audio_intf && audio_intf->alsa_pcm_close) {
+                audio_intf->alsa_pcm_close(audio_data, pcm_handle);
+            } else
+#endif
             snd_pcm_close(pcm_handle);
 
             goto fail;
@@ -720,6 +864,9 @@ fail:
 }
 
 snd_pcm_t *pa_alsa_open_by_template(
+#ifdef __TIZEN__
+        pa_core *c,
+#endif
         char **template,
         const char *dev_id,
         char **dev,
@@ -742,6 +889,9 @@ snd_pcm_t *pa_alsa_open_by_template(
         d = pa_replace(*i, "%f", dev_id);
 
         pcm_handle = pa_alsa_open_by_device_string(
+#ifdef __TIZEN__
+                c,
+#endif
                 d,
                 dev,
                 ss,
@@ -803,12 +953,12 @@ void pa_alsa_dump_status(snd_pcm_t *pcm) {
     }
 
     if ((err = snd_pcm_status_dump(status, out)) < 0) {
-        pa_log_debug("snd_pcm_dump(): %s", pa_alsa_strerror(err));
+        pa_log_debug("snd_pcm_status_dump(): %s", pa_alsa_strerror(err));
         goto finish;
     }
 
     snd_output_buffer_string(out, &s);
-    pa_log_debug("snd_pcm_dump():\n%s", pa_strnull(s));
+    pa_log_debug("snd_pcm_status_dump():\n%s", pa_strnull(s));
 
 finish:
 
@@ -866,7 +1016,7 @@ pa_bool_t pa_alsa_init_description(pa_proplist *p) {
     k = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_DESCRIPTION);
 
     if (d && k)
-        pa_proplist_setf(p, PA_PROP_DEVICE_DESCRIPTION, _("%s %s"), d, k);
+        pa_proplist_setf(p, PA_PROP_DEVICE_DESCRIPTION, "%s %s", d, k);
     else if (d)
         pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, d);
 
@@ -882,12 +1032,12 @@ void pa_alsa_init_proplist_card(pa_core *c, pa_proplist *p, int card) {
     pa_proplist_setf(p, "alsa.card", "%i", card);
 
     if (snd_card_get_name(card, &cn) >= 0) {
-        pa_proplist_sets(p, "alsa.card_name", cn);
+        pa_proplist_sets(p, "alsa.card_name", pa_strip(cn));
         free(cn);
     }
 
     if (snd_card_get_longname(card, &lcn) >= 0) {
-        pa_proplist_sets(p, "alsa.long_card_name", lcn);
+        pa_proplist_sets(p, "alsa.long_card_name", pa_strip(lcn));
         free(lcn);
     }
 
@@ -899,10 +1049,6 @@ void pa_alsa_init_proplist_card(pa_core *c, pa_proplist *p, int card) {
 #ifdef HAVE_UDEV
     pa_udev_get_info(card, p);
 #endif
-
-#ifdef HAVE_HAL
-    pa_hal_get_info(c, p, card);
-#endif
 }
 
 void pa_alsa_init_proplist_pcm_info(pa_core *c, pa_proplist *p, snd_pcm_info_t *pcm_info) {
@@ -945,8 +1091,11 @@ void pa_alsa_init_proplist_pcm_info(pa_core *c, pa_proplist *p, snd_pcm_info_t *
         if (alsa_subclass_table[subclass])
             pa_proplist_sets(p, "alsa.subclass", alsa_subclass_table[subclass]);
 
-    if ((n = snd_pcm_info_get_name(pcm_info)))
-        pa_proplist_sets(p, "alsa.name", n);
+    if ((n = snd_pcm_info_get_name(pcm_info))) {
+        char *t = pa_xstrdup(n);
+        pa_proplist_sets(p, "alsa.name", pa_strip(t));
+        pa_xfree(t);
+    }
 
     if ((id = snd_pcm_info_get_id(pcm_info)))
         pa_proplist_sets(p, "alsa.id", id);
@@ -1109,8 +1258,8 @@ snd_pcm_sframes_t pa_alsa_safe_avail(snd_pcm_t *pcm, size_t hwbuf_size, const pa
 
     k = (size_t) n * pa_frame_size(ss);
 
-    if (k >= hwbuf_size * 5 ||
-        k >= pa_bytes_per_second(ss)*10) {
+    if (PA_UNLIKELY(k >= hwbuf_size * 5 ||
+                    k >= pa_bytes_per_second(ss)*10)) {
 
         PA_ONCE_BEGIN {
             char *dn = pa_alsa_get_driver_name_by_pcm(pcm);
@@ -1130,10 +1279,12 @@ snd_pcm_sframes_t pa_alsa_safe_avail(snd_pcm_t *pcm, size_t hwbuf_size, const pa
     return n;
 }
 
-int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delay, size_t hwbuf_size, const pa_sample_spec *ss) {
+int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_status_t *status, snd_pcm_sframes_t *delay, size_t hwbuf_size, const pa_sample_spec *ss,
+                       pa_bool_t capture) {
     ssize_t k;
     size_t abs_k;
-    int r;
+    int err;
+    snd_pcm_sframes_t avail = 0;
 
     pa_assert(pcm);
     pa_assert(delay);
@@ -1141,17 +1292,24 @@ int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delay, size_t hwbuf_si
     pa_assert(ss);
 
     /* Some ALSA driver expose weird bugs, let's inform the user about
-     * what is going on */
+     * what is going on. We're going to get both the avail and delay values so
+     * that we can compare and check them for capture.
+     * This is done with snd_pcm_status() which provides
+     * avail, delay and timestamp values in a single kernel call to improve
+     * timer-based scheduling */
 
-    if ((r = snd_pcm_delay(pcm, delay)) < 0)
-        return r;
+    if ((err = snd_pcm_status(pcm, status)) < 0)
+        return err;
+
+    avail = snd_pcm_status_get_avail(status);
+    *delay = snd_pcm_status_get_delay(status);
 
     k = (ssize_t) *delay * (ssize_t) pa_frame_size(ss);
 
     abs_k = k >= 0 ? (size_t) k : (size_t) -k;
 
-    if (abs_k >= hwbuf_size * 5 ||
-        abs_k >= pa_bytes_per_second(ss)*10) {
+    if (PA_UNLIKELY(abs_k >= hwbuf_size * 5 ||
+                    abs_k >= pa_bytes_per_second(ss)*10)) {
 
         PA_ONCE_BEGIN {
             char *dn = pa_alsa_get_driver_name_by_pcm(pcm);
@@ -1172,6 +1330,44 @@ int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delay, size_t hwbuf_si
             *delay = (snd_pcm_sframes_t) (hwbuf_size / pa_frame_size(ss));
     }
 
+    if (capture) {
+        abs_k = (size_t) avail * pa_frame_size(ss);
+
+        if (PA_UNLIKELY(abs_k >= hwbuf_size * 5 ||
+                        abs_k >= pa_bytes_per_second(ss)*10)) {
+
+            PA_ONCE_BEGIN {
+                char *dn = pa_alsa_get_driver_name_by_pcm(pcm);
+                pa_log(_("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."),
+                       (unsigned long) k,
+                       (unsigned long) (pa_bytes_to_usec(k, ss) / PA_USEC_PER_MSEC),
+                       pa_strnull(dn));
+                pa_xfree(dn);
+                pa_alsa_dump(PA_LOG_ERROR, pcm);
+            } PA_ONCE_END;
+
+            /* Mhmm, let's try not to fail completely */
+            avail = (snd_pcm_sframes_t) (hwbuf_size / pa_frame_size(ss));
+        }
+
+        if (PA_UNLIKELY(*delay < avail)) {
+            PA_ONCE_BEGIN {
+                char *dn = pa_alsa_get_driver_name_by_pcm(pcm);
+                pa_log(_("snd_pcm_avail_delay() returned strange values: delay %lu is less than avail %lu.\n"
+                         "Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers."),
+                       (unsigned long) *delay,
+                       (unsigned long) avail,
+                       pa_strnull(dn));
+                pa_xfree(dn);
+                pa_alsa_dump(PA_LOG_ERROR, pcm);
+            } PA_ONCE_END;
+
+            /* try to fixup */
+            *delay = avail;
+        }
+    }
+
     return 0;
 }
 
@@ -1196,10 +1392,9 @@ int pa_alsa_safe_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas
 
     k = (size_t) *frames * pa_frame_size(ss);
 
-    if (*frames > before ||
-        k >= hwbuf_size * 3 ||
-        k >= pa_bytes_per_second(ss)*10)
-
+    if (PA_UNLIKELY(*frames > before ||
+                    k >= hwbuf_size * 3 ||
+                    k >= pa_bytes_per_second(ss)*10))
         PA_ONCE_BEGIN {
             char *dn = pa_alsa_get_driver_name_by_pcm(pcm);
             pa_log(_("snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes (%lu ms).\n"
@@ -1269,6 +1464,57 @@ char *pa_alsa_get_reserve_name(const char *device) {
     return pa_sprintf_malloc("Audio%i", i);
 }
 
+unsigned int *pa_alsa_get_supported_rates(snd_pcm_t *pcm, unsigned int fallback_rate) {
+    static unsigned int all_rates[] = { 8000, 11025, 12000,
+                                        16000, 22050, 24000,
+                                        32000, 44100, 48000,
+                                        64000, 88200, 96000,
+                                        128000, 176400, 192000,
+                                        384000 };
+    pa_bool_t supported[PA_ELEMENTSOF(all_rates)] = { FALSE, };
+    snd_pcm_hw_params_t *hwparams;
+    unsigned int i, j, n, *rates = NULL;
+    int ret;
+
+    snd_pcm_hw_params_alloca(&hwparams);
+
+    if ((ret = snd_pcm_hw_params_any(pcm, hwparams)) < 0) {
+        pa_log_debug("snd_pcm_hw_params_any() failed: %s", pa_alsa_strerror(ret));
+        return NULL;
+    }
+
+    for (i = 0, n = 0; i < PA_ELEMENTSOF(all_rates); i++) {
+        if (snd_pcm_hw_params_test_rate(pcm, hwparams, all_rates[i], 0) == 0) {
+            supported[i] = TRUE;
+            n++;
+        }
+    }
+
+    if (n > 0) {
+        rates = pa_xnew(unsigned int, n + 1);
+
+        for (i = 0, j = 0; i < PA_ELEMENTSOF(all_rates); i++) {
+            if (supported[i])
+                rates[j++] = all_rates[i];
+        }
+
+        rates[j] = 0;
+    } else {
+        rates = pa_xnew(unsigned int, 2);
+
+        rates[0] = fallback_rate;
+        if ((ret = snd_pcm_hw_params_set_rate_near(pcm, hwparams, &rates[0], NULL)) < 0) {
+            pa_log_debug("snd_pcm_hw_params_set_rate_near() failed: %s", pa_alsa_strerror(ret));
+            pa_xfree(rates);
+            return NULL;
+        }
+
+        rates[1] = 0;
+    }
+
+    return rates;
+}
+
 pa_bool_t pa_alsa_pcm_is_hw(snd_pcm_t *pcm) {
     snd_pcm_info_t* info;
     snd_pcm_info_alloca(&info);
@@ -1293,6 +1539,27 @@ pa_bool_t pa_alsa_pcm_is_modem(snd_pcm_t *pcm) {
     return snd_pcm_info_get_class(info) == SND_PCM_CLASS_MODEM;
 }
 
+#ifdef __TIZEN__
+pa_bool_t pa_alsa_pcm_is_voip(snd_pcm_t *pcm) {
+    char *id = NULL;
+    snd_pcm_info_t* info;
+    snd_pcm_info_alloca(&info);
+
+    pa_assert(pcm);
+
+    if (snd_pcm_info(pcm, info) < 0)
+        return FALSE;
+
+    if (!(id = snd_pcm_info_get_id(info)))
+        return FALSE;
+
+    if(!strncmp(id, "VoIP",4))
+        return TRUE;
+
+    return FALSE;
+}
+#endif
+
 PA_STATIC_TLS_DECLARE(cstrerror, pa_xfree);
 
 const char* pa_alsa_strerror(int errnum) {
@@ -1339,6 +1606,284 @@ pa_bool_t pa_alsa_may_tsched(pa_bool_t want) {
         return FALSE;
     }
 
-
     return TRUE;
 }
+
+snd_hctl_elem_t* pa_alsa_find_jack(snd_hctl_t *hctl, const char* jack_name)
+{
+    snd_ctl_elem_id_t *id;
+
+    snd_ctl_elem_id_alloca(&id);
+    snd_ctl_elem_id_clear(id);
+    snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_CARD);
+    snd_ctl_elem_id_set_name(id, jack_name);
+
+    return snd_hctl_find_elem(hctl, id);
+}
+
+snd_hctl_elem_t* pa_alsa_find_eld_ctl(snd_hctl_t *hctl, int device) {
+    snd_ctl_elem_id_t *id;
+
+    /* See if we can find the ELD control */
+    snd_ctl_elem_id_alloca(&id);
+    snd_ctl_elem_id_clear(id);
+    snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_PCM);
+    snd_ctl_elem_id_set_name(id, "ELD");
+    snd_ctl_elem_id_set_device(id, device);
+
+    return snd_hctl_find_elem(hctl, id);
+}
+
+
+static int prepare_mixer(snd_mixer_t *mixer, const char *dev, snd_hctl_t **hctl) {
+    int err;
+
+    pa_assert(mixer);
+    pa_assert(dev);
+
+    if ((err = snd_mixer_attach(mixer, dev)) < 0) {
+        pa_log_info("Unable to attach to mixer %s: %s", dev, pa_alsa_strerror(err));
+        return -1;
+    }
+
+    /* Note: The hctl handle returned should not be freed.
+       It is closed/freed by alsa-lib on snd_mixer_close/free */
+    if (hctl && (err = snd_mixer_get_hctl(mixer, dev, hctl)) < 0) {
+        pa_log_info("Unable to get hctl of mixer %s: %s", dev, pa_alsa_strerror(err));
+        return -1;
+    }
+
+    if ((err = snd_mixer_selem_register(mixer, NULL, NULL)) < 0) {
+        pa_log_warn("Unable to register mixer: %s", pa_alsa_strerror(err));
+        return -1;
+    }
+
+    if ((err = snd_mixer_load(mixer)) < 0) {
+        pa_log_warn("Unable to load mixer: %s", pa_alsa_strerror(err));
+        return -1;
+    }
+
+    pa_log_info("Successfully attached to mixer '%s'", dev);
+    return 0;
+}
+
+snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device, snd_hctl_t **hctl) {
+    int err;
+    snd_mixer_t *m;
+    char *md;
+    snd_pcm_info_t* info;
+    snd_pcm_info_alloca(&info);
+
+    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, hctl) >= 0) {
+
+        if (ctl_device)
+            *ctl_device = md;
+        else
+            pa_xfree(md);
+
+        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, snd_hctl_t **hctl) {
+    int err;
+    snd_mixer_t *m;
+    const char *dev;
+    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, hctl) >= 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, hctl) >= 0) {
+
+                    if (ctl_device)
+                        *ctl_device = md;
+                    else
+                        pa_xfree(md);
+
+                    return m;
+                }
+
+            pa_xfree(md);
+        }
+    }
+
+    snd_mixer_close(m);
+    return NULL;
+}
+
+int pa_alsa_get_hdmi_eld(snd_hctl_t *hctl, int device, pa_hdmi_eld *eld) {
+
+    /* The ELD format is specific to HDA Intel sound cards and defined in the
+       HDA specification: http://www.intel.com/content/www/us/en/standards/high-definition-audio-specification.html */
+    int err;
+    snd_hctl_elem_t *elem;
+    snd_ctl_elem_info_t *info;
+    snd_ctl_elem_value_t *value;
+    uint8_t *elddata;
+    unsigned int eldsize, mnl;
+
+    pa_assert(eld != NULL);
+
+    /* See if we can find the ELD control */
+    elem = pa_alsa_find_eld_ctl(hctl, device);
+    if (elem == NULL) {
+        pa_log_debug("No ELD info control found (for device=%d)", device);
+        return -1;
+    }
+
+    /* Does it have any contents? */
+    snd_ctl_elem_info_alloca(&info);
+    snd_ctl_elem_value_alloca(&value);
+    if ((err = snd_hctl_elem_info(elem, info)) < 0 ||
+       (err = snd_hctl_elem_read(elem, value)) < 0) {
+        pa_log_warn("Accessing ELD control failed with error %s", snd_strerror(err));
+        return -1;
+    }
+
+    eldsize = snd_ctl_elem_info_get_count(info);
+    elddata = (unsigned char *) snd_ctl_elem_value_get_bytes(value);
+    if (elddata == NULL || eldsize == 0) {
+        pa_log_debug("ELD info empty (for device=%d)", device);
+        return -1;
+    }
+    if (eldsize < 20 || eldsize > 256) {
+        pa_log_debug("ELD info has wrong size (for device=%d)", device);
+        return -1;
+    }
+
+    /* Try to fetch monitor name */
+    mnl = elddata[4] & 0x1f;
+    if (mnl == 0 || mnl > 16 || 20 + mnl > eldsize) {
+        pa_log_debug("No monitor name in ELD info (for device=%d)", device);
+        mnl = 0;
+    }
+    memcpy(eld->monitor_name, &elddata[20], mnl);
+    eld->monitor_name[mnl] = '\0';
+    if (mnl)
+        pa_log_debug("Monitor name in ELD info is '%s' (for device=%d)", eld->monitor_name, device);
+
+    return 0;
+}
+
+#ifdef __TIZEN__
+int pa_alsa_set_mixer_control(const char *ctl_name, int val)
+{
+    snd_ctl_t *handle;
+    snd_ctl_elem_value_t *control;
+    snd_ctl_elem_id_t *id;
+    snd_ctl_elem_info_t *info;
+    snd_ctl_elem_type_t type;
+
+    char *card_name = NULL;
+    int ret = 0, count = 0, i = 0;
+
+    snd_card_get_name(0, &card_name);
+    if(!card_name)
+        card_name = strdup("default");
+
+    ret = snd_ctl_open(&handle, card_name, 0);
+    if (ret < 0) {
+        pa_log_error("snd_ctl_open error, card: %s: %s", card_name, snd_strerror(ret));
+        if (card_name != NULL) {
+            free(card_name);
+            card_name = NULL;
+        }
+        return -1;
+    }
+    if (card_name != NULL) {
+        free(card_name);
+        card_name = NULL;
+    }
+    // Get Element Info
+
+    snd_ctl_elem_id_alloca(&id);
+    snd_ctl_elem_info_alloca(&info);
+    snd_ctl_elem_value_alloca(&control);
+
+    snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
+    snd_ctl_elem_id_set_name(id, ctl_name);
+
+    snd_ctl_elem_info_set_id(info, id);
+    if(snd_ctl_elem_info(handle, info) < 0 ) {
+        pa_log_error("Cannot find control element: %s", ctl_name);
+        goto close;
+    }
+    snd_ctl_elem_info_get_id(info, id);
+
+    type = snd_ctl_elem_info_get_type(info);
+    count = snd_ctl_elem_info_get_count(info);
+
+    snd_ctl_elem_value_set_id(control, id);
+
+    snd_ctl_elem_read(handle, control);
+
+    pa_log_debug("type(%d), count(%d): ", type, count);
+
+    switch (type) {
+    case SND_CTL_ELEM_TYPE_BOOLEAN:
+        for (i = 0; i < count; i++)
+            snd_ctl_elem_value_set_boolean(control, i, val);
+        break;
+    case SND_CTL_ELEM_TYPE_INTEGER:
+        for (i = 0; i < count; i++)
+            snd_ctl_elem_value_set_integer(control, i,val);
+        break;
+    case SND_CTL_ELEM_TYPE_ENUMERATED:
+        for (i = 0; i < count; i++)
+            snd_ctl_elem_value_set_enumerated(control, i,val);
+        break;
+
+    default:
+        pa_log_warn("unsupported control element type");
+        goto close;
+    }
+
+    snd_ctl_elem_write(handle, control);
+
+    snd_ctl_close(handle);
+
+    return 0;
+
+close:
+    pa_log_error("Error");
+    snd_ctl_close(handle);
+    return -1;
+}
+#endif
old mode 100644 (file)
new mode 100755 (executable)
index 1d1256b..3c18b81
 #include <asoundlib.h>
 
 #include <pulse/sample.h>
-#include <pulse/volume.h>
-#include <pulse/mainloop-api.h>
 #include <pulse/channelmap.h>
 #include <pulse/proplist.h>
-#include <pulse/volume.h>
 
-#include <pulsecore/llist.h>
 #include <pulsecore/rtpoll.h>
 #include <pulsecore/core.h>
 #include <pulsecore/log.h>
@@ -49,13 +45,25 @@ int pa_alsa_set_hw_params(
         pa_bool_t *use_tsched,             /* modified at return */
         pa_bool_t require_exact_channel_number);
 
+#ifdef __TIZEN__
+int pa_alsa_set_sw_params(
+        snd_pcm_t *pcm,
+        snd_pcm_uframes_t avail_min,
+        pa_bool_t period_event,
+        int start_threshold,
+        int sampling_rate );
+#else
 int pa_alsa_set_sw_params(
         snd_pcm_t *pcm,
         snd_pcm_uframes_t avail_min,
         pa_bool_t period_event);
+#endif
 
 /* Picks a working mapping from the profile set based on the specified ss/map */
 snd_pcm_t *pa_alsa_open_by_device_id_auto(
+#ifdef __TIZEN__
+        pa_core *c,
+#endif
         const char *dev_id,
         char **dev,                       /* modified at return */
         pa_sample_spec *ss,               /* modified at return */
@@ -71,6 +79,9 @@ snd_pcm_t *pa_alsa_open_by_device_id_auto(
 
 /* Uses the specified mapping */
 snd_pcm_t *pa_alsa_open_by_device_id_mapping(
+#ifdef __TIZEN__
+        pa_core *c,
+#endif
         const char *dev_id,
         char **dev,                       /* modified at return */
         pa_sample_spec *ss,               /* modified at return */
@@ -85,6 +96,9 @@ snd_pcm_t *pa_alsa_open_by_device_id_mapping(
 
 /* Opens the explicit ALSA device */
 snd_pcm_t *pa_alsa_open_by_device_string(
+#ifdef __TIZEN__
+        pa_core *c,
+#endif
         const char *dir,
         char **dev,                       /* modified at return */
         pa_sample_spec *ss,               /* modified at return */
@@ -99,6 +113,9 @@ snd_pcm_t *pa_alsa_open_by_device_string(
 
 /* Opens the explicit ALSA device with a fallback list */
 snd_pcm_t *pa_alsa_open_by_template(
+#ifdef __TIZEN__
+        pa_core *c,
+#endif
         char **template,
         const char *dev_id,
         char **dev,                       /* modified at return */
@@ -129,7 +146,7 @@ int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents);
 pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll);
 
 snd_pcm_sframes_t pa_alsa_safe_avail(snd_pcm_t *pcm, size_t hwbuf_size, const pa_sample_spec *ss);
-int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delay, size_t hwbuf_size, const pa_sample_spec *ss);
+int pa_alsa_safe_delay(snd_pcm_t *pcm, snd_pcm_status_t *status, snd_pcm_sframes_t *delay, size_t hwbuf_size, const pa_sample_spec *ss, pa_bool_t capture);
 int pa_alsa_safe_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames, size_t hwbuf_size, const pa_sample_spec *ss);
 
 char *pa_alsa_get_driver_name(int card);
@@ -137,11 +154,32 @@ char *pa_alsa_get_driver_name_by_pcm(snd_pcm_t *pcm);
 
 char *pa_alsa_get_reserve_name(const char *device);
 
+unsigned int *pa_alsa_get_supported_rates(snd_pcm_t *pcm, unsigned int fallback_rate);
+
 pa_bool_t pa_alsa_pcm_is_hw(snd_pcm_t *pcm);
 pa_bool_t pa_alsa_pcm_is_modem(snd_pcm_t *pcm);
+#ifdef __TIZEN__
+pa_bool_t pa_alsa_pcm_is_voip(snd_pcm_t *pcm);
+#endif
 
 const char* pa_alsa_strerror(int errnum);
 
 pa_bool_t pa_alsa_may_tsched(pa_bool_t want);
 
+snd_hctl_elem_t* pa_alsa_find_jack(snd_hctl_t *hctl, const char* jack_name);
+snd_hctl_elem_t* pa_alsa_find_eld_ctl(snd_hctl_t *hctl, int device);
+
+snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device, snd_hctl_t **hctl);
+
+typedef struct pa_hdmi_eld pa_hdmi_eld;
+struct pa_hdmi_eld {
+    char monitor_name[17];
+};
+
+int pa_alsa_get_hdmi_eld(snd_hctl_t *hctl, int device, pa_hdmi_eld *eld);
+
+#ifdef __TIZEN__
+int pa_alsa_set_mixer_control(const char *ctl_name, int val);
+#endif
+
 #endif
index db78eb4..e6aa064 100644 (file)
@@ -19,7 +19,7 @@
 ; See analog-output.conf.common for an explanation on the directives
 
 [General]
-priority = 90
+priority = 80
 name = analog-input
 
 [Element Capture]
@@ -32,6 +32,10 @@ override-map.2 = all-left,all-right
 switch = off
 volume = off
 
+[Element Internal Mic]
+switch = off
+volume = off
+
 [Element Line]
 switch = off
 volume = off
diff --git a/src/modules/alsa/mixer/paths/analog-input-dock-mic.conf b/src/modules/alsa/mixer/paths/analog-input-dock-mic.conf
new file mode 100644 (file)
index 0000000..f6ea94b
--- /dev/null
@@ -0,0 +1,105 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; For devices where a 'Dock Mic' or 'Dock Mic Boost' element exists
+;
+; See analog-output.conf.common for an explanation on the directives
+
+[General]
+priority = 78
+name = analog-input-microphone-dock
+
+[Jack Dock Mic]
+required-any = any
+
+[Jack Dock Mic Phantom]
+state.plugged = unknown
+state.unplugged = unknown
+required-any = any
+
+[Element Dock Mic Boost]
+required-any = any
+switch = select
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Option Dock Mic Boost:on]
+name = input-boost-on
+
+[Option Dock Mic Boost:off]
+name = input-boost-off
+
+[Element Dock Mic]
+required-any = any
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Capture]
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Input Source]
+enumeration = select
+
+[Option Input Source:Dock Mic]
+name = analog-input-microphone-dock
+required-any = any
+
+[Element Capture Source]
+enumeration = select
+
+[Option Capture Source:Dock Mic]
+name = analog-input-microphone-dock
+required-any = any
+
+[Element Mic]
+switch = off
+volume = off
+
+[Element Internal Mic]
+switch = off
+volume = off
+
+[Element Front Mic]
+switch = off
+volume = off
+
+[Element Rear Mic]
+switch = off
+volume = off
+
+[Element Mic Boost]
+switch = off
+volume = off
+
+[Element Internal Mic Boost]
+switch = off
+volume = off
+
+[Element Front Mic Boost]
+switch = off
+volume = off
+
+[Element Rear Mic Boost]
+switch = off
+volume = off
+
+.include analog-input-mic.conf.common
index baf674a..7f150e3 100644 (file)
@@ -32,6 +32,10 @@ override-map.2 = all-left,all-right
 switch = off
 volume = off
 
+[Element Internal Mic]
+switch = off
+volume = off
+
 [Element Line]
 switch = off
 volume = off
diff --git a/src/modules/alsa/mixer/paths/analog-input-front-mic.conf b/src/modules/alsa/mixer/paths/analog-input-front-mic.conf
new file mode 100644 (file)
index 0000000..bb2e806
--- /dev/null
@@ -0,0 +1,105 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; For devices where a 'Front Mic' or 'Front Mic Boost' element exists
+;
+; See analog-output.conf.common for an explanation on the directives
+
+[General]
+priority = 85
+name = analog-input-microphone-front
+
+[Jack Front Mic]
+required-any = any
+
+[Jack Front Mic Phantom]
+required-any = any
+state.plugged = unknown
+state.unplugged = unknown
+
+[Element Front Mic Boost]
+required-any = any
+switch = select
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Option Front Mic Boost:on]
+name = input-boost-on
+
+[Option Front Mic Boost:off]
+name = input-boost-off
+
+[Element Front Mic]
+required-any = any
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Capture]
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Input Source]
+enumeration = select
+
+[Option Input Source:Front Mic]
+name = analog-input-microphone-front
+required-any = any
+
+[Element Capture Source]
+enumeration = select
+
+[Option Capture Source:Front Mic]
+name = analog-input-microphone-front
+required-any = any
+
+[Element Mic]
+switch = off
+volume = off
+
+[Element Internal Mic]
+switch = off
+volume = off
+
+[Element Rear Mic]
+switch = off
+volume = off
+
+[Element Dock Mic]
+switch = off
+volume = off
+
+[Element Mic Boost]
+switch = off
+volume = off
+
+[Element Dock Mic Boost]
+switch = off
+volume = off
+
+[Element Internal Mic Boost]
+switch = off
+volume = off
+
+[Element Rear Mic Boost]
+switch = off
+volume = off
+
+.include analog-input-mic.conf.common
diff --git a/src/modules/alsa/mixer/paths/analog-input-headphone-mic.conf b/src/modules/alsa/mixer/paths/analog-input-headphone-mic.conf
new file mode 100644 (file)
index 0000000..9b9213a
--- /dev/null
@@ -0,0 +1,103 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; For some ASUS netbooks that have one jack that can be either a Headphone
+; *or* a mic. This path will be active only when it is used as a mic.
+;
+; See analog-output.conf.common for an explanation on the directives
+
+[General]
+priority = 87
+name = analog-input-microphone
+
+[Jack Headphone Mic]
+required-any = any
+state.plugged = unknown
+
+[Element Headphone Mic Boost]
+required-any = any
+switch = select
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Headphone Mic]
+required-any = any
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Capture]
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Input Source]
+enumeration = select
+
+[Option Input Source:Headphone Mic]
+name = analog-input-microphone
+required-any = any
+
+[Element Capture Source]
+enumeration = select
+
+[Option Capture Source:Headphone Mic]
+name = analog-input-microphone
+required-any = any
+
+; Make sure the internal speakers are not auto-muted when you plug a mic in
+[Element Auto-Mute Mode]
+enumeration = select
+
+[Option Auto-Mute Mode:Disabled]
+name = analog-input-microphone
+
+[Element Front Mic]
+switch = off
+volume = off
+
+[Element Internal Mic]
+switch = off
+volume = off
+
+[Element Rear Mic]
+switch = off
+volume = off
+
+[Element Dock Mic]
+switch = off
+volume = off
+
+[Element Dock Mic Boost]
+switch = off
+volume = off
+
+[Element Internal Mic Boost]
+switch = off
+volume = off
+
+[Element Front Mic Boost]
+switch = off
+volume = off
+
+[Element Rear Mic Boost]
+switch = off
+volume = off
+
+.include analog-input-mic.conf.common
diff --git a/src/modules/alsa/mixer/paths/analog-input-headset-mic.conf b/src/modules/alsa/mixer/paths/analog-input-headset-mic.conf
new file mode 100644 (file)
index 0000000..9a9dc35
--- /dev/null
@@ -0,0 +1,112 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; For devices where a 'Headset Mic' or 'Headset Mic Boost' element exists
+;
+; See analog-output.conf.common for an explanation on the directives
+
+[General]
+priority = 87
+name = analog-input-microphone-headset
+
+[Jack Headset Mic]
+required-any = any
+
+[Jack Headset Mic Phantom]
+state.plugged = unknown
+state.unplugged = unknown
+required-any = any
+
+[Jack Headphone]
+state.plugged = unknown
+
+[Jack Headphone Mic]
+state.plugged = unknown
+
+[Element Headset Mic Boost]
+required-any = any
+switch = select
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Headset Mic]
+required-any = any
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Headset]
+required-any = any
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Capture]
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Input Source]
+enumeration = select
+
+[Option Input Source:Headset Mic]
+name = Headset Microphone
+required-any = any
+
+[Element Capture Source]
+enumeration = select
+
+[Option Capture Source:Headset Mic]
+name = Headset Microphone
+required-any = any
+
+[Element Front Mic]
+switch = off
+volume = off
+
+[Element Internal Mic]
+switch = off
+volume = off
+
+[Element Rear Mic]
+switch = off
+volume = off
+
+[Element Dock Mic]
+switch = off
+volume = off
+
+[Element Dock Mic Boost]
+switch = off
+volume = off
+
+[Element Internal Mic Boost]
+switch = off
+volume = off
+
+[Element Front Mic Boost]
+switch = off
+volume = off
+
+[Element Rear Mic Boost]
+switch = off
+volume = off
+
+.include analog-input-mic.conf.common
diff --git a/src/modules/alsa/mixer/paths/analog-input-internal-mic-always.conf b/src/modules/alsa/mixer/paths/analog-input-internal-mic-always.conf
new file mode 100644 (file)
index 0000000..37f9b17
--- /dev/null
@@ -0,0 +1,135 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; For devices where a 'Internal Mic' or 'Internal Mic Boost' element exists
+; 'Int Mic' and 'Int Mic Boost' are for compatibility with kernels < 2.6.38
+;
+; See analog-output.conf.common for an explanation on the directives
+
+[General]
+priority = 89
+name = analog-input-microphone-internal
+
+[Jack Mic]
+state.plugged = no
+state.unplugged = unknown
+
+[Jack Dock Mic]
+state.plugged = no
+state.unplugged = unknown
+
+[Jack Front Mic]
+state.plugged = no
+state.unplugged = unknown
+
+[Jack Rear Mic]
+state.plugged = no
+state.unplugged = unknown
+
+[Element Internal Mic Boost]
+switch = select
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Option Internal Mic Boost:on]
+name = input-boost-on
+
+[Option Internal Mic Boost:off]
+name = input-boost-off
+
+[Element Int Mic Boost]
+switch = select
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Option Int Mic Boost:on]
+name = input-boost-on
+
+[Option Int Mic Boost:off]
+name = input-boost-off
+
+
+[Element Internal Mic]
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Int Mic]
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Capture]
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Input Source]
+enumeration = select
+
+[Option Input Source:Internal Mic]
+name = analog-input-microphone-internal
+
+[Option Input Source:Int Mic]
+name = analog-input-microphone-internal
+
+[Element Capture Source]
+enumeration = select
+
+[Option Capture Source:Internal Mic]
+name = analog-input-microphone-internal
+
+[Option Capture Source:Int Mic]
+name = analog-input-microphone-internal
+
+[Element Mic]
+switch = off
+volume = off
+
+[Element Dock Mic]
+switch = off
+volume = off
+
+[Element Front Mic]
+switch = off
+volume = off
+
+[Element Rear Mic]
+switch = off
+volume = off
+
+[Element Mic Boost]
+switch = off
+volume = off
+
+[Element Dock Mic Boost]
+switch = off
+volume = off
+
+[Element Front Mic Boost]
+switch = off
+volume = off
+
+[Element Rear Mic Boost]
+switch = off
+volume = off
+
+.include analog-input-mic.conf.common
diff --git a/src/modules/alsa/mixer/paths/analog-input-internal-mic.conf b/src/modules/alsa/mixer/paths/analog-input-internal-mic.conf
new file mode 100644 (file)
index 0000000..4718dd0
--- /dev/null
@@ -0,0 +1,156 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; For devices where a 'Internal Mic' or 'Internal Mic Boost' element exists
+; 'Int Mic' and 'Int Mic Boost' are for compatibility with kernels < 2.6.38
+;
+; See analog-output.conf.common for an explanation on the directives
+
+[General]
+priority = 89
+name = analog-input-microphone-internal
+
+[Jack Mic]
+state.plugged = no
+state.unplugged = unknown
+
+[Jack Dock Mic]
+state.plugged = no
+state.unplugged = unknown
+
+[Jack Front Mic]
+state.plugged = no
+state.unplugged = unknown
+
+[Jack Rear Mic]
+state.plugged = no
+state.unplugged = unknown
+
+[Jack Internal Mic Phantom]
+state.plugged = unknown
+state.unplugged = unknown
+required-any = any
+
+[Element Internal Mic Boost]
+required-any = any
+switch = select
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Option Internal Mic Boost:on]
+name = input-boost-on
+
+[Option Internal Mic Boost:off]
+name = input-boost-off
+
+[Element Int Mic Boost]
+required-any = any
+switch = select
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Option Int Mic Boost:on]
+name = input-boost-on
+
+[Option Int Mic Boost:off]
+name = input-boost-off
+
+
+[Element Internal Mic]
+required-any = any
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Int Mic]
+required-any = any
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Capture]
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Input Source]
+enumeration = select
+
+[Option Input Source:Internal Mic]
+name = analog-input-microphone-internal
+required-any = any
+
+[Option Input Source:Int Mic]
+name = analog-input-microphone-internal
+required-any = any
+
+[Element Capture Source]
+enumeration = select
+
+[Option Capture Source:Internal Mic]
+name = analog-input-microphone-internal
+required-any = any
+
+[Option Capture Source:Int Mic]
+name = analog-input-microphone-internal
+required-any = any
+
+[Element Mic]
+switch = off
+volume = off
+
+[Element Dock Mic]
+switch = off
+volume = off
+
+[Element Front Mic]
+switch = off
+volume = off
+
+[Element Rear Mic]
+switch = off
+volume = off
+
+[Element Headphone Mic]
+switch = off
+volume = off
+
+[Element Headphone Mic Boost]
+switch = off
+volume = off
+
+[Element Mic Boost]
+switch = off
+volume = off
+
+[Element Dock Mic Boost]
+switch = off
+volume = off
+
+[Element Front Mic Boost]
+switch = off
+volume = off
+
+[Element Rear Mic Boost]
+switch = off
+volume = off
+
+.include analog-input-mic.conf.common
index 4be5722..3a8c2a0 100644 (file)
 ; See analog-output.conf.common for an explanation on the directives
 
 [General]
-priority = 90
+priority = 81
+
+[Jack Line]
+required-any = any
+
+[Jack Line Phantom]
+required-any = any
+state.plugged = unknown
+state.unplugged = unknown
 
 [Element Capture]
 switch = mute
@@ -27,17 +35,74 @@ volume = merge
 override-map.1 = all
 override-map.2 = all-left,all-right
 
-[Element Mic]
-switch = off
-volume = off
+[Element Line Boost]
+required-any = any
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
 
 [Element Line]
-required = any
+required-any = any
 switch = mute
 volume = merge
 override-map.1 = all
 override-map.2 = all-left,all-right
 
+[Element Input Source]
+enumeration = select
+
+[Option Input Source:Line]
+name = analog-input-linein
+required-any = any
+
+[Element Capture Source]
+enumeration = select
+
+[Option Capture Source:Line]
+name = analog-input-linein
+required-any = any
+
+[Element Mic]
+switch = off
+volume = off
+
+[Element Dock Mic]
+switch = off
+volume = off
+
+[Element Internal Mic]
+switch = off
+volume = off
+
+[Element Front Mic]
+switch = off
+volume = off
+
+[Element Rear Mic]
+switch = off
+volume = off
+
+[Element Mic Boost]
+switch = off
+volume = off
+
+[Element Dock Mic Boost]
+switch = off
+volume = off
+
+[Element Internal Mic Boost]
+switch = off
+volume = off
+
+[Element Front Mic Boost]
+switch = off
+volume = off
+
+[Element Rear Mic Boost]
+switch = off
+volume = off
+
 [Element Aux]
 switch = off
 volume = off
@@ -58,4 +123,9 @@ volume = off
 switch = off
 volume = off
 
-.include analog-input.conf.common
+[Element Mic Jack Mode]
+enumeration = select
+
+[Option Mic Jack Mode:Line In]
+priority = 19
+name = input-linein
index f7f3085..fb80838 100644 (file)
@@ -19,7 +19,7 @@
 ; See analog-output.conf.common for an explanation on the directives
 
 [General]
-priority = 90
+priority = 85
 name = analog-input
 
 [Element Capture]
@@ -32,6 +32,10 @@ override-map.2 = all-left,all-right
 switch = off
 volume = off
 
+[Element Internal Mic]
+switch = off
+volume = off
+
 [Element Line]
 switch = off
 volume = off
index 2a36f2f..9e5f044 100644 (file)
 # along with PulseAudio; if not, write to the Free Software Foundation,
 # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 
-; For devices where a 'Mic' element exists
+; For devices where a 'Mic' or 'Mic Boost' element exists
 ;
 ; See analog-output.conf.common for an explanation on the directives
 
 [General]
-priority = 100
+priority = 87
 name = analog-input-microphone
 
-[Element Capture]
-switch = mute
+[Jack Mic]
+required-any = any
+
+[Jack Mic Phantom]
+required-any = any
+state.plugged = unknown
+state.unplugged = unknown
+
+[Element Mic Boost]
+required-any = any
+switch = select
 volume = merge
 override-map.1 = all
 override-map.2 = all-left,all-right
 
+[Option Mic Boost:on]
+name = input-boost-on
+
+[Option Mic Boost:off]
+name = input-boost-off
+
 [Element Mic]
-required = any
+required-any = any
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Capture]
 switch = mute
 volume = merge
 override-map.1 = all
 override-map.2 = all-left,all-right
 
-[Element Line]
+[Element Input Source]
+enumeration = select
+
+[Option Input Source:Mic]
+name = analog-input-microphone
+required-any = any
+
+[Element Capture Source]
+enumeration = select
+
+[Option Capture Source:Mic]
+name = analog-input-microphone
+required-any = any
+
+;;; Some AC'97s have "Mic Select" and "Mic Boost (+20dB)"
+
+[Element Mic Select]
+enumeration = select
+
+[Option Mic Select:Mic1]
+name = input-microphone
+priority = 20
+
+[Option Mic Select:Mic2]
+name = input-microphone
+priority = 19
+
+[Element Mic Boost (+20dB)]
+switch = select
+volume = merge
+
+[Option Mic Boost (+20dB):on]
+name = input-boost-on
+
+[Option Mic Boost (+20dB):off]
+name = input-boost-off
+
+[Element Front Mic]
+switch = off
+volume = off
+
+[Element Internal Mic]
+switch = off
+volume = off
+
+[Element Rear Mic]
 switch = off
 volume = off
 
-[Element Aux]
+[Element Dock Mic]
 switch = off
 volume = off
 
-[Element Video]
+[Element Dock Mic Boost]
 switch = off
 volume = off
 
-[Element Mic/Line]
+[Element Internal Mic Boost]
 switch = off
 volume = off
 
-[Element TV Tuner]
+[Element Front Mic Boost]
 switch = off
 volume = off
 
-[Element FM]
+[Element Rear Mic Boost]
 switch = off
 volume = off
 
-.include analog-input.conf.common
 .include analog-input-mic.conf.common
index b35e7af..27bbccb 100644 (file)
 ;
 ; See analog-output.conf.common for an explanation on the directives
 
-;;; 'Mic Select'
+[Properties]
+device.icon_name = audio-input-microphone
 
-[Element Mic Select]
-enumeration = select
-
-[Option Mic Select:Mic1]
-name = input-microphone
-priority = 20
-
-[Option Mic Select:Mic2]
-name = input-microphone
-priority = 19
-
-;;; Various Boosts
+[Element Line]
+switch = off
+volume = off
 
-[Element Mic Boost (+20dB)]
-switch = select
-volume = merge
+[Element Line Boost]
+switch = off
+volume = off
 
-[Option Mic Boost (+20dB):on]
-name = input-boost-on
+[Element Aux]
+switch = off
+volume = off
 
-[Option Mic Boost (+20dB):off]
-name = input-boost-off
+[Element Video]
+switch = off
+volume = off
 
-[Element Mic Boost]
-switch = select
-volume = merge
+[Element Mic/Line]
+switch = off
+volume = off
 
-[Option Mic Boost:on]
-name = input-boost-on
+[Element TV Tuner]
+switch = off
+volume = off
 
-[Option Mic Boost:off]
-name = input-boost-off
+[Element FM]
+switch = off
+volume = off
 
-[Element Front Mic Boost]
-switch = select
+[Element Inverted Internal Mic]
+switch = off
+volume = off
 
-[Option Front Mic Boost:on]
-name = input-boost-on
+[Element Mic Jack Mode]
+enumeration = select
 
-[Option Front Mic Boost:off]
-name = input-boost-off
+[Option Mic Jack Mode:Mic In]
+priority = 19
+name = input-microphone
diff --git a/src/modules/alsa/mixer/paths/analog-input-rear-mic.conf b/src/modules/alsa/mixer/paths/analog-input-rear-mic.conf
new file mode 100644 (file)
index 0000000..397efba
--- /dev/null
@@ -0,0 +1,105 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; For devices where a 'Rear Mic' or 'Rear Mic Boost' element exists
+;
+; See analog-output.conf.common for an explanation on the directives
+
+[General]
+priority = 82
+name = analog-input-microphone-rear
+
+[Jack Rear Mic]
+required-any = any
+
+[Jack Rear Mic Phantom]
+required-any = any
+state.plugged = unknown
+state.unplugged = unknown
+
+[Element Rear Mic Boost]
+required-any = any
+switch = select
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Option Rear Mic Boost:on]
+name = input-boost-on
+
+[Option Rear Mic Boost:off]
+name = input-boost-off
+
+[Element Rear Mic]
+required-any = any
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Capture]
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Input Source]
+enumeration = select
+
+[Option Input Source:Rear Mic]
+name = analog-input-microphone-rear
+required-any = any
+
+[Element Capture Source]
+enumeration = select
+
+[Option Capture Source:Rear Mic]
+name = analog-input-microphone-rear
+required-any = any
+
+[Element Mic]
+switch = off
+volume = off
+
+[Element Internal Mic]
+switch = off
+volume = off
+
+[Element Front Mic]
+switch = off
+volume = off
+
+[Element Dock Mic]
+switch = off
+volume = off
+
+[Element Mic Boost]
+switch = off
+volume = off
+
+[Element Dock Mic Boost]
+switch = off
+volume = off
+
+[Element Internal Mic Boost]
+switch = off
+volume = off
+
+[Element Front Mic Boost]
+switch = off
+volume = off
+
+.include analog-input-mic.conf.common
index 8531ec7..fae3ce8 100644 (file)
@@ -32,6 +32,10 @@ override-map.2 = all-left,all-right
 switch = off
 volume = off
 
+[Element Internal Mic]
+switch = off
+volume = off
+
 [Element Line]
 switch = off
 volume = off
index 74c76f0..19f1809 100644 (file)
@@ -31,6 +31,10 @@ override-map.2 = all-left,all-right
 switch = off
 volume = off
 
+[Element Internal Mic]
+switch = off
+volume = off
+
 [Element Line]
 switch = off
 volume = off
index 5055f90..c8f8e3c 100644 (file)
@@ -14,7 +14,7 @@
 # along with PulseAudio; if not, write to the Free Software Foundation,
 # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 
-; A fallback for devices that lack seperate Mic/Line/Aux/Video/TV
+; A fallback for devices that lack separate Mic/Line/Aux/Video/TV
 ; Tuner/FM elements
 ;
 ; See analog-output.conf.common for an explanation on the directives
@@ -23,7 +23,6 @@
 priority = 100
 
 [Element Capture]
-required = volume
 switch = mute
 volume = merge
 override-map.1 = all
@@ -32,6 +31,36 @@ override-map.2 = all-left,all-right
 [Element Mic]
 required-absent = any
 
+[Element Dock Mic]
+required-absent = any
+
+[Element Dock Mic Boost]
+required-absent = any
+
+[Element Front Mic]
+required-absent = any
+
+[Element Front Mic Boost]
+required-absent = any
+
+[Element Int Mic]
+required-absent = any
+
+[Element Int Mic Boost]
+required-absent = any
+
+[Element Internal Mic]
+required-absent = any
+
+[Element Internal Mic Boost]
+required-absent = any
+
+[Element Rear Mic]
+required-absent = any
+
+[Element Rear Mic Boost]
+required-absent = any
+
 [Element Line]
 required-absent = any
 
@@ -51,4 +80,3 @@ required-absent = any
 required-absent = any
 
 .include analog-input.conf.common
-.include analog-input-mic.conf.common
index 951e11f..77d46bf 100644 (file)
@@ -62,7 +62,7 @@ priority = 5
 [Element Input Source]
 enumeration = select
 
-[Option Input Source:Mic]
+[Option Input Source:Digital Mic]
 name = input-microphone
 priority = 20
 
@@ -70,22 +70,14 @@ priority = 20
 name = input-microphone
 priority = 20
 
-[Option Input Source:Front Mic]
-name = input-microphone
-priority = 19
-
 [Option Input Source:Front Microphone]
 name = input-microphone
 priority = 19
 
-[Option Input Source:Internal Mic]
+[Option Input Source:Internal Mic 1]
 name = input-microphone
 priority = 19
 
-[Option Input Source:Line]
-name = input-linein
-priority = 18
-
 [Option Input Source:Line-In]
 name = input-linein
 priority = 18
@@ -119,21 +111,12 @@ name = input
 [Option Capture Source:Line/Mic]
 name = input
 
-[Option Capture Source:Mic]
-name = input-microphone
-
 [Option Capture Source:Microphone]
 name = input-microphone
 
-[Option Capture Source:Int Mic]
-name = input-microphone-internal
-
 [Option Capture Source:Int DMic]
 name = input-microphone-internal
 
-[Option Capture Source:Internal Mic]
-name = input-microphone-internal
-
 [Option Capture Source:iMic]
 name = input-microphone-internal
 
@@ -143,15 +126,9 @@ name = input-microphone-internal
 [Option Capture Source:Internal Microphone]
 name = input-microphone-internal
 
-[Option Capture Source:Front Mic]
-name = input-microphone
-
 [Option Capture Source:Front Microphone]
 name = input-microphone
 
-[Option Capture Source:Rear Mic]
-name = input-microphone
-
 [Option Capture Source:Mic1]
 name = input-microphone
 
@@ -182,9 +159,6 @@ name = input-linein
 [Option Capture Source:Analog]
 name = input
 
-[Option Capture Source:Line]
-name = input-linein
-
 [Option Capture Source:Line-In]
 name = input-linein
 
@@ -245,9 +219,6 @@ name = input
 [Option Capture Source:Docking-Station]
 name = input-docking
 
-[Option Capture Source:Dock Mic]
-name = input-docking-microphone
-
 ;;; 'Mic Jack Mode'
 
 [Element Mic Jack Mode]
@@ -264,15 +235,40 @@ name = input-linein
 [Element Digital Input Source]
 enumeration = select
 
+[Option Digital Input Source:Digital Mic 1]
+name = input-microphone
+
 [Option Digital Input Source:Analog Inputs]
 name = input
 
-[Option Digital Input Source:Digital Mic 1]
+[Option Digital Input Source:Digital Mic 2]
 name = input-microphone
 
-[Option Digital Input Source:Digital Mic 2]
+;;; 'Analog Source'
+
+[Element Analog Source]
+enumeration = select
+
+[Option Analog Source:Mic]
 name = input-microphone
 
+[Option Analog Source:Line in]
+name = input-linein
+
+[Option Analog Source:Aux]
+name = input
+
+;;; 'Shared Mic/Line in'
+
+[Element Shared Mic/Line in]
+enumeration = select
+
+[Option Shared Mic/Line in:Mic in]
+name = input-microphone
+
+[Option Shared Mic/Line in:Line in]
+name = input-linein
+
 ;;; Various Boosts
 
 [Element Capture Boost]
 # along with PulseAudio; if not, write to the Free Software Foundation,
 # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 
-; Intended for usage in laptops that have a seperate LFE speaker
-; connected to the Master mono connector
+; Path for mixers that have a 'Desktop Speaker' control
 ;
 ; See analog-output.conf.common for an explanation on the directives
 
 [General]
-priority = 40
+priority = 101
+name = analog-output-speaker
+
+[Properties]
+device.icon_name = audio-speakers
 
 [Element Hardware Master]
 switch = mute
@@ -31,19 +34,16 @@ override-map.2 = all-left,all-right
 [Element Master]
 switch = mute
 volume = merge
-override-map.1 = all-no-lfe
+override-map.1 = all
 override-map.2 = all-left,all-right
 
 [Element Master Mono]
-required = any
-switch = mute
-volume = merge
-override-map.1 = lfe
-override-map.2 = lfe,lfe
+switch = off
+volume = off
 
-; This profile path is intended to control the speaker, not the
-; headphones. But it should not hurt if we leave the headphone jack
-; enabled nonetheless.
+; This profile path is intended to control the desktop speaker, not
+; the headphones. But it should not hurt if we leave the headphone
+; jack enabled nonetheless.
 [Element Headphone]
 switch = mute
 volume = zero
@@ -53,33 +53,50 @@ switch = mute
 volume = zero
 
 [Element Speaker]
+switch = off
+volume = off
+
+[Element Desktop Speaker]
+required = any
 switch = mute
 volume = merge
 override-map.1 = all
 override-map.2 = all-left,all-right
 
 [Element Front]
-switch = off
-volume = off
+switch = mute
+volume = merge
+override-map.1 = all-front
+override-map.2 = front-left,front-right
 
 [Element Rear]
-switch = off
-volume = off
+switch = mute
+volume = merge
+override-map.1 = all-rear
+override-map.2 = rear-left,rear-right
 
 [Element Surround]
-switch = off
-volume = off
+switch = mute
+volume = merge
+override-map.1 = all-rear
+override-map.2 = rear-left,rear-right
 
 [Element Side]
-switch = off
-volume = off
+switch = mute
+volume = merge
+override-map.1 = all-side
+override-map.2 = side-left,side-right
 
 [Element Center]
-switch = off
-volume = off
+switch = mute
+volume = merge
+override-map.1 = all-center
+override-map.2 = all-center,all-center
 
 [Element LFE]
-switch = off
-volume = off
+switch = mute
+volume = merge
+override-map.1 = lfe
+override-map.2 = lfe,lfe
 
 .include analog-output.conf.common
index f2fd31c..6161ff5 100644 (file)
 
 [General]
 priority = 89
+name = analog-output-headphones
+
+[Properties]
+device.icon_name = audio-headphones
 
 [Element Hardware Master]
 switch = mute
@@ -55,10 +59,15 @@ override-map.2 = all-left,all-right
 switch = off
 volume = off
 
-[Element Front]
+[Element Desktop Speaker]
 switch = off
 volume = off
 
+; On some machines Front is actually a part of the Headphone path
+[Element Front]
+switch = mute
+volume = zero
+
 [Element Rear]
 switch = off
 volume = off
index 2131cfe..76cd01e 100644 (file)
 
 [General]
 priority = 90
+name = analog-output-headphones
+
+[Properties]
+device.icon_name = audio-headphones
+
+[Jack Front Headphone]
+required-any = any
+
+[Jack Front Headphone Phantom]
+required-any = any
+state.plugged = unknown
+state.unplugged = unknown
+
+[Jack Headphone]
+required-any = any
+
+[Jack Headphone Phantom]
+required-any = any
+state.plugged = unknown
+state.unplugged = unknown
+
+# This jack can be either a headphone *or* a mic. Used on some ASUS netbooks.
+[Jack Headphone Mic]
+required-any = any
 
 [Element Hardware Master]
 switch = mute
@@ -38,12 +62,22 @@ switch = off
 volume = off
 
 [Element Headphone]
-required = any
+required-any = any
 switch = mute
 volume = merge
 override-map.1 = all
 override-map.2 = all-left,all-right
 
+[Element Headset]
+required-any = any
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Line HP Swap]
+switch = on
+
 ; This profile path is intended to control the first headphones, not
 ; the second headphones. But it should not hurt if we leave the second
 ; headphone jack enabled nonetheless.
@@ -55,10 +89,15 @@ volume = zero
 switch = off
 volume = off
 
-[Element Front]
+[Element Desktop Speaker]
 switch = off
 volume = off
 
+; On some machines Front is actually a part of the Headphone path
+[Element Front]
+switch = mute
+volume = zero
+
 [Element Rear]
 switch = off
 volume = off
index 542edc4..87b5081 100644 (file)
@@ -14,7 +14,7 @@
 # along with PulseAudio; if not, write to the Free Software Foundation,
 # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 
-; Intended for usage on boards that have a seperate Mono output plug.
+; Intended for usage on boards that have a separate Mono output plug.
 ;
 ; See analog-output.conf.common for an explanation on the directives
 
@@ -55,6 +55,10 @@ volume = merge
 override-map.1 = all
 override-map.2 = all-left,all-right
 
+[Element Desktop Speaker]
+switch = off
+volume = off
+
 [Element Front]
 switch = off
 volume = off
diff --git a/src/modules/alsa/mixer/paths/analog-output-speaker-always.conf b/src/modules/alsa/mixer/paths/analog-output-speaker-always.conf
new file mode 100644 (file)
index 0000000..8a2b3df
--- /dev/null
@@ -0,0 +1,146 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; Path for mixers that don't have a 'Speaker' control, but where we
+; force enable the speaker paths nonetheless.
+; Needed for some older Dell laptops.
+; See analog-output.conf.common for an explanation on the directives
+
+[General]
+priority = 100
+name = analog-output-speaker
+
+[Properties]
+device.icon_name = audio-speakers
+
+[Jack Headphone]
+state.plugged = no
+state.unplugged = unknown
+
+[Jack Front Headphone]
+state.plugged = no
+state.unplugged = unknown
+
+[Element Hardware Master]
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Master]
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Master Mono]
+switch = off
+volume = off
+
+; This profile path is intended to control the speaker, not the
+; headphones. But it should not hurt if we leave the headphone jack
+; enabled nonetheless.
+[Element Headphone]
+switch = mute
+volume = zero
+
+[Element Headphone2]
+switch = mute
+volume = zero
+
+[Element Speaker]
+switch = mute
+volume = merge
+override-map.1 = all
+override-map.2 = all-left,all-right
+
+[Element Desktop Speaker]
+switch = off
+volume = off
+
+[Element Front]
+switch = mute
+volume = merge
+override-map.1 = all-front
+override-map.2 = front-left,front-right
+
+[Element Front Speaker]
+switch = mute
+volume = merge
+override-map.1 = all-front
+override-map.2 = front-left,front-right
+
+[Element Rear]
+switch = mute
+volume = merge
+override-map.1 = all-rear
+override-map.2 = rear-left,rear-right
+
+[Element Surround]
+switch = mute
+volume = merge
+override-map.1 = all-rear
+override-map.2 = rear-left,rear-right
+
+[Element Surround Speaker]
+switch = mute
+volume = merge
+override-map.1 = all-rear
+override-map.2 = rear-left,rear-right
+
+[Element Side]
+switch = mute
+volume = merge
+override-map.1 = all-side
+override-map.2 = side-left,side-right
+
+[Element Center]
+switch = mute
+volume = merge
+override-map.1 = all-center
+override-map.2 = all-center,all-center
+
+[Element Center Speaker]
+switch = mute
+volume = merge
+override-map.1 = all-center
+override-map.2 = all-center,all-center
+
+[Element LFE]
+switch = mute
+volume = merge
+override-map.1 = lfe
+override-map.2 = lfe,lfe
+
+[Element LFE Speaker]
+switch = mute
+volume = merge
+override-map.1 = lfe
+override-map.2 = lfe,lfe
+
+[Element Bass Speaker]
+switch = mute
+volume = merge
+override-map.1 = lfe
+override-map.2 = lfe,lfe
+
+[Element CLFE]
+switch = mute
+volume = merge
+override-map.1 = all-center
+override-map.2 = all-center,lfe
+
+.include analog-output.conf.common
index aea7853..7b47fc2 100644 (file)
 
 [General]
 priority = 100
+name = analog-output-speaker
+
+[Properties]
+device.icon_name = audio-speakers
+
+[Jack Headphone]
+state.plugged = no
+state.unplugged = unknown
+
+[Jack Front Headphone]
+state.plugged = no
+state.unplugged = unknown
+
+[Jack Speaker Phantom]
+required-any = any
+state.plugged = unknown
+state.unplugged = unknown
 
 [Element Hardware Master]
 switch = mute
@@ -49,18 +66,29 @@ switch = mute
 volume = zero
 
 [Element Speaker]
-required = any
+required-any = any
 switch = mute
 volume = merge
 override-map.1 = all
 override-map.2 = all-left,all-right
 
+[Element Desktop Speaker]
+switch = off
+volume = off
+
 [Element Front]
 switch = mute
 volume = merge
 override-map.1 = all-front
 override-map.2 = front-left,front-right
 
+[Element Front Speaker]
+switch = mute
+volume = merge
+override-map.1 = all-front
+override-map.2 = front-left,front-right
+required-any = any
+
 [Element Rear]
 switch = mute
 volume = merge
@@ -73,6 +101,13 @@ volume = merge
 override-map.1 = all-rear
 override-map.2 = rear-left,rear-right
 
+[Element Surround Speaker]
+switch = mute
+volume = merge
+override-map.1 = all-rear
+override-map.2 = rear-left,rear-right
+required-any = any
+
 [Element Side]
 switch = mute
 volume = merge
@@ -85,10 +120,37 @@ volume = merge
 override-map.1 = all-center
 override-map.2 = all-center,all-center
 
+[Element Center Speaker]
+switch = mute
+volume = merge
+override-map.1 = all-center
+override-map.2 = all-center,all-center
+required-any = any
+
 [Element LFE]
 switch = mute
 volume = merge
 override-map.1 = lfe
 override-map.2 = lfe,lfe
 
+[Element LFE Speaker]
+switch = mute
+volume = merge
+override-map.1 = lfe
+override-map.2 = lfe,lfe
+required-any = any
+
+[Element Bass Speaker]
+switch = mute
+volume = merge
+override-map.1 = lfe
+override-map.2 = lfe,lfe
+required-any = any
+
+[Element CLFE]
+switch = mute
+volume = merge
+override-map.1 = all-center
+override-map.2 = all-center,lfe
+
 .include analog-output.conf.common
index fc30800..3a552c9 100644 (file)
 [General]
 priority = 99
 
+[Jack Line Out]
+state.plugged = unknown
+state.unplugged = unknown
+
+[Jack Line Out Phantom]
+state.plugged = unknown
+state.unplugged = unknown
+
 [Element Hardware Master]
-switch = ignore
+switch = mute
 volume = merge
 override-map.1 = all
 override-map.2 = all-left,all-right
 
 [Element Master]
-switch = ignore
-volume = ignore
+switch = mute
+volume = merge
 override-map.1 = all
 override-map.2 = all-left,all-right
 
@@ -38,55 +46,68 @@ override-map.2 = all-left,all-right
 switch = off
 volume = off
 
+[Element Line HP Swap]
+switch = off
+
 ; This profile path is intended to control the default output, not the
 ; headphones. But it should not hurt if we leave the headphone jack
 ; enabled nonetheless.
 [Element Headphone]
-switch = ignore
+switch = mute
 volume = zero
 
 [Element Headphone2]
-switch = ignore
+switch = mute
 volume = zero
 
 [Element Speaker]
-switch = ignore
+switch = mute
+volume = off
+
+[Element Desktop Speaker]
+switch = mute
 volume = off
 
 [Element Front]
-switch = ignore
+switch = mute
 volume = merge
 override-map.1 = all-front
 override-map.2 = front-left,front-right
 
 [Element Rear]
-switch = ignore
+switch = mute
 volume = merge
 override-map.1 = all-rear
 override-map.2 = rear-left,rear-right
 
 [Element Surround]
-switch = ignore
+switch = mute
 volume = merge
 override-map.1 = all-rear
 override-map.2 = rear-left,rear-right
 
 [Element Side]
-switch = ignore
+switch = mute
 volume = merge
 override-map.1 = all-side
 override-map.2 = side-left,side-right
 
 [Element Center]
-switch = ignore
+switch = mute
 volume = merge
 override-map.1 = all-center
 override-map.2 = all-center,all-center
 
 [Element LFE]
-switch = ignore
+switch = mute
 volume = merge
 override-map.1 = lfe
 override-map.2 = lfe,lfe
 
+[Element CLFE]
+switch = mute
+volume = merge
+override-map.1 = all-center
+override-map.2 = all-center,lfe
+
 .include analog-output.conf.common
index 3204846..73d09f8 100644 (file)
 ; [General]
 ; priority = ...                         # Priority for this path
 ; description = ...
+; mute-during-activation = yes | no      # If this path supports hardware mute, should the hw mute be used while activating this
+;                                        # path? In some cases this can reduce extra noises during port switching, while in other
+;                                        # cases this can increase such noises. Default: no.
+; eld-device = ...                       # If this is an HDMI port, here's where to specify the device number for the ELD mixer
+;                                        # control. The default is to not make use of ELD information.
+;
+; [Properties]                           # Property list for this path. The list is merged into the port property list.
+; <key> = <value>                        # Each property is defined on its own line.
+; ...
 ;
 ; [Option ...:...]                       # For each option of an enumeration or switch element
 ;                                        # that shall be exposed as a sink/source port. Needs to
 ;                                        # by the option name, resp. on/off if the element is a switch.
 ; name = ...                             # Logical name to use in the path identifier
 ; priority = ...                         # Priority if this is made into a device port
+; required = ignore | enumeration | any            # In this element, this option must exist or the path will be invalid. ("any" is an alias for "enumeration".)
+; 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
 ; 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
+;                                                             # path must be present, otherwise this path is invalid for the card
 ; required-absent = ignore | switch | volume                  # If set, require this element to not be of this kind and not
 ;                                                             # available, otherwise don't consider this path valid for the card
 ;
-; switch = ignore | mute | off | on | select                  # What to do with this switch: ignore it, make it follow mute status,
-;                                                             # always set it to off, always to on, or make it selectable as port.
-;                                                             # If set to 'select' you need to define an Option section for on
-;                                                             # and off
-; volume = ignore | merge | off | zero   # What to do with this volume: ignore it, merge it into the device
-;                                        # volume slider, always set it to the lowest value possible, or always
-;                                        # set it to 0 dB (for whatever that means)
+; switch = ignore | mute | off | on | select # What to do with this switch: ignore it, make it follow mute status,
+;                                            # always set it to off, always to on, or make it selectable as port.
+;                                            # If set to 'select' you need to define an Option section for on
+;                                            # and off
+; volume = ignore | merge | off | zero | <volume step> # What to do with this volume: ignore it, merge it into the device
+;                                                      # volume slider, always set it to the lowest value possible, or always
+;                                                      # set it to 0 dB (for whatever that means), or always set it to
+;                                                      # <volume step> (this only makes sense in path configurations where
+;                                                      # the exact hardware and driver are known beforehand).
+; volume-limit = <volume step>           # Limit the maximum volume by disabling the volume steps above <volume step>.
 ; enumeration = ignore | select          # What to do with this enumeration, ignore it or make it selectable
 ;                                        # via device ports. If set to 'select' you need to define an Option section
 ;                                        # for each of the items you want to expose
 ;                                        # channel mask. A channel mask may either be the name of a single channel, or the words "all-left",
 ;                                        # "all-right", "all-center", "all-front", "all-rear", and "all" to encode a specific subset of
 ;                                        # channels in a mask
+; [Jack ...]                           # For each jack that we will use for jack detection
+;                                      # The name 'Jack Foo' must match ALSA's 'Foo Jack' control.
+; required = ignore | any              # If not set to ignore, make the path invalid if this jack control is not present.
+; required-absent = ignore | any       # If not set to ignore, make the path invalid if this jack control is present.
+; required-any = ignore | any          # If not set to ignore, make the path invalid if no jack controls and no elements with
+;                                      # the required-any are present.
+; state.plugged = yes | no | unknown   # Normally a plugged jack would mean the port becomes available, and an unplugged means it's
+; state.unplugged = yes | no | unknown # unavailable, but the port status can be overridden by specifying state.plugged and/or state.unplugged.
 
 [Element PCM]
-switch = ignore
+switch = mute
 volume = merge
 override-map.1 = all
 override-map.2 = all-left,all-right
@@ -110,6 +135,23 @@ priority = 10
 name = output-amplifier-off
 priority = 0
 
+[Element Bass Boost]
+switch = select
+
+[Option Bass Boost:on]
+name = output-bass-boost-on
+priority = 0
+
+[Option Bass Boost:off]
+name = output-bass-boost-off
+priority = 10
+
+[Element IEC958]
+switch = off
+
+[Element IEC958 Optical Raw]
+switch = off
+
 ;;; 'Analog Output'
 
 [Element Analog Output]
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-0.conf b/src/modules/alsa/mixer/paths/hdmi-output-0.conf
new file mode 100644 (file)
index 0000000..3310147
--- /dev/null
@@ -0,0 +1,10 @@
+[General]
+description = HDMI / DisplayPort
+priority = 59
+eld-device = 3
+
+[Properties]
+device.icon_name = video-display
+
+[Jack HDMI/DP,pcm=3]
+required = ignore
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-1.conf b/src/modules/alsa/mixer/paths/hdmi-output-1.conf
new file mode 100644 (file)
index 0000000..d81ee78
--- /dev/null
@@ -0,0 +1,10 @@
+[General]
+description = HDMI / DisplayPort 2
+priority = 58
+eld-device = 7
+
+[Properties]
+device.icon_name = video-display
+
+[Jack HDMI/DP,pcm=7]
+required = ignore
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-2.conf b/src/modules/alsa/mixer/paths/hdmi-output-2.conf
new file mode 100644 (file)
index 0000000..349812f
--- /dev/null
@@ -0,0 +1,10 @@
+[General]
+description = HDMI / DisplayPort 3
+priority = 57
+eld-device = 8
+
+[Properties]
+device.icon_name = video-display
+
+[Jack HDMI/DP,pcm=8]
+required = ignore
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-3.conf b/src/modules/alsa/mixer/paths/hdmi-output-3.conf
new file mode 100644 (file)
index 0000000..81463c9
--- /dev/null
@@ -0,0 +1,10 @@
+[General]
+description = HDMI / DisplayPort 4
+priority = 56
+eld-device = 9
+
+[Properties]
+device.icon_name = video-display
+
+[Jack HDMI/DP,pcm=9]
+required = ignore
diff --git a/src/modules/alsa/mixer/paths/iec958-stereo-output.conf b/src/modules/alsa/mixer/paths/iec958-stereo-output.conf
new file mode 100644 (file)
index 0000000..8506a58
--- /dev/null
@@ -0,0 +1,19 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+
+[Element IEC958]
+switch = mute
index ea1a2fe..560ff1c 100644 (file)
@@ -10,7 +10,7 @@
 # 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.
+# Lesser General Public License for more details.
 #
 # You should have received a copy of the GNU Lesser General Public License
 # along with PulseAudio; if not, write to the Free Software Foundation,
 SUBSYSTEM!="sound", GOTO="pulseaudio_end"
 ACTION!="change", GOTO="pulseaudio_end"
 KERNEL!="card*", GOTO="pulseaudio_end"
+SUBSYSTEMS=="usb", GOTO="pulseaudio_check_usb"
 
-SUBSYSTEMS=="usb", ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1978", ENV{PULSE_PROFILE_SET}="native-instruments-audio8dj.conf"
-SUBSYSTEMS=="usb", ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="0839", ENV{PULSE_PROFILE_SET}="native-instruments-audio4dj.conf"
+SUBSYSTEMS=="platform", DRIVERS=="thinkpad_acpi", ENV{PULSE_IGNORE}="1"
+
+# NVidia and Intel HDAs often have more than one HDMI codec/port on the same card
+ATTRS{vendor}=="0x10de", ENV{PULSE_PROFILE_SET}="extra-hdmi.conf"
+ATTRS{vendor}=="0x8086", ENV{PULSE_PROFILE_SET}="extra-hdmi.conf"
+
+# Force enable speaker and internal mic for some laptops
+# This should only be necessary for kernels 3.3, 3.4 and 3.5 (as they are lacking the phantom jack kctls).
+# Acer AOA150
+ATTRS{subsystem_vendor}=="0x1025", ATTRS{subsystem_device}=="0x015b", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Acer Aspire 4810TZ
+ATTRS{subsystem_vendor}=="0x1025", ATTRS{subsystem_device}=="0x022a", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Packard bell dot m/a
+ATTRS{subsystem_vendor}=="0x1025", ATTRS{subsystem_device}=="0x028c", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Acer Aspire 1810TZ
+ATTRS{subsystem_vendor}=="0x1025", ATTRS{subsystem_device}=="0x029b", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Acer AOD260 and AO532h
+ATTRS{subsystem_vendor}=="0x1025", ATTRS{subsystem_device}=="0x0349", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Dell MXC051
+ATTRS{subsystem_vendor}=="0x1028", ATTRS{subsystem_device}=="0x01b5", ENV{PULSE_PROFILE_SET}="force-speaker.conf"
+# Dell Inspiron 6400 and E1505
+ATTRS{subsystem_vendor}=="0x1028", ATTRS{subsystem_device}=="0x01bd", ENV{PULSE_PROFILE_SET}="force-speaker.conf"
+# Dell Latitude D620
+ATTRS{subsystem_vendor}=="0x1028", ATTRS{subsystem_device}=="0x01c2", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Dell Latitude D820
+ATTRS{subsystem_vendor}=="0x1028", ATTRS{subsystem_device}=="0x01cc", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Dell Latitude D520
+ATTRS{subsystem_vendor}=="0x1028", ATTRS{subsystem_device}=="0x01d4", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Dell Latitude D420
+ATTRS{subsystem_vendor}=="0x1028", ATTRS{subsystem_device}=="0x01d6", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Dell Inspiron 1525
+ATTRS{subsystem_vendor}=="0x1028", ATTRS{subsystem_device}=="0x022f", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Dell Inspiron 1011
+ATTRS{subsystem_vendor}=="0x1028", ATTRS{subsystem_device}=="0x02f4", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Dell XPS 14 (L401X)
+ATTRS{subsystem_vendor}=="0x1028", ATTRS{subsystem_device}=="0x0468", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Dell XPS 15 (L501X)
+ATTRS{subsystem_vendor}=="0x1028", ATTRS{subsystem_device}=="0x046e", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Dell XPS 15 (L502X)
+ATTRS{subsystem_vendor}=="0x1028", ATTRS{subsystem_device}=="0x050e", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Dell Inspiron 3420
+ATTRS{subsystem_vendor}=="0x1028", ATTRS{subsystem_device}=="0x0553", ENV{PULSE_PROFILE_SET}="force-speaker.conf"
+# Dell Inspiron 3520
+ATTRS{subsystem_vendor}=="0x1028", ATTRS{subsystem_device}=="0x0555", ENV{PULSE_PROFILE_SET}="force-speaker.conf"
+# Dell Vostro 2420
+ATTRS{subsystem_vendor}=="0x1028", ATTRS{subsystem_device}=="0x0556", ENV{PULSE_PROFILE_SET}="force-speaker.conf"
+# Dell Vostro 2520
+ATTRS{subsystem_vendor}=="0x1028", ATTRS{subsystem_device}=="0x0558", ENV{PULSE_PROFILE_SET}="force-speaker.conf"
+# Dell Inspiron One 2020
+ATTRS{subsystem_vendor}=="0x1028", ATTRS{subsystem_device}=="0x0579", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Asus 904HA (1000H)
+ATTRS{subsystem_vendor}=="0x1043", ATTRS{subsystem_device}=="0x831a", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Asus T101MT
+ATTRS{subsystem_vendor}=="0x1043", ATTRS{subsystem_device}=="0x83ce", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Sony Vaio VGN-SR21M
+ATTRS{subsystem_vendor}=="0x104d", ATTRS{subsystem_device}=="0x9033", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Sony Vaio VPC-W115XG
+ATTRS{subsystem_vendor}=="0x104d", ATTRS{subsystem_device}=="0x9064", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Fujitsu Lifebook S7110
+ATTRS{subsystem_vendor}=="0x10cf", ATTRS{subsystem_device}=="0x1397", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Fujitsu Lifebook A530
+ATTRS{subsystem_vendor}=="0x10cf", ATTRS{subsystem_device}=="0x1531", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Toshiba A200
+ATTRS{subsystem_vendor}=="0x1179", ATTRS{subsystem_device}=="0xff00", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# MSI X360
+ATTRS{subsystem_vendor}=="0x1462", ATTRS{subsystem_device}=="0x1053", ENV{PULSE_PROFILE_SET}="force-speaker-and-int-mic.conf"
+# Lenovo 3000 Y410
+ATTRS{subsystem_vendor}=="0x17aa", ATTRS{subsystem_device}=="0x384e", ENV{PULSE_PROFILE_SET}="force-speaker.conf"
+
+GOTO="pulseaudio_end"
+
+LABEL="pulseaudio_check_usb"
+ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1978", ENV{PULSE_PROFILE_SET}="native-instruments-audio8dj.conf"
+ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="0839", ENV{PULSE_PROFILE_SET}="native-instruments-audio4dj.conf"
+ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="baff", ENV{PULSE_PROFILE_SET}="native-instruments-traktorkontrol-s4.conf"
+ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="4711", ENV{PULSE_PROFILE_SET}="native-instruments-korecontroller.conf"
+ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="041d", ENV{PULSE_PROFILE_SET}="native-instruments-traktor-audio2.conf"
+ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1011", ENV{PULSE_PROFILE_SET}="native-instruments-traktor-audio6.conf"
+ATTRS{idVendor}=="17cc", ATTRS{idProduct}=="1021", ENV{PULSE_PROFILE_SET}="native-instruments-traktor-audio10.conf"
+ATTRS{idVendor}=="0763", ATTRS{idProduct}=="2012", ENV{PULSE_PROFILE_SET}="maudio-fasttrack-pro.conf"
+ATTRS{idVendor}=="045e", ATTRS{idProduct}=="02bb", ENV{PULSE_PROFILE_SET}="kinect-audio.conf"
 
 LABEL="pulseaudio_end"
index 9838138..3599535 100644 (file)
 
 ; Default profile definitions for the ALSA backend of PulseAudio. This
 ; is used as fallback for all cards that have no special mapping
-; assigned. (and should be good enough for the vast majority of
-; cards).  Use the udev property PULSE_PROFILE_SET to assign a
-; different profile set than this one to a device.  So what is this
-; about? Simply, what we do here is map ALSA devices to how they are
-; exposed in PA. We say which ALSA device string to use to open a
-; device, which channel mapping to use then, and which mixer path to
-; use. This is encoded in a 'mapping'. Multiple of these mappings can
-; be bound together in a 'profile' which is then directly exposed in
-; the UI as a card profile. Each mapping assigned to a profile will
-; result in one sink/source to be created if the profile is selected
-; for the card.
+; assigned (and should be good enough for the vast majority of
+; cards). If you want to assign a different profile set than this one
+; to a device, either set the udev property PULSE_PROFILE_SET for the
+; card, or use the "profile_set" module argument when loading
+; module-alsa-card.
+;
+; So what is this about? Simply, what we do here is map ALSA devices
+; to how they are exposed in PA. We say which ALSA device string to
+; use to open a device, which channel mapping to use then, and which
+; mixer path to use. This is encoded in a 'mapping'. Multiple of these
+; mappings can be bound together in a 'profile' which is then directly
+; exposed in the UI as a card profile. Each mapping assigned to a
+; profile will result in one sink/source to be created if the profile
+; is selected for the card.
+;
+; Additionally, the path set configuration files can describe the
+; decibel values assigned to the steps of the volume elements. This
+; can be used to work around situations when the alsa driver doesn't
+; provide any decibel information, or when the information is
+; incorrect.
+
 
 ; [General]
 ; auto-profiles = no | yes                  # Instead of defining all profiles manually, autogenerate
 ; skip-probe = no | yes                     # Skip probing for availability? If this is yes then this profile
 ;                                           # will be assumed as working without probing. Makes initialization
 ;                                           # a bit faster but only works if the card is really known well.
+;
+; [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.
+;                                           #
+;                                           # 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
+;                                           # decibel mappings!
+;                                           #
+;                                           # If you need this feature, then you should make sure that when you have
+;                                           # the correct values figured out, the alsa driver developers get informed
+;                                           # too, so that they can fix the driver.
+;
+; db-values = ...                           # The option value consists of pairs of step numbers and decibel values.
+;                                           # The pairs are separated with whitespace, and steps are separated from
+;                                           # the corresponding decibel values with a colon. The values must be in an
+;                                           # increasing order. Here's an example of a valid string:
+;                                           #
+;                                           #     "0:-40.50  1:-38.70  3:-33.00  11:0"
+;                                           #
+;                                           # The lowest step imposes a lower limit for hardware volume and the
+;                                           # highest step correspondingly imposes a higher limit. That means that
+;                                           # that the mixer will never be set outside those values - the rest of the
+;                                           # volume scale is done using software volume.
+;                                           #
+;                                           # As can be seen in the example, you don't need to specify a dB value for
+;                                           # each step. The dB values for skipped steps will be linearly interpolated
+;                                           # using the nearest steps that are given.
 
 [General]
 auto-profiles = yes
 
 [Mapping analog-mono]
-device-strings = hw:0
+device-strings = hw:%f
 channel-map = mono
-paths-output = analog-output analog-output-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono analog-output-lfe-on-mono
-paths-input = analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono
+paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headset-mic
 priority = 1
 
 [Mapping analog-stereo]
-device-strings = front:%f hw:0
+device-strings = front:%f hw:%f
 channel-map = left,right
-paths-output = analog-output analog-output-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono analog-output-lfe-on-mono
-paths-input = analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker analog-output-headphones analog-output-headphones-2
+paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic analog-input-headset-mic
 priority = 10
 
 [Mapping analog-surround-40]
 device-strings = surround40:%f
 channel-map = front-left,front-right,rear-left,rear-right
-paths-output = analog-output analog-output-speaker analog-output-lfe-on-mono
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker
 priority = 7
 direction = output
 
 [Mapping analog-surround-41]
 device-strings = surround41:%f
 channel-map = front-left,front-right,rear-left,rear-right,lfe
-paths-output = analog-output analog-output-speaker analog-output-lfe-on-mono
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker
 priority = 8
 direction = output
 
 [Mapping analog-surround-50]
 device-strings = surround50:%f
 channel-map = front-left,front-right,rear-left,rear-right,front-center
-paths-output = analog-output analog-output-speaker analog-output-lfe-on-mono
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker
 priority = 7
 direction = output
 
 [Mapping analog-surround-51]
 device-strings = surround51:%f
 channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
-paths-output = analog-output analog-output-speaker analog-output-lfe-on-mono
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker
 priority = 8
 direction = output
 
@@ -105,29 +144,44 @@ direction = output
 device-strings = surround71:%f
 channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right
 description = Analog Surround 7.1
-paths-output = analog-output analog-output-speaker analog-output-lfe-on-mono
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker
 priority = 7
 direction = output
 
+[Mapping analog-4-channel-input]
+# Alsa doesn't currently provide any better device name than "hw" for 4-channel
+# input. If this causes trouble at some point, then we will need to get a new
+# device name standardized in alsa.
+device-strings = hw:%f
+channel-map = aux0,aux1,aux2,aux3
+priority = 1
+direction = input
+
 [Mapping iec958-stereo]
 device-strings = iec958:%f
 channel-map = left,right
+paths-input = iec958-stereo-input
+paths-output = iec958-stereo-output
 priority = 5
 
-[Mapping iec958-surround-40]
-device-strings = iec958:%f
-channel-map = front-left,front-right,rear-left,rear-right
-priority = 1
-
 [Mapping iec958-ac3-surround-40]
 device-strings = a52:%f
 channel-map = front-left,front-right,rear-left,rear-right
+paths-output = iec958-stereo-output
 priority = 2
 direction = output
 
 [Mapping iec958-ac3-surround-51]
 device-strings = a52:%f
 channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+paths-output = iec958-stereo-output
+priority = 3
+direction = output
+
+[Mapping iec958-dts-surround-51]
+device-strings = dca:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+paths-output = iec958-stereo-output
 priority = 3
 direction = output
 
@@ -136,6 +190,7 @@ device-strings = hdmi:%f
 channel-map = left,right
 priority = 4
 direction = output
+paths-output = hdmi-output-0
 
 ; An example for defining multiple-sink profiles
 #[Profile output:analog-stereo+output:iec958-stereo+input:analog-stereo]
diff --git a/src/modules/alsa/mixer/profile-sets/extra-hdmi.conf b/src/modules/alsa/mixer/profile-sets/extra-hdmi.conf
new file mode 100644 (file)
index 0000000..098de03
--- /dev/null
@@ -0,0 +1,164 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; This is a profile for Nvidia and Intel cards - some cards have four HDMI codecs,
+; and which ones are working seems to vary a lot between GPU boards. In addition,
+; Nvidia and Intel make southbridges as well, so we need to keep the existing
+; analog profiles.
+; (And by not adding all these extra profiles to default.conf, we make sure
+; there is no performance hit for non-Nvidia/Intel cards.)
+
+[General]
+auto-profiles = yes
+
+[Mapping analog-mono]
+device-strings = hw:%f
+channel-map = mono
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono
+paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headset-mic
+priority = 1
+
+[Mapping analog-stereo]
+device-strings = front:%f hw:%f
+channel-map = left,right
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker analog-output-headphones analog-output-headphones-2
+paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line analog-input-headphone-mic analog-input-headset-mic
+priority = 10
+
+[Mapping analog-surround-40]
+device-strings = surround40:%f
+channel-map = front-left,front-right,rear-left,rear-right
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker
+priority = 7
+direction = output
+
+[Mapping analog-surround-41]
+device-strings = surround41:%f
+channel-map = front-left,front-right,rear-left,rear-right,lfe
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker
+priority = 8
+direction = output
+
+[Mapping analog-surround-50]
+device-strings = surround50:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker
+priority = 7
+direction = output
+
+[Mapping analog-surround-51]
+device-strings = surround51:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker
+priority = 8
+direction = output
+
+[Mapping analog-surround-71]
+device-strings = surround71:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right
+description = Analog Surround 7.1
+paths-output = analog-output analog-output-speaker analog-output-desktop-speaker
+priority = 7
+direction = output
+
+[Mapping iec958-stereo]
+device-strings = iec958:%f
+channel-map = left,right
+paths-input = iec958-stereo-input
+paths-output = iec958-stereo-output
+priority = 5
+
+[Mapping iec958-ac3-surround-40]
+device-strings = a52:%f
+channel-map = front-left,front-right,rear-left,rear-right
+priority = 2
+direction = output
+
+[Mapping iec958-ac3-surround-51]
+device-strings = a52:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+priority = 3
+direction = output
+
+[Mapping iec958-dts-surround-51]
+device-strings = dca:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+priority = 3
+direction = output
+
+[Mapping hdmi-stereo]
+device-strings = hdmi:%f
+description = Digital Stereo (HDMI)
+paths-output = hdmi-output-0
+channel-map = left,right
+priority = 4
+direction = output
+
+[Mapping hdmi-surround]
+description = Digital Surround 5.1 (HDMI)
+device-strings = hdmi:%f
+paths-output = hdmi-output-0
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+priority = 3
+direction = output
+
+[Mapping hdmi-stereo-extra1]
+description = Digital Stereo (HDMI)
+device-strings = hdmi:%f,1
+paths-output = hdmi-output-1
+channel-map = left,right
+priority = 2
+direction = output
+
+[Mapping hdmi-surround-extra1]
+description = Digital Surround 5.1 (HDMI)
+device-strings = hdmi:%f,1
+paths-output = hdmi-output-1
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+priority = 1
+direction = output
+
+[Mapping hdmi-stereo-extra2]
+description = Digital Stereo (HDMI)
+device-strings = hdmi:%f,2
+paths-output = hdmi-output-2
+channel-map = left,right
+priority = 2
+direction = output
+
+[Mapping hdmi-surround-extra2]
+description = Digital Surround 5.1 (HDMI)
+device-strings = hdmi:%f,2
+paths-output = hdmi-output-2
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+priority = 1
+direction = output
+
+[Mapping hdmi-stereo-extra3]
+description = Digital Stereo (HDMI)
+device-strings = hdmi:%f,3
+paths-output = hdmi-output-3
+channel-map = left,right
+priority = 2
+direction = output
+
+[Mapping hdmi-surround-extra3]
+description = Digital Surround 5.1 (HDMI)
+device-strings = hdmi:%f,3
+paths-output = hdmi-output-3
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+priority = 1
+direction = output
diff --git a/src/modules/alsa/mixer/profile-sets/force-speaker-and-int-mic.conf b/src/modules/alsa/mixer/profile-sets/force-speaker-and-int-mic.conf
new file mode 100644 (file)
index 0000000..2095cf9
--- /dev/null
@@ -0,0 +1,122 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; This profile forces speaker and internal mic ports even if we have no way
+; of identifying those.
+; See default.conf for explanations.
+
+[General]
+auto-profiles = yes
+
+[Mapping analog-mono]
+device-strings = hw:%f
+channel-map = mono
+paths-output = analog-output analog-output-speaker-always analog-output-desktop-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono
+paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic-always analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line
+priority = 1
+
+[Mapping analog-stereo]
+device-strings = front:%f hw:%f
+channel-map = left,right
+paths-output = analog-output analog-output-speaker-always analog-output-desktop-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono
+paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic-always analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line
+priority = 10
+
+[Mapping analog-surround-40]
+device-strings = surround40:%f
+channel-map = front-left,front-right,rear-left,rear-right
+paths-output = analog-output analog-output-speaker-always analog-output-desktop-speaker
+priority = 7
+direction = output
+
+[Mapping analog-surround-41]
+device-strings = surround41:%f
+channel-map = front-left,front-right,rear-left,rear-right,lfe
+paths-output = analog-output analog-output-speaker-always analog-output-desktop-speaker
+priority = 8
+direction = output
+
+[Mapping analog-surround-50]
+device-strings = surround50:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center
+paths-output = analog-output analog-output-speaker-always analog-output-desktop-speaker
+priority = 7
+direction = output
+
+[Mapping analog-surround-51]
+device-strings = surround51:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+paths-output = analog-output analog-output-speaker-always analog-output-desktop-speaker
+priority = 8
+direction = output
+
+[Mapping analog-surround-71]
+device-strings = surround71:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right
+description = Analog Surround 7.1
+paths-output = analog-output analog-output-speaker-always analog-output-desktop-speaker
+priority = 7
+direction = output
+
+[Mapping analog-4-channel-input]
+# Alsa doesn't currently provide any better device name than "hw" for 4-channel
+# input. If this causes trouble at some point, then we will need to get a new
+# device name standardized in alsa.
+device-strings = hw:%f
+channel-map = aux0,aux1,aux2,aux3
+priority = 1
+direction = input
+
+[Mapping iec958-stereo]
+device-strings = iec958:%f
+channel-map = left,right
+paths-input = iec958-stereo-input
+paths-output = iec958-stereo-output
+priority = 5
+
+[Mapping iec958-ac3-surround-40]
+device-strings = a52:%f
+channel-map = front-left,front-right,rear-left,rear-right
+paths-output = iec958-stereo-output
+priority = 2
+direction = output
+
+[Mapping iec958-ac3-surround-51]
+device-strings = a52:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+paths-output = iec958-stereo-output
+priority = 3
+direction = output
+
+[Mapping iec958-dts-surround-51]
+device-strings = dca:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+paths-output = iec958-stereo-output
+priority = 3
+direction = output
+
+[Mapping hdmi-stereo]
+device-strings = hdmi:%f
+channel-map = left,right
+priority = 4
+direction = output
+paths-output = hdmi-output-0
+
+; An example for defining multiple-sink profiles
+#[Profile output:analog-stereo+output:iec958-stereo+input:analog-stereo]
+#description = Foobar
+#output-mappings = analog-stereo iec958-stereo
+#input-mappings = analog-stereo
diff --git a/src/modules/alsa/mixer/profile-sets/force-speaker.conf b/src/modules/alsa/mixer/profile-sets/force-speaker.conf
new file mode 100644 (file)
index 0000000..f03ada6
--- /dev/null
@@ -0,0 +1,121 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; This profile forces a speaker port even if we have no way of identifying it.
+; See default.conf for explanations.
+
+[General]
+auto-profiles = yes
+
+[Mapping analog-mono]
+device-strings = hw:%f
+channel-map = mono
+paths-output = analog-output analog-output-speaker-always analog-output-desktop-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono
+paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line
+priority = 1
+
+[Mapping analog-stereo]
+device-strings = front:%f hw:%f
+channel-map = left,right
+paths-output = analog-output analog-output-speaker-always analog-output-desktop-speaker analog-output-headphones analog-output-headphones-2 analog-output-mono
+paths-input = analog-input-front-mic analog-input-rear-mic analog-input-internal-mic analog-input-dock-mic analog-input analog-input-mic analog-input-linein analog-input-aux analog-input-video analog-input-tvtuner analog-input-fm analog-input-mic-line
+priority = 10
+
+[Mapping analog-surround-40]
+device-strings = surround40:%f
+channel-map = front-left,front-right,rear-left,rear-right
+paths-output = analog-output analog-output-speaker-always analog-output-desktop-speaker
+priority = 7
+direction = output
+
+[Mapping analog-surround-41]
+device-strings = surround41:%f
+channel-map = front-left,front-right,rear-left,rear-right,lfe
+paths-output = analog-output analog-output-speaker-always analog-output-desktop-speaker
+priority = 8
+direction = output
+
+[Mapping analog-surround-50]
+device-strings = surround50:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center
+paths-output = analog-output analog-output-speaker-always analog-output-desktop-speaker
+priority = 7
+direction = output
+
+[Mapping analog-surround-51]
+device-strings = surround51:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+paths-output = analog-output analog-output-speaker-always analog-output-desktop-speaker
+priority = 8
+direction = output
+
+[Mapping analog-surround-71]
+device-strings = surround71:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right
+description = Analog Surround 7.1
+paths-output = analog-output analog-output-speaker-always analog-output-desktop-speaker
+priority = 7
+direction = output
+
+[Mapping analog-4-channel-input]
+# Alsa doesn't currently provide any better device name than "hw" for 4-channel
+# input. If this causes trouble at some point, then we will need to get a new
+# device name standardized in alsa.
+device-strings = hw:%f
+channel-map = aux0,aux1,aux2,aux3
+priority = 1
+direction = input
+
+[Mapping iec958-stereo]
+device-strings = iec958:%f
+channel-map = left,right
+paths-input = iec958-stereo-input
+paths-output = iec958-stereo-output
+priority = 5
+
+[Mapping iec958-ac3-surround-40]
+device-strings = a52:%f
+channel-map = front-left,front-right,rear-left,rear-right
+paths-output = iec958-stereo-output
+priority = 2
+direction = output
+
+[Mapping iec958-ac3-surround-51]
+device-strings = a52:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+paths-output = iec958-stereo-output
+priority = 3
+direction = output
+
+[Mapping iec958-dts-surround-51]
+device-strings = dca:%f
+channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
+paths-output = iec958-stereo-output
+priority = 3
+direction = output
+
+[Mapping hdmi-stereo]
+device-strings = hdmi:%f
+channel-map = left,right
+priority = 4
+direction = output
+paths-output = hdmi-output-0
+
+; An example for defining multiple-sink profiles
+#[Profile output:analog-stereo+output:iec958-stereo+input:analog-stereo]
+#description = Foobar
+#output-mappings = analog-stereo iec958-stereo
+#input-mappings = analog-stereo
diff --git a/src/modules/alsa/mixer/profile-sets/kinect-audio.conf b/src/modules/alsa/mixer/profile-sets/kinect-audio.conf
new file mode 100644 (file)
index 0000000..a66730a
--- /dev/null
@@ -0,0 +1,39 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; Audio profile for the Microsoft Kinect Sensor device in UAC mode.
+;
+; Copyright (C) 2011  Antonio Ospite <ospite@studenti.unina.it>
+;
+; This device has an array of four microphones, and no playback capability.
+;
+; See default.conf for an explanation on the directives used here.
+
+[General]
+auto-profiles = no
+
+[Mapping input-4-channels]
+device-strings = hw:%f
+channel-map = front-left,front-right,rear-left,rear-right
+description = 4 Channels Input
+direction = input
+priority = 5
+
+[Profile input:mic-array]
+description = Microphone Array
+input-mappings = input-4-channels
+priority = 2
+skip-probe = yes
diff --git a/src/modules/alsa/mixer/profile-sets/maudio-fasttrack-pro.conf b/src/modules/alsa/mixer/profile-sets/maudio-fasttrack-pro.conf
new file mode 100644 (file)
index 0000000..c8025fd
--- /dev/null
@@ -0,0 +1,87 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; M-Audio FastTrack Pro
+;
+; This card has one duplex stereo channel called A and an additional
+; stereo output channel called B.
+;
+; We knowingly only define a subset of the theoretically possible
+; mapping combinations as profiles here.
+;
+; See default.conf for an explanation on the directives used here.
+
+[General]
+auto-profiles = no
+
+[Mapping analog-stereo-a-output]
+description = Analog Stereo Channel A
+device-strings = hw:%f,0,0
+channel-map = left,right
+direction = output
+
+; Try both device 0 and device 1 for input, see
+; http://mailman.alsa-project.org/pipermail/alsa-devel/2012-March/050701.html
+[Mapping analog-stereo-a-input]
+description = Analog Stereo Channel A
+device-strings = hw:%f,0,0 hw:%f,1,0
+channel-map = left,right
+direction = input
+
+[Mapping analog-stereo-b-output]
+description = Analog Stereo Channel B
+device-strings = hw:%f,1,0
+channel-map = left,right
+direction = output
+
+[Profile output:analog-stereo-all+input:analog-stereo-all]
+description = Analog Stereo Duplex Channel A, Analog Stereo output Channel B
+output-mappings = analog-stereo-a-output  analog-stereo-b-output
+input-mappings = analog-stereo-a-input
+priority = 100
+skip-probe = yes
+
+[Profile output:analog-stereo-a-output+input:analog-stereo-a-input]
+description = Analog Stereo Duplex Channel A
+output-mappings = analog-stereo-a-output
+input-mappings = analog-stereo-a-input
+priority = 40
+skip-probe = yes
+
+[Profile output:analog-stereo-b+input:analog-stereo-b]
+description = Analog Stereo Output Channel B
+output-mappings = analog-stereo-b-output
+input-mappings =
+priority = 50
+skip-probe = yes
+
+[Profile output:analog-stereo-a]
+description = Analog Stereo Output Channel A
+output-mappings = analog-stereo-a-output
+priority = 5
+skip-probe = yes
+
+[Profile output:analog-stereo-b]
+description = Analog Stereo Output Channel B
+output-mappings = analog-stereo-b-output
+priority = 6
+skip-probe = yes
+
+[Profile input:analog-stereo-a]
+description = Analog Stereo Input Channel A
+input-mappings = analog-stereo-a-input
+priority = 2
+skip-probe = yes
index 3fe3cc5..d2990de 100644 (file)
@@ -39,7 +39,7 @@ device-strings = hw:%f,0,1
 channel-map = left,right
 
 # Since we want to set a different description for channel C's/D's input
-# and output we define two seperate mappings for them
+# and output we define two separate mappings for them
 [Mapping analog-stereo-c-output]
 description = Analog Stereo Channel C
 device-strings = hw:%f,0,2
diff --git a/src/modules/alsa/mixer/profile-sets/native-instruments-korecontroller.conf b/src/modules/alsa/mixer/profile-sets/native-instruments-korecontroller.conf
new file mode 100644 (file)
index 0000000..904357d
--- /dev/null
@@ -0,0 +1,85 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; Native Instruments Kore Controller
+;
+; This card has one stereo pairs of input and two stereo pairs of
+; output, named "Master" and "Headphone". The master channel has
+; an additional Coax S/PDIF connector which is always on.
+;
+; We knowingly only define a subset of the theoretically possible
+; mapping combinations as profiles here.
+;
+; See default.conf for an explanation on the directives used here.
+
+[General]
+auto-profiles = no
+
+[Mapping analog-stereo-master-out]
+description = Analog Stereo Master Channel
+device-strings = hw:%f,0,0
+channel-map = left,right
+
+[Mapping analog-stereo-headphone-out]
+description = Analog Stereo Headphone Channel
+device-strings = hw:%f,0,1
+channel-map = left,right
+direction = output
+
+[Mapping analog-stereo-input]
+description = Analog Stereo
+device-strings = hw:%f,0,0
+channel-map = left,right
+direction = input
+
+[Profile output:analog-stereo-all+input:analog-stereo-all]
+description = Analog Stereo Duplex Master Output, Headphones Output
+output-mappings = analog-stereo-master-out analog-stereo-headphone-out
+input-mappings = analog-stereo-input
+priority = 100
+skip-probe = yes
+
+[Profile output:analog-stereo-master+input:analog-stereo-input]
+description = Analog Stereo Duplex Master Output
+output-mappings = analog-stereo-master-out
+input-mappings = analog-stereo-input
+priority = 40
+skip-probe = yes
+
+[Profile output:analog-stereo-headphone-out+input:analog-stereo-input]
+description = Analog Stereo Headphones Output
+output-mappings = analog-stereo-headphone-out
+input-mappings = analog-stereo-input
+priority = 30
+skip-probe = yes
+
+[Profile output:analog-stereo-master]
+description = Analog Stereo Master Output
+output-mappings = analog-stereo-master-out
+priority = 3
+skip-probe = yes
+
+[Profile output:analog-stereo-headphone]
+description = Analog Stereo Headphones Output
+output-mappings = analog-stereo-headphone-out
+priority = 2
+skip-probe = yes
+
+[Profile input:analog-stereo-input]
+description = Analog Stereo Input
+input-mappings = analog-stereo-input
+priority = 1
+skip-probe = yes
diff --git a/src/modules/alsa/mixer/profile-sets/native-instruments-traktor-audio10.conf b/src/modules/alsa/mixer/profile-sets/native-instruments-traktor-audio10.conf
new file mode 100644 (file)
index 0000000..4deb65d
--- /dev/null
@@ -0,0 +1,131 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; Native Instruments Audio 10 DJ
+;
+; This card has five stereo pairs of input and five stereo pairs of
+; output
+;
+; We knowingly only define a subset of the theoretically possible
+; mapping combinations as profiles here.
+;
+; See default.conf for an explanation on the directives used here.
+
+[General]
+auto-profiles = no
+
+[Mapping analog-stereo-out-main]
+description = Analog Stereo Main
+device-strings = hw:%f,0,0
+channel-map = left,right
+
+[Mapping analog-stereo-out-a]
+description = Analog Stereo Channel A
+device-strings = hw:%f,0,1
+channel-map = left,right
+direction = output
+
+[Mapping analog-stereo-out-b]
+description = Analog Stereo Channel B
+device-strings = hw:%f,0,1
+channel-map = left,right
+direction = output
+
+[Mapping analog-stereo-out-c]
+description = Analog Stereo Channel C
+device-strings = hw:%f,0,2
+channel-map = left,right
+direction = output
+
+[Mapping analog-stereo-out-d]
+description = Analog Stereo Channel D
+device-strings = hw:%f,0,3
+channel-map = left,right
+direction = output
+
+[Mapping analog-stereo-in-main]
+description = Analog Stereo Main
+device-strings = hw:%f,0,0
+channel-map = left,right
+
+[Mapping analog-stereo-in-a]
+description = Analog Stereo Channel A
+device-strings = hw:%f,0,1
+channel-map = left,right
+direction = input
+
+[Mapping analog-stereo-in-b]
+description = Analog Stereo Channel B
+device-strings = hw:%f,0,1
+channel-map = left,right
+direction = input
+
+[Mapping analog-stereo-in-c]
+description = Analog Stereo Channel C
+device-strings = hw:%f,0,2
+channel-map = left,right
+direction = input
+
+[Mapping analog-stereo-in-d]
+description = Analog Stereo Channel D
+device-strings = hw:%f,0,3
+channel-map = left,right
+direction = input
+
+
+
+
+[Profile output:analog-stereo-all+input:analog-stereo-all]
+description = Analog Stereo Duplex Channels Main, A, B, C, D
+output-mappings = analog-stereo-out-main analog-stereo-out-a analog-stereo-out-b analog-stereo-out-c analog-stereo-out-d
+input-mappings = analog-stereo-in-main analog-stereo-in-a analog-stereo-in-b analog-stereo-in-c analog-stereo-in-d
+priority = 100
+skip-probe = yes
+
+[Profile output:analog-stereo-main+input:analog-stereo-main]
+description = Analog Stereo Duplex Main
+output-mappings = analog-stereo-out-main
+input-mappings = analog-stereo-in-main
+priority = 50
+skip-probe = yes
+
+[Profile output:analog-stereo-a+input:analog-stereo-a]
+description = Analog Stereo Duplex Channel A
+output-mappings = analog-stereo-out-a
+input-mappings = analog-stereo-in-a
+priority = 40
+skip-probe = yes
+
+[Profile output:analog-stereo-b+input:analog-stereo-b]
+description = Analog Stereo Duplex Channel B
+output-mappings = analog-stereo-out-b
+input-mappings = analog-stereo-in-b
+priority = 30
+skip-probe = yes
+
+[Profile output:analog-stereo-a+input:analog-stereo-c]
+description = Analog Stereo Duplex Channel C
+output-mappings = analog-stereo-out-c
+input-mappings = analog-stereo-in-c
+priority = 20
+skip-probe = yes
+
+[Profile output:analog-stereo-a+input:analog-stereo-d]
+description = Analog Stereo Duplex Channel D
+output-mappings = analog-stereo-out-d
+input-mappings = analog-stereo-in-d
+priority = 10
+skip-probe = yes
diff --git a/src/modules/alsa/mixer/profile-sets/native-instruments-traktor-audio6.conf b/src/modules/alsa/mixer/profile-sets/native-instruments-traktor-audio6.conf
new file mode 100644 (file)
index 0000000..48d9058
--- /dev/null
@@ -0,0 +1,92 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; Native Instruments Audio 6 DJ
+;
+; This card has three stereo pairs of input and three stereo pairs of
+; output
+;
+; We knowingly only define a subset of the theoretically possible
+; mapping combinations as profiles here.
+;
+; See default.conf for an explanation on the directives used here.
+
+[General]
+auto-profiles = no
+
+[Mapping analog-stereo-out-main]
+description = Analog Stereo Main
+device-strings = hw:%f,0,0
+channel-map = left,right
+
+[Mapping analog-stereo-out-a]
+description = Analog Stereo Channel A
+device-strings = hw:%f,0,1
+channel-map = left,right
+direction = output
+
+[Mapping analog-stereo-out-b]
+description = Analog Stereo Channel B
+device-strings = hw:%f,0,1
+channel-map = left,right
+direction = output
+
+[Mapping analog-stereo-in-main]
+description = Analog Stereo Main
+device-strings = hw:%f,0,0
+channel-map = left,right
+
+[Mapping analog-stereo-in-a]
+description = Analog Stereo Channel A
+device-strings = hw:%f,0,1
+channel-map = left,right
+direction = input
+
+[Mapping analog-stereo-in-b]
+description = Analog Stereo Channel B
+device-strings = hw:%f,0,1
+channel-map = left,right
+direction = input
+
+
+
+[Profile output:analog-stereo-all+input:analog-stereo-all]
+description = Analog Stereo Duplex Channels A, B (Headphones)
+output-mappings = analog-stereo-out-main analog-stereo-out-a analog-stereo-out-b
+input-mappings = analog-stereo-in-main analog-stereo-in-a analog-stereo-in-b
+priority = 100
+skip-probe = yes
+
+[Profile output:analog-stereo-main+input:analog-stereo-main]
+description = Analog Stereo Duplex Channel Main
+output-mappings = analog-stereo-out-main
+input-mappings = analog-stereo-in-main
+priority = 50
+skip-probe = yes
+
+[Profile output:analog-stereo-a+input:analog-stereo-a]
+description = Analog Stereo Duplex Channel A
+output-mappings = analog-stereo-out-a
+input-mappings = analog-stereo-in-a
+priority = 40
+skip-probe = yes
+
+[Profile output:analog-stereo-b+input:analog-stereo-b]
+description = Analog Stereo Duplex Channel B
+output-mappings = analog-stereo-out-b
+input-mappings = analog-stereo-in-b
+priority = 30
+skip-probe = yes
diff --git a/src/modules/alsa/mixer/profile-sets/native-instruments-traktorkontrol-s4.conf b/src/modules/alsa/mixer/profile-sets/native-instruments-traktorkontrol-s4.conf
new file mode 100644 (file)
index 0000000..1da843a
--- /dev/null
@@ -0,0 +1,81 @@
+# This file is part of PulseAudio.
+#
+# 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+; Native Instruments Traktor Kontrol S4
+;
+; This controller has two stereo pairs of input (named "Channel C" and
+; "Channel D") and two stereo pairs of output, one "Main Out" and
+; "Headphone Out".
+;
+; See default.conf for an explanation on the directives used here.
+
+[General]
+auto-profiles = no
+
+[Mapping analog-stereo-output-main]
+description = Analog Stereo Main Out
+device-strings = hw:%f,0,0
+channel-map = left,right
+
+[Mapping analog-stereo-output-headphone]
+description = Analog Stereo Headphones Out
+device-strings = hw:%f,0,1
+channel-map = left,right
+direction = output
+
+[Mapping analog-stereo-c-input]
+description = Analog Stereo Channel C
+device-strings = hw:%f,0,1
+channel-map = left,right
+direction = input
+
+[Mapping analog-stereo-d-input]
+description = Analog Stereo Channel D
+device-strings = hw:%f,0,1
+channel-map = left,right
+direction = input
+
+[Profile output:analog-stereo-all+input:analog-stereo-all]
+description = Analog Stereo Duplex
+output-mappings = analog-stereo-output-main analog-stereo-output-headphone
+input-mappings = analog-stereo-c-input analog-stereo-d-input
+priority = 100
+skip-probe = yes
+
+[Profile output:analog-stereo-main]
+description = Analog Stereo Main Output
+output-mappings = analog-stereo-output-main
+priority = 4
+skip-probe = yes
+
+[Profile output:analog-stereo-headphone]
+description = Analog Stereo Output Headphones Out
+output-mappings = analog-stereo-output-headphone
+priority = 3
+skip-probe = yes
+
+[Profile input:analog-stereo-c]
+description = Analog Stereo Input Channel C
+input-mappings = analog-stereo-c-input
+priority = 2
+skip-probe = yes
+
+[Profile input:analog-stereo-d]
+description = Analog Stereo Input Channel D
+input-mappings = analog-stereo-d-input
+priority = 1
+skip-probe = yes
+
diff --git a/src/modules/alsa/module-alsa-card-symdef.h b/src/modules/alsa/module-alsa-card-symdef.h
deleted file mode 100644 (file)
index 9613c51..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulealsacardsymdeffoo
-#define foomodulealsacardsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_alsa_card_LTX_pa__init
-#define pa__done module_alsa_card_LTX_pa__done
-#define pa__get_author module_alsa_card_LTX_pa__get_author
-#define pa__get_description module_alsa_card_LTX_pa__get_description
-#define pa__get_usage module_alsa_card_LTX_pa__get_usage
-#define pa__get_version module_alsa_card_LTX_pa__get_version
-#define pa__get_deprecated module_alsa_card_LTX_pa__get_deprecated
-#define pa__load_once module_alsa_card_LTX_pa__load_once
-#define pa__get_n_used module_alsa_card_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 6bea33d..8f7299f 100644 (file)
@@ -24,9 +24,9 @@
 #endif
 
 #include <pulse/xmalloc.h>
-#include <pulse/i18n.h>
 
 #include <pulsecore/core-util.h>
+#include <pulsecore/i18n.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/queue.h>
 
@@ -37,6 +37,7 @@
 #endif
 
 #include "alsa-util.h"
+#include "alsa-ucm.h"
 #include "alsa-sink.h"
 #include "alsa-source.h"
 #include "module-alsa-card-symdef.h"
@@ -53,6 +54,7 @@ PA_MODULE_USAGE(
         "sink_properties=<properties for the sink> "
         "source_name=<name for the source> "
         "source_properties=<properties for the source> "
+        "namereg_fail=<when false attempt to synthesise new names if they are already taken> "
         "device_id=<ALSA card index> "
         "format=<sample format> "
         "rate=<sample rate> "
@@ -63,7 +65,13 @@ PA_MODULE_USAGE(
         "tsched_buffer_size=<buffer size when using timer based scheduling> "
         "tsched_buffer_watermark=<lower fill watermark> "
         "profile=<profile name> "
-        "ignore_dB=<ignore dB information from the device?>");
+        "fixed_latency_range=<disable latency range changes on underrun?> "
+        "ignore_dB=<ignore dB information from the device?> "
+        "deferred_volume=<Synchronize software and hardware volume changes to avoid momentary jumps?> "
+        "profile_set=<profile set configuration file> "
+        "paths_dir=<directory containing the path configuration files> "
+        "use_ucm=<load use case manager> "
+);
 
 static const char* const valid_modargs[] = {
     "name",
@@ -73,6 +81,7 @@ static const char* const valid_modargs[] = {
     "sink_properties",
     "source_name",
     "source_properties",
+    "namereg_fail",
     "device_id",
     "format",
     "rate",
@@ -82,8 +91,13 @@ static const char* const valid_modargs[] = {
     "tsched",
     "tsched_buffer_size",
     "tsched_buffer_watermark",
+    "fixed_latency_range",
     "profile",
     "ignore_dB",
+    "deferred_volume",
+    "profile_set",
+    "paths_dir",
+    "use_ucm",
     NULL
 };
 
@@ -94,19 +108,36 @@ struct userdata {
     pa_module *module;
 
     char *device_id;
+    int alsa_card_index;
+
+    snd_mixer_t *mixer_handle;
+    snd_hctl_t *hctl_handle;
+    pa_hashmap *jacks;
+    pa_alsa_fdlist *mixer_fdl;
 
     pa_card *card;
 
     pa_modargs *modargs;
 
     pa_alsa_profile_set *profile_set;
+
+    /* ucm stuffs */
+    pa_bool_t use_ucm;
+    pa_alsa_ucm_config ucm;
+
+    /* hooks for modifier action */
+    pa_hook_slot
+        *sink_input_put_hook_slot,
+        *source_output_put_hook_slot,
+        *sink_input_unlink_hook_slot,
+        *source_output_unlink_hook_slot;
 };
 
 struct profile_data {
     pa_alsa_profile *profile;
 };
 
-static void add_profiles(struct userdata *u, pa_hashmap *h) {
+static void add_profiles(struct userdata *u, pa_hashmap *h, pa_hashmap *ports) {
     pa_alsa_profile *ap;
     void *state;
 
@@ -125,17 +156,27 @@ static void add_profiles(struct userdata *u, pa_hashmap *h) {
         if (ap->output_mappings) {
             cp->n_sinks = pa_idxset_size(ap->output_mappings);
 
-            PA_IDXSET_FOREACH(m, ap->output_mappings, idx)
+            PA_IDXSET_FOREACH(m, ap->output_mappings, idx) {
+                if (u->use_ucm)
+                    pa_alsa_ucm_add_ports_combination(NULL, &m->ucm_context, TRUE, ports, cp, u->core);
+                else
+                    pa_alsa_path_set_add_ports(m->output_path_set, cp, ports, NULL, u->core);
                 if (m->channel_map.channels > cp->max_sink_channels)
                     cp->max_sink_channels = m->channel_map.channels;
+            }
         }
 
         if (ap->input_mappings) {
             cp->n_sources = pa_idxset_size(ap->input_mappings);
 
-            PA_IDXSET_FOREACH(m, ap->input_mappings, idx)
+            PA_IDXSET_FOREACH(m, ap->input_mappings, idx) {
+                if (u->use_ucm)
+                    pa_alsa_ucm_add_ports_combination(NULL, &m->ucm_context, FALSE, ports, cp, u->core);
+                else
+                    pa_alsa_path_set_add_ports(m->input_path_set, cp, ports, NULL, u->core);
                 if (m->channel_map.channels > cp->max_source_channels)
                     cp->max_source_channels = m->channel_map.channels;
+            }
         }
 
         d = PA_CARD_PROFILE_DATA(cp);
@@ -201,6 +242,13 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
             am->source = NULL;
         }
 
+    /* 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,
+                    od->profile ? od->profile->name : NULL) < 0)
+            return -1;
+    }
+
     if (nd->profile && nd->profile->output_mappings)
         PA_IDXSET_FOREACH(am, nd->profile->output_mappings, idx) {
 
@@ -238,11 +286,20 @@ static void init_profile(struct userdata *u) {
     uint32_t idx;
     pa_alsa_mapping *am;
     struct profile_data *d;
+    pa_alsa_ucm_config *ucm = &u->ucm;
 
     pa_assert(u);
 
     d = PA_CARD_PROFILE_DATA(u->card->active_profile);
 
+    if (d->profile && u->use_ucm) {
+        /* Set initial verb */
+        if (pa_alsa_ucm_set_profile(ucm, d->profile->name, NULL) < 0) {
+            pa_log("Failed to set ucm profile %s", d->profile->name);
+            return;
+        }
+    }
+
     if (d->profile && d->profile->output_mappings)
         PA_IDXSET_FOREACH(am, d->profile->output_mappings, idx)
             am->sink = pa_alsa_sink_new(u->module, u->modargs, __FILE__, u->card, am);
@@ -252,6 +309,214 @@ static void init_profile(struct userdata *u) {
             am->source = pa_alsa_source_new(u->module, u->modargs, __FILE__, u->card, am);
 }
 
+static void report_port_state(pa_device_port *p, struct userdata *u)
+{
+    void *state;
+    pa_alsa_jack *jack;
+    pa_available_t pa = PA_AVAILABLE_UNKNOWN;
+    pa_device_port *port;
+
+    PA_HASHMAP_FOREACH(jack, u->jacks, state) {
+        pa_available_t cpa;
+
+        if (u->use_ucm)
+            port = pa_hashmap_get(u->card->ports, jack->name);
+        else {
+            if (jack->path)
+                port = jack->path->port;
+            else
+                continue;
+        }
+
+        if (p != port)
+            continue;
+
+        cpa = jack->plugged_in ? jack->state_plugged : jack->state_unplugged;
+
+        /* "Yes" and "no" trumphs "unknown" if we have more than one jack */
+        if (cpa == PA_AVAILABLE_UNKNOWN)
+            continue;
+
+        if ((cpa == PA_AVAILABLE_NO && pa == PA_AVAILABLE_YES) ||
+            (pa == PA_AVAILABLE_NO && cpa == PA_AVAILABLE_YES))
+            pa_log_warn("Availability of port '%s' is inconsistent!", p->name);
+        else
+            pa = cpa;
+    }
+
+    pa_device_port_set_available(p, pa);
+}
+
+static int report_jack_state(snd_hctl_elem_t *elem, unsigned int mask)
+{
+    struct userdata *u = snd_hctl_elem_get_callback_private(elem);
+    snd_ctl_elem_value_t *elem_value;
+    pa_bool_t plugged_in;
+    void *state;
+    pa_alsa_jack *jack;
+    pa_device_port *port;
+
+    pa_assert(u);
+
+    if (mask == SND_CTL_EVENT_MASK_REMOVE)
+        return 0;
+
+    snd_ctl_elem_value_alloca(&elem_value);
+    if (snd_hctl_elem_read(elem, elem_value) < 0) {
+        pa_log_warn("Failed to read jack detection from '%s'", pa_strnull(snd_hctl_elem_get_name(elem)));
+        return 0;
+    }
+
+    plugged_in = !!snd_ctl_elem_value_get_boolean(elem_value, 0);
+
+    pa_log_debug("Jack '%s' is now %s", pa_strnull(snd_hctl_elem_get_name(elem)), plugged_in ? "plugged in" : "unplugged");
+
+    PA_HASHMAP_FOREACH(jack, u->jacks, state)
+        if (jack->hctl_elem == elem) {
+            jack->plugged_in = plugged_in;
+            if (u->use_ucm) {
+                pa_assert(u->card->ports);
+                port = pa_hashmap_get(u->card->ports, jack->name);
+                pa_assert(port);
+            }
+            else {
+                pa_assert(jack->path && jack->path->port);
+                port = jack->path->port;
+            }
+            report_port_state(port, u);
+        }
+    return 0;
+}
+
+static pa_device_port* find_port_with_eld_device(pa_hashmap *ports, 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;
+    }
+    return NULL;
+}
+
+static int hdmi_eld_changed(snd_hctl_elem_t *elem, unsigned int mask) {
+    struct userdata *u = snd_hctl_elem_get_callback_private(elem);
+    int device = snd_hctl_elem_get_device(elem);
+    const char *old_monitor_name;
+    pa_device_port *p;
+    pa_hdmi_eld eld;
+    bool changed = false;
+
+    if (mask == SND_CTL_EVENT_MASK_REMOVE)
+        return 0;
+
+    p = find_port_with_eld_device(u->card->ports, device);
+    if (p == NULL) {
+        pa_log_error("Invalid device changed in ALSA: %d", device);
+        return 0;
+    }
+
+    if (pa_alsa_get_hdmi_eld(u->hctl_handle, device, &eld) < 0)
+        memset(&eld, 0, sizeof(eld));
+
+    old_monitor_name = pa_proplist_gets(p->proplist, PA_PROP_DEVICE_PRODUCT_NAME);
+    if (eld.monitor_name[0] == '\0') {
+        changed |= old_monitor_name != NULL;
+        pa_proplist_unset(p->proplist, PA_PROP_DEVICE_PRODUCT_NAME);
+    } else {
+        changed |= (old_monitor_name == NULL) || (strcmp(old_monitor_name, eld.monitor_name) != 0);
+        pa_proplist_sets(p->proplist, PA_PROP_DEVICE_PRODUCT_NAME, eld.monitor_name);
+    }
+
+    if (changed && mask != 0)
+        pa_subscription_post(u->core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, u->card->index);
+
+    return 0;
+}
+
+static void init_eld_ctls(struct userdata *u) {
+    void *state;
+    pa_device_port *port;
+
+    if (!u->hctl_handle)
+        return;
+
+    PA_HASHMAP_FOREACH(port, u->card->ports, state) {
+        pa_alsa_port_data *data = PA_DEVICE_PORT_DATA(port);
+        snd_hctl_elem_t* hctl_elem;
+        int device;
+
+        pa_assert(data->path);
+        device = data->path->eld_device;
+        if (device < 0)
+            continue;
+
+        hctl_elem = pa_alsa_find_eld_ctl(u->hctl_handle, device);
+        if (!hctl_elem) {
+            pa_log_debug("No ELD device found for port %s.", port->name);
+            continue;
+        }
+
+        snd_hctl_elem_set_callback_private(hctl_elem, u);
+        snd_hctl_elem_set_callback(hctl_elem, hdmi_eld_changed);
+        hdmi_eld_changed(hctl_elem, 0);
+    }
+}
+
+static void init_jacks(struct userdata *u) {
+    void *state;
+    pa_alsa_path* path;
+    pa_alsa_jack* jack;
+
+    u->jacks = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+
+    if (u->use_ucm) {
+        PA_LLIST_FOREACH(jack, u->ucm.jacks)
+            if (jack->has_control)
+                pa_hashmap_put(u->jacks, jack, jack);
+    } else {
+        /* See if we have any jacks */
+        if (u->profile_set->output_paths)
+            PA_HASHMAP_FOREACH(path, u->profile_set->output_paths, state)
+                PA_LLIST_FOREACH(jack, path->jacks)
+                    if (jack->has_control)
+                        pa_hashmap_put(u->jacks, jack, jack);
+
+        if (u->profile_set->input_paths)
+            PA_HASHMAP_FOREACH(path, u->profile_set->input_paths, state)
+                PA_LLIST_FOREACH(jack, path->jacks)
+                    if (jack->has_control)
+                        pa_hashmap_put(u->jacks, jack, jack);
+    }
+
+    pa_log_debug("Found %d jacks.", pa_hashmap_size(u->jacks));
+
+    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, &u->hctl_handle);
+    if (u->mixer_handle && pa_alsa_fdlist_set_handle(u->mixer_fdl, NULL, u->hctl_handle, u->core->mainloop) >= 0) {
+        PA_HASHMAP_FOREACH(jack, u->jacks, state) {
+            jack->hctl_elem = pa_alsa_find_jack(u->hctl_handle, jack->alsa_name);
+            if (!jack->hctl_elem) {
+                pa_log_warn("Jack '%s' seems to have disappeared.", jack->alsa_name);
+                jack->has_control = FALSE;
+                continue;
+            }
+            snd_hctl_elem_set_callback_private(jack->hctl_elem, u);
+            snd_hctl_elem_set_callback(jack->hctl_elem, report_jack_state);
+            report_jack_state(jack->hctl_elem, 0);
+        }
+
+    } else
+        pa_log("Failed to open hctl/mixer for jack detection");
+
+}
+
 static void set_card_name(pa_card_new_data *data, pa_modargs *ma, const char *device_id) {
     char *t;
     const char *n;
@@ -278,14 +543,76 @@ static void set_card_name(pa_card_new_data *data, pa_modargs *ma, const char *de
     pa_xfree(t);
 }
 
+static pa_hook_result_t sink_input_put_hook_callback(pa_core *c, pa_sink_input *sink_input, struct userdata *u) {
+    const char *role;
+    pa_sink *sink = sink_input->sink;
+
+    pa_assert(sink);
+
+    role = pa_proplist_gets(sink_input->proplist, PA_PROP_MEDIA_ROLE);
+
+    /* new sink input linked to sink of this card */
+    if (role && sink->card == u->card)
+        pa_alsa_ucm_roled_stream_begin(&u->ucm, role, PA_DIRECTION_OUTPUT);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t source_output_put_hook_callback(pa_core *c, pa_source_output *source_output, struct userdata *u) {
+    const char *role;
+    pa_source *source = source_output->source;
+
+    pa_assert(source);
+
+    role = pa_proplist_gets(source_output->proplist, PA_PROP_MEDIA_ROLE);
+
+    /* new source output linked to source of this card */
+    if (role && source->card == u->card)
+        pa_alsa_ucm_roled_stream_begin(&u->ucm, role, PA_DIRECTION_INPUT);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sink_input_unlink_hook_callback(pa_core *c, pa_sink_input *sink_input, struct userdata *u) {
+    const char *role;
+    pa_sink *sink = sink_input->sink;
+
+    pa_assert(sink);
+
+    role = pa_proplist_gets(sink_input->proplist, PA_PROP_MEDIA_ROLE);
+
+    /* new sink input unlinked from sink of this card */
+    if (role && sink->card == u->card)
+        pa_alsa_ucm_roled_stream_end(&u->ucm, role, PA_DIRECTION_OUTPUT);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t source_output_unlink_hook_callback(pa_core *c, pa_source_output *source_output, struct userdata *u) {
+    const char *role;
+    pa_source *source = source_output->source;
+
+    pa_assert(source);
+
+    role = pa_proplist_gets(source_output->proplist, PA_PROP_MEDIA_ROLE);
+
+    /* new source output unlinked from source of this card */
+    if (role && source->card == u->card)
+        pa_alsa_ucm_roled_stream_end(&u->ucm, role, PA_DIRECTION_INPUT);
+
+    return PA_HOOK_OK;
+}
+
 int pa__init(pa_module *m) {
     pa_card_new_data data;
     pa_modargs *ma;
-    int alsa_card_index;
+    pa_bool_t ignore_dB = FALSE;
     struct userdata *u;
     pa_reserve_wrapper *reserve = NULL;
     const char *description;
+    const char *profile = NULL;
     char *fn = NULL;
+    pa_bool_t namereg_fail = FALSE;
 
     pa_alsa_refcnt_inc();
 
@@ -296,14 +623,22 @@ int pa__init(pa_module *m) {
         goto fail;
     }
 
+    if (pa_modargs_get_value_boolean(ma, "ignore_dB", &ignore_dB) < 0) {
+        pa_log("Failed to parse ignore_dB argument.");
+        goto fail;
+    }
+
     m->userdata = u = pa_xnew0(struct userdata, 1);
     u->core = m->core;
     u->module = m;
     u->device_id = pa_xstrdup(pa_modargs_get_value(ma, "device_id", DEFAULT_DEVICE_ID));
     u->modargs = ma;
 
-    if ((alsa_card_index = snd_card_get_index(u->device_id)) < 0) {
-        pa_log("Card '%s' doesn't exist: %s", u->device_id, pa_alsa_strerror(alsa_card_index));
+    u->use_ucm = TRUE;
+    u->ucm.core = m->core;
+
+    if ((u->alsa_card_index = snd_card_get_index(u->device_id)) < 0) {
+        pa_log("Card '%s' doesn't exist: %s", u->device_id, pa_alsa_strerror(u->alsa_card_index));
         goto fail;
     }
 
@@ -319,34 +654,81 @@ int pa__init(pa_module *m) {
         }
     }
 
+    pa_modargs_get_value_boolean(ma, "use_ucm", &u->use_ucm);
+    if (u->use_ucm && !pa_alsa_ucm_query_profiles(&u->ucm, u->alsa_card_index)) {
+        pa_log_info("Found UCM profiles");
+
+        u->profile_set = pa_alsa_ucm_add_profile_set(&u->ucm, &u->core->default_channel_map);
+
+        /* hook start of sink input/source output to enable modifiers */
+        /* A little bit later than module-role-cork */
+        u->sink_input_put_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], PA_HOOK_LATE+10,
+                (pa_hook_cb_t) sink_input_put_hook_callback, u);
+        u->source_output_put_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], PA_HOOK_LATE+10,
+                (pa_hook_cb_t) source_output_put_hook_callback, u);
+
+        /* hook end of sink input/source output to disable modifiers */
+        /* A little bit later than module-role-cork */
+        u->sink_input_unlink_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_LATE+10,
+                (pa_hook_cb_t) sink_input_unlink_hook_callback, u);
+        u->source_output_unlink_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK], PA_HOOK_LATE+10,
+                (pa_hook_cb_t) source_output_unlink_hook_callback, u);
+    }
+    else {
+        u->use_ucm = FALSE;
 #ifdef HAVE_UDEV
-    fn = pa_udev_get_property(alsa_card_index, "PULSE_PROFILE_SET");
+        fn = pa_udev_get_property(u->alsa_card_index, "PULSE_PROFILE_SET");
+        pa_log("PULSE_PROFILE_SET = %s", fn);
+        if (fn == NULL) {
+            fn = strdup ("tizen_usb.conf");
+            pa_log("(new) PULSE_PROFILE_SET = %s", fn);
+        }
 #endif
 
-    u->profile_set = pa_alsa_profile_set_new(fn, &u->core->default_channel_map);
-    pa_xfree(fn);
+        if (pa_modargs_get_value(ma, "profile_set", NULL)) {
+            pa_xfree(fn);
+            fn = pa_xstrdup(pa_modargs_get_value(ma, "profile_set", NULL));
+        }
+
+        u->profile_set = pa_alsa_profile_set_new(fn, &u->core->default_channel_map);
+        pa_xfree(fn);
+    }
 
     if (!u->profile_set)
         goto fail;
 
+    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_dump(u->profile_set);
 
     pa_card_new_data_init(&data);
     data.driver = __FILE__;
     data.module = m;
 
-    pa_alsa_init_proplist_card(m->core, data.proplist, alsa_card_index);
+    pa_alsa_init_proplist_card(m->core, data.proplist, u->alsa_card_index);
 
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device_id);
     pa_alsa_init_description(data.proplist);
     set_card_name(&data, ma, u->device_id);
 
+    /* We need to give pa_modargs_get_value_boolean() a pointer to a local
+     * variable instead of using &data.namereg_fail directly, because
+     * data.namereg_fail is a bitfield and taking the address of a bitfield
+     * variable is impossible. */
+    namereg_fail = data.namereg_fail;
+    if (pa_modargs_get_value_boolean(ma, "namereg_fail", &namereg_fail) < 0) {
+        pa_log("Failed to parse namereg_fail argument.");
+        pa_card_new_data_done(&data);
+        goto fail;
+    }
+    data.namereg_fail = namereg_fail;
+
     if (reserve)
         if ((description = pa_proplist_gets(data.proplist, PA_PROP_DEVICE_DESCRIPTION)))
             pa_reserve_wrapper_set_application_device_name(reserve, description);
 
-    data.profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-    add_profiles(u, data.profiles);
+    add_profiles(u, data.profiles, data.ports);
 
     if (pa_hashmap_isempty(data.profiles)) {
         pa_log("Failed to find a working profile.");
@@ -362,6 +744,9 @@ int pa__init(pa_module *m) {
         goto fail;
     }
 
+    if ((profile = pa_modargs_get_value(ma, "profile", NULL)))
+        pa_card_new_data_set_profile(&data, profile);
+
     u->card = pa_card_new(m->core, &data);
     pa_card_new_data_done(&data);
 
@@ -371,11 +756,21 @@ int pa__init(pa_module *m) {
     u->card->userdata = u;
     u->card->set_profile = card_set_profile;
 
+    init_jacks(u);
     init_profile(u);
+    init_eld_ctls(u);
 
     if (reserve)
         pa_reserve_wrapper_unref(reserve);
 
+    if (!pa_hashmap_isempty(u->profile_set->decibel_fixes))
+        pa_log_warn("Card %s uses decibel fixes (i.e. overrides the decibel information for some alsa volume elements). "
+                    "Please note that this feature is meant just as a help for figuring out the correct decibel values. "
+                    "PulseAudio is not the correct place to maintain the decibel mappings! The fixed decibel values "
+                    "should be sent to ALSA developers so that they can fix the driver. If it turns out that this feature "
+                    "is abused (i.e. fixes are not pushed to ALSA), the decibel fix feature may be removed in some future "
+                    "PulseAudio version.", u->card->name);
+
     return 0;
 
 fail:
@@ -415,19 +810,30 @@ void pa__done(pa_module*m) {
     if (!(u = m->userdata))
         goto finish;
 
-    if (u->card && u->card->sinks) {
-        pa_sink *s;
+    if (u->sink_input_put_hook_slot)
+        pa_hook_slot_free(u->sink_input_put_hook_slot);
 
-        while ((s = pa_idxset_steal_first(u->card->sinks, NULL)))
-            pa_alsa_sink_free(s);
-    }
+    if (u->sink_input_unlink_hook_slot)
+        pa_hook_slot_free(u->sink_input_unlink_hook_slot);
 
-    if (u->card && u->card->sources) {
-        pa_source *s;
+    if (u->source_output_put_hook_slot)
+        pa_hook_slot_free(u->source_output_put_hook_slot);
 
-        while ((s = pa_idxset_steal_first(u->card->sources, NULL)))
-            pa_alsa_source_free(s);
-    }
+    if (u->source_output_unlink_hook_slot)
+        pa_hook_slot_free(u->source_output_unlink_hook_slot);
+
+    if (u->mixer_fdl)
+        pa_alsa_fdlist_free(u->mixer_fdl);
+    if (u->mixer_handle)
+        snd_mixer_close(u->mixer_handle);
+    if (u->jacks)
+        pa_hashmap_free(u->jacks, NULL);
+
+    if (u->card && u->card->sinks)
+        pa_idxset_remove_all(u->card->sinks, (pa_free_cb_t) pa_alsa_sink_free);
+
+    if (u->card && u->card->sources)
+        pa_idxset_remove_all(u->card->sources, (pa_free_cb_t) pa_alsa_source_free);
 
     if (u->card)
         pa_card_free(u->card);
@@ -438,6 +844,8 @@ void pa__done(pa_module*m) {
     if (u->profile_set)
         pa_alsa_profile_set_free(u->profile_set);
 
+    pa_alsa_ucm_free(&u->ucm);
+
     pa_xfree(u->device_id);
     pa_xfree(u);
 
diff --git a/src/modules/alsa/module-alsa-sink-symdef.h b/src/modules/alsa/module-alsa-sink-symdef.h
deleted file mode 100644 (file)
index cda3cd9..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulealsasinksymdeffoo
-#define foomodulealsasinksymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_alsa_sink_LTX_pa__init
-#define pa__done module_alsa_sink_LTX_pa__done
-#define pa__get_author module_alsa_sink_LTX_pa__get_author
-#define pa__get_description module_alsa_sink_LTX_pa__get_description
-#define pa__get_usage module_alsa_sink_LTX_pa__get_usage
-#define pa__get_version module_alsa_sink_LTX_pa__get_version
-#define pa__get_deprecated module_alsa_sink_LTX_pa__get_deprecated
-#define pa__load_once module_alsa_sink_LTX_pa__load_once
-#define pa__get_n_used module_alsa_sink_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 3aa89b2..3d20e84 100644 (file)
@@ -24,7 +24,6 @@
 #include <config.h>
 #endif
 
-#include <pulsecore/core.h>
 #include <pulsecore/module.h>
 #include <pulsecore/sink.h>
 #include <pulsecore/modargs.h>
@@ -40,11 +39,13 @@ PA_MODULE_LOAD_ONCE(FALSE);
 PA_MODULE_USAGE(
         "name=<name of the sink, to be prefixed> "
         "sink_name=<name for the sink> "
-        "sink_properities=<properties for the sink> "
+        "sink_properties=<properties for the sink> "
+        "namereg_fail=<when false attempt to synthesise new sink_name if it is already taken> "
         "device=<ALSA device> "
         "device_id=<ALSA card index> "
         "format=<sample format> "
         "rate=<sample rate> "
+        "alternate_rate=<alternate sample rate> "
         "channels=<number of channels> "
         "channel_map=<channel map> "
         "fragments=<number of fragments> "
@@ -54,16 +55,24 @@ 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> "
+        "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> "
+        "deferred_volume_extra_delay=<usec adjustment to HW volume changes> "
+        "fixed_latency_range=<disable latency range changes on underrun?>"
+        "need_audio_pm=<indicates whether this device needs audio power management>");
 
 static const char* const valid_modargs[] = {
     "name",
     "sink_name",
     "sink_properties",
+    "namereg_fail",
     "device",
     "device_id",
     "format",
     "rate",
+    "alternate_rate",
     "channels",
     "channel_map",
     "fragments",
@@ -74,6 +83,15 @@ static const char* const valid_modargs[] = {
     "tsched_buffer_watermark",
     "ignore_dB",
     "control",
+    "rewind_safeguard",
+    "deferred_volume",
+    "deferred_volume_safety_margin",
+    "deferred_volume_extra_delay",
+    "fixed_latency_range",
+    "need_audio_pm",
+#ifdef __TIZEN__
+    "start_threshold",
+#endif
     NULL
 };
 
diff --git a/src/modules/alsa/module-alsa-source-symdef.h b/src/modules/alsa/module-alsa-source-symdef.h
deleted file mode 100644 (file)
index 0ff3967..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulealsasourcesymdeffoo
-#define foomodulealsasourcesymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_alsa_source_LTX_pa__init
-#define pa__done module_alsa_source_LTX_pa__done
-#define pa__get_author module_alsa_source_LTX_pa__get_author
-#define pa__get_description module_alsa_source_LTX_pa__get_description
-#define pa__get_usage module_alsa_source_LTX_pa__get_usage
-#define pa__get_version module_alsa_source_LTX_pa__get_version
-#define pa__get_deprecated module_alsa_source_LTX_pa__get_deprecated
-#define pa__load_once module_alsa_source_LTX_pa__load_once
-#define pa__get_n_used module_alsa_source_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 23da418..4b0fd63 100644 (file)
 #include <valgrind/memcheck.h>
 #endif
 
-#include <pulse/xmalloc.h>
-#include <pulse/util.h>
-#include <pulse/timeval.h>
-
-#include <pulsecore/core-error.h>
-#include <pulsecore/core-rtclock.h>
-#include <pulsecore/core.h>
 #include <pulsecore/module.h>
-#include <pulsecore/memchunk.h>
-#include <pulsecore/sink.h>
 #include <pulsecore/modargs.h>
-#include <pulsecore/core-util.h>
-#include <pulsecore/sample-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/thread.h>
-#include <pulsecore/core-error.h>
-#include <pulsecore/thread-mq.h>
-#include <pulsecore/rtpoll.h>
-#include <pulsecore/time-smoother.h>
 
 #include "alsa-util.h"
 #include "alsa-source.h"
@@ -65,10 +49,12 @@ PA_MODULE_USAGE(
         "name=<name for the source, to be prefixed> "
         "source_name=<name for the source> "
         "source_properties=<properties for the source> "
+        "namereg_fail=<when false attempt to synthesise new source_name if it is already taken> "
         "device=<ALSA device> "
         "device_id=<ALSA card index> "
         "format=<sample format> "
         "rate=<sample rate> "
+        "alternate_rate=<alternate sample rate> "
         "channels=<number of channels> "
         "channel_map=<channel map> "
         "fragments=<number of fragments> "
@@ -78,16 +64,23 @@ 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>"
+        "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> "
+        "fixed_latency_range=<disable latency range changes on overrun?>"
+        "need_audio_pm=<indicates whether this device needs audio power management>");
 
 static const char* const valid_modargs[] = {
     "name",
     "source_name",
     "source_properties",
+    "namereg_fail",
     "device",
     "device_id",
     "format",
     "rate",
+    "alternate_rate",
     "channels",
     "channel_map",
     "fragments",
@@ -98,6 +91,14 @@ static const char* const valid_modargs[] = {
     "tsched_buffer_watermark",
     "ignore_dB",
     "control",
+    "deferred_volume",
+    "deferred_volume_safety_margin",
+    "deferred_volume_extra_delay",
+    "fixed_latency_range",
+    "need_audio_pm",
+#ifdef __TIZEN__
+    "start_threshold",
+#endif
     NULL
 };
 
diff --git a/src/modules/ascenario-ymu831.c b/src/modules/ascenario-ymu831.c
new file mode 100644 (file)
index 0000000..2e2815e
--- /dev/null
@@ -0,0 +1,1141 @@
+/*
+ * Copyright(c) 2012 Yamaha Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <alsa/asoundlib.h>
+#include <errno.h>
+
+#include <pulsecore/log.h>
+
+#define USE_SCN_TO_GRP_FILE
+
+#define YSOUND_CONF                    "/usr/etc/sound/ymu831/ysound.conf"
+#define MIXER_NAME_OUT                 "default"
+#define DEVFILE_HW_CARD_NUMBER         0
+#define DEVFILE_HW_DEVICE_NUMBER       0
+
+#define MAX_NAME                       (64)
+#define MAX_PATH_NAME                  (256)
+#define MAX_VALUE_LEN                  (8)
+#define ERROR                          (-1)
+#define TARGET_PARAMETER               (1)
+#define TARGET_MIXER                   (2)
+#define NOT_FINED                      (-1)
+#define MC_ASOC_MAGIC                  'N'
+#define MC_ASOC_IOCTL_SET_CTRL         (1)
+#define YMC_IOCTL_SET_CTRL \
+       _IOW(MC_ASOC_MAGIC, MC_ASOC_IOCTL_SET_CTRL, ymc_ctrl_args_t)
+#define FILE_OPEN_MODE                 "rb"
+#define USE_FOPEN                      (0)
+
+#define YMC_DSP_OUTPUT_BASE            0x00000000
+#define YMC_DSP_INPUT_BASE             0x00000010
+#define YMC_DSP_VOICECALL_BASE_1MIC    0x00000100
+#define YMC_DSP_VOICECALL_BASE_2MIC    0x00000200
+#define YMC_DSP_VOICECALL_BASE_COMMON  0x00000F00
+#define YMC_DSP_OPTION_ERROR           0xFFFFFFFF
+
+#define DSP_OUTPUT_NAME                        "DSP (Output)"
+#define DSP_INPUT_NAME                 "DSP (Input)"
+#define DSP_VOICECALL_NAME             "VoiceCall"
+#define DSP_VOICECALL_1MIC_NAME                "VoiceCall (1MIC)"
+#define DSP_VOICECALL_2MIC_NAME                "VoiceCall (2MIC)"
+
+/* Added for header */
+#define IN             0
+#define OUT    16
+#define ADDON  31
+
+#define INPUT_CH_0                     ((1 << (0 + IN)))       /* Main Mic.         0x00000001 */
+#define INPUT_CH_1                     ((1 << (1 + IN)))       /* Sub Mic.          0x00000002 */
+#define INPUT_CH_2                     ((1 << (2 + IN)))       /* Stereo Mic. ,     0x00000004 */
+#define INPUT_CH_3                     ((1 << (3 + IN)))       /* Ear Mic. ,        0x00000008 */
+#define INPUT_CH_4                     ((1 << (4 + IN)))       /* BT Mic.           0x00000010 */
+#define INPUT_CH_5                     ((1 << (5 + IN)))       /* AP                0x00000020 */
+#define INPUT_CH_6                     ((1 << (6 + IN)))       /* CP                0x00000040 */
+#define INPUT_CH_7                     ((1 << (7 + IN)))       /* FM Radio          0x00000080 */
+#define INPUT_CH_8                     ((1 << (8 + IN)))       /* Reserved */
+#define INPUT_CH_9                     ((1 << (9 + IN)))       /* Reserved */
+
+#define OUTPUT_CH_0                    ((1 << (0 + OUT)))      /* Headset (Earphone)    0x00010000 */
+#define OUTPUT_CH_1                    ((1 << (1 + OUT)))      /* Left Speaker ,        0x00020000 */
+#define OUTPUT_CH_2                    ((1 << (2 + OUT)))      /* Right Speaker ,       0x00040000 */
+#define OUTPUT_CH_3                    ((1 << (3 + OUT)))      /* Stereo Speaker ,      0x00080000 */
+#define OUTPUT_CH_4                    ((1 << (4 + OUT)))      /* Receiver (Mono) ,     0x00100000 */
+#define OUTPUT_CH_5                    ((1 << (5 + OUT)))      /* BT Headset            0x00200000 */
+#define OUTPUT_CH_6                    ((1 << (6 + OUT)))      /* CP                    0x00400000 */
+#define OUTPUT_CH_7                    ((1 << (7 + OUT)))      /* AP                    0x00800000 */
+#define OUTPUT_CH_8                    ((1 << (8 + OUT)))      /* Gain                  0x01000000 */
+#define OUTPUT_CH_9                    ((1 << (9 + OUT)))      /* Video call gain       0x02000000 */
+#define OUTPUT_CH_10                   ((1 << (10 + OUT)))     /* Video call gain       0x04000000 */
+#define OUTPUT_CH_11                   ((1 << (11 + OUT)))     /* HDMI                  0x08000000 */
+#define OUTPUT_CH_12                   ((1 << (12 + OUT)))     /* Dock                  0x10000000 */
+#define OUTPUT_CH_13                   ((1 << (13 + OUT)))     /* Call alert Gain       0x20000000 */
+#define OUTPUT_CH_14                   ((1 << (14 + OUT)))     /* Reserved              0x40000000 */
+#define ADDON_MODE                     (1 << ADDON)            /* For add-ons           0x80000000 */
+enum {
+       ADDON_AP_PLAYBACK_INCALL = 1,
+       ADDON_AP_PLAYBACK_1MIC_INCALL,
+       ADDON_AP_PLAYBACK_BT_INCALL,
+
+};
+
+#define INPUT_MAIN_MIC         (INPUT_CH_0)
+#define INPUT_SUB_MIC          (INPUT_CH_1)
+#define INPUT_STEREO_MIC       (INPUT_CH_2)
+#define INPUT_EAR_MIC          (INPUT_CH_3)
+#define INPUT_BT_MIC           (INPUT_CH_4)
+#define INPUT_AP                       (INPUT_CH_5)
+#define INPUT_CP                       (INPUT_CH_6)
+#define INPUT_FMRADIO          (INPUT_CH_7)
+
+#define OUTPUT_HEADSET         (OUTPUT_CH_0)
+#define OUTPUT_LEFT_SPK                (OUTPUT_CH_1)
+#define OUTPUT_RIGHT_SPK       (OUTPUT_CH_2)
+#define OUTPUT_STEREO_SPK      (OUTPUT_CH_3)
+#define OUTPUT_RECV                    (OUTPUT_CH_4)
+#define OUTPUT_BT_HEADSET      (OUTPUT_CH_5)
+#define OUTPUT_CP                      (OUTPUT_CH_6)
+#define OUTPUT_AP                      (OUTPUT_CH_7)
+#define OUTPUT_HDMI                    (OUTPUT_CH_11)
+#define OUTPUT_DOCK                    (OUTPUT_CH_12)
+
+#define GAIN_MODE                      (OUTPUT_CH_8)
+#define GAIN_VIDEO_CALL                (OUTPUT_CH_9)
+#define GAIN_VOICE_CALL                (OUTPUT_CH_10)
+
+
+#define GAIN_CALLALERT         (OUTPUT_CH_13)
+/* Added for header : End */
+
+struct GROUP_INFO {
+       char abName[MAX_NAME];
+       int nStartPos;
+       int nEndPos;
+};
+
+typedef struct _ymc_ctrl_args {
+       void            *param;
+       unsigned long   size;
+       unsigned long   option;
+} ymc_ctrl_args_t;
+
+struct FILE_DATA {
+       char *pbData;
+       int nSize;
+};
+
+struct SCENARIO_GROUP {
+       char *pbScenario;
+       char *pbGroup;
+#ifdef USE_SCN_TO_GRP_FILE
+       void *pNext;
+#endif
+};
+
+#define STR_GAIN                                                       "_gain"
+#define STR_VC_GAIN                                                    "_voicecall_gain"
+#define STR_RT_GAIN                                                    "_ringtone_gain"
+#define STR_VT_GAIN                                                    "_videocall_gain"
+#define STR_VOIP_GAIN                                          "_voip_gain"
+/* AP PLAYBACK */
+#define STR_AP_SPK                                                     "ap_to_speaker"
+#define STR_AP_HEADSET                                         "ap_to_headset"
+#define STR_AP_RECV                                                    "ap_to_receiver"
+#define STR_AP_BT                                                      "ap_to_bt"
+#define STR_AP_HDMI                                                    "ap_to_hdmi"
+#define STR_AP_DOCK                                                    "ap_to_dock"
+#define STR_AP_SP_HS                                           "ap_to_sp_hs"
+/* AP CAPTURE */
+#define STR_MIC1_AP                                                    "mainmic_to_ap"
+#define STR_MIC2_AP                                                    "submic_to_ap"
+#define STR_STEREO_MIC_AP                                      "stereomic_to_ap"
+#define STR_EARMIC_AP                                          "earmic_to_ap"
+#define STR_CAMCORDER_STEREO                           "capture_ap_camcorder_stereo"
+#define STR_BT_AP                                                      "bt_to_ap"
+#define STR_CP_AP                                                      "cp_to_ap"
+/* CP PLAYBACK */
+#define STR_CP_SPK                                                     "cp_to_speaker"
+#define STR_CP_HEADSET                                         "cp_to_headset"
+#define STR_CP_HEADPHONE                                       "cp_to_headphone"
+#define STR_CP_RECV_2MIC                                       "cp_to_receiver_2mic"
+#define STR_CP_RECV                                                    "cp_to_receiver"
+#define STR_CP_BT                                                      "cp_to_bt"
+/* CP CAPTURE */
+#define STR_MIC1_CP                                                    "mainmic_to_cp"
+#define STR_MIC2_CP                                                    "submic_to_cp"
+#define STR_EARMIC_CP                                          "earmic_to_cp"
+#define STR_BT_CP                                                      "bt_to_cp"
+/* FMRADIO */
+#define STR_FM_AP                                                      "fmradio_to_ap"
+#define STR_FM_SPEAKER                                         "fmradio_to_speaker"
+#define STR_FM_HEADSET                                         "fmradio_to_headset"
+/* VOICECALL */
+#define STR_VOICECALL_SPK                                      "voicecall_speaker"
+#define STR_VOICECALL_SPK_EXTVOL                       "voicecall_speaker_extvol"
+#define STR_VOICECALL_SPK_NB                           "voicecall_speaker_upsampling"
+#define STR_VOICECALL_SPK_NB_EXTVOL                    "voicecall_speakerupsampling_extvol"
+#define STR_VOICECALL_SPK_2MIC                         "voicecall_speaker_2mic"
+#define STR_VOICECALL_SPK_2MIC_EXTVOL          "voicecall_speaker_2mic_extvol"
+#define STR_VOICECALL_SPK_2MIC_NB                      "voicecall_speaker_2mic_upsampling"
+#define STR_VOICECALL_SPK_2MIC_NB_EXTVOL       "voicecall_speaker_2mic_upsampling_extvol"
+#define STR_VOICECALL_RCV                                      "voicecall_receiver"
+#define STR_VOICECALL_RCV_EXTVOL                       "voicecall_receiver_extvol"
+#define STR_VOICECALL_RCV_NB                           "voicecall_receiver_upsampling"
+#define STR_VOICECALL_RCV_NB_EXTVOL                    "voicecall_receiver_upsampling_extvol"
+#define STR_VOICECALL_RCV_2MIC                         "voicecall_receiver_2mic"
+#define STR_VOICECALL_RCV_2MIC_EXTVOL          "voicecall_receiver_2mic_extvol"
+#define STR_VOICECALL_RCV_2MIC_NB                      "voicecall_receiver_2mic_upsampling"
+#define STR_VOICECALL_RCV_2MIC_NB_EXTVOL       "voicecall_receiver_2mic_upsampling_extvol"
+#define STR_VOICECALL_HEADPHONE                                "voicecall_headphone"
+#define STR_VOICECALL_HEADPHONE_NB                     "voicecall_headphone_upsampling"
+#define STR_VOICECALL_HEADSET                          "voicecall_headset"
+#define STR_VOICECALL_HEADSET_NB                       "voicecall_headset_upsampling"
+#define STR_VOICECALL_BLUETOOTH                                "voicecall_bt_wb"
+#define STR_VOICECALL_BLUETOOTH_NREC           "voicecall_bt_wb_nrec"
+/* VIDEOCALL */
+#define STR_VIDEOCALL_SPK_2MIC                         "videocall_speaker_2mic"
+#define STR_VIDEOCALL_SPK_2MIC_NB                      "videocall_speaker_2mic_upsampling"
+#define STR_VIDEOCALL_RCV_2MIC                         "videocall_receiver_2mic"
+#define STR_VIDEOCALL_RCV_2MIC_NB                      "videocall_receiver_2mic_upsampling"
+#define STR_VIDEOCALL_HEADPHONE                                "videocall_headphone"
+#define STR_VIDEOCALL_HEADPHONE_NB                     "videocall_headphone_upsampling"
+#define STR_VIDEOCALL_HEADSET                          "videocall_headset"
+#define STR_VIDEOCALL_HEADSET_NB                       "videocall_headset_upsampling"
+#define STR_VIDEOCALL_BLUETOOTH                                "videocall_bt_wb"
+#define STR_VIDEOCALL_BLUETOOTH_NREC           "videocall_bt_wb_nrec"
+/* INCALL ADDON */
+#define STR_INCALL_ADDON                                       "ap_playback_incall_addon"
+#define STR_INCALL_1MIC_ADDON                          "ap_playback_incall_1mic_addon"
+#define STR_INCALL_BT_ADDON                                    "ap_playback_incall_bt_addon"
+/* VOIP */
+#define STR_CHATON_SPK                                         "voip_chaton_speaker"
+#define STR_CHATON_RCV                                         "voip_chaton_receiver"
+#define STR_CHATON_HEADPHONE                           "voip_chaton_headphone"
+#define STR_CHATON_HEADSET                                     "voip_chaton_headset"
+#define STR_CHATON_BLUETOOTH                           "voip_chaton_bt"
+
+#ifndef USE_SCN_TO_GRP_FILE
+static struct SCENARIO_GROUP gaScnToGrp[] = {
+       /* AP PLAYBACK */
+       {STR_AP_SPK, "AP_SP"},
+       {STR_AP_HEADSET, "AP_HS"},
+       {STR_AP_RECV, "AP_RS"},
+       {STR_AP_BT, "AP_BT"},
+       {STR_AP_HDMI, "AP_SP"},
+       {STR_AP_DOCK, "AP_LO1"},
+       {STR_AP_SP_HS, "AP_SP_HS"},
+       /* AP CAPTURE */
+       {STR_MIC1_AP, "GENERIC_AP"},
+       {STR_MIC2_AP, "GENERIC_AP"},
+       {STR_STEREO_MIC_AP, "GENERIC_AP"},
+       {STR_EARMIC_AP, "GENERIC_AP"},
+       {STR_CAMCORDER_STEREO, "GENERIC_AP"},
+       {STR_BT_AP, "BT_AP"},
+       {STR_CP_AP, "CP_AP"},
+       /* CP PLAYBACK */
+       {STR_CP_SPK, "CP_SP"},
+       {STR_CP_HEADSET, "CP_HS"},
+       {STR_CP_HEADPHONE, "CP_HP"},
+       {STR_CP_RECV_2MIC, "CP_RC"},
+       {STR_CP_RECV, "CP_RC"},
+       {STR_CP_BT, "CP_BT"},
+       /* CP CAPTURE */
+       {STR_MIC1_CP, "MIC_CP"},
+       {STR_MIC2_CP, "MIC_CP"},
+       {STR_EARMIC_CP, "HS_CP"},
+       {STR_BT_CP, "BT_CP"},
+       /* FMRADIO */
+       {STR_FM_AP, "GENERIC_AP"},
+       {STR_FM_SPEAKER, "FM_SP"},
+       {STR_FM_HEADSET, "FM_HS"},
+       /* VOICECALL */
+       {STR_VOICECALL_SPK, "VC_SP"},
+       {STR_VOICECALL_SPK_EXTVOL, "VC_SP_EXT_VOL"},
+       {STR_VOICECALL_SPK_NB, "VC_SP"},
+       {STR_VOICECALL_SPK_NB_EXTVOL, "VC_SP_EXT_VOL"},
+       {STR_VOICECALL_SPK_2MIC, "VC_SP_2MIC"},
+       {STR_VOICECALL_SPK_2MIC_EXTVOL, "VC_SP_2MIC_EXT_VOL"},
+       {STR_VOICECALL_SPK_2MIC_NB, "VC_SP_2MIC"},
+       {STR_VOICECALL_SPK_2MIC_NB_EXTVOL, "VC_SP_2MIC_EXT_VOL"},
+       {STR_VOICECALL_RCV, "VC_RCV"},
+       {STR_VOICECALL_RCV_EXTVOL, "VC_RCV_EXT_VOL"},
+       {STR_VOICECALL_RCV_NB, "VC_RCV"},
+       {STR_VOICECALL_RCV_NB_EXTVOL, "VC_RCV_EXT_VOL"},
+       {STR_VOICECALL_RCV_2MIC, "VC_RCV_2MIC"},
+       {STR_VOICECALL_RCV_2MIC_EXTVOL, "VC_RCV_2MIC_EXT_VOL"},
+       {STR_VOICECALL_RCV_2MIC_NB, "VC_RCV_2MIC"},
+       {STR_VOICECALL_RCV_2MIC_NB_EXTVOL, "VC_RCV_2MIC_EXT_VOL"},
+       {STR_VOICECALL_HEADPHONE, "VC_HP"},
+       {STR_VOICECALL_HEADPHONE_NB, "VC_HP"},
+       {STR_VOICECALL_HEADSET, "VC_HS"},
+       {STR_VOICECALL_HEADSET_NB, "VC_HS"},
+       {STR_VOICECALL_BLUETOOTH, "VC_BT_WB"},
+       {STR_VOICECALL_BLUETOOTH_NREC, "VC_BT_WB"},
+       /* VIDEOCALL */
+       {STR_VIDEOCALL_SPK_2MIC, "VT_SP"},
+       {STR_VIDEOCALL_SPK_2MIC_NB, "VT_SP"},
+       {STR_VIDEOCALL_RCV_2MIC, "VT_RCV"},
+       {STR_VIDEOCALL_RCV_2MIC_NB, "VT_RCV"},
+       {STR_VIDEOCALL_HEADPHONE, "VT_HP"},
+       {STR_VIDEOCALL_HEADPHONE_NB, "VT_HP"},
+       {STR_VIDEOCALL_HEADSET, "VT_HS"},
+       {STR_VIDEOCALL_HEADSET_NB, "VT_HS"},
+       {STR_VIDEOCALL_BLUETOOTH, "VT_BT_WB"},
+       {STR_VIDEOCALL_BLUETOOTH_NREC, "VT_BT_WB"},
+       /* INCALL ADDON */
+       {STR_INCALL_ADDON, "AP_INCALL"},
+       {STR_INCALL_1MIC_ADDON, "AP_INCALL_1MIC"},
+       {STR_INCALL_BT_ADDON, "AP_INCALL_BT"},
+       /* VOIP */
+       {STR_CHATON_SPK, "CHATONV_SP"},
+       {STR_CHATON_RCV, "CHATONV_RCV"},
+       {STR_CHATON_HEADPHONE, "CHATONV_HP"},
+       {STR_CHATON_HEADSET, "CHATONV_HS"},
+       {STR_CHATON_BLUETOOTH, "CHATONV_BT"},
+};
+#endif
+
+static struct FILE_DATA gsFileData = {NULL, 0};
+static int gnGroupInfoNum = 0;
+static int gnAllocGroupInfoNum = 0;
+static char gabRootDir[MAX_PATH_NAME];
+static struct GROUP_INFO *gpGroupInfo;
+
+#ifdef USE_SCN_TO_GRP_FILE
+#define MAX_BUFFER_SIZE                                        256
+#define SCENARIO_GROUP_MATCHING_TABLE  "/usr/etc/sound/ymu831/matching_table"
+static int initialized = 0;
+static struct SCENARIO_GROUP *gpScnToGrp = NULL;
+
+static int InitScenarioGroup(void)
+{
+       FILE *fp = NULL;
+       struct SCENARIO_GROUP *pScnToGrp = NULL;
+       char line_buffer[MAX_BUFFER_SIZE] = {0,};
+
+       fp = fopen(SCENARIO_GROUP_MATCHING_TABLE, FILE_OPEN_MODE);
+
+       if (!fp)
+               return errno;
+
+       while (fgets(line_buffer, sizeof(line_buffer), fp) != NULL) {
+               char *p_start = NULL, *p_end = NULL;
+
+               if (gpScnToGrp == NULL) {
+                       gpScnToGrp = malloc(sizeof(struct SCENARIO_GROUP));
+                       pScnToGrp = gpScnToGrp;
+               } else {
+                       pScnToGrp->pNext = malloc(sizeof(struct SCENARIO_GROUP));
+                       pScnToGrp = pScnToGrp->pNext;
+               }
+               memset(pScnToGrp, 0x00, sizeof(struct SCENARIO_GROUP));
+
+               /* Skip comment */
+               if ((line_buffer[0] == '#') || 
+                       ((line_buffer[0] == '/') && (line_buffer[1] == '/'))) {
+                       continue;
+               }
+
+               /* Parse Scenario */
+               p_start = p_end = line_buffer;
+               while (!isspace(*p_end))
+                       p_end++;
+               pScnToGrp->pbScenario = malloc(p_end - p_start + 1);
+               strncpy(pScnToGrp->pbScenario, p_start, p_end - p_start);
+               pScnToGrp->pbScenario[p_end - p_start] = '\0';
+
+               /* Parse Group */
+               p_start = p_end;
+               while (isspace(*p_start))
+                       p_start++;
+               p_end = p_start;
+               while (!isspace(*p_end))
+                       p_end++;
+               pScnToGrp->pbGroup = malloc(p_end - p_start + 1);
+               strncpy(pScnToGrp->pbGroup, p_start, p_end - p_start);
+               pScnToGrp->pbGroup[p_end - p_start] = '\0';
+       }
+       fclose(fp);
+
+       return 0;
+}
+#endif
+
+static int GetValue(char *pbStart, int nSize, char *pbBuff, int nBuffSize)
+{
+       int nPos;
+       int nValueSize;
+       int nValidValue;
+
+       memset(pbBuff, 0x00, nBuffSize);
+
+       nBuffSize--;
+       if (nBuffSize <= 0)
+               return ERROR;
+
+       nPos = 0;
+       while (nPos < nSize) {
+               if (!isblank(pbStart[nPos]))
+                       break;
+               nPos++;
+       }
+
+       if ((nPos == nSize) || (pbStart[nPos] != '"'))
+               return ERROR;
+       nPos++;
+
+       nValueSize = 0;
+       nValidValue = 0;
+       while (nPos < nSize) {
+               if ((pbStart[nPos] == '\r') || (pbStart[nPos] == '\n'))
+                       return ERROR;
+
+               if (pbStart[nPos] == '"') {
+                       nPos++;
+                       nValidValue = 1;
+                       break;
+               }
+
+               if (nValueSize < nBuffSize) {
+                       pbBuff[nValueSize] = pbStart[nPos];
+                       nValueSize++;
+               }
+
+               nPos++;
+       }
+
+       if (nValidValue == 0)
+               return ERROR;
+
+       return nPos;
+}
+
+static int ReadFileData(FILE *pFile, struct FILE_DATA *pFileData)
+{
+       int nSize;
+       int nReadSize;
+       char *pbData;
+       long pos = 0;
+
+       pFileData->pbData = NULL;
+       pFileData->nSize = 0;
+
+       fseek(pFile, 0, SEEK_END);
+       pos = ftell(pFile);
+       fseek(pFile, 0, SEEK_SET);
+       pos -= ftell(pFile);
+
+       if (pos <= 0)
+               return ERROR;
+
+       nSize = (int)pos;
+       pbData = malloc(nSize);
+       if (pbData == NULL)
+               return ERROR;
+
+       nReadSize = (int)fread(pbData, 1, nSize, pFile);
+       if (nReadSize != nSize) {
+               free(pbData);
+               return ERROR;
+       }
+
+       pFileData->pbData = pbData;
+       pFileData->nSize = nSize;
+
+       return nSize;
+}
+
+#ifdef USE_FOPEN
+static int ReadFile(char *pbPathName, struct FILE_DATA *pFileData)
+{
+       int nResult = 0;
+       FILE *pFile;
+
+       pFile = fopen(pbPathName, FILE_OPEN_MODE);
+       if (pFile == NULL)
+               return errno;
+
+       nResult = ReadFileData(pFile, pFileData);
+
+       fclose(pFile);
+
+       return nResult;
+}
+#else
+static int ReadFile(char *pbPathName, struct FILE_DATA *pFileData)
+{
+       int nResult;
+       int nFd;
+       FILE *pFile;
+
+       nFd = open(pbPathName, O_RDONLY);
+       if (nFd < 0)
+               return nFd;
+
+       pFile = fdopen(nFd, FILE_OPEN_MODE);
+       if (pFile == NULL) {
+               close(nFd);
+               return errno;
+       }
+
+       nResult = ReadFileData(pFile, pFileData);
+
+       fclose(pFile);
+       close(nFd);
+
+       return nResult;
+}
+#endif
+
+static void ReleaseFileData(struct FILE_DATA *pFileData)
+{
+       if (pFileData->pbData != NULL)
+               free(pFileData->pbData);
+
+       pFileData->pbData = NULL;
+       pFileData->nSize = 0;
+}
+
+static int AddGroupInfo(char *pbName, int nStartPos, int nEndPos)
+{
+       int i;
+       struct GROUP_INFO *pTemp;
+
+       pa_log_debug("%s", pbName);
+
+       if (gnAllocGroupInfoNum <= (gnGroupInfoNum + 1)) {
+               gnAllocGroupInfoNum = gnGroupInfoNum * 2;
+               pTemp = malloc(
+                       sizeof(struct GROUP_INFO) * gnAllocGroupInfoNum);
+               if (pTemp == NULL)
+                       return ERROR;
+
+               for (i = 0; i < gnGroupInfoNum; ++i) {
+                       strncpy(pTemp[i].abName,
+                                       gpGroupInfo[i].abName, MAX_NAME);
+                       pTemp[i].nStartPos = gpGroupInfo[i].nStartPos;
+                       pTemp[i].nEndPos = gpGroupInfo[i].nEndPos;
+                       pa_log_debug("abName[%s]:nStartPos[%d]:nEndPos[%d]",
+                                                       gpGroupInfo[i].abName,
+                                                       gpGroupInfo[i].nStartPos,
+                                                       gpGroupInfo[i].nEndPos);
+               }
+
+               free(gpGroupInfo);
+               gpGroupInfo = pTemp;
+       }
+
+       strncpy(gpGroupInfo[gnGroupInfoNum].abName, pbName, MAX_NAME-1);
+       gpGroupInfo[gnGroupInfoNum].abName[MAX_NAME-1] = '\0';
+       gpGroupInfo[gnGroupInfoNum].nStartPos = nStartPos;
+       gpGroupInfo[gnGroupInfoNum].nEndPos = nEndPos;
+
+       gnGroupInfoNum++;
+       return gnGroupInfoNum;
+}
+
+static int ConfigAnalyze(struct FILE_DATA *pFileData,
+                                       char *pbRootDir, int nRootDirSize)
+{
+       int nPos;
+       int nRemain;
+       int nResult;
+       int nYmcStart;
+       int nGroupStart;
+       char abName[MAX_NAME];
+       char *pbStart;
+       int nSize;
+
+       pbStart = pFileData->pbData;
+       nSize = pFileData->nSize;
+
+       nPos = 0;
+       nYmcStart = 0;
+       nGroupStart = 0;
+       while (nPos < nSize) {
+               nRemain = (nSize - nPos);
+               if (isblank(pbStart[nPos])) {
+                       nPos++;
+               } else if ((5 <= nRemain) &&
+                       (strncmp(&pbStart[nPos], "<ymc>", 5) == 0)) {
+                       if (nYmcStart != 0)
+                               return ERROR;
+                       nPos += 5;
+                       nYmcStart = nPos;
+               } else if ((6 <= nRemain) &&
+                       (strncmp(&pbStart[nPos], "</ymc>", 6) == 0)) {
+                       if (nYmcStart == 0)
+                               return ERROR;
+                       nPos += 6;
+                       nYmcStart = 0;
+               } else if (nYmcStart == 0) {
+                       nPos++;
+               } else if ((19 <= nRemain) &&
+                               (strncmp(&pbStart[nPos],
+                                       "<parameter rootdir=", 19) == 0)) {
+                       if (nGroupStart != 0)
+                               return ERROR;
+
+                       nPos += 19;
+                       nRemain = (nSize - nPos);
+                       nResult = GetValue(&pbStart[nPos], nRemain,
+                                               pbRootDir, nRootDirSize);
+                       if (nResult < 0)
+                               return nResult;
+                       else
+                               pa_log_debug("pbRootDir:%s", pbRootDir);
+
+                       nPos += nResult;
+                       while (nPos < nSize) {
+                               nRemain = (nSize - nPos);
+                               if (isblank(pbStart[nPos])) {
+                                       nPos++;
+                               } else if ((2 <= nRemain) &&
+                                       (strncmp(&pbStart[nPos], "/>", 2) == 0)) {
+                                       nPos += 2;
+                                       break;
+                               } else {
+                                       return ERROR;
+                               }
+                       }
+               } else if ((12 <= nRemain) &&
+                       (strncmp(&pbStart[nPos], "<group name=", 12) == 0)) {
+                       if (nGroupStart != 0)
+                               return ERROR;
+
+                       nPos += 12;
+                       nRemain = (nSize - nPos);
+                       nResult = GetValue(&pbStart[nPos], nRemain,
+                                               abName, sizeof(abName));
+                       if (nResult < 0)
+                               return nResult;
+                       else
+                               pa_log_debug("abName:%s", abName);
+
+                       nPos += nResult;
+                       while (nPos < nSize) {
+                               if (isblank(pbStart[nPos])) {
+                                       nPos++;
+                               } else if (pbStart[nPos] == '>') {
+                                       nPos++;
+                                       break;
+                               } else {
+                                       return ERROR;
+                               }
+                       }
+                       nGroupStart = nPos;
+               } else if ((8 <= nRemain) &&
+                       (strncmp(&pbStart[nPos], "</group>", 8) == 0)) {
+                       if (nGroupStart == 0)
+                               return ERROR;
+                       if (nPos <= 0)
+                               return ERROR;
+
+                       nResult = AddGroupInfo(abName,
+                                               nGroupStart, (nPos - 1));
+                       if (nResult < 0)
+                               return nResult;
+
+                       nPos += 8;
+                       nGroupStart = 0;
+               } else {
+                       nPos++;
+               }
+       }
+
+       if ((nGroupStart != 0) || (nYmcStart != 0))
+               return ERROR;
+
+       return 0;
+}
+
+static int HwdevOpen()
+{
+       int handle;
+       char hwdev_path[MAX_NAME];
+
+       snprintf(hwdev_path, MAX_NAME, "/dev/snd/hwC%uD%u",
+               DEVFILE_HW_CARD_NUMBER, DEVFILE_HW_DEVICE_NUMBER);
+       handle = open(hwdev_path, O_RDWR);
+       return handle;
+}
+
+static void HwdevClose(int handle)
+{
+        close(handle);
+}
+
+static unsigned long GetOption(char *pbName)
+{
+       unsigned long dResult;
+       dResult = YMC_DSP_OPTION_ERROR;
+
+       if (strcasecmp(pbName, DSP_OUTPUT_NAME) == 0)
+               dResult = YMC_DSP_OUTPUT_BASE;
+       else if (strcasecmp(pbName, DSP_INPUT_NAME) == 0)
+               dResult = YMC_DSP_INPUT_BASE;
+       else if (strcasecmp(pbName, DSP_VOICECALL_NAME) == 0)
+               dResult = YMC_DSP_VOICECALL_BASE_COMMON;
+       else if (strcasecmp(pbName, DSP_VOICECALL_1MIC_NAME) == 0)
+               dResult = YMC_DSP_VOICECALL_BASE_1MIC;
+       else if (strcasecmp(pbName, DSP_VOICECALL_2MIC_NAME) == 0)
+               dResult = YMC_DSP_VOICECALL_BASE_2MIC;
+
+       return dResult;
+}
+
+static int SetParameter(char *pbName, char *pbPathName)
+{
+       int nResult;
+       int handle;
+       struct FILE_DATA Parameter;
+       ymc_ctrl_args_t args;
+
+       pa_log_debug("Name[%s] PathName[%s]", pbName, pbPathName);
+
+       args.option = GetOption(pbName);
+       if (args.option == YMC_DSP_OPTION_ERROR)
+               return ERROR;
+
+       nResult = ReadFile(pbPathName, &Parameter);
+       if (nResult < 0)
+               return nResult;
+       else
+               pa_log_debug("Read %s %d bytes done",
+                                       pbPathName, Parameter.nSize);
+
+       args.param = Parameter.pbData;
+       args.size = Parameter.nSize;
+
+       handle = HwdevOpen();
+       if (handle >= 0) {
+               nResult = ioctl(handle, YMC_IOCTL_SET_CTRL, &args);
+               if (nResult < 0)
+                       pa_log_error("ioctl YMC_IOCTL_SET_CTRL has failed with %s", strerror(errno));
+               HwdevClose(handle);
+       } else {
+               pa_log_error("HwdevOpen failed, ret handle is %d, err is %s", handle, strerror(errno));
+       }
+
+       ReleaseFileData(&Parameter);
+
+       return nResult;
+}
+
+static snd_mixer_t *MixOpen(char* ifaceName)
+{
+       int nResult;
+       snd_mixer_t *handle;
+
+       nResult = snd_mixer_open(&handle, 0);
+       if (nResult < 0)
+               return NULL;
+
+       nResult = snd_mixer_attach(handle, ifaceName);
+       if (nResult < 0) {
+               snd_mixer_close(handle);
+               return NULL;
+       }
+
+       nResult = snd_mixer_selem_register(handle, NULL, NULL);
+       if (nResult < 0) {
+               snd_mixer_close(handle);
+               return NULL;
+       }
+
+       nResult = snd_mixer_load(handle);
+       if (nResult < 0) {
+               snd_mixer_close(handle);
+               return NULL;
+       }
+
+       return handle;
+}
+
+static int get_mixer_elem(snd_mixer_t *handle,
+                                       char *name, snd_mixer_elem_t **elem)
+{
+       int nResult;
+       snd_mixer_selem_id_t* sid;
+       sid = NULL;
+
+       nResult = snd_mixer_selem_id_malloc(&sid);
+       if (nResult < 0)
+               return ERROR;
+
+       snd_mixer_selem_id_set_index(sid, 0);
+       snd_mixer_selem_id_set_name(sid, name);
+       *elem = snd_mixer_find_selem(handle, sid);
+       snd_mixer_selem_id_free(sid);
+       if (*elem == NULL)
+               return ERROR;
+
+       return 0;
+}
+
+static int SetMixEnum(snd_mixer_t *handle, char *name, int index)
+{
+       int nResult;
+       int items;
+       snd_mixer_elem_t *elem;
+
+       nResult = get_mixer_elem(handle, name, &elem);
+       if (nResult < 0)
+               return nResult;
+
+       if (!snd_mixer_selem_is_enumerated(elem)) {
+               return ERROR;
+       }
+
+       items = snd_mixer_selem_get_enum_items(elem);
+       if (items <= 0)
+               return ERROR;
+
+       if (items <= index)
+               return ERROR;
+
+       nResult = snd_mixer_selem_set_enum_item(elem, 0, index);
+
+       return nResult;
+}
+
+static void MixClose(snd_mixer_t *handle)
+{
+    snd_mixer_close(handle);
+}
+
+static int SetMixer(char *pbName, char *pbValue0, char *pbValue1)
+{
+       int nResult;
+       snd_mixer_t *handle;
+
+       (void)pbValue1;
+
+       handle = MixOpen(MIXER_NAME_OUT);
+       if (handle == NULL)
+               return ERROR;
+
+       nResult = SetMixEnum(handle, pbName, atoi(pbValue0));
+
+       MixClose(handle);
+
+       return nResult;
+}
+
+static int SetParamMix(char *pbStart, int nSize, char *pbRootDir, int nTarget)
+{
+       int nPos;
+       int nResult;
+       int nRootDirSize;
+       int nValidValue;
+       int nRemain;
+       char abName[MAX_NAME];
+       char abPathName[MAX_PATH_NAME];
+       char abValue0[MAX_VALUE_LEN];
+       char abValue1[MAX_VALUE_LEN];
+
+       memset(abName, 0x00, sizeof(abName));
+       memset(abPathName, 0x00, sizeof(abPathName));
+       memset(abValue0, 0x00, sizeof(abValue0));
+       memset(abValue1, 0x00, sizeof(abValue1));
+
+       snprintf(abPathName, MAX_PATH_NAME, "%s/", pbRootDir);
+       nRootDirSize = (int)strlen(abPathName);
+
+       nPos = 0;
+       nValidValue = 0;
+       while (nPos < nSize) {
+               if ((pbStart[nPos] == '\r') || (pbStart[nPos] == '\n'))
+                       return ERROR;
+
+               nRemain = (nSize - nPos);
+               if (isblank(pbStart[nPos])) {
+                       nPos++;
+               } else if ((2 <= nRemain) &&
+                       (strncmp(&pbStart[nPos], "/>", 2) == 0)) {
+                       nPos += 2;
+                       nValidValue = 1;
+                       break;
+
+               } else if ((5 <= nRemain) &&
+                       (strncmp(&pbStart[nPos], "name=", 5) == 0)) {
+                       if (strlen(abName) != 0)
+                               return ERROR;
+
+                       nPos += 5;
+                       nRemain = (nSize - nPos);
+                       nResult = GetValue(&pbStart[nPos], nRemain,
+                                               abName, sizeof(abName));
+                       if (nResult < 0)
+                               return nResult;
+
+                       nPos += nResult;
+               } else if ((5 <= nRemain) &&
+                       (strncmp(&pbStart[nPos], "file=", 5) == 0)) {
+                       if (nRootDirSize < (int)strlen(abPathName))
+                               return ERROR;
+
+                       nPos += 5;
+                       nRemain = (nSize - nPos);
+                       nResult = GetValue(&pbStart[nPos], nRemain,
+                                       &abPathName[nRootDirSize],
+                                       (sizeof(abPathName) - nRootDirSize));
+                       if (nResult < 0)
+                               return nResult;
+
+                       nPos += nResult;
+               } else if ((7 <= nRemain) &&
+                       (strncmp(&pbStart[nPos], "value0=", 7) == 0)) {
+
+                       if (strlen(abValue0) != 0)
+                               return ERROR;
+
+                       nPos += 7;
+                       nRemain = (nSize - nPos);
+                       nResult = GetValue(&pbStart[nPos], nRemain,
+                                               abValue0, sizeof(abValue0));
+                       if (nResult < 0)
+                               return nResult;
+
+                       nPos += nResult;
+               } else if ((7 <= nRemain) &&
+                       (strncmp(&pbStart[nPos], "value1=", 7) == 0)) {
+
+                       if (strlen(abValue1) != 0)
+                               return ERROR;
+
+                       nPos += 7;
+                       nRemain = (nSize - nPos);
+                       nResult = GetValue(&pbStart[nPos], nRemain,
+                                               abValue1, sizeof(abValue1));
+                       if (nResult < 0)
+                               return nResult;
+
+                       nPos += nResult;
+               } else {
+                       return ERROR;
+               }
+       }
+
+       if (nValidValue == 0)
+               return ERROR;
+
+       switch(nTarget) {
+       case TARGET_PARAMETER:
+               nResult = SetParameter(abName, abPathName);
+               break;
+
+       case TARGET_MIXER:
+               nResult = SetMixer(abName, abValue0, abValue1);
+               break;
+
+       default:
+               nResult = ERROR;
+               break;
+       }
+
+       return (nResult < 0) ? nResult : nPos;
+}
+
+static int SetGroup(char *pbStart, int nSize, char *pbRootDir)
+{
+       int nPos;
+       int nRemain;
+       int nResult;
+
+       nPos = 0;
+       while (nPos < nSize) {
+               nRemain = (nSize - nPos);
+               if (isblank(pbStart[nPos]) ||
+                       pbStart[nPos] == '\r' || pbStart[nPos] == '\n') {
+                       nPos++;
+               } else if ((11 <= nRemain) &&
+                       (strncmp(&pbStart[nPos], "<parameter ", 11) == 0)) {
+                       nPos += 11;
+                       nRemain = (nSize - nPos);
+
+                       nResult = SetParamMix(&pbStart[nPos], nRemain,
+                                               pbRootDir, TARGET_PARAMETER);
+                       if (nResult < 0)
+                               return nResult;
+
+                       nPos += nResult;
+               } else if ((7 <= nRemain) &&
+                               (strncmp(&pbStart[nPos], "<mixer ", 7) == 0)) {
+                       nPos += 7;
+                       nRemain = (nSize - nPos);
+
+                       nResult = SetParamMix(&pbStart[nPos], nRemain,
+                                               pbRootDir, TARGET_MIXER);
+                       if (nResult < 0)
+                               return nResult;
+
+                       nPos += nResult;
+               } else {
+                       return ERROR;
+               }
+       }
+
+       return 0;
+}
+
+#ifdef USE_SCN_TO_GRP_FILE
+static char *FindGroup(char *ascn_str)
+{
+       struct SCENARIO_GROUP *pScnToGrp;
+
+       for (pScnToGrp = gpScnToGrp; pScnToGrp; pScnToGrp = pScnToGrp->pNext) {
+               if (strncmp(ascn_str, pScnToGrp->pbScenario, MAX_NAME) == 0)
+                       return pScnToGrp->pbGroup;
+       }
+       return NULL;
+}
+#else
+static int GetGroup(char *ascn_str)
+{
+       int i = 0;
+       int nNum = sizeof(gaScnToGrp) / sizeof(struct SCENARIO_GROUP);
+
+       for (i = 0; i < nNum; ++i)
+               if (strncmp(ascn_str, gaScnToGrp[i].pbScenario, MAX_NAME) == 0)
+                       break;
+
+       return (i == nNum) ? NOT_FINED : i;
+}
+#endif
+
+static int Init()
+{
+       int nResult;
+
+       gnGroupInfoNum = 0;
+       gnAllocGroupInfoNum = 64;
+       gpGroupInfo = malloc(
+                       sizeof(struct GROUP_INFO) * gnAllocGroupInfoNum);
+       if (gpGroupInfo == NULL)
+               return ERROR;
+
+       memset(gpGroupInfo, 0x00,
+                       sizeof(struct GROUP_INFO) * gnAllocGroupInfoNum);
+
+       nResult = ReadFile(YSOUND_CONF, &gsFileData);
+       if (nResult < 0) {
+               free(gpGroupInfo);
+               gpGroupInfo = NULL;
+               return nResult;
+       }
+
+       nResult = ConfigAnalyze(
+                               &gsFileData, gabRootDir, sizeof(gabRootDir));
+       if (nResult < 0) {
+               free(gpGroupInfo);
+               gpGroupInfo = NULL;
+               return nResult;
+       }
+
+       return nResult;
+}
+
+static void Term()
+{
+       if (gsFileData.pbData != NULL)
+               free(gsFileData.pbData);
+
+       gsFileData.pbData = NULL;
+       gsFileData.nSize = 0;
+
+       free(gpGroupInfo);
+       gpGroupInfo = NULL;
+}
+
+int ymu831_set_scenario(char *ascn_str)
+{
+       char *pbData;
+       int nGroup;
+       int nSize;
+       int i;
+       int nResult;
+#ifdef USE_SCN_TO_GRP_FILE
+       char *pbGroup;
+
+       if (!initialized) {
+               pa_log_warn("Initialize ymu831 scenario files\n");
+               nResult = Init();
+               if (nResult < 0) {
+                       pa_log_error("Init() failed with %d\n", nResult);
+                       return nResult;
+               }
+               InitScenarioGroup();
+               initialized = 1;
+       }
+
+       pbGroup = FindGroup(ascn_str);
+       if (!pbGroup)
+               return 0;
+
+       pa_log_warn("scn:%s grp:%s\n", ascn_str, pbGroup);
+
+       for (i = 0; i < gnGroupInfoNum; ++i)
+               if (strncmp(gpGroupInfo[i].abName, pbGroup, MAX_NAME) == 0)
+                       break;
+
+       if (gnGroupInfoNum <= i)
+               return ERROR;
+
+#else
+       /* scenario->group */
+       nGroup = GetGroup(ascn_str);
+       if (nGroup == NOT_FINED)
+               return 0;
+
+       pa_log_warn("%s\n", gaScnToGrp[nGroup].pbScenario);
+
+       nResult = Init();
+       if (nResult < 0) {
+               pa_log_error ("Init() failed with %d", nResult);
+               return nResult;
+       }
+
+       for (i = 0; i < gnGroupInfoNum; ++i)
+               if (strncmp(gpGroupInfo[i].abName,
+                               gaScnToGrp[nGroup].pbGroup, MAX_NAME) == 0)
+                       break;
+
+       if (gnGroupInfoNum <= i) {
+               Term();
+               return ERROR;
+       }
+#endif
+
+       pbData = &gsFileData.pbData[gpGroupInfo[i].nStartPos];
+       nSize = gpGroupInfo[i].nEndPos - gpGroupInfo[i].nStartPos + 1;
+       nResult = SetGroup(pbData, nSize, gabRootDir);
+
+#ifndef USE_SCN_TO_GRP_FILE
+       Term();
+#endif
+
+       return nResult;
+}
old mode 100644 (file)
new mode 100755 (executable)
index 51c796a..64b4bd8
 #define A2DP_CODEC_MPEG12              0x01
 #define A2DP_CODEC_MPEG24              0x02
 #define A2DP_CODEC_ATRAC               0x03
+#ifdef __TIZEN_BT__
+#define A2DP_CODEC_VENDOR               0xFF
+#endif
+#define A2DP_CODEC_NON_A2DP            0xFF
 
 #define SBC_SAMPLING_FREQ_16000                (1 << 3)
 #define SBC_SAMPLING_FREQ_32000                (1 << 2)
 #define MPEG_SAMPLING_FREQ_44100       (1 << 1)
 #define MPEG_SAMPLING_FREQ_48000       1
 
+
+#if defined(__TIZEN_BT__) && defined(ADJUST_ANDROID_BITPOOL)
+#define MAX_BITPOOL 35
+#else
 #define MAX_BITPOOL 64
+#endif
 #define MIN_BITPOOL 2
 
+#ifdef BLUETOOTH_APTX_SUPPORT
+/*#define APTX_CHANNEL_MODE_STEREO                     2 */
+/*
+ * aptX codec for Bluetooth only supports stereo mode with value 2
+ * But we do have sink devices programmed to send capabilities with other channel mode support.
+ * So to handle the case and keeping codec symmetry with SBC etc., we do define other channel mode,
+ * and we always make sure to set configuration with APTX_CHANNEL_MODE_STEREO only.
+ *
+ * */
+
+#define APTX_CHANNEL_MODE_MONO                 (1 << 3)
+#define APTX_CHANNEL_MODE_DUAL_CHANNEL (1 << 2)
+#define APTX_CHANNEL_MODE_STEREO               (1 << 1)
+#define APTX_CHANNEL_MODE_JOINT_STEREO 1
+
+#define APTX_VENDOR_ID0                0x4F /*APTX codec ID 79*/
+#define APTX_VENDOR_ID1                0x0
+#define APTX_VENDOR_ID2                0x0
+#define APTX_VENDOR_ID3                0x0
+
+#define APTX_CODEC_ID0         0x1
+#define APTX_CODEC_ID1         0x0
+
+#define APTX_SAMPLING_FREQ_16000       (1 << 3)
+#define APTX_SAMPLING_FREQ_32000       (1 << 2)
+#define APTX_SAMPLING_FREQ_44100       (1 << 1)
+#define APTX_SAMPLING_FREQ_48000       1
+#endif
+
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 
 typedef struct {
@@ -89,6 +127,14 @@ typedef struct {
        uint16_t bitrate;
 } __attribute__ ((packed)) a2dp_mpeg_t;
 
+#ifdef BLUETOOTH_APTX_SUPPORT
+typedef struct {
+       uint8_t vendor_id[4];
+       uint8_t codec_id[2];
+       uint8_t channel_mode:4;
+       uint8_t frequency:4;
+} __attribute__ ((packed)) a2dp_aptx_t;
+#endif
 #elif __BYTE_ORDER == __BIG_ENDIAN
 
 typedef struct {
@@ -111,6 +157,15 @@ typedef struct {
        uint16_t bitrate;
 } __attribute__ ((packed)) a2dp_mpeg_t;
 
+#ifdef BLUETOOTH_APTX_SUPPORT
+typedef struct {
+       uint8_t vendor_id[4];
+       uint8_t codec_id[2];
+       uint8_t frequency:4;
+       uint8_t channel_mode:4;
+} __attribute__ ((packed)) a2dp_aptx_t;
+#endif
+
 #else
 #error "Unknown byte order"
 #endif
diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c
deleted file mode 100644 (file)
index 3f39a91..0000000
+++ /dev/null
@@ -1,1654 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2008-2009 Joao Paulo Rechi Vita
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as
-  published by the Free Software Foundation; either version 2.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, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <pulse/xmalloc.h>
-
-#include <pulsecore/core-util.h>
-#include <pulsecore/shared.h>
-#include <pulsecore/dbus-shared.h>
-
-#include "bluetooth-util.h"
-#include "ipc.h"
-#include "a2dp-codecs.h"
-
-#define HFP_AG_ENDPOINT "/MediaEndpoint/HFPAG"
-#define HFP_HS_ENDPOINT "/MediaEndpoint/HFPHS"
-#define A2DP_SOURCE_ENDPOINT "/MediaEndpoint/A2DPSource"
-#define A2DP_SINK_ENDPOINT "/MediaEndpoint/A2DPSink"
-
-#define ENDPOINT_INTROSPECT_XML                                         \
-    DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                           \
-    "<node>"                                                            \
-    " <interface name=\"org.bluez.MediaEndpoint\">"                     \
-    "  <method name=\"SetConfiguration\">"                              \
-    "   <arg name=\"transport\" direction=\"in\" type=\"o\"/>"          \
-    "   <arg name=\"configuration\" direction=\"in\" type=\"ay\"/>"     \
-    "  </method>"                                                       \
-    "  <method name=\"SelectConfiguration\">"                           \
-    "   <arg name=\"capabilities\" direction=\"in\" type=\"ay\"/>"      \
-    "   <arg name=\"configuration\" direction=\"out\" type=\"ay\"/>"    \
-    "  </method>"                                                       \
-    "  <method name=\"ClearConfiguration\">"                            \
-    "  </method>"                                                       \
-    "  <method name=\"Release\">"                                       \
-    "  </method>"                                                       \
-    " </interface>"                                                     \
-    " <interface name=\"org.freedesktop.DBus.Introspectable\">"         \
-    "  <method name=\"Introspect\">"                                    \
-    "   <arg name=\"data\" type=\"s\" direction=\"out\"/>"              \
-    "  </method>"                                                       \
-    " </interface>"                                                     \
-    "</node>"
-
-struct pa_bluetooth_discovery {
-    PA_REFCNT_DECLARE;
-
-    pa_core *core;
-    pa_dbus_connection *connection;
-    PA_LLIST_HEAD(pa_dbus_pending, pending);
-    pa_hashmap *devices;
-    pa_hook hook;
-    pa_bool_t filter_added;
-};
-
-static void get_properties_reply(DBusPendingCall *pending, void *userdata);
-static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_discovery *y, DBusMessage *m, DBusPendingCallNotifyFunction func, void *call_data);
-
-pa_bt_audio_state_t pa_bt_audio_state_from_string(const char* value) {
-    pa_assert(value);
-
-    if (pa_streq(value, "disconnected"))
-        return PA_BT_AUDIO_STATE_DISCONNECTED;
-    else if (pa_streq(value, "connecting"))
-        return PA_BT_AUDIO_STATE_CONNECTING;
-    else if (pa_streq(value, "connected"))
-        return PA_BT_AUDIO_STATE_CONNECTED;
-    else if (pa_streq(value, "playing"))
-        return PA_BT_AUDIO_STATE_PLAYING;
-
-    return PA_BT_AUDIO_STATE_INVALID;
-}
-
-static pa_bluetooth_uuid *uuid_new(const char *uuid) {
-    pa_bluetooth_uuid *u;
-
-    u = pa_xnew(pa_bluetooth_uuid, 1);
-    u->uuid = pa_xstrdup(uuid);
-    PA_LLIST_INIT(pa_bluetooth_uuid, u);
-
-    return u;
-}
-
-static void uuid_free(pa_bluetooth_uuid *u) {
-    pa_assert(u);
-
-    pa_xfree(u->uuid);
-    pa_xfree(u);
-}
-
-static pa_bluetooth_device* device_new(const char *path) {
-    pa_bluetooth_device *d;
-
-    d = pa_xnew(pa_bluetooth_device, 1);
-
-    d->dead = FALSE;
-
-    d->device_info_valid = 0;
-
-    d->name = NULL;
-    d->path = pa_xstrdup(path);
-    d->transports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-    d->paired = -1;
-    d->alias = NULL;
-    d->device_connected = -1;
-    PA_LLIST_HEAD_INIT(pa_bluetooth_uuid, d->uuids);
-    d->address = NULL;
-    d->class = -1;
-    d->trusted = -1;
-
-    d->audio_state = PA_BT_AUDIO_STATE_INVALID;
-    d->audio_sink_state = PA_BT_AUDIO_STATE_INVALID;
-    d->audio_source_state = PA_BT_AUDIO_STATE_INVALID;
-    d->headset_state = PA_BT_AUDIO_STATE_INVALID;
-    d->hfgw_state = PA_BT_AUDIO_STATE_INVALID;
-
-    return d;
-}
-
-static void transport_free(pa_bluetooth_transport *t) {
-    pa_assert(t);
-
-    pa_xfree(t->path);
-    pa_xfree(t->config);
-    pa_xfree(t);
-}
-
-static void device_free(pa_bluetooth_device *d) {
-    pa_bluetooth_uuid *u;
-    pa_bluetooth_transport *t;
-
-    pa_assert(d);
-
-    while ((t = pa_hashmap_steal_first(d->transports)))
-        transport_free(t);
-
-    pa_hashmap_free(d->transports, NULL, NULL);
-
-    while ((u = d->uuids)) {
-        PA_LLIST_REMOVE(pa_bluetooth_uuid, d->uuids, u);
-        uuid_free(u);
-    }
-
-    pa_xfree(d->name);
-    pa_xfree(d->path);
-    pa_xfree(d->alias);
-    pa_xfree(d->address);
-    pa_xfree(d);
-}
-
-static pa_bool_t device_is_audio(pa_bluetooth_device *d) {
-    pa_assert(d);
-
-    return
-        d->device_info_valid && (d->hfgw_state != PA_BT_AUDIO_STATE_INVALID ||
-        (d->audio_state != PA_BT_AUDIO_STATE_INVALID &&
-         (d->audio_sink_state != PA_BT_AUDIO_STATE_INVALID ||
-          d->audio_source_state != PA_BT_AUDIO_STATE_INVALID ||
-          d->headset_state != PA_BT_AUDIO_STATE_INVALID)));
-}
-
-static int parse_device_property(pa_bluetooth_discovery *y, pa_bluetooth_device *d, DBusMessageIter *i) {
-    const char *key;
-    DBusMessageIter variant_i;
-
-    pa_assert(y);
-    pa_assert(d);
-    pa_assert(i);
-
-    if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING) {
-        pa_log("Property name not a string.");
-        return -1;
-    }
-
-    dbus_message_iter_get_basic(i, &key);
-
-    if (!dbus_message_iter_next(i)) {
-        pa_log("Property value missing");
-        return -1;
-    }
-
-    if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_VARIANT) {
-        pa_log("Property value not a variant.");
-        return -1;
-    }
-
-    dbus_message_iter_recurse(i, &variant_i);
-
-/*     pa_log_debug("Parsing property org.bluez.Device.%s", key); */
-
-    switch (dbus_message_iter_get_arg_type(&variant_i)) {
-
-        case DBUS_TYPE_STRING: {
-
-            const char *value;
-            dbus_message_iter_get_basic(&variant_i, &value);
-
-            if (pa_streq(key, "Name")) {
-                pa_xfree(d->name);
-                d->name = pa_xstrdup(value);
-            } else if (pa_streq(key, "Alias")) {
-                pa_xfree(d->alias);
-                d->alias = pa_xstrdup(value);
-            } else if (pa_streq(key, "Address")) {
-                pa_xfree(d->address);
-                d->address = pa_xstrdup(value);
-            }
-
-/*             pa_log_debug("Value %s", value); */
-
-            break;
-        }
-
-        case DBUS_TYPE_BOOLEAN: {
-
-            dbus_bool_t value;
-            dbus_message_iter_get_basic(&variant_i, &value);
-
-            if (pa_streq(key, "Paired"))
-                d->paired = !!value;
-            else if (pa_streq(key, "Connected"))
-                d->device_connected = !!value;
-            else if (pa_streq(key, "Trusted"))
-                d->trusted = !!value;
-
-/*             pa_log_debug("Value %s", pa_yes_no(value)); */
-
-            break;
-        }
-
-        case DBUS_TYPE_UINT32: {
-
-            uint32_t value;
-            dbus_message_iter_get_basic(&variant_i, &value);
-
-            if (pa_streq(key, "Class"))
-                d->class = (int) value;
-
-/*             pa_log_debug("Value %u", (unsigned) value); */
-
-            break;
-        }
-
-        case DBUS_TYPE_ARRAY: {
-
-            DBusMessageIter ai;
-            dbus_message_iter_recurse(&variant_i, &ai);
-
-            if (dbus_message_iter_get_arg_type(&ai) == DBUS_TYPE_STRING &&
-                pa_streq(key, "UUIDs")) {
-                    DBusMessage *m;
-                    pa_bool_t has_audio = FALSE;
-
-                while (dbus_message_iter_get_arg_type(&ai) != DBUS_TYPE_INVALID) {
-                    pa_bluetooth_uuid *node;
-                    const char *value;
-
-                    dbus_message_iter_get_basic(&ai, &value);
-                    node = uuid_new(value);
-                    PA_LLIST_PREPEND(pa_bluetooth_uuid, d->uuids, node);
-
-                    /* Vudentz said the interfaces are here when the UUIDs are announced */
-                    if (strcasecmp(HSP_AG_UUID, value) == 0 || strcasecmp(HFP_AG_UUID, value) == 0) {
-                        pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.HandsfreeGateway", "GetProperties"));
-                        send_and_add_to_pending(y, m, get_properties_reply, d);
-                        has_audio = TRUE;
-                    } else if (strcasecmp(HSP_HS_UUID, value) == 0 || strcasecmp(HFP_HS_UUID, value) == 0) {
-                        pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.Headset", "GetProperties"));
-                        send_and_add_to_pending(y, m, get_properties_reply, d);
-                        has_audio = TRUE;
-                    } else if (strcasecmp(A2DP_SINK_UUID, value) == 0) {
-                        pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.AudioSink", "GetProperties"));
-                        send_and_add_to_pending(y, m, get_properties_reply, d);
-                        has_audio = TRUE;
-                    } else if (strcasecmp(A2DP_SOURCE_UUID, value) == 0) {
-                        pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.AudioSource", "GetProperties"));
-                        send_and_add_to_pending(y, m, get_properties_reply, d);
-                        has_audio = TRUE;
-                    }
-
-                    if (!dbus_message_iter_next(&ai))
-                        break;
-                }
-
-                /* this might eventually be racy if .Audio is not there yet, but the State change will come anyway later, so this call is for cold-detection mostly */
-                if (has_audio) {
-                    pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.Audio", "GetProperties"));
-                    send_and_add_to_pending(y, m, get_properties_reply, d);
-                }
-            }
-
-            break;
-        }
-    }
-
-    return 0;
-}
-
-static int parse_audio_property(pa_bluetooth_discovery *u, int *state, DBusMessageIter *i) {
-    const char *key;
-    DBusMessageIter variant_i;
-
-    pa_assert(u);
-    pa_assert(state);
-    pa_assert(i);
-
-    if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING) {
-        pa_log("Property name not a string.");
-        return -1;
-    }
-
-    dbus_message_iter_get_basic(i, &key);
-
-    if (!dbus_message_iter_next(i)) {
-        pa_log("Property value missing");
-        return -1;
-    }
-
-    if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_VARIANT) {
-        pa_log("Property value not a variant.");
-        return -1;
-    }
-
-    dbus_message_iter_recurse(i, &variant_i);
-
-/*     pa_log_debug("Parsing property org.bluez.{Audio|AudioSink|AudioSource|Headset}.%s", key); */
-
-    switch (dbus_message_iter_get_arg_type(&variant_i)) {
-
-        case DBUS_TYPE_STRING: {
-
-            const char *value;
-            dbus_message_iter_get_basic(&variant_i, &value);
-
-            if (pa_streq(key, "State")) {
-                *state = pa_bt_audio_state_from_string(value);
-                pa_log_debug("dbus: property 'State' changed to value '%s'", value);
-            }
-
-            break;
-        }
-    }
-
-    return 0;
-}
-
-static void run_callback(pa_bluetooth_discovery *y, pa_bluetooth_device *d, pa_bool_t dead) {
-    pa_assert(y);
-    pa_assert(d);
-
-    if (!device_is_audio(d))
-        return;
-
-    d->dead = dead;
-    pa_hook_fire(&y->hook, d);
-}
-
-static void remove_all_devices(pa_bluetooth_discovery *y) {
-    pa_bluetooth_device *d;
-
-    pa_assert(y);
-
-    while ((d = pa_hashmap_steal_first(y->devices))) {
-        run_callback(y, d, TRUE);
-        device_free(d);
-    }
-}
-
-static pa_bluetooth_device *found_device(pa_bluetooth_discovery *y, const char* path) {
-    DBusMessage *m;
-    pa_bluetooth_device *d;
-
-    pa_assert(y);
-    pa_assert(path);
-
-    d = pa_hashmap_get(y->devices, path);
-    if (d)
-        return d;
-
-    d = device_new(path);
-
-    pa_hashmap_put(y->devices, d->path, d);
-
-    pa_assert_se(m = dbus_message_new_method_call("org.bluez", path, "org.bluez.Device", "GetProperties"));
-    send_and_add_to_pending(y, m, get_properties_reply, d);
-
-    /* Before we read the other properties (Audio, AudioSink, AudioSource,
-     * Headset) we wait that the UUID is read */
-    return d;
-}
-
-static void get_properties_reply(DBusPendingCall *pending, void *userdata) {
-    DBusMessage *r;
-    DBusMessageIter arg_i, element_i;
-    pa_dbus_pending *p;
-    pa_bluetooth_device *d;
-    pa_bluetooth_discovery *y;
-    int valid;
-
-    pa_assert_se(p = userdata);
-    pa_assert_se(y = p->context_data);
-    pa_assert_se(r = dbus_pending_call_steal_reply(pending));
-
-/*     pa_log_debug("Got %s.GetProperties response for %s", */
-/*                  dbus_message_get_interface(p->message), */
-/*                  dbus_message_get_path(p->message)); */
-
-    /* We don't use p->call_data here right-away since the device
-     * might already be invalidated at this point */
-
-    if (!(d = pa_hashmap_get(y->devices, dbus_message_get_path(p->message))))
-        return;
-
-    pa_assert(p->call_data == d);
-
-    valid = dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR ? -1 : 1;
-
-    if (dbus_message_is_method_call(p->message, "org.bluez.Device", "GetProperties"))
-        d->device_info_valid = valid;
-
-    if (dbus_message_is_error(r, DBUS_ERROR_SERVICE_UNKNOWN)) {
-        pa_log_debug("Bluetooth daemon is apparently not available.");
-        remove_all_devices(y);
-        goto finish2;
-    }
-
-    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
-        pa_log("%s.GetProperties() failed: %s: %s", dbus_message_get_interface(p->message), dbus_message_get_error_name(r), pa_dbus_get_error_message(r));
-        goto finish;
-    }
-
-    if (!dbus_message_iter_init(r, &arg_i)) {
-        pa_log("GetProperties reply has no arguments.");
-        goto finish;
-    }
-
-    if (dbus_message_iter_get_arg_type(&arg_i) != DBUS_TYPE_ARRAY) {
-        pa_log("GetProperties argument is not an array.");
-        goto finish;
-    }
-
-    dbus_message_iter_recurse(&arg_i, &element_i);
-    while (dbus_message_iter_get_arg_type(&element_i) != DBUS_TYPE_INVALID) {
-
-        if (dbus_message_iter_get_arg_type(&element_i) == DBUS_TYPE_DICT_ENTRY) {
-            DBusMessageIter dict_i;
-
-            dbus_message_iter_recurse(&element_i, &dict_i);
-
-            if (dbus_message_has_interface(p->message, "org.bluez.Device")) {
-                if (parse_device_property(y, d, &dict_i) < 0)
-                    goto finish;
-
-            } else if (dbus_message_has_interface(p->message, "org.bluez.Audio")) {
-                if (parse_audio_property(y, &d->audio_state, &dict_i) < 0)
-                    goto finish;
-
-            } else if (dbus_message_has_interface(p->message, "org.bluez.Headset")) {
-                if (parse_audio_property(y, &d->headset_state, &dict_i) < 0)
-                    goto finish;
-
-            }  else if (dbus_message_has_interface(p->message, "org.bluez.AudioSink")) {
-                if (parse_audio_property(y, &d->audio_sink_state, &dict_i) < 0)
-                    goto finish;
-
-            }  else if (dbus_message_has_interface(p->message, "org.bluez.AudioSource")) {
-                if (parse_audio_property(y, &d->audio_source_state, &dict_i) < 0)
-                    goto finish;
-
-            }  else if (dbus_message_has_interface(p->message, "org.bluez.HandsfreeGateway")) {
-                if (parse_audio_property(y, &d->hfgw_state, &dict_i) < 0)
-                    goto finish;
-
-            }
-        }
-
-        if (!dbus_message_iter_next(&element_i))
-            break;
-    }
-
-finish:
-    run_callback(y, d, FALSE);
-
-finish2:
-    dbus_message_unref(r);
-
-    PA_LLIST_REMOVE(pa_dbus_pending, y->pending, p);
-    pa_dbus_pending_free(p);
-}
-
-static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_discovery *y, DBusMessage *m, DBusPendingCallNotifyFunction func, void *call_data) {
-    pa_dbus_pending *p;
-    DBusPendingCall *call;
-
-    pa_assert(y);
-    pa_assert(m);
-
-    pa_assert_se(dbus_connection_send_with_reply(pa_dbus_connection_get(y->connection), m, &call, -1));
-
-    p = pa_dbus_pending_new(pa_dbus_connection_get(y->connection), m, call, y, call_data);
-    PA_LLIST_PREPEND(pa_dbus_pending, y->pending, p);
-    dbus_pending_call_set_notify(call, func, p, NULL);
-
-    return p;
-}
-
-static void register_endpoint_reply(DBusPendingCall *pending, void *userdata) {
-    DBusError e;
-    DBusMessage *r;
-    pa_dbus_pending *p;
-    pa_bluetooth_discovery *y;
-    char *endpoint;
-
-    pa_assert(pending);
-
-    dbus_error_init(&e);
-
-    pa_assert_se(p = userdata);
-    pa_assert_se(y = p->context_data);
-    pa_assert_se(endpoint = p->call_data);
-    pa_assert_se(r = dbus_pending_call_steal_reply(pending));
-
-    if (dbus_message_is_error(r, DBUS_ERROR_SERVICE_UNKNOWN)) {
-        pa_log_debug("Bluetooth daemon is apparently not available.");
-        remove_all_devices(y);
-        goto finish;
-    }
-
-    if (dbus_message_is_error(r, PA_BLUETOOTH_ERROR_NOT_SUPPORTED)) {
-        pa_log_info("Couldn't register endpoint %s, because BlueZ is configured to disable the endpoint type.", endpoint);
-        goto finish;
-    }
-
-    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
-        pa_log("org.bluez.Media.RegisterEndpoint() failed: %s: %s", dbus_message_get_error_name(r), pa_dbus_get_error_message(r));
-        goto finish;
-    }
-
-finish:
-    dbus_message_unref(r);
-
-    PA_LLIST_REMOVE(pa_dbus_pending, y->pending, p);
-    pa_dbus_pending_free(p);
-
-    pa_xfree(endpoint);
-}
-
-static void list_devices_reply(DBusPendingCall *pending, void *userdata) {
-    DBusError e;
-    DBusMessage *r;
-    char **paths = NULL;
-    int num = -1;
-    pa_dbus_pending *p;
-    pa_bluetooth_discovery *y;
-
-    pa_assert(pending);
-
-    dbus_error_init(&e);
-
-    pa_assert_se(p = userdata);
-    pa_assert_se(y = p->context_data);
-    pa_assert_se(r = dbus_pending_call_steal_reply(pending));
-
-    if (dbus_message_is_error(r, DBUS_ERROR_SERVICE_UNKNOWN)) {
-        pa_log_debug("Bluetooth daemon is apparently not available.");
-        remove_all_devices(y);
-        goto finish;
-    }
-
-    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
-        pa_log("org.bluez.Adapter.ListDevices() failed: %s: %s", dbus_message_get_error_name(r), pa_dbus_get_error_message(r));
-        goto finish;
-    }
-
-    if (!dbus_message_get_args(r, &e, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, &num, DBUS_TYPE_INVALID)) {
-        pa_log("org.bluez.Adapter.ListDevices returned an error: '%s'\n", e.message);
-        dbus_error_free(&e);
-    } else {
-        int i;
-
-        for (i = 0; i < num; ++i)
-            found_device(y, paths[i]);
-    }
-
-finish:
-    if (paths)
-        dbus_free_string_array(paths);
-
-    dbus_message_unref(r);
-
-    PA_LLIST_REMOVE(pa_dbus_pending, y->pending, p);
-    pa_dbus_pending_free(p);
-}
-
-static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const char *endpoint, const char *uuid) {
-    DBusMessage *m;
-    DBusMessageIter i, d;
-    uint8_t codec = 0;
-
-    pa_log_debug("Registering %s on adapter %s.", endpoint, path);
-
-    pa_assert_se(m = dbus_message_new_method_call("org.bluez", path, "org.bluez.Media", "RegisterEndpoint"));
-
-    dbus_message_iter_init_append(m, &i);
-
-    dbus_message_iter_append_basic(&i, DBUS_TYPE_OBJECT_PATH, &endpoint);
-
-    dbus_message_iter_open_container(&i, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
-                                    DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
-                                    &d);
-
-    pa_dbus_append_basic_variant_dict_entry(&d, "UUID", DBUS_TYPE_STRING, &uuid);
-
-    pa_dbus_append_basic_variant_dict_entry(&d, "Codec", DBUS_TYPE_BYTE, &codec);
-
-    if (pa_streq(uuid, HFP_AG_UUID) || pa_streq(uuid, HFP_HS_UUID)) {
-        uint8_t capability = 0;
-        pa_dbus_append_basic_array_variant_dict_entry(&d, "Capabilities", DBUS_TYPE_BYTE, &capability, 1);
-    } else {
-        a2dp_sbc_t capabilities;
-
-        capabilities.channel_mode = BT_A2DP_CHANNEL_MODE_MONO | BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL |
-                                    BT_A2DP_CHANNEL_MODE_STEREO | BT_A2DP_CHANNEL_MODE_JOINT_STEREO;
-        capabilities.frequency = BT_SBC_SAMPLING_FREQ_16000 | BT_SBC_SAMPLING_FREQ_32000 |
-                                 BT_SBC_SAMPLING_FREQ_44100 | BT_SBC_SAMPLING_FREQ_48000;
-        capabilities.allocation_method = BT_A2DP_ALLOCATION_SNR | BT_A2DP_ALLOCATION_LOUDNESS;
-        capabilities.subbands = BT_A2DP_SUBBANDS_4 | BT_A2DP_SUBBANDS_8;
-        capabilities.block_length = BT_A2DP_BLOCK_LENGTH_4 | BT_A2DP_BLOCK_LENGTH_8 |
-                                    BT_A2DP_BLOCK_LENGTH_12 | BT_A2DP_BLOCK_LENGTH_16;
-        capabilities.min_bitpool = MIN_BITPOOL;
-        capabilities.max_bitpool = MAX_BITPOOL;
-
-        pa_dbus_append_basic_array_variant_dict_entry(&d, "Capabilities", DBUS_TYPE_BYTE, &capabilities, sizeof(capabilities));
-    }
-
-    dbus_message_iter_close_container(&i, &d);
-
-    send_and_add_to_pending(y, m, register_endpoint_reply, pa_xstrdup(endpoint));
-}
-
-static void found_adapter(pa_bluetooth_discovery *y, const char *path) {
-    DBusMessage *m;
-
-    pa_assert_se(m = dbus_message_new_method_call("org.bluez", path, "org.bluez.Adapter", "ListDevices"));
-    send_and_add_to_pending(y, m, list_devices_reply, NULL);
-
-    register_endpoint(y, path, HFP_AG_ENDPOINT, HFP_AG_UUID);
-    register_endpoint(y, path, HFP_HS_ENDPOINT, HFP_HS_UUID);
-    register_endpoint(y, path, A2DP_SOURCE_ENDPOINT, A2DP_SOURCE_UUID);
-    register_endpoint(y, path, A2DP_SINK_ENDPOINT, A2DP_SINK_UUID);
-}
-
-static void list_adapters_reply(DBusPendingCall *pending, void *userdata) {
-    DBusError e;
-    DBusMessage *r;
-    char **paths = NULL;
-    int num = -1;
-    pa_dbus_pending *p;
-    pa_bluetooth_discovery *y;
-
-    pa_assert(pending);
-
-    dbus_error_init(&e);
-
-    pa_assert_se(p = userdata);
-    pa_assert_se(y = p->context_data);
-    pa_assert_se(r = dbus_pending_call_steal_reply(pending));
-
-    if (dbus_message_is_error(r, DBUS_ERROR_SERVICE_UNKNOWN)) {
-        pa_log_debug("Bluetooth daemon is apparently not available.");
-        remove_all_devices(y);
-        goto finish;
-    }
-
-    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
-        pa_log("org.bluez.Manager.ListAdapters() failed: %s: %s", dbus_message_get_error_name(r), pa_dbus_get_error_message(r));
-        goto finish;
-    }
-
-    if (!dbus_message_get_args(r, &e, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, &num, DBUS_TYPE_INVALID)) {
-        pa_log("org.bluez.Manager.ListAdapters returned an error: %s", e.message);
-        dbus_error_free(&e);
-    } else {
-        int i;
-
-        for (i = 0; i < num; ++i)
-            found_adapter(y, paths[i]);
-    }
-
-finish:
-    if (paths)
-        dbus_free_string_array(paths);
-
-    dbus_message_unref(r);
-
-    PA_LLIST_REMOVE(pa_dbus_pending, y->pending, p);
-    pa_dbus_pending_free(p);
-}
-
-static void list_adapters(pa_bluetooth_discovery *y) {
-    DBusMessage *m;
-    pa_assert(y);
-
-    pa_assert_se(m = dbus_message_new_method_call("org.bluez", "/", "org.bluez.Manager", "ListAdapters"));
-    send_and_add_to_pending(y, m, list_adapters_reply, NULL);
-}
-
-int pa_bluetooth_transport_parse_property(pa_bluetooth_transport *t, DBusMessageIter *i)
-{
-    const char *key;
-    DBusMessageIter variant_i;
-
-    if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING) {
-        pa_log("Property name not a string.");
-        return -1;
-    }
-
-    dbus_message_iter_get_basic(i, &key);
-
-    if (!dbus_message_iter_next(i))  {
-        pa_log("Property value missing");
-        return -1;
-    }
-
-    if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_VARIANT) {
-        pa_log("Property value not a variant.");
-        return -1;
-    }
-
-    dbus_message_iter_recurse(i, &variant_i);
-
-    switch (dbus_message_iter_get_arg_type(&variant_i)) {
-
-        case DBUS_TYPE_BOOLEAN: {
-
-            pa_bool_t *value;
-            dbus_message_iter_get_basic(&variant_i, &value);
-
-            if (pa_streq(key, "NREC"))
-                t->nrec = value;
-
-            break;
-         }
-    }
-
-    return 0;
-}
-
-static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *userdata) {
-    DBusError err;
-    pa_bluetooth_discovery *y;
-
-    pa_assert(bus);
-    pa_assert(m);
-
-    pa_assert_se(y = userdata);
-
-    dbus_error_init(&err);
-
-    pa_log_debug("dbus: interface=%s, path=%s, member=%s\n",
-            dbus_message_get_interface(m),
-            dbus_message_get_path(m),
-            dbus_message_get_member(m));
-
-    if (dbus_message_is_signal(m, "org.bluez.Adapter", "DeviceRemoved")) {
-        const char *path;
-        pa_bluetooth_device *d;
-
-        if (!dbus_message_get_args(m, &err, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) {
-            pa_log("Failed to parse org.bluez.Adapter.DeviceRemoved: %s", err.message);
-            goto fail;
-        }
-
-        pa_log_debug("Device %s removed", path);
-
-        if ((d = pa_hashmap_remove(y->devices, path))) {
-            run_callback(y, d, TRUE);
-            device_free(d);
-        }
-
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-    } else if (dbus_message_is_signal(m, "org.bluez.Adapter", "DeviceCreated")) {
-        const char *path;
-
-        if (!dbus_message_get_args(m, &err, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) {
-            pa_log("Failed to parse org.bluez.Adapter.DeviceCreated: %s", err.message);
-            goto fail;
-        }
-
-        pa_log_debug("Device %s created", path);
-
-        found_device(y, path);
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-    } else if (dbus_message_is_signal(m, "org.bluez.Manager", "AdapterAdded")) {
-        const char *path;
-
-        if (!dbus_message_get_args(m, &err, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) {
-            pa_log("Failed to parse org.bluez.Manager.AdapterAdded: %s", err.message);
-            goto fail;
-        }
-
-        pa_log_debug("Adapter %s created", path);
-
-        found_adapter(y, path);
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-    } else if (dbus_message_is_signal(m, "org.bluez.Audio", "PropertyChanged") ||
-               dbus_message_is_signal(m, "org.bluez.Headset", "PropertyChanged") ||
-               dbus_message_is_signal(m, "org.bluez.AudioSink", "PropertyChanged") ||
-               dbus_message_is_signal(m, "org.bluez.AudioSource", "PropertyChanged") ||
-               dbus_message_is_signal(m, "org.bluez.HandsfreeGateway", "PropertyChanged") ||
-               dbus_message_is_signal(m, "org.bluez.Device", "PropertyChanged")) {
-
-        pa_bluetooth_device *d;
-
-        if ((d = pa_hashmap_get(y->devices, dbus_message_get_path(m)))) {
-            DBusMessageIter arg_i;
-
-            if (!dbus_message_iter_init(m, &arg_i)) {
-                pa_log("Failed to parse PropertyChanged: %s", err.message);
-                goto fail;
-            }
-
-            if (dbus_message_has_interface(m, "org.bluez.Device")) {
-                if (parse_device_property(y, d, &arg_i) < 0)
-                    goto fail;
-
-            } else if (dbus_message_has_interface(m, "org.bluez.Audio")) {
-                if (parse_audio_property(y, &d->audio_state, &arg_i) < 0)
-                    goto fail;
-
-            } else if (dbus_message_has_interface(m, "org.bluez.Headset")) {
-                if (parse_audio_property(y, &d->headset_state, &arg_i) < 0)
-                    goto fail;
-
-            }  else if (dbus_message_has_interface(m, "org.bluez.AudioSink")) {
-                if (parse_audio_property(y, &d->audio_sink_state, &arg_i) < 0)
-                    goto fail;
-
-            }  else if (dbus_message_has_interface(m, "org.bluez.AudioSource")) {
-                if (parse_audio_property(y, &d->audio_source_state, &arg_i) < 0)
-                    goto fail;
-
-            }  else if (dbus_message_has_interface(m, "org.bluez.HandsfreeGateway")) {
-                if (parse_audio_property(y, &d->hfgw_state, &arg_i) < 0)
-                    goto fail;
-            }
-
-            run_callback(y, d, FALSE);
-        }
-
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-    } else if (dbus_message_is_signal(m, "org.bluez.Device", "DisconnectRequested")) {
-        pa_bluetooth_device *d;
-
-        if ((d = pa_hashmap_get(y->devices, dbus_message_get_path(m)))) {
-            /* Device will disconnect in 2 sec */
-            d->audio_state = PA_BT_AUDIO_STATE_DISCONNECTED;
-            d->audio_sink_state = PA_BT_AUDIO_STATE_DISCONNECTED;
-            d->audio_source_state = PA_BT_AUDIO_STATE_DISCONNECTED;
-            d->headset_state = PA_BT_AUDIO_STATE_DISCONNECTED;
-            d->hfgw_state = PA_BT_AUDIO_STATE_DISCONNECTED;
-
-            run_callback(y, d, FALSE);
-        }
-
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-    } else if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged")) {
-        const char *name, *old_owner, *new_owner;
-
-        if (!dbus_message_get_args(m, &err,
-                                   DBUS_TYPE_STRING, &name,
-                                   DBUS_TYPE_STRING, &old_owner,
-                                   DBUS_TYPE_STRING, &new_owner,
-                                   DBUS_TYPE_INVALID)) {
-            pa_log("Failed to parse org.freedesktop.DBus.NameOwnerChanged: %s", err.message);
-            goto fail;
-        }
-
-        if (pa_streq(name, "org.bluez")) {
-            if (old_owner && *old_owner) {
-                pa_log_debug("Bluetooth daemon disappeared.");
-                remove_all_devices(y);
-            }
-
-            if (new_owner && *new_owner) {
-                pa_log_debug("Bluetooth daemon appeared.");
-                list_adapters(y);
-            }
-        }
-
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-    } else if (dbus_message_is_signal(m, "org.bluez.MediaTransport", "PropertyChanged")) {
-        pa_bluetooth_device *d;
-        pa_bluetooth_transport *t = NULL;
-        void *state = NULL;
-        DBusMessageIter arg_i;
-
-        while ((d = pa_hashmap_iterate(y->devices, &state, NULL)))
-            if ((t = pa_hashmap_get(d->transports, dbus_message_get_path(m))))
-                break;
-
-        if (!t)
-            goto fail;
-
-        if (!dbus_message_iter_init(m, &arg_i)) {
-            pa_log("Failed to parse PropertyChanged: %s", err.message);
-            goto fail;
-        }
-
-        if (pa_bluetooth_transport_parse_property(t, &arg_i) < 0)
-            goto fail;
-
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-    }
-
-fail:
-    dbus_error_free(&err);
-
-    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-const pa_bluetooth_device* pa_bluetooth_discovery_get_by_address(pa_bluetooth_discovery *y, const char* address) {
-    pa_bluetooth_device *d;
-    void *state = NULL;
-
-    pa_assert(y);
-    pa_assert(PA_REFCNT_VALUE(y) > 0);
-    pa_assert(address);
-
-    if (!pa_hook_is_firing(&y->hook))
-        pa_bluetooth_discovery_sync(y);
-
-    while ((d = pa_hashmap_iterate(y->devices, &state, NULL)))
-        if (pa_streq(d->address, address))
-            return device_is_audio(d) ? d : NULL;
-
-    return NULL;
-}
-
-const pa_bluetooth_device* pa_bluetooth_discovery_get_by_path(pa_bluetooth_discovery *y, const char* path) {
-    pa_bluetooth_device *d;
-
-    pa_assert(y);
-    pa_assert(PA_REFCNT_VALUE(y) > 0);
-    pa_assert(path);
-
-    if (!pa_hook_is_firing(&y->hook))
-        pa_bluetooth_discovery_sync(y);
-
-    if ((d = pa_hashmap_get(y->devices, path)))
-        if (device_is_audio(d))
-            return d;
-
-    return NULL;
-}
-
-const pa_bluetooth_transport* pa_bluetooth_discovery_get_transport(pa_bluetooth_discovery *y, const char *path) {
-    pa_bluetooth_device *d;
-    pa_bluetooth_transport *t;
-    void *state = NULL;
-
-    pa_assert(y);
-    pa_assert(PA_REFCNT_VALUE(y) > 0);
-    pa_assert(path);
-
-    while ((d = pa_hashmap_iterate(y->devices, &state, NULL)))
-        if ((t = pa_hashmap_get(d->transports, path)))
-            return t;
-
-    return NULL;
-}
-
-const pa_bluetooth_transport* pa_bluetooth_device_get_transport(const pa_bluetooth_device *d, enum profile profile) {
-    pa_bluetooth_transport *t;
-    void *state = NULL;
-
-    pa_assert(d);
-
-    while ((t = pa_hashmap_iterate(d->transports, &state, NULL)))
-        if (t->profile == profile)
-            return t;
-
-    return NULL;
-}
-
-int pa_bluetooth_transport_acquire(const pa_bluetooth_transport *t, const char *accesstype, size_t *imtu, size_t *omtu) {
-    DBusMessage *m, *r;
-    DBusError err;
-    int ret;
-    uint16_t i, o;
-
-    pa_assert(t);
-    pa_assert(t->y);
-
-    dbus_error_init(&err);
-
-    pa_assert_se(m = dbus_message_new_method_call("org.bluez", t->path, "org.bluez.MediaTransport", "Acquire"));
-    pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, &accesstype, DBUS_TYPE_INVALID));
-    r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t->y->connection), m, -1, &err);
-
-    if (dbus_error_is_set(&err) || !r) {
-        pa_log("Failed to acquire transport fd: %s", err.message);
-        dbus_error_free(&err);
-        return -1;
-    }
-
-    if (!dbus_message_get_args(r, &err, DBUS_TYPE_UNIX_FD, &ret, DBUS_TYPE_UINT16, &i, DBUS_TYPE_UINT16, &o, DBUS_TYPE_INVALID)) {
-        pa_log("Failed to parse org.bluez.MediaTransport.Acquire(): %s", err.message);
-        ret = -1;
-        dbus_error_free(&err);
-        goto fail;
-    }
-
-    if (imtu)
-        *imtu = i;
-
-    if (omtu)
-        *omtu = o;
-
-fail:
-    dbus_message_unref(r);
-    return ret;
-}
-
-void pa_bluetooth_transport_release(const pa_bluetooth_transport *t, const char *accesstype) {
-    DBusMessage *m;
-    DBusError err;
-
-    pa_assert(t);
-    pa_assert(t->y);
-
-    dbus_error_init(&err);
-
-    pa_assert_se(m = dbus_message_new_method_call("org.bluez", t->path, "org.bluez.MediaTransport", "Release"));
-    pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, &accesstype, DBUS_TYPE_INVALID));
-    dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t->y->connection), m, -1, &err);
-
-    if (dbus_error_is_set(&err)) {
-        pa_log("Failed to release transport %s: %s", t->path, err.message);
-        dbus_error_free(&err);
-    } else
-        pa_log_info("Transport %s released", t->path);
-}
-
-static int setup_dbus(pa_bluetooth_discovery *y) {
-    DBusError err;
-
-    dbus_error_init(&err);
-
-    y->connection = pa_dbus_bus_get(y->core, DBUS_BUS_SYSTEM, &err);
-
-    if (dbus_error_is_set(&err) || !y->connection) {
-        pa_log("Failed to get D-Bus connection: %s", err.message);
-        dbus_error_free(&err);
-        return -1;
-    }
-
-    return 0;
-}
-
-static pa_bluetooth_transport *transport_new(pa_bluetooth_discovery *y, const char *path, enum profile p, const uint8_t *config, int size) {
-    pa_bluetooth_transport *t;
-
-    t = pa_xnew0(pa_bluetooth_transport, 1);
-    t->y = y;
-    t->path = pa_xstrdup(path);
-    t->profile = p;
-    t->config_size = size;
-
-    if (size > 0) {
-        t->config = pa_xnew(uint8_t, size);
-        memcpy(t->config, config, size);
-    }
-
-    return t;
-}
-
-static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage *m, void *userdata) {
-    pa_bluetooth_discovery *y = userdata;
-    pa_bluetooth_device *d;
-    pa_bluetooth_transport *t;
-    const char *path, *dev_path = NULL, *uuid = NULL;
-    uint8_t *config = NULL;
-    int size = 0;
-    pa_bool_t nrec = FALSE;
-    enum profile p;
-    DBusMessageIter args, props;
-    DBusMessage *r;
-
-    dbus_message_iter_init(m, &args);
-
-    dbus_message_iter_get_basic(&args, &path);
-    if (!dbus_message_iter_next(&args))
-        goto fail;
-
-    dbus_message_iter_recurse(&args, &props);
-    if (dbus_message_iter_get_arg_type(&props) != DBUS_TYPE_DICT_ENTRY)
-        goto fail;
-
-    /* Read transport properties */
-    while (dbus_message_iter_get_arg_type(&props) == DBUS_TYPE_DICT_ENTRY) {
-        const char *key;
-        DBusMessageIter value, entry;
-        int var;
-
-        dbus_message_iter_recurse(&props, &entry);
-        dbus_message_iter_get_basic(&entry, &key);
-
-        dbus_message_iter_next(&entry);
-        dbus_message_iter_recurse(&entry, &value);
-
-        var = dbus_message_iter_get_arg_type(&value);
-        if (strcasecmp(key, "UUID") == 0) {
-            if (var != DBUS_TYPE_STRING)
-                goto fail;
-            dbus_message_iter_get_basic(&value, &uuid);
-        } else if (strcasecmp(key, "Device") == 0) {
-            if (var != DBUS_TYPE_OBJECT_PATH)
-                goto fail;
-            dbus_message_iter_get_basic(&value, &dev_path);
-        } else if (strcasecmp(key, "NREC") == 0) {
-            if (var != DBUS_TYPE_BOOLEAN)
-                goto fail;
-            dbus_message_iter_get_basic(&value, &nrec);
-        } else if (strcasecmp(key, "Configuration") == 0) {
-            DBusMessageIter array;
-            if (var != DBUS_TYPE_ARRAY)
-                goto fail;
-            dbus_message_iter_recurse(&value, &array);
-            dbus_message_iter_get_fixed_array(&array, &config, &size);
-        }
-
-        dbus_message_iter_next(&props);
-    }
-
-    d = found_device(y, dev_path);
-    if (!d)
-        goto fail;
-
-    if (dbus_message_has_path(m, HFP_AG_ENDPOINT))
-        p = PROFILE_HSP;
-    else if (dbus_message_has_path(m, HFP_HS_ENDPOINT))
-        p = PROFILE_HFGW;
-    else if (dbus_message_has_path(m, A2DP_SOURCE_ENDPOINT))
-        p = PROFILE_A2DP;
-    else
-        p = PROFILE_A2DP_SOURCE;
-
-    t = transport_new(y, path, p, config, size);
-    if (nrec)
-        t->nrec = nrec;
-    pa_hashmap_put(d->transports, t->path, t);
-
-    pa_log_debug("Transport %s profile %d available", t->path, t->profile);
-
-    pa_assert_se(r = dbus_message_new_method_return(m));
-
-    return r;
-
-fail:
-    pa_log("org.bluez.MediaEndpoint.SetConfiguration: invalid arguments");
-    pa_assert_se(r = (dbus_message_new_error(m, "org.bluez.MediaEndpoint.Error.InvalidArguments",
-                                                        "Unable to set configuration")));
-    return r;
-}
-
-static DBusMessage *endpoint_clear_configuration(DBusConnection *c, DBusMessage *m, void *userdata) {
-    pa_bluetooth_discovery *y = userdata;
-    pa_bluetooth_device *d;
-    pa_bluetooth_transport *t;
-    void *state = NULL;
-    DBusMessage *r;
-    DBusError e;
-    const char *path;
-
-    dbus_error_init(&e);
-
-    if (!dbus_message_get_args(m, &e, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) {
-        pa_log("org.bluez.MediaEndpoint.ClearConfiguration: %s", e.message);
-        dbus_error_free(&e);
-        goto fail;
-    }
-
-    while ((d = pa_hashmap_iterate(y->devices, &state, NULL))) {
-        if ((t = pa_hashmap_get(d->transports, path))) {
-            pa_log_debug("Clearing transport %s profile %d", t->path, t->profile);
-            pa_hashmap_remove(d->transports, t->path);
-            transport_free(t);
-            break;
-        }
-    }
-
-    pa_assert_se(r = dbus_message_new_method_return(m));
-
-    return r;
-
-fail:
-    pa_assert_se(r = (dbus_message_new_error(m, "org.bluez.MediaEndpoint.Error.InvalidArguments",
-                                                        "Unable to clear configuration")));
-    return r;
-}
-
-static uint8_t a2dp_default_bitpool(uint8_t freq, uint8_t mode) {
-
-    switch (freq) {
-        case BT_SBC_SAMPLING_FREQ_16000:
-        case BT_SBC_SAMPLING_FREQ_32000:
-            return 53;
-
-        case BT_SBC_SAMPLING_FREQ_44100:
-
-            switch (mode) {
-                case BT_A2DP_CHANNEL_MODE_MONO:
-                case BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL:
-                    return 31;
-
-                case BT_A2DP_CHANNEL_MODE_STEREO:
-                case BT_A2DP_CHANNEL_MODE_JOINT_STEREO:
-                    return 53;
-
-                default:
-                    pa_log_warn("Invalid channel mode %u", mode);
-                    return 53;
-            }
-
-        case BT_SBC_SAMPLING_FREQ_48000:
-
-            switch (mode) {
-                case BT_A2DP_CHANNEL_MODE_MONO:
-                case BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL:
-                    return 29;
-
-                case BT_A2DP_CHANNEL_MODE_STEREO:
-                case BT_A2DP_CHANNEL_MODE_JOINT_STEREO:
-                    return 51;
-
-                default:
-                    pa_log_warn("Invalid channel mode %u", mode);
-                    return 51;
-            }
-
-        default:
-            pa_log_warn("Invalid sampling freq %u", freq);
-            return 53;
-    }
-}
-
-static DBusMessage *endpoint_select_configuration(DBusConnection *c, DBusMessage *m, void *userdata) {
-    pa_bluetooth_discovery *y = userdata;
-    a2dp_sbc_t *cap, config;
-    uint8_t *pconf = (uint8_t *) &config;
-    int i, size;
-    DBusMessage *r;
-    DBusError e;
-
-    static const struct {
-        uint32_t rate;
-        uint8_t cap;
-    } freq_table[] = {
-        { 16000U, BT_SBC_SAMPLING_FREQ_16000 },
-        { 32000U, BT_SBC_SAMPLING_FREQ_32000 },
-        { 44100U, BT_SBC_SAMPLING_FREQ_44100 },
-        { 48000U, BT_SBC_SAMPLING_FREQ_48000 }
-    };
-
-    dbus_error_init(&e);
-
-    if (!dbus_message_get_args(m, &e, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &cap, &size, DBUS_TYPE_INVALID)) {
-        pa_log("org.bluez.MediaEndpoint.SelectConfiguration: %s", e.message);
-        dbus_error_free(&e);
-        goto fail;
-    }
-
-    if (dbus_message_has_path(m, HFP_AG_ENDPOINT) || dbus_message_has_path(m, HFP_HS_ENDPOINT))
-        goto done;
-
-    pa_assert(size == sizeof(config));
-
-    memset(&config, 0, sizeof(config));
-
-    /* Find the lowest freq that is at least as high as the requested
-     * sampling rate */
-    for (i = 0; (unsigned) i < PA_ELEMENTSOF(freq_table); i++)
-        if (freq_table[i].rate >= y->core->default_sample_spec.rate && (cap->frequency & freq_table[i].cap)) {
-            config.frequency = freq_table[i].cap;
-            break;
-        }
-
-    if ((unsigned) i == PA_ELEMENTSOF(freq_table)) {
-        for (--i; i >= 0; i--) {
-            if (cap->frequency & freq_table[i].cap) {
-                config.frequency = freq_table[i].cap;
-                break;
-            }
-        }
-
-        if (i < 0) {
-            pa_log("Not suitable sample rate");
-            goto fail;
-        }
-    }
-
-    pa_assert((unsigned) i < PA_ELEMENTSOF(freq_table));
-
-    if (y->core->default_sample_spec.channels <= 1) {
-        if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_MONO)
-            config.channel_mode = BT_A2DP_CHANNEL_MODE_MONO;
-    }
-
-    if (y->core->default_sample_spec.channels >= 2) {
-        if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_JOINT_STEREO)
-            config.channel_mode = BT_A2DP_CHANNEL_MODE_JOINT_STEREO;
-        else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO)
-            config.channel_mode = BT_A2DP_CHANNEL_MODE_STEREO;
-        else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL)
-            config.channel_mode = BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL;
-        else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_MONO) {
-            config.channel_mode = BT_A2DP_CHANNEL_MODE_MONO;
-        } else {
-            pa_log("No supported channel modes");
-            goto fail;
-        }
-    }
-
-    if (cap->block_length & BT_A2DP_BLOCK_LENGTH_16)
-        config.block_length = BT_A2DP_BLOCK_LENGTH_16;
-    else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_12)
-        config.block_length = BT_A2DP_BLOCK_LENGTH_12;
-    else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_8)
-        config.block_length = BT_A2DP_BLOCK_LENGTH_8;
-    else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_4)
-        config.block_length = BT_A2DP_BLOCK_LENGTH_4;
-    else {
-        pa_log_error("No supported block lengths");
-        goto fail;
-    }
-
-    if (cap->subbands & BT_A2DP_SUBBANDS_8)
-        config.subbands = BT_A2DP_SUBBANDS_8;
-    else if (cap->subbands & BT_A2DP_SUBBANDS_4)
-        config.subbands = BT_A2DP_SUBBANDS_4;
-    else {
-        pa_log_error("No supported subbands");
-        goto fail;
-    }
-
-    if (cap->allocation_method & BT_A2DP_ALLOCATION_LOUDNESS)
-        config.allocation_method = BT_A2DP_ALLOCATION_LOUDNESS;
-    else if (cap->allocation_method & BT_A2DP_ALLOCATION_SNR)
-        config.allocation_method = BT_A2DP_ALLOCATION_SNR;
-
-    config.min_bitpool = (uint8_t) PA_MAX(MIN_BITPOOL, cap->min_bitpool);
-    config.max_bitpool = (uint8_t) PA_MIN(a2dp_default_bitpool(config.frequency, config.channel_mode), cap->max_bitpool);
-
-done:
-    pa_assert_se(r = dbus_message_new_method_return(m));
-
-    pa_assert_se(dbus_message_append_args(
-                                     r,
-                                     DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pconf, size,
-                                     DBUS_TYPE_INVALID));
-
-    return r;
-
-fail:
-    pa_assert_se(r = (dbus_message_new_error(m, "org.bluez.MediaEndpoint.Error.InvalidArguments",
-                                                        "Unable to select configuration")));
-    return r;
-}
-
-static DBusHandlerResult endpoint_handler(DBusConnection *c, DBusMessage *m, void *userdata) {
-    struct pa_bluetooth_discovery *y = userdata;
-    DBusMessage *r = NULL;
-    DBusError e;
-    const char *path;
-
-    pa_assert(y);
-
-    pa_log_debug("dbus: interface=%s, path=%s, member=%s\n",
-            dbus_message_get_interface(m),
-            dbus_message_get_path(m),
-            dbus_message_get_member(m));
-
-    path = dbus_message_get_path(m);
-    dbus_error_init(&e);
-
-    if (!pa_streq(path, A2DP_SOURCE_ENDPOINT) && !pa_streq(path, A2DP_SINK_ENDPOINT) && !pa_streq(path, HFP_AG_ENDPOINT) && !pa_streq(path, HFP_HS_ENDPOINT))
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-    if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
-        const char *xml = ENDPOINT_INTROSPECT_XML;
-
-        pa_assert_se(r = dbus_message_new_method_return(m));
-        pa_assert_se(dbus_message_append_args(
-                                 r,
-                                 DBUS_TYPE_STRING, &xml,
-                                 DBUS_TYPE_INVALID));
-
-    } else if (dbus_message_is_method_call(m, "org.bluez.MediaEndpoint", "SetConfiguration")) {
-        r = endpoint_set_configuration(c, m, userdata);
-    } else if (dbus_message_is_method_call(m, "org.bluez.MediaEndpoint", "SelectConfiguration")) {
-        r = endpoint_select_configuration(c, m, userdata);
-    } else if (dbus_message_is_method_call(m, "org.bluez.MediaEndpoint", "ClearConfiguration"))
-        r = endpoint_clear_configuration(c, m, userdata);
-    else
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-    if (r) {
-        pa_assert_se(dbus_connection_send(pa_dbus_connection_get(y->connection), r, NULL));
-        dbus_message_unref(r);
-    }
-
-    return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) {
-    DBusError err;
-    pa_bluetooth_discovery *y;
-    static const DBusObjectPathVTable vtable_endpoint = {
-        .message_function = endpoint_handler,
-    };
-
-    pa_assert(c);
-
-    dbus_error_init(&err);
-
-    if ((y = pa_shared_get(c, "bluetooth-discovery")))
-        return pa_bluetooth_discovery_ref(y);
-
-    y = pa_xnew0(pa_bluetooth_discovery, 1);
-    PA_REFCNT_INIT(y);
-    y->core = c;
-    y->devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-    PA_LLIST_HEAD_INIT(pa_dbus_pending, y->pending);
-    pa_hook_init(&y->hook, y);
-    pa_shared_set(c, "bluetooth-discovery", y);
-
-    if (setup_dbus(y) < 0)
-        goto fail;
-
-    /* dynamic detection of bluetooth audio devices */
-    if (!dbus_connection_add_filter(pa_dbus_connection_get(y->connection), filter_cb, y, NULL)) {
-        pa_log_error("Failed to add filter function");
-        goto fail;
-    }
-    y->filter_added = TRUE;
-
-    if (pa_dbus_add_matches(
-                pa_dbus_connection_get(y->connection), &err,
-                "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',arg0='org.bluez'",
-                "type='signal',sender='org.bluez',interface='org.bluez.Manager',member='AdapterAdded'",
-                "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceRemoved'",
-                "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceCreated'",
-                "type='signal',sender='org.bluez',interface='org.bluez.Device',member='PropertyChanged'",
-                "type='signal',sender='org.bluez',interface='org.bluez.Device',member='DisconnectRequested'",
-                "type='signal',sender='org.bluez',interface='org.bluez.Audio',member='PropertyChanged'",
-                "type='signal',sender='org.bluez',interface='org.bluez.Headset',member='PropertyChanged'",
-                "type='signal',sender='org.bluez',interface='org.bluez.AudioSink',member='PropertyChanged'",
-                "type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged'",
-                "type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged'",
-                "type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged'",
-                NULL) < 0) {
-        pa_log("Failed to add D-Bus matches: %s", err.message);
-        goto fail;
-    }
-
-    pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(y->connection), HFP_AG_ENDPOINT, &vtable_endpoint, y));
-    pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(y->connection), HFP_HS_ENDPOINT, &vtable_endpoint, y));
-    pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(y->connection), A2DP_SOURCE_ENDPOINT, &vtable_endpoint, y));
-    pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(y->connection), A2DP_SINK_ENDPOINT, &vtable_endpoint, y));
-
-    list_adapters(y);
-
-    return y;
-
-fail:
-
-    if (y)
-        pa_bluetooth_discovery_unref(y);
-
-    dbus_error_free(&err);
-
-    return NULL;
-}
-
-pa_bluetooth_discovery* pa_bluetooth_discovery_ref(pa_bluetooth_discovery *y) {
-    pa_assert(y);
-    pa_assert(PA_REFCNT_VALUE(y) > 0);
-
-    PA_REFCNT_INC(y);
-
-    return y;
-}
-
-void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) {
-    pa_assert(y);
-    pa_assert(PA_REFCNT_VALUE(y) > 0);
-
-    if (PA_REFCNT_DEC(y) > 0)
-        return;
-
-    pa_dbus_free_pending_list(&y->pending);
-
-    if (y->devices) {
-        remove_all_devices(y);
-        pa_hashmap_free(y->devices, NULL, NULL);
-    }
-
-    if (y->connection) {
-        dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), HFP_AG_ENDPOINT);
-        dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), HFP_HS_ENDPOINT);
-        dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), A2DP_SOURCE_ENDPOINT);
-        dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), A2DP_SINK_ENDPOINT);
-        pa_dbus_remove_matches(pa_dbus_connection_get(y->connection),
-                               "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',arg0='org.bluez'",
-                               "type='signal',sender='org.bluez',interface='org.bluez.Manager',member='AdapterAdded'",
-                               "type='signal',sender='org.bluez',interface='org.bluez.Manager',member='AdapterRemoved'",
-                               "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceRemoved'",
-                               "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceCreated'",
-                               "type='signal',sender='org.bluez',interface='org.bluez.Device',member='PropertyChanged'",
-                               "type='signal',sender='org.bluez',interface='org.bluez.Device',member='DisconnectRequested'",
-                               "type='signal',sender='org.bluez',interface='org.bluez.Audio',member='PropertyChanged'",
-                               "type='signal',sender='org.bluez',interface='org.bluez.Headset',member='PropertyChanged'",
-                               "type='signal',sender='org.bluez',interface='org.bluez.AudioSink',member='PropertyChanged'",
-                               "type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged'",
-                               "type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged'",
-                               "type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged'",
-                               NULL);
-
-        if (y->filter_added)
-            dbus_connection_remove_filter(pa_dbus_connection_get(y->connection), filter_cb, y);
-
-        pa_dbus_connection_unref(y->connection);
-    }
-
-    pa_hook_done(&y->hook);
-
-    if (y->core)
-        pa_shared_remove(y->core, "bluetooth-discovery");
-
-    pa_xfree(y);
-}
-
-void pa_bluetooth_discovery_sync(pa_bluetooth_discovery *y) {
-    pa_assert(y);
-    pa_assert(PA_REFCNT_VALUE(y) > 0);
-
-    pa_dbus_sync_pending_list(&y->pending);
-}
-
-pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *y) {
-    pa_assert(y);
-    pa_assert(PA_REFCNT_VALUE(y) > 0);
-
-    return &y->hook;
-}
-
-const char*pa_bluetooth_get_form_factor(uint32_t class) {
-    unsigned i;
-    const char *r;
-
-    static const char * const table[] = {
-        [1] = "headset",
-        [2] = "hands-free",
-        [4] = "microphone",
-        [5] = "speaker",
-        [6] = "headphone",
-        [7] = "portable",
-        [8] = "car",
-        [10] = "hifi"
-    };
-
-    if (((class >> 8) & 31) != 4)
-        return NULL;
-
-    if ((i = (class >> 2) & 63) > PA_ELEMENTSOF(table))
-        r =  NULL;
-    else
-        r = table[i];
-
-    if (!r)
-        pa_log_debug("Unknown Bluetooth minor device class %u", i);
-
-    return r;
-}
-
-char *pa_bluetooth_cleanup_name(const char *name) {
-    char *t, *s, *d;
-    pa_bool_t space = FALSE;
-
-    pa_assert(name);
-
-    while ((*name >= 1 && *name <= 32) || *name >= 127)
-        name++;
-
-    t = pa_xstrdup(name);
-
-    for (s = d = t; *s; s++) {
-
-        if (*s <= 32 || *s >= 127 || *s == '_') {
-            space = TRUE;
-            continue;
-        }
-
-        if (space) {
-            *(d++) = ' ';
-            space = FALSE;
-        }
-
-        *(d++) = *s;
-    }
-
-    *d = 0;
-
-    return t;
-}
-
-pa_bool_t pa_bluetooth_uuid_has(pa_bluetooth_uuid *uuids, const char *uuid) {
-    pa_assert(uuid);
-
-    while (uuids) {
-        if (strcasecmp(uuids->uuid, uuid) == 0)
-            return TRUE;
-
-        uuids = uuids->next;
-    }
-
-    return FALSE;
-}
index 2752a69..859ad2d 100644 (file)
@@ -43,6 +43,8 @@
 #define A2DP_SOURCE_UUID        "0000110a-0000-1000-8000-00805f9b34fb"
 #define A2DP_SINK_UUID          "0000110b-0000-1000-8000-00805f9b34fb"
 
+#define HSP_MAX_GAIN 15
+
 typedef struct pa_bluetooth_uuid pa_bluetooth_uuid;
 typedef struct pa_bluetooth_device pa_bluetooth_device;
 typedef struct pa_bluetooth_discovery pa_bluetooth_discovery;
@@ -63,14 +65,43 @@ enum profile {
     PROFILE_OFF
 };
 
+#define PA_BLUETOOTH_PROFILE_COUNT PROFILE_OFF
+
+struct pa_bluetooth_hook_uuid_data {
+    pa_bluetooth_device *device;
+    const char *uuid;
+};
+
+/* Hook data: pa_bluetooth_discovery pointer. */
+typedef enum pa_bluetooth_hook {
+    PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED, /* Call data: pa_bluetooth_device */
+    PA_BLUETOOTH_HOOK_DEVICE_UUID_ADDED, /* Call data: pa_bluetooth_hook_uuid_data */
+    PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED, /* Call data: pa_bluetooth_transport */
+    PA_BLUETOOTH_HOOK_TRANSPORT_NREC_CHANGED, /* Call data: pa_bluetooth_transport */
+    PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED, /* Call data: pa_bluetooth_transport */
+    PA_BLUETOOTH_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED, /* Call data: pa_bluetooth_transport */
+    PA_BLUETOOTH_HOOK_MAX
+} pa_bluetooth_hook_t;
+
+typedef enum pa_bluetooth_transport_state {
+    PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED,
+    PA_BLUETOOTH_TRANSPORT_STATE_IDLE, /* Connected but not playing */
+    PA_BLUETOOTH_TRANSPORT_STATE_PLAYING
+} pa_bluetooth_transport_state_t;
+
 struct pa_bluetooth_transport {
-    pa_bluetooth_discovery *y;
+    pa_bluetooth_device *device;
+    char *owner;
     char *path;
     enum profile profile;
     uint8_t codec;
     uint8_t *config;
     int config_size;
-    pa_bool_t nrec;
+
+    pa_bluetooth_transport_state_t state;
+    bool nrec;
+    uint16_t microphone_gain; /* Used for HSP/HFP */
+    uint16_t speaker_gain; /* Used for HSP/HFP */
 };
 
 /* This enum is shared among Audio, Headset, AudioSink, and AudioSource, although not all values are acceptable in all profiles */
@@ -83,17 +114,17 @@ typedef enum pa_bt_audio_state {
 } pa_bt_audio_state_t;
 
 struct pa_bluetooth_device {
-    pa_bool_t dead;
+    pa_bluetooth_discovery *discovery;
+    bool dead;
 
     int device_info_valid;      /* 0: no results yet; 1: good results; -1: bad results ... */
 
     /* Device information */
     char *name;
     char *path;
-    pa_hashmap *transports;
+    pa_bluetooth_transport *transports[PA_BLUETOOTH_PROFILE_COUNT];
     int paired;
     char *alias;
-    int device_connected;
     PA_LLIST_HEAD(pa_bluetooth_uuid, uuids);
     char *address;
     int class;
@@ -102,42 +133,51 @@ struct pa_bluetooth_device {
     /* Audio state */
     pa_bt_audio_state_t audio_state;
 
-    /* AudioSink state */
-    pa_bt_audio_state_t audio_sink_state;
-
-    /* AudioSource state */
-    pa_bt_audio_state_t audio_source_state;
-
-    /* Headset state */
-    pa_bt_audio_state_t headset_state;
-
-    /* HandsfreeGateway state */
-    pa_bt_audio_state_t hfgw_state;
+    /* AudioSink, AudioSource, Headset and HandsfreeGateway states */
+    pa_bt_audio_state_t profile_state[PA_BLUETOOTH_PROFILE_COUNT];
 };
 
 pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *core);
 pa_bluetooth_discovery* pa_bluetooth_discovery_ref(pa_bluetooth_discovery *y);
 void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *d);
 
-void pa_bluetooth_discovery_sync(pa_bluetooth_discovery *d);
+pa_bluetooth_device* pa_bluetooth_discovery_get_by_path(pa_bluetooth_discovery *d, const char* path);
+pa_bluetooth_device* pa_bluetooth_discovery_get_by_address(pa_bluetooth_discovery *d, const char* address);
 
-const pa_bluetooth_device* pa_bluetooth_discovery_get_by_path(pa_bluetooth_discovery *d, const char* path);
-const pa_bluetooth_device* pa_bluetooth_discovery_get_by_address(pa_bluetooth_discovery *d, const char* address);
+bool pa_bluetooth_device_any_audio_connected(const pa_bluetooth_device *d);
 
-const pa_bluetooth_transport* pa_bluetooth_discovery_get_transport(pa_bluetooth_discovery *y, const char *path);
-const pa_bluetooth_transport* pa_bluetooth_device_get_transport(const pa_bluetooth_device *d, enum profile profile);
+int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu);
+void pa_bluetooth_transport_release(pa_bluetooth_transport *t);
 
-int pa_bluetooth_transport_acquire(const pa_bluetooth_transport *t, const char *accesstype, size_t *imtu, size_t *omtu);
-void pa_bluetooth_transport_release(const pa_bluetooth_transport *t, const char *accesstype);
-int pa_bluetooth_transport_parse_property(pa_bluetooth_transport *t, DBusMessageIter *i);
+void pa_bluetooth_transport_set_microphone_gain(pa_bluetooth_transport *t, uint16_t value);
+void pa_bluetooth_transport_set_speaker_gain(pa_bluetooth_transport *t, uint16_t value);
 
-pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *d);
+pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *y, pa_bluetooth_hook_t hook);
 
-const char* pa_bluetooth_get_form_factor(uint32_t class);
+typedef enum pa_bt_form_factor {
+    PA_BT_FORM_FACTOR_UNKNOWN,
+    PA_BT_FORM_FACTOR_HEADSET,
+    PA_BT_FORM_FACTOR_HANDSFREE,
+    PA_BT_FORM_FACTOR_MICROPHONE,
+    PA_BT_FORM_FACTOR_SPEAKER,
+    PA_BT_FORM_FACTOR_HEADPHONE,
+    PA_BT_FORM_FACTOR_PORTABLE,
+    PA_BT_FORM_FACTOR_CAR,
+    PA_BT_FORM_FACTOR_HIFI,
+    PA_BT_FORM_FACTOR_PHONE,
+} pa_bt_form_factor_t;
+
+pa_bt_form_factor_t pa_bluetooth_get_form_factor(uint32_t class);
+const char *pa_bt_form_factor_to_string(pa_bt_form_factor_t ff);
 
 char *pa_bluetooth_cleanup_name(const char *name);
 
-pa_bool_t pa_bluetooth_uuid_has(pa_bluetooth_uuid *uuids, const char *uuid);
-pa_bt_audio_state_t pa_bt_audio_state_from_string(const char* value);
+bool pa_bluetooth_uuid_has(pa_bluetooth_uuid *uuids, const char *uuid);
+const char *pa_bt_profile_to_string(enum profile profile);
 
+#ifdef BLUETOOTH_APTX_SUPPORT
+int pa_load_aptx(const char *aptx_lib_name);
+int pa_unload_aptx(void);
+void* pa_aptx_get_handle(void);
+#endif
 #endif
diff --git a/src/modules/bluetooth/bluez4-util.c b/src/modules/bluetooth/bluez4-util.c
new file mode 100644 (file)
index 0000000..929abde
--- /dev/null
@@ -0,0 +1,2096 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2008-2013 João Paulo Rechi Vita
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef BLUETOOTH_APTX_SUPPORT
+#include <dlfcn.h>
+#endif
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/shared.h>
+#include <pulsecore/dbus-shared.h>
+
+#include "bluez4-util.h"
+#include "a2dp-codecs.h"
+
+#define ENDPOINT_PATH_HFP_AG "/MediaEndpoint/BlueZ4/HFPAG"
+#define ENDPOINT_PATH_HFP_HS "/MediaEndpoint/BlueZ4/HFPHS"
+#define ENDPOINT_PATH_A2DP_SOURCE "/MediaEndpoint/BlueZ4/A2DPSource"
+#define ENDPOINT_PATH_A2DP_SINK "/MediaEndpoint/BlueZ4/A2DPSink"
+#ifdef BLUETOOTH_APTX_SUPPORT
+#define ENDPOINT_PATH_A2DP_APTX_SOURCE "/MediaEndpoint/Bluez4/A2DPSource_aptx"
+#endif
+
+#define ENDPOINT_INTROSPECT_XML                                         \
+    DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                           \
+    "<node>"                                                            \
+    " <interface name=\"org.bluez.MediaEndpoint\">"                     \
+    "  <method name=\"SetConfiguration\">"                              \
+    "   <arg name=\"transport\" direction=\"in\" type=\"o\"/>"          \
+    "   <arg name=\"configuration\" direction=\"in\" type=\"ay\"/>"     \
+    "  </method>"                                                       \
+    "  <method name=\"SelectConfiguration\">"                           \
+    "   <arg name=\"capabilities\" direction=\"in\" type=\"ay\"/>"      \
+    "   <arg name=\"configuration\" direction=\"out\" type=\"ay\"/>"    \
+    "  </method>"                                                       \
+    "  <method name=\"ClearConfiguration\">"                            \
+    "  </method>"                                                       \
+    "  <method name=\"Release\">"                                       \
+    "  </method>"                                                       \
+    " </interface>"                                                     \
+    " <interface name=\"org.freedesktop.DBus.Introspectable\">"         \
+    "  <method name=\"Introspect\">"                                    \
+    "   <arg name=\"data\" type=\"s\" direction=\"out\"/>"              \
+    "  </method>"                                                       \
+    " </interface>"                                                     \
+    "</node>"
+
+struct pa_bluez4_discovery {
+    PA_REFCNT_DECLARE;
+
+    pa_core *core;
+    pa_dbus_connection *connection;
+    PA_LLIST_HEAD(pa_dbus_pending, pending);
+    bool adapters_listed;
+    pa_hashmap *devices;
+    pa_hashmap *transports;
+    pa_hook hooks[PA_BLUEZ4_HOOK_MAX];
+    bool filter_added;
+};
+
+static void get_properties_reply(DBusPendingCall *pending, void *userdata);
+static pa_dbus_pending* send_and_add_to_pending(pa_bluez4_discovery *y, DBusMessage *m, DBusPendingCallNotifyFunction func,
+                                                void *call_data);
+static void found_adapter(pa_bluez4_discovery *y, const char *path);
+static pa_bluez4_device *found_device(pa_bluez4_discovery *y, const char* path);
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+static void *aptx_handle = NULL;
+
+int pa_unload_aptx(void)
+{
+       if (aptx_handle == NULL) {
+               pa_log_warn("Unable to unload apt-X library");
+               return -1;
+       }
+
+       dlclose(aptx_handle);
+       aptx_handle = NULL;
+
+       pa_log_debug("unloaded apt-X library successfully");
+       return 0;
+}
+
+int pa_load_aptx(const char *aptx_lib_name)
+{
+       char* lib_path = NULL ;
+
+        if(aptx_lib_name == NULL)
+               return -1;
+
+        lib_path = pa_sprintf_malloc("%s/%s", PA_DLSEARCHPATH, aptx_lib_name);
+
+       if (!lib_path)
+               return -1;
+
+       pa_log_info("aptx_lib_path = [%s]", lib_path);
+
+       aptx_handle = dlopen(lib_path, RTLD_LAZY);
+       if (aptx_handle == NULL) {
+               pa_log_warn("Unable to load apt-X library [%s]", dlerror());
+               pa_xfree(lib_path);
+               return -1;
+       }
+
+       pa_log_debug("loaded apt-X library successfully");
+       pa_xfree(lib_path);
+
+       return 0;
+}
+
+void* pa_aptx_get_handle(void)
+{
+       return aptx_handle;
+}
+#endif
+
+static pa_bluez4_audio_state_t audio_state_from_string(const char* value) {
+    pa_assert(value);
+
+    if (pa_streq(value, "disconnected"))
+        return PA_BLUEZ4_AUDIO_STATE_DISCONNECTED;
+    else if (pa_streq(value, "connecting"))
+        return PA_BLUEZ4_AUDIO_STATE_CONNECTING;
+    else if (pa_streq(value, "connected"))
+        return PA_BLUEZ4_AUDIO_STATE_CONNECTED;
+    else if (pa_streq(value, "playing"))
+        return PA_BLUEZ4_AUDIO_STATE_PLAYING;
+
+    return PA_BLUEZ4_AUDIO_STATE_INVALID;
+}
+
+const char *pa_bluez4_profile_to_string(pa_bluez4_profile_t profile) {
+    switch(profile) {
+        case PA_BLUEZ4_PROFILE_A2DP:
+            return "a2dp";
+        case PA_BLUEZ4_PROFILE_A2DP_SOURCE:
+            return "a2dp_source";
+        case PA_BLUEZ4_PROFILE_HSP:
+            return "hsp";
+        case PA_BLUEZ4_PROFILE_HFGW:
+            return "hfgw";
+        case PA_BLUEZ4_PROFILE_OFF:
+            pa_assert_not_reached();
+    }
+
+    pa_assert_not_reached();
+}
+
+static int profile_from_interface(const char *interface, pa_bluez4_profile_t *p) {
+    pa_assert(interface);
+    pa_assert(p);
+
+    if (pa_streq(interface, "org.bluez.AudioSink")) {
+        *p = PA_BLUEZ4_PROFILE_A2DP;
+        return 0;
+    } else if (pa_streq(interface, "org.bluez.AudioSource")) {
+        *p = PA_BLUEZ4_PROFILE_A2DP_SOURCE;
+        return 0;
+    } else if (pa_streq(interface, "org.bluez.Headset")) {
+        *p = PA_BLUEZ4_PROFILE_HSP;
+        return 0;
+    } else if (pa_streq(interface, "org.bluez.HandsfreeGateway")) {
+        *p = PA_BLUEZ4_PROFILE_HFGW;
+        return 0;
+    }
+
+    return -1;
+}
+
+static pa_bluez4_transport_state_t audio_state_to_transport_state(pa_bluez4_audio_state_t state) {
+    switch (state) {
+        case PA_BLUEZ4_AUDIO_STATE_INVALID: /* Typically if state hasn't been received yet */
+        case PA_BLUEZ4_AUDIO_STATE_DISCONNECTED:
+        case PA_BLUEZ4_AUDIO_STATE_CONNECTING:
+            return PA_BLUEZ4_TRANSPORT_STATE_DISCONNECTED;
+        case PA_BLUEZ4_AUDIO_STATE_CONNECTED:
+            return PA_BLUEZ4_TRANSPORT_STATE_IDLE;
+        case PA_BLUEZ4_AUDIO_STATE_PLAYING:
+            return PA_BLUEZ4_TRANSPORT_STATE_PLAYING;
+    }
+
+    pa_assert_not_reached();
+}
+
+static pa_bluez4_uuid *uuid_new(const char *uuid) {
+    pa_bluez4_uuid *u;
+
+    u = pa_xnew(pa_bluez4_uuid, 1);
+    u->uuid = pa_xstrdup(uuid);
+    PA_LLIST_INIT(pa_bluez4_uuid, u);
+
+    return u;
+}
+
+static void uuid_free(pa_bluez4_uuid *u) {
+    pa_assert(u);
+
+    pa_xfree(u->uuid);
+    pa_xfree(u);
+}
+
+static pa_bluez4_device* device_new(pa_bluez4_discovery *discovery, const char *path) {
+    pa_bluez4_device *d;
+    unsigned i;
+
+    pa_assert(discovery);
+    pa_assert(path);
+
+    d = pa_xnew0(pa_bluez4_device, 1);
+
+    d->discovery = discovery;
+    d->dead = false;
+
+    d->device_info_valid = 0;
+
+    d->name = NULL;
+    d->path = pa_xstrdup(path);
+    d->paired = -1;
+    d->alias = NULL;
+    PA_LLIST_HEAD_INIT(pa_bluez4_uuid, d->uuids);
+    d->address = NULL;
+    d->class = -1;
+    d->trusted = -1;
+
+    d->audio_state = PA_BLUEZ4_AUDIO_STATE_INVALID;
+
+    for (i = 0; i < PA_BLUEZ4_PROFILE_COUNT; i++)
+        d->profile_state[i] = PA_BLUEZ4_AUDIO_STATE_INVALID;
+
+    return d;
+}
+
+static void transport_free(pa_bluez4_transport *t) {
+    pa_assert(t);
+
+    pa_xfree(t->owner);
+    pa_xfree(t->path);
+    pa_xfree(t->config);
+    pa_xfree(t);
+}
+
+static void device_free(pa_bluez4_device *d) {
+    pa_bluez4_uuid *u;
+    pa_bluez4_transport *t;
+    unsigned i;
+
+    pa_assert(d);
+
+    for (i = 0; i < PA_BLUEZ4_PROFILE_COUNT; i++) {
+        if (!(t = d->transports[i]))
+            continue;
+
+        d->transports[i] = NULL;
+        pa_hashmap_remove(d->discovery->transports, t->path);
+        t->state = PA_BLUEZ4_TRANSPORT_STATE_DISCONNECTED;
+        pa_hook_fire(&d->discovery->hooks[PA_BLUEZ4_HOOK_TRANSPORT_STATE_CHANGED], t);
+        transport_free(t);
+    }
+
+    while ((u = d->uuids)) {
+        PA_LLIST_REMOVE(pa_bluez4_uuid, d->uuids, u);
+        uuid_free(u);
+    }
+
+    pa_xfree(d->name);
+    pa_xfree(d->path);
+    pa_xfree(d->alias);
+    pa_xfree(d->address);
+    pa_xfree(d);
+}
+
+static const char *check_variant_property(DBusMessageIter *i) {
+    const char *key;
+
+    pa_assert(i);
+
+    if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING) {
+        pa_log("Property name not a string.");
+        return NULL;
+    }
+
+    dbus_message_iter_get_basic(i, &key);
+
+    if (!dbus_message_iter_next(i)) {
+        pa_log("Property value missing");
+        return NULL;
+    }
+
+    if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_VARIANT) {
+        pa_log("Property value not a variant.");
+        return NULL;
+    }
+
+    return key;
+}
+
+static int parse_manager_property(pa_bluez4_discovery *y, DBusMessageIter *i, bool is_property_change) {
+    const char *key;
+    DBusMessageIter variant_i;
+
+    pa_assert(y);
+
+    key = check_variant_property(i);
+    if (key == NULL)
+        return -1;
+
+    dbus_message_iter_recurse(i, &variant_i);
+
+    switch (dbus_message_iter_get_arg_type(&variant_i)) {
+
+        case DBUS_TYPE_ARRAY: {
+
+            DBusMessageIter ai;
+            dbus_message_iter_recurse(&variant_i, &ai);
+
+            if (pa_streq(key, "Adapters")) {
+                y->adapters_listed = true;
+
+                if (dbus_message_iter_get_arg_type(&ai) != DBUS_TYPE_OBJECT_PATH)
+                    break;
+
+                while (dbus_message_iter_get_arg_type(&ai) != DBUS_TYPE_INVALID) {
+                    const char *value;
+
+                    dbus_message_iter_get_basic(&ai, &value);
+
+                    found_adapter(y, value);
+
+                    dbus_message_iter_next(&ai);
+                }
+            }
+
+            break;
+        }
+    }
+
+    return 0;
+}
+
+static int parse_adapter_property(pa_bluez4_discovery *y, DBusMessageIter *i, bool is_property_change) {
+    const char *key;
+    DBusMessageIter variant_i;
+
+    pa_assert(y);
+
+    key = check_variant_property(i);
+    if (key == NULL)
+        return -1;
+
+    dbus_message_iter_recurse(i, &variant_i);
+
+    switch (dbus_message_iter_get_arg_type(&variant_i)) {
+
+        case DBUS_TYPE_ARRAY: {
+
+            DBusMessageIter ai;
+            dbus_message_iter_recurse(&variant_i, &ai);
+
+            if (dbus_message_iter_get_arg_type(&ai) == DBUS_TYPE_OBJECT_PATH &&
+                pa_streq(key, "Devices")) {
+
+                while (dbus_message_iter_get_arg_type(&ai) != DBUS_TYPE_INVALID) {
+                    const char *value;
+
+                    dbus_message_iter_get_basic(&ai, &value);
+
+                    found_device(y, value);
+
+                    dbus_message_iter_next(&ai);
+                }
+            }
+
+            break;
+        }
+    }
+
+    return 0;
+}
+
+static int parse_device_property(pa_bluez4_device *d, DBusMessageIter *i, bool is_property_change) {
+    const char *key;
+    DBusMessageIter variant_i;
+
+    pa_assert(d);
+
+    key = check_variant_property(i);
+    if (key == NULL)
+        return -1;
+
+    dbus_message_iter_recurse(i, &variant_i);
+
+/*     pa_log_debug("Parsing property org.bluez.Device.%s", key); */
+
+    switch (dbus_message_iter_get_arg_type(&variant_i)) {
+
+        case DBUS_TYPE_STRING: {
+
+            const char *value;
+            dbus_message_iter_get_basic(&variant_i, &value);
+
+            if (pa_streq(key, "Name")) {
+                pa_xfree(d->name);
+                d->name = pa_xstrdup(value);
+            } else if (pa_streq(key, "Alias")) {
+                pa_xfree(d->alias);
+                d->alias = pa_xstrdup(value);
+            } else if (pa_streq(key, "Address")) {
+                if (is_property_change) {
+                    pa_log("Device property 'Address' expected to be constant but changed for %s", d->path);
+                    return -1;
+                }
+
+                if (d->address) {
+                    pa_log("Device %s: Received a duplicate Address property.", d->path);
+                    return -1;
+                }
+
+                d->address = pa_xstrdup(value);
+            }
+
+/*             pa_log_debug("Value %s", value); */
+
+            break;
+        }
+
+        case DBUS_TYPE_BOOLEAN: {
+
+            dbus_bool_t value;
+            dbus_message_iter_get_basic(&variant_i, &value);
+
+            if (pa_streq(key, "Paired"))
+                d->paired = !!value;
+            else if (pa_streq(key, "Trusted"))
+                d->trusted = !!value;
+
+/*             pa_log_debug("Value %s", pa_yes_no(value)); */
+
+            break;
+        }
+
+        case DBUS_TYPE_UINT32: {
+
+            uint32_t value;
+            dbus_message_iter_get_basic(&variant_i, &value);
+
+            if (pa_streq(key, "Class"))
+                d->class = (int) value;
+
+/*             pa_log_debug("Value %u", (unsigned) value); */
+
+            break;
+        }
+
+        case DBUS_TYPE_ARRAY: {
+
+            DBusMessageIter ai;
+            dbus_message_iter_recurse(&variant_i, &ai);
+
+            if (dbus_message_iter_get_arg_type(&ai) == DBUS_TYPE_STRING && pa_streq(key, "UUIDs")) {
+                DBusMessage *m;
+                bool has_audio = false;
+
+                while (dbus_message_iter_get_arg_type(&ai) != DBUS_TYPE_INVALID) {
+                    pa_bluez4_uuid *node;
+                    const char *value;
+                    struct pa_bluez4_hook_uuid_data uuiddata;
+
+                    dbus_message_iter_get_basic(&ai, &value);
+
+                    if (pa_bluez4_uuid_has(d->uuids, value)) {
+                        dbus_message_iter_next(&ai);
+                        continue;
+                    }
+
+                    node = uuid_new(value);
+                    PA_LLIST_PREPEND(pa_bluez4_uuid, d->uuids, node);
+
+                    uuiddata.device = d;
+                    uuiddata.uuid = value;
+                    pa_hook_fire(&d->discovery->hooks[PA_BLUEZ4_HOOK_DEVICE_UUID_ADDED], &uuiddata);
+
+                    /* Vudentz said the interfaces are here when the UUIDs are announced */
+                    if (strcasecmp(HSP_AG_UUID, value) == 0 || strcasecmp(HFP_AG_UUID, value) == 0) {
+                        pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.HandsfreeGateway",
+                                                                      "GetProperties"));
+                        send_and_add_to_pending(d->discovery, m, get_properties_reply, d);
+                        has_audio = true;
+                    } else if (strcasecmp(HSP_HS_UUID, value) == 0 || strcasecmp(HFP_HS_UUID, value) == 0) {
+                        pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.Headset",
+                                                                      "GetProperties"));
+                        send_and_add_to_pending(d->discovery, m, get_properties_reply, d);
+                        has_audio = true;
+                    } else if (strcasecmp(A2DP_SINK_UUID, value) == 0) {
+                        pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.AudioSink",
+                                                                      "GetProperties"));
+                        send_and_add_to_pending(d->discovery, m, get_properties_reply, d);
+                        has_audio = true;
+                    } else if (strcasecmp(A2DP_SOURCE_UUID, value) == 0) {
+                        pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.AudioSource",
+                                                                      "GetProperties"));
+                        send_and_add_to_pending(d->discovery, m, get_properties_reply, d);
+                        has_audio = true;
+                    }
+
+                    dbus_message_iter_next(&ai);
+                }
+
+                /* this might eventually be racy if .Audio is not there yet, but
+                   the State change will come anyway later, so this call is for
+                   cold-detection mostly */
+                if (has_audio) {
+                    pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->path, "org.bluez.Audio", "GetProperties"));
+                    send_and_add_to_pending(d->discovery, m, get_properties_reply, d);
+                }
+            }
+
+            break;
+        }
+    }
+
+    return 0;
+}
+
+static const char *transport_state_to_string(pa_bluez4_transport_state_t state) {
+    switch (state) {
+        case PA_BLUEZ4_TRANSPORT_STATE_DISCONNECTED:
+            return "disconnected";
+        case PA_BLUEZ4_TRANSPORT_STATE_IDLE:
+            return "idle";
+        case PA_BLUEZ4_TRANSPORT_STATE_PLAYING:
+            return "playing";
+    }
+
+    pa_assert_not_reached();
+}
+
+static int parse_audio_property(pa_bluez4_device *d, const char *interface, DBusMessageIter *i, bool is_property_change) {
+    pa_bluez4_transport *transport;
+    const char *key;
+    DBusMessageIter variant_i;
+    bool is_audio_interface;
+    pa_bluez4_profile_t p = PA_BLUEZ4_PROFILE_OFF;
+
+    pa_assert(d);
+    pa_assert(interface);
+    pa_assert(i);
+
+    if (!(is_audio_interface = pa_streq(interface, "org.bluez.Audio")))
+        if (profile_from_interface(interface, &p) < 0)
+            return 0; /* Interface not known so silently ignore property */
+
+    key = check_variant_property(i);
+    if (key == NULL)
+        return -1;
+
+    transport = p == PA_BLUEZ4_PROFILE_OFF ? NULL : d->transports[p];
+
+    dbus_message_iter_recurse(i, &variant_i);
+
+/*     pa_log_debug("Parsing property org.bluez.{Audio|AudioSink|AudioSource|Headset}.%s", key); */
+
+    switch (dbus_message_iter_get_arg_type(&variant_i)) {
+
+        case DBUS_TYPE_STRING: {
+
+            const char *value;
+            dbus_message_iter_get_basic(&variant_i, &value);
+
+            if (pa_streq(key, "State")) {
+                pa_bluez4_audio_state_t state = audio_state_from_string(value);
+                pa_bluez4_transport_state_t old_state;
+
+                pa_log_debug("Device %s interface %s property 'State' changed to value '%s'", d->path, interface, value);
+
+                if (state == PA_BLUEZ4_AUDIO_STATE_INVALID)
+                    return -1;
+
+                if (is_audio_interface) {
+                    d->audio_state = state;
+                    break;
+                }
+
+                pa_assert(p != PA_BLUEZ4_PROFILE_OFF);
+
+                d->profile_state[p] = state;
+
+                if (!transport)
+                    break;
+
+                old_state = transport->state;
+                transport->state = audio_state_to_transport_state(state);
+
+                if (transport->state != old_state) {
+                    pa_log_debug("Transport %s (profile %s) changed state from %s to %s.", transport->path,
+                                 pa_bluez4_profile_to_string(transport->profile), transport_state_to_string(old_state),
+                                 transport_state_to_string(transport->state));
+
+                    pa_hook_fire(&d->discovery->hooks[PA_BLUEZ4_HOOK_TRANSPORT_STATE_CHANGED], transport);
+                }
+            }
+
+            break;
+        }
+
+        case DBUS_TYPE_UINT16: {
+            uint16_t value;
+
+            dbus_message_iter_get_basic(&variant_i, &value);
+
+            if (pa_streq(key, "MicrophoneGain")) {
+                uint16_t gain;
+
+                pa_log_debug("dbus: property '%s' changed to value '%u'", key, value);
+
+                if (!transport) {
+                    pa_log("Volume change does not have an associated transport");
+                    return -1;
+                }
+
+                if ((gain = PA_MIN(value, HSP_MAX_GAIN)) == transport->microphone_gain)
+                    break;
+
+                transport->microphone_gain = gain;
+                pa_hook_fire(&d->discovery->hooks[PA_BLUEZ4_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED], transport);
+            } else if (pa_streq(key, "SpeakerGain")) {
+                uint16_t gain;
+
+                pa_log_debug("dbus: property '%s' changed to value '%u'", key, value);
+
+                if (!transport) {
+                    pa_log("Volume change does not have an associated transport");
+                    return -1;
+                }
+
+                if ((gain = PA_MIN(value, HSP_MAX_GAIN)) == transport->speaker_gain)
+                    break;
+
+                transport->speaker_gain = gain;
+                pa_hook_fire(&d->discovery->hooks[PA_BLUEZ4_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED], transport);
+            }
+
+            break;
+        }
+    }
+
+    return 0;
+}
+
+static void run_callback(pa_bluez4_device *d, bool dead) {
+    pa_assert(d);
+
+    if (d->device_info_valid != 1)
+        return;
+
+    d->dead = dead;
+    pa_hook_fire(&d->discovery->hooks[PA_BLUEZ4_HOOK_DEVICE_CONNECTION_CHANGED], d);
+}
+
+static void remove_all_devices(pa_bluez4_discovery *y) {
+    pa_bluez4_device *d;
+
+    pa_assert(y);
+
+    while ((d = pa_hashmap_steal_first(y->devices))) {
+        run_callback(d, true);
+        device_free(d);
+    }
+}
+
+static pa_bluez4_device *found_device(pa_bluez4_discovery *y, const char* path) {
+    DBusMessage *m;
+    pa_bluez4_device *d;
+
+    pa_assert(y);
+    pa_assert(path);
+
+    d = pa_hashmap_get(y->devices, path);
+    if (d)
+        return d;
+
+    d = device_new(y, path);
+
+    pa_hashmap_put(y->devices, d->path, d);
+
+    pa_assert_se(m = dbus_message_new_method_call("org.bluez", path, "org.bluez.Device", "GetProperties"));
+    send_and_add_to_pending(y, m, get_properties_reply, d);
+
+    /* Before we read the other properties (Audio, AudioSink, AudioSource,
+     * Headset) we wait that the UUID is read */
+    return d;
+}
+
+static void get_properties_reply(DBusPendingCall *pending, void *userdata) {
+    DBusMessage *r;
+    DBusMessageIter arg_i, element_i;
+    pa_dbus_pending *p;
+    pa_bluez4_device *d;
+    pa_bluez4_discovery *y;
+    int valid;
+    bool old_any_connected;
+
+    pa_assert_se(p = userdata);
+    pa_assert_se(y = p->context_data);
+    pa_assert_se(r = dbus_pending_call_steal_reply(pending));
+
+/*     pa_log_debug("Got %s.GetProperties response for %s", */
+/*                  dbus_message_get_interface(p->message), */
+/*                  dbus_message_get_path(p->message)); */
+
+    /* We don't use p->call_data here right-away since the device
+     * might already be invalidated at this point */
+
+    if (dbus_message_has_interface(p->message, "org.bluez.Manager") ||
+        dbus_message_has_interface(p->message, "org.bluez.Adapter"))
+        d = NULL;
+    else if (!(d = pa_hashmap_get(y->devices, dbus_message_get_path(p->message)))) {
+        pa_log_warn("Received GetProperties() reply from unknown device: %s (device removed?)", dbus_message_get_path(p->message));
+        goto finish2;
+    }
+
+    pa_assert(p->call_data == d);
+
+    if (d != NULL)
+        old_any_connected = pa_bluez4_device_any_audio_connected(d);
+
+    valid = dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR ? -1 : 1;
+
+    if (dbus_message_is_method_call(p->message, "org.bluez.Device", "GetProperties"))
+        d->device_info_valid = valid;
+
+    if (dbus_message_is_error(r, DBUS_ERROR_SERVICE_UNKNOWN)) {
+        pa_log_debug("Bluetooth daemon is apparently not available.");
+        remove_all_devices(y);
+        goto finish2;
+    }
+
+    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
+        pa_log("%s.GetProperties() failed: %s: %s", dbus_message_get_interface(p->message), dbus_message_get_error_name(r),
+               pa_dbus_get_error_message(r));
+        goto finish;
+    }
+
+    if (!dbus_message_iter_init(r, &arg_i)) {
+        pa_log("GetProperties reply has no arguments.");
+        goto finish;
+    }
+
+    if (dbus_message_iter_get_arg_type(&arg_i) != DBUS_TYPE_ARRAY) {
+        pa_log("GetProperties argument is not an array.");
+        goto finish;
+    }
+
+    dbus_message_iter_recurse(&arg_i, &element_i);
+    while (dbus_message_iter_get_arg_type(&element_i) != DBUS_TYPE_INVALID) {
+
+        if (dbus_message_iter_get_arg_type(&element_i) == DBUS_TYPE_DICT_ENTRY) {
+            DBusMessageIter dict_i;
+
+            dbus_message_iter_recurse(&element_i, &dict_i);
+
+            if (dbus_message_has_interface(p->message, "org.bluez.Manager")) {
+                if (parse_manager_property(y, &dict_i, false) < 0)
+                    goto finish;
+
+            } else if (dbus_message_has_interface(p->message, "org.bluez.Adapter")) {
+                if (parse_adapter_property(y, &dict_i, false) < 0)
+                    goto finish;
+
+            } else if (dbus_message_has_interface(p->message, "org.bluez.Device")) {
+                if (parse_device_property(d, &dict_i, false) < 0)
+                    goto finish;
+
+            } else if (parse_audio_property(d, dbus_message_get_interface(p->message), &dict_i, false) < 0)
+                goto finish;
+
+        }
+
+        dbus_message_iter_next(&element_i);
+    }
+
+finish:
+    if (d != NULL && old_any_connected != pa_bluez4_device_any_audio_connected(d))
+        run_callback(d, false);
+
+finish2:
+    dbus_message_unref(r);
+
+    PA_LLIST_REMOVE(pa_dbus_pending, y->pending, p);
+    pa_dbus_pending_free(p);
+}
+
+static pa_dbus_pending* send_and_add_to_pending(pa_bluez4_discovery *y, DBusMessage *m, DBusPendingCallNotifyFunction func,
+                                                void *call_data) {
+    pa_dbus_pending *p;
+    DBusPendingCall *call;
+
+    pa_assert(y);
+    pa_assert(m);
+
+    pa_assert_se(dbus_connection_send_with_reply(pa_dbus_connection_get(y->connection), m, &call, -1));
+
+    p = pa_dbus_pending_new(pa_dbus_connection_get(y->connection), m, call, y, call_data);
+    PA_LLIST_PREPEND(pa_dbus_pending, y->pending, p);
+    dbus_pending_call_set_notify(call, func, p, NULL);
+
+    return p;
+}
+
+static void register_endpoint_reply(DBusPendingCall *pending, void *userdata) {
+    DBusMessage *r;
+    pa_dbus_pending *p;
+    pa_bluez4_discovery *y;
+    char *endpoint;
+
+    pa_assert(pending);
+    pa_assert_se(p = userdata);
+    pa_assert_se(y = p->context_data);
+    pa_assert_se(endpoint = p->call_data);
+    pa_assert_se(r = dbus_pending_call_steal_reply(pending));
+
+    if (dbus_message_is_error(r, DBUS_ERROR_SERVICE_UNKNOWN)) {
+        pa_log_debug("Bluetooth daemon is apparently not available.");
+        remove_all_devices(y);
+        goto finish;
+    }
+
+    if (dbus_message_is_error(r, PA_BLUEZ4_ERROR_NOT_SUPPORTED)) {
+        pa_log_info("Couldn't register endpoint %s, because BlueZ is configured to disable the endpoint type.", endpoint);
+        goto finish;
+    }
+
+    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
+        pa_log("org.bluez.Media.RegisterEndpoint() failed: %s: %s", dbus_message_get_error_name(r),
+               pa_dbus_get_error_message(r));
+        goto finish;
+    }
+
+finish:
+    dbus_message_unref(r);
+
+    PA_LLIST_REMOVE(pa_dbus_pending, y->pending, p);
+    pa_dbus_pending_free(p);
+
+    pa_xfree(endpoint);
+}
+
+static void register_endpoint(pa_bluez4_discovery *y, const char *path, const char *endpoint, const char *uuid) {
+    DBusMessage *m;
+    DBusMessageIter i, d;
+    uint8_t codec = 0;
+
+    pa_log_debug("Registering %s on adapter %s.", endpoint, path);
+
+    pa_assert_se(m = dbus_message_new_method_call("org.bluez", path, "org.bluez.Media", "RegisterEndpoint"));
+
+    dbus_message_iter_init_append(m, &i);
+
+    dbus_message_iter_append_basic(&i, DBUS_TYPE_OBJECT_PATH, &endpoint);
+
+    dbus_message_iter_open_container(&i, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+                                    DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+                                    &d);
+
+    pa_dbus_append_basic_variant_dict_entry(&d, "UUID", DBUS_TYPE_STRING, &uuid);
+
+    pa_dbus_append_basic_variant_dict_entry(&d, "Codec", DBUS_TYPE_BYTE, &codec);
+
+    if (pa_streq(uuid, HFP_AG_UUID) || pa_streq(uuid, HFP_HS_UUID)) {
+        uint8_t capability = 0;
+        pa_dbus_append_basic_array_variant_dict_entry(&d, "Capabilities", DBUS_TYPE_BYTE, &capability, 1);
+    } else {
+        pa_log_debug("register_endpoint: codec=%d[%s]", codec, codec==A2DP_CODEC_SBC ? "A2DP_CODEC_SBC" : codec==A2DP_CODEC_NON_A2DP ? "A2DP_CODEC_NON_A2DP" : "unknown");
+        if (codec == A2DP_CODEC_SBC) {
+        a2dp_sbc_t capabilities;
+
+        capabilities.channel_mode = SBC_CHANNEL_MODE_MONO | SBC_CHANNEL_MODE_DUAL_CHANNEL |
+                                    SBC_CHANNEL_MODE_STEREO | SBC_CHANNEL_MODE_JOINT_STEREO;
+        capabilities.frequency = SBC_SAMPLING_FREQ_16000 | SBC_SAMPLING_FREQ_32000 |
+                                 SBC_SAMPLING_FREQ_44100 | SBC_SAMPLING_FREQ_48000;
+        capabilities.allocation_method = SBC_ALLOCATION_SNR | SBC_ALLOCATION_LOUDNESS;
+        capabilities.subbands = SBC_SUBBANDS_4 | SBC_SUBBANDS_8;
+        capabilities.block_length = SBC_BLOCK_LENGTH_4 | SBC_BLOCK_LENGTH_8 |
+                                    SBC_BLOCK_LENGTH_12 | SBC_BLOCK_LENGTH_16;
+        capabilities.min_bitpool = MIN_BITPOOL;
+        capabilities.max_bitpool = MAX_BITPOOL;
+
+        pa_dbus_append_basic_array_variant_dict_entry(&d, "Capabilities", DBUS_TYPE_BYTE, &capabilities, sizeof(capabilities));
+        } else if (codec == A2DP_CODEC_NON_A2DP ) {
+          /* aptx */
+            a2dp_aptx_t capabilities;
+
+            capabilities.vendor_id[0] = APTX_VENDOR_ID0;
+            capabilities.vendor_id[1] = APTX_VENDOR_ID1;
+            capabilities.vendor_id[2] = APTX_VENDOR_ID2;
+            capabilities.vendor_id[3] = APTX_VENDOR_ID3;
+
+            capabilities.codec_id[0] = APTX_CODEC_ID0;
+            capabilities.codec_id[1] = APTX_CODEC_ID1;
+
+            capabilities.channel_mode= APTX_CHANNEL_MODE_STEREO;
+            capabilities.frequency= APTX_SAMPLING_FREQ_44100;
+
+            pa_dbus_append_basic_array_variant_dict_entry(&d, "Capabilities", DBUS_TYPE_BYTE, &capabilities, sizeof(capabilities));
+        }
+    }
+
+    dbus_message_iter_close_container(&i, &d);
+
+    send_and_add_to_pending(y, m, register_endpoint_reply, pa_xstrdup(endpoint));
+}
+
+static void found_adapter(pa_bluez4_discovery *y, const char *path) {
+
+    DBusMessage *m;
+
+    pa_assert_se(m = dbus_message_new_method_call("org.bluez", path, "org.bluez.Adapter", "GetProperties"));
+    send_and_add_to_pending(y, m, get_properties_reply, NULL);
+
+    register_endpoint(y, path, ENDPOINT_PATH_HFP_AG, HFP_AG_UUID);
+    register_endpoint(y, path, ENDPOINT_PATH_HFP_HS, HFP_HS_UUID);
+    register_endpoint(y, path, ENDPOINT_PATH_A2DP_SOURCE, A2DP_SOURCE_UUID);
+    register_endpoint(y, path, ENDPOINT_PATH_A2DP_SINK, A2DP_SINK_UUID);
+#ifdef BLUETOOTH_APTX_SUPPORT
+    if (aptx_handle)
+        register_endpoint(y, path, ENDPOINT_PATH_A2DP_APTX_SOURCE, A2DP_SOURCE_UUID);
+#endif
+}
+
+static void list_adapters(pa_bluez4_discovery *y) {
+    DBusMessage *m;
+    pa_assert(y);
+
+    pa_assert_se(m = dbus_message_new_method_call("org.bluez", "/", "org.bluez.Manager", "GetProperties"));
+    send_and_add_to_pending(y, m, get_properties_reply, NULL);
+}
+
+static int transport_parse_property(pa_bluez4_transport *t, DBusMessageIter *i) {
+    const char *key;
+    DBusMessageIter variant_i;
+
+    key = check_variant_property(i);
+    if (key == NULL)
+        return -1;
+
+    dbus_message_iter_recurse(i, &variant_i);
+
+    switch (dbus_message_iter_get_arg_type(&variant_i)) {
+
+        case DBUS_TYPE_BOOLEAN: {
+
+            dbus_bool_t value;
+            dbus_message_iter_get_basic(&variant_i, &value);
+
+            if (pa_streq(key, "NREC") && t->nrec != value) {
+                t->nrec = value;
+                pa_log_debug("Transport %s: Property 'NREC' changed to %s.", t->path, t->nrec ? "True" : "False");
+                pa_hook_fire(&t->device->discovery->hooks[PA_BLUEZ4_HOOK_TRANSPORT_NREC_CHANGED], t);
+            }
+
+            break;
+         }
+    }
+
+    return 0;
+}
+
+static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *userdata) {
+    DBusError err;
+    pa_bluez4_discovery *y;
+
+    pa_assert(bus);
+    pa_assert(m);
+
+    pa_assert_se(y = userdata);
+
+    dbus_error_init(&err);
+
+    pa_log_debug("dbus: interface=%s, path=%s, member=%s\n",
+            dbus_message_get_interface(m),
+            dbus_message_get_path(m),
+            dbus_message_get_member(m));
+
+    if (dbus_message_is_signal(m, "org.bluez.Adapter", "DeviceRemoved")) {
+        const char *path;
+        pa_bluez4_device *d;
+
+        if (!dbus_message_get_args(m, &err, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) {
+            pa_log("Failed to parse org.bluez.Adapter.DeviceRemoved: %s", err.message);
+            goto fail;
+        }
+
+        pa_log_debug("Device %s removed", path);
+
+        if ((d = pa_hashmap_remove(y->devices, path))) {
+            run_callback(d, true);
+            device_free(d);
+        }
+
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    } else if (dbus_message_is_signal(m, "org.bluez.Adapter", "DeviceCreated")) {
+        const char *path;
+
+        if (!dbus_message_get_args(m, &err, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) {
+            pa_log("Failed to parse org.bluez.Adapter.DeviceCreated: %s", err.message);
+            goto fail;
+        }
+
+        pa_log_debug("Device %s created", path);
+
+        found_device(y, path);
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    } else if (dbus_message_is_signal(m, "org.bluez.Manager", "AdapterAdded")) {
+        const char *path;
+
+        if (!dbus_message_get_args(m, &err, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) {
+            pa_log("Failed to parse org.bluez.Manager.AdapterAdded: %s", err.message);
+            goto fail;
+        }
+
+        if (!y->adapters_listed) {
+            pa_log_debug("Ignoring 'AdapterAdded' because initial adapter list has not been received yet.");
+            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+        }
+
+        pa_log_debug("Adapter %s created", path);
+
+        found_adapter(y, path);
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    } else if (dbus_message_is_signal(m, "org.bluez.Audio", "PropertyChanged") ||
+               dbus_message_is_signal(m, "org.bluez.Headset", "PropertyChanged") ||
+               dbus_message_is_signal(m, "org.bluez.AudioSink", "PropertyChanged") ||
+               dbus_message_is_signal(m, "org.bluez.AudioSource", "PropertyChanged") ||
+               dbus_message_is_signal(m, "org.bluez.HandsfreeGateway", "PropertyChanged") ||
+               dbus_message_is_signal(m, "org.bluez.Device", "PropertyChanged")) {
+
+        pa_bluez4_device *d;
+
+        if ((d = pa_hashmap_get(y->devices, dbus_message_get_path(m)))) {
+            DBusMessageIter arg_i;
+            bool old_any_connected = pa_bluez4_device_any_audio_connected(d);
+
+            if (!dbus_message_iter_init(m, &arg_i)) {
+                pa_log("Failed to parse PropertyChanged for device %s", d->path);
+                goto fail;
+            }
+
+            if (dbus_message_has_interface(m, "org.bluez.Device")) {
+                if (parse_device_property(d, &arg_i, true) < 0)
+                    goto fail;
+
+            } else if (parse_audio_property(d, dbus_message_get_interface(m), &arg_i, true) < 0)
+                goto fail;
+
+            if (old_any_connected != pa_bluez4_device_any_audio_connected(d))
+                run_callback(d, false);
+        }
+
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    } else if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged")) {
+        const char *name, *old_owner, *new_owner;
+
+        if (!dbus_message_get_args(m, &err,
+                                   DBUS_TYPE_STRING, &name,
+                                   DBUS_TYPE_STRING, &old_owner,
+                                   DBUS_TYPE_STRING, &new_owner,
+                                   DBUS_TYPE_INVALID)) {
+            pa_log("Failed to parse org.freedesktop.DBus.NameOwnerChanged: %s", err.message);
+            goto fail;
+        }
+
+        if (pa_streq(name, "org.bluez")) {
+            if (old_owner && *old_owner) {
+                pa_log_debug("Bluetooth daemon disappeared.");
+                remove_all_devices(y);
+                y->adapters_listed = false;
+            }
+
+            if (new_owner && *new_owner) {
+                pa_log_debug("Bluetooth daemon appeared.");
+                list_adapters(y);
+            }
+        }
+
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+    } else if (dbus_message_is_signal(m, "org.bluez.MediaTransport", "PropertyChanged")) {
+        pa_bluez4_transport *t;
+        DBusMessageIter arg_i;
+
+        if (!(t = pa_hashmap_get(y->transports, dbus_message_get_path(m))))
+            goto fail;
+
+        if (!dbus_message_iter_init(m, &arg_i)) {
+            pa_log("Failed to parse PropertyChanged for transport %s", t->path);
+            goto fail;
+        }
+
+        if (transport_parse_property(t, &arg_i) < 0)
+            goto fail;
+
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+    }
+
+fail:
+    dbus_error_free(&err);
+
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+pa_bluez4_device* pa_bluez4_discovery_get_by_address(pa_bluez4_discovery *y, const char* address) {
+    pa_bluez4_device *d;
+    void *state = NULL;
+
+    pa_assert(y);
+    pa_assert(PA_REFCNT_VALUE(y) > 0);
+    pa_assert(address);
+
+    while ((d = pa_hashmap_iterate(y->devices, &state, NULL)))
+        if (pa_streq(d->address, address))
+            return d->device_info_valid == 1 ? d : NULL;
+
+    return NULL;
+}
+
+pa_bluez4_device* pa_bluez4_discovery_get_by_path(pa_bluez4_discovery *y, const char* path) {
+    pa_bluez4_device *d;
+
+    pa_assert(y);
+    pa_assert(PA_REFCNT_VALUE(y) > 0);
+    pa_assert(path);
+
+    if ((d = pa_hashmap_get(y->devices, path)))
+        if (d->device_info_valid == 1)
+            return d;
+
+    return NULL;
+}
+
+bool pa_bluez4_device_any_audio_connected(const pa_bluez4_device *d) {
+    unsigned i;
+
+    pa_assert(d);
+
+    if (d->dead || d->device_info_valid != 1)
+        return false;
+
+    if (d->audio_state == PA_BLUEZ4_AUDIO_STATE_INVALID)
+        return false;
+
+    /* Make sure audio_state is *not* in CONNECTING state before we fire the
+     * hook to report the new device state. This is actually very important in
+     * order to make module-card-restore work well with headsets: if the headset
+     * supports both HSP and A2DP, one of those profiles is connected first and
+     * then the other, and lastly the Audio interface becomes connected.
+     * Checking only audio_state means that this function will return false at
+     * the time when only the first connection has been made. This is good,
+     * because otherwise, if the first connection is for HSP and we would
+     * already load a new device module instance, and module-card-restore tries
+     * to restore the A2DP profile, that would fail because A2DP is not yet
+     * connected. Waiting until the Audio interface gets connected means that
+     * both headset profiles will be connected when the device module is
+     * loaded. */
+    if (d->audio_state == PA_BLUEZ4_AUDIO_STATE_CONNECTING)
+        return false;
+
+    for (i = 0; i < PA_BLUEZ4_PROFILE_COUNT; i++)
+        if (d->transports[i] && d->transports[i]->state != PA_BLUEZ4_TRANSPORT_STATE_DISCONNECTED)
+            return true;
+
+    return false;
+}
+
+int pa_bluez4_transport_acquire(pa_bluez4_transport *t, bool optional, size_t *imtu, size_t *omtu) {
+    const char *accesstype = "rw";
+    DBusMessage *m, *r;
+    DBusError err;
+    int ret;
+    uint16_t i, o;
+
+    pa_assert(t);
+    pa_assert(t->device);
+    pa_assert(t->device->discovery);
+
+    if (optional) {
+        /* FIXME: we are trying to acquire the transport only if the stream is
+           playing, without actually initiating the stream request from our side
+           (which is typically undesireable specially for hfgw use-cases.
+           However this approach is racy, since the stream could have been
+           suspended in the meantime, so we can't really guarantee that the
+           stream will not be requested until BlueZ's API supports this
+           atomically. */
+        if (t->state < PA_BLUEZ4_TRANSPORT_STATE_PLAYING) {
+            pa_log_info("Failed optional acquire of transport %s", t->path);
+            return -1;
+        }
+    }
+
+    dbus_error_init(&err);
+
+    pa_assert_se(m = dbus_message_new_method_call(t->owner, t->path, "org.bluez.MediaTransport", "Acquire"));
+    pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, &accesstype, DBUS_TYPE_INVALID));
+    r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t->device->discovery->connection), m, -1, &err);
+
+    if (!r) {
+        dbus_error_free(&err);
+        return -1;
+    }
+
+    if (!dbus_message_get_args(r, &err, DBUS_TYPE_UNIX_FD, &ret, DBUS_TYPE_UINT16, &i, DBUS_TYPE_UINT16, &o,
+                               DBUS_TYPE_INVALID)) {
+        pa_log("Failed to parse org.bluez.MediaTransport.Acquire(): %s", err.message);
+        ret = -1;
+        dbus_error_free(&err);
+        goto fail;
+    }
+
+    if (imtu)
+        *imtu = i;
+
+    if (omtu)
+        *omtu = o;
+
+fail:
+    dbus_message_unref(r);
+    return ret;
+}
+
+void pa_bluez4_transport_release(pa_bluez4_transport *t) {
+    const char *accesstype = "rw";
+    DBusMessage *m;
+    DBusError err;
+
+    pa_assert(t);
+    pa_assert(t->device);
+    pa_assert(t->device->discovery);
+
+    dbus_error_init(&err);
+
+    pa_assert_se(m = dbus_message_new_method_call(t->owner, t->path, "org.bluez.MediaTransport", "Release"));
+    pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, &accesstype, DBUS_TYPE_INVALID));
+    dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t->device->discovery->connection), m, -1, &err);
+
+    if (dbus_error_is_set(&err)) {
+        pa_log("Failed to release transport %s: %s", t->path, err.message);
+        dbus_error_free(&err);
+    } else
+        pa_log_info("Transport %s released", t->path);
+}
+
+static void set_property(pa_bluez4_discovery *y, const char *bus, const char *path, const char *interface,
+                         const char *prop_name, int prop_type, void *prop_value) {
+    DBusMessage *m;
+    DBusMessageIter i;
+
+    pa_assert(y);
+    pa_assert(path);
+    pa_assert(interface);
+    pa_assert(prop_name);
+
+    pa_assert_se(m = dbus_message_new_method_call(bus, path, interface, "SetProperty"));
+    dbus_message_iter_init_append(m, &i);
+    dbus_message_iter_append_basic(&i, DBUS_TYPE_STRING, &prop_name);
+    pa_dbus_append_basic_variant(&i, prop_type, prop_value);
+
+    dbus_message_set_no_reply(m, true);
+    pa_assert_se(dbus_connection_send(pa_dbus_connection_get(y->connection), m, NULL));
+    dbus_message_unref(m);
+}
+
+void pa_bluez4_transport_set_microphone_gain(pa_bluez4_transport *t, uint16_t value) {
+    dbus_uint16_t gain = PA_MIN(value, HSP_MAX_GAIN);
+
+    pa_assert(t);
+    pa_assert(t->profile == PA_BLUEZ4_PROFILE_HSP);
+
+    set_property(t->device->discovery, "org.bluez", t->device->path, "org.bluez.Headset",
+                 "MicrophoneGain", DBUS_TYPE_UINT16, &gain);
+}
+
+void pa_bluez4_transport_set_speaker_gain(pa_bluez4_transport *t, uint16_t value) {
+    dbus_uint16_t gain = PA_MIN(value, HSP_MAX_GAIN);
+
+    pa_assert(t);
+    pa_assert(t->profile == PA_BLUEZ4_PROFILE_HSP);
+
+    set_property(t->device->discovery, "org.bluez", t->device->path, "org.bluez.Headset",
+                 "SpeakerGain", DBUS_TYPE_UINT16, &gain);
+}
+
+static int setup_dbus(pa_bluez4_discovery *y) {
+    DBusError err;
+
+    dbus_error_init(&err);
+
+    if (!(y->connection = pa_dbus_bus_get(y->core, DBUS_BUS_SYSTEM, &err))) {
+        pa_log("Failed to get D-Bus connection: %s", err.message);
+        dbus_error_free(&err);
+        return -1;
+    }
+
+    return 0;
+}
+
+static pa_bluez4_transport *transport_new(pa_bluez4_device *d, const char *owner, const char *path, pa_bluez4_profile_t p,
+                                             const uint8_t *config, int size) {
+    pa_bluez4_transport *t;
+
+    t = pa_xnew0(pa_bluez4_transport, 1);
+    t->device = d;
+    t->owner = pa_xstrdup(owner);
+    t->path = pa_xstrdup(path);
+    t->profile = p;
+    t->config_size = size;
+
+    if (size > 0) {
+        t->config = pa_xnew(uint8_t, size);
+        memcpy(t->config, config, size);
+    }
+
+    t->state = audio_state_to_transport_state(d->profile_state[p]);
+
+    return t;
+}
+
+static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage *m, void *userdata) {
+    pa_bluez4_discovery *y = userdata;
+    pa_bluez4_device *d;
+    pa_bluez4_transport *t;
+    const char *sender, *path, *dev_path = NULL, *uuid = NULL;
+    uint8_t *config = NULL;
+    int size = 0;
+    bool nrec = false;
+    pa_bluez4_profile_t p;
+    DBusMessageIter args, props;
+    DBusMessage *r;
+    bool old_any_connected;
+
+    if (!dbus_message_iter_init(m, &args) || !pa_streq(dbus_message_get_signature(m), "oa{sv}")) {
+        pa_log("Invalid signature for method SetConfiguration");
+        goto fail2;
+    }
+
+    dbus_message_iter_get_basic(&args, &path);
+
+    if (pa_hashmap_get(y->transports, path)) {
+        pa_log("org.bluez.MediaEndpoint.SetConfiguration: Transport %s is already configured.", path);
+        goto fail2;
+    }
+
+    pa_assert_se(dbus_message_iter_next(&args));
+
+    dbus_message_iter_recurse(&args, &props);
+    if (dbus_message_iter_get_arg_type(&props) != DBUS_TYPE_DICT_ENTRY)
+        goto fail;
+
+    /* Read transport properties */
+    while (dbus_message_iter_get_arg_type(&props) == DBUS_TYPE_DICT_ENTRY) {
+        const char *key;
+        DBusMessageIter value, entry;
+        int var;
+
+        dbus_message_iter_recurse(&props, &entry);
+        dbus_message_iter_get_basic(&entry, &key);
+
+        dbus_message_iter_next(&entry);
+        dbus_message_iter_recurse(&entry, &value);
+
+        var = dbus_message_iter_get_arg_type(&value);
+
+        if (strcasecmp(key, "UUID") == 0) {
+            if (var != DBUS_TYPE_STRING)
+                goto fail;
+
+            dbus_message_iter_get_basic(&value, &uuid);
+        } else if (strcasecmp(key, "Device") == 0) {
+            if (var != DBUS_TYPE_OBJECT_PATH)
+                goto fail;
+
+            dbus_message_iter_get_basic(&value, &dev_path);
+        } else if (strcasecmp(key, "NREC") == 0) {
+            dbus_bool_t tmp_boolean;
+            if (var != DBUS_TYPE_BOOLEAN)
+                goto fail;
+
+            dbus_message_iter_get_basic(&value, &tmp_boolean);
+            nrec = tmp_boolean;
+        } else if (strcasecmp(key, "Configuration") == 0) {
+            DBusMessageIter array;
+            if (var != DBUS_TYPE_ARRAY)
+                goto fail;
+
+            dbus_message_iter_recurse(&value, &array);
+            dbus_message_iter_get_fixed_array(&array, &config, &size);
+        }
+
+        dbus_message_iter_next(&props);
+    }
+
+    d = found_device(y, dev_path);
+    if (!d)
+        goto fail;
+
+    if (dbus_message_has_path(m, ENDPOINT_PATH_HFP_AG))
+        p = PA_BLUEZ4_PROFILE_HSP;
+    else if (dbus_message_has_path(m, ENDPOINT_PATH_HFP_HS))
+        p = PA_BLUEZ4_PROFILE_HFGW;
+#ifdef BLUETOOTH_APTX_SUPPORT
+    else if (dbus_message_has_path(m, ENDPOINT_PATH_A2DP_SOURCE) || dbus_message_has_path(m, ENDPOINT_PATH_A2DP_APTX_SOURCE))
+#else
+    else if (dbus_message_has_path(m, ENDPOINT_PATH_A2DP_SOURCE))
+#endif
+        p = PA_BLUEZ4_PROFILE_A2DP;
+    else
+        p = PA_BLUEZ4_PROFILE_A2DP_SOURCE;
+
+    if (d->transports[p] != NULL) {
+        pa_log("Cannot configure transport %s because profile %d is already used", path, p);
+        goto fail2;
+    }
+
+    old_any_connected = pa_bluez4_device_any_audio_connected(d);
+
+    sender = dbus_message_get_sender(m);
+
+    t = transport_new(d, sender, path, p, config, size);
+    if (nrec)
+        t->nrec = nrec;
+
+    d->transports[p] = t;
+    pa_assert_se(pa_hashmap_put(y->transports, t->path, t) >= 0);
+
+    pa_log_debug("Transport %s profile %d available", t->path, t->profile);
+
+    pa_assert_se(r = dbus_message_new_method_return(m));
+    pa_assert_se(dbus_connection_send(pa_dbus_connection_get(y->connection), r, NULL));
+    dbus_message_unref(r);
+
+    if (old_any_connected != pa_bluez4_device_any_audio_connected(d))
+        run_callback(d, false);
+
+    return NULL;
+
+fail:
+    pa_log("org.bluez.MediaEndpoint.SetConfiguration: invalid arguments");
+
+fail2:
+    pa_assert_se(r = dbus_message_new_error(m, "org.bluez.MediaEndpoint.Error.InvalidArguments",
+                                            "Unable to set configuration"));
+    return r;
+}
+
+static DBusMessage *endpoint_clear_configuration(DBusConnection *c, DBusMessage *m, void *userdata) {
+    pa_bluez4_discovery *y = userdata;
+    pa_bluez4_transport *t;
+    DBusMessage *r;
+    DBusError e;
+    const char *path;
+
+    dbus_error_init(&e);
+
+    if (!dbus_message_get_args(m, &e, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) {
+        pa_log("org.bluez.MediaEndpoint.ClearConfiguration: %s", e.message);
+        dbus_error_free(&e);
+        goto fail;
+    }
+
+    if ((t = pa_hashmap_get(y->transports, path))) {
+        bool old_any_connected = pa_bluez4_device_any_audio_connected(t->device);
+
+        pa_log_debug("Clearing transport %s profile %d", t->path, t->profile);
+        t->device->transports[t->profile] = NULL;
+        pa_hashmap_remove(y->transports, t->path);
+        t->state = PA_BLUEZ4_TRANSPORT_STATE_DISCONNECTED;
+        pa_hook_fire(&y->hooks[PA_BLUEZ4_HOOK_TRANSPORT_STATE_CHANGED], t);
+
+        if (old_any_connected != pa_bluez4_device_any_audio_connected(t->device))
+            run_callback(t->device, false);
+
+        transport_free(t);
+    }
+
+    pa_assert_se(r = dbus_message_new_method_return(m));
+
+    return r;
+
+fail:
+    pa_assert_se(r = dbus_message_new_error(m, "org.bluez.MediaEndpoint.Error.InvalidArguments",
+                                            "Unable to clear configuration"));
+    return r;
+}
+
+static uint8_t a2dp_default_bitpool(uint8_t freq, uint8_t mode) {
+
+    switch (freq) {
+        case SBC_SAMPLING_FREQ_16000:
+        case SBC_SAMPLING_FREQ_32000:
+            return 53;
+
+        case SBC_SAMPLING_FREQ_44100:
+
+            switch (mode) {
+                case SBC_CHANNEL_MODE_MONO:
+                case SBC_CHANNEL_MODE_DUAL_CHANNEL:
+                    return 31;
+
+                case SBC_CHANNEL_MODE_STEREO:
+                case SBC_CHANNEL_MODE_JOINT_STEREO:
+#if defined(__TIZEN_BT__) && defined(ADJUST_ANDROID_BITPOOL)
+                    return 35;
+#else
+                    return 53;
+#endif
+                default:
+                    pa_log_warn("Invalid channel mode %u", mode);
+                    return 53;
+            }
+
+        case SBC_SAMPLING_FREQ_48000:
+
+            switch (mode) {
+                case SBC_CHANNEL_MODE_MONO:
+                case SBC_CHANNEL_MODE_DUAL_CHANNEL:
+                    return 29;
+
+                case SBC_CHANNEL_MODE_STEREO:
+                case SBC_CHANNEL_MODE_JOINT_STEREO:
+                    return 51;
+
+                default:
+                    pa_log_warn("Invalid channel mode %u", mode);
+                    return 51;
+            }
+
+        default:
+            pa_log_warn("Invalid sampling freq %u", freq);
+            return 53;
+    }
+}
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+static DBusMessage *endpoint_select_configuration_for_aptx(DBusConnection *c, DBusMessage *m, void *userdata) {
+    a2dp_aptx_t *cap;
+    a2dp_aptx_t config;
+    uint8_t *pconf = (uint8_t *) &config;
+    int size;
+    DBusMessage *r;
+    DBusError e;
+
+    dbus_error_init(&e);
+
+    if (!dbus_message_get_args(m, &e, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &cap, &size, DBUS_TYPE_INVALID)) {
+        pa_log("org.bluez.MediaEndpoint.SelectConfiguration: %s", e.message);
+        dbus_error_free(&e);
+        goto fail;
+    }
+
+    pa_assert(size == sizeof(config));
+
+    memset(&config, 0, sizeof(config));
+
+    if (cap->vendor_id[0] == APTX_VENDOR_ID0 &&
+        cap->vendor_id[1] == APTX_VENDOR_ID1 &&
+        cap->vendor_id[2] == APTX_VENDOR_ID2 &&
+        cap->vendor_id[3] == APTX_VENDOR_ID3 &&
+         cap->codec_id[0] == APTX_CODEC_ID0  &&
+         cap->codec_id[1] == APTX_CODEC_ID1  )
+        pa_log_debug("A2DP_CODEC_NON_A2DP and this is APTX Codec");
+    else {
+        pa_log_debug("A2DP_CODEC_NON_A2DP but this is not APTX Codec");
+        goto fail;
+    }
+
+    memcpy(&config,cap, sizeof(config));
+
+/* The below code shuld be re-written by aptx */
+/* And we should configure pulseaudio freq */
+
+    if (cap->frequency & APTX_SAMPLING_FREQ_44100)
+        config.frequency = APTX_SAMPLING_FREQ_44100;
+    else if (cap->frequency & APTX_SAMPLING_FREQ_48000)
+        config.frequency = APTX_SAMPLING_FREQ_48000;
+    else if (cap->frequency & APTX_SAMPLING_FREQ_32000)
+        config.frequency = APTX_SAMPLING_FREQ_32000;
+    else if (cap->frequency & APTX_SAMPLING_FREQ_16000)
+        config.frequency = APTX_SAMPLING_FREQ_16000;
+    else {
+        pa_log_error("No aptx supported frequencies");
+        goto fail;
+    }
+
+    if (cap->channel_mode & APTX_CHANNEL_MODE_JOINT_STEREO)
+        config.channel_mode = APTX_CHANNEL_MODE_STEREO;
+    else if (cap->channel_mode & APTX_CHANNEL_MODE_STEREO)
+        config.channel_mode = APTX_CHANNEL_MODE_STEREO;
+    else if (cap->channel_mode & APTX_CHANNEL_MODE_DUAL_CHANNEL)
+        config.channel_mode = APTX_CHANNEL_MODE_STEREO;
+    else {
+        pa_log_error("No aptx supported channel modes");
+        goto fail;
+    }
+
+    pa_assert_se(r = dbus_message_new_method_return(m));
+
+    pa_assert_se(dbus_message_append_args(
+                                     r,
+                                     DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pconf, size,
+                                     DBUS_TYPE_INVALID));
+
+    return r;
+
+fail:
+    pa_assert_se(r = (dbus_message_new_error(m, "org.bluez.MediaEndpoint.Error.InvalidArguments",
+                                                        "Unable to select configuration")));
+    return r;
+}
+#endif
+
+static DBusMessage *endpoint_select_configuration(DBusConnection *c, DBusMessage *m, void *userdata) {
+    pa_bluez4_discovery *y = userdata;
+    a2dp_sbc_t *cap, config;
+    uint8_t *pconf = (uint8_t *) &config;
+    int i, size;
+    DBusMessage *r;
+    DBusError e;
+
+    static const struct {
+        uint32_t rate;
+        uint8_t cap;
+    } freq_table[] = {
+        { 16000U, SBC_SAMPLING_FREQ_16000 },
+        { 32000U, SBC_SAMPLING_FREQ_32000 },
+        { 44100U, SBC_SAMPLING_FREQ_44100 },
+        { 48000U, SBC_SAMPLING_FREQ_48000 }
+    };
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+    if (dbus_message_has_path(m, A2DP_APTX_SOURCE_ENDPOINT))
+        return endpoint_select_configuration_for_aptx(c ,m ,userdata);
+#endif
+    dbus_error_init(&e);
+
+    if (!dbus_message_get_args(m, &e, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &cap, &size, DBUS_TYPE_INVALID)) {
+        pa_log("org.bluez.MediaEndpoint.SelectConfiguration: %s", e.message);
+        dbus_error_free(&e);
+        goto fail;
+    }
+
+    if (dbus_message_has_path(m, ENDPOINT_PATH_HFP_AG) || dbus_message_has_path(m, ENDPOINT_PATH_HFP_HS))
+        goto done;
+
+    pa_assert(size == sizeof(config));
+
+    memset(&config, 0, sizeof(config));
+
+    /* Find the lowest freq that is at least as high as the requested
+     * sampling rate */
+    for (i = 0; (unsigned) i < PA_ELEMENTSOF(freq_table); i++)
+        if (freq_table[i].rate >= y->core->default_sample_spec.rate && (cap->frequency & freq_table[i].cap)) {
+            config.frequency = freq_table[i].cap;
+            break;
+        }
+
+    if ((unsigned) i == PA_ELEMENTSOF(freq_table)) {
+        for (--i; i >= 0; i--) {
+            if (cap->frequency & freq_table[i].cap) {
+                config.frequency = freq_table[i].cap;
+                break;
+            }
+        }
+
+        if (i < 0) {
+            pa_log("Not suitable sample rate");
+            goto fail;
+        }
+    }
+
+    pa_assert((unsigned) i < PA_ELEMENTSOF(freq_table));
+
+    if (y->core->default_sample_spec.channels <= 1) {
+        if (cap->channel_mode & SBC_CHANNEL_MODE_MONO)
+            config.channel_mode = SBC_CHANNEL_MODE_MONO;
+    }
+
+    if (y->core->default_sample_spec.channels >= 2) {
+        if (cap->channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO)
+            config.channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
+        else if (cap->channel_mode & SBC_CHANNEL_MODE_STEREO)
+            config.channel_mode = SBC_CHANNEL_MODE_STEREO;
+        else if (cap->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL)
+            config.channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
+        else if (cap->channel_mode & SBC_CHANNEL_MODE_MONO) {
+            config.channel_mode = SBC_CHANNEL_MODE_MONO;
+        } else {
+            pa_log("No supported channel modes");
+            goto fail;
+        }
+    }
+
+    if (cap->block_length & SBC_BLOCK_LENGTH_16)
+        config.block_length = SBC_BLOCK_LENGTH_16;
+    else if (cap->block_length & SBC_BLOCK_LENGTH_12)
+        config.block_length = SBC_BLOCK_LENGTH_12;
+    else if (cap->block_length & SBC_BLOCK_LENGTH_8)
+        config.block_length = SBC_BLOCK_LENGTH_8;
+    else if (cap->block_length & SBC_BLOCK_LENGTH_4)
+        config.block_length = SBC_BLOCK_LENGTH_4;
+    else {
+        pa_log_error("No supported block lengths");
+        goto fail;
+    }
+
+    if (cap->subbands & SBC_SUBBANDS_8)
+        config.subbands = SBC_SUBBANDS_8;
+    else if (cap->subbands & SBC_SUBBANDS_4)
+        config.subbands = SBC_SUBBANDS_4;
+    else {
+        pa_log_error("No supported subbands");
+        goto fail;
+    }
+
+    if (cap->allocation_method & SBC_ALLOCATION_LOUDNESS)
+        config.allocation_method = SBC_ALLOCATION_LOUDNESS;
+    else if (cap->allocation_method & SBC_ALLOCATION_SNR)
+        config.allocation_method = SBC_ALLOCATION_SNR;
+
+    config.min_bitpool = (uint8_t) PA_MAX(MIN_BITPOOL, cap->min_bitpool);
+    config.max_bitpool = (uint8_t) PA_MIN(a2dp_default_bitpool(config.frequency, config.channel_mode), cap->max_bitpool);
+
+done:
+    pa_assert_se(r = dbus_message_new_method_return(m));
+
+    pa_assert_se(dbus_message_append_args(
+                                     r,
+                                     DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pconf, size,
+                                     DBUS_TYPE_INVALID));
+
+    return r;
+
+fail:
+    pa_assert_se(r = dbus_message_new_error(m, "org.bluez.MediaEndpoint.Error.InvalidArguments",
+                                            "Unable to select configuration"));
+    return r;
+}
+
+static DBusHandlerResult endpoint_handler(DBusConnection *c, DBusMessage *m, void *userdata) {
+    struct pa_bluez4_discovery *y = userdata;
+    DBusMessage *r = NULL;
+    DBusError e;
+    const char *path, *interface, *member;
+
+    pa_assert(y);
+
+    path = dbus_message_get_path(m);
+    interface = dbus_message_get_interface(m);
+    member = dbus_message_get_member(m);
+
+    pa_log_debug("dbus: path=%s, interface=%s, member=%s", path, interface, member);
+
+    dbus_error_init(&e);
+
+    if (!pa_streq(path, ENDPOINT_PATH_A2DP_SOURCE) &&
+        !pa_streq(path, ENDPOINT_PATH_A2DP_SINK) &&
+        !pa_streq(path, ENDPOINT_PATH_HFP_AG) &&
+#ifdef BLUETOOTH_APTX_SUPPORT
+        !pa_streq(path, ENDPOINT_PATH_A2DP_APTX_SOURCE) &&
+#endif
+        !pa_streq(path, ENDPOINT_PATH_HFP_HS))
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
+        const char *xml = ENDPOINT_INTROSPECT_XML;
+
+        pa_assert_se(r = dbus_message_new_method_return(m));
+        pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID));
+
+    } else if (dbus_message_is_method_call(m, "org.bluez.MediaEndpoint", "SetConfiguration"))
+        r = endpoint_set_configuration(c, m, userdata);
+    else if (dbus_message_is_method_call(m, "org.bluez.MediaEndpoint", "SelectConfiguration"))
+        r = endpoint_select_configuration(c, m, userdata);
+    else if (dbus_message_is_method_call(m, "org.bluez.MediaEndpoint", "ClearConfiguration"))
+        r = endpoint_clear_configuration(c, m, userdata);
+    else
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    if (r) {
+        pa_assert_se(dbus_connection_send(pa_dbus_connection_get(y->connection), r, NULL));
+        dbus_message_unref(r);
+    }
+
+    return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+pa_bluez4_discovery* pa_bluez4_discovery_get(pa_core *c) {
+    DBusError err;
+    pa_bluez4_discovery *y;
+    DBusConnection *conn;
+    unsigned i;
+    static const DBusObjectPathVTable vtable_endpoint = {
+        .message_function = endpoint_handler,
+    };
+
+    pa_assert(c);
+
+    dbus_error_init(&err);
+
+    if ((y = pa_shared_get(c, "bluez4-discovery")))
+        return pa_bluez4_discovery_ref(y);
+
+    y = pa_xnew0(pa_bluez4_discovery, 1);
+    PA_REFCNT_INIT(y);
+    y->core = c;
+    y->devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    y->transports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    PA_LLIST_HEAD_INIT(pa_dbus_pending, y->pending);
+
+    for (i = 0; i < PA_BLUEZ4_HOOK_MAX; i++)
+        pa_hook_init(&y->hooks[i], y);
+
+    pa_shared_set(c, "bluez4-discovery", y);
+
+    if (setup_dbus(y) < 0)
+        goto fail;
+
+    conn = pa_dbus_connection_get(y->connection);
+
+    /* dynamic detection of bluetooth audio devices */
+    if (!dbus_connection_add_filter(conn, filter_cb, y, NULL)) {
+        pa_log_error("Failed to add filter function");
+        goto fail;
+    }
+
+    y->filter_added = true;
+
+    if (pa_dbus_add_matches(
+                conn, &err,
+                "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged'"
+                ",arg0='org.bluez'",
+                "type='signal',sender='org.bluez',interface='org.bluez.Manager',member='AdapterAdded'",
+                "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceRemoved'",
+                "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceCreated'",
+                "type='signal',sender='org.bluez',interface='org.bluez.Device',member='PropertyChanged'",
+                "type='signal',sender='org.bluez',interface='org.bluez.Audio',member='PropertyChanged'",
+                "type='signal',sender='org.bluez',interface='org.bluez.Headset',member='PropertyChanged'",
+                "type='signal',sender='org.bluez',interface='org.bluez.AudioSink',member='PropertyChanged'",
+                "type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged'",
+                "type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged'",
+                "type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged'",
+                NULL) < 0) {
+        pa_log("Failed to add D-Bus matches: %s", err.message);
+        goto fail;
+    }
+
+    pa_assert_se(dbus_connection_register_object_path(conn, ENDPOINT_PATH_HFP_AG, &vtable_endpoint, y));
+    pa_assert_se(dbus_connection_register_object_path(conn, ENDPOINT_PATH_HFP_HS, &vtable_endpoint, y));
+    pa_assert_se(dbus_connection_register_object_path(conn, ENDPOINT_PATH_A2DP_SOURCE, &vtable_endpoint, y));
+    pa_assert_se(dbus_connection_register_object_path(conn, ENDPOINT_PATH_A2DP_SINK, &vtable_endpoint, y));
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+    if (aptx_handle)
+        pa_assert_se(dbus_connection_register_object_path(conn, ENDPOINT_PATH_A2DP_APTX_SOURCE, &vtable_endpoint, y));
+#endif
+
+    list_adapters(y);
+
+    return y;
+
+fail:
+    if (y)
+        pa_bluez4_discovery_unref(y);
+
+    dbus_error_free(&err);
+
+    return NULL;
+}
+
+pa_bluez4_discovery* pa_bluez4_discovery_ref(pa_bluez4_discovery *y) {
+    pa_assert(y);
+    pa_assert(PA_REFCNT_VALUE(y) > 0);
+
+    PA_REFCNT_INC(y);
+
+    return y;
+}
+
+void pa_bluez4_discovery_unref(pa_bluez4_discovery *y) {
+    unsigned i;
+
+    pa_assert(y);
+    pa_assert(PA_REFCNT_VALUE(y) > 0);
+
+    if (PA_REFCNT_DEC(y) > 0)
+        return;
+
+    pa_dbus_free_pending_list(&y->pending);
+
+    if (y->devices) {
+       remove_all_devices(y);
+#ifdef __TIZEN_BT__
+       pa_hashmap_free(y->devices,NULL);
+#else
+       pa_hashmap_free(y->devices);
+#endif
+    }
+
+    if (y->transports) {
+        pa_assert(pa_hashmap_isempty(y->transports));
+#ifdef __TIZEN_BT__
+        pa_hashmap_free(y->transports,NULL);
+#else
+        pa_hashmap_free(y->transports);
+#endif
+    }
+
+    if (y->connection) {
+        dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), ENDPOINT_PATH_HFP_AG);
+        dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), ENDPOINT_PATH_HFP_HS);
+        dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), ENDPOINT_PATH_A2DP_SOURCE);
+        dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), ENDPOINT_PATH_A2DP_SINK);
+#ifdef BLUETOOTH_APTX_SUPPORT
+        if (aptx_handle)
+            dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), ENDPOINT_PATH_A2DP_APTX_SOURCE);
+#endif
+        pa_dbus_remove_matches(
+            pa_dbus_connection_get(y->connection),
+            "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged'"
+            ",arg0='org.bluez'",
+            "type='signal',sender='org.bluez',interface='org.bluez.Manager',member='AdapterAdded'",
+            "type='signal',sender='org.bluez',interface='org.bluez.Manager',member='AdapterRemoved'",
+            "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceRemoved'",
+            "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceCreated'",
+            "type='signal',sender='org.bluez',interface='org.bluez.Device',member='PropertyChanged'",
+            "type='signal',sender='org.bluez',interface='org.bluez.Audio',member='PropertyChanged'",
+            "type='signal',sender='org.bluez',interface='org.bluez.Headset',member='PropertyChanged'",
+            "type='signal',sender='org.bluez',interface='org.bluez.AudioSink',member='PropertyChanged'",
+            "type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged'",
+            "type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged'",
+            "type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged'",
+            NULL);
+
+        if (y->filter_added)
+            dbus_connection_remove_filter(pa_dbus_connection_get(y->connection), filter_cb, y);
+
+        pa_dbus_connection_unref(y->connection);
+    }
+
+    for (i = 0; i < PA_BLUEZ4_HOOK_MAX; i++)
+        pa_hook_done(&y->hooks[i]);
+
+    if (y->core)
+        pa_shared_remove(y->core, "bluez4-discovery");
+
+    pa_xfree(y);
+}
+
+pa_hook* pa_bluez4_discovery_hook(pa_bluez4_discovery *y, pa_bluez4_hook_t hook) {
+    pa_assert(y);
+    pa_assert(PA_REFCNT_VALUE(y) > 0);
+
+    return &y->hooks[hook];
+}
+
+pa_bluez4_form_factor_t pa_bluez4_get_form_factor(uint32_t class) {
+    unsigned major, minor;
+    pa_bluez4_form_factor_t r;
+
+    static const pa_bluez4_form_factor_t table[] = {
+        [1] = PA_BLUEZ4_FORM_FACTOR_HEADSET,
+        [2] = PA_BLUEZ4_FORM_FACTOR_HANDSFREE,
+        [4] = PA_BLUEZ4_FORM_FACTOR_MICROPHONE,
+        [5] = PA_BLUEZ4_FORM_FACTOR_SPEAKER,
+        [6] = PA_BLUEZ4_FORM_FACTOR_HEADPHONE,
+        [7] = PA_BLUEZ4_FORM_FACTOR_PORTABLE,
+        [8] = PA_BLUEZ4_FORM_FACTOR_CAR,
+        [10] = PA_BLUEZ4_FORM_FACTOR_HIFI
+    };
+
+    /*
+     * See Bluetooth Assigned Numbers:
+     * https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
+     */
+    major = (class >> 8) & 0x1F;
+    minor = (class >> 2) & 0x3F;
+
+    switch (major) {
+        case 2:
+            return PA_BLUEZ4_FORM_FACTOR_PHONE;
+        case 4:
+            break;
+        default:
+            pa_log_debug("Unknown Bluetooth major device class %u", major);
+            return PA_BLUEZ4_FORM_FACTOR_UNKNOWN;
+    }
+
+    r = minor < PA_ELEMENTSOF(table) ? table[minor] : PA_BLUEZ4_FORM_FACTOR_UNKNOWN;
+
+    if (!r)
+        pa_log_debug("Unknown Bluetooth minor device class %u", minor);
+
+    return r;
+}
+
+const char *pa_bluez4_form_factor_to_string(pa_bluez4_form_factor_t ff) {
+    switch (ff) {
+        case PA_BLUEZ4_FORM_FACTOR_UNKNOWN:
+            return "unknown";
+        case PA_BLUEZ4_FORM_FACTOR_HEADSET:
+            return "headset";
+        case PA_BLUEZ4_FORM_FACTOR_HANDSFREE:
+            return "hands-free";
+        case PA_BLUEZ4_FORM_FACTOR_MICROPHONE:
+            return "microphone";
+        case PA_BLUEZ4_FORM_FACTOR_SPEAKER:
+            return "speaker";
+        case PA_BLUEZ4_FORM_FACTOR_HEADPHONE:
+            return "headphone";
+        case PA_BLUEZ4_FORM_FACTOR_PORTABLE:
+            return "portable";
+        case PA_BLUEZ4_FORM_FACTOR_CAR:
+            return "car";
+        case PA_BLUEZ4_FORM_FACTOR_HIFI:
+            return "hifi";
+        case PA_BLUEZ4_FORM_FACTOR_PHONE:
+            return "phone";
+    }
+
+    pa_assert_not_reached();
+}
+
+char *pa_bluez4_cleanup_name(const char *name) {
+    char *t, *s, *d;
+    bool space = false;
+
+    pa_assert(name);
+
+    while ((*name >= 1 && *name <= 32) || *name >= 127)
+        name++;
+
+    t = pa_xstrdup(name);
+
+    for (s = d = t; *s; s++) {
+
+        if (*s <= 32 || *s >= 127 || *s == '_') {
+            space = true;
+            continue;
+        }
+
+        if (space) {
+            *(d++) = ' ';
+            space = false;
+        }
+
+        *(d++) = *s;
+    }
+
+    *d = 0;
+
+    return t;
+}
+
+bool pa_bluez4_uuid_has(pa_bluez4_uuid *uuids, const char *uuid) {
+    pa_assert(uuid);
+
+    while (uuids) {
+        if (strcasecmp(uuids->uuid, uuid) == 0)
+            return true;
+
+        uuids = uuids->next;
+    }
+
+    return false;
+}
diff --git a/src/modules/bluetooth/bluez4-util.h b/src/modules/bluetooth/bluez4-util.h
new file mode 100644 (file)
index 0000000..9667975
--- /dev/null
@@ -0,0 +1,178 @@
+#ifndef foobluez4utilhfoo
+#define foobluez4utilhfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2008-2013 João Paulo Rechi Vita
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <dbus/dbus.h>
+
+#include <pulsecore/llist.h>
+#include <pulsecore/macro.h>
+
+#define PA_BLUEZ4_ERROR_NOT_SUPPORTED "org.bluez.Error.NotSupported"
+
+/* UUID copied from bluez/audio/device.h */
+#define GENERIC_AUDIO_UUID      "00001203-0000-1000-8000-00805f9b34fb"
+
+#define HSP_HS_UUID             "00001108-0000-1000-8000-00805f9b34fb"
+#define HSP_AG_UUID             "00001112-0000-1000-8000-00805f9b34fb"
+
+#define HFP_HS_UUID             "0000111e-0000-1000-8000-00805f9b34fb"
+#define HFP_AG_UUID             "0000111f-0000-1000-8000-00805f9b34fb"
+
+#define ADVANCED_AUDIO_UUID     "0000110d-0000-1000-8000-00805f9b34fb"
+
+#define A2DP_SOURCE_UUID        "0000110a-0000-1000-8000-00805f9b34fb"
+#define A2DP_SINK_UUID          "0000110b-0000-1000-8000-00805f9b34fb"
+
+#define HSP_MAX_GAIN 15
+
+typedef struct pa_bluez4_uuid pa_bluez4_uuid;
+typedef struct pa_bluez4_device pa_bluez4_device;
+typedef struct pa_bluez4_discovery pa_bluez4_discovery;
+typedef struct pa_bluez4_transport pa_bluez4_transport;
+
+struct userdata;
+
+struct pa_bluez4_uuid {
+    char *uuid;
+    PA_LLIST_FIELDS(pa_bluez4_uuid);
+};
+
+typedef enum pa_bluez4_profile {
+    PA_BLUEZ4_PROFILE_A2DP,
+    PA_BLUEZ4_PROFILE_A2DP_SOURCE,
+    PA_BLUEZ4_PROFILE_HSP,
+    PA_BLUEZ4_PROFILE_HFGW,
+    PA_BLUEZ4_PROFILE_OFF
+} pa_bluez4_profile_t;
+
+#define PA_BLUEZ4_PROFILE_COUNT PA_BLUEZ4_PROFILE_OFF
+
+struct pa_bluez4_hook_uuid_data {
+    pa_bluez4_device *device;
+    const char *uuid;
+};
+
+/* Hook data: pa_bluez4_discovery pointer. */
+typedef enum pa_bluez4_hook {
+    PA_BLUEZ4_HOOK_DEVICE_CONNECTION_CHANGED, /* Call data: pa_bluez4_device */
+    PA_BLUEZ4_HOOK_DEVICE_UUID_ADDED, /* Call data: pa_bluez4_hook_uuid_data */
+    PA_BLUEZ4_HOOK_TRANSPORT_STATE_CHANGED, /* Call data: pa_bluez4_transport */
+    PA_BLUEZ4_HOOK_TRANSPORT_NREC_CHANGED, /* Call data: pa_bluez4_transport */
+    PA_BLUEZ4_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED, /* Call data: pa_bluez4_transport */
+    PA_BLUEZ4_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED, /* Call data: pa_bluez4_transport */
+    PA_BLUEZ4_HOOK_MAX
+} pa_bluez4_hook_t;
+
+typedef enum pa_bluez4_transport_state {
+    PA_BLUEZ4_TRANSPORT_STATE_DISCONNECTED,
+    PA_BLUEZ4_TRANSPORT_STATE_IDLE, /* Connected but not playing */
+    PA_BLUEZ4_TRANSPORT_STATE_PLAYING
+} pa_bluez4_transport_state_t;
+
+struct pa_bluez4_transport {
+    pa_bluez4_device *device;
+    char *owner;
+    char *path;
+    pa_bluez4_profile_t profile;
+    uint8_t codec;
+    uint8_t *config;
+    int config_size;
+
+    pa_bluez4_transport_state_t state;
+    bool nrec;
+    uint16_t microphone_gain; /* Used for HSP/HFP */
+    uint16_t speaker_gain; /* Used for HSP/HFP */
+};
+
+/* This enum is shared among Audio, Headset, AudioSink, and AudioSource, although not all values are acceptable in all profiles */
+typedef enum pa_bluez4_audio_state {
+    PA_BLUEZ4_AUDIO_STATE_INVALID = -1,
+    PA_BLUEZ4_AUDIO_STATE_DISCONNECTED,
+    PA_BLUEZ4_AUDIO_STATE_CONNECTING,
+    PA_BLUEZ4_AUDIO_STATE_CONNECTED,
+    PA_BLUEZ4_AUDIO_STATE_PLAYING
+} pa_bluez4_audio_state_t;
+
+struct pa_bluez4_device {
+    pa_bluez4_discovery *discovery;
+    bool dead;
+
+    int device_info_valid;      /* 0: no results yet; 1: good results; -1: bad results ... */
+
+    /* Device information */
+    char *name;
+    char *path;
+    pa_bluez4_transport *transports[PA_BLUEZ4_PROFILE_COUNT];
+    int paired;
+    char *alias;
+    PA_LLIST_HEAD(pa_bluez4_uuid, uuids);
+    char *address;
+    int class;
+    int trusted;
+
+    /* Audio state */
+    pa_bluez4_audio_state_t audio_state;
+
+    /* AudioSink, AudioSource, Headset and HandsfreeGateway states */
+    pa_bluez4_audio_state_t profile_state[PA_BLUEZ4_PROFILE_COUNT];
+};
+
+pa_bluez4_discovery* pa_bluez4_discovery_get(pa_core *core);
+pa_bluez4_discovery* pa_bluez4_discovery_ref(pa_bluez4_discovery *y);
+void pa_bluez4_discovery_unref(pa_bluez4_discovery *d);
+
+pa_bluez4_device* pa_bluez4_discovery_get_by_path(pa_bluez4_discovery *d, const char* path);
+pa_bluez4_device* pa_bluez4_discovery_get_by_address(pa_bluez4_discovery *d, const char* address);
+
+bool pa_bluez4_device_any_audio_connected(const pa_bluez4_device *d);
+
+int pa_bluez4_transport_acquire(pa_bluez4_transport *t, bool optional, size_t *imtu, size_t *omtu);
+void pa_bluez4_transport_release(pa_bluez4_transport *t);
+
+void pa_bluez4_transport_set_microphone_gain(pa_bluez4_transport *t, uint16_t value);
+void pa_bluez4_transport_set_speaker_gain(pa_bluez4_transport *t, uint16_t value);
+
+pa_hook* pa_bluez4_discovery_hook(pa_bluez4_discovery *y, pa_bluez4_hook_t hook);
+
+typedef enum pa_bluez4_form_factor {
+    PA_BLUEZ4_FORM_FACTOR_UNKNOWN,
+    PA_BLUEZ4_FORM_FACTOR_HEADSET,
+    PA_BLUEZ4_FORM_FACTOR_HANDSFREE,
+    PA_BLUEZ4_FORM_FACTOR_MICROPHONE,
+    PA_BLUEZ4_FORM_FACTOR_SPEAKER,
+    PA_BLUEZ4_FORM_FACTOR_HEADPHONE,
+    PA_BLUEZ4_FORM_FACTOR_PORTABLE,
+    PA_BLUEZ4_FORM_FACTOR_CAR,
+    PA_BLUEZ4_FORM_FACTOR_HIFI,
+    PA_BLUEZ4_FORM_FACTOR_PHONE,
+} pa_bluez4_form_factor_t;
+
+pa_bluez4_form_factor_t pa_bluez4_get_form_factor(uint32_t class);
+const char *pa_bluez4_form_factor_to_string(pa_bluez4_form_factor_t ff);
+
+char *pa_bluez4_cleanup_name(const char *name);
+
+bool pa_bluez4_uuid_has(pa_bluez4_uuid *uuids, const char *uuid);
+const char *pa_bluez4_profile_to_string(pa_bluez4_profile_t profile);
+
+#endif
diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c
new file mode 100644 (file)
index 0000000..1d24293
--- /dev/null
@@ -0,0 +1,1985 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2008-2013 João Paulo Rechi Vita
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/core.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-shared.h>
+#include <pulsecore/log.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/refcnt.h>
+#include <pulsecore/shared.h>
+
+#include "a2dp-codecs.h"
+#include "hfaudioagent.h"
+
+#include "bluez5-util.h"
+#ifdef BLUETOOTH_APTX_SUPPORT
+#include <dlfcn.h>
+#endif
+
+#define BLUEZ_SERVICE "org.bluez"
+#define BLUEZ_ADAPTER_INTERFACE BLUEZ_SERVICE ".Adapter1"
+#define BLUEZ_DEVICE_INTERFACE BLUEZ_SERVICE ".Device1"
+#define BLUEZ_MEDIA_INTERFACE BLUEZ_SERVICE ".Media1"
+#define BLUEZ_MEDIA_ENDPOINT_INTERFACE BLUEZ_SERVICE ".MediaEndpoint1"
+#define BLUEZ_MEDIA_TRANSPORT_INTERFACE BLUEZ_SERVICE ".MediaTransport1"
+
+#define BLUEZ_ERROR_NOT_SUPPORTED "org.bluez.Error.NotSupported"
+
+#define A2DP_SOURCE_ENDPOINT "/MediaEndpoint/A2DPSource"
+#define A2DP_SINK_ENDPOINT "/MediaEndpoint/A2DPSink"
+#ifdef BLUETOOTH_APTX_SUPPORT
+#define A2DP_APTX_SOURCE_ENDPOINT "/MediaEndpoint/A2DPSource_aptx"
+#endif
+
+#define ENDPOINT_INTROSPECT_XML                                         \
+    DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                           \
+    "<node>"                                                            \
+    " <interface name=\"" BLUEZ_MEDIA_ENDPOINT_INTERFACE "\">"          \
+    "  <method name=\"SetConfiguration\">"                              \
+    "   <arg name=\"transport\" direction=\"in\" type=\"o\"/>"          \
+    "   <arg name=\"properties\" direction=\"in\" type=\"ay\"/>"        \
+    "  </method>"                                                       \
+    "  <method name=\"SelectConfiguration\">"                           \
+    "   <arg name=\"capabilities\" direction=\"in\" type=\"ay\"/>"      \
+    "   <arg name=\"configuration\" direction=\"out\" type=\"ay\"/>"    \
+    "  </method>"                                                       \
+    "  <method name=\"ClearConfiguration\">"                            \
+    "   <arg name=\"transport\" direction=\"in\" type=\"o\"/>"          \
+    "  </method>"                                                       \
+    "  <method name=\"Release\">"                                       \
+    "  </method>"                                                       \
+    "  <method name=\"SuspendMedia\">"                                  \
+    "  </method>"                                                       \
+    " </interface>"                                                     \
+    " <interface name=\"org.freedesktop.DBus.Introspectable\">"         \
+    "  <method name=\"Introspect\">"                                    \
+    "   <arg name=\"data\" type=\"s\" direction=\"out\"/>"              \
+    "  </method>"                                                       \
+    " </interface>"                                                     \
+    "</node>"
+
+struct pa_bluetooth_discovery {
+    PA_REFCNT_DECLARE;
+
+    pa_core *core;
+    pa_dbus_connection *connection;
+    bool filter_added;
+    bool matches_added;
+    bool objects_listed;
+    pa_hook hooks[PA_BLUETOOTH_HOOK_MAX];
+    pa_hashmap *adapters;
+    pa_hashmap *devices;
+    pa_hashmap *transports;
+
+    hf_audio_agent_data *hf_audio_agent;
+    PA_LLIST_HEAD(pa_dbus_pending, pending);
+};
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+static void *aptx_handle = NULL;
+
+int pa_unload_aptx(void)
+{
+       if (aptx_handle == NULL) {
+               pa_log_warn("Unable to unload apt-X library");
+               return -1;
+       }
+
+       dlclose(aptx_handle);
+       aptx_handle = NULL;
+
+       pa_log_debug("unloaded apt-X library successfully");
+       return 0;
+}
+
+int pa_load_aptx(const char *aptx_lib_name)
+{
+       char* lib_path = NULL ;
+
+        if(aptx_lib_name == NULL)
+               return -1;
+
+        lib_path = pa_sprintf_malloc("%s/%s", PA_DLSEARCHPATH, aptx_lib_name);
+
+       if (!lib_path)
+               return -1;
+
+       pa_log_info("aptx_lib_path = [%s]", lib_path);
+
+       aptx_handle = dlopen(lib_path, RTLD_LAZY);
+       if (aptx_handle == NULL) {
+               pa_log_warn("Unable to load apt-X library [%s]", dlerror());
+               pa_xfree(lib_path);
+               return -1;
+       }
+
+       pa_log_debug("loaded apt-X library successfully");
+       pa_xfree(lib_path);
+
+       return 0;
+}
+
+void* pa_aptx_get_handle(void)
+{
+       return aptx_handle;
+}
+#endif
+
+static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_discovery *y, DBusMessage *m,
+                                                                  DBusPendingCallNotifyFunction func, void *call_data) {
+    pa_dbus_pending *p;
+    DBusPendingCall *call;
+
+    pa_assert(y);
+    pa_assert(m);
+
+    pa_assert_se(dbus_connection_send_with_reply(pa_dbus_connection_get(y->connection), m, &call, -1));
+
+    p = pa_dbus_pending_new(pa_dbus_connection_get(y->connection), m, call, y, call_data);
+    PA_LLIST_PREPEND(pa_dbus_pending, y->pending, p);
+    dbus_pending_call_set_notify(call, func, p, NULL);
+
+    return p;
+}
+
+static const char *check_variant_property(DBusMessageIter *i) {
+    const char *key;
+
+    pa_assert(i);
+
+    if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING) {
+        pa_log_error("Property name not a string.");
+        return NULL;
+    }
+
+    dbus_message_iter_get_basic(i, &key);
+
+    if (!dbus_message_iter_next(i)) {
+        pa_log_error("Property value missing");
+        return NULL;
+    }
+
+    if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_VARIANT) {
+        pa_log_error("Property value not a variant.");
+        return NULL;
+    }
+
+    return key;
+}
+
+pa_bluetooth_transport *pa_bluetooth_transport_new(pa_bluetooth_device *d, const char *owner, const char *path,
+                                                   pa_bluetooth_profile_t p, const uint8_t *config, size_t size) {
+    pa_bluetooth_transport *t;
+
+    t = pa_xnew0(pa_bluetooth_transport, 1);
+    t->device = d;
+    t->owner = pa_xstrdup(owner);
+    t->path = pa_xstrdup(path);
+    t->profile = p;
+    t->config_size = size;
+
+    if (size > 0) {
+        t->config = pa_xnew(uint8_t, size);
+        memcpy(t->config, config, size);
+    }
+
+    pa_assert_se(pa_hashmap_put(d->discovery->transports, t->path, t) >= 0);
+
+    return t;
+}
+
+static const char *transport_state_to_string(pa_bluetooth_transport_state_t state) {
+    switch(state) {
+        case PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED:
+            return "disconnected";
+        case PA_BLUETOOTH_TRANSPORT_STATE_IDLE:
+            return "idle";
+        case PA_BLUETOOTH_TRANSPORT_STATE_PLAYING:
+            return "playing";
+    }
+
+    return "invalid";
+}
+
+static void transport_state_changed(pa_bluetooth_transport *t, pa_bluetooth_transport_state_t state) {
+    bool old_any_connected;
+
+    pa_assert(t);
+
+    if (t->state == state)
+        return;
+
+    old_any_connected = pa_bluetooth_device_any_transport_connected(t->device);
+
+    pa_log_debug("Transport %s state changed from %s to %s",
+                 t->path, transport_state_to_string(t->state), transport_state_to_string(state));
+
+    t->state = state;
+    if (state == PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED)
+        t->device->transports[t->profile] = NULL;
+
+    pa_hook_fire(&t->device->discovery->hooks[PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED], t);
+
+    if (old_any_connected != pa_bluetooth_device_any_transport_connected(t->device))
+        pa_hook_fire(&t->device->discovery->hooks[PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED], t->device);
+}
+
+void pa_bluetooth_transport_put(pa_bluetooth_transport *t) {
+    transport_state_changed(t, PA_BLUETOOTH_TRANSPORT_STATE_IDLE);
+}
+
+void pa_bluetooth_transport_free(pa_bluetooth_transport *t) {
+    pa_assert(t);
+
+    pa_hashmap_remove(t->device->discovery->transports, t->path);
+    pa_xfree(t->owner);
+    pa_xfree(t->path);
+    pa_xfree(t->config);
+    pa_xfree(t);
+}
+
+static int bluez5_transport_acquire_cb(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) {
+    DBusMessage *m, *r;
+    DBusError err;
+    int ret;
+    uint16_t i, o;
+    const char *method = optional ? "TryAcquire" : "Acquire";
+
+    pa_assert(t);
+    pa_assert(t->device);
+    pa_assert(t->device->discovery);
+
+    pa_assert_se(m = dbus_message_new_method_call(t->owner, t->path, BLUEZ_MEDIA_TRANSPORT_INTERFACE, method));
+
+    dbus_error_init(&err);
+
+    r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t->device->discovery->connection), m, -1, &err);
+    if (!r) {
+        if (optional && pa_streq(err.name, "org.bluez.Error.NotAvailable"))
+            pa_log_info("Failed optional acquire of unavailable transport %s", t->path);
+        else
+            pa_log_error("Transport %s() failed for transport %s (%s)", method, t->path, err.message);
+
+        dbus_error_free(&err);
+        return -1;
+    }
+
+    if (!dbus_message_get_args(r, &err, DBUS_TYPE_UNIX_FD, &ret, DBUS_TYPE_UINT16, &i, DBUS_TYPE_UINT16, &o,
+                               DBUS_TYPE_INVALID)) {
+        pa_log_error("Failed to parse %s() reply: %s", method, err.message);
+        dbus_error_free(&err);
+        ret = -1;
+        goto finish;
+    }
+
+    if (imtu)
+        *imtu = i;
+
+    if (omtu)
+        *omtu = o;
+
+finish:
+    dbus_message_unref(r);
+    return ret;
+}
+
+static void bluez5_transport_release_cb(pa_bluetooth_transport *t) {
+    DBusMessage *m;
+    DBusError err;
+
+    pa_assert(t);
+    pa_assert(t->device);
+    pa_assert(t->device->discovery);
+
+    dbus_error_init(&err);
+
+
+    if (t->state <= PA_BLUETOOTH_TRANSPORT_STATE_IDLE) {
+        pa_log_info("Transport %s auto-released by BlueZ or already released", t->path);
+        return;
+    }
+
+    pa_assert_se(m = dbus_message_new_method_call(t->owner, t->path, BLUEZ_MEDIA_TRANSPORT_INTERFACE, "Release"));
+    dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t->device->discovery->connection), m, -1, &err);
+
+    if (dbus_error_is_set(&err)) {
+        pa_log_error("Failed to release transport %s: %s", t->path, err.message);
+        dbus_error_free(&err);
+    } else
+        pa_log_info("Transport %s released", t->path);
+}
+
+bool pa_bluetooth_device_any_transport_connected(const pa_bluetooth_device *d) {
+    unsigned i;
+
+    pa_assert(d);
+
+    if (d->device_info_valid != 1)
+        return false;
+
+    for (i = 0; i < PA_BLUETOOTH_PROFILE_COUNT; i++)
+        if (d->transports[i] && d->transports[i]->state != PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED)
+            return true;
+
+    return false;
+}
+
+#ifdef __TIZEN_BT__
+bool pa_bluetooth_device_sink_transport_connected(const pa_bluetooth_device *d) {
+    unsigned i;
+
+    pa_assert(d);
+
+    if (d->device_info_valid != 1)
+        return false;
+
+    for (i = 0; i < PA_BLUETOOTH_PROFILE_COUNT; i++)
+        if (d->transports[i] &&
+            d->transports[i]->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK &&
+            d->transports[i]->state != PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED)
+            return true;
+
+    return false;
+}
+#endif
+
+static int transport_state_from_string(const char* value, pa_bluetooth_transport_state_t *state) {
+    pa_assert(value);
+    pa_assert(state);
+
+    if (pa_streq(value, "idle"))
+        *state = PA_BLUETOOTH_TRANSPORT_STATE_IDLE;
+    else if (pa_streq(value, "pending") || pa_streq(value, "active"))
+        *state = PA_BLUETOOTH_TRANSPORT_STATE_PLAYING;
+    else
+        return -1;
+
+    return 0;
+}
+
+static void parse_transport_property(pa_bluetooth_transport *t, DBusMessageIter *i) {
+    const char *key;
+    DBusMessageIter variant_i;
+
+    key = check_variant_property(i);
+    if (key == NULL)
+        return;
+
+    dbus_message_iter_recurse(i, &variant_i);
+
+    switch (dbus_message_iter_get_arg_type(&variant_i)) {
+
+        case DBUS_TYPE_STRING: {
+
+            const char *value;
+            dbus_message_iter_get_basic(&variant_i, &value);
+
+            if (pa_streq(key, "State")) {
+                pa_bluetooth_transport_state_t state;
+
+                if (transport_state_from_string(value, &state) < 0) {
+                    pa_log_error("Invalid state received: %s", value);
+                    return;
+                }
+
+                transport_state_changed(t, state);
+            }
+
+            break;
+        }
+    }
+
+    return;
+}
+
+static int parse_transport_properties(pa_bluetooth_transport *t, DBusMessageIter *i) {
+    DBusMessageIter element_i;
+
+    dbus_message_iter_recurse(i, &element_i);
+
+    while (dbus_message_iter_get_arg_type(&element_i) == DBUS_TYPE_DICT_ENTRY) {
+        DBusMessageIter dict_i;
+
+        dbus_message_iter_recurse(&element_i, &dict_i);
+
+        parse_transport_property(t, &dict_i);
+
+        dbus_message_iter_next(&element_i);
+    }
+
+    return 0;
+}
+
+static pa_bluetooth_device* device_create(pa_bluetooth_discovery *y, const char *path) {
+    pa_bluetooth_device *d;
+
+    pa_assert(y);
+    pa_assert(path);
+
+    d = pa_xnew0(pa_bluetooth_device, 1);
+    d->discovery = y;
+    d->path = pa_xstrdup(path);
+
+#ifdef __TIZEN_BT__
+    d->uuids = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+#else
+    d->uuids = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, pa_xfree);
+#endif
+
+    pa_hashmap_put(y->devices, d->path, d);
+
+    return d;
+}
+
+pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_path(pa_bluetooth_discovery *y, const char *path) {
+    pa_bluetooth_device *d;
+
+    pa_assert(y);
+    pa_assert(PA_REFCNT_VALUE(y) > 0);
+    pa_assert(path);
+
+    if ((d = pa_hashmap_get(y->devices, path)))
+        if (d->device_info_valid == 1)
+            return d;
+
+    return NULL;
+}
+
+pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_address(pa_bluetooth_discovery *y, const char *remote, const char *local) {
+    pa_bluetooth_device *d;
+    void *state = NULL;
+
+    pa_assert(y);
+    pa_assert(PA_REFCNT_VALUE(y) > 0);
+    pa_assert(remote);
+    pa_assert(local);
+
+    while ((d = pa_hashmap_iterate(y->devices, &state, NULL)))
+        if (pa_streq(d->address, remote) && pa_streq(d->adapter->address, local))
+            return d->device_info_valid == 1 ? d : NULL;
+
+    return NULL;
+}
+
+static void device_free(pa_bluetooth_device *d) {
+    unsigned i;
+
+    pa_assert(d);
+
+    for (i = 0; i < PA_BLUETOOTH_PROFILE_COUNT; i++) {
+        pa_bluetooth_transport *t;
+
+        if (!(t = d->transports[i]))
+            continue;
+
+        transport_state_changed(t, PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED);
+        pa_bluetooth_transport_free(t);
+    }
+
+    if (d->uuids) {
+#ifdef __TIZEN_BT__
+        pa_hashmap_free(d->uuids, NULL);
+#else
+        pa_hashmap_free(d->uuids);
+#endif
+    }
+
+    d->discovery = NULL;
+    d->adapter = NULL;
+    pa_xfree(d->path);
+    pa_xfree(d->alias);
+    pa_xfree(d->address);
+    pa_xfree(d);
+}
+
+static void device_remove(pa_bluetooth_discovery *y, const char *path) {
+    pa_bluetooth_device *d;
+
+    if (!(d = pa_hashmap_remove(y->devices, path)))
+        pa_log_warn("Unknown device removed %s", path);
+    else {
+        pa_log_debug("Device %s removed", path);
+        device_free(d);
+    }
+}
+
+static void device_remove_all(pa_bluetooth_discovery *y) {
+    pa_bluetooth_device *d;
+
+    pa_assert(y);
+
+    while ((d = pa_hashmap_steal_first(y->devices))) {
+        d->device_info_valid = -1;
+        pa_hook_fire(&y->hooks[PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED], d);
+        device_free(d);
+   }
+}
+
+static pa_bluetooth_adapter* adapter_create(pa_bluetooth_discovery *y, const char *path) {
+    pa_bluetooth_adapter *a;
+
+    pa_assert(y);
+    pa_assert(path);
+
+    a = pa_xnew0(pa_bluetooth_adapter, 1);
+    a->discovery = y;
+    a->path = pa_xstrdup(path);
+
+    pa_hashmap_put(y->adapters, a->path, a);
+
+    return a;
+}
+
+static void adapter_free(pa_bluetooth_adapter *a) {
+    pa_bluetooth_device *d;
+    void *state;
+
+    pa_assert(a);
+    pa_assert(a->discovery);
+
+    PA_HASHMAP_FOREACH(d, a->discovery->devices, state)
+        if (d->adapter == a)
+            d->adapter = NULL;
+
+    pa_xfree(a->path);
+    pa_xfree(a->address);
+    pa_xfree(a);
+}
+
+static void adapter_remove(pa_bluetooth_discovery *y, const char *path) {
+    pa_bluetooth_adapter *a;
+
+    if (!(a = pa_hashmap_remove(y->adapters, path)))
+        pa_log_warn("Unknown adapter removed %s", path);
+    else {
+        pa_log_debug("Adapter %s removed", path);
+        adapter_free(a);
+    }
+}
+
+static void adapter_remove_all(pa_bluetooth_discovery *y) {
+    pa_bluetooth_adapter *a;
+
+    pa_assert(y);
+
+    /* When this function is called all devices have already been freed */
+
+    while ((a = pa_hashmap_steal_first(y->adapters)))
+        adapter_free(a);
+}
+
+static void parse_device_property(pa_bluetooth_device *d, DBusMessageIter *i, bool is_property_change) {
+    const char *key;
+    DBusMessageIter variant_i;
+
+    pa_assert(d);
+
+    key = check_variant_property(i);
+    if (key == NULL) {
+        pa_log_error("Received invalid property for device %s", d->path);
+        return;
+    }
+
+    dbus_message_iter_recurse(i, &variant_i);
+
+    switch (dbus_message_iter_get_arg_type(&variant_i)) {
+
+        case DBUS_TYPE_STRING: {
+            const char *value;
+            dbus_message_iter_get_basic(&variant_i, &value);
+
+            if (pa_streq(key, "Alias")) {
+                pa_xfree(d->alias);
+                d->alias = pa_xstrdup(value);
+                pa_log_debug("%s: %s", key, value);
+            } else if (pa_streq(key, "Address")) {
+                if (is_property_change) {
+                    pa_log_warn("Device property 'Address' expected to be constant but changed for %s, ignoring", d->path);
+                    return;
+                }
+
+                if (d->address) {
+                    pa_log_warn("Device %s: Received a duplicate 'Address' property, ignoring", d->path);
+                    return;
+                }
+
+                d->address = pa_xstrdup(value);
+                pa_log_debug("%s: %s", key, value);
+            }
+
+            break;
+        }
+
+        case DBUS_TYPE_OBJECT_PATH: {
+            const char *value;
+            dbus_message_iter_get_basic(&variant_i, &value);
+
+            if (pa_streq(key, "Adapter")) {
+
+                if (is_property_change) {
+                    pa_log_warn("Device property 'Adapter' expected to be constant but changed for %s, ignoring", d->path);
+                    return;
+                }
+
+                if (d->adapter_path) {
+                    pa_log_warn("Device %s: Received a duplicate 'Adapter' property, ignoring", d->path);
+                    return;
+                }
+
+                d->adapter_path = pa_xstrdup(value);
+
+                d->adapter = pa_hashmap_get(d->discovery->adapters, value);
+                if (!d->adapter)
+                    pa_log_info("Device %s: 'Adapter' property references an unknown adapter %s.", d->path, value);
+
+                pa_log_debug("%s: %s", key, value);
+            }
+
+            break;
+        }
+
+        case DBUS_TYPE_UINT32: {
+            uint32_t value;
+            dbus_message_iter_get_basic(&variant_i, &value);
+
+            if (pa_streq(key, "Class")) {
+                d->class_of_device = value;
+                pa_log_debug("%s: %d", key, value);
+            }
+
+            break;
+        }
+
+        case DBUS_TYPE_ARRAY: {
+            DBusMessageIter ai;
+            dbus_message_iter_recurse(&variant_i, &ai);
+
+            if (dbus_message_iter_get_arg_type(&ai) == DBUS_TYPE_STRING && pa_streq(key, "UUIDs")) {
+                /* bluetoothd never removes UUIDs from a device object so there
+                 * is no need to handle it here. */
+                while (dbus_message_iter_get_arg_type(&ai) != DBUS_TYPE_INVALID) {
+                    const char *value;
+                    char *uuid;
+
+                    dbus_message_iter_get_basic(&ai, &value);
+
+                    if (pa_hashmap_get(d->uuids, value)) {
+                        dbus_message_iter_next(&ai);
+                        continue;
+                    }
+
+                    uuid = pa_xstrdup(value);
+                    pa_hashmap_put(d->uuids, uuid, uuid);
+
+                    pa_log_debug("%s: %s", key, value);
+                    dbus_message_iter_next(&ai);
+                }
+            }
+
+            break;
+        }
+    }
+}
+
+static int parse_device_properties(pa_bluetooth_device *d, DBusMessageIter *i, bool is_property_change) {
+    DBusMessageIter element_i;
+    int ret = 0;
+
+    dbus_message_iter_recurse(i, &element_i);
+
+    while (dbus_message_iter_get_arg_type(&element_i) == DBUS_TYPE_DICT_ENTRY) {
+        DBusMessageIter dict_i;
+
+        dbus_message_iter_recurse(&element_i, &dict_i);
+        parse_device_property(d, &dict_i, is_property_change);
+        dbus_message_iter_next(&element_i);
+    }
+
+    if (!d->address || !d->adapter_path || !d->alias) {
+        pa_log_error("Non-optional information missing for device %s", d->path);
+        d->device_info_valid = -1;
+        return -1;
+    }
+
+    d->device_info_valid = 1;
+    return ret;
+}
+
+static void parse_adapter_properties(pa_bluetooth_adapter *a, DBusMessageIter *i, bool is_property_change) {
+    DBusMessageIter element_i;
+
+    pa_assert(a);
+
+    dbus_message_iter_recurse(i, &element_i);
+
+    while (dbus_message_iter_get_arg_type(&element_i) == DBUS_TYPE_DICT_ENTRY) {
+        DBusMessageIter dict_i, variant_i;
+        const char *key;
+
+        dbus_message_iter_recurse(&element_i, &dict_i);
+
+        key = check_variant_property(&dict_i);
+        if (key == NULL) {
+            pa_log_error("Received invalid property for adapter %s", a->path);
+            return;
+        }
+
+        dbus_message_iter_recurse(&dict_i, &variant_i);
+
+        if (dbus_message_iter_get_arg_type(&variant_i) == DBUS_TYPE_STRING && pa_streq(key, "Address")) {
+            char *value;
+
+            if (is_property_change) {
+                pa_log_warn("Adapter property 'Address' expected to be constant but changed for %s, ignoring", a->path);
+                return;
+            }
+
+            if (a->address) {
+                pa_log_warn("Adapter %s received a duplicate 'Address' property, ignoring", a->path);
+                return;
+            }
+
+            dbus_message_iter_get_basic(&variant_i, &value);
+            a->address = pa_xstrdup(value);
+        }
+
+        dbus_message_iter_next(&element_i);
+    }
+}
+
+static void register_endpoint_reply(DBusPendingCall *pending, void *userdata) {
+    DBusMessage *r;
+    pa_dbus_pending *p;
+    pa_bluetooth_discovery *y;
+    char *endpoint;
+
+    pa_assert(pending);
+    pa_assert_se(p = userdata);
+    pa_assert_se(y = p->context_data);
+    pa_assert_se(endpoint = p->call_data);
+    pa_assert_se(r = dbus_pending_call_steal_reply(pending));
+
+    if (dbus_message_is_error(r, BLUEZ_ERROR_NOT_SUPPORTED)) {
+        pa_log_info("Couldn't register endpoint %s because it is disabled in BlueZ", endpoint);
+        goto finish;
+    }
+
+    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
+        pa_log_error(BLUEZ_MEDIA_INTERFACE ".RegisterEndpoint() failed: %s: %s", dbus_message_get_error_name(r),
+                     pa_dbus_get_error_message(r));
+        goto finish;
+    }
+
+finish:
+    dbus_message_unref(r);
+
+    PA_LLIST_REMOVE(pa_dbus_pending, y->pending, p);
+    pa_dbus_pending_free(p);
+
+    pa_xfree(endpoint);
+}
+
+static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const char *endpoint, const char *uuid) {
+    DBusMessage *m;
+    DBusMessageIter i, d;
+    uint8_t codec = 0;
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+    if(pa_streq(endpoint,A2DP_APTX_SOURCE_ENDPOINT))
+       codec = A2DP_CODEC_VENDOR;
+#endif
+    pa_log_debug("Registering %s on adapter %s", endpoint, path);
+
+    pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, path, BLUEZ_MEDIA_INTERFACE, "RegisterEndpoint"));
+
+    dbus_message_iter_init_append(m, &i);
+    dbus_message_iter_append_basic(&i, DBUS_TYPE_OBJECT_PATH, &endpoint);
+    dbus_message_iter_open_container(&i, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING
+                                         DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &d);
+    pa_dbus_append_basic_variant_dict_entry(&d, "UUID", DBUS_TYPE_STRING, &uuid);
+    pa_dbus_append_basic_variant_dict_entry(&d, "Codec", DBUS_TYPE_BYTE, &codec);
+
+    if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SOURCE) || pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SINK)) {
+#ifdef __TIZEN_BT__
+    if (codec == A2DP_CODEC_SBC) {
+       a2dp_sbc_t capabilities;
+       capabilities.channel_mode = SBC_CHANNEL_MODE_MONO | SBC_CHANNEL_MODE_DUAL_CHANNEL | SBC_CHANNEL_MODE_STEREO |
+                                       SBC_CHANNEL_MODE_JOINT_STEREO;
+       capabilities.frequency = SBC_SAMPLING_FREQ_16000 | SBC_SAMPLING_FREQ_32000 | SBC_SAMPLING_FREQ_44100 |
+                                       SBC_SAMPLING_FREQ_48000;
+       capabilities.allocation_method = SBC_ALLOCATION_SNR | SBC_ALLOCATION_LOUDNESS;
+       capabilities.subbands = SBC_SUBBANDS_4 | SBC_SUBBANDS_8;
+       capabilities.block_length = SBC_BLOCK_LENGTH_4 | SBC_BLOCK_LENGTH_8 | SBC_BLOCK_LENGTH_12 | SBC_BLOCK_LENGTH_16;
+       capabilities.min_bitpool = MIN_BITPOOL;
+       capabilities.max_bitpool = MAX_BITPOOL;
+       pa_dbus_append_basic_array_variant_dict_entry(&d, "Capabilities", DBUS_TYPE_BYTE, &capabilities, sizeof(capabilities));
+    }
+#ifdef BLUETOOTH_APTX_SUPPORT
+       if (codec == A2DP_CODEC_VENDOR ) {
+               /* aptx */
+               a2dp_aptx_t capabilities;
+               capabilities.vendor_id[0] = APTX_VENDOR_ID0;
+               capabilities.vendor_id[1] = APTX_VENDOR_ID1;
+               capabilities.vendor_id[2] = APTX_VENDOR_ID2;
+               capabilities.vendor_id[3] = APTX_VENDOR_ID3;
+               capabilities.codec_id[0] = APTX_CODEC_ID0;
+               capabilities.codec_id[1] = APTX_CODEC_ID1;
+               capabilities.channel_mode= APTX_CHANNEL_MODE_STEREO;
+               capabilities.frequency= APTX_SAMPLING_FREQ_44100;
+               pa_dbus_append_basic_array_variant_dict_entry(&d, "Capabilities", DBUS_TYPE_BYTE, &capabilities, sizeof(capabilities));
+       }
+#endif /* BLUETOOTH_APTX_SUPPORT */
+#else
+               a2dp_sbc_t capabilities;
+               capabilities.channel_mode = SBC_CHANNEL_MODE_MONO | SBC_CHANNEL_MODE_DUAL_CHANNEL | SBC_CHANNEL_MODE_STEREO |
+                                                                       SBC_CHANNEL_MODE_JOINT_STEREO;
+               capabilities.frequency = SBC_SAMPLING_FREQ_16000 | SBC_SAMPLING_FREQ_32000 | SBC_SAMPLING_FREQ_44100 |
+                                                                SBC_SAMPLING_FREQ_48000;
+               capabilities.allocation_method = SBC_ALLOCATION_SNR | SBC_ALLOCATION_LOUDNESS;
+               capabilities.subbands = SBC_SUBBANDS_4 | SBC_SUBBANDS_8;
+               capabilities.block_length = SBC_BLOCK_LENGTH_4 | SBC_BLOCK_LENGTH_8 | SBC_BLOCK_LENGTH_12 | SBC_BLOCK_LENGTH_16;
+               capabilities.min_bitpool = MIN_BITPOOL;
+               capabilities.max_bitpool = MAX_BITPOOL;
+               pa_dbus_append_basic_array_variant_dict_entry(&d, "Capabilities", DBUS_TYPE_BYTE, &capabilities, sizeof(capabilities));
+#endif /* __TIZEN_BT__ */
+       }
+
+    dbus_message_iter_close_container(&i, &d);
+
+    send_and_add_to_pending(y, m, register_endpoint_reply, pa_xstrdup(endpoint));
+}
+
+static void parse_interfaces_and_properties(pa_bluetooth_discovery *y, DBusMessageIter *dict_i) {
+    DBusMessageIter element_i;
+    const char *path;
+    void *state;
+    pa_bluetooth_device *d;
+
+    pa_assert(dbus_message_iter_get_arg_type(dict_i) == DBUS_TYPE_OBJECT_PATH);
+    dbus_message_iter_get_basic(dict_i, &path);
+
+    pa_assert_se(dbus_message_iter_next(dict_i));
+    pa_assert(dbus_message_iter_get_arg_type(dict_i) == DBUS_TYPE_ARRAY);
+
+    dbus_message_iter_recurse(dict_i, &element_i);
+
+    while (dbus_message_iter_get_arg_type(&element_i) == DBUS_TYPE_DICT_ENTRY) {
+        DBusMessageIter iface_i;
+        const char *interface;
+
+        dbus_message_iter_recurse(&element_i, &iface_i);
+
+        pa_assert(dbus_message_iter_get_arg_type(&iface_i) == DBUS_TYPE_STRING);
+        dbus_message_iter_get_basic(&iface_i, &interface);
+
+        pa_assert_se(dbus_message_iter_next(&iface_i));
+        pa_assert(dbus_message_iter_get_arg_type(&iface_i) == DBUS_TYPE_ARRAY);
+
+        if (pa_streq(interface, BLUEZ_ADAPTER_INTERFACE)) {
+            pa_bluetooth_adapter *a;
+
+            if ((a = pa_hashmap_get(y->adapters, path))) {
+                pa_log_error("Found duplicated D-Bus path for device %s", path);
+                return;
+            } else
+                a = adapter_create(y, path);
+
+            pa_log_debug("Adapter %s found", path);
+
+            parse_adapter_properties(a, &iface_i, false);
+            if (!a->address)
+                return;
+
+            register_endpoint(y, path, A2DP_SOURCE_ENDPOINT, PA_BLUETOOTH_UUID_A2DP_SOURCE);
+#ifndef __TIZEN_BT__
+            register_endpoint(y, path, A2DP_SINK_ENDPOINT, PA_BLUETOOTH_UUID_A2DP_SINK);
+#endif
+#ifdef BLUETOOTH_APTX_SUPPORT
+            if (aptx_handle)
+               register_endpoint(y, path, A2DP_APTX_SOURCE_ENDPOINT, PA_BLUETOOTH_UUID_A2DP_SOURCE);
+#endif
+        } else if (pa_streq(interface, BLUEZ_DEVICE_INTERFACE)) {
+
+            if ((d = pa_hashmap_get(y->devices, path))) {
+                if (d->device_info_valid != 0) {
+                    pa_log_error("Found duplicated D-Bus path for device %s", path);
+                    return;
+                }
+            } else
+                d = device_create(y, path);
+
+            pa_log_debug("Device %s found", d->path);
+
+            parse_device_properties(d, &iface_i, false);
+
+        } else
+            pa_log_debug("Unknown interface %s found, skipping", interface);
+
+        dbus_message_iter_next(&element_i);
+    }
+
+    PA_HASHMAP_FOREACH(d, y->devices, state)
+        if (!d->adapter && d->adapter_path) {
+            d->adapter = pa_hashmap_get(d->discovery->adapters, d->adapter_path);
+            if (!d->adapter) {
+                pa_log_error("Device %s is child of nonexistent adapter %s", d->path, d->adapter_path);
+                d->device_info_valid = -1;
+            }
+        }
+
+    return;
+}
+
+static void get_managed_objects_reply(DBusPendingCall *pending, void *userdata) {
+    pa_dbus_pending *p;
+    pa_bluetooth_discovery *y;
+    DBusMessage *r;
+    DBusMessageIter arg_i, element_i;
+
+    pa_assert_se(p = userdata);
+    pa_assert_se(y = p->context_data);
+    pa_assert_se(r = dbus_pending_call_steal_reply(pending));
+
+    if (dbus_message_is_error(r, DBUS_ERROR_UNKNOWN_METHOD)) {
+        pa_log_warn("BlueZ D-Bus ObjectManager not available");
+        goto finish;
+    }
+
+    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
+        pa_log_error("GetManagedObjects() failed: %s: %s", dbus_message_get_error_name(r), pa_dbus_get_error_message(r));
+        goto finish;
+    }
+
+    if (!dbus_message_iter_init(r, &arg_i) || !pa_streq(dbus_message_get_signature(r), "a{oa{sa{sv}}}")) {
+        pa_log_error("Invalid reply signature for GetManagedObjects()");
+        goto finish;
+    }
+
+    dbus_message_iter_recurse(&arg_i, &element_i);
+    while (dbus_message_iter_get_arg_type(&element_i) == DBUS_TYPE_DICT_ENTRY) {
+        DBusMessageIter dict_i;
+
+        dbus_message_iter_recurse(&element_i, &dict_i);
+
+        parse_interfaces_and_properties(y, &dict_i);
+
+        dbus_message_iter_next(&element_i);
+    }
+
+    y->objects_listed = true;
+
+finish:
+    dbus_message_unref(r);
+
+    PA_LLIST_REMOVE(pa_dbus_pending, y->pending, p);
+    pa_dbus_pending_free(p);
+}
+
+static void get_managed_objects(pa_bluetooth_discovery *y) {
+    DBusMessage *m;
+
+    pa_assert(y);
+
+    pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, "/", "org.freedesktop.DBus.ObjectManager",
+                                                  "GetManagedObjects"));
+    send_and_add_to_pending(y, m, get_managed_objects_reply, NULL);
+}
+
+pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *y, pa_bluetooth_hook_t hook) {
+    pa_assert(y);
+    pa_assert(PA_REFCNT_VALUE(y) > 0);
+
+    return &y->hooks[hook];
+}
+
+static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *userdata) {
+    pa_bluetooth_discovery *y;
+    DBusError err;
+
+    pa_assert(bus);
+    pa_assert(m);
+    pa_assert_se(y = userdata);
+
+    dbus_error_init(&err);
+
+    if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged")) {
+        const char *name, *old_owner, *new_owner;
+
+        if (!dbus_message_get_args(m, &err,
+                                   DBUS_TYPE_STRING, &name,
+                                   DBUS_TYPE_STRING, &old_owner,
+                                   DBUS_TYPE_STRING, &new_owner,
+                                   DBUS_TYPE_INVALID)) {
+            pa_log_error("Failed to parse org.freedesktop.DBus.NameOwnerChanged: %s", err.message);
+            goto fail;
+        }
+
+        if (pa_streq(name, BLUEZ_SERVICE)) {
+            if (old_owner && *old_owner) {
+                pa_log_debug("Bluetooth daemon disappeared");
+                device_remove_all(y);
+                adapter_remove_all(y);
+                y->objects_listed = false;
+            }
+
+            if (new_owner && *new_owner) {
+                pa_log_debug("Bluetooth daemon appeared");
+                get_managed_objects(y);
+            }
+        }
+
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+    } else if (dbus_message_is_signal(m, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded")) {
+        DBusMessageIter arg_i;
+#ifndef __TIZEN_BT__
+        if (!y->objects_listed)
+            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */
+#endif
+        if (!dbus_message_iter_init(m, &arg_i) || !pa_streq(dbus_message_get_signature(m), "oa{sa{sv}}")) {
+            pa_log_error("Invalid signature found in InterfacesAdded");
+            goto fail;
+        }
+
+        parse_interfaces_and_properties(y, &arg_i);
+
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+    } else if (dbus_message_is_signal(m, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved")) {
+        const char *p;
+        DBusMessageIter arg_i;
+        DBusMessageIter element_i;
+
+        if (!y->objects_listed)
+            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */
+
+        if (!dbus_message_iter_init(m, &arg_i) || !pa_streq(dbus_message_get_signature(m), "oas")) {
+            pa_log_error("Invalid signature found in InterfacesRemoved");
+            goto fail;
+        }
+
+        dbus_message_iter_get_basic(&arg_i, &p);
+
+        pa_assert_se(dbus_message_iter_next(&arg_i));
+        pa_assert(dbus_message_iter_get_arg_type(&arg_i) == DBUS_TYPE_ARRAY);
+
+        dbus_message_iter_recurse(&arg_i, &element_i);
+
+        while (dbus_message_iter_get_arg_type(&element_i) == DBUS_TYPE_STRING) {
+            const char *iface;
+
+            dbus_message_iter_get_basic(&element_i, &iface);
+
+            if (pa_streq(iface, BLUEZ_DEVICE_INTERFACE))
+                device_remove(y, p);
+            else if (pa_streq(iface, BLUEZ_ADAPTER_INTERFACE))
+                adapter_remove(y, p);
+
+            dbus_message_iter_next(&element_i);
+        }
+
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    } else if (dbus_message_is_signal(m, "org.freedesktop.DBus.Properties", "PropertiesChanged")) {
+        DBusMessageIter arg_i;
+        const char *iface;
+
+#ifndef __TIZEN_BT__
+        if (!y->objects_listed)
+            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; /* No reply received yet from GetManagedObjects */
+#endif
+
+        if (!dbus_message_iter_init(m, &arg_i) || !pa_streq(dbus_message_get_signature(m), "sa{sv}as")) {
+            pa_log_error("Invalid signature found in PropertiesChanged");
+            goto fail;
+        }
+
+        dbus_message_iter_get_basic(&arg_i, &iface);
+
+        pa_assert_se(dbus_message_iter_next(&arg_i));
+        pa_assert(dbus_message_iter_get_arg_type(&arg_i) == DBUS_TYPE_ARRAY);
+
+        if (pa_streq(iface, BLUEZ_ADAPTER_INTERFACE)) {
+            pa_bluetooth_adapter *a;
+
+            pa_log_debug("Properties changed in adapter %s", dbus_message_get_path(m));
+
+            if (!(a = pa_hashmap_get(y->adapters, dbus_message_get_path(m)))) {
+                pa_log_warn("Properties changed in unknown adapter");
+                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+            }
+
+            parse_adapter_properties(a, &arg_i, true);
+
+        } else if (pa_streq(iface, BLUEZ_DEVICE_INTERFACE)) {
+            pa_bluetooth_device *d;
+
+            pa_log_debug("Properties changed in device %s", dbus_message_get_path(m));
+
+            if (!(d = pa_hashmap_get(y->devices, dbus_message_get_path(m)))) {
+                pa_log_warn("Properties changed in unknown device");
+                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+            }
+
+            if (d->device_info_valid != 1) {
+                pa_log_warn("Properties changed in a device which information is unknown or invalid");
+                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+            }
+
+            parse_device_properties(d, &arg_i, true);
+        } else if (pa_streq(iface, BLUEZ_MEDIA_TRANSPORT_INTERFACE)) {
+            pa_bluetooth_transport *t;
+
+            pa_log_debug("Properties changed in transport %s", dbus_message_get_path(m));
+
+            if (!(t = pa_hashmap_get(y->transports, dbus_message_get_path(m))))
+                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+            parse_transport_properties(t, &arg_i);
+        }
+
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+#ifdef __TIZEN_BT__
+       } else if (dbus_message_is_signal(m, "org.bluez.ag_agent", "SuspendMedia")) {
+               pa_bluetooth_transport *t;
+               pa_log_debug("Signal from ag-agent to Suspend Media");
+               if (!(t = pa_hashmap_first(y->transports)))
+               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+               pa_hook_fire(&t->device->discovery->hooks[PA_BLUETOOTH_HOOK_SCO_STATE_CHANGED], t);
+               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+#endif
+       }
+
+fail:
+    dbus_error_free(&err);
+
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static uint8_t a2dp_default_bitpool(uint8_t freq, uint8_t mode) {
+    /* These bitpool values were chosen based on the A2DP spec recommendation */
+    switch (freq) {
+        case SBC_SAMPLING_FREQ_16000:
+        case SBC_SAMPLING_FREQ_32000:
+            return 53;
+
+        case SBC_SAMPLING_FREQ_44100:
+
+            switch (mode) {
+                case SBC_CHANNEL_MODE_MONO:
+                case SBC_CHANNEL_MODE_DUAL_CHANNEL:
+                    return 31;
+
+                case SBC_CHANNEL_MODE_STEREO:
+                case SBC_CHANNEL_MODE_JOINT_STEREO:
+#if defined(__TIZEN_BT__) && defined(ADJUST_ANDROID_BITPOOL)
+                    return 35;
+#else
+                    return 53;
+#endif
+            }
+
+            pa_log_warn("Invalid channel mode %u", mode);
+            return 53;
+
+        case SBC_SAMPLING_FREQ_48000:
+
+            switch (mode) {
+                case SBC_CHANNEL_MODE_MONO:
+                case SBC_CHANNEL_MODE_DUAL_CHANNEL:
+                    return 29;
+
+                case SBC_CHANNEL_MODE_STEREO:
+                case SBC_CHANNEL_MODE_JOINT_STEREO:
+                    return 51;
+            }
+
+            pa_log_warn("Invalid channel mode %u", mode);
+            return 51;
+    }
+
+    pa_log_warn("Invalid sampling freq %u", freq);
+    return 53;
+}
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+static DBusMessage *endpoint_select_configuration_for_aptx(DBusConnection *c, DBusMessage *m, void *userdata) {
+    a2dp_aptx_t *cap;
+    a2dp_aptx_t config;
+    uint8_t *pconf = (uint8_t *) &config;
+    int size;
+    DBusMessage *r;
+    DBusError e;
+
+    dbus_error_init(&e);
+
+    if (!dbus_message_get_args(m, &e, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &cap, &size, DBUS_TYPE_INVALID)) {
+        pa_log("org.bluez.MediaEndpoint.SelectConfiguration: %s", e.message);
+        dbus_error_free(&e);
+        goto fail;
+    }
+
+    pa_assert(size == sizeof(config));
+
+    memset(&config, 0, sizeof(config));
+
+    if (cap->vendor_id[0] == APTX_VENDOR_ID0 &&
+        cap->vendor_id[1] == APTX_VENDOR_ID1 &&
+        cap->vendor_id[2] == APTX_VENDOR_ID2 &&
+        cap->vendor_id[3] == APTX_VENDOR_ID3 &&
+         cap->codec_id[0] == APTX_CODEC_ID0  &&
+         cap->codec_id[1] == APTX_CODEC_ID1  )
+        pa_log_debug("A2DP_CODEC_NON_A2DP and this is APTX Codec");
+    else {
+        pa_log_debug("A2DP_CODEC_NON_A2DP but this is not APTX Codec");
+        goto fail;
+    }
+
+    memcpy(&config,cap, sizeof(config));
+
+/* The below code shuld be re-written by aptx */
+/* And we should configure pulseaudio freq */
+
+    if (cap->frequency & APTX_SAMPLING_FREQ_44100)
+        config.frequency = APTX_SAMPLING_FREQ_44100;
+    else if (cap->frequency & APTX_SAMPLING_FREQ_48000)
+        config.frequency = APTX_SAMPLING_FREQ_48000;
+    else if (cap->frequency & APTX_SAMPLING_FREQ_32000)
+        config.frequency = APTX_SAMPLING_FREQ_32000;
+    else if (cap->frequency & APTX_SAMPLING_FREQ_16000)
+        config.frequency = APTX_SAMPLING_FREQ_16000;
+    else {
+        pa_log_error("No aptx supported frequencies");
+        goto fail;
+    }
+
+    if (cap->channel_mode & APTX_CHANNEL_MODE_JOINT_STEREO)
+        config.channel_mode = APTX_CHANNEL_MODE_STEREO;
+    else if (cap->channel_mode & APTX_CHANNEL_MODE_STEREO)
+        config.channel_mode = APTX_CHANNEL_MODE_STEREO;
+    else if (cap->channel_mode & APTX_CHANNEL_MODE_DUAL_CHANNEL)
+        config.channel_mode = APTX_CHANNEL_MODE_STEREO;
+    else {
+        pa_log_error("No aptx supported channel modes");
+        goto fail;
+    }
+
+    pa_assert_se(r = dbus_message_new_method_return(m));
+
+    pa_assert_se(dbus_message_append_args(
+                                     r,
+                                     DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pconf, size,
+                                     DBUS_TYPE_INVALID));
+
+    return r;
+
+fail:
+    pa_assert_se(r = (dbus_message_new_error(m, "org.bluez.MediaEndpoint.Error.InvalidArguments",
+                                                        "Unable to select configuration")));
+    return r;
+}
+#endif
+
+const char *pa_bluetooth_profile_to_string(pa_bluetooth_profile_t profile) {
+    switch(profile) {
+        case PA_BLUETOOTH_PROFILE_A2DP_SINK:
+            return "a2dp_sink";
+        case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
+            return "a2dp_source";
+        case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+            return "hsp";
+        case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+            return "hfgw";
+        case PA_BLUETOOTH_PROFILE_OFF:
+            return "off";
+    }
+
+    return NULL;
+}
+
+static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage *m, void *userdata) {
+    pa_bluetooth_discovery *y = userdata;
+    pa_bluetooth_device *d;
+    pa_bluetooth_transport *t;
+    const char *sender, *path, *endpoint_path, *dev_path = NULL, *uuid = NULL;
+#ifdef __TIZEN_BT__
+    uint8_t codec = 0;
+#endif
+    const uint8_t *config = NULL;
+    int size = 0;
+    pa_bluetooth_profile_t p = PA_BLUETOOTH_PROFILE_OFF;
+    DBusMessageIter args, props;
+    DBusMessage *r;
+
+    if (!dbus_message_iter_init(m, &args) || !pa_streq(dbus_message_get_signature(m), "oa{sv}")) {
+        pa_log_error("Invalid signature for method SetConfiguration()");
+        goto fail2;
+    }
+
+    dbus_message_iter_get_basic(&args, &path);
+
+    if (pa_hashmap_get(y->transports, path)) {
+        pa_log_error("Endpoint SetConfiguration(): Transport %s is already configured.", path);
+        goto fail2;
+    }
+
+    pa_assert_se(dbus_message_iter_next(&args));
+
+    dbus_message_iter_recurse(&args, &props);
+    if (dbus_message_iter_get_arg_type(&props) != DBUS_TYPE_DICT_ENTRY)
+        goto fail;
+
+    /* Read transport properties */
+    while (dbus_message_iter_get_arg_type(&props) == DBUS_TYPE_DICT_ENTRY) {
+        const char *key;
+        DBusMessageIter value, entry;
+        int var;
+
+        dbus_message_iter_recurse(&props, &entry);
+        dbus_message_iter_get_basic(&entry, &key);
+
+        dbus_message_iter_next(&entry);
+        dbus_message_iter_recurse(&entry, &value);
+
+        var = dbus_message_iter_get_arg_type(&value);
+
+        if (pa_streq(key, "UUID")) {
+            if (var != DBUS_TYPE_STRING) {
+                pa_log_error("Property %s of wrong type %c", key, (char)var);
+                goto fail;
+            }
+
+            dbus_message_iter_get_basic(&value, &uuid);
+
+            endpoint_path = dbus_message_get_path(m);
+#ifdef BLUETOOTH_APTX_SUPPORT
+            if (pa_streq(endpoint_path, A2DP_SOURCE_ENDPOINT) ||
+               pa_streq(endpoint_path, A2DP_APTX_SOURCE_ENDPOINT)) {
+                if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SOURCE))
+                    p = PA_BLUETOOTH_PROFILE_A2DP_SINK;
+            }
+#else
+            if (pa_streq(endpoint_path, A2DP_SOURCE_ENDPOINT)) {
+                if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SOURCE))
+                    p = PA_BLUETOOTH_PROFILE_A2DP_SINK;
+            }
+#endif
+            else if (pa_streq(endpoint_path, A2DP_SINK_ENDPOINT)) {
+                if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SINK))
+                    p = PA_BLUETOOTH_PROFILE_A2DP_SOURCE;
+            }
+
+            if (p == PA_BLUETOOTH_PROFILE_OFF) {
+                pa_log_error("UUID %s of transport %s incompatible with endpoint %s", uuid, path, endpoint_path);
+                goto fail;
+            }
+#ifdef __TIZEN_BT__
+        } else if (pa_streq(key, "Codec")) {
+           if (var != DBUS_TYPE_BYTE) {
+               pa_log_error("Property %s of wrong type %c", key, (char)var);
+               goto fail;
+           }
+
+           dbus_message_iter_get_basic(&value, &codec);
+#endif
+        } else if (pa_streq(key, "Device")) {
+            if (var != DBUS_TYPE_OBJECT_PATH) {
+                pa_log_error("Property %s of wrong type %c", key, (char)var);
+                goto fail;
+            }
+
+            dbus_message_iter_get_basic(&value, &dev_path);
+        } else if (pa_streq(key, "Configuration")) {
+            DBusMessageIter array;
+            a2dp_sbc_t *c;
+
+            if (var != DBUS_TYPE_ARRAY) {
+                pa_log_error("Property %s of wrong type %c", key, (char)var);
+                goto fail;
+            }
+
+            dbus_message_iter_recurse(&value, &array);
+            var = dbus_message_iter_get_arg_type(&array);
+            if (var != DBUS_TYPE_BYTE) {
+                pa_log_error("%s is an array of wrong type %c", key, (char)var);
+                goto fail;
+            }
+
+            dbus_message_iter_get_fixed_array(&array, &config, &size);
+#ifndef BLUETOOTH_APTX_SUPPORT
+            if (size != sizeof(a2dp_sbc_t)) {
+                pa_log_error("Configuration array of invalid size");
+                goto fail;
+            }
+
+            c = (a2dp_sbc_t *) config;
+
+            if (c->frequency != SBC_SAMPLING_FREQ_16000 && c->frequency != SBC_SAMPLING_FREQ_32000 &&
+                c->frequency != SBC_SAMPLING_FREQ_44100 && c->frequency != SBC_SAMPLING_FREQ_48000) {
+                pa_log_error("Invalid sampling frequency in configuration");
+                goto fail;
+            }
+
+            if (c->channel_mode != SBC_CHANNEL_MODE_MONO && c->channel_mode != SBC_CHANNEL_MODE_DUAL_CHANNEL &&
+                c->channel_mode != SBC_CHANNEL_MODE_STEREO && c->channel_mode != SBC_CHANNEL_MODE_JOINT_STEREO) {
+                pa_log_error("Invalid channel mode in configuration");
+                goto fail;
+            }
+
+            if (c->allocation_method != SBC_ALLOCATION_SNR && c->allocation_method != SBC_ALLOCATION_LOUDNESS) {
+                pa_log_error("Invalid allocation method in configuration");
+                goto fail;
+            }
+
+            if (c->subbands != SBC_SUBBANDS_4 && c->subbands != SBC_SUBBANDS_8) {
+                pa_log_error("Invalid SBC subbands in configuration");
+                goto fail;
+            }
+
+            if (c->block_length != SBC_BLOCK_LENGTH_4 && c->block_length != SBC_BLOCK_LENGTH_8 &&
+                c->block_length != SBC_BLOCK_LENGTH_12 && c->block_length != SBC_BLOCK_LENGTH_16) {
+                pa_log_error("Invalid block length in configuration");
+                goto fail;
+            }
+#endif
+        }
+
+        dbus_message_iter_next(&props);
+    }
+
+    if ((d = pa_hashmap_get(y->devices, dev_path))) {
+        if (d->device_info_valid == -1) {
+            pa_log_error("Information about device %s is invalid", dev_path);
+            goto fail2;
+        }
+    } else {
+        /* InterfacesAdded signal is probably on it's way, device_info_valid is kept as 0. */
+        pa_log_warn("SetConfiguration() received for unknown device %s", dev_path);
+        d = device_create(y, dev_path);
+    }
+
+    if (d->transports[p] != NULL) {
+        pa_log_error("Cannot configure transport %s because profile %s is already used", path, pa_bluetooth_profile_to_string(p));
+        goto fail2;
+    }
+
+    sender = dbus_message_get_sender(m);
+
+    pa_assert_se(r = dbus_message_new_method_return(m));
+    pa_assert_se(dbus_connection_send(pa_dbus_connection_get(y->connection), r, NULL));
+    dbus_message_unref(r);
+
+    d->transports[p] = t = pa_bluetooth_transport_new(d, sender, path, p, config, size);
+#ifdef __TIZEN_BT__
+    t->codec = codec;
+    d->transports[p] = t;
+#endif
+
+    t->acquire = bluez5_transport_acquire_cb;
+    t->release = bluez5_transport_release_cb;
+    pa_bluetooth_transport_put(t);
+
+    pa_log_debug("Transport %s available for profile %s", t->path, pa_bluetooth_profile_to_string(t->profile));
+
+    return NULL;
+
+fail:
+    pa_log_error("Endpoint SetConfiguration(): invalid arguments");
+
+fail2:
+    pa_assert_se(r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments", "Unable to set configuration"));
+    return r;
+}
+
+static DBusMessage *endpoint_select_configuration(DBusConnection *conn, DBusMessage *m, void *userdata) {
+    pa_bluetooth_discovery *y = userdata;
+    a2dp_sbc_t *cap, config;
+    uint8_t *pconf = (uint8_t *) &config;
+    int i, size;
+    DBusMessage *r;
+    DBusError err;
+
+    static const struct {
+        uint32_t rate;
+        uint8_t cap;
+    } freq_table[] = {
+        { 16000U, SBC_SAMPLING_FREQ_16000 },
+        { 32000U, SBC_SAMPLING_FREQ_32000 },
+        { 44100U, SBC_SAMPLING_FREQ_44100 },
+        { 48000U, SBC_SAMPLING_FREQ_48000 }
+    };
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+    if (dbus_message_has_path(m, A2DP_APTX_SOURCE_ENDPOINT))
+        return endpoint_select_configuration_for_aptx(conn ,m ,userdata);
+#endif
+
+    dbus_error_init(&err);
+
+    if (!dbus_message_get_args(m, &err, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &cap, &size, DBUS_TYPE_INVALID)) {
+        pa_log_error("Endpoint SelectConfiguration(): %s", err.message);
+        dbus_error_free(&err);
+        goto fail;
+    }
+
+    if (size != sizeof(config)) {
+        pa_log_error("Capabilities array has invalid size");
+        goto fail;
+    }
+
+    pa_zero(config);
+
+    /* Find the lowest freq that is at least as high as the requested sampling rate */
+    for (i = 0; (unsigned) i < PA_ELEMENTSOF(freq_table); i++)
+        if (freq_table[i].rate >= y->core->default_sample_spec.rate && (cap->frequency & freq_table[i].cap)) {
+            config.frequency = freq_table[i].cap;
+            break;
+        }
+
+    if ((unsigned) i == PA_ELEMENTSOF(freq_table)) {
+        for (--i; i >= 0; i--) {
+            if (cap->frequency & freq_table[i].cap) {
+                config.frequency = freq_table[i].cap;
+                break;
+            }
+        }
+
+        if (i < 0) {
+            pa_log_error("Not suitable sample rate");
+            goto fail;
+        }
+    }
+
+    pa_assert((unsigned) i < PA_ELEMENTSOF(freq_table));
+
+    if (y->core->default_sample_spec.channels <= 1) {
+        if (cap->channel_mode & SBC_CHANNEL_MODE_MONO)
+            config.channel_mode = SBC_CHANNEL_MODE_MONO;
+        else if (cap->channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO)
+            config.channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
+        else if (cap->channel_mode & SBC_CHANNEL_MODE_STEREO)
+            config.channel_mode = SBC_CHANNEL_MODE_STEREO;
+        else if (cap->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL)
+            config.channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
+        else {
+            pa_log_error("No supported channel modes");
+            goto fail;
+        }
+    }
+
+    if (y->core->default_sample_spec.channels >= 2) {
+        if (cap->channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO)
+            config.channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
+        else if (cap->channel_mode & SBC_CHANNEL_MODE_STEREO)
+            config.channel_mode = SBC_CHANNEL_MODE_STEREO;
+        else if (cap->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL)
+            config.channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
+        else if (cap->channel_mode & SBC_CHANNEL_MODE_MONO)
+            config.channel_mode = SBC_CHANNEL_MODE_MONO;
+        else {
+            pa_log_error("No supported channel modes");
+            goto fail;
+        }
+    }
+
+    if (cap->block_length & SBC_BLOCK_LENGTH_16)
+        config.block_length = SBC_BLOCK_LENGTH_16;
+    else if (cap->block_length & SBC_BLOCK_LENGTH_12)
+        config.block_length = SBC_BLOCK_LENGTH_12;
+    else if (cap->block_length & SBC_BLOCK_LENGTH_8)
+        config.block_length = SBC_BLOCK_LENGTH_8;
+    else if (cap->block_length & SBC_BLOCK_LENGTH_4)
+        config.block_length = SBC_BLOCK_LENGTH_4;
+    else {
+        pa_log_error("No supported block lengths");
+        goto fail;
+    }
+
+    if (cap->subbands & SBC_SUBBANDS_8)
+        config.subbands = SBC_SUBBANDS_8;
+    else if (cap->subbands & SBC_SUBBANDS_4)
+        config.subbands = SBC_SUBBANDS_4;
+    else {
+        pa_log_error("No supported subbands");
+        goto fail;
+    }
+
+    if (cap->allocation_method & SBC_ALLOCATION_LOUDNESS)
+        config.allocation_method = SBC_ALLOCATION_LOUDNESS;
+    else if (cap->allocation_method & SBC_ALLOCATION_SNR)
+        config.allocation_method = SBC_ALLOCATION_SNR;
+
+    config.min_bitpool = (uint8_t) PA_MAX(MIN_BITPOOL, cap->min_bitpool);
+    config.max_bitpool = (uint8_t) PA_MIN(a2dp_default_bitpool(config.frequency, config.channel_mode), cap->max_bitpool);
+
+    if (config.min_bitpool > config.max_bitpool)
+        goto fail;
+
+    pa_assert_se(r = dbus_message_new_method_return(m));
+    pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pconf, size, DBUS_TYPE_INVALID));
+
+    return r;
+
+fail:
+    pa_assert_se(r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments", "Unable to select configuration"));
+    return r;
+}
+
+static DBusMessage *endpoint_clear_configuration(DBusConnection *conn, DBusMessage *m, void *userdata) {
+    pa_bluetooth_discovery *y = userdata;
+    pa_bluetooth_transport *t;
+    DBusMessage *r;
+    DBusError err;
+    const char *path;
+
+    dbus_error_init(&err);
+
+    if (!dbus_message_get_args(m, &err, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) {
+        pa_log_error("Endpoint ClearConfiguration(): %s", err.message);
+        dbus_error_free(&err);
+        goto fail;
+    }
+
+    if ((t = pa_hashmap_get(y->transports, path))) {
+        pa_log_debug("Clearing transport %s profile %s", t->path, pa_bluetooth_profile_to_string(t->profile));
+        transport_state_changed(t, PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED);
+        pa_bluetooth_transport_free(t);
+    }
+
+    pa_assert_se(r = dbus_message_new_method_return(m));
+
+    return r;
+
+fail:
+    pa_assert_se(r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments", "Unable to clear configuration"));
+    return r;
+}
+
+static DBusMessage *endpoint_release(DBusConnection *conn, DBusMessage *m, void *userdata) {
+    DBusMessage *r;
+
+    pa_assert_se(r = dbus_message_new_error(m, BLUEZ_MEDIA_ENDPOINT_INTERFACE ".Error.NotImplemented",
+                                            "Method not implemented"));
+
+    return r;
+}
+
+#ifdef __TIZEN_BT__
+static DBusMessage *endpoint_suspend_media(DBusConnection *conn, DBusMessage *m, void *userdata) {
+    pa_bluetooth_discovery *y = userdata;
+    pa_bluetooth_transport *t;
+    DBusMessage *r;
+    const char *path;
+
+    pa_log_debug("dbus Call from to Suspend Media");
+    if (!(t = pa_hashmap_first(y->transports)))
+        goto fail;
+
+    pa_hook_fire(&t->device->discovery->hooks[PA_BLUETOOTH_HOOK_SCO_STATE_CHANGED], t);
+
+    pa_assert_se(r = dbus_message_new_method_return(m));
+
+    return r;
+
+fail:
+    pa_assert_se(r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments", "Unable to clear configuration"));
+    return r;
+}
+#endif
+
+static DBusHandlerResult endpoint_handler(DBusConnection *c, DBusMessage *m, void *userdata) {
+    struct pa_bluetooth_discovery *y = userdata;
+    DBusMessage *r = NULL;
+    const char *path, *interface, *member;
+
+    pa_assert(y);
+
+    path = dbus_message_get_path(m);
+    interface = dbus_message_get_interface(m);
+    member = dbus_message_get_member(m);
+
+    pa_log_debug("dbus: path=%s, interface=%s, member=%s", path, interface, member);
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+    if (!pa_streq(path, A2DP_SOURCE_ENDPOINT) && !pa_streq(path, A2DP_SINK_ENDPOINT)
+         && !pa_streq(path,A2DP_APTX_SOURCE_ENDPOINT))
+       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+#else
+    if (!pa_streq(path, A2DP_SOURCE_ENDPOINT) && !pa_streq(path, A2DP_SINK_ENDPOINT))
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+#endif /* BLUETOOTH_APTX_SUPPORT */
+
+    if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
+        const char *xml = ENDPOINT_INTROSPECT_XML;
+
+        pa_assert_se(r = dbus_message_new_method_return(m));
+        pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID));
+
+    } else if (dbus_message_is_method_call(m, BLUEZ_MEDIA_ENDPOINT_INTERFACE, "SetConfiguration"))
+        r = endpoint_set_configuration(c, m, userdata);
+    else if (dbus_message_is_method_call(m, BLUEZ_MEDIA_ENDPOINT_INTERFACE, "SelectConfiguration"))
+        r = endpoint_select_configuration(c, m, userdata);
+    else if (dbus_message_is_method_call(m, BLUEZ_MEDIA_ENDPOINT_INTERFACE, "ClearConfiguration"))
+        r = endpoint_clear_configuration(c, m, userdata);
+    else if (dbus_message_is_method_call(m, BLUEZ_MEDIA_ENDPOINT_INTERFACE, "Release"))
+        r = endpoint_release(c, m, userdata);
+#ifdef __TIZEN_BT__
+    else if (dbus_message_is_method_call(m, BLUEZ_MEDIA_ENDPOINT_INTERFACE, "SuspendMedia"))
+               endpoint_suspend_media(c, m, userdata);
+#endif
+    else
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    if (r) {
+        pa_assert_se(dbus_connection_send(pa_dbus_connection_get(y->connection), r, NULL));
+        dbus_message_unref(r);
+    }
+
+    return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static void endpoint_init(pa_bluetooth_discovery *y, pa_bluetooth_profile_t profile) {
+    static const DBusObjectPathVTable vtable_endpoint = {
+        .message_function = endpoint_handler,
+    };
+
+    pa_assert(y);
+
+    switch(profile) {
+        case PA_BLUETOOTH_PROFILE_A2DP_SINK:
+            pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(y->connection), A2DP_SOURCE_ENDPOINT,
+                                                              &vtable_endpoint, y));
+#ifdef BLUETOOTH_APTX_SUPPORT
+            pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(y->connection), A2DP_APTX_SOURCE_ENDPOINT,
+                                                              &vtable_endpoint, y));
+#endif
+            break;
+        case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
+            pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(y->connection), A2DP_SINK_ENDPOINT,
+                                                              &vtable_endpoint, y));
+            break;
+        default:
+            pa_assert_not_reached();
+            break;
+    }
+}
+
+static void endpoint_done(pa_bluetooth_discovery *y, pa_bluetooth_profile_t profile) {
+    pa_assert(y);
+
+    switch(profile) {
+        case PA_BLUETOOTH_PROFILE_A2DP_SINK:
+            dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), A2DP_SOURCE_ENDPOINT);
+#ifdef BLUETOOTH_APTX_SUPPORT
+            dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), A2DP_APTX_SOURCE_ENDPOINT);
+#endif
+            break;
+        case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
+            dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), A2DP_SINK_ENDPOINT);
+            break;
+        default:
+            pa_assert_not_reached();
+            break;
+    }
+}
+
+pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) {
+    pa_bluetooth_discovery *y;
+    DBusError err;
+    DBusConnection *conn;
+    unsigned i;
+
+    y = pa_xnew0(pa_bluetooth_discovery, 1);
+    PA_REFCNT_INIT(y);
+    y->core = c;
+    y->adapters = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    y->devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    y->transports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    PA_LLIST_HEAD_INIT(pa_dbus_pending, y->pending);
+
+    for (i = 0; i < PA_BLUETOOTH_HOOK_MAX; i++)
+        pa_hook_init(&y->hooks[i], y);
+
+    pa_shared_set(c, "bluetooth-discovery", y);
+
+    dbus_error_init(&err);
+
+    if (!(y->connection = pa_dbus_bus_get(y->core, DBUS_BUS_SYSTEM, &err))) {
+        pa_log_error("Failed to get D-Bus connection: %s", err.message);
+        goto fail;
+    }
+
+    conn = pa_dbus_connection_get(y->connection);
+#ifdef __TIZEN_BT__
+    if (dbus_bus_request_name(conn, "org.PulseAudio2", DBUS_NAME_FLAG_REPLACE_EXISTING, &err)
+                                       != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+       pa_log_error("Failed to set D-Bus name: %s", err.message);
+        goto fail;
+    }
+#endif
+    /* dynamic detection of bluetooth audio devices */
+    if (!dbus_connection_add_filter(conn, filter_cb, y, NULL)) {
+        pa_log_error("Failed to add filter function");
+        goto fail;
+    }
+    y->filter_added = true;
+
+    if (pa_dbus_add_matches(conn, &err,
+            "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged'"
+            ",arg0='" BLUEZ_SERVICE "'",
+            "type='signal',sender='" BLUEZ_SERVICE "',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded'",
+            "type='signal',sender='" BLUEZ_SERVICE "',interface='org.freedesktop.DBus.ObjectManager',"
+            "member='InterfacesRemoved'",
+            "type='signal',sender='" BLUEZ_SERVICE "',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'"
+            ",arg0='" BLUEZ_ADAPTER_INTERFACE "'",
+            "type='signal',sender='" BLUEZ_SERVICE "',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'"
+            ",arg0='" BLUEZ_DEVICE_INTERFACE "'",
+            "type='signal',sender='" BLUEZ_SERVICE "',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'"
+            ",arg0='" BLUEZ_MEDIA_TRANSPORT_INTERFACE "'",
+#ifdef __TIZEN_BT__
+            "type='signal',interface='org.bluez.ag_agent',member='SuspendMedia'",
+#endif
+            NULL) < 0) {
+        pa_log_error("Failed to add D-Bus matches: %s", err.message);
+        goto fail;
+    }
+    y->matches_added = true;
+
+    endpoint_init(y, PA_BLUETOOTH_PROFILE_A2DP_SINK);
+
+#ifndef __TIZEN_BT__
+    endpoint_init(y, PA_BLUETOOTH_PROFILE_A2DP_SOURCE);
+#endif
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+    endpoint_init(y, PA_BLUETOOTH_PROFILE_A2DP_SOURCE);
+#endif
+
+#ifndef __TIZEN_BT__
+    y->hf_audio_agent = hf_audio_agent_init(c);
+#endif
+
+    get_managed_objects(y);
+
+    return y;
+
+fail:
+    pa_bluetooth_discovery_unref(y);
+    dbus_error_free(&err);
+
+    return NULL;
+}
+
+pa_bluetooth_discovery* pa_bluetooth_discovery_ref(pa_bluetooth_discovery *y) {
+    pa_assert(y);
+    pa_assert(PA_REFCNT_VALUE(y) > 0);
+
+    PA_REFCNT_INC(y);
+
+    return y;
+}
+
+void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) {
+    pa_assert(y);
+    pa_assert(PA_REFCNT_VALUE(y) > 0);
+
+    if (PA_REFCNT_DEC(y) > 0)
+        return;
+
+    pa_dbus_free_pending_list(&y->pending);
+
+    if (y->devices) {
+        device_remove_all(y);
+#ifdef __TIZEN_BT__
+        pa_hashmap_free(y->devices, NULL);
+#else
+        pa_hashmap_free(y->devices);
+#endif
+    }
+
+    if (y->adapters) {
+        adapter_remove_all(y);
+#ifdef __TIZEN_BT__
+        pa_hashmap_free(y->adapters, NULL);
+#else
+        pa_hashmap_free(y->adapters);
+#endif
+    }
+
+    if (y->transports) {
+        pa_assert(pa_hashmap_isempty(y->transports));
+#ifdef __TIZEN_BT__
+        pa_hashmap_free(y->transports, NULL);
+#else
+        pa_hashmap_free(y->transports);
+#endif
+    }
+
+#ifndef __TIZEN_BT__
+    if (y->hf_audio_agent)
+        hf_audio_agent_done(y->hf_audio_agent);
+#endif
+
+    if (y->connection) {
+
+        if (y->matches_added)
+            pa_dbus_remove_matches(pa_dbus_connection_get(y->connection),
+                "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',"
+                "arg0='" BLUEZ_SERVICE "'",
+                "type='signal',sender='" BLUEZ_SERVICE "',interface='org.freedesktop.DBus.ObjectManager',"
+                "member='InterfacesAdded'",
+                "type='signal',sender='" BLUEZ_SERVICE "',interface='org.freedesktop.DBus.ObjectManager',"
+                "member='InterfacesRemoved'",
+                "type='signal',sender='" BLUEZ_SERVICE "',interface='org.freedesktop.DBus.Properties',"
+                "member='PropertiesChanged',arg0='" BLUEZ_ADAPTER_INTERFACE "'",
+                "type='signal',sender='" BLUEZ_SERVICE "',interface='org.freedesktop.DBus.Properties',"
+                "member='PropertiesChanged',arg0='" BLUEZ_DEVICE_INTERFACE "'",
+                "type='signal',sender='" BLUEZ_SERVICE "',interface='org.freedesktop.DBus.Properties',"
+                "member='PropertiesChanged',arg0='" BLUEZ_MEDIA_TRANSPORT_INTERFACE "'",
+#ifdef __TIZEN_BT__
+                 "type='signal',interface='org.bluez.ag_agent',member='SuspendMedia'",
+#endif
+                NULL);
+
+        if (y->filter_added)
+            dbus_connection_remove_filter(pa_dbus_connection_get(y->connection), filter_cb, y);
+
+        endpoint_done(y, PA_BLUETOOTH_PROFILE_A2DP_SINK);
+
+#ifndef __TIZEN_BT__
+        endpoint_done(y, PA_BLUETOOTH_PROFILE_A2DP_SOURCE);
+#endif
+#ifdef BLUETOOTH_APTX_SUPPORT
+        endpoint_done(y, PA_BLUETOOTH_PROFILE_A2DP_SOURCE);
+#endif
+
+        pa_dbus_connection_unref(y->connection);
+    }
+
+    pa_shared_remove(y->core, "bluetooth-discovery");
+    pa_xfree(y);
+}
diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h
new file mode 100644 (file)
index 0000000..ad1f9d1
--- /dev/null
@@ -0,0 +1,135 @@
+#ifndef foobluez5utilhfoo
+#define foobluez5utilhfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2008-2013 João Paulo Rechi Vita
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <pulsecore/core.h>
+
+#define PA_BLUETOOTH_UUID_A2DP_SOURCE "0000110a-0000-1000-8000-00805f9b34fb"
+#define PA_BLUETOOTH_UUID_A2DP_SINK   "0000110b-0000-1000-8000-00805f9b34fb"
+#define PA_BLUETOOTH_UUID_HSP_HS      "00001108-0000-1000-8000-00805f9b34fb"
+#define PA_BLUETOOTH_UUID_HSP_AG      "00001112-0000-1000-8000-00805f9b34fb"
+#define PA_BLUETOOTH_UUID_HFP_HF      "0000111e-0000-1000-8000-00805f9b34fb"
+#define PA_BLUETOOTH_UUID_HFP_AG      "0000111f-0000-1000-8000-00805f9b34fb"
+
+typedef struct pa_bluetooth_transport pa_bluetooth_transport;
+typedef struct pa_bluetooth_device pa_bluetooth_device;
+typedef struct pa_bluetooth_adapter pa_bluetooth_adapter;
+typedef struct pa_bluetooth_discovery pa_bluetooth_discovery;
+
+typedef enum pa_bluetooth_hook {
+    PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED,          /* Call data: pa_bluetooth_device */
+    PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED,            /* Call data: pa_bluetooth_transport */
+#ifdef __TIZEN_BT__
+    PA_BLUETOOTH_HOOK_SCO_STATE_CHANGED,            /* Call data: pa_bluetooth_transport */
+#endif
+    PA_BLUETOOTH_HOOK_MAX
+} pa_bluetooth_hook_t;
+
+typedef enum profile {
+    PA_BLUETOOTH_PROFILE_A2DP_SINK,
+    PA_BLUETOOTH_PROFILE_A2DP_SOURCE,
+    PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT,
+    PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY,
+    PA_BLUETOOTH_PROFILE_OFF
+} pa_bluetooth_profile_t;
+#define PA_BLUETOOTH_PROFILE_COUNT PA_BLUETOOTH_PROFILE_OFF
+
+typedef enum pa_bluetooth_transport_state {
+    PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED,
+    PA_BLUETOOTH_TRANSPORT_STATE_IDLE,
+    PA_BLUETOOTH_TRANSPORT_STATE_PLAYING
+} pa_bluetooth_transport_state_t;
+
+typedef int (*pa_bluetooth_transport_acquire_cb)(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu);
+typedef void (*pa_bluetooth_transport_release_cb)(pa_bluetooth_transport *t);
+
+struct pa_bluetooth_transport {
+    pa_bluetooth_device *device;
+
+    char *owner;
+    char *path;
+    pa_bluetooth_profile_t profile;
+
+    uint8_t codec;
+    uint8_t *config;
+    size_t config_size;
+
+    pa_bluetooth_transport_state_t state;
+
+    pa_bluetooth_transport_acquire_cb acquire;
+    pa_bluetooth_transport_release_cb release;
+    void *userdata;
+};
+
+struct pa_bluetooth_device {
+    pa_bluetooth_discovery *discovery;
+    pa_bluetooth_adapter *adapter;
+
+    int device_info_valid;      /* 0: no results yet; 1: good results; -1: bad results ... */
+
+    /* Device information */
+    char *path;
+    char *adapter_path;
+    char *alias;
+    char *address;
+    uint32_t class_of_device;
+    pa_hashmap *uuids;
+
+    pa_bluetooth_transport *transports[PA_BLUETOOTH_PROFILE_COUNT];
+};
+
+struct pa_bluetooth_adapter {
+    pa_bluetooth_discovery *discovery;
+    char *path;
+    char *address;
+};
+
+pa_bluetooth_transport *pa_bluetooth_transport_new(pa_bluetooth_device *d, const char *owner, const char *path,
+                                                   pa_bluetooth_profile_t p, const uint8_t *config, size_t size);
+
+void pa_bluetooth_transport_put(pa_bluetooth_transport *t);
+void pa_bluetooth_transport_free(pa_bluetooth_transport *t);
+
+bool pa_bluetooth_device_any_transport_connected(const pa_bluetooth_device *d);
+#ifdef __TIZEN_BT__
+bool pa_bluetooth_device_sink_transport_connected(const pa_bluetooth_device *d);
+#endif
+
+pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_path(pa_bluetooth_discovery *y, const char *path);
+pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_address(pa_bluetooth_discovery *y, const char *remote, const char *local);
+
+pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *y, pa_bluetooth_hook_t hook);
+
+const char *pa_bluetooth_profile_to_string(pa_bluetooth_profile_t profile);
+
+pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *core);
+pa_bluetooth_discovery* pa_bluetooth_discovery_ref(pa_bluetooth_discovery *y);
+void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y);
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+int pa_load_aptx(const char *aptx_lib_name);
+int pa_unload_aptx(void);
+void* pa_aptx_get_handle(void);
+#endif
+
+#endif
diff --git a/src/modules/bluetooth/hfaudioagent-null.c b/src/modules/bluetooth/hfaudioagent-null.c
new file mode 100644 (file)
index 0000000..96fca06
--- /dev/null
@@ -0,0 +1,37 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2013 João Paulo Rechi Vita
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulsecore/log.h>
+
+#include "hfaudioagent.h"
+
+hf_audio_agent_data *hf_audio_agent_init(pa_core *c) {
+    pa_log_debug("HandsfreeAudioAgent API support disabled");
+    return NULL;
+}
+
+void hf_audio_agent_done(hf_audio_agent_data *data) {
+    /* Nothing to do here */
+}
diff --git a/src/modules/bluetooth/hfaudioagent-ofono.c b/src/modules/bluetooth/hfaudioagent-ofono.c
new file mode 100644 (file)
index 0000000..8badabd
--- /dev/null
@@ -0,0 +1,680 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2013 João Paulo Rechi Vita
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-shared.h>
+#include <pulsecore/shared.h>
+
+#include "bluez5-util.h"
+
+#include "hfaudioagent.h"
+
+#define HFP_AUDIO_CODEC_CVSD    0x01
+#define HFP_AUDIO_CODEC_MSBC    0x02
+
+#define OFONO_SERVICE "org.ofono"
+#define HF_AUDIO_AGENT_INTERFACE OFONO_SERVICE ".HandsfreeAudioAgent"
+#define HF_AUDIO_MANAGER_INTERFACE OFONO_SERVICE ".HandsfreeAudioManager"
+
+#define HF_AUDIO_AGENT_PATH "/HandsfreeAudioAgent"
+
+#define HF_AUDIO_AGENT_XML                                          \
+    DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                       \
+    "<node>"                                                        \
+    "  <interface name=\"org.freedesktop.DBus.Introspectable\">"    \
+    "    <method name=\"Introspect\">"                              \
+    "      <arg direction=\"out\" type=\"s\" />"                    \
+    "    </method>"                                                 \
+    "  </interface>"                                                \
+    "  <interface name=\"org.ofono.HandsfreeAudioAgent\">"          \
+    "    <method name=\"Release\">"                                 \
+    "    </method>"                                                 \
+    "    <method name=\"NewConnection\">"                           \
+    "      <arg direction=\"in\"  type=\"o\" name=\"card_path\" />" \
+    "      <arg direction=\"in\"  type=\"h\" name=\"sco_fd\" />"    \
+    "      <arg direction=\"in\"  type=\"y\" name=\"codec\" />"     \
+    "    </method>"                                                 \
+    "  </interface>"                                                \
+    "</node>"
+
+typedef struct hf_audio_card {
+    char *path;
+    char *remote;
+    char *local;
+
+    int fd;
+    uint8_t codec;
+
+    pa_bluetooth_transport *transport;
+} hf_audio_card;
+
+struct hf_audio_agent_data {
+    pa_core *core;
+    pa_dbus_connection *connection;
+    pa_bluetooth_discovery *discovery;
+
+    bool filter_added;
+    char *ofono_bus_id;
+    pa_hashmap *hf_audio_cards;
+
+    PA_LLIST_HEAD(pa_dbus_pending, pending);
+};
+
+static pa_dbus_pending* pa_bluetooth_dbus_send_and_add_to_pending(hf_audio_agent_data *hfdata, DBusMessage *m,
+                                                                  DBusPendingCallNotifyFunction func, void *call_data) {
+    pa_dbus_pending *p;
+    DBusPendingCall *call;
+
+    pa_assert(hfdata);
+    pa_assert(m);
+
+    pa_assert_se(dbus_connection_send_with_reply(pa_dbus_connection_get(hfdata->connection), m, &call, -1));
+
+    p = pa_dbus_pending_new(pa_dbus_connection_get(hfdata->connection), m, call, hfdata, call_data);
+    PA_LLIST_PREPEND(pa_dbus_pending, hfdata->pending, p);
+    dbus_pending_call_set_notify(call, func, p, NULL);
+
+    return p;
+}
+
+static hf_audio_card *hf_audio_card_new(hf_audio_agent_data *hfdata, const char *path) {
+    hf_audio_card *hfac = pa_xnew0(hf_audio_card, 1);
+
+    hfac->path = pa_xstrdup(path);
+    hfac->fd = -1;
+
+    return hfac;
+}
+
+static void hf_audio_card_free(void *data) {
+    hf_audio_card *hfac = data;
+
+    pa_assert(hfac);
+
+    pa_bluetooth_transport_free(hfac->transport);
+    pa_xfree(hfac->path);
+    pa_xfree(hfac->remote);
+    pa_xfree(hfac->local);
+    pa_xfree(hfac);
+}
+
+static int hf_audio_agent_transport_acquire(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) {
+    hf_audio_agent_data *hfdata = t->userdata;
+    hf_audio_card *hfac = pa_hashmap_get(hfdata->hf_audio_cards, t->path);
+
+    if (hfac->fd < 0) {
+        DBusMessage *m;
+
+        pa_assert_se(m = dbus_message_new_method_call(t->owner, t->path, "org.ofono.HandsfreeAudioCard", "Connect"));
+        pa_assert_se(dbus_connection_send(pa_dbus_connection_get(hfdata->connection), m, NULL));
+
+        return -1;
+    }
+
+    /* The correct block size should take into account the SCO MTU from
+     * the Bluetooth adapter and (for adapters in the USB bus) the MxPS
+     * value from the Isoc USB endpoint in use by btusb and should be
+     * made available to userspace by the Bluetooth kernel subsystem.
+     * Meanwhile the empiric value 48 will be used. */
+    if (imtu)
+        *imtu = 48;
+    if (omtu)
+        *omtu = 48;
+
+    if (hfac) {
+        t->codec = hfac->codec;
+        return hfac->fd;
+    } else
+        return -1;
+}
+
+static void hf_audio_agent_transport_release(pa_bluetooth_transport *t) {
+    hf_audio_agent_data *hfdata = t->userdata;
+    hf_audio_card *hfac = pa_hashmap_get(hfdata->hf_audio_cards, t->path);
+
+    if (hfac) {
+        shutdown(hfac->fd, SHUT_RDWR);
+        hfac->fd = -1;
+    }
+}
+
+static void hf_audio_agent_card_found(hf_audio_agent_data *hfdata, const char *path, DBusMessageIter *props_i) {
+    DBusMessageIter i, value_i;
+    const char *key, *value;
+    hf_audio_card *hfac;
+    pa_bluetooth_device *d;
+
+    pa_assert(hfdata);
+    pa_assert(path);
+    pa_assert(props_i);
+
+    pa_log_debug("New HF card found: %s", path);
+
+    hfac = hf_audio_card_new(hfdata, path);
+
+    while (dbus_message_iter_get_arg_type(props_i) != DBUS_TYPE_INVALID) {
+        char c;
+
+        if ((c = dbus_message_iter_get_arg_type(props_i)) != DBUS_TYPE_DICT_ENTRY) {
+            pa_log_error("Invalid properties for %s: expected \'e\', received \'%c\'", path, c);
+            goto fail;
+        }
+
+        dbus_message_iter_recurse(props_i, &i);
+
+        if ((c = dbus_message_iter_get_arg_type(&i)) != DBUS_TYPE_STRING) {
+            pa_log_error("Invalid properties for %s: expected \'s\', received \'%c\'", path, c);
+            goto fail;
+        }
+
+        dbus_message_iter_get_basic(&i, &key);
+        dbus_message_iter_next(&i);
+
+        if ((c = dbus_message_iter_get_arg_type(&i)) != DBUS_TYPE_VARIANT) {
+            pa_log_error("Invalid properties for %s: expected \'v\', received \'%c\'", path, c);
+            goto fail;
+        }
+
+        dbus_message_iter_recurse(&i, &value_i);
+
+        if ((c = dbus_message_iter_get_arg_type(&value_i)) != DBUS_TYPE_STRING) {
+            pa_log_error("Invalid properties for %s: expected \'s\', received \'%c\'", path, c);
+            goto fail;
+        }
+
+        dbus_message_iter_get_basic(&value_i, &value);
+
+        if (pa_streq(key, "RemoteAddress"))
+            hfac->remote = pa_xstrdup(value);
+        else if (pa_streq(key, "LocalAddress"))
+            hfac->local = pa_xstrdup(value);
+
+        pa_log_debug("%s: %s", key, value);
+
+        dbus_message_iter_next(props_i);
+    }
+
+    pa_hashmap_put(hfdata->hf_audio_cards, hfac->path, hfac);
+
+    d = pa_bluetooth_discovery_get_device_by_address(hfdata->discovery, hfac->remote, hfac->local);
+    if (d) {
+        hfac->transport = pa_bluetooth_transport_new(d, hfdata->ofono_bus_id, path, PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY, NULL, 0);
+        hfac->transport->acquire = hf_audio_agent_transport_acquire;
+        hfac->transport->release = hf_audio_agent_transport_release;
+        hfac->transport->userdata = hfdata;
+
+        d->transports[PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY] = hfac->transport;
+
+        pa_bluetooth_transport_put(hfac->transport);
+    } else
+        pa_log_error("Device doesnt exist for %s", path);
+
+    return;
+
+fail:
+    pa_xfree(hfac);
+}
+
+static void hf_audio_agent_get_cards_reply(DBusPendingCall *pending, void *userdata) {
+    DBusMessage *r;
+    pa_dbus_pending *p;
+    hf_audio_agent_data *hfdata;
+    DBusMessageIter i, array_i, struct_i, props_i;
+    char c;
+
+    pa_assert_se(p = userdata);
+    pa_assert_se(hfdata = p->context_data);
+    pa_assert_se(r = dbus_pending_call_steal_reply(pending));
+
+    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
+        pa_log_error("Failed to get a list of handsfree audio cards from ofono: %s: %s",
+                     dbus_message_get_error_name(r), pa_dbus_get_error_message(r));
+        goto finish;
+    }
+
+    dbus_message_iter_init(r, &i);
+    if ((c = dbus_message_iter_get_arg_type(&i)) != DBUS_TYPE_ARRAY) {
+        pa_log_error("Invalid arguments in GetCards() reply: expected \'a\', received \'%c\'", c);
+        goto finish;
+    }
+
+    dbus_message_iter_recurse(&i, &array_i);
+    while (dbus_message_iter_get_arg_type(&array_i) != DBUS_TYPE_INVALID) {
+        const char *path;
+
+        if ((c = dbus_message_iter_get_arg_type(&array_i)) != DBUS_TYPE_STRUCT) {
+            pa_log_error("Invalid arguments in GetCards() reply: expected \'r\', received \'%c\'", c);
+            goto finish;
+        }
+
+        dbus_message_iter_recurse(&array_i, &struct_i);
+        if ((c = dbus_message_iter_get_arg_type(&struct_i)) != DBUS_TYPE_OBJECT_PATH) {
+            pa_log_error("Invalid arguments in GetCards() reply: expected \'o\', received \'%c\'", c);
+            goto finish;
+        }
+
+        dbus_message_iter_get_basic(&struct_i, &path);
+
+        dbus_message_iter_next(&struct_i);
+        if ((c = dbus_message_iter_get_arg_type(&struct_i)) != DBUS_TYPE_ARRAY) {
+            pa_log_error("Invalid arguments in GetCards() reply: expected \'a\', received \'%c\'", c);
+            goto finish;
+        }
+
+        dbus_message_iter_recurse(&struct_i, &props_i);
+
+        hf_audio_agent_card_found(hfdata, path, &props_i);
+
+        dbus_message_iter_next(&array_i);
+    }
+
+finish:
+    dbus_message_unref(r);
+
+    PA_LLIST_REMOVE(pa_dbus_pending, hfdata->pending, p);
+    pa_dbus_pending_free(p);
+}
+
+static void hf_audio_agent_get_cards(hf_audio_agent_data *hfdata) {
+    DBusMessage *m;
+
+    pa_assert(hfdata);
+
+    pa_assert_se(m = dbus_message_new_method_call(OFONO_SERVICE, "/", HF_AUDIO_MANAGER_INTERFACE, "GetCards"));
+    pa_bluetooth_dbus_send_and_add_to_pending(hfdata, m, hf_audio_agent_get_cards_reply, NULL);
+}
+
+static void hf_audio_agent_register_reply(DBusPendingCall *pending, void *userdata) {
+    DBusMessage *r;
+    pa_dbus_pending *p;
+    hf_audio_agent_data *hfdata;
+
+    pa_assert_se(p = userdata);
+    pa_assert_se(hfdata = p->context_data);
+    pa_assert_se(r = dbus_pending_call_steal_reply(pending));
+
+    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
+        pa_log_error("Failed to register as a handsfree audio agent with ofono: %s: %s",
+                     dbus_message_get_error_name(r), pa_dbus_get_error_message(r));
+        goto finish;
+    }
+
+    hfdata->ofono_bus_id = pa_xstrdup(dbus_message_get_sender(r));
+
+    hf_audio_agent_get_cards(hfdata);
+
+finish:
+    dbus_message_unref(r);
+
+    PA_LLIST_REMOVE(pa_dbus_pending, hfdata->pending, p);
+    pa_dbus_pending_free(p);
+}
+
+static void hf_audio_agent_register(hf_audio_agent_data *hfdata) {
+    DBusMessage *m;
+    unsigned char codecs[2];
+    const unsigned char *pcodecs = codecs;
+    int ncodecs = 0;
+    const char *path = HF_AUDIO_AGENT_PATH;
+
+    pa_assert(hfdata);
+
+    pa_assert_se(m = dbus_message_new_method_call(OFONO_SERVICE, "/", HF_AUDIO_MANAGER_INTERFACE, "Register"));
+
+    codecs[ncodecs++] = HFP_AUDIO_CODEC_CVSD;
+    codecs[ncodecs++] = HFP_AUDIO_CODEC_MSBC;
+
+    pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pcodecs, ncodecs,
+                                          DBUS_TYPE_INVALID));
+
+    pa_bluetooth_dbus_send_and_add_to_pending(hfdata, m, hf_audio_agent_register_reply, NULL);
+}
+
+static void hf_audio_agent_unregister(hf_audio_agent_data *hfdata) {
+    DBusMessage *m;
+    const char *path = HF_AUDIO_AGENT_PATH;
+
+    pa_assert(hfdata);
+    pa_assert(hfdata->connection);
+
+    if (hfdata->ofono_bus_id) {
+        pa_assert_se(m = dbus_message_new_method_call(hfdata->ofono_bus_id, "/", HF_AUDIO_MANAGER_INTERFACE, "Unregister"));
+        pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID));
+        pa_assert_se(dbus_connection_send(pa_dbus_connection_get(hfdata->connection), m, NULL));
+
+        pa_xfree(hfdata->ofono_bus_id);
+        hfdata->ofono_bus_id = NULL;
+    }
+}
+
+static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *data) {
+    const char *sender;
+    DBusError err;
+    hf_audio_agent_data *hfdata = data;
+
+    pa_assert(bus);
+    pa_assert(m);
+    pa_assert(hfdata);
+
+    sender = dbus_message_get_sender(m);
+    if (!pa_safe_streq(hfdata->ofono_bus_id, sender) && !pa_safe_streq("org.freedesktop.DBus", sender))
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    dbus_error_init(&err);
+
+    if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged")) {
+        const char *name, *old_owner, *new_owner;
+
+        if (!dbus_message_get_args(m, &err,
+                                   DBUS_TYPE_STRING, &name,
+                                   DBUS_TYPE_STRING, &old_owner,
+                                   DBUS_TYPE_STRING, &new_owner,
+                                   DBUS_TYPE_INVALID)) {
+            pa_log_error("Failed to parse org.freedesktop.DBus.NameOwnerChanged: %s", err.message);
+            goto fail;
+        }
+
+        if (pa_streq(name, OFONO_SERVICE)) {
+
+            if (old_owner && *old_owner) {
+                pa_log_debug("oFono disappeared");
+
+                if (hfdata->hf_audio_cards)
+                    pa_hashmap_remove_all(hfdata->hf_audio_cards);
+
+                if(hfdata->ofono_bus_id) {
+                    pa_xfree(hfdata->ofono_bus_id);
+                    hfdata->ofono_bus_id = NULL;
+                }
+            }
+
+            if (new_owner && *new_owner) {
+                pa_log_debug("oFono appeared");
+                hf_audio_agent_register(hfdata);
+            }
+        }
+
+    } else if (dbus_message_is_signal(m, "org.ofono.HandsfreeAudioManager", "CardAdded")) {
+        const char *p;
+        DBusMessageIter arg_i, props_i;
+
+        if (!dbus_message_iter_init(m, &arg_i) || !pa_streq(dbus_message_get_signature(m), "oa{sv}")) {
+            pa_log_error("Failed to parse org.ofono.HandsfreeAudioManager.CardAdded");
+            goto fail;
+        }
+
+        dbus_message_iter_get_basic(&arg_i, &p);
+
+        pa_assert_se(dbus_message_iter_next(&arg_i));
+        pa_assert(dbus_message_iter_get_arg_type(&arg_i) == DBUS_TYPE_ARRAY);
+
+        dbus_message_iter_recurse(&arg_i, &props_i);
+
+        hf_audio_agent_card_found(hfdata, p, &props_i);
+
+    } else if (dbus_message_is_signal(m, "org.ofono.HandsfreeAudioManager", "CardRemoved")) {
+        const char *p;
+        hf_audio_card *hfac;
+        bool old_any_connected;
+
+        if (!dbus_message_get_args(m, &err, DBUS_TYPE_OBJECT_PATH, &p, DBUS_TYPE_INVALID)) {
+            pa_log_error("Failed to parse org.ofono.HandsfreeAudioManager.CardRemoved: %s", err.message);
+            goto fail;
+        }
+
+        if ((hfac = pa_hashmap_remove(hfdata->hf_audio_cards, p)) != NULL) {
+            old_any_connected = pa_bluetooth_device_any_transport_connected(hfac->transport->device);
+
+            hfac->transport->state = PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED;
+            hfac->transport->device->transports[hfac->transport->profile] = NULL;
+            pa_hook_fire(pa_bluetooth_discovery_hook(hfdata->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED), hfac->transport);
+
+            if (old_any_connected != pa_bluetooth_device_any_transport_connected(hfac->transport->device)) {
+                pa_hook_fire(pa_bluetooth_discovery_hook(hfdata->discovery, PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED), hfac->transport->device);
+            }
+
+            hf_audio_card_free(hfac);
+        }
+    }
+
+fail:
+    dbus_error_free(&err);
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static DBusMessage *hf_audio_agent_release(DBusConnection *c, DBusMessage *m, void *data) {
+    DBusMessage *r;
+    const char *sender;
+    hf_audio_agent_data *hfdata = data;
+
+    pa_assert(hfdata);
+
+    sender = dbus_message_get_sender(m);
+    if (!pa_streq(hfdata->ofono_bus_id, sender)) {
+        pa_assert_se(r = dbus_message_new_error(m, "org.ofono.Error.NotAllowed", "Operation is not allowed by this sender"));
+        return r;
+    }
+
+    pa_log_debug("HF audio agent has been unregistered by oFono (%s)", hfdata->ofono_bus_id);
+
+    if (hfdata->hf_audio_cards) {
+#ifdef __TIZEN_BT__
+        pa_hashmap_free(hfdata->hf_audio_cards,NULL);
+#else
+        pa_hashmap_free(hfdata->hf_audio_cards);
+#endif
+        hfdata->hf_audio_cards = NULL;
+    }
+
+    if(hfdata->ofono_bus_id) {
+        pa_xfree(hfdata->ofono_bus_id);
+        hfdata->ofono_bus_id = NULL;
+    }
+
+    pa_assert_se(r = dbus_message_new_method_return(m));
+
+    return r;
+}
+
+static DBusMessage *hf_audio_agent_new_connection(DBusConnection *c, DBusMessage *m, void *data) {
+    DBusMessage *r;
+    const char *sender, *card;
+    int fd;
+    uint8_t codec;
+    hf_audio_card *hfac;
+    hf_audio_agent_data *hfdata = data;
+
+    pa_assert(hfdata);
+
+    sender = dbus_message_get_sender(m);
+    if (!pa_streq(hfdata->ofono_bus_id, sender)) {
+        pa_assert_se(r = dbus_message_new_error(m, "org.ofono.Error.NotAllowed", "Operation is not allowed by this sender"));
+        return r;
+    }
+
+    if (dbus_message_get_args(m, NULL,
+                              DBUS_TYPE_OBJECT_PATH, &card,
+                              DBUS_TYPE_UNIX_FD, &fd,
+                              DBUS_TYPE_BYTE, &codec,
+                              DBUS_TYPE_INVALID) == FALSE) {
+        pa_assert_se(r = dbus_message_new_error(m, "org.ofono.Error.InvalidArguments", "Invalid arguments in method call"));
+        return r;
+    }
+
+    if ( !(hfac = pa_hashmap_get(hfdata->hf_audio_cards, card)) ) {
+        pa_log_warn("New audio connection on unknown card %s (fd=%d, codec=%d)", card, fd, codec);
+        pa_assert_se(r = dbus_message_new_error(m, "org.ofono.Error.InvalidArguments", "Unknown card"));
+        return r;
+    }
+
+    pa_log_debug("New audio connection on card %s (fd=%d, codec=%d)", card, fd, codec);
+
+    /* Do the socket defered setup */
+    if (recv(fd, NULL, 0, 0) < 0) {
+        const char *strerr = strerror(errno);
+        pa_log_warn("Defered setup failed: %d (%s)", errno, strerr);
+        pa_assert_se(r = dbus_message_new_error(m, "org.ofono.Error.InvalidArguments", strerr));
+    }
+
+    hfac->fd = fd;
+    hfac->codec = codec;
+    hfac->transport->state = PA_BLUETOOTH_TRANSPORT_STATE_PLAYING;
+    pa_hook_fire(pa_bluetooth_discovery_hook(hfdata->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED), hfac->transport);
+
+    pa_assert_se(r = dbus_message_new_method_return(m));
+
+    return r;
+}
+
+static DBusHandlerResult hf_audio_agent_handler(DBusConnection *c, DBusMessage *m, void *data) {
+    hf_audio_agent_data *hfdata = data;
+    DBusMessage *r = NULL;
+    const char *path, *interface, *member;
+
+    pa_assert(hfdata);
+
+    path = dbus_message_get_path(m);
+    interface = dbus_message_get_interface(m);
+    member = dbus_message_get_member(m);
+
+    if (!pa_streq(path, HF_AUDIO_AGENT_PATH))
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    pa_log_debug("dbus: path=%s, interface=%s, member=%s", path, interface, member);
+
+    if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
+        const char *xml = HF_AUDIO_AGENT_XML;
+
+        pa_assert_se(r = dbus_message_new_method_return(m));
+        pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID));
+
+    } else if (dbus_message_is_method_call(m, HF_AUDIO_AGENT_INTERFACE, "NewConnection"))
+        r = hf_audio_agent_new_connection(c, m, data);
+    else if (dbus_message_is_method_call(m, HF_AUDIO_AGENT_INTERFACE, "Release"))
+        r = hf_audio_agent_release(c, m, data);
+    else
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    if (r) {
+        pa_assert_se(dbus_connection_send(pa_dbus_connection_get(hfdata->connection), r, NULL));
+        dbus_message_unref(r);
+    }
+
+    return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+hf_audio_agent_data *hf_audio_agent_init(pa_core *c) {
+    hf_audio_agent_data *hfdata;
+    DBusError err;
+    static const DBusObjectPathVTable vtable_hf_audio_agent = {
+        .message_function = hf_audio_agent_handler,
+    };
+
+    pa_assert(c);
+
+    hfdata = pa_xnew0(hf_audio_agent_data, 1);
+    hfdata->core = c;
+    hfdata->hf_audio_cards = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func,
+                                                 NULL, hf_audio_card_free);
+    hfdata->discovery = pa_shared_get(c, "bluetooth-discovery");
+
+    dbus_error_init(&err);
+
+    if (!(hfdata->connection = pa_dbus_bus_get(c, DBUS_BUS_SYSTEM, &err))) {
+        pa_log("Failed to get D-Bus connection: %s", err.message);
+        dbus_error_free(&err);
+        return NULL;
+    }
+
+    /* dynamic detection of handsfree audio cards */
+    if (!dbus_connection_add_filter(pa_dbus_connection_get(hfdata->connection), filter_cb, hfdata, NULL)) {
+        pa_log_error("Failed to add filter function");
+        hf_audio_agent_done(hfdata);
+        return NULL;
+    }
+    hfdata->filter_added = true;
+
+    if (pa_dbus_add_matches(pa_dbus_connection_get(hfdata->connection), &err,
+            "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',"
+            "arg0='" OFONO_SERVICE "'",
+            "type='signal',sender='" OFONO_SERVICE "',interface='" HF_AUDIO_MANAGER_INTERFACE "',member='CardAdded'",
+            "type='signal',sender='" OFONO_SERVICE "',interface='" HF_AUDIO_MANAGER_INTERFACE "',member='CardRemoved'",
+            NULL) < 0) {
+        pa_log("Failed to add oFono D-Bus matches: %s", err.message);
+        hf_audio_agent_done(hfdata);
+        return NULL;
+    }
+
+    pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(hfdata->connection), HF_AUDIO_AGENT_PATH,
+                                                      &vtable_hf_audio_agent, hfdata));
+
+    hf_audio_agent_register(hfdata);
+
+    return hfdata;
+}
+
+void hf_audio_agent_done(hf_audio_agent_data *data) {
+    hf_audio_agent_data *hfdata = data;
+
+    pa_assert(hfdata);
+
+    pa_dbus_free_pending_list(&hfdata->pending);
+
+    if (hfdata->hf_audio_cards) {
+#ifdef __TIZEN_BT__
+        pa_hashmap_free(hfdata->hf_audio_cards,NULL);
+#else
+        pa_hashmap_free(hfdata->hf_audio_cards);
+#endif
+        hfdata->hf_audio_cards = NULL;
+    }
+
+    if (hfdata->connection) {
+
+        pa_dbus_remove_matches(
+            pa_dbus_connection_get(hfdata->connection),
+            "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',"
+            "arg0='" OFONO_SERVICE "'",
+            "type='signal',sender='" OFONO_SERVICE "',interface='" HF_AUDIO_MANAGER_INTERFACE "',member='CardAdded'",
+            "type='signal',sender='" OFONO_SERVICE "',interface='" HF_AUDIO_MANAGER_INTERFACE "',member='CardRemoved'",
+            NULL);
+
+        if (hfdata->filter_added)
+            dbus_connection_remove_filter(pa_dbus_connection_get(hfdata->connection), filter_cb, hfdata);
+
+        hf_audio_agent_unregister(hfdata);
+
+        dbus_connection_unregister_object_path(pa_dbus_connection_get(hfdata->connection), HF_AUDIO_AGENT_PATH);
+
+        pa_dbus_connection_unref(hfdata->connection);
+    }
+
+    if (hfdata->discovery)
+        hfdata->discovery = NULL;
+
+    pa_xfree(hfdata);
+}
diff --git a/src/modules/bluetooth/hfaudioagent.h b/src/modules/bluetooth/hfaudioagent.h
new file mode 100644 (file)
index 0000000..2982034
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef foohfagenthfoo
+#define foohfagenthfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2013 João Paulo Rechi Vita
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <pulsecore/core.h>
+
+typedef struct hf_audio_agent_data hf_audio_agent_data;
+
+hf_audio_agent_data *hf_audio_agent_init(pa_core *c);
+void hf_audio_agent_done(hf_audio_agent_data *data);
+#endif
diff --git a/src/modules/bluetooth/ipc.c b/src/modules/bluetooth/ipc.c
deleted file mode 100644 (file)
index 02d956b..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "ipc.h"
-
-#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
-
-/* This table contains the string representation for messages types */
-static const char *strtypes[] = {
-       "BT_REQUEST",
-       "BT_RESPONSE",
-       "BT_INDICATION",
-       "BT_ERROR",
-};
-
-/* This table contains the string representation for messages names */
-static const char *strnames[] = {
-       "BT_GET_CAPABILITIES",
-       "BT_OPEN",
-       "BT_SET_CONFIGURATION",
-       "BT_NEW_STREAM",
-       "BT_START_STREAM",
-       "BT_STOP_STREAM",
-       "BT_SUSPEND_STREAM",
-       "BT_RESUME_STREAM",
-       "BT_CONTROL",
-};
-
-int bt_audio_service_open(void)
-{
-       int sk;
-       int err;
-       struct sockaddr_un addr = {
-               AF_UNIX, BT_IPC_SOCKET_NAME
-       };
-
-       sk = socket(PF_LOCAL, SOCK_STREAM, 0);
-       if (sk < 0) {
-               err = -errno;
-               fprintf(stderr, "%s: Cannot open socket: %s (%d)\n",
-                       __FUNCTION__, strerror(-err), -err);
-               errno = -err;
-               return -1;
-       }
-
-       if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-               err = -errno;
-               fprintf(stderr, "%s: connect() failed: %s (%d)\n",
-                       __FUNCTION__, strerror(-err), -err);
-               close(sk);
-               errno = -err;
-               return -1;
-       }
-
-       return sk;
-}
-
-int bt_audio_service_close(int sk)
-{
-       return close(sk);
-}
-
-int bt_audio_service_get_data_fd(int sk)
-{
-       char cmsg_b[CMSG_SPACE(sizeof(int))], m;
-       int err, ret;
-       struct iovec iov = { &m, sizeof(m) };
-       struct msghdr msgh;
-       struct cmsghdr *cmsg;
-
-       memset(&msgh, 0, sizeof(msgh));
-       msgh.msg_iov = &iov;
-       msgh.msg_iovlen = 1;
-       msgh.msg_control = &cmsg_b;
-       msgh.msg_controllen = CMSG_LEN(sizeof(int));
-
-       ret = recvmsg(sk, &msgh, 0);
-       if (ret < 0) {
-               err = -errno;
-               fprintf(stderr, "%s: Unable to receive fd: %s (%d)\n",
-                       __FUNCTION__, strerror(-err), -err);
-               errno = -err;
-               return -1;
-       }
-
-       /* Receive auxiliary data in msgh */
-       for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
-                       cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
-               if (cmsg->cmsg_level == SOL_SOCKET
-                               && cmsg->cmsg_type == SCM_RIGHTS) {
-                       memcpy(&ret, CMSG_DATA(cmsg), sizeof(int));
-                       return ret;
-               }
-       }
-
-       errno = EINVAL;
-       return -1;
-}
-
-const char *bt_audio_strtype(uint8_t type)
-{
-       if (type >= ARRAY_SIZE(strtypes))
-               return NULL;
-
-       return strtypes[type];
-}
-
-const char *bt_audio_strname(uint8_t name)
-{
-       if (name >= ARRAY_SIZE(strnames))
-               return NULL;
-
-       return strnames[name];
-}
diff --git a/src/modules/bluetooth/ipc.h b/src/modules/bluetooth/ipc.h
deleted file mode 100644 (file)
index 61ae019..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- *
- *  BlueZ - Bluetooth protocol stack for Linux
- *
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-/*
-  Message sequence chart of streaming sequence for A2DP transport
-
-  Audio daemon                 User
-                               on snd_pcm_open
-                               <--BT_GET_CAPABILITIES_REQ
-
-  BT_GET_CAPABILITIES_RSP-->
-
-                               on snd_pcm_hw_params
-                               <--BT_SETCONFIGURATION_REQ
-
-  BT_SET_CONFIGURATION_RSP-->
-
-                               on snd_pcm_prepare
-                               <--BT_START_STREAM_REQ
-
-  <Moves to streaming state>
-  BT_START_STREAM_RSP-->
-
-  BT_NEW_STREAM_IND -->
-
-                               <  streams data >
-                               ..........
-
-                               on snd_pcm_drop/snd_pcm_drain
-
-                               <--BT_STOP_STREAM_REQ
-
-  <Moves to open state>
-  BT_STOP_STREAM_RSP-->
-
-                               on IPC close or appl crash
-  <Moves to idle>
-
- */
-
-#ifndef BT_AUDIOCLIENT_H
-#define BT_AUDIOCLIENT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <errno.h>
-
-#define BT_SUGGESTED_BUFFER_SIZE   512
-#define BT_IPC_SOCKET_NAME "\0/org/bluez/audio"
-
-/* Generic message header definition, except for RESPONSE messages */
-typedef struct {
-       uint8_t type;
-       uint8_t name;
-       uint16_t length;
-} __attribute__ ((packed)) bt_audio_msg_header_t;
-
-typedef struct {
-       bt_audio_msg_header_t h;
-       uint8_t posix_errno;
-} __attribute__ ((packed)) bt_audio_error_t;
-
-/* Message types */
-#define BT_REQUEST                     0
-#define BT_RESPONSE                    1
-#define BT_INDICATION                  2
-#define BT_ERROR                       3
-
-/* Messages names */
-#define BT_GET_CAPABILITIES            0
-#define BT_OPEN                                1
-#define BT_SET_CONFIGURATION           2
-#define BT_NEW_STREAM                  3
-#define BT_START_STREAM                        4
-#define BT_STOP_STREAM                 5
-#define BT_CLOSE                       6
-#define BT_CONTROL                     7
-#define BT_DELAY_REPORT                        8
-
-#define BT_CAPABILITIES_TRANSPORT_A2DP 0
-#define BT_CAPABILITIES_TRANSPORT_SCO  1
-#define BT_CAPABILITIES_TRANSPORT_ANY  2
-
-#define BT_CAPABILITIES_ACCESS_MODE_READ       1
-#define BT_CAPABILITIES_ACCESS_MODE_WRITE      2
-#define BT_CAPABILITIES_ACCESS_MODE_READWRITE  3
-
-#define BT_FLAG_AUTOCONNECT    1
-
-struct bt_get_capabilities_req {
-       bt_audio_msg_header_t   h;
-       char                    source[18];     /* Address of the local Device */
-       char                    destination[18];/* Address of the remote Device */
-       char                    object[128];    /* DBus object path */
-       uint8_t                 transport;      /* Requested transport */
-       uint8_t                 flags;          /* Requested flags */
-       uint8_t                 seid;           /* Requested capability configuration */
-} __attribute__ ((packed));
-
-/**
- * SBC Codec parameters as per A2DP profile 1.0 § 4.3
- */
-
-/* A2DP seid are 6 bytes long so HSP/HFP are assigned to 7-8 bits */
-#define BT_A2DP_SEID_RANGE                     (1 << 6) - 1
-
-#define BT_A2DP_SBC_SOURCE                     0x00
-#define BT_A2DP_SBC_SINK                       0x01
-#define BT_A2DP_MPEG12_SOURCE                  0x02
-#define BT_A2DP_MPEG12_SINK                    0x03
-#define BT_A2DP_MPEG24_SOURCE                  0x04
-#define BT_A2DP_MPEG24_SINK                    0x05
-#define BT_A2DP_ATRAC_SOURCE                   0x06
-#define BT_A2DP_ATRAC_SINK                     0x07
-#define BT_A2DP_UNKNOWN_SOURCE                 0x08
-#define BT_A2DP_UNKNOWN_SINK                   0x09
-
-#define BT_SBC_SAMPLING_FREQ_16000             (1 << 3)
-#define BT_SBC_SAMPLING_FREQ_32000             (1 << 2)
-#define BT_SBC_SAMPLING_FREQ_44100             (1 << 1)
-#define BT_SBC_SAMPLING_FREQ_48000             1
-
-#define BT_A2DP_CHANNEL_MODE_MONO              (1 << 3)
-#define BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL      (1 << 2)
-#define BT_A2DP_CHANNEL_MODE_STEREO            (1 << 1)
-#define BT_A2DP_CHANNEL_MODE_JOINT_STEREO      1
-
-#define BT_A2DP_BLOCK_LENGTH_4                 (1 << 3)
-#define BT_A2DP_BLOCK_LENGTH_8                 (1 << 2)
-#define BT_A2DP_BLOCK_LENGTH_12                        (1 << 1)
-#define BT_A2DP_BLOCK_LENGTH_16                        1
-
-#define BT_A2DP_SUBBANDS_4                     (1 << 1)
-#define BT_A2DP_SUBBANDS_8                     1
-
-#define BT_A2DP_ALLOCATION_SNR                 (1 << 1)
-#define BT_A2DP_ALLOCATION_LOUDNESS            1
-
-#define BT_MPEG_SAMPLING_FREQ_16000            (1 << 5)
-#define BT_MPEG_SAMPLING_FREQ_22050            (1 << 4)
-#define BT_MPEG_SAMPLING_FREQ_24000            (1 << 3)
-#define BT_MPEG_SAMPLING_FREQ_32000            (1 << 2)
-#define BT_MPEG_SAMPLING_FREQ_44100            (1 << 1)
-#define BT_MPEG_SAMPLING_FREQ_48000            1
-
-#define BT_MPEG_LAYER_1                                (1 << 2)
-#define BT_MPEG_LAYER_2                                (1 << 1)
-#define BT_MPEG_LAYER_3                                1
-
-#define BT_HFP_CODEC_PCM                       0x00
-
-#define BT_PCM_FLAG_NREC                       0x01
-#define BT_PCM_FLAG_PCM_ROUTING                        0x02
-
-#define BT_WRITE_LOCK                          (1 << 1)
-#define BT_READ_LOCK                           1
-
-typedef struct {
-       uint8_t seid;
-       uint8_t transport;
-       uint8_t type;
-       uint8_t length;
-       uint8_t configured;
-       uint8_t lock;
-       uint8_t data[0];
-} __attribute__ ((packed)) codec_capabilities_t;
-
-typedef struct {
-       codec_capabilities_t capability;
-       uint8_t channel_mode;
-       uint8_t frequency;
-       uint8_t allocation_method;
-       uint8_t subbands;
-       uint8_t block_length;
-       uint8_t min_bitpool;
-       uint8_t max_bitpool;
-} __attribute__ ((packed)) sbc_capabilities_t;
-
-typedef struct {
-       codec_capabilities_t capability;
-       uint8_t channel_mode;
-       uint8_t crc;
-       uint8_t layer;
-       uint8_t frequency;
-       uint8_t mpf;
-       uint16_t bitrate;
-} __attribute__ ((packed)) mpeg_capabilities_t;
-
-typedef struct {
-       codec_capabilities_t capability;
-       uint8_t flags;
-       uint16_t sampling_rate;
-} __attribute__ ((packed)) pcm_capabilities_t;
-
-struct bt_get_capabilities_rsp {
-       bt_audio_msg_header_t   h;
-       char                    source[18];     /* Address of the local Device */
-       char                    destination[18];/* Address of the remote Device */
-       char                    object[128];    /* DBus object path */
-       uint8_t                 data[0];        /* First codec_capabilities_t */
-} __attribute__ ((packed));
-
-struct bt_open_req {
-       bt_audio_msg_header_t   h;
-       char                    source[18];     /* Address of the local Device */
-       char                    destination[18];/* Address of the remote Device */
-       char                    object[128];    /* DBus object path */
-       uint8_t                 seid;           /* Requested capability configuration to lock */
-       uint8_t                 lock;           /* Requested lock */
-} __attribute__ ((packed));
-
-struct bt_open_rsp {
-       bt_audio_msg_header_t   h;
-       char                    source[18];     /* Address of the local Device */
-       char                    destination[18];/* Address of the remote Device */
-       char                    object[128];    /* DBus object path */
-} __attribute__ ((packed));
-
-struct bt_set_configuration_req {
-       bt_audio_msg_header_t   h;
-       codec_capabilities_t    codec;          /* Requested codec */
-} __attribute__ ((packed));
-
-struct bt_set_configuration_rsp {
-       bt_audio_msg_header_t   h;
-       uint16_t                link_mtu;       /* Max length that transport supports */
-} __attribute__ ((packed));
-
-#define BT_STREAM_ACCESS_READ          0
-#define BT_STREAM_ACCESS_WRITE         1
-#define BT_STREAM_ACCESS_READWRITE     2
-struct bt_start_stream_req {
-       bt_audio_msg_header_t   h;
-} __attribute__ ((packed));
-
-struct bt_start_stream_rsp {
-       bt_audio_msg_header_t   h;
-} __attribute__ ((packed));
-
-/* This message is followed by one byte of data containing the stream data fd
-   as ancillary data */
-struct bt_new_stream_ind {
-       bt_audio_msg_header_t   h;
-} __attribute__ ((packed));
-
-struct bt_stop_stream_req {
-       bt_audio_msg_header_t   h;
-} __attribute__ ((packed));
-
-struct bt_stop_stream_rsp {
-       bt_audio_msg_header_t   h;
-} __attribute__ ((packed));
-
-struct bt_close_req {
-       bt_audio_msg_header_t   h;
-} __attribute__ ((packed));
-
-struct bt_close_rsp {
-       bt_audio_msg_header_t   h;
-} __attribute__ ((packed));
-
-struct bt_suspend_stream_ind {
-       bt_audio_msg_header_t   h;
-} __attribute__ ((packed));
-
-struct bt_resume_stream_ind {
-       bt_audio_msg_header_t   h;
-} __attribute__ ((packed));
-
-#define BT_CONTROL_KEY_POWER                   0x40
-#define BT_CONTROL_KEY_VOL_UP                  0x41
-#define BT_CONTROL_KEY_VOL_DOWN                        0x42
-#define BT_CONTROL_KEY_MUTE                    0x43
-#define BT_CONTROL_KEY_PLAY                    0x44
-#define BT_CONTROL_KEY_STOP                    0x45
-#define BT_CONTROL_KEY_PAUSE                   0x46
-#define BT_CONTROL_KEY_RECORD                  0x47
-#define BT_CONTROL_KEY_REWIND                  0x48
-#define BT_CONTROL_KEY_FAST_FORWARD            0x49
-#define BT_CONTROL_KEY_EJECT                   0x4A
-#define BT_CONTROL_KEY_FORWARD                 0x4B
-#define BT_CONTROL_KEY_BACKWARD                        0x4C
-
-struct bt_control_req {
-       bt_audio_msg_header_t   h;
-       uint8_t                 mode;           /* Control Mode */
-       uint8_t                 key;            /* Control Key */
-} __attribute__ ((packed));
-
-struct bt_control_rsp {
-       bt_audio_msg_header_t   h;
-       uint8_t                 mode;           /* Control Mode */
-       uint8_t                 key;            /* Control Key */
-} __attribute__ ((packed));
-
-struct bt_control_ind {
-       bt_audio_msg_header_t   h;
-       uint8_t                 mode;           /* Control Mode */
-       uint8_t                 key;            /* Control Key */
-} __attribute__ ((packed));
-
-struct bt_delay_report_req {
-       bt_audio_msg_header_t   h;
-       uint16_t                delay;
-} __attribute__ ((packed));
-
-struct bt_delay_report_ind {
-       bt_audio_msg_header_t   h;
-       uint16_t                delay;
-} __attribute__ ((packed));
-
-/* Function declaration */
-
-/* Opens a connection to the audio service: return a socket descriptor */
-int bt_audio_service_open(void);
-
-/* Closes a connection to the audio service */
-int bt_audio_service_close(int sk);
-
-/* Receives stream data file descriptor : must be called after a
-BT_STREAMFD_IND message is returned */
-int bt_audio_service_get_data_fd(int sk);
-
-/* Human readable message type string */
-const char *bt_audio_strtype(uint8_t type);
-
-/* Human readable message name string */
-const char *bt_audio_strname(uint8_t name);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BT_AUDIOCLIENT_H */
old mode 100644 (file)
new mode 100755 (executable)
index 253aa1c..ec3bf1d
@@ -1,7 +1,7 @@
 /***
   This file is part of PulseAudio.
 
-  Copyright 2008-2009 Joao Paulo Rechi Vita
+  Copyright 2013 João Paulo Rechi Vita
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as
 #include <config.h>
 #endif
 
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <pulse/xmalloc.h>
-#include <pulsecore/module.h>
 #include <pulsecore/core-util.h>
-#include <pulsecore/modargs.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/core-util.h>
-#include <pulsecore/dbus-shared.h>
+#include <pulsecore/module.h>
+#ifdef BLUETOOTH_APTX_SUPPORT
+#include <pulsecore/modargs.h>
+#endif
 
 #include "module-bluetooth-discover-symdef.h"
-#include "bluetooth-util.h"
 
-PA_MODULE_AUTHOR("Joao Paulo Rechi Vita");
-PA_MODULE_DESCRIPTION("Detect available bluetooth audio devices and load bluetooth audio drivers");
+PA_MODULE_AUTHOR("João Paulo Rechi Vita");
+PA_MODULE_DESCRIPTION("Detect available Bluetooth daemon and load the corresponding discovery module");
 PA_MODULE_VERSION(PACKAGE_VERSION);
-PA_MODULE_USAGE("async=<Asynchronous initialization?> "
-                "sco_sink=<name of sink> "
-                "sco_source=<name of source> ");
-PA_MODULE_LOAD_ONCE(TRUE);
+PA_MODULE_USAGE("sco_sink=<name of sink> "
+               "sco_source=<name of source> "
+#ifdef BLUETOOTH_APTX_SUPPORT
+               "aptx_lib_name=<name of aptx library name>"
+#endif
+);
+PA_MODULE_LOAD_ONCE(true);
 
 static const char* const valid_modargs[] = {
-    "sco_sink",
-    "sco_source",
-    "async",
+       "sco_sink",
+       "sco_source",
+       "async", /* deprecated */
+#ifdef BLUETOOTH_APTX_SUPPORT
+    "aptx_lib_name",
+#endif
+#ifdef __TIZEN_BT__
+    "enable_scmst",
+#endif
     NULL
 };
 
 struct userdata {
-    pa_module *module;
-    pa_modargs *modargs;
-    pa_core *core;
-    pa_bluetooth_discovery *discovery;
-    pa_hook_slot *slot;
-    pa_hashmap *hashmap;
+    uint32_t bluez5_module_idx;
+    uint32_t bluez4_module_idx;
 };
 
-struct module_info {
-    char *path;
-    uint32_t module;
-};
-
-static pa_hook_result_t load_module_for_device(pa_bluetooth_discovery *y, const pa_bluetooth_device *d, struct userdata *u) {
-    struct module_info *mi;
-
-    pa_assert(u);
-    pa_assert(d);
-
-    mi = pa_hashmap_get(u->hashmap, d->path);
+static bool pa_module_exists(const char *name) {
+    const char *paths, *state = NULL;
+    char *n, *p, *pathname;
+    bool result;
 
-    if (!d->dead && d->device_connected > 0 &&
-        /*(d->audio_state >= PA_BT_AUDIO_STATE_CONNECTED ||*/
-        (d->audio_sink_state >= PA_BT_AUDIO_STATE_CONNECTED ||
-         d->audio_source_state >= PA_BT_AUDIO_STATE_CONNECTED ||
-         d->hfgw_state >= PA_BT_AUDIO_STATE_CONNECTED)) {
+    pa_assert(name);
 
-        if (!mi) {
-            pa_module *m = NULL;
-            char *args;
-
-            /* Oh, awesome, a new device has shown up and been connected! */
-
-            args = pa_sprintf_malloc("address=\"%s\" path=\"%s\"", d->address, d->path);
-#if 0
-            /* This is in case we have to use hsp immediately, without waiting for .Audio.State = Connected */
-            if (d->headset_state >= PA_BT_AUDIO_STATE_CONNECTED && somecondition) {
-                char *tmp;
-                tmp = pa_sprintf_malloc("%s profile=\"hsp\"", args);
-                pa_xfree(args);
-                args = tmp;
-            }
-#endif
-
-            if (pa_modargs_get_value(u->modargs, "sco_sink", NULL) &&
-                pa_modargs_get_value(u->modargs, "sco_source", NULL)) {
-                char *tmp;
-
-                tmp = pa_sprintf_malloc("%s sco_sink=\"%s\" sco_source=\"%s\"", args,
-                                        pa_modargs_get_value(u->modargs, "sco_sink", NULL),
-                                        pa_modargs_get_value(u->modargs, "sco_source", NULL));
-                pa_xfree(args);
-                args = tmp;
-            }
-
-            if (d->audio_source_state >= PA_BT_AUDIO_STATE_CONNECTED)
-                args = pa_sprintf_malloc("%s profile=\"a2dp_source\" auto_connect=no", args);
-
-            if (d->hfgw_state >= PA_BT_AUDIO_STATE_CONNECTED)
-                args = pa_sprintf_malloc("%s profile=\"hfgw\"", args);
-
-            if (d->audio_sink_state >= PA_BT_AUDIO_STATE_CONNECTED)
-                args = pa_sprintf_malloc("%s profile=\"a2dp\"", args);
-
-            pa_log_debug("Loading module-bluetooth-device %s", args);
-            m = pa_module_load(u->module->core, "module-bluetooth-device", args);
-            pa_xfree(args);
-
-            if (m) {
-                mi = pa_xnew(struct module_info, 1);
-                mi->module = m->index;
-                mi->path = pa_xstrdup(d->path);
+    if (name[0] == PA_PATH_SEP_CHAR) {
+        result = access(name, F_OK) == 0 ? true : false;
+        pa_log_debug("Checking for existence of '%s': %s", name, result ? "success" : "failure");
+        if (result)
+            return true;
+    }
 
-                pa_hashmap_put(u->hashmap, mi->path, mi);
-            } else
-                pa_log_debug("Failed to load module for device %s", d->path);
+    if (!(paths = lt_dlgetsearchpath()))
+        return false;
+
+    /* strip .so from the end of name, if present */
+    n = pa_xstrdup(name);
+    p = rindex(n, '.');
+    if (p && pa_streq(p, PA_SOEXT))
+        p[0] = 0;
+
+    while ((p = pa_split(paths, ":", &state))) {
+        pathname = pa_sprintf_malloc("%s" PA_PATH_SEP "%s" PA_SOEXT, p, n);
+        result = access(pathname, F_OK) == 0 ? true : false;
+        pa_log_debug("Checking for existence of '%s': %s", pathname, result ? "success" : "failure");
+        pa_xfree(pathname);
+        pa_xfree(p);
+        if (result) {
+            pa_xfree(n);
+            return true;
         }
+    }
 
-    } else {
-
-        if (mi) {
-
-            /* Hmm, disconnection? Then let's unload our module */
-
-            pa_log_debug("Unloading module for %s", d->path);
-            pa_module_unload_request_by_index(u->core, mi->module, TRUE);
-
-            pa_hashmap_remove(u->hashmap, mi->path);
-            pa_xfree(mi->path);
-            pa_xfree(mi);
+    state = NULL;
+    if (PA_UNLIKELY(pa_run_from_build_tree())) {
+        while ((p = pa_split(paths, ":", &state))) {
+            pathname = pa_sprintf_malloc("%s" PA_PATH_SEP ".libs" PA_PATH_SEP "%s" PA_SOEXT, p, n);
+            result = access(pathname, F_OK) == 0 ? true : false;
+            pa_log_debug("Checking for existence of '%s': %s", pathname, result ? "success" : "failure");
+            pa_xfree(pathname);
+            pa_xfree(p);
+            if (result) {
+                pa_xfree(n);
+                return true;
+            }
         }
     }
 
-    return PA_HOOK_OK;
+    pa_xfree(n);
+    return false;
 }
 
+
 int pa__init(pa_module* m) {
     struct userdata *u;
-    pa_modargs *ma = NULL;
-    pa_bool_t async = FALSE;
+    pa_module *mm;
 
+#ifdef BLUETOOTH_APTX_SUPPORT
+    pa_modargs *ma = NULL;
+    const char *aptx_lib_name = NULL;
+    char* args;
+#endif
     pa_assert(m);
 
+#ifdef BLUETOOTH_APTX_SUPPORT
     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
         pa_log("Failed to parse module arguments");
-        goto fail;
+        pa__done(m);
+        return -1;
     }
 
-    if (pa_modargs_get_value_boolean(ma, "async", &async) < 0) {
-        pa_log("Failed to parse async argument.");
-        goto fail;
-    }
+    if (pa_modargs_get_value(ma, "async", NULL))
+        pa_log_warn("The 'async' argument is deprecated and does nothing.");
 
-    m->userdata = u = pa_xnew0(struct userdata, 1);
-    u->module = m;
-    u->core = m->core;
-    u->modargs = ma;
-    ma = NULL;
-    u->hashmap = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    aptx_lib_name = pa_modargs_get_value(ma, "aptx_lib_name", NULL);
+    args =  pa_sprintf_malloc("aptx_lib_name=%s",aptx_lib_name);
+#endif
 
-    if (!(u->discovery = pa_bluetooth_discovery_get(u->core)))
-        goto fail;
+    m->userdata = u = pa_xnew0(struct userdata, 1);
+    u->bluez5_module_idx = PA_INVALID_INDEX;
+    u->bluez4_module_idx = PA_INVALID_INDEX;
+
+    if (pa_module_exists("module-bluez5-discover")) {
+#ifdef BLUETOOTH_APTX_SUPPORT
+        mm = pa_module_load(m->core, "module-bluez5-discover", args);
+#else
+        mm = pa_module_load(m->core, "module-bluez5-discover", NULL);
+#endif
+        if (mm)
+            u->bluez5_module_idx = mm->index;
+    }
 
-    u->slot = pa_hook_connect(pa_bluetooth_discovery_hook(u->discovery), PA_HOOK_NORMAL, (pa_hook_cb_t) load_module_for_device, u);
+    if (pa_module_exists("module-bluez4-discover")) {
+        mm = pa_module_load(m->core, "module-bluez4-discover",  NULL);
+        if (mm)
+            u->bluez4_module_idx = mm->index;
+    }
 
-    if (!async)
-        pa_bluetooth_discovery_sync(u->discovery);
+    if (u->bluez5_module_idx == PA_INVALID_INDEX && u->bluez4_module_idx == PA_INVALID_INDEX) {
+        pa_xfree(u);
+#ifdef __TIZEN__
+            pa_xfree(args);
+            pa_modargs_free(ma);
+#endif
+        return -1;
+    }
+#ifdef __TIZEN__
+    pa_xfree(args);
+    pa_modargs_free(ma);
+#endif
 
     return 0;
-
-fail:
-    pa__done(m);
-
-    if (ma)
-        pa_modargs_free(ma);
-
-    return -1;
 }
 
 void pa__done(pa_module* m) {
@@ -200,25 +185,11 @@ void pa__done(pa_module* m) {
     if (!(u = m->userdata))
         return;
 
-    if (u->slot)
-        pa_hook_slot_free(u->slot);
-
-    if (u->discovery)
-        pa_bluetooth_discovery_unref(u->discovery);
-
-    if (u->hashmap) {
-        struct module_info *mi;
-
-        while ((mi = pa_hashmap_steal_first(u->hashmap))) {
-            pa_xfree(mi->path);
-            pa_xfree(mi);
-        }
-
-        pa_hashmap_free(u->hashmap, NULL, NULL);
-    }
+    if (u->bluez5_module_idx != PA_INVALID_INDEX)
+        pa_module_unload_by_index(m->core, u->bluez5_module_idx, true);
 
-    if (u->modargs)
-        pa_modargs_free(u->modargs);
+    if (u->bluez4_module_idx != PA_INVALID_INDEX)
+        pa_module_unload_by_index(m->core, u->bluez4_module_idx, true);
 
     pa_xfree(u);
 }
diff --git a/src/modules/bluetooth/module-bluetooth-policy.c b/src/modules/bluetooth/module-bluetooth-policy.c
new file mode 100644 (file)
index 0000000..db34ecf
--- /dev/null
@@ -0,0 +1,277 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2006 Lennart Poettering
+  Copyright 2009 Canonical Ltd
+  Copyright (C) 2012 Intel Corporation
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/core.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/source-output.h>
+#include <pulsecore/source.h>
+#include <pulsecore/core-util.h>
+
+#include "module-bluetooth-policy-symdef.h"
+
+PA_MODULE_AUTHOR("Frédéric Dalleau");
+PA_MODULE_DESCRIPTION("When a bluetooth sink or source is added, load module-loopback");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(true);
+PA_MODULE_USAGE(
+        "a2dp_source=<Handle a2dp_source card profile (sink role)?> "
+        "hfgw=<Handle hfgw card profile (headset role)?>");
+
+static const char* const valid_modargs[] = {
+    "a2dp_source",
+    "hfgw",
+    NULL
+};
+
+struct userdata {
+    bool enable_a2dp_source;
+    bool enable_hfgw;
+    pa_hook_slot *source_put_slot;
+    pa_hook_slot *sink_put_slot;
+    pa_hook_slot *profile_available_changed_slot;
+};
+
+/* When a source is created, loopback it to default sink */
+static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, void *userdata) {
+    struct userdata *u = userdata;
+    const char *s;
+    const char *role;
+    char *args;
+
+    pa_assert(c);
+    pa_assert(source);
+
+    /* Only consider bluetooth sinks and sources */
+    s = pa_proplist_gets(source->proplist, PA_PROP_DEVICE_BUS);
+    if (!s)
+        return PA_HOOK_OK;
+
+    if (!pa_streq(s, "bluetooth"))
+        return PA_HOOK_OK;
+
+    s = pa_proplist_gets(source->proplist, "bluetooth.protocol");
+    if (!s)
+        return PA_HOOK_OK;
+
+    if (u->enable_a2dp_source && pa_streq(s, "a2dp_source")) /* A2DP profile (we're doing sink role) */
+        role = "music";
+    else if (u->enable_hfgw && pa_streq(s, "hfgw")) /* HFP profile (we're doing headset role) */
+        role = "phone";
+    else {
+        pa_log_debug("Profile %s cannot be selected for loopback", s);
+        return PA_HOOK_OK;
+    }
+
+    /* Load module-loopback */
+    args = pa_sprintf_malloc("source=\"%s\" source_dont_move=\"true\" sink_input_properties=\"media.role=%s\"", source->name, role);
+    (void) pa_module_load(c, "module-loopback", args);
+    pa_xfree(args);
+
+    return PA_HOOK_OK;
+}
+
+/* When a sink is created, loopback it to default source */
+static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void *userdata) {
+    struct userdata *u = userdata;
+    const char *s;
+    const char *role;
+    char *args;
+
+    pa_assert(c);
+    pa_assert(sink);
+
+    /* Only consider bluetooth sinks and sources */
+    s = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_BUS);
+    if (!s)
+        return PA_HOOK_OK;
+
+    if (!pa_streq(s, "bluetooth"))
+        return PA_HOOK_OK;
+
+    s = pa_proplist_gets(sink->proplist, "bluetooth.protocol");
+    if (!s)
+        return PA_HOOK_OK;
+
+    if (u->enable_hfgw && pa_streq(s, "hfgw")) /* HFP profile (we're doing headset role) */
+        role = "phone";
+    else {
+        pa_log_debug("Profile %s cannot be selected for loopback", s);
+        return PA_HOOK_OK;
+    }
+
+    /* Load module-loopback */
+    args = pa_sprintf_malloc("sink=\"%s\" sink_dont_move=\"true\" source_output_properties=\"media.role=%s\"", sink->name, role);
+    (void) pa_module_load(c, "module-loopback", args);
+    pa_xfree(args);
+
+    return PA_HOOK_OK;
+}
+
+static pa_card_profile *find_best_profile(pa_card *card) {
+    void *state;
+    pa_card_profile *profile;
+    pa_card_profile *result = card->active_profile;
+    pa_card_profile *off;
+
+    pa_assert_se(off = pa_hashmap_get(card->profiles, "off"));
+
+    PA_HASHMAP_FOREACH(profile, card->profiles, state) {
+        if (profile->available == PA_AVAILABLE_NO || profile == off)
+            continue;
+
+        if (result == NULL ||
+            (profile->available == PA_AVAILABLE_YES && result->available == PA_AVAILABLE_UNKNOWN) ||
+            (profile->available == result->available && profile->priority > profile->priority))
+            result = profile;
+    }
+
+    return result ? result : off;
+}
+
+static pa_hook_result_t profile_available_hook_callback(pa_core *c, pa_card_profile *profile, void *userdata) {
+    pa_card *card;
+    const char *s;
+    bool is_active_profile;
+    pa_card_profile *selected_profile;
+
+    pa_assert(c);
+    pa_assert(profile);
+    pa_assert_se((card = profile->card));
+
+    /* Only consider bluetooth cards */
+    s = pa_proplist_gets(card->proplist, PA_PROP_DEVICE_BUS);
+    if (!s || !pa_streq(s, "bluetooth"))
+        return PA_HOOK_OK;
+
+    /* Do not automatically switch profiles for headsets, just in case */
+    if (pa_streq(profile->name, "hsp") || pa_streq(profile->name, "a2dp_sink"))
+        return PA_HOOK_OK;
+
+    is_active_profile = card->active_profile == profile;
+
+    if (profile->available == PA_AVAILABLE_YES) {
+        if (is_active_profile)
+            return PA_HOOK_OK;
+
+        if (card->active_profile->available == PA_AVAILABLE_YES && card->active_profile->priority >= profile->priority)
+            return PA_HOOK_OK;
+
+        selected_profile = profile;
+    } else {
+        if (!is_active_profile)
+            return PA_HOOK_OK;
+
+        pa_assert_se((selected_profile = find_best_profile(card)));
+
+        if (selected_profile == card->active_profile)
+            return PA_HOOK_OK;
+    }
+
+    pa_log_debug("Setting card '%s' to profile '%s'", card->name, selected_profile->name);
+
+    if (pa_card_set_profile(card, selected_profile->name, false) != 0)
+        pa_log_warn("Could not set profile '%s'", selected_profile->name);
+
+    return PA_HOOK_OK;
+}
+
+static void handle_all_profiles(pa_core *core) {
+    pa_card *card;
+    uint32_t state;
+
+    PA_IDXSET_FOREACH(card, core->cards, state) {
+        pa_card_profile *profile;
+        void *state2;
+
+        PA_HASHMAP_FOREACH(profile, card->profiles, state2)
+            profile_available_hook_callback(core, profile, NULL);
+    }
+}
+
+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_error("Failed to parse module arguments");
+        return -1;
+    }
+
+    m->userdata = u = pa_xnew0(struct userdata, 1);
+
+    u->enable_a2dp_source = true;
+    if (pa_modargs_get_value_boolean(ma, "a2dp_source", &u->enable_a2dp_source) < 0) {
+        pa_log("Failed to parse a2dp_source argument.");
+        goto fail;
+    }
+
+    u->enable_hfgw = true;
+    if (pa_modargs_get_value_boolean(ma, "hfgw", &u->enable_hfgw) < 0) {
+        pa_log("Failed to parse hfgw argument.");
+        goto fail;
+    }
+
+    u->source_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_NORMAL, (pa_hook_cb_t) source_put_hook_callback, u);
+
+    u->sink_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_NORMAL, (pa_hook_cb_t) sink_put_hook_callback, u);
+
+    u->profile_available_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_CARD_PROFILE_AVAILABLE_CHANGED],
+                                                        PA_HOOK_NORMAL, (pa_hook_cb_t) profile_available_hook_callback, u);
+
+    handle_all_profiles(m->core);
+
+    pa_modargs_free(ma);
+    return 0;
+
+fail:
+    pa_modargs_free(ma);
+    return -1;
+}
+
+void pa__done(pa_module *m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    if (u->source_put_slot)
+        pa_hook_slot_free(u->source_put_slot);
+
+    if (u->sink_put_slot)
+        pa_hook_slot_free(u->sink_put_slot);
+
+    if (u->profile_available_changed_slot)
+        pa_hook_slot_free(u->profile_available_changed_slot);
+
+    pa_xfree(u);
+}
diff --git a/src/modules/bluetooth/module-bluetooth-proximity.c b/src/modules/bluetooth/module-bluetooth-proximity.c
deleted file mode 100644 (file)
index 3247017..0000000
+++ /dev/null
@@ -1,487 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2005-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, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#include <pulse/xmalloc.h>
-#include <pulsecore/module.h>
-#include <pulsecore/log.h>
-#include <pulsecore/namereg.h>
-#include <pulsecore/sink.h>
-#include <pulsecore/modargs.h>
-#include <pulsecore/macro.h>
-#include <pulsecore/core-util.h>
-#include <pulsecore/core-error.h>
-#include <pulsecore/start-child.h>
-#include <pulsecore/dbus-shared.h>
-
-#include "module-bluetooth-proximity-symdef.h"
-
-PA_MODULE_AUTHOR("Lennart Poettering");
-PA_MODULE_DESCRIPTION("Bluetooth Proximity Volume Control");
-PA_MODULE_VERSION(PACKAGE_VERSION);
-PA_MODULE_LOAD_ONCE(TRUE);
-PA_MODULE_USAGE(
-        "sink=<sink name> "
-        "hci=<hci device> "
-);
-
-#define DEFAULT_HCI "hci0"
-
-static const char* const valid_modargs[] = {
-    "sink",
-    "hci",
-    NULL,
-};
-
-struct bonding {
-    struct userdata *userdata;
-    char address[18];
-
-    pid_t pid;
-    int fd;
-
-    pa_io_event *io_event;
-
-    enum {
-        UNKNOWN,
-        FOUND,
-        NOT_FOUND
-    } state;
-};
-
-struct userdata {
-    pa_module *module;
-    pa_dbus_connection *dbus_connection;
-
-    char *sink_name;
-    char *hci, *hci_path;
-
-    pa_hashmap *bondings;
-
-    unsigned n_found;
-    unsigned n_unknown;
-
-    pa_bool_t muted:1;
-    pa_bool_t filter_added:1;
-};
-
-static void update_volume(struct userdata *u) {
-    pa_assert(u);
-
-    if (u->muted && u->n_found > 0) {
-        pa_sink *s;
-
-        u->muted = FALSE;
-
-        if (!(s = pa_namereg_get(u->module->core, u->sink_name, PA_NAMEREG_SINK))) {
-            pa_log_warn("Sink device '%s' not available for unmuting.", pa_strnull(u->sink_name));
-            return;
-        }
-
-        pa_log_info("Found %u BT devices, unmuting.", u->n_found);
-        pa_sink_set_mute(s, FALSE, FALSE);
-
-    } else if (!u->muted && (u->n_found+u->n_unknown) <= 0) {
-        pa_sink *s;
-
-        u->muted = TRUE;
-
-        if (!(s = pa_namereg_get(u->module->core, u->sink_name, PA_NAMEREG_SINK))) {
-            pa_log_warn("Sink device '%s' not available for muting.", pa_strnull(u->sink_name));
-            return;
-        }
-
-        pa_log_info("No BT devices found, muting.");
-        pa_sink_set_mute(s, TRUE, FALSE);
-
-    } else
-        pa_log_info("%u devices now active, %u with unknown state.", u->n_found, u->n_unknown);
-}
-
-static void bonding_free(struct bonding *b) {
-    pa_assert(b);
-
-    if (b->state == FOUND)
-        pa_assert_se(b->userdata->n_found-- >= 1);
-
-    if (b->state == UNKNOWN)
-        pa_assert_se(b->userdata->n_unknown-- >= 1);
-
-    if (b->pid != (pid_t) -1) {
-        kill(b->pid, SIGTERM);
-        waitpid(b->pid, NULL, 0);
-    }
-
-    if (b->fd >= 0)
-        pa_close(b->fd);
-
-    if (b->io_event)
-        b->userdata->module->core->mainloop->io_free(b->io_event);
-
-    pa_xfree(b);
-}
-
-static void io_event_cb(
-        pa_mainloop_api*a,
-        pa_io_event* e,
-        int fd,
-        pa_io_event_flags_t events,
-        void *userdata) {
-
-    struct bonding *b = userdata;
-    char x;
-    ssize_t r;
-
-    pa_assert(b);
-
-    if ((r = read(fd, &x, 1)) <= 0) {
-        pa_log_warn("Child watching '%s' died abnormally: %s", b->address, r == 0 ? "EOF" : pa_cstrerror(errno));
-
-        pa_assert_se(pa_hashmap_remove(b->userdata->bondings, b->address) == b);
-        bonding_free(b);
-        return;
-    }
-
-    pa_assert_se(r == 1);
-
-    if (b->state == UNKNOWN)
-        pa_assert_se(b->userdata->n_unknown-- >= 1);
-
-    if (x == '+') {
-        pa_assert(b->state == UNKNOWN || b->state == NOT_FOUND);
-
-        b->state = FOUND;
-        b->userdata->n_found++;
-
-        pa_log_info("Device '%s' is alive.", b->address);
-
-    } else {
-        pa_assert(x == '-');
-        pa_assert(b->state == UNKNOWN || b->state == FOUND);
-
-        if (b->state == FOUND)
-            b->userdata->n_found--;
-
-        b->state = NOT_FOUND;
-
-        pa_log_info("Device '%s' is dead.", b->address);
-    }
-
-    update_volume(b->userdata);
-}
-
-static struct bonding* bonding_new(struct userdata *u, const char *a) {
-    struct bonding *b = NULL;
-    DBusMessage *m = NULL, *r = NULL;
-    DBusError e;
-    const char *class;
-
-    pa_assert(u);
-    pa_assert(a);
-
-    pa_return_val_if_fail(strlen(a) == 17, NULL);
-    pa_return_val_if_fail(!pa_hashmap_get(u->bondings, a), NULL);
-
-    dbus_error_init(&e);
-
-    pa_assert_se(m = dbus_message_new_method_call("org.bluez", u->hci_path, "org.bluez.Adapter", "GetRemoteMajorClass"));
-    pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, &a, DBUS_TYPE_INVALID));
-    r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(u->dbus_connection), m, -1, &e);
-
-    if (!r) {
-        pa_log("org.bluez.Adapter.GetRemoteMajorClass(%s) failed: %s", a, e.message);
-        goto fail;
-    }
-
-    if (!(dbus_message_get_args(r, &e, DBUS_TYPE_STRING, &class, DBUS_TYPE_INVALID))) {
-        pa_log("Malformed org.bluez.Adapter.GetRemoteMajorClass signal: %s", e.message);
-        goto fail;
-    }
-
-    if (strcmp(class, "phone")) {
-        pa_log_info("Found device '%s' of class '%s', ignoring.", a, class);
-        goto fail;
-    }
-
-    b = pa_xnew(struct bonding, 1);
-    b->userdata = u;
-    pa_strlcpy(b->address, a, sizeof(b->address));
-    b->pid = (pid_t) -1;
-    b->fd = -1;
-    b->io_event = NULL;
-    b->state = UNKNOWN;
-    u->n_unknown ++;
-
-    pa_log_info("Watching device '%s' of class '%s'.", b->address, class);
-
-    if ((b->fd = pa_start_child_for_read(PA_BT_PROXIMITY_HELPER, a, &b->pid)) < 0) {
-        pa_log("Failed to start helper tool.");
-        goto fail;
-    }
-
-    b->io_event = u->module->core->mainloop->io_new(
-            u->module->core->mainloop,
-            b->fd,
-            PA_IO_EVENT_INPUT,
-            io_event_cb,
-            b);
-
-    dbus_message_unref(m);
-    dbus_message_unref(r);
-
-    pa_hashmap_put(u->bondings, b->address, b);
-
-    return b;
-
-fail:
-    if (m)
-        dbus_message_unref(m);
-    if (r)
-        dbus_message_unref(r);
-
-    if (b)
-        bonding_free(b);
-
-    dbus_error_free(&e);
-    return NULL;
-}
-
-static void bonding_remove(struct userdata *u, const char *a) {
-    struct bonding *b;
-    pa_assert(u);
-
-    pa_return_if_fail((b = pa_hashmap_remove(u->bondings, a)));
-
-    pa_log_info("No longer watching device '%s'", b->address);
-    bonding_free(b);
-}
-
-static DBusHandlerResult filter_func(DBusConnection *connection, DBusMessage *m, void *userdata) {
-    struct userdata *u = userdata;
-    DBusError e;
-
-    dbus_error_init(&e);
-
-    if (dbus_message_is_signal(m, "org.bluez.Adapter", "BondingCreated")) {
-        const char *a;
-
-        if (!(dbus_message_get_args(m, &e, DBUS_TYPE_STRING, &a, DBUS_TYPE_INVALID))) {
-            pa_log("Malformed org.bluez.Adapter.BondingCreated signal: %s", e.message);
-            goto finish;
-        }
-
-        bonding_new(u, a);
-
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-    } else if (dbus_message_is_signal(m, "org.bluez.Adapter", "BondingRemoved")) {
-
-        const char *a;
-
-        if (!(dbus_message_get_args(m, &e, DBUS_TYPE_STRING, &a, DBUS_TYPE_INVALID))) {
-            pa_log("Malformed org.bluez.Adapter.BondingRemoved signal: %s", e.message);
-            goto finish;
-        }
-
-        bonding_remove(u, a);
-
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-    }
-
-finish:
-
-    dbus_error_free(&e);
-
-    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-static int update_matches(struct userdata *u, pa_bool_t add) {
-    char *filter1, *filter2;
-    DBusError e;
-    int r = -1;
-
-    pa_assert(u);
-    dbus_error_init(&e);
-
-    filter1 = pa_sprintf_malloc("type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='BondingCreated',path='%s'", u->hci_path);
-    filter2 = pa_sprintf_malloc("type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='BondingRemoved',path='%s'", u->hci_path);
-
-    if (add) {
-        dbus_bus_add_match(pa_dbus_connection_get(u->dbus_connection), filter1, &e);
-
-        if (dbus_error_is_set(&e)) {
-            pa_log("dbus_bus_add_match(%s) failed: %s", filter1, e.message);
-            goto finish;
-        }
-    } else
-        dbus_bus_remove_match(pa_dbus_connection_get(u->dbus_connection), filter1, NULL);
-
-
-    if (add) {
-        dbus_bus_add_match(pa_dbus_connection_get(u->dbus_connection), filter2, &e);
-
-        if (dbus_error_is_set(&e)) {
-            pa_log("dbus_bus_add_match(%s) failed: %s", filter2, e.message);
-            dbus_bus_remove_match(pa_dbus_connection_get(u->dbus_connection), filter1, NULL);
-            goto finish;
-        }
-    } else
-        dbus_bus_remove_match(pa_dbus_connection_get(u->dbus_connection), filter2, NULL);
-
-    if (add) {
-        pa_assert_se(dbus_connection_add_filter(pa_dbus_connection_get(u->dbus_connection), filter_func, u, NULL));
-        u->filter_added = TRUE;
-    } else if (u->filter_added)
-        dbus_connection_remove_filter(pa_dbus_connection_get(u->dbus_connection), filter_func, u);
-
-    r = 0;
-
-finish:
-    pa_xfree(filter1);
-    pa_xfree(filter2);
-    dbus_error_free(&e);
-
-    return r;
-}
-
-int pa__init(pa_module*m) {
-    pa_modargs *ma = NULL;
-    struct userdata *u;
-    DBusError e;
-    DBusMessage *msg = NULL, *r = NULL;
-    DBusMessageIter iter, sub;
-
-    pa_assert(m);
-    dbus_error_init(&e);
-
-    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
-        pa_log("Failed to parse module arguments");
-        goto fail;
-    }
-
-    m->userdata = u = pa_xnew0(struct userdata, 1);
-    u->module = m;
-    u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
-    u->hci = pa_xstrdup(pa_modargs_get_value(ma, "hci", DEFAULT_HCI));
-    u->hci_path = pa_sprintf_malloc("/org/bluez/%s", u->hci);
-    u->bondings = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-
-    if (!(u->dbus_connection = pa_dbus_bus_get(m->core, DBUS_BUS_SYSTEM, &e))) {
-        pa_log("Failed to get D-Bus connection: %s", e.message);
-        goto fail;
-    }
-
-    if (update_matches(u, TRUE) < 0)
-        goto fail;
-
-    pa_assert_se(msg = dbus_message_new_method_call("org.bluez", u->hci_path, "org.bluez.Adapter", "ListBondings"));
-
-    if (!(r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(u->dbus_connection), msg, -1, &e))) {
-        pa_log("org.bluez.Adapter.ListBondings failed: %s", e.message);
-        goto fail;
-    }
-
-    dbus_message_iter_init(r, &iter);
-
-    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
-        pa_log("Malformed reply to org.bluez.Adapter.ListBondings.");
-        goto fail;
-    }
-
-    dbus_message_iter_recurse(&iter, &sub);
-
-    while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) {
-        const char *a = NULL;
-
-        dbus_message_iter_get_basic(&sub, &a);
-        bonding_new(u, a);
-
-        dbus_message_iter_next(&sub);
-    }
-
-    dbus_message_unref(r);
-    dbus_message_unref(msg);
-
-    pa_modargs_free(ma);
-
-    if (pa_hashmap_size(u->bondings) == 0)
-        pa_log_warn("Warning: no phone device bonded.");
-
-    update_volume(u);
-
-    return 0;
-
-fail:
-
-    if (ma)
-        pa_modargs_free(ma);
-
-    pa__done(m);
-
-    dbus_error_free(&e);
-
-    if (msg)
-        dbus_message_unref(msg);
-
-    if (r)
-        dbus_message_unref(r);
-
-    return -1;
-}
-
-void pa__done(pa_module*m) {
-    struct userdata *u;
-    pa_assert(m);
-
-    if (!(u = m->userdata))
-        return;
-
-    if (u->bondings) {
-        struct bonding *b;
-
-        while ((b = pa_hashmap_steal_first(u->bondings)))
-            bonding_free(b);
-
-        pa_hashmap_free(u->bondings, NULL, NULL);
-    }
-
-    if (u->dbus_connection) {
-        update_matches(u, FALSE);
-        pa_dbus_connection_unref(u->dbus_connection);
-    }
-
-    pa_xfree(u->sink_name);
-    pa_xfree(u->hci_path);
-    pa_xfree(u->hci);
-    pa_xfree(u);
-}
@@ -1,7 +1,8 @@
 /***
   This file is part of PulseAudio.
 
-  Copyright 2008-2009 Joao Paulo Rechi Vita
+  Copyright 2008-2013 João Paulo Rechi Vita
+  Copyright 2011-2013 BMW Car IT GmbH.
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as
 
 #include <string.h>
 #include <errno.h>
+#include <math.h>
 #include <linux/sockios.h>
 #include <arpa/inet.h>
+#ifdef BLUETOOTH_APTX_SUPPORT
+#include <dlfcn.h>
+#endif
 
-#include <pulse/i18n.h>
 #include <pulse/rtclock.h>
 #include <pulse/sample.h>
 #include <pulse/timeval.h>
 #include <pulse/xmalloc.h>
 
+#include <pulsecore/i18n.h>
 #include <pulsecore/module.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/core-rtclock.h>
 #include <pulsecore/rtpoll.h>
 #include <pulsecore/time-smoother.h>
 #include <pulsecore/namereg.h>
-#include <pulsecore/dbus-shared.h>
 
-#include "module-bluetooth-device-symdef.h"
-#include "ipc.h"
-#include "sbc.h"
+#include <sbc/sbc.h>
+
+#include "module-bluez4-device-symdef.h"
 #include "a2dp-codecs.h"
 #include "rtp.h"
-#include "bluetooth-util.h"
+#include "bluez4-util.h"
 
 #define BITPOOL_DEC_LIMIT 32
 #define BITPOOL_DEC_STEP 5
-#define HSP_MAX_GAIN 15
 
-PA_MODULE_AUTHOR("Joao Paulo Rechi Vita");
-PA_MODULE_DESCRIPTION("Bluetooth audio sink and source");
+PA_MODULE_AUTHOR("João Paulo Rechi Vita");
+PA_MODULE_DESCRIPTION("BlueZ 4 Bluetooth audio sink and source");
 PA_MODULE_VERSION(PACKAGE_VERSION);
-PA_MODULE_LOAD_ONCE(FALSE);
+PA_MODULE_LOAD_ONCE(false);
 PA_MODULE_USAGE(
         "name=<name for the card/sink/source, to be prefixed> "
         "card_name=<name for the card> "
@@ -103,11 +106,14 @@ static const char* const valid_modargs[] = {
 };
 
 struct a2dp_info {
-    sbc_capabilities_t sbc_capabilities;
     sbc_t sbc;                           /* Codec data */
-    pa_bool_t sbc_initialized;           /* Keep track if the encoder is initialized */
+    bool sbc_initialized;                /* Keep track if the encoder is initialized */
     size_t codesize, frame_length;       /* SBC Codesize, frame_length. We simply cache those values here */
 
+#ifdef BLUETOOTH_APTX_SUPPORT
+    pa_bool_t aptx_initialized;        /* Keep track if the encoder is initialized */
+    void *aptx;                        /* Codec data */
+#endif
     void* buffer;                        /* Codec transfer buffer */
     size_t buffer_size;                  /* Size of the buffer */
 
@@ -117,13 +123,10 @@ struct a2dp_info {
 };
 
 struct hsp_info {
-    pcm_capabilities_t pcm_capabilities;
     pa_sink *sco_sink;
     void (*sco_sink_set_volume)(pa_sink *s);
     pa_source *sco_source;
     void (*sco_source_set_volume)(pa_source *s);
-    pa_hook_slot *sink_state_changed_slot;
-    pa_hook_slot *source_state_changed_slot;
 };
 
 struct bluetooth_msg {
@@ -139,15 +142,25 @@ struct userdata {
     pa_core *core;
     pa_module *module;
 
+    pa_bluez4_device *device;
+    pa_hook_slot *uuid_added_slot;
     char *address;
     char *path;
-    char *transport;
-    char *accesstype;
+    pa_bluez4_transport *transport;
+    bool transport_acquired;
+    pa_hook_slot *discovery_slot;
+    pa_hook_slot *sink_state_changed_slot;
+    pa_hook_slot *source_state_changed_slot;
+    pa_hook_slot *transport_state_changed_slot;
+    pa_hook_slot *transport_nrec_changed_slot;
+    pa_hook_slot *transport_microphone_changed_slot;
+    pa_hook_slot *transport_speaker_changed_slot;
 
-    pa_bluetooth_discovery *discovery;
-    pa_bool_t auto_connect;
+    pa_bluez4_discovery *discovery;
+    bool auto_connect;
 
-    pa_dbus_connection *connection;
+    char *output_port_name;
+    char *input_port_name;
 
     pa_card *card;
     pa_sink *sink;
@@ -167,23 +180,22 @@ struct userdata {
 
     pa_sample_spec sample_spec, requested_sample_spec;
 
-    int service_fd;
     int stream_fd;
 
-    size_t link_mtu;
-    size_t block_size;
+    size_t read_link_mtu;
+    size_t read_block_size;
+
+    size_t write_link_mtu;
+    size_t write_block_size;
 
     struct a2dp_info a2dp;
     struct hsp_info hsp;
 
-    enum profile profile;
+    pa_bluez4_profile_t profile;
 
     pa_modargs *modargs;
 
     int stream_write_type;
-    int service_write_type, service_read_type;
-
-    pa_bool_t filter_added;
 };
 
 enum {
@@ -198,568 +210,48 @@ enum {
 
 #define MAX_PLAYBACK_CATCH_UP_USEC (100*PA_USEC_PER_MSEC)
 
-#define USE_SCO_OVER_PCM(u) (u->profile == PROFILE_HSP && (u->hsp.sco_sink && u->hsp.sco_source))
+#define USE_SCO_OVER_PCM(u) (u->profile == PA_BLUEZ4_PROFILE_HSP && (u->hsp.sco_sink && u->hsp.sco_source))
 
-static int init_bt(struct userdata *u);
 static int init_profile(struct userdata *u);
 
-static int service_send(struct userdata *u, const bt_audio_msg_header_t *msg) {
-    ssize_t r;
-
-    pa_assert(u);
-    pa_assert(msg);
-    pa_assert(msg->length > 0);
-
-    if (u->service_fd < 0) {
-        pa_log_warn("Service not connected");
-        return -1;
-    }
-
-    pa_log_debug("Sending %s -> %s",
-                 pa_strnull(bt_audio_strtype(msg->type)),
-                 pa_strnull(bt_audio_strname(msg->name)));
-
-    if ((r = pa_loop_write(u->service_fd, msg, msg->length, &u->service_write_type)) == (ssize_t) msg->length)
-        return 0;
-
-    if (r < 0)
-        pa_log_error("Error sending data to audio service: %s", pa_cstrerror(errno));
-    else
-        pa_log_error("Short write()");
-
-    return -1;
-}
-
-static int service_recv(struct userdata *u, bt_audio_msg_header_t *msg, size_t room) {
-    ssize_t r;
-
-    pa_assert(u);
-    pa_assert(u->service_fd >= 0);
-    pa_assert(msg);
-    pa_assert(room >= sizeof(*msg));
-
-    pa_log_debug("Trying to receive message from audio service...");
-
-    /* First, read the header */
-    if ((r = pa_loop_read(u->service_fd, msg, sizeof(*msg), &u->service_read_type)) != sizeof(*msg))
-        goto read_fail;
-
-    if (msg->length < sizeof(*msg)) {
-        pa_log_error("Invalid message size.");
-        return -1;
-    }
-
-    if (msg->length > room) {
-        pa_log_error("Not enough room.");
-        return -1;
-    }
-
-    /* Secondly, read the payload */
-    if (msg->length > sizeof(*msg)) {
-
-        size_t remains = msg->length - sizeof(*msg);
-
-        if ((r = pa_loop_read(u->service_fd,
-                              (uint8_t*) msg + sizeof(*msg),
-                              remains,
-                              &u->service_read_type)) != (ssize_t) remains)
-            goto read_fail;
-    }
-
-    pa_log_debug("Received %s <- %s",
-                 pa_strnull(bt_audio_strtype(msg->type)),
-                 pa_strnull(bt_audio_strname(msg->name)));
-
-    return 0;
-
-read_fail:
-
-    if (r < 0)
-        pa_log_error("Error receiving data from audio service: %s", pa_cstrerror(errno));
-    else
-        pa_log_error("Short read()");
-
-    return -1;
-}
-
-static ssize_t service_expect(struct userdata*u, bt_audio_msg_header_t *rsp, size_t room, uint8_t expected_name, size_t expected_size) {
-    int r;
-
-    pa_assert(u);
-    pa_assert(u->service_fd >= 0);
-    pa_assert(rsp);
-
-    if ((r = service_recv(u, rsp, room)) < 0)
-        return r;
-
-    if ((rsp->type != BT_INDICATION && rsp->type != BT_RESPONSE) ||
-        rsp->name != expected_name ||
-        (expected_size > 0 && rsp->length != expected_size)) {
-
-        if (rsp->type == BT_ERROR && rsp->length == sizeof(bt_audio_error_t))
-            pa_log_error("Received error condition: %s", pa_cstrerror(((bt_audio_error_t*) rsp)->posix_errno));
-        else
-            pa_log_error("Bogus message %s received while %s was expected",
-                         pa_strnull(bt_audio_strname(rsp->name)),
-                         pa_strnull(bt_audio_strname(expected_name)));
-        return -1;
-    }
-
-    return 0;
-}
-
-/* Run from main thread */
-static int parse_caps(struct userdata *u, uint8_t seid, const struct bt_get_capabilities_rsp *rsp) {
-    uint16_t bytes_left;
-    const codec_capabilities_t *codec;
-
-    pa_assert(u);
-    pa_assert(rsp);
-
-    bytes_left = rsp->h.length - sizeof(*rsp);
-
-    if (bytes_left < sizeof(codec_capabilities_t)) {
-        pa_log_error("Packet too small to store codec information.");
-        return -1;
-    }
-
-    codec = (codec_capabilities_t *) rsp->data; /** ALIGNMENT? **/
-
-    pa_log_debug("Payload size is %lu %lu", (unsigned long) bytes_left, (unsigned long) sizeof(*codec));
-
-    if (((u->profile == PROFILE_A2DP || u->profile == PROFILE_A2DP_SOURCE) && codec->transport != BT_CAPABILITIES_TRANSPORT_A2DP) ||
-        ((u->profile == PROFILE_HSP || u->profile == PROFILE_HFGW) && codec->transport != BT_CAPABILITIES_TRANSPORT_SCO)) {
-        pa_log_error("Got capabilities for wrong codec.");
-        return -1;
-    }
-
-    if (u->profile == PROFILE_HSP || u->profile == PROFILE_HFGW) {
-
-        if (bytes_left <= 0 || codec->length != sizeof(u->hsp.pcm_capabilities))
-            return -1;
-
-        pa_assert(codec->type == BT_HFP_CODEC_PCM);
-
-        if (codec->configured && seid == 0)
-            return codec->seid;
-
-        memcpy(&u->hsp.pcm_capabilities, codec, sizeof(u->hsp.pcm_capabilities));
-
-    } else if (u->profile == PROFILE_A2DP) {
-
-        while (bytes_left > 0) {
-            if ((codec->type == BT_A2DP_SBC_SINK) && !codec->lock)
-                break;
-
-            bytes_left -= codec->length;
-            codec = (const codec_capabilities_t*) ((const uint8_t*) codec + codec->length);
-        }
-
-        if (bytes_left <= 0 || codec->length != sizeof(u->a2dp.sbc_capabilities))
-            return -1;
-
-        pa_assert(codec->type == BT_A2DP_SBC_SINK);
-
-        if (codec->configured && seid == 0)
-            return codec->seid;
-
-        memcpy(&u->a2dp.sbc_capabilities, codec, sizeof(u->a2dp.sbc_capabilities));
-
-    } else if (u->profile == PROFILE_A2DP_SOURCE) {
-
-        while (bytes_left > 0) {
-            if ((codec->type == BT_A2DP_SBC_SOURCE) && !codec->lock)
-                break;
-
-            bytes_left -= codec->length;
-            codec = (const codec_capabilities_t*) ((const uint8_t*) codec + codec->length);
-        }
-
-        if (bytes_left <= 0 || codec->length != sizeof(u->a2dp.sbc_capabilities))
-            return -1;
-
-        pa_assert(codec->type == BT_A2DP_SBC_SOURCE);
-
-        if (codec->configured && seid == 0)
-            return codec->seid;
-
-        memcpy(&u->a2dp.sbc_capabilities, codec, sizeof(u->a2dp.sbc_capabilities));
-    }
-
-    return 0;
-}
-
-/* Run from main thread */
-static int get_caps(struct userdata *u, uint8_t seid) {
-    union {
-        struct bt_get_capabilities_req getcaps_req;
-        struct bt_get_capabilities_rsp getcaps_rsp;
-        bt_audio_error_t error;
-        uint8_t buf[BT_SUGGESTED_BUFFER_SIZE];
-    } msg;
-    int ret;
-
-    pa_assert(u);
-
-    memset(&msg, 0, sizeof(msg));
-    msg.getcaps_req.h.type = BT_REQUEST;
-    msg.getcaps_req.h.name = BT_GET_CAPABILITIES;
-    msg.getcaps_req.h.length = sizeof(msg.getcaps_req);
-    msg.getcaps_req.seid = seid;
-
-    pa_strlcpy(msg.getcaps_req.object, u->path, sizeof(msg.getcaps_req.object));
-    if (u->profile == PROFILE_A2DP || u->profile == PROFILE_A2DP_SOURCE)
-        msg.getcaps_req.transport = BT_CAPABILITIES_TRANSPORT_A2DP;
-    else {
-        pa_assert(u->profile == PROFILE_HSP || u->profile == PROFILE_HFGW);
-        msg.getcaps_req.transport = BT_CAPABILITIES_TRANSPORT_SCO;
-    }
-    msg.getcaps_req.flags = u->auto_connect ? BT_FLAG_AUTOCONNECT : 0;
-
-    if (service_send(u, &msg.getcaps_req.h) < 0)
-        return -1;
-
-    if (service_expect(u, &msg.getcaps_rsp.h, sizeof(msg), BT_GET_CAPABILITIES, 0) < 0)
-        return -1;
-
-    ret = parse_caps(u, seid, &msg.getcaps_rsp);
-    if (ret <= 0)
-        return ret;
-
-    return get_caps(u, ret);
-}
-
-/* Run from main thread */
-static uint8_t a2dp_default_bitpool(uint8_t freq, uint8_t mode) {
-
-    switch (freq) {
-        case BT_SBC_SAMPLING_FREQ_16000:
-        case BT_SBC_SAMPLING_FREQ_32000:
-            return 53;
-
-        case BT_SBC_SAMPLING_FREQ_44100:
-
-            switch (mode) {
-                case BT_A2DP_CHANNEL_MODE_MONO:
-                case BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL:
-                    return 31;
-
-                case BT_A2DP_CHANNEL_MODE_STEREO:
-                case BT_A2DP_CHANNEL_MODE_JOINT_STEREO:
-                    return 53;
-
-                default:
-                    pa_log_warn("Invalid channel mode %u", mode);
-                    return 53;
-            }
-
-        case BT_SBC_SAMPLING_FREQ_48000:
-
-            switch (mode) {
-                case BT_A2DP_CHANNEL_MODE_MONO:
-                case BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL:
-                    return 29;
+#ifdef BLUETOOTH_APTX_SUPPORT
+void* (*aptx_new)(short endian);
+int (*aptx_encode)(void* _state, void* _pcmL, void* _pcmR, void* _buffer);
 
-                case BT_A2DP_CHANNEL_MODE_STEREO:
-                case BT_A2DP_CHANNEL_MODE_JOINT_STEREO:
-                    return 51;
+const char *aptx_new_name = "NewAptxEnc";
+const char *aptx_encode_name = "aptxbtenc_encodestereo";
 
-                default:
-                    pa_log_warn("Invalid channel mode %u", mode);
-                    return 51;
-            }
-
-        default:
-            pa_log_warn("Invalid sampling freq %u", freq);
-            return 53;
-    }
-}
-
-/* Run from main thread */
-static int setup_a2dp(struct userdata *u) {
-    sbc_capabilities_t *cap;
-    int i;
-
-    static const struct {
-        uint32_t rate;
-        uint8_t cap;
-    } freq_table[] = {
-        { 16000U, BT_SBC_SAMPLING_FREQ_16000 },
-        { 32000U, BT_SBC_SAMPLING_FREQ_32000 },
-        { 44100U, BT_SBC_SAMPLING_FREQ_44100 },
-        { 48000U, BT_SBC_SAMPLING_FREQ_48000 }
-    };
-
-    pa_assert(u);
-    pa_assert(u->profile == PROFILE_A2DP || u->profile == PROFILE_A2DP_SOURCE);
-
-    cap = &u->a2dp.sbc_capabilities;
-
-    /* Find the lowest freq that is at least as high as the requested
-     * sampling rate */
-    for (i = 0; (unsigned) i < PA_ELEMENTSOF(freq_table); i++)
-        if (freq_table[i].rate >= u->sample_spec.rate && (cap->frequency & freq_table[i].cap)) {
-            u->sample_spec.rate = freq_table[i].rate;
-            cap->frequency = freq_table[i].cap;
-            break;
-        }
-
-    if ((unsigned) i == PA_ELEMENTSOF(freq_table)) {
-        for (--i; i >= 0; i--) {
-            if (cap->frequency & freq_table[i].cap) {
-                u->sample_spec.rate = freq_table[i].rate;
-                cap->frequency = freq_table[i].cap;
-                break;
-            }
-        }
-
-        if (i < 0) {
-            pa_log("Not suitable sample rate");
-            return -1;
-        }
-    }
-
-    pa_assert((unsigned) i < PA_ELEMENTSOF(freq_table));
+static pa_bool_t pa_load_aptx_sym(void *handle )
+{
+       if (!handle)
+               return FALSE;
 
-    if (cap->capability.configured)
-        return 0;
+       aptx_new = (void* (*)(short endian))dlsym(handle, aptx_new_name);
 
-    if (u->sample_spec.channels <= 1) {
-        if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_MONO) {
-            cap->channel_mode = BT_A2DP_CHANNEL_MODE_MONO;
-            u->sample_spec.channels = 1;
-        } else
-            u->sample_spec.channels = 2;
-    }
+       if (aptx_new) {
+           pa_log_debug("Load Symbol(%s)", aptx_new_name);
+        } else {
+           pa_log_debug("Fail to Load Symbol(%s)", aptx_new_name);
+           return FALSE;
+       }
 
-    if (u->sample_spec.channels >= 2) {
-        u->sample_spec.channels = 2;
+       aptx_encode = (int (*)(void* _state, void* _pcmL, void* _pcmR,
+                                void* _buffer))
+                      dlsym(handle, "aptxbtenc_encodestereo");
 
-        if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_JOINT_STEREO)
-            cap->channel_mode = BT_A2DP_CHANNEL_MODE_JOINT_STEREO;
-        else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO)
-            cap->channel_mode = BT_A2DP_CHANNEL_MODE_STEREO;
-        else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL)
-            cap->channel_mode = BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL;
-        else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_MONO) {
-            cap->channel_mode = BT_A2DP_CHANNEL_MODE_MONO;
-            u->sample_spec.channels = 1;
+       if (aptx_encode) {
+           pa_log_debug("Load Symbol(%s)", aptx_encode_name);
         } else {
-            pa_log("No supported channel modes");
-            return -1;
+           pa_log_debug("Fail to Load Symbol(%s)", aptx_encode_name);
+           return FALSE;
         }
-    }
-
-    if (cap->block_length & BT_A2DP_BLOCK_LENGTH_16)
-        cap->block_length = BT_A2DP_BLOCK_LENGTH_16;
-    else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_12)
-        cap->block_length = BT_A2DP_BLOCK_LENGTH_12;
-    else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_8)
-        cap->block_length = BT_A2DP_BLOCK_LENGTH_8;
-    else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_4)
-        cap->block_length = BT_A2DP_BLOCK_LENGTH_4;
-    else {
-        pa_log_error("No supported block lengths");
-        return -1;
-    }
-
-    if (cap->subbands & BT_A2DP_SUBBANDS_8)
-        cap->subbands = BT_A2DP_SUBBANDS_8;
-    else if (cap->subbands & BT_A2DP_SUBBANDS_4)
-        cap->subbands = BT_A2DP_SUBBANDS_4;
-    else {
-        pa_log_error("No supported subbands");
-        return -1;
-    }
-
-    if (cap->allocation_method & BT_A2DP_ALLOCATION_LOUDNESS)
-        cap->allocation_method = BT_A2DP_ALLOCATION_LOUDNESS;
-    else if (cap->allocation_method & BT_A2DP_ALLOCATION_SNR)
-        cap->allocation_method = BT_A2DP_ALLOCATION_SNR;
-
-    cap->min_bitpool = (uint8_t) PA_MAX(MIN_BITPOOL, cap->min_bitpool);
-    cap->max_bitpool = (uint8_t) PA_MIN(a2dp_default_bitpool(cap->frequency, cap->channel_mode), cap->max_bitpool);
-
-    return 0;
-}
-
-/* Run from main thread */
-static void setup_sbc(struct a2dp_info *a2dp, enum profile p) {
-    sbc_capabilities_t *active_capabilities;
-
-    pa_assert(a2dp);
-
-    active_capabilities = &a2dp->sbc_capabilities;
-
-    if (a2dp->sbc_initialized)
-        sbc_reinit(&a2dp->sbc, 0);
-    else
-        sbc_init(&a2dp->sbc, 0);
-    a2dp->sbc_initialized = TRUE;
-
-    switch (active_capabilities->frequency) {
-        case BT_SBC_SAMPLING_FREQ_16000:
-            a2dp->sbc.frequency = SBC_FREQ_16000;
-            break;
-        case BT_SBC_SAMPLING_FREQ_32000:
-            a2dp->sbc.frequency = SBC_FREQ_32000;
-            break;
-        case BT_SBC_SAMPLING_FREQ_44100:
-            a2dp->sbc.frequency = SBC_FREQ_44100;
-            break;
-        case BT_SBC_SAMPLING_FREQ_48000:
-            a2dp->sbc.frequency = SBC_FREQ_48000;
-            break;
-        default:
-            pa_assert_not_reached();
-    }
-
-    switch (active_capabilities->channel_mode) {
-        case BT_A2DP_CHANNEL_MODE_MONO:
-            a2dp->sbc.mode = SBC_MODE_MONO;
-            break;
-        case BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL:
-            a2dp->sbc.mode = SBC_MODE_DUAL_CHANNEL;
-            break;
-        case BT_A2DP_CHANNEL_MODE_STEREO:
-            a2dp->sbc.mode = SBC_MODE_STEREO;
-            break;
-        case BT_A2DP_CHANNEL_MODE_JOINT_STEREO:
-            a2dp->sbc.mode = SBC_MODE_JOINT_STEREO;
-            break;
-        default:
-            pa_assert_not_reached();
-    }
-
-    switch (active_capabilities->allocation_method) {
-        case BT_A2DP_ALLOCATION_SNR:
-            a2dp->sbc.allocation = SBC_AM_SNR;
-            break;
-        case BT_A2DP_ALLOCATION_LOUDNESS:
-            a2dp->sbc.allocation = SBC_AM_LOUDNESS;
-            break;
-        default:
-            pa_assert_not_reached();
-    }
-
-    switch (active_capabilities->subbands) {
-        case BT_A2DP_SUBBANDS_4:
-            a2dp->sbc.subbands = SBC_SB_4;
-            break;
-        case BT_A2DP_SUBBANDS_8:
-            a2dp->sbc.subbands = SBC_SB_8;
-            break;
-        default:
-            pa_assert_not_reached();
-    }
 
-    switch (active_capabilities->block_length) {
-        case BT_A2DP_BLOCK_LENGTH_4:
-            a2dp->sbc.blocks = SBC_BLK_4;
-            break;
-        case BT_A2DP_BLOCK_LENGTH_8:
-            a2dp->sbc.blocks = SBC_BLK_8;
-            break;
-        case BT_A2DP_BLOCK_LENGTH_12:
-            a2dp->sbc.blocks = SBC_BLK_12;
-            break;
-        case BT_A2DP_BLOCK_LENGTH_16:
-            a2dp->sbc.blocks = SBC_BLK_16;
-            break;
-        default:
-            pa_assert_not_reached();
-    }
-
-    a2dp->min_bitpool = active_capabilities->min_bitpool;
-    a2dp->max_bitpool = active_capabilities->max_bitpool;
-
-    /* Set minimum bitpool for source to get the maximum possible block_size */
-    a2dp->sbc.bitpool = p == PROFILE_A2DP ? a2dp->max_bitpool : a2dp->min_bitpool;
-    a2dp->codesize = sbc_get_codesize(&a2dp->sbc);
-    a2dp->frame_length = sbc_get_frame_length(&a2dp->sbc);
-}
-
-/* Run from main thread */
-static int set_conf(struct userdata *u) {
-    union {
-        struct bt_open_req open_req;
-        struct bt_open_rsp open_rsp;
-        struct bt_set_configuration_req setconf_req;
-        struct bt_set_configuration_rsp setconf_rsp;
-        bt_audio_error_t error;
-        uint8_t buf[BT_SUGGESTED_BUFFER_SIZE];
-    } msg;
-
-    memset(&msg, 0, sizeof(msg));
-    msg.open_req.h.type = BT_REQUEST;
-    msg.open_req.h.name = BT_OPEN;
-    msg.open_req.h.length = sizeof(msg.open_req);
-
-    pa_strlcpy(msg.open_req.object, u->path, sizeof(msg.open_req.object));
-    msg.open_req.seid = (u->profile == PROFILE_A2DP || u->profile == PROFILE_A2DP_SOURCE) ? u->a2dp.sbc_capabilities.capability.seid : BT_A2DP_SEID_RANGE + 1;
-    msg.open_req.lock = (u->profile == PROFILE_A2DP) ? BT_WRITE_LOCK : BT_READ_LOCK | BT_WRITE_LOCK;
-
-    if (service_send(u, &msg.open_req.h) < 0)
-        return -1;
-
-    if (service_expect(u, &msg.open_rsp.h, sizeof(msg), BT_OPEN, sizeof(msg.open_rsp)) < 0)
-        return -1;
-
-    if (u->profile == PROFILE_A2DP || u->profile == PROFILE_A2DP_SOURCE) {
-        u->sample_spec.format = PA_SAMPLE_S16LE;
-
-        if (setup_a2dp(u) < 0)
-            return -1;
-    } else {
-        pa_assert(u->profile == PROFILE_HSP || u->profile == PROFILE_HFGW);
-
-        u->sample_spec.format = PA_SAMPLE_S16LE;
-        u->sample_spec.channels = 1;
-        u->sample_spec.rate = 8000;
-    }
-
-    memset(&msg, 0, sizeof(msg));
-    msg.setconf_req.h.type = BT_REQUEST;
-    msg.setconf_req.h.name = BT_SET_CONFIGURATION;
-    msg.setconf_req.h.length = sizeof(msg.setconf_req);
-
-    if (u->profile == PROFILE_A2DP || u->profile == PROFILE_A2DP_SOURCE) {
-        memcpy(&msg.setconf_req.codec, &u->a2dp.sbc_capabilities, sizeof(u->a2dp.sbc_capabilities));
-    } else {
-        msg.setconf_req.codec.transport = BT_CAPABILITIES_TRANSPORT_SCO;
-        msg.setconf_req.codec.seid = BT_A2DP_SEID_RANGE + 1;
-        msg.setconf_req.codec.length = sizeof(pcm_capabilities_t);
-    }
-    msg.setconf_req.h.length += msg.setconf_req.codec.length - sizeof(msg.setconf_req.codec);
-
-    if (service_send(u, &msg.setconf_req.h) < 0)
-        return -1;
-
-    if (service_expect(u, &msg.setconf_rsp.h, sizeof(msg), BT_SET_CONFIGURATION, sizeof(msg.setconf_rsp)) < 0)
-        return -1;
-
-    u->link_mtu = msg.setconf_rsp.link_mtu;
-
-    /* setup SBC encoder now we agree on parameters */
-    if (u->profile == PROFILE_A2DP || u->profile == PROFILE_A2DP_SOURCE) {
-        setup_sbc(&u->a2dp, u->profile);
-
-        u->block_size =
-            ((u->link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
-            / u->a2dp.frame_length
-            * u->a2dp.codesize);
-
-        pa_log_info("SBC parameters:\n\tallocation=%u\n\tsubbands=%u\n\tblocks=%u\n\tbitpool=%u\n",
-                    u->a2dp.sbc.allocation, u->a2dp.sbc.subbands, u->a2dp.sbc.blocks, u->a2dp.sbc.bitpool);
-    } else
-        u->block_size = u->link_mtu;
-
-    return 0;
+       return TRUE;
 }
+#endif
 
 /* from IO thread */
-static void a2dp_set_bitpool(struct userdata *u, uint8_t bitpool)
-{
+static void a2dp_set_bitpool(struct userdata *u, uint8_t bitpool) {
     struct a2dp_info *a2dp;
 
     pa_assert(u);
@@ -781,21 +273,63 @@ static void a2dp_set_bitpool(struct userdata *u, uint8_t bitpool)
 
     pa_log_debug("Bitpool has changed to %u", a2dp->sbc.bitpool);
 
-    u->block_size =
-            (u->link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
-            / a2dp->frame_length * a2dp->codesize;
+    u->read_block_size =
+        (u->read_link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
+        / a2dp->frame_length * a2dp->codesize;
 
-    pa_sink_set_max_request_within_thread(u->sink, u->block_size);
+    u->write_block_size =
+        (u->write_link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
+        / a2dp->frame_length * a2dp->codesize;
+
+    pa_sink_set_max_request_within_thread(u->sink, u->write_block_size);
     pa_sink_set_fixed_latency_within_thread(u->sink,
-            FIXED_LATENCY_PLAYBACK_A2DP + pa_bytes_to_usec(u->block_size, &u->sample_spec));
+            FIXED_LATENCY_PLAYBACK_A2DP + pa_bytes_to_usec(u->write_block_size, &u->sample_spec));
 }
 
 /* from IO thread, except in SCO over PCM */
+static void bt_transport_config_mtu(struct userdata *u) {
+    /* Calculate block sizes */
+    if (u->profile == PA_BLUEZ4_PROFILE_HSP || u->profile == PA_BLUEZ4_PROFILE_HFGW) {
+        u->read_block_size = u->read_link_mtu;
+        u->write_block_size = u->write_link_mtu;
+    } else {
+        u->read_block_size =
+            (u->read_link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
+            / u->a2dp.frame_length * u->a2dp.codesize;
+
+        u->write_block_size =
+            (u->write_link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
+            / u->a2dp.frame_length * u->a2dp.codesize;
+    }
+
+    if (USE_SCO_OVER_PCM(u))
+        return;
+
+    if (u->sink) {
+        pa_sink_set_max_request_within_thread(u->sink, u->write_block_size);
+        pa_sink_set_fixed_latency_within_thread(u->sink,
+                                                (u->profile == PA_BLUEZ4_PROFILE_A2DP ?
+                                                 FIXED_LATENCY_PLAYBACK_A2DP : FIXED_LATENCY_PLAYBACK_HSP) +
+                                                pa_bytes_to_usec(u->write_block_size, &u->sample_spec));
+    }
 
-static int setup_stream(struct userdata *u) {
+    if (u->source)
+        pa_source_set_fixed_latency_within_thread(u->source,
+                                                  (u->profile == PA_BLUEZ4_PROFILE_A2DP_SOURCE ?
+                                                   FIXED_LATENCY_RECORD_A2DP : FIXED_LATENCY_RECORD_HSP) +
+                                                  pa_bytes_to_usec(u->read_block_size, &u->sample_spec));
+}
+
+/* from IO thread, except in SCO over PCM */
+
+static void setup_stream(struct userdata *u) {
     struct pollfd *pollfd;
     int one;
 
+    pa_log_info("Transport %s resuming", u->transport->path);
+
+    bt_transport_config_mtu(u);
+
     pa_make_fd_nonblock(u->stream_fd);
     pa_make_socket_low_delay(u->stream_fd);
 
@@ -805,7 +339,7 @@ static int setup_stream(struct userdata *u) {
 
     pa_log_debug("Stream properly set up, we're ready to roll!");
 
-    if (u->profile == PROFILE_A2DP)
+    if (u->profile == PA_BLUEZ4_PROFILE_A2DP)
         a2dp_set_bitpool(u, u->a2dp.max_bitpool);
 
     u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1);
@@ -820,81 +354,20 @@ static int setup_stream(struct userdata *u) {
         u->read_smoother = pa_smoother_new(
                 PA_USEC_PER_SEC,
                 PA_USEC_PER_SEC*2,
-                TRUE,
-                TRUE,
+                true,
+                true,
                 10,
                 pa_rtclock_now(),
-                TRUE);
-
-    return 0;
+                true);
 }
 
-static int start_stream_fd(struct userdata *u) {
-    union {
-        bt_audio_msg_header_t rsp;
-        struct bt_start_stream_req start_req;
-        struct bt_start_stream_rsp start_rsp;
-        struct bt_new_stream_ind streamfd_ind;
-        bt_audio_error_t error;
-        uint8_t buf[BT_SUGGESTED_BUFFER_SIZE];
-    } msg;
-
-    pa_assert(u);
-    pa_assert(u->rtpoll);
-    pa_assert(!u->rtpoll_item);
-    pa_assert(u->stream_fd < 0);
-
-    memset(msg.buf, 0, BT_SUGGESTED_BUFFER_SIZE);
-    msg.start_req.h.type = BT_REQUEST;
-    msg.start_req.h.name = BT_START_STREAM;
-    msg.start_req.h.length = sizeof(msg.start_req);
-
-    if (service_send(u, &msg.start_req.h) < 0)
-        return -1;
-
-    if (service_expect(u, &msg.rsp, sizeof(msg), BT_START_STREAM, sizeof(msg.start_rsp)) < 0)
-        return -1;
-
-    if (service_expect(u, &msg.rsp, sizeof(msg), BT_NEW_STREAM, sizeof(msg.streamfd_ind)) < 0)
-        return -1;
-
-    if ((u->stream_fd = bt_audio_service_get_data_fd(u->service_fd)) < 0) {
-        pa_log("Failed to get stream fd from audio service.");
-        return -1;
-    }
-
-    return setup_stream(u);
-}
-
-/* from IO thread */
-static int stop_stream_fd(struct userdata *u) {
-    union {
-        bt_audio_msg_header_t rsp;
-        struct bt_stop_stream_req start_req;
-        struct bt_stop_stream_rsp start_rsp;
-        bt_audio_error_t error;
-        uint8_t buf[BT_SUGGESTED_BUFFER_SIZE];
-    } msg;
-    int r = 0;
-
-    pa_assert(u);
-    pa_assert(u->rtpoll);
-
+static void teardown_stream(struct userdata *u) {
     if (u->rtpoll_item) {
         pa_rtpoll_item_free(u->rtpoll_item);
         u->rtpoll_item = NULL;
     }
 
     if (u->stream_fd >= 0) {
-        memset(msg.buf, 0, BT_SUGGESTED_BUFFER_SIZE);
-        msg.start_req.h.type = BT_REQUEST;
-        msg.start_req.h.name = BT_STOP_STREAM;
-        msg.start_req.h.length = sizeof(msg.start_req);
-
-        if (service_send(u, &msg.start_req.h) < 0 ||
-            service_expect(u, &msg.rsp, sizeof(msg), BT_STOP_STREAM, sizeof(msg.start_rsp)) < 0)
-            r = -1;
-
         pa_close(u->stream_fd);
         u->stream_fd = -1;
     }
@@ -904,85 +377,62 @@ static int stop_stream_fd(struct userdata *u) {
         u->read_smoother = NULL;
     }
 
-    return r;
+    if (u->write_memchunk.memblock) {
+        pa_memblock_unref(u->write_memchunk.memblock);
+        pa_memchunk_reset(&u->write_memchunk);
+    }
+
+    pa_log_debug("Audio stream torn down");
 }
 
 static void bt_transport_release(struct userdata *u) {
-    const char *accesstype = "rw";
-    const pa_bluetooth_transport *t;
+    pa_assert(u->transport);
 
     /* Ignore if already released */
-    if (!u->accesstype)
+    if (!u->transport_acquired)
         return;
 
-    pa_log_debug("Releasing transport %s", u->transport);
+    pa_log_debug("Releasing transport %s", u->transport->path);
 
-    t = pa_bluetooth_discovery_get_transport(u->discovery, u->transport);
-    if (t)
-        pa_bluetooth_transport_release(t, accesstype);
-
-    pa_xfree(u->accesstype);
-    u->accesstype = NULL;
-
-    if (u->rtpoll_item) {
-        pa_rtpoll_item_free(u->rtpoll_item);
-        u->rtpoll_item = NULL;
-    }
+    pa_bluez4_transport_release(u->transport);
 
-    if (u->stream_fd >= 0) {
-        pa_close(u->stream_fd);
-        u->stream_fd = -1;
-    }
+    u->transport_acquired = false;
 
-    if (u->read_smoother) {
-        pa_smoother_free(u->read_smoother);
-        u->read_smoother = NULL;
-    }
+    teardown_stream(u);
 }
 
-static int bt_transport_acquire(struct userdata *u, pa_bool_t start) {
-    const char *accesstype = "rw";
-    const pa_bluetooth_transport *t;
+static int bt_transport_acquire(struct userdata *u, bool optional) {
+    pa_assert(u->transport);
 
-    if (u->accesstype) {
-        if (start)
-            goto done;
+    if (u->transport_acquired)
         return 0;
-    }
 
-    pa_log_debug("Acquiring transport %s", u->transport);
+    pa_log_debug("Acquiring transport %s", u->transport->path);
 
-    t = pa_bluetooth_discovery_get_transport(u->discovery, u->transport);
-    if (!t) {
-        pa_log("Transport %s no longer available", u->transport);
-        pa_xfree(u->transport);
-        u->transport = NULL;
-        return -1;
-    }
+    u->stream_fd = pa_bluez4_transport_acquire(u->transport, optional, &u->read_link_mtu, &u->write_link_mtu);
+    if (u->stream_fd < 0) {
+        if (!optional)
+            pa_log("Failed to acquire transport %s", u->transport->path);
+        else
+            pa_log_info("Failed optional acquire of transport %s", u->transport->path);
 
-    /* FIXME: Handle in/out MTU properly when unix socket is not longer supported */
-    u->stream_fd = pa_bluetooth_transport_acquire(t, accesstype, NULL, &u->link_mtu);
-    if (u->stream_fd < 0)
         return -1;
+    }
 
-    u->accesstype = pa_xstrdup(accesstype);
-    pa_log_info("Transport %s acquired: fd %d", u->transport, u->stream_fd);
-
-    if (!start)
-        return 0;
+    u->transport_acquired = true;
+    pa_log_info("Transport %s acquired: fd %d", u->transport->path, u->stream_fd);
 
-done:
-    pa_log_info("Transport %s resuming", u->transport);
-    return setup_stream(u);
+    return 0;
 }
 
 /* Run from IO thread */
 static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
     struct userdata *u = PA_SINK(o)->userdata;
-    pa_bool_t failed = FALSE;
+    bool failed = false;
     int r;
 
     pa_assert(u->sink == PA_SINK(o));
+    pa_assert(u->transport);
 
     switch (code) {
 
@@ -991,18 +441,16 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
             switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) {
 
                 case PA_SINK_SUSPENDED:
-                    pa_assert(PA_SINK_IS_OPENED(u->sink->thread_info.state));
+                    /* Ignore if transition is PA_SINK_INIT->PA_SINK_SUSPENDED */
+                    if (!PA_SINK_IS_OPENED(u->sink->thread_info.state))
+                        break;
 
                     /* Stop the device if the source is suspended as well */
-                    if (!u->source || u->source->state == PA_SOURCE_SUSPENDED) {
+                    if (!u->source || u->source->state == PA_SOURCE_SUSPENDED)
                         /* We deliberately ignore whether stopping
                          * actually worked. Since the stream_fd is
                          * closed it doesn't really matter */
-                        if (u->transport)
-                            bt_transport_release(u);
-                        else
-                            stop_stream_fd(u);
-                    }
+                        bt_transport_release(u);
 
                     break;
 
@@ -1012,12 +460,11 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
                         break;
 
                     /* Resume the device if the source was suspended as well */
-                    if (!u->source || u->source->state == PA_SOURCE_SUSPENDED) {
-                        if (u->transport) {
-                            if (bt_transport_acquire(u, TRUE) < 0)
-                                failed = TRUE;
-                        } else if (start_stream_fd(u) < 0)
-                            failed = TRUE;
+                    if (!u->source || !PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
+                        if (bt_transport_acquire(u, false) < 0)
+                            failed = true;
+                        else
+                            setup_stream(u);
                     }
                     break;
 
@@ -1034,7 +481,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
                 pa_usec_t wi, ri;
 
                 ri = pa_smoother_get(u->read_smoother, pa_rtclock_now());
-                wi = pa_bytes_to_usec(u->write_index + u->block_size, &u->sample_spec);
+                wi = pa_bytes_to_usec(u->write_index + u->write_block_size, &u->sample_spec);
 
                 *((pa_usec_t*) data) = wi > ri ? wi - ri : 0;
             } else {
@@ -1059,10 +506,11 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
 /* Run from IO thread */
 static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
     struct userdata *u = PA_SOURCE(o)->userdata;
-    pa_bool_t failed = FALSE;
+    bool failed = false;
     int r;
 
     pa_assert(u->source == PA_SOURCE(o));
+    pa_assert(u->transport);
 
     switch (code) {
 
@@ -1071,15 +519,13 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
             switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) {
 
                 case PA_SOURCE_SUSPENDED:
-                    pa_assert(PA_SOURCE_IS_OPENED(u->source->thread_info.state));
+                    /* Ignore if transition is PA_SOURCE_INIT->PA_SOURCE_SUSPENDED */
+                    if (!PA_SOURCE_IS_OPENED(u->source->thread_info.state))
+                        break;
 
                     /* Stop the device if the sink is suspended as well */
-                    if (!u->sink || u->sink->state == PA_SINK_SUSPENDED) {
-                        if (u->transport)
-                            bt_transport_release(u);
-                        else
-                            stop_stream_fd(u);
-                    }
+                    if (!u->sink || u->sink->state == PA_SINK_SUSPENDED)
+                        bt_transport_release(u);
 
                     if (u->read_smoother)
                         pa_smoother_pause(u->read_smoother, pa_rtclock_now());
@@ -1091,12 +537,11 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
                         break;
 
                     /* Resume the device if the sink was suspended as well */
-                    if (!u->sink || u->sink->thread_info.state == PA_SINK_SUSPENDED) {
-                        if (u->transport) {
-                            if (bt_transport_acquire(u, TRUE) < 0)
-                            failed = TRUE;
-                        } else if (start_stream_fd(u) < 0)
-                            failed = TRUE;
+                    if (!u->sink || !PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
+                        if (bt_transport_acquire(u, false) < 0)
+                            failed = true;
+                        else
+                            setup_stream(u);
                     }
                     /* We don't resume the smoother here. Instead we
                      * wait until the first packet arrives */
@@ -1133,23 +578,17 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
 /* Called from main thread context */
 static int device_process_msg(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
     struct bluetooth_msg *u = BLUETOOTH_MSG(obj);
-    char *user_data = (char*)data;
 
     switch (code) {
         case BLUETOOTH_MESSAGE_IO_THREAD_FAILED: {
             if (u->card->module->unload_requested)
                 break;
 
-           pa_log_debug("Switching the profile to off due to IO thread failure.");
-           if (user_data == NULL)
-               break;
+            pa_log_debug("Switching the profile to off due to IO thread failure.");
 
-           if (pa_streq(user_data, "off")) {
-               if (pa_card_set_profile(u->card, "off", FALSE) < 0)
-                   pa_log_debug("Failed to switch profile to off");
-           }
-           break;
-       }
+            pa_assert_se(pa_card_set_profile(u->card, "off", false) >= 0);
+            break;
+        }
     }
     return 0;
 }
@@ -1159,14 +598,14 @@ static int hsp_process_render(struct userdata *u) {
     int ret = 0;
 
     pa_assert(u);
-    pa_assert(u->profile == PROFILE_HSP || u->profile == PROFILE_HFGW);
+    pa_assert(u->profile == PA_BLUEZ4_PROFILE_HSP || u->profile == PA_BLUEZ4_PROFILE_HFGW);
     pa_assert(u->sink);
 
     /* First, render some data */
     if (!u->write_memchunk.memblock)
-        pa_sink_render_full(u->sink, u->block_size, &u->write_memchunk);
+        pa_sink_render_full(u->sink, u->write_block_size, &u->write_memchunk);
 
-    pa_assert(u->write_memchunk.length == u->block_size);
+    pa_assert(u->write_memchunk.length == u->write_block_size);
 
     for (;;) {
         ssize_t l;
@@ -1176,7 +615,7 @@ static int hsp_process_render(struct userdata *u) {
          * SEQPACKET, and we generated the data of the MTU size, so this
          * should just work. */
 
-        p = (const uint8_t*) pa_memblock_acquire(u->write_memchunk.memblock) + u->write_memchunk.index;
+        p = (const uint8_t *) pa_memblock_acquire_chunk(&u->write_memchunk);
         l = pa_write(u->stream_fd, p, u->write_memchunk.length, &u->stream_write_type);
         pa_memblock_release(u->write_memchunk.memblock);
 
@@ -1224,11 +663,11 @@ static int hsp_process_push(struct userdata *u) {
     pa_memchunk memchunk;
 
     pa_assert(u);
-    pa_assert(u->profile == PROFILE_HSP || u->profile == PROFILE_HFGW);
+    pa_assert(u->profile == PA_BLUEZ4_PROFILE_HSP || u->profile == PA_BLUEZ4_PROFILE_HFGW);
     pa_assert(u->source);
     pa_assert(u->read_smoother);
 
-    memchunk.memblock = pa_memblock_new(u->core->mempool, u->block_size);
+    memchunk.memblock = pa_memblock_new(u->core->mempool, u->read_block_size);
     memchunk.index = memchunk.length = 0;
 
     for (;;) {
@@ -1238,7 +677,7 @@ static int hsp_process_push(struct userdata *u) {
         struct cmsghdr *cm;
         uint8_t aux[1024];
         struct iovec iov;
-        pa_bool_t found_tstamp = FALSE;
+        bool found_tstamp = false;
         pa_usec_t tstamp;
 
         memset(&m, 0, sizeof(m));
@@ -1258,125 +697,264 @@ static int hsp_process_push(struct userdata *u) {
 
         if (l <= 0) {
 
-            if (l < 0 && errno == EINTR)
+            if (l < 0 && errno == EINTR)
+                /* Retry right away if we got interrupted */
+                continue;
+
+            else if (l < 0 && errno == EAGAIN)
+                /* Hmm, apparently the socket was not readable, give up for now. */
+                break;
+
+            pa_log_error("Failed to read data from SCO socket: %s", l < 0 ? pa_cstrerror(errno) : "EOF");
+            ret = -1;
+            break;
+        }
+
+        pa_assert((size_t) l <= pa_memblock_get_length(memchunk.memblock));
+
+        /* In some rare occasions, we might receive packets of a very strange
+         * size. This could potentially be possible if the SCO packet was
+         * received partially over-the-air, or more probably due to hardware
+         * issues in our Bluetooth adapter. In these cases, in order to avoid
+         * an assertion failure due to unaligned data, just discard the whole
+         * packet */
+        if (!pa_frame_aligned(l, &u->sample_spec)) {
+            pa_log_warn("SCO packet received of unaligned size: %zu", l);
+            break;
+        }
+
+        memchunk.length = (size_t) l;
+        u->read_index += (uint64_t) l;
+
+        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!");
+            tstamp = pa_rtclock_now();
+        }
+
+        pa_smoother_put(u->read_smoother, tstamp, pa_bytes_to_usec(u->read_index, &u->sample_spec));
+        pa_smoother_resume(u->read_smoother, tstamp, true);
+
+        pa_source_post(u->source, &memchunk);
+
+        ret = l;
+        break;
+    }
+
+    pa_memblock_unref(memchunk.memblock);
+
+    return ret;
+}
+
+/* Run from IO thread */
+static void a2dp_prepare_buffer(struct userdata *u) {
+    size_t min_buffer_size = PA_MAX(u->read_link_mtu, u->write_link_mtu);
+
+    pa_assert(u);
+
+    if (u->a2dp.buffer_size >= min_buffer_size)
+        return;
+
+    u->a2dp.buffer_size = 2 * min_buffer_size;
+    pa_xfree(u->a2dp.buffer);
+    u->a2dp.buffer = pa_xmalloc(u->a2dp.buffer_size);
+}
+
+/* Run from IO thread */
+static int a2dp_process_render(struct userdata *u) {
+    struct a2dp_info *a2dp;
+    struct rtp_header *header;
+    struct rtp_payload *payload;
+    size_t nbytes;
+    void *d;
+    const void *p;
+    size_t to_write, to_encode;
+    unsigned frame_count;
+    int ret = 0;
+
+    pa_assert(u);
+    pa_assert(u->profile == PA_BLUEZ4_PROFILE_A2DP);
+    pa_assert(u->sink);
+
+    /* First, render some data */
+    if (!u->write_memchunk.memblock)
+        pa_sink_render_full(u->sink, u->write_block_size, &u->write_memchunk);
+
+    pa_assert(u->write_memchunk.length == u->write_block_size);
+
+    a2dp_prepare_buffer(u);
+
+    a2dp = &u->a2dp;
+    header = a2dp->buffer;
+    payload = (struct rtp_payload*) ((uint8_t*) a2dp->buffer + sizeof(*header));
+
+    frame_count = 0;
+
+    /* Try to create a packet of the full MTU */
+
+    p = (const uint8_t *) pa_memblock_acquire_chunk(&u->write_memchunk);
+    to_encode = u->write_memchunk.length;
+
+    d = (uint8_t*) a2dp->buffer + sizeof(*header) + sizeof(*payload);
+    to_write = a2dp->buffer_size - sizeof(*header) - sizeof(*payload);
+
+    while (PA_LIKELY(to_encode > 0 && to_write > 0)) {
+        ssize_t written;
+        ssize_t encoded;
+
+        encoded = sbc_encode(&a2dp->sbc,
+                             p, to_encode,
+                             d, to_write,
+                             &written);
+
+        if (PA_UNLIKELY(encoded <= 0)) {
+            pa_log_error("SBC encoding error (%li)", (long) encoded);
+            pa_memblock_release(u->write_memchunk.memblock);
+            return -1;
+        }
+
+/*         pa_log_debug("SBC: encoded: %lu; written: %lu", (unsigned long) encoded, (unsigned long) written); */
+/*         pa_log_debug("SBC: codesize: %lu; frame_length: %lu", (unsigned long) a2dp->codesize, (unsigned long) a2dp->frame_length); */
+
+        pa_assert_fp((size_t) encoded <= to_encode);
+        pa_assert_fp((size_t) encoded == a2dp->codesize);
+
+        pa_assert_fp((size_t) written <= to_write);
+        pa_assert_fp((size_t) written == a2dp->frame_length);
+
+        p = (const uint8_t*) p + encoded;
+        to_encode -= encoded;
+
+        d = (uint8_t*) d + written;
+        to_write -= written;
+
+        frame_count++;
+    }
+
+    pa_memblock_release(u->write_memchunk.memblock);
+
+    pa_assert(to_encode == 0);
+
+    PA_ONCE_BEGIN {
+        pa_log_debug("Using SBC encoder implementation: %s", pa_strnull(sbc_get_implementation_info(&a2dp->sbc)));
+    } PA_ONCE_END;
+
+    /* write it to the fifo */
+    memset(a2dp->buffer, 0, sizeof(*header) + sizeof(*payload));
+    header->v = 2;
+    header->pt = 1;
+    header->sequence_number = htons(a2dp->seq_num++);
+    header->timestamp = htonl(u->write_index / pa_frame_size(&u->sample_spec));
+    header->ssrc = htonl(1);
+    payload->frame_count = frame_count;
+
+    nbytes = (uint8_t*) d - (uint8_t*) a2dp->buffer;
+
+    for (;;) {
+        ssize_t l;
+
+        l = pa_write(u->stream_fd, a2dp->buffer, nbytes, &u->stream_write_type);
+
+        pa_assert(l != 0);
+
+        if (l < 0) {
+
+            if (errno == EINTR)
                 /* Retry right away if we got interrupted */
                 continue;
 
-            else if (l < 0 && errno == EAGAIN)
-                /* Hmm, apparently the socket was not readable, give up for now. */
+            else if (errno == EAGAIN)
+                /* Hmm, apparently the socket was not writable, give up for now */
                 break;
 
-            pa_log_error("Failed to read data from SCO socket: %s", l < 0 ? pa_cstrerror(errno) : "EOF");
+            pa_log_error("Failed to write data to socket: %s", pa_cstrerror(errno));
             ret = -1;
             break;
         }
 
-        pa_assert((size_t) l <= pa_memblock_get_length(memchunk.memblock));
-
-        memchunk.length = (size_t) l;
-        u->read_index += (uint64_t) l;
-
-        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;
-            }
+        pa_assert((size_t) l <= nbytes);
 
-        if (!found_tstamp) {
-            pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() data!");
-            tstamp = pa_rtclock_now();
+        if ((size_t) l != nbytes) {
+            pa_log_warn("Wrote memory block to socket only partially! %llu written, wanted to write %llu.",
+                        (unsigned long long) l,
+                        (unsigned long long) nbytes);
+            ret = -1;
+            break;
         }
 
-        pa_smoother_put(u->read_smoother, tstamp, pa_bytes_to_usec(u->read_index, &u->sample_spec));
-        pa_smoother_resume(u->read_smoother, tstamp, TRUE);
-
-        pa_source_post(u->source, &memchunk);
+        u->write_index += (uint64_t) u->write_memchunk.length;
+        pa_memblock_unref(u->write_memchunk.memblock);
+        pa_memchunk_reset(&u->write_memchunk);
 
         ret = 1;
+
         break;
     }
 
-    pa_memblock_unref(memchunk.memblock);
-
     return ret;
 }
 
+#ifdef BLUETOOTH_APTX_SUPPORT
 /* Run from IO thread */
-static void a2dp_prepare_buffer(struct userdata *u) {
-    pa_assert(u);
-
-    if (u->a2dp.buffer_size >= u->link_mtu)
-        return;
-
-    u->a2dp.buffer_size = 2 * u->link_mtu;
-    pa_xfree(u->a2dp.buffer);
-    u->a2dp.buffer = pa_xmalloc(u->a2dp.buffer_size);
-}
-
-/* Run from IO thread */
-static int a2dp_process_render(struct userdata *u) {
+static int a2dp_aptx_process_render(struct userdata *u) {
     struct a2dp_info *a2dp;
-    struct rtp_header *header;
-    struct rtp_payload *payload;
     size_t nbytes;
     void *d;
     const void *p;
     size_t to_write, to_encode;
-    unsigned frame_count;
     int ret = 0;
 
+    int pcmL[4],pcmR[4];
+    int i=0;
+    const short *mybuffer;
+
     pa_assert(u);
     pa_assert(u->profile == PROFILE_A2DP);
     pa_assert(u->sink);
 
     /* First, render some data */
     if (!u->write_memchunk.memblock)
-        pa_sink_render_full(u->sink, u->block_size, &u->write_memchunk);
+        pa_sink_render_full(u->sink, u->write_block_size, &u->write_memchunk);
 
-    pa_assert(u->write_memchunk.length == u->block_size);
+    pa_assert(u->write_memchunk.length == u->write_block_size);
 
     a2dp_prepare_buffer(u);
 
     a2dp = &u->a2dp;
-    header = a2dp->buffer;
-    payload = (struct rtp_payload*) ((uint8_t*) a2dp->buffer + sizeof(*header));
-
-    frame_count = 0;
 
     /* Try to create a packet of the full MTU */
-
     p = (const uint8_t*) pa_memblock_acquire(u->write_memchunk.memblock) + u->write_memchunk.index;
     to_encode = u->write_memchunk.length;
 
-    d = (uint8_t*) a2dp->buffer + sizeof(*header) + sizeof(*payload);
-    to_write = a2dp->buffer_size - sizeof(*header) - sizeof(*payload);
+    d = (uint8_t*) a2dp->buffer ;
+    to_write = a2dp->buffer_size;
 
     while (PA_LIKELY(to_encode > 0 && to_write > 0)) {
-        ssize_t written;
+        size_t written;
         ssize_t encoded;
 
-        encoded = sbc_encode(&a2dp->sbc,
-                             p, to_encode,
-                             d, to_write,
-                             &written);
+        mybuffer=(uint8_t *)p;
 
-        if (PA_UNLIKELY(encoded <= 0)) {
-            pa_log_error("SBC encoding error (%li)", (long) encoded);
-            pa_memblock_release(u->write_memchunk.memblock);
-            return -1;
+        for (i = 0; i < 4; i += 1) {
+           pcmL[i] = mybuffer[2*i];
+           pcmR[i] = mybuffer[2*i+1];
         }
+       /*(8 audio samples)16 bytes of audo data encoded to 4 bytes*/
+       aptx_encode(a2dp->aptx, pcmL, pcmR, (short*)d);
 
-/*         pa_log_debug("SBC: encoded: %lu; written: %lu", (unsigned long) encoded, (unsigned long) written); */
-/*         pa_log_debug("SBC: codesize: %lu; frame_length: %lu", (unsigned long) a2dp->codesize, (unsigned long) a2dp->frame_length); */
+        encoded=16;
+        written=4;
 
         pa_assert_fp((size_t) encoded <= to_encode);
-        pa_assert_fp((size_t) encoded == a2dp->codesize);
-
         pa_assert_fp((size_t) written <= to_write);
-        pa_assert_fp((size_t) written == a2dp->frame_length);
 
         p = (const uint8_t*) p + encoded;
         to_encode -= encoded;
@@ -1384,7 +962,6 @@ static int a2dp_process_render(struct userdata *u) {
         d = (uint8_t*) d + written;
         to_write -= written;
 
-        frame_count++;
     }
 
     pa_memblock_release(u->write_memchunk.memblock);
@@ -1392,18 +969,9 @@ static int a2dp_process_render(struct userdata *u) {
     pa_assert(to_encode == 0);
 
     PA_ONCE_BEGIN {
-        pa_log_debug("Using SBC encoder implementation: %s", pa_strnull(sbc_get_implementation_info(&a2dp->sbc)));
+        pa_log_debug("Using APTX encoder implementation");
     } PA_ONCE_END;
 
-    /* write it to the fifo */
-    memset(a2dp->buffer, 0, sizeof(*header) + sizeof(*payload));
-    header->v = 2;
-    header->pt = 1;
-    header->sequence_number = htons(a2dp->seq_num++);
-    header->timestamp = htonl(u->write_index / pa_frame_size(&u->sample_spec));
-    header->ssrc = htonl(1);
-    payload->frame_count = frame_count;
-
     nbytes = (uint8_t*) d - (uint8_t*) a2dp->buffer;
 
     for (;;) {
@@ -1424,7 +992,7 @@ static int a2dp_process_render(struct userdata *u) {
                 break;
 
             pa_log_error("Failed to write data to socket: %s", pa_cstrerror(errno));
-            ret = -1;
+            ret  = -1;
             break;
         }
 
@@ -1449,21 +1017,22 @@ static int a2dp_process_render(struct userdata *u) {
 
     return ret;
 }
+#endif
 
 static int a2dp_process_push(struct userdata *u) {
     int ret = 0;
     pa_memchunk memchunk;
 
     pa_assert(u);
-    pa_assert(u->profile == PROFILE_A2DP_SOURCE);
+    pa_assert(u->profile == PA_BLUEZ4_PROFILE_A2DP_SOURCE);
     pa_assert(u->source);
     pa_assert(u->read_smoother);
 
-    memchunk.memblock = pa_memblock_new(u->core->mempool, u->block_size);
+    memchunk.memblock = pa_memblock_new(u->core->mempool, u->read_block_size);
     memchunk.index = memchunk.length = 0;
 
     for (;;) {
-        pa_bool_t found_tstamp = FALSE;
+        bool found_tstamp = false;
         pa_usec_t tstamp;
         struct a2dp_info *a2dp;
         struct rtp_header *header;
@@ -1507,7 +1076,7 @@ static int a2dp_process_push(struct userdata *u) {
         }
 
         pa_smoother_put(u->read_smoother, tstamp, pa_bytes_to_usec(u->read_index, &u->sample_spec));
-        pa_smoother_resume(u->read_smoother, tstamp, TRUE);
+        pa_smoother_resume(u->read_smoother, tstamp, true);
 
         p = (uint8_t*) a2dp->buffer + sizeof(*header) + sizeof(*payload);
         to_decode = l - sizeof(*header) - sizeof(*payload);
@@ -1555,7 +1124,7 @@ static int a2dp_process_push(struct userdata *u) {
 
         pa_source_post(u->source, &memchunk);
 
-        ret = 1;
+        ret = l;
         break;
     }
 
@@ -1564,8 +1133,7 @@ static int a2dp_process_push(struct userdata *u) {
     return ret;
 }
 
-static void a2dp_reduce_bitpool(struct userdata *u)
-{
+static void a2dp_reduce_bitpool(struct userdata *u) {
     struct a2dp_info *a2dp;
     uint8_t bitpool;
 
@@ -1588,9 +1156,11 @@ static void a2dp_reduce_bitpool(struct userdata *u)
 static void thread_func(void *userdata) {
     struct userdata *u = userdata;
     unsigned do_write = 0;
-    pa_bool_t writable = FALSE;
+    unsigned pending_read_bytes = 0;
+    bool writable = false;
 
     pa_assert(u);
+    pa_assert(u->transport);
 
     pa_log_debug("IO Thread starting up");
 
@@ -1599,16 +1169,14 @@ static void thread_func(void *userdata) {
 
     pa_thread_mq_install(&u->thread_mq);
 
-    if (u->transport) {
-        if (bt_transport_acquire(u, TRUE) < 0)
-            goto fail;
-    } else if (start_stream_fd(u) < 0)
-        goto fail;
+    /* Setup the stream only if the transport was already acquired */
+    if (u->transport_acquired)
+        setup_stream(u);
 
     for (;;) {
         struct pollfd *pollfd;
         int ret;
-        pa_bool_t disable_timer = TRUE;
+        bool disable_timer = true;
 
         pollfd = u->rtpoll_item ? pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL) : NULL;
 
@@ -1623,27 +1191,29 @@ static void thread_func(void *userdata) {
             if (pollfd && (pollfd->revents & POLLIN)) {
                 int n_read;
 
-                if (u->profile == PROFILE_HSP || u->profile == PROFILE_HFGW)
+                if (u->profile == PA_BLUEZ4_PROFILE_HSP || u->profile == PA_BLUEZ4_PROFILE_HFGW)
                     n_read = hsp_process_push(u);
                 else
                     n_read = a2dp_process_push(u);
 
                 if (n_read < 0)
-                    goto fail;
+                    goto io_fail;
 
                 /* We just read something, so we are supposed to write something, too */
-                do_write += n_read;
+                pending_read_bytes += n_read;
+                do_write += pending_read_bytes / u->write_block_size;
+                pending_read_bytes = pending_read_bytes % u->write_block_size;
             }
         }
 
         if (u->sink && PA_SINK_IS_LINKED(u->sink->thread_info.state)) {
 
-            if (u->sink->thread_info.rewind_requested)
+            if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
                 pa_sink_process_rewind(u->sink, 0);
 
             if (pollfd) {
                 if (pollfd->revents & POLLOUT)
-                    writable = TRUE;
+                    writable = true;
 
                 if ((!u->source || !PA_SOURCE_IS_LINKED(u->source->thread_info.state)) && do_write <= 0 && writable) {
                     pa_usec_t time_passed;
@@ -1677,12 +1247,13 @@ static void thread_func(void *userdata) {
                                 pa_memblock_unref(tmp.memblock);
                                 u->write_index += skip_bytes;
 
-                                if (u->profile == PROFILE_A2DP)
+                                if (u->profile == PA_BLUEZ4_PROFILE_A2DP)
                                     a2dp_reduce_bitpool(u);
                             }
                         }
 
                         do_write = 1;
+                        pending_read_bytes = 0;
                     }
                 }
 
@@ -1692,19 +1263,24 @@ static void thread_func(void *userdata) {
                     if (u->write_index <= 0)
                         u->started_at = pa_rtclock_now();
 
-                    if (u->profile == PROFILE_A2DP) {
+                    if (u->profile == PA_BLUEZ4_PROFILE_A2DP) {
+#ifdef BLUETOOTH_APTX_SUPPORT
+                        if ((n_written = a2dp_aptx_process_render(u)) < 0)
+                                goto io_fail;
+#else
                         if ((n_written = a2dp_process_render(u)) < 0)
-                            goto fail;
+                            goto io_fail;
+#endif
                     } else {
                         if ((n_written = hsp_process_render(u)) < 0)
-                            goto fail;
+                            goto io_fail;
                     }
 
                     if (n_written == 0)
                         pa_log("Broken kernel: we got EAGAIN on write() after POLLOUT!");
 
                     do_write -= n_written;
-                    writable = FALSE;
+                    writable = false;
                 }
 
                 if ((!u->source || !PA_SOURCE_IS_LINKED(u->source->thread_info.state)) && do_write <= 0) {
@@ -1723,7 +1299,7 @@ static void thread_func(void *userdata) {
                         sleep_for = PA_USEC_PER_MSEC * 500;
 
                     pa_rtpoll_set_timer_relative(u->rtpoll, sleep_for);
-                    disable_timer = FALSE;
+                    disable_timer = false;
                 }
             }
         }
@@ -1736,11 +1312,15 @@ static void thread_func(void *userdata) {
             pollfd->events = (short) (((u->sink && PA_SINK_IS_LINKED(u->sink->thread_info.state) && !writable) ? POLLOUT : 0) |
                                       (u->source && PA_SOURCE_IS_LINKED(u->source->thread_info.state) ? POLLIN : 0));
 
-        if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
+        if ((ret = pa_rtpoll_run(u->rtpoll, true)) < 0) {
+            pa_log_debug("pa_rtpoll_run failed with: %d", ret);
             goto fail;
-
-        if (ret == 0)
+        }
+        if (ret == 0) {
+            pa_log_debug("IO thread shutdown requested, stopping cleanly");
+            bt_transport_release(u);
             goto finish;
+        }
 
         pollfd = u->rtpoll_item ? pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL) : NULL;
 
@@ -1750,8 +1330,21 @@ static void thread_func(void *userdata) {
                         pollfd->revents & POLLHUP ? "POLLHUP " :"",
                         pollfd->revents & POLLPRI ? "POLLPRI " :"",
                         pollfd->revents & POLLNVAL ? "POLLNVAL " :"");
-            goto fail;
+            goto io_fail;
         }
+
+        continue;
+
+io_fail:
+        /* In case of HUP, just tear down the streams */
+        if (!pollfd || (pollfd->revents & POLLHUP) == 0)
+            goto fail;
+
+        do_write = 0;
+        pending_read_bytes = 0;
+        writable = false;
+
+        teardown_stream(u);
     }
 
 fail:
@@ -1764,142 +1357,129 @@ finish:
     pa_log_debug("IO thread shutting down");
 }
 
-/* Run from main thread */
-static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *userdata) {
-    DBusError err;
-    struct userdata *u;
-
-    pa_assert(bus);
-    pa_assert(m);
-    pa_assert_se(u = userdata);
-
-    dbus_error_init(&err);
+static pa_available_t transport_state_to_availability(pa_bluez4_transport_state_t state) {
+    if (state == PA_BLUEZ4_TRANSPORT_STATE_DISCONNECTED)
+        return PA_AVAILABLE_NO;
+    else if (state >= PA_BLUEZ4_TRANSPORT_STATE_PLAYING)
+        return PA_AVAILABLE_YES;
+    else
+        return PA_AVAILABLE_UNKNOWN;
+}
 
-    pa_log_debug("dbus: interface=%s, path=%s, member=%s\n",
-                 dbus_message_get_interface(m),
-                 dbus_message_get_path(m),
-                 dbus_message_get_member(m));
+static pa_direction_t get_profile_direction(pa_bluez4_profile_t p) {
+    static const pa_direction_t profile_direction[] = {
+        [PA_BLUEZ4_PROFILE_A2DP] = PA_DIRECTION_OUTPUT,
+        [PA_BLUEZ4_PROFILE_A2DP_SOURCE] = PA_DIRECTION_INPUT,
+        [PA_BLUEZ4_PROFILE_HSP] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
+        [PA_BLUEZ4_PROFILE_HFGW] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
+        [PA_BLUEZ4_PROFILE_OFF] = 0
+    };
 
-    if (!dbus_message_has_path(m, u->path) && !dbus_message_has_path(m, u->transport))
-        goto fail;
+    return profile_direction[p];
+}
 
-    if (dbus_message_is_signal(m, "org.bluez.Headset", "SpeakerGainChanged") ||
-        dbus_message_is_signal(m, "org.bluez.Headset", "MicrophoneGainChanged")) {
+/* Run from main thread */
+static pa_available_t get_port_availability(struct userdata *u, pa_direction_t direction) {
+    pa_available_t result = PA_AVAILABLE_NO;
+    unsigned i;
 
-        dbus_uint16_t gain;
-        pa_cvolume v;
+    pa_assert(u);
+    pa_assert(u->device);
 
-        if (!dbus_message_get_args(m, &err, DBUS_TYPE_UINT16, &gain, DBUS_TYPE_INVALID) || gain > HSP_MAX_GAIN) {
-            pa_log("Failed to parse org.bluez.Headset.{Speaker|Microphone}GainChanged: %s", err.message);
-            goto fail;
-        }
+    for (i = 0; i < PA_BLUEZ4_PROFILE_COUNT; i++) {
+        pa_bluez4_transport *transport;
 
-        if (u->profile == PROFILE_HSP) {
-            if (u->sink && dbus_message_is_signal(m, "org.bluez.Headset", "SpeakerGainChanged")) {
-                pa_volume_t volume = (pa_volume_t) (gain * PA_VOLUME_NORM / HSP_MAX_GAIN);
+        if (!(get_profile_direction(i) & direction))
+            continue;
 
-                /* increment volume by one to correct rounding errors */
-                if (volume < PA_VOLUME_NORM)
-                    volume++;
+        if (!(transport = u->device->transports[i]))
+            continue;
 
-                pa_cvolume_set(&v, u->sample_spec.channels, volume);
-                pa_sink_volume_changed(u->sink, &v);
+        switch(transport->state) {
+            case PA_BLUEZ4_TRANSPORT_STATE_DISCONNECTED:
+                continue;
 
-            } else if (u->source && dbus_message_is_signal(m, "org.bluez.Headset", "MicrophoneGainChanged")) {
-                pa_volume_t volume = (pa_volume_t) (gain * PA_VOLUME_NORM / HSP_MAX_GAIN);
+            case PA_BLUEZ4_TRANSPORT_STATE_IDLE:
+                if (result == PA_AVAILABLE_NO)
+                    result = PA_AVAILABLE_UNKNOWN;
 
-                /* increment volume by one to correct rounding errors */
-                if (volume < PA_VOLUME_NORM)
-                    volume++;
+                break;
 
-                pa_cvolume_set(&v, u->sample_spec.channels, volume);
-                pa_source_volume_changed(u->source, &v);
-            }
+            case PA_BLUEZ4_TRANSPORT_STATE_PLAYING:
+                return PA_AVAILABLE_YES;
         }
-    } else if (dbus_message_is_signal(m, "org.bluez.MediaTransport", "PropertyChanged")) {
-        DBusMessageIter arg_i;
-        pa_bluetooth_transport *t;
-        pa_bool_t nrec;
+    }
 
-        t = (pa_bluetooth_transport *) pa_bluetooth_discovery_get_transport(u->discovery, u->transport);
-        pa_assert(t);
+    return result;
+}
 
-        if (!dbus_message_iter_init(m, &arg_i)) {
-            pa_log("Failed to parse PropertyChanged: %s", err.message);
-            goto fail;
-        }
+/* Run from main thread */
+static void handle_transport_state_change(struct userdata *u, struct pa_bluez4_transport *transport) {
+    bool acquire = false;
+    bool release = false;
+    pa_bluez4_profile_t profile;
+    pa_card_profile *cp;
+    pa_bluez4_transport_state_t state;
+    pa_device_port *port;
 
-        nrec = t->nrec;
+    pa_assert(u);
+    pa_assert(transport);
 
-        if (pa_bluetooth_transport_parse_property(t, &arg_i) < 0)
-            goto fail;
+    profile = transport->profile;
+    state = transport->state;
 
-        if (nrec != t->nrec) {
-            pa_log_debug("dbus: property 'NREC' changed to value '%s'", t->nrec ? "True" : "False");
-            pa_proplist_sets(u->source->proplist, "bluetooth.nrec", t->nrec ? "1" : "0");
-        }
-    } else if (dbus_message_is_signal(m, "org.bluez.HandsfreeGateway", "PropertyChanged")) {
-        const char *key;
-        DBusMessageIter iter;
-        DBusMessageIter variant;
-        pa_bt_audio_state_t state = PA_BT_AUDIO_STATE_INVALID;
-
-        if (!dbus_message_iter_init(m, &iter)) {
-            pa_log("Failed to parse PropertyChanged: %s", err.message);
-            goto fail;
-        }
+    /* Update profile availability */
+    if (!(cp = pa_hashmap_get(u->card->profiles, pa_bluez4_profile_to_string(profile))))
+        return;
 
-        if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
-            pa_log("Property name not a string.");
-            goto fail;
-        }
+    pa_card_profile_set_available(cp, transport_state_to_availability(state));
 
-        dbus_message_iter_get_basic(&iter, &key);
+    /* Update port availability */
+    pa_assert_se(port = pa_hashmap_get(u->card->ports, u->output_port_name));
+    pa_device_port_set_available(port, get_port_availability(u, PA_DIRECTION_OUTPUT));
 
-        if (!dbus_message_iter_next(&iter)) {
-            pa_log("Property value missing");
-            goto fail;
-        }
+    pa_assert_se(port = pa_hashmap_get(u->card->ports, u->input_port_name));
+    pa_device_port_set_available(port, get_port_availability(u, PA_DIRECTION_INPUT));
 
-        dbus_message_iter_recurse(&iter, &variant);
+    /* Acquire or release transport as needed */
+    acquire = (state == PA_BLUEZ4_TRANSPORT_STATE_PLAYING && u->profile == profile);
+    release = (state != PA_BLUEZ4_TRANSPORT_STATE_PLAYING && u->profile == profile);
 
-        if (dbus_message_iter_get_arg_type(&variant) == DBUS_TYPE_STRING) {
-            const char *value;
-            dbus_message_iter_get_basic(&variant, &value);
+    if (acquire)
+        if (bt_transport_acquire(u, true) >= 0) {
+            if (u->source) {
+                pa_log_debug("Resuming source %s, because the bluetooth audio state changed to 'playing'.", u->source->name);
+                pa_source_suspend(u->source, false, PA_SUSPEND_IDLE|PA_SUSPEND_USER);
+            }
 
-            if (pa_streq(key, "State")) {
-                pa_log_debug("dbus: HSHFAG property 'State' changed to value '%s'", value);
-                state = pa_bt_audio_state_from_string(value);
+            if (u->sink) {
+                pa_log_debug("Resuming sink %s, because the bluetooth audio state changed to 'playing'.", u->sink->name);
+                pa_sink_suspend(u->sink, false, PA_SUSPEND_IDLE|PA_SUSPEND_USER);
             }
         }
 
-        switch(state) {
-            case PA_BT_AUDIO_STATE_INVALID:
-            case PA_BT_AUDIO_STATE_DISCONNECTED:
-            case PA_BT_AUDIO_STATE_CONNECTED:
-            case PA_BT_AUDIO_STATE_CONNECTING:
-                goto fail;
-
-            case PA_BT_AUDIO_STATE_PLAYING:
-                if (u->card) {
-                    pa_log_debug("Changing profile to hfgw");
-                    if (pa_card_set_profile(u->card, "hfgw", FALSE) < 0)
-                        pa_log("Failed to change profile to hfgw");
-                }
-                break;
-        }
-    }
+    if (release && u->transport_acquired) {
+        /* FIXME: this release is racy, since the audio stream might have
+           been set up again in the meantime (but not processed yet by PA).
+           BlueZ should probably release the transport automatically, and
+           in that case we would just mark the transport as released */
 
-fail:
-    dbus_error_free(&err);
+        /* Remote side closed the stream so we consider it PA_SUSPEND_USER */
+        if (u->source) {
+            pa_log_debug("Suspending source %s, because the remote end closed the stream.", u->source->name);
+            pa_source_suspend(u->source, true, PA_SUSPEND_USER);
+        }
 
-    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+        if (u->sink) {
+            pa_log_debug("Suspending sink %s, because the remote end closed the stream.", u->sink->name);
+            pa_sink_suspend(u->sink, true, PA_SUSPEND_USER);
+        }
+    }
 }
 
 /* Run from main thread */
 static void sink_set_volume_cb(pa_sink *s) {
-    DBusMessage *m;
-    dbus_uint16_t gain;
+    uint16_t gain;
     pa_volume_t volume;
     struct userdata *u;
     char *k;
@@ -1913,31 +1493,20 @@ static void sink_set_volume_cb(pa_sink *s) {
 
     pa_assert(u);
     pa_assert(u->sink == s);
-    pa_assert(u->profile == PROFILE_HSP);
+    pa_assert(u->profile == PA_BLUEZ4_PROFILE_HSP);
+    pa_assert(u->transport);
 
-    gain = (pa_cvolume_max(&s->real_volume) * HSP_MAX_GAIN) / PA_VOLUME_NORM;
-
-    if (gain > HSP_MAX_GAIN)
-        gain = HSP_MAX_GAIN;
-
-    volume = (pa_volume_t) (gain * PA_VOLUME_NORM / HSP_MAX_GAIN);
-
-    /* increment volume by one to correct rounding errors */
-    if (volume < PA_VOLUME_NORM)
-        volume++;
+    gain = (dbus_uint16_t) round((double) pa_cvolume_max(&s->real_volume) * HSP_MAX_GAIN / PA_VOLUME_NORM);
+    volume = (pa_volume_t) round((double) gain * PA_VOLUME_NORM / HSP_MAX_GAIN);
 
     pa_cvolume_set(&s->real_volume, u->sample_spec.channels, volume);
 
-    pa_assert_se(m = dbus_message_new_method_call("org.bluez", u->path, "org.bluez.Headset", "SetSpeakerGain"));
-    pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_UINT16, &gain, DBUS_TYPE_INVALID));
-    pa_assert_se(dbus_connection_send(pa_dbus_connection_get(u->connection), m, NULL));
-    dbus_message_unref(m);
+    pa_bluez4_transport_set_speaker_gain(u->transport, gain);
 }
 
 /* Run from main thread */
 static void source_set_volume_cb(pa_source *s) {
-    DBusMessage *m;
-    dbus_uint16_t gain;
+    uint16_t gain;
     pa_volume_t volume;
     struct userdata *u;
     char *k;
@@ -1951,31 +1520,19 @@ static void source_set_volume_cb(pa_source *s) {
 
     pa_assert(u);
     pa_assert(u->source == s);
-    pa_assert(u->profile == PROFILE_HSP);
-
-    /* gain = (pa_cvolume_max(&s->real_volume) * HSP_MAX_GAIN) / PA_VOLUME_NORM; */
-    gain = (pa_cvolume_max(&s->volume) * HSP_MAX_GAIN) / PA_VOLUME_NORM;
+    pa_assert(u->profile == PA_BLUEZ4_PROFILE_HSP);
+    pa_assert(u->transport);
 
-    if (gain > HSP_MAX_GAIN)
-        gain = HSP_MAX_GAIN;
+    gain = (dbus_uint16_t) round((double) pa_cvolume_max(&s->real_volume) * HSP_MAX_GAIN / PA_VOLUME_NORM);
+    volume = (pa_volume_t) round((double) gain * PA_VOLUME_NORM / HSP_MAX_GAIN);
 
-    volume = (pa_volume_t) (gain * PA_VOLUME_NORM / HSP_MAX_GAIN);
-
-    /* increment volume by one to correct rounding errors */
-    if (volume < PA_VOLUME_NORM)
-        volume++;
-
-    /* pa_cvolume_set(&s->real_volume, u->sample_spec.channels, volume); */
-    pa_cvolume_set(&s->volume, u->sample_spec.channels, volume);
+    pa_cvolume_set(&s->real_volume, u->sample_spec.channels, volume);
 
-    pa_assert_se(m = dbus_message_new_method_call("org.bluez", u->path, "org.bluez.Headset", "SetMicrophoneGain"));
-    pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_UINT16, &gain, DBUS_TYPE_INVALID));
-    pa_assert_se(dbus_connection_send(pa_dbus_connection_get(u->connection), m, NULL));
-    dbus_message_unref(m);
+    pa_bluez4_transport_set_microphone_gain(u->transport, gain);
 }
 
 /* Run from main thread */
-static char *get_name(const char *type, pa_modargs *ma, const char *device_id, pa_bool_t *namereg_fail) {
+static char *get_name(const char *type, pa_modargs *ma, const char *device_id, bool *namereg_fail) {
     char *t;
     const char *n;
 
@@ -1989,59 +1546,51 @@ static char *get_name(const char *type, pa_modargs *ma, const char *device_id, p
     pa_xfree(t);
 
     if (n) {
-        *namereg_fail = TRUE;
+        *namereg_fail = true;
         return pa_xstrdup(n);
     }
 
     if ((n = pa_modargs_get_value(ma, "name", NULL)))
-        *namereg_fail = TRUE;
+        *namereg_fail = true;
     else {
         n = device_id;
-        *namereg_fail = FALSE;
+        *namereg_fail = false;
     }
 
     return pa_sprintf_malloc("bluez_%s.%s", type, n);
 }
 
-static int sco_over_pcm_state_update(struct userdata *u, pa_bool_t changed) {
+static int sco_over_pcm_state_update(struct userdata *u, bool changed) {
     pa_assert(u);
     pa_assert(USE_SCO_OVER_PCM(u));
 
     if (PA_SINK_IS_OPENED(pa_sink_get_state(u->hsp.sco_sink)) ||
         PA_SOURCE_IS_OPENED(pa_source_get_state(u->hsp.sco_source))) {
 
-        if (u->service_fd >= 0 && u->stream_fd >= 0)
+        if (u->stream_fd >= 0)
             return 0;
 
-        init_bt(u);
-
         pa_log_debug("Resuming SCO over PCM");
         if (init_profile(u) < 0) {
             pa_log("Can't resume SCO over PCM");
             return -1;
         }
 
-        if (u->transport)
-            return bt_transport_acquire(u, TRUE);
+        if (bt_transport_acquire(u, false) < 0)
+            return -1;
+
+        setup_stream(u);
 
-        return start_stream_fd(u);
+        return 0;
     }
 
     if (changed) {
-        if (u->service_fd < 0 && u->stream_fd < 0)
+        if (u->stream_fd < 0)
             return 0;
 
         pa_log_debug("Closing SCO over PCM");
 
-        if (u->transport)
-            bt_transport_release(u);
-        else if (u->stream_fd >= 0)
-            stop_stream_fd(u);
-
-        if (u->service_fd >= 0) {
-            pa_close(u->service_fd);
-            u->service_fd = -1;
-        }
+        bt_transport_release(u);
     }
 
     return 0;
@@ -2052,10 +1601,10 @@ static pa_hook_result_t sink_state_changed_cb(pa_core *c, pa_sink *s, struct use
     pa_sink_assert_ref(s);
     pa_assert(u);
 
-    if (s != u->hsp.sco_sink)
+    if (!USE_SCO_OVER_PCM(u) || s != u->hsp.sco_sink)
         return PA_HOOK_OK;
 
-    sco_over_pcm_state_update(u, TRUE);
+    sco_over_pcm_state_update(u, true);
 
     return PA_HOOK_OK;
 }
@@ -2065,40 +1614,118 @@ static pa_hook_result_t source_state_changed_cb(pa_core *c, pa_source *s, struct
     pa_source_assert_ref(s);
     pa_assert(u);
 
-    if (s != u->hsp.sco_source)
+    if (!USE_SCO_OVER_PCM(u) || s != u->hsp.sco_source)
+        return PA_HOOK_OK;
+
+    sco_over_pcm_state_update(u, true);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t transport_nrec_changed_cb(pa_bluez4_discovery *y, pa_bluez4_transport *t, struct userdata *u) {
+    pa_proplist *p;
+
+    pa_assert(t);
+    pa_assert(u);
+
+    if (t != u->transport)
+        return PA_HOOK_OK;
+
+    p = pa_proplist_new();
+    pa_proplist_sets(p, "bluetooth.nrec", t->nrec ? "1" : "0");
+    pa_source_update_proplist(u->source, PA_UPDATE_REPLACE, p);
+    pa_proplist_free(p);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t transport_microphone_gain_changed_cb(pa_bluez4_discovery *y, pa_bluez4_transport *t,
+                                                             struct userdata *u) {
+    pa_cvolume v;
+
+    pa_assert(t);
+    pa_assert(u);
+
+    if (t != u->transport)
+        return PA_HOOK_OK;
+
+    pa_assert(u->source);
+
+    pa_cvolume_set(&v, u->sample_spec.channels,
+                   (pa_volume_t) round((double) t->microphone_gain * PA_VOLUME_NORM / HSP_MAX_GAIN));
+    pa_source_volume_changed(u->source, &v);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t transport_speaker_gain_changed_cb(pa_bluez4_discovery *y, pa_bluez4_transport *t,
+                                                          struct userdata *u) {
+    pa_cvolume v;
+
+    pa_assert(t);
+    pa_assert(u);
+
+    if (t != u->transport)
         return PA_HOOK_OK;
 
-    sco_over_pcm_state_update(u, TRUE);
+    pa_assert(u->sink);
+
+    pa_cvolume_set(&v, u->sample_spec.channels, (pa_volume_t) round((double) t->speaker_gain * PA_VOLUME_NORM / HSP_MAX_GAIN));
+    pa_sink_volume_changed(u->sink, &v);
 
     return PA_HOOK_OK;
 }
 
+static void connect_ports(struct userdata *u, void *sink_or_source_new_data, pa_direction_t direction) {
+    pa_device_port *port;
+
+    if (direction == PA_DIRECTION_OUTPUT) {
+        pa_sink_new_data *sink_new_data = sink_or_source_new_data;
+
+        pa_assert_se(port = pa_hashmap_get(u->card->ports, u->output_port_name));
+        pa_assert_se(pa_hashmap_put(sink_new_data->ports, port->name, port) >= 0);
+        pa_device_port_ref(port);
+    } else {
+        pa_source_new_data *source_new_data = sink_or_source_new_data;
+
+        pa_assert_se(port = pa_hashmap_get(u->card->ports, u->input_port_name));
+        pa_assert_se(pa_hashmap_put(source_new_data->ports, port->name, port) >= 0);
+        pa_device_port_ref(port);
+    }
+}
+
+static int sink_set_port_cb(pa_sink *s, pa_device_port *p) {
+    return 0;
+}
+
+static int source_set_port_cb(pa_source *s, pa_device_port *p) {
+    return 0;
+}
+
 /* Run from main thread */
 static int add_sink(struct userdata *u) {
     char *k;
 
+    pa_assert(u->transport);
+
     if (USE_SCO_OVER_PCM(u)) {
         pa_proplist *p;
 
         u->sink = u->hsp.sco_sink;
         p = pa_proplist_new();
-        pa_proplist_sets(p, "bluetooth.protocol", "sco");
+        pa_proplist_sets(p, "bluetooth.protocol", pa_bluez4_profile_to_string(u->profile));
         pa_proplist_update(u->sink->proplist, PA_UPDATE_MERGE, p);
         pa_proplist_free(p);
-
-        if (!u->hsp.sink_state_changed_slot)
-            u->hsp.sink_state_changed_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) sink_state_changed_cb, u);
-
     } else {
         pa_sink_new_data data;
-        pa_bool_t b;
+        bool b;
 
         pa_sink_new_data_init(&data);
         data.driver = __FILE__;
         data.module = u->module;
         pa_sink_new_data_set_sample_spec(&data, &u->sample_spec);
-        pa_proplist_sets(data.proplist, "bluetooth.protocol", u->profile == PROFILE_A2DP ? "a2dp" : "sco");
-        if (u->profile == PROFILE_HSP)
+        pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluez4_profile_to_string(u->profile));
+        if (u->profile == PA_BLUEZ4_PROFILE_HSP)
             pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
         data.card = u->card;
         data.name = get_name("sink", u->modargs, u->address, &b);
@@ -2109,6 +1736,21 @@ static int add_sink(struct userdata *u) {
             pa_sink_new_data_done(&data);
             return -1;
         }
+        connect_ports(u, &data, PA_DIRECTION_OUTPUT);
+
+        if (!u->transport_acquired)
+            switch (u->profile) {
+                case PA_BLUEZ4_PROFILE_A2DP:
+                case PA_BLUEZ4_PROFILE_HSP:
+                    pa_assert_not_reached(); /* Profile switch should have failed */
+                    break;
+                case PA_BLUEZ4_PROFILE_HFGW:
+                    data.suspend_cause = PA_SUSPEND_USER;
+                    break;
+                case PA_BLUEZ4_PROFILE_A2DP_SOURCE:
+                case PA_BLUEZ4_PROFILE_OFF:
+                    pa_assert_not_reached();
+            }
 
         u->sink = pa_sink_new(u->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
         pa_sink_new_data_done(&data);
@@ -2120,17 +1762,11 @@ static int add_sink(struct userdata *u) {
 
         u->sink->userdata = u;
         u->sink->parent.process_msg = sink_process_msg;
-
-        pa_sink_set_max_request(u->sink, u->block_size);
-        pa_sink_set_fixed_latency(u->sink,
-                                  (u->profile == PROFILE_A2DP ? FIXED_LATENCY_PLAYBACK_A2DP : FIXED_LATENCY_PLAYBACK_HSP) +
-                                  pa_bytes_to_usec(u->block_size, &u->sample_spec));
+        u->sink->set_port = sink_set_port_cb;
     }
 
-    if (u->profile == PROFILE_HSP) {
-        /* pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb); */
-        u->sink->set_volume = sink_set_volume_cb;
-
+    if (u->profile == PA_BLUEZ4_PROFILE_HSP) {
+        pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
         u->sink->n_volume_steps = 16;
 
         k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->sink);
@@ -2145,23 +1781,21 @@ static int add_sink(struct userdata *u) {
 static int add_source(struct userdata *u) {
     char *k;
 
+    pa_assert(u->transport);
+
     if (USE_SCO_OVER_PCM(u)) {
         u->source = u->hsp.sco_source;
-        pa_proplist_sets(u->source->proplist, "bluetooth.protocol", "hsp");
-
-        if (!u->hsp.source_state_changed_slot)
-            u->hsp.source_state_changed_slot = pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) source_state_changed_cb, u);
-
+        pa_proplist_sets(u->source->proplist, "bluetooth.protocol", pa_bluez4_profile_to_string(u->profile));
     } else {
         pa_source_new_data data;
-        pa_bool_t b;
+        bool b;
 
         pa_source_new_data_init(&data);
         data.driver = __FILE__;
         data.module = u->module;
         pa_source_new_data_set_sample_spec(&data, &u->sample_spec);
-        pa_proplist_sets(data.proplist, "bluetooth.protocol", u->profile == PROFILE_A2DP_SOURCE ? "a2dp_source" : "hsp");
-        if ((u->profile == PROFILE_HSP) || (u->profile == PROFILE_HFGW))
+        pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluez4_profile_to_string(u->profile));
+        if (u->profile == PA_BLUEZ4_PROFILE_HSP)
             pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
 
         data.card = u->card;
@@ -2174,6 +1808,22 @@ static int add_source(struct userdata *u) {
             return -1;
         }
 
+        connect_ports(u, &data, PA_DIRECTION_INPUT);
+
+        if (!u->transport_acquired)
+            switch (u->profile) {
+                case PA_BLUEZ4_PROFILE_HSP:
+                    pa_assert_not_reached(); /* Profile switch should have failed */
+                    break;
+                case PA_BLUEZ4_PROFILE_A2DP_SOURCE:
+                case PA_BLUEZ4_PROFILE_HFGW:
+                    data.suspend_cause = PA_SUSPEND_USER;
+                    break;
+                case PA_BLUEZ4_PROFILE_A2DP:
+                case PA_BLUEZ4_PROFILE_OFF:
+                    pa_assert_not_reached();
+            }
+
         u->source = pa_source_new(u->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
         pa_source_new_data_done(&data);
 
@@ -2184,25 +1834,16 @@ static int add_source(struct userdata *u) {
 
         u->source->userdata = u;
         u->source->parent.process_msg = source_process_msg;
-
-        pa_source_set_fixed_latency(u->source,
-                                    (u->profile == PROFILE_A2DP_SOURCE ? FIXED_LATENCY_RECORD_A2DP : FIXED_LATENCY_RECORD_HSP) +
-                                    pa_bytes_to_usec(u->block_size, &u->sample_spec));
+        u->source->set_port = source_set_port_cb;
     }
 
-    if ((u->profile == PROFILE_HSP) || (u->profile == PROFILE_HFGW)) {
-        if (u->transport) {
-            const pa_bluetooth_transport *t;
-            t = pa_bluetooth_discovery_get_transport(u->discovery, u->transport);
-            pa_assert(t);
-            pa_proplist_sets(u->source->proplist, "bluetooth.nrec", t->nrec ? "1" : "0");
-        } else
-            pa_proplist_sets(u->source->proplist, "bluetooth.nrec", (u->hsp.pcm_capabilities.flags & BT_PCM_FLAG_NREC) ? "1" : "0");
+    if ((u->profile == PA_BLUEZ4_PROFILE_HSP) || (u->profile == PA_BLUEZ4_PROFILE_HFGW)) {
+        pa_bluez4_transport *t = u->transport;
+        pa_proplist_sets(u->source->proplist, "bluetooth.nrec", t->nrec ? "1" : "0");
     }
 
-    if (u->profile == PROFILE_HSP) {
-        /* pa_source_set_set_volume_callback(u->source, source_set_volume_cb); */
-        u->source->set_volume = source_set_volume_cb;
+    if (u->profile == PA_BLUEZ4_PROFILE_HSP) {
+        pa_source_set_set_volume_callback(u->source, source_set_volume_cb);
         u->source->n_volume_steps = 16;
 
         k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->source);
@@ -2213,38 +1854,73 @@ static int add_source(struct userdata *u) {
     return 0;
 }
 
-/* Run from main thread */
-static void shutdown_bt(struct userdata *u) {
-    pa_assert(u);
+#ifdef BLUETOOTH_APTX_SUPPORT
+/* should be implemeted */
+static int bt_transport_config_a2dp_for_aptx(struct userdata *u) {
+    //const pa_bluetooth_transport *t;
+    struct a2dp_info *a2dp = &u->a2dp;
+    //a2dp_sbc_t *config;
 
-    if (u->stream_fd >= 0) {
-        pa_close(u->stream_fd);
-        u->stream_fd = -1;
+    //t = pa_bluetooth_discovery_get_transport(u->discovery, u->transport);
+    //pa_assert(t);
 
-        u->stream_write_type = 0;
-    }
+    //config = (a2dp_sbc_t *) t->config;
 
-    if (u->service_fd >= 0) {
-        pa_close(u->service_fd);
-        u->service_fd = -1;
-        u->service_write_type = 0;
-        u->service_read_type = 0;
-    }
+    u->sample_spec.format = PA_SAMPLE_S16LE;
 
-    if (u->write_memchunk.memblock) {
-        pa_memblock_unref(u->write_memchunk.memblock);
-        pa_memchunk_reset(&u->write_memchunk);
+    if (!a2dp->aptx_initialized){
+       #if __BYTE_ORDER==__LITTLE_ENDIAN
+               a2dp->aptx = aptx_new(1);
+       #elif __BYTE_ORDER==__BIG_ENDIAN
+               a2dp->aptx = aptx_new(0);
+       #else
+               #error "Unknown byte order"
+       #endif
+               a2dp->aptx_initialized = TRUE;
     }
+
+    pa_log_debug("aptx Encoder is intialized !!");
+
+    u->write_block_size =(size_t)(u->write_link_mtu/(size_t)16) *16*4 ;
+    u->read_block_size =(size_t)(u->read_link_mtu/(size_t)16) *16*4 ;
+
+    pa_log_info("APTX parameters write_block_size(%d),write_link_mtu(%d)",u->write_block_size,u->write_link_mtu);
+    pa_log_info("APTX parameters read_block_size(%d),read_link_mtu(%d)",u->read_block_size,u->read_link_mtu);
+
+    return 0;
 }
+#endif
 
-static int bt_transport_config_a2dp(struct userdata *u) {
-    const pa_bluetooth_transport *t;
+static void bt_transport_config_a2dp(struct userdata *u) {
+    const pa_bluez4_transport *t;
     struct a2dp_info *a2dp = &u->a2dp;
     a2dp_sbc_t *config;
+#ifdef BLUETOOTH_APTX_SUPPORT
+    a2dp_aptx_t *aptx_config;
+#endif
 
-    t = pa_bluetooth_discovery_get_transport(u->discovery, u->transport);
+    t = u->transport;
     pa_assert(t);
 
+#ifdef BLUETOOTH_APTX_SUPPORT
+    if (t->codec == A2DP_CODEC_NON_A2DP) {
+        aptx_config = (a2dp_aptx_t *) t->config;
+        if (aptx_config->vendor_id[0] == APTX_VENDOR_ID0 &&
+            aptx_config->vendor_id[1] == APTX_VENDOR_ID1 &&
+            aptx_config->vendor_id[2] == APTX_VENDOR_ID2 &&
+            aptx_config->vendor_id[3] == APTX_VENDOR_ID3 &&
+            aptx_config->codec_id[0] == APTX_CODEC_ID0  &&
+            aptx_config->codec_id[1] == APTX_CODEC_ID1  ){
+            pa_log("A2DP_CODEC_NON_A2DP and this is APTX Codec");
+
+            return bt_transport_config_a2dp_for_aptx(u);
+        } else {
+            pa_log("A2DP_CODEC_NON_A2DP but this is not APTX Codec");
+            return -1;
+        }
+    }
+#endif
+
     config = (a2dp_sbc_t *) t->config;
 
     u->sample_spec.format = PA_SAMPLE_S16LE;
@@ -2253,22 +1929,22 @@ static int bt_transport_config_a2dp(struct userdata *u) {
         sbc_reinit(&a2dp->sbc, 0);
     else
         sbc_init(&a2dp->sbc, 0);
-    a2dp->sbc_initialized = TRUE;
+    a2dp->sbc_initialized = true;
 
     switch (config->frequency) {
-        case BT_SBC_SAMPLING_FREQ_16000:
+        case SBC_SAMPLING_FREQ_16000:
             a2dp->sbc.frequency = SBC_FREQ_16000;
             u->sample_spec.rate = 16000U;
             break;
-        case BT_SBC_SAMPLING_FREQ_32000:
+        case SBC_SAMPLING_FREQ_32000:
             a2dp->sbc.frequency = SBC_FREQ_32000;
             u->sample_spec.rate = 32000U;
             break;
-        case BT_SBC_SAMPLING_FREQ_44100:
+        case SBC_SAMPLING_FREQ_44100:
             a2dp->sbc.frequency = SBC_FREQ_44100;
             u->sample_spec.rate = 44100U;
             break;
-        case BT_SBC_SAMPLING_FREQ_48000:
+        case SBC_SAMPLING_FREQ_48000:
             a2dp->sbc.frequency = SBC_FREQ_48000;
             u->sample_spec.rate = 48000U;
             break;
@@ -2277,19 +1953,19 @@ static int bt_transport_config_a2dp(struct userdata *u) {
     }
 
     switch (config->channel_mode) {
-        case BT_A2DP_CHANNEL_MODE_MONO:
+        case SBC_CHANNEL_MODE_MONO:
             a2dp->sbc.mode = SBC_MODE_MONO;
             u->sample_spec.channels = 1;
             break;
-        case BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL:
+        case SBC_CHANNEL_MODE_DUAL_CHANNEL:
             a2dp->sbc.mode = SBC_MODE_DUAL_CHANNEL;
             u->sample_spec.channels = 2;
             break;
-        case BT_A2DP_CHANNEL_MODE_STEREO:
+        case SBC_CHANNEL_MODE_STEREO:
             a2dp->sbc.mode = SBC_MODE_STEREO;
             u->sample_spec.channels = 2;
             break;
-        case BT_A2DP_CHANNEL_MODE_JOINT_STEREO:
+        case SBC_CHANNEL_MODE_JOINT_STEREO:
             a2dp->sbc.mode = SBC_MODE_JOINT_STEREO;
             u->sample_spec.channels = 2;
             break;
@@ -2298,10 +1974,10 @@ static int bt_transport_config_a2dp(struct userdata *u) {
     }
 
     switch (config->allocation_method) {
-        case BT_A2DP_ALLOCATION_SNR:
+        case SBC_ALLOCATION_SNR:
             a2dp->sbc.allocation = SBC_AM_SNR;
             break;
-        case BT_A2DP_ALLOCATION_LOUDNESS:
+        case SBC_ALLOCATION_LOUDNESS:
             a2dp->sbc.allocation = SBC_AM_LOUDNESS;
             break;
         default:
@@ -2309,10 +1985,10 @@ static int bt_transport_config_a2dp(struct userdata *u) {
     }
 
     switch (config->subbands) {
-        case BT_A2DP_SUBBANDS_4:
+        case SBC_SUBBANDS_4:
             a2dp->sbc.subbands = SBC_SB_4;
             break;
-        case BT_A2DP_SUBBANDS_8:
+        case SBC_SUBBANDS_8:
             a2dp->sbc.subbands = SBC_SB_8;
             break;
         default:
@@ -2320,16 +1996,16 @@ static int bt_transport_config_a2dp(struct userdata *u) {
     }
 
     switch (config->block_length) {
-        case BT_A2DP_BLOCK_LENGTH_4:
+        case SBC_BLOCK_LENGTH_4:
             a2dp->sbc.blocks = SBC_BLK_4;
             break;
-        case BT_A2DP_BLOCK_LENGTH_8:
+        case SBC_BLOCK_LENGTH_8:
             a2dp->sbc.blocks = SBC_BLK_8;
             break;
-        case BT_A2DP_BLOCK_LENGTH_12:
+        case SBC_BLOCK_LENGTH_12:
             a2dp->sbc.blocks = SBC_BLK_12;
             break;
-        case BT_A2DP_BLOCK_LENGTH_16:
+        case SBC_BLOCK_LENGTH_16:
             a2dp->sbc.blocks = SBC_BLK_16;
             break;
         default:
@@ -2340,103 +2016,60 @@ static int bt_transport_config_a2dp(struct userdata *u) {
     a2dp->max_bitpool = config->max_bitpool;
 
     /* Set minimum bitpool for source to get the maximum possible block_size */
-    a2dp->sbc.bitpool = u->profile == PROFILE_A2DP ? a2dp->max_bitpool : a2dp->min_bitpool;
+    a2dp->sbc.bitpool = u->profile == PA_BLUEZ4_PROFILE_A2DP ? a2dp->max_bitpool : a2dp->min_bitpool;
     a2dp->codesize = sbc_get_codesize(&a2dp->sbc);
     a2dp->frame_length = sbc_get_frame_length(&a2dp->sbc);
 
-    u->block_size =
-        ((u->link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
-        / a2dp->frame_length
-        * a2dp->codesize);
-
     pa_log_info("SBC parameters:\n\tallocation=%u\n\tsubbands=%u\n\tblocks=%u\n\tbitpool=%u\n",
                 a2dp->sbc.allocation, a2dp->sbc.subbands, a2dp->sbc.blocks, a2dp->sbc.bitpool);
-
-    return 0;
 }
 
-static int bt_transport_config(struct userdata *u) {
-    if (u->profile == PROFILE_HSP || u->profile == PROFILE_HFGW) {
-        u->block_size = u->link_mtu;
+static void bt_transport_config(struct userdata *u) {
+    if (u->profile == PA_BLUEZ4_PROFILE_HSP || u->profile == PA_BLUEZ4_PROFILE_HFGW) {
         u->sample_spec.format = PA_SAMPLE_S16LE;
         u->sample_spec.channels = 1;
         u->sample_spec.rate = 8000;
-        return 0;
-    }
-
-    return bt_transport_config_a2dp(u);
-}
-
-/* Run from main thread */
-static int bt_transport_open(struct userdata *u) {
-    if (bt_transport_acquire(u, FALSE) < 0)
-        return -1;
-
-    return bt_transport_config(u);
+    } else
+        bt_transport_config_a2dp(u);
 }
 
 /* Run from main thread */
-static int init_bt(struct userdata *u) {
+static pa_hook_result_t transport_state_changed_cb(pa_bluez4_discovery *y, pa_bluez4_transport *t, struct userdata *u) {
+    pa_assert(t);
     pa_assert(u);
 
-    shutdown_bt(u);
-
-    u->stream_write_type = 0;
-    u->service_write_type = 0;
-    u->service_read_type = 0;
-
-    if ((u->service_fd = bt_audio_service_open()) < 0) {
-        pa_log_warn("Bluetooth audio service not available");
-        return -1;
-    }
+    if (t == u->transport && t->state == PA_BLUEZ4_TRANSPORT_STATE_DISCONNECTED)
+        pa_assert_se(pa_card_set_profile(u->card, "off", false) >= 0);
 
-    pa_log_debug("Connected to the bluetooth audio service");
+    if (t->device == u->device)
+        handle_transport_state_change(u, t);
 
-    return 0;
+    return PA_HOOK_OK;
 }
 
 /* Run from main thread */
-static int setup_bt(struct userdata *u) {
-    const pa_bluetooth_device *d;
-    const pa_bluetooth_transport *t;
+static int setup_transport(struct userdata *u) {
+    pa_bluez4_transport *t;
 
     pa_assert(u);
-
-    if (!(d = pa_bluetooth_discovery_get_by_path(u->discovery, u->path))) {
-        pa_log_error("Failed to get device object.");
-        return -1;
-    }
-
-    /* release transport if exist */
-    if (u->transport) {
-        bt_transport_release(u);
-        pa_xfree(u->transport);
-        u->transport = NULL;
-    }
+    pa_assert(!u->transport);
+    pa_assert(u->profile != PA_BLUEZ4_PROFILE_OFF);
 
     /* check if profile has a transport */
-    t = pa_bluetooth_device_get_transport(d, u->profile);
-    if (t) {
-        u->transport = pa_xstrdup(t->path);
-        return bt_transport_open(u);
-    }
-
-    if (get_caps(u, 0) < 0)
-        return -1;
-
-    pa_log_debug("Got device capabilities");
-
-    if (set_conf(u) < 0)
+    t = u->device->transports[u->profile];
+    if (!t || t->state == PA_BLUEZ4_TRANSPORT_STATE_DISCONNECTED) {
+        pa_log_warn("Profile has no transport");
         return -1;
+    }
 
-    pa_log_debug("Connection to the device configured");
+    u->transport = t;
 
-    if (USE_SCO_OVER_PCM(u)) {
-        pa_log_debug("Configured to use SCO over PCM");
-        return 0;
-    }
+    if (u->profile == PA_BLUEZ4_PROFILE_A2DP_SOURCE || u->profile == PA_BLUEZ4_PROFILE_HFGW)
+        bt_transport_acquire(u, true); /* In case of error, the sink/sources will be created suspended */
+    else if (bt_transport_acquire(u, false) < 0)
+        return -1; /* We need to fail here until the interactions with module-suspend-on-idle and alike get improved */
 
-    pa_log_debug("Got the stream socket");
+    bt_transport_config(u);
 
     return 0;
 }
@@ -2445,20 +2078,22 @@ static int setup_bt(struct userdata *u) {
 static int init_profile(struct userdata *u) {
     int r = 0;
     pa_assert(u);
-    pa_assert(u->profile != PROFILE_OFF);
+    pa_assert(u->profile != PA_BLUEZ4_PROFILE_OFF);
 
-    if (setup_bt(u) < 0)
+    if (setup_transport(u) < 0)
         return -1;
 
-    if (u->profile == PROFILE_A2DP ||
-        u->profile == PROFILE_HSP ||
-        u->profile == PROFILE_HFGW)
+    pa_assert(u->transport);
+
+    if (u->profile == PA_BLUEZ4_PROFILE_A2DP ||
+        u->profile == PA_BLUEZ4_PROFILE_HSP ||
+        u->profile == PA_BLUEZ4_PROFILE_HFGW)
         if (add_sink(u) < 0)
             r = -1;
 
-    if (u->profile == PROFILE_HSP ||
-        u->profile == PROFILE_A2DP_SOURCE ||
-        u->profile == PROFILE_HFGW)
+    if (u->profile == PA_BLUEZ4_PROFILE_HSP ||
+        u->profile == PA_BLUEZ4_PROFILE_A2DP_SOURCE ||
+        u->profile == PA_BLUEZ4_PROFILE_HFGW)
         if (add_source(u) < 0)
             r = -1;
 
@@ -2471,6 +2106,12 @@ static void stop_thread(struct userdata *u) {
 
     pa_assert(u);
 
+    if (u->sink && !USE_SCO_OVER_PCM(u))
+        pa_sink_unlink(u->sink);
+
+    if (u->source && !USE_SCO_OVER_PCM(u))
+        pa_source_unlink(u->source);
+
     if (u->thread) {
         pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
         pa_thread_free(u->thread);
@@ -2482,18 +2123,20 @@ static void stop_thread(struct userdata *u) {
         u->rtpoll_item = NULL;
     }
 
-    if (u->hsp.sink_state_changed_slot) {
-        pa_hook_slot_free(u->hsp.sink_state_changed_slot);
-        u->hsp.sink_state_changed_slot = NULL;
+    if (u->rtpoll) {
+        pa_thread_mq_done(&u->thread_mq);
+
+        pa_rtpoll_free(u->rtpoll);
+        u->rtpoll = NULL;
     }
 
-    if (u->hsp.source_state_changed_slot) {
-        pa_hook_slot_free(u->hsp.source_state_changed_slot);
-        u->hsp.source_state_changed_slot = NULL;
+    if (u->transport) {
+        bt_transport_release(u);
+        u->transport = NULL;
     }
 
     if (u->sink) {
-        if (u->profile == PROFILE_HSP) {
+        if (u->profile == PA_BLUEZ4_PROFILE_HSP) {
             k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->sink);
             pa_shared_remove(u->core, k);
             pa_xfree(k);
@@ -2504,7 +2147,7 @@ static void stop_thread(struct userdata *u) {
     }
 
     if (u->source) {
-        if (u->profile == PROFILE_HSP) {
+        if (u->profile == PA_BLUEZ4_PROFILE_HSP) {
             k = pa_sprintf_malloc("bluetooth-device@%p", (void*) u->source);
             pa_shared_remove(u->core, k);
             pa_xfree(k);
@@ -2514,13 +2157,6 @@ static void stop_thread(struct userdata *u) {
         u->source = NULL;
     }
 
-    if (u->rtpoll) {
-        pa_thread_mq_done(&u->thread_mq);
-
-        pa_rtpoll_free(u->rtpoll);
-        u->rtpoll = NULL;
-    }
-
     if (u->read_smoother) {
         pa_smoother_free(u->read_smoother);
         u->read_smoother = NULL;
@@ -2538,7 +2174,7 @@ static int start_thread(struct userdata *u) {
     pa_thread_mq_init(&u->thread_mq, u->core->mainloop, u->rtpoll);
 
     if (USE_SCO_OVER_PCM(u)) {
-        if (sco_over_pcm_state_update(u, FALSE) < 0) {
+        if (sco_over_pcm_state_update(u, false) < 0) {
             char *k;
 
             if (u->sink) {
@@ -2562,12 +2198,8 @@ static int start_thread(struct userdata *u) {
         return 0;
     }
 
-    /* Fix PA version mis-match. */
-    /* if (!(u->thread = pa_thread_new("bluetooth", thread_func, u))) {
-    */
-    if (!(u->thread = pa_thread_new(thread_func, u))) {
+    if (!(u->thread = pa_thread_new("bluetooth", thread_func, u))) {
         pa_log_error("Failed to create IO thread");
-        stop_thread(u);
         return -1;
     }
 
@@ -2604,18 +2236,14 @@ static void restore_sco_volume_callbacks(struct userdata *u) {
     pa_assert(u);
     pa_assert(USE_SCO_OVER_PCM(u));
 
-    /* pa_sink_set_set_volume_callback(u->hsp.sco_sink, u->hsp.sco_sink_set_volume); */
-    /* pa_source_set_set_volume_callback(u->hsp.sco_source, u->hsp.sco_source_set_volume); */
-    u->hsp.sco_sink->set_volume = u->hsp.sco_sink_set_volume;
-    u->hsp.sco_source->set_volume = u->hsp.sco_source_set_volume;
+    pa_sink_set_set_volume_callback(u->hsp.sco_sink, u->hsp.sco_sink_set_volume);
+    pa_source_set_set_volume_callback(u->hsp.sco_source, u->hsp.sco_source_set_volume);
 }
 
 /* Run from main thread */
 static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
     struct userdata *u;
-    enum profile *d;
-    pa_queue *inputs = NULL, *outputs = NULL;
-    const pa_bluetooth_device *device;
+    pa_bluez4_profile_t *d;
 
     pa_assert(c);
     pa_assert(new_profile);
@@ -2623,53 +2251,17 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
 
     d = PA_CARD_PROFILE_DATA(new_profile);
 
-    if (!(device = pa_bluetooth_discovery_get_by_path(u->discovery, u->path))) {
-        pa_log_error("Failed to get device object.");
-        return -PA_ERR_IO;
-    }
-
-    /* The state signal is sent by bluez, so it is racy to check
-       strictly for CONNECTED, we should also accept STREAMING state
-       as being good enough. However, if the profile is used
-       concurrently (which is unlikely), ipc will fail later on, and
-       module will be unloaded. */
-    if (device->headset_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HSP) {
-        pa_log_warn("HSP is not connected, refused to switch profile");
-        return -PA_ERR_IO;
-    }
-    else if (device->audio_sink_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_A2DP) {
-        pa_log_warn("A2DP is not connected, refused to switch profile");
-        return -PA_ERR_IO;
-    }
-    else if (device->hfgw_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HFGW) {
-        pa_log_warn("HandsfreeGateway is not connected, refused to switch profile");
-        return -PA_ERR_IO;
-    }
-
-    if (u->sink) {
-        inputs = pa_sink_move_all_start(u->sink, NULL);
-
-        if (!USE_SCO_OVER_PCM(u))
-            pa_sink_unlink(u->sink);
-    }
-
-    if (u->source) {
-        outputs = pa_source_move_all_start(u->source, NULL);
+    if (*d != PA_BLUEZ4_PROFILE_OFF) {
+        const pa_bluez4_device *device = u->device;
 
-        if (!USE_SCO_OVER_PCM(u))
-            pa_source_unlink(u->source);
+        if (!device->transports[*d] || device->transports[*d]->state == PA_BLUEZ4_TRANSPORT_STATE_DISCONNECTED) {
+            pa_log_warn("Profile not connected, refused to switch profile to %s", new_profile->name);
+            return -PA_ERR_IO;
+        }
     }
 
     stop_thread(u);
 
-    if (u->profile != PROFILE_OFF && u->transport) {
-        bt_transport_release(u);
-        pa_xfree(u->transport);
-        u->transport = NULL;
-    }
-
-    shutdown_bt(u);
-
     if (USE_SCO_OVER_PCM(u))
         restore_sco_volume_callbacks(u);
 
@@ -2679,140 +2271,271 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
     if (USE_SCO_OVER_PCM(u))
         save_sco_volume_callbacks(u);
 
-    init_bt(u);
-
-    if (u->profile != PROFILE_OFF)
-        init_profile(u);
+    if (u->profile != PA_BLUEZ4_PROFILE_OFF)
+        if (init_profile(u) < 0)
+            goto off;
 
     if (u->sink || u->source)
-        start_thread(u);
+        if (start_thread(u) < 0)
+            goto off;
 
-    if (inputs) {
-        if (u->sink)
-            pa_sink_move_all_finish(u->sink, inputs, FALSE);
-        else
-            pa_sink_move_all_fail(inputs);
-    }
+    return 0;
 
-    if (outputs) {
-        if (u->source)
-            pa_source_move_all_finish(u->source, outputs, FALSE);
-        else
-            pa_source_move_all_fail(outputs);
-    }
+off:
+    stop_thread(u);
 
-    return 0;
+    pa_assert_se(pa_card_set_profile(u->card, "off", false) >= 0);
+
+    return -PA_ERR_IO;
 }
 
 /* Run from main thread */
-static int add_card(struct userdata *u, const pa_bluetooth_device *device) {
-    pa_card_new_data data;
-    pa_bool_t b;
-    pa_card_profile *p;
-    enum profile *d;
-    const char *ff;
-    char *n;
-    const char *default_profile;
+static void create_card_ports(struct userdata *u, pa_hashmap *ports) {
+    pa_device_port *port;
+#ifndef __TIZEN_BT__
+    pa_device_port_new_data port_data;
+#endif
+
+    const char *name_prefix = NULL;
+    const char *input_description = NULL;
+    const char *output_description = NULL;
 
     pa_assert(u);
-    pa_assert(device);
+    pa_assert(ports);
+    pa_assert(u->device);
 
-    pa_card_new_data_init(&data);
-    data.driver = __FILE__;
-    data.module = u->module;
+    switch (pa_bluez4_get_form_factor(u->device->class)) {
+        case PA_BLUEZ4_FORM_FACTOR_UNKNOWN:
+            break;
 
-    n = pa_bluetooth_cleanup_name(device->name);
-    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, n);
-    pa_xfree(n);
-    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, device->address);
-    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, "bluez");
-    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "sound");
-    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_BUS, "bluetooth");
-    if ((ff = pa_bluetooth_get_form_factor(device->class)))
-        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_FORM_FACTOR, ff);
-    pa_proplist_sets(data.proplist, "bluez.path", device->path);
-    pa_proplist_setf(data.proplist, "bluez.class", "0x%06x", (unsigned) device->class);
-    pa_proplist_sets(data.proplist, "bluez.name", device->name);
-    data.name = get_name("card", u->modargs, device->address, &b);
-    data.namereg_fail = b;
+        case PA_BLUEZ4_FORM_FACTOR_HEADSET:
+            name_prefix = "headset";
+            input_description = output_description = _("Headset");
+            break;
 
-    if (pa_modargs_get_proplist(u->modargs, "card_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
-        pa_log("Invalid properties");
-        pa_card_new_data_done(&data);
-        return -1;
+        case PA_BLUEZ4_FORM_FACTOR_HANDSFREE:
+            name_prefix = "handsfree";
+            input_description = output_description = _("Handsfree");
+            break;
+
+        case PA_BLUEZ4_FORM_FACTOR_MICROPHONE:
+            name_prefix = "microphone";
+            input_description = _("Microphone");
+            break;
+
+        case PA_BLUEZ4_FORM_FACTOR_SPEAKER:
+            name_prefix = "speaker";
+            output_description = _("Speaker");
+            break;
+
+        case PA_BLUEZ4_FORM_FACTOR_HEADPHONE:
+            name_prefix = "headphone";
+            output_description = _("Headphone");
+            break;
+
+        case PA_BLUEZ4_FORM_FACTOR_PORTABLE:
+            name_prefix = "portable";
+            input_description = output_description = _("Portable");
+            break;
+
+        case PA_BLUEZ4_FORM_FACTOR_CAR:
+            name_prefix = "car";
+            input_description = output_description = _("Car");
+            break;
+
+        case PA_BLUEZ4_FORM_FACTOR_HIFI:
+            name_prefix = "hifi";
+            input_description = output_description = _("HiFi");
+            break;
+
+        case PA_BLUEZ4_FORM_FACTOR_PHONE:
+            name_prefix = "phone";
+            input_description = output_description = _("Phone");
+            break;
     }
 
-    data.profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    if (!name_prefix)
+        name_prefix = "unknown";
+
+    if (!output_description)
+        output_description = _("Bluetooth Output");
+
+    if (!input_description)
+        input_description = _("Bluetooth Input");
+
+    u->output_port_name = pa_sprintf_malloc("%s-output", name_prefix);
+    u->input_port_name = pa_sprintf_malloc("%s-input", name_prefix);
+
+#ifdef __TIZEN_BT__
+    pa_assert_se(port = pa_device_port_new(u->core, u->output_port_name, output_description, 0));
+    pa_assert_se(pa_hashmap_put(ports, port->name, port) >= 0);
+    port->is_output = 1;
+    port->is_input = 0;
+    port->available = get_port_availability(u, PA_DIRECTION_OUTPUT);
+
+    pa_assert_se(port = pa_device_port_new(u->core, u->input_port_name, input_description, 0));
+    pa_assert_se(pa_hashmap_put(ports, port->name, port) >= 0);
+    port->is_output = 0;
+    port->is_input = 1;
+    port->available = get_port_availability(u, PA_DIRECTION_INPUT);
+#else
+    pa_device_port_new_data_init(&port_data);
+    pa_device_port_new_data_set_name(&port_data, u->output_port_name);
+    pa_device_port_new_data_set_description(&port_data, output_description);
+    pa_device_port_new_data_set_direction(&port_data, PA_DIRECTION_OUTPUT);
+    pa_device_port_new_data_set_available(&port_data, get_port_availability(u, PA_DIRECTION_OUTPUT));
+    pa_assert_se(port = pa_device_port_new(u->core, &port_data, 0));
+    pa_assert_se(pa_hashmap_put(ports, port->name, port) >= 0);
+    pa_device_port_new_data_done(&port_data);
+
+    pa_device_port_new_data_init(&port_data);
+    pa_device_port_new_data_set_name(&port_data, u->input_port_name);
+    pa_device_port_new_data_set_description(&port_data, input_description);
+    pa_device_port_new_data_set_direction(&port_data, PA_DIRECTION_INPUT);
+    pa_device_port_new_data_set_available(&port_data, get_port_availability(u, PA_DIRECTION_INPUT));
+    pa_assert_se(port = pa_device_port_new(u->core, &port_data, 0));
+    pa_assert_se(pa_hashmap_put(ports, port->name, port) >= 0);
+    pa_device_port_new_data_done(&port_data);
+#endif
+}
 
-    /* we base hsp/a2dp availability on UUIDs.
-       Ideally, it would be based on "Connected" state, but
-       we can't afford to wait for this information when
-       we are loaded with profile="hsp", for instance */
-    if (pa_bluetooth_uuid_has(device->uuids, A2DP_SINK_UUID)) {
-        p = pa_card_profile_new("a2dp", _("High Fidelity Playback (A2DP)"), sizeof(enum profile));
+/* Run from main thread */
+static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid, pa_hashmap *ports) {
+    pa_device_port *input_port, *output_port;
+    pa_card_profile *p = NULL;
+    pa_bluez4_profile_t *d;
+
+    pa_assert(u->input_port_name);
+    pa_assert(u->output_port_name);
+    pa_assert_se(input_port = pa_hashmap_get(ports, u->input_port_name));
+    pa_assert_se(output_port = pa_hashmap_get(ports, u->output_port_name));
+
+    if (pa_streq(uuid, A2DP_SINK_UUID)) {
+        p = pa_card_profile_new("a2dp", _("High Fidelity Playback (A2DP)"), sizeof(pa_bluez4_profile_t));
         p->priority = 10;
         p->n_sinks = 1;
         p->n_sources = 0;
         p->max_sink_channels = 2;
         p->max_source_channels = 0;
+        pa_hashmap_put(output_port->profiles, p->name, p);
 
         d = PA_CARD_PROFILE_DATA(p);
-        *d = PROFILE_A2DP;
-
-        pa_hashmap_put(data.profiles, p->name, p);
-    }
-
-#if BT_FULL_AUDIO_FEATURE
-    if (pa_bluetooth_uuid_has(device->uuids, A2DP_SOURCE_UUID)) {
-        p = pa_card_profile_new("a2dp_source", _("High Fidelity Capture (A2DP)"), sizeof(enum profile));
+        *d = PA_BLUEZ4_PROFILE_A2DP;
+    } else if (pa_streq(uuid, A2DP_SOURCE_UUID)) {
+        p = pa_card_profile_new("a2dp_source", _("High Fidelity Capture (A2DP)"), sizeof(pa_bluez4_profile_t));
         p->priority = 10;
         p->n_sinks = 0;
         p->n_sources = 1;
         p->max_sink_channels = 0;
         p->max_source_channels = 2;
+        pa_hashmap_put(input_port->profiles, p->name, p);
 
         d = PA_CARD_PROFILE_DATA(p);
-        *d = PROFILE_A2DP_SOURCE;
-
-        pa_hashmap_put(data.profiles, p->name, p);
-    }
-
-    if (pa_bluetooth_uuid_has(device->uuids, HSP_HS_UUID) ||
-        pa_bluetooth_uuid_has(device->uuids, HFP_HS_UUID)) {
-        p = pa_card_profile_new("hsp", _("Telephony Duplex (HSP/HFP)"), sizeof(enum profile));
+        *d = PA_BLUEZ4_PROFILE_A2DP_SOURCE;
+    } else if (pa_streq(uuid, HSP_HS_UUID) || pa_streq(uuid, HFP_HS_UUID)) {
+        p = pa_card_profile_new("hsp", _("Telephony Duplex (HSP/HFP)"), sizeof(pa_bluez4_profile_t));
         p->priority = 20;
         p->n_sinks = 1;
         p->n_sources = 1;
         p->max_sink_channels = 1;
         p->max_source_channels = 1;
+        pa_hashmap_put(input_port->profiles, p->name, p);
+        pa_hashmap_put(output_port->profiles, p->name, p);
 
         d = PA_CARD_PROFILE_DATA(p);
-        *d = PROFILE_HSP;
-
-        pa_hashmap_put(data.profiles, p->name, p);
-    }
-
-    if (pa_bluetooth_uuid_has(device->uuids, HFP_AG_UUID)) {
-        p = pa_card_profile_new("hfgw", _("Handsfree Gateway"), sizeof(enum profile));
+        *d = PA_BLUEZ4_PROFILE_HSP;
+    } else if (pa_streq(uuid, HFP_AG_UUID)) {
+        p = pa_card_profile_new("hfgw", _("Handsfree Gateway"), sizeof(pa_bluez4_profile_t));
         p->priority = 20;
         p->n_sinks = 1;
         p->n_sources = 1;
         p->max_sink_channels = 1;
         p->max_source_channels = 1;
+        pa_hashmap_put(input_port->profiles, p->name, p);
+        pa_hashmap_put(output_port->profiles, p->name, p);
 
         d = PA_CARD_PROFILE_DATA(p);
-        *d = PROFILE_HFGW;
+        *d = PA_BLUEZ4_PROFILE_HFGW;
+    }
+
+    if (p) {
+        pa_bluez4_transport *t;
+
+        if ((t = u->device->transports[*d]))
+            p->available = transport_state_to_availability(t->state);
+    }
+
+    return p;
+}
+
+/* Run from main thread */
+static int add_card(struct userdata *u) {
+    pa_card_new_data data;
+    bool b;
+    pa_card_profile *p;
+    pa_bluez4_profile_t *d;
+    pa_bluez4_form_factor_t ff;
+    char *n;
+    const char *default_profile;
+    const pa_bluez4_device *device;
+    const pa_bluez4_uuid *uuid;
+
+    pa_assert(u);
+    pa_assert(u->device);
+
+    device = u->device;
+
+    pa_card_new_data_init(&data);
+    data.driver = __FILE__;
+    data.module = u->module;
+
+    n = pa_bluez4_cleanup_name(device->alias);
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, n);
+    pa_xfree(n);
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, device->address);
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, "bluez");
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "sound");
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_BUS, "bluetooth");
+
+    if ((ff = pa_bluez4_get_form_factor(device->class)) != PA_BLUEZ4_FORM_FACTOR_UNKNOWN)
+        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_FORM_FACTOR, pa_bluez4_form_factor_to_string(ff));
+
+    pa_proplist_sets(data.proplist, "bluez.path", device->path);
+    pa_proplist_setf(data.proplist, "bluez.class", "0x%06x", (unsigned) device->class);
+    pa_proplist_sets(data.proplist, "bluez.alias", device->alias);
+    data.name = get_name("card", u->modargs, device->address, &b);
+    data.namereg_fail = b;
+
+    if (pa_modargs_get_proplist(u->modargs, "card_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
+        pa_log("Invalid properties");
+        pa_card_new_data_done(&data);
+        return -1;
+    }
+
+    create_card_ports(u, data.ports);
+
+    PA_LLIST_FOREACH(uuid, device->uuids) {
+        p = create_card_profile(u, uuid->uuid, data.ports);
+
+        if (!p)
+            continue;
+
+        if (pa_hashmap_get(data.profiles, p->name)) {
+            pa_card_profile_free(p);
+            continue;
+        }
 
         pa_hashmap_put(data.profiles, p->name, p);
     }
-#endif
 
     pa_assert(!pa_hashmap_isempty(data.profiles));
 
-    p = pa_card_profile_new("off", _("Off"), sizeof(enum profile));
+    p = pa_card_profile_new("off", _("Off"), sizeof(pa_bluez4_profile_t));
+    p->available = PA_AVAILABLE_YES;
     d = PA_CARD_PROFILE_DATA(p);
-    *d = PROFILE_OFF;
+    *d = PA_BLUEZ4_PROFILE_OFF;
     pa_hashmap_put(data.profiles, p->name, p);
+    pa_card_new_data_set_profile(&data, "off");
 
     if ((default_profile = pa_modargs_get_value(u->modargs, "profile", NULL))) {
         if (pa_hashmap_get(data.profiles, default_profile))
@@ -2820,6 +2543,8 @@ static int add_card(struct userdata *u, const pa_bluetooth_device *device) {
         else
             pa_log_warn("Profile '%s' not valid or not supported by device.", default_profile);
     }
+    else
+      pa_card_new_data_set_profile(&data, p->name);
 
     u->card = pa_card_new(u->core, &data);
     pa_card_new_data_done(&data);
@@ -2834,12 +2559,11 @@ static int add_card(struct userdata *u, const pa_bluetooth_device *device) {
 
     d = PA_CARD_PROFILE_DATA(u->card->active_profile);
 
-    if ((device->headset_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HSP) ||
-        (device->audio_sink_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_A2DP) ||
-        (device->hfgw_state < PA_BT_AUDIO_STATE_CONNECTED && *d == PROFILE_HFGW)) {
+    if (*d != PA_BLUEZ4_PROFILE_OFF && (!device->transports[*d] ||
+                              device->transports[*d]->state == PA_BLUEZ4_TRANSPORT_STATE_DISCONNECTED)) {
         pa_log_warn("Default profile not connected, selecting off profile");
         u->card->active_profile = pa_hashmap_get(u->card->profiles, "off");
-        u->card->save_profile = FALSE;
+        u->card->save_profile = false;
     }
 
     d = PA_CARD_PROFILE_DATA(u->card->active_profile);
@@ -2852,8 +2576,8 @@ static int add_card(struct userdata *u, const pa_bluetooth_device *device) {
 }
 
 /* Run from main thread */
-static const pa_bluetooth_device* find_device(struct userdata *u, const char *address, const char *path) {
-    const pa_bluetooth_device *d = NULL;
+static pa_bluez4_device* find_device(struct userdata *u, const char *address, const char *path) {
+    pa_bluez4_device *d = NULL;
 
     pa_assert(u);
 
@@ -2863,7 +2587,7 @@ static const pa_bluetooth_device* find_device(struct userdata *u, const char *ad
     }
 
     if (path) {
-        if (!(d = pa_bluetooth_discovery_get_by_path(u->discovery, path))) {
+        if (!(d = pa_bluez4_discovery_get_by_path(u->discovery, path))) {
             pa_log_error("%s is not a valid BlueZ audio device.", path);
             return NULL;
         }
@@ -2874,7 +2598,7 @@ static const pa_bluetooth_device* find_device(struct userdata *u, const char *ad
         }
 
     } else {
-        if (!(d = pa_bluetooth_discovery_get_by_address(u->discovery, address))) {
+        if (!(d = pa_bluez4_discovery_get_by_address(u->discovery, address))) {
             pa_log_error("%s is not known.", address);
             return NULL;
         }
@@ -2889,35 +2613,65 @@ static const pa_bluetooth_device* find_device(struct userdata *u, const char *ad
 }
 
 /* Run from main thread */
-static int setup_dbus(struct userdata *u) {
-    DBusError err;
+static pa_hook_result_t uuid_added_cb(pa_bluez4_discovery *y, const struct pa_bluez4_hook_uuid_data *data,
+                                      struct userdata *u) {
+    pa_card_profile *p;
 
-    dbus_error_init(&err);
+    pa_assert(data);
+    pa_assert(data->device);
+    pa_assert(data->uuid);
+    pa_assert(u);
+
+    if (data->device != u->device)
+        return PA_HOOK_OK;
 
-    u->connection = pa_dbus_bus_get(u->core, DBUS_BUS_SYSTEM, &err);
+    p = create_card_profile(u, data->uuid, u->card->ports);
 
-    if (dbus_error_is_set(&err) || !u->connection) {
-        pa_log("Failed to get D-Bus connection: %s", err.message);
-        dbus_error_free(&err);
-        return -1;
+    if (!p)
+        return PA_HOOK_OK;
+
+    if (pa_hashmap_get(u->card->profiles, p->name)) {
+        pa_card_profile_free(p);
+        return PA_HOOK_OK;
     }
 
-    return 0;
+    pa_card_add_profile(u->card, p);
+
+    return PA_HOOK_OK;
+}
+
+/* Run from main thread */
+static pa_hook_result_t discovery_hook_cb(pa_bluez4_discovery *y, const pa_bluez4_device *d, struct userdata *u) {
+    pa_assert(u);
+    pa_assert(d);
+
+    if (d != u->device)
+        return PA_HOOK_OK;
+
+    if (d->dead)
+        pa_log_debug("Device %s removed: unloading module", d->path);
+    else if (!pa_bluez4_device_any_audio_connected(d))
+        pa_log_debug("Unloading module, because device %s doesn't have any audio profiles connected anymore.", d->path);
+    else
+        return PA_HOOK_OK;
+
+    pa_module_unload(u->core, u->module, true);
+
+    return PA_HOOK_OK;
 }
 
-int pa__init(pa_modulem) {
+int pa__init(pa_module *m) {
     pa_modargs *ma;
     uint32_t channels;
     struct userdata *u;
     const char *address, *path;
-    DBusError err;
-    char *mike, *speaker;
-    const pa_bluetooth_device *device;
+    pa_bluez4_device *device;
+#ifdef BLUETOOTH_APTX_SUPPORT
+    void *handle;
+#endif
 
     pa_assert(m);
 
-    dbus_error_init(&err);
-
     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
         pa_log_error("Failed to parse module arguments");
         goto fail;
@@ -2926,7 +2680,6 @@ int pa__init(pa_module* m) {
     m->userdata = u = pa_xnew0(struct userdata, 1);
     u->module = m;
     u->core = m->core;
-    u->service_fd = -1;
     u->stream_fd = -1;
     u->sample_spec = m->core->default_sample_spec;
     u->modargs = ma;
@@ -2949,7 +2702,7 @@ int pa__init(pa_module* m) {
         goto fail;
     }
 
-    u->auto_connect = TRUE;
+    u->auto_connect = true;
     if (pa_modargs_get_value_boolean(ma, "auto_connect", &u->auto_connect)) {
         pa_log("Failed to parse auto_connect= argument");
         goto fail;
@@ -2967,17 +2720,48 @@ int pa__init(pa_module* m) {
     address = pa_modargs_get_value(ma, "address", NULL);
     path = pa_modargs_get_value(ma, "path", NULL);
 
-    if (setup_dbus(u) < 0)
-        goto fail;
-
-    if (!(u->discovery = pa_bluetooth_discovery_get(m->core)))
+    if (!(u->discovery = pa_bluez4_discovery_get(m->core)))
         goto fail;
 
     if (!(device = find_device(u, address, path)))
         goto fail;
 
+    u->device = device;
+
+    u->discovery_slot =
+        pa_hook_connect(pa_bluez4_discovery_hook(u->discovery, PA_BLUEZ4_HOOK_DEVICE_CONNECTION_CHANGED),
+                        PA_HOOK_NORMAL, (pa_hook_cb_t) discovery_hook_cb, u);
+
+    u->uuid_added_slot =
+        pa_hook_connect(pa_bluez4_discovery_hook(u->discovery, PA_BLUEZ4_HOOK_DEVICE_UUID_ADDED),
+                        PA_HOOK_NORMAL, (pa_hook_cb_t) uuid_added_cb, u);
+
+    u->sink_state_changed_slot =
+        pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED],
+                        PA_HOOK_NORMAL, (pa_hook_cb_t) sink_state_changed_cb, u);
+
+    u->source_state_changed_slot =
+        pa_hook_connect(&u->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED],
+                        PA_HOOK_NORMAL, (pa_hook_cb_t) source_state_changed_cb, u);
+
+    u->transport_state_changed_slot =
+        pa_hook_connect(pa_bluez4_discovery_hook(u->discovery, PA_BLUEZ4_HOOK_TRANSPORT_STATE_CHANGED),
+                        PA_HOOK_NORMAL, (pa_hook_cb_t) transport_state_changed_cb, u);
+
+    u->transport_nrec_changed_slot =
+        pa_hook_connect(pa_bluez4_discovery_hook(u->discovery, PA_BLUEZ4_HOOK_TRANSPORT_NREC_CHANGED),
+                        PA_HOOK_NORMAL, (pa_hook_cb_t) transport_nrec_changed_cb, u);
+
+    u->transport_microphone_changed_slot =
+        pa_hook_connect(pa_bluez4_discovery_hook(u->discovery, PA_BLUEZ4_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED),
+                        PA_HOOK_NORMAL, (pa_hook_cb_t) transport_microphone_gain_changed_cb, u);
+
+    u->transport_speaker_changed_slot =
+        pa_hook_connect(pa_bluez4_discovery_hook(u->discovery, PA_BLUEZ4_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED),
+                        PA_HOOK_NORMAL, (pa_hook_cb_t) transport_speaker_gain_changed_cb, u);
+
     /* Add the card structure. This will also initialize the default profile */
-    if (add_card(u, device) < 0)
+    if (add_card(u) < 0)
         goto fail;
 
     if (!(u->msg = pa_msgobject_new(bluetooth_msg)))
@@ -2986,43 +2770,29 @@ int pa__init(pa_module* m) {
     u->msg->parent.process_msg = device_process_msg;
     u->msg->card = u->card;
 
-    if (!dbus_connection_add_filter(pa_dbus_connection_get(u->connection), filter_cb, u, NULL)) {
-        pa_log_error("Failed to add filter function");
-        goto fail;
-    }
-    u->filter_added = TRUE;
-
-    speaker = pa_sprintf_malloc("type='signal',sender='org.bluez',interface='org.bluez.Headset',member='SpeakerGainChanged',path='%s'", u->path);
-    mike = pa_sprintf_malloc("type='signal',sender='org.bluez',interface='org.bluez.Headset',member='MicrophoneGainChanged',path='%s'", u->path);
-
-    if (pa_dbus_add_matches(
-                pa_dbus_connection_get(u->connection), &err,
-                speaker,
-                mike,
-                "type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged'",
-                "type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged'",
-                NULL) < 0) {
-
-        pa_xfree(speaker);
-        pa_xfree(mike);
+#ifdef BLUETOOTH_APTX_SUPPORT
+    handle = pa_aptx_get_handle();
 
-        pa_log("Failed to add D-Bus matches: %s", err.message);
-        goto fail;
+    if (handle) {
+        pa_log_debug("Aptx Library loaded\n");
+        pa_load_aptx_sym(handle);
     }
+#endif
 
-    pa_xfree(speaker);
-    pa_xfree(mike);
-
-    /* Connect to the BT service */
-    init_bt(u);
-
-    if (u->profile != PROFILE_OFF)
+    if (u->profile != PA_BLUEZ4_PROFILE_OFF)
         if (init_profile(u) < 0)
-            goto fail;
+            goto off;
 
     if (u->sink || u->source)
         if (start_thread(u) < 0)
-            goto fail;
+            goto off;
+
+    return 0;
+
+off:
+    stop_thread(u);
+
+    pa_assert_se(pa_card_set_profile(u->card, "off", false) >= 0);
 
     return 0;
 
@@ -3030,8 +2800,6 @@ fail:
 
     pa__done(m);
 
-    dbus_error_free(&err);
-
     return -1;
 }
 
@@ -3054,38 +2822,34 @@ void pa__done(pa_module *m) {
     if (!(u = m->userdata))
         return;
 
-    if (u->sink && !USE_SCO_OVER_PCM(u))
-        pa_sink_unlink(u->sink);
+    stop_thread(u);
 
-    if (u->source && !USE_SCO_OVER_PCM(u))
-        pa_source_unlink(u->source);
+    if (u->discovery_slot)
+        pa_hook_slot_free(u->discovery_slot);
 
-    stop_thread(u);
+    if (u->uuid_added_slot)
+        pa_hook_slot_free(u->uuid_added_slot);
 
-    if (USE_SCO_OVER_PCM(u))
-        restore_sco_volume_callbacks(u);
+    if (u->sink_state_changed_slot)
+        pa_hook_slot_free(u->sink_state_changed_slot);
 
-    if (u->connection) {
+    if (u->source_state_changed_slot)
+        pa_hook_slot_free(u->source_state_changed_slot);
 
-        if (u->path) {
-            char *speaker, *mike;
-            speaker = pa_sprintf_malloc("type='signal',sender='org.bluez',interface='org.bluez.Headset',member='SpeakerGainChanged',path='%s'", u->path);
-            mike = pa_sprintf_malloc("type='signal',sender='org.bluez',interface='org.bluez.Headset',member='MicrophoneGainChanged',path='%s'", u->path);
+    if (u->transport_state_changed_slot)
+        pa_hook_slot_free(u->transport_state_changed_slot);
 
-            pa_dbus_remove_matches(pa_dbus_connection_get(u->connection), speaker, mike,
-                "type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged'",
-                "type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged'",
-                NULL);
+    if (u->transport_nrec_changed_slot)
+        pa_hook_slot_free(u->transport_nrec_changed_slot);
 
-            pa_xfree(speaker);
-            pa_xfree(mike);
-        }
+    if (u->transport_microphone_changed_slot)
+        pa_hook_slot_free(u->transport_microphone_changed_slot);
 
-        if (u->filter_added)
-            dbus_connection_remove_filter(pa_dbus_connection_get(u->connection), filter_cb, u);
+    if (u->transport_speaker_changed_slot)
+        pa_hook_slot_free(u->transport_speaker_changed_slot);
 
-        pa_dbus_connection_unref(u->connection);
-    }
+    if (USE_SCO_OVER_PCM(u))
+        restore_sco_volume_callbacks(u);
 
     if (u->msg)
         pa_xfree(u->msg);
@@ -3093,11 +2857,6 @@ void pa__done(pa_module *m) {
     if (u->card)
         pa_card_free(u->card);
 
-    if (u->read_smoother)
-        pa_smoother_free(u->read_smoother);
-
-    shutdown_bt(u);
-
     if (u->a2dp.buffer)
         pa_xfree(u->a2dp.buffer);
 
@@ -3106,16 +2865,14 @@ void pa__done(pa_module *m) {
     if (u->modargs)
         pa_modargs_free(u->modargs);
 
+    pa_xfree(u->output_port_name);
+    pa_xfree(u->input_port_name);
+
     pa_xfree(u->address);
     pa_xfree(u->path);
 
-    if (u->transport) {
-        bt_transport_release(u);
-        pa_xfree(u->transport);
-    }
-
     if (u->discovery)
-        pa_bluetooth_discovery_unref(u->discovery);
+        pa_bluez4_discovery_unref(u->discovery);
 
     pa_xfree(u);
 }
diff --git a/src/modules/bluetooth/module-bluez4-discover.c b/src/modules/bluetooth/module-bluez4-discover.c
new file mode 100644 (file)
index 0000000..9b0dea6
--- /dev/null
@@ -0,0 +1,215 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2008-2013 João Paulo Rechi Vita
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <pulse/xmalloc.h>
+#include <pulsecore/module.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-shared.h>
+
+#include "module-bluez4-discover-symdef.h"
+#include "bluez4-util.h"
+
+PA_MODULE_AUTHOR("João Paulo Rechi Vita");
+PA_MODULE_DESCRIPTION("Detect available BlueZ 4 Bluetooth audio devices and load BlueZ 4 Bluetooth audio drivers");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_USAGE("sco_sink=<name of sink> "
+                "sco_source=<name of source> ");
+PA_MODULE_LOAD_ONCE(true);
+
+static const char* const valid_modargs[] = {
+    "sco_sink",
+    "sco_source",
+    "async", /* deprecated */
+    NULL
+};
+
+struct userdata {
+    pa_module *module;
+    pa_modargs *modargs;
+    pa_core *core;
+    pa_bluez4_discovery *discovery;
+    pa_hook_slot *slot;
+    pa_hashmap *hashmap;
+};
+
+struct module_info {
+    char *path;
+    uint32_t module;
+};
+
+static pa_hook_result_t load_module_for_device(pa_bluez4_discovery *y, const pa_bluez4_device *d, struct userdata *u) {
+    struct module_info *mi;
+
+    pa_assert(u);
+    pa_assert(d);
+
+    mi = pa_hashmap_get(u->hashmap, d->path);
+
+    if (pa_bluez4_device_any_audio_connected(d)) {
+
+        if (!mi) {
+            pa_module *m = NULL;
+            char *args;
+
+#ifdef BLUETOOTH_PROFILE_SET
+            const char *profile = NULL;
+
+            if ((d->transports[PROFILE_A2DP] && d->transports[PROFILE_A2DP]->state != PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED)) {
+                profile = "a2dp";
+            } if ((d->transports[PROFILE_A2DP_SOURCE] && d->transports[PROFILE_A2DP_SOURCE]->state != PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED)) {
+                profile = "a2dp_source";
+            } else if ((d->transports[PROFILE_HFGW] && d->transports[PROFILE_HFGW]->state != PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED)) {
+                profile = "hfgw";
+            }
+            if (!profile)
+                return PA_HOOK_OK;
+#endif
+
+            /* Oh, awesome, a new device has shown up and been connected! */
+
+#ifdef BLUETOOTH_PROFILE_SET
+            args = pa_sprintf_malloc("address=\"%s\" path=\"%s\" profile=\"%s\"", d->address, d->path, profile);
+#else
+            args = pa_sprintf_malloc("address=\"%s\" path=\"%s\"", d->address, d->path);
+#endif
+
+            if (pa_modargs_get_value(u->modargs, "sco_sink", NULL) &&
+                pa_modargs_get_value(u->modargs, "sco_source", NULL)) {
+                char *tmp;
+
+                tmp = pa_sprintf_malloc("%s sco_sink=\"%s\" sco_source=\"%s\"", args,
+                                        pa_modargs_get_value(u->modargs, "sco_sink", NULL),
+                                        pa_modargs_get_value(u->modargs, "sco_source", NULL));
+                pa_xfree(args);
+                args = tmp;
+            }
+
+            pa_log_debug("Loading module-bluez4-device %s", args);
+            m = pa_module_load(u->module->core, "module-bluez4-device", args);
+            pa_xfree(args);
+
+            if (m) {
+                mi = pa_xnew(struct module_info, 1);
+                mi->module = m->index;
+                mi->path = pa_xstrdup(d->path);
+
+                pa_hashmap_put(u->hashmap, mi->path, mi);
+            } else
+                pa_log_debug("Failed to load module for device %s", d->path);
+        }
+
+    } else {
+
+        if (mi) {
+
+            /* Hmm, disconnection? Then the module unloads itself */
+
+            pa_log_debug("Unregistering module for %s", d->path);
+            pa_hashmap_remove(u->hashmap, mi->path);
+            pa_xfree(mi->path);
+            pa_xfree(mi);
+        }
+    }
+
+    return PA_HOOK_OK;
+}
+
+int pa__init(pa_module* m) {
+    struct userdata *u;
+    pa_modargs *ma = NULL;
+
+    pa_assert(m);
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments");
+        goto fail;
+    }
+
+    if (pa_modargs_get_value(ma, "async", NULL))
+        pa_log_warn("The 'async' argument is deprecated and does nothing.");
+
+    m->userdata = u = pa_xnew0(struct userdata, 1);
+    u->module = m;
+    u->core = m->core;
+    u->modargs = ma;
+    ma = NULL;
+    u->hashmap = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+
+    if (!(u->discovery = pa_bluez4_discovery_get(u->core)))
+        goto fail;
+
+    u->slot = pa_hook_connect(pa_bluez4_discovery_hook(u->discovery, PA_BLUEZ4_HOOK_DEVICE_CONNECTION_CHANGED),
+                              PA_HOOK_NORMAL, (pa_hook_cb_t) load_module_for_device, u);
+
+    return 0;
+
+fail:
+    pa__done(m);
+
+    if (ma)
+        pa_modargs_free(ma);
+
+    return -1;
+}
+
+void pa__done(pa_module* m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    if (u->slot)
+        pa_hook_slot_free(u->slot);
+
+    if (u->discovery)
+        pa_bluez4_discovery_unref(u->discovery);
+
+    if (u->hashmap) {
+        struct module_info *mi;
+
+        while ((mi = pa_hashmap_steal_first(u->hashmap))) {
+            pa_xfree(mi->path);
+            pa_xfree(mi);
+        }
+#ifdef __TIZEN_BT__
+        pa_hashmap_free(u->hashmap,NULL);
+#else
+        pa_hashmap_free(u->hashmap);
+#endif
+    }
+
+    if (u->modargs)
+        pa_modargs_free(u->modargs);
+
+    pa_xfree(u);
+}
diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c
new file mode 100644 (file)
index 0000000..14ab0ed
--- /dev/null
@@ -0,0 +1,2549 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2008-2013 João Paulo Rechi Vita
+  Copyright 2011-2013 BMW Car IT GmbH.
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+
+#include <arpa/inet.h>
+#include <sbc/sbc.h>
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+#include <dlfcn.h>
+#endif
+
+#include <pulse/rtclock.h>
+#include <pulse/timeval.h>
+
+#include <pulsecore/core-error.h>
+#include <pulsecore/core-rtclock.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/i18n.h>
+#include <pulsecore/module.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/poll.h>
+#include <pulsecore/rtpoll.h>
+#include <pulsecore/shared.h>
+#include <pulsecore/socket-util.h>
+#include <pulsecore/thread.h>
+#include <pulsecore/thread-mq.h>
+#include <pulsecore/time-smoother.h>
+
+#include "a2dp-codecs.h"
+#include "bluez5-util.h"
+#include "rtp.h"
+
+#include "module-bluez5-device-symdef.h"
+
+PA_MODULE_AUTHOR("João Paulo Rechi Vita");
+PA_MODULE_DESCRIPTION("BlueZ 5 Bluetooth audio sink and source");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(false);
+PA_MODULE_USAGE("path=<device object path>");
+
+#define MAX_PLAYBACK_CATCH_UP_USEC (100 * PA_USEC_PER_MSEC)
+#define FIXED_LATENCY_PLAYBACK_A2DP (25 * PA_USEC_PER_MSEC)
+#define FIXED_LATENCY_PLAYBACK_SCO (125 * PA_USEC_PER_MSEC)
+#define FIXED_LATENCY_RECORD_A2DP   (25 * PA_USEC_PER_MSEC)
+#define FIXED_LATENCY_RECORD_SCO    (25 * PA_USEC_PER_MSEC)
+
+#define BITPOOL_DEC_LIMIT 32
+#define BITPOOL_DEC_STEP 5
+
+static const char* const valid_modargs[] = {
+    "path",
+#ifdef __TIZEN_BT__
+    "address",
+    "profile",
+#endif
+    NULL
+};
+
+enum {
+    BLUETOOTH_MESSAGE_IO_THREAD_FAILED,
+    BLUETOOTH_MESSAGE_TRANSPORT_STATE_CHANGED,
+    BLUETOOTH_MESSAGE_MAX
+};
+
+typedef struct bluetooth_msg {
+    pa_msgobject parent;
+    pa_card *card;
+} bluetooth_msg;
+PA_DEFINE_PRIVATE_CLASS(bluetooth_msg, pa_msgobject);
+#define BLUETOOTH_MSG(o) (bluetooth_msg_cast(o))
+
+typedef struct sbc_info {
+    sbc_t sbc;                           /* Codec data */
+    bool sbc_initialized;                /* Keep track if the encoder is initialized */
+    size_t codesize, frame_length;       /* SBC Codesize, frame_length. We simply cache those values here */
+    uint16_t seq_num;                    /* Cumulative packet sequence */
+    uint8_t min_bitpool;
+    uint8_t max_bitpool;
+#ifdef BLUETOOTH_APTX_SUPPORT
+    pa_bool_t aptx_initialized;          /* Keep track if the encoder is initialized */
+    void *aptx;                          /* aptx Codec data */
+#endif
+    void* buffer;                        /* Codec transfer buffer */
+    size_t buffer_size;                  /* Size of the buffer */
+} sbc_info_t;
+
+struct userdata {
+    pa_module *module;
+    pa_core *core;
+
+    pa_hook_slot *device_connection_changed_slot;
+    pa_hook_slot *transport_state_changed_slot;
+#ifdef __TIZEN_BT__
+    pa_hook_slot *sco_state_changed_slot;
+#endif
+
+    pa_bluetooth_discovery *discovery;
+    pa_bluetooth_device *device;
+    pa_bluetooth_transport *transport;
+    bool transport_acquired;
+
+#ifdef __TIZEN_BT__
+    bool transport_suspended_by_remote;
+#endif
+
+    pa_card *card;
+    pa_sink *sink;
+    pa_source *source;
+    pa_bluetooth_profile_t profile;
+    char *output_port_name;
+    char *input_port_name;
+
+    pa_thread *thread;
+    pa_thread_mq thread_mq;
+    pa_rtpoll *rtpoll;
+    pa_rtpoll_item *rtpoll_item;
+    bluetooth_msg *msg;
+
+    int stream_fd;
+    int stream_write_type;
+    size_t read_link_mtu;
+    size_t write_link_mtu;
+    size_t read_block_size;
+    size_t write_block_size;
+    uint64_t read_index;
+    uint64_t write_index;
+    pa_usec_t started_at;
+    pa_smoother *read_smoother;
+    pa_memchunk write_memchunk;
+    pa_sample_spec sample_spec;
+    struct sbc_info sbc_info;
+
+#ifdef __TIZEN_BT__
+    pa_modargs *modargs;
+#endif
+};
+
+typedef enum pa_bluetooth_form_factor {
+    PA_BLUETOOTH_FORM_FACTOR_UNKNOWN,
+    PA_BLUETOOTH_FORM_FACTOR_HEADSET,
+    PA_BLUETOOTH_FORM_FACTOR_HANDSFREE,
+    PA_BLUETOOTH_FORM_FACTOR_MICROPHONE,
+    PA_BLUETOOTH_FORM_FACTOR_SPEAKER,
+    PA_BLUETOOTH_FORM_FACTOR_HEADPHONE,
+    PA_BLUETOOTH_FORM_FACTOR_PORTABLE,
+    PA_BLUETOOTH_FORM_FACTOR_CAR,
+    PA_BLUETOOTH_FORM_FACTOR_HIFI,
+    PA_BLUETOOTH_FORM_FACTOR_PHONE,
+} pa_bluetooth_form_factor_t;
+
+/* Run from main thread */
+static pa_bluetooth_form_factor_t form_factor_from_class(uint32_t class_of_device) {
+    unsigned major, minor;
+    pa_bluetooth_form_factor_t r;
+
+    static const pa_bluetooth_form_factor_t table[] = {
+        [1] = PA_BLUETOOTH_FORM_FACTOR_HEADSET,
+        [2] = PA_BLUETOOTH_FORM_FACTOR_HANDSFREE,
+        [4] = PA_BLUETOOTH_FORM_FACTOR_MICROPHONE,
+        [5] = PA_BLUETOOTH_FORM_FACTOR_SPEAKER,
+        [6] = PA_BLUETOOTH_FORM_FACTOR_HEADPHONE,
+        [7] = PA_BLUETOOTH_FORM_FACTOR_PORTABLE,
+        [8] = PA_BLUETOOTH_FORM_FACTOR_CAR,
+        [10] = PA_BLUETOOTH_FORM_FACTOR_HIFI
+    };
+
+    /*
+     * See Bluetooth Assigned Numbers:
+     * https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
+     */
+    major = (class_of_device >> 8) & 0x1F;
+    minor = (class_of_device >> 2) & 0x3F;
+
+    switch (major) {
+        case 2:
+            return PA_BLUETOOTH_FORM_FACTOR_PHONE;
+        case 4:
+            break;
+        default:
+            pa_log_debug("Unknown Bluetooth major device class %u", major);
+            return PA_BLUETOOTH_FORM_FACTOR_UNKNOWN;
+    }
+
+    r = minor < PA_ELEMENTSOF(table) ? table[minor] : PA_BLUETOOTH_FORM_FACTOR_UNKNOWN;
+
+    if (!r)
+        pa_log_debug("Unknown Bluetooth minor device class %u", minor);
+
+    return r;
+}
+
+/* Run from main thread */
+static const char *form_factor_to_string(pa_bluetooth_form_factor_t ff) {
+    switch (ff) {
+        case PA_BLUETOOTH_FORM_FACTOR_UNKNOWN:
+            return "unknown";
+        case PA_BLUETOOTH_FORM_FACTOR_HEADSET:
+            return "headset";
+        case PA_BLUETOOTH_FORM_FACTOR_HANDSFREE:
+            return "hands-free";
+        case PA_BLUETOOTH_FORM_FACTOR_MICROPHONE:
+            return "microphone";
+        case PA_BLUETOOTH_FORM_FACTOR_SPEAKER:
+            return "speaker";
+        case PA_BLUETOOTH_FORM_FACTOR_HEADPHONE:
+            return "headphone";
+        case PA_BLUETOOTH_FORM_FACTOR_PORTABLE:
+            return "portable";
+        case PA_BLUETOOTH_FORM_FACTOR_CAR:
+            return "car";
+        case PA_BLUETOOTH_FORM_FACTOR_HIFI:
+            return "hifi";
+        case PA_BLUETOOTH_FORM_FACTOR_PHONE:
+            return "phone";
+    }
+
+    pa_assert_not_reached();
+}
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+void* (*aptx_new)(short endian);
+int (*aptx_encode)(void* _state, void* _pcmL, void* _pcmR, void* _buffer);
+
+const char *aptx_new_name = "NewAptxEnc";
+const char *aptx_encode_name = "aptxbtenc_encodestereo";
+
+static pa_bool_t pa_load_aptx_sym(void *handle )
+{
+       if (!handle)
+               return FALSE;
+
+       aptx_new = (void* (*)(short endian))dlsym(handle, aptx_new_name);
+
+       if (aptx_new) {
+           pa_log_debug("Load Symbol(%s)", aptx_new_name);
+        } else {
+           pa_log_debug("Fail to Load Symbol(%s)", aptx_new_name);
+           return FALSE;
+       }
+
+       aptx_encode = (int (*)(void* _state, void* _pcmL, void* _pcmR,
+                                void* _buffer))
+                      dlsym(handle, "aptxbtenc_encodestereo");
+
+       if (aptx_encode) {
+           pa_log_debug("Load Symbol(%s)", aptx_encode_name);
+        } else {
+           pa_log_debug("Fail to Load Symbol(%s)", aptx_encode_name);
+           return FALSE;
+        }
+
+       return TRUE;
+}
+#endif
+
+/* Run from main thread */
+static void connect_ports(struct userdata *u, void *new_data, pa_direction_t direction) {
+    pa_device_port *port;
+
+    if (direction == PA_DIRECTION_OUTPUT) {
+        pa_sink_new_data *sink_new_data = new_data;
+
+        pa_assert_se(port = pa_hashmap_get(u->card->ports, u->output_port_name));
+        pa_assert_se(pa_hashmap_put(sink_new_data->ports, port->name, port) >= 0);
+        pa_device_port_ref(port);
+    } else {
+        pa_source_new_data *source_new_data = new_data;
+
+        pa_assert_se(port = pa_hashmap_get(u->card->ports, u->input_port_name));
+        pa_assert_se(pa_hashmap_put(source_new_data->ports, port->name, port) >= 0);
+        pa_device_port_ref(port);
+    }
+}
+
+/* Run from IO thread */
+static int sco_process_render(struct userdata *u) {
+    int ret = 0;
+
+    pa_assert(u);
+    pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY);
+    pa_assert(u->sink);
+
+    /* First, render some data */
+    if (!u->write_memchunk.memblock)
+        pa_sink_render_full(u->sink, u->write_block_size, &u->write_memchunk);
+
+    pa_assert(u->write_memchunk.length == u->write_block_size);
+
+    for (;;) {
+        ssize_t l;
+        const void *p;
+
+        /* Now write that data to the socket. The socket is of type
+         * SEQPACKET, and we generated the data of the MTU size, so this
+         * should just work. */
+
+        p = (const uint8_t *) pa_memblock_acquire_chunk(&u->write_memchunk);
+        l = pa_write(u->stream_fd, p, u->write_memchunk.length, &u->stream_write_type);
+        pa_memblock_release(u->write_memchunk.memblock);
+
+        pa_assert(l != 0);
+
+        if (l < 0) {
+
+            if (errno == EINTR)
+                /* Retry right away if we got interrupted */
+                continue;
+
+            else if (errno == EAGAIN)
+                /* Hmm, apparently the socket was not writable, give up for now */
+                break;
+
+            pa_log_error("Failed to write data to SCO socket: %s", pa_cstrerror(errno));
+            ret = -1;
+            break;
+        }
+
+        pa_assert((size_t) l <= u->write_memchunk.length);
+
+        if ((size_t) l != u->write_memchunk.length) {
+            pa_log_error("Wrote memory block to socket only partially! %llu written, wanted to write %llu.",
+                        (unsigned long long) l,
+                        (unsigned long long) u->write_memchunk.length);
+            ret = -1;
+            break;
+        }
+
+        u->write_index += (uint64_t) u->write_memchunk.length;
+        pa_memblock_unref(u->write_memchunk.memblock);
+        pa_memchunk_reset(&u->write_memchunk);
+
+        ret = 1;
+        break;
+    }
+
+    return ret;
+}
+
+/* Run from IO thread */
+static int sco_process_push(struct userdata *u) {
+    int ret = 0;
+    pa_memchunk memchunk;
+
+    pa_assert(u);
+    pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY);
+    pa_assert(u->source);
+    pa_assert(u->read_smoother);
+
+    memchunk.memblock = pa_memblock_new(u->core->mempool, u->read_block_size);
+    memchunk.index = memchunk.length = 0;
+
+    for (;;) {
+        ssize_t l;
+        void *p;
+        struct msghdr m;
+        struct cmsghdr *cm;
+        uint8_t aux[1024];
+        struct iovec iov;
+        bool found_tstamp = false;
+        pa_usec_t tstamp;
+
+        memset(&m, 0, sizeof(m));
+        memset(&aux, 0, sizeof(aux));
+        memset(&iov, 0, sizeof(iov));
+
+        m.msg_iov = &iov;
+        m.msg_iovlen = 1;
+        m.msg_control = aux;
+        m.msg_controllen = sizeof(aux);
+
+        p = pa_memblock_acquire(memchunk.memblock);
+        iov.iov_base = p;
+        iov.iov_len = pa_memblock_get_length(memchunk.memblock);
+        l = recvmsg(u->stream_fd, &m, 0);
+        pa_memblock_release(memchunk.memblock);
+
+        if (l <= 0) {
+
+            if (l < 0 && errno == EINTR)
+                /* Retry right away if we got interrupted */
+                continue;
+
+            else if (l < 0 && errno == EAGAIN)
+                /* Hmm, apparently the socket was not readable, give up for now. */
+                break;
+
+            pa_log_error("Failed to read data from SCO socket: %s", l < 0 ? pa_cstrerror(errno) : "EOF");
+            ret = -1;
+            break;
+        }
+
+        pa_assert((size_t) l <= pa_memblock_get_length(memchunk.memblock));
+
+        /* In some rare occasions, we might receive packets of a very strange
+         * size. This could potentially be possible if the SCO packet was
+         * received partially over-the-air, or more probably due to hardware
+         * issues in our Bluetooth adapter. In these cases, in order to avoid
+         * an assertion failure due to unaligned data, just discard the whole
+         * packet */
+        if (!pa_frame_aligned(l, &u->sample_spec)) {
+            pa_log_warn("SCO packet received of unaligned size: %zu", l);
+            break;
+        }
+
+        memchunk.length = (size_t) l;
+        u->read_index += (uint64_t) l;
+
+        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!");
+            tstamp = pa_rtclock_now();
+        }
+
+        pa_smoother_put(u->read_smoother, tstamp, pa_bytes_to_usec(u->read_index, &u->sample_spec));
+        pa_smoother_resume(u->read_smoother, tstamp, true);
+
+        pa_source_post(u->source, &memchunk);
+
+        ret = l;
+        break;
+    }
+
+    pa_memblock_unref(memchunk.memblock);
+
+    return ret;
+}
+
+/* Run from IO thread */
+static void a2dp_prepare_buffer(struct userdata *u) {
+    size_t min_buffer_size = PA_MAX(u->read_link_mtu, u->write_link_mtu);
+
+    pa_assert(u);
+
+    if (u->sbc_info.buffer_size >= min_buffer_size)
+        return;
+
+    u->sbc_info.buffer_size = 2 * min_buffer_size;
+    pa_xfree(u->sbc_info.buffer);
+    u->sbc_info.buffer = pa_xmalloc(u->sbc_info.buffer_size);
+}
+
+/* Run from IO thread */
+static int a2dp_process_render(struct userdata *u) {
+    struct sbc_info *sbc_info;
+    struct rtp_header *header;
+    struct rtp_payload *payload;
+    size_t nbytes;
+    void *d;
+    const void *p;
+    size_t to_write, to_encode;
+    unsigned frame_count;
+    int ret = 0;
+
+    pa_assert(u);
+    pa_assert(u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK);
+    pa_assert(u->sink);
+
+    /* First, render some data */
+    if (!u->write_memchunk.memblock)
+        pa_sink_render_full(u->sink, u->write_block_size, &u->write_memchunk);
+
+    pa_assert(u->write_memchunk.length == u->write_block_size);
+
+    a2dp_prepare_buffer(u);
+
+    sbc_info = &u->sbc_info;
+    header = sbc_info->buffer;
+    payload = (struct rtp_payload*) ((uint8_t*) sbc_info->buffer + sizeof(*header));
+
+    frame_count = 0;
+
+    /* Try to create a packet of the full MTU */
+
+    p = (const uint8_t *) pa_memblock_acquire_chunk(&u->write_memchunk);
+    to_encode = u->write_memchunk.length;
+
+    d = (uint8_t*) sbc_info->buffer + sizeof(*header) + sizeof(*payload);
+    to_write = sbc_info->buffer_size - sizeof(*header) - sizeof(*payload);
+
+    while (PA_LIKELY(to_encode > 0 && to_write > 0)) {
+        ssize_t written;
+        ssize_t encoded;
+
+        encoded = sbc_encode(&sbc_info->sbc,
+                             p, to_encode,
+                             d, to_write,
+                             &written);
+
+        if (PA_UNLIKELY(encoded <= 0)) {
+            pa_log_error("SBC encoding error (%li)", (long) encoded);
+            pa_memblock_release(u->write_memchunk.memblock);
+            return -1;
+        }
+
+        pa_assert_fp((size_t) encoded <= to_encode);
+        pa_assert_fp((size_t) encoded == sbc_info->codesize);
+
+        pa_assert_fp((size_t) written <= to_write);
+        pa_assert_fp((size_t) written == sbc_info->frame_length);
+
+        p = (const uint8_t*) p + encoded;
+        to_encode -= encoded;
+
+        d = (uint8_t*) d + written;
+        to_write -= written;
+
+        frame_count++;
+    }
+
+    pa_memblock_release(u->write_memchunk.memblock);
+
+    pa_assert(to_encode == 0);
+
+    PA_ONCE_BEGIN {
+        pa_log_debug("Using SBC encoder implementation: %s", pa_strnull(sbc_get_implementation_info(&sbc_info->sbc)));
+    } PA_ONCE_END;
+
+    /* write it to the fifo */
+    memset(sbc_info->buffer, 0, sizeof(*header) + sizeof(*payload));
+    header->v = 2;
+    header->pt = 1;
+    header->sequence_number = htons(sbc_info->seq_num++);
+    header->timestamp = htonl(u->write_index / pa_frame_size(&u->sample_spec));
+    header->ssrc = htonl(1);
+    payload->frame_count = frame_count;
+
+    nbytes = (uint8_t*) d - (uint8_t*) sbc_info->buffer;
+
+    for (;;) {
+        ssize_t l;
+
+        l = pa_write(u->stream_fd, sbc_info->buffer, nbytes, &u->stream_write_type);
+
+        pa_assert(l != 0);
+
+        if (l < 0) {
+
+            if (errno == EINTR)
+                /* Retry right away if we got interrupted */
+                continue;
+
+            else if (errno == EAGAIN)
+                /* Hmm, apparently the socket was not writable, give up for now */
+                break;
+
+            pa_log_error("Failed to write data to socket: %s", pa_cstrerror(errno));
+            ret = -1;
+            break;
+        }
+
+        pa_assert((size_t) l <= nbytes);
+
+        if ((size_t) l != nbytes) {
+            pa_log_warn("Wrote memory block to socket only partially! %llu written, wanted to write %llu.",
+                        (unsigned long long) l,
+                        (unsigned long long) nbytes);
+            ret = -1;
+            break;
+        }
+
+        u->write_index += (uint64_t) u->write_memchunk.length;
+        pa_memblock_unref(u->write_memchunk.memblock);
+        pa_memchunk_reset(&u->write_memchunk);
+
+        ret = 1;
+
+        break;
+    }
+
+    return ret;
+}
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+/* Run from IO thread */
+static int a2dp_aptx_process_render(struct userdata *u) {
+    struct sbc_info *a2dp;
+    size_t nbytes;
+    void *d;
+    const void *p;
+    size_t to_write, to_encode;
+    int ret = 0;
+
+    int pcmL[4],pcmR[4];
+    int i=0;
+    const short *mybuffer;
+
+    pa_assert(u);
+    pa_assert(u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK);
+    pa_assert(u->sink);
+
+    /* First, render some data */
+    if (!u->write_memchunk.memblock)
+        pa_sink_render_full(u->sink, u->write_block_size, &u->write_memchunk);
+
+    pa_assert(u->write_memchunk.length == u->write_block_size);
+
+    a2dp_prepare_buffer(u);
+
+    a2dp = &u->sbc_info;
+
+    /* Try to create a packet of the full MTU */
+    p = (const uint8_t*) pa_memblock_acquire(u->write_memchunk.memblock) + u->write_memchunk.index;
+    to_encode = u->write_memchunk.length;
+
+    d = (uint8_t*) a2dp->buffer ;
+    to_write = a2dp->buffer_size;
+
+    while (PA_LIKELY(to_encode > 0 && to_write > 0)) {
+        size_t written;
+        ssize_t encoded;
+
+        mybuffer=(uint8_t *)p;
+
+        for (i = 0; i < 4; i += 1) {
+           pcmL[i] = mybuffer[2*i];
+           pcmR[i] = mybuffer[2*i+1];
+        }
+       /*(8 audio samples)16 bytes of audo data encoded to 4 bytes*/
+       aptx_encode(a2dp->aptx, pcmL, pcmR, (short*)d);
+
+        encoded=16;
+        written=4;
+
+        pa_assert_fp((size_t) encoded <= to_encode);
+        pa_assert_fp((size_t) written <= to_write);
+
+        p = (const uint8_t*) p + encoded;
+        to_encode -= encoded;
+
+        d = (uint8_t*) d + written;
+        to_write -= written;
+
+    }
+
+    pa_memblock_release(u->write_memchunk.memblock);
+
+    pa_assert(to_encode == 0);
+
+    PA_ONCE_BEGIN {
+        pa_log_debug("Using APTX encoder implementation");
+    } PA_ONCE_END;
+
+    nbytes = (uint8_t*) d - (uint8_t*) a2dp->buffer;
+
+    for (;;) {
+        ssize_t l;
+
+        l = pa_write(u->stream_fd, a2dp->buffer, nbytes, &u->stream_write_type);
+
+        pa_assert(l != 0);
+
+        if (l < 0) {
+
+            if (errno == EINTR)
+                /* Retry right away if we got interrupted */
+                continue;
+
+            else if (errno == EAGAIN)
+                /* Hmm, apparently the socket was not writable, give up for now */
+                break;
+
+            pa_log_error("Failed to write data to socket: %s", pa_cstrerror(errno));
+            ret  = -1;
+            break;
+        }
+
+        pa_assert((size_t) l <= nbytes);
+
+        if ((size_t) l != nbytes) {
+            pa_log_warn("Wrote memory block to socket only partially! %llu written, wanted to write %llu.",
+                        (unsigned long long) l,
+                        (unsigned long long) nbytes);
+            ret = -1;
+            break;
+        }
+
+        u->write_index += (uint64_t) u->write_memchunk.length;
+        pa_memblock_unref(u->write_memchunk.memblock);
+        pa_memchunk_reset(&u->write_memchunk);
+
+        ret = 1;
+
+        break;
+    }
+
+    return ret;
+}
+
+/* Run from IO thread */
+static int a2dp_process_null_render(struct userdata *u) {
+    pa_assert(u);
+    pa_assert(u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK);
+    pa_assert(u->sink);
+
+    /* First, render some data */
+    if (!u->write_memchunk.memblock)
+        pa_sink_render_full(u->sink, u->write_block_size, &u->write_memchunk);
+
+    pa_assert(u->write_memchunk.length == u->write_block_size);
+
+    u->write_index += (uint64_t) u->write_memchunk.length;
+    pa_memblock_unref(u->write_memchunk.memblock);
+    pa_memchunk_reset(&u->write_memchunk);
+
+    return 1;
+}
+#endif
+
+/* Run from IO thread */
+static int a2dp_process_push(struct userdata *u) {
+    int ret = 0;
+    pa_memchunk memchunk;
+
+    pa_assert(u);
+    pa_assert(u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE);
+    pa_assert(u->source);
+    pa_assert(u->read_smoother);
+
+    memchunk.memblock = pa_memblock_new(u->core->mempool, u->read_block_size);
+    memchunk.index = memchunk.length = 0;
+
+    for (;;) {
+        bool found_tstamp = false;
+        pa_usec_t tstamp;
+        struct sbc_info *sbc_info;
+        struct rtp_header *header;
+        struct rtp_payload *payload;
+        const void *p;
+        void *d;
+        ssize_t l;
+        size_t to_write, to_decode;
+
+        a2dp_prepare_buffer(u);
+
+        sbc_info = &u->sbc_info;
+        header = sbc_info->buffer;
+        payload = (struct rtp_payload*) ((uint8_t*) sbc_info->buffer + sizeof(*header));
+
+        l = pa_read(u->stream_fd, sbc_info->buffer, sbc_info->buffer_size, &u->stream_write_type);
+
+        if (l <= 0) {
+
+            if (l < 0 && errno == EINTR)
+                /* Retry right away if we got interrupted */
+                continue;
+
+            else if (l < 0 && errno == EAGAIN)
+                /* Hmm, apparently the socket was not readable, give up for now. */
+                break;
+
+            pa_log_error("Failed to read data from socket: %s", l < 0 ? pa_cstrerror(errno) : "EOF");
+            ret = -1;
+            break;
+        }
+
+        pa_assert((size_t) l <= sbc_info->buffer_size);
+
+        u->read_index += (uint64_t) l;
+
+        /* TODO: get timestamp from rtp */
+        if (!found_tstamp) {
+            /* pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() data!"); */
+            tstamp = pa_rtclock_now();
+        }
+
+        pa_smoother_put(u->read_smoother, tstamp, pa_bytes_to_usec(u->read_index, &u->sample_spec));
+        pa_smoother_resume(u->read_smoother, tstamp, true);
+
+        p = (uint8_t*) sbc_info->buffer + sizeof(*header) + sizeof(*payload);
+        to_decode = l - sizeof(*header) - sizeof(*payload);
+
+        d = pa_memblock_acquire(memchunk.memblock);
+        to_write = memchunk.length = pa_memblock_get_length(memchunk.memblock);
+
+        while (PA_LIKELY(to_decode > 0)) {
+            size_t written;
+            ssize_t decoded;
+
+            decoded = sbc_decode(&sbc_info->sbc,
+                                 p, to_decode,
+                                 d, to_write,
+                                 &written);
+
+            if (PA_UNLIKELY(decoded <= 0)) {
+                pa_log_error("SBC decoding error (%li)", (long) decoded);
+                pa_memblock_release(memchunk.memblock);
+                pa_memblock_unref(memchunk.memblock);
+                return -1;
+            }
+
+            /* Reset frame length, it can be changed due to bitpool change */
+            sbc_info->frame_length = sbc_get_frame_length(&sbc_info->sbc);
+
+            pa_assert_fp((size_t) decoded <= to_decode);
+            pa_assert_fp((size_t) decoded == sbc_info->frame_length);
+
+            pa_assert_fp((size_t) written == sbc_info->codesize);
+
+            p = (const uint8_t*) p + decoded;
+            to_decode -= decoded;
+
+            d = (uint8_t*) d + written;
+            to_write -= written;
+        }
+
+        memchunk.length -= to_write;
+
+        pa_memblock_release(memchunk.memblock);
+
+        pa_source_post(u->source, &memchunk);
+
+        ret = l;
+        break;
+    }
+
+    pa_memblock_unref(memchunk.memblock);
+
+    return ret;
+}
+
+/* Run from I/O thread */
+static void a2dp_set_bitpool(struct userdata *u, uint8_t bitpool) {
+    struct sbc_info *sbc_info;
+
+    pa_assert(u);
+
+    sbc_info = &u->sbc_info;
+
+    if (sbc_info->sbc.bitpool == bitpool)
+        return;
+
+    if (bitpool > sbc_info->max_bitpool)
+        bitpool = sbc_info->max_bitpool;
+    else if (bitpool < sbc_info->min_bitpool)
+        bitpool = sbc_info->min_bitpool;
+
+    sbc_info->sbc.bitpool = bitpool;
+
+    sbc_info->codesize = sbc_get_codesize(&sbc_info->sbc);
+    sbc_info->frame_length = sbc_get_frame_length(&sbc_info->sbc);
+
+    pa_log_debug("Bitpool has changed to %u", sbc_info->sbc.bitpool);
+
+    u->read_block_size =
+        (u->read_link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
+        / sbc_info->frame_length * sbc_info->codesize;
+
+    u->write_block_size =
+        (u->write_link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
+        / sbc_info->frame_length * sbc_info->codesize;
+
+    pa_sink_set_max_request_within_thread(u->sink, u->write_block_size);
+    pa_sink_set_fixed_latency_within_thread(u->sink,
+            FIXED_LATENCY_PLAYBACK_A2DP + pa_bytes_to_usec(u->write_block_size, &u->sample_spec));
+}
+
+/* Run from I/O thread */
+static void a2dp_reduce_bitpool(struct userdata *u) {
+    struct sbc_info *sbc_info;
+    uint8_t bitpool;
+
+    pa_assert(u);
+
+    sbc_info = &u->sbc_info;
+
+    /* Check if bitpool is already at its limit */
+    if (sbc_info->sbc.bitpool <= BITPOOL_DEC_LIMIT)
+        return;
+
+    bitpool = sbc_info->sbc.bitpool - BITPOOL_DEC_STEP;
+
+    if (bitpool < BITPOOL_DEC_LIMIT)
+        bitpool = BITPOOL_DEC_LIMIT;
+
+    a2dp_set_bitpool(u, bitpool);
+}
+
+static void teardown_stream(struct userdata *u) {
+    if (u->rtpoll_item) {
+        pa_rtpoll_item_free(u->rtpoll_item);
+        u->rtpoll_item = NULL;
+    }
+
+    if (u->stream_fd >= 0) {
+        pa_close(u->stream_fd);
+        u->stream_fd = -1;
+    }
+
+    if (u->read_smoother) {
+        pa_smoother_free(u->read_smoother);
+        u->read_smoother = NULL;
+    }
+
+    if (u->write_memchunk.memblock) {
+        pa_memblock_unref(u->write_memchunk.memblock);
+        pa_memchunk_reset(&u->write_memchunk);
+    }
+
+    pa_log_debug("Audio stream torn down");
+}
+
+static int transport_acquire(struct userdata *u, bool optional) {
+    pa_assert(u->transport);
+
+    if (u->transport_acquired)
+        return 0;
+
+    pa_log_debug("Acquiring transport %s", u->transport->path);
+
+    u->stream_fd = u->transport->acquire(u->transport, optional, &u->read_link_mtu, &u->write_link_mtu);
+    if (u->stream_fd < 0)
+        return -1;
+
+    u->transport_acquired = true;
+
+#ifdef __TIZEN_BT__
+    u->transport_suspended_by_remote = false;
+#endif
+    pa_log_info("Transport %s acquired: fd %d", u->transport->path, u->stream_fd);
+
+    return 0;
+}
+
+static void transport_release(struct userdata *u) {
+    pa_assert(u->transport);
+
+    /* Ignore if already released */
+    if (!u->transport_acquired)
+        return;
+
+    pa_log_debug("Releasing transport %s", u->transport->path);
+
+    u->transport->release(u->transport);
+
+    u->transport_acquired = false;
+
+#ifdef __TIZEN_BT__
+    /* The below code would be less effect for most of case */
+    if (u->transport_suspended_by_remote)
+        pa_log_info("Released by remote suspend request");
+#endif
+
+    if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY) {
+        u->transport->state = PA_BLUETOOTH_TRANSPORT_STATE_IDLE;
+        pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(u->msg), BLUETOOTH_MESSAGE_TRANSPORT_STATE_CHANGED, u, 0,
+                              NULL, NULL);
+    }
+
+    teardown_stream(u);
+}
+
+/* Run from I/O thread */
+static void transport_config_mtu(struct userdata *u) {
+    if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY) {
+        u->read_block_size = u->read_link_mtu;
+        u->write_block_size = u->write_link_mtu;
+#ifdef __TIZEN_BT__
+    } else if(u->sbc_info.sbc_initialized) {
+#else
+    } else {
+#endif
+        u->read_block_size =
+            (u->read_link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
+            / u->sbc_info.frame_length * u->sbc_info.codesize;
+
+        u->write_block_size =
+            (u->write_link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
+            / u->sbc_info.frame_length * u->sbc_info.codesize;
+    }
+
+    if (u->sink) {
+        pa_sink_set_max_request_within_thread(u->sink, u->write_block_size);
+        pa_sink_set_fixed_latency_within_thread(u->sink,
+                                                (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK ?
+                                                 FIXED_LATENCY_PLAYBACK_A2DP : FIXED_LATENCY_PLAYBACK_SCO) +
+                                                pa_bytes_to_usec(u->write_block_size, &u->sample_spec));
+    }
+
+    if (u->source)
+        pa_source_set_fixed_latency_within_thread(u->source,
+                                                  (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE ?
+                                                   FIXED_LATENCY_RECORD_A2DP : FIXED_LATENCY_RECORD_SCO) +
+                                                  pa_bytes_to_usec(u->read_block_size, &u->sample_spec));
+}
+
+/* Run from I/O thread */
+static void setup_stream(struct userdata *u) {
+    struct pollfd *pollfd;
+    int one;
+
+    pa_log_info("Transport %s resuming", u->transport->path);
+
+    transport_config_mtu(u);
+
+    pa_make_fd_nonblock(u->stream_fd);
+    pa_make_socket_low_delay(u->stream_fd);
+
+    one = 1;
+    if (setsockopt(u->stream_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one)) < 0)
+        pa_log_warn("Failed to enable SO_TIMESTAMP: %s", pa_cstrerror(errno));
+
+    pa_log_debug("Stream properly set up, we're ready to roll!");
+
+    if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK)
+        a2dp_set_bitpool(u, u->sbc_info.max_bitpool);
+
+    u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1);
+    pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
+    pollfd->fd = u->stream_fd;
+    pollfd->events = pollfd->revents = 0;
+
+    u->read_index = u->write_index = 0;
+    u->started_at = 0;
+
+    if (u->source)
+        u->read_smoother = pa_smoother_new(PA_USEC_PER_SEC, 2*PA_USEC_PER_SEC, true, true, 10, pa_rtclock_now(), true);
+}
+
+/* Run from IO thread */
+static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
+    struct userdata *u = PA_SOURCE(o)->userdata;
+    bool failed = false;
+    int r;
+
+    pa_assert(u->source == PA_SOURCE(o));
+    pa_assert(u->transport);
+
+    switch (code) {
+
+        case PA_SOURCE_MESSAGE_SET_STATE:
+
+            switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) {
+
+                case PA_SOURCE_SUSPENDED:
+                    /* Ignore if transition is PA_SOURCE_INIT->PA_SOURCE_SUSPENDED */
+                    if (!PA_SOURCE_IS_OPENED(u->source->thread_info.state))
+                        break;
+
+                    /* Stop the device if the sink is suspended as well */
+                    if (!u->sink || u->sink->state == PA_SINK_SUSPENDED)
+                        transport_release(u);
+
+                    if (u->read_smoother)
+                        pa_smoother_pause(u->read_smoother, pa_rtclock_now());
+
+                    break;
+
+                case PA_SOURCE_IDLE:
+                case PA_SOURCE_RUNNING:
+                    if (u->source->thread_info.state != PA_SOURCE_SUSPENDED)
+                        break;
+
+                    /* Resume the device if the sink was suspended as well */
+                    if (!u->sink || !PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
+                        if (transport_acquire(u, false) < 0)
+                            failed = true;
+                        else
+                            setup_stream(u);
+                    }
+
+                    /* We don't resume the smoother here. Instead we
+                     * wait until the first packet arrives */
+
+                    break;
+
+                case PA_SOURCE_UNLINKED:
+                case PA_SOURCE_INIT:
+                case PA_SOURCE_INVALID_STATE:
+                    break;
+            }
+
+            break;
+
+        case PA_SOURCE_MESSAGE_GET_LATENCY: {
+            pa_usec_t wi, ri;
+
+            if (u->read_smoother) {
+                wi = pa_smoother_get(u->read_smoother, pa_rtclock_now());
+                ri = pa_bytes_to_usec(u->read_index, &u->sample_spec);
+
+                *((pa_usec_t*) data) = FIXED_LATENCY_RECORD_A2DP + wi > ri ? FIXED_LATENCY_RECORD_A2DP + wi - ri : 0;
+            } else
+                *((pa_usec_t*) data) = 0;
+
+            return 0;
+        }
+
+    }
+
+    r = pa_source_process_msg(o, code, data, offset, chunk);
+
+    return (r < 0 || !failed) ? r : -1;
+}
+
+/* Run from main thread */
+static int add_source(struct userdata *u) {
+    pa_source_new_data data;
+
+    pa_assert(u->transport);
+
+    pa_source_new_data_init(&data);
+    data.module = u->module;
+    data.card = u->card;
+    data.driver = __FILE__;
+    data.name = pa_sprintf_malloc("bluez_source.%s", u->device->address);
+    data.namereg_fail = false;
+    pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluetooth_profile_to_string(u->profile));
+    pa_source_new_data_set_sample_spec(&data, &u->sample_spec);
+    if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT)
+        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
+
+    connect_ports(u, &data, PA_DIRECTION_INPUT);
+
+    if (!u->transport_acquired)
+        switch (u->profile) {
+            case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
+            case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+                data.suspend_cause = PA_SUSPEND_USER;
+                break;
+            case PA_BLUETOOTH_PROFILE_A2DP_SINK:
+            case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+            case PA_BLUETOOTH_PROFILE_OFF:
+                pa_assert_not_reached();
+                break;
+        }
+
+    u->source = pa_source_new(u->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
+    pa_source_new_data_done(&data);
+    if (!u->source) {
+        pa_log_error("Failed to create source");
+        return -1;
+    }
+
+    u->source->userdata = u;
+    u->source->parent.process_msg = source_process_msg;
+
+    return 0;
+}
+
+/* Run from IO thread */
+static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
+    struct userdata *u = PA_SINK(o)->userdata;
+    bool failed = false;
+    int r;
+
+#ifdef __TIZEN_BT__
+    int i;
+#endif
+    pa_assert(u->sink == PA_SINK(o));
+    pa_assert(u->transport);
+
+    switch (code) {
+
+        case PA_SINK_MESSAGE_SET_STATE:
+
+            switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) {
+
+                case PA_SINK_SUSPENDED:
+                    /* Ignore if transition is PA_SINK_INIT->PA_SINK_SUSPENDED */
+                    if (!PA_SINK_IS_OPENED(u->sink->thread_info.state))
+                        break;
+
+                    /* Stop the device if the source is suspended as well */
+                    if (!u->source || u->source->state == PA_SOURCE_SUSPENDED)
+                        /* We deliberately ignore whether stopping
+                         * actually worked. Since the stream_fd is
+                         * closed it doesn't really matter */
+                        transport_release(u);
+
+                    break;
+
+                case PA_SINK_IDLE:
+                case PA_SINK_RUNNING:
+                    if (u->sink->thread_info.state != PA_SINK_SUSPENDED)
+                        break;
+#ifdef __TIZEN_BT__
+                   /* Wait until PA_BLUETOOTH_TRANSPORT_IDLE */
+                   if ((u->transport != NULL) && (u->transport->state ==
+                                               PA_BLUETOOTH_TRANSPORT_STATE_IDLE))
+                        pa_log_info("This is good time for(%d)",
+                                        (pa_sink_state_t) PA_PTR_TO_UINT(data));
+                   else
+                        pa_log_info("Wait for PA_BLUETOOTH_TRANSPORT_STATE_IDLE");
+#endif
+                    /* Resume the device if the source was suspended as well */
+                    if (!u->source || !PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
+                        if (transport_acquire(u, false) < 0)
+                            failed = true;
+                        else
+                            setup_stream(u);
+                    }
+
+                    break;
+
+                case PA_SINK_UNLINKED:
+                case PA_SINK_INIT:
+                case PA_SINK_INVALID_STATE:
+                    break;
+            }
+
+            break;
+
+        case PA_SINK_MESSAGE_GET_LATENCY: {
+            pa_usec_t wi, ri;
+
+            if (u->read_smoother) {
+                ri = pa_smoother_get(u->read_smoother, pa_rtclock_now());
+                wi = pa_bytes_to_usec(u->write_index + u->write_block_size, &u->sample_spec);
+            } else {
+                ri = pa_rtclock_now() - u->started_at;
+                wi = pa_bytes_to_usec(u->write_index, &u->sample_spec);
+            }
+
+            *((pa_usec_t*) data) = FIXED_LATENCY_PLAYBACK_A2DP + wi > ri ? FIXED_LATENCY_PLAYBACK_A2DP + wi - ri : 0;
+
+            return 0;
+        }
+    }
+
+    r = pa_sink_process_msg(o, code, data, offset, chunk);
+
+    return (r < 0 || !failed) ? r : -1;
+}
+
+/* Run from main thread */
+static int add_sink(struct userdata *u) {
+    pa_sink_new_data data;
+
+    pa_assert(u->transport);
+
+    pa_sink_new_data_init(&data);
+    data.module = u->module;
+    data.card = u->card;
+    data.driver = __FILE__;
+    data.name = pa_sprintf_malloc("bluez_sink.%s", u->device->address);
+    data.namereg_fail = false;
+    pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluetooth_profile_to_string(u->profile));
+    pa_sink_new_data_set_sample_spec(&data, &u->sample_spec);
+    if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT)
+        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
+
+    connect_ports(u, &data, PA_DIRECTION_OUTPUT);
+
+    if (!u->transport_acquired)
+        switch (u->profile) {
+            case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+                data.suspend_cause = PA_SUSPEND_USER;
+                break;
+            case PA_BLUETOOTH_PROFILE_A2DP_SINK:
+                /* Profile switch should have failed */
+            case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
+            case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+            case PA_BLUETOOTH_PROFILE_OFF:
+                pa_assert_not_reached();
+                break;
+        }
+
+    u->sink = pa_sink_new(u->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
+    pa_sink_new_data_done(&data);
+    if (!u->sink) {
+        pa_log_error("Failed to create sink");
+        return -1;
+    }
+
+    u->sink->userdata = u;
+    u->sink->parent.process_msg = sink_process_msg;
+
+    return 0;
+}
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+/* should be implemeted */
+static void bt_transport_config_a2dp_for_aptx(struct userdata *u) {
+    const pa_bluetooth_transport *t;
+    struct sbc_info *a2dp = &u->sbc_info;
+    a2dp_sbc_t *config;
+
+    t = u->transport;
+    pa_assert(t);
+
+    config = (a2dp_sbc_t *) t->config;
+
+    u->sample_spec.format = PA_SAMPLE_S16LE;
+
+    if (!a2dp->aptx_initialized) {
+       #if __BYTE_ORDER==__LITTLE_ENDIAN
+               a2dp->aptx = aptx_new(1);
+       #elif __BYTE_ORDER==__BIG_ENDIAN
+               a2dp->aptx = aptx_new(0);
+       #else
+               #error "Unknown byte order"
+       #endif
+               a2dp->aptx_initialized = TRUE;
+    }
+
+    pa_log_debug("aptx Encoder is intialized !!");
+
+    u->write_block_size =(size_t)(u->write_link_mtu/(size_t)16) *16*4 ;
+    pa_log_info("APTX parameters block_size(%d),link_mtu(%d)",u->write_block_size,u->write_link_mtu);
+
+}
+#endif
+
+/* Run from main thread */
+static void transport_config(struct userdata *u) {
+    if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY) {
+        u->sample_spec.format = PA_SAMPLE_S16LE;
+        u->sample_spec.channels = 1;
+        u->sample_spec.rate = 8000;
+    } else {
+        sbc_info_t *sbc_info = &u->sbc_info;
+        a2dp_sbc_t *config;
+#ifdef BLUETOOTH_APTX_SUPPORT
+        const pa_bluetooth_transport *t;
+        a2dp_aptx_t *aptx_config;
+#endif
+
+        pa_assert(u->transport);
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+        t = u->transport;
+        if (t->codec == A2DP_CODEC_VENDOR) {
+           aptx_config = (a2dp_aptx_t *) t->config;
+               if (aptx_config->vendor_id[0] == APTX_VENDOR_ID0 &&
+                   aptx_config->vendor_id[1] == APTX_VENDOR_ID1 &&
+                   aptx_config->vendor_id[2] == APTX_VENDOR_ID2 &&
+                   aptx_config->vendor_id[3] == APTX_VENDOR_ID3 &&
+                   aptx_config->codec_id[0] == APTX_CODEC_ID0  &&
+                   aptx_config->codec_id[1] == APTX_CODEC_ID1  ){
+                   pa_log("A2DP_CODEC_NON_A2DP and this is APTX Codec");
+
+                   bt_transport_config_a2dp_for_aptx(u);
+                   return;
+               } else {
+                   pa_log("A2DP_CODEC_NON_A2DP but this is not APTX Codec");
+                   return;
+               }
+        }
+#endif
+
+        u->sample_spec.format = PA_SAMPLE_S16LE;
+        config = (a2dp_sbc_t *) u->transport->config;
+
+        if (sbc_info->sbc_initialized)
+            sbc_reinit(&sbc_info->sbc, 0);
+        else
+            sbc_init(&sbc_info->sbc, 0);
+        sbc_info->sbc_initialized = true;
+
+        switch (config->frequency) {
+            case SBC_SAMPLING_FREQ_16000:
+                sbc_info->sbc.frequency = SBC_FREQ_16000;
+                u->sample_spec.rate = 16000U;
+                break;
+            case SBC_SAMPLING_FREQ_32000:
+                sbc_info->sbc.frequency = SBC_FREQ_32000;
+                u->sample_spec.rate = 32000U;
+                break;
+            case SBC_SAMPLING_FREQ_44100:
+                sbc_info->sbc.frequency = SBC_FREQ_44100;
+                u->sample_spec.rate = 44100U;
+                break;
+            case SBC_SAMPLING_FREQ_48000:
+                sbc_info->sbc.frequency = SBC_FREQ_48000;
+                u->sample_spec.rate = 48000U;
+                break;
+            default:
+                pa_assert_not_reached();
+        }
+
+        switch (config->channel_mode) {
+            case SBC_CHANNEL_MODE_MONO:
+                sbc_info->sbc.mode = SBC_MODE_MONO;
+                u->sample_spec.channels = 1;
+                break;
+            case SBC_CHANNEL_MODE_DUAL_CHANNEL:
+                sbc_info->sbc.mode = SBC_MODE_DUAL_CHANNEL;
+                u->sample_spec.channels = 2;
+                break;
+            case SBC_CHANNEL_MODE_STEREO:
+                sbc_info->sbc.mode = SBC_MODE_STEREO;
+                u->sample_spec.channels = 2;
+                break;
+            case SBC_CHANNEL_MODE_JOINT_STEREO:
+                sbc_info->sbc.mode = SBC_MODE_JOINT_STEREO;
+                u->sample_spec.channels = 2;
+                break;
+            default:
+                pa_assert_not_reached();
+        }
+
+        switch (config->allocation_method) {
+            case SBC_ALLOCATION_SNR:
+                sbc_info->sbc.allocation = SBC_AM_SNR;
+                break;
+            case SBC_ALLOCATION_LOUDNESS:
+                sbc_info->sbc.allocation = SBC_AM_LOUDNESS;
+                break;
+            default:
+                pa_assert_not_reached();
+        }
+
+        switch (config->subbands) {
+            case SBC_SUBBANDS_4:
+                sbc_info->sbc.subbands = SBC_SB_4;
+                break;
+            case SBC_SUBBANDS_8:
+                sbc_info->sbc.subbands = SBC_SB_8;
+                break;
+            default:
+                pa_assert_not_reached();
+        }
+
+        switch (config->block_length) {
+            case SBC_BLOCK_LENGTH_4:
+                sbc_info->sbc.blocks = SBC_BLK_4;
+                break;
+            case SBC_BLOCK_LENGTH_8:
+                sbc_info->sbc.blocks = SBC_BLK_8;
+                break;
+            case SBC_BLOCK_LENGTH_12:
+                sbc_info->sbc.blocks = SBC_BLK_12;
+                break;
+            case SBC_BLOCK_LENGTH_16:
+                sbc_info->sbc.blocks = SBC_BLK_16;
+                break;
+            default:
+                pa_assert_not_reached();
+        }
+
+        sbc_info->min_bitpool = config->min_bitpool;
+        sbc_info->max_bitpool = config->max_bitpool;
+
+        /* Set minimum bitpool for source to get the maximum possible block_size */
+        sbc_info->sbc.bitpool = u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK ? sbc_info->max_bitpool : sbc_info->min_bitpool;
+        sbc_info->codesize = sbc_get_codesize(&sbc_info->sbc);
+        sbc_info->frame_length = sbc_get_frame_length(&sbc_info->sbc);
+
+        pa_log_info("SBC parameters: allocation=%u, subbands=%u, blocks=%u, bitpool=%u",
+                    sbc_info->sbc.allocation, sbc_info->sbc.subbands, sbc_info->sbc.blocks, sbc_info->sbc.bitpool);
+    }
+}
+
+/* Run from main thread */
+static int setup_transport(struct userdata *u) {
+    pa_bluetooth_transport *t;
+
+    pa_assert(u);
+    pa_assert(!u->transport);
+    pa_assert(u->profile != PA_BLUETOOTH_PROFILE_OFF);
+
+    /* check if profile has a transport */
+    t = u->device->transports[u->profile];
+    if (!t || t->state <= PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED) {
+        pa_log_warn("Profile has no transport");
+        return -1;
+    }
+
+    u->transport = t;
+
+    if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
+        transport_acquire(u, true); /* In case of error, the sink/sources will be created suspended */
+    else if (transport_acquire(u, false) < 0)
+        return -1; /* We need to fail here until the interactions with module-suspend-on-idle and alike get improved */
+
+    transport_config(u);
+
+    return 0;
+}
+
+/* Run from main thread */
+static int init_profile(struct userdata *u) {
+    int r = 0;
+    pa_assert(u);
+    pa_assert(u->profile != PA_BLUETOOTH_PROFILE_OFF);
+
+    if (setup_transport(u) < 0)
+        return -1;
+
+    pa_assert(u->transport);
+
+    if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT ||
+        u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
+        if (add_sink(u) < 0)
+            r = -1;
+
+    if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT ||
+        u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
+        if (add_source(u) < 0)
+            r = -1;
+
+    return r;
+}
+
+/* I/O thread function */
+static void thread_func(void *userdata) {
+    struct userdata *u = userdata;
+    unsigned do_write = 0;
+    unsigned pending_read_bytes = 0;
+    bool writable = false;
+
+    pa_assert(u);
+    pa_assert(u->transport);
+
+    pa_log_debug("IO Thread starting up");
+
+    if (u->core->realtime_scheduling)
+        pa_make_realtime(u->core->realtime_priority);
+
+    pa_thread_mq_install(&u->thread_mq);
+
+    /* Setup the stream only if the transport was already acquired */
+    if (u->transport_acquired)
+        setup_stream(u);
+
+    for (;;) {
+        struct pollfd *pollfd;
+        int ret;
+        bool disable_timer = true;
+
+        pollfd = u->rtpoll_item ? pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL) : NULL;
+
+        if (u->source && PA_SOURCE_IS_LINKED(u->source->thread_info.state)) {
+
+            /* We should send two blocks to the device before we expect
+             * a response. */
+
+            if (u->write_index == 0 && u->read_index <= 0)
+                do_write = 2;
+
+            if (pollfd && (pollfd->revents & POLLIN)) {
+                int n_read;
+
+                if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
+                    n_read = sco_process_push(u);
+                else
+                    n_read = a2dp_process_push(u);
+
+                if (n_read < 0)
+                    goto io_fail;
+
+                /* We just read something, so we are supposed to write something, too */
+                pending_read_bytes += n_read;
+                do_write += pending_read_bytes / u->write_block_size;
+                pending_read_bytes = pending_read_bytes % u->write_block_size;
+            }
+        }
+
+        if (u->sink && PA_SINK_IS_LINKED(u->sink->thread_info.state)) {
+
+            if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
+                pa_sink_process_rewind(u->sink, 0);
+
+            if (pollfd) {
+                if (pollfd->revents & POLLOUT)
+                    writable = true;
+
+                if ((!u->source || !PA_SOURCE_IS_LINKED(u->source->thread_info.state)) && do_write <= 0 && writable) {
+                    pa_usec_t time_passed;
+                    pa_usec_t audio_sent;
+
+                    /* Hmm, there is no input stream we could synchronize
+                     * to. So let's do things by time */
+
+                    time_passed = pa_rtclock_now() - u->started_at;
+                    audio_sent = pa_bytes_to_usec(u->write_index, &u->sample_spec);
+
+                    if (audio_sent <= time_passed) {
+                        pa_usec_t audio_to_send = time_passed - audio_sent;
+
+                        /* Never try to catch up for more than 100ms */
+                        if (u->write_index > 0 && audio_to_send > MAX_PLAYBACK_CATCH_UP_USEC) {
+                            pa_usec_t skip_usec;
+                            uint64_t skip_bytes;
+
+                            skip_usec = audio_to_send - MAX_PLAYBACK_CATCH_UP_USEC;
+                            skip_bytes = pa_usec_to_bytes(skip_usec, &u->sample_spec);
+
+                            if (skip_bytes > 0) {
+                                pa_memchunk tmp;
+
+                                pa_log_warn("Skipping %llu us (= %llu bytes) in audio stream",
+                                            (unsigned long long) skip_usec,
+                                            (unsigned long long) skip_bytes);
+
+                                pa_sink_render_full(u->sink, skip_bytes, &tmp);
+                                pa_memblock_unref(tmp.memblock);
+                                u->write_index += skip_bytes;
+
+                                if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK)
+                                    a2dp_reduce_bitpool(u);
+                            }
+                        }
+
+                        do_write = 1;
+                        pending_read_bytes = 0;
+                    }
+                }
+
+                if (writable && do_write > 0) {
+                    int n_written;
+
+                    if (u->write_index <= 0)
+                        u->started_at = pa_rtclock_now();
+#ifdef __TIZEN_BT__
+                    if ((u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK) &&
+                                           !u->transport_suspended_by_remote) {
+                       if(u->sbc_info.sbc_initialized) {
+                           if ((n_written = a2dp_process_render(u)) < 0)
+                               goto io_fail;
+                       } else {
+                           if ((n_written = a2dp_aptx_process_render(u)) < 0)
+                               goto io_fail;
+                       }
+                    } else if ((u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK) &&
+                                           u->transport_suspended_by_remote) {
+                        a2dp_process_null_render(u);
+#else
+                    if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK ) {
+                        if ((n_written = a2dp_process_render(u)) < 0)
+                            goto io_fail;
+#endif
+                    } else {
+                        if ((n_written = sco_process_render(u)) < 0)
+                            goto io_fail;
+                    }
+
+                    if (n_written == 0)
+                        pa_log("Broken kernel: we got EAGAIN on write() after POLLOUT!");
+
+                    do_write -= n_written;
+                    writable = false;
+                }
+
+                if ((!u->source || !PA_SOURCE_IS_LINKED(u->source->thread_info.state)) && do_write <= 0) {
+                    pa_usec_t sleep_for;
+                    pa_usec_t time_passed, next_write_at;
+
+                    if (writable) {
+                        /* Hmm, there is no input stream we could synchronize
+                         * to. So let's estimate when we need to wake up the latest */
+                        time_passed = pa_rtclock_now() - u->started_at;
+                        next_write_at = pa_bytes_to_usec(u->write_index, &u->sample_spec);
+                        sleep_for = time_passed < next_write_at ? next_write_at - time_passed : 0;
+                        /* pa_log("Sleeping for %lu; time passed %lu, next write at %lu", (unsigned long) sleep_for, (unsigned long) time_passed, (unsigned long)next_write_at); */
+                    } else
+                        /* drop stream every 500 ms */
+                        sleep_for = PA_USEC_PER_MSEC * 500;
+
+                    pa_rtpoll_set_timer_relative(u->rtpoll, sleep_for);
+                    disable_timer = false;
+                }
+            }
+        }
+
+        if (disable_timer)
+            pa_rtpoll_set_timer_disabled(u->rtpoll);
+
+        /* Hmm, nothing to do. Let's sleep */
+        if (pollfd)
+            pollfd->events = (short) (((u->sink && PA_SINK_IS_LINKED(u->sink->thread_info.state) && !writable) ? POLLOUT : 0) |
+                                      (u->source && PA_SOURCE_IS_LINKED(u->source->thread_info.state) ? POLLIN : 0));
+
+        if ((ret = pa_rtpoll_run(u->rtpoll, true)) < 0) {
+            pa_log_debug("pa_rtpoll_run failed with: %d", ret);
+            goto fail;
+        }
+
+        if (ret == 0) {
+            pa_log_debug("IO thread shutdown requested, stopping cleanly");
+            transport_release(u);
+            goto finish;
+        }
+
+        pollfd = u->rtpoll_item ? pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL) : NULL;
+
+        if (pollfd && (pollfd->revents & ~(POLLOUT|POLLIN))) {
+            pa_log_info("FD error: %s%s%s%s",
+                        pollfd->revents & POLLERR ? "POLLERR " :"",
+                        pollfd->revents & POLLHUP ? "POLLHUP " :"",
+                        pollfd->revents & POLLPRI ? "POLLPRI " :"",
+                        pollfd->revents & POLLNVAL ? "POLLNVAL " :"");
+            goto io_fail;
+        }
+
+        continue;
+
+io_fail:
+        /* In case of HUP, just tear down the streams */
+        if (!pollfd || (pollfd->revents & POLLHUP) == 0)
+            goto fail;
+
+        do_write = 0;
+        pending_read_bytes = 0;
+        writable = false;
+
+        transport_release(u);
+    }
+
+fail:
+    /* If this was no regular exit from the loop we have to continue processing messages until we receive PA_MESSAGE_SHUTDOWN */
+    pa_log_debug("IO thread failed");
+    pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(u->msg), BLUETOOTH_MESSAGE_IO_THREAD_FAILED, NULL, 0, NULL, NULL);
+    pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
+
+finish:
+    pa_log_debug("IO thread shutting down");
+}
+
+/* Run from main thread */
+static int start_thread(struct userdata *u) {
+    pa_assert(u);
+    pa_assert(!u->thread);
+    pa_assert(!u->rtpoll);
+    pa_assert(!u->rtpoll_item);
+
+    u->rtpoll = pa_rtpoll_new();
+    pa_thread_mq_init(&u->thread_mq, u->core->mainloop, u->rtpoll);
+
+    if (!(u->thread = pa_thread_new("bluetooth", thread_func, u))) {
+        pa_log_error("Failed to create IO thread");
+        return -1;
+    }
+
+    if (u->sink) {
+        pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
+        pa_sink_set_rtpoll(u->sink, u->rtpoll);
+        pa_sink_put(u->sink);
+
+        if (u->sink->set_volume)
+            u->sink->set_volume(u->sink);
+    }
+
+    if (u->source) {
+        pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
+        pa_source_set_rtpoll(u->source, u->rtpoll);
+        pa_source_put(u->source);
+
+        if (u->source->set_volume)
+            u->source->set_volume(u->source);
+    }
+
+    return 0;
+}
+
+/* Run from main thread */
+static void stop_thread(struct userdata *u) {
+    pa_assert(u);
+
+    if (u->sink)
+        pa_sink_unlink(u->sink);
+
+    if (u->source)
+        pa_source_unlink(u->source);
+
+    if (u->thread) {
+        pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
+        pa_thread_free(u->thread);
+        u->thread = NULL;
+    }
+
+    if (u->rtpoll_item) {
+        pa_rtpoll_item_free(u->rtpoll_item);
+        u->rtpoll_item = NULL;
+    }
+
+    if (u->rtpoll) {
+        pa_thread_mq_done(&u->thread_mq);
+        pa_rtpoll_free(u->rtpoll);
+        u->rtpoll = NULL;
+    }
+
+    if (u->transport) {
+        transport_release(u);
+        u->transport = NULL;
+    }
+
+    if (u->sink) {
+        pa_sink_unref(u->sink);
+        u->sink = NULL;
+    }
+
+    if (u->source) {
+        pa_source_unref(u->source);
+        u->source = NULL;
+    }
+
+    if (u->read_smoother) {
+        pa_smoother_free(u->read_smoother);
+        u->read_smoother = NULL;
+    }
+}
+
+/* Run from main thread */
+static char *cleanup_name(const char *name) {
+    char *t, *s, *d;
+    bool space = false;
+
+    pa_assert(name);
+
+    while ((*name >= 1 && *name <= 32) || *name >= 127)
+        name++;
+
+    t = pa_xstrdup(name);
+
+    for (s = d = t; *s; s++) {
+
+        if (*s <= 32 || *s >= 127 || *s == '_') {
+            space = true;
+            continue;
+        }
+
+        if (space) {
+            *(d++) = ' ';
+            space = false;
+        }
+
+        *(d++) = *s;
+    }
+
+    *d = 0;
+
+    return t;
+}
+
+/* Run from main thread */
+static pa_direction_t get_profile_direction(pa_bluetooth_profile_t p) {
+    static const pa_direction_t profile_direction[] = {
+        [PA_BLUETOOTH_PROFILE_A2DP_SINK] = PA_DIRECTION_OUTPUT,
+        [PA_BLUETOOTH_PROFILE_A2DP_SOURCE] = PA_DIRECTION_INPUT,
+        [PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
+        [PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
+        [PA_BLUETOOTH_PROFILE_OFF] = 0
+    };
+
+    return profile_direction[p];
+}
+
+/* Run from main thread */
+static pa_available_t get_port_availability(struct userdata *u, pa_direction_t direction) {
+    pa_available_t result = PA_AVAILABLE_NO;
+    unsigned i;
+
+    pa_assert(u);
+    pa_assert(u->device);
+
+    for (i = 0; i < PA_BLUETOOTH_PROFILE_COUNT; i++) {
+        pa_bluetooth_transport *transport;
+
+        if (!(get_profile_direction(i) & direction))
+            continue;
+
+        if (!(transport = u->device->transports[i]))
+            continue;
+
+        switch(transport->state) {
+            case PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED:
+                continue;
+
+            case PA_BLUETOOTH_TRANSPORT_STATE_IDLE:
+                if (result == PA_AVAILABLE_NO)
+                    result = PA_AVAILABLE_UNKNOWN;
+
+                break;
+
+            case PA_BLUETOOTH_TRANSPORT_STATE_PLAYING:
+                return PA_AVAILABLE_YES;
+        }
+    }
+
+    return result;
+}
+
+/* Run from main thread */
+static pa_available_t transport_state_to_availability(pa_bluetooth_transport_state_t state) {
+    switch (state) {
+        case PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED:
+            return PA_AVAILABLE_NO;
+        case PA_BLUETOOTH_TRANSPORT_STATE_PLAYING:
+            return PA_AVAILABLE_YES;
+        default:
+            return PA_AVAILABLE_UNKNOWN;
+    }
+}
+
+/* Run from main thread */
+static void create_card_ports(struct userdata *u, pa_hashmap *ports) {
+    pa_device_port *port;
+#ifndef __TIZEN_BT__
+    pa_device_port_new_data port_data;
+#endif
+    const char *name_prefix, *input_description, *output_description;
+
+    pa_assert(u);
+    pa_assert(ports);
+    pa_assert(u->device);
+
+    name_prefix = "unknown";
+    input_description = _("Bluetooth Input");
+    output_description = _("Bluetooth Output");
+
+    switch (form_factor_from_class(u->device->class_of_device)) {
+        case PA_BLUETOOTH_FORM_FACTOR_HEADSET:
+            name_prefix = "headset";
+            input_description = output_description = _("Headset");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_HANDSFREE:
+            name_prefix = "handsfree";
+            input_description = output_description = _("Handsfree");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_MICROPHONE:
+            name_prefix = "microphone";
+            input_description = _("Microphone");
+            output_description = _("Bluetooth Output");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_SPEAKER:
+            name_prefix = "speaker";
+            input_description = _("Bluetooth Input");
+            output_description = _("Speaker");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_HEADPHONE:
+            name_prefix = "headphone";
+            input_description = _("Bluetooth Input");
+            output_description = _("Headphone");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_PORTABLE:
+            name_prefix = "portable";
+            input_description = output_description = _("Portable");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_CAR:
+            name_prefix = "car";
+            input_description = output_description = _("Car");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_HIFI:
+            name_prefix = "hifi";
+            input_description = output_description = _("HiFi");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_PHONE:
+            name_prefix = "phone";
+            input_description = output_description = _("Phone");
+            break;
+
+        case PA_BLUETOOTH_FORM_FACTOR_UNKNOWN:
+            name_prefix = "unknown";
+            input_description = _("Bluetooth Input");
+            output_description = _("Bluetooth Output");
+            break;
+    }
+
+#ifdef __TIZEN_BT__
+    u->output_port_name = pa_sprintf_malloc("%s-output", name_prefix);
+    u->input_port_name = pa_sprintf_malloc("%s-input", name_prefix);
+
+    pa_assert_se(port = pa_device_port_new(u->core, u->output_port_name, output_description, 0));
+    pa_assert_se(pa_hashmap_put(ports, port->name, port) >= 0);
+    port->is_output = 1;
+    port->is_input = 0;
+    port->available = get_port_availability(u, PA_DIRECTION_OUTPUT);
+
+    pa_assert_se(port = pa_device_port_new(u->core, u->input_port_name, input_description, 0));
+    pa_assert_se(pa_hashmap_put(ports, port->name, port) >= 0);
+    port->is_output = 0;
+    port->is_input = 1;
+    port->available = get_port_availability(u, PA_DIRECTION_INPUT);
+#else
+    u->output_port_name = pa_sprintf_malloc("%s-output", name_prefix);
+    pa_device_port_new_data_init(&port_data);
+    pa_device_port_new_data_set_name(&port_data, u->output_port_name);
+    pa_device_port_new_data_set_description(&port_data, output_description);
+    pa_device_port_new_data_set_direction(&port_data, PA_DIRECTION_OUTPUT);
+    pa_device_port_new_data_set_available(&port_data, get_port_availability(u, PA_DIRECTION_OUTPUT));
+    pa_assert_se(port = pa_device_port_new(u->core, &port_data, 0));
+    pa_assert_se(pa_hashmap_put(ports, port->name, port) >= 0);
+    pa_device_port_new_data_done(&port_data);
+
+    u->input_port_name = pa_sprintf_malloc("%s-input", name_prefix);
+    pa_device_port_new_data_init(&port_data);
+    pa_device_port_new_data_set_name(&port_data, u->input_port_name);
+    pa_device_port_new_data_set_description(&port_data, input_description);
+    pa_device_port_new_data_set_direction(&port_data, PA_DIRECTION_INPUT);
+    pa_device_port_new_data_set_available(&port_data, get_port_availability(u, PA_DIRECTION_INPUT));
+    pa_assert_se(port = pa_device_port_new(u->core, &port_data, 0));
+    pa_assert_se(pa_hashmap_put(ports, port->name, port) >= 0);
+    pa_device_port_new_data_done(&port_data);
+#endif
+}
+
+/* Run from main thread */
+static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid, pa_hashmap *ports) {
+    pa_device_port *input_port, *output_port;
+    pa_card_profile *cp = NULL;
+    pa_bluetooth_profile_t *p;
+
+    pa_assert(u->input_port_name);
+    pa_assert(u->output_port_name);
+    pa_assert_se(input_port = pa_hashmap_get(ports, u->input_port_name));
+    pa_assert_se(output_port = pa_hashmap_get(ports, u->output_port_name));
+
+    if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SINK)) {
+       /* TODO: Change this profile's name to a2dp_sink, to reflect the remote
+         * device's role and be consistent with the a2dp source profile */
+        cp = pa_card_profile_new("a2dp_sink", _("High Fidelity Playback (A2DP Sink)"), sizeof(pa_bluetooth_profile_t));
+        cp->priority = 10;
+        cp->n_sinks = 1;
+        cp->n_sources = 0;
+        cp->max_sink_channels = 2;
+        cp->max_source_channels = 0;
+        pa_hashmap_put(output_port->profiles, cp->name, cp);
+
+        p = PA_CARD_PROFILE_DATA(cp);
+        *p = PA_BLUETOOTH_PROFILE_A2DP_SINK;
+#ifndef __TIZEN_BT__
+    } else if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SOURCE)) {
+        cp = pa_card_profile_new("a2dp_source", _("High Fidelity Capture (A2DP Source)"), sizeof(pa_bluetooth_profile_t));
+        cp->priority = 10;
+        cp->n_sinks = 0;
+        cp->n_sources = 1;
+        cp->max_sink_channels = 0;
+        cp->max_source_channels = 2;
+        pa_hashmap_put(input_port->profiles, cp->name, cp);
+
+        p = PA_CARD_PROFILE_DATA(cp);
+        *p = PA_BLUETOOTH_PROFILE_A2DP_SOURCE;
+    } else if (pa_streq(uuid, PA_BLUETOOTH_UUID_HSP_HS) || pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_HF)) {
+       /* TODO: Change this profile's name to headset_head_unit, to reflect the remote
+         * device's role and be consistent with the other profiles */
+        cp = pa_card_profile_new("hsp", _("Headset Head Unit (HSP/HFP)"), sizeof(enum profile));
+        cp->priority = 20;
+        cp->n_sinks = 1;
+        cp->n_sources = 1;
+        cp->max_sink_channels = 1;
+        cp->max_source_channels = 1;
+        pa_hashmap_put(input_port->profiles, cp->name, cp);
+        pa_hashmap_put(output_port->profiles, cp->name, cp);
+
+        p = PA_CARD_PROFILE_DATA(cp);
+        *p = PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT;
+    } else if (pa_streq(uuid, PA_BLUETOOTH_UUID_HSP_AG) || pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_AG)) {
+       /* TODO: Change this profile's name to headset_audio_gateway, to reflect the remote
+         * device's role and be consistent with the other profiles */
+        cp = pa_card_profile_new("hfgw", _("Headset Audio Gateway (HSP/HFP)"), sizeof(enum profile));
+        cp->priority = 20;
+        cp->n_sinks = 1;
+        cp->n_sources = 1;
+        cp->max_sink_channels = 1;
+        cp->max_source_channels = 1;
+        pa_hashmap_put(input_port->profiles, cp->name, cp);
+        pa_hashmap_put(output_port->profiles, cp->name, cp);
+
+        p = PA_CARD_PROFILE_DATA(cp);
+        *p = PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY;
+#endif
+    }
+
+    if (cp && u->device->transports[*p])
+        cp->available = transport_state_to_availability(u->device->transports[*p]->state);
+
+    return cp;
+}
+
+/* Run from main thread */
+static int set_profile_cb(pa_card *c, pa_card_profile *new_profile) {
+    struct userdata *u;
+    pa_bluetooth_profile_t *p;
+
+    pa_assert(c);
+    pa_assert(new_profile);
+    pa_assert_se(u = c->userdata);
+
+    p = PA_CARD_PROFILE_DATA(new_profile);
+
+    if (*p != PA_BLUETOOTH_PROFILE_OFF) {
+        const pa_bluetooth_device *d = u->device;
+
+        if (!d->transports[*p] || d->transports[*p]->state <= PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED) {
+            pa_log_warn("Refused to switch profile to %s: Not connected", new_profile->name);
+            return -PA_ERR_IO;
+        }
+    }
+
+    stop_thread(u);
+
+    u->profile = *p;
+
+    if (u->profile != PA_BLUETOOTH_PROFILE_OFF)
+        if (init_profile(u) < 0)
+            goto off;
+
+    if (u->sink || u->source)
+        if (start_thread(u) < 0)
+            goto off;
+
+    return 0;
+
+off:
+    stop_thread(u);
+
+    pa_assert_se(pa_card_set_profile(u->card, "off", false) >= 0);
+
+    return -PA_ERR_IO;
+}
+
+/* Run from main thread */
+static int add_card(struct userdata *u) {
+    const pa_bluetooth_device *d;
+    pa_card_new_data data;
+    char *alias;
+    pa_bluetooth_form_factor_t ff;
+    pa_card_profile *cp;
+    pa_bluetooth_profile_t *p;
+    const char *uuid;
+    void *state;
+#ifdef __TIZEN_BT__
+    const char *default_profile;
+#endif
+
+    pa_assert(u);
+    pa_assert(u->device);
+
+    d = u->device;
+
+    pa_card_new_data_init(&data);
+    data.driver = __FILE__;
+    data.module = u->module;
+
+    alias = cleanup_name(d->alias);
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, alias);
+    pa_xfree(alias);
+
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, d->address);
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, "bluez");
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "sound");
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_BUS, "bluetooth");
+
+    if ((ff = form_factor_from_class(d->class_of_device)) != PA_BLUETOOTH_FORM_FACTOR_UNKNOWN)
+        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_FORM_FACTOR, form_factor_to_string(ff));
+
+    pa_proplist_sets(data.proplist, "bluez.path", d->path);
+    pa_proplist_setf(data.proplist, "bluez.class", "0x%06x", d->class_of_device);
+    pa_proplist_sets(data.proplist, "bluez.alias", d->alias);
+    data.name = pa_sprintf_malloc("bluez_card.%s", d->address);
+    data.namereg_fail = false;
+
+    create_card_ports(u, data.ports);
+
+    PA_HASHMAP_FOREACH(uuid, d->uuids, state) {
+        cp = create_card_profile(u, uuid, data.ports);
+
+        if (!cp)
+            continue;
+
+        if (pa_hashmap_get(data.profiles, cp->name)) {
+            pa_card_profile_free(cp);
+            continue;
+        }
+
+        pa_hashmap_put(data.profiles, cp->name, cp);
+    }
+
+    pa_assert(!pa_hashmap_isempty(data.profiles));
+
+    cp = pa_card_profile_new("off", _("Off"), sizeof(pa_bluetooth_profile_t));
+    cp->available = PA_AVAILABLE_YES;
+    p = PA_CARD_PROFILE_DATA(cp);
+    *p = PA_BLUETOOTH_PROFILE_OFF;
+    pa_hashmap_put(data.profiles, cp->name, cp);
+    pa_card_new_data_set_profile(&data, "off");
+
+#ifdef __TIZEN_BT__
+    if ((default_profile = pa_modargs_get_value(u->modargs, "profile", NULL))) {
+       pa_log_debug("default_profile: %s", default_profile);
+
+        if (pa_hashmap_get(data.profiles, default_profile))
+            pa_card_new_data_set_profile(&data, default_profile);
+        else
+            pa_log_warn("Profile '%s' not valid or not supported by device.", default_profile);
+    }
+#endif
+
+    u->card = pa_card_new(u->core, &data);
+    pa_card_new_data_done(&data);
+    if (!u->card) {
+        pa_log("Failed to allocate card.");
+        return -1;
+    }
+
+    u->card->userdata = u;
+    u->card->set_profile = set_profile_cb;
+
+    p = PA_CARD_PROFILE_DATA(u->card->active_profile);
+    u->profile = *p;
+
+    return 0;
+}
+
+/* Run from main thread */
+static void handle_transport_state_change(struct userdata *u, struct pa_bluetooth_transport *t) {
+    bool acquire = false;
+    bool release = false;
+    pa_card_profile *cp;
+    pa_device_port *port;
+
+    pa_assert(u);
+    pa_assert(t);
+
+    /* Update profile availability */
+    if (!(cp = pa_hashmap_get(u->card->profiles, pa_bluetooth_profile_to_string(t->profile))))
+        return;
+    pa_card_profile_set_available(cp, transport_state_to_availability(t->state));
+
+    /* Update port availability */
+    pa_assert_se(port = pa_hashmap_get(u->card->ports, u->output_port_name));
+    pa_device_port_set_available(port, get_port_availability(u, PA_DIRECTION_OUTPUT));
+    pa_assert_se(port = pa_hashmap_get(u->card->ports, u->input_port_name));
+    pa_device_port_set_available(port, get_port_availability(u, PA_DIRECTION_INPUT));
+
+    /* Acquire or release transport as needed */
+    acquire = (t->state == PA_BLUETOOTH_TRANSPORT_STATE_PLAYING && u->profile == t->profile);
+    release = (t->state != PA_BLUETOOTH_TRANSPORT_STATE_PLAYING && u->profile == t->profile);
+
+    if (acquire && transport_acquire(u, true) >= 0) {
+        if (u->source) {
+            pa_log_debug("Resuming source %s because its transport state changed to playing", u->source->name);
+
+            /* We remove the IDLE suspend cause, because otherwise
+             * module-loopback doesn't uncork its streams. FIXME: Messing with
+             * the IDLE suspend cause here is wrong, the correct way to handle
+             * this would probably be to uncork the loopback streams not only
+             * when the other end is unsuspended, but also when the other end's
+             * suspend cause changes to IDLE only (currently there's no
+             * notification mechanism for suspend cause changes, though). */
+            pa_source_suspend(u->source, false, PA_SUSPEND_IDLE|PA_SUSPEND_USER);
+        }
+
+        if (u->sink) {
+            pa_log_debug("Resuming sink %s because its transport state changed to playing", u->sink->name);
+
+#ifdef __TIZEN_BT__
+            u->transport_suspended_by_remote = false;
+#endif
+            /* FIXME: See the previous comment. */
+            pa_sink_suspend(u->sink, false, PA_SUSPEND_IDLE|PA_SUSPEND_USER);
+        }
+    }
+
+    if (release && u->transport_acquired) {
+        /* FIXME: this release is racy, since the audio stream might have
+         * been set up again in the meantime (but not processed yet by PA).
+         * BlueZ should probably release the transport automatically, and in
+         * that case we would just mark the transport as released */
+
+        /* Remote side closed the stream so we consider it PA_SUSPEND_USER */
+        if (u->source) {
+            pa_log_debug("Suspending source %s because the remote end closed the stream", u->source->name);
+            pa_source_suspend(u->source, true, PA_SUSPEND_USER);
+        }
+
+        if (u->sink) {
+            pa_log_info("Suspending sink %s because the remote end closed the stream", u->sink->name);
+#ifdef __TIZEN_BT__
+           /* if we change PA state as Suspend, PA client application
+            * such as music app would face lock-up */
+            u->transport_suspended_by_remote = true;
+#else
+            pa_sink_suspend(u->sink, true, PA_SUSPEND_USER);
+#endif
+        }
+    }
+}
+
+/* Run from main thread */
+static pa_hook_result_t device_connection_changed_cb(pa_bluetooth_discovery *y, const pa_bluetooth_device *d, struct userdata *u) {
+    pa_assert(d);
+    pa_assert(u);
+
+    if (d != u->device || pa_bluetooth_device_any_transport_connected(d))
+        return PA_HOOK_OK;
+
+    pa_log_debug("Unloading module for device %s", d->path);
+    pa_module_unload(u->core, u->module, true);
+
+    return PA_HOOK_OK;
+}
+
+#ifdef __TIZEN_BT__
+dbus_sco_open_handler(struct userdata *u, struct pa_bluetooth_transport *t)
+{
+    if (u->sink) {
+            pa_log_info("Suspending sink %s to handle the SCO connection", u->sink->name);
+
+            pa_sink *sink_null;
+            pa_sink_input *si;
+            uint32_t idx;
+
+            if (pa_sink_check_suspend(u->sink) > 0) {
+                 sink_null = (pa_sink *)pa_namereg_get(u->core, "null", 0);
+                 PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+                     pa_sink_input_move_to(si, sink_null, FALSE);
+                 }
+            }
+            pa_sink_suspend(u->sink, true, PA_SUSPEND_SWITCH);
+        }
+}
+
+/* Run from main thread */
+static pa_hook_result_t sco_state_changed_cb(pa_bluetooth_discovery *y, pa_bluetooth_transport *t, struct userdata *u) {
+    pa_assert(t);
+    pa_assert(u);
+
+    if (t == u->transport && t->state <= PA_BLUETOOTH_TRANSPORT_STATE_IDLE)
+        return PA_HOOK_OK;
+
+    if (t->device == u->device)
+        dbus_sco_open_handler(u, t);
+
+    return PA_HOOK_OK;
+}
+#endif
+
+/* Run from main thread */
+static pa_hook_result_t transport_state_changed_cb(pa_bluetooth_discovery *y, pa_bluetooth_transport *t, struct userdata *u) {
+    pa_assert(t);
+    pa_assert(u);
+
+    if (t == u->transport && t->state <= PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED)
+        pa_assert_se(pa_card_set_profile(u->card, "off", false) >= 0);
+
+    if (t->device == u->device)
+        handle_transport_state_change(u, t);
+
+    return PA_HOOK_OK;
+}
+
+/* Run from main thread context */
+static int device_process_msg(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
+    struct bluetooth_msg *b = BLUETOOTH_MSG(obj);
+    struct userdata *u = data;
+
+    switch (code) {
+        case BLUETOOTH_MESSAGE_TRANSPORT_STATE_CHANGED:
+            handle_transport_state_change(u, u->transport);
+            break;
+        case BLUETOOTH_MESSAGE_IO_THREAD_FAILED:
+            if (b->card->module->unload_requested)
+                break;
+
+            pa_log_debug("Switching the profile to off due to IO thread failure.");
+            pa_assert_se(pa_card_set_profile(b->card, "off", false) >= 0);
+            break;
+    }
+
+    return 0;
+}
+
+int pa__init(pa_module* m) {
+    struct userdata *u;
+    const char *path;
+    pa_modargs *ma;
+#ifdef BLUETOOTH_APTX_SUPPORT
+    void *handle;
+#endif
+
+    pa_assert(m);
+
+    m->userdata = u = pa_xnew0(struct userdata, 1);
+    u->module = m;
+    u->core = m->core;
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log_error("Failed to parse module arguments");
+        goto fail;
+    }
+
+#ifdef __TIZEN_BT__
+    u->sample_spec = m->core->default_sample_spec;
+    u->modargs = ma;
+#endif
+
+    if (!(path = pa_modargs_get_value(ma, "path", NULL))) {
+        pa_log_error("Failed to get device path from module arguments");
+        goto fail;
+    }
+
+    if ((u->discovery = pa_shared_get(u->core, "bluetooth-discovery")))
+        pa_bluetooth_discovery_ref(u->discovery);
+    else {
+        pa_log_error("module-bluez5-discover doesn't seem to be loaded, refusing to load module-bluez5-device");
+        goto fail;
+    }
+
+    if (!(u->device = pa_bluetooth_discovery_get_device_by_path(u->discovery, path))) {
+        pa_log_error("%s is unknown", path);
+        goto fail;
+    }
+
+#ifndef __TIZEN_BT__
+    pa_modargs_free(ma);
+#endif
+
+    u->device_connection_changed_slot =
+        pa_hook_connect(pa_bluetooth_discovery_hook(u->discovery, PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED),
+                        PA_HOOK_NORMAL, (pa_hook_cb_t) device_connection_changed_cb, u);
+
+    u->transport_state_changed_slot =
+        pa_hook_connect(pa_bluetooth_discovery_hook(u->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED),
+                        PA_HOOK_NORMAL, (pa_hook_cb_t) transport_state_changed_cb, u);
+#ifdef __TIZEN_BT__
+    u->sco_state_changed_slot =
+        pa_hook_connect(pa_bluetooth_discovery_hook(u->discovery, PA_BLUETOOTH_HOOK_SCO_STATE_CHANGED),
+                        PA_HOOK_NORMAL, (pa_hook_cb_t) sco_state_changed_cb, u);
+#endif
+
+    if (add_card(u) < 0)
+        goto fail;
+
+#ifdef __TIZEN_BT__
+    pa_modargs_free(ma);
+#endif
+    if (!(u->msg = pa_msgobject_new(bluetooth_msg)))
+        goto fail;
+
+    u->msg->parent.process_msg = device_process_msg;
+    u->msg->card = u->card;
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+    handle = pa_aptx_get_handle();
+
+    if (handle) {
+           pa_log_debug("Aptx Library loaded\n");
+           pa_load_aptx_sym(handle);
+    }
+#endif
+
+    if (u->profile != PA_BLUETOOTH_PROFILE_OFF)
+        if (init_profile(u) < 0)
+            goto off;
+
+    if (u->sink || u->source)
+        if (start_thread(u) < 0)
+            goto off;
+
+    return 0;
+
+off:
+    stop_thread(u);
+
+    pa_assert_se(pa_card_set_profile(u->card, "off", false) >= 0);
+
+    return 0;
+
+fail:
+
+    if (ma)
+        pa_modargs_free(ma);
+
+    pa__done(m);
+
+    return -1;
+}
+
+void pa__done(pa_module *m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    stop_thread(u);
+
+    if (u->device_connection_changed_slot)
+        pa_hook_slot_free(u->device_connection_changed_slot);
+
+    if (u->transport_state_changed_slot)
+        pa_hook_slot_free(u->transport_state_changed_slot);
+#ifdef __TIZEN_BT__
+    if (u->sco_state_changed_slot)
+        pa_hook_slot_free(u->sco_state_changed_slot);
+#endif
+
+    if (u->sbc_info.buffer)
+        pa_xfree(u->sbc_info.buffer);
+
+    if (u->sbc_info.sbc_initialized)
+        sbc_finish(&u->sbc_info.sbc);
+
+    if (u->msg)
+        pa_xfree(u->msg);
+
+    if (u->card)
+        pa_card_free(u->card);
+
+    if (u->discovery)
+        pa_bluetooth_discovery_unref(u->discovery);
+
+    pa_xfree(u->output_port_name);
+    pa_xfree(u->input_port_name);
+
+    pa_xfree(u);
+}
+
+int pa__get_n_used(pa_module *m) {
+    struct userdata *u;
+
+    pa_assert(m);
+    pa_assert_se(u = m->userdata);
+
+    return (u->sink ? pa_sink_linked_by(u->sink) : 0) + (u->source ? pa_source_linked_by(u->source) : 0);
+}
diff --git a/src/modules/bluetooth/module-bluez5-discover.c b/src/modules/bluetooth/module-bluez5-discover.c
new file mode 100644 (file)
index 0000000..f572a4a
--- /dev/null
@@ -0,0 +1,196 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2008-2013 João Paulo Rechi Vita
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulsecore/core.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/module.h>
+#include <pulsecore/shared.h>
+#ifdef __TIZEN_BT__
+#include <pulsecore/modargs.h>
+#endif
+#include "bluez5-util.h"
+
+#include "module-bluez5-discover-symdef.h"
+
+PA_MODULE_AUTHOR("João Paulo Rechi Vita");
+PA_MODULE_DESCRIPTION("Detect available BlueZ 5 Bluetooth audio devices and load BlueZ 5 Bluetooth audio drivers");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+#ifdef __TIZEN_BT__
+PA_MODULE_USAGE("sco_sink=<name of sink> "
+                                       "sco_source=<name of source> "
+#ifdef BLUETOOTH_APTX_SUPPORT
+                                       "aptx_lib_name=<name of aptx library name>"
+#endif
+);
+#endif
+PA_MODULE_LOAD_ONCE(true);
+
+#ifdef __TIZEN_BT__
+static const char* const valid_modargs[] = {
+    "sco_sink",
+    "sco_source",
+#ifdef BLUETOOTH_APTX_SUPPORT
+    "aptx_lib_name",
+#endif
+    NULL
+};
+#endif
+
+struct userdata {
+    pa_module *module;
+    pa_core *core;
+    pa_hashmap *loaded_device_paths;
+    pa_hook_slot *device_connection_changed_slot;
+    pa_bluetooth_discovery *discovery;
+};
+
+static pa_hook_result_t device_connection_changed_cb(pa_bluetooth_discovery *y, const pa_bluetooth_device *d, struct userdata *u) {
+    bool module_loaded;
+
+    pa_assert(d);
+    pa_assert(u);
+
+    module_loaded = pa_hashmap_get(u->loaded_device_paths, d->path) ? true : false;
+
+    if (module_loaded && !pa_bluetooth_device_any_transport_connected(d)) {
+        /* disconnection, the module unloads itself */
+        pa_log_debug("Unregistering module for %s", d->path);
+        pa_hashmap_remove(u->loaded_device_paths, d->path);
+        return PA_HOOK_OK;
+    }
+
+    if (!module_loaded && pa_bluetooth_device_any_transport_connected(d)) {
+        /* a new device has been connected */
+        pa_module *m;
+
+#ifdef __TIZEN_BT__
+       char *args = pa_sprintf_malloc("address=\"%s\" path=\"%s\"", d->address, d->path);
+#else
+       char *args = pa_sprintf_malloc("path=%s", d->path);
+#endif
+
+#ifdef __TIZEN_BT__
+       if (pa_bluetooth_device_sink_transport_connected(d) == true) {
+               char *tmp = pa_sprintf_malloc("%s profile=\"a2dp_sink\"", args);
+               pa_xfree(args);
+               args = tmp;
+       }
+#endif
+
+        pa_log_debug("Loading module-bluez5-device %s", args);
+        m = pa_module_load(u->module->core, "module-bluez5-device", args);
+        pa_xfree(args);
+
+        if (m)
+            /* No need to duplicate the path here since the device object will
+             * exist for the whole hashmap entry lifespan */
+            pa_hashmap_put(u->loaded_device_paths, d->path, d->path);
+        else
+            pa_log_warn("Failed to load module for device %s", d->path);
+
+        return PA_HOOK_OK;
+    }
+
+    return PA_HOOK_OK;
+}
+
+int pa__init(pa_module *m) {
+    struct userdata *u;
+#ifdef BLUETOOTH_APTX_SUPPORT
+    pa_modargs *ma = NULL;
+    const char *aptx_lib_name = NULL;
+#endif
+
+    pa_assert(m);
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments");
+        goto fail;
+    }
+
+    if (pa_modargs_get_value(ma, "async", NULL))
+        pa_log_warn("The 'async' argument is deprecated and does nothing.");
+
+    aptx_lib_name = pa_modargs_get_value(ma, "aptx_lib_name", NULL);
+    if (aptx_lib_name)
+        pa_load_aptx(aptx_lib_name);
+    else
+        pa_log("Failed to parse aptx_lib_name argument.");
+#endif
+
+    m->userdata = u = pa_xnew0(struct userdata, 1);
+    u->module = m;
+    u->core = m->core;
+    u->loaded_device_paths = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+
+    if (!(u->discovery = pa_bluetooth_discovery_get(u->core)))
+        goto fail;
+
+    u->device_connection_changed_slot =
+        pa_hook_connect(pa_bluetooth_discovery_hook(u->discovery, PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED),
+                        PA_HOOK_NORMAL, (pa_hook_cb_t) device_connection_changed_cb, u);
+
+    if (ma)
+           pa_modargs_free(ma);
+
+    return 0;
+
+fail:
+    if (ma)
+           pa_modargs_free(ma);
+
+    pa__done(m);
+    return -1;
+}
+
+void pa__done(pa_module *m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    if (u->device_connection_changed_slot)
+        pa_hook_slot_free(u->device_connection_changed_slot);
+
+    if (u->discovery)
+        pa_bluetooth_discovery_unref(u->discovery);
+
+    if (u->loaded_device_paths)
+#ifdef __TIZEN_BT__
+        pa_hashmap_free(u->loaded_device_paths,NULL);
+#else
+        pa_hashmap_free(u->loaded_device_paths);
+#endif
+
+#ifdef BLUETOOTH_APTX_SUPPORT
+    pa_unload_aptx();
+#endif
+
+    pa_xfree(u);
+}
diff --git a/src/modules/bluetooth/proximity-helper.c b/src/modules/bluetooth/proximity-helper.c
deleted file mode 100644 (file)
index 3767f01..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Small SUID helper that allows us to ping a BT device. Borrows
- * heavily from bluez-utils' l2ping, which is licensed as GPL2+
- * and comes with a copyright like this:
- *
- *  Copyright (C) 2000-2001  Qualcomm Incorporated
- *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
- *  Copyright (C) 2002-2007  Marcel Holtmann <marcel@holtmann.org>
- *
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program 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 General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#undef NDEBUG
-
-#include <assert.h>
-#include <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <sys/select.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/hci.h>
-#include <bluetooth/hci_lib.h>
-#include <bluetooth/l2cap.h>
-
-#define PING_STRING "PulseAudio"
-#define IDENT 200
-#define TIMEOUT 4
-#define INTERVAL 2
-
-static void update_status(int found) {
-    static int status = -1;
-
-    if (!found && status != 0)
-        printf("-");
-    if (found && status <= 0)
-        printf("+");
-
-    fflush(stdout);
-    status = !!found;
-}
-
-int main(int argc, char *argv[]) {
-    struct sockaddr_l2 addr;
-    union {
-        l2cap_cmd_hdr hdr;
-        uint8_t buf[L2CAP_CMD_HDR_SIZE + sizeof(PING_STRING)];
-    }  packet;
-    int fd = -1;
-    uint8_t id = IDENT;
-    int connected = 0;
-
-    assert(argc == 2);
-
-    for (;;) {
-        fd_set fds;
-        struct timeval end;
-        ssize_t r;
-
-        if (!connected) {
-
-            if (fd >= 0)
-                close(fd);
-
-            if ((fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP)) < 0) {
-                fprintf(stderr, "socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP) failed: %s", strerror(errno));
-                goto finish;
-            }
-
-            memset(&addr, 0, sizeof(addr));
-            addr.l2_family = AF_BLUETOOTH;
-            bacpy(&addr.l2_bdaddr, BDADDR_ANY);
-
-            if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-                fprintf(stderr, "bind() failed: %s", strerror(errno));
-                goto finish;
-            }
-
-            memset(&addr, 0, sizeof(addr));
-            addr.l2_family = AF_BLUETOOTH;
-            str2ba(argv[1], &addr.l2_bdaddr);
-
-            if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-
-                if (errno == EHOSTDOWN || errno == ECONNRESET || errno == ETIMEDOUT) {
-                    update_status(0);
-                    sleep(INTERVAL);
-                    continue;
-                }
-
-                fprintf(stderr, "connect() failed: %s", strerror(errno));
-                goto finish;
-            }
-
-            connected = 1;
-        }
-
-        assert(connected);
-
-        memset(&packet, 0, sizeof(packet));
-        strcpy((char*) packet.buf + L2CAP_CMD_HDR_SIZE, PING_STRING);
-        packet.hdr.ident = id;
-        packet.hdr.len = htobs(sizeof(PING_STRING));
-        packet.hdr.code = L2CAP_ECHO_REQ;
-
-        if ((r = send(fd, &packet, sizeof(packet), 0)) < 0) {
-
-            if (errno == EHOSTDOWN || errno == ECONNRESET || errno == ETIMEDOUT) {
-                update_status(0);
-                connected = 0;
-                sleep(INTERVAL);
-                continue;
-            }
-
-            fprintf(stderr, "send() failed: %s", strerror(errno));
-            goto finish;
-        }
-
-        assert(r == sizeof(packet));
-
-        gettimeofday(&end, NULL);
-        end.tv_sec += TIMEOUT;
-
-        for (;;) {
-            struct timeval now, delta;
-
-            gettimeofday(&now, NULL);
-
-            if (timercmp(&end, &now, <=)) {
-                update_status(0);
-                connected = 0;
-                sleep(INTERVAL);
-                break;
-            }
-
-            timersub(&end, &now, &delta);
-
-            FD_ZERO(&fds);
-            FD_SET(fd, &fds);
-
-            if (select(fd+1, &fds, NULL, NULL, &delta) < 0) {
-                fprintf(stderr, "select() failed: %s", strerror(errno));
-                goto finish;
-            }
-
-            if ((r = recv(fd, &packet, sizeof(packet), 0)) <= 0) {
-
-                if (errno == EHOSTDOWN || errno == ECONNRESET || errno == ETIMEDOUT) {
-                    update_status(0);
-                    connected = 0;
-                    sleep(INTERVAL);
-                    break;
-                }
-
-                fprintf(stderr, "send() failed: %s", r == 0 ? "EOF" : strerror(errno));
-                goto finish;
-            }
-
-            assert(r >= L2CAP_CMD_HDR_SIZE);
-
-            if (packet.hdr.ident != id)
-                continue;
-
-            if (packet.hdr.code == L2CAP_ECHO_RSP || packet.hdr.code == L2CAP_COMMAND_REJ) {
-
-                if (++id >= 0xFF)
-                    id = IDENT;
-
-                update_status(1);
-                sleep(INTERVAL);
-                break;
-            }
-        }
-    }
-
-finish:
-
-    if (fd >= 0)
-        close(fd);
-
-    return 1;
-}
diff --git a/src/modules/bluetooth/sbc/sbc.c b/src/modules/bluetooth/sbc/sbc.c
deleted file mode 100644 (file)
index c5015ab..0000000
+++ /dev/null
@@ -1,1241 +0,0 @@
-/*
- *
- *  Bluetooth low-complexity, subband codec (SBC) library
- *
- *  Copyright (C) 2008-2010  Nokia Corporation
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
- *  Copyright (C) 2005-2008  Brad Midgley <bmidgley@xmission.com>
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-/* todo items:
-
-  use a log2 table for byte integer scale factors calculation (sum log2 results
-  for high and low bytes) fill bitpool by 16 bits instead of one at a time in
-  bits allocation/bitpool generation port to the dsp
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <limits.h>
-
-#include "sbc_math.h"
-#include "sbc_tables.h"
-
-#include "sbc.h"
-#include "sbc_primitives.h"
-
-#define SBC_SYNCWORD   0x9C
-
-/* This structure contains an unpacked SBC frame.
-   Yes, there is probably quite some unused space herein */
-struct sbc_frame {
-       uint8_t frequency;
-       uint8_t block_mode;
-       uint8_t blocks;
-       enum {
-               MONO            = SBC_MODE_MONO,
-               DUAL_CHANNEL    = SBC_MODE_DUAL_CHANNEL,
-               STEREO          = SBC_MODE_STEREO,
-               JOINT_STEREO    = SBC_MODE_JOINT_STEREO
-       } mode;
-       uint8_t channels;
-       enum {
-               LOUDNESS        = SBC_AM_LOUDNESS,
-               SNR             = SBC_AM_SNR
-       } allocation;
-       uint8_t subband_mode;
-       uint8_t subbands;
-       uint8_t bitpool;
-       uint16_t codesize;
-       uint8_t length;
-
-       /* bit number x set means joint stereo has been used in subband x */
-       uint8_t joint;
-
-       /* only the lower 4 bits of every element are to be used */
-       uint32_t SBC_ALIGNED scale_factor[2][8];
-
-       /* raw integer subband samples in the frame */
-       int32_t SBC_ALIGNED sb_sample_f[16][2][8];
-
-       /* modified subband samples */
-       int32_t SBC_ALIGNED sb_sample[16][2][8];
-
-       /* original pcm audio samples */
-       int16_t SBC_ALIGNED pcm_sample[2][16*8];
-};
-
-struct sbc_decoder_state {
-       int subbands;
-       int32_t V[2][170];
-       int offset[2][16];
-};
-
-/*
- * Calculates the CRC-8 of the first len bits in data
- */
-static const uint8_t crc_table[256] = {
-       0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53,
-       0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB,
-       0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E,
-       0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76,
-       0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4,
-       0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C,
-       0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19,
-       0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1,
-       0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40,
-       0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8,
-       0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D,
-       0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65,
-       0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7,
-       0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F,
-       0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A,
-       0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2,
-       0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75,
-       0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D,
-       0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8,
-       0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50,
-       0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2,
-       0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A,
-       0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F,
-       0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7,
-       0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66,
-       0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E,
-       0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB,
-       0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43,
-       0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1,
-       0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09,
-       0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C,
-       0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4
-};
-
-static uint8_t sbc_crc8(const uint8_t *data, size_t len)
-{
-       uint8_t crc = 0x0f;
-       size_t i;
-       uint8_t octet;
-
-       for (i = 0; i < len / 8; i++)
-               crc = crc_table[crc ^ data[i]];
-
-       octet = data[i];
-       for (i = 0; i < len % 8; i++) {
-               char bit = ((octet ^ crc) & 0x80) >> 7;
-
-               crc = ((crc & 0x7f) << 1) ^ (bit ? 0x1d : 0);
-
-               octet = octet << 1;
-       }
-
-       return crc;
-}
-
-/*
- * Code straight from the spec to calculate the bits array
- * Takes a pointer to the frame in question, a pointer to the bits array and
- * the sampling frequency (as 2 bit integer)
- */
-static SBC_ALWAYS_INLINE void sbc_calculate_bits_internal(
-               const struct sbc_frame *frame, int (*bits)[8], int subbands)
-{
-       uint8_t sf = frame->frequency;
-
-       if (frame->mode == MONO || frame->mode == DUAL_CHANNEL) {
-               int bitneed[2][8], loudness, max_bitneed, bitcount, slicecount, bitslice;
-               int ch, sb;
-
-               for (ch = 0; ch < frame->channels; ch++) {
-                       max_bitneed = 0;
-                       if (frame->allocation == SNR) {
-                               for (sb = 0; sb < subbands; sb++) {
-                                       bitneed[ch][sb] = frame->scale_factor[ch][sb];
-                                       if (bitneed[ch][sb] > max_bitneed)
-                                               max_bitneed = bitneed[ch][sb];
-                               }
-                       } else {
-                               for (sb = 0; sb < subbands; sb++) {
-                                       if (frame->scale_factor[ch][sb] == 0)
-                                               bitneed[ch][sb] = -5;
-                                       else {
-                                               if (subbands == 4)
-                                                       loudness = frame->scale_factor[ch][sb] - sbc_offset4[sf][sb];
-                                               else
-                                                       loudness = frame->scale_factor[ch][sb] - sbc_offset8[sf][sb];
-                                               if (loudness > 0)
-                                                       bitneed[ch][sb] = loudness / 2;
-                                               else
-                                                       bitneed[ch][sb] = loudness;
-                                       }
-                                       if (bitneed[ch][sb] > max_bitneed)
-                                               max_bitneed = bitneed[ch][sb];
-                               }
-                       }
-
-                       bitcount = 0;
-                       slicecount = 0;
-                       bitslice = max_bitneed + 1;
-                       do {
-                               bitslice--;
-                               bitcount += slicecount;
-                               slicecount = 0;
-                               for (sb = 0; sb < subbands; sb++) {
-                                       if ((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16))
-                                               slicecount++;
-                                       else if (bitneed[ch][sb] == bitslice + 1)
-                                               slicecount += 2;
-                               }
-                       } while (bitcount + slicecount < frame->bitpool);
-
-                       if (bitcount + slicecount == frame->bitpool) {
-                               bitcount += slicecount;
-                               bitslice--;
-                       }
-
-                       for (sb = 0; sb < subbands; sb++) {
-                               if (bitneed[ch][sb] < bitslice + 2)
-                                       bits[ch][sb] = 0;
-                               else {
-                                       bits[ch][sb] = bitneed[ch][sb] - bitslice;
-                                       if (bits[ch][sb] > 16)
-                                               bits[ch][sb] = 16;
-                               }
-                       }
-
-                       for (sb = 0; bitcount < frame->bitpool &&
-                                                       sb < subbands; sb++) {
-                               if ((bits[ch][sb] >= 2) && (bits[ch][sb] < 16)) {
-                                       bits[ch][sb]++;
-                                       bitcount++;
-                               } else if ((bitneed[ch][sb] == bitslice + 1) && (frame->bitpool > bitcount + 1)) {
-                                       bits[ch][sb] = 2;
-                                       bitcount += 2;
-                               }
-                       }
-
-                       for (sb = 0; bitcount < frame->bitpool &&
-                                                       sb < subbands; sb++) {
-                               if (bits[ch][sb] < 16) {
-                                       bits[ch][sb]++;
-                                       bitcount++;
-                               }
-                       }
-
-               }
-
-       } else if (frame->mode == STEREO || frame->mode == JOINT_STEREO) {
-               int bitneed[2][8], loudness, max_bitneed, bitcount, slicecount, bitslice;
-               int ch, sb;
-
-               max_bitneed = 0;
-               if (frame->allocation == SNR) {
-                       for (ch = 0; ch < 2; ch++) {
-                               for (sb = 0; sb < subbands; sb++) {
-                                       bitneed[ch][sb] = frame->scale_factor[ch][sb];
-                                       if (bitneed[ch][sb] > max_bitneed)
-                                               max_bitneed = bitneed[ch][sb];
-                               }
-                       }
-               } else {
-                       for (ch = 0; ch < 2; ch++) {
-                               for (sb = 0; sb < subbands; sb++) {
-                                       if (frame->scale_factor[ch][sb] == 0)
-                                               bitneed[ch][sb] = -5;
-                                       else {
-                                               if (subbands == 4)
-                                                       loudness = frame->scale_factor[ch][sb] - sbc_offset4[sf][sb];
-                                               else
-                                                       loudness = frame->scale_factor[ch][sb] - sbc_offset8[sf][sb];
-                                               if (loudness > 0)
-                                                       bitneed[ch][sb] = loudness / 2;
-                                               else
-                                                       bitneed[ch][sb] = loudness;
-                                       }
-                                       if (bitneed[ch][sb] > max_bitneed)
-                                               max_bitneed = bitneed[ch][sb];
-                               }
-                       }
-               }
-
-               bitcount = 0;
-               slicecount = 0;
-               bitslice = max_bitneed + 1;
-               do {
-                       bitslice--;
-                       bitcount += slicecount;
-                       slicecount = 0;
-                       for (ch = 0; ch < 2; ch++) {
-                               for (sb = 0; sb < subbands; sb++) {
-                                       if ((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16))
-                                               slicecount++;
-                                       else if (bitneed[ch][sb] == bitslice + 1)
-                                               slicecount += 2;
-                               }
-                       }
-               } while (bitcount + slicecount < frame->bitpool);
-
-               if (bitcount + slicecount == frame->bitpool) {
-                       bitcount += slicecount;
-                       bitslice--;
-               }
-
-               for (ch = 0; ch < 2; ch++) {
-                       for (sb = 0; sb < subbands; sb++) {
-                               if (bitneed[ch][sb] < bitslice + 2) {
-                                       bits[ch][sb] = 0;
-                               } else {
-                                       bits[ch][sb] = bitneed[ch][sb] - bitslice;
-                                       if (bits[ch][sb] > 16)
-                                               bits[ch][sb] = 16;
-                               }
-                       }
-               }
-
-               ch = 0;
-               sb = 0;
-               while (bitcount < frame->bitpool) {
-                       if ((bits[ch][sb] >= 2) && (bits[ch][sb] < 16)) {
-                               bits[ch][sb]++;
-                               bitcount++;
-                       } else if ((bitneed[ch][sb] == bitslice + 1) && (frame->bitpool > bitcount + 1)) {
-                               bits[ch][sb] = 2;
-                               bitcount += 2;
-                       }
-                       if (ch == 1) {
-                               ch = 0;
-                               sb++;
-                               if (sb >= subbands)
-                                       break;
-                       } else
-                               ch = 1;
-               }
-
-               ch = 0;
-               sb = 0;
-               while (bitcount < frame->bitpool) {
-                       if (bits[ch][sb] < 16) {
-                               bits[ch][sb]++;
-                               bitcount++;
-                       }
-                       if (ch == 1) {
-                               ch = 0;
-                               sb++;
-                               if (sb >= subbands)
-                                       break;
-                       } else
-                               ch = 1;
-               }
-
-       }
-
-}
-
-static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8])
-{
-       if (frame->subbands == 4)
-               sbc_calculate_bits_internal(frame, bits, 4);
-       else
-               sbc_calculate_bits_internal(frame, bits, 8);
-}
-
-/*
- * Unpacks a SBC frame at the beginning of the stream in data,
- * which has at most len bytes into frame.
- * Returns the length in bytes of the packed frame, or a negative
- * value on error. The error codes are:
- *
- *  -1   Data stream too short
- *  -2   Sync byte incorrect
- *  -3   CRC8 incorrect
- *  -4   Bitpool value out of bounds
- */
-static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame,
-                                                               size_t len)
-{
-       unsigned int consumed;
-       /* Will copy the parts of the header that are relevant to crc
-        * calculation here */
-       uint8_t crc_header[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-       int crc_pos = 0;
-       int32_t temp;
-
-       uint32_t audio_sample;
-       int ch, sb, blk, bit;   /* channel, subband, block and bit standard
-                                  counters */
-       int bits[2][8];         /* bits distribution */
-       uint32_t levels[2][8];  /* levels derived from that */
-
-       if (len < 4)
-               return -1;
-
-       if (data[0] != SBC_SYNCWORD)
-               return -2;
-
-       frame->frequency = (data[1] >> 6) & 0x03;
-
-       frame->block_mode = (data[1] >> 4) & 0x03;
-       switch (frame->block_mode) {
-       case SBC_BLK_4:
-               frame->blocks = 4;
-               break;
-       case SBC_BLK_8:
-               frame->blocks = 8;
-               break;
-       case SBC_BLK_12:
-               frame->blocks = 12;
-               break;
-       case SBC_BLK_16:
-               frame->blocks = 16;
-               break;
-       }
-
-       frame->mode = (data[1] >> 2) & 0x03;
-       switch (frame->mode) {
-       case MONO:
-               frame->channels = 1;
-               break;
-       case DUAL_CHANNEL:      /* fall-through */
-       case STEREO:
-       case JOINT_STEREO:
-               frame->channels = 2;
-               break;
-       }
-
-       frame->allocation = (data[1] >> 1) & 0x01;
-
-       frame->subband_mode = (data[1] & 0x01);
-       frame->subbands = frame->subband_mode ? 8 : 4;
-
-       frame->bitpool = data[2];
-
-       if ((frame->mode == MONO || frame->mode == DUAL_CHANNEL) &&
-                       frame->bitpool > 16 * frame->subbands)
-               return -4;
-
-       if ((frame->mode == STEREO || frame->mode == JOINT_STEREO) &&
-                       frame->bitpool > 32 * frame->subbands)
-               return -4;
-
-       /* data[3] is crc, we're checking it later */
-
-       consumed = 32;
-
-       crc_header[0] = data[1];
-       crc_header[1] = data[2];
-       crc_pos = 16;
-
-       if (frame->mode == JOINT_STEREO) {
-               if (len * 8 < consumed + frame->subbands)
-                       return -1;
-
-               frame->joint = 0x00;
-               for (sb = 0; sb < frame->subbands - 1; sb++)
-                       frame->joint |= ((data[4] >> (7 - sb)) & 0x01) << sb;
-               if (frame->subbands == 4)
-                       crc_header[crc_pos / 8] = data[4] & 0xf0;
-               else
-                       crc_header[crc_pos / 8] = data[4];
-
-               consumed += frame->subbands;
-               crc_pos += frame->subbands;
-       }
-
-       if (len * 8 < consumed + (4 * frame->subbands * frame->channels))
-               return -1;
-
-       for (ch = 0; ch < frame->channels; ch++) {
-               for (sb = 0; sb < frame->subbands; sb++) {
-                       /* FIXME assert(consumed % 4 == 0); */
-                       frame->scale_factor[ch][sb] =
-                               (data[consumed >> 3] >> (4 - (consumed & 0x7))) & 0x0F;
-                       crc_header[crc_pos >> 3] |=
-                               frame->scale_factor[ch][sb] << (4 - (crc_pos & 0x7));
-
-                       consumed += 4;
-                       crc_pos += 4;
-               }
-       }
-
-       if (data[3] != sbc_crc8(crc_header, crc_pos))
-               return -3;
-
-       sbc_calculate_bits(frame, bits);
-
-       for (ch = 0; ch < frame->channels; ch++) {
-               for (sb = 0; sb < frame->subbands; sb++)
-                       levels[ch][sb] = (1 << bits[ch][sb]) - 1;
-       }
-
-       for (blk = 0; blk < frame->blocks; blk++) {
-               for (ch = 0; ch < frame->channels; ch++) {
-                       for (sb = 0; sb < frame->subbands; sb++) {
-                               uint32_t shift;
-
-                               if (levels[ch][sb] == 0) {
-                                       frame->sb_sample[blk][ch][sb] = 0;
-                                       continue;
-                               }
-
-                               shift = frame->scale_factor[ch][sb] +
-                                               1 + SBCDEC_FIXED_EXTRA_BITS;
-
-                               audio_sample = 0;
-                               for (bit = 0; bit < bits[ch][sb]; bit++) {
-                                       if (consumed > len * 8)
-                                               return -1;
-
-                                       if ((data[consumed >> 3] >> (7 - (consumed & 0x7))) & 0x01)
-                                               audio_sample |= 1 << (bits[ch][sb] - bit - 1);
-
-                                       consumed++;
-                               }
-
-                               frame->sb_sample[blk][ch][sb] = (int32_t)
-                                       (((((uint64_t) audio_sample << 1) | 1) << shift) /
-                                       levels[ch][sb]) - (1 << shift);
-                       }
-               }
-       }
-
-       if (frame->mode == JOINT_STEREO) {
-               for (blk = 0; blk < frame->blocks; blk++) {
-                       for (sb = 0; sb < frame->subbands; sb++) {
-                               if (frame->joint & (0x01 << sb)) {
-                                       temp = frame->sb_sample[blk][0][sb] +
-                                               frame->sb_sample[blk][1][sb];
-                                       frame->sb_sample[blk][1][sb] =
-                                               frame->sb_sample[blk][0][sb] -
-                                               frame->sb_sample[blk][1][sb];
-                                       frame->sb_sample[blk][0][sb] = temp;
-                               }
-                       }
-               }
-       }
-
-       if ((consumed & 0x7) != 0)
-               consumed += 8 - (consumed & 0x7);
-
-       return consumed >> 3;
-}
-
-static void sbc_decoder_init(struct sbc_decoder_state *state,
-                                       const struct sbc_frame *frame)
-{
-       int i, ch;
-
-       memset(state->V, 0, sizeof(state->V));
-       state->subbands = frame->subbands;
-
-       for (ch = 0; ch < 2; ch++)
-               for (i = 0; i < frame->subbands * 2; i++)
-                       state->offset[ch][i] = (10 * i + 10);
-}
-
-static SBC_ALWAYS_INLINE int16_t sbc_clip16(int32_t s)
-{
-       if (s > 0x7FFF)
-               return 0x7FFF;
-       else if (s < -0x8000)
-               return -0x8000;
-       else
-               return s;
-}
-
-static inline void sbc_synthesize_four(struct sbc_decoder_state *state,
-                               struct sbc_frame *frame, int ch, int blk)
-{
-       int i, k, idx;
-       int32_t *v = state->V[ch];
-       int *offset = state->offset[ch];
-
-       for (i = 0; i < 8; i++) {
-               /* Shifting */
-               offset[i]--;
-               if (offset[i] < 0) {
-                       offset[i] = 79;
-                       memcpy(v + 80, v, 9 * sizeof(*v));
-               }
-
-               /* Distribute the new matrix value to the shifted position */
-               v[offset[i]] = SCALE4_STAGED1(
-                       MULA(synmatrix4[i][0], frame->sb_sample[blk][ch][0],
-                       MULA(synmatrix4[i][1], frame->sb_sample[blk][ch][1],
-                       MULA(synmatrix4[i][2], frame->sb_sample[blk][ch][2],
-                       MUL (synmatrix4[i][3], frame->sb_sample[blk][ch][3])))));
-       }
-
-       /* Compute the samples */
-       for (idx = 0, i = 0; i < 4; i++, idx += 5) {
-               k = (i + 4) & 0xf;
-
-               /* Store in output, Q0 */
-               frame->pcm_sample[ch][blk * 4 + i] = sbc_clip16(SCALE4_STAGED1(
-                       MULA(v[offset[i] + 0], sbc_proto_4_40m0[idx + 0],
-                       MULA(v[offset[k] + 1], sbc_proto_4_40m1[idx + 0],
-                       MULA(v[offset[i] + 2], sbc_proto_4_40m0[idx + 1],
-                       MULA(v[offset[k] + 3], sbc_proto_4_40m1[idx + 1],
-                       MULA(v[offset[i] + 4], sbc_proto_4_40m0[idx + 2],
-                       MULA(v[offset[k] + 5], sbc_proto_4_40m1[idx + 2],
-                       MULA(v[offset[i] + 6], sbc_proto_4_40m0[idx + 3],
-                       MULA(v[offset[k] + 7], sbc_proto_4_40m1[idx + 3],
-                       MULA(v[offset[i] + 8], sbc_proto_4_40m0[idx + 4],
-                       MUL( v[offset[k] + 9], sbc_proto_4_40m1[idx + 4]))))))))))));
-       }
-}
-
-static inline void sbc_synthesize_eight(struct sbc_decoder_state *state,
-                               struct sbc_frame *frame, int ch, int blk)
-{
-       int i, j, k, idx;
-       int *offset = state->offset[ch];
-
-       for (i = 0; i < 16; i++) {
-               /* Shifting */
-               offset[i]--;
-               if (offset[i] < 0) {
-                       offset[i] = 159;
-                       for (j = 0; j < 9; j++)
-                               state->V[ch][j + 160] = state->V[ch][j];
-               }
-
-               /* Distribute the new matrix value to the shifted position */
-               state->V[ch][offset[i]] = SCALE8_STAGED1(
-                       MULA(synmatrix8[i][0], frame->sb_sample[blk][ch][0],
-                       MULA(synmatrix8[i][1], frame->sb_sample[blk][ch][1],
-                       MULA(synmatrix8[i][2], frame->sb_sample[blk][ch][2],
-                       MULA(synmatrix8[i][3], frame->sb_sample[blk][ch][3],
-                       MULA(synmatrix8[i][4], frame->sb_sample[blk][ch][4],
-                       MULA(synmatrix8[i][5], frame->sb_sample[blk][ch][5],
-                       MULA(synmatrix8[i][6], frame->sb_sample[blk][ch][6],
-                       MUL( synmatrix8[i][7], frame->sb_sample[blk][ch][7])))))))));
-       }
-
-       /* Compute the samples */
-       for (idx = 0, i = 0; i < 8; i++, idx += 5) {
-               k = (i + 8) & 0xf;
-
-               /* Store in output, Q0 */
-               frame->pcm_sample[ch][blk * 8 + i] = sbc_clip16(SCALE8_STAGED1(
-                       MULA(state->V[ch][offset[i] + 0], sbc_proto_8_80m0[idx + 0],
-                       MULA(state->V[ch][offset[k] + 1], sbc_proto_8_80m1[idx + 0],
-                       MULA(state->V[ch][offset[i] + 2], sbc_proto_8_80m0[idx + 1],
-                       MULA(state->V[ch][offset[k] + 3], sbc_proto_8_80m1[idx + 1],
-                       MULA(state->V[ch][offset[i] + 4], sbc_proto_8_80m0[idx + 2],
-                       MULA(state->V[ch][offset[k] + 5], sbc_proto_8_80m1[idx + 2],
-                       MULA(state->V[ch][offset[i] + 6], sbc_proto_8_80m0[idx + 3],
-                       MULA(state->V[ch][offset[k] + 7], sbc_proto_8_80m1[idx + 3],
-                       MULA(state->V[ch][offset[i] + 8], sbc_proto_8_80m0[idx + 4],
-                       MUL( state->V[ch][offset[k] + 9], sbc_proto_8_80m1[idx + 4]))))))))))));
-       }
-}
-
-static int sbc_synthesize_audio(struct sbc_decoder_state *state,
-                                               struct sbc_frame *frame)
-{
-       int ch, blk;
-
-       switch (frame->subbands) {
-       case 4:
-               for (ch = 0; ch < frame->channels; ch++) {
-                       for (blk = 0; blk < frame->blocks; blk++)
-                               sbc_synthesize_four(state, frame, ch, blk);
-               }
-               return frame->blocks * 4;
-
-       case 8:
-               for (ch = 0; ch < frame->channels; ch++) {
-                       for (blk = 0; blk < frame->blocks; blk++)
-                               sbc_synthesize_eight(state, frame, ch, blk);
-               }
-               return frame->blocks * 8;
-
-       default:
-               return -EIO;
-       }
-}
-
-static int sbc_analyze_audio(struct sbc_encoder_state *state,
-                                               struct sbc_frame *frame)
-{
-       int ch, blk;
-       int16_t *x;
-
-       switch (frame->subbands) {
-       case 4:
-               for (ch = 0; ch < frame->channels; ch++) {
-                       x = &state->X[ch][state->position - 16 +
-                                                       frame->blocks * 4];
-                       for (blk = 0; blk < frame->blocks; blk += 4) {
-                               state->sbc_analyze_4b_4s(
-                                       x,
-                                       frame->sb_sample_f[blk][ch],
-                                       frame->sb_sample_f[blk + 1][ch] -
-                                       frame->sb_sample_f[blk][ch]);
-                               x -= 16;
-                       }
-               }
-               return frame->blocks * 4;
-
-       case 8:
-               for (ch = 0; ch < frame->channels; ch++) {
-                       x = &state->X[ch][state->position - 32 +
-                                                       frame->blocks * 8];
-                       for (blk = 0; blk < frame->blocks; blk += 4) {
-                               state->sbc_analyze_4b_8s(
-                                       x,
-                                       frame->sb_sample_f[blk][ch],
-                                       frame->sb_sample_f[blk + 1][ch] -
-                                       frame->sb_sample_f[blk][ch]);
-                               x -= 32;
-                       }
-               }
-               return frame->blocks * 8;
-
-       default:
-               return -EIO;
-       }
-}
-
-/* Supplementary bitstream writing macros for 'sbc_pack_frame' */
-
-#define PUT_BITS(data_ptr, bits_cache, bits_count, v, n)               \
-       do {                                                            \
-               bits_cache = (v) | (bits_cache << (n));                 \
-               bits_count += (n);                                      \
-               if (bits_count >= 16) {                                 \
-                       bits_count -= 8;                                \
-                       *data_ptr++ = (uint8_t)                         \
-                               (bits_cache >> bits_count);             \
-                       bits_count -= 8;                                \
-                       *data_ptr++ = (uint8_t)                         \
-                               (bits_cache >> bits_count);             \
-               }                                                       \
-       } while (0)
-
-#define FLUSH_BITS(data_ptr, bits_cache, bits_count)                   \
-       do {                                                            \
-               while (bits_count >= 8) {                               \
-                       bits_count -= 8;                                \
-                       *data_ptr++ = (uint8_t)                         \
-                               (bits_cache >> bits_count);             \
-               }                                                       \
-               if (bits_count > 0)                                     \
-                       *data_ptr++ = (uint8_t)                         \
-                               (bits_cache << (8 - bits_count));       \
-       } while (0)
-
-/*
- * Packs the SBC frame from frame into the memory at data. At most len
- * bytes will be used, should more memory be needed an appropriate
- * error code will be returned. Returns the length of the packed frame
- * on success or a negative value on error.
- *
- * The error codes are:
- * -1 Not enough memory reserved
- * -2 Unsupported sampling rate
- * -3 Unsupported number of blocks
- * -4 Unsupported number of subbands
- * -5 Bitpool value out of bounds
- * -99 not implemented
- */
-
-static SBC_ALWAYS_INLINE ssize_t sbc_pack_frame_internal(uint8_t *data,
-                                       struct sbc_frame *frame, size_t len,
-                                       int frame_subbands, int frame_channels,
-                                       int joint)
-{
-       /* Bitstream writer starts from the fourth byte */
-       uint8_t *data_ptr = data + 4;
-       uint32_t bits_cache = 0;
-       uint32_t bits_count = 0;
-
-       /* Will copy the header parts for CRC-8 calculation here */
-       uint8_t crc_header[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-       int crc_pos = 0;
-
-       uint32_t audio_sample;
-
-       int ch, sb, blk;        /* channel, subband, block and bit counters */
-       int bits[2][8];         /* bits distribution */
-       uint32_t levels[2][8];  /* levels are derived from that */
-       uint32_t sb_sample_delta[2][8];
-
-       data[0] = SBC_SYNCWORD;
-
-       data[1] = (frame->frequency & 0x03) << 6;
-
-       data[1] |= (frame->block_mode & 0x03) << 4;
-
-       data[1] |= (frame->mode & 0x03) << 2;
-
-       data[1] |= (frame->allocation & 0x01) << 1;
-
-       switch (frame_subbands) {
-       case 4:
-               /* Nothing to do */
-               break;
-       case 8:
-               data[1] |= 0x01;
-               break;
-       default:
-               return -4;
-               break;
-       }
-
-       data[2] = frame->bitpool;
-
-       if ((frame->mode == MONO || frame->mode == DUAL_CHANNEL) &&
-                       frame->bitpool > frame_subbands << 4)
-               return -5;
-
-       if ((frame->mode == STEREO || frame->mode == JOINT_STEREO) &&
-                       frame->bitpool > frame_subbands << 5)
-               return -5;
-
-       /* Can't fill in crc yet */
-
-       crc_header[0] = data[1];
-       crc_header[1] = data[2];
-       crc_pos = 16;
-
-       if (frame->mode == JOINT_STEREO) {
-               PUT_BITS(data_ptr, bits_cache, bits_count,
-                       joint, frame_subbands);
-               crc_header[crc_pos >> 3] = joint;
-               crc_pos += frame_subbands;
-       }
-
-       for (ch = 0; ch < frame_channels; ch++) {
-               for (sb = 0; sb < frame_subbands; sb++) {
-                       PUT_BITS(data_ptr, bits_cache, bits_count,
-                               frame->scale_factor[ch][sb] & 0x0F, 4);
-                       crc_header[crc_pos >> 3] <<= 4;
-                       crc_header[crc_pos >> 3] |= frame->scale_factor[ch][sb] & 0x0F;
-                       crc_pos += 4;
-               }
-       }
-
-       /* align the last crc byte */
-       if (crc_pos % 8)
-               crc_header[crc_pos >> 3] <<= 8 - (crc_pos % 8);
-
-       data[3] = sbc_crc8(crc_header, crc_pos);
-
-       sbc_calculate_bits(frame, bits);
-
-       for (ch = 0; ch < frame_channels; ch++) {
-               for (sb = 0; sb < frame_subbands; sb++) {
-                       levels[ch][sb] = ((1 << bits[ch][sb]) - 1) <<
-                               (32 - (frame->scale_factor[ch][sb] +
-                                       SCALE_OUT_BITS + 2));
-                       sb_sample_delta[ch][sb] = (uint32_t) 1 <<
-                               (frame->scale_factor[ch][sb] +
-                                       SCALE_OUT_BITS + 1);
-               }
-       }
-
-       for (blk = 0; blk < frame->blocks; blk++) {
-               for (ch = 0; ch < frame_channels; ch++) {
-                       for (sb = 0; sb < frame_subbands; sb++) {
-
-                               if (bits[ch][sb] == 0)
-                                       continue;
-
-                               audio_sample = ((uint64_t) levels[ch][sb] *
-                                       (sb_sample_delta[ch][sb] +
-                                       frame->sb_sample_f[blk][ch][sb])) >> 32;
-
-                               PUT_BITS(data_ptr, bits_cache, bits_count,
-                                       audio_sample, bits[ch][sb]);
-                       }
-               }
-       }
-
-       FLUSH_BITS(data_ptr, bits_cache, bits_count);
-
-       return data_ptr - data;
-}
-
-static ssize_t sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len,
-                                                               int joint)
-{
-       if (frame->subbands == 4) {
-               if (frame->channels == 1)
-                       return sbc_pack_frame_internal(
-                               data, frame, len, 4, 1, joint);
-               else
-                       return sbc_pack_frame_internal(
-                               data, frame, len, 4, 2, joint);
-       } else {
-               if (frame->channels == 1)
-                       return sbc_pack_frame_internal(
-                               data, frame, len, 8, 1, joint);
-               else
-                       return sbc_pack_frame_internal(
-                               data, frame, len, 8, 2, joint);
-       }
-}
-
-static void sbc_encoder_init(struct sbc_encoder_state *state,
-                                       const struct sbc_frame *frame)
-{
-       memset(&state->X, 0, sizeof(state->X));
-       state->position = (SBC_X_BUFFER_SIZE - frame->subbands * 9) & ~7;
-
-       sbc_init_primitives(state);
-}
-
-struct sbc_priv {
-       int init;
-       struct SBC_ALIGNED sbc_frame frame;
-       struct SBC_ALIGNED sbc_decoder_state dec_state;
-       struct SBC_ALIGNED sbc_encoder_state enc_state;
-};
-
-static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
-{
-       sbc->frequency = SBC_FREQ_44100;
-       sbc->mode = SBC_MODE_STEREO;
-       sbc->subbands = SBC_SB_8;
-       sbc->blocks = SBC_BLK_16;
-       sbc->bitpool = 32;
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-       sbc->endian = SBC_LE;
-#elif __BYTE_ORDER == __BIG_ENDIAN
-       sbc->endian = SBC_BE;
-#else
-#error "Unknown byte order"
-#endif
-}
-
-int sbc_init(sbc_t *sbc, unsigned long flags)
-{
-       if (!sbc)
-               return -EIO;
-
-       memset(sbc, 0, sizeof(sbc_t));
-
-       sbc->priv_alloc_base = malloc(sizeof(struct sbc_priv) + SBC_ALIGN_MASK);
-       if (!sbc->priv_alloc_base)
-               return -ENOMEM;
-
-       sbc->priv = (void *) (((uintptr_t) sbc->priv_alloc_base +
-                       SBC_ALIGN_MASK) & ~((uintptr_t) SBC_ALIGN_MASK));
-
-       memset(sbc->priv, 0, sizeof(struct sbc_priv));
-
-       sbc_set_defaults(sbc, flags);
-
-       return 0;
-}
-
-ssize_t sbc_parse(sbc_t *sbc, const void *input, size_t input_len)
-{
-       return sbc_decode(sbc, input, input_len, NULL, 0, NULL);
-}
-
-ssize_t sbc_decode(sbc_t *sbc, const void *input, size_t input_len,
-                       void *output, size_t output_len, size_t *written)
-{
-       struct sbc_priv *priv;
-       char *ptr;
-       int i, ch, framelen, samples;
-
-       if (!sbc || !input)
-               return -EIO;
-
-       priv = sbc->priv;
-
-       framelen = sbc_unpack_frame(input, &priv->frame, input_len);
-
-       if (!priv->init) {
-               sbc_decoder_init(&priv->dec_state, &priv->frame);
-               priv->init = 1;
-
-               sbc->frequency = priv->frame.frequency;
-               sbc->mode = priv->frame.mode;
-               sbc->subbands = priv->frame.subband_mode;
-               sbc->blocks = priv->frame.block_mode;
-               sbc->allocation = priv->frame.allocation;
-               sbc->bitpool = priv->frame.bitpool;
-
-               priv->frame.codesize = sbc_get_codesize(sbc);
-               priv->frame.length = framelen;
-       } else if (priv->frame.bitpool != sbc->bitpool) {
-               priv->frame.length = framelen;
-               sbc->bitpool = priv->frame.bitpool;
-       }
-
-       if (!output)
-               return framelen;
-
-       if (written)
-               *written = 0;
-
-       if (framelen <= 0)
-               return framelen;
-
-       samples = sbc_synthesize_audio(&priv->dec_state, &priv->frame);
-
-       ptr = output;
-
-       if (output_len < (size_t) (samples * priv->frame.channels * 2))
-               samples = output_len / (priv->frame.channels * 2);
-
-       for (i = 0; i < samples; i++) {
-               for (ch = 0; ch < priv->frame.channels; ch++) {
-                       int16_t s;
-                       s = priv->frame.pcm_sample[ch][i];
-
-                       if (sbc->endian == SBC_BE) {
-                               *ptr++ = (s & 0xff00) >> 8;
-                               *ptr++ = (s & 0x00ff);
-                       } else {
-                               *ptr++ = (s & 0x00ff);
-                               *ptr++ = (s & 0xff00) >> 8;
-                       }
-               }
-       }
-
-       if (written)
-               *written = samples * priv->frame.channels * 2;
-
-       return framelen;
-}
-
-ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len,
-                       void *output, size_t output_len, ssize_t *written)
-{
-       struct sbc_priv *priv;
-       int samples;
-       ssize_t framelen;
-       int (*sbc_enc_process_input)(int position,
-                       const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
-                       int nsamples, int nchannels);
-
-       if (!sbc || !input)
-               return -EIO;
-
-       priv = sbc->priv;
-
-       if (written)
-               *written = 0;
-
-       if (!priv->init) {
-               priv->frame.frequency = sbc->frequency;
-               priv->frame.mode = sbc->mode;
-               priv->frame.channels = sbc->mode == SBC_MODE_MONO ? 1 : 2;
-               priv->frame.allocation = sbc->allocation;
-               priv->frame.subband_mode = sbc->subbands;
-               priv->frame.subbands = sbc->subbands ? 8 : 4;
-               priv->frame.block_mode = sbc->blocks;
-               priv->frame.blocks = 4 + (sbc->blocks * 4);
-               priv->frame.bitpool = sbc->bitpool;
-               priv->frame.codesize = sbc_get_codesize(sbc);
-               priv->frame.length = sbc_get_frame_length(sbc);
-
-               sbc_encoder_init(&priv->enc_state, &priv->frame);
-               priv->init = 1;
-       } else if (priv->frame.bitpool != sbc->bitpool) {
-               priv->frame.length = sbc_get_frame_length(sbc);
-               priv->frame.bitpool = sbc->bitpool;
-       }
-
-       /* input must be large enough to encode a complete frame */
-       if (input_len < priv->frame.codesize)
-               return 0;
-
-       /* output must be large enough to receive the encoded frame */
-       if (!output || output_len < priv->frame.length)
-               return -ENOSPC;
-
-       /* Select the needed input data processing function and call it */
-       if (priv->frame.subbands == 8) {
-               if (sbc->endian == SBC_BE)
-                       sbc_enc_process_input =
-                               priv->enc_state.sbc_enc_process_input_8s_be;
-               else
-                       sbc_enc_process_input =
-                               priv->enc_state.sbc_enc_process_input_8s_le;
-       } else {
-               if (sbc->endian == SBC_BE)
-                       sbc_enc_process_input =
-                               priv->enc_state.sbc_enc_process_input_4s_be;
-               else
-                       sbc_enc_process_input =
-                               priv->enc_state.sbc_enc_process_input_4s_le;
-       }
-
-       priv->enc_state.position = sbc_enc_process_input(
-               priv->enc_state.position, (const uint8_t *) input,
-               priv->enc_state.X, priv->frame.subbands * priv->frame.blocks,
-               priv->frame.channels);
-
-       samples = sbc_analyze_audio(&priv->enc_state, &priv->frame);
-
-       if (priv->frame.mode == JOINT_STEREO) {
-               int j = priv->enc_state.sbc_calc_scalefactors_j(
-                       priv->frame.sb_sample_f, priv->frame.scale_factor,
-                       priv->frame.blocks, priv->frame.subbands);
-               framelen = sbc_pack_frame(output, &priv->frame, output_len, j);
-       } else {
-               priv->enc_state.sbc_calc_scalefactors(
-                       priv->frame.sb_sample_f, priv->frame.scale_factor,
-                       priv->frame.blocks, priv->frame.channels,
-                       priv->frame.subbands);
-               framelen = sbc_pack_frame(output, &priv->frame, output_len, 0);
-       }
-
-       if (written)
-               *written = framelen;
-
-       return samples * priv->frame.channels * 2;
-}
-
-void sbc_finish(sbc_t *sbc)
-{
-       if (!sbc)
-               return;
-
-       free(sbc->priv_alloc_base);
-
-       memset(sbc, 0, sizeof(sbc_t));
-}
-
-size_t sbc_get_frame_length(sbc_t *sbc)
-{
-       int ret;
-       uint8_t subbands, channels, blocks, joint, bitpool;
-       struct sbc_priv *priv;
-
-       priv = sbc->priv;
-       if (priv->init && priv->frame.bitpool == sbc->bitpool)
-               return priv->frame.length;
-
-       subbands = sbc->subbands ? 8 : 4;
-       blocks = 4 + (sbc->blocks * 4);
-       channels = sbc->mode == SBC_MODE_MONO ? 1 : 2;
-       joint = sbc->mode == SBC_MODE_JOINT_STEREO ? 1 : 0;
-       bitpool = sbc->bitpool;
-
-       ret = 4 + (4 * subbands * channels) / 8;
-       /* This term is not always evenly divide so we round it up */
-       if (channels == 1)
-               ret += ((blocks * channels * bitpool) + 7) / 8;
-       else
-               ret += (((joint ? subbands : 0) + blocks * bitpool) + 7) / 8;
-
-       return ret;
-}
-
-unsigned sbc_get_frame_duration(sbc_t *sbc)
-{
-       uint8_t subbands, blocks;
-       uint16_t frequency;
-       struct sbc_priv *priv;
-
-       priv = sbc->priv;
-       if (!priv->init) {
-               subbands = sbc->subbands ? 8 : 4;
-               blocks = 4 + (sbc->blocks * 4);
-       } else {
-               subbands = priv->frame.subbands;
-               blocks = priv->frame.blocks;
-       }
-
-       switch (sbc->frequency) {
-       case SBC_FREQ_16000:
-               frequency = 16000;
-               break;
-
-       case SBC_FREQ_32000:
-               frequency = 32000;
-               break;
-
-       case SBC_FREQ_44100:
-               frequency = 44100;
-               break;
-
-       case SBC_FREQ_48000:
-               frequency = 48000;
-               break;
-       default:
-               return 0;
-       }
-
-       return (1000000 * blocks * subbands) / frequency;
-}
-
-size_t sbc_get_codesize(sbc_t *sbc)
-{
-       uint16_t subbands, channels, blocks;
-       struct sbc_priv *priv;
-
-       priv = sbc->priv;
-       if (!priv->init) {
-               subbands = sbc->subbands ? 8 : 4;
-               blocks = 4 + (sbc->blocks * 4);
-               channels = sbc->mode == SBC_MODE_MONO ? 1 : 2;
-       } else {
-               subbands = priv->frame.subbands;
-               blocks = priv->frame.blocks;
-               channels = priv->frame.channels;
-       }
-
-       return subbands * blocks * channels * 2;
-}
-
-const char *sbc_get_implementation_info(sbc_t *sbc)
-{
-       struct sbc_priv *priv;
-
-       if (!sbc)
-               return NULL;
-
-       priv = sbc->priv;
-       if (!priv)
-               return NULL;
-
-       return priv->enc_state.implementation_info;
-}
-
-int sbc_reinit(sbc_t *sbc, unsigned long flags)
-{
-       struct sbc_priv *priv;
-
-       if (!sbc || !sbc->priv)
-               return -EIO;
-
-       priv = sbc->priv;
-
-       if (priv->init == 1)
-               memset(sbc->priv, 0, sizeof(struct sbc_priv));
-
-       sbc_set_defaults(sbc, flags);
-
-       return 0;
-}
diff --git a/src/modules/bluetooth/sbc/sbc.h b/src/modules/bluetooth/sbc/sbc.h
deleted file mode 100644 (file)
index 2f830ad..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *
- *  Bluetooth low-complexity, subband codec (SBC) library
- *
- *  Copyright (C) 2008-2010  Nokia Corporation
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
- *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef __SBC_H
-#define __SBC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-#include <sys/types.h>
-
-/* sampling frequency */
-#define SBC_FREQ_16000         0x00
-#define SBC_FREQ_32000         0x01
-#define SBC_FREQ_44100         0x02
-#define SBC_FREQ_48000         0x03
-
-/* blocks */
-#define SBC_BLK_4              0x00
-#define SBC_BLK_8              0x01
-#define SBC_BLK_12             0x02
-#define SBC_BLK_16             0x03
-
-/* channel mode */
-#define SBC_MODE_MONO          0x00
-#define SBC_MODE_DUAL_CHANNEL  0x01
-#define SBC_MODE_STEREO                0x02
-#define SBC_MODE_JOINT_STEREO  0x03
-
-/* allocation method */
-#define SBC_AM_LOUDNESS                0x00
-#define SBC_AM_SNR             0x01
-
-/* subbands */
-#define SBC_SB_4               0x00
-#define SBC_SB_8               0x01
-
-/* Data endianess */
-#define SBC_LE                 0x00
-#define SBC_BE                 0x01
-
-struct sbc_struct {
-       unsigned long flags;
-
-       uint8_t frequency;
-       uint8_t blocks;
-       uint8_t subbands;
-       uint8_t mode;
-       uint8_t allocation;
-       uint8_t bitpool;
-       uint8_t endian;
-
-       void *priv;
-       void *priv_alloc_base;
-};
-
-typedef struct sbc_struct sbc_t;
-
-int sbc_init(sbc_t *sbc, unsigned long flags);
-int sbc_reinit(sbc_t *sbc, unsigned long flags);
-
-ssize_t sbc_parse(sbc_t *sbc, const void *input, size_t input_len);
-
-/* Decodes ONE input block into ONE output block */
-ssize_t sbc_decode(sbc_t *sbc, const void *input, size_t input_len,
-                       void *output, size_t output_len, size_t *written);
-
-/* Encodes ONE input block into ONE output block */
-ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len,
-                       void *output, size_t output_len, ssize_t *written);
-
-/* Returns the output block size in bytes */
-size_t sbc_get_frame_length(sbc_t *sbc);
-
-/* Returns the time one input/output block takes to play in msec*/
-unsigned sbc_get_frame_duration(sbc_t *sbc);
-
-/* Returns the input block size in bytes */
-size_t sbc_get_codesize(sbc_t *sbc);
-
-const char *sbc_get_implementation_info(sbc_t *sbc);
-void sbc_finish(sbc_t *sbc);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __SBC_H */
diff --git a/src/modules/bluetooth/sbc/sbc_math.h b/src/modules/bluetooth/sbc/sbc_math.h
deleted file mode 100644 (file)
index 5476860..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *
- *  Bluetooth low-complexity, subband codec (SBC) library
- *
- *  Copyright (C) 2008-2010  Nokia Corporation
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
- *  Copyright (C) 2005-2008  Brad Midgley <bmidgley@xmission.com>
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#define fabs(x) ((x) < 0 ? -(x) : (x))
-/* C does not provide an explicit arithmetic shift right but this will
-   always be correct and every compiler *should* generate optimal code */
-#define ASR(val, bits) ((-2 >> 1 == -1) ? \
-                ((int32_t)(val)) >> (bits) : ((int32_t) (val)) / (1 << (bits)))
-
-#define SCALE_SPROTO4_TBL      12
-#define SCALE_SPROTO8_TBL      14
-#define SCALE_NPROTO4_TBL      11
-#define SCALE_NPROTO8_TBL      11
-#define SCALE4_STAGED1_BITS    15
-#define SCALE4_STAGED2_BITS    16
-#define SCALE8_STAGED1_BITS    15
-#define SCALE8_STAGED2_BITS    16
-
-typedef int32_t sbc_fixed_t;
-
-#define SCALE4_STAGED1(src) ASR(src, SCALE4_STAGED1_BITS)
-#define SCALE4_STAGED2(src) ASR(src, SCALE4_STAGED2_BITS)
-#define SCALE8_STAGED1(src) ASR(src, SCALE8_STAGED1_BITS)
-#define SCALE8_STAGED2(src) ASR(src, SCALE8_STAGED2_BITS)
-
-#define SBC_FIXED_0(val) { val = 0; }
-#define MUL(a, b)        ((a) * (b))
-#if defined(__arm__) && (!defined(__thumb__) || defined(__thumb2__))
-#define MULA(a, b, res) ({                             \
-               int tmp = res;                  \
-               __asm__(                                \
-                       "mla %0, %2, %3, %0"            \
-                       : "=&r" (tmp)                   \
-                       : "0" (tmp), "r" (a), "r" (b)); \
-               tmp; })
-#else
-#define MULA(a, b, res)  ((a) * (b) + (res))
-#endif
diff --git a/src/modules/bluetooth/sbc/sbc_primitives.c b/src/modules/bluetooth/sbc/sbc_primitives.c
deleted file mode 100644 (file)
index ad780d0..0000000
+++ /dev/null
@@ -1,554 +0,0 @@
-/*
- *
- *  Bluetooth low-complexity, subband codec (SBC) library
- *
- *  Copyright (C) 2008-2010  Nokia Corporation
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
- *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include <stdint.h>
-#include <limits.h>
-#include <string.h>
-#include "sbc.h"
-#include "sbc_math.h"
-#include "sbc_tables.h"
-
-#include "sbc_primitives.h"
-#include "sbc_primitives_mmx.h"
-#include "sbc_primitives_iwmmxt.h"
-#include "sbc_primitives_neon.h"
-#include "sbc_primitives_armv6.h"
-
-/*
- * A reference C code of analysis filter with SIMD-friendly tables
- * reordering and code layout. This code can be used to develop platform
- * specific SIMD optimizations. Also it may be used as some kind of test
- * for compiler autovectorization capabilities (who knows, if the compiler
- * is very good at this stuff, hand optimized assembly may be not strictly
- * needed for some platform).
- *
- * Note: It is also possible to make a simple variant of analysis filter,
- * which needs only a single constants table without taking care about
- * even/odd cases. This simple variant of filter can be implemented without
- * input data permutation. The only thing that would be lost is the
- * possibility to use pairwise SIMD multiplications. But for some simple
- * CPU cores without SIMD extensions it can be useful. If anybody is
- * interested in implementing such variant of a filter, sourcecode from
- * bluez versions 4.26/4.27 can be used as a reference and the history of
- * the changes in git repository done around that time may be worth checking.
- */
-
-static inline void sbc_analyze_four_simd(const int16_t *in, int32_t *out,
-                                                       const FIXED_T *consts)
-{
-       FIXED_A t1[4];
-       FIXED_T t2[4];
-       int hop = 0;
-
-       /* rounding coefficient */
-       t1[0] = t1[1] = t1[2] = t1[3] =
-               (FIXED_A) 1 << (SBC_PROTO_FIXED4_SCALE - 1);
-
-       /* low pass polyphase filter */
-       for (hop = 0; hop < 40; hop += 8) {
-               t1[0] += (FIXED_A) in[hop] * consts[hop];
-               t1[0] += (FIXED_A) in[hop + 1] * consts[hop + 1];
-               t1[1] += (FIXED_A) in[hop + 2] * consts[hop + 2];
-               t1[1] += (FIXED_A) in[hop + 3] * consts[hop + 3];
-               t1[2] += (FIXED_A) in[hop + 4] * consts[hop + 4];
-               t1[2] += (FIXED_A) in[hop + 5] * consts[hop + 5];
-               t1[3] += (FIXED_A) in[hop + 6] * consts[hop + 6];
-               t1[3] += (FIXED_A) in[hop + 7] * consts[hop + 7];
-       }
-
-       /* scaling */
-       t2[0] = t1[0] >> SBC_PROTO_FIXED4_SCALE;
-       t2[1] = t1[1] >> SBC_PROTO_FIXED4_SCALE;
-       t2[2] = t1[2] >> SBC_PROTO_FIXED4_SCALE;
-       t2[3] = t1[3] >> SBC_PROTO_FIXED4_SCALE;
-
-       /* do the cos transform */
-       t1[0]  = (FIXED_A) t2[0] * consts[40 + 0];
-       t1[0] += (FIXED_A) t2[1] * consts[40 + 1];
-       t1[1]  = (FIXED_A) t2[0] * consts[40 + 2];
-       t1[1] += (FIXED_A) t2[1] * consts[40 + 3];
-       t1[2]  = (FIXED_A) t2[0] * consts[40 + 4];
-       t1[2] += (FIXED_A) t2[1] * consts[40 + 5];
-       t1[3]  = (FIXED_A) t2[0] * consts[40 + 6];
-       t1[3] += (FIXED_A) t2[1] * consts[40 + 7];
-
-       t1[0] += (FIXED_A) t2[2] * consts[40 + 8];
-       t1[0] += (FIXED_A) t2[3] * consts[40 + 9];
-       t1[1] += (FIXED_A) t2[2] * consts[40 + 10];
-       t1[1] += (FIXED_A) t2[3] * consts[40 + 11];
-       t1[2] += (FIXED_A) t2[2] * consts[40 + 12];
-       t1[2] += (FIXED_A) t2[3] * consts[40 + 13];
-       t1[3] += (FIXED_A) t2[2] * consts[40 + 14];
-       t1[3] += (FIXED_A) t2[3] * consts[40 + 15];
-
-       out[0] = t1[0] >>
-               (SBC_COS_TABLE_FIXED4_SCALE - SCALE_OUT_BITS);
-       out[1] = t1[1] >>
-               (SBC_COS_TABLE_FIXED4_SCALE - SCALE_OUT_BITS);
-       out[2] = t1[2] >>
-               (SBC_COS_TABLE_FIXED4_SCALE - SCALE_OUT_BITS);
-       out[3] = t1[3] >>
-               (SBC_COS_TABLE_FIXED4_SCALE - SCALE_OUT_BITS);
-}
-
-static inline void sbc_analyze_eight_simd(const int16_t *in, int32_t *out,
-                                                       const FIXED_T *consts)
-{
-       FIXED_A t1[8];
-       FIXED_T t2[8];
-       int i, hop;
-
-       /* rounding coefficient */
-       t1[0] = t1[1] = t1[2] = t1[3] = t1[4] = t1[5] = t1[6] = t1[7] =
-               (FIXED_A) 1 << (SBC_PROTO_FIXED8_SCALE-1);
-
-       /* low pass polyphase filter */
-       for (hop = 0; hop < 80; hop += 16) {
-               t1[0] += (FIXED_A) in[hop] * consts[hop];
-               t1[0] += (FIXED_A) in[hop + 1] * consts[hop + 1];
-               t1[1] += (FIXED_A) in[hop + 2] * consts[hop + 2];
-               t1[1] += (FIXED_A) in[hop + 3] * consts[hop + 3];
-               t1[2] += (FIXED_A) in[hop + 4] * consts[hop + 4];
-               t1[2] += (FIXED_A) in[hop + 5] * consts[hop + 5];
-               t1[3] += (FIXED_A) in[hop + 6] * consts[hop + 6];
-               t1[3] += (FIXED_A) in[hop + 7] * consts[hop + 7];
-               t1[4] += (FIXED_A) in[hop + 8] * consts[hop + 8];
-               t1[4] += (FIXED_A) in[hop + 9] * consts[hop + 9];
-               t1[5] += (FIXED_A) in[hop + 10] * consts[hop + 10];
-               t1[5] += (FIXED_A) in[hop + 11] * consts[hop + 11];
-               t1[6] += (FIXED_A) in[hop + 12] * consts[hop + 12];
-               t1[6] += (FIXED_A) in[hop + 13] * consts[hop + 13];
-               t1[7] += (FIXED_A) in[hop + 14] * consts[hop + 14];
-               t1[7] += (FIXED_A) in[hop + 15] * consts[hop + 15];
-       }
-
-       /* scaling */
-       t2[0] = t1[0] >> SBC_PROTO_FIXED8_SCALE;
-       t2[1] = t1[1] >> SBC_PROTO_FIXED8_SCALE;
-       t2[2] = t1[2] >> SBC_PROTO_FIXED8_SCALE;
-       t2[3] = t1[3] >> SBC_PROTO_FIXED8_SCALE;
-       t2[4] = t1[4] >> SBC_PROTO_FIXED8_SCALE;
-       t2[5] = t1[5] >> SBC_PROTO_FIXED8_SCALE;
-       t2[6] = t1[6] >> SBC_PROTO_FIXED8_SCALE;
-       t2[7] = t1[7] >> SBC_PROTO_FIXED8_SCALE;
-
-
-       /* do the cos transform */
-       t1[0] = t1[1] = t1[2] = t1[3] = t1[4] = t1[5] = t1[6] = t1[7] = 0;
-
-       for (i = 0; i < 4; i++) {
-               t1[0] += (FIXED_A) t2[i * 2 + 0] * consts[80 + i * 16 + 0];
-               t1[0] += (FIXED_A) t2[i * 2 + 1] * consts[80 + i * 16 + 1];
-               t1[1] += (FIXED_A) t2[i * 2 + 0] * consts[80 + i * 16 + 2];
-               t1[1] += (FIXED_A) t2[i * 2 + 1] * consts[80 + i * 16 + 3];
-               t1[2] += (FIXED_A) t2[i * 2 + 0] * consts[80 + i * 16 + 4];
-               t1[2] += (FIXED_A) t2[i * 2 + 1] * consts[80 + i * 16 + 5];
-               t1[3] += (FIXED_A) t2[i * 2 + 0] * consts[80 + i * 16 + 6];
-               t1[3] += (FIXED_A) t2[i * 2 + 1] * consts[80 + i * 16 + 7];
-               t1[4] += (FIXED_A) t2[i * 2 + 0] * consts[80 + i * 16 + 8];
-               t1[4] += (FIXED_A) t2[i * 2 + 1] * consts[80 + i * 16 + 9];
-               t1[5] += (FIXED_A) t2[i * 2 + 0] * consts[80 + i * 16 + 10];
-               t1[5] += (FIXED_A) t2[i * 2 + 1] * consts[80 + i * 16 + 11];
-               t1[6] += (FIXED_A) t2[i * 2 + 0] * consts[80 + i * 16 + 12];
-               t1[6] += (FIXED_A) t2[i * 2 + 1] * consts[80 + i * 16 + 13];
-               t1[7] += (FIXED_A) t2[i * 2 + 0] * consts[80 + i * 16 + 14];
-               t1[7] += (FIXED_A) t2[i * 2 + 1] * consts[80 + i * 16 + 15];
-       }
-
-       for (i = 0; i < 8; i++)
-               out[i] = t1[i] >>
-                       (SBC_COS_TABLE_FIXED8_SCALE - SCALE_OUT_BITS);
-}
-
-static inline void sbc_analyze_4b_4s_simd(int16_t *x,
-                                               int32_t *out, int out_stride)
-{
-       /* Analyze blocks */
-       sbc_analyze_four_simd(x + 12, out, analysis_consts_fixed4_simd_odd);
-       out += out_stride;
-       sbc_analyze_four_simd(x + 8, out, analysis_consts_fixed4_simd_even);
-       out += out_stride;
-       sbc_analyze_four_simd(x + 4, out, analysis_consts_fixed4_simd_odd);
-       out += out_stride;
-       sbc_analyze_four_simd(x + 0, out, analysis_consts_fixed4_simd_even);
-}
-
-static inline void sbc_analyze_4b_8s_simd(int16_t *x,
-                                         int32_t *out, int out_stride)
-{
-       /* Analyze blocks */
-       sbc_analyze_eight_simd(x + 24, out, analysis_consts_fixed8_simd_odd);
-       out += out_stride;
-       sbc_analyze_eight_simd(x + 16, out, analysis_consts_fixed8_simd_even);
-       out += out_stride;
-       sbc_analyze_eight_simd(x + 8, out, analysis_consts_fixed8_simd_odd);
-       out += out_stride;
-       sbc_analyze_eight_simd(x + 0, out, analysis_consts_fixed8_simd_even);
-}
-
-static inline int16_t unaligned16_be(const uint8_t *ptr)
-{
-       return (int16_t) ((ptr[0] << 8) | ptr[1]);
-}
-
-static inline int16_t unaligned16_le(const uint8_t *ptr)
-{
-       return (int16_t) (ptr[0] | (ptr[1] << 8));
-}
-
-/*
- * Internal helper functions for input data processing. In order to get
- * optimal performance, it is important to have "nsamples", "nchannels"
- * and "big_endian" arguments used with this inline function as compile
- * time constants.
- */
-
-static SBC_ALWAYS_INLINE int sbc_encoder_process_input_s4_internal(
-       int position,
-       const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
-       int nsamples, int nchannels, int big_endian)
-{
-       /* handle X buffer wraparound */
-       if (position < nsamples) {
-               if (nchannels > 0)
-                       memcpy(&X[0][SBC_X_BUFFER_SIZE - 40], &X[0][position],
-                                                       36 * sizeof(int16_t));
-               if (nchannels > 1)
-                       memcpy(&X[1][SBC_X_BUFFER_SIZE - 40], &X[1][position],
-                                                       36 * sizeof(int16_t));
-               position = SBC_X_BUFFER_SIZE - 40;
-       }
-
-       #define PCM(i) (big_endian ? \
-               unaligned16_be(pcm + (i) * 2) : unaligned16_le(pcm + (i) * 2))
-
-       /* copy/permutate audio samples */
-       while ((nsamples -= 8) >= 0) {
-               position -= 8;
-               if (nchannels > 0) {
-                       int16_t *x = &X[0][position];
-                       x[0]  = PCM(0 + 7 * nchannels);
-                       x[1]  = PCM(0 + 3 * nchannels);
-                       x[2]  = PCM(0 + 6 * nchannels);
-                       x[3]  = PCM(0 + 4 * nchannels);
-                       x[4]  = PCM(0 + 0 * nchannels);
-                       x[5]  = PCM(0 + 2 * nchannels);
-                       x[6]  = PCM(0 + 1 * nchannels);
-                       x[7]  = PCM(0 + 5 * nchannels);
-               }
-               if (nchannels > 1) {
-                       int16_t *x = &X[1][position];
-                       x[0]  = PCM(1 + 7 * nchannels);
-                       x[1]  = PCM(1 + 3 * nchannels);
-                       x[2]  = PCM(1 + 6 * nchannels);
-                       x[3]  = PCM(1 + 4 * nchannels);
-                       x[4]  = PCM(1 + 0 * nchannels);
-                       x[5]  = PCM(1 + 2 * nchannels);
-                       x[6]  = PCM(1 + 1 * nchannels);
-                       x[7]  = PCM(1 + 5 * nchannels);
-               }
-               pcm += 16 * nchannels;
-       }
-       #undef PCM
-
-       return position;
-}
-
-static SBC_ALWAYS_INLINE int sbc_encoder_process_input_s8_internal(
-       int position,
-       const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
-       int nsamples, int nchannels, int big_endian)
-{
-       /* handle X buffer wraparound */
-       if (position < nsamples) {
-               if (nchannels > 0)
-                       memcpy(&X[0][SBC_X_BUFFER_SIZE - 72], &X[0][position],
-                                                       72 * sizeof(int16_t));
-               if (nchannels > 1)
-                       memcpy(&X[1][SBC_X_BUFFER_SIZE - 72], &X[1][position],
-                                                       72 * sizeof(int16_t));
-               position = SBC_X_BUFFER_SIZE - 72;
-       }
-
-       #define PCM(i) (big_endian ? \
-               unaligned16_be(pcm + (i) * 2) : unaligned16_le(pcm + (i) * 2))
-
-       /* copy/permutate audio samples */
-       while ((nsamples -= 16) >= 0) {
-               position -= 16;
-               if (nchannels > 0) {
-                       int16_t *x = &X[0][position];
-                       x[0]  = PCM(0 + 15 * nchannels);
-                       x[1]  = PCM(0 + 7 * nchannels);
-                       x[2]  = PCM(0 + 14 * nchannels);
-                       x[3]  = PCM(0 + 8 * nchannels);
-                       x[4]  = PCM(0 + 13 * nchannels);
-                       x[5]  = PCM(0 + 9 * nchannels);
-                       x[6]  = PCM(0 + 12 * nchannels);
-                       x[7]  = PCM(0 + 10 * nchannels);
-                       x[8]  = PCM(0 + 11 * nchannels);
-                       x[9]  = PCM(0 + 3 * nchannels);
-                       x[10] = PCM(0 + 6 * nchannels);
-                       x[11] = PCM(0 + 0 * nchannels);
-                       x[12] = PCM(0 + 5 * nchannels);
-                       x[13] = PCM(0 + 1 * nchannels);
-                       x[14] = PCM(0 + 4 * nchannels);
-                       x[15] = PCM(0 + 2 * nchannels);
-               }
-               if (nchannels > 1) {
-                       int16_t *x = &X[1][position];
-                       x[0]  = PCM(1 + 15 * nchannels);
-                       x[1]  = PCM(1 + 7 * nchannels);
-                       x[2]  = PCM(1 + 14 * nchannels);
-                       x[3]  = PCM(1 + 8 * nchannels);
-                       x[4]  = PCM(1 + 13 * nchannels);
-                       x[5]  = PCM(1 + 9 * nchannels);
-                       x[6]  = PCM(1 + 12 * nchannels);
-                       x[7]  = PCM(1 + 10 * nchannels);
-                       x[8]  = PCM(1 + 11 * nchannels);
-                       x[9]  = PCM(1 + 3 * nchannels);
-                       x[10] = PCM(1 + 6 * nchannels);
-                       x[11] = PCM(1 + 0 * nchannels);
-                       x[12] = PCM(1 + 5 * nchannels);
-                       x[13] = PCM(1 + 1 * nchannels);
-                       x[14] = PCM(1 + 4 * nchannels);
-                       x[15] = PCM(1 + 2 * nchannels);
-               }
-               pcm += 32 * nchannels;
-       }
-       #undef PCM
-
-       return position;
-}
-
-/*
- * Input data processing functions. The data is endian converted if needed,
- * channels are deintrleaved and audio samples are reordered for use in
- * SIMD-friendly analysis filter function. The results are put into "X"
- * array, getting appended to the previous data (or it is better to say
- * prepended, as the buffer is filled from top to bottom). Old data is
- * discarded when neededed, but availability of (10 * nrof_subbands)
- * contiguous samples is always guaranteed for the input to the analysis
- * filter. This is achieved by copying a sufficient part of old data
- * to the top of the buffer on buffer wraparound.
- */
-
-static int sbc_enc_process_input_4s_le(int position,
-               const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
-               int nsamples, int nchannels)
-{
-       if (nchannels > 1)
-               return sbc_encoder_process_input_s4_internal(
-                       position, pcm, X, nsamples, 2, 0);
-       else
-               return sbc_encoder_process_input_s4_internal(
-                       position, pcm, X, nsamples, 1, 0);
-}
-
-static int sbc_enc_process_input_4s_be(int position,
-               const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
-               int nsamples, int nchannels)
-{
-       if (nchannels > 1)
-               return sbc_encoder_process_input_s4_internal(
-                       position, pcm, X, nsamples, 2, 1);
-       else
-               return sbc_encoder_process_input_s4_internal(
-                       position, pcm, X, nsamples, 1, 1);
-}
-
-static int sbc_enc_process_input_8s_le(int position,
-               const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
-               int nsamples, int nchannels)
-{
-       if (nchannels > 1)
-               return sbc_encoder_process_input_s8_internal(
-                       position, pcm, X, nsamples, 2, 0);
-       else
-               return sbc_encoder_process_input_s8_internal(
-                       position, pcm, X, nsamples, 1, 0);
-}
-
-static int sbc_enc_process_input_8s_be(int position,
-               const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
-               int nsamples, int nchannels)
-{
-       if (nchannels > 1)
-               return sbc_encoder_process_input_s8_internal(
-                       position, pcm, X, nsamples, 2, 1);
-       else
-               return sbc_encoder_process_input_s8_internal(
-                       position, pcm, X, nsamples, 1, 1);
-}
-
-/* Supplementary function to count the number of leading zeros */
-
-static inline int sbc_clz(uint32_t x)
-{
-#ifdef __GNUC__
-       return __builtin_clz(x);
-#else
-       /* TODO: this should be replaced with something better if good
-        * performance is wanted when using compilers other than gcc */
-       int cnt = 0;
-       while (x) {
-               cnt++;
-               x >>= 1;
-       }
-       return 32 - cnt;
-#endif
-}
-
-static void sbc_calc_scalefactors(
-       int32_t sb_sample_f[16][2][8],
-       uint32_t scale_factor[2][8],
-       int blocks, int channels, int subbands)
-{
-       int ch, sb, blk;
-       for (ch = 0; ch < channels; ch++) {
-               for (sb = 0; sb < subbands; sb++) {
-                       uint32_t x = 1 << SCALE_OUT_BITS;
-                       for (blk = 0; blk < blocks; blk++) {
-                               int32_t tmp = fabs(sb_sample_f[blk][ch][sb]);
-                               if (tmp != 0)
-                                       x |= tmp - 1;
-                       }
-                       scale_factor[ch][sb] = (31 - SCALE_OUT_BITS) -
-                               sbc_clz(x);
-               }
-       }
-}
-
-static int sbc_calc_scalefactors_j(
-       int32_t sb_sample_f[16][2][8],
-       uint32_t scale_factor[2][8],
-       int blocks, int subbands)
-{
-       int blk, joint = 0;
-       int32_t tmp0, tmp1;
-       uint32_t x, y;
-
-       /* last subband does not use joint stereo */
-       int sb = subbands - 1;
-       x = 1 << SCALE_OUT_BITS;
-       y = 1 << SCALE_OUT_BITS;
-       for (blk = 0; blk < blocks; blk++) {
-               tmp0 = fabs(sb_sample_f[blk][0][sb]);
-               tmp1 = fabs(sb_sample_f[blk][1][sb]);
-               if (tmp0 != 0)
-                       x |= tmp0 - 1;
-               if (tmp1 != 0)
-                       y |= tmp1 - 1;
-       }
-       scale_factor[0][sb] = (31 - SCALE_OUT_BITS) - sbc_clz(x);
-       scale_factor[1][sb] = (31 - SCALE_OUT_BITS) - sbc_clz(y);
-
-       /* the rest of subbands can use joint stereo */
-       while (--sb >= 0) {
-               int32_t sb_sample_j[16][2];
-               x = 1 << SCALE_OUT_BITS;
-               y = 1 << SCALE_OUT_BITS;
-               for (blk = 0; blk < blocks; blk++) {
-                       tmp0 = sb_sample_f[blk][0][sb];
-                       tmp1 = sb_sample_f[blk][1][sb];
-                       sb_sample_j[blk][0] = ASR(tmp0, 1) + ASR(tmp1, 1);
-                       sb_sample_j[blk][1] = ASR(tmp0, 1) - ASR(tmp1, 1);
-                       tmp0 = fabs(tmp0);
-                       tmp1 = fabs(tmp1);
-                       if (tmp0 != 0)
-                               x |= tmp0 - 1;
-                       if (tmp1 != 0)
-                               y |= tmp1 - 1;
-               }
-               scale_factor[0][sb] = (31 - SCALE_OUT_BITS) -
-                       sbc_clz(x);
-               scale_factor[1][sb] = (31 - SCALE_OUT_BITS) -
-                       sbc_clz(y);
-               x = 1 << SCALE_OUT_BITS;
-               y = 1 << SCALE_OUT_BITS;
-               for (blk = 0; blk < blocks; blk++) {
-                       tmp0 = fabs(sb_sample_j[blk][0]);
-                       tmp1 = fabs(sb_sample_j[blk][1]);
-                       if (tmp0 != 0)
-                               x |= tmp0 - 1;
-                       if (tmp1 != 0)
-                               y |= tmp1 - 1;
-               }
-               x = (31 - SCALE_OUT_BITS) - sbc_clz(x);
-               y = (31 - SCALE_OUT_BITS) - sbc_clz(y);
-
-               /* decide whether to use joint stereo for this subband */
-               if ((scale_factor[0][sb] + scale_factor[1][sb]) > x + y) {
-                       joint |= 1 << (subbands - 1 - sb);
-                       scale_factor[0][sb] = x;
-                       scale_factor[1][sb] = y;
-                       for (blk = 0; blk < blocks; blk++) {
-                               sb_sample_f[blk][0][sb] = sb_sample_j[blk][0];
-                               sb_sample_f[blk][1][sb] = sb_sample_j[blk][1];
-                       }
-               }
-       }
-
-       /* bitmask with the information about subbands using joint stereo */
-       return joint;
-}
-
-/*
- * Detect CPU features and setup function pointers
- */
-void sbc_init_primitives(struct sbc_encoder_state *state)
-{
-       /* Default implementation for analyze functions */
-       state->sbc_analyze_4b_4s = sbc_analyze_4b_4s_simd;
-       state->sbc_analyze_4b_8s = sbc_analyze_4b_8s_simd;
-
-       /* Default implementation for input reordering / deinterleaving */
-       state->sbc_enc_process_input_4s_le = sbc_enc_process_input_4s_le;
-       state->sbc_enc_process_input_4s_be = sbc_enc_process_input_4s_be;
-       state->sbc_enc_process_input_8s_le = sbc_enc_process_input_8s_le;
-       state->sbc_enc_process_input_8s_be = sbc_enc_process_input_8s_be;
-
-       /* Default implementation for scale factors calculation */
-       state->sbc_calc_scalefactors = sbc_calc_scalefactors;
-       state->sbc_calc_scalefactors_j = sbc_calc_scalefactors_j;
-       state->implementation_info = "Generic C";
-
-       /* X86/AMD64 optimizations */
-#ifdef SBC_BUILD_WITH_MMX_SUPPORT
-       sbc_init_primitives_mmx(state);
-#endif
-
-       /* ARM optimizations */
-#ifdef SBC_BUILD_WITH_ARMV6_SUPPORT
-       sbc_init_primitives_armv6(state);
-#endif
-#ifdef SBC_BUILD_WITH_IWMMXT_SUPPORT
-       sbc_init_primitives_iwmmxt(state);
-#endif
-#ifdef SBC_BUILD_WITH_NEON_SUPPORT
-       sbc_init_primitives_neon(state);
-#endif
-}
diff --git a/src/modules/bluetooth/sbc/sbc_primitives.h b/src/modules/bluetooth/sbc/sbc_primitives.h
deleted file mode 100644 (file)
index 17ad4f7..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- *
- *  Bluetooth low-complexity, subband codec (SBC) library
- *
- *  Copyright (C) 2008-2010  Nokia Corporation
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
- *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef __SBC_PRIMITIVES_H
-#define __SBC_PRIMITIVES_H
-
-#define SCALE_OUT_BITS 15
-#define SBC_X_BUFFER_SIZE 328
-
-#ifdef __GNUC__
-#define SBC_ALWAYS_INLINE inline __attribute__((always_inline))
-#else
-#define SBC_ALWAYS_INLINE inline
-#endif
-
-struct sbc_encoder_state {
-       int position;
-       int16_t SBC_ALIGNED X[2][SBC_X_BUFFER_SIZE];
-       /* Polyphase analysis filter for 4 subbands configuration,
-        * it handles 4 blocks at once */
-       void (*sbc_analyze_4b_4s)(int16_t *x, int32_t *out, int out_stride);
-       /* Polyphase analysis filter for 8 subbands configuration,
-        * it handles 4 blocks at once */
-       void (*sbc_analyze_4b_8s)(int16_t *x, int32_t *out, int out_stride);
-       /* Process input data (deinterleave, endian conversion, reordering),
-        * depending on the number of subbands and input data byte order */
-       int (*sbc_enc_process_input_4s_le)(int position,
-                       const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
-                       int nsamples, int nchannels);
-       int (*sbc_enc_process_input_4s_be)(int position,
-                       const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
-                       int nsamples, int nchannels);
-       int (*sbc_enc_process_input_8s_le)(int position,
-                       const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
-                       int nsamples, int nchannels);
-       int (*sbc_enc_process_input_8s_be)(int position,
-                       const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
-                       int nsamples, int nchannels);
-       /* Scale factors calculation */
-       void (*sbc_calc_scalefactors)(int32_t sb_sample_f[16][2][8],
-                       uint32_t scale_factor[2][8],
-                       int blocks, int channels, int subbands);
-       /* Scale factors calculation with joint stereo support */
-       int (*sbc_calc_scalefactors_j)(int32_t sb_sample_f[16][2][8],
-                       uint32_t scale_factor[2][8],
-                       int blocks, int subbands);
-       const char *implementation_info;
-};
-
-/*
- * Initialize pointers to the functions which are the basic "building bricks"
- * of SBC codec. Best implementation is selected based on target CPU
- * capabilities.
- */
-void sbc_init_primitives(struct sbc_encoder_state *encoder_state);
-
-#endif
diff --git a/src/modules/bluetooth/sbc/sbc_primitives_armv6.c b/src/modules/bluetooth/sbc/sbc_primitives_armv6.c
deleted file mode 100644 (file)
index b321272..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- *
- *  Bluetooth low-complexity, subband codec (SBC) library
- *
- *  Copyright (C) 2008-2010  Nokia Corporation
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
- *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include <stdint.h>
-#include <limits.h>
-#include "sbc.h"
-#include "sbc_math.h"
-#include "sbc_tables.h"
-
-#include "sbc_primitives_armv6.h"
-
-/*
- * ARMv6 optimizations. The instructions are scheduled for ARM11 pipeline.
- */
-
-#ifdef SBC_BUILD_WITH_ARMV6_SUPPORT
-
-static void __attribute__((naked)) sbc_analyze_four_armv6()
-{
-       /* r0 = in, r1 = out, r2 = consts */
-       __asm__ volatile (
-               "push   {r1, r4-r7, lr}\n"
-               "push   {r8-r11}\n"
-               "ldrd   r4,  r5,  [r0, #0]\n"
-               "ldrd   r6,  r7,  [r2, #0]\n"
-               "ldrd   r8,  r9,  [r0, #16]\n"
-               "ldrd   r10, r11, [r2, #16]\n"
-               "mov    r14, #0x8000\n"
-               "smlad  r3,  r4,  r6,  r14\n"
-               "smlad  r12, r5,  r7,  r14\n"
-               "ldrd   r4,  r5,  [r0, #32]\n"
-               "ldrd   r6,  r7,  [r2, #32]\n"
-               "smlad  r3,  r8,  r10, r3\n"
-               "smlad  r12, r9,  r11, r12\n"
-               "ldrd   r8,  r9,  [r0, #48]\n"
-               "ldrd   r10, r11, [r2, #48]\n"
-               "smlad  r3,  r4,  r6,  r3\n"
-               "smlad  r12, r5,  r7,  r12\n"
-               "ldrd   r4,  r5,  [r0, #64]\n"
-               "ldrd   r6,  r7,  [r2, #64]\n"
-               "smlad  r3,  r8,  r10, r3\n"
-               "smlad  r12, r9,  r11, r12\n"
-               "ldrd   r8,  r9,  [r0, #8]\n"
-               "ldrd   r10, r11, [r2, #8]\n"
-               "smlad  r3,  r4,  r6,  r3\n"      /* t1[0] is done */
-               "smlad  r12, r5,  r7,  r12\n"     /* t1[1] is done */
-               "ldrd   r4,  r5,  [r0, #24]\n"
-               "ldrd   r6,  r7,  [r2, #24]\n"
-               "pkhtb  r3,  r12, r3, asr #16\n"  /* combine t1[0] and t1[1] */
-               "smlad  r12, r8,  r10, r14\n"
-               "smlad  r14, r9,  r11, r14\n"
-               "ldrd   r8,  r9,  [r0, #40]\n"
-               "ldrd   r10, r11, [r2, #40]\n"
-               "smlad  r12, r4,  r6,  r12\n"
-               "smlad  r14, r5,  r7,  r14\n"
-               "ldrd   r4,  r5,  [r0, #56]\n"
-               "ldrd   r6,  r7,  [r2, #56]\n"
-               "smlad  r12, r8,  r10, r12\n"
-               "smlad  r14, r9,  r11, r14\n"
-               "ldrd   r8,  r9,  [r0, #72]\n"
-               "ldrd   r10, r11, [r2, #72]\n"
-               "smlad  r12, r4,  r6,  r12\n"
-               "smlad  r14, r5,  r7,  r14\n"
-               "ldrd   r4,  r5,  [r2, #80]\n"    /* start loading cos table */
-               "smlad  r12, r8,  r10, r12\n"     /* t1[2] is done */
-               "smlad  r14, r9,  r11, r14\n"     /* t1[3] is done */
-               "ldrd   r6,  r7,  [r2, #88]\n"
-               "ldrd   r8,  r9,  [r2, #96]\n"
-               "ldrd   r10, r11, [r2, #104]\n"   /* cos table fully loaded */
-               "pkhtb  r12, r14, r12, asr #16\n" /* combine t1[2] and t1[3] */
-               "smuad  r4,  r3,  r4\n"
-               "smuad  r5,  r3,  r5\n"
-               "smlad  r4,  r12, r8,  r4\n"
-               "smlad  r5,  r12, r9,  r5\n"
-               "smuad  r6,  r3,  r6\n"
-               "smuad  r7,  r3,  r7\n"
-               "smlad  r6,  r12, r10, r6\n"
-               "smlad  r7,  r12, r11, r7\n"
-               "pop    {r8-r11}\n"
-               "stmia  r1, {r4, r5, r6, r7}\n"
-               "pop    {r1, r4-r7, pc}\n"
-       );
-}
-
-#define sbc_analyze_four(in, out, consts) \
-       ((void (*)(int16_t *, int32_t *, const FIXED_T*)) \
-               sbc_analyze_four_armv6)((in), (out), (consts))
-
-static void __attribute__((naked)) sbc_analyze_eight_armv6()
-{
-       /* r0 = in, r1 = out, r2 = consts */
-       __asm__ volatile (
-               "push   {r1, r4-r7, lr}\n"
-               "push   {r8-r11}\n"
-               "ldrd   r4,  r5,  [r0, #24]\n"
-               "ldrd   r6,  r7,  [r2, #24]\n"
-               "ldrd   r8,  r9,  [r0, #56]\n"
-               "ldrd   r10, r11, [r2, #56]\n"
-               "mov    r14, #0x8000\n"
-               "smlad  r3,  r4,  r6,  r14\n"
-               "smlad  r12, r5,  r7,  r14\n"
-               "ldrd   r4,  r5,  [r0, #88]\n"
-               "ldrd   r6,  r7,  [r2, #88]\n"
-               "smlad  r3,  r8,  r10, r3\n"
-               "smlad  r12, r9,  r11, r12\n"
-               "ldrd   r8,  r9,  [r0, #120]\n"
-               "ldrd   r10, r11, [r2, #120]\n"
-               "smlad  r3,  r4,  r6,  r3\n"
-               "smlad  r12, r5,  r7,  r12\n"
-               "ldrd   r4,  r5,  [r0, #152]\n"
-               "ldrd   r6,  r7,  [r2, #152]\n"
-               "smlad  r3,  r8,  r10, r3\n"
-               "smlad  r12, r9,  r11, r12\n"
-               "ldrd   r8,  r9,  [r0, #16]\n"
-               "ldrd   r10, r11, [r2, #16]\n"
-               "smlad  r3,  r4,  r6,  r3\n"      /* t1[6] is done */
-               "smlad  r12, r5,  r7,  r12\n"     /* t1[7] is done */
-               "ldrd   r4,  r5,  [r0, #48]\n"
-               "ldrd   r6,  r7,  [r2, #48]\n"
-               "pkhtb  r3,  r12, r3, asr #16\n"  /* combine t1[6] and t1[7] */
-               "str    r3,  [sp, #-4]!\n"        /* save to stack */
-               "smlad  r3,  r8,  r10, r14\n"
-               "smlad  r12, r9,  r11, r14\n"
-               "ldrd   r8,  r9,  [r0, #80]\n"
-               "ldrd   r10, r11, [r2, #80]\n"
-               "smlad  r3,  r4,  r6,  r3\n"
-               "smlad  r12, r5,  r7,  r12\n"
-               "ldrd   r4,  r5,  [r0, #112]\n"
-               "ldrd   r6,  r7,  [r2, #112]\n"
-               "smlad  r3,  r8,  r10, r3\n"
-               "smlad  r12, r9,  r11, r12\n"
-               "ldrd   r8,  r9,  [r0, #144]\n"
-               "ldrd   r10, r11, [r2, #144]\n"
-               "smlad  r3,  r4,  r6,  r3\n"
-               "smlad  r12, r5,  r7,  r12\n"
-               "ldrd   r4,  r5,  [r0, #0]\n"
-               "ldrd   r6,  r7,  [r2, #0]\n"
-               "smlad  r3,  r8,  r10, r3\n"      /* t1[4] is done */
-               "smlad  r12, r9,  r11, r12\n"     /* t1[5] is done */
-               "ldrd   r8,  r9,  [r0, #32]\n"
-               "ldrd   r10, r11, [r2, #32]\n"
-               "pkhtb  r3,  r12, r3, asr #16\n"  /* combine t1[4] and t1[5] */
-               "str    r3,  [sp, #-4]!\n"        /* save to stack */
-               "smlad  r3,  r4,  r6,  r14\n"
-               "smlad  r12, r5,  r7,  r14\n"
-               "ldrd   r4,  r5,  [r0, #64]\n"
-               "ldrd   r6,  r7,  [r2, #64]\n"
-               "smlad  r3,  r8,  r10, r3\n"
-               "smlad  r12, r9,  r11, r12\n"
-               "ldrd   r8,  r9,  [r0, #96]\n"
-               "ldrd   r10, r11, [r2, #96]\n"
-               "smlad  r3,  r4,  r6,  r3\n"
-               "smlad  r12, r5,  r7,  r12\n"
-               "ldrd   r4,  r5,  [r0, #128]\n"
-               "ldrd   r6,  r7,  [r2, #128]\n"
-               "smlad  r3,  r8,  r10, r3\n"
-               "smlad  r12, r9,  r11, r12\n"
-               "ldrd   r8,  r9,  [r0, #8]\n"
-               "ldrd   r10, r11, [r2, #8]\n"
-               "smlad  r3,  r4,  r6,  r3\n"      /* t1[0] is done */
-               "smlad  r12, r5,  r7,  r12\n"     /* t1[1] is done */
-               "ldrd   r4,  r5,  [r0, #40]\n"
-               "ldrd   r6,  r7,  [r2, #40]\n"
-               "pkhtb  r3,  r12, r3, asr #16\n"  /* combine t1[0] and t1[1] */
-               "smlad  r12, r8,  r10, r14\n"
-               "smlad  r14, r9,  r11, r14\n"
-               "ldrd   r8,  r9,  [r0, #72]\n"
-               "ldrd   r10, r11, [r2, #72]\n"
-               "smlad  r12, r4,  r6,  r12\n"
-               "smlad  r14, r5,  r7,  r14\n"
-               "ldrd   r4,  r5,  [r0, #104]\n"
-               "ldrd   r6,  r7,  [r2, #104]\n"
-               "smlad  r12, r8,  r10, r12\n"
-               "smlad  r14, r9,  r11, r14\n"
-               "ldrd   r8,  r9,  [r0, #136]\n"
-               "ldrd   r10, r11, [r2, #136]!\n"
-               "smlad  r12, r4,  r6,  r12\n"
-               "smlad  r14, r5,  r7,  r14\n"
-               "ldrd   r4,  r5,  [r2, #(160 - 136 + 0)]\n"
-               "smlad  r12, r8,  r10, r12\n"     /* t1[2] is done */
-               "smlad  r14, r9,  r11, r14\n"     /* t1[3] is done */
-               "ldrd   r6,  r7,  [r2, #(160 - 136 + 8)]\n"
-               "smuad  r4,  r3,  r4\n"
-               "smuad  r5,  r3,  r5\n"
-               "pkhtb  r12, r14, r12, asr #16\n" /* combine t1[2] and t1[3] */
-                                                 /* r3  = t2[0:1] */
-                                                 /* r12 = t2[2:3] */
-               "pop    {r0, r14}\n"              /* t2[4:5], t2[6:7] */
-               "ldrd   r8,  r9,  [r2, #(160 - 136 + 32)]\n"
-               "smuad  r6,  r3,  r6\n"
-               "smuad  r7,  r3,  r7\n"
-               "ldrd   r10, r11, [r2, #(160 - 136 + 40)]\n"
-               "smlad  r4,  r12, r8,  r4\n"
-               "smlad  r5,  r12, r9,  r5\n"
-               "ldrd   r8,  r9,  [r2, #(160 - 136 + 64)]\n"
-               "smlad  r6,  r12, r10, r6\n"
-               "smlad  r7,  r12, r11, r7\n"
-               "ldrd   r10, r11, [r2, #(160 - 136 + 72)]\n"
-               "smlad  r4,  r0,  r8,  r4\n"
-               "smlad  r5,  r0,  r9,  r5\n"
-               "ldrd   r8,  r9,  [r2, #(160 - 136 + 96)]\n"
-               "smlad  r6,  r0,  r10, r6\n"
-               "smlad  r7,  r0,  r11, r7\n"
-               "ldrd   r10, r11, [r2, #(160 - 136 + 104)]\n"
-               "smlad  r4,  r14, r8,  r4\n"
-               "smlad  r5,  r14, r9,  r5\n"
-               "ldrd   r8,  r9,  [r2, #(160 - 136 + 16 + 0)]\n"
-               "smlad  r6,  r14, r10, r6\n"
-               "smlad  r7,  r14, r11, r7\n"
-               "ldrd   r10, r11, [r2, #(160 - 136 + 16 + 8)]\n"
-               "stmia  r1!, {r4, r5}\n"
-               "smuad  r4,  r3,  r8\n"
-               "smuad  r5,  r3,  r9\n"
-               "ldrd   r8,  r9,  [r2, #(160 - 136 + 16 + 32)]\n"
-               "stmia  r1!, {r6, r7}\n"
-               "smuad  r6,  r3,  r10\n"
-               "smuad  r7,  r3,  r11\n"
-               "ldrd   r10, r11, [r2, #(160 - 136 + 16 + 40)]\n"
-               "smlad  r4,  r12, r8,  r4\n"
-               "smlad  r5,  r12, r9,  r5\n"
-               "ldrd   r8,  r9,  [r2, #(160 - 136 + 16 + 64)]\n"
-               "smlad  r6,  r12, r10, r6\n"
-               "smlad  r7,  r12, r11, r7\n"
-               "ldrd   r10, r11, [r2, #(160 - 136 + 16 + 72)]\n"
-               "smlad  r4,  r0,  r8,  r4\n"
-               "smlad  r5,  r0,  r9,  r5\n"
-               "ldrd   r8,  r9,  [r2, #(160 - 136 + 16 + 96)]\n"
-               "smlad  r6,  r0,  r10, r6\n"
-               "smlad  r7,  r0,  r11, r7\n"
-               "ldrd   r10, r11, [r2, #(160 - 136 + 16 + 104)]\n"
-               "smlad  r4,  r14, r8,  r4\n"
-               "smlad  r5,  r14, r9,  r5\n"
-               "smlad  r6,  r14, r10, r6\n"
-               "smlad  r7,  r14, r11, r7\n"
-               "pop    {r8-r11}\n"
-               "stmia  r1!, {r4, r5, r6, r7}\n"
-               "pop    {r1, r4-r7, pc}\n"
-       );
-}
-
-#define sbc_analyze_eight(in, out, consts) \
-       ((void (*)(int16_t *, int32_t *, const FIXED_T*)) \
-               sbc_analyze_eight_armv6)((in), (out), (consts))
-
-static void sbc_analyze_4b_4s_armv6(int16_t *x, int32_t *out, int out_stride)
-{
-       /* Analyze blocks */
-       sbc_analyze_four(x + 12, out, analysis_consts_fixed4_simd_odd);
-       out += out_stride;
-       sbc_analyze_four(x + 8, out, analysis_consts_fixed4_simd_even);
-       out += out_stride;
-       sbc_analyze_four(x + 4, out, analysis_consts_fixed4_simd_odd);
-       out += out_stride;
-       sbc_analyze_four(x + 0, out, analysis_consts_fixed4_simd_even);
-}
-
-static void sbc_analyze_4b_8s_armv6(int16_t *x, int32_t *out, int out_stride)
-{
-       /* Analyze blocks */
-       sbc_analyze_eight(x + 24, out, analysis_consts_fixed8_simd_odd);
-       out += out_stride;
-       sbc_analyze_eight(x + 16, out, analysis_consts_fixed8_simd_even);
-       out += out_stride;
-       sbc_analyze_eight(x + 8, out, analysis_consts_fixed8_simd_odd);
-       out += out_stride;
-       sbc_analyze_eight(x + 0, out, analysis_consts_fixed8_simd_even);
-}
-
-void sbc_init_primitives_armv6(struct sbc_encoder_state *state)
-{
-       state->sbc_analyze_4b_4s = sbc_analyze_4b_4s_armv6;
-       state->sbc_analyze_4b_8s = sbc_analyze_4b_8s_armv6;
-       state->implementation_info = "ARMv6 SIMD";
-}
-
-#endif
diff --git a/src/modules/bluetooth/sbc/sbc_primitives_armv6.h b/src/modules/bluetooth/sbc/sbc_primitives_armv6.h
deleted file mode 100644 (file)
index 6a9efe5..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *
- *  Bluetooth low-complexity, subband codec (SBC) library
- *
- *  Copyright (C) 2008-2010  Nokia Corporation
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
- *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef __SBC_PRIMITIVES_ARMV6_H
-#define __SBC_PRIMITIVES_ARMV6_H
-
-#include "sbc_primitives.h"
-
-#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
-       defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \
-       defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) || \
-       defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_7__) || \
-       defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || \
-       defined(__ARM_ARCH_7M__)
-#define SBC_HAVE_ARMV6 1
-#endif
-
-#if !defined(SBC_HIGH_PRECISION) && (SCALE_OUT_BITS == 15) && \
-       defined(__GNUC__) && defined(SBC_HAVE_ARMV6) && \
-       defined(__ARM_EABI__) && !defined(__ARM_NEON__) && \
-       (!defined(__thumb__) || defined(__thumb2__))
-
-#define SBC_BUILD_WITH_ARMV6_SUPPORT
-
-void sbc_init_primitives_armv6(struct sbc_encoder_state *encoder_state);
-
-#endif
-
-#endif
diff --git a/src/modules/bluetooth/sbc/sbc_primitives_iwmmxt.c b/src/modules/bluetooth/sbc/sbc_primitives_iwmmxt.c
deleted file mode 100644 (file)
index e0bd060..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- *
- *  Bluetooth low-complexity, subband codec (SBC) library
- *
- *  Copyright (C) 2010 Keith Mok <ek9852@gmail.com>
- *  Copyright (C) 2008-2010  Nokia Corporation
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
- *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include <stdint.h>
-#include <limits.h>
-#include "sbc.h"
-#include "sbc_math.h"
-#include "sbc_tables.h"
-
-#include "sbc_primitives_iwmmxt.h"
-
-/*
- * IWMMXT optimizations
- */
-
-#ifdef SBC_BUILD_WITH_IWMMXT_SUPPORT
-
-static inline void sbc_analyze_four_iwmmxt(const int16_t *in, int32_t *out,
-                                       const FIXED_T *consts)
-{
-       __asm__ volatile (
-               "wldrd        wr0, [%0]\n"
-               "tbcstw       wr4, %2\n"
-               "wldrd        wr2, [%1]\n"
-               "wldrd        wr1, [%0, #8]\n"
-               "wldrd        wr3, [%1, #8]\n"
-               "wmadds       wr0, wr2, wr0\n"
-               " wldrd       wr6, [%0, #16]\n"
-               "wmadds       wr1, wr3, wr1\n"
-               " wldrd       wr7, [%0, #24]\n"
-               "waddwss      wr0, wr0, wr4\n"
-               " wldrd       wr8, [%1, #16]\n"
-               "waddwss      wr1, wr1, wr4\n"
-               " wldrd       wr9, [%1, #24]\n"
-               " wmadds      wr6, wr8, wr6\n"
-               "  wldrd      wr2, [%0, #32]\n"
-               " wmadds      wr7, wr9, wr7\n"
-               "  wldrd      wr3, [%0, #40]\n"
-               " waddwss     wr0, wr6, wr0\n"
-               "  wldrd      wr4, [%1, #32]\n"
-               " waddwss     wr1, wr7, wr1\n"
-               "  wldrd      wr5, [%1, #40]\n"
-               "  wmadds     wr2, wr4, wr2\n"
-               "wldrd        wr6, [%0, #48]\n"
-               "  wmadds     wr3, wr5, wr3\n"
-               "wldrd        wr7, [%0, #56]\n"
-               "  waddwss    wr0, wr2, wr0\n"
-               "wldrd        wr8, [%1, #48]\n"
-               "  waddwss    wr1, wr3, wr1\n"
-               "wldrd        wr9, [%1, #56]\n"
-               "wmadds       wr6, wr8, wr6\n"
-               " wldrd       wr2, [%0, #64]\n"
-               "wmadds       wr7, wr9, wr7\n"
-               " wldrd       wr3, [%0, #72]\n"
-               "waddwss      wr0, wr6, wr0\n"
-               " wldrd       wr4, [%1, #64]\n"
-               "waddwss      wr1, wr7, wr1\n"
-               " wldrd       wr5, [%1, #72]\n"
-               " wmadds      wr2, wr4, wr2\n"
-               "tmcr       wcgr0, %4\n"
-               " wmadds      wr3, wr5, wr3\n"
-               " waddwss     wr0, wr2, wr0\n"
-               " waddwss     wr1, wr3, wr1\n"
-               "\n"
-               "wsrawg       wr0, wr0, wcgr0\n"
-               " wldrd       wr4, [%1, #80]\n"
-               "wsrawg       wr1, wr1, wcgr0\n"
-               " wldrd       wr5, [%1, #88]\n"
-               "wpackwss     wr0, wr0, wr0\n"
-               " wldrd       wr6, [%1, #96]\n"
-               "wpackwss     wr1, wr1, wr1\n"
-               "wmadds       wr2, wr5, wr0\n"
-               " wldrd       wr7, [%1, #104]\n"
-               "wmadds       wr0, wr4, wr0\n"
-               "\n"
-               " wmadds      wr3, wr7, wr1\n"
-               " wmadds      wr1, wr6, wr1\n"
-               " waddwss     wr2, wr3, wr2\n"
-               " waddwss     wr0, wr1, wr0\n"
-               "\n"
-               "wstrd        wr0, [%3]\n"
-               "wstrd        wr2, [%3, #8]\n"
-               :
-               : "r" (in), "r" (consts),
-                       "r" (1 << (SBC_PROTO_FIXED4_SCALE - 1)), "r" (out),
-                       "r" (SBC_PROTO_FIXED4_SCALE)
-               : "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
-                 "wr8", "wr9", "wcgr0", "memory");
-}
-
-static inline void sbc_analyze_eight_iwmmxt(const int16_t *in, int32_t *out,
-                                                       const FIXED_T *consts)
-{
-       __asm__ volatile (
-               "wldrd        wr0, [%0]\n"
-               "tbcstw       wr15, %2\n"
-               "wldrd        wr1, [%0, #8]\n"
-               "wldrd        wr2, [%0, #16]\n"
-               "wldrd        wr3, [%0, #24]\n"
-               "wldrd        wr4, [%1]\n"
-               "wldrd        wr5, [%1, #8]\n"
-               "wldrd        wr6, [%1, #16]\n"
-               "wldrd        wr7, [%1, #24]\n"
-               "wmadds       wr0, wr0, wr4\n"
-               " wldrd       wr8, [%1, #32]\n"
-               "wmadds       wr1, wr1, wr5\n"
-               " wldrd       wr9, [%1, #40]\n"
-               "wmadds       wr2, wr2, wr6\n"
-               " wldrd      wr10, [%1, #48]\n"
-               "wmadds       wr3, wr3, wr7\n"
-               " wldrd      wr11, [%1, #56]\n"
-               "waddwss      wr0, wr0, wr15\n"
-               " wldrd       wr4, [%0, #32]\n"
-               "waddwss      wr1, wr1, wr15\n"
-               " wldrd       wr5, [%0, #40]\n"
-               "waddwss      wr2, wr2, wr15\n"
-               " wldrd       wr6, [%0, #48]\n"
-               "waddwss      wr3, wr3, wr15\n"
-               " wldrd       wr7, [%0, #56]\n"
-               " wmadds      wr4, wr4, wr8\n"
-               "  wldrd     wr12, [%0, #64]\n"
-               " wmadds      wr5, wr5, wr9\n"
-               "  wldrd     wr13, [%0, #72]\n"
-               " wmadds      wr6, wr6, wr10\n"
-               "  wldrd     wr14, [%0, #80]\n"
-               " wmadds      wr7, wr7, wr11\n"
-               "  wldrd     wr15, [%0, #88]\n"
-               " waddwss     wr0, wr4, wr0\n"
-               "  wldrd      wr8, [%1, #64]\n"
-               " waddwss     wr1, wr5, wr1\n"
-               "  wldrd      wr9, [%1, #72]\n"
-               " waddwss     wr2, wr6, wr2\n"
-               "  wldrd     wr10, [%1, #80]\n"
-               " waddwss     wr3, wr7, wr3\n"
-               "  wldrd     wr11, [%1, #88]\n"
-               "  wmadds    wr12, wr12, wr8\n"
-               "wldrd        wr4, [%0, #96]\n"
-               "  wmadds    wr13, wr13, wr9\n"
-               "wldrd        wr5, [%0, #104]\n"
-               "  wmadds    wr14, wr14, wr10\n"
-               "wldrd        wr6, [%0, #112]\n"
-               "  wmadds    wr15, wr15, wr11\n"
-               "wldrd        wr7, [%0, #120]\n"
-               "  waddwss    wr0, wr12, wr0\n"
-               "wldrd        wr8, [%1, #96]\n"
-               "  waddwss    wr1, wr13, wr1\n"
-               "wldrd        wr9, [%1, #104]\n"
-               "  waddwss    wr2, wr14, wr2\n"
-               "wldrd       wr10, [%1, #112]\n"
-               "  waddwss    wr3, wr15, wr3\n"
-               "wldrd       wr11, [%1, #120]\n"
-               "wmadds       wr4, wr4, wr8\n"
-               " wldrd      wr12, [%0, #128]\n"
-               "wmadds       wr5, wr5, wr9\n"
-               " wldrd      wr13, [%0, #136]\n"
-               "wmadds       wr6, wr6, wr10\n"
-               " wldrd      wr14, [%0, #144]\n"
-               "wmadds       wr7, wr7, wr11\n"
-               " wldrd      wr15, [%0, #152]\n"
-               "waddwss      wr0, wr4, wr0\n"
-               " wldrd       wr8, [%1, #128]\n"
-               "waddwss      wr1, wr5, wr1\n"
-               " wldrd       wr9, [%1, #136]\n"
-               "waddwss      wr2, wr6, wr2\n"
-               " wldrd      wr10, [%1, #144]\n"
-               " waddwss     wr3, wr7, wr3\n"
-               " wldrd     wr11, [%1, #152]\n"
-               " wmadds     wr12, wr12, wr8\n"
-               "tmcr       wcgr0, %4\n"
-               " wmadds     wr13, wr13, wr9\n"
-               " wmadds     wr14, wr14, wr10\n"
-               " wmadds     wr15, wr15, wr11\n"
-               " waddwss     wr0, wr12, wr0\n"
-               " waddwss     wr1, wr13, wr1\n"
-               " waddwss     wr2, wr14, wr2\n"
-               " waddwss     wr3, wr15, wr3\n"
-               "\n"
-               "wsrawg       wr0, wr0, wcgr0\n"
-               "wsrawg       wr1, wr1, wcgr0\n"
-               "wsrawg       wr2, wr2, wcgr0\n"
-               "wsrawg       wr3, wr3, wcgr0\n"
-               "\n"
-               "wpackwss     wr0, wr0, wr0\n"
-               "wpackwss     wr1, wr1, wr1\n"
-               " wldrd       wr4, [%1, #160]\n"
-               "wpackwss     wr2, wr2, wr2\n"
-               " wldrd       wr5, [%1, #168]\n"
-               "wpackwss     wr3, wr3, wr3\n"
-               "  wldrd      wr6, [%1, #192]\n"
-               " wmadds      wr4, wr4, wr0\n"
-               "  wldrd      wr7, [%1, #200]\n"
-               " wmadds      wr5, wr5, wr0\n"
-               "   wldrd     wr8, [%1, #224]\n"
-               "  wmadds     wr6, wr6, wr1\n"
-               "   wldrd     wr9, [%1, #232]\n"
-               "  wmadds     wr7, wr7, wr1\n"
-               "  waddwss    wr4, wr6, wr4\n"
-               "  waddwss    wr5, wr7, wr5\n"
-               "   wmadds    wr8, wr8, wr2\n"
-               "wldrd        wr6, [%1, #256]\n"
-               "   wmadds    wr9, wr9, wr2\n"
-               "wldrd        wr7, [%1, #264]\n"
-               "waddwss      wr4, wr8, wr4\n"
-               "   waddwss   wr5, wr9, wr5\n"
-               "wmadds       wr6, wr6, wr3\n"
-               "wmadds       wr7, wr7, wr3\n"
-               "waddwss      wr4, wr6, wr4\n"
-               "waddwss      wr5, wr7, wr5\n"
-               "\n"
-               "wstrd        wr4, [%3]\n"
-               "wstrd        wr5, [%3, #8]\n"
-               "\n"
-               "wldrd        wr6, [%1, #176]\n"
-               "wldrd        wr5, [%1, #184]\n"
-               "wmadds       wr5, wr5, wr0\n"
-               "wldrd        wr8, [%1, #208]\n"
-               "wmadds       wr0, wr6, wr0\n"
-               "wldrd        wr9, [%1, #216]\n"
-               "wmadds       wr9, wr9, wr1\n"
-               "wldrd        wr6, [%1, #240]\n"
-               "wmadds       wr1, wr8, wr1\n"
-               "wldrd        wr7, [%1, #248]\n"
-               "waddwss      wr0, wr1, wr0\n"
-               "waddwss      wr5, wr9, wr5\n"
-               "wmadds       wr7, wr7, wr2\n"
-               "wldrd        wr8, [%1, #272]\n"
-               "wmadds       wr2, wr6, wr2\n"
-               "wldrd        wr9, [%1, #280]\n"
-               "waddwss      wr0, wr2, wr0\n"
-               "waddwss      wr5, wr7, wr5\n"
-               "wmadds       wr9, wr9, wr3\n"
-               "wmadds       wr3, wr8, wr3\n"
-               "waddwss      wr0, wr3, wr0\n"
-               "waddwss      wr5, wr9, wr5\n"
-               "\n"
-               "wstrd        wr0, [%3, #16]\n"
-               "wstrd        wr5, [%3, #24]\n"
-               :
-               : "r" (in), "r" (consts),
-                       "r" (1 << (SBC_PROTO_FIXED8_SCALE - 1)), "r" (out),
-                       "r" (SBC_PROTO_FIXED8_SCALE)
-               : "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
-                 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15",
-                 "wcgr0", "memory");
-}
-
-static inline void sbc_analyze_4b_4s_iwmmxt(int16_t *x, int32_t *out,
-                                               int out_stride)
-{
-       /* Analyze blocks */
-       sbc_analyze_four_iwmmxt(x + 12, out, analysis_consts_fixed4_simd_odd);
-       out += out_stride;
-       sbc_analyze_four_iwmmxt(x + 8, out, analysis_consts_fixed4_simd_even);
-       out += out_stride;
-       sbc_analyze_four_iwmmxt(x + 4, out, analysis_consts_fixed4_simd_odd);
-       out += out_stride;
-       sbc_analyze_four_iwmmxt(x + 0, out, analysis_consts_fixed4_simd_even);
-}
-
-static inline void sbc_analyze_4b_8s_iwmmxt(int16_t *x, int32_t *out,
-                                               int out_stride)
-{
-       /* Analyze blocks */
-       sbc_analyze_eight_iwmmxt(x + 24, out, analysis_consts_fixed8_simd_odd);
-       out += out_stride;
-       sbc_analyze_eight_iwmmxt(x + 16, out, analysis_consts_fixed8_simd_even);
-       out += out_stride;
-       sbc_analyze_eight_iwmmxt(x + 8, out, analysis_consts_fixed8_simd_odd);
-       out += out_stride;
-       sbc_analyze_eight_iwmmxt(x + 0, out, analysis_consts_fixed8_simd_even);
-}
-
-void sbc_init_primitives_iwmmxt(struct sbc_encoder_state *state)
-{
-       state->sbc_analyze_4b_4s = sbc_analyze_4b_4s_iwmmxt;
-       state->sbc_analyze_4b_8s = sbc_analyze_4b_8s_iwmmxt;
-       state->implementation_info = "IWMMXT";
-}
-
-#endif
diff --git a/src/modules/bluetooth/sbc/sbc_primitives_iwmmxt.h b/src/modules/bluetooth/sbc/sbc_primitives_iwmmxt.h
deleted file mode 100644 (file)
index b535e68..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *
- *  Bluetooth low-complexity, subband codec (SBC) library
- *
- *  Copyright (C) 2010 Keith Mok <ek9852@gmail.com>
- *  Copyright (C) 2008-2010  Nokia Corporation
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
- *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef __SBC_PRIMITIVES_IWMMXT_H
-#define __SBC_PRIMITIVES_IWMMXT_H
-
-#include "sbc_primitives.h"
-
-#if defined(__GNUC__) && defined(__IWMMXT__) && \
-               !defined(SBC_HIGH_PRECISION) && (SCALE_OUT_BITS == 15)
-
-#define SBC_BUILD_WITH_IWMMXT_SUPPORT
-
-void sbc_init_primitives_iwmmxt(struct sbc_encoder_state *encoder_state);
-
-#endif
-
-#endif
diff --git a/src/modules/bluetooth/sbc/sbc_primitives_mmx.c b/src/modules/bluetooth/sbc/sbc_primitives_mmx.c
deleted file mode 100644 (file)
index 27e9a56..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- *
- *  Bluetooth low-complexity, subband codec (SBC) library
- *
- *  Copyright (C) 2008-2010  Nokia Corporation
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
- *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include <stdint.h>
-#include <limits.h>
-#include "sbc.h"
-#include "sbc_math.h"
-#include "sbc_tables.h"
-
-#include "sbc_primitives_mmx.h"
-
-/*
- * MMX optimizations
- */
-
-#ifdef SBC_BUILD_WITH_MMX_SUPPORT
-
-static inline void sbc_analyze_four_mmx(const int16_t *in, int32_t *out,
-                                       const FIXED_T *consts)
-{
-       static const SBC_ALIGNED int32_t round_c[2] = {
-               1 << (SBC_PROTO_FIXED4_SCALE - 1),
-               1 << (SBC_PROTO_FIXED4_SCALE - 1),
-       };
-       __asm__ volatile (
-               "movq        (%0), %%mm0\n"
-               "movq       8(%0), %%mm1\n"
-               "pmaddwd     (%1), %%mm0\n"
-               "pmaddwd    8(%1), %%mm1\n"
-               "paddd       (%2), %%mm0\n"
-               "paddd       (%2), %%mm1\n"
-               "\n"
-               "movq      16(%0), %%mm2\n"
-               "movq      24(%0), %%mm3\n"
-               "pmaddwd   16(%1), %%mm2\n"
-               "pmaddwd   24(%1), %%mm3\n"
-               "paddd      %%mm2, %%mm0\n"
-               "paddd      %%mm3, %%mm1\n"
-               "\n"
-               "movq      32(%0), %%mm2\n"
-               "movq      40(%0), %%mm3\n"
-               "pmaddwd   32(%1), %%mm2\n"
-               "pmaddwd   40(%1), %%mm3\n"
-               "paddd      %%mm2, %%mm0\n"
-               "paddd      %%mm3, %%mm1\n"
-               "\n"
-               "movq      48(%0), %%mm2\n"
-               "movq      56(%0), %%mm3\n"
-               "pmaddwd   48(%1), %%mm2\n"
-               "pmaddwd   56(%1), %%mm3\n"
-               "paddd      %%mm2, %%mm0\n"
-               "paddd      %%mm3, %%mm1\n"
-               "\n"
-               "movq      64(%0), %%mm2\n"
-               "movq      72(%0), %%mm3\n"
-               "pmaddwd   64(%1), %%mm2\n"
-               "pmaddwd   72(%1), %%mm3\n"
-               "paddd      %%mm2, %%mm0\n"
-               "paddd      %%mm3, %%mm1\n"
-               "\n"
-               "psrad         %4, %%mm0\n"
-               "psrad         %4, %%mm1\n"
-               "packssdw   %%mm0, %%mm0\n"
-               "packssdw   %%mm1, %%mm1\n"
-               "\n"
-               "movq       %%mm0, %%mm2\n"
-               "pmaddwd   80(%1), %%mm0\n"
-               "pmaddwd   88(%1), %%mm2\n"
-               "\n"
-               "movq       %%mm1, %%mm3\n"
-               "pmaddwd   96(%1), %%mm1\n"
-               "pmaddwd  104(%1), %%mm3\n"
-               "paddd      %%mm1, %%mm0\n"
-               "paddd      %%mm3, %%mm2\n"
-               "\n"
-               "movq       %%mm0, (%3)\n"
-               "movq       %%mm2, 8(%3)\n"
-               :
-               : "r" (in), "r" (consts), "r" (&round_c), "r" (out),
-                       "i" (SBC_PROTO_FIXED4_SCALE)
-               : "cc", "memory");
-}
-
-static inline void sbc_analyze_eight_mmx(const int16_t *in, int32_t *out,
-                                                       const FIXED_T *consts)
-{
-       static const SBC_ALIGNED int32_t round_c[2] = {
-               1 << (SBC_PROTO_FIXED8_SCALE - 1),
-               1 << (SBC_PROTO_FIXED8_SCALE - 1),
-       };
-       __asm__ volatile (
-               "movq        (%0), %%mm0\n"
-               "movq       8(%0), %%mm1\n"
-               "movq      16(%0), %%mm2\n"
-               "movq      24(%0), %%mm3\n"
-               "pmaddwd     (%1), %%mm0\n"
-               "pmaddwd    8(%1), %%mm1\n"
-               "pmaddwd   16(%1), %%mm2\n"
-               "pmaddwd   24(%1), %%mm3\n"
-               "paddd       (%2), %%mm0\n"
-               "paddd       (%2), %%mm1\n"
-               "paddd       (%2), %%mm2\n"
-               "paddd       (%2), %%mm3\n"
-               "\n"
-               "movq      32(%0), %%mm4\n"
-               "movq      40(%0), %%mm5\n"
-               "movq      48(%0), %%mm6\n"
-               "movq      56(%0), %%mm7\n"
-               "pmaddwd   32(%1), %%mm4\n"
-               "pmaddwd   40(%1), %%mm5\n"
-               "pmaddwd   48(%1), %%mm6\n"
-               "pmaddwd   56(%1), %%mm7\n"
-               "paddd      %%mm4, %%mm0\n"
-               "paddd      %%mm5, %%mm1\n"
-               "paddd      %%mm6, %%mm2\n"
-               "paddd      %%mm7, %%mm3\n"
-               "\n"
-               "movq      64(%0), %%mm4\n"
-               "movq      72(%0), %%mm5\n"
-               "movq      80(%0), %%mm6\n"
-               "movq      88(%0), %%mm7\n"
-               "pmaddwd   64(%1), %%mm4\n"
-               "pmaddwd   72(%1), %%mm5\n"
-               "pmaddwd   80(%1), %%mm6\n"
-               "pmaddwd   88(%1), %%mm7\n"
-               "paddd      %%mm4, %%mm0\n"
-               "paddd      %%mm5, %%mm1\n"
-               "paddd      %%mm6, %%mm2\n"
-               "paddd      %%mm7, %%mm3\n"
-               "\n"
-               "movq      96(%0), %%mm4\n"
-               "movq     104(%0), %%mm5\n"
-               "movq     112(%0), %%mm6\n"
-               "movq     120(%0), %%mm7\n"
-               "pmaddwd   96(%1), %%mm4\n"
-               "pmaddwd  104(%1), %%mm5\n"
-               "pmaddwd  112(%1), %%mm6\n"
-               "pmaddwd  120(%1), %%mm7\n"
-               "paddd      %%mm4, %%mm0\n"
-               "paddd      %%mm5, %%mm1\n"
-               "paddd      %%mm6, %%mm2\n"
-               "paddd      %%mm7, %%mm3\n"
-               "\n"
-               "movq     128(%0), %%mm4\n"
-               "movq     136(%0), %%mm5\n"
-               "movq     144(%0), %%mm6\n"
-               "movq     152(%0), %%mm7\n"
-               "pmaddwd  128(%1), %%mm4\n"
-               "pmaddwd  136(%1), %%mm5\n"
-               "pmaddwd  144(%1), %%mm6\n"
-               "pmaddwd  152(%1), %%mm7\n"
-               "paddd      %%mm4, %%mm0\n"
-               "paddd      %%mm5, %%mm1\n"
-               "paddd      %%mm6, %%mm2\n"
-               "paddd      %%mm7, %%mm3\n"
-               "\n"
-               "psrad         %4, %%mm0\n"
-               "psrad         %4, %%mm1\n"
-               "psrad         %4, %%mm2\n"
-               "psrad         %4, %%mm3\n"
-               "\n"
-               "packssdw   %%mm0, %%mm0\n"
-               "packssdw   %%mm1, %%mm1\n"
-               "packssdw   %%mm2, %%mm2\n"
-               "packssdw   %%mm3, %%mm3\n"
-               "\n"
-               "movq       %%mm0, %%mm4\n"
-               "movq       %%mm0, %%mm5\n"
-               "pmaddwd  160(%1), %%mm4\n"
-               "pmaddwd  168(%1), %%mm5\n"
-               "\n"
-               "movq       %%mm1, %%mm6\n"
-               "movq       %%mm1, %%mm7\n"
-               "pmaddwd  192(%1), %%mm6\n"
-               "pmaddwd  200(%1), %%mm7\n"
-               "paddd      %%mm6, %%mm4\n"
-               "paddd      %%mm7, %%mm5\n"
-               "\n"
-               "movq       %%mm2, %%mm6\n"
-               "movq       %%mm2, %%mm7\n"
-               "pmaddwd  224(%1), %%mm6\n"
-               "pmaddwd  232(%1), %%mm7\n"
-               "paddd      %%mm6, %%mm4\n"
-               "paddd      %%mm7, %%mm5\n"
-               "\n"
-               "movq       %%mm3, %%mm6\n"
-               "movq       %%mm3, %%mm7\n"
-               "pmaddwd  256(%1), %%mm6\n"
-               "pmaddwd  264(%1), %%mm7\n"
-               "paddd      %%mm6, %%mm4\n"
-               "paddd      %%mm7, %%mm5\n"
-               "\n"
-               "movq       %%mm4, (%3)\n"
-               "movq       %%mm5, 8(%3)\n"
-               "\n"
-               "movq       %%mm0, %%mm5\n"
-               "pmaddwd  176(%1), %%mm0\n"
-               "pmaddwd  184(%1), %%mm5\n"
-               "\n"
-               "movq       %%mm1, %%mm7\n"
-               "pmaddwd  208(%1), %%mm1\n"
-               "pmaddwd  216(%1), %%mm7\n"
-               "paddd      %%mm1, %%mm0\n"
-               "paddd      %%mm7, %%mm5\n"
-               "\n"
-               "movq       %%mm2, %%mm7\n"
-               "pmaddwd  240(%1), %%mm2\n"
-               "pmaddwd  248(%1), %%mm7\n"
-               "paddd      %%mm2, %%mm0\n"
-               "paddd      %%mm7, %%mm5\n"
-               "\n"
-               "movq       %%mm3, %%mm7\n"
-               "pmaddwd  272(%1), %%mm3\n"
-               "pmaddwd  280(%1), %%mm7\n"
-               "paddd      %%mm3, %%mm0\n"
-               "paddd      %%mm7, %%mm5\n"
-               "\n"
-               "movq       %%mm0, 16(%3)\n"
-               "movq       %%mm5, 24(%3)\n"
-               :
-               : "r" (in), "r" (consts), "r" (&round_c), "r" (out),
-                       "i" (SBC_PROTO_FIXED8_SCALE)
-               : "cc", "memory");
-}
-
-static inline void sbc_analyze_4b_4s_mmx(int16_t *x, int32_t *out,
-                                               int out_stride)
-{
-       /* Analyze blocks */
-       sbc_analyze_four_mmx(x + 12, out, analysis_consts_fixed4_simd_odd);
-       out += out_stride;
-       sbc_analyze_four_mmx(x + 8, out, analysis_consts_fixed4_simd_even);
-       out += out_stride;
-       sbc_analyze_four_mmx(x + 4, out, analysis_consts_fixed4_simd_odd);
-       out += out_stride;
-       sbc_analyze_four_mmx(x + 0, out, analysis_consts_fixed4_simd_even);
-
-       __asm__ volatile ("emms\n");
-}
-
-static inline void sbc_analyze_4b_8s_mmx(int16_t *x, int32_t *out,
-                                               int out_stride)
-{
-       /* Analyze blocks */
-       sbc_analyze_eight_mmx(x + 24, out, analysis_consts_fixed8_simd_odd);
-       out += out_stride;
-       sbc_analyze_eight_mmx(x + 16, out, analysis_consts_fixed8_simd_even);
-       out += out_stride;
-       sbc_analyze_eight_mmx(x + 8, out, analysis_consts_fixed8_simd_odd);
-       out += out_stride;
-       sbc_analyze_eight_mmx(x + 0, out, analysis_consts_fixed8_simd_even);
-
-       __asm__ volatile ("emms\n");
-}
-
-static void sbc_calc_scalefactors_mmx(
-       int32_t sb_sample_f[16][2][8],
-       uint32_t scale_factor[2][8],
-       int blocks, int channels, int subbands)
-{
-       static const SBC_ALIGNED int32_t consts[2] = {
-               1 << SCALE_OUT_BITS,
-               1 << SCALE_OUT_BITS,
-       };
-       int ch, sb;
-       intptr_t blk;
-       for (ch = 0; ch < channels; ch++) {
-               for (sb = 0; sb < subbands; sb += 2) {
-                       blk = (blocks - 1) * (((char *) &sb_sample_f[1][0][0] -
-                               (char *) &sb_sample_f[0][0][0]));
-                       __asm__ volatile (
-                               "movq         (%4), %%mm0\n"
-                       "1:\n"
-                               "movq     (%1, %0), %%mm1\n"
-                               "pxor        %%mm2, %%mm2\n"
-                               "pcmpgtd     %%mm2, %%mm1\n"
-                               "paddd    (%1, %0), %%mm1\n"
-                               "pcmpgtd     %%mm1, %%mm2\n"
-                               "pxor        %%mm2, %%mm1\n"
-
-                               "por         %%mm1, %%mm0\n"
-
-                               "sub            %2, %0\n"
-                               "jns            1b\n"
-
-                               "movd        %%mm0, %k0\n"
-                               "psrlq         $32, %%mm0\n"
-                               "bsrl          %k0, %k0\n"
-                               "subl           %5, %k0\n"
-                               "movl          %k0, (%3)\n"
-
-                               "movd        %%mm0, %k0\n"
-                               "bsrl          %k0, %k0\n"
-                               "subl           %5, %k0\n"
-                               "movl          %k0, 4(%3)\n"
-                       : "+r" (blk)
-                       : "r" (&sb_sample_f[0][ch][sb]),
-                               "i" ((char *) &sb_sample_f[1][0][0] -
-                                       (char *) &sb_sample_f[0][0][0]),
-                               "r" (&scale_factor[ch][sb]),
-                               "r" (&consts),
-                               "i" (SCALE_OUT_BITS)
-                       : "cc", "memory");
-               }
-       }
-       __asm__ volatile ("emms\n");
-}
-
-static int check_mmx_support(void)
-{
-#ifdef __amd64__
-       return 1; /* We assume that all 64-bit processors have MMX support */
-#else
-       int cpuid_feature_information;
-       __asm__ volatile (
-               /* According to Intel manual, CPUID instruction is supported
-                * if the value of ID bit (bit 21) in EFLAGS can be modified */
-               "pushf\n"
-               "movl     (%%esp),   %0\n"
-               "xorl     $0x200000, (%%esp)\n" /* try to modify ID bit */
-               "popf\n"
-               "pushf\n"
-               "xorl     (%%esp),   %0\n"      /* check if ID bit changed */
-               "jz       1f\n"
-               "push     %%eax\n"
-               "push     %%ebx\n"
-               "push     %%ecx\n"
-               "mov      $1,        %%eax\n"
-               "cpuid\n"
-               "pop      %%ecx\n"
-               "pop      %%ebx\n"
-               "pop      %%eax\n"
-               "1:\n"
-               "popf\n"
-               : "=d" (cpuid_feature_information)
-               :
-               : "cc");
-    return cpuid_feature_information & (1 << 23);
-#endif
-}
-
-void sbc_init_primitives_mmx(struct sbc_encoder_state *state)
-{
-       if (check_mmx_support()) {
-               state->sbc_analyze_4b_4s = sbc_analyze_4b_4s_mmx;
-               state->sbc_analyze_4b_8s = sbc_analyze_4b_8s_mmx;
-               state->sbc_calc_scalefactors = sbc_calc_scalefactors_mmx;
-               state->implementation_info = "MMX";
-       }
-}
-
-#endif
diff --git a/src/modules/bluetooth/sbc/sbc_primitives_mmx.h b/src/modules/bluetooth/sbc/sbc_primitives_mmx.h
deleted file mode 100644 (file)
index e0e728b..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *
- *  Bluetooth low-complexity, subband codec (SBC) library
- *
- *  Copyright (C) 2008-2010  Nokia Corporation
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
- *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef __SBC_PRIMITIVES_MMX_H
-#define __SBC_PRIMITIVES_MMX_H
-
-#include "sbc_primitives.h"
-
-#if defined(__GNUC__) && (defined(__i386__) || defined(__amd64__)) && \
-               !defined(SBC_HIGH_PRECISION) && (SCALE_OUT_BITS == 15)
-
-#define SBC_BUILD_WITH_MMX_SUPPORT
-
-void sbc_init_primitives_mmx(struct sbc_encoder_state *encoder_state);
-
-#endif
-
-#endif
diff --git a/src/modules/bluetooth/sbc/sbc_primitives_neon.c b/src/modules/bluetooth/sbc/sbc_primitives_neon.c
deleted file mode 100644 (file)
index 5d4d0e3..0000000
+++ /dev/null
@@ -1,893 +0,0 @@
-/*
- *
- *  Bluetooth low-complexity, subband codec (SBC) library
- *
- *  Copyright (C) 2008-2010  Nokia Corporation
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
- *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include <stdint.h>
-#include <limits.h>
-#include "sbc.h"
-#include "sbc_math.h"
-#include "sbc_tables.h"
-
-#include "sbc_primitives_neon.h"
-
-/*
- * ARM NEON optimizations
- */
-
-#ifdef SBC_BUILD_WITH_NEON_SUPPORT
-
-static inline void _sbc_analyze_four_neon(const int16_t *in, int32_t *out,
-                                                       const FIXED_T *consts)
-{
-       /* TODO: merge even and odd cases (or even merge all four calls to this
-        * function) in order to have only aligned reads from 'in' array
-        * and reduce number of load instructions */
-       __asm__ volatile (
-               "vld1.16    {d4, d5}, [%0, :64]!\n"
-               "vld1.16    {d8, d9}, [%1, :128]!\n"
-
-               "vmull.s16  q0, d4, d8\n"
-               "vld1.16    {d6,  d7}, [%0, :64]!\n"
-               "vmull.s16  q1, d5, d9\n"
-               "vld1.16    {d10, d11}, [%1, :128]!\n"
-
-               "vmlal.s16  q0, d6, d10\n"
-               "vld1.16    {d4, d5}, [%0, :64]!\n"
-               "vmlal.s16  q1, d7, d11\n"
-               "vld1.16    {d8, d9}, [%1, :128]!\n"
-
-               "vmlal.s16  q0, d4, d8\n"
-               "vld1.16    {d6,  d7}, [%0, :64]!\n"
-               "vmlal.s16  q1, d5, d9\n"
-               "vld1.16    {d10, d11}, [%1, :128]!\n"
-
-               "vmlal.s16  q0, d6, d10\n"
-               "vld1.16    {d4, d5}, [%0, :64]!\n"
-               "vmlal.s16  q1, d7, d11\n"
-               "vld1.16    {d8, d9}, [%1, :128]!\n"
-
-               "vmlal.s16  q0, d4, d8\n"
-               "vmlal.s16  q1, d5, d9\n"
-
-               "vpadd.s32  d0, d0, d1\n"
-               "vpadd.s32  d1, d2, d3\n"
-
-               "vrshrn.s32 d0, q0, %3\n"
-
-               "vld1.16    {d2, d3, d4, d5}, [%1, :128]!\n"
-
-               "vdup.i32   d1, d0[1]\n"  /* TODO: can be eliminated */
-               "vdup.i32   d0, d0[0]\n"  /* TODO: can be eliminated */
-
-               "vmull.s16  q3, d2, d0\n"
-               "vmull.s16  q4, d3, d0\n"
-               "vmlal.s16  q3, d4, d1\n"
-               "vmlal.s16  q4, d5, d1\n"
-
-               "vpadd.s32  d0, d6, d7\n" /* TODO: can be eliminated */
-               "vpadd.s32  d1, d8, d9\n" /* TODO: can be eliminated */
-
-               "vst1.32    {d0, d1}, [%2, :128]\n"
-               : "+r" (in), "+r" (consts)
-               : "r" (out),
-                       "i" (SBC_PROTO_FIXED4_SCALE)
-               : "memory",
-                       "d0", "d1", "d2", "d3", "d4", "d5",
-                       "d6", "d7", "d8", "d9", "d10", "d11");
-}
-
-static inline void _sbc_analyze_eight_neon(const int16_t *in, int32_t *out,
-                                                       const FIXED_T *consts)
-{
-       /* TODO: merge even and odd cases (or even merge all four calls to this
-        * function) in order to have only aligned reads from 'in' array
-        * and reduce number of load instructions */
-       __asm__ volatile (
-               "vld1.16    {d4, d5}, [%0, :64]!\n"
-               "vld1.16    {d8, d9}, [%1, :128]!\n"
-
-               "vmull.s16  q6, d4, d8\n"
-               "vld1.16    {d6,  d7}, [%0, :64]!\n"
-               "vmull.s16  q7, d5, d9\n"
-               "vld1.16    {d10, d11}, [%1, :128]!\n"
-               "vmull.s16  q8, d6, d10\n"
-               "vld1.16    {d4, d5}, [%0, :64]!\n"
-               "vmull.s16  q9, d7, d11\n"
-               "vld1.16    {d8, d9}, [%1, :128]!\n"
-
-               "vmlal.s16  q6, d4, d8\n"
-               "vld1.16    {d6,  d7}, [%0, :64]!\n"
-               "vmlal.s16  q7, d5, d9\n"
-               "vld1.16    {d10, d11}, [%1, :128]!\n"
-               "vmlal.s16  q8, d6, d10\n"
-               "vld1.16    {d4, d5}, [%0, :64]!\n"
-               "vmlal.s16  q9, d7, d11\n"
-               "vld1.16    {d8, d9}, [%1, :128]!\n"
-
-               "vmlal.s16  q6, d4, d8\n"
-               "vld1.16    {d6,  d7}, [%0, :64]!\n"
-               "vmlal.s16  q7, d5, d9\n"
-               "vld1.16    {d10, d11}, [%1, :128]!\n"
-               "vmlal.s16  q8, d6, d10\n"
-               "vld1.16    {d4, d5}, [%0, :64]!\n"
-               "vmlal.s16  q9, d7, d11\n"
-               "vld1.16    {d8, d9}, [%1, :128]!\n"
-
-               "vmlal.s16  q6, d4, d8\n"
-               "vld1.16    {d6,  d7}, [%0, :64]!\n"
-               "vmlal.s16  q7, d5, d9\n"
-               "vld1.16    {d10, d11}, [%1, :128]!\n"
-               "vmlal.s16  q8, d6, d10\n"
-               "vld1.16    {d4, d5}, [%0, :64]!\n"
-               "vmlal.s16  q9, d7, d11\n"
-               "vld1.16    {d8, d9}, [%1, :128]!\n"
-
-               "vmlal.s16  q6, d4, d8\n"
-               "vld1.16    {d6,  d7}, [%0, :64]!\n"
-               "vmlal.s16  q7, d5, d9\n"
-               "vld1.16    {d10, d11}, [%1, :128]!\n"
-
-               "vmlal.s16  q8, d6, d10\n"
-               "vmlal.s16  q9, d7, d11\n"
-
-               "vpadd.s32  d0, d12, d13\n"
-               "vpadd.s32  d1, d14, d15\n"
-               "vpadd.s32  d2, d16, d17\n"
-               "vpadd.s32  d3, d18, d19\n"
-
-               "vrshr.s32 q0, q0, %3\n"
-               "vrshr.s32 q1, q1, %3\n"
-               "vmovn.s32 d0, q0\n"
-               "vmovn.s32 d1, q1\n"
-
-               "vdup.i32   d3, d1[1]\n"  /* TODO: can be eliminated */
-               "vdup.i32   d2, d1[0]\n"  /* TODO: can be eliminated */
-               "vdup.i32   d1, d0[1]\n"  /* TODO: can be eliminated */
-               "vdup.i32   d0, d0[0]\n"  /* TODO: can be eliminated */
-
-               "vld1.16    {d4, d5}, [%1, :128]!\n"
-               "vmull.s16  q6, d4, d0\n"
-               "vld1.16    {d6, d7}, [%1, :128]!\n"
-               "vmull.s16  q7, d5, d0\n"
-               "vmull.s16  q8, d6, d0\n"
-               "vmull.s16  q9, d7, d0\n"
-
-               "vld1.16    {d4, d5}, [%1, :128]!\n"
-               "vmlal.s16  q6, d4, d1\n"
-               "vld1.16    {d6, d7}, [%1, :128]!\n"
-               "vmlal.s16  q7, d5, d1\n"
-               "vmlal.s16  q8, d6, d1\n"
-               "vmlal.s16  q9, d7, d1\n"
-
-               "vld1.16    {d4, d5}, [%1, :128]!\n"
-               "vmlal.s16  q6, d4, d2\n"
-               "vld1.16    {d6, d7}, [%1, :128]!\n"
-               "vmlal.s16  q7, d5, d2\n"
-               "vmlal.s16  q8, d6, d2\n"
-               "vmlal.s16  q9, d7, d2\n"
-
-               "vld1.16    {d4, d5}, [%1, :128]!\n"
-               "vmlal.s16  q6, d4, d3\n"
-               "vld1.16    {d6, d7}, [%1, :128]!\n"
-               "vmlal.s16  q7, d5, d3\n"
-               "vmlal.s16  q8, d6, d3\n"
-               "vmlal.s16  q9, d7, d3\n"
-
-               "vpadd.s32  d0, d12, d13\n" /* TODO: can be eliminated */
-               "vpadd.s32  d1, d14, d15\n" /* TODO: can be eliminated */
-               "vpadd.s32  d2, d16, d17\n" /* TODO: can be eliminated */
-               "vpadd.s32  d3, d18, d19\n" /* TODO: can be eliminated */
-
-               "vst1.32    {d0, d1, d2, d3}, [%2, :128]\n"
-               : "+r" (in), "+r" (consts)
-               : "r" (out),
-                       "i" (SBC_PROTO_FIXED8_SCALE)
-               : "memory",
-                       "d0", "d1", "d2", "d3", "d4", "d5",
-                       "d6", "d7", "d8", "d9", "d10", "d11",
-                       "d12", "d13", "d14", "d15", "d16", "d17",
-                       "d18", "d19");
-}
-
-static inline void sbc_analyze_4b_4s_neon(int16_t *x,
-                                               int32_t *out, int out_stride)
-{
-       /* Analyze blocks */
-       _sbc_analyze_four_neon(x + 12, out, analysis_consts_fixed4_simd_odd);
-       out += out_stride;
-       _sbc_analyze_four_neon(x + 8, out, analysis_consts_fixed4_simd_even);
-       out += out_stride;
-       _sbc_analyze_four_neon(x + 4, out, analysis_consts_fixed4_simd_odd);
-       out += out_stride;
-       _sbc_analyze_four_neon(x + 0, out, analysis_consts_fixed4_simd_even);
-}
-
-static inline void sbc_analyze_4b_8s_neon(int16_t *x,
-                                               int32_t *out, int out_stride)
-{
-       /* Analyze blocks */
-       _sbc_analyze_eight_neon(x + 24, out, analysis_consts_fixed8_simd_odd);
-       out += out_stride;
-       _sbc_analyze_eight_neon(x + 16, out, analysis_consts_fixed8_simd_even);
-       out += out_stride;
-       _sbc_analyze_eight_neon(x + 8, out, analysis_consts_fixed8_simd_odd);
-       out += out_stride;
-       _sbc_analyze_eight_neon(x + 0, out, analysis_consts_fixed8_simd_even);
-}
-
-static void sbc_calc_scalefactors_neon(
-       int32_t sb_sample_f[16][2][8],
-       uint32_t scale_factor[2][8],
-       int blocks, int channels, int subbands)
-{
-       int ch, sb;
-       for (ch = 0; ch < channels; ch++) {
-               for (sb = 0; sb < subbands; sb += 4) {
-                       int blk = blocks;
-                       int32_t *in = &sb_sample_f[0][ch][sb];
-                       __asm__ volatile (
-                               "vmov.s32  q0, #0\n"
-                               "vmov.s32  q1, %[c1]\n"
-                               "vmov.s32  q14, #1\n"
-                               "vmov.s32  q15, %[c2]\n"
-                               "vadd.s32  q1, q1, q14\n"
-                       "1:\n"
-                               "vld1.32   {d16, d17}, [%[in], :128], %[inc]\n"
-                               "vabs.s32  q8,  q8\n"
-                               "vld1.32   {d18, d19}, [%[in], :128], %[inc]\n"
-                               "vabs.s32  q9,  q9\n"
-                               "vld1.32   {d20, d21}, [%[in], :128], %[inc]\n"
-                               "vabs.s32  q10, q10\n"
-                               "vld1.32   {d22, d23}, [%[in], :128], %[inc]\n"
-                               "vabs.s32  q11, q11\n"
-                               "vmax.s32  q0,  q0,  q8\n"
-                               "vmax.s32  q1,  q1,  q9\n"
-                               "vmax.s32  q0,  q0,  q10\n"
-                               "vmax.s32  q1,  q1,  q11\n"
-                               "subs      %[blk], %[blk], #4\n"
-                               "bgt       1b\n"
-                               "vmax.s32  q0,  q0,  q1\n"
-                               "vsub.s32  q0,  q0,  q14\n"
-                               "vclz.s32  q0,  q0\n"
-                               "vsub.s32  q0,  q15, q0\n"
-                               "vst1.32   {d0, d1}, [%[out], :128]\n"
-                       :
-                         [blk]    "+r" (blk),
-                         [in]     "+r" (in)
-                       :
-                         [inc]     "r" ((char *) &sb_sample_f[1][0][0] -
-                                        (char *) &sb_sample_f[0][0][0]),
-                         [out]     "r" (&scale_factor[ch][sb]),
-                         [c1]      "i" (1 << SCALE_OUT_BITS),
-                         [c2]      "i" (31 - SCALE_OUT_BITS)
-                       : "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19",
-                         "d20", "d21", "d22", "d23", "d24", "d25", "d26",
-                         "d27", "d28", "d29", "d30", "d31", "cc", "memory");
-               }
-       }
-}
-
-int sbc_calc_scalefactors_j_neon(
-       int32_t sb_sample_f[16][2][8],
-       uint32_t scale_factor[2][8],
-       int blocks, int subbands)
-{
-       static SBC_ALIGNED int32_t joint_bits_mask[8] = {
-               8,   4,  2,  1, 128, 64, 32, 16
-       };
-       int joint, i;
-       int32_t  *in0, *in1;
-       int32_t  *in = &sb_sample_f[0][0][0];
-       uint32_t *out0, *out1;
-       uint32_t *out = &scale_factor[0][0];
-       int32_t  *consts = joint_bits_mask;
-
-       i = subbands;
-
-       __asm__ volatile (
-               /*
-                * constants: q13 = (31 - SCALE_OUT_BITS), q14 = 1
-                * input:     q0  = ((1 << SCALE_OUT_BITS) + 1)
-                *            %[in0] - samples for channel 0
-                *            %[in1] - samples for shannel 1
-                * output:    q0, q1 - scale factors without joint stereo
-                *            q2, q3 - scale factors with joint stereo
-                *            q15    - joint stereo selection mask
-                */
-               ".macro calc_scalefactors\n"
-                       "vmov.s32  q1, q0\n"
-                       "vmov.s32  q2, q0\n"
-                       "vmov.s32  q3, q0\n"
-                       "mov       %[i], %[blocks]\n"
-               "1:\n"
-                       "vld1.32   {d18, d19}, [%[in1], :128], %[inc]\n"
-                       "vbic.s32  q11, q9,  q14\n"
-                       "vld1.32   {d16, d17}, [%[in0], :128], %[inc]\n"
-                       "vhadd.s32 q10, q8,  q11\n"
-                       "vhsub.s32 q11, q8,  q11\n"
-                       "vabs.s32  q8,  q8\n"
-                       "vabs.s32  q9,  q9\n"
-                       "vabs.s32  q10, q10\n"
-                       "vabs.s32  q11, q11\n"
-                       "vmax.s32  q0,  q0,  q8\n"
-                       "vmax.s32  q1,  q1,  q9\n"
-                       "vmax.s32  q2,  q2,  q10\n"
-                       "vmax.s32  q3,  q3,  q11\n"
-                       "subs      %[i], %[i], #1\n"
-                       "bgt       1b\n"
-                       "vsub.s32  q0,  q0,  q14\n"
-                       "vsub.s32  q1,  q1,  q14\n"
-                       "vsub.s32  q2,  q2,  q14\n"
-                       "vsub.s32  q3,  q3,  q14\n"
-                       "vclz.s32  q0,  q0\n"
-                       "vclz.s32  q1,  q1\n"
-                       "vclz.s32  q2,  q2\n"
-                       "vclz.s32  q3,  q3\n"
-                       "vsub.s32  q0,  q13, q0\n"
-                       "vsub.s32  q1,  q13, q1\n"
-                       "vsub.s32  q2,  q13, q2\n"
-                       "vsub.s32  q3,  q13, q3\n"
-               ".endm\n"
-               /*
-                * constants: q14 = 1
-                * input: q15    - joint stereo selection mask
-                *        %[in0] - value set by calc_scalefactors macro
-                *        %[in1] - value set by calc_scalefactors macro
-                */
-               ".macro update_joint_stereo_samples\n"
-                       "sub       %[out1], %[in1], %[inc]\n"
-                       "sub       %[out0], %[in0], %[inc]\n"
-                       "sub       %[in1], %[in1], %[inc], asl #1\n"
-                       "sub       %[in0], %[in0], %[inc], asl #1\n"
-                       "vld1.32   {d18, d19}, [%[in1], :128]\n"
-                       "vbic.s32  q11, q9,  q14\n"
-                       "vld1.32   {d16, d17}, [%[in0], :128]\n"
-                       "vld1.32   {d2, d3}, [%[out1], :128]\n"
-                       "vbic.s32  q3,  q1,  q14\n"
-                       "vld1.32   {d0, d1}, [%[out0], :128]\n"
-                       "vhsub.s32 q10, q8,  q11\n"
-                       "vhadd.s32 q11, q8,  q11\n"
-                       "vhsub.s32 q2,  q0,  q3\n"
-                       "vhadd.s32 q3,  q0,  q3\n"
-                       "vbif.s32  q10, q9,  q15\n"
-                       "vbif.s32  d22, d16, d30\n"
-                       "sub       %[inc], %[zero], %[inc], asl #1\n"
-                       "sub       %[i], %[blocks], #2\n"
-               "2:\n"
-                       "vbif.s32  d23, d17, d31\n"
-                       "vst1.32   {d20, d21}, [%[in1], :128], %[inc]\n"
-                       "vbif.s32  d4,  d2,  d30\n"
-                       "vld1.32   {d18, d19}, [%[in1], :128]\n"
-                       "vbif.s32  d5,  d3,  d31\n"
-                       "vst1.32   {d22, d23}, [%[in0], :128], %[inc]\n"
-                       "vbif.s32  d6,  d0,  d30\n"
-                       "vld1.32   {d16, d17}, [%[in0], :128]\n"
-                       "vbif.s32  d7,  d1,  d31\n"
-                       "vst1.32   {d4, d5}, [%[out1], :128], %[inc]\n"
-                       "vbic.s32  q11, q9,  q14\n"
-                       "vld1.32   {d2, d3}, [%[out1], :128]\n"
-                       "vst1.32   {d6, d7}, [%[out0], :128], %[inc]\n"
-                       "vbic.s32  q3,  q1,  q14\n"
-                       "vld1.32   {d0, d1}, [%[out0], :128]\n"
-                       "vhsub.s32 q10, q8,  q11\n"
-                       "vhadd.s32 q11, q8,  q11\n"
-                       "vhsub.s32 q2,  q0,  q3\n"
-                       "vhadd.s32 q3,  q0,  q3\n"
-                       "vbif.s32  q10, q9,  q15\n"
-                       "vbif.s32  d22, d16, d30\n"
-                       "subs      %[i], %[i], #2\n"
-                       "bgt       2b\n"
-                       "sub       %[inc], %[zero], %[inc], asr #1\n"
-                       "vbif.s32  d23, d17, d31\n"
-                       "vst1.32   {d20, d21}, [%[in1], :128]\n"
-                       "vbif.s32  q2,  q1,  q15\n"
-                       "vst1.32   {d22, d23}, [%[in0], :128]\n"
-                       "vbif.s32  q3,  q0,  q15\n"
-                       "vst1.32   {d4, d5}, [%[out1], :128]\n"
-                       "vst1.32   {d6, d7}, [%[out0], :128]\n"
-               ".endm\n"
-
-               "vmov.s32  q14, #1\n"
-               "vmov.s32  q13, %[c2]\n"
-
-               "cmp   %[i], #4\n"
-               "bne   8f\n"
-
-       "4:\n" /* 4 subbands */
-               "add   %[in0], %[in], #0\n"
-               "add   %[in1], %[in], #32\n"
-               "add   %[out0], %[out], #0\n"
-               "add   %[out1], %[out], #32\n"
-               "vmov.s32  q0, %[c1]\n"
-               "vadd.s32  q0, q0, q14\n"
-
-               "calc_scalefactors\n"
-
-               /* check whether to use joint stereo for subbands 0, 1, 2 */
-               "vadd.s32  q15, q0,  q1\n"
-               "vadd.s32  q9,  q2,  q3\n"
-               "vmov.s32  d31[1], %[zero]\n" /* last subband -> no joint */
-               "vld1.32   {d16, d17}, [%[consts], :128]!\n"
-               "vcgt.s32  q15, q15, q9\n"
-
-               /* calculate and save to memory 'joint' variable */
-               /* update and save scale factors to memory */
-               "  vand.s32  q8, q8, q15\n"
-               "vbit.s32  q0,  q2,  q15\n"
-               "  vpadd.s32 d16, d16, d17\n"
-               "vbit.s32  q1,  q3,  q15\n"
-               "  vpadd.s32 d16, d16, d16\n"
-               "vst1.32   {d0, d1}, [%[out0], :128]\n"
-               "vst1.32   {d2, d3}, [%[out1], :128]\n"
-               "  vst1.32   {d16[0]}, [%[joint]]\n"
-
-               "update_joint_stereo_samples\n"
-               "b     9f\n"
-
-       "8:\n" /* 8 subbands */
-               "add   %[in0], %[in], #16\n\n"
-               "add   %[in1], %[in], #48\n"
-               "add   %[out0], %[out], #16\n\n"
-               "add   %[out1], %[out], #48\n"
-               "vmov.s32  q0, %[c1]\n"
-               "vadd.s32  q0, q0, q14\n"
-
-               "calc_scalefactors\n"
-
-               /* check whether to use joint stereo for subbands 4, 5, 6 */
-               "vadd.s32  q15, q0,  q1\n"
-               "vadd.s32  q9,  q2,  q3\n"
-               "vmov.s32  d31[1], %[zero]\n"  /* last subband -> no joint */
-               "vld1.32   {d16, d17}, [%[consts], :128]!\n"
-               "vcgt.s32  q15, q15, q9\n"
-
-               /* calculate part of 'joint' variable and save it to d24 */
-               /* update and save scale factors to memory */
-               "  vand.s32  q8, q8, q15\n"
-               "vbit.s32  q0,  q2,  q15\n"
-               "  vpadd.s32 d16, d16, d17\n"
-               "vbit.s32  q1,  q3,  q15\n"
-               "vst1.32   {d0, d1}, [%[out0], :128]\n"
-               "vst1.32   {d2, d3}, [%[out1], :128]\n"
-               "  vpadd.s32 d24, d16, d16\n"
-
-               "update_joint_stereo_samples\n"
-
-               "add   %[in0], %[in], #0\n"
-               "add   %[in1], %[in], #32\n"
-               "add   %[out0], %[out], #0\n\n"
-               "add   %[out1], %[out], #32\n"
-               "vmov.s32  q0, %[c1]\n"
-               "vadd.s32  q0, q0, q14\n"
-
-               "calc_scalefactors\n"
-
-               /* check whether to use joint stereo for subbands 0, 1, 2, 3 */
-               "vadd.s32  q15, q0,  q1\n"
-               "vadd.s32  q9,  q2,  q3\n"
-               "vld1.32   {d16, d17}, [%[consts], :128]!\n"
-               "vcgt.s32  q15, q15, q9\n"
-
-               /* combine last part of 'joint' with d24 and save to memory */
-               /* update and save scale factors to memory */
-               "  vand.s32  q8, q8, q15\n"
-               "vbit.s32  q0,  q2,  q15\n"
-               "  vpadd.s32 d16, d16, d17\n"
-               "vbit.s32  q1,  q3,  q15\n"
-               "  vpadd.s32 d16, d16, d16\n"
-               "vst1.32   {d0, d1}, [%[out0], :128]\n"
-               "  vadd.s32  d16, d16, d24\n"
-               "vst1.32   {d2, d3}, [%[out1], :128]\n"
-               "  vst1.32   {d16[0]}, [%[joint]]\n"
-
-               "update_joint_stereo_samples\n"
-       "9:\n"
-               ".purgem calc_scalefactors\n"
-               ".purgem update_joint_stereo_samples\n"
-               :
-                 [i]      "+&r" (i),
-                 [in]     "+&r" (in),
-                 [in0]    "=&r" (in0),
-                 [in1]    "=&r" (in1),
-                 [out]    "+&r" (out),
-                 [out0]   "=&r" (out0),
-                 [out1]   "=&r" (out1),
-                 [consts] "+&r" (consts)
-               :
-                 [inc]      "r" ((char *) &sb_sample_f[1][0][0] -
-                                (char *) &sb_sample_f[0][0][0]),
-                 [blocks]   "r" (blocks),
-                 [joint]    "r" (&joint),
-                 [c1]       "i" (1 << SCALE_OUT_BITS),
-                 [c2]       "i" (31 - SCALE_OUT_BITS),
-                 [zero]     "r" (0)
-               : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
-                 "d16", "d17", "d18", "d19", "d20", "d21", "d22",
-                 "d23", "d24", "d25", "d26", "d27", "d28", "d29",
-                 "d30", "d31", "cc", "memory");
-
-       return joint;
-}
-
-#define PERM_BE(a, b, c, d) {             \
-               (a * 2) + 1, (a * 2) + 0, \
-               (b * 2) + 1, (b * 2) + 0, \
-               (c * 2) + 1, (c * 2) + 0, \
-               (d * 2) + 1, (d * 2) + 0  \
-       }
-#define PERM_LE(a, b, c, d) {             \
-               (a * 2) + 0, (a * 2) + 1, \
-               (b * 2) + 0, (b * 2) + 1, \
-               (c * 2) + 0, (c * 2) + 1, \
-               (d * 2) + 0, (d * 2) + 1  \
-       }
-
-static SBC_ALWAYS_INLINE int sbc_enc_process_input_4s_neon_internal(
-       int position,
-       const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
-       int nsamples, int nchannels, int big_endian)
-{
-       static SBC_ALIGNED uint8_t perm_be[2][8] = {
-               PERM_BE(7, 3, 6, 4),
-               PERM_BE(0, 2, 1, 5)
-       };
-       static SBC_ALIGNED uint8_t perm_le[2][8] = {
-               PERM_LE(7, 3, 6, 4),
-               PERM_LE(0, 2, 1, 5)
-       };
-       /* handle X buffer wraparound */
-       if (position < nsamples) {
-               int16_t *dst = &X[0][SBC_X_BUFFER_SIZE - 40];
-               int16_t *src = &X[0][position];
-               __asm__ volatile (
-                       "vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
-                       "vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
-                       "vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
-                       "vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
-                       "vld1.16 {d0}, [%[src], :64]!\n"
-                       "vst1.16 {d0}, [%[dst], :64]!\n"
-                       :
-                         [dst] "+r" (dst),
-                         [src] "+r" (src)
-                       : : "memory", "d0", "d1", "d2", "d3");
-               if (nchannels > 1) {
-                       dst = &X[1][SBC_X_BUFFER_SIZE - 40];
-                       src = &X[1][position];
-                       __asm__ volatile (
-                               "vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
-                               "vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
-                               "vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
-                               "vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
-                               "vld1.16 {d0}, [%[src], :64]!\n"
-                               "vst1.16 {d0}, [%[dst], :64]!\n"
-                               :
-                                 [dst] "+r" (dst),
-                                 [src] "+r" (src)
-                               : : "memory", "d0", "d1", "d2", "d3");
-               }
-               position = SBC_X_BUFFER_SIZE - 40;
-       }
-
-       if ((nchannels > 1) && ((uintptr_t)pcm & 1)) {
-               /* poor 'pcm' alignment */
-               int16_t *x = &X[0][position];
-               int16_t *y = &X[1][position];
-               __asm__ volatile (
-                       "vld1.8  {d0, d1}, [%[perm], :128]\n"
-               "1:\n"
-                       "sub     %[x], %[x], #16\n"
-                       "sub     %[y], %[y], #16\n"
-                       "sub     %[position], %[position], #8\n"
-                       "vld1.8  {d4, d5}, [%[pcm]]!\n"
-                       "vuzp.16 d4,  d5\n"
-                       "vld1.8  {d20, d21}, [%[pcm]]!\n"
-                       "vuzp.16 d20, d21\n"
-                       "vswp    d5,  d20\n"
-                       "vtbl.8  d16, {d4, d5}, d0\n"
-                       "vtbl.8  d17, {d4, d5}, d1\n"
-                       "vtbl.8  d18, {d20, d21}, d0\n"
-                       "vtbl.8  d19, {d20, d21}, d1\n"
-                       "vst1.16 {d16, d17}, [%[x], :128]\n"
-                       "vst1.16 {d18, d19}, [%[y], :128]\n"
-                       "subs    %[nsamples], %[nsamples], #8\n"
-                       "bgt     1b\n"
-                       :
-                         [x]        "+r" (x),
-                         [y]        "+r" (y),
-                         [pcm]      "+r" (pcm),
-                         [nsamples] "+r" (nsamples),
-                         [position] "+r" (position)
-                       :
-                         [perm]      "r" (big_endian ? perm_be : perm_le)
-                       : "cc", "memory", "d0", "d1", "d2", "d3", "d4",
-                         "d5", "d6", "d7", "d16", "d17", "d18", "d19",
-                         "d20", "d21", "d22", "d23");
-       } else if (nchannels > 1) {
-               /* proper 'pcm' alignment */
-               int16_t *x = &X[0][position];
-               int16_t *y = &X[1][position];
-               __asm__ volatile (
-                       "vld1.8  {d0, d1}, [%[perm], :128]\n"
-               "1:\n"
-                       "sub     %[x], %[x], #16\n"
-                       "sub     %[y], %[y], #16\n"
-                       "sub     %[position], %[position], #8\n"
-                       "vld2.16 {d4, d5}, [%[pcm]]!\n"
-                       "vld2.16 {d20, d21}, [%[pcm]]!\n"
-                       "vswp    d5, d20\n"
-                       "vtbl.8  d16, {d4, d5}, d0\n"
-                       "vtbl.8  d17, {d4, d5}, d1\n"
-                       "vtbl.8  d18, {d20, d21}, d0\n"
-                       "vtbl.8  d19, {d20, d21}, d1\n"
-                       "vst1.16 {d16, d17}, [%[x], :128]\n"
-                       "vst1.16 {d18, d19}, [%[y], :128]\n"
-                       "subs    %[nsamples], %[nsamples], #8\n"
-                       "bgt     1b\n"
-                       :
-                         [x]        "+r" (x),
-                         [y]        "+r" (y),
-                         [pcm]      "+r" (pcm),
-                         [nsamples] "+r" (nsamples),
-                         [position] "+r" (position)
-                       :
-                         [perm]      "r" (big_endian ? perm_be : perm_le)
-                       : "cc", "memory", "d0", "d1", "d2", "d3", "d4",
-                         "d5", "d6", "d7", "d16", "d17", "d18", "d19",
-                         "d20", "d21", "d22", "d23");
-       } else {
-               int16_t *x = &X[0][position];
-               __asm__ volatile (
-                       "vld1.8  {d0, d1}, [%[perm], :128]\n"
-               "1:\n"
-                       "sub     %[x], %[x], #16\n"
-                       "sub     %[position], %[position], #8\n"
-                       "vld1.8  {d4, d5}, [%[pcm]]!\n"
-                       "vtbl.8  d16, {d4, d5}, d0\n"
-                       "vtbl.8  d17, {d4, d5}, d1\n"
-                       "vst1.16 {d16, d17}, [%[x], :128]\n"
-                       "subs    %[nsamples], %[nsamples], #8\n"
-                       "bgt     1b\n"
-                       :
-                         [x]        "+r" (x),
-                         [pcm]      "+r" (pcm),
-                         [nsamples] "+r" (nsamples),
-                         [position] "+r" (position)
-                       :
-                         [perm]      "r" (big_endian ? perm_be : perm_le)
-                       : "cc", "memory", "d0", "d1", "d2", "d3", "d4",
-                         "d5", "d6", "d7", "d16", "d17", "d18", "d19");
-       }
-       return position;
-}
-
-static SBC_ALWAYS_INLINE int sbc_enc_process_input_8s_neon_internal(
-       int position,
-       const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
-       int nsamples, int nchannels, int big_endian)
-{
-       static SBC_ALIGNED uint8_t perm_be[4][8] = {
-               PERM_BE(15, 7, 14, 8),
-               PERM_BE(13, 9, 12, 10),
-               PERM_BE(11, 3, 6,  0),
-               PERM_BE(5,  1, 4,  2)
-       };
-       static SBC_ALIGNED uint8_t perm_le[4][8] = {
-               PERM_LE(15, 7, 14, 8),
-               PERM_LE(13, 9, 12, 10),
-               PERM_LE(11, 3, 6,  0),
-               PERM_LE(5,  1, 4,  2)
-       };
-       /* handle X buffer wraparound */
-       if (position < nsamples) {
-               int16_t *dst = &X[0][SBC_X_BUFFER_SIZE - 72];
-               int16_t *src = &X[0][position];
-               __asm__ volatile (
-                       "vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
-                       "vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
-                       "vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
-                       "vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
-                       "vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
-                       "vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
-                       "vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
-                       "vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
-                       "vld1.16 {d0, d1}, [%[src], :128]!\n"
-                       "vst1.16 {d0, d1}, [%[dst], :128]!\n"
-                       :
-                         [dst] "+r" (dst),
-                         [src] "+r" (src)
-                       : : "memory", "d0", "d1", "d2", "d3");
-               if (nchannels > 1) {
-                       dst = &X[1][SBC_X_BUFFER_SIZE - 72];
-                       src = &X[1][position];
-                       __asm__ volatile (
-                               "vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
-                               "vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
-                               "vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
-                               "vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
-                               "vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
-                               "vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
-                               "vld1.16 {d0, d1, d2, d3}, [%[src], :128]!\n"
-                               "vst1.16 {d0, d1, d2, d3}, [%[dst], :128]!\n"
-                               "vld1.16 {d0, d1}, [%[src], :128]!\n"
-                               "vst1.16 {d0, d1}, [%[dst], :128]!\n"
-                               :
-                                 [dst] "+r" (dst),
-                                 [src] "+r" (src)
-                               : : "memory", "d0", "d1", "d2", "d3");
-               }
-               position = SBC_X_BUFFER_SIZE - 72;
-       }
-
-       if ((nchannels > 1) && ((uintptr_t)pcm & 1)) {
-               /* poor 'pcm' alignment */
-               int16_t *x = &X[0][position];
-               int16_t *y = &X[1][position];
-               __asm__ volatile (
-                       "vld1.8  {d0, d1, d2, d3}, [%[perm], :128]\n"
-               "1:\n"
-                       "sub     %[x], %[x], #32\n"
-                       "sub     %[y], %[y], #32\n"
-                       "sub     %[position], %[position], #16\n"
-                       "vld1.8  {d4, d5, d6, d7}, [%[pcm]]!\n"
-                       "vuzp.16 q2,  q3\n"
-                       "vld1.8  {d20, d21, d22, d23}, [%[pcm]]!\n"
-                       "vuzp.16 q10, q11\n"
-                       "vswp    q3,  q10\n"
-                       "vtbl.8  d16, {d4, d5, d6, d7}, d0\n"
-                       "vtbl.8  d17, {d4, d5, d6, d7}, d1\n"
-                       "vtbl.8  d18, {d4, d5, d6, d7}, d2\n"
-                       "vtbl.8  d19, {d4, d5, d6, d7}, d3\n"
-                       "vst1.16 {d16, d17, d18, d19}, [%[x], :128]\n"
-                       "vtbl.8  d16, {d20, d21, d22, d23}, d0\n"
-                       "vtbl.8  d17, {d20, d21, d22, d23}, d1\n"
-                       "vtbl.8  d18, {d20, d21, d22, d23}, d2\n"
-                       "vtbl.8  d19, {d20, d21, d22, d23}, d3\n"
-                       "vst1.16 {d16, d17, d18, d19}, [%[y], :128]\n"
-                       "subs    %[nsamples], %[nsamples], #16\n"
-                       "bgt     1b\n"
-                       :
-                         [x]        "+r" (x),
-                         [y]        "+r" (y),
-                         [pcm]      "+r" (pcm),
-                         [nsamples] "+r" (nsamples),
-                         [position] "+r" (position)
-                       :
-                         [perm]      "r" (big_endian ? perm_be : perm_le)
-                       : "cc", "memory", "d0", "d1", "d2", "d3", "d4",
-                         "d5", "d6", "d7", "d16", "d17", "d18", "d19",
-                         "d20", "d21", "d22", "d23");
-       } else if (nchannels > 1) {
-               /* proper 'pcm' alignment */
-               int16_t *x = &X[0][position];
-               int16_t *y = &X[1][position];
-               __asm__ volatile (
-                       "vld1.8  {d0, d1, d2, d3}, [%[perm], :128]\n"
-               "1:\n"
-                       "sub     %[x], %[x], #32\n"
-                       "sub     %[y], %[y], #32\n"
-                       "sub     %[position], %[position], #16\n"
-                       "vld2.16  {d4, d5, d6, d7}, [%[pcm]]!\n"
-                       "vld2.16  {d20, d21, d22, d23}, [%[pcm]]!\n"
-                       "vswp    q3, q10\n"
-                       "vtbl.8  d16, {d4, d5, d6, d7}, d0\n"
-                       "vtbl.8  d17, {d4, d5, d6, d7}, d1\n"
-                       "vtbl.8  d18, {d4, d5, d6, d7}, d2\n"
-                       "vtbl.8  d19, {d4, d5, d6, d7}, d3\n"
-                       "vst1.16 {d16, d17, d18, d19}, [%[x], :128]\n"
-                       "vtbl.8  d16, {d20, d21, d22, d23}, d0\n"
-                       "vtbl.8  d17, {d20, d21, d22, d23}, d1\n"
-                       "vtbl.8  d18, {d20, d21, d22, d23}, d2\n"
-                       "vtbl.8  d19, {d20, d21, d22, d23}, d3\n"
-                       "vst1.16 {d16, d17, d18, d19}, [%[y], :128]\n"
-                       "subs    %[nsamples], %[nsamples], #16\n"
-                       "bgt     1b\n"
-                       :
-                         [x]        "+r" (x),
-                         [y]        "+r" (y),
-                         [pcm]      "+r" (pcm),
-                         [nsamples] "+r" (nsamples),
-                         [position] "+r" (position)
-                       :
-                         [perm]      "r" (big_endian ? perm_be : perm_le)
-                       : "cc", "memory", "d0", "d1", "d2", "d3", "d4",
-                         "d5", "d6", "d7", "d16", "d17", "d18", "d19",
-                         "d20", "d21", "d22", "d23");
-       } else {
-               int16_t *x = &X[0][position];
-               __asm__ volatile (
-                       "vld1.8  {d0, d1, d2, d3}, [%[perm], :128]\n"
-               "1:\n"
-                       "sub     %[x], %[x], #32\n"
-                       "sub     %[position], %[position], #16\n"
-                       "vld1.8  {d4, d5, d6, d7}, [%[pcm]]!\n"
-                       "vtbl.8  d16, {d4, d5, d6, d7}, d0\n"
-                       "vtbl.8  d17, {d4, d5, d6, d7}, d1\n"
-                       "vtbl.8  d18, {d4, d5, d6, d7}, d2\n"
-                       "vtbl.8  d19, {d4, d5, d6, d7}, d3\n"
-                       "vst1.16 {d16, d17, d18, d19}, [%[x], :128]\n"
-                       "subs    %[nsamples], %[nsamples], #16\n"
-                       "bgt     1b\n"
-                       :
-                         [x]        "+r" (x),
-                         [pcm]      "+r" (pcm),
-                         [nsamples] "+r" (nsamples),
-                         [position] "+r" (position)
-                       :
-                         [perm]      "r" (big_endian ? perm_be : perm_le)
-                       : "cc", "memory", "d0", "d1", "d2", "d3", "d4",
-                         "d5", "d6", "d7", "d16", "d17", "d18", "d19");
-       }
-       return position;
-}
-
-#undef PERM_BE
-#undef PERM_LE
-
-static int sbc_enc_process_input_4s_be_neon(int position, const uint8_t *pcm,
-                                       int16_t X[2][SBC_X_BUFFER_SIZE],
-                                       int nsamples, int nchannels)
-{
-       return sbc_enc_process_input_4s_neon_internal(
-               position, pcm, X, nsamples, nchannels, 1);
-}
-
-static int sbc_enc_process_input_4s_le_neon(int position, const uint8_t *pcm,
-                                       int16_t X[2][SBC_X_BUFFER_SIZE],
-                                       int nsamples, int nchannels)
-{
-       return sbc_enc_process_input_4s_neon_internal(
-               position, pcm, X, nsamples, nchannels, 0);
-}
-
-static int sbc_enc_process_input_8s_be_neon(int position, const uint8_t *pcm,
-                                       int16_t X[2][SBC_X_BUFFER_SIZE],
-                                       int nsamples, int nchannels)
-{
-       return sbc_enc_process_input_8s_neon_internal(
-               position, pcm, X, nsamples, nchannels, 1);
-}
-
-static int sbc_enc_process_input_8s_le_neon(int position, const uint8_t *pcm,
-                                       int16_t X[2][SBC_X_BUFFER_SIZE],
-                                       int nsamples, int nchannels)
-{
-       return sbc_enc_process_input_8s_neon_internal(
-               position, pcm, X, nsamples, nchannels, 0);
-}
-
-void sbc_init_primitives_neon(struct sbc_encoder_state *state)
-{
-       state->sbc_analyze_4b_4s = sbc_analyze_4b_4s_neon;
-       state->sbc_analyze_4b_8s = sbc_analyze_4b_8s_neon;
-       state->sbc_calc_scalefactors = sbc_calc_scalefactors_neon;
-       state->sbc_calc_scalefactors_j = sbc_calc_scalefactors_j_neon;
-       state->sbc_enc_process_input_4s_le = sbc_enc_process_input_4s_le_neon;
-       state->sbc_enc_process_input_4s_be = sbc_enc_process_input_4s_be_neon;
-       state->sbc_enc_process_input_8s_le = sbc_enc_process_input_8s_le_neon;
-       state->sbc_enc_process_input_8s_be = sbc_enc_process_input_8s_be_neon;
-       state->implementation_info = "NEON";
-}
-
-#endif
diff --git a/src/modules/bluetooth/sbc/sbc_primitives_neon.h b/src/modules/bluetooth/sbc/sbc_primitives_neon.h
deleted file mode 100644 (file)
index ea3da06..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *
- *  Bluetooth low-complexity, subband codec (SBC) library
- *
- *  Copyright (C) 2008-2010  Nokia Corporation
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
- *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef __SBC_PRIMITIVES_NEON_H
-#define __SBC_PRIMITIVES_NEON_H
-
-#include "sbc_primitives.h"
-
-#if defined(__GNUC__) && defined(__ARM_NEON__) && \
-               !defined(SBC_HIGH_PRECISION) && (SCALE_OUT_BITS == 15)
-
-#define SBC_BUILD_WITH_NEON_SUPPORT
-
-void sbc_init_primitives_neon(struct sbc_encoder_state *encoder_state);
-
-#endif
-
-#endif
diff --git a/src/modules/bluetooth/sbc/sbc_tables.h b/src/modules/bluetooth/sbc/sbc_tables.h
deleted file mode 100644 (file)
index 25e24e6..0000000
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- *
- *  Bluetooth low-complexity, subband codec (SBC) library
- *
- *  Copyright (C) 2008-2010  Nokia Corporation
- *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
- *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
- *
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-/* A2DP specification: Appendix B, page 69 */
-static const int sbc_offset4[4][4] = {
-       { -1, 0, 0, 0 },
-       { -2, 0, 0, 1 },
-       { -2, 0, 0, 1 },
-       { -2, 0, 0, 1 }
-};
-
-/* A2DP specification: Appendix B, page 69 */
-static const int sbc_offset8[4][8] = {
-       { -2, 0, 0, 0, 0, 0, 0, 1 },
-       { -3, 0, 0, 0, 0, 0, 1, 2 },
-       { -4, 0, 0, 0, 0, 0, 1, 2 },
-       { -4, 0, 0, 0, 0, 0, 1, 2 }
-};
-
-/* extra bits of precision for the synthesis filter input data */
-#define SBCDEC_FIXED_EXTRA_BITS 2
-
-#define SS4(val) ASR(val, SCALE_SPROTO4_TBL)
-#define SS8(val) ASR(val, SCALE_SPROTO8_TBL)
-#define SN4(val) ASR(val, SCALE_NPROTO4_TBL + 1 + SBCDEC_FIXED_EXTRA_BITS)
-#define SN8(val) ASR(val, SCALE_NPROTO8_TBL + 1 + SBCDEC_FIXED_EXTRA_BITS)
-
-static const int32_t sbc_proto_4_40m0[] = {
-       SS4(0x00000000), SS4(0xffa6982f), SS4(0xfba93848), SS4(0x0456c7b8),
-       SS4(0x005967d1), SS4(0xfffb9ac7), SS4(0xff589157), SS4(0xf9c2a8d8),
-       SS4(0x027c1434), SS4(0x0019118b), SS4(0xfff3c74c), SS4(0xff137330),
-       SS4(0xf81b8d70), SS4(0x00ec1b8b), SS4(0xfff0b71a), SS4(0xffe99b00),
-       SS4(0xfef84470), SS4(0xf6fb4370), SS4(0xffcdc351), SS4(0xffe01dc7)
-};
-
-static const int32_t sbc_proto_4_40m1[] = {
-       SS4(0xffe090ce), SS4(0xff2c0475), SS4(0xf694f800), SS4(0xff2c0475),
-       SS4(0xffe090ce), SS4(0xffe01dc7), SS4(0xffcdc351), SS4(0xf6fb4370),
-       SS4(0xfef84470), SS4(0xffe99b00), SS4(0xfff0b71a), SS4(0x00ec1b8b),
-       SS4(0xf81b8d70), SS4(0xff137330), SS4(0xfff3c74c), SS4(0x0019118b),
-       SS4(0x027c1434), SS4(0xf9c2a8d8), SS4(0xff589157), SS4(0xfffb9ac7)
-};
-
-static const int32_t sbc_proto_8_80m0[] = {
-       SS8(0x00000000), SS8(0xfe8d1970), SS8(0xee979f00), SS8(0x11686100),
-       SS8(0x0172e690), SS8(0xfff5bd1a), SS8(0xfdf1c8d4), SS8(0xeac182c0),
-       SS8(0x0d9daee0), SS8(0x00e530da), SS8(0xffe9811d), SS8(0xfd52986c),
-       SS8(0xe7054ca0), SS8(0x0a00d410), SS8(0x006c1de4), SS8(0xffdba705),
-       SS8(0xfcbc98e8), SS8(0xe3889d20), SS8(0x06af2308), SS8(0x000bb7db),
-       SS8(0xffca00ed), SS8(0xfc3fbb68), SS8(0xe071bc00), SS8(0x03bf7948),
-       SS8(0xffc4e05c), SS8(0xffb54b3b), SS8(0xfbedadc0), SS8(0xdde26200),
-       SS8(0x0142291c), SS8(0xff960e94), SS8(0xff9f3e17), SS8(0xfbd8f358),
-       SS8(0xdbf79400), SS8(0xff405e01), SS8(0xff7d4914), SS8(0xff8b1a31),
-       SS8(0xfc1417b8), SS8(0xdac7bb40), SS8(0xfdbb828c), SS8(0xff762170)
-};
-
-static const int32_t sbc_proto_8_80m1[] = {
-       SS8(0xff7c272c), SS8(0xfcb02620), SS8(0xda612700), SS8(0xfcb02620),
-       SS8(0xff7c272c), SS8(0xff762170), SS8(0xfdbb828c), SS8(0xdac7bb40),
-       SS8(0xfc1417b8), SS8(0xff8b1a31), SS8(0xff7d4914), SS8(0xff405e01),
-       SS8(0xdbf79400), SS8(0xfbd8f358), SS8(0xff9f3e17), SS8(0xff960e94),
-       SS8(0x0142291c), SS8(0xdde26200), SS8(0xfbedadc0), SS8(0xffb54b3b),
-       SS8(0xffc4e05c), SS8(0x03bf7948), SS8(0xe071bc00), SS8(0xfc3fbb68),
-       SS8(0xffca00ed), SS8(0x000bb7db), SS8(0x06af2308), SS8(0xe3889d20),
-       SS8(0xfcbc98e8), SS8(0xffdba705), SS8(0x006c1de4), SS8(0x0a00d410),
-       SS8(0xe7054ca0), SS8(0xfd52986c), SS8(0xffe9811d), SS8(0x00e530da),
-       SS8(0x0d9daee0), SS8(0xeac182c0), SS8(0xfdf1c8d4), SS8(0xfff5bd1a)
-};
-
-static const int32_t synmatrix4[8][4] = {
-       { SN4(0x05a82798), SN4(0xfa57d868), SN4(0xfa57d868), SN4(0x05a82798) },
-       { SN4(0x030fbc54), SN4(0xf89be510), SN4(0x07641af0), SN4(0xfcf043ac) },
-       { SN4(0x00000000), SN4(0x00000000), SN4(0x00000000), SN4(0x00000000) },
-       { SN4(0xfcf043ac), SN4(0x07641af0), SN4(0xf89be510), SN4(0x030fbc54) },
-       { SN4(0xfa57d868), SN4(0x05a82798), SN4(0x05a82798), SN4(0xfa57d868) },
-       { SN4(0xf89be510), SN4(0xfcf043ac), SN4(0x030fbc54), SN4(0x07641af0) },
-       { SN4(0xf8000000), SN4(0xf8000000), SN4(0xf8000000), SN4(0xf8000000) },
-       { SN4(0xf89be510), SN4(0xfcf043ac), SN4(0x030fbc54), SN4(0x07641af0) }
-};
-
-static const int32_t synmatrix8[16][8] = {
-       { SN8(0x05a82798), SN8(0xfa57d868), SN8(0xfa57d868), SN8(0x05a82798),
-         SN8(0x05a82798), SN8(0xfa57d868), SN8(0xfa57d868), SN8(0x05a82798) },
-       { SN8(0x0471ced0), SN8(0xf8275a10), SN8(0x018f8b84), SN8(0x06a6d988),
-         SN8(0xf9592678), SN8(0xfe70747c), SN8(0x07d8a5f0), SN8(0xfb8e3130) },
-       { SN8(0x030fbc54), SN8(0xf89be510), SN8(0x07641af0), SN8(0xfcf043ac),
-         SN8(0xfcf043ac), SN8(0x07641af0), SN8(0xf89be510), SN8(0x030fbc54) },
-       { SN8(0x018f8b84), SN8(0xfb8e3130), SN8(0x06a6d988), SN8(0xf8275a10),
-         SN8(0x07d8a5f0), SN8(0xf9592678), SN8(0x0471ced0), SN8(0xfe70747c) },
-       { SN8(0x00000000), SN8(0x00000000), SN8(0x00000000), SN8(0x00000000),
-         SN8(0x00000000), SN8(0x00000000), SN8(0x00000000), SN8(0x00000000) },
-       { SN8(0xfe70747c), SN8(0x0471ced0), SN8(0xf9592678), SN8(0x07d8a5f0),
-         SN8(0xf8275a10), SN8(0x06a6d988), SN8(0xfb8e3130), SN8(0x018f8b84) },
-       { SN8(0xfcf043ac), SN8(0x07641af0), SN8(0xf89be510), SN8(0x030fbc54),
-         SN8(0x030fbc54), SN8(0xf89be510), SN8(0x07641af0), SN8(0xfcf043ac) },
-       { SN8(0xfb8e3130), SN8(0x07d8a5f0), SN8(0xfe70747c), SN8(0xf9592678),
-         SN8(0x06a6d988), SN8(0x018f8b84), SN8(0xf8275a10), SN8(0x0471ced0) },
-       { SN8(0xfa57d868), SN8(0x05a82798), SN8(0x05a82798), SN8(0xfa57d868),
-         SN8(0xfa57d868), SN8(0x05a82798), SN8(0x05a82798), SN8(0xfa57d868) },
-       { SN8(0xf9592678), SN8(0x018f8b84), SN8(0x07d8a5f0), SN8(0x0471ced0),
-         SN8(0xfb8e3130), SN8(0xf8275a10), SN8(0xfe70747c), SN8(0x06a6d988) },
-       { SN8(0xf89be510), SN8(0xfcf043ac), SN8(0x030fbc54), SN8(0x07641af0),
-         SN8(0x07641af0), SN8(0x030fbc54), SN8(0xfcf043ac), SN8(0xf89be510) },
-       { SN8(0xf8275a10), SN8(0xf9592678), SN8(0xfb8e3130), SN8(0xfe70747c),
-         SN8(0x018f8b84), SN8(0x0471ced0), SN8(0x06a6d988), SN8(0x07d8a5f0) },
-       { SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000),
-         SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000) },
-       { SN8(0xf8275a10), SN8(0xf9592678), SN8(0xfb8e3130), SN8(0xfe70747c),
-         SN8(0x018f8b84), SN8(0x0471ced0), SN8(0x06a6d988), SN8(0x07d8a5f0) },
-       { SN8(0xf89be510), SN8(0xfcf043ac), SN8(0x030fbc54), SN8(0x07641af0),
-         SN8(0x07641af0), SN8(0x030fbc54), SN8(0xfcf043ac), SN8(0xf89be510) },
-       { SN8(0xf9592678), SN8(0x018f8b84), SN8(0x07d8a5f0), SN8(0x0471ced0),
-         SN8(0xfb8e3130), SN8(0xf8275a10), SN8(0xfe70747c), SN8(0x06a6d988) }
-};
-
-/* Uncomment the following line to enable high precision build of SBC encoder */
-
-/* #define SBC_HIGH_PRECISION */
-
-#ifdef SBC_HIGH_PRECISION
-#define FIXED_A int64_t /* data type for fixed point accumulator */
-#define FIXED_T int32_t /* data type for fixed point constants */
-#define SBC_FIXED_EXTRA_BITS 16
-#else
-#define FIXED_A int32_t /* data type for fixed point accumulator */
-#define FIXED_T int16_t /* data type for fixed point constants */
-#define SBC_FIXED_EXTRA_BITS 0
-#endif
-
-/* A2DP specification: Section 12.8 Tables
- *
- * Original values are premultiplied by 2 for better precision (that is the
- * maximum which is possible without overflows)
- *
- * Note: in each block of 8 numbers sign was changed for elements 2 and 7
- * in order to compensate the same change applied to cos_table_fixed_4
- */
-#define SBC_PROTO_FIXED4_SCALE \
-       ((sizeof(FIXED_T) * CHAR_BIT - 1) - SBC_FIXED_EXTRA_BITS + 1)
-#define F_PROTO4(x) (FIXED_A) ((x * 2) * \
-       ((FIXED_A) 1 << (sizeof(FIXED_T) * CHAR_BIT - 1)) + 0.5)
-#define F(x) F_PROTO4(x)
-static const FIXED_T _sbc_proto_fixed4[40] = {
-       F(0.00000000E+00),  F(5.36548976E-04),
-       -F(1.49188357E-03),  F(2.73370904E-03),
-       F(3.83720193E-03),  F(3.89205149E-03),
-       F(1.86581691E-03),  F(3.06012286E-03),
-
-       F(1.09137620E-02),  F(2.04385087E-02),
-       -F(2.88757392E-02),  F(3.21939290E-02),
-       F(2.58767811E-02),  F(6.13245186E-03),
-       -F(2.88217274E-02),  F(7.76463494E-02),
-
-       F(1.35593274E-01),  F(1.94987841E-01),
-       -F(2.46636662E-01),  F(2.81828203E-01),
-       F(2.94315332E-01),  F(2.81828203E-01),
-       F(2.46636662E-01), -F(1.94987841E-01),
-
-       -F(1.35593274E-01), -F(7.76463494E-02),
-       F(2.88217274E-02),  F(6.13245186E-03),
-       F(2.58767811E-02),  F(3.21939290E-02),
-       F(2.88757392E-02), -F(2.04385087E-02),
-
-       -F(1.09137620E-02), -F(3.06012286E-03),
-       -F(1.86581691E-03),  F(3.89205149E-03),
-       F(3.83720193E-03),  F(2.73370904E-03),
-       F(1.49188357E-03), -F(5.36548976E-04),
-};
-#undef F
-
-/*
- * To produce this cosine matrix in Octave:
- *
- * b = zeros(4, 8);
- * for i = 0:3
- * for j = 0:7 b(i+1, j+1) = cos((i + 0.5) * (j - 2) * (pi/4))
- * endfor
- * endfor;
- * printf("%.10f, ", b');
- *
- * Note: in each block of 8 numbers sign was changed for elements 2 and 7
- *
- * Change of sign for element 2 allows to replace constant 1.0 (not
- * representable in Q15 format) with -1.0 (fine with Q15).
- * Changed sign for element 7 allows to have more similar constants
- * and simplify subband filter function code.
- */
-#define SBC_COS_TABLE_FIXED4_SCALE \
-       ((sizeof(FIXED_T) * CHAR_BIT - 1) + SBC_FIXED_EXTRA_BITS)
-#define F_COS4(x) (FIXED_A) ((x) * \
-       ((FIXED_A) 1 << (sizeof(FIXED_T) * CHAR_BIT - 1)) + 0.5)
-#define F(x) F_COS4(x)
-static const FIXED_T cos_table_fixed_4[32] = {
-       F(0.7071067812),  F(0.9238795325), -F(1.0000000000),  F(0.9238795325),
-       F(0.7071067812),  F(0.3826834324),  F(0.0000000000),  F(0.3826834324),
-
-       -F(0.7071067812),  F(0.3826834324), -F(1.0000000000),  F(0.3826834324),
-       -F(0.7071067812), -F(0.9238795325), -F(0.0000000000), -F(0.9238795325),
-
-       -F(0.7071067812), -F(0.3826834324), -F(1.0000000000), -F(0.3826834324),
-       -F(0.7071067812),  F(0.9238795325),  F(0.0000000000),  F(0.9238795325),
-
-       F(0.7071067812), -F(0.9238795325), -F(1.0000000000), -F(0.9238795325),
-       F(0.7071067812), -F(0.3826834324), -F(0.0000000000), -F(0.3826834324),
-};
-#undef F
-
-/* A2DP specification: Section 12.8 Tables
- *
- * Original values are premultiplied by 4 for better precision (that is the
- * maximum which is possible without overflows)
- *
- * Note: in each block of 16 numbers sign was changed for elements 4, 13, 14, 15
- * in order to compensate the same change applied to cos_table_fixed_8
- */
-#define SBC_PROTO_FIXED8_SCALE \
-       ((sizeof(FIXED_T) * CHAR_BIT - 1) - SBC_FIXED_EXTRA_BITS + 1)
-#define F_PROTO8(x) (FIXED_A) ((x * 2) * \
-       ((FIXED_A) 1 << (sizeof(FIXED_T) * CHAR_BIT - 1)) + 0.5)
-#define F(x) F_PROTO8(x)
-static const FIXED_T _sbc_proto_fixed8[80] = {
-       F(0.00000000E+00),  F(1.56575398E-04),
-       F(3.43256425E-04),  F(5.54620202E-04),
-       -F(8.23919506E-04),  F(1.13992507E-03),
-       F(1.47640169E-03),  F(1.78371725E-03),
-       F(2.01182542E-03),  F(2.10371989E-03),
-       F(1.99454554E-03),  F(1.61656283E-03),
-       F(9.02154502E-04),  F(1.78805361E-04),
-       F(1.64973098E-03),  F(3.49717454E-03),
-
-       F(5.65949473E-03),  F(8.02941163E-03),
-       F(1.04584443E-02),  F(1.27472335E-02),
-       -F(1.46525263E-02),  F(1.59045603E-02),
-       F(1.62208471E-02),  F(1.53184106E-02),
-       F(1.29371806E-02),  F(8.85757540E-03),
-       F(2.92408442E-03), -F(4.91578024E-03),
-       -F(1.46404076E-02),  F(2.61098752E-02),
-       F(3.90751381E-02),  F(5.31873032E-02),
-
-       F(6.79989431E-02),  F(8.29847578E-02),
-       F(9.75753918E-02),  F(1.11196689E-01),
-       -F(1.23264548E-01),  F(1.33264415E-01),
-       F(1.40753505E-01),  F(1.45389847E-01),
-       F(1.46955068E-01),  F(1.45389847E-01),
-       F(1.40753505E-01),  F(1.33264415E-01),
-       F(1.23264548E-01), -F(1.11196689E-01),
-       -F(9.75753918E-02), -F(8.29847578E-02),
-
-       -F(6.79989431E-02), -F(5.31873032E-02),
-       -F(3.90751381E-02), -F(2.61098752E-02),
-       F(1.46404076E-02), -F(4.91578024E-03),
-       F(2.92408442E-03),  F(8.85757540E-03),
-       F(1.29371806E-02),  F(1.53184106E-02),
-       F(1.62208471E-02),  F(1.59045603E-02),
-       F(1.46525263E-02), -F(1.27472335E-02),
-       -F(1.04584443E-02), -F(8.02941163E-03),
-
-       -F(5.65949473E-03), -F(3.49717454E-03),
-       -F(1.64973098E-03), -F(1.78805361E-04),
-       -F(9.02154502E-04),  F(1.61656283E-03),
-       F(1.99454554E-03),  F(2.10371989E-03),
-       F(2.01182542E-03),  F(1.78371725E-03),
-       F(1.47640169E-03),  F(1.13992507E-03),
-       F(8.23919506E-04), -F(5.54620202E-04),
-       -F(3.43256425E-04), -F(1.56575398E-04),
-};
-#undef F
-
-/*
- * To produce this cosine matrix in Octave:
- *
- * b = zeros(8, 16);
- * for i = 0:7
- * for j = 0:15 b(i+1, j+1) = cos((i + 0.5) * (j - 4) * (pi/8))
- * endfor endfor;
- * printf("%.10f, ", b');
- *
- * Note: in each block of 16 numbers sign was changed for elements 4, 13, 14, 15
- *
- * Change of sign for element 4 allows to replace constant 1.0 (not
- * representable in Q15 format) with -1.0 (fine with Q15).
- * Changed signs for elements 13, 14, 15 allow to have more similar constants
- * and simplify subband filter function code.
- */
-#define SBC_COS_TABLE_FIXED8_SCALE \
-       ((sizeof(FIXED_T) * CHAR_BIT - 1) + SBC_FIXED_EXTRA_BITS)
-#define F_COS8(x) (FIXED_A) ((x) * \
-       ((FIXED_A) 1 << (sizeof(FIXED_T) * CHAR_BIT - 1)) + 0.5)
-#define F(x) F_COS8(x)
-static const FIXED_T cos_table_fixed_8[128] = {
-       F(0.7071067812),  F(0.8314696123),  F(0.9238795325),  F(0.9807852804),
-       -F(1.0000000000),  F(0.9807852804),  F(0.9238795325),  F(0.8314696123),
-       F(0.7071067812),  F(0.5555702330),  F(0.3826834324),  F(0.1950903220),
-       F(0.0000000000),  F(0.1950903220),  F(0.3826834324),  F(0.5555702330),
-
-       -F(0.7071067812), -F(0.1950903220),  F(0.3826834324),  F(0.8314696123),
-       -F(1.0000000000),  F(0.8314696123),  F(0.3826834324), -F(0.1950903220),
-       -F(0.7071067812), -F(0.9807852804), -F(0.9238795325), -F(0.5555702330),
-       -F(0.0000000000), -F(0.5555702330), -F(0.9238795325), -F(0.9807852804),
-
-       -F(0.7071067812), -F(0.9807852804), -F(0.3826834324),  F(0.5555702330),
-       -F(1.0000000000),  F(0.5555702330), -F(0.3826834324), -F(0.9807852804),
-       -F(0.7071067812),  F(0.1950903220),  F(0.9238795325),  F(0.8314696123),
-       F(0.0000000000),  F(0.8314696123),  F(0.9238795325),  F(0.1950903220),
-
-       F(0.7071067812), -F(0.5555702330), -F(0.9238795325),  F(0.1950903220),
-       -F(1.0000000000),  F(0.1950903220), -F(0.9238795325), -F(0.5555702330),
-       F(0.7071067812),  F(0.8314696123), -F(0.3826834324), -F(0.9807852804),
-       -F(0.0000000000), -F(0.9807852804), -F(0.3826834324),  F(0.8314696123),
-
-       F(0.7071067812),  F(0.5555702330), -F(0.9238795325), -F(0.1950903220),
-       -F(1.0000000000), -F(0.1950903220), -F(0.9238795325),  F(0.5555702330),
-       F(0.7071067812), -F(0.8314696123), -F(0.3826834324),  F(0.9807852804),
-       F(0.0000000000),  F(0.9807852804), -F(0.3826834324), -F(0.8314696123),
-
-       -F(0.7071067812),  F(0.9807852804), -F(0.3826834324), -F(0.5555702330),
-       -F(1.0000000000), -F(0.5555702330), -F(0.3826834324),  F(0.9807852804),
-       -F(0.7071067812), -F(0.1950903220),  F(0.9238795325), -F(0.8314696123),
-       -F(0.0000000000), -F(0.8314696123),  F(0.9238795325), -F(0.1950903220),
-
-       -F(0.7071067812),  F(0.1950903220),  F(0.3826834324), -F(0.8314696123),
-       -F(1.0000000000), -F(0.8314696123),  F(0.3826834324),  F(0.1950903220),
-       -F(0.7071067812),  F(0.9807852804), -F(0.9238795325),  F(0.5555702330),
-       -F(0.0000000000),  F(0.5555702330), -F(0.9238795325),  F(0.9807852804),
-
-       F(0.7071067812), -F(0.8314696123),  F(0.9238795325), -F(0.9807852804),
-       -F(1.0000000000), -F(0.9807852804),  F(0.9238795325), -F(0.8314696123),
-       F(0.7071067812), -F(0.5555702330),  F(0.3826834324), -F(0.1950903220),
-       -F(0.0000000000), -F(0.1950903220),  F(0.3826834324), -F(0.5555702330),
-};
-#undef F
-
-/*
- * Enforce 16 byte alignment for the data, which is supposed to be used
- * with SIMD optimized code.
- */
-
-#define SBC_ALIGN_BITS 4
-#define SBC_ALIGN_MASK ((1 << (SBC_ALIGN_BITS)) - 1)
-
-#ifdef __GNUC__
-#define SBC_ALIGNED __attribute__((aligned(1 << (SBC_ALIGN_BITS))))
-#else
-#define SBC_ALIGNED
-#endif
-
-/*
- * Constant tables for the use in SIMD optimized analysis filters
- * Each table consists of two parts:
- * 1. reordered "proto" table
- * 2. reordered "cos" table
- *
- * Due to non-symmetrical reordering, separate tables for "even"
- * and "odd" cases are needed
- */
-
-static const FIXED_T SBC_ALIGNED analysis_consts_fixed4_simd_even[40 + 16] = {
-#define C0 1.0932568993
-#define C1 1.3056875580
-#define C2 1.3056875580
-#define C3 1.6772280856
-
-#define F(x) F_PROTO4(x)
-        F(0.00000000E+00 * C0),  F(3.83720193E-03 * C0),
-        F(5.36548976E-04 * C1),  F(2.73370904E-03 * C1),
-        F(3.06012286E-03 * C2),  F(3.89205149E-03 * C2),
-        F(0.00000000E+00 * C3), -F(1.49188357E-03 * C3),
-        F(1.09137620E-02 * C0),  F(2.58767811E-02 * C0),
-        F(2.04385087E-02 * C1),  F(3.21939290E-02 * C1),
-        F(7.76463494E-02 * C2),  F(6.13245186E-03 * C2),
-        F(0.00000000E+00 * C3), -F(2.88757392E-02 * C3),
-        F(1.35593274E-01 * C0),  F(2.94315332E-01 * C0),
-        F(1.94987841E-01 * C1),  F(2.81828203E-01 * C1),
-       -F(1.94987841E-01 * C2),  F(2.81828203E-01 * C2),
-        F(0.00000000E+00 * C3), -F(2.46636662E-01 * C3),
-       -F(1.35593274E-01 * C0),  F(2.58767811E-02 * C0),
-       -F(7.76463494E-02 * C1),  F(6.13245186E-03 * C1),
-       -F(2.04385087E-02 * C2),  F(3.21939290E-02 * C2),
-        F(0.00000000E+00 * C3),  F(2.88217274E-02 * C3),
-       -F(1.09137620E-02 * C0),  F(3.83720193E-03 * C0),
-       -F(3.06012286E-03 * C1),  F(3.89205149E-03 * C1),
-       -F(5.36548976E-04 * C2),  F(2.73370904E-03 * C2),
-        F(0.00000000E+00 * C3), -F(1.86581691E-03 * C3),
-#undef F
-#define F(x) F_COS4(x)
-        F(0.7071067812 / C0),  F(0.9238795325 / C1),
-       -F(0.7071067812 / C0),  F(0.3826834324 / C1),
-       -F(0.7071067812 / C0), -F(0.3826834324 / C1),
-        F(0.7071067812 / C0), -F(0.9238795325 / C1),
-        F(0.3826834324 / C2), -F(1.0000000000 / C3),
-       -F(0.9238795325 / C2), -F(1.0000000000 / C3),
-        F(0.9238795325 / C2), -F(1.0000000000 / C3),
-       -F(0.3826834324 / C2), -F(1.0000000000 / C3),
-#undef F
-
-#undef C0
-#undef C1
-#undef C2
-#undef C3
-};
-
-static const FIXED_T SBC_ALIGNED analysis_consts_fixed4_simd_odd[40 + 16] = {
-#define C0 1.3056875580
-#define C1 1.6772280856
-#define C2 1.0932568993
-#define C3 1.3056875580
-
-#define F(x) F_PROTO4(x)
-        F(2.73370904E-03 * C0),  F(5.36548976E-04 * C0),
-       -F(1.49188357E-03 * C1),  F(0.00000000E+00 * C1),
-        F(3.83720193E-03 * C2),  F(1.09137620E-02 * C2),
-        F(3.89205149E-03 * C3),  F(3.06012286E-03 * C3),
-        F(3.21939290E-02 * C0),  F(2.04385087E-02 * C0),
-       -F(2.88757392E-02 * C1),  F(0.00000000E+00 * C1),
-        F(2.58767811E-02 * C2),  F(1.35593274E-01 * C2),
-        F(6.13245186E-03 * C3),  F(7.76463494E-02 * C3),
-        F(2.81828203E-01 * C0),  F(1.94987841E-01 * C0),
-       -F(2.46636662E-01 * C1),  F(0.00000000E+00 * C1),
-        F(2.94315332E-01 * C2), -F(1.35593274E-01 * C2),
-        F(2.81828203E-01 * C3), -F(1.94987841E-01 * C3),
-        F(6.13245186E-03 * C0), -F(7.76463494E-02 * C0),
-        F(2.88217274E-02 * C1),  F(0.00000000E+00 * C1),
-        F(2.58767811E-02 * C2), -F(1.09137620E-02 * C2),
-        F(3.21939290E-02 * C3), -F(2.04385087E-02 * C3),
-        F(3.89205149E-03 * C0), -F(3.06012286E-03 * C0),
-       -F(1.86581691E-03 * C1),  F(0.00000000E+00 * C1),
-        F(3.83720193E-03 * C2),  F(0.00000000E+00 * C2),
-        F(2.73370904E-03 * C3), -F(5.36548976E-04 * C3),
-#undef F
-#define F(x) F_COS4(x)
-        F(0.9238795325 / C0), -F(1.0000000000 / C1),
-        F(0.3826834324 / C0), -F(1.0000000000 / C1),
-       -F(0.3826834324 / C0), -F(1.0000000000 / C1),
-       -F(0.9238795325 / C0), -F(1.0000000000 / C1),
-        F(0.7071067812 / C2),  F(0.3826834324 / C3),
-       -F(0.7071067812 / C2), -F(0.9238795325 / C3),
-       -F(0.7071067812 / C2),  F(0.9238795325 / C3),
-        F(0.7071067812 / C2), -F(0.3826834324 / C3),
-#undef F
-
-#undef C0
-#undef C1
-#undef C2
-#undef C3
-};
-
-static const FIXED_T SBC_ALIGNED analysis_consts_fixed8_simd_even[80 + 64] = {
-#define C0 2.7906148894
-#define C1 2.4270044280
-#define C2 2.8015616024
-#define C3 3.1710363741
-#define C4 2.5377944043
-#define C5 2.4270044280
-#define C6 2.8015616024
-#define C7 3.1710363741
-
-#define F(x) F_PROTO8(x)
-        F(0.00000000E+00 * C0),  F(2.01182542E-03 * C0),
-        F(1.56575398E-04 * C1),  F(1.78371725E-03 * C1),
-        F(3.43256425E-04 * C2),  F(1.47640169E-03 * C2),
-        F(5.54620202E-04 * C3),  F(1.13992507E-03 * C3),
-       -F(8.23919506E-04 * C4),  F(0.00000000E+00 * C4),
-        F(2.10371989E-03 * C5),  F(3.49717454E-03 * C5),
-        F(1.99454554E-03 * C6),  F(1.64973098E-03 * C6),
-        F(1.61656283E-03 * C7),  F(1.78805361E-04 * C7),
-        F(5.65949473E-03 * C0),  F(1.29371806E-02 * C0),
-        F(8.02941163E-03 * C1),  F(1.53184106E-02 * C1),
-        F(1.04584443E-02 * C2),  F(1.62208471E-02 * C2),
-        F(1.27472335E-02 * C3),  F(1.59045603E-02 * C3),
-       -F(1.46525263E-02 * C4),  F(0.00000000E+00 * C4),
-        F(8.85757540E-03 * C5),  F(5.31873032E-02 * C5),
-        F(2.92408442E-03 * C6),  F(3.90751381E-02 * C6),
-       -F(4.91578024E-03 * C7),  F(2.61098752E-02 * C7),
-        F(6.79989431E-02 * C0),  F(1.46955068E-01 * C0),
-        F(8.29847578E-02 * C1),  F(1.45389847E-01 * C1),
-        F(9.75753918E-02 * C2),  F(1.40753505E-01 * C2),
-        F(1.11196689E-01 * C3),  F(1.33264415E-01 * C3),
-       -F(1.23264548E-01 * C4),  F(0.00000000E+00 * C4),
-        F(1.45389847E-01 * C5), -F(8.29847578E-02 * C5),
-        F(1.40753505E-01 * C6), -F(9.75753918E-02 * C6),
-        F(1.33264415E-01 * C7), -F(1.11196689E-01 * C7),
-       -F(6.79989431E-02 * C0),  F(1.29371806E-02 * C0),
-       -F(5.31873032E-02 * C1),  F(8.85757540E-03 * C1),
-       -F(3.90751381E-02 * C2),  F(2.92408442E-03 * C2),
-       -F(2.61098752E-02 * C3), -F(4.91578024E-03 * C3),
-        F(1.46404076E-02 * C4),  F(0.00000000E+00 * C4),
-        F(1.53184106E-02 * C5), -F(8.02941163E-03 * C5),
-        F(1.62208471E-02 * C6), -F(1.04584443E-02 * C6),
-        F(1.59045603E-02 * C7), -F(1.27472335E-02 * C7),
-       -F(5.65949473E-03 * C0),  F(2.01182542E-03 * C0),
-       -F(3.49717454E-03 * C1),  F(2.10371989E-03 * C1),
-       -F(1.64973098E-03 * C2),  F(1.99454554E-03 * C2),
-       -F(1.78805361E-04 * C3),  F(1.61656283E-03 * C3),
-       -F(9.02154502E-04 * C4),  F(0.00000000E+00 * C4),
-        F(1.78371725E-03 * C5), -F(1.56575398E-04 * C5),
-        F(1.47640169E-03 * C6), -F(3.43256425E-04 * C6),
-        F(1.13992507E-03 * C7), -F(5.54620202E-04 * C7),
-#undef F
-#define F(x) F_COS8(x)
-        F(0.7071067812 / C0),  F(0.8314696123 / C1),
-       -F(0.7071067812 / C0), -F(0.1950903220 / C1),
-       -F(0.7071067812 / C0), -F(0.9807852804 / C1),
-        F(0.7071067812 / C0), -F(0.5555702330 / C1),
-        F(0.7071067812 / C0),  F(0.5555702330 / C1),
-       -F(0.7071067812 / C0),  F(0.9807852804 / C1),
-       -F(0.7071067812 / C0),  F(0.1950903220 / C1),
-        F(0.7071067812 / C0), -F(0.8314696123 / C1),
-        F(0.9238795325 / C2),  F(0.9807852804 / C3),
-        F(0.3826834324 / C2),  F(0.8314696123 / C3),
-       -F(0.3826834324 / C2),  F(0.5555702330 / C3),
-       -F(0.9238795325 / C2),  F(0.1950903220 / C3),
-       -F(0.9238795325 / C2), -F(0.1950903220 / C3),
-       -F(0.3826834324 / C2), -F(0.5555702330 / C3),
-        F(0.3826834324 / C2), -F(0.8314696123 / C3),
-        F(0.9238795325 / C2), -F(0.9807852804 / C3),
-       -F(1.0000000000 / C4),  F(0.5555702330 / C5),
-       -F(1.0000000000 / C4), -F(0.9807852804 / C5),
-       -F(1.0000000000 / C4),  F(0.1950903220 / C5),
-       -F(1.0000000000 / C4),  F(0.8314696123 / C5),
-       -F(1.0000000000 / C4), -F(0.8314696123 / C5),
-       -F(1.0000000000 / C4), -F(0.1950903220 / C5),
-       -F(1.0000000000 / C4),  F(0.9807852804 / C5),
-       -F(1.0000000000 / C4), -F(0.5555702330 / C5),
-        F(0.3826834324 / C6),  F(0.1950903220 / C7),
-       -F(0.9238795325 / C6), -F(0.5555702330 / C7),
-        F(0.9238795325 / C6),  F(0.8314696123 / C7),
-       -F(0.3826834324 / C6), -F(0.9807852804 / C7),
-       -F(0.3826834324 / C6),  F(0.9807852804 / C7),
-        F(0.9238795325 / C6), -F(0.8314696123 / C7),
-       -F(0.9238795325 / C6),  F(0.5555702330 / C7),
-        F(0.3826834324 / C6), -F(0.1950903220 / C7),
-#undef F
-
-#undef C0
-#undef C1
-#undef C2
-#undef C3
-#undef C4
-#undef C5
-#undef C6
-#undef C7
-};
-
-static const FIXED_T SBC_ALIGNED analysis_consts_fixed8_simd_odd[80 + 64] = {
-#define C0 2.5377944043
-#define C1 2.4270044280
-#define C2 2.8015616024
-#define C3 3.1710363741
-#define C4 2.7906148894
-#define C5 2.4270044280
-#define C6 2.8015616024
-#define C7 3.1710363741
-
-#define F(x) F_PROTO8(x)
-        F(0.00000000E+00 * C0), -F(8.23919506E-04 * C0),
-        F(1.56575398E-04 * C1),  F(1.78371725E-03 * C1),
-        F(3.43256425E-04 * C2),  F(1.47640169E-03 * C2),
-        F(5.54620202E-04 * C3),  F(1.13992507E-03 * C3),
-        F(2.01182542E-03 * C4),  F(5.65949473E-03 * C4),
-        F(2.10371989E-03 * C5),  F(3.49717454E-03 * C5),
-        F(1.99454554E-03 * C6),  F(1.64973098E-03 * C6),
-        F(1.61656283E-03 * C7),  F(1.78805361E-04 * C7),
-        F(0.00000000E+00 * C0), -F(1.46525263E-02 * C0),
-        F(8.02941163E-03 * C1),  F(1.53184106E-02 * C1),
-        F(1.04584443E-02 * C2),  F(1.62208471E-02 * C2),
-        F(1.27472335E-02 * C3),  F(1.59045603E-02 * C3),
-        F(1.29371806E-02 * C4),  F(6.79989431E-02 * C4),
-        F(8.85757540E-03 * C5),  F(5.31873032E-02 * C5),
-        F(2.92408442E-03 * C6),  F(3.90751381E-02 * C6),
-       -F(4.91578024E-03 * C7),  F(2.61098752E-02 * C7),
-        F(0.00000000E+00 * C0), -F(1.23264548E-01 * C0),
-        F(8.29847578E-02 * C1),  F(1.45389847E-01 * C1),
-        F(9.75753918E-02 * C2),  F(1.40753505E-01 * C2),
-        F(1.11196689E-01 * C3),  F(1.33264415E-01 * C3),
-        F(1.46955068E-01 * C4), -F(6.79989431E-02 * C4),
-        F(1.45389847E-01 * C5), -F(8.29847578E-02 * C5),
-        F(1.40753505E-01 * C6), -F(9.75753918E-02 * C6),
-        F(1.33264415E-01 * C7), -F(1.11196689E-01 * C7),
-        F(0.00000000E+00 * C0),  F(1.46404076E-02 * C0),
-       -F(5.31873032E-02 * C1),  F(8.85757540E-03 * C1),
-       -F(3.90751381E-02 * C2),  F(2.92408442E-03 * C2),
-       -F(2.61098752E-02 * C3), -F(4.91578024E-03 * C3),
-        F(1.29371806E-02 * C4), -F(5.65949473E-03 * C4),
-        F(1.53184106E-02 * C5), -F(8.02941163E-03 * C5),
-        F(1.62208471E-02 * C6), -F(1.04584443E-02 * C6),
-        F(1.59045603E-02 * C7), -F(1.27472335E-02 * C7),
-        F(0.00000000E+00 * C0), -F(9.02154502E-04 * C0),
-       -F(3.49717454E-03 * C1),  F(2.10371989E-03 * C1),
-       -F(1.64973098E-03 * C2),  F(1.99454554E-03 * C2),
-       -F(1.78805361E-04 * C3),  F(1.61656283E-03 * C3),
-        F(2.01182542E-03 * C4),  F(0.00000000E+00 * C4),
-        F(1.78371725E-03 * C5), -F(1.56575398E-04 * C5),
-        F(1.47640169E-03 * C6), -F(3.43256425E-04 * C6),
-        F(1.13992507E-03 * C7), -F(5.54620202E-04 * C7),
-#undef F
-#define F(x) F_COS8(x)
-       -F(1.0000000000 / C0),  F(0.8314696123 / C1),
-       -F(1.0000000000 / C0), -F(0.1950903220 / C1),
-       -F(1.0000000000 / C0), -F(0.9807852804 / C1),
-       -F(1.0000000000 / C0), -F(0.5555702330 / C1),
-       -F(1.0000000000 / C0),  F(0.5555702330 / C1),
-       -F(1.0000000000 / C0),  F(0.9807852804 / C1),
-       -F(1.0000000000 / C0),  F(0.1950903220 / C1),
-       -F(1.0000000000 / C0), -F(0.8314696123 / C1),
-        F(0.9238795325 / C2),  F(0.9807852804 / C3),
-        F(0.3826834324 / C2),  F(0.8314696123 / C3),
-       -F(0.3826834324 / C2),  F(0.5555702330 / C3),
-       -F(0.9238795325 / C2),  F(0.1950903220 / C3),
-       -F(0.9238795325 / C2), -F(0.1950903220 / C3),
-       -F(0.3826834324 / C2), -F(0.5555702330 / C3),
-        F(0.3826834324 / C2), -F(0.8314696123 / C3),
-        F(0.9238795325 / C2), -F(0.9807852804 / C3),
-        F(0.7071067812 / C4),  F(0.5555702330 / C5),
-       -F(0.7071067812 / C4), -F(0.9807852804 / C5),
-       -F(0.7071067812 / C4),  F(0.1950903220 / C5),
-        F(0.7071067812 / C4),  F(0.8314696123 / C5),
-        F(0.7071067812 / C4), -F(0.8314696123 / C5),
-       -F(0.7071067812 / C4), -F(0.1950903220 / C5),
-       -F(0.7071067812 / C4),  F(0.9807852804 / C5),
-        F(0.7071067812 / C4), -F(0.5555702330 / C5),
-        F(0.3826834324 / C6),  F(0.1950903220 / C7),
-       -F(0.9238795325 / C6), -F(0.5555702330 / C7),
-        F(0.9238795325 / C6),  F(0.8314696123 / C7),
-       -F(0.3826834324 / C6), -F(0.9807852804 / C7),
-       -F(0.3826834324 / C6),  F(0.9807852804 / C7),
-        F(0.9238795325 / C6), -F(0.8314696123 / C7),
-       -F(0.9238795325 / C6),  F(0.5555702330 / C7),
-        F(0.3826834324 / C6), -F(0.1950903220 / C7),
-#undef F
-
-#undef C0
-#undef C1
-#undef C2
-#undef C3
-#undef C4
-#undef C5
-#undef C6
-#undef C7
-};
diff --git a/src/modules/dbus/iface-card-profile.c b/src/modules/dbus/iface-card-profile.c
new file mode 100644 (file)
index 0000000..004e2e8
--- /dev/null
@@ -0,0 +1,228 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dbus/dbus.h>
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-util.h>
+
+#include "iface-card-profile.h"
+
+#define OBJECT_NAME "profile"
+
+static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_description(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_sinks(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_sources(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_priority(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+struct pa_dbusiface_card_profile {
+    uint32_t index;
+    pa_card_profile *profile;
+    char *path;
+    pa_dbus_protocol *dbus_protocol;
+};
+
+enum property_handler_index {
+    PROPERTY_HANDLER_INDEX,
+    PROPERTY_HANDLER_NAME,
+    PROPERTY_HANDLER_DESCRIPTION,
+    PROPERTY_HANDLER_SINKS,
+    PROPERTY_HANDLER_SOURCES,
+    PROPERTY_HANDLER_PRIORITY,
+    PROPERTY_HANDLER_MAX
+};
+
+static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = {
+    [PROPERTY_HANDLER_INDEX]       = { .property_name = "Index",       .type = "u", .get_cb = handle_get_index,       .set_cb = NULL },
+    [PROPERTY_HANDLER_NAME]        = { .property_name = "Name",        .type = "s", .get_cb = handle_get_name,        .set_cb = NULL },
+    [PROPERTY_HANDLER_DESCRIPTION] = { .property_name = "Description", .type = "s", .get_cb = handle_get_description, .set_cb = NULL },
+    [PROPERTY_HANDLER_SINKS]       = { .property_name = "Sinks",       .type = "u", .get_cb = handle_get_sinks,       .set_cb = NULL },
+    [PROPERTY_HANDLER_SOURCES]     = { .property_name = "Sources",     .type = "u", .get_cb = handle_get_sources,     .set_cb = NULL },
+    [PROPERTY_HANDLER_PRIORITY]    = { .property_name = "Priority",    .type = "u", .get_cb = handle_get_priority,    .set_cb = NULL },
+};
+
+static pa_dbus_interface_info profile_interface_info = {
+    .name = PA_DBUSIFACE_CARD_PROFILE_INTERFACE,
+    .method_handlers = NULL,
+    .n_method_handlers = 0,
+    .property_handlers = property_handlers,
+    .n_property_handlers = PROPERTY_HANDLER_MAX,
+    .get_all_properties_cb = handle_get_all,
+    .signals = NULL,
+    .n_signals = 0
+};
+
+static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card_profile *p = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(p);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &p->index);
+}
+
+static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card_profile *p = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(p);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &p->profile->name);
+}
+
+static void handle_get_description(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card_profile *p = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(p);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &p->profile->description);
+}
+
+static void handle_get_sinks(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card_profile *p = userdata;
+    dbus_uint32_t sinks = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(p);
+
+    sinks = p->profile->n_sinks;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &sinks);
+}
+
+static void handle_get_sources(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card_profile *p = userdata;
+    dbus_uint32_t sources = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(p);
+
+    sources = p->profile->n_sources;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &sources);
+}
+
+static void handle_get_priority(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card_profile *p = userdata;
+    dbus_uint32_t priority = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(p);
+
+    priority = p->profile->priority;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &priority);
+}
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card_profile *p = userdata;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+    DBusMessageIter dict_iter;
+    dbus_uint32_t sinks = 0;
+    dbus_uint32_t sources = 0;
+    dbus_uint32_t priority = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(p);
+
+    sinks = p->profile->n_sinks;
+    sources = p->profile->n_sources;
+    priority = p->profile->priority;
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_INDEX].property_name, DBUS_TYPE_UINT32, &p->index);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_NAME].property_name, DBUS_TYPE_STRING, &p->profile->name);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DESCRIPTION].property_name, DBUS_TYPE_STRING, &p->profile->description);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SINKS].property_name, DBUS_TYPE_UINT32, &sinks);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SOURCES].property_name, DBUS_TYPE_UINT32, &sources);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PRIORITY].property_name, DBUS_TYPE_UINT32, &priority);
+
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+}
+
+pa_dbusiface_card_profile *pa_dbusiface_card_profile_new(
+        pa_dbusiface_card *card,
+        pa_core *core,
+        pa_card_profile *profile,
+        uint32_t idx) {
+    pa_dbusiface_card_profile *p = NULL;
+
+    pa_assert(card);
+    pa_assert(core);
+    pa_assert(profile);
+
+    p = pa_xnew(pa_dbusiface_card_profile, 1);
+    p->index = idx;
+    p->profile = profile;
+    p->path = pa_sprintf_malloc("%s/%s%u", pa_dbusiface_card_get_path(card), OBJECT_NAME, idx);
+    p->dbus_protocol = pa_dbus_protocol_get(core);
+
+    pa_assert_se(pa_dbus_protocol_add_interface(p->dbus_protocol, p->path, &profile_interface_info, p) >= 0);
+
+    return p;
+}
+
+void pa_dbusiface_card_profile_free(pa_dbusiface_card_profile *p) {
+    pa_assert(p);
+
+    pa_assert_se(pa_dbus_protocol_remove_interface(p->dbus_protocol, p->path, profile_interface_info.name) >= 0);
+
+    pa_dbus_protocol_unref(p->dbus_protocol);
+
+    pa_xfree(p->path);
+    pa_xfree(p);
+}
+
+const char *pa_dbusiface_card_profile_get_path(pa_dbusiface_card_profile *p) {
+    pa_assert(p);
+
+    return p->path;
+}
+
+const char *pa_dbusiface_card_profile_get_name(pa_dbusiface_card_profile *p) {
+    pa_assert(p);
+
+    return p->profile->name;
+}
diff --git a/src/modules/dbus/iface-card-profile.h b/src/modules/dbus/iface-card-profile.h
new file mode 100644 (file)
index 0000000..8ffb4b9
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef foodbusifacecardprofilehfoo
+#define foodbusifacecardprofilehfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+/* This object implements the D-Bus interface org.PulseAudio.Core1.CardProfile.
+ *
+ * See http://pulseaudio.org/wiki/DBusInterface for the CardProfile interface
+ * documentation.
+ */
+
+#include <pulsecore/protocol-dbus.h>
+
+#include "iface-card.h"
+
+#define PA_DBUSIFACE_CARD_PROFILE_INTERFACE PA_DBUS_CORE_INTERFACE ".CardProfile"
+
+typedef struct pa_dbusiface_card_profile pa_dbusiface_card_profile;
+
+pa_dbusiface_card_profile *pa_dbusiface_card_profile_new(
+        pa_dbusiface_card *card,
+        pa_core *core,
+        pa_card_profile *profile,
+        uint32_t idx);
+void pa_dbusiface_card_profile_free(pa_dbusiface_card_profile *p);
+
+const char *pa_dbusiface_card_profile_get_path(pa_dbusiface_card_profile *p);
+const char *pa_dbusiface_card_profile_get_name(pa_dbusiface_card_profile *p);
+
+#endif
diff --git a/src/modules/dbus/iface-card.c b/src/modules/dbus/iface-card.c
new file mode 100644 (file)
index 0000000..945f5bb
--- /dev/null
@@ -0,0 +1,566 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dbus/dbus.h>
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-util.h>
+#include <pulsecore/protocol-dbus.h>
+
+#include "iface-card-profile.h"
+
+#include "iface-card.h"
+
+#define OBJECT_NAME "card"
+
+static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_driver(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_owner_module(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_sinks(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_sources(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_profiles(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_active_profile(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_active_profile(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+static void handle_get_property_list(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_get_profile_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+struct pa_dbusiface_card {
+    pa_dbusiface_core *core;
+
+    pa_card *card;
+    char *path;
+    pa_hashmap *profiles;
+    uint32_t next_profile_index;
+    pa_card_profile *active_profile;
+    pa_proplist *proplist;
+
+    pa_hook_slot *card_profile_added_slot;
+
+    pa_dbus_protocol *dbus_protocol;
+    pa_subscription *subscription;
+};
+
+enum property_handler_index {
+    PROPERTY_HANDLER_INDEX,
+    PROPERTY_HANDLER_NAME,
+    PROPERTY_HANDLER_DRIVER,
+    PROPERTY_HANDLER_OWNER_MODULE,
+    PROPERTY_HANDLER_SINKS,
+    PROPERTY_HANDLER_SOURCES,
+    PROPERTY_HANDLER_PROFILES,
+    PROPERTY_HANDLER_ACTIVE_PROFILE,
+    PROPERTY_HANDLER_PROPERTY_LIST,
+    PROPERTY_HANDLER_MAX
+};
+
+static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = {
+    [PROPERTY_HANDLER_INDEX]          = { .property_name = "Index",         .type = "u",      .get_cb = handle_get_index,          .set_cb = NULL },
+    [PROPERTY_HANDLER_NAME]           = { .property_name = "Name",          .type = "s",      .get_cb = handle_get_name,           .set_cb = NULL },
+    [PROPERTY_HANDLER_DRIVER]         = { .property_name = "Driver",        .type = "s",      .get_cb = handle_get_driver,         .set_cb = NULL },
+    [PROPERTY_HANDLER_OWNER_MODULE]   = { .property_name = "OwnerModule",   .type = "o",      .get_cb = handle_get_owner_module,   .set_cb = NULL },
+    [PROPERTY_HANDLER_SINKS]          = { .property_name = "Sinks",         .type = "ao",     .get_cb = handle_get_sinks,          .set_cb = NULL },
+    [PROPERTY_HANDLER_SOURCES]        = { .property_name = "Sources",       .type = "ao",     .get_cb = handle_get_sources,        .set_cb = NULL },
+    [PROPERTY_HANDLER_PROFILES]       = { .property_name = "Profiles",      .type = "ao",     .get_cb = handle_get_profiles,       .set_cb = NULL },
+    [PROPERTY_HANDLER_ACTIVE_PROFILE] = { .property_name = "ActiveProfile", .type = "o",      .get_cb = handle_get_active_profile, .set_cb = handle_set_active_profile },
+    [PROPERTY_HANDLER_PROPERTY_LIST]  = { .property_name = "PropertyList",  .type = "a{say}", .get_cb = handle_get_property_list,  .set_cb = NULL }
+};
+
+enum method_handler_index {
+    METHOD_HANDLER_GET_PROFILE_BY_NAME,
+    METHOD_HANDLER_MAX
+};
+
+static pa_dbus_arg_info get_profile_by_name_args[] = { { "name", "s", "in" }, { "profile", "o", "out" } };
+
+static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
+    [METHOD_HANDLER_GET_PROFILE_BY_NAME] = {
+        .method_name = "GetProfileByName",
+        .arguments = get_profile_by_name_args,
+        .n_arguments = sizeof(get_profile_by_name_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_get_profile_by_name }
+};
+
+enum signal_index {
+    SIGNAL_ACTIVE_PROFILE_UPDATED,
+    SIGNAL_NEW_PROFILE,
+    SIGNAL_PROPERTY_LIST_UPDATED,
+    SIGNAL_MAX
+};
+
+static pa_dbus_arg_info active_profile_updated_args[] = { { "profile",       "o",      NULL } };
+static pa_dbus_arg_info new_profile_args[] =            { { "profile",       "o",      NULL } };
+static pa_dbus_arg_info property_list_updated_args[] =  { { "property_list", "a{say}", NULL } };
+
+static pa_dbus_signal_info signals[SIGNAL_MAX] = {
+    [SIGNAL_ACTIVE_PROFILE_UPDATED] = { .name = "ActiveProfileUpdated", .arguments = active_profile_updated_args, .n_arguments = 1 },
+    [SIGNAL_NEW_PROFILE]            = { .name = "NewProfile",           .arguments = new_profile_args,            .n_arguments = 1 },
+    [SIGNAL_PROPERTY_LIST_UPDATED]  = { .name = "PropertyListUpdated",  .arguments = property_list_updated_args,  .n_arguments = 1 }
+};
+
+static pa_dbus_interface_info card_interface_info = {
+    .name = PA_DBUSIFACE_CARD_INTERFACE,
+    .method_handlers = method_handlers,
+    .n_method_handlers = METHOD_HANDLER_MAX,
+    .property_handlers = property_handlers,
+    .n_property_handlers = PROPERTY_HANDLER_MAX,
+    .get_all_properties_cb = handle_get_all,
+    .signals = signals,
+    .n_signals = SIGNAL_MAX
+};
+
+static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card *c = userdata;
+    dbus_uint32_t idx;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    idx = c->card->index;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &idx);
+}
+
+static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card *c = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &c->card->name);
+}
+
+static void handle_get_driver(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card *c = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &c->card->driver);
+}
+
+static void handle_get_owner_module(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card *c = userdata;
+    const char *owner_module;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    if (!c->card->module) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "Card %s doesn't have an owner module.", c->card->name);
+        return;
+    }
+
+    owner_module = pa_dbusiface_core_get_module_path(c->core, c->card->module);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &owner_module);
+}
+
+/* The caller frees the array, but not the strings. */
+static const char **get_sinks(pa_dbusiface_card *c, unsigned *n) {
+    const char **sinks = NULL;
+    unsigned i = 0;
+    uint32_t idx = 0;
+    pa_sink *sink = NULL;
+
+    pa_assert(c);
+    pa_assert(n);
+
+    *n = pa_idxset_size(c->card->sinks);
+
+    if (*n == 0)
+        return NULL;
+
+    sinks = pa_xnew(const char *, *n);
+
+    PA_IDXSET_FOREACH(sink, c->card->sinks, idx) {
+        sinks[i] = pa_dbusiface_core_get_sink_path(c->core, sink);
+        ++i;
+    }
+
+    return sinks;
+}
+
+static void handle_get_sinks(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card *c = userdata;
+    const char **sinks;
+    unsigned n_sinks;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    sinks = get_sinks(c, &n_sinks);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, sinks, n_sinks);
+
+    pa_xfree(sinks);
+}
+
+/* The caller frees the array, but not the strings. */
+static const char **get_sources(pa_dbusiface_card *c, unsigned *n) {
+    const char **sources = NULL;
+    unsigned i = 0;
+    uint32_t idx = 0;
+    pa_source *source = NULL;
+
+    pa_assert(c);
+    pa_assert(n);
+
+    *n = pa_idxset_size(c->card->sources);
+
+    if (*n == 0)
+        return NULL;
+
+    sources = pa_xnew(const char *, *n);
+
+    PA_IDXSET_FOREACH(source, c->card->sinks, idx) {
+        sources[i] = pa_dbusiface_core_get_source_path(c->core, source);
+        ++i;
+    }
+
+    return sources;
+}
+
+static void handle_get_sources(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card *c = userdata;
+    const char **sources;
+    unsigned n_sources;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    sources = get_sources(c, &n_sources);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, sources, n_sources);
+
+    pa_xfree(sources);
+}
+
+/* The caller frees the array, but not the strings. */
+static const char **get_profiles(pa_dbusiface_card *c, unsigned *n) {
+    const char **profiles;
+    unsigned i = 0;
+    void *state = NULL;
+    pa_dbusiface_card_profile *profile;
+
+    pa_assert(c);
+    pa_assert(n);
+
+    *n = pa_hashmap_size(c->profiles);
+
+    if (*n == 0)
+        return NULL;
+
+    profiles = pa_xnew(const char *, *n);
+
+    PA_HASHMAP_FOREACH(profile, c->profiles, state)
+        profiles[i++] = pa_dbusiface_card_profile_get_path(profile);
+
+    return profiles;
+}
+
+static void handle_get_profiles(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card *c = userdata;
+    const char **profiles;
+    unsigned n_profiles;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    profiles = get_profiles(c, &n_profiles);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, profiles, n_profiles);
+
+    pa_xfree(profiles);
+}
+
+static void handle_get_active_profile(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card *c = userdata;
+    const char *active_profile;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    active_profile = pa_dbusiface_card_profile_get_path(pa_hashmap_get(c->profiles, c->active_profile->name));
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &active_profile);
+}
+
+static void handle_set_active_profile(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
+    pa_dbusiface_card *c = userdata;
+    const char *new_active_path;
+    pa_dbusiface_card_profile *new_active;
+    int r;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(c);
+
+    dbus_message_iter_get_basic(iter, &new_active_path);
+
+    if (!(new_active = pa_hashmap_get(c->profiles, new_active_path))) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such profile.", new_active_path);
+        return;
+    }
+
+    if ((r = pa_card_set_profile(c->card, pa_dbusiface_card_profile_get_name(new_active), TRUE)) < 0) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED,
+                           "Internal error in PulseAudio: pa_card_set_profile() failed with error code %i.", r);
+        return;
+    }
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+static void handle_get_property_list(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card *c = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    pa_dbus_send_proplist_variant_reply(conn, msg, c->proplist);
+}
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card *c = userdata;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+    DBusMessageIter dict_iter;
+    dbus_uint32_t idx;
+    const char *owner_module = NULL;
+    const char **sinks = NULL;
+    unsigned n_sinks = 0;
+    const char **sources = NULL;
+    unsigned n_sources = 0;
+    const char **profiles = NULL;
+    unsigned n_profiles = 0;
+    const char *active_profile = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    idx = c->card->index;
+    if (c->card->module)
+        owner_module = pa_dbusiface_core_get_module_path(c->core, c->card->module);
+    sinks = get_sinks(c, &n_sinks);
+    sources = get_sources(c, &n_sources);
+    profiles = get_profiles(c, &n_profiles);
+    active_profile = pa_dbusiface_card_profile_get_path(pa_hashmap_get(c->profiles, c->active_profile->name));
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_INDEX].property_name, DBUS_TYPE_UINT32, &idx);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_NAME].property_name, DBUS_TYPE_STRING, &c->card->name);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DRIVER].property_name, DBUS_TYPE_STRING, &c->card->driver);
+
+    if (owner_module)
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_OWNER_MODULE].property_name, DBUS_TYPE_OBJECT_PATH, &owner_module);
+
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SINKS].property_name, DBUS_TYPE_OBJECT_PATH, sinks, n_sinks);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SOURCES].property_name, DBUS_TYPE_OBJECT_PATH, sources, n_sources);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PROFILES].property_name, DBUS_TYPE_OBJECT_PATH, profiles, n_profiles);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_ACTIVE_PROFILE].property_name, DBUS_TYPE_OBJECT_PATH, &active_profile);
+
+    pa_dbus_append_proplist_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PROPERTY_LIST].property_name, c->proplist);
+
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+
+    dbus_message_unref(reply);
+
+    pa_xfree(sinks);
+    pa_xfree(sources);
+    pa_xfree(profiles);
+}
+
+static void handle_get_profile_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_card *c = userdata;
+    const char *profile_name = NULL;
+    pa_dbusiface_card_profile *profile = NULL;
+    const char *profile_path = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &profile_name, DBUS_TYPE_INVALID));
+
+    if (!(profile = pa_hashmap_get(c->profiles, profile_name))) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such profile on card %s.", profile_name, c->card->name);
+        return;
+    }
+
+    profile_path = pa_dbusiface_card_profile_get_path(profile);
+
+    pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &profile_path);
+}
+
+static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
+    pa_dbusiface_card *c = userdata;
+    DBusMessage *signal_msg = NULL;
+
+    pa_assert(core);
+    pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_CARD);
+    pa_assert(c);
+
+    /* We can't use idx != c->card->index, because the c->card pointer may
+     * be stale at this point. */
+    if (pa_idxset_get_by_index(core->cards, idx) != c->card)
+        return;
+
+    if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) != PA_SUBSCRIPTION_EVENT_CHANGE)
+        return;
+
+    if (c->active_profile != c->card->active_profile) {
+        const char *object_path;
+
+        c->active_profile = c->card->active_profile;
+        object_path = pa_dbusiface_card_profile_get_path(pa_hashmap_get(c->profiles, c->active_profile->name));
+
+        pa_assert_se(signal_msg = dbus_message_new_signal(c->path,
+                                                         PA_DBUSIFACE_CARD_INTERFACE,
+                                                         signals[SIGNAL_ACTIVE_PROFILE_UPDATED].name));
+        pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+        pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
+    }
+
+    if (!pa_proplist_equal(c->proplist, c->card->proplist)) {
+        DBusMessageIter msg_iter;
+
+        pa_proplist_update(c->proplist, PA_UPDATE_SET, c->card->proplist);
+
+        pa_assert_se(signal_msg = dbus_message_new_signal(c->path,
+                                                         PA_DBUSIFACE_CARD_INTERFACE,
+                                                         signals[SIGNAL_PROPERTY_LIST_UPDATED].name));
+        dbus_message_iter_init_append(signal_msg, &msg_iter);
+        pa_dbus_append_proplist(&msg_iter, c->proplist);
+
+        pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
+    }
+}
+
+static pa_hook_result_t card_profile_added_cb(void *hook_data, void *call_data, void *slot_data) {
+    pa_core *core = hook_data;
+    pa_dbusiface_card *c = slot_data;
+    pa_card_profile *profile = call_data;
+    pa_dbusiface_card_profile *p;
+    const char *object_path;
+    DBusMessage *signal_msg;
+
+    if (profile->card != c->card)
+        return PA_HOOK_OK;
+
+    p = pa_dbusiface_card_profile_new(c, core, profile, c->next_profile_index++);
+    pa_assert_se(pa_hashmap_put(c->profiles, pa_dbusiface_card_profile_get_name(p), p) >= 0);
+
+    /* Send D-Bus signal */
+    object_path = pa_dbusiface_card_profile_get_path(p);
+
+    pa_assert_se(signal_msg = dbus_message_new_signal(c->path,
+                                                      PA_DBUSIFACE_CARD_INTERFACE,
+                                                      signals[SIGNAL_NEW_PROFILE].name));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+
+    return PA_HOOK_OK;
+}
+
+pa_dbusiface_card *pa_dbusiface_card_new(pa_dbusiface_core *core, pa_card *card) {
+    pa_dbusiface_card *c = NULL;
+    pa_card_profile *profile;
+    void *state;
+
+    pa_assert(core);
+    pa_assert(card);
+
+    c = pa_xnew0(pa_dbusiface_card, 1);
+    c->core = core;
+    c->card = card;
+    c->path = pa_sprintf_malloc("%s/%s%u", PA_DBUS_CORE_OBJECT_PATH, OBJECT_NAME, card->index);
+    c->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    c->next_profile_index = 0;
+    c->active_profile = card->active_profile;
+    c->proplist = pa_proplist_copy(card->proplist);
+    c->dbus_protocol = pa_dbus_protocol_get(card->core);
+    c->subscription = pa_subscription_new(card->core, PA_SUBSCRIPTION_MASK_CARD, subscription_cb, c);
+
+    PA_HASHMAP_FOREACH(profile, card->profiles, state) {
+        pa_dbusiface_card_profile *p = pa_dbusiface_card_profile_new(c, card->core, profile, c->next_profile_index++);
+        pa_hashmap_put(c->profiles, pa_dbusiface_card_profile_get_name(p), p);
+    }
+
+    pa_assert_se(pa_dbus_protocol_add_interface(c->dbus_protocol, c->path, &card_interface_info, c) >= 0);
+
+    c->card_profile_added_slot = pa_hook_connect(&card->core->hooks[PA_CORE_HOOK_CARD_PROFILE_ADDED], PA_HOOK_NORMAL,
+                                                 card_profile_added_cb, c);
+
+    return c;
+}
+
+void pa_dbusiface_card_free(pa_dbusiface_card *c) {
+    pa_assert(c);
+
+    pa_assert_se(pa_dbus_protocol_remove_interface(c->dbus_protocol, c->path, card_interface_info.name) >= 0);
+
+    pa_hook_slot_free(c->card_profile_added_slot);
+
+    pa_hashmap_free(c->profiles, (pa_free_cb_t) pa_dbusiface_card_profile_free);
+    pa_proplist_free(c->proplist);
+    pa_dbus_protocol_unref(c->dbus_protocol);
+    pa_subscription_free(c->subscription);
+
+    pa_xfree(c->path);
+    pa_xfree(c);
+}
+
+const char *pa_dbusiface_card_get_path(pa_dbusiface_card *c) {
+    pa_assert(c);
+
+    return c->path;
+}
diff --git a/src/modules/dbus/iface-card.h b/src/modules/dbus/iface-card.h
new file mode 100644 (file)
index 0000000..e2c08a3
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef foodbusifacecardhfoo
+#define foodbusifacecardhfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+/* This object implements the D-Bus interface org.PulseAudio.Core1.Card.
+ *
+ * See http://pulseaudio.org/wiki/DBusInterface for the Card interface
+ * documentation.
+ */
+
+#include <pulsecore/card.h>
+#include <pulsecore/protocol-dbus.h>
+
+#include "iface-core.h"
+
+#define PA_DBUSIFACE_CARD_INTERFACE PA_DBUS_CORE_INTERFACE ".Card"
+
+typedef struct pa_dbusiface_card pa_dbusiface_card;
+
+pa_dbusiface_card *pa_dbusiface_card_new(pa_dbusiface_core *core, pa_card *card);
+void pa_dbusiface_card_free(pa_dbusiface_card *c);
+
+const char *pa_dbusiface_card_get_path(pa_dbusiface_card *c);
+
+#endif
diff --git a/src/modules/dbus/iface-client.c b/src/modules/dbus/iface-client.c
new file mode 100644 (file)
index 0000000..e667544
--- /dev/null
@@ -0,0 +1,461 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+  Copyright 2009 Vincent Filali-Ansary <filali.v@azurdigitalnetworks.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dbus/dbus.h>
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-util.h>
+#include <pulsecore/protocol-dbus.h>
+
+#include "iface-client.h"
+
+#define OBJECT_NAME "client"
+
+struct pa_dbusiface_client {
+    pa_dbusiface_core *core;
+
+    pa_client *client;
+    char *path;
+    pa_proplist *proplist;
+
+    pa_dbus_protocol *dbus_protocol;
+    pa_subscription *subscription;
+};
+
+static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_driver(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_owner_module(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_playback_streams(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_record_streams(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_property_list(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_kill(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_update_properties(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_remove_properties(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+enum property_handler_index {
+    PROPERTY_HANDLER_INDEX,
+    PROPERTY_HANDLER_DRIVER,
+    PROPERTY_HANDLER_OWNER_MODULE,
+    PROPERTY_HANDLER_PLAYBACK_STREAMS,
+    PROPERTY_HANDLER_RECORD_STREAMS,
+    PROPERTY_HANDLER_PROPERTY_LIST,
+    PROPERTY_HANDLER_MAX
+};
+
+static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = {
+    [PROPERTY_HANDLER_INDEX]            = { .property_name = "Index",           .type = "u",      .get_cb = handle_get_index,            .set_cb = NULL },
+    [PROPERTY_HANDLER_DRIVER]           = { .property_name = "Driver",          .type = "s",      .get_cb = handle_get_driver,           .set_cb = NULL },
+    [PROPERTY_HANDLER_OWNER_MODULE]     = { .property_name = "OwnerModule",     .type = "o",      .get_cb = handle_get_owner_module,     .set_cb = NULL },
+    [PROPERTY_HANDLER_PLAYBACK_STREAMS] = { .property_name = "PlaybackStreams", .type = "ao",     .get_cb = handle_get_playback_streams, .set_cb = NULL },
+    [PROPERTY_HANDLER_RECORD_STREAMS]   = { .property_name = "RecordStreams",   .type = "ao",     .get_cb = handle_get_record_streams,   .set_cb = NULL },
+    [PROPERTY_HANDLER_PROPERTY_LIST]    = { .property_name = "PropertyList",    .type = "a{say}", .get_cb = handle_get_property_list,    .set_cb = NULL }
+};
+
+enum method_handler_index {
+    METHOD_HANDLER_KILL,
+    METHOD_HANDLER_UPDATE_PROPERTIES,
+    METHOD_HANDLER_REMOVE_PROPERTIES,
+    METHOD_HANDLER_MAX
+};
+
+static pa_dbus_arg_info update_properties_args[] = { { "property_list", "a{say}", "in" }, { "update_mode", "u", "in" } };
+static pa_dbus_arg_info remove_properties_args[] = { { "keys", "as", "in" } };
+
+static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
+    [METHOD_HANDLER_KILL] = {
+        .method_name = "Kill",
+        .arguments = NULL,
+        .n_arguments = 0,
+        .receive_cb = handle_kill },
+    [METHOD_HANDLER_UPDATE_PROPERTIES] = {
+        .method_name = "UpdateProperties",
+        .arguments = update_properties_args,
+        .n_arguments = sizeof(update_properties_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_update_properties },
+    [METHOD_HANDLER_REMOVE_PROPERTIES] = {
+        .method_name = "RemoveProperties",
+        .arguments = remove_properties_args,
+        .n_arguments = sizeof(remove_properties_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_remove_properties }
+};
+
+enum signal_index {
+    SIGNAL_PROPERTY_LIST_UPDATED,
+    SIGNAL_CLIENT_EVENT,
+    SIGNAL_MAX
+};
+
+static pa_dbus_arg_info property_list_updated_args[] = { { "property_list", "a{say}", NULL } };
+static pa_dbus_arg_info client_event_args[]          = { { "name",          "s",      NULL },
+                                                         { "property_list", "a{say}", NULL } };
+
+static pa_dbus_signal_info signals[SIGNAL_MAX] = {
+    [SIGNAL_PROPERTY_LIST_UPDATED] = { .name = "PropertyListUpdated", .arguments = property_list_updated_args, .n_arguments = 1 },
+    /* ClientEvent is sent from module-dbus-protocol.c. */
+    [SIGNAL_CLIENT_EVENT]          = { .name = "ClientEvent",         .arguments = client_event_args,          .n_arguments = 1 }
+};
+
+static pa_dbus_interface_info client_interface_info = {
+    .name = PA_DBUSIFACE_CLIENT_INTERFACE,
+    .method_handlers = method_handlers,
+    .n_method_handlers = METHOD_HANDLER_MAX,
+    .property_handlers = property_handlers,
+    .n_property_handlers = PROPERTY_HANDLER_MAX,
+    .get_all_properties_cb = handle_get_all,
+    .signals = signals,
+    .n_signals = SIGNAL_MAX
+};
+
+static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_client *c = userdata;
+    dbus_uint32_t idx = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    idx = c->client->index;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &idx);
+}
+
+static void handle_get_driver(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_client *c = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &c->client->driver);
+}
+
+static void handle_get_owner_module(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_client *c = userdata;
+    const char *owner_module = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    if (!c->client->module) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "Client %d doesn't have an owner module.", c->client->index);
+        return;
+    }
+
+    owner_module = pa_dbusiface_core_get_module_path(c->core, c->client->module);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &owner_module);
+}
+
+/* The caller frees the array, but not the strings. */
+static const char **get_playback_streams(pa_dbusiface_client *c, unsigned *n) {
+    const char **playback_streams = NULL;
+    unsigned i = 0;
+    uint32_t idx = 0;
+    pa_sink_input *sink_input = NULL;
+
+    pa_assert(c);
+    pa_assert(n);
+
+    *n = pa_idxset_size(c->client->sink_inputs);
+
+    if (*n == 0)
+        return NULL;
+
+    playback_streams = pa_xnew(const char *, *n);
+
+    PA_IDXSET_FOREACH(sink_input, c->client->sink_inputs, idx)
+        playback_streams[i++] = pa_dbusiface_core_get_playback_stream_path(c->core, sink_input);
+
+    return playback_streams;
+}
+
+static void handle_get_playback_streams(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_client *c = userdata;
+    const char **playback_streams = NULL;
+    unsigned n_playback_streams = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    playback_streams = get_playback_streams(c, &n_playback_streams);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, playback_streams, n_playback_streams);
+
+    pa_xfree(playback_streams);
+}
+
+/* The caller frees the array, but not the strings. */
+static const char **get_record_streams(pa_dbusiface_client *c, unsigned *n) {
+    const char **record_streams = NULL;
+    unsigned i = 0;
+    uint32_t idx = 0;
+    pa_source_output *source_output = NULL;
+
+    pa_assert(c);
+    pa_assert(n);
+
+    *n = pa_idxset_size(c->client->source_outputs);
+
+    if (*n == 0)
+        return NULL;
+
+    record_streams = pa_xnew(const char *, *n);
+
+    PA_IDXSET_FOREACH(source_output, c->client->source_outputs, idx)
+        record_streams[i++] = pa_dbusiface_core_get_record_stream_path(c->core, source_output);
+
+    return record_streams;
+}
+
+static void handle_get_record_streams(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_client *c = userdata;
+    const char **record_streams = NULL;
+    unsigned n_record_streams = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    record_streams = get_record_streams(c, &n_record_streams);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, record_streams, n_record_streams);
+
+    pa_xfree(record_streams);
+}
+
+static void handle_get_property_list(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_client *c = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    pa_dbus_send_proplist_variant_reply(conn, msg, c->client->proplist);
+}
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_client *c = userdata;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+    DBusMessageIter dict_iter;
+    dbus_uint32_t idx = 0;
+    const char *owner_module = NULL;
+    const char **playback_streams = NULL;
+    unsigned n_playback_streams = 0;
+    const char **record_streams = NULL;
+    unsigned n_record_streams = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    idx = c->client->index;
+    if (c->client->module)
+        owner_module = pa_dbusiface_core_get_module_path(c->core, c->client->module);
+    playback_streams = get_playback_streams(c, &n_playback_streams);
+    record_streams = get_record_streams(c, &n_record_streams);
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_INDEX].property_name, DBUS_TYPE_UINT32, &idx);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DRIVER].property_name, DBUS_TYPE_STRING, &c->client->driver);
+
+    if (owner_module)
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_OWNER_MODULE].property_name, DBUS_TYPE_OBJECT_PATH, &owner_module);
+
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PLAYBACK_STREAMS].property_name, DBUS_TYPE_OBJECT_PATH, playback_streams, n_playback_streams);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_RECORD_STREAMS].property_name, DBUS_TYPE_OBJECT_PATH, record_streams, n_record_streams);
+    pa_dbus_append_proplist_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PROPERTY_LIST].property_name, c->client->proplist);
+
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+
+    dbus_message_unref(reply);
+
+    pa_xfree(playback_streams);
+    pa_xfree(record_streams);
+}
+
+static void handle_kill(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_client *c = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    dbus_connection_ref(conn);
+
+    pa_client_kill(c->client);
+
+    pa_dbus_send_empty_reply(conn, msg);
+
+    dbus_connection_unref(conn);
+}
+
+static void handle_update_properties(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_client *c = userdata;
+    DBusMessageIter msg_iter;
+    pa_proplist *property_list = NULL;
+    dbus_uint32_t update_mode = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    if (pa_dbus_protocol_get_client(c->dbus_protocol, conn) != c->client) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_ACCESS_DENIED, "Client tried to modify the property list of another client.");
+        return;
+    }
+
+    pa_assert_se(dbus_message_iter_init(msg, &msg_iter));
+
+    if (!(property_list = pa_dbus_get_proplist_arg(conn, msg, &msg_iter)))
+        return;
+
+    dbus_message_iter_get_basic(&msg_iter, &update_mode);
+
+    if (!(update_mode == PA_UPDATE_SET || update_mode == PA_UPDATE_MERGE || update_mode == PA_UPDATE_REPLACE)) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid update mode: %u", update_mode);
+        goto finish;
+    }
+
+    pa_client_update_proplist(c->client, update_mode, property_list);
+
+    pa_dbus_send_empty_reply(conn, msg);
+
+finish:
+    if (property_list)
+        pa_proplist_free(property_list);
+}
+
+static void handle_remove_properties(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_client *c = userdata;
+    char **keys = NULL;
+    int n_keys = 0;
+    pa_bool_t changed = FALSE;
+    int i = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    if (pa_dbus_protocol_get_client(c->dbus_protocol, conn) != c->client) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_ACCESS_DENIED, "Client tried to modify the property list of another client.");
+        return;
+    }
+
+    pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &keys, &n_keys, DBUS_TYPE_INVALID));
+
+    for (i = 0; i < n_keys; ++i)
+        changed |= pa_proplist_unset(c->client->proplist, keys[i]) >= 0;
+
+    pa_dbus_send_empty_reply(conn, msg);
+
+    if (changed)
+        pa_subscription_post(c->client->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_CHANGE, c->client->index);
+
+    dbus_free_string_array(keys);
+}
+
+static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
+    pa_dbusiface_client *c = userdata;
+    DBusMessage *signal_msg = NULL;
+
+    pa_assert(core);
+    pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_CLIENT);
+    pa_assert(c);
+
+    /* We can't use idx != c->client->index, because the c->client pointer may
+     * be stale at this point. */
+    if (pa_idxset_get_by_index(core->clients, idx) != c->client)
+        return;
+
+    if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) != PA_SUBSCRIPTION_EVENT_CHANGE)
+        return;
+
+    if (!pa_proplist_equal(c->proplist, c->client->proplist)) {
+        DBusMessageIter msg_iter;
+
+        pa_proplist_update(c->proplist, PA_UPDATE_SET, c->client->proplist);
+
+        pa_assert_se(signal_msg = dbus_message_new_signal(c->path,
+                                                         PA_DBUSIFACE_CLIENT_INTERFACE,
+                                                         signals[SIGNAL_PROPERTY_LIST_UPDATED].name));
+        dbus_message_iter_init_append(signal_msg, &msg_iter);
+        pa_dbus_append_proplist(&msg_iter, c->proplist);
+
+        pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
+    }
+}
+
+pa_dbusiface_client *pa_dbusiface_client_new(pa_dbusiface_core *core, pa_client *client) {
+    pa_dbusiface_client *c = NULL;
+
+    pa_assert(core);
+    pa_assert(client);
+
+    c = pa_xnew(pa_dbusiface_client, 1);
+    c->core = core;
+    c->client = client;
+    c->path = pa_sprintf_malloc("%s/%s%u", PA_DBUS_CORE_OBJECT_PATH, OBJECT_NAME, client->index);
+    c->proplist = pa_proplist_copy(client->proplist);
+    c->dbus_protocol = pa_dbus_protocol_get(client->core);
+    c->subscription = pa_subscription_new(client->core, PA_SUBSCRIPTION_MASK_CLIENT, subscription_cb, c);
+
+    pa_assert_se(pa_dbus_protocol_add_interface(c->dbus_protocol, c->path, &client_interface_info, c) >= 0);
+
+    return c;
+}
+
+void pa_dbusiface_client_free(pa_dbusiface_client *c) {
+    pa_assert(c);
+
+    pa_assert_se(pa_dbus_protocol_remove_interface(c->dbus_protocol, c->path, client_interface_info.name) >= 0);
+
+    pa_proplist_free(c->proplist);
+    pa_dbus_protocol_unref(c->dbus_protocol);
+    pa_subscription_free(c->subscription);
+
+    pa_xfree(c->path);
+    pa_xfree(c);
+}
+
+const char *pa_dbusiface_client_get_path(pa_dbusiface_client *c) {
+    pa_assert(c);
+
+    return c->path;
+}
diff --git a/src/modules/dbus/iface-client.h b/src/modules/dbus/iface-client.h
new file mode 100644 (file)
index 0000000..e8f151c
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef foodbusifaceclienthfoo
+#define foodbusifaceclienthfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+/* This object implements the D-Bus interface org.PulseAudio.Core1.Client.
+ *
+ * See http://pulseaudio.org/wiki/DBusInterface for the Client interface
+ * documentation.
+ */
+
+#include <pulsecore/client.h>
+#include <pulsecore/protocol-dbus.h>
+
+#include "iface-core.h"
+
+#define PA_DBUSIFACE_CLIENT_INTERFACE PA_DBUS_CORE_INTERFACE ".Client"
+
+typedef struct pa_dbusiface_client pa_dbusiface_client;
+
+pa_dbusiface_client *pa_dbusiface_client_new(pa_dbusiface_core *core, pa_client *client);
+void pa_dbusiface_client_free(pa_dbusiface_client *c);
+
+const char *pa_dbusiface_client_get_path(pa_dbusiface_client *c);
+
+#endif
diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c
new file mode 100644 (file)
index 0000000..a9716bc
--- /dev/null
@@ -0,0 +1,2203 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+
+#include <dbus/dbus.h>
+
+#include <pulse/utf8.h>
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-util.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/namereg.h>
+#include <pulsecore/protocol-dbus.h>
+#include <pulsecore/socket-util.h>
+#include <pulsecore/strbuf.h>
+
+#include "iface-card.h"
+#include "iface-client.h"
+#include "iface-device.h"
+#include "iface-memstats.h"
+#include "iface-module.h"
+#include "iface-sample.h"
+#include "iface-stream.h"
+
+#include "iface-core.h"
+
+#define INTERFACE_REVISION 0
+
+static void handle_get_interface_revision(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_version(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_is_local(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_username(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_hostname(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_default_channels(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_default_channels(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+static void handle_get_default_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_default_sample_format(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+static void handle_get_default_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_default_sample_rate(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+static void handle_get_alternate_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_alternate_sample_rate(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+static void handle_get_cards(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_sinks(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_fallback_sink(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+static void handle_get_sources(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_fallback_source(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+static void handle_get_playback_streams(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_record_streams(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_samples(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_modules(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_clients(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_my_client(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_extensions(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_get_card_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_sink_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_source_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_sample_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_exit(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_listen_for_signal(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_stop_listening_for_signal(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+struct pa_dbusiface_core {
+    pa_core *core;
+    pa_subscription *subscription;
+
+    pa_dbus_protocol *dbus_protocol;
+
+    pa_hashmap *cards;
+    pa_hashmap *sinks_by_index;
+    pa_hashmap *sinks_by_path;
+    pa_hashmap *sources_by_index;
+    pa_hashmap *sources_by_path;
+    pa_hashmap *playback_streams;
+    pa_hashmap *record_streams;
+    pa_hashmap *samples;
+    pa_hashmap *modules;
+    pa_hashmap *clients;
+
+    pa_sink *fallback_sink;
+    pa_source *fallback_source;
+
+    pa_hook_slot *sink_put_slot;
+    pa_hook_slot *sink_unlink_slot;
+    pa_hook_slot *source_put_slot;
+    pa_hook_slot *source_unlink_slot;
+    pa_hook_slot *extension_registered_slot;
+    pa_hook_slot *extension_unregistered_slot;
+
+    pa_dbusiface_memstats *memstats;
+};
+
+enum property_handler_index {
+    PROPERTY_HANDLER_INTERFACE_REVISION,
+    PROPERTY_HANDLER_NAME,
+    PROPERTY_HANDLER_VERSION,
+    PROPERTY_HANDLER_IS_LOCAL,
+    PROPERTY_HANDLER_USERNAME,
+    PROPERTY_HANDLER_HOSTNAME,
+    PROPERTY_HANDLER_DEFAULT_CHANNELS,
+    PROPERTY_HANDLER_DEFAULT_SAMPLE_FORMAT,
+    PROPERTY_HANDLER_DEFAULT_SAMPLE_RATE,
+    PROPERTY_HANDLER_ALTERNATE_SAMPLE_RATE,
+    PROPERTY_HANDLER_CARDS,
+    PROPERTY_HANDLER_SINKS,
+    PROPERTY_HANDLER_FALLBACK_SINK,
+    PROPERTY_HANDLER_SOURCES,
+    PROPERTY_HANDLER_FALLBACK_SOURCE,
+    PROPERTY_HANDLER_PLAYBACK_STREAMS,
+    PROPERTY_HANDLER_RECORD_STREAMS,
+    PROPERTY_HANDLER_SAMPLES,
+    PROPERTY_HANDLER_MODULES,
+    PROPERTY_HANDLER_CLIENTS,
+    PROPERTY_HANDLER_MY_CLIENT,
+    PROPERTY_HANDLER_EXTENSIONS,
+    PROPERTY_HANDLER_MAX
+};
+
+static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = {
+    [PROPERTY_HANDLER_INTERFACE_REVISION]    = { .property_name = "InterfaceRevision",   .type = "u",  .get_cb = handle_get_interface_revision,    .set_cb = NULL },
+    [PROPERTY_HANDLER_NAME]                  = { .property_name = "Name",                .type = "s",  .get_cb = handle_get_name,                  .set_cb = NULL },
+    [PROPERTY_HANDLER_VERSION]               = { .property_name = "Version",             .type = "s",  .get_cb = handle_get_version,               .set_cb = NULL },
+    [PROPERTY_HANDLER_IS_LOCAL]              = { .property_name = "IsLocal",             .type = "b",  .get_cb = handle_get_is_local,              .set_cb = NULL },
+    [PROPERTY_HANDLER_USERNAME]              = { .property_name = "Username",            .type = "s",  .get_cb = handle_get_username,              .set_cb = NULL },
+    [PROPERTY_HANDLER_HOSTNAME]              = { .property_name = "Hostname",            .type = "s",  .get_cb = handle_get_hostname,              .set_cb = NULL },
+    [PROPERTY_HANDLER_DEFAULT_CHANNELS]      = { .property_name = "DefaultChannels",     .type = "au", .get_cb = handle_get_default_channels,      .set_cb = handle_set_default_channels },
+    [PROPERTY_HANDLER_DEFAULT_SAMPLE_FORMAT] = { .property_name = "DefaultSampleFormat", .type = "u",  .get_cb = handle_get_default_sample_format, .set_cb = handle_set_default_sample_format },
+    [PROPERTY_HANDLER_DEFAULT_SAMPLE_RATE]   = { .property_name = "DefaultSampleRate",   .type = "u",  .get_cb = handle_get_default_sample_rate,   .set_cb = handle_set_default_sample_rate },
+    [PROPERTY_HANDLER_ALTERNATE_SAMPLE_RATE]   = { .property_name = "AlternateSampleRate",   .type = "u",  .get_cb = handle_get_alternate_sample_rate,   .set_cb = handle_set_alternate_sample_rate },
+    [PROPERTY_HANDLER_CARDS]                 = { .property_name = "Cards",               .type = "ao", .get_cb = handle_get_cards,                 .set_cb = NULL },
+    [PROPERTY_HANDLER_SINKS]                 = { .property_name = "Sinks",               .type = "ao", .get_cb = handle_get_sinks,                 .set_cb = NULL },
+    [PROPERTY_HANDLER_FALLBACK_SINK]         = { .property_name = "FallbackSink",        .type = "o",  .get_cb = handle_get_fallback_sink,         .set_cb = handle_set_fallback_sink },
+    [PROPERTY_HANDLER_SOURCES]               = { .property_name = "Sources",             .type = "ao", .get_cb = handle_get_sources,               .set_cb = NULL },
+    [PROPERTY_HANDLER_FALLBACK_SOURCE]       = { .property_name = "FallbackSource",      .type = "o",  .get_cb = handle_get_fallback_source,       .set_cb = handle_set_fallback_source },
+    [PROPERTY_HANDLER_PLAYBACK_STREAMS]      = { .property_name = "PlaybackStreams",     .type = "ao", .get_cb = handle_get_playback_streams,      .set_cb = NULL },
+    [PROPERTY_HANDLER_RECORD_STREAMS]        = { .property_name = "RecordStreams",       .type = "ao", .get_cb = handle_get_record_streams,        .set_cb = NULL },
+    [PROPERTY_HANDLER_SAMPLES]               = { .property_name = "Samples",             .type = "ao", .get_cb = handle_get_samples,               .set_cb = NULL },
+    [PROPERTY_HANDLER_MODULES]               = { .property_name = "Modules",             .type = "ao", .get_cb = handle_get_modules,               .set_cb = NULL },
+    [PROPERTY_HANDLER_CLIENTS]               = { .property_name = "Clients",             .type = "ao", .get_cb = handle_get_clients,               .set_cb = NULL },
+    [PROPERTY_HANDLER_MY_CLIENT]             = { .property_name = "MyClient",            .type = "o",  .get_cb = handle_get_my_client,             .set_cb = NULL },
+    [PROPERTY_HANDLER_EXTENSIONS]            = { .property_name = "Extensions",          .type = "as", .get_cb = handle_get_extensions,            .set_cb = NULL }
+};
+
+enum method_handler_index {
+    METHOD_HANDLER_GET_CARD_BY_NAME,
+    METHOD_HANDLER_GET_SINK_BY_NAME,
+    METHOD_HANDLER_GET_SOURCE_BY_NAME,
+    METHOD_HANDLER_GET_SAMPLE_BY_NAME,
+    METHOD_HANDLER_UPLOAD_SAMPLE,
+    METHOD_HANDLER_LOAD_MODULE,
+    METHOD_HANDLER_EXIT,
+    METHOD_HANDLER_LISTEN_FOR_SIGNAL,
+    METHOD_HANDLER_STOP_LISTENING_FOR_SIGNAL,
+    METHOD_HANDLER_MAX
+};
+
+static pa_dbus_arg_info get_card_by_name_args[] = { { "name", "s", "in" }, { "card", "o", "out" } };
+static pa_dbus_arg_info get_sink_by_name_args[] = { { "name", "s", "in" }, { "sink", "o", "out" } };
+static pa_dbus_arg_info get_source_by_name_args[] = { { "name", "s", "in" }, { "source", "o", "out" } };
+static pa_dbus_arg_info get_sample_by_name_args[] = { { "name", "s", "in" }, { "sample", "o", "out" } };
+static pa_dbus_arg_info upload_sample_args[] = { { "name",           "s",      "in" },
+                                                 { "sample_format",  "u",      "in" },
+                                                 { "sample_rate",    "u",      "in" },
+                                                 { "channels",       "au",     "in" },
+                                                 { "default_volume", "au",     "in" },
+                                                 { "property_list",  "a{say}", "in" },
+                                                 { "data",           "ay",     "in" },
+                                                 { "sample",         "o",      "out" } };
+static pa_dbus_arg_info load_module_args[] = { { "name", "s", "in" }, { "arguments", "a{ss}", "in" }, { "module", "o", "out" } };
+static pa_dbus_arg_info listen_for_signal_args[] = { { "signal", "s", "in" }, { "objects", "ao", "in" } };
+static pa_dbus_arg_info stop_listening_for_signal_args[] = { { "signal", "s", "in" } };
+
+static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
+    [METHOD_HANDLER_GET_CARD_BY_NAME] = {
+        .method_name = "GetCardByName",
+        .arguments = get_card_by_name_args,
+        .n_arguments = sizeof(get_card_by_name_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_get_card_by_name },
+    [METHOD_HANDLER_GET_SINK_BY_NAME] = {
+        .method_name = "GetSinkByName",
+        .arguments = get_sink_by_name_args,
+        .n_arguments = sizeof(get_sink_by_name_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_get_sink_by_name },
+    [METHOD_HANDLER_GET_SOURCE_BY_NAME] = {
+        .method_name = "GetSourceByName",
+        .arguments = get_source_by_name_args,
+        .n_arguments = sizeof(get_source_by_name_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_get_source_by_name },
+    [METHOD_HANDLER_GET_SAMPLE_BY_NAME] = {
+        .method_name = "GetSampleByName",
+        .arguments = get_sample_by_name_args,
+        .n_arguments = sizeof(get_sample_by_name_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_get_sample_by_name },
+    [METHOD_HANDLER_UPLOAD_SAMPLE] = {
+        .method_name = "UploadSample",
+        .arguments = upload_sample_args,
+        .n_arguments = sizeof(upload_sample_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_upload_sample },
+    [METHOD_HANDLER_LOAD_MODULE] = {
+        .method_name = "LoadModule",
+        .arguments = load_module_args,
+        .n_arguments = sizeof(load_module_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_load_module },
+    [METHOD_HANDLER_EXIT] = {
+        .method_name = "Exit",
+        .arguments = NULL,
+        .n_arguments = 0,
+        .receive_cb = handle_exit },
+    [METHOD_HANDLER_LISTEN_FOR_SIGNAL] = {
+        .method_name = "ListenForSignal",
+        .arguments = listen_for_signal_args,
+        .n_arguments = sizeof(listen_for_signal_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_listen_for_signal },
+    [METHOD_HANDLER_STOP_LISTENING_FOR_SIGNAL] = {
+        .method_name = "StopListeningForSignal",
+        .arguments = stop_listening_for_signal_args,
+        .n_arguments = sizeof(stop_listening_for_signal_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_stop_listening_for_signal }
+};
+
+enum signal_index {
+    SIGNAL_NEW_CARD,
+    SIGNAL_CARD_REMOVED,
+    SIGNAL_NEW_SINK,
+    SIGNAL_SINK_REMOVED,
+    SIGNAL_FALLBACK_SINK_UPDATED,
+    SIGNAL_FALLBACK_SINK_UNSET,
+    SIGNAL_NEW_SOURCE,
+    SIGNAL_SOURCE_REMOVED,
+    SIGNAL_FALLBACK_SOURCE_UPDATED,
+    SIGNAL_FALLBACK_SOURCE_UNSET,
+    SIGNAL_NEW_PLAYBACK_STREAM,
+    SIGNAL_PLAYBACK_STREAM_REMOVED,
+    SIGNAL_NEW_RECORD_STREAM,
+    SIGNAL_RECORD_STREAM_REMOVED,
+    SIGNAL_NEW_SAMPLE,
+    SIGNAL_SAMPLE_REMOVED,
+    SIGNAL_NEW_MODULE,
+    SIGNAL_MODULE_REMOVED,
+    SIGNAL_NEW_CLIENT,
+    SIGNAL_CLIENT_REMOVED,
+    SIGNAL_NEW_EXTENSION,
+    SIGNAL_EXTENSION_REMOVED,
+    SIGNAL_MAX
+};
+
+static pa_dbus_arg_info new_card_args[] =                { { "card",            "o", NULL } };
+static pa_dbus_arg_info card_removed_args[] =            { { "card",            "o", NULL } };
+static pa_dbus_arg_info new_sink_args[] =                { { "sink",            "o", NULL } };
+static pa_dbus_arg_info sink_removed_args[] =            { { "sink",            "o", NULL } };
+static pa_dbus_arg_info fallback_sink_updated_args[] =   { { "sink",            "o", NULL } };
+static pa_dbus_arg_info new_source_args[] =              { { "source",          "o", NULL } };
+static pa_dbus_arg_info source_removed_args[] =          { { "source",          "o", NULL } };
+static pa_dbus_arg_info fallback_source_updated_args[] = { { "source",          "o", NULL } };
+static pa_dbus_arg_info new_playback_stream_args[] =     { { "playback_stream", "o", NULL } };
+static pa_dbus_arg_info playback_stream_removed_args[] = { { "playback_stream", "o", NULL } };
+static pa_dbus_arg_info new_record_stream_args[] =       { { "record_stream",   "o", NULL } };
+static pa_dbus_arg_info record_stream_removed_args[] =   { { "record_stream",   "o", NULL } };
+static pa_dbus_arg_info new_sample_args[] =              { { "sample",          "o", NULL } };
+static pa_dbus_arg_info sample_removed_args[] =          { { "sample",          "o", NULL } };
+static pa_dbus_arg_info new_module_args[] =              { { "module",          "o", NULL } };
+static pa_dbus_arg_info module_removed_args[] =          { { "module",          "o", NULL } };
+static pa_dbus_arg_info new_client_args[] =              { { "client",          "o", NULL } };
+static pa_dbus_arg_info client_removed_args[] =          { { "client",          "o", NULL } };
+static pa_dbus_arg_info new_extension_args[] =           { { "extension",       "s", NULL } };
+static pa_dbus_arg_info extension_removed_args[] =       { { "extension",       "s", NULL } };
+
+static pa_dbus_signal_info signals[SIGNAL_MAX] = {
+    [SIGNAL_NEW_CARD]                = { .name = "NewCard",               .arguments = new_card_args,                .n_arguments = 1 },
+    [SIGNAL_CARD_REMOVED]            = { .name = "CardRemoved",           .arguments = card_removed_args,            .n_arguments = 1 },
+    [SIGNAL_NEW_SINK]                = { .name = "NewSink",               .arguments = new_sink_args,                .n_arguments = 1 },
+    [SIGNAL_SINK_REMOVED]            = { .name = "SinkRemoved",           .arguments = sink_removed_args,            .n_arguments = 1 },
+    [SIGNAL_FALLBACK_SINK_UPDATED]   = { .name = "FallbackSinkUpdated",   .arguments = fallback_sink_updated_args,   .n_arguments = 1 },
+    [SIGNAL_FALLBACK_SINK_UNSET]     = { .name = "FallbackSinkUnset",     .arguments = NULL,                         .n_arguments = 0 },
+    [SIGNAL_NEW_SOURCE]              = { .name = "NewSource",             .arguments = new_source_args,              .n_arguments = 1 },
+    [SIGNAL_SOURCE_REMOVED]          = { .name = "SourceRemoved",         .arguments = source_removed_args,          .n_arguments = 1 },
+    [SIGNAL_FALLBACK_SOURCE_UPDATED] = { .name = "FallbackSourceUpdated", .arguments = fallback_source_updated_args, .n_arguments = 1 },
+    [SIGNAL_FALLBACK_SOURCE_UNSET]   = { .name = "FallbackSourceUnset",   .arguments = NULL,                         .n_arguments = 0 },
+    [SIGNAL_NEW_PLAYBACK_STREAM]     = { .name = "NewPlaybackStream",     .arguments = new_playback_stream_args,     .n_arguments = 1 },
+    [SIGNAL_PLAYBACK_STREAM_REMOVED] = { .name = "PlaybackStreamRemoved", .arguments = playback_stream_removed_args, .n_arguments = 1 },
+    [SIGNAL_NEW_RECORD_STREAM]       = { .name = "NewRecordStream",       .arguments = new_record_stream_args,       .n_arguments = 1 },
+    [SIGNAL_RECORD_STREAM_REMOVED]   = { .name = "RecordStreamRemoved",   .arguments = record_stream_removed_args,   .n_arguments = 1 },
+    [SIGNAL_NEW_SAMPLE]              = { .name = "NewSample",             .arguments = new_sample_args,              .n_arguments = 1 },
+    [SIGNAL_SAMPLE_REMOVED]          = { .name = "SampleRemoved",         .arguments = sample_removed_args,          .n_arguments = 1 },
+    [SIGNAL_NEW_MODULE]              = { .name = "NewModule",             .arguments = new_module_args,              .n_arguments = 1 },
+    [SIGNAL_MODULE_REMOVED]          = { .name = "ModuleRemoved",         .arguments = module_removed_args,          .n_arguments = 1 },
+    [SIGNAL_NEW_CLIENT]              = { .name = "NewClient",             .arguments = new_client_args,              .n_arguments = 1 },
+    [SIGNAL_CLIENT_REMOVED]          = { .name = "ClientRemoved",         .arguments = client_removed_args,          .n_arguments = 1 },
+    [SIGNAL_NEW_EXTENSION]           = { .name = "NewExtension",          .arguments = new_extension_args,           .n_arguments = 1 },
+    [SIGNAL_EXTENSION_REMOVED]       = { .name = "ExtensionRemoved",      .arguments = extension_removed_args,       .n_arguments = 1 }
+};
+
+static pa_dbus_interface_info core_interface_info = {
+    .name = PA_DBUS_CORE_INTERFACE,
+    .method_handlers = method_handlers,
+    .n_method_handlers = METHOD_HANDLER_MAX,
+    .property_handlers = property_handlers,
+    .n_property_handlers = PROPERTY_HANDLER_MAX,
+    .get_all_properties_cb = handle_get_all,
+    .signals = signals,
+    .n_signals = SIGNAL_MAX
+};
+
+static void handle_get_interface_revision(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    dbus_uint32_t interface_revision = INTERFACE_REVISION;
+
+    pa_assert(conn);
+    pa_assert(msg);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &interface_revision);
+}
+
+static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    const char *server_name = PACKAGE_NAME;
+
+    pa_assert(conn);
+    pa_assert(msg);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &server_name);
+}
+
+static void handle_get_version(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    const char *version = PACKAGE_VERSION;
+
+    pa_assert(conn);
+    pa_assert(msg);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &version);
+}
+
+static dbus_bool_t get_is_local(DBusConnection *conn) {
+    int conn_fd;
+
+    pa_assert(conn);
+
+    if (!dbus_connection_get_socket(conn, &conn_fd))
+        return FALSE;
+
+    return pa_socket_is_local(conn_fd);
+}
+
+static void handle_get_is_local(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    dbus_bool_t is_local;
+
+    pa_assert(conn);
+    pa_assert(msg);
+
+    is_local = get_is_local(conn);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &is_local);
+}
+
+static void handle_get_username(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    char *username = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+
+    username = pa_get_user_name_malloc();
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &username);
+
+    pa_xfree(username);
+}
+
+static void handle_get_hostname(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    char *hostname = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+
+    hostname = pa_get_host_name_malloc();
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &hostname);
+
+    pa_xfree(hostname);
+}
+
+/* Caller frees the returned array. */
+static dbus_uint32_t *get_default_channels(pa_dbusiface_core *c, unsigned *n) {
+    dbus_uint32_t *default_channels = NULL;
+    unsigned i;
+
+    pa_assert(c);
+    pa_assert(n);
+
+    *n = c->core->default_channel_map.channels;
+    default_channels = pa_xnew(dbus_uint32_t, *n);
+
+    for (i = 0; i < *n; ++i)
+        default_channels[i] = c->core->default_channel_map.map[i];
+
+    return default_channels;
+}
+
+static void handle_get_default_channels(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    dbus_uint32_t *default_channels = NULL;
+    unsigned n;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    default_channels = get_default_channels(c, &n);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_UINT32, default_channels, n);
+
+    pa_xfree(default_channels);
+}
+
+static void handle_set_default_channels(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    DBusMessageIter array_iter;
+    pa_channel_map new_channel_map;
+    const dbus_uint32_t *default_channels;
+    int n_channels;
+    unsigned i;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(c);
+
+    pa_channel_map_init(&new_channel_map);
+
+    dbus_message_iter_recurse(iter, &array_iter);
+    dbus_message_iter_get_fixed_array(&array_iter, &default_channels, &n_channels);
+
+    if (n_channels <= 0) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Empty channel array.");
+        return;
+    }
+
+    if (n_channels > (int) PA_CHANNELS_MAX) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS,
+                           "Too many channels: %i. The maximum number of channels is %u.", n_channels, PA_CHANNELS_MAX);
+        return;
+    }
+
+    new_channel_map.channels = n_channels;
+
+    for (i = 0; i < new_channel_map.channels; ++i) {
+        if (default_channels[i] >= PA_CHANNEL_POSITION_MAX) {
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid channel position: %u.", default_channels[i]);
+            return;
+        }
+
+        new_channel_map.map[i] = default_channels[i];
+    }
+
+    c->core->default_channel_map = new_channel_map;
+    c->core->default_sample_spec.channels = n_channels;
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+static void handle_get_default_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    dbus_uint32_t default_sample_format;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    default_sample_format = c->core->default_sample_spec.format;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &default_sample_format);
+}
+
+static void handle_set_default_sample_format(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    dbus_uint32_t default_sample_format;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(c);
+
+    dbus_message_iter_get_basic(iter, &default_sample_format);
+
+    if (default_sample_format >= PA_SAMPLE_MAX) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample format.");
+        return;
+    }
+
+    c->core->default_sample_spec.format = default_sample_format;
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+static void handle_get_default_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    dbus_uint32_t default_sample_rate;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    default_sample_rate = c->core->default_sample_spec.rate;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &default_sample_rate);
+}
+
+static void handle_set_default_sample_rate(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    dbus_uint32_t default_sample_rate;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(c);
+
+    dbus_message_iter_get_basic(iter, &default_sample_rate);
+
+    if (default_sample_rate <= 0 || default_sample_rate > PA_RATE_MAX ||
+        !((default_sample_rate % 4000 == 0) || (default_sample_rate % 11025 == 0)))  {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample rate.");
+        return;
+    }
+
+    c->core->default_sample_spec.rate = default_sample_rate;
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+static void handle_get_alternate_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    dbus_uint32_t alternate_sample_rate;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    alternate_sample_rate = c->core->alternate_sample_rate;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &alternate_sample_rate);
+}
+
+static void handle_set_alternate_sample_rate(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    dbus_uint32_t alternate_sample_rate;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(c);
+
+    dbus_message_iter_get_basic(iter, &alternate_sample_rate);
+
+    if (alternate_sample_rate <= 0 || alternate_sample_rate > PA_RATE_MAX ||
+        !((alternate_sample_rate % 4000 == 0) || (alternate_sample_rate % 11025 == 0))) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample rate.");
+        return;
+    }
+
+    c->core->alternate_sample_rate = alternate_sample_rate;
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+/* The caller frees the array, but not the strings. */
+static const char **get_cards(pa_dbusiface_core *c, unsigned *n) {
+    const char **cards;
+    unsigned i = 0;
+    void *state = NULL;
+    pa_dbusiface_card *card;
+
+    pa_assert(c);
+    pa_assert(n);
+
+    *n = pa_hashmap_size(c->cards);
+
+    if (*n == 0)
+        return NULL;
+
+    cards = pa_xnew(const char *, *n);
+
+    PA_HASHMAP_FOREACH(card, c->cards, state)
+        cards[i++] = pa_dbusiface_card_get_path(card);
+
+    return cards;
+}
+
+static void handle_get_cards(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    const char **cards;
+    unsigned n;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    cards = get_cards(c, &n);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, cards, n);
+
+    pa_xfree(cards);
+}
+
+/* The caller frees the array, but not the strings. */
+static const char **get_sinks(pa_dbusiface_core *c, unsigned *n) {
+    const char **sinks;
+    unsigned i = 0;
+    void *state = NULL;
+    pa_dbusiface_device *sink;
+
+    pa_assert(c);
+    pa_assert(n);
+
+    *n = pa_hashmap_size(c->sinks_by_index);
+
+    if (*n == 0)
+        return NULL;
+
+    sinks = pa_xnew(const char *, *n);
+
+    PA_HASHMAP_FOREACH(sink, c->sinks_by_index, state)
+        sinks[i++] = pa_dbusiface_device_get_path(sink);
+
+    return sinks;
+}
+
+static void handle_get_sinks(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    const char **sinks;
+    unsigned n;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    sinks = get_sinks(c, &n);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, sinks, n);
+
+    pa_xfree(sinks);
+}
+
+static void handle_get_fallback_sink(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    pa_dbusiface_device *fallback_sink;
+    const char *object_path;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    if (!c->fallback_sink) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                           "There are no sinks, and therefore no fallback sink either.");
+        return;
+    }
+
+    pa_assert_se((fallback_sink = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index))));
+    object_path = pa_dbusiface_device_get_path(fallback_sink);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path);
+}
+
+static void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    pa_dbusiface_device *fallback_sink;
+    const char *object_path;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(c);
+
+    if (!c->fallback_sink) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                           "There are no sinks, and therefore no fallback sink either.");
+        return;
+    }
+
+    dbus_message_iter_get_basic(iter, &object_path);
+
+    if (!(fallback_sink = pa_hashmap_get(c->sinks_by_path, object_path))) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such sink.", object_path);
+        return;
+    }
+
+    pa_namereg_set_default_sink(c->core, pa_dbusiface_device_get_sink(fallback_sink));
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+/* The caller frees the array, but not the strings. */
+static const char **get_sources(pa_dbusiface_core *c, unsigned *n) {
+    const char **sources;
+    unsigned i = 0;
+    void *state = NULL;
+    pa_dbusiface_device *source;
+
+    pa_assert(c);
+    pa_assert(n);
+
+    *n = pa_hashmap_size(c->sources_by_index);
+
+    if (*n == 0)
+        return NULL;
+
+    sources = pa_xnew(const char *, *n);
+
+    PA_HASHMAP_FOREACH(source, c->sources_by_index, state)
+        sources[i++] = pa_dbusiface_device_get_path(source);
+
+    return sources;
+}
+
+static void handle_get_sources(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    const char **sources;
+    unsigned n;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    sources = get_sources(c, &n);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, sources, n);
+
+    pa_xfree(sources);
+}
+
+static void handle_get_fallback_source(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    pa_dbusiface_device *fallback_source;
+    const char *object_path;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    if (!c->fallback_source) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                           "There are no sources, and therefore no fallback source either.");
+        return;
+    }
+
+    pa_assert_se((fallback_source = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(c->fallback_source->index))));
+    object_path = pa_dbusiface_device_get_path(fallback_source);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path);
+}
+
+static void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    pa_dbusiface_device *fallback_source;
+    const char *object_path;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(c);
+
+    if (!c->fallback_source) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                           "There are no sources, and therefore no fallback source either.");
+        return;
+    }
+
+    dbus_message_iter_get_basic(iter, &object_path);
+
+    if (!(fallback_source = pa_hashmap_get(c->sources_by_path, object_path))) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such source.", object_path);
+        return;
+    }
+
+    pa_namereg_set_default_source(c->core, pa_dbusiface_device_get_source(fallback_source));
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+/* The caller frees the array, but not the strings. */
+static const char **get_playback_streams(pa_dbusiface_core *c, unsigned *n) {
+    const char **streams;
+    unsigned i = 0;
+    void *state = NULL;
+    pa_dbusiface_stream *stream;
+
+    pa_assert(c);
+    pa_assert(n);
+
+    *n = pa_hashmap_size(c->playback_streams);
+
+    if (*n == 0)
+        return NULL;
+
+    streams = pa_xnew(const char *, *n);
+
+    PA_HASHMAP_FOREACH(stream, c->playback_streams, state)
+        streams[i++] = pa_dbusiface_stream_get_path(stream);
+
+    return streams;
+}
+
+static void handle_get_playback_streams(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    const char **playback_streams;
+    unsigned n;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    playback_streams = get_playback_streams(c, &n);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, playback_streams, n);
+
+    pa_xfree(playback_streams);
+}
+
+/* The caller frees the array, but not the strings. */
+static const char **get_record_streams(pa_dbusiface_core *c, unsigned *n) {
+    const char **streams;
+    unsigned i = 0;
+    void *state = NULL;
+    pa_dbusiface_stream *stream;
+
+    pa_assert(c);
+    pa_assert(n);
+
+    *n = pa_hashmap_size(c->record_streams);
+
+    if (*n == 0)
+        return NULL;
+
+    streams = pa_xnew(const char *, *n);
+
+    PA_HASHMAP_FOREACH(stream, c->record_streams, state)
+        streams[i++] = pa_dbusiface_stream_get_path(stream);
+
+    return streams;
+}
+
+static void handle_get_record_streams(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    const char **record_streams;
+    unsigned n;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    record_streams = get_record_streams(c, &n);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, record_streams, n);
+
+    pa_xfree(record_streams);
+}
+
+/* The caller frees the array, but not the strings. */
+static const char **get_samples(pa_dbusiface_core *c, unsigned *n) {
+    const char **samples;
+    unsigned i = 0;
+    void *state = NULL;
+    pa_dbusiface_sample *sample;
+
+    pa_assert(c);
+    pa_assert(n);
+
+    *n = pa_hashmap_size(c->samples);
+
+    if (*n == 0)
+        return NULL;
+
+    samples = pa_xnew(const char *, *n);
+
+    PA_HASHMAP_FOREACH(sample, c->samples, state)
+        samples[i++] = pa_dbusiface_sample_get_path(sample);
+
+    return samples;
+}
+
+static void handle_get_samples(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    const char **samples;
+    unsigned n;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    samples = get_samples(c, &n);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, samples, n);
+
+    pa_xfree(samples);
+}
+
+/* The caller frees the array, but not the strings. */
+static const char **get_modules(pa_dbusiface_core *c, unsigned *n) {
+    const char **modules;
+    unsigned i = 0;
+    void *state = NULL;
+    pa_dbusiface_module *module;
+
+    pa_assert(c);
+    pa_assert(n);
+
+    *n = pa_hashmap_size(c->modules);
+
+    if (*n == 0)
+        return NULL;
+
+    modules = pa_xnew(const char *, *n);
+
+    PA_HASHMAP_FOREACH(module, c->modules, state)
+        modules[i++] = pa_dbusiface_module_get_path(module);
+
+    return modules;
+}
+
+static void handle_get_modules(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    const char **modules;
+    unsigned n;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    modules = get_modules(c, &n);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, modules, n);
+
+    pa_xfree(modules);
+}
+
+/* The caller frees the array, but not the strings. */
+static const char **get_clients(pa_dbusiface_core *c, unsigned *n) {
+    const char **clients;
+    unsigned i = 0;
+    void *state = NULL;
+    pa_dbusiface_client *client;
+
+    pa_assert(c);
+    pa_assert(n);
+
+    *n = pa_hashmap_size(c->clients);
+
+    if (*n == 0)
+        return NULL;
+
+    clients = pa_xnew(const char *, *n);
+
+    PA_HASHMAP_FOREACH(client, c->clients, state)
+        clients[i++] = pa_dbusiface_client_get_path(client);
+
+    return clients;
+}
+
+static void handle_get_clients(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    const char **clients;
+    unsigned n;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    clients = get_clients(c, &n);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, clients, n);
+
+    pa_xfree(clients);
+}
+
+static const char *get_my_client(pa_dbusiface_core *c, DBusConnection *conn) {
+    pa_client *my_client;
+
+    pa_assert(c);
+    pa_assert(conn);
+
+    pa_assert_se((my_client = pa_dbus_protocol_get_client(c->dbus_protocol, conn)));
+
+    return pa_dbusiface_client_get_path(pa_hashmap_get(c->clients, PA_UINT32_TO_PTR(my_client->index)));
+}
+
+static void handle_get_my_client(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    const char *my_client;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    my_client = get_my_client(c, conn);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &my_client);
+}
+
+static void handle_get_extensions(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    const char **extensions;
+    unsigned n;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    extensions = pa_dbus_protocol_get_extensions(c->dbus_protocol, &n);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_STRING, extensions, n);
+
+    pa_xfree(extensions);
+}
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+    DBusMessageIter dict_iter;
+    dbus_uint32_t interface_revision;
+    const char *server_name;
+    const char *version;
+    dbus_bool_t is_local;
+    char *username;
+    char *hostname;
+    dbus_uint32_t *default_channels;
+    unsigned n_default_channels;
+    dbus_uint32_t default_sample_format;
+    dbus_uint32_t default_sample_rate;
+    dbus_uint32_t alternate_sample_rate;
+    const char **cards;
+    unsigned n_cards;
+    const char **sinks;
+    unsigned n_sinks;
+    const char *fallback_sink;
+    const char **sources;
+    unsigned n_sources;
+    const char *fallback_source;
+    const char **playback_streams;
+    unsigned n_playback_streams;
+    const char **record_streams;
+    unsigned n_record_streams;
+    const char **samples;
+    unsigned n_samples;
+    const char **modules;
+    unsigned n_modules;
+    const char **clients;
+    unsigned n_clients;
+    const char *my_client;
+    const char **extensions;
+    unsigned n_extensions;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    interface_revision = INTERFACE_REVISION;
+    server_name = PACKAGE_NAME;
+    version = PACKAGE_VERSION;
+    is_local = get_is_local(conn);
+    username = pa_get_user_name_malloc();
+    hostname = pa_get_host_name_malloc();
+    default_channels = get_default_channels(c, &n_default_channels);
+    default_sample_format = c->core->default_sample_spec.format;
+    default_sample_rate = c->core->default_sample_spec.rate;
+    alternate_sample_rate = c->core->alternate_sample_rate;
+    cards = get_cards(c, &n_cards);
+    sinks = get_sinks(c, &n_sinks);
+    fallback_sink = c->fallback_sink
+                    ? pa_dbusiface_device_get_path(pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index)))
+                    : NULL;
+    sources = get_sources(c, &n_sources);
+    fallback_source = c->fallback_source
+                      ? pa_dbusiface_device_get_path(pa_hashmap_get(c->sources_by_index,
+                                                                    PA_UINT32_TO_PTR(c->fallback_source->index)))
+                      : NULL;
+    playback_streams = get_playback_streams(c, &n_playback_streams);
+    record_streams = get_record_streams(c, &n_record_streams);
+    samples = get_samples(c, &n_samples);
+    modules = get_modules(c, &n_modules);
+    clients = get_clients(c, &n_clients);
+    my_client = get_my_client(c, conn);
+    extensions = pa_dbus_protocol_get_extensions(c->dbus_protocol, &n_extensions);
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_INTERFACE_REVISION].property_name, DBUS_TYPE_UINT32, &interface_revision);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_NAME].property_name, DBUS_TYPE_STRING, &server_name);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_VERSION].property_name, DBUS_TYPE_STRING, &version);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_IS_LOCAL].property_name, DBUS_TYPE_BOOLEAN, &is_local);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_USERNAME].property_name, DBUS_TYPE_STRING, &username);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_HOSTNAME].property_name, DBUS_TYPE_STRING, &hostname);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DEFAULT_CHANNELS].property_name, DBUS_TYPE_UINT32, default_channels, n_default_channels);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DEFAULT_SAMPLE_FORMAT].property_name, DBUS_TYPE_UINT32, &default_sample_format);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DEFAULT_SAMPLE_RATE].property_name, DBUS_TYPE_UINT32, &default_sample_rate);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_ALTERNATE_SAMPLE_RATE].property_name, DBUS_TYPE_UINT32, &alternate_sample_rate);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CARDS].property_name, DBUS_TYPE_OBJECT_PATH, cards, n_cards);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SINKS].property_name, DBUS_TYPE_OBJECT_PATH, sinks, n_sinks);
+
+    if (fallback_sink)
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_FALLBACK_SINK].property_name, DBUS_TYPE_OBJECT_PATH, &fallback_sink);
+
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SOURCES].property_name, DBUS_TYPE_OBJECT_PATH, sources, n_sources);
+
+    if (fallback_source)
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_FALLBACK_SOURCE].property_name, DBUS_TYPE_OBJECT_PATH, &fallback_source);
+
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PLAYBACK_STREAMS].property_name, DBUS_TYPE_OBJECT_PATH, playback_streams, n_playback_streams);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_RECORD_STREAMS].property_name, DBUS_TYPE_OBJECT_PATH, record_streams, n_record_streams);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SAMPLES].property_name, DBUS_TYPE_OBJECT_PATH, samples, n_samples);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_MODULES].property_name, DBUS_TYPE_OBJECT_PATH, modules, n_modules);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CLIENTS].property_name, DBUS_TYPE_OBJECT_PATH, clients, n_clients);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_MY_CLIENT].property_name, DBUS_TYPE_OBJECT_PATH, &my_client);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_EXTENSIONS].property_name, DBUS_TYPE_STRING, extensions, n_extensions);
+
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+
+    dbus_message_unref(reply);
+
+    pa_xfree(username);
+    pa_xfree(hostname);
+    pa_xfree(default_channels);
+    pa_xfree(cards);
+    pa_xfree(sinks);
+    pa_xfree(sources);
+    pa_xfree(playback_streams);
+    pa_xfree(record_streams);
+    pa_xfree(samples);
+    pa_xfree(modules);
+    pa_xfree(clients);
+    pa_xfree(extensions);
+}
+
+static void handle_get_card_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    char *card_name;
+    pa_card *card;
+    pa_dbusiface_card *dbus_card;
+    const char *object_path;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &card_name, DBUS_TYPE_INVALID));
+
+    if (!(card = pa_namereg_get(c->core, card_name, PA_NAMEREG_CARD))) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such card.");
+        return;
+    }
+
+    pa_assert_se((dbus_card = pa_hashmap_get(c->cards, PA_UINT32_TO_PTR(card->index))));
+
+    object_path = pa_dbusiface_card_get_path(dbus_card);
+
+    pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path);
+}
+
+static void handle_get_sink_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    char *sink_name;
+    pa_sink *sink;
+    pa_dbusiface_device *dbus_sink;
+    const char *object_path;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &sink_name, DBUS_TYPE_INVALID));
+
+    if (!(sink = pa_namereg_get(c->core, sink_name, PA_NAMEREG_SINK))) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such sink.", sink_name);
+        return;
+    }
+
+    pa_assert_se((dbus_sink = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(sink->index))));
+
+    object_path = pa_dbusiface_device_get_path(dbus_sink);
+
+    pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path);
+}
+
+static void handle_get_source_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    char *source_name;
+    pa_source *source;
+    pa_dbusiface_device *dbus_source;
+    const char *object_path;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &source_name, DBUS_TYPE_INVALID));
+
+    if (!(source = pa_namereg_get(c->core, source_name, PA_NAMEREG_SOURCE))) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such source.", source_name);
+        return;
+    }
+
+    pa_assert_se((dbus_source = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(source->index))));
+
+    object_path = pa_dbusiface_device_get_path(dbus_source);
+
+    pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path);
+}
+
+static void handle_get_sample_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    char *sample_name;
+    pa_scache_entry *sample;
+    pa_dbusiface_sample *dbus_sample;
+    const char *object_path;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &sample_name, DBUS_TYPE_INVALID));
+
+    if (!(sample = pa_namereg_get(c->core, sample_name, PA_NAMEREG_SAMPLE))) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such sample.");
+        return;
+    }
+
+    pa_assert_se((dbus_sample = pa_hashmap_get(c->samples, PA_UINT32_TO_PTR(sample->index))));
+
+    object_path = pa_dbusiface_sample_get_path(dbus_sample);
+
+    pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path);
+}
+
+static void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    DBusMessageIter msg_iter;
+    DBusMessageIter array_iter;
+    const char *name;
+    dbus_uint32_t sample_format;
+    dbus_uint32_t sample_rate;
+    const dbus_uint32_t *channels;
+    int n_channels;
+    const dbus_uint32_t *default_volume;
+    int n_volume_entries;
+    pa_proplist *property_list;
+    const uint8_t *data;
+    int data_length;
+    int i;
+    pa_sample_spec ss;
+    pa_channel_map map;
+    pa_memchunk chunk;
+    uint32_t idx;
+    pa_dbusiface_sample *dbus_sample = NULL;
+    pa_scache_entry *sample = NULL;
+    const char *object_path;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    chunk.memblock = NULL;
+
+    pa_assert_se(dbus_message_iter_init(msg, &msg_iter));
+    dbus_message_iter_get_basic(&msg_iter, &name);
+
+    pa_assert_se(dbus_message_iter_next(&msg_iter));
+    dbus_message_iter_get_basic(&msg_iter, &sample_format);
+
+    pa_assert_se(dbus_message_iter_next(&msg_iter));
+    dbus_message_iter_get_basic(&msg_iter, &sample_rate);
+
+    pa_assert_se(dbus_message_iter_next(&msg_iter));
+    dbus_message_iter_recurse(&msg_iter, &array_iter);
+    dbus_message_iter_get_fixed_array(&array_iter, &channels, &n_channels);
+
+    pa_assert_se(dbus_message_iter_next(&msg_iter));
+    dbus_message_iter_recurse(&msg_iter, &array_iter);
+    dbus_message_iter_get_fixed_array(&array_iter, &default_volume, &n_volume_entries);
+
+    pa_assert_se(dbus_message_iter_next(&msg_iter));
+    if (!(property_list = pa_dbus_get_proplist_arg(conn, msg, &msg_iter)))
+        return;
+
+    dbus_message_iter_recurse(&msg_iter, &array_iter);
+    dbus_message_iter_get_fixed_array(&array_iter, &data, &data_length);
+
+    if (sample_format >= PA_SAMPLE_MAX) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample format.");
+        goto finish;
+    }
+
+    if (sample_rate <= 0 || sample_rate > PA_RATE_MAX) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample rate.");
+        goto finish;
+    }
+
+    if (n_channels <= 0) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Empty channel map.");
+        goto finish;
+    }
+
+    if (n_channels > (int) PA_CHANNELS_MAX) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS,
+                           "Too many channels: %i. The maximum is %u.", n_channels, PA_CHANNELS_MAX);
+        goto finish;
+    }
+
+    for (i = 0; i < n_channels; ++i) {
+        if (channels[i] >= PA_CHANNEL_POSITION_MAX) {
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid channel position.");
+            goto finish;
+        }
+    }
+
+    if (n_volume_entries != 0 && n_volume_entries != n_channels) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS,
+                           "The channels and default_volume arguments have different number of elements (%i and %i, resp).",
+                           n_channels, n_volume_entries);
+        goto finish;
+    }
+
+    for (i = 0; i < n_volume_entries; ++i) {
+        if (!PA_VOLUME_IS_VALID(default_volume[i])) {
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid volume: %u.", default_volume[i]);
+            goto finish;
+        }
+    }
+
+    if (data_length == 0) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Empty data.");
+        goto finish;
+    }
+
+    if (data_length > PA_SCACHE_ENTRY_SIZE_MAX) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS,
+                           "Too big sample: %i bytes. The maximum sample length is %u bytes.",
+                           data_length, PA_SCACHE_ENTRY_SIZE_MAX);
+        goto finish;
+    }
+
+    ss.format = sample_format;
+    ss.rate = sample_rate;
+    ss.channels = n_channels;
+
+    pa_assert(pa_sample_spec_valid(&ss));
+
+    if (!pa_frame_aligned(data_length, &ss)) {
+        char buf[PA_SAMPLE_SPEC_SNPRINT_MAX];
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS,
+                           "The sample length (%i bytes) doesn't align with the sample format and channels (%s).",
+                           data_length, pa_sample_spec_snprint(buf, sizeof(buf), &ss));
+        goto finish;
+    }
+
+    map.channels = n_channels;
+    for (i = 0; i < n_channels; ++i)
+        map.map[i] = channels[i];
+
+    chunk.memblock = pa_memblock_new(c->core->mempool, data_length);
+    chunk.index = 0;
+    chunk.length = data_length;
+
+    memcpy(pa_memblock_acquire(chunk.memblock), data, data_length);
+    pa_memblock_release(chunk.memblock);
+
+    if (pa_scache_add_item(c->core, name, &ss, &map, &chunk, property_list, &idx) < 0) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Adding the sample failed.");
+        goto finish;
+    }
+
+    pa_assert_se(sample = pa_idxset_get_by_index(c->core->scache, idx));
+
+    if (n_volume_entries > 0) {
+        sample->volume.channels = n_channels;
+        for (i = 0; i < n_volume_entries; ++i)
+            sample->volume.values[i] = default_volume[i];
+        sample->volume_is_set = TRUE;
+    } else {
+        sample->volume_is_set = FALSE;
+    }
+
+    dbus_sample = pa_dbusiface_sample_new(c, sample);
+    pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), dbus_sample);
+
+    object_path = pa_dbusiface_sample_get_path(dbus_sample);
+
+    pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path);
+
+finish:
+    if (property_list)
+        pa_proplist_free(property_list);
+
+    if (chunk.memblock)
+        pa_memblock_unref(chunk.memblock);
+}
+
+static pa_bool_t contains_space(const char *string) {
+    const char *p;
+
+    pa_assert(string);
+
+    for (p = string; *p; ++p) {
+        if (isspace(*p))
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    DBusMessageIter msg_iter;
+    DBusMessageIter dict_iter;
+    DBusMessageIter dict_entry_iter;
+    char *name = NULL;
+    const char *key = NULL;
+    const char *value = NULL;
+    char *escaped_value = NULL;
+    pa_strbuf *arg_buffer = NULL;
+    char *arg_string = NULL;
+    pa_module *module = NULL;
+    pa_dbusiface_module *dbus_module = NULL;
+    const char *object_path = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    if (c->core->disallow_module_loading) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_ACCESS_DENIED, "The server is configured to disallow module loading.");
+        return;
+    }
+
+    pa_assert_se(dbus_message_iter_init(msg, &msg_iter));
+    dbus_message_iter_get_basic(&msg_iter, &name);
+
+    arg_buffer = pa_strbuf_new();
+
+    pa_assert_se(dbus_message_iter_next(&msg_iter));
+    dbus_message_iter_recurse(&msg_iter, &dict_iter);
+
+    while (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_INVALID) {
+        if (!pa_strbuf_isempty(arg_buffer))
+            pa_strbuf_putc(arg_buffer, ' ');
+
+        dbus_message_iter_recurse(&dict_iter, &dict_entry_iter);
+
+        dbus_message_iter_get_basic(&dict_entry_iter, &key);
+
+        if (strlen(key) <= 0 || !pa_ascii_valid(key) || contains_space(key)) {
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid module argument name: %s", key);
+            goto finish;
+        }
+
+        pa_assert_se(dbus_message_iter_next(&dict_entry_iter));
+        dbus_message_iter_get_basic(&dict_entry_iter, &value);
+
+        escaped_value = pa_escape(value, "\"");
+        pa_strbuf_printf(arg_buffer, "%s=\"%s\"", key, escaped_value);
+        pa_xfree(escaped_value);
+
+        dbus_message_iter_next(&dict_iter);
+    }
+
+    arg_string = pa_strbuf_tostring(arg_buffer);
+
+    if (!(module = pa_module_load(c->core, name, arg_string))) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Failed to load module.");
+        goto finish;
+    }
+
+    dbus_module = pa_dbusiface_module_new(module);
+    pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(module->index), dbus_module);
+
+    object_path = pa_dbusiface_module_get_path(dbus_module);
+
+    pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path);
+
+finish:
+    if (arg_buffer)
+        pa_strbuf_free(arg_buffer);
+
+    pa_xfree(arg_string);
+}
+
+static void handle_exit(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    if (c->core->disallow_exit) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_ACCESS_DENIED, "The server is configured to disallow exiting.");
+        return;
+    }
+
+    pa_dbus_send_empty_reply(conn, msg);
+
+    pa_core_exit(c->core, FALSE, 0);
+}
+
+static void handle_listen_for_signal(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    const char *signal_str;
+    char **objects = NULL;
+    int n_objects;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    pa_assert_se(dbus_message_get_args(msg, NULL,
+                                       DBUS_TYPE_STRING, &signal_str,
+                                       DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objects, &n_objects,
+                                       DBUS_TYPE_INVALID));
+
+    pa_dbus_protocol_add_signal_listener(c->dbus_protocol, conn, *signal_str ? signal_str : NULL, objects, n_objects);
+
+    pa_dbus_send_empty_reply(conn, msg);
+
+    dbus_free_string_array(objects);
+}
+
+static void handle_stop_listening_for_signal(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    const char *signal_str;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &signal_str, DBUS_TYPE_INVALID));
+
+    pa_dbus_protocol_remove_signal_listener(c->dbus_protocol, conn, *signal_str ? signal_str : NULL);
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    pa_dbusiface_card *card_iface = NULL;
+    pa_dbusiface_device *device_iface = NULL;
+    pa_dbusiface_stream *stream_iface = NULL;
+    pa_dbusiface_sample *sample_iface = NULL;
+    pa_dbusiface_module *module_iface = NULL;
+    pa_dbusiface_client *client_iface = NULL;
+    DBusMessage *signal_msg = NULL;
+    const char *object_path = NULL;
+    pa_sink *new_fallback_sink = NULL;
+    pa_source *new_fallback_source = NULL;
+
+    pa_assert(c);
+
+    switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) {
+        case PA_SUBSCRIPTION_EVENT_SERVER:
+            new_fallback_sink = pa_namereg_get_default_sink(core);
+            new_fallback_source = pa_namereg_get_default_source(core);
+
+            if (c->fallback_sink != new_fallback_sink) {
+                if (c->fallback_sink)
+                    pa_sink_unref(c->fallback_sink);
+                c->fallback_sink = new_fallback_sink ? pa_sink_ref(new_fallback_sink) : NULL;
+
+                if (c->fallback_sink) {
+                    pa_assert_se(device_iface = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index)));
+                    object_path = pa_dbusiface_device_get_path(device_iface);
+
+                    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                                      PA_DBUS_CORE_INTERFACE,
+                                                                      signals[SIGNAL_FALLBACK_SINK_UPDATED].name)));
+                    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+                    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+                    dbus_message_unref(signal_msg);
+                    signal_msg = NULL;
+
+                } else {
+                    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                                       PA_DBUS_CORE_INTERFACE,
+                                                                       signals[SIGNAL_FALLBACK_SINK_UNSET].name)));
+                    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+                    dbus_message_unref(signal_msg);
+                    signal_msg = NULL;
+                }
+            }
+
+            if (c->fallback_source != new_fallback_source) {
+                if (c->fallback_source)
+                    pa_source_unref(c->fallback_source);
+                c->fallback_source = new_fallback_source ? pa_source_ref(new_fallback_source) : NULL;
+
+                if (c->fallback_source) {
+                    pa_assert_se(device_iface = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(c->fallback_source->index)));
+                    object_path = pa_dbusiface_device_get_path(device_iface);
+
+                    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                                      PA_DBUS_CORE_INTERFACE,
+                                                                      signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name)));
+                    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+                    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+                    dbus_message_unref(signal_msg);
+                    signal_msg = NULL;
+
+                } else {
+                    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                                       PA_DBUS_CORE_INTERFACE,
+                                                                       signals[SIGNAL_FALLBACK_SOURCE_UNSET].name)));
+                    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+                    dbus_message_unref(signal_msg);
+                    signal_msg = NULL;
+                }
+            }
+            break;
+
+        case PA_SUBSCRIPTION_EVENT_CARD:
+            if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
+                if (!(card_iface = pa_hashmap_get(c->cards, PA_UINT32_TO_PTR(idx)))) {
+                    pa_card *card = NULL;
+
+                    if (!(card = pa_idxset_get_by_index(core->cards, idx)))
+                        return; /* The card was removed immediately after creation. */
+
+                    card_iface = pa_dbusiface_card_new(c, card);
+                    pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), card_iface);
+                }
+
+                object_path = pa_dbusiface_card_get_path(card_iface);
+
+                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                                  PA_DBUS_CORE_INTERFACE,
+                                                                  signals[SIGNAL_NEW_CARD].name)));
+                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+            } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
+                if (!(card_iface = pa_hashmap_remove(c->cards, PA_UINT32_TO_PTR(idx))))
+                    return;
+
+                object_path = pa_dbusiface_card_get_path(card_iface);
+
+                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                                  PA_DBUS_CORE_INTERFACE,
+                                                                  signals[SIGNAL_CARD_REMOVED].name)));
+                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+                pa_dbusiface_card_free(card_iface);
+            }
+            break;
+
+        case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
+            if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
+                pa_sink_input *sink_input = NULL;
+
+                if (!(sink_input = pa_idxset_get_by_index(core->sink_inputs, idx)))
+                    return; /* The sink input was removed immediately after creation. */
+
+                if (!(stream_iface = pa_hashmap_get(c->playback_streams, PA_UINT32_TO_PTR(idx)))) {
+                    stream_iface = pa_dbusiface_stream_new_playback(c, sink_input);
+                    pa_hashmap_put(c->playback_streams, PA_UINT32_TO_PTR(idx), stream_iface);
+                }
+
+                object_path = pa_dbusiface_stream_get_path(stream_iface);
+
+                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                                  PA_DBUS_CORE_INTERFACE,
+                                                                  signals[SIGNAL_NEW_PLAYBACK_STREAM].name)));
+                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+            } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
+                if (!(stream_iface = pa_hashmap_remove(c->playback_streams, PA_UINT32_TO_PTR(idx))))
+                    return;
+
+                object_path = pa_dbusiface_stream_get_path(stream_iface);
+
+                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                                  PA_DBUS_CORE_INTERFACE,
+                                                                  signals[SIGNAL_PLAYBACK_STREAM_REMOVED].name)));
+                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+                pa_dbusiface_stream_free(stream_iface);
+            }
+            break;
+
+        case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT:
+            if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
+                pa_source_output *source_output = NULL;
+
+                if (!(source_output = pa_idxset_get_by_index(core->source_outputs, idx)))
+                    return; /* The source output was removed immediately after creation. */
+
+                if (!(stream_iface = pa_hashmap_get(c->record_streams, PA_UINT32_TO_PTR(idx)))) {
+                    stream_iface = pa_dbusiface_stream_new_record(c, source_output);
+                    pa_hashmap_put(c->record_streams, PA_UINT32_TO_PTR(idx), stream_iface);
+                }
+
+                object_path = pa_dbusiface_stream_get_path(stream_iface);
+
+                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                                  PA_DBUS_CORE_INTERFACE,
+                                                                  signals[SIGNAL_NEW_RECORD_STREAM].name)));
+                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+            } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
+                if (!(stream_iface = pa_hashmap_remove(c->record_streams, PA_UINT32_TO_PTR(idx))))
+                    return;
+
+                object_path = pa_dbusiface_stream_get_path(stream_iface);
+
+                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                                  PA_DBUS_CORE_INTERFACE,
+                                                                  signals[SIGNAL_RECORD_STREAM_REMOVED].name)));
+                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+                pa_dbusiface_stream_free(stream_iface);
+            }
+            break;
+
+        case PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE:
+            if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
+                pa_scache_entry *sample = NULL;
+
+                if (!(sample = pa_idxset_get_by_index(core->scache, idx)))
+                    return; /* The sample was removed immediately after creation. */
+
+                if (!(sample_iface = pa_hashmap_get(c->samples, PA_UINT32_TO_PTR(idx)))) {
+                    sample_iface = pa_dbusiface_sample_new(c, sample);
+                    pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), sample_iface);
+                }
+
+                object_path = pa_dbusiface_sample_get_path(sample_iface);
+
+                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                                  PA_DBUS_CORE_INTERFACE,
+                                                                  signals[SIGNAL_NEW_SAMPLE].name)));
+                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+            } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
+                if (!(sample_iface = pa_hashmap_remove(c->samples, PA_UINT32_TO_PTR(idx))))
+                    return;
+
+                object_path = pa_dbusiface_sample_get_path(sample_iface);
+
+                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                                  PA_DBUS_CORE_INTERFACE,
+                                                                  signals[SIGNAL_SAMPLE_REMOVED].name)));
+                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+                pa_dbusiface_sample_free(sample_iface);
+            }
+            break;
+
+        case PA_SUBSCRIPTION_EVENT_MODULE:
+            if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
+                pa_module *module = NULL;
+
+                if (!(module = pa_idxset_get_by_index(core->modules, idx)))
+                    return; /* The module was removed immediately after creation. */
+
+                if (!(module_iface = pa_hashmap_get(c->modules, PA_UINT32_TO_PTR(idx)))) {
+                    module_iface = pa_dbusiface_module_new(module);
+                    pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(idx), module_iface);
+                }
+
+                object_path = pa_dbusiface_module_get_path(module_iface);
+
+                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                                  PA_DBUS_CORE_INTERFACE,
+                                                                  signals[SIGNAL_NEW_MODULE].name)));
+                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+            } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
+                if (!(module_iface = pa_hashmap_remove(c->modules, PA_UINT32_TO_PTR(idx))))
+                    return;
+
+                object_path = pa_dbusiface_module_get_path(module_iface);
+
+                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                                  PA_DBUS_CORE_INTERFACE,
+                                                                  signals[SIGNAL_MODULE_REMOVED].name)));
+                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+                pa_dbusiface_module_free(module_iface);
+            }
+            break;
+
+        case PA_SUBSCRIPTION_EVENT_CLIENT:
+            if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
+                pa_client *client = NULL;
+
+                if (!(client = pa_idxset_get_by_index(core->clients, idx)))
+                    return; /* The client was removed immediately after creation. */
+
+                if (!(client_iface = pa_hashmap_get(c->clients, PA_UINT32_TO_PTR(idx)))) {
+                    client_iface = pa_dbusiface_client_new(c, client);
+                    pa_hashmap_put(c->clients, PA_UINT32_TO_PTR(idx), client_iface);
+                }
+
+                object_path = pa_dbusiface_client_get_path(client_iface);
+
+                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                                  PA_DBUS_CORE_INTERFACE,
+                                                                  signals[SIGNAL_NEW_CLIENT].name)));
+                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+            } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
+                if (!(client_iface = pa_hashmap_remove(c->clients, PA_UINT32_TO_PTR(idx))))
+                    return;
+
+                object_path = pa_dbusiface_client_get_path(client_iface);
+
+                pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                                  PA_DBUS_CORE_INTERFACE,
+                                                                  signals[SIGNAL_CLIENT_REMOVED].name)));
+                pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+                pa_dbusiface_client_free(client_iface);
+            }
+            break;
+    }
+
+    if (signal_msg) {
+        pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+    }
+}
+
+static pa_hook_result_t sink_put_cb(void *hook_data, void *call_data, void *slot_data) {
+    pa_dbusiface_core *c = slot_data;
+    pa_sink *s = call_data;
+    pa_dbusiface_device *d = NULL;
+    const char *object_path = NULL;
+    DBusMessage *signal_msg = NULL;
+
+    pa_assert(c);
+    pa_assert(s);
+
+    d = pa_dbusiface_device_new_sink(c, s);
+    object_path = pa_dbusiface_device_get_path(d);
+
+    pa_assert_se(pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(s->index), d) >= 0);
+    pa_assert_se(pa_hashmap_put(c->sinks_by_path, object_path, d) >= 0);
+
+    pa_assert_se(signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                      PA_DBUS_CORE_INTERFACE,
+                                                      signals[SIGNAL_NEW_SINK].name));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sink_unlink_cb(void *hook_data, void *call_data, void *slot_data) {
+    pa_dbusiface_core *c = slot_data;
+    pa_sink *s = call_data;
+    pa_dbusiface_device *d = NULL;
+    const char *object_path = NULL;
+    DBusMessage *signal_msg = NULL;
+
+    pa_assert(c);
+    pa_assert(s);
+
+    pa_assert_se(d = pa_hashmap_remove(c->sinks_by_index, PA_UINT32_TO_PTR(s->index)));
+    object_path = pa_dbusiface_device_get_path(d);
+    pa_assert_se(pa_hashmap_remove(c->sinks_by_path, object_path));
+
+    pa_assert_se(signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                      PA_DBUS_CORE_INTERFACE,
+                                                      signals[SIGNAL_SINK_REMOVED].name));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+
+    pa_dbusiface_device_free(d);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t source_put_cb(void *hook_data, void *call_data, void *slot_data) {
+    pa_dbusiface_core *c = slot_data;
+    pa_source *s = call_data;
+    pa_dbusiface_device *d = NULL;
+    const char *object_path = NULL;
+    DBusMessage *signal_msg = NULL;
+
+    pa_assert(c);
+    pa_assert(s);
+
+    d = pa_dbusiface_device_new_source(c, s);
+    object_path = pa_dbusiface_device_get_path(d);
+
+    pa_assert_se(pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(s->index), d) >= 0);
+    pa_assert_se(pa_hashmap_put(c->sources_by_path, object_path, d) >= 0);
+
+    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                       PA_DBUS_CORE_INTERFACE,
+                                                       signals[SIGNAL_NEW_SOURCE].name)));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t source_unlink_cb(void *hook_data, void *call_data, void *slot_data) {
+    pa_dbusiface_core *c = slot_data;
+    pa_source *s = call_data;
+    pa_dbusiface_device *d = NULL;
+    const char *object_path = NULL;
+    DBusMessage *signal_msg = NULL;
+
+    pa_assert(c);
+    pa_assert(s);
+
+    pa_assert_se(d = pa_hashmap_remove(c->sources_by_index, PA_UINT32_TO_PTR(s->index)));
+    object_path = pa_dbusiface_device_get_path(d);
+    pa_assert_se(pa_hashmap_remove(c->sources_by_path, object_path));
+
+    pa_assert_se(signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                      PA_DBUS_CORE_INTERFACE,
+                                                      signals[SIGNAL_SOURCE_REMOVED].name));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+
+    pa_dbusiface_device_free(d);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t extension_registered_cb(void *hook_data, void *call_data, void *slot_data) {
+    pa_dbusiface_core *c = slot_data;
+    const char *ext_name = call_data;
+    DBusMessage *signal_msg = NULL;
+
+    pa_assert(c);
+    pa_assert(ext_name);
+
+    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                      PA_DBUS_CORE_INTERFACE,
+                                                      signals[SIGNAL_NEW_EXTENSION].name)));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_STRING, &ext_name, DBUS_TYPE_INVALID));
+
+    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t extension_unregistered_cb(void *hook_data, void *call_data, void *slot_data) {
+    pa_dbusiface_core *c = slot_data;
+    const char *ext_name = call_data;
+    DBusMessage *signal_msg = NULL;
+
+    pa_assert(c);
+    pa_assert(ext_name);
+
+    pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
+                                                      PA_DBUS_CORE_INTERFACE,
+                                                      signals[SIGNAL_EXTENSION_REMOVED].name)));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_STRING, &ext_name, DBUS_TYPE_INVALID));
+
+    pa_dbus_protocol_send_signal(c->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+
+    return PA_HOOK_OK;
+}
+
+pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) {
+    pa_dbusiface_core *c;
+    pa_card *card;
+    pa_sink *sink;
+    pa_source *source;
+    pa_dbusiface_device *device;
+    pa_sink_input *sink_input;
+    pa_source_output *source_output;
+    pa_scache_entry *sample;
+    pa_module *module;
+    pa_client *client;
+    uint32_t idx;
+
+    pa_assert(core);
+
+    c = pa_xnew(pa_dbusiface_core, 1);
+    c->core = core;
+    c->subscription = pa_subscription_new(core, PA_SUBSCRIPTION_MASK_ALL, subscription_cb, c);
+    c->dbus_protocol = pa_dbus_protocol_get(core);
+    c->cards = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+    c->sinks_by_index = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+    c->sinks_by_path = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    c->sources_by_index = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+    c->sources_by_path = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    c->playback_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+    c->record_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+    c->samples = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+    c->modules = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+    c->clients = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+    c->fallback_sink = pa_namereg_get_default_sink(core);
+    c->fallback_source = pa_namereg_get_default_source(core);
+    c->sink_put_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_NORMAL, sink_put_cb, c);
+    c->sink_unlink_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_NORMAL, sink_unlink_cb, c);
+    c->source_put_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_NORMAL, source_put_cb, c);
+    c->source_unlink_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_NORMAL, source_unlink_cb, c);
+    c->extension_registered_slot = pa_dbus_protocol_hook_connect(c->dbus_protocol,
+                                                                 PA_DBUS_PROTOCOL_HOOK_EXTENSION_REGISTERED,
+                                                                 PA_HOOK_NORMAL,
+                                                                 extension_registered_cb,
+                                                                 c);
+    c->extension_unregistered_slot = pa_dbus_protocol_hook_connect(c->dbus_protocol,
+                                                                   PA_DBUS_PROTOCOL_HOOK_EXTENSION_UNREGISTERED,
+                                                                   PA_HOOK_NORMAL,
+                                                                   extension_unregistered_cb,
+                                                                   c);
+    c->memstats = pa_dbusiface_memstats_new(c, core);
+
+    if (c->fallback_sink)
+        pa_sink_ref(c->fallback_sink);
+    if (c->fallback_source)
+        pa_source_ref(c->fallback_source);
+
+    PA_IDXSET_FOREACH(card, core->cards, idx)
+        pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), pa_dbusiface_card_new(c, card));
+
+    PA_IDXSET_FOREACH(sink, core->sinks, idx) {
+        device = pa_dbusiface_device_new_sink(c, sink);
+        pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(idx), device);
+        pa_hashmap_put(c->sinks_by_path, pa_dbusiface_device_get_path(device), device);
+    }
+
+    PA_IDXSET_FOREACH(source, core->sources, idx) {
+        device = pa_dbusiface_device_new_source(c, source);
+        pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(idx), device);
+        pa_hashmap_put(c->sources_by_path, pa_dbusiface_device_get_path(device), device);
+    }
+
+    PA_IDXSET_FOREACH(sink_input, core->sink_inputs, idx)
+        pa_hashmap_put(c->playback_streams, PA_UINT32_TO_PTR(idx), pa_dbusiface_stream_new_playback(c, sink_input));
+
+    PA_IDXSET_FOREACH(source_output, core->source_outputs, idx)
+        pa_hashmap_put(c->record_streams, PA_UINT32_TO_PTR(idx), pa_dbusiface_stream_new_record(c, source_output));
+
+    PA_IDXSET_FOREACH(sample, core->scache, idx)
+        pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), pa_dbusiface_sample_new(c, sample));
+
+    PA_IDXSET_FOREACH(module, core->modules, idx)
+        pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(idx), pa_dbusiface_module_new(module));
+
+    PA_IDXSET_FOREACH(client, core->clients, idx)
+        pa_hashmap_put(c->clients, PA_UINT32_TO_PTR(idx), pa_dbusiface_client_new(c, client));
+
+    pa_assert_se(pa_dbus_protocol_add_interface(c->dbus_protocol, PA_DBUS_CORE_OBJECT_PATH, &core_interface_info, c) >= 0);
+
+    return c;
+}
+
+void pa_dbusiface_core_free(pa_dbusiface_core *c) {
+    pa_assert(c);
+
+    pa_assert_se(pa_dbus_protocol_remove_interface(c->dbus_protocol, PA_DBUS_CORE_OBJECT_PATH, core_interface_info.name) >= 0);
+
+    /* Note that the order of freeing is important below.
+     * Do not change it for the sake of tidiness without checking! */
+    pa_subscription_free(c->subscription);
+    pa_hashmap_free(c->cards, (pa_free_cb_t) pa_dbusiface_card_free);
+    pa_hashmap_free(c->sinks_by_path, NULL);
+    pa_hashmap_free(c->sinks_by_index, (pa_free_cb_t) pa_dbusiface_device_free);
+    pa_hashmap_free(c->sources_by_path, NULL);
+    pa_hashmap_free(c->sources_by_index, (pa_free_cb_t) pa_dbusiface_device_free);
+    pa_hashmap_free(c->playback_streams, (pa_free_cb_t) pa_dbusiface_stream_free);
+    pa_hashmap_free(c->record_streams, (pa_free_cb_t) pa_dbusiface_stream_free);
+    pa_hashmap_free(c->samples, (pa_free_cb_t) pa_dbusiface_sample_free);
+    pa_hashmap_free(c->modules, (pa_free_cb_t) pa_dbusiface_module_free);
+    pa_hashmap_free(c->clients, (pa_free_cb_t) pa_dbusiface_client_free);
+    pa_hook_slot_free(c->sink_put_slot);
+    pa_hook_slot_free(c->sink_unlink_slot);
+    pa_hook_slot_free(c->source_put_slot);
+    pa_hook_slot_free(c->source_unlink_slot);
+    pa_hook_slot_free(c->extension_registered_slot);
+    pa_hook_slot_free(c->extension_unregistered_slot);
+    pa_dbusiface_memstats_free(c->memstats);
+
+    if (c->fallback_sink)
+        pa_sink_unref(c->fallback_sink);
+    if (c->fallback_source)
+        pa_source_unref(c->fallback_source);
+
+    pa_dbus_protocol_unref(c->dbus_protocol);
+
+    pa_xfree(c);
+}
+
+const char *pa_dbusiface_core_get_card_path(pa_dbusiface_core *c, const pa_card *card) {
+    pa_assert(c);
+    pa_assert(card);
+
+    return pa_dbusiface_card_get_path(pa_hashmap_get(c->cards, PA_UINT32_TO_PTR(card->index)));
+}
+
+const char *pa_dbusiface_core_get_sink_path(pa_dbusiface_core *c, const pa_sink *sink) {
+    pa_assert(c);
+    pa_assert(sink);
+
+    return pa_dbusiface_device_get_path(pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(sink->index)));
+}
+
+const char *pa_dbusiface_core_get_source_path(pa_dbusiface_core *c, const pa_source *source) {
+    pa_assert(c);
+    pa_assert(source);
+
+    return pa_dbusiface_device_get_path(pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(source->index)));
+}
+
+const char *pa_dbusiface_core_get_playback_stream_path(pa_dbusiface_core *c, const pa_sink_input *sink_input) {
+    pa_assert(c);
+    pa_assert(sink_input);
+
+    return pa_dbusiface_stream_get_path(pa_hashmap_get(c->playback_streams, PA_UINT32_TO_PTR(sink_input->index)));
+}
+
+const char *pa_dbusiface_core_get_record_stream_path(pa_dbusiface_core *c, const pa_source_output *source_output) {
+    pa_assert(c);
+    pa_assert(source_output);
+
+    return pa_dbusiface_stream_get_path(pa_hashmap_get(c->record_streams, PA_UINT32_TO_PTR(source_output->index)));
+}
+
+const char *pa_dbusiface_core_get_module_path(pa_dbusiface_core *c, const pa_module *module) {
+    pa_assert(c);
+    pa_assert(module);
+
+    return pa_dbusiface_module_get_path(pa_hashmap_get(c->modules, PA_UINT32_TO_PTR(module->index)));
+}
+
+const char *pa_dbusiface_core_get_client_path(pa_dbusiface_core *c, const pa_client *client) {
+    pa_assert(c);
+    pa_assert(client);
+
+    return pa_dbusiface_client_get_path(pa_hashmap_get(c->clients, PA_UINT32_TO_PTR(client->index)));
+}
+
+pa_sink *pa_dbusiface_core_get_sink(pa_dbusiface_core *c, const char *object_path) {
+    pa_dbusiface_device *device = NULL;
+
+    pa_assert(c);
+    pa_assert(object_path);
+
+    device = pa_hashmap_get(c->sinks_by_path, object_path);
+
+    if (device)
+        return pa_dbusiface_device_get_sink(device);
+    else
+        return NULL;
+}
+
+pa_source *pa_dbusiface_core_get_source(pa_dbusiface_core *c, const char *object_path) {
+    pa_dbusiface_device *device = NULL;
+
+    pa_assert(c);
+    pa_assert(object_path);
+
+    device = pa_hashmap_get(c->sources_by_path, object_path);
+
+    if (device)
+        return pa_dbusiface_device_get_source(device);
+    else
+        return NULL;
+}
diff --git a/src/modules/dbus/iface-core.h b/src/modules/dbus/iface-core.h
new file mode 100644 (file)
index 0000000..900b6d1
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef foodbusifacecorehfoo
+#define foodbusifacecorehfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+/* This object implements the D-Bus interface org.PulseAudio.Core1.
+ *
+ * See http://pulseaudio.org/wiki/DBusInterface for the Core interface
+ * documentation.
+ */
+
+#include <pulsecore/core.h>
+
+typedef struct pa_dbusiface_core pa_dbusiface_core;
+
+pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core);
+void pa_dbusiface_core_free(pa_dbusiface_core *c);
+
+const char *pa_dbusiface_core_get_card_path(pa_dbusiface_core *c, const pa_card *card);
+const char *pa_dbusiface_core_get_sink_path(pa_dbusiface_core *c, const pa_sink *sink);
+const char *pa_dbusiface_core_get_source_path(pa_dbusiface_core *c, const pa_source *source);
+const char *pa_dbusiface_core_get_playback_stream_path(pa_dbusiface_core *c, const pa_sink_input *sink_input);
+const char *pa_dbusiface_core_get_record_stream_path(pa_dbusiface_core *c, const pa_source_output *source_output);
+const char *pa_dbusiface_core_get_module_path(pa_dbusiface_core *c, const pa_module *module);
+const char *pa_dbusiface_core_get_client_path(pa_dbusiface_core *c, const pa_client *client);
+
+/* Returns NULL if there's no sink with the given path. */
+pa_sink *pa_dbusiface_core_get_sink(pa_dbusiface_core *c, const char *object_path);
+
+/* Returns NULL if there's no source with the given path. */
+pa_source *pa_dbusiface_core_get_source(pa_dbusiface_core *c, const char *object_path);
+
+#endif
diff --git a/src/modules/dbus/iface-device-port.c b/src/modules/dbus/iface-device-port.c
new file mode 100644 (file)
index 0000000..d403b6a
--- /dev/null
@@ -0,0 +1,190 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dbus/dbus.h>
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-util.h>
+
+#include "iface-device-port.h"
+
+#define OBJECT_NAME "port"
+
+static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_description(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_priority(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+struct pa_dbusiface_device_port {
+    uint32_t index;
+    pa_device_port *port;
+    char *path;
+    pa_dbus_protocol *dbus_protocol;
+};
+
+enum property_handler_index {
+    PROPERTY_HANDLER_INDEX,
+    PROPERTY_HANDLER_NAME,
+    PROPERTY_HANDLER_DESCRIPTION,
+    PROPERTY_HANDLER_PRIORITY,
+    PROPERTY_HANDLER_MAX
+};
+
+static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = {
+    [PROPERTY_HANDLER_INDEX]       = { .property_name = "Index",       .type = "u", .get_cb = handle_get_index,       .set_cb = NULL },
+    [PROPERTY_HANDLER_NAME]        = { .property_name = "Name",        .type = "s", .get_cb = handle_get_name,        .set_cb = NULL },
+    [PROPERTY_HANDLER_DESCRIPTION] = { .property_name = "Description", .type = "s", .get_cb = handle_get_description, .set_cb = NULL },
+    [PROPERTY_HANDLER_PRIORITY]    = { .property_name = "Priority",    .type = "u", .get_cb = handle_get_priority,    .set_cb = NULL },
+};
+
+static pa_dbus_interface_info port_interface_info = {
+    .name = PA_DBUSIFACE_DEVICE_PORT_INTERFACE,
+    .method_handlers = NULL,
+    .n_method_handlers = 0,
+    .property_handlers = property_handlers,
+    .n_property_handlers = PROPERTY_HANDLER_MAX,
+    .get_all_properties_cb = handle_get_all,
+    .signals = NULL,
+    .n_signals = 0
+};
+
+static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device_port *p = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(p);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &p->index);
+}
+
+static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device_port *p = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(p);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &p->port->name);
+}
+
+static void handle_get_description(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device_port *p = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(p);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &p->port->description);
+}
+
+static void handle_get_priority(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device_port *p = userdata;
+    dbus_uint32_t priority = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(p);
+
+    priority = p->port->priority;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &priority);
+}
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device_port *p = userdata;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+    DBusMessageIter dict_iter;
+    dbus_uint32_t priority = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(p);
+
+    priority = p->port->priority;
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_INDEX].property_name, DBUS_TYPE_UINT32, &p->index);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_NAME].property_name, DBUS_TYPE_STRING, &p->port->name);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DESCRIPTION].property_name, DBUS_TYPE_STRING, &p->port->description);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PRIORITY].property_name, DBUS_TYPE_UINT32, &priority);
+
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+}
+
+pa_dbusiface_device_port *pa_dbusiface_device_port_new(
+        pa_dbusiface_device *device,
+        pa_core *core,
+        pa_device_port *port,
+        uint32_t idx) {
+    pa_dbusiface_device_port *p = NULL;
+
+    pa_assert(device);
+    pa_assert(core);
+    pa_assert(port);
+
+    p = pa_xnew(pa_dbusiface_device_port, 1);
+    p->index = idx;
+    p->port = port;
+    p->path = pa_sprintf_malloc("%s/%s%u", pa_dbusiface_device_get_path(device), OBJECT_NAME, idx);
+    p->dbus_protocol = pa_dbus_protocol_get(core);
+
+    pa_assert_se(pa_dbus_protocol_add_interface(p->dbus_protocol, p->path, &port_interface_info, p) >= 0);
+
+    return p;
+}
+
+void pa_dbusiface_device_port_free(pa_dbusiface_device_port *p) {
+    pa_assert(p);
+
+    pa_assert_se(pa_dbus_protocol_remove_interface(p->dbus_protocol, p->path, port_interface_info.name) >= 0);
+
+    pa_dbus_protocol_unref(p->dbus_protocol);
+
+    pa_xfree(p->path);
+    pa_xfree(p);
+}
+
+const char *pa_dbusiface_device_port_get_path(pa_dbusiface_device_port *p) {
+    pa_assert(p);
+
+    return p->path;
+}
+
+const char *pa_dbusiface_device_port_get_name(pa_dbusiface_device_port *p) {
+    pa_assert(p);
+
+    return p->port->name;
+}
diff --git a/src/modules/dbus/iface-device-port.h b/src/modules/dbus/iface-device-port.h
new file mode 100644 (file)
index 0000000..0461e2f
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef foodbusifacedeviceporthfoo
+#define foodbusifacedeviceporthfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+/* This object implements the D-Bus interface org.PulseAudio.Core1.DevicePort.
+ *
+ * See http://pulseaudio.org/wiki/DBusInterface for the DevicePort interface
+ * documentation.
+ */
+
+#include <pulsecore/protocol-dbus.h>
+#include <pulsecore/sink.h>
+
+#include "iface-device.h"
+
+#define PA_DBUSIFACE_DEVICE_PORT_INTERFACE PA_DBUS_CORE_INTERFACE ".DevicePort"
+
+typedef struct pa_dbusiface_device_port pa_dbusiface_device_port;
+
+pa_dbusiface_device_port *pa_dbusiface_device_port_new(
+        pa_dbusiface_device *device,
+        pa_core *core,
+        pa_device_port *port,
+        uint32_t idx);
+void pa_dbusiface_device_port_free(pa_dbusiface_device_port *p);
+
+const char *pa_dbusiface_device_port_get_path(pa_dbusiface_device_port *p);
+const char *pa_dbusiface_device_port_get_name(pa_dbusiface_device_port *p);
+
+#endif
diff --git a/src/modules/dbus/iface-device.c b/src/modules/dbus/iface-device.c
new file mode 100644 (file)
index 0000000..888d407
--- /dev/null
@@ -0,0 +1,1309 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-util.h>
+#include <pulsecore/protocol-dbus.h>
+
+#include "iface-device-port.h"
+
+#include "iface-device.h"
+
+#define SINK_OBJECT_NAME "sink"
+#define SOURCE_OBJECT_NAME "source"
+
+static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_driver(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_owner_module(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_card(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_channels(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_volume(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+static void handle_get_has_flat_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_has_convertible_to_decibel_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_base_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_volume_steps(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_mute(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_mute(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+static void handle_get_has_hardware_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_has_hardware_mute(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_configured_latency(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_has_dynamic_latency(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_latency(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_is_hardware_device(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_is_network_device(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_state(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_ports(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_active_port(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_active_port(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+static void handle_get_property_list(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_suspend(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_port_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_sink_get_monitor_source(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_sink_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_source_get_monitor_of_sink(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_source_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+struct pa_dbusiface_device {
+    pa_dbusiface_core *core;
+
+    union {
+        pa_sink *sink;
+        pa_source *source;
+    };
+    pa_device_type_t type;
+    char *path;
+    pa_cvolume volume;
+    dbus_bool_t mute;
+    union {
+        pa_sink_state_t sink_state;
+        pa_source_state_t source_state;
+    };
+    pa_hashmap *ports;
+    uint32_t next_port_index;
+    pa_device_port *active_port;
+    pa_proplist *proplist;
+
+    pa_dbus_protocol *dbus_protocol;
+    pa_subscription *subscription;
+};
+
+enum property_handler_index {
+    PROPERTY_HANDLER_INDEX,
+    PROPERTY_HANDLER_NAME,
+    PROPERTY_HANDLER_DRIVER,
+    PROPERTY_HANDLER_OWNER_MODULE,
+    PROPERTY_HANDLER_CARD,
+    PROPERTY_HANDLER_SAMPLE_FORMAT,
+    PROPERTY_HANDLER_SAMPLE_RATE,
+    PROPERTY_HANDLER_CHANNELS,
+    PROPERTY_HANDLER_VOLUME,
+    PROPERTY_HANDLER_HAS_FLAT_VOLUME,
+    PROPERTY_HANDLER_HAS_CONVERTIBLE_TO_DECIBEL_VOLUME,
+    PROPERTY_HANDLER_BASE_VOLUME,
+    PROPERTY_HANDLER_VOLUME_STEPS,
+    PROPERTY_HANDLER_MUTE,
+    PROPERTY_HANDLER_HAS_HARDWARE_VOLUME,
+    PROPERTY_HANDLER_HAS_HARDWARE_MUTE,
+    PROPERTY_HANDLER_CONFIGURED_LATENCY,
+    PROPERTY_HANDLER_HAS_DYNAMIC_LATENCY,
+    PROPERTY_HANDLER_LATENCY,
+    PROPERTY_HANDLER_IS_HARDWARE_DEVICE,
+    PROPERTY_HANDLER_IS_NETWORK_DEVICE,
+    PROPERTY_HANDLER_STATE,
+    PROPERTY_HANDLER_PORTS,
+    PROPERTY_HANDLER_ACTIVE_PORT,
+    PROPERTY_HANDLER_PROPERTY_LIST,
+    PROPERTY_HANDLER_MAX
+};
+
+enum sink_property_handler_index {
+    SINK_PROPERTY_HANDLER_MONITOR_SOURCE,
+    SINK_PROPERTY_HANDLER_MAX
+};
+
+enum source_property_handler_index {
+    SOURCE_PROPERTY_HANDLER_MONITOR_OF_SINK,
+    SOURCE_PROPERTY_HANDLER_MAX
+};
+
+static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = {
+    [PROPERTY_HANDLER_INDEX]                             = { .property_name = "Index",                         .type = "u",      .get_cb = handle_get_index,                             .set_cb = NULL },
+    [PROPERTY_HANDLER_NAME]                              = { .property_name = "Name",                          .type = "s",      .get_cb = handle_get_name,                              .set_cb = NULL },
+    [PROPERTY_HANDLER_DRIVER]                            = { .property_name = "Driver",                        .type = "s",      .get_cb = handle_get_driver,                            .set_cb = NULL },
+    [PROPERTY_HANDLER_OWNER_MODULE]                      = { .property_name = "OwnerModule",                   .type = "o",      .get_cb = handle_get_owner_module,                      .set_cb = NULL },
+    [PROPERTY_HANDLER_CARD]                              = { .property_name = "Card",                          .type = "o",      .get_cb = handle_get_card,                              .set_cb = NULL },
+    [PROPERTY_HANDLER_SAMPLE_FORMAT]                     = { .property_name = "SampleFormat",                  .type = "u",      .get_cb = handle_get_sample_format,                     .set_cb = NULL },
+    [PROPERTY_HANDLER_SAMPLE_RATE]                       = { .property_name = "SampleRate",                    .type = "u",      .get_cb = handle_get_sample_rate,                       .set_cb = NULL },
+    [PROPERTY_HANDLER_CHANNELS]                          = { .property_name = "Channels",                      .type = "au",     .get_cb = handle_get_channels,                          .set_cb = NULL },
+    [PROPERTY_HANDLER_VOLUME]                            = { .property_name = "Volume",                        .type = "au",     .get_cb = handle_get_volume,                            .set_cb = handle_set_volume },
+    [PROPERTY_HANDLER_HAS_FLAT_VOLUME]                   = { .property_name = "HasFlatVolume",                 .type = "b",      .get_cb = handle_get_has_flat_volume,                   .set_cb = NULL },
+    [PROPERTY_HANDLER_HAS_CONVERTIBLE_TO_DECIBEL_VOLUME] = { .property_name = "HasConvertibleToDecibelVolume", .type = "b",      .get_cb = handle_get_has_convertible_to_decibel_volume, .set_cb = NULL },
+    [PROPERTY_HANDLER_BASE_VOLUME]                       = { .property_name = "BaseVolume",                    .type = "u",      .get_cb = handle_get_base_volume,                       .set_cb = NULL },
+    [PROPERTY_HANDLER_VOLUME_STEPS]                      = { .property_name = "VolumeSteps",                   .type = "u",      .get_cb = handle_get_volume_steps,                      .set_cb = NULL },
+    [PROPERTY_HANDLER_MUTE]                              = { .property_name = "Mute",                          .type = "b",      .get_cb = handle_get_mute,                              .set_cb = handle_set_mute },
+    [PROPERTY_HANDLER_HAS_HARDWARE_VOLUME]               = { .property_name = "HasHardwareVolume",             .type = "b",      .get_cb = handle_get_has_hardware_volume,               .set_cb = NULL },
+    [PROPERTY_HANDLER_HAS_HARDWARE_MUTE]                 = { .property_name = "HasHardwareMute",               .type = "b",      .get_cb = handle_get_has_hardware_mute,                 .set_cb = NULL },
+    [PROPERTY_HANDLER_CONFIGURED_LATENCY]                = { .property_name = "ConfiguredLatency",             .type = "t",      .get_cb = handle_get_configured_latency,                .set_cb = NULL },
+    [PROPERTY_HANDLER_HAS_DYNAMIC_LATENCY]               = { .property_name = "HasDynamicLatency",             .type = "b",      .get_cb = handle_get_has_dynamic_latency,               .set_cb = NULL },
+    [PROPERTY_HANDLER_LATENCY]                           = { .property_name = "Latency",                       .type = "t",      .get_cb = handle_get_latency,                           .set_cb = NULL },
+    [PROPERTY_HANDLER_IS_HARDWARE_DEVICE]                = { .property_name = "IsHardwareDevice",              .type = "b",      .get_cb = handle_get_is_hardware_device,                .set_cb = NULL },
+    [PROPERTY_HANDLER_IS_NETWORK_DEVICE]                 = { .property_name = "IsNetworkDevice",               .type = "b",      .get_cb = handle_get_is_network_device,                 .set_cb = NULL },
+    [PROPERTY_HANDLER_STATE]                             = { .property_name = "State",                         .type = "u",      .get_cb = handle_get_state,                             .set_cb = NULL },
+    [PROPERTY_HANDLER_PORTS]                             = { .property_name = "Ports",                         .type = "ao",     .get_cb = handle_get_ports,                             .set_cb = NULL },
+    [PROPERTY_HANDLER_ACTIVE_PORT]                       = { .property_name = "ActivePort",                    .type = "o",      .get_cb = handle_get_active_port,                       .set_cb = handle_set_active_port },
+    [PROPERTY_HANDLER_PROPERTY_LIST]                     = { .property_name = "PropertyList",                  .type = "a{say}", .get_cb = handle_get_property_list,                     .set_cb = NULL }
+};
+
+static pa_dbus_property_handler sink_property_handlers[SINK_PROPERTY_HANDLER_MAX] = {
+    [SINK_PROPERTY_HANDLER_MONITOR_SOURCE] = { .property_name = "MonitorSource", .type = "o", .get_cb = handle_sink_get_monitor_source, .set_cb = NULL }
+};
+
+static pa_dbus_property_handler source_property_handlers[SOURCE_PROPERTY_HANDLER_MAX] = {
+    [SOURCE_PROPERTY_HANDLER_MONITOR_OF_SINK] = { .property_name = "MonitorOfSink", .type = "o", .get_cb = handle_source_get_monitor_of_sink, .set_cb = NULL }
+};
+
+enum method_handler_index {
+    METHOD_HANDLER_SUSPEND,
+    METHOD_HANDLER_GET_PORT_BY_NAME,
+    METHOD_HANDLER_MAX
+};
+
+static pa_dbus_arg_info suspend_args[] = { { "suspend", "b", "in" } };
+static pa_dbus_arg_info get_port_by_name_args[] = { { "name", "s", "in" }, { "port", "o", "out" } };
+
+static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
+    [METHOD_HANDLER_SUSPEND] = {
+        .method_name = "Suspend",
+        .arguments = suspend_args,
+        .n_arguments = sizeof(suspend_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_suspend },
+    [METHOD_HANDLER_GET_PORT_BY_NAME] = {
+        .method_name = "GetPortByName",
+        .arguments = get_port_by_name_args,
+        .n_arguments = sizeof(get_port_by_name_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_get_port_by_name }
+};
+
+enum signal_index {
+    SIGNAL_VOLUME_UPDATED,
+    SIGNAL_MUTE_UPDATED,
+    SIGNAL_STATE_UPDATED,
+    SIGNAL_ACTIVE_PORT_UPDATED,
+    SIGNAL_PROPERTY_LIST_UPDATED,
+    SIGNAL_MAX
+};
+
+static pa_dbus_arg_info volume_updated_args[]        = { { "volume",        "au",     NULL } };
+static pa_dbus_arg_info mute_updated_args[]          = { { "muted",         "b",      NULL } };
+static pa_dbus_arg_info state_updated_args[]         = { { "state",         "u",      NULL } };
+static pa_dbus_arg_info active_port_updated_args[]   = { { "port",          "o",      NULL } };
+static pa_dbus_arg_info property_list_updated_args[] = { { "property_list", "a{say}", NULL } };
+
+static pa_dbus_signal_info signals[SIGNAL_MAX] = {
+    [SIGNAL_VOLUME_UPDATED]        = { .name = "VolumeUpdated",       .arguments = volume_updated_args,        .n_arguments = 1 },
+    [SIGNAL_MUTE_UPDATED]          = { .name = "MuteUpdated",         .arguments = mute_updated_args,          .n_arguments = 1 },
+    [SIGNAL_STATE_UPDATED]         = { .name = "StateUpdated",        .arguments = state_updated_args,         .n_arguments = 1 },
+    [SIGNAL_ACTIVE_PORT_UPDATED]   = { .name = "ActivePortUpdated",   .arguments = active_port_updated_args,   .n_arguments = 1 },
+    [SIGNAL_PROPERTY_LIST_UPDATED] = { .name = "PropertyListUpdated", .arguments = property_list_updated_args, .n_arguments = 1 }
+};
+
+static pa_dbus_interface_info device_interface_info = {
+    .name = PA_DBUSIFACE_DEVICE_INTERFACE,
+    .method_handlers = method_handlers,
+    .n_method_handlers = METHOD_HANDLER_MAX,
+    .property_handlers = property_handlers,
+    .n_property_handlers = PROPERTY_HANDLER_MAX,
+    .get_all_properties_cb = handle_get_all,
+    .signals = signals,
+    .n_signals = SIGNAL_MAX
+};
+
+static pa_dbus_interface_info sink_interface_info = {
+    .name = PA_DBUSIFACE_SINK_INTERFACE,
+    .method_handlers = NULL,
+    .n_method_handlers = 0,
+    .property_handlers = sink_property_handlers,
+    .n_property_handlers = SINK_PROPERTY_HANDLER_MAX,
+    .get_all_properties_cb = handle_sink_get_all,
+    .signals = NULL,
+    .n_signals = 0
+};
+
+static pa_dbus_interface_info source_interface_info = {
+    .name = PA_DBUSIFACE_SOURCE_INTERFACE,
+    .method_handlers = NULL,
+    .n_method_handlers = 0,
+    .property_handlers = source_property_handlers,
+    .n_property_handlers = SOURCE_PROPERTY_HANDLER_MAX,
+    .get_all_properties_cb = handle_source_get_all,
+    .signals = NULL,
+    .n_signals = 0
+};
+
+static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_uint32_t idx = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    idx = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->index : d->source->index;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &idx);
+}
+
+static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    const char *name = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    name = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->name : d->source->name;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &name);
+}
+
+static void handle_get_driver(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    const char *driver = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    driver = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->driver : d->source->driver;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &driver);
+}
+
+static void handle_get_owner_module(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    pa_module *owner_module = NULL;
+    const char *object_path = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    owner_module = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->module : d->source->module;
+
+    if (!owner_module) {
+        if (d->type == PA_DEVICE_TYPE_SINK)
+            pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                               "Sink %s doesn't have an owner module.", d->sink->name);
+        else
+            pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                               "Source %s doesn't have an owner module.", d->source->name);
+        return;
+    }
+
+    object_path = pa_dbusiface_core_get_module_path(d->core, owner_module);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path);
+}
+
+static void handle_get_card(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    pa_card *card = NULL;
+    const char *object_path = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    card = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->card : d->source->card;
+
+    if (!card) {
+        if (d->type == PA_DEVICE_TYPE_SINK)
+            pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                               "Sink %s doesn't belong to any card.", d->sink->name);
+        else
+            pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                               "Source %s doesn't belong to any card.", d->source->name);
+        return;
+    }
+
+    object_path = pa_dbusiface_core_get_card_path(d->core, card);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path);
+}
+
+static void handle_get_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_uint32_t sample_format = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    sample_format = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->sample_spec.format : d->source->sample_spec.format;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &sample_format);
+}
+
+static void handle_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_uint32_t sample_rate = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    sample_rate = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->sample_spec.rate : d->source->sample_spec.rate;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &sample_rate);
+}
+
+static void handle_get_channels(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    pa_channel_map *channel_map = NULL;
+    dbus_uint32_t channels[PA_CHANNELS_MAX];
+    unsigned i = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    channel_map = (d->type == PA_DEVICE_TYPE_SINK) ? &d->sink->channel_map : &d->source->channel_map;
+
+    for (i = 0; i < channel_map->channels; ++i)
+        channels[i] = channel_map->map[i];
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_UINT32, channels, channel_map->channels);
+}
+
+static void handle_get_volume(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_uint32_t volume[PA_CHANNELS_MAX];
+    unsigned i = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    for (i = 0; i < d->volume.channels; ++i)
+        volume[i] = d->volume.values[i];
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_UINT32, volume, d->volume.channels);
+}
+
+static void handle_set_volume(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    DBusMessageIter array_iter;
+    int device_channels = 0;
+    dbus_uint32_t *volume = NULL;
+    int n_volume_entries = 0;
+    pa_cvolume new_vol;
+    int i = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(d);
+
+    device_channels = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->channel_map.channels : d->source->channel_map.channels;
+
+    dbus_message_iter_recurse(iter, &array_iter);
+    dbus_message_iter_get_fixed_array(&array_iter, &volume, &n_volume_entries);
+
+    if (n_volume_entries != device_channels && n_volume_entries != 1) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS,
+                           "Expected %u volume entries, got %i.", device_channels, n_volume_entries);
+        return;
+    }
+
+    pa_cvolume_init(&new_vol);
+    new_vol.channels = n_volume_entries;
+
+    for (i = 0; i < n_volume_entries; ++i) {
+        if (!PA_VOLUME_IS_VALID(volume[i])) {
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too large volume value: %u", volume[i]);
+            return;
+        }
+        new_vol.values[i] = volume[i];
+    }
+
+    if (d->type == PA_DEVICE_TYPE_SINK)
+        pa_sink_set_volume(d->sink, &new_vol, TRUE, TRUE);
+    else
+        pa_source_set_volume(d->source, &new_vol, TRUE, TRUE);
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+static void handle_get_has_flat_volume(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_bool_t has_flat_volume = FALSE;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    has_flat_volume = (d->type == PA_DEVICE_TYPE_SINK) ? (d->sink->flags & PA_SINK_FLAT_VOLUME) : FALSE;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &has_flat_volume);
+}
+
+static void handle_get_has_convertible_to_decibel_volume(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_bool_t has_convertible_to_decibel_volume = FALSE;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    has_convertible_to_decibel_volume = (d->type == PA_DEVICE_TYPE_SINK)
+                                        ? (d->sink->flags & PA_SINK_DECIBEL_VOLUME)
+                                        : (d->source->flags & PA_SOURCE_DECIBEL_VOLUME);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &has_convertible_to_decibel_volume);
+}
+
+static void handle_get_base_volume(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_uint32_t base_volume;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    base_volume = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->base_volume : d->source->base_volume;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &base_volume);
+}
+
+static void handle_get_volume_steps(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_uint32_t volume_steps;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    volume_steps = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->n_volume_steps : d->source->n_volume_steps;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &volume_steps);
+}
+
+static void handle_get_mute(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &d->mute);
+}
+
+static void handle_set_mute(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_bool_t mute = FALSE;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(d);
+
+    dbus_message_iter_get_basic(iter, &mute);
+
+    if (d->type == PA_DEVICE_TYPE_SINK)
+        pa_sink_set_mute(d->sink, mute, TRUE);
+    else
+        pa_source_set_mute(d->source, mute, TRUE);
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+static void handle_get_has_hardware_volume(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_bool_t has_hardware_volume = FALSE;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    has_hardware_volume = (d->type == PA_DEVICE_TYPE_SINK)
+                          ? (d->sink->flags & PA_SINK_HW_VOLUME_CTRL)
+                          : (d->source->flags & PA_SOURCE_HW_VOLUME_CTRL);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &has_hardware_volume);
+}
+
+static void handle_get_has_hardware_mute(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_bool_t has_hardware_mute = FALSE;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    has_hardware_mute = (d->type == PA_DEVICE_TYPE_SINK)
+                        ? (d->sink->flags & PA_SINK_HW_MUTE_CTRL)
+                        : (d->source->flags & PA_SOURCE_HW_MUTE_CTRL);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &has_hardware_mute);
+}
+
+static void handle_get_configured_latency(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_uint64_t configured_latency = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    configured_latency = (d->type == PA_DEVICE_TYPE_SINK)
+                         ? pa_sink_get_requested_latency(d->sink)
+                         : pa_source_get_requested_latency(d->source);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT64, &configured_latency);
+}
+
+static void handle_get_has_dynamic_latency(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_bool_t has_dynamic_latency = FALSE;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    has_dynamic_latency = (d->type == PA_DEVICE_TYPE_SINK)
+                          ? (d->sink->flags & PA_SINK_DYNAMIC_LATENCY)
+                          : (d->source->flags & PA_SOURCE_DYNAMIC_LATENCY);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &has_dynamic_latency);
+}
+
+static void handle_get_latency(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_uint64_t latency = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    if (d->type == PA_DEVICE_TYPE_SINK && !(d->sink->flags & PA_SINK_LATENCY)) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                           "Sink %s doesn't support latency querying.", d->sink->name);
+        return;
+    }
+
+    if (d->type == PA_DEVICE_TYPE_SOURCE && !(d->source->flags & PA_SOURCE_LATENCY)) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                           "Source %s doesn't support latency querying.", d->source->name);
+        return;
+    }
+
+    latency = (d->type == PA_DEVICE_TYPE_SINK) ? pa_sink_get_latency(d->sink) : pa_source_get_latency(d->source);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT64, &latency);
+}
+
+static void handle_get_is_hardware_device(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_bool_t is_hardware_device = FALSE;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    is_hardware_device = (d->type == PA_DEVICE_TYPE_SINK)
+                         ? (d->sink->flags & PA_SINK_HARDWARE)
+                         : (d->source->flags & PA_SOURCE_HARDWARE);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &is_hardware_device);
+}
+
+static void handle_get_is_network_device(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_bool_t is_network_device = FALSE;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    is_network_device = (d->type == PA_DEVICE_TYPE_SINK)
+                        ? (d->sink->flags & PA_SINK_NETWORK)
+                        : (d->source->flags & PA_SOURCE_NETWORK);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &is_network_device);
+}
+
+static void handle_get_state(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_uint32_t state;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    state = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink_state : d->source_state;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &state);
+}
+
+/* The caller frees the array, but not the strings. */
+static const char **get_ports(pa_dbusiface_device *d, unsigned *n) {
+    const char **ports;
+    unsigned i = 0;
+    void *state = NULL;
+    pa_dbusiface_device_port *port = NULL;
+
+    pa_assert(d);
+    pa_assert(n);
+
+    *n = pa_hashmap_size(d->ports);
+
+    if (*n == 0)
+        return NULL;
+
+    ports = pa_xnew(const char *, *n);
+
+    PA_HASHMAP_FOREACH(port, d->ports, state)
+        ports[i++] = pa_dbusiface_device_port_get_path(port);
+
+    return ports;
+}
+
+static void handle_get_ports(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    const char **ports = NULL;
+    unsigned n_ports = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    ports = get_ports(d, &n_ports);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, ports, n_ports);
+
+    pa_xfree(ports);
+}
+
+static void handle_get_active_port(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    const char *active_port;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    if (!d->active_port) {
+        pa_assert(pa_hashmap_isempty(d->ports));
+
+        if (d->type == PA_DEVICE_TYPE_SINK)
+            pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                               "The sink %s has no ports, and therefore there's no active port either.", d->sink->name);
+        else
+            pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                               "The source %s has no ports, and therefore there's no active port either.", d->source->name);
+        return;
+    }
+
+    active_port = pa_dbusiface_device_port_get_path(pa_hashmap_get(d->ports, d->active_port->name));
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &active_port);
+}
+
+static void handle_set_active_port(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    const char *new_active_path;
+    pa_dbusiface_device_port *new_active;
+    int r;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(d);
+
+    if (!d->active_port) {
+        pa_assert(pa_hashmap_isempty(d->ports));
+
+        if (d->type == PA_DEVICE_TYPE_SINK)
+            pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                               "The sink %s has no ports, and therefore there's no active port either.", d->sink->name);
+        else
+            pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                               "The source %s has no ports, and therefore there's no active port either.", d->source->name);
+        return;
+    }
+
+    dbus_message_iter_get_basic(iter, &new_active_path);
+
+    if (!(new_active = pa_hashmap_get(d->ports, new_active_path))) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such port: %s", new_active_path);
+        return;
+    }
+
+    if (d->type == PA_DEVICE_TYPE_SINK) {
+        if ((r = pa_sink_set_port(d->sink, pa_dbusiface_device_port_get_name(new_active), TRUE)) < 0) {
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED,
+                               "Internal error in PulseAudio: pa_sink_set_port() failed with error code %i.", r);
+            return;
+        }
+    } else {
+        if ((r = pa_source_set_port(d->source, pa_dbusiface_device_port_get_name(new_active), TRUE)) < 0) {
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED,
+                               "Internal error in PulseAudio: pa_source_set_port() failed with error code %i.", r);
+            return;
+        }
+    }
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+static void handle_get_property_list(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    pa_dbus_send_proplist_variant_reply(conn, msg, d->proplist);
+}
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+    DBusMessageIter dict_iter;
+    dbus_uint32_t idx = 0;
+    const char *name = NULL;
+    const char *driver = NULL;
+    pa_module *owner_module = NULL;
+    const char *owner_module_path = NULL;
+    pa_card *card = NULL;
+    const char *card_path = NULL;
+    dbus_uint32_t sample_format = 0;
+    dbus_uint32_t sample_rate = 0;
+    pa_channel_map *channel_map = NULL;
+    dbus_uint32_t channels[PA_CHANNELS_MAX];
+    dbus_uint32_t volume[PA_CHANNELS_MAX];
+    dbus_bool_t has_flat_volume = FALSE;
+    dbus_bool_t has_convertible_to_decibel_volume = FALSE;
+    dbus_uint32_t base_volume = 0;
+    dbus_uint32_t volume_steps = 0;
+    dbus_bool_t has_hardware_volume = FALSE;
+    dbus_bool_t has_hardware_mute = FALSE;
+    dbus_uint64_t configured_latency = 0;
+    dbus_bool_t has_dynamic_latency = FALSE;
+    dbus_uint64_t latency = 0;
+    dbus_bool_t is_hardware_device = FALSE;
+    dbus_bool_t is_network_device = FALSE;
+    dbus_uint32_t state = 0;
+    const char **ports = NULL;
+    unsigned n_ports = 0;
+    const char *active_port = NULL;
+    unsigned i = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    if (d->type == PA_DEVICE_TYPE_SINK) {
+        idx = d->sink->index;
+        name = d->sink->name;
+        driver = d->sink->driver;
+        owner_module = d->sink->module;
+        card = d->sink->card;
+        sample_format = d->sink->sample_spec.format;
+        sample_rate = d->sink->sample_spec.rate;
+        channel_map = &d->sink->channel_map;
+        has_flat_volume = d->sink->flags & PA_SINK_FLAT_VOLUME;
+        has_convertible_to_decibel_volume = d->sink->flags & PA_SINK_DECIBEL_VOLUME;
+        base_volume = d->sink->base_volume;
+        volume_steps = d->sink->n_volume_steps;
+        has_hardware_volume = d->sink->flags & PA_SINK_HW_VOLUME_CTRL;
+        has_hardware_mute = d->sink->flags & PA_SINK_HW_MUTE_CTRL;
+        configured_latency = pa_sink_get_requested_latency(d->sink);
+        has_dynamic_latency = d->sink->flags & PA_SINK_DYNAMIC_LATENCY;
+        latency = pa_sink_get_latency(d->sink);
+        is_hardware_device = d->sink->flags & PA_SINK_HARDWARE;
+        is_network_device = d->sink->flags & PA_SINK_NETWORK;
+        state = pa_sink_get_state(d->sink);
+    } else {
+        idx = d->source->index;
+        name = d->source->name;
+        driver = d->source->driver;
+        owner_module = d->source->module;
+        card = d->source->card;
+        sample_format = d->source->sample_spec.format;
+        sample_rate = d->source->sample_spec.rate;
+        channel_map = &d->source->channel_map;
+        has_flat_volume = FALSE;
+        has_convertible_to_decibel_volume = d->source->flags & PA_SOURCE_DECIBEL_VOLUME;
+        base_volume = d->source->base_volume;
+        volume_steps = d->source->n_volume_steps;
+        has_hardware_volume = d->source->flags & PA_SOURCE_HW_VOLUME_CTRL;
+        has_hardware_mute = d->source->flags & PA_SOURCE_HW_MUTE_CTRL;
+        configured_latency = pa_source_get_requested_latency(d->source);
+        has_dynamic_latency = d->source->flags & PA_SOURCE_DYNAMIC_LATENCY;
+        latency = pa_source_get_latency(d->source);
+        is_hardware_device = d->source->flags & PA_SOURCE_HARDWARE;
+        is_network_device = d->source->flags & PA_SOURCE_NETWORK;
+        state = pa_source_get_state(d->source);
+    }
+    if (owner_module)
+        owner_module_path = pa_dbusiface_core_get_module_path(d->core, owner_module);
+    if (card)
+        card_path = pa_dbusiface_core_get_card_path(d->core, card);
+    for (i = 0; i < channel_map->channels; ++i)
+        channels[i] = channel_map->map[i];
+    for (i = 0; i < d->volume.channels; ++i)
+        volume[i] = d->volume.values[i];
+    ports = get_ports(d, &n_ports);
+    if (d->active_port)
+        active_port = pa_dbusiface_device_port_get_path(pa_hashmap_get(d->ports, d->active_port->name));
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_INDEX].property_name, DBUS_TYPE_UINT32, &idx);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_NAME].property_name, DBUS_TYPE_STRING, &name);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DRIVER].property_name, DBUS_TYPE_STRING, &driver);
+
+    if (owner_module)
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_OWNER_MODULE].property_name, DBUS_TYPE_OBJECT_PATH, &owner_module_path);
+
+    if (card)
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CARD].property_name, DBUS_TYPE_OBJECT_PATH, &card_path);
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SAMPLE_FORMAT].property_name, DBUS_TYPE_UINT32, &sample_format);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SAMPLE_RATE].property_name, DBUS_TYPE_UINT32, &sample_rate);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CHANNELS].property_name, DBUS_TYPE_UINT32, channels, channel_map->channels);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_VOLUME].property_name, DBUS_TYPE_UINT32, volume, d->volume.channels);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_HAS_FLAT_VOLUME].property_name, DBUS_TYPE_BOOLEAN, &has_flat_volume);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_HAS_CONVERTIBLE_TO_DECIBEL_VOLUME].property_name, DBUS_TYPE_BOOLEAN, &has_convertible_to_decibel_volume);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_BASE_VOLUME].property_name, DBUS_TYPE_UINT32, &base_volume);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_VOLUME_STEPS].property_name, DBUS_TYPE_UINT32, &volume_steps);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_MUTE].property_name, DBUS_TYPE_BOOLEAN, &d->mute);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_HAS_HARDWARE_VOLUME].property_name, DBUS_TYPE_BOOLEAN, &has_hardware_volume);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_HAS_HARDWARE_MUTE].property_name, DBUS_TYPE_BOOLEAN, &has_hardware_mute);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CONFIGURED_LATENCY].property_name, DBUS_TYPE_UINT64, &configured_latency);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_HAS_DYNAMIC_LATENCY].property_name, DBUS_TYPE_BOOLEAN, &has_dynamic_latency);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_LATENCY].property_name, DBUS_TYPE_UINT64, &latency);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_IS_HARDWARE_DEVICE].property_name, DBUS_TYPE_BOOLEAN, &is_hardware_device);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_IS_NETWORK_DEVICE].property_name, DBUS_TYPE_BOOLEAN, &is_network_device);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_STATE].property_name, DBUS_TYPE_UINT32, &state);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PORTS].property_name, DBUS_TYPE_OBJECT_PATH, ports, n_ports);
+
+    if (active_port)
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_ACTIVE_PORT].property_name, DBUS_TYPE_OBJECT_PATH, &active_port);
+
+    pa_dbus_append_proplist_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PROPERTY_LIST].property_name, d->proplist);
+
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+
+    dbus_message_unref(reply);
+
+    pa_xfree(ports);
+}
+
+static void handle_suspend(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    dbus_bool_t suspend = FALSE;
+    pa_client *client;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &suspend, DBUS_TYPE_INVALID));
+    pa_assert_se(client = pa_dbus_protocol_get_client(d->dbus_protocol, conn));
+
+    if (d->type == PA_DEVICE_TYPE_SINK) {
+        pa_log_debug("%s sink %s requested by client %" PRIu32 ".", suspend ? "Suspending" : "Resuming", d->sink->name, client->index);
+
+        if (pa_sink_suspend(d->sink, suspend, PA_SUSPEND_USER) < 0) {
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Internal error in PulseAudio: pa_sink_suspend() failed.");
+            return;
+        }
+
+    } else {
+        pa_log_debug("%s source %s requested by client %" PRIu32 ".", suspend ? "Suspending" : "Resuming", d->source->name, client->index);
+
+        if (pa_source_suspend(d->source, suspend, PA_SUSPEND_USER) < 0) {
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Internal error in PulseAudio: pa_source_suspend() failed.");
+            return;
+        }
+    }
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+static void handle_get_port_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    const char *port_name = NULL;
+    pa_dbusiface_device_port *port = NULL;
+    const char *port_path = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+
+    pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &port_name, DBUS_TYPE_INVALID));
+
+    if (!(port = pa_hashmap_get(d->ports, port_name))) {
+        if (d->type == PA_DEVICE_TYPE_SINK)
+            pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND,
+                               "%s: No such port on sink %s.", port_name, d->sink->name);
+        else
+            pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND,
+                               "%s: No such port on source %s.", port_name, d->source->name);
+        return;
+    }
+
+    port_path = pa_dbusiface_device_port_get_path(port);
+
+    pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &port_path);
+}
+
+static void handle_sink_get_monitor_source(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    const char *monitor_source = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+    pa_assert(d->type == PA_DEVICE_TYPE_SINK);
+
+    monitor_source = pa_dbusiface_core_get_source_path(d->core, d->sink->monitor_source);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &monitor_source);
+}
+
+static void handle_sink_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+    DBusMessageIter dict_iter;
+    const char *monitor_source = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+    pa_assert(d->type == PA_DEVICE_TYPE_SINK);
+
+    monitor_source = pa_dbusiface_core_get_source_path(d->core, d->sink->monitor_source);
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[SINK_PROPERTY_HANDLER_MONITOR_SOURCE].property_name, DBUS_TYPE_OBJECT_PATH, &monitor_source);
+
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+
+    dbus_message_unref(reply);
+}
+
+static void handle_source_get_monitor_of_sink(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    const char *monitor_of_sink = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+    pa_assert(d->type == PA_DEVICE_TYPE_SOURCE);
+
+    if (!d->source->monitor_of) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "Source %s is not a monitor source.", d->source->name);
+        return;
+    }
+
+    monitor_of_sink = pa_dbusiface_core_get_sink_path(d->core, d->source->monitor_of);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &monitor_of_sink);
+}
+
+static void handle_source_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+    DBusMessageIter dict_iter;
+    const char *monitor_of_sink = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(d);
+    pa_assert(d->type == PA_DEVICE_TYPE_SOURCE);
+
+    if (d->source->monitor_of)
+        monitor_of_sink = pa_dbusiface_core_get_sink_path(d->core, d->source->monitor_of);
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+
+    if (monitor_of_sink)
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[SOURCE_PROPERTY_HANDLER_MONITOR_OF_SINK].property_name, DBUS_TYPE_OBJECT_PATH, &monitor_of_sink);
+
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+
+    dbus_message_unref(reply);
+}
+
+static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
+    pa_dbusiface_device *d = userdata;
+    DBusMessage *signal_msg = NULL;
+    const pa_cvolume *new_volume = NULL;
+    pa_bool_t new_mute = FALSE;
+    pa_sink_state_t new_sink_state = 0;
+    pa_source_state_t new_source_state = 0;
+    pa_device_port *new_active_port = NULL;
+    pa_proplist *new_proplist = NULL;
+    unsigned i = 0;
+
+    pa_assert(c);
+    pa_assert(d);
+
+    if ((d->type == PA_DEVICE_TYPE_SINK && idx != d->sink->index) || (d->type == PA_DEVICE_TYPE_SOURCE && idx != d->source->index))
+        return;
+
+    if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) != PA_SUBSCRIPTION_EVENT_CHANGE)
+        return;
+
+    pa_assert(((d->type == PA_DEVICE_TYPE_SINK)
+                && ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK))
+              || ((d->type == PA_DEVICE_TYPE_SOURCE)
+                   && ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE)));
+
+    new_volume = (d->type == PA_DEVICE_TYPE_SINK)
+                 ? pa_sink_get_volume(d->sink, FALSE)
+                 : pa_source_get_volume(d->source, FALSE);
+
+    if (!pa_cvolume_equal(&d->volume, new_volume)) {
+        dbus_uint32_t volume[PA_CHANNELS_MAX];
+        dbus_uint32_t *volume_ptr = volume;
+
+        d->volume = *new_volume;
+
+        for (i = 0; i < d->volume.channels; ++i)
+            volume[i] = d->volume.values[i];
+
+        pa_assert_se(signal_msg = dbus_message_new_signal(d->path,
+                                                         PA_DBUSIFACE_DEVICE_INTERFACE,
+                                                         signals[SIGNAL_VOLUME_UPDATED].name));
+        pa_assert_se(dbus_message_append_args(signal_msg,
+                                              DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &volume_ptr, d->volume.channels,
+                                              DBUS_TYPE_INVALID));
+
+        pa_dbus_protocol_send_signal(d->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
+    }
+
+    new_mute = (d->type == PA_DEVICE_TYPE_SINK) ? pa_sink_get_mute(d->sink, FALSE) : pa_source_get_mute(d->source, FALSE);
+
+    if (d->mute != new_mute) {
+        d->mute = new_mute;
+
+        pa_assert_se(signal_msg = dbus_message_new_signal(d->path,
+                                                         PA_DBUSIFACE_DEVICE_INTERFACE,
+                                                         signals[SIGNAL_MUTE_UPDATED].name));
+        pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_BOOLEAN, &d->mute, DBUS_TYPE_INVALID));
+
+        pa_dbus_protocol_send_signal(d->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
+    }
+
+    if (d->type == PA_DEVICE_TYPE_SINK)
+        new_sink_state = pa_sink_get_state(d->sink);
+    else
+        new_source_state = pa_source_get_state(d->source);
+
+    if ((d->type == PA_DEVICE_TYPE_SINK && d->sink_state != new_sink_state)
+        || (d->type == PA_DEVICE_TYPE_SOURCE && d->source_state != new_source_state)) {
+        dbus_uint32_t state = 0;
+
+        if (d->type == PA_DEVICE_TYPE_SINK)
+            d->sink_state = new_sink_state;
+        else
+            d->source_state = new_source_state;
+
+        state = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink_state : d->source_state;
+
+        pa_assert_se(signal_msg = dbus_message_new_signal(d->path,
+                                                         PA_DBUSIFACE_DEVICE_INTERFACE,
+                                                         signals[SIGNAL_STATE_UPDATED].name));
+        pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID));
+
+        pa_dbus_protocol_send_signal(d->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
+    }
+
+    new_active_port = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->active_port : d->source->active_port;
+
+    if (d->active_port != new_active_port) {
+        const char *object_path = NULL;
+
+        d->active_port = new_active_port;
+        object_path = pa_dbusiface_device_port_get_path(pa_hashmap_get(d->ports, d->active_port->name));
+
+        pa_assert_se(signal_msg = dbus_message_new_signal(d->path,
+                                                         PA_DBUSIFACE_DEVICE_INTERFACE,
+                                                         signals[SIGNAL_ACTIVE_PORT_UPDATED].name));
+        pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
+
+        pa_dbus_protocol_send_signal(d->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
+    }
+
+    new_proplist = (d->type == PA_DEVICE_TYPE_SINK) ? d->sink->proplist : d->source->proplist;
+
+    if (!pa_proplist_equal(d->proplist, new_proplist)) {
+        DBusMessageIter msg_iter;
+
+        pa_proplist_update(d->proplist, PA_UPDATE_SET, new_proplist);
+
+        pa_assert_se(signal_msg = dbus_message_new_signal(d->path,
+                                                         PA_DBUSIFACE_DEVICE_INTERFACE,
+                                                         signals[SIGNAL_PROPERTY_LIST_UPDATED].name));
+        dbus_message_iter_init_append(signal_msg, &msg_iter);
+        pa_dbus_append_proplist(&msg_iter, d->proplist);
+
+        pa_dbus_protocol_send_signal(d->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
+    }
+}
+
+pa_dbusiface_device *pa_dbusiface_device_new_sink(pa_dbusiface_core *core, pa_sink *sink) {
+    pa_dbusiface_device *d = NULL;
+    pa_device_port *port;
+    void *state;
+
+    pa_assert(core);
+    pa_assert(sink);
+
+    d = pa_xnew0(pa_dbusiface_device, 1);
+    d->core = core;
+    d->sink = pa_sink_ref(sink);
+    d->type = PA_DEVICE_TYPE_SINK;
+    d->path = pa_sprintf_malloc("%s/%s%u", PA_DBUS_CORE_OBJECT_PATH, SINK_OBJECT_NAME, sink->index);
+    d->volume = *pa_sink_get_volume(sink, FALSE);
+    d->mute = pa_sink_get_mute(sink, FALSE);
+    d->sink_state = pa_sink_get_state(sink);
+    d->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    d->next_port_index = 0;
+    d->active_port = sink->active_port;
+    d->proplist = pa_proplist_copy(sink->proplist);
+    d->dbus_protocol = pa_dbus_protocol_get(sink->core);
+    d->subscription = pa_subscription_new(sink->core, PA_SUBSCRIPTION_MASK_SINK, subscription_cb, d);
+
+    PA_HASHMAP_FOREACH(port, sink->ports, state) {
+        pa_dbusiface_device_port *p = pa_dbusiface_device_port_new(d, sink->core, port, d->next_port_index++);
+        pa_hashmap_put(d->ports, pa_dbusiface_device_port_get_name(p), p);
+    }
+
+    pa_assert_se(pa_dbus_protocol_add_interface(d->dbus_protocol, d->path, &device_interface_info, d) >= 0);
+    pa_assert_se(pa_dbus_protocol_add_interface(d->dbus_protocol, d->path, &sink_interface_info, d) >= 0);
+
+    return d;
+}
+
+pa_dbusiface_device *pa_dbusiface_device_new_source(pa_dbusiface_core *core, pa_source *source) {
+    pa_dbusiface_device *d = NULL;
+    pa_device_port *port;
+    void *state;
+
+    pa_assert(core);
+    pa_assert(source);
+
+    d = pa_xnew0(pa_dbusiface_device, 1);
+    d->core = core;
+    d->source = pa_source_ref(source);
+    d->type = PA_DEVICE_TYPE_SOURCE;
+    d->path = pa_sprintf_malloc("%s/%s%u", PA_DBUS_CORE_OBJECT_PATH, SOURCE_OBJECT_NAME, source->index);
+    d->volume = *pa_source_get_volume(source, FALSE);
+    d->mute = pa_source_get_mute(source, FALSE);
+    d->source_state = pa_source_get_state(source);
+    d->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    d->next_port_index = 0;
+    d->active_port = source->active_port;
+    d->proplist = pa_proplist_copy(source->proplist);
+    d->dbus_protocol = pa_dbus_protocol_get(source->core);
+    d->subscription = pa_subscription_new(source->core, PA_SUBSCRIPTION_MASK_SOURCE, subscription_cb, d);
+
+    PA_HASHMAP_FOREACH(port, source->ports, state) {
+        pa_dbusiface_device_port *p = pa_dbusiface_device_port_new(d, source->core, port, d->next_port_index++);
+        pa_hashmap_put(d->ports, pa_dbusiface_device_port_get_name(p), p);
+    }
+
+    pa_assert_se(pa_dbus_protocol_add_interface(d->dbus_protocol, d->path, &device_interface_info, d) >= 0);
+    pa_assert_se(pa_dbus_protocol_add_interface(d->dbus_protocol, d->path, &source_interface_info, d) >= 0);
+
+    return d;
+}
+
+void pa_dbusiface_device_free(pa_dbusiface_device *d) {
+    pa_assert(d);
+
+    pa_assert_se(pa_dbus_protocol_remove_interface(d->dbus_protocol, d->path, device_interface_info.name) >= 0);
+
+    if (d->type == PA_DEVICE_TYPE_SINK) {
+        pa_assert_se(pa_dbus_protocol_remove_interface(d->dbus_protocol, d->path, sink_interface_info.name) >= 0);
+        pa_sink_unref(d->sink);
+
+    } else {
+        pa_assert_se(pa_dbus_protocol_remove_interface(d->dbus_protocol, d->path, source_interface_info.name) >= 0);
+        pa_source_unref(d->source);
+    }
+    pa_hashmap_free(d->ports, (pa_free_cb_t) pa_dbusiface_device_port_free);
+    pa_proplist_free(d->proplist);
+    pa_dbus_protocol_unref(d->dbus_protocol);
+    pa_subscription_free(d->subscription);
+
+    pa_xfree(d->path);
+    pa_xfree(d);
+}
+
+const char *pa_dbusiface_device_get_path(pa_dbusiface_device *d) {
+    pa_assert(d);
+
+    return d->path;
+}
+
+pa_sink *pa_dbusiface_device_get_sink(pa_dbusiface_device *d) {
+    pa_assert(d);
+    pa_assert(d->type == PA_DEVICE_TYPE_SINK);
+
+    return d->sink;
+}
+
+pa_source *pa_dbusiface_device_get_source(pa_dbusiface_device *d) {
+    pa_assert(d);
+    pa_assert(d->type == PA_DEVICE_TYPE_SOURCE);
+
+    return d->source;
+}
diff --git a/src/modules/dbus/iface-device.h b/src/modules/dbus/iface-device.h
new file mode 100644 (file)
index 0000000..62e05e9
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef foodbusifacedevicehfoo
+#define foodbusifacedevicehfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+/* This object implements the D-Bus interfaces org.PulseAudio.Core1.Device,
+ * org.PulseAudio.Core1.Sink and org.PulseAudio.Core1.Source.
+ *
+ * See http://pulseaudio.org/wiki/DBusInterface for the interface
+ * documentation.
+ */
+
+#include <pulsecore/protocol-dbus.h>
+#include <pulsecore/sink.h>
+#include <pulsecore/source.h>
+
+#include "iface-core.h"
+
+#define PA_DBUSIFACE_DEVICE_INTERFACE PA_DBUS_CORE_INTERFACE ".Device"
+#define PA_DBUSIFACE_SINK_INTERFACE PA_DBUS_CORE_INTERFACE ".Sink"
+#define PA_DBUSIFACE_SOURCE_INTERFACE PA_DBUS_CORE_INTERFACE ".Source"
+
+typedef struct pa_dbusiface_device pa_dbusiface_device;
+
+pa_dbusiface_device *pa_dbusiface_device_new_sink(pa_dbusiface_core *core, pa_sink *sink);
+pa_dbusiface_device *pa_dbusiface_device_new_source(pa_dbusiface_core *core, pa_source *source);
+void pa_dbusiface_device_free(pa_dbusiface_device *d);
+
+const char *pa_dbusiface_device_get_path(pa_dbusiface_device *d);
+
+pa_sink *pa_dbusiface_device_get_sink(pa_dbusiface_device *d);
+pa_source *pa_dbusiface_device_get_source(pa_dbusiface_device *d);
+
+#endif
diff --git a/src/modules/dbus/iface-memstats.c b/src/modules/dbus/iface-memstats.c
new file mode 100644 (file)
index 0000000..4cd692d
--- /dev/null
@@ -0,0 +1,230 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dbus/dbus.h>
+
+#include <pulsecore/core-scache.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-util.h>
+#include <pulsecore/protocol-dbus.h>
+
+#include "iface-memstats.h"
+
+#define OBJECT_NAME "memstats"
+
+static void handle_get_current_memblocks(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_current_memblocks_size(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_accumulated_memblocks(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_accumulated_memblocks_size(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_sample_cache_size(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+struct pa_dbusiface_memstats {
+    pa_core *core;
+    char *path;
+    pa_dbus_protocol *dbus_protocol;
+};
+
+enum property_handler_index {
+    PROPERTY_HANDLER_CURRENT_MEMBLOCKS,
+    PROPERTY_HANDLER_CURRENT_MEMBLOCKS_SIZE,
+    PROPERTY_HANDLER_ACCUMULATED_MEMBLOCKS,
+    PROPERTY_HANDLER_ACCUMULATED_MEMBLOCKS_SIZE,
+    PROPERTY_HANDLER_SAMPLE_CACHE_SIZE,
+    PROPERTY_HANDLER_MAX
+};
+
+static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = {
+    [PROPERTY_HANDLER_CURRENT_MEMBLOCKS]          = { .property_name = "CurrentMemblocks",         .type = "u", .get_cb = handle_get_current_memblocks,          .set_cb = NULL },
+    [PROPERTY_HANDLER_CURRENT_MEMBLOCKS_SIZE]     = { .property_name = "CurrentMemblocksSize",     .type = "u", .get_cb = handle_get_current_memblocks_size,     .set_cb = NULL },
+    [PROPERTY_HANDLER_ACCUMULATED_MEMBLOCKS]      = { .property_name = "AccumulatedMemblocks",     .type = "u", .get_cb = handle_get_accumulated_memblocks,      .set_cb = NULL },
+    [PROPERTY_HANDLER_ACCUMULATED_MEMBLOCKS_SIZE] = { .property_name = "AccumulatedMemblocksSize", .type = "u", .get_cb = handle_get_accumulated_memblocks_size, .set_cb = NULL },
+    [PROPERTY_HANDLER_SAMPLE_CACHE_SIZE]          = { .property_name = "SampleCacheSize",          .type = "u", .get_cb = handle_get_sample_cache_size,          .set_cb = NULL }
+};
+
+static pa_dbus_interface_info memstats_interface_info = {
+    .name = PA_DBUSIFACE_MEMSTATS_INTERFACE,
+    .method_handlers = NULL,
+    .n_method_handlers = 0,
+    .property_handlers = property_handlers,
+    .n_property_handlers = PROPERTY_HANDLER_MAX,
+    .get_all_properties_cb = handle_get_all,
+    .signals = NULL,
+    .n_signals = 0
+};
+
+static void handle_get_current_memblocks(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_memstats *m = userdata;
+    const pa_mempool_stat *stat;
+    dbus_uint32_t current_memblocks;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    stat = pa_mempool_get_stat(m->core->mempool);
+
+    current_memblocks = pa_atomic_load(&stat->n_allocated);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &current_memblocks);
+}
+
+static void handle_get_current_memblocks_size(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_memstats *m = userdata;
+    const pa_mempool_stat *stat;
+    dbus_uint32_t current_memblocks_size;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    stat = pa_mempool_get_stat(m->core->mempool);
+
+    current_memblocks_size = pa_atomic_load(&stat->allocated_size);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &current_memblocks_size);
+}
+
+static void handle_get_accumulated_memblocks(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_memstats *m = userdata;
+    const pa_mempool_stat *stat;
+    dbus_uint32_t accumulated_memblocks;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    stat = pa_mempool_get_stat(m->core->mempool);
+
+    accumulated_memblocks = pa_atomic_load(&stat->n_accumulated);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &accumulated_memblocks);
+}
+
+static void handle_get_accumulated_memblocks_size(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_memstats *m = userdata;
+    const pa_mempool_stat *stat;
+    dbus_uint32_t accumulated_memblocks_size;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    stat = pa_mempool_get_stat(m->core->mempool);
+
+    accumulated_memblocks_size = pa_atomic_load(&stat->accumulated_size);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &accumulated_memblocks_size);
+}
+
+static void handle_get_sample_cache_size(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_memstats *m = userdata;
+    dbus_uint32_t sample_cache_size;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    sample_cache_size = pa_scache_total_size(m->core);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &sample_cache_size);
+}
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_memstats *m = userdata;
+    const pa_mempool_stat *stat;
+    dbus_uint32_t current_memblocks;
+    dbus_uint32_t current_memblocks_size;
+    dbus_uint32_t accumulated_memblocks;
+    dbus_uint32_t accumulated_memblocks_size;
+    dbus_uint32_t sample_cache_size;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+    DBusMessageIter dict_iter;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    stat = pa_mempool_get_stat(m->core->mempool);
+
+    current_memblocks = pa_atomic_load(&stat->n_allocated);
+    current_memblocks_size = pa_atomic_load(&stat->allocated_size);
+    accumulated_memblocks = pa_atomic_load(&stat->n_accumulated);
+    accumulated_memblocks_size = pa_atomic_load(&stat->accumulated_size);
+    sample_cache_size = pa_scache_total_size(m->core);
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CURRENT_MEMBLOCKS].property_name, DBUS_TYPE_UINT32, &current_memblocks);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CURRENT_MEMBLOCKS_SIZE].property_name, DBUS_TYPE_UINT32, &current_memblocks_size);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_ACCUMULATED_MEMBLOCKS].property_name, DBUS_TYPE_UINT32, &accumulated_memblocks);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_ACCUMULATED_MEMBLOCKS_SIZE].property_name, DBUS_TYPE_UINT32, &accumulated_memblocks_size);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SAMPLE_CACHE_SIZE].property_name, DBUS_TYPE_UINT32, &sample_cache_size);
+
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+
+    dbus_message_unref(reply);
+}
+
+pa_dbusiface_memstats *pa_dbusiface_memstats_new(pa_dbusiface_core *dbus_core, pa_core *core) {
+    pa_dbusiface_memstats *m;
+
+    pa_assert(dbus_core);
+    pa_assert(core);
+
+    m = pa_xnew(pa_dbusiface_memstats, 1);
+    m->core = core;
+    m->path = pa_sprintf_malloc("%s/%s", PA_DBUS_CORE_OBJECT_PATH, OBJECT_NAME);
+    m->dbus_protocol = pa_dbus_protocol_get(core);
+
+    pa_assert_se(pa_dbus_protocol_add_interface(m->dbus_protocol, m->path, &memstats_interface_info, m) >= 0);
+
+    return m;
+}
+
+void pa_dbusiface_memstats_free(pa_dbusiface_memstats *m) {
+    pa_assert(m);
+
+    pa_assert_se(pa_dbus_protocol_remove_interface(m->dbus_protocol, m->path, memstats_interface_info.name) >= 0);
+
+    pa_xfree(m->path);
+
+    pa_dbus_protocol_unref(m->dbus_protocol);
+
+    pa_xfree(m);
+}
+
+const char *pa_dbusiface_memstats_get_path(pa_dbusiface_memstats *m) {
+    pa_assert(m);
+
+    return m->path;
+}
diff --git a/src/modules/dbus/iface-memstats.h b/src/modules/dbus/iface-memstats.h
new file mode 100644 (file)
index 0000000..0820e8f
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef foodbusifacememstatshfoo
+#define foodbusifacememstatshfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+/* This object implements the D-Bus interface org.PulseAudio.Core1.Memstats.
+ *
+ * See http://pulseaudio.org/wiki/DBusInterface for the Memstats interface
+ * documentation.
+ */
+
+#include <pulsecore/core.h>
+#include <pulsecore/protocol-dbus.h>
+
+#include "iface-core.h"
+
+#define PA_DBUSIFACE_MEMSTATS_INTERFACE PA_DBUS_CORE_INTERFACE ".Memstats"
+
+typedef struct pa_dbusiface_memstats pa_dbusiface_memstats;
+
+pa_dbusiface_memstats *pa_dbusiface_memstats_new(pa_dbusiface_core *dbus_core, pa_core *core);
+void pa_dbusiface_memstats_free(pa_dbusiface_memstats *m);
+
+const char *pa_dbusiface_memstats_get_path(pa_dbusiface_memstats *m);
+
+#endif
diff --git a/src/modules/dbus/iface-module.c b/src/modules/dbus/iface-module.c
new file mode 100644 (file)
index 0000000..9973166
--- /dev/null
@@ -0,0 +1,336 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-util.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/protocol-dbus.h>
+
+#include "iface-module.h"
+
+#define OBJECT_NAME "module"
+
+struct pa_dbusiface_module {
+    pa_module *module;
+    char *path;
+    pa_proplist *proplist;
+
+    pa_dbus_protocol *dbus_protocol;
+    pa_subscription *subscription;
+};
+
+static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_arguments(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_usage_counter(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_property_list(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_unload(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+enum property_handler_index {
+    PROPERTY_HANDLER_INDEX,
+    PROPERTY_HANDLER_NAME,
+    PROPERTY_HANDLER_ARGUMENTS,
+    PROPERTY_HANDLER_USAGE_COUNTER,
+    PROPERTY_HANDLER_PROPERTY_LIST,
+    PROPERTY_HANDLER_MAX
+};
+
+static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = {
+    [PROPERTY_HANDLER_INDEX]         = { .property_name = "Index",        .type = "u",      .get_cb = handle_get_index,         .set_cb = NULL },
+    [PROPERTY_HANDLER_NAME]          = { .property_name = "Name",         .type = "s",      .get_cb = handle_get_name,          .set_cb = NULL },
+    [PROPERTY_HANDLER_ARGUMENTS]     = { .property_name = "Arguments",    .type = "a{ss}",  .get_cb = handle_get_arguments,     .set_cb = NULL },
+    [PROPERTY_HANDLER_USAGE_COUNTER] = { .property_name = "UsageCounter", .type = "u",      .get_cb = handle_get_usage_counter, .set_cb = NULL },
+    [PROPERTY_HANDLER_PROPERTY_LIST] = { .property_name = "PropertyList", .type = "a{say}", .get_cb = handle_get_property_list, .set_cb = NULL }
+};
+
+enum method_handler_index {
+    METHOD_HANDLER_UNLOAD,
+    METHOD_HANDLER_MAX
+};
+
+static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
+    [METHOD_HANDLER_UNLOAD] = {
+        .method_name = "Unload",
+        .arguments = NULL,
+        .n_arguments = 0,
+        .receive_cb = handle_unload }
+};
+
+enum signal_index {
+    SIGNAL_PROPERTY_LIST_UPDATED,
+    SIGNAL_MAX
+};
+
+static pa_dbus_arg_info property_list_updated_args[] =  { { "property_list", "a{say}", NULL } };
+
+static pa_dbus_signal_info signals[SIGNAL_MAX] = {
+    [SIGNAL_PROPERTY_LIST_UPDATED] = { .name = "PropertyListUpdated", .arguments = property_list_updated_args, .n_arguments = 1 }
+};
+
+static pa_dbus_interface_info module_interface_info = {
+    .name = PA_DBUSIFACE_MODULE_INTERFACE,
+    .method_handlers = method_handlers,
+    .n_method_handlers = METHOD_HANDLER_MAX,
+    .property_handlers = property_handlers,
+    .n_property_handlers = PROPERTY_HANDLER_MAX,
+    .get_all_properties_cb = handle_get_all,
+    .signals = signals,
+    .n_signals = SIGNAL_MAX
+};
+
+static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_module *m = userdata;
+    dbus_uint32_t idx = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    idx = m->module->index;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &idx);
+}
+
+static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_module *m = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &m->module->name);
+}
+
+static void append_modargs_variant(DBusMessageIter *iter, pa_dbusiface_module *m) {
+    pa_modargs *ma = NULL;
+    DBusMessageIter variant_iter;
+    DBusMessageIter dict_iter;
+    DBusMessageIter dict_entry_iter;
+    void *state = NULL;
+    const char *key = NULL;
+    const char *value = NULL;
+
+    pa_assert(iter);
+    pa_assert(m);
+
+    pa_assert_se(ma = pa_modargs_new(m->module->argument, NULL));
+
+    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a{ss}", &variant_iter));
+    pa_assert_se(dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY, "{ss}", &dict_iter));
+
+    for (state = NULL, key = pa_modargs_iterate(ma, &state); key; key = pa_modargs_iterate(ma, &state)) {
+        pa_assert_se(value = pa_modargs_get_value(ma, key, NULL));
+
+        pa_assert_se(dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter));
+
+        pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &key));
+        pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &value));
+
+        pa_assert_se(dbus_message_iter_close_container(&dict_iter, &dict_entry_iter));
+    }
+
+    pa_assert_se(dbus_message_iter_close_container(&variant_iter, &dict_iter));
+    pa_assert_se(dbus_message_iter_close_container(iter, &variant_iter));
+
+    pa_modargs_free(ma);
+}
+
+static void handle_get_arguments(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_module *m = userdata;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    pa_assert_se(reply = dbus_message_new_method_return(msg));
+    dbus_message_iter_init_append(reply, &msg_iter);
+    append_modargs_variant(&msg_iter, m);
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+}
+
+static void handle_get_usage_counter(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_module *m = userdata;
+    int real_counter_value = -1;
+    dbus_uint32_t usage_counter = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    if (!m->module->get_n_used || (real_counter_value = m->module->get_n_used(m->module)) < 0) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                           "Module %u (%s) doesn't have a usage counter.", m->module->index, m->module->name);
+        return;
+    }
+
+    usage_counter = real_counter_value;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &usage_counter);
+}
+
+static void handle_get_property_list(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_module *m = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    pa_dbus_send_proplist_variant_reply(conn, msg, m->proplist);
+}
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_module *m = userdata;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+    DBusMessageIter dict_iter;
+    DBusMessageIter dict_entry_iter;
+    dbus_uint32_t idx = 0;
+    int real_counter_value = -1;
+    dbus_uint32_t usage_counter = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    idx = m->module->index;
+    if (m->module->get_n_used && (real_counter_value = m->module->get_n_used(m->module)) >= 0)
+        usage_counter = real_counter_value;
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_INDEX].property_name, DBUS_TYPE_UINT32, &idx);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_NAME].property_name, DBUS_TYPE_STRING, &m->module->name);
+
+    pa_assert_se(dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter));
+    pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &property_handlers[PROPERTY_HANDLER_ARGUMENTS].property_name));
+    append_modargs_variant(&dict_entry_iter, m);
+    pa_assert_se(dbus_message_iter_close_container(&dict_iter, &dict_entry_iter));
+
+    if (real_counter_value >= 0)
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_ARGUMENTS].property_name, DBUS_TYPE_UINT32, &usage_counter);
+
+    pa_dbus_append_proplist_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PROPERTY_LIST].property_name, m->proplist);
+
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+
+    dbus_message_unref(reply);
+}
+
+static void handle_unload(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_module *m = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    if (m->module->core->disallow_module_loading) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_ACCESS_DENIED, "The server is configured to disallow module unloading.");
+        return;
+    }
+
+    pa_module_unload_request(m->module, FALSE);
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
+    pa_dbusiface_module *m = userdata;
+    DBusMessage *signal_msg = NULL;
+
+    pa_assert(core);
+    pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_MODULE);
+    pa_assert(m);
+
+    /* We can't use idx != m->module->index, because the m->module pointer may
+     * be stale at this point. */
+    if (pa_idxset_get_by_index(core->modules, idx) != m->module)
+        return;
+
+    if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) != PA_SUBSCRIPTION_EVENT_CHANGE)
+        return;
+
+    if (!pa_proplist_equal(m->proplist, m->module->proplist)) {
+        DBusMessageIter msg_iter;
+
+        pa_proplist_update(m->proplist, PA_UPDATE_SET, m->module->proplist);
+
+        pa_assert_se(signal_msg = dbus_message_new_signal(m->path,
+                                                         PA_DBUSIFACE_MODULE_INTERFACE,
+                                                         signals[SIGNAL_PROPERTY_LIST_UPDATED].name));
+        dbus_message_iter_init_append(signal_msg, &msg_iter);
+        pa_dbus_append_proplist(&msg_iter, m->proplist);
+
+        pa_dbus_protocol_send_signal(m->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
+    }
+}
+
+pa_dbusiface_module *pa_dbusiface_module_new(pa_module *module) {
+    pa_dbusiface_module *m;
+
+    pa_assert(module);
+
+    m = pa_xnew0(pa_dbusiface_module, 1);
+    m->module = module;
+    m->path = pa_sprintf_malloc("%s/%s%u", PA_DBUS_CORE_OBJECT_PATH, OBJECT_NAME, module->index);
+    m->proplist = pa_proplist_copy(module->proplist);
+    m->dbus_protocol = pa_dbus_protocol_get(module->core);
+    m->subscription = pa_subscription_new(module->core, PA_SUBSCRIPTION_MASK_MODULE, subscription_cb, m);
+
+    pa_assert_se(pa_dbus_protocol_add_interface(m->dbus_protocol, m->path, &module_interface_info, m) >= 0);
+
+    return m;
+}
+
+void pa_dbusiface_module_free(pa_dbusiface_module *m) {
+    pa_assert(m);
+
+    pa_assert_se(pa_dbus_protocol_remove_interface(m->dbus_protocol, m->path, module_interface_info.name) >= 0);
+
+    pa_proplist_free(m->proplist);
+    pa_dbus_protocol_unref(m->dbus_protocol);
+    pa_subscription_free(m->subscription);
+
+    pa_xfree(m->path);
+    pa_xfree(m);
+}
+
+const char *pa_dbusiface_module_get_path(pa_dbusiface_module *m) {
+    pa_assert(m);
+
+    return m->path;
+}
diff --git a/src/modules/dbus/iface-module.h b/src/modules/dbus/iface-module.h
new file mode 100644 (file)
index 0000000..68ca1de
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef foodbusifacemodulehfoo
+#define foodbusifacemodulehfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+/* This object implements the D-Bus interface org.PulseAudio.Core1.Module.
+ *
+ * See http://pulseaudio.org/wiki/DBusInterface for the Module interface
+ * documentation.
+ */
+
+#include <pulsecore/module.h>
+#include <pulsecore/protocol-dbus.h>
+
+#include "iface-core.h"
+
+#define PA_DBUSIFACE_MODULE_INTERFACE PA_DBUS_CORE_INTERFACE ".Module"
+
+typedef struct pa_dbusiface_module pa_dbusiface_module;
+
+pa_dbusiface_module *pa_dbusiface_module_new(pa_module *module);
+void pa_dbusiface_module_free(pa_dbusiface_module *m);
+
+const char *pa_dbusiface_module_get_path(pa_dbusiface_module *m);
+
+#endif
diff --git a/src/modules/dbus/iface-sample.c b/src/modules/dbus/iface-sample.c
new file mode 100644 (file)
index 0000000..93d4fc8
--- /dev/null
@@ -0,0 +1,519 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-util.h>
+#include <pulsecore/namereg.h>
+#include <pulsecore/protocol-dbus.h>
+
+#include "iface-sample.h"
+
+#define OBJECT_NAME "sample"
+
+struct pa_dbusiface_sample {
+    pa_dbusiface_core *core;
+
+    pa_scache_entry *sample;
+    char *path;
+    pa_proplist *proplist;
+
+    pa_dbus_protocol *dbus_protocol;
+    pa_subscription *subscription;
+};
+
+static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_channels(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_default_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_duration(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_bytes(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_property_list(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_play(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_play_to_sink(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_remove(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+enum property_handler_index {
+    PROPERTY_HANDLER_INDEX,
+    PROPERTY_HANDLER_NAME,
+    PROPERTY_HANDLER_SAMPLE_FORMAT,
+    PROPERTY_HANDLER_SAMPLE_RATE,
+    PROPERTY_HANDLER_CHANNELS,
+    PROPERTY_HANDLER_DEFAULT_VOLUME,
+    PROPERTY_HANDLER_DURATION,
+    PROPERTY_HANDLER_BYTES,
+    PROPERTY_HANDLER_PROPERTY_LIST,
+    PROPERTY_HANDLER_MAX
+};
+
+static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = {
+    [PROPERTY_HANDLER_INDEX]          = { .property_name = "Index",         .type = "u",      .get_cb = handle_get_index,          .set_cb = NULL },
+    [PROPERTY_HANDLER_NAME]           = { .property_name = "Name",          .type = "s",      .get_cb = handle_get_name,           .set_cb = NULL },
+    [PROPERTY_HANDLER_SAMPLE_FORMAT]  = { .property_name = "SampleFormat",  .type = "u",      .get_cb = handle_get_sample_format,  .set_cb = NULL },
+    [PROPERTY_HANDLER_SAMPLE_RATE]    = { .property_name = "SampleRate",    .type = "u",      .get_cb = handle_get_sample_rate,    .set_cb = NULL },
+    [PROPERTY_HANDLER_CHANNELS]       = { .property_name = "Channels",      .type = "au",     .get_cb = handle_get_channels,       .set_cb = NULL },
+    [PROPERTY_HANDLER_DEFAULT_VOLUME] = { .property_name = "DefaultVolume", .type = "au",     .get_cb = handle_get_default_volume, .set_cb = NULL },
+    [PROPERTY_HANDLER_DURATION]       = { .property_name = "Duration",      .type = "t",      .get_cb = handle_get_duration,       .set_cb = NULL },
+    [PROPERTY_HANDLER_BYTES]          = { .property_name = "Bytes",         .type = "u",      .get_cb = handle_get_bytes,          .set_cb = NULL },
+    [PROPERTY_HANDLER_PROPERTY_LIST]  = { .property_name = "PropertyList",  .type = "a{say}", .get_cb = handle_get_property_list,  .set_cb = NULL }
+};
+
+enum method_handler_index {
+    METHOD_HANDLER_PLAY,
+    METHOD_HANDLER_PLAY_TO_SINK,
+    METHOD_HANDLER_REMOVE,
+    METHOD_HANDLER_MAX
+};
+
+static pa_dbus_arg_info play_args[] = { { "volume", "u", "in" }, { "property_list", "a{say}", "in" } };
+static pa_dbus_arg_info play_to_sink_args[] = { { "sink",          "o",      "in" },
+                                                { "volume",        "u",      "in" },
+                                                { "property_list", "a{say}", "in" } };
+
+static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
+    [METHOD_HANDLER_PLAY] = {
+        .method_name = "Play",
+        .arguments = play_args,
+        .n_arguments = sizeof(play_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_play },
+    [METHOD_HANDLER_PLAY_TO_SINK] = {
+        .method_name = "PlayToSink",
+        .arguments = play_to_sink_args,
+        .n_arguments = sizeof(play_to_sink_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_play_to_sink },
+    [METHOD_HANDLER_REMOVE] = {
+        .method_name = "Remove",
+        .arguments = NULL,
+        .n_arguments = 0,
+        .receive_cb = handle_remove }
+};
+
+enum signal_index {
+    SIGNAL_PROPERTY_LIST_UPDATED,
+    SIGNAL_MAX
+};
+
+static pa_dbus_arg_info property_list_updated_args[] = { { "property_list", "a{say}", NULL } };
+
+static pa_dbus_signal_info signals[SIGNAL_MAX] = {
+    [SIGNAL_PROPERTY_LIST_UPDATED] = { .name = "PropertyListUpdated", .arguments = property_list_updated_args, .n_arguments = 1 }
+};
+
+static pa_dbus_interface_info sample_interface_info = {
+    .name = PA_DBUSIFACE_SAMPLE_INTERFACE,
+    .method_handlers = method_handlers,
+    .n_method_handlers = METHOD_HANDLER_MAX,
+    .property_handlers = property_handlers,
+    .n_property_handlers = PROPERTY_HANDLER_MAX,
+    .get_all_properties_cb = handle_get_all,
+    .signals = signals,
+    .n_signals = SIGNAL_MAX
+};
+
+static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_sample *s = userdata;
+    dbus_uint32_t idx = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    idx = s->sample->index;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &idx);
+}
+
+static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_sample *s = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &s->sample->name);
+}
+
+static void handle_get_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_sample *s = userdata;
+    dbus_uint32_t sample_format = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    if (!s->sample->memchunk.memblock) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                           "Sample %s isn't loaded into memory yet, so its sample format is unknown.", s->sample->name);
+        return;
+    }
+
+    sample_format = s->sample->sample_spec.format;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &sample_format);
+}
+
+static void handle_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_sample *s = userdata;
+    dbus_uint32_t sample_rate = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    if (!s->sample->memchunk.memblock) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                           "Sample %s isn't loaded into memory yet, so its sample rate is unknown.", s->sample->name);
+        return;
+    }
+
+    sample_rate = s->sample->sample_spec.rate;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &sample_rate);
+}
+
+static void handle_get_channels(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_sample *s = userdata;
+    dbus_uint32_t channels[PA_CHANNELS_MAX];
+    unsigned i = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    if (!s->sample->memchunk.memblock) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                           "Sample %s isn't loaded into memory yet, so its channel map is unknown.", s->sample->name);
+        return;
+    }
+
+    for (i = 0; i < s->sample->channel_map.channels; ++i)
+        channels[i] = s->sample->channel_map.map[i];
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_UINT32, channels, s->sample->channel_map.channels);
+}
+
+static void handle_get_default_volume(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_sample *s = userdata;
+    dbus_uint32_t default_volume[PA_CHANNELS_MAX];
+    unsigned i = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    if (!s->sample->volume_is_set) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                           "Sample %s doesn't have default volume stored.", s->sample->name);
+        return;
+    }
+
+    for (i = 0; i < s->sample->volume.channels; ++i)
+        default_volume[i] = s->sample->volume.values[i];
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_UINT32, default_volume, s->sample->volume.channels);
+}
+
+static void handle_get_duration(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_sample *s = userdata;
+    dbus_uint64_t duration = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    if (!s->sample->memchunk.memblock) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                           "Sample %s isn't loaded into memory yet, so its duration is unknown.", s->sample->name);
+        return;
+    }
+
+    duration = pa_bytes_to_usec(s->sample->memchunk.length, &s->sample->sample_spec);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT64, &duration);
+}
+
+static void handle_get_bytes(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_sample *s = userdata;
+    dbus_uint32_t bytes = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    if (!s->sample->memchunk.memblock) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY,
+                           "Sample %s isn't loaded into memory yet, so its size is unknown.", s->sample->name);
+        return;
+    }
+
+    bytes = s->sample->memchunk.length;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &bytes);
+}
+
+static void handle_get_property_list(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_sample *s = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    pa_dbus_send_proplist_variant_reply(conn, msg, s->proplist);
+}
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_sample *s = userdata;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+    DBusMessageIter dict_iter;
+    dbus_uint32_t idx = 0;
+    dbus_uint32_t sample_format = 0;
+    dbus_uint32_t sample_rate = 0;
+    dbus_uint32_t channels[PA_CHANNELS_MAX];
+    dbus_uint32_t default_volume[PA_CHANNELS_MAX];
+    dbus_uint64_t duration = 0;
+    dbus_uint32_t bytes = 0;
+    unsigned i = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    idx = s->sample->index;
+    if (s->sample->memchunk.memblock) {
+        sample_format = s->sample->sample_spec.format;
+        sample_rate = s->sample->sample_spec.rate;
+        for (i = 0; i < s->sample->channel_map.channels; ++i)
+            channels[i] = s->sample->channel_map.map[i];
+        duration = pa_bytes_to_usec(s->sample->memchunk.length, &s->sample->sample_spec);
+        bytes = s->sample->memchunk.length;
+    }
+    if (s->sample->volume_is_set) {
+        for (i = 0; i < s->sample->volume.channels; ++i)
+            default_volume[i] = s->sample->volume.values[i];
+    }
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_INDEX].property_name, DBUS_TYPE_UINT32, &idx);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_NAME].property_name, DBUS_TYPE_STRING, &s->sample->name);
+
+    if (s->sample->memchunk.memblock) {
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SAMPLE_FORMAT].property_name, DBUS_TYPE_UINT32, &sample_format);
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SAMPLE_RATE].property_name, DBUS_TYPE_UINT32, &sample_rate);
+        pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CHANNELS].property_name, DBUS_TYPE_UINT32, channels, s->sample->channel_map.channels);
+    }
+
+    if (s->sample->volume_is_set)
+        pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DEFAULT_VOLUME].property_name, DBUS_TYPE_UINT32, default_volume, s->sample->volume.channels);
+
+    if (s->sample->memchunk.memblock) {
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DURATION].property_name, DBUS_TYPE_UINT64, &duration);
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_BYTES].property_name, DBUS_TYPE_UINT32, &bytes);
+    }
+
+    pa_dbus_append_proplist_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PROPERTY_LIST].property_name, s->proplist);
+
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+}
+
+static void handle_play(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_sample *s = userdata;
+    DBusMessageIter msg_iter;
+    dbus_uint32_t volume = 0;
+    pa_proplist *property_list = NULL;
+    pa_sink *sink = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    pa_assert_se(dbus_message_iter_init(msg, &msg_iter));
+    dbus_message_iter_get_basic(&msg_iter, &volume);
+
+    pa_assert_se(dbus_message_iter_next(&msg_iter));
+    if (!(property_list = pa_dbus_get_proplist_arg(conn, msg, &msg_iter)))
+        return;
+
+    if (!PA_VOLUME_IS_VALID(volume)) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid volume.");
+        goto finish;
+    }
+
+    if (!(sink = pa_namereg_get_default_sink(s->sample->core))) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED,
+                           "Can't play sample %s, because there are no sinks available.", s->sample->name);
+        goto finish;
+    }
+
+    if (pa_scache_play_item(s->sample->core, s->sample->name, sink, volume, property_list, NULL) < 0) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Playing sample %s failed.", s->sample->name);
+        goto finish;
+    }
+
+    pa_dbus_send_empty_reply(conn, msg);
+
+finish:
+    if (property_list)
+        pa_proplist_free(property_list);
+}
+
+static void handle_play_to_sink(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_sample *s = userdata;
+    DBusMessageIter msg_iter;
+    const char *sink_path = NULL;
+    dbus_uint32_t volume = 0;
+    pa_proplist *property_list = NULL;
+    pa_sink *sink = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    pa_assert_se(dbus_message_iter_init(msg, &msg_iter));
+    dbus_message_iter_get_basic(&msg_iter, &sink_path);
+
+    pa_assert_se(dbus_message_iter_next(&msg_iter));
+    dbus_message_iter_get_basic(&msg_iter, &volume);
+
+    pa_assert_se(dbus_message_iter_next(&msg_iter));
+    if (!(property_list = pa_dbus_get_proplist_arg(conn, msg, &msg_iter)))
+        return;
+
+    if (!(sink = pa_dbusiface_core_get_sink(s->core, sink_path))) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such sink.", sink_path);
+        goto finish;
+    }
+
+    if (!PA_VOLUME_IS_VALID(volume)) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid volume.");
+        goto finish;
+    }
+
+    if (pa_scache_play_item(s->sample->core, s->sample->name, sink, volume, property_list, NULL) < 0) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Playing sample %s failed.", s->sample->name);
+        goto finish;
+    }
+
+    pa_dbus_send_empty_reply(conn, msg);
+
+finish:
+    if (property_list)
+        pa_proplist_free(property_list);
+}
+
+static void handle_remove(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_sample *s = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    if (pa_scache_remove_item(s->sample->core, s->sample->name) < 0) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Removing sample %s failed.", s->sample->name);
+        return;
+    }
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
+    pa_dbusiface_sample *s = userdata;
+    DBusMessage *signal_msg = NULL;
+
+    pa_assert(c);
+    pa_assert(s);
+
+    /* We can't use idx != s->sample->index, because the s->sample pointer may
+     * be stale at this point. */
+    if (pa_idxset_get_by_index(c->scache, idx) != s->sample)
+        return;
+
+    if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) != PA_SUBSCRIPTION_EVENT_CHANGE)
+        return;
+
+    if (!pa_proplist_equal(s->proplist, s->sample->proplist)) {
+        DBusMessageIter msg_iter;
+
+        pa_proplist_update(s->proplist, PA_UPDATE_SET, s->sample->proplist);
+
+        pa_assert_se(signal_msg = dbus_message_new_signal(s->path,
+                                                         PA_DBUSIFACE_SAMPLE_INTERFACE,
+                                                         signals[SIGNAL_PROPERTY_LIST_UPDATED].name));
+        dbus_message_iter_init_append(signal_msg, &msg_iter);
+        pa_dbus_append_proplist(&msg_iter, s->proplist);
+
+        pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
+    }
+}
+
+pa_dbusiface_sample *pa_dbusiface_sample_new(pa_dbusiface_core *core, pa_scache_entry *sample) {
+    pa_dbusiface_sample *s = NULL;
+
+    pa_assert(core);
+    pa_assert(sample);
+
+    s = pa_xnew0(pa_dbusiface_sample, 1);
+    s->core = core;
+    s->sample = sample;
+    s->path = pa_sprintf_malloc("%s/%s%u", PA_DBUS_CORE_OBJECT_PATH, OBJECT_NAME, sample->index);
+    s->proplist = pa_proplist_copy(sample->proplist);
+    s->dbus_protocol = pa_dbus_protocol_get(sample->core);
+    s->subscription = pa_subscription_new(sample->core, PA_SUBSCRIPTION_MASK_SAMPLE_CACHE, subscription_cb, s);
+
+    pa_assert_se(pa_dbus_protocol_add_interface(s->dbus_protocol, s->path, &sample_interface_info, s) >= 0);
+
+    return s;
+}
+
+void pa_dbusiface_sample_free(pa_dbusiface_sample *s) {
+    pa_assert(s);
+
+    pa_assert_se(pa_dbus_protocol_remove_interface(s->dbus_protocol, s->path, sample_interface_info.name) >= 0);
+
+    pa_proplist_free(s->proplist);
+    pa_dbus_protocol_unref(s->dbus_protocol);
+    pa_subscription_free(s->subscription);
+
+    pa_xfree(s->path);
+    pa_xfree(s);
+}
+
+const char *pa_dbusiface_sample_get_path(pa_dbusiface_sample *s) {
+    pa_assert(s);
+
+    return s->path;
+}
diff --git a/src/modules/dbus/iface-sample.h b/src/modules/dbus/iface-sample.h
new file mode 100644 (file)
index 0000000..f1947ce
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef foodbusifacesamplehfoo
+#define foodbusifacesamplehfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+/* This object implements the D-Bus interface org.PulseAudio.Core1.Sample.
+ *
+ * See http://pulseaudio.org/wiki/DBusInterface for the Sample interface
+ * documentation.
+ */
+
+#include <pulsecore/core-scache.h>
+#include <pulsecore/protocol-dbus.h>
+
+#include "iface-core.h"
+
+#define PA_DBUSIFACE_SAMPLE_INTERFACE PA_DBUS_CORE_INTERFACE ".Sample"
+
+typedef struct pa_dbusiface_sample pa_dbusiface_sample;
+
+pa_dbusiface_sample *pa_dbusiface_sample_new(pa_dbusiface_core *core, pa_scache_entry *sample);
+void pa_dbusiface_sample_free(pa_dbusiface_sample *c);
+
+const char *pa_dbusiface_sample_get_path(pa_dbusiface_sample *c);
+
+#endif
diff --git a/src/modules/dbus/iface-stream.c b/src/modules/dbus/iface-stream.c
new file mode 100644 (file)
index 0000000..c6dc1c9
--- /dev/null
@@ -0,0 +1,933 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+  Copyright 2009 Vincent Filali-Ansary <filali.v@azurdigitalnetworks.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-util.h>
+#include <pulsecore/protocol-dbus.h>
+
+#include "iface-stream.h"
+
+#define PLAYBACK_OBJECT_NAME "playback_stream"
+#define RECORD_OBJECT_NAME "record_stream"
+
+enum stream_type {
+    STREAM_TYPE_PLAYBACK,
+    STREAM_TYPE_RECORD
+};
+
+struct pa_dbusiface_stream {
+    pa_dbusiface_core *core;
+
+    union {
+        pa_sink_input *sink_input;
+        pa_source_output *source_output;
+    };
+    enum stream_type type;
+    char *path;
+    union {
+        pa_sink *sink;
+        pa_source *source;
+    };
+    uint32_t sample_rate;
+    pa_cvolume volume;
+    dbus_bool_t mute;
+    pa_proplist *proplist;
+
+    pa_bool_t has_volume;
+
+    pa_dbus_protocol *dbus_protocol;
+    pa_subscription *subscription;
+    pa_hook_slot *send_event_slot;
+};
+
+static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_driver(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_owner_module(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_client(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_device(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_channels(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_volume(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+static void handle_get_mute(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_mute(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+static void handle_get_buffer_latency(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_device_latency(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_resample_method(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_property_list(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_move(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_kill(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+enum property_handler_index {
+    PROPERTY_HANDLER_INDEX,
+    PROPERTY_HANDLER_DRIVER,
+    PROPERTY_HANDLER_OWNER_MODULE,
+    PROPERTY_HANDLER_CLIENT,
+    PROPERTY_HANDLER_DEVICE,
+    PROPERTY_HANDLER_SAMPLE_FORMAT,
+    PROPERTY_HANDLER_SAMPLE_RATE,
+    PROPERTY_HANDLER_CHANNELS,
+    PROPERTY_HANDLER_VOLUME,
+    PROPERTY_HANDLER_MUTE,
+    PROPERTY_HANDLER_BUFFER_LATENCY,
+    PROPERTY_HANDLER_DEVICE_LATENCY,
+    PROPERTY_HANDLER_RESAMPLE_METHOD,
+    PROPERTY_HANDLER_PROPERTY_LIST,
+    PROPERTY_HANDLER_MAX
+};
+
+static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = {
+    [PROPERTY_HANDLER_INDEX]           = { .property_name = "Index",          .type = "u",      .get_cb = handle_get_index,           .set_cb = NULL },
+    [PROPERTY_HANDLER_DRIVER]          = { .property_name = "Driver",         .type = "s",      .get_cb = handle_get_driver,          .set_cb = NULL },
+    [PROPERTY_HANDLER_OWNER_MODULE]    = { .property_name = "OwnerModule",    .type = "o",      .get_cb = handle_get_owner_module,    .set_cb = NULL },
+    [PROPERTY_HANDLER_CLIENT]          = { .property_name = "Client",         .type = "o",      .get_cb = handle_get_client,          .set_cb = NULL },
+    [PROPERTY_HANDLER_DEVICE]          = { .property_name = "Device",         .type = "o",      .get_cb = handle_get_device,          .set_cb = NULL },
+    [PROPERTY_HANDLER_SAMPLE_FORMAT]   = { .property_name = "SampleFormat",   .type = "u",      .get_cb = handle_get_sample_format,   .set_cb = NULL },
+    [PROPERTY_HANDLER_SAMPLE_RATE]     = { .property_name = "SampleRate",     .type = "u",      .get_cb = handle_get_sample_rate,     .set_cb = NULL },
+    [PROPERTY_HANDLER_CHANNELS]        = { .property_name = "Channels",       .type = "au",     .get_cb = handle_get_channels,        .set_cb = NULL },
+    [PROPERTY_HANDLER_VOLUME]          = { .property_name = "Volume",         .type = "au",     .get_cb = handle_get_volume,          .set_cb = handle_set_volume },
+    [PROPERTY_HANDLER_MUTE]            = { .property_name = "Mute",           .type = "b",      .get_cb = handle_get_mute,            .set_cb = handle_set_mute },
+    [PROPERTY_HANDLER_BUFFER_LATENCY]  = { .property_name = "BufferLatency",  .type = "t",      .get_cb = handle_get_buffer_latency,  .set_cb = NULL },
+    [PROPERTY_HANDLER_DEVICE_LATENCY]  = { .property_name = "DeviceLatency",  .type = "t",      .get_cb = handle_get_device_latency,  .set_cb = NULL },
+    [PROPERTY_HANDLER_RESAMPLE_METHOD] = { .property_name = "ResampleMethod", .type = "s",      .get_cb = handle_get_resample_method, .set_cb = NULL },
+    [PROPERTY_HANDLER_PROPERTY_LIST]   = { .property_name = "PropertyList",   .type = "a{say}", .get_cb = handle_get_property_list,   .set_cb = NULL }
+};
+
+enum method_handler_index {
+    METHOD_HANDLER_MOVE,
+    METHOD_HANDLER_KILL,
+    METHOD_HANDLER_MAX
+};
+
+static pa_dbus_arg_info move_args[] = { { "device", "o", "in" } };
+
+static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
+    [METHOD_HANDLER_MOVE] = {
+        .method_name = "Move",
+        .arguments = move_args,
+        .n_arguments = sizeof(move_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_move },
+    [METHOD_HANDLER_KILL] = {
+        .method_name = "Kill",
+        .arguments = NULL,
+        .n_arguments = 0,
+        .receive_cb = handle_kill }
+};
+
+enum signal_index {
+    SIGNAL_DEVICE_UPDATED,
+    SIGNAL_SAMPLE_RATE_UPDATED,
+    SIGNAL_VOLUME_UPDATED,
+    SIGNAL_MUTE_UPDATED,
+    SIGNAL_PROPERTY_LIST_UPDATED,
+    SIGNAL_STREAM_EVENT,
+    SIGNAL_MAX
+};
+
+static pa_dbus_arg_info device_updated_args[]        = { { "device",        "o",      NULL } };
+static pa_dbus_arg_info sample_rate_updated_args[]   = { { "sample_rate",   "u",      NULL } };
+static pa_dbus_arg_info volume_updated_args[]        = { { "volume",        "au",     NULL } };
+static pa_dbus_arg_info mute_updated_args[]          = { { "muted",         "b",      NULL } };
+static pa_dbus_arg_info property_list_updated_args[] = { { "property_list", "a{say}", NULL } };
+static pa_dbus_arg_info stream_event_args[]          = { { "name",          "s",      NULL }, { "property_list", "a{say}", NULL } };
+
+static pa_dbus_signal_info signals[SIGNAL_MAX] = {
+    [SIGNAL_DEVICE_UPDATED]        = { .name = "DeviceUpdated",       .arguments = device_updated_args,        .n_arguments = 1 },
+    [SIGNAL_SAMPLE_RATE_UPDATED]   = { .name = "SampleRateUpdated",   .arguments = sample_rate_updated_args,   .n_arguments = 1 },
+    [SIGNAL_VOLUME_UPDATED]        = { .name = "VolumeUpdated",       .arguments = volume_updated_args,        .n_arguments = 1 },
+    [SIGNAL_MUTE_UPDATED]          = { .name = "MuteUpdated",         .arguments = mute_updated_args,          .n_arguments = 1 },
+    [SIGNAL_PROPERTY_LIST_UPDATED] = { .name = "PropertyListUpdated", .arguments = property_list_updated_args, .n_arguments = 1 },
+    [SIGNAL_STREAM_EVENT]          = { .name = "StreamEvent",         .arguments = stream_event_args,          .n_arguments = sizeof(stream_event_args) / sizeof(pa_dbus_arg_info) }
+};
+
+static pa_dbus_interface_info stream_interface_info = {
+    .name = PA_DBUSIFACE_STREAM_INTERFACE,
+    .method_handlers = method_handlers,
+    .n_method_handlers = METHOD_HANDLER_MAX,
+    .property_handlers = property_handlers,
+    .n_property_handlers = PROPERTY_HANDLER_MAX,
+    .get_all_properties_cb = handle_get_all,
+    .signals = signals,
+    .n_signals = SIGNAL_MAX
+};
+
+static void handle_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+    dbus_uint32_t idx;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    idx = (s->type == STREAM_TYPE_PLAYBACK) ? s->sink_input->index : s->source_output->index;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &idx);
+}
+
+/* The returned string has to be freed with pa_xfree() by the caller. */
+static char *stream_to_string(pa_dbusiface_stream *s) {
+    if (s->type == STREAM_TYPE_PLAYBACK)
+        return pa_sprintf_malloc("Playback stream %u", (unsigned) s->sink_input->index);
+    else
+        return pa_sprintf_malloc("Record stream %u", (unsigned) s->source_output->index);
+}
+
+static void handle_get_driver(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+    const char *driver = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    driver = (s->type == STREAM_TYPE_PLAYBACK) ? s->sink_input->driver : s->source_output->driver;
+
+    if (!driver) {
+        char *str = stream_to_string(s);
+
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "%s doesn't have a driver.", str);
+        pa_xfree(str);
+
+        return;
+    }
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &driver);
+}
+
+static void handle_get_owner_module(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+    pa_module *owner_module = NULL;
+    const char *object_path = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    owner_module = (s->type == STREAM_TYPE_PLAYBACK) ? s->sink_input->module : s->source_output->module;
+
+    if (!owner_module) {
+        char *str = stream_to_string(s);
+
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "%s doesn't have an owner module.", str);
+        pa_xfree(str);
+
+        return;
+    }
+
+    object_path = pa_dbusiface_core_get_module_path(s->core, owner_module);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path);
+}
+
+static void handle_get_client(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+    pa_client *client = NULL;
+    const char *object_path = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    client = (s->type == STREAM_TYPE_PLAYBACK) ? s->sink_input->client : s->source_output->client;
+
+    if (!client) {
+        char *str = stream_to_string(s);
+
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "%s isn't associated to any client.", str);
+        pa_xfree(str);
+
+        return;
+    }
+
+    object_path = pa_dbusiface_core_get_client_path(s->core, client);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path);
+}
+
+static void handle_get_device(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+    const char *device = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    if (s->type == STREAM_TYPE_PLAYBACK)
+        device = pa_dbusiface_core_get_sink_path(s->core, s->sink);
+    else
+        device = pa_dbusiface_core_get_source_path(s->core, s->source);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &device);
+}
+
+static void handle_get_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+    dbus_uint32_t sample_format = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    sample_format = (s->type == STREAM_TYPE_PLAYBACK)
+                    ? s->sink_input->sample_spec.format
+                    : s->source_output->sample_spec.format;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &sample_format);
+}
+
+static void handle_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &s->sample_rate);
+}
+
+static void handle_get_channels(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+    pa_channel_map *channel_map = NULL;
+    dbus_uint32_t channels[PA_CHANNELS_MAX];
+    unsigned i = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    channel_map = (s->type == STREAM_TYPE_PLAYBACK) ? &s->sink_input->channel_map : &s->source_output->channel_map;
+
+    for (i = 0; i < channel_map->channels; ++i)
+        channels[i] = channel_map->map[i];
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_UINT32, channels, channel_map->channels);
+}
+
+static void handle_get_volume(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+    dbus_uint32_t volume[PA_CHANNELS_MAX];
+    unsigned i = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    if (!s->has_volume) {
+        char *str = stream_to_string(s);
+
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "%s doesn't have volume.", str);
+        pa_xfree(str);
+
+        return;
+    }
+
+    for (i = 0; i < s->volume.channels; ++i)
+        volume[i] = s->volume.values[i];
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_UINT32, volume, s->volume.channels);
+}
+
+static void handle_set_volume(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+    pa_bool_t volume_writable = TRUE;
+    DBusMessageIter array_iter;
+    int stream_channels = 0;
+    dbus_uint32_t *volume = NULL;
+    int n_volume_entries = 0;
+    pa_cvolume new_vol;
+    int i = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(s);
+
+    volume_writable = (s->type == STREAM_TYPE_PLAYBACK) ? s->sink_input->volume_writable : FALSE;
+
+    if (!s->has_volume || !volume_writable) {
+        char *str = stream_to_string(s);
+
+        if (!s->has_volume)
+            pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "%s doesn't have volume.", str);
+        else if (!volume_writable)
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_ACCESS_DENIED, "%s has read-only volume.", str);
+        pa_xfree(str);
+
+        return;
+    }
+
+    stream_channels = s->sink_input->channel_map.channels;
+
+    dbus_message_iter_recurse(iter, &array_iter);
+    dbus_message_iter_get_fixed_array(&array_iter, &volume, &n_volume_entries);
+
+    if (n_volume_entries != stream_channels && n_volume_entries != 1) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS,
+                           "Expected %u volume entries, got %u.", stream_channels, n_volume_entries);
+        return;
+    }
+
+    pa_cvolume_init(&new_vol);
+    new_vol.channels = n_volume_entries;
+
+    for (i = 0; i < n_volume_entries; ++i) {
+        if (!PA_VOLUME_IS_VALID(volume[i])) {
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid volume: %u", volume[i]);
+            return;
+        }
+        new_vol.values[i] = volume[i];
+    }
+
+    pa_sink_input_set_volume(s->sink_input, &new_vol, TRUE, TRUE);
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+static void handle_get_mute(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    if (s->type == STREAM_TYPE_RECORD) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "Record streams don't have mute.");
+        return;
+    }
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &s->mute);
+}
+
+static void handle_set_mute(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+    dbus_bool_t mute = FALSE;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(s);
+
+    dbus_message_iter_get_basic(iter, &mute);
+
+    if (s->type == STREAM_TYPE_RECORD) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "Record streams don't have mute.");
+        return;
+    }
+
+    pa_sink_input_set_mute(s->sink_input, mute, TRUE);
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+static void handle_get_buffer_latency(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+    dbus_uint64_t buffer_latency = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    if (s->type == STREAM_TYPE_PLAYBACK)
+        buffer_latency = pa_sink_input_get_latency(s->sink_input, NULL);
+    else
+        buffer_latency = pa_source_output_get_latency(s->source_output, NULL);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT64, &buffer_latency);
+}
+
+static void handle_get_device_latency(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+    dbus_uint64_t device_latency = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    if (s->type == STREAM_TYPE_PLAYBACK)
+        pa_sink_input_get_latency(s->sink_input, &device_latency);
+    else
+        pa_source_output_get_latency(s->source_output, &device_latency);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT64, &device_latency);
+}
+
+static void handle_get_resample_method(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+    const char *resample_method = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    if (s->type == STREAM_TYPE_PLAYBACK)
+        resample_method = pa_resample_method_to_string(s->sink_input->actual_resample_method);
+    else
+        resample_method = pa_resample_method_to_string(s->source_output->actual_resample_method);
+
+    if (!resample_method)
+        resample_method = "";
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &resample_method);
+}
+
+static void handle_get_property_list(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    pa_dbus_send_proplist_variant_reply(conn, msg, s->proplist);
+}
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+    DBusMessageIter dict_iter;
+    dbus_uint32_t idx = 0;
+    const char *driver = NULL;
+    pa_module *owner_module = NULL;
+    const char *owner_module_path = NULL;
+    pa_client *client = NULL;
+    const char *client_path = NULL;
+    const char *device = NULL;
+    dbus_uint32_t sample_format = 0;
+    pa_channel_map *channel_map = NULL;
+    dbus_uint32_t channels[PA_CHANNELS_MAX];
+    dbus_uint32_t volume[PA_CHANNELS_MAX];
+    dbus_uint64_t buffer_latency = 0;
+    dbus_uint64_t device_latency = 0;
+    const char *resample_method = NULL;
+    unsigned i = 0;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    if (s->has_volume) {
+        for (i = 0; i < s->volume.channels; ++i)
+            volume[i] = s->volume.values[i];
+    }
+
+    if (s->type == STREAM_TYPE_PLAYBACK) {
+        idx = s->sink_input->index;
+        driver = s->sink_input->driver;
+        owner_module = s->sink_input->module;
+        client = s->sink_input->client;
+        device = pa_dbusiface_core_get_sink_path(s->core, s->sink);
+        sample_format = s->sink_input->sample_spec.format;
+        channel_map = &s->sink_input->channel_map;
+        buffer_latency = pa_sink_input_get_latency(s->sink_input, &device_latency);
+        resample_method = pa_resample_method_to_string(s->sink_input->actual_resample_method);
+    } else {
+        idx = s->source_output->index;
+        driver = s->source_output->driver;
+        owner_module = s->source_output->module;
+        client = s->source_output->client;
+        device = pa_dbusiface_core_get_source_path(s->core, s->source);
+        sample_format = s->source_output->sample_spec.format;
+        channel_map = &s->source_output->channel_map;
+        buffer_latency = pa_source_output_get_latency(s->source_output, &device_latency);
+        resample_method = pa_resample_method_to_string(s->source_output->actual_resample_method);
+    }
+    if (owner_module)
+        owner_module_path = pa_dbusiface_core_get_module_path(s->core, owner_module);
+    if (client)
+        client_path = pa_dbusiface_core_get_client_path(s->core, client);
+    for (i = 0; i < channel_map->channels; ++i)
+        channels[i] = channel_map->map[i];
+    if (!resample_method)
+        resample_method = "";
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_INDEX].property_name, DBUS_TYPE_UINT32, &idx);
+
+    if (driver)
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DRIVER].property_name, DBUS_TYPE_STRING, &driver);
+
+    if (owner_module)
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_OWNER_MODULE].property_name, DBUS_TYPE_OBJECT_PATH, &owner_module_path);
+
+    if (client)
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CLIENT].property_name, DBUS_TYPE_OBJECT_PATH, &client_path);
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DEVICE].property_name, DBUS_TYPE_OBJECT_PATH, &device);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SAMPLE_FORMAT].property_name, DBUS_TYPE_UINT32, &sample_format);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SAMPLE_RATE].property_name, DBUS_TYPE_UINT32, &s->sample_rate);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CHANNELS].property_name, DBUS_TYPE_UINT32, channels, channel_map->channels);
+
+    if (s->has_volume) {
+        pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_VOLUME].property_name, DBUS_TYPE_UINT32, volume, s->volume.channels);
+        pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_MUTE].property_name, DBUS_TYPE_BOOLEAN, &s->mute);
+    }
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_BUFFER_LATENCY].property_name, DBUS_TYPE_UINT64, &buffer_latency);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DEVICE_LATENCY].property_name, DBUS_TYPE_UINT64, &device_latency);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_RESAMPLE_METHOD].property_name, DBUS_TYPE_STRING, &resample_method);
+    pa_dbus_append_proplist_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PROPERTY_LIST].property_name, s->proplist);
+
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+}
+
+static void handle_move(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+    const char *device = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device, DBUS_TYPE_INVALID));
+
+    if (s->type == STREAM_TYPE_PLAYBACK) {
+        pa_sink *sink = pa_dbusiface_core_get_sink(s->core, device);
+
+        if (!sink) {
+            pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such sink.", device);
+            return;
+        }
+
+        if (pa_sink_input_move_to(s->sink_input, sink, TRUE) < 0) {
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED,
+                               "Moving playback stream %u to sink %s failed.", s->sink_input->index, sink->name);
+            return;
+        }
+    } else {
+        pa_source *source = pa_dbusiface_core_get_source(s->core, device);
+
+        if (!source) {
+            pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such source.", device);
+            return;
+        }
+
+        if (pa_source_output_move_to(s->source_output, source, TRUE) < 0) {
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED,
+                               "Moving record stream %u to source %s failed.", s->source_output->index, source->name);
+            return;
+        }
+    }
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+static void handle_kill(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(s);
+
+    if (s->type == STREAM_TYPE_PLAYBACK)
+        pa_sink_input_kill(s->sink_input);
+    else
+        pa_source_output_kill(s->source_output);
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+static void subscription_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
+    pa_dbusiface_stream *s = userdata;
+    DBusMessage *signal_msg = NULL;
+    const char *new_device_path = NULL;
+    uint32_t new_sample_rate = 0;
+    pa_proplist *new_proplist = NULL;
+    unsigned i = 0;
+
+    pa_assert(c);
+    pa_assert(s);
+
+    if ((s->type == STREAM_TYPE_PLAYBACK && idx != s->sink_input->index)
+        || (s->type == STREAM_TYPE_RECORD && idx != s->source_output->index))
+        return;
+
+    if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) != PA_SUBSCRIPTION_EVENT_CHANGE)
+        return;
+
+    pa_assert(((s->type == STREAM_TYPE_PLAYBACK)
+                && ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK_INPUT))
+              || ((s->type == STREAM_TYPE_RECORD)
+                   && ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT)));
+
+    if (s->type == STREAM_TYPE_PLAYBACK) {
+        pa_sink *new_sink = s->sink_input->sink;
+
+        if (s->sink != new_sink) {
+            pa_sink_unref(s->sink);
+            s->sink = pa_sink_ref(new_sink);
+
+            new_device_path = pa_dbusiface_core_get_sink_path(s->core, new_sink);
+
+            pa_assert_se(signal_msg = dbus_message_new_signal(s->path,
+                                                             PA_DBUSIFACE_STREAM_INTERFACE,
+                                                             signals[SIGNAL_DEVICE_UPDATED].name));
+            pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &new_device_path, DBUS_TYPE_INVALID));
+
+            pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg);
+            dbus_message_unref(signal_msg);
+            signal_msg = NULL;
+        }
+    } else {
+        pa_source *new_source = s->source_output->source;
+
+        if (s->source != new_source) {
+            pa_source_unref(s->source);
+            s->source = pa_source_ref(new_source);
+
+            new_device_path = pa_dbusiface_core_get_source_path(s->core, new_source);
+
+            pa_assert_se(signal_msg = dbus_message_new_signal(s->path,
+                                                             PA_DBUSIFACE_STREAM_INTERFACE,
+                                                             signals[SIGNAL_DEVICE_UPDATED].name));
+            pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &new_device_path, DBUS_TYPE_INVALID));
+
+            pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg);
+            dbus_message_unref(signal_msg);
+            signal_msg = NULL;
+        }
+    }
+
+    new_sample_rate = (s->type == STREAM_TYPE_PLAYBACK) ? s->sink_input->sample_spec.rate : s->source_output->sample_spec.rate;
+
+    if (s->sample_rate != new_sample_rate) {
+        s->sample_rate = new_sample_rate;
+
+        pa_assert_se(signal_msg = dbus_message_new_signal(s->path,
+                                                         PA_DBUSIFACE_STREAM_INTERFACE,
+                                                         signals[SIGNAL_SAMPLE_RATE_UPDATED].name));
+        pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_UINT32, &s->sample_rate, DBUS_TYPE_INVALID));
+
+        pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
+    }
+
+    if (s->type == STREAM_TYPE_PLAYBACK) {
+        pa_bool_t new_mute = FALSE;
+
+        if (s->has_volume) {
+            pa_cvolume new_volume;
+
+            pa_sink_input_get_volume(s->sink_input, &new_volume, TRUE);
+
+            if (!pa_cvolume_equal(&s->volume, &new_volume)) {
+                dbus_uint32_t volume[PA_CHANNELS_MAX];
+                dbus_uint32_t *volume_ptr = volume;
+
+                s->volume = new_volume;
+
+                for (i = 0; i < s->volume.channels; ++i)
+                    volume[i] = s->volume.values[i];
+
+                pa_assert_se(signal_msg = dbus_message_new_signal(s->path,
+                                                                  PA_DBUSIFACE_STREAM_INTERFACE,
+                                                                  signals[SIGNAL_VOLUME_UPDATED].name));
+                pa_assert_se(dbus_message_append_args(signal_msg,
+                                                      DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &volume_ptr, s->volume.channels,
+                                                      DBUS_TYPE_INVALID));
+
+                pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg);
+                dbus_message_unref(signal_msg);
+                signal_msg = NULL;
+            }
+        }
+
+        new_mute = pa_sink_input_get_mute(s->sink_input);
+
+        if (s->mute != new_mute) {
+            s->mute = new_mute;
+
+            pa_assert_se(signal_msg = dbus_message_new_signal(s->path,
+                                                             PA_DBUSIFACE_STREAM_INTERFACE,
+                                                             signals[SIGNAL_MUTE_UPDATED].name));
+            pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_BOOLEAN, &s->mute, DBUS_TYPE_INVALID));
+
+            pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg);
+            dbus_message_unref(signal_msg);
+            signal_msg = NULL;
+        }
+    }
+
+    new_proplist = (s->type == STREAM_TYPE_PLAYBACK) ? s->sink_input->proplist : s->source_output->proplist;
+
+    if (!pa_proplist_equal(s->proplist, new_proplist)) {
+        DBusMessageIter msg_iter;
+
+        pa_proplist_update(s->proplist, PA_UPDATE_SET, new_proplist);
+
+        pa_assert_se(signal_msg = dbus_message_new_signal(s->path,
+                                                         PA_DBUSIFACE_STREAM_INTERFACE,
+                                                         signals[SIGNAL_PROPERTY_LIST_UPDATED].name));
+        dbus_message_iter_init_append(signal_msg, &msg_iter);
+        pa_dbus_append_proplist(&msg_iter, s->proplist);
+
+        pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg);
+        dbus_message_unref(signal_msg);
+        signal_msg = NULL;
+    }
+}
+
+static pa_hook_result_t send_event_cb(void *hook_data, void *call_data, void *slot_data) {
+    pa_dbusiface_stream *s = slot_data;
+    DBusMessage *signal_msg = NULL;
+    DBusMessageIter msg_iter;
+    const char *name = NULL;
+    pa_proplist *property_list = NULL;
+
+    pa_assert(call_data);
+    pa_assert(s);
+
+    if (s->type == STREAM_TYPE_PLAYBACK) {
+        pa_sink_input_send_event_hook_data *data = call_data;
+
+        if (data->sink_input != s->sink_input)
+            return PA_HOOK_OK;
+
+        name = data->event;
+        property_list = data->data;
+    } else {
+        pa_source_output_send_event_hook_data *data = call_data;
+
+        if (data->source_output != s->source_output)
+            return PA_HOOK_OK;
+
+        name = data->event;
+        property_list = data->data;
+    }
+
+    pa_assert_se(signal_msg = dbus_message_new_signal(s->path,
+                                                     PA_DBUSIFACE_STREAM_INTERFACE,
+                                                     signals[SIGNAL_STREAM_EVENT].name));
+    dbus_message_iter_init_append(signal_msg, &msg_iter);
+    pa_assert_se(dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_STRING, &name));
+    pa_dbus_append_proplist(&msg_iter, property_list);
+
+    pa_dbus_protocol_send_signal(s->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+
+    return PA_HOOK_OK;
+}
+
+pa_dbusiface_stream *pa_dbusiface_stream_new_playback(pa_dbusiface_core *core, pa_sink_input *sink_input) {
+    pa_dbusiface_stream *s;
+
+    pa_assert(core);
+    pa_assert(sink_input);
+
+    s = pa_xnew(pa_dbusiface_stream, 1);
+    s->core = core;
+    s->sink_input = pa_sink_input_ref(sink_input);
+    s->type = STREAM_TYPE_PLAYBACK;
+    s->path = pa_sprintf_malloc("%s/%s%u", PA_DBUS_CORE_OBJECT_PATH, PLAYBACK_OBJECT_NAME, sink_input->index);
+    s->sink = pa_sink_ref(sink_input->sink);
+    s->sample_rate = sink_input->sample_spec.rate;
+    s->has_volume = pa_sink_input_is_volume_readable(sink_input);
+
+    if (s->has_volume)
+        pa_sink_input_get_volume(sink_input, &s->volume, TRUE);
+    else
+        pa_cvolume_init(&s->volume);
+
+    s->mute = pa_sink_input_get_mute(sink_input);
+    s->proplist = pa_proplist_copy(sink_input->proplist);
+    s->dbus_protocol = pa_dbus_protocol_get(sink_input->core);
+    s->subscription = pa_subscription_new(sink_input->core, PA_SUBSCRIPTION_MASK_SINK_INPUT, subscription_cb, s);
+    s->send_event_slot = pa_hook_connect(&sink_input->core->hooks[PA_CORE_HOOK_SINK_INPUT_SEND_EVENT],
+                                         PA_HOOK_NORMAL,
+                                         send_event_cb,
+                                         s);
+
+    pa_assert_se(pa_dbus_protocol_add_interface(s->dbus_protocol, s->path, &stream_interface_info, s) >= 0);
+
+    return s;
+}
+
+pa_dbusiface_stream *pa_dbusiface_stream_new_record(pa_dbusiface_core *core, pa_source_output *source_output) {
+    pa_dbusiface_stream *s;
+
+    pa_assert(core);
+    pa_assert(source_output);
+
+    s = pa_xnew(pa_dbusiface_stream, 1);
+    s->core = core;
+    s->source_output = pa_source_output_ref(source_output);
+    s->type = STREAM_TYPE_RECORD;
+    s->path = pa_sprintf_malloc("%s/%s%u", PA_DBUS_CORE_OBJECT_PATH, RECORD_OBJECT_NAME, source_output->index);
+    s->source = pa_source_ref(source_output->source);
+    s->sample_rate = source_output->sample_spec.rate;
+    pa_cvolume_init(&s->volume);
+    s->mute = FALSE;
+    s->proplist = pa_proplist_copy(source_output->proplist);
+    s->has_volume = FALSE;
+    s->dbus_protocol = pa_dbus_protocol_get(source_output->core);
+    s->subscription = pa_subscription_new(source_output->core, PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT, subscription_cb, s);
+    s->send_event_slot = pa_hook_connect(&source_output->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_SEND_EVENT],
+                                         PA_HOOK_NORMAL,
+                                         send_event_cb,
+                                         s);
+
+    pa_assert_se(pa_dbus_protocol_add_interface(s->dbus_protocol, s->path, &stream_interface_info, s) >= 0);
+
+    return s;
+}
+
+void pa_dbusiface_stream_free(pa_dbusiface_stream *s) {
+    pa_assert(s);
+
+    pa_assert_se(pa_dbus_protocol_remove_interface(s->dbus_protocol, s->path, stream_interface_info.name) >= 0);
+
+    if (s->type == STREAM_TYPE_PLAYBACK) {
+        pa_sink_input_unref(s->sink_input);
+        pa_sink_unref(s->sink);
+    } else {
+        pa_source_output_unref(s->source_output);
+        pa_source_unref(s->source);
+    }
+
+    pa_proplist_free(s->proplist);
+    pa_dbus_protocol_unref(s->dbus_protocol);
+    pa_subscription_free(s->subscription);
+    pa_hook_slot_free(s->send_event_slot);
+
+    pa_xfree(s->path);
+    pa_xfree(s);
+}
+
+const char *pa_dbusiface_stream_get_path(pa_dbusiface_stream *s) {
+    pa_assert(s);
+
+    return s->path;
+}
diff --git a/src/modules/dbus/iface-stream.h b/src/modules/dbus/iface-stream.h
new file mode 100644 (file)
index 0000000..036b4e7
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef foodbusifacestreamhfoo
+#define foodbusifacestreamhfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+/* This object implements the D-Bus interface org.PulseAudio.Core1.Stream.
+ *
+ * See http://pulseaudio.org/wiki/DBusInterface for the Stream interface
+ * documentation.
+ */
+
+#include <pulsecore/protocol-dbus.h>
+#include <pulsecore/sink-input.h>
+#include <pulsecore/source-output.h>
+
+#include "iface-core.h"
+
+#define PA_DBUSIFACE_STREAM_INTERFACE PA_DBUS_CORE_INTERFACE ".Stream"
+
+typedef struct pa_dbusiface_stream pa_dbusiface_stream;
+
+pa_dbusiface_stream *pa_dbusiface_stream_new_playback(pa_dbusiface_core *core, pa_sink_input *sink_input);
+pa_dbusiface_stream *pa_dbusiface_stream_new_record(pa_dbusiface_core *core, pa_source_output *source_output);
+void pa_dbusiface_stream_free(pa_dbusiface_stream *s);
+
+const char *pa_dbusiface_stream_get_path(pa_dbusiface_stream *s);
+
+#endif
diff --git a/src/modules/dbus/module-dbus-protocol.c b/src/modules/dbus/module-dbus-protocol.c
new file mode 100644 (file)
index 0000000..7e49d93
--- /dev/null
@@ -0,0 +1,621 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+  Copyright 2006 Lennart Poettering
+  Copyright 2006 Shams E. King
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dbus/dbus.h>
+
+#include <pulse/mainloop-api.h>
+#include <pulse/timeval.h>
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/client.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-util.h>
+#include <pulsecore/idxset.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/module.h>
+#include <pulsecore/protocol-dbus.h>
+
+#include "iface-client.h"
+#include "iface-core.h"
+
+#include "module-dbus-protocol-symdef.h"
+
+PA_MODULE_DESCRIPTION("D-Bus interface");
+PA_MODULE_USAGE(
+        "access=local|remote|local,remote "
+        "tcp_port=<port number> "
+        "tcp_listen=<hostname>");
+PA_MODULE_LOAD_ONCE(TRUE);
+PA_MODULE_AUTHOR("Tanu Kaskinen");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+
+enum server_type {
+    SERVER_TYPE_LOCAL,
+    SERVER_TYPE_TCP
+};
+
+struct server;
+struct connection;
+
+struct userdata {
+    pa_module *module;
+    pa_bool_t local_access;
+    pa_bool_t remote_access;
+    uint32_t tcp_port;
+    char *tcp_listen;
+
+    struct server *local_server;
+    struct server *tcp_server;
+
+    pa_idxset *connections;
+
+    pa_defer_event *cleanup_event;
+
+    pa_dbus_protocol *dbus_protocol;
+    pa_dbusiface_core *core_iface;
+};
+
+struct server {
+    struct userdata *userdata;
+    enum server_type type;
+    DBusServer *dbus_server;
+};
+
+struct connection {
+    struct server *server;
+    pa_dbus_wrap_connection *wrap_conn;
+    pa_client *client;
+};
+
+static const char* const valid_modargs[] = {
+    "access",
+    "tcp_port",
+    "tcp_listen",
+    NULL
+};
+
+static void connection_free(struct connection *c) {
+    pa_assert(c);
+
+    pa_assert_se(pa_dbus_protocol_unregister_connection(c->server->userdata->dbus_protocol, pa_dbus_wrap_connection_get(c->wrap_conn)) >= 0);
+
+    pa_client_free(c->client);
+    pa_dbus_wrap_connection_free(c->wrap_conn);
+    pa_xfree(c);
+}
+
+/* Called from pa_client_kill(). */
+static void client_kill_cb(pa_client *c) {
+    struct connection *conn;
+
+    pa_assert(c);
+    pa_assert(c->userdata);
+
+    conn = c->userdata;
+    pa_idxset_remove_by_data(conn->server->userdata->connections, conn, NULL);
+    connection_free(conn);
+    c->userdata = NULL;
+
+    pa_log_info("Connection killed.");
+}
+
+/* Called from pa_client_send_event(). */
+static void client_send_event_cb(pa_client *c, const char *name, pa_proplist *data) {
+    struct connection *conn = NULL;
+    DBusMessage *signal_msg = NULL;
+    DBusMessageIter msg_iter;
+
+    pa_assert(c);
+    pa_assert(name);
+    pa_assert(data);
+    pa_assert(c->userdata);
+
+    conn = c->userdata;
+
+    pa_assert_se(signal_msg = dbus_message_new_signal(pa_dbusiface_core_get_client_path(conn->server->userdata->core_iface, c),
+                                                     PA_DBUSIFACE_CLIENT_INTERFACE,
+                                                     "ClientEvent"));
+    dbus_message_iter_init_append(signal_msg, &msg_iter);
+    pa_assert_se(dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_STRING, &name));
+    pa_dbus_append_proplist(&msg_iter, data);
+
+    pa_assert_se(dbus_connection_send(pa_dbus_wrap_connection_get(conn->wrap_conn), signal_msg, NULL));
+    dbus_message_unref(signal_msg);
+}
+
+/* Called by D-Bus at the authentication phase. */
+static dbus_bool_t user_check_cb(DBusConnection *connection, unsigned long uid, void *data) {
+    pa_log_debug("Allowing connection by user %lu.", uid);
+
+    return TRUE;
+}
+
+static DBusHandlerResult disconnection_filter_cb(DBusConnection *connection, DBusMessage *message, void *user_data) {
+    struct connection *c = user_data;
+
+    pa_assert(connection);
+    pa_assert(message);
+    pa_assert(c);
+
+    if (dbus_message_is_signal(message, "org.freedesktop.DBus.Local", "Disconnected")) {
+        /* The connection died. Now we want to free the connection object, but
+         * let's wait until this message is fully processed, in case someone
+         * else is interested in this signal too. */
+        c->server->userdata->module->core->mainloop->defer_enable(c->server->userdata->cleanup_event, 1);
+    }
+
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+/* Called by D-Bus when a new client connection is received. */
+static void connection_new_cb(DBusServer *dbus_server, DBusConnection *new_connection, void *data) {
+    struct server *s = data;
+    struct connection *c;
+    pa_client_new_data new_data;
+    pa_client *client;
+
+    pa_assert(new_connection);
+    pa_assert(s);
+
+    pa_client_new_data_init(&new_data);
+    new_data.module = s->userdata->module;
+    new_data.driver = __FILE__;
+    pa_proplist_sets(new_data.proplist, PA_PROP_APPLICATION_NAME, "D-Bus client");
+    client = pa_client_new(s->userdata->module->core, &new_data);
+    pa_client_new_data_done(&new_data);
+
+    if (!client) {
+        dbus_connection_close(new_connection);
+        return;
+    }
+
+    if (s->type == SERVER_TYPE_TCP || s->userdata->module->core->server_type == PA_SERVER_TYPE_SYSTEM) {
+        /* FIXME: Here we allow anyone from anywhere to access the server,
+         * anonymously. Access control should be configurable. */
+        dbus_connection_set_unix_user_function(new_connection, user_check_cb, NULL, NULL);
+        dbus_connection_set_allow_anonymous(new_connection, TRUE);
+    }
+
+    c = pa_xnew(struct connection, 1);
+    c->server = s;
+    c->wrap_conn = pa_dbus_wrap_connection_new_from_existing(s->userdata->module->core->mainloop, TRUE, new_connection);
+    c->client = client;
+
+    c->client->kill = client_kill_cb;
+    c->client->send_event = client_send_event_cb;
+    c->client->userdata = c;
+
+    pa_assert_se(dbus_connection_add_filter(new_connection, disconnection_filter_cb, c, NULL));
+
+    pa_idxset_put(s->userdata->connections, c, NULL);
+
+    pa_assert_se(pa_dbus_protocol_register_connection(s->userdata->dbus_protocol, new_connection, c->client) >= 0);
+}
+
+/* Called by PA mainloop when a D-Bus fd watch event needs handling. */
+static void io_event_cb(pa_mainloop_api *mainloop, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
+    unsigned int flags = 0;
+    DBusWatch *watch = userdata;
+
+#if HAVE_DBUS_WATCH_GET_UNIX_FD
+    pa_assert(fd == dbus_watch_get_unix_fd(watch));
+#else
+    pa_assert(fd == dbus_watch_get_fd(watch));
+#endif
+
+    if (!dbus_watch_get_enabled(watch)) {
+        pa_log_warn("Asked to handle disabled watch: %p %i", (void*) watch, fd);
+        return;
+    }
+
+    if (events & PA_IO_EVENT_INPUT)
+        flags |= DBUS_WATCH_READABLE;
+    if (events & PA_IO_EVENT_OUTPUT)
+        flags |= DBUS_WATCH_WRITABLE;
+    if (events & PA_IO_EVENT_HANGUP)
+        flags |= DBUS_WATCH_HANGUP;
+    if (events & PA_IO_EVENT_ERROR)
+        flags |= DBUS_WATCH_ERROR;
+
+    dbus_watch_handle(watch, flags);
+}
+
+/* Called by PA mainloop when a D-Bus timer event needs handling. */
+static void time_event_cb(pa_mainloop_api *mainloop, pa_time_event* e, const struct timeval *tv, void *userdata) {
+    DBusTimeout *timeout = userdata;
+
+    if (dbus_timeout_get_enabled(timeout)) {
+        struct timeval next = *tv;
+        dbus_timeout_handle(timeout);
+
+        /* restart it for the next scheduled time */
+        pa_timeval_add(&next, (pa_usec_t) dbus_timeout_get_interval(timeout) * 1000);
+        mainloop->time_restart(e, &next);
+    }
+}
+
+/* Translates D-Bus fd watch event flags to PA IO event flags. */
+static pa_io_event_flags_t get_watch_flags(DBusWatch *watch) {
+    unsigned int flags;
+    pa_io_event_flags_t events = 0;
+
+    pa_assert(watch);
+
+    flags = dbus_watch_get_flags(watch);
+
+    /* no watch flags for disabled watches */
+    if (!dbus_watch_get_enabled(watch))
+        return PA_IO_EVENT_NULL;
+
+    if (flags & DBUS_WATCH_READABLE)
+        events |= PA_IO_EVENT_INPUT;
+    if (flags & DBUS_WATCH_WRITABLE)
+        events |= PA_IO_EVENT_OUTPUT;
+
+    return events | PA_IO_EVENT_HANGUP | PA_IO_EVENT_ERROR;
+}
+
+/* Called by D-Bus when a D-Bus fd watch event is added. */
+static dbus_bool_t watch_add_cb(DBusWatch *watch, void *data) {
+    struct server *s = data;
+    pa_mainloop_api *mainloop;
+    pa_io_event *ev;
+
+    pa_assert(watch);
+    pa_assert(s);
+
+    mainloop = s->userdata->module->core->mainloop;
+
+    ev = mainloop->io_new(
+            mainloop,
+#if HAVE_DBUS_WATCH_GET_UNIX_FD
+            dbus_watch_get_unix_fd(watch),
+#else
+            dbus_watch_get_fd(watch),
+#endif
+            get_watch_flags(watch), io_event_cb, watch);
+
+    dbus_watch_set_data(watch, ev, NULL);
+
+    return TRUE;
+}
+
+/* Called by D-Bus when a D-Bus fd watch event is removed. */
+static void watch_remove_cb(DBusWatch *watch, void *data) {
+    struct server *s = data;
+    pa_io_event *ev;
+
+    pa_assert(watch);
+    pa_assert(s);
+
+    if ((ev = dbus_watch_get_data(watch)))
+        s->userdata->module->core->mainloop->io_free(ev);
+}
+
+/* Called by D-Bus when a D-Bus fd watch event is toggled. */
+static void watch_toggled_cb(DBusWatch *watch, void *data) {
+    struct server *s = data;
+    pa_io_event *ev;
+
+    pa_assert(watch);
+    pa_assert(s);
+
+    pa_assert_se(ev = dbus_watch_get_data(watch));
+
+    /* get_watch_flags() checks if the watch is enabled */
+    s->userdata->module->core->mainloop->io_enable(ev, get_watch_flags(watch));
+}
+
+/* Called by D-Bus when a D-Bus timer event is added. */
+static dbus_bool_t timeout_add_cb(DBusTimeout *timeout, void *data) {
+    struct server *s = data;
+    pa_mainloop_api *mainloop;
+    pa_time_event *ev;
+    struct timeval tv;
+
+    pa_assert(timeout);
+    pa_assert(s);
+
+    if (!dbus_timeout_get_enabled(timeout))
+        return FALSE;
+
+    mainloop = s->userdata->module->core->mainloop;
+
+    pa_gettimeofday(&tv);
+    pa_timeval_add(&tv, (pa_usec_t) dbus_timeout_get_interval(timeout) * 1000);
+
+    ev = mainloop->time_new(mainloop, &tv, time_event_cb, timeout);
+
+    dbus_timeout_set_data(timeout, ev, NULL);
+
+    return TRUE;
+}
+
+/* Called by D-Bus when a D-Bus timer event is removed. */
+static void timeout_remove_cb(DBusTimeout *timeout, void *data) {
+    struct server *s = data;
+    pa_time_event *ev;
+
+    pa_assert(timeout);
+    pa_assert(s);
+
+    if ((ev = dbus_timeout_get_data(timeout)))
+        s->userdata->module->core->mainloop->time_free(ev);
+}
+
+/* Called by D-Bus when a D-Bus timer event is toggled. */
+static void timeout_toggled_cb(DBusTimeout *timeout, void *data) {
+    struct server *s = data;
+    pa_mainloop_api *mainloop;
+    pa_time_event *ev;
+
+    pa_assert(timeout);
+    pa_assert(s);
+
+    mainloop = s->userdata->module->core->mainloop;
+
+    pa_assert_se(ev = dbus_timeout_get_data(timeout));
+
+    if (dbus_timeout_get_enabled(timeout)) {
+        struct timeval tv;
+
+        pa_gettimeofday(&tv);
+        pa_timeval_add(&tv, (pa_usec_t) dbus_timeout_get_interval(timeout) * 1000);
+
+        mainloop->time_restart(ev, &tv);
+    } else
+        mainloop->time_restart(ev, NULL);
+}
+
+static void server_free(struct server *s) {
+    pa_assert(s);
+
+    if (s->dbus_server) {
+        dbus_server_disconnect(s->dbus_server);
+        dbus_server_unref(s->dbus_server);
+    }
+
+    pa_xfree(s);
+}
+
+static struct server *start_server(struct userdata *u, const char *address, enum server_type type) {
+    /* XXX: We assume that when we unref the DBusServer instance at module
+     * shutdown, nobody else holds any references to it. If we stop assuming
+     * that someday, dbus_server_set_new_connection_function,
+     * dbus_server_set_watch_functions and dbus_server_set_timeout_functions
+     * calls should probably register free callbacks, instead of providing NULL
+     * as they do now. */
+
+    struct server *s = NULL;
+    DBusError error;
+
+    pa_assert(u);
+    pa_assert(address);
+
+    dbus_error_init(&error);
+
+    s = pa_xnew0(struct server, 1);
+    s->userdata = u;
+    s->type = type;
+    s->dbus_server = dbus_server_listen(address, &error);
+
+    if (dbus_error_is_set(&error)) {
+        pa_log("dbus_server_listen() failed: %s: %s", error.name, error.message);
+        goto fail;
+    }
+
+    dbus_server_set_new_connection_function(s->dbus_server, connection_new_cb, s, NULL);
+
+    if (!dbus_server_set_watch_functions(s->dbus_server, watch_add_cb, watch_remove_cb, watch_toggled_cb, s, NULL)) {
+        pa_log("dbus_server_set_watch_functions() ran out of memory.");
+        goto fail;
+    }
+
+    if (!dbus_server_set_timeout_functions(s->dbus_server, timeout_add_cb, timeout_remove_cb, timeout_toggled_cb, s, NULL)) {
+        pa_log("dbus_server_set_timeout_functions() ran out of memory.");
+        goto fail;
+    }
+
+    return s;
+
+fail:
+    if (s)
+        server_free(s);
+
+    dbus_error_free(&error);
+
+    return NULL;
+}
+
+static struct server *start_local_server(struct userdata *u) {
+    struct server *s = NULL;
+    char *address = NULL;
+
+    pa_assert(u);
+
+    address = pa_get_dbus_address_from_server_type(u->module->core->server_type);
+
+    s = start_server(u, address, SERVER_TYPE_LOCAL); /* May return NULL */
+
+    pa_xfree(address);
+
+    return s;
+}
+
+static struct server *start_tcp_server(struct userdata *u) {
+    struct server *s = NULL;
+    char *address = NULL;
+
+    pa_assert(u);
+
+    address = pa_sprintf_malloc("tcp:host=%s,port=%u", u->tcp_listen, u->tcp_port);
+
+    s = start_server(u, address, SERVER_TYPE_TCP); /* May return NULL */
+
+    pa_xfree(address);
+
+    return s;
+}
+
+static int get_access_arg(pa_modargs *ma, pa_bool_t *local_access, pa_bool_t *remote_access) {
+    const char *value = NULL;
+
+    pa_assert(ma);
+    pa_assert(local_access);
+    pa_assert(remote_access);
+
+    if (!(value = pa_modargs_get_value(ma, "access", NULL)))
+        return 0;
+
+    if (pa_streq(value, "local")) {
+        *local_access = TRUE;
+        *remote_access = FALSE;
+    } else if (pa_streq(value, "remote")) {
+        *local_access = FALSE;
+        *remote_access = TRUE;
+    } else if (pa_streq(value, "local,remote")) {
+        *local_access = TRUE;
+        *remote_access = TRUE;
+    } else
+        return -1;
+
+    return 0;
+}
+
+/* Frees dead client connections. */
+static void cleanup_cb(pa_mainloop_api *a, pa_defer_event *e, void *userdata) {
+    struct userdata *u = userdata;
+    struct connection *conn = NULL;
+    uint32_t idx;
+
+    PA_IDXSET_FOREACH(conn, u->connections, idx) {
+        if (!dbus_connection_get_is_connected(pa_dbus_wrap_connection_get(conn->wrap_conn))) {
+            pa_idxset_remove_by_data(u->connections, conn, NULL);
+            connection_free(conn);
+        }
+    }
+
+    u->module->core->mainloop->defer_enable(e, 0);
+}
+
+int pa__init(pa_module *m) {
+    struct userdata *u = NULL;
+    pa_modargs *ma = NULL;
+
+    pa_assert(m);
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments.");
+        goto fail;
+    }
+
+    m->userdata = u = pa_xnew0(struct userdata, 1);
+    u->module = m;
+    u->local_access = TRUE;
+    u->remote_access = FALSE;
+    u->tcp_port = PA_DBUS_DEFAULT_PORT;
+
+    if (get_access_arg(ma, &u->local_access, &u->remote_access) < 0) {
+        pa_log("Invalid access argument: '%s'", pa_modargs_get_value(ma, "access", NULL));
+        goto fail;
+    }
+
+    if (pa_modargs_get_value_u32(ma, "tcp_port", &u->tcp_port) < 0 || u->tcp_port < 1 || u->tcp_port > 49150) {
+        pa_log("Invalid tcp_port argument: '%s'", pa_modargs_get_value(ma, "tcp_port", NULL));
+        goto fail;
+    }
+
+    u->tcp_listen = pa_xstrdup(pa_modargs_get_value(ma, "tcp_listen", "0.0.0.0"));
+
+    if (u->local_access && !(u->local_server = start_local_server(u))) {
+        pa_log("Starting the local D-Bus server failed.");
+        goto fail;
+    }
+
+    if (u->remote_access && !(u->tcp_server = start_tcp_server(u))) {
+        pa_log("Starting the D-Bus server for remote connections failed.");
+        goto fail;
+    }
+
+    u->connections = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+
+    u->cleanup_event = m->core->mainloop->defer_new(m->core->mainloop, cleanup_cb, u);
+    m->core->mainloop->defer_enable(u->cleanup_event, 0);
+
+    u->dbus_protocol = pa_dbus_protocol_get(m->core);
+    u->core_iface = pa_dbusiface_core_new(m->core);
+
+    pa_modargs_free(ma);
+
+    return 0;
+
+fail:
+    if (ma)
+        pa_modargs_free(ma);
+
+    pa__done(m);
+
+    return -1;
+}
+
+void pa__done(pa_module *m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    if (u->core_iface)
+        pa_dbusiface_core_free(u->core_iface);
+
+    if (u->connections)
+        pa_idxset_free(u->connections, (pa_free_cb_t) connection_free);
+
+    /* This must not be called before the connections are freed, because if
+     * there are any connections left, they will emit the
+     * org.freedesktop.DBus.Local.Disconnected signal, and
+     * disconnection_filter_cb() will be called. disconnection_filter_cb() then
+     * tries to enable the defer event, and if it's already freed, an assertion
+     * will be hit in mainloop.c. */
+    if (u->cleanup_event)
+        m->core->mainloop->defer_free(u->cleanup_event);
+
+    if (u->tcp_server)
+        server_free(u->tcp_server);
+
+    if (u->local_server)
+        server_free(u->local_server);
+
+    if (u->dbus_protocol)
+        pa_dbus_protocol_unref(u->dbus_protocol);
+
+    pa_xfree(u->tcp_listen);
+    pa_xfree(u);
+    m->userdata = NULL;
+}
diff --git a/src/modules/echo-cancel/adrian-aec-orc-dist.c b/src/modules/echo-cancel/adrian-aec-orc-dist.c
deleted file mode 100644 (file)
index ea93d0b..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-
-/* autogenerated from adrian-aec-orc.orc */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#ifndef DISABLE_ORC
-#include <orc/orc.h>
-#endif
-
-#ifndef _ORC_INTEGER_TYPEDEFS_
-#define _ORC_INTEGER_TYPEDEFS_
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-#include <stdint.h>
-typedef int8_t orc_int8;
-typedef int16_t orc_int16;
-typedef int32_t orc_int32;
-typedef int64_t orc_int64;
-typedef uint8_t orc_uint8;
-typedef uint16_t orc_uint16;
-typedef uint32_t orc_uint32;
-typedef uint64_t orc_uint64;
-#elif defined(_MSC_VER)
-typedef signed __int8 orc_int8;
-typedef signed __int16 orc_int16;
-typedef signed __int32 orc_int32;
-typedef signed __int64 orc_int64;
-typedef unsigned __int8 orc_uint8;
-typedef unsigned __int16 orc_uint16;
-typedef unsigned __int32 orc_uint32;
-typedef unsigned __int64 orc_uint64;
-#else
-#include <limits.h>
-typedef signed char orc_int8;
-typedef short orc_int16;
-typedef int orc_int32;
-typedef unsigned char orc_uint8;
-typedef unsigned short orc_uint16;
-typedef unsigned int orc_uint32;
-#if INT_MAX == LONG_MAX
-typedef long long orc_int64;
-typedef unsigned long long orc_uint64;
-#else
-typedef long orc_int64;
-typedef unsigned long orc_uint64;
-#endif
-#endif
-typedef union { orc_int16 i; orc_int8 x2[2]; } orc_union16;
-typedef union { orc_int32 i; float f; orc_int16 x2[2]; orc_int8 x4[4]; } orc_union32;
-typedef union { orc_int64 i; double f; orc_int32 x2[2]; orc_int16 x4[4]; } orc_union64;
-#endif
-
-void update_tap_weights (float * d1, const float * s1, float p1, int n);
-
-
-/* begin Orc C target preamble */
-#define ORC_CLAMP(x,a,b) ((x)<(a) ? (a) : ((x)>(b) ? (b) : (x)))
-#define ORC_ABS(a) ((a)<0 ? -(a) : (a))
-#define ORC_MIN(a,b) ((a)<(b) ? (a) : (b))
-#define ORC_MAX(a,b) ((a)>(b) ? (a) : (b))
-#define ORC_SB_MAX 127
-#define ORC_SB_MIN (-1-ORC_SB_MAX)
-#define ORC_UB_MAX 255
-#define ORC_UB_MIN 0
-#define ORC_SW_MAX 32767
-#define ORC_SW_MIN (-1-ORC_SW_MAX)
-#define ORC_UW_MAX 65535
-#define ORC_UW_MIN 0
-#define ORC_SL_MAX 2147483647
-#define ORC_SL_MIN (-1-ORC_SL_MAX)
-#define ORC_UL_MAX 4294967295U
-#define ORC_UL_MIN 0
-#define ORC_CLAMP_SB(x) ORC_CLAMP(x,ORC_SB_MIN,ORC_SB_MAX)
-#define ORC_CLAMP_UB(x) ORC_CLAMP(x,ORC_UB_MIN,ORC_UB_MAX)
-#define ORC_CLAMP_SW(x) ORC_CLAMP(x,ORC_SW_MIN,ORC_SW_MAX)
-#define ORC_CLAMP_UW(x) ORC_CLAMP(x,ORC_UW_MIN,ORC_UW_MAX)
-#define ORC_CLAMP_SL(x) ORC_CLAMP(x,ORC_SL_MIN,ORC_SL_MAX)
-#define ORC_CLAMP_UL(x) ORC_CLAMP(x,ORC_UL_MIN,ORC_UL_MAX)
-#define ORC_SWAP_W(x) ((((x)&0xff)<<8) | (((x)&0xff00)>>8))
-#define ORC_SWAP_L(x) ((((x)&0xff)<<24) | (((x)&0xff00)<<8) | (((x)&0xff0000)>>8) | (((x)&0xff000000)>>24))
-#define ORC_SWAP_Q(x) ((((x)&0xffULL)<<56) | (((x)&0xff00ULL)<<40) | (((x)&0xff0000ULL)<<24) | (((x)&0xff000000ULL)<<8) | (((x)&0xff00000000ULL)>>8) | (((x)&0xff0000000000ULL)>>24) | (((x)&0xff000000000000ULL)>>40) | (((x)&0xff00000000000000ULL)>>56))
-#define ORC_PTR_OFFSET(ptr,offset) ((void *)(((unsigned char *)(ptr)) + (offset)))
-#define ORC_DENORMAL(x) ((x) & ((((x)&0x7f800000) == 0) ? 0xff800000 : 0xffffffff))
-#define ORC_ISNAN(x) ((((x)&0x7f800000) == 0x7f800000) && (((x)&0x007fffff) != 0))
-#define ORC_DENORMAL_DOUBLE(x) ((x) & ((((x)&0x7ff0000000000000ULL) == 0) ? 0xfff0000000000000ULL : 0xffffffffffffffffULL))
-#define ORC_ISNAN_DOUBLE(x) ((((x)&0x7ff0000000000000ULL) == 0x7ff0000000000000ULL) && (((x)&0x000fffffffffffffULL) != 0))
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-#define ORC_RESTRICT restrict
-#elif defined(__GNUC__) && __GNUC__ >= 4
-#define ORC_RESTRICT __restrict__
-#else
-#define ORC_RESTRICT
-#endif
-/* end Orc C target preamble */
-
-
-
-/* update_tap_weights */
-#ifdef DISABLE_ORC
-void
-update_tap_weights (float * d1, const float * s1, float p1, int n){
-  int i;
-  orc_union32 * ORC_RESTRICT ptr0;
-  const orc_union32 * ORC_RESTRICT ptr4;
-  orc_union32 var33;
-  orc_union32 var34;
-  orc_union32 var35;
-  orc_union32 var36;
-  orc_union32 var37;
-
-  ptr0 = (orc_union32 *)d1;
-  ptr4 = (orc_union32 *)s1;
-
-    /* 0: loadpl */
-    var33.i = p1;
-
-  for (i = 0; i < n; i++) {
-    /* 1: loadl */
-    var34 = ptr4[i];
-    /* 2: mulf */
-    {
-       orc_union32 _src1;
-       orc_union32 _src2;
-       orc_union32 _dest1;
-       _src1.i = ORC_DENORMAL(var33.i);
-       _src2.i = ORC_DENORMAL(var34.i);
-       _dest1.f = _src1.f * _src2.f;
-       var37.i = ORC_DENORMAL(_dest1.i);
-    }
-    /* 3: loadl */
-    var35 = ptr0[i];
-    /* 4: addf */
-    {
-       orc_union32 _src1;
-       orc_union32 _src2;
-       orc_union32 _dest1;
-       _src1.i = ORC_DENORMAL(var35.i);
-       _src2.i = ORC_DENORMAL(var37.i);
-       _dest1.f = _src1.f + _src2.f;
-       var36.i = ORC_DENORMAL(_dest1.i);
-    }
-    /* 5: storel */
-    ptr0[i] = var36;
-  }
-
-}
-
-#else
-static void
-_backup_update_tap_weights (OrcExecutor * ORC_RESTRICT ex)
-{
-  int i;
-  int n = ex->n;
-  orc_union32 * ORC_RESTRICT ptr0;
-  const orc_union32 * ORC_RESTRICT ptr4;
-  orc_union32 var33;
-  orc_union32 var34;
-  orc_union32 var35;
-  orc_union32 var36;
-  orc_union32 var37;
-
-  ptr0 = (orc_union32 *)ex->arrays[0];
-  ptr4 = (orc_union32 *)ex->arrays[4];
-
-    /* 0: loadpl */
-    var33.i = ex->params[24];
-
-  for (i = 0; i < n; i++) {
-    /* 1: loadl */
-    var34 = ptr4[i];
-    /* 2: mulf */
-    {
-       orc_union32 _src1;
-       orc_union32 _src2;
-       orc_union32 _dest1;
-       _src1.i = ORC_DENORMAL(var33.i);
-       _src2.i = ORC_DENORMAL(var34.i);
-       _dest1.f = _src1.f * _src2.f;
-       var37.i = ORC_DENORMAL(_dest1.i);
-    }
-    /* 3: loadl */
-    var35 = ptr0[i];
-    /* 4: addf */
-    {
-       orc_union32 _src1;
-       orc_union32 _src2;
-       orc_union32 _dest1;
-       _src1.i = ORC_DENORMAL(var35.i);
-       _src2.i = ORC_DENORMAL(var37.i);
-       _dest1.f = _src1.f + _src2.f;
-       var36.i = ORC_DENORMAL(_dest1.i);
-    }
-    /* 5: storel */
-    ptr0[i] = var36;
-  }
-
-}
-
-void
-update_tap_weights (float * d1, const float * s1, float p1, int n)
-{
-  OrcExecutor _ex, *ex = &_ex;
-  static int p_inited = 0;
-  static OrcProgram *p = 0;
-  void (*func) (OrcExecutor *);
-
-  if (!p_inited) {
-    orc_once_mutex_lock ();
-    if (!p_inited) {
-      OrcCompileResult result;
-
-      p = orc_program_new ();
-      orc_program_set_name (p, "update_tap_weights");
-      orc_program_set_backup_function (p, _backup_update_tap_weights);
-      orc_program_add_destination (p, 4, "d1");
-      orc_program_add_source (p, 4, "s1");
-      orc_program_add_constant (p, 0, 0x00000000, "c1");
-      orc_program_add_constant (p, 0, 0x00000000, "c2");
-      orc_program_add_constant (p, 0, 0x00000000, "c3");
-      orc_program_add_constant (p, 0, 0x00000000, "c4");
-      orc_program_add_constant (p, 0, 0x00000000, "c5");
-      orc_program_add_constant (p, 0, 0x00000000, "c6");
-      orc_program_add_constant (p, 0, 0x00000000, "c7");
-      orc_program_add_constant (p, 0, 0x00000000, "c8");
-      orc_program_add_parameter_float (p, 4, "p1");
-      orc_program_add_temporary (p, 4, "t1");
-
-      orc_program_append_2 (p, "mulf", 0, ORC_VAR_T1, ORC_VAR_P1, ORC_VAR_S1, ORC_VAR_D1);
-      orc_program_append_2 (p, "addf", 0, ORC_VAR_D1, ORC_VAR_D1, ORC_VAR_T1, ORC_VAR_D1);
-
-      result = orc_program_compile (p);
-    }
-    p_inited = TRUE;
-    orc_once_mutex_unlock ();
-  }
-  ex->program = p;
-
-  ex->n = n;
-  ex->arrays[ORC_VAR_D1] = d1;
-  ex->arrays[ORC_VAR_S1] = (void *)s1;
-  {
-    orc_union32 tmp;
-    tmp.f = p1;
-    ex->params[ORC_VAR_P1] = tmp.i;
-  }
-
-  func = p->code_exec;
-  func (ex);
-}
-#endif
diff --git a/src/modules/echo-cancel/adrian-aec-orc-dist.h b/src/modules/echo-cancel/adrian-aec-orc-dist.h
deleted file mode 100644 (file)
index 00228c6..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-
-/* autogenerated from adrian-aec-orc.orc */
-
-#ifndef ___MODULES_ECHO_CANCEL_ADRIAN_AEC_ORC_H_
-#define ___MODULES_ECHO_CANCEL_ADRIAN_AEC_ORC_H_
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-
-#ifndef _ORC_INTEGER_TYPEDEFS_
-#define _ORC_INTEGER_TYPEDEFS_
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-#include <stdint.h>
-typedef int8_t orc_int8;
-typedef int16_t orc_int16;
-typedef int32_t orc_int32;
-typedef int64_t orc_int64;
-typedef uint8_t orc_uint8;
-typedef uint16_t orc_uint16;
-typedef uint32_t orc_uint32;
-typedef uint64_t orc_uint64;
-#elif defined(_MSC_VER)
-typedef signed __int8 orc_int8;
-typedef signed __int16 orc_int16;
-typedef signed __int32 orc_int32;
-typedef signed __int64 orc_int64;
-typedef unsigned __int8 orc_uint8;
-typedef unsigned __int16 orc_uint16;
-typedef unsigned __int32 orc_uint32;
-typedef unsigned __int64 orc_uint64;
-#else
-#include <limits.h>
-typedef signed char orc_int8;
-typedef short orc_int16;
-typedef int orc_int32;
-typedef unsigned char orc_uint8;
-typedef unsigned short orc_uint16;
-typedef unsigned int orc_uint32;
-#if INT_MAX == LONG_MAX
-typedef long long orc_int64;
-typedef unsigned long long orc_uint64;
-#else
-typedef long orc_int64;
-typedef unsigned long orc_uint64;
-#endif
-#endif
-typedef union { orc_int16 i; orc_int8 x2[2]; } orc_union16;
-typedef union { orc_int32 i; float f; orc_int16 x2[2]; orc_int8 x4[4]; } orc_union32;
-typedef union { orc_int64 i; double f; orc_int32 x2[2]; orc_int16 x4[4]; } orc_union64;
-#endif
-void update_tap_weights (float * d1, const float * s1, float p1, int n);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
index 269bd61..67a2794 100644 (file)
  * Version 0.4 Leaky Normalized LMS - pre whitening algorithm
  */
 
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
 #include <math.h>
 #include <string.h>
+#include <stdint.h>
 
 #include <pulse/xmalloc.h>
 
 #include "adrian-aec.h"
 
 #ifndef DISABLE_ORC
-#include "adrian-aec-orc.h"
+#include "adrian-aec-orc-gen.h"
 #endif
 
 #ifdef __SSE__
@@ -28,7 +33,7 @@
 /* Vector Dot Product */
 static REAL dotp(REAL a[], REAL b[])
 {
-  REAL sum0 = 0.0, sum1 = 0.0;
+  REAL sum0 = 0.0f, sum1 = 0.0f;
   int j;
 
   for (j = 0; j < NLMS_LEN; j += 2) {
@@ -39,7 +44,6 @@ static REAL dotp(REAL a[], REAL b[])
   return sum0 + sum1;
 }
 
-static REAL dotp_sse(REAL a[], REAL b[]) __attribute__((noinline));
 static REAL dotp_sse(REAL a[], REAL b[])
 {
 #ifdef __SSE__
@@ -66,13 +70,8 @@ static REAL dotp_sse(REAL a[], REAL b[])
 
 AEC* AEC_init(int RATE, int have_vector)
 {
-  AEC *a = pa_xnew(AEC, 1);
-  a->hangover = 0;
-  memset(a->x, 0, sizeof(a->x));
-  memset(a->xf, 0, sizeof(a->xf));
-  memset(a->w, 0, sizeof(a->w));
+  AEC *a = pa_xnew0(AEC, 1);
   a->j = NLMS_EXT;
-  a->delta = 0.0f;
   AEC_setambient(a, NoiseFloor);
   a->dfast = a->dslow = M75dB_PCM;
   a->xfast = a->xslow = M80dB_PCM;
@@ -86,17 +85,31 @@ AEC* AEC_init(int RATE, int have_vector)
   a->aes_y2 = M0dB;
 
   a->fdwdisplay = -1;
-  a->dumpcnt = 0;
-  memset(a->ws, 0, sizeof(a->ws));
 
-  if (have_vector)
+  if (have_vector) {
+      /* Get a 16-byte aligned location */
+      a->w = (REAL *) (((uintptr_t) a->w_arr) - (((uintptr_t) a->w_arr) % 16) + 16);
       a->dotp = dotp_sse;
-  else
+  } else {
+      /* We don't care about alignment, just use the array as-is */
+      a->w = a->w_arr;
       a->dotp = dotp;
+  }
 
   return a;
 }
 
+void AEC_done(AEC *a) {
+    pa_assert(a);
+
+    pa_xfree(a->Fx);
+    pa_xfree(a->Fe);
+    pa_xfree(a->acMic);
+    pa_xfree(a->acSpk);
+    pa_xfree(a->cutoff);
+    pa_xfree(a);
+}
+
 // Adrian soft decision DTD
 // (Dual Average Near-End to Far-End signal Ratio DTD)
 // This algorithm uses exponential smoothing with differnt
@@ -107,8 +120,7 @@ AEC* AEC_init(int RATE, int have_vector)
 // mapped to 1.0 with a limited linear function.
 static float AEC_dtd(AEC *a, REAL d, REAL x)
 {
-  float stepsize;
-  float ratio, M;
+  float ratio, stepsize;
 
   // fast near-end and far-end average
   a->dfast += ALPHAFAST * (fabsf(d) - a->dfast);
@@ -119,26 +131,23 @@ static float AEC_dtd(AEC *a, REAL d, REAL x)
   a->xslow += ALPHASLOW * (fabsf(x) - a->xslow);
 
   if (a->xfast < M70dB_PCM) {
-    return 0.0;   // no Spk signal
+    return 0.0f;   // no Spk signal
   }
 
   if (a->dfast < M70dB_PCM) {
-    return 0.0;   // no Mic signal
+    return 0.0f;   // no Mic signal
   }
 
   // ratio of NFRs
   ratio = (a->dfast * a->xslow) / (a->dslow * a->xfast);
 
-  // begrenzte lineare Kennlinie
-  M = (STEPY2 - STEPY1) / (STEPX2 - STEPX1);
-  if (ratio < STEPX1) {
+  // Linear interpolation with clamping at the limits
+  if (ratio < STEPX1)
     stepsize = STEPY1;
-  } else if (ratio > STEPX2) {
+  else if (ratio > STEPX2)
     stepsize = STEPY2;
-  } else {
-    // Punktrichtungsform einer Geraden
-    stepsize = M * (ratio - STEPX1) + STEPY1;
-  }
+  else
+    stepsize = STEPY1 + (STEPY2 - STEPY1) * (ratio - STEPX1) / (STEPX2 - STEPX1);
 
   return stepsize;
 }
@@ -158,7 +167,7 @@ static void AEC_leaky(AEC *a)
     } else if (1 == a->hangover) {
       --(a->hangover);
       // My Leaky NLMS is to erase vector w when hangover expires
-      memset(a->w, 0, sizeof(a->w));
+      memset(a->w_arr, 0, sizeof(a->w_arr));
     }
   }
 }
@@ -190,7 +199,7 @@ static REAL AEC_nlms_pw(AEC *a, REAL d, REAL x_, float stepsize)
   // optimize: iterative dotp(xf, xf)
   a->dotp_xf_xf += (a->xf[a->j] * a->xf[a->j] - a->xf[a->j + NLMS_LEN - 1] * a->xf[a->j + NLMS_LEN - 1]);
 
-  if (stepsize > 0.0) {
+  if (stepsize > 0.0f) {
     // calculate variable step size
     REAL mikro_ef = stepsize * ef / a->dotp_xf_xf;
 
index 235984b..6271774 100644 (file)
 #include <config.h>
 #endif
 
-#include <pulsecore/macro.h>
+#include <pulse/gccmacro.h>
 #include <pulse/xmalloc.h>
 
+#include <pulsecore/macro.h>
+
 #define WIDEB 2
 
 // use double if your CPU does software-emulation of float
@@ -121,7 +123,7 @@ static  REAL IIR_HP_highpass(IIR_HP *i, REAL in) {
     /* Highpass = Signal - Lowpass. Lowpass = Exponential Smoothing */
     i->x += a0 * (in - i->x);
     return in - i->x;
-  };
+  }
 
 typedef struct FIR_HP_300Hz FIR_HP_300Hz;
 
@@ -306,7 +308,8 @@ struct AEC {
   // NLMS-pw
   REAL x[NLMS_LEN + NLMS_EXT];  // tap delayed loudspeaker signal
   REAL xf[NLMS_LEN + NLMS_EXT]; // pre-whitening tap delayed signal
-  PA_DECLARE_ALIGNED(16, REAL, w[NLMS_LEN]);             // tap weights
+  REAL w_arr[NLMS_LEN + (16 / sizeof(REAL))]; // tap weights
+  REAL *w;                      // this will be a 16-byte aligned pointer into w_arr
   int j;                        // optimize: less memory copies
   double dotp_xf_xf;            // double to avoid loss of precision
   float delta;                  // noise floor to stabilize NLMS
@@ -348,7 +351,8 @@ static  void AEC_leaky(AEC *a);
  */
 static  REAL AEC_nlms_pw(AEC *a, REAL d, REAL x_, float stepsize);
 
-  AEC* AEC_init(int RATE, int have_vector);
+AEC* AEC_init(int RATE, int have_vector);
+void AEC_done(AEC *a);
 
 /* Acoustic Echo Cancellation and Suppression of one sample
  * in   d:  microphone signal with echo
@@ -357,24 +361,23 @@ static  REAL AEC_nlms_pw(AEC *a, REAL d, REAL x_, float stepsize);
  */
   int AEC_doAEC(AEC *a, int d_, int x_);
 
-static  float AEC_getambient(AEC *a) {
+PA_GCC_UNUSED static  float AEC_getambient(AEC *a) {
     return a->dfast;
-  };
+  }
 static  void AEC_setambient(AEC *a, float Min_xf) {
     a->dotp_xf_xf -= a->delta;  // subtract old delta
     a->delta = (NLMS_LEN-1) * Min_xf * Min_xf;
     a->dotp_xf_xf += a->delta;  // add new delta
-  };
-static  void AEC_setgain(AEC *a, float gain_) {
+  }
+PA_GCC_UNUSED static  void AEC_setgain(AEC *a, float gain_) {
     a->gain = gain_;
-  };
+  }
 #if 0
   void AEC_openwdisplay(AEC *a);
 #endif
-static  void AEC_setaes(AEC *a, float aes_y2_) {
+PA_GCC_UNUSED static  void AEC_setaes(AEC *a, float aes_y2_) {
     a->aes_y2 = aes_y2_;
-  };
-static  double AEC_max_dotp_xf_xf(AEC *a, double u);
+  }
 
 #define _AEC_H
 #endif
index 85b2788..ab828be 100644 (file)
 #include <config.h>
 #endif
 
+#include <pulse/xmalloc.h>
+
 #include <pulsecore/modargs.h>
-#include <pulsecore/endianmacros.h>
+
 #include "echo-cancel.h"
 
 /* should be between 10-20 ms */
@@ -41,23 +43,27 @@ static const char* const valid_modargs[] = {
     NULL
 };
 
-static void pa_adrian_ec_fixate_spec(pa_sample_spec *source_ss, pa_channel_map *source_map,
-                                   pa_sample_spec *sink_ss, pa_channel_map *sink_map)
+static void pa_adrian_ec_fixate_spec(pa_sample_spec *rec_ss, pa_channel_map *rec_map,
+                                     pa_sample_spec *play_ss, pa_channel_map *play_map,
+                                     pa_sample_spec *out_ss, pa_channel_map *out_map)
 {
-    source_ss->format = PA_SAMPLE_S16NE;
-    source_ss->channels = 1;
-    pa_channel_map_init_mono(source_map);
-
-    *sink_ss = *source_ss;
-    *sink_map = *source_map;
+    out_ss->format = PA_SAMPLE_S16NE;
+    out_ss->channels = 1;
+    pa_channel_map_init_mono(out_map);
+
+    *play_ss = *out_ss;
+    *play_map = *out_map;
+    *rec_ss = *out_ss;
+    *rec_map = *out_map;
 }
 
 pa_bool_t pa_adrian_ec_init(pa_core *c, pa_echo_canceller *ec,
-                           pa_sample_spec *source_ss, pa_channel_map *source_map,
-                           pa_sample_spec *sink_ss, pa_channel_map *sink_map,
-                           uint32_t *blocksize, const char *args)
+                            pa_sample_spec *rec_ss, pa_channel_map *rec_map,
+                            pa_sample_spec *play_ss, pa_channel_map *play_map,
+                            pa_sample_spec *out_ss, pa_channel_map *out_map,
+                            uint32_t *nframes, const char *args)
 {
-    int framelen, rate, have_vector = 0;
+    int rate, have_vector = 0;
     uint32_t frame_size_ms;
     pa_modargs *ma;
 
@@ -72,36 +78,32 @@ pa_bool_t pa_adrian_ec_init(pa_core *c, pa_echo_canceller *ec,
         goto fail;
     }
 
-    pa_adrian_ec_fixate_spec(source_ss, source_map, sink_ss, sink_map);
+    pa_adrian_ec_fixate_spec(rec_ss, rec_map, play_ss, play_map, out_ss, out_map);
 
-    rate = source_ss->rate;
-    framelen = (rate * frame_size_ms) / 1000;
+    rate = out_ss->rate;
+    *nframes = (rate * frame_size_ms) / 1000;
+    ec->params.priv.adrian.blocksize = (*nframes) * pa_frame_size(out_ss);
 
-    *blocksize = ec->params.priv.adrian.blocksize = framelen * pa_frame_size (source_ss);
-
-    pa_log_debug ("Using framelen %d, blocksize %u, channels %d, rate %d", framelen, ec->params.priv.adrian.blocksize, source_ss->channels, source_ss->rate);
+    pa_log_debug ("Using nframes %d, blocksize %u, channels %d, rate %d", *nframes, ec->params.priv.adrian.blocksize, out_ss->channels, out_ss->rate);
 
     /* For now we only support SSE */
-#if 0
     if (c->cpu_info.cpu_type == PA_CPU_X86 && (c->cpu_info.flags.x86 & PA_CPU_X86_SSE))
         have_vector = 1;
-#endif
 
     ec->params.priv.adrian.aec = AEC_init(rate, have_vector);
     if (!ec->params.priv.adrian.aec)
-       goto fail;
+        goto fail;
 
     pa_modargs_free(ma);
     return TRUE;
 
 fail:
     if (ma)
-       pa_modargs_free(ma);
+        pa_modargs_free(ma);
     return FALSE;
 }
 
-void pa_adrian_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out)
-{
+void pa_adrian_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out) {
     unsigned int i;
 
     for (i = 0; i < ec->params.priv.adrian.blocksize; i += 2) {
@@ -112,8 +114,9 @@ void pa_adrian_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *
     }
 }
 
-void pa_adrian_ec_done(pa_echo_canceller *ec)
-{
-    pa_xfree(ec->params.priv.adrian.aec);
-    ec->params.priv.adrian.aec = NULL;
+void pa_adrian_ec_done(pa_echo_canceller *ec) {
+    if (ec->params.priv.adrian.aec) {
+        AEC_done(ec->params.priv.adrian.aec);
+        ec->params.priv.adrian.aec = NULL;
+    }
 }
index 639fa9e..4ace392 100644 (file)
@@ -28,4 +28,5 @@
 typedef struct AEC AEC;
 
 AEC* AEC_init(int RATE, int have_vector);
+void AEC_done(AEC *a);
 int AEC_doAEC(AEC *a, int d_, int x_);
index 5f6adbc..0a6c640 100644 (file)
@@ -19,6 +19,9 @@
     USA.
 ***/
 
+#ifndef fooechocancelhfoo
+#define fooechocancelhfoo
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 #include <pulsecore/core.h>
 #include <pulsecore/macro.h>
 
+#ifdef HAVE_SPEEX
 #include <speex/speex_echo.h>
+#include <speex/speex_preprocess.h>
+#endif
+
 #include "adrian.h"
 
 /* Common data structures */
 
+typedef struct pa_echo_canceller_msg pa_echo_canceller_msg;
+
 typedef struct pa_echo_canceller_params pa_echo_canceller_params;
 
 struct pa_echo_canceller_params {
     union {
         struct {
+            pa_sample_spec out_ss;
+        } null;
+#ifdef HAVE_SPEEX
+        struct {
             SpeexEchoState *state;
+            SpeexPreprocessState *pp_state;
         } speex;
+#endif
+#ifdef HAVE_ADRIAN_EC
         struct {
             uint32_t blocksize;
             AEC *aec;
         } adrian;
+#endif
+#ifdef HAVE_WEBRTC
+        struct {
+            /* This is a void* so that we don't have to convert this whole file
+             * to C++ linkage. apm is a pointer to an AudioProcessing object */
+            void *apm;
+            uint32_t blocksize;
+            pa_sample_spec sample_spec;
+            pa_bool_t agc;
+        } webrtc;
+#endif
         /* each canceller-specific structure goes here */
     } priv;
+
+    /* Set this if canceller can do drift compensation. Also see set_drift()
+     * below */
+    pa_bool_t drift_compensation;
+};
+
+enum{
+       DEVICE_NONE,
+       DEVICE_IN_MIC_OUT_SPEAKER,
+       DEVICE_IN_MIC_OUT_RECEIVER,
+       DEVICE_IN_MIC_OUT_WIRED,
+       DEVICE_IN_WIRED_OUT_WIRED,
+       DEVICE_IN_BT_SCO_OUT_BT_SCO,
 };
 
 typedef struct pa_echo_canceller pa_echo_canceller;
 
 struct pa_echo_canceller {
+    /* Initialise canceller engine. */
     pa_bool_t   (*init)                 (pa_core *c,
                                          pa_echo_canceller *ec,
-                                         pa_sample_spec *source_ss,
-                                         pa_channel_map *source_map,
-                                         pa_sample_spec *sink_ss,
-                                         pa_channel_map *sink_map,
-                                         uint32_t *blocksize,
+                                         pa_sample_spec *rec_ss,
+                                         pa_channel_map *rec_map,
+                                         pa_sample_spec *play_ss,
+                                         pa_channel_map *play_map,
+                                         pa_sample_spec *out_ss,
+                                         pa_channel_map *out_map,
+                                         uint32_t *nframes,
                                          const char *args);
+
+    /* You should have only one of play()+record() or run() set. The first
+     * works under the assumption that you'll handle buffering and matching up
+     * samples yourself. If you set run(), module-echo-cancel will handle
+     * synchronising the playback and record streams. */
+
+    /* Feed the engine 'nframes' playback frames. */
+    void        (*play)                 (pa_echo_canceller *ec, const uint8_t *play);
+    /* Feed the engine 'nframes' record frames. nframes processed frames are
+     * returned in out. */
+    void        (*record)               (pa_echo_canceller *ec, const uint8_t *rec, uint8_t *out);
+    /* Feed the engine nframes playback and record frames, with a reasonable
+     * effort at keeping the two in sync. nframes processed frames are
+     * returned in out. */
     void        (*run)                  (pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out);
-    void        (*done)                 (pa_echo_canceller *ec);
 
+    /* Optional callback to set the drift, expressed as the ratio of the
+     * difference in number of playback and capture samples to the number of
+     * capture samples, for some instant of time. This is used only if the
+     * canceller signals that it supports drift compensation, and is called
+     * before record(). The actual implementation needs to derive drift based
+     * on point samples -- the individual values are not accurate enough to use
+     * as-is. */
+    /* NOTE: the semantics of this function might change in the future. */
+    void        (*set_drift)            (pa_echo_canceller *ec, float drift);
+
+    /* Free up resources. */
+    void        (*done)                 (pa_echo_canceller *ec);
+    /* Structure with common and engine-specific canceller parameters. */
     pa_echo_canceller_params params;
+
+    pa_bool_t tx_agc;
+    pa_bool_t tx_denoise;
+    pa_bool_t echo_suppress;
+    int32_t echo_suppress_attenuation; // negative dB value (default in speex is -40)
+    int32_t echo_suppress_attenuation_active; // negative dB value (default in speex is -15)
+    
+    /* msgobject that can be used to send messages back to the main thread */
+    pa_echo_canceller_msg *msg;
 };
 
+/* Functions to be used by the canceller analog gain control routines */
+void pa_echo_canceller_get_capture_volume(pa_echo_canceller *ec, pa_cvolume *v);
+void pa_echo_canceller_set_capture_volume(pa_echo_canceller *ec, pa_cvolume *v);
+
+/* Computes EC block size in frames (rounded down to nearest power-of-2) based
+ * on sample rate and milliseconds. */
+uint32_t pa_echo_canceller_blocksize_power2(unsigned rate, unsigned ms);
+
+/* Null canceller functions */
+pa_bool_t pa_null_ec_init(pa_core *c, pa_echo_canceller *ec,
+                          pa_sample_spec *rec_ss, pa_channel_map *rec_map,
+                          pa_sample_spec *play_ss, pa_channel_map *play_map,
+                          pa_sample_spec *out_ss, pa_channel_map *out_map,
+                          uint32_t *nframes, const char *args);
+void pa_null_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out);
+void pa_null_ec_done(pa_echo_canceller *ec);
+
+#ifdef HAVE_SPEEX
 /* Speex canceller functions */
 pa_bool_t pa_speex_ec_init(pa_core *c, pa_echo_canceller *ec,
-                           pa_sample_spec *source_ss, pa_channel_map *source_map,
-                           pa_sample_spec *sink_ss, pa_channel_map *sink_map,
-                           uint32_t *blocksize, const char *args);
+                           pa_sample_spec *rec_ss, pa_channel_map *rec_map,
+                           pa_sample_spec *play_ss, pa_channel_map *play_map,
+                           pa_sample_spec *out_ss, pa_channel_map *out_map,
+                           uint32_t *nframes, const char *args);
 void pa_speex_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out);
 void pa_speex_ec_done(pa_echo_canceller *ec);
+#endif
 
+#ifdef HAVE_ADRIAN_EC
 /* Adrian Andre's echo canceller */
 pa_bool_t pa_adrian_ec_init(pa_core *c, pa_echo_canceller *ec,
-                           pa_sample_spec *source_ss, pa_channel_map *source_map,
-                           pa_sample_spec *sink_ss, pa_channel_map *sink_map,
-                           uint32_t *blocksize, const char *args);
+                            pa_sample_spec *rec_ss, pa_channel_map *rec_map,
+                            pa_sample_spec *play_ss, pa_channel_map *play_map,
+                            pa_sample_spec *out_ss, pa_channel_map *out_map,
+                            uint32_t *nframes, const char *args);
 void pa_adrian_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out);
 void pa_adrian_ec_done(pa_echo_canceller *ec);
+#endif
+
+#ifdef HAVE_WEBRTC
+/* WebRTC canceller functions */
+PA_C_DECL_BEGIN
+pa_bool_t pa_webrtc_ec_init(pa_core *c, pa_echo_canceller *ec,
+                            pa_sample_spec *rec_ss, pa_channel_map *rec_map,
+                            pa_sample_spec *play_ss, pa_channel_map *play_map,
+                            pa_sample_spec *out_ss, pa_channel_map *out_map,
+                            uint32_t *nframes, const char *args);
+void pa_webrtc_ec_play(pa_echo_canceller *ec, const uint8_t *play);
+void pa_webrtc_ec_record(pa_echo_canceller *ec, const uint8_t *rec, uint8_t *out);
+void pa_webrtc_ec_set_drift(pa_echo_canceller *ec, float drift);
+void pa_webrtc_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out);
+void pa_webrtc_ec_done(pa_echo_canceller *ec);
+PA_C_DECL_END
+#endif
+
+#endif /* fooechocancelhfoo */
diff --git a/src/modules/echo-cancel/module-echo-cancel-symdef.h b/src/modules/echo-cancel/module-echo-cancel-symdef.h
deleted file mode 100644 (file)
index 6435170..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleechocancelsymdeffoo
-#define foomoduleechocancelsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_echo_cancel_LTX_pa__init
-#define pa__done module_echo_cancel_LTX_pa__done
-#define pa__get_author module_echo_cancel_LTX_pa__get_author
-#define pa__get_description module_echo_cancel_LTX_pa__get_description
-#define pa__get_usage module_echo_cancel_LTX_pa__get_usage
-#define pa__get_version module_echo_cancel_LTX_pa__get_version
-#define pa__get_deprecated module_echo_cancel_LTX_pa__get_deprecated
-#define pa__load_once module_echo_cancel_LTX_pa__load_once
-#define pa__get_n_used module_echo_cancel_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 611ebb7..9990ba4 100644 (file)
 #include "echo-cancel.h"
 
 #include <pulse/xmalloc.h>
-#include <pulse/i18n.h>
 #include <pulse/timeval.h>
 #include <pulse/rtclock.h>
 
+#include <pulsecore/i18n.h>
 #include <pulsecore/atomic.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/core-error.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/sink.h>
 #include <pulsecore/module.h>
 #include <pulsecore/core-rtclock.h>
 #include <pulsecore/core-util.h>
-#include <pulsecore/core-error.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/log.h>
-#include <pulsecore/thread.h>
-#include <pulsecore/thread-mq.h>
 #include <pulsecore/rtpoll.h>
 #include <pulsecore/sample-util.h>
 #include <pulsecore/ltdl-helper.h>
 
+#include <pulsecore/protocol-native.h>
+#include <pulsecore/pstream-util.h>
+
 #include "module-echo-cancel-symdef.h"
 
 PA_MODULE_AUTHOR("Wim Taymans");
-PA_MODULE_DESCRIPTION("Echo Cancelation");
+PA_MODULE_DESCRIPTION("Echo Cancellation");
 PA_MODULE_VERSION(PACKAGE_VERSION);
 PA_MODULE_LOAD_ONCE(FALSE);
 PA_MODULE_USAGE(
@@ -71,44 +70,104 @@ PA_MODULE_USAGE(
           "sink_properties=<properties for the sink> "
           "sink_master=<name of sink to filter> "
           "adjust_time=<how often to readjust rates in s> "
+          "adjust_threshold=<how much drift to readjust after in ms> "
           "format=<sample format> "
           "rate=<sample rate> "
           "channels=<number of channels> "
           "channel_map=<channel map> "
           "aec_method=<implementation to use> "
           "aec_args=<parameters for the AEC engine> "
+          "agc=<perform automagic gain control?> "
+          "denoise=<apply denoising?> "
+          "echo_suppress=<perform residual echo suppression? (only with the speex canceller)> "
+          "echo_suppress_attenuation=<dB value of residual echo attenuation> "
+          "echo_suppress_attenuation_active=<dB value of residual echo attenuation when near end is active> "
           "save_aec=<save AEC data in /tmp> "
+          "autoloaded=<set if this module is being loaded automatically> "
+          "use_volume_sharing=<yes or no> "
         ));
 
 /* NOTE: Make sure the enum and ec_table are maintained in the correct order */
 typedef enum {
     PA_ECHO_CANCELLER_INVALID = -1,
-    PA_ECHO_CANCELLER_SPEEX = 0,
+    PA_ECHO_CANCELLER_NULL,
+#ifdef HAVE_SPEEX
+    PA_ECHO_CANCELLER_SPEEX,
+#endif
+#ifdef HAVE_ADRIAN_EC
     PA_ECHO_CANCELLER_ADRIAN,
+#endif
+#ifdef HAVE_WEBRTC
+    PA_ECHO_CANCELLER_WEBRTC,
+#endif
 } pa_echo_canceller_method_t;
 
+enum {
+       AEC_SET_VOLUME,
+       AEC_SET_DEVICE,
+};
+
+#ifdef HAVE_WEBRTC
+#define DEFAULT_ECHO_CANCELLER "webrtc"
+#else
 #define DEFAULT_ECHO_CANCELLER "speex"
+#endif
 
 static const pa_echo_canceller ec_table[] = {
     {
+        /* Null, Dummy echo canceller (just copies data) */
+        .init                   = pa_null_ec_init,
+        .run                    = pa_null_ec_run,
+        .done                   = pa_null_ec_done,
+    },
+#ifdef HAVE_SPEEX
+    {
         /* Speex */
         .init                   = pa_speex_ec_init,
         .run                    = pa_speex_ec_run,
         .done                   = pa_speex_ec_done,
     },
+#endif
+#ifdef HAVE_ADRIAN_EC
     {
         /* Adrian Andre's NLMS implementation */
         .init                   = pa_adrian_ec_init,
         .run                    = pa_adrian_ec_run,
         .done                   = pa_adrian_ec_done,
     },
+#endif
+#ifdef HAVE_WEBRTC
+    {
+        /* WebRTC's audio processing engine */
+        .init                   = pa_webrtc_ec_init,
+        .play                   = pa_webrtc_ec_play,
+        .record                 = pa_webrtc_ec_record,
+        .set_drift              = pa_webrtc_ec_set_drift,
+        .run                    = pa_webrtc_ec_run,
+        .done                   = pa_webrtc_ec_done,
+    },
+#endif
 };
 
+#define DEFAULT_RATE 32000
+#define DEFAULT_CHANNELS 1
 #define DEFAULT_ADJUST_TIME_USEC (1*PA_USEC_PER_SEC)
-#define DEFAULT_SAVE_AEC 0
+#define DEFAULT_ADJUST_TOLERANCE (5*PA_USEC_PER_MSEC)
+#define DEFAULT_SAVE_AEC FALSE
+#define DEFAULT_AUTOLOADED FALSE
+
+#define DEFAULT_AGC_ENABLED FALSE
+#define DEFAULT_DENOISE_ENABLED FALSE
+#define DEFAULT_ECHO_SUPPRESS_ENABLED FALSE
+#define DEFAULT_ECHO_SUPPRESS_ATTENUATION 0
+
 
 #define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
 
+/* Can only be used in main context */
+#define IS_ACTIVE(u) ((pa_source_get_state((u)->source) == PA_SOURCE_RUNNING) && \
+                      (pa_sink_get_state((u)->sink) == PA_SINK_RUNNING))
+
 /* This module creates a new (virtual) source and sink.
  *
  * The data sent to the new sink is kept in a memblockq before being
@@ -124,20 +183,30 @@ static const pa_echo_canceller ec_table[] = {
  *
  * Alignment is performed in two steps:
  *
- * 1) when something happens that requires quick adjustement of the alignment of
+ * 1) when something happens that requires quick adjustment of the alignment of
  *    capture and playback samples, we perform a resync. This adjusts the
  *    position in the playback memblock to the requested sample. Quick
- *    adjustements include moving the playback samples before the capture
+ *    adjustments include moving the playback samples before the capture
  *    samples (because else the echo canceler does not work) or when the
  *    playback pointer drifts too far away.
  *
- * 2) periodically check the difference between capture and playback. we use a
- *    low and high watermark for adjusting the alignment. playback should always
+ * 2) periodically check the difference between capture and playback. We use a
+ *    low and high watermark for adjusting the alignment. Playback should always
  *    be before capture and the difference should not be bigger than one frame
  *    size. We would ideally like to resample the sink_input but most driver
  *    don't give enough accuracy to be able to do that right now.
  */
 
+struct userdata;
+
+struct pa_echo_canceller_msg {
+    pa_msgobject parent;
+    struct userdata *userdata;
+};
+
+PA_DEFINE_PRIVATE_CLASS(pa_echo_canceller_msg, pa_msgobject);
+#define PA_ECHO_CANCELLER_MSG(o) (pa_echo_canceller_msg_cast(o))
+
 struct snapshot {
     pa_usec_t sink_now;
     pa_usec_t sink_latency;
@@ -156,15 +225,18 @@ struct userdata {
     pa_core *core;
     pa_module *module;
 
-    uint32_t save_aec;
+    pa_bool_t autoloaded;
+    pa_bool_t dead;
+    pa_bool_t save_aec;
 
     pa_echo_canceller *ec;
-    uint32_t blocksize;
+    uint32_t source_output_blocksize;
+    uint32_t source_blocksize;
+    uint32_t sink_blocksize;
 
     pa_bool_t need_realign;
 
     /* to wakeup the source I/O thread */
-    pa_bool_t in_push;
     pa_asyncmsgq *asyncmsgq;
     pa_rtpoll_item *rtpoll_item_read, *rtpoll_item_write;
 
@@ -182,15 +254,27 @@ struct userdata {
     int64_t recv_counter;
     size_t sink_skip;
 
+    /* Bytes left over from previous iteration */
+    size_t sink_rem;
+    size_t source_rem;
+
     pa_atomic_t request_resync;
 
-    int active_mask;
     pa_time_event *time_event;
     pa_usec_t adjust_time;
+    int adjust_threshold;
 
     FILE *captured_file;
     FILE *played_file;
     FILE *canceled_file;
+    FILE *drift_file;
+
+    pa_native_protocol *protocol;
+    pa_bool_t use_volume_sharing;
+
+    struct {
+        pa_cvolume current_volume;
+    } thread_info;
 };
 
 static void source_output_snapshot_within_thread(struct userdata *u, struct snapshot *snapshot);
@@ -203,13 +287,21 @@ static const char* const valid_modargs[] = {
     "sink_properties",
     "sink_master",
     "adjust_time",
+    "adjust_threshold",
     "format",
     "rate",
     "channels",
     "channel_map",
     "aec_method",
     "aec_args",
+    "agc",
+    "denoise",
+    "echo_suppress",
+    "echo_suppress_attenuation",
+    "echo_suppress_attenuation_active",
     "save_aec",
+    "autoloaded",
+    "use_volume_sharing",
     NULL
 };
 
@@ -224,35 +316,43 @@ enum {
     SINK_INPUT_MESSAGE_LATENCY_SNAPSHOT
 };
 
-static int64_t calc_diff(struct userdata *u, struct snapshot *snapshot) {
-    int64_t buffer, diff_time, buffer_latency;
+enum {
+    ECHO_CANCELLER_MESSAGE_SET_VOLUME,
+};
 
-    /* get the number of samples between capture and playback */
-    if (snapshot->plen > snapshot->rlen)
-        buffer = snapshot->plen - snapshot->rlen;
+static int64_t calc_diff(struct userdata *u, struct snapshot *snapshot) {
+    int64_t diff_time, buffer_latency;
+    pa_usec_t plen, rlen, source_delay, sink_delay, recv_counter, send_counter;
+
+    /* get latency difference between playback and record */
+    plen = pa_bytes_to_usec(snapshot->plen, &u->sink_input->sample_spec);
+    rlen = pa_bytes_to_usec(snapshot->rlen, &u->source_output->sample_spec);
+    if (plen > rlen)
+        buffer_latency = plen - rlen;
     else
-        buffer = 0;
+        buffer_latency = 0;
 
-    buffer += snapshot->source_delay + snapshot->sink_delay;
+    source_delay = pa_bytes_to_usec(snapshot->source_delay, &u->source_output->sample_spec);
+    sink_delay = pa_bytes_to_usec(snapshot->sink_delay, &u->sink_input->sample_spec);
+    buffer_latency += source_delay + sink_delay;
 
-    /* add the amount of samples not yet transfered to the source context */
-    if (snapshot->recv_counter <= snapshot->send_counter)
-        buffer += (int64_t) (snapshot->send_counter - snapshot->recv_counter);
+    /* add the latency difference due to samples not yet transferred */
+    send_counter = pa_bytes_to_usec(snapshot->send_counter, &u->sink->sample_spec);
+    recv_counter = pa_bytes_to_usec(snapshot->recv_counter, &u->sink->sample_spec);
+    if (recv_counter <= send_counter)
+        buffer_latency += (int64_t) (send_counter - recv_counter);
     else
-        buffer += PA_CLIP_SUB(buffer, (int64_t) (snapshot->recv_counter - snapshot->send_counter));
-
-    /* convert to time */
-    buffer_latency = pa_bytes_to_usec(buffer, &u->source_output->sample_spec);
+        buffer_latency += PA_CLIP_SUB(buffer_latency, (int64_t) (recv_counter - send_counter));
 
-    /* capture and playback samples are perfectly aligned when diff_time is 0 */
+    /* capture and playback are perfectly aligned when diff_time is 0 */
     diff_time = (snapshot->sink_now + snapshot->sink_latency - buffer_latency) -
           (snapshot->source_now - snapshot->source_latency);
 
-    pa_log_debug("diff %lld (%lld - %lld + %lld) %lld %lld %lld %lld", (long long) diff_time,
+    pa_log_debug("Diff %lld (%lld - %lld + %lld) %lld %lld %lld %lld", (long long) diff_time,
         (long long) snapshot->sink_latency,
         (long long) buffer_latency, (long long) snapshot->source_latency,
-        (long long) snapshot->source_delay, (long long) snapshot->sink_delay,
-        (long long) (snapshot->send_counter - snapshot->recv_counter),
+        (long long) source_delay, (long long) sink_delay,
+        (long long) (send_counter - recv_counter),
         (long long) (snapshot->sink_now - snapshot->source_now));
 
     return diff_time;
@@ -263,7 +363,7 @@ static void time_callback(pa_mainloop_api *a, pa_time_event *e, const struct tim
     struct userdata *u = userdata;
     uint32_t old_rate, base_rate, new_rate;
     int64_t diff_time;
-    size_t fs;
+    /*size_t fs*/
     struct snapshot latency_snapshot;
 
     pa_assert(u);
@@ -271,7 +371,7 @@ static void time_callback(pa_mainloop_api *a, pa_time_event *e, const struct tim
     pa_assert(u->time_event == e);
     pa_assert_ctl_context();
 
-    if (u->active_mask != 3)
+    if (!IS_ACTIVE(u))
         return;
 
     /* update our snapshots */
@@ -281,7 +381,7 @@ static void time_callback(pa_mainloop_api *a, pa_time_event *e, const struct tim
     /* calculate drift between capture and playback */
     diff_time = calc_diff(u, &latency_snapshot);
 
-    fs = pa_frame_size(&u->source_output->sample_spec);
+    /*fs = pa_frame_size(&u->source_output->sample_spec);*/
     old_rate = u->sink_input->sample_spec.rate;
     base_rate = u->source_output->sample_spec.rate;
 
@@ -290,24 +390,24 @@ static void time_callback(pa_mainloop_api *a, pa_time_event *e, const struct tim
          * canceler does not work in this case. */
         pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->source_output), SOURCE_OUTPUT_MESSAGE_APPLY_DIFF_TIME,
             NULL, diff_time, NULL, NULL);
-        //new_rate = base_rate - ((pa_usec_to_bytes (-diff_time, &u->source_output->sample_spec) / fs) * PA_USEC_PER_SEC) / u->adjust_time;
+        /*new_rate = base_rate - ((pa_usec_to_bytes(-diff_time, &u->source_output->sample_spec) / fs) * PA_USEC_PER_SEC) / u->adjust_time;*/
         new_rate = base_rate;
     }
     else {
-        if (diff_time > 1000) {
+        if (diff_time > u->adjust_threshold) {
             /* diff too big, quickly adjust */
             pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->source_output), SOURCE_OUTPUT_MESSAGE_APPLY_DIFF_TIME,
                 NULL, diff_time, NULL, NULL);
         }
 
         /* recording behind playback, we need to slowly adjust the rate to match */
-        //new_rate = base_rate + ((pa_usec_to_bytes (diff_time, &u->source_output->sample_spec) / fs) * PA_USEC_PER_SEC) / u->adjust_time;
+        /*new_rate = base_rate + ((pa_usec_to_bytes(diff_time, &u->source_output->sample_spec) / fs) * PA_USEC_PER_SEC) / u->adjust_time;*/
 
         /* assume equal samplerates for now */
         new_rate = base_rate;
     }
 
-    /* make sure we don't make too big adjustements because that sounds horrible */
+    /* make sure we don't make too big adjustments because that sounds horrible */
     if (new_rate > base_rate * 1.1 || new_rate < base_rate * 0.9)
         new_rate = base_rate;
 
@@ -344,10 +444,13 @@ static int source_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t
                 /* Add the latency internal to our source output on top */
                 pa_bytes_to_usec(pa_memblockq_get_length(u->source_output->thread_info.delay_memblockq), &u->source_output->source->sample_spec) +
                 /* and the buffering we do on the source */
-                pa_bytes_to_usec(u->blocksize, &u->source_output->source->sample_spec);
+                pa_bytes_to_usec(u->source_output_blocksize, &u->source_output->source->sample_spec);
 
             return 0;
 
+        case PA_SOURCE_MESSAGE_SET_VOLUME_SYNCED:
+            u->thread_info.current_volume = u->source->reference_volume;
+            break;
     }
 
     return pa_source_process_msg(o, code, data, offset, chunk);
@@ -396,20 +499,17 @@ static int source_set_state_cb(pa_source *s, pa_source_state_t state) {
         !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
         return 0;
 
-    pa_log_debug("Source state %d %d", state, u->active_mask);
-
     if (state == PA_SOURCE_RUNNING) {
         /* restart timer when both sink and source are active */
-        u->active_mask |= 1;
-        if (u->active_mask == 3)
+        if (IS_ACTIVE(u) && u->adjust_time)
             pa_core_rttime_restart(u->core, u->time_event, pa_rtclock_now() + u->adjust_time);
 
-        pa_atomic_store (&u->request_resync, 1);
+        pa_atomic_store(&u->request_resync, 1);
         pa_source_output_cork(u->source_output, FALSE);
     } else if (state == PA_SOURCE_SUSPENDED) {
-        u->active_mask &= ~1;
         pa_source_output_cork(u->source_output, TRUE);
     }
+
     return 0;
 }
 
@@ -424,24 +524,21 @@ static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
         !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
         return 0;
 
-    pa_log_debug("Sink state %d %d", state, u->active_mask);
-
     if (state == PA_SINK_RUNNING) {
         /* restart timer when both sink and source are active */
-        u->active_mask |= 2;
-        if (u->active_mask == 3)
+        if (IS_ACTIVE(u) && u->adjust_time)
             pa_core_rttime_restart(u->core, u->time_event, pa_rtclock_now() + u->adjust_time);
 
-        pa_atomic_store (&u->request_resync, 1);
+        pa_atomic_store(&u->request_resync, 1);
         pa_sink_input_cork(u->sink_input, FALSE);
     } else if (state == PA_SINK_SUSPENDED) {
-        u->active_mask &= ~2;
         pa_sink_input_cork(u->sink_input, TRUE);
     }
+
     return 0;
 }
 
-/* Called from I/O thread context */
+/* Called from source I/O thread context */
 static void source_update_requested_latency_cb(pa_source *s) {
     struct userdata *u;
 
@@ -460,7 +557,7 @@ static void source_update_requested_latency_cb(pa_source *s) {
             pa_source_get_requested_latency_within_thread(s));
 }
 
-/* Called from I/O thread context */
+/* Called from sink I/O thread context */
 static void sink_update_requested_latency_cb(pa_sink *s) {
     struct userdata *u;
 
@@ -479,7 +576,7 @@ static void sink_update_requested_latency_cb(pa_sink *s) {
             pa_sink_get_requested_latency_within_thread(s));
 }
 
-/* Called from I/O thread context */
+/* Called from sink I/O thread context */
 static void sink_request_rewind_cb(pa_sink *s) {
     struct userdata *u;
 
@@ -508,8 +605,7 @@ static void source_set_volume_cb(pa_source *s) {
         !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
         return;
 
-    /* FIXME, no volume control in source_output, set volume at the master */
-    pa_source_set_volume(u->source_output->source, &s->volume, TRUE);
+    pa_source_output_set_volume(u->source_output, &s->real_volume, s->save_volume, TRUE);
 }
 
 /* Called from main context */
@@ -526,8 +622,10 @@ static void sink_set_volume_cb(pa_sink *s) {
     pa_sink_input_set_volume(u->sink_input, &s->real_volume, s->save_volume, TRUE);
 }
 
+/* Called from main context. */
 static void source_get_volume_cb(pa_source *s) {
     struct userdata *u;
+    pa_cvolume v;
 
     pa_source_assert_ref(s);
     pa_assert_se(u = s->userdata);
@@ -536,18 +634,16 @@ static void source_get_volume_cb(pa_source *s) {
         !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
         return;
 
-    /* FIXME, no volume control in source_output, get the info from the master */
-    pa_source_get_volume(u->source_output->source, TRUE);
+    pa_source_output_get_volume(u->source_output, &v, TRUE);
 
-    if (pa_cvolume_equal(&s->volume,&u->source_output->source->volume))
+    if (pa_cvolume_equal(&s->real_volume, &v))
         /* no change */
         return;
 
-    s->volume = u->source_output->source->volume;
+    s->real_volume = v;
     pa_source_set_soft_volume(s, NULL);
 }
 
-
 /* Called from main context */
 static void source_set_mute_cb(pa_source *s) {
     struct userdata *u;
@@ -559,8 +655,7 @@ static void source_set_mute_cb(pa_source *s) {
         !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
         return;
 
-    /* FIXME, no volume control in source_output, set mute at the master */
-    pa_source_set_mute(u->source_output->source, TRUE, TRUE);
+    pa_source_output_set_mute(u->source_output, s->muted, s->save_muted);
 }
 
 /* Called from main context */
@@ -588,21 +683,20 @@ static void source_get_mute_cb(pa_source *s) {
         !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
         return;
 
-    /* FIXME, no volume control in source_output, get the info from the master */
-    pa_source_get_mute(u->source_output->source, TRUE);
+    pa_source_output_get_mute(u->source_output);
 }
 
-/* must be called from the input thread context */
+/* Called from source I/O thread context. */
 static void apply_diff_time(struct userdata *u, int64_t diff_time) {
     int64_t diff;
 
     if (diff_time < 0) {
-        diff = pa_usec_to_bytes (-diff_time, &u->source_output->sample_spec);
+        diff = pa_usec_to_bytes(-diff_time, &u->sink_input->sample_spec);
 
         if (diff > 0) {
             /* add some extra safety samples to compensate for jitter in the
              * timings */
-            diff += 10 * pa_frame_size (&u->source_output->sample_spec);
+            diff += 10 * pa_frame_size (&u->sink_input->sample_spec);
 
             pa_log("Playback after capture (%lld), drop sink %lld", (long long) diff_time, (long long) diff);
 
@@ -610,10 +704,10 @@ static void apply_diff_time(struct userdata *u, int64_t diff_time) {
             u->source_skip = 0;
         }
     } else if (diff_time > 0) {
-        diff = pa_usec_to_bytes (diff_time, &u->source_output->sample_spec);
+        diff = pa_usec_to_bytes(diff_time, &u->source_output->sample_spec);
 
         if (diff > 0) {
-            pa_log("playback too far ahead (%lld), drop source %lld", (long long) diff_time, (long long) diff);
+            pa_log("Playback too far ahead (%lld), drop source %lld", (long long) diff_time, (long long) diff);
 
             u->source_skip = diff;
             u->sink_skip = 0;
@@ -621,7 +715,7 @@ static void apply_diff_time(struct userdata *u, int64_t diff_time) {
     }
 }
 
-/* must be called from the input thread */
+/* Called from source I/O thread context. */
 static void do_resync(struct userdata *u) {
     int64_t diff_time;
     struct snapshot latency_snapshot;
@@ -639,123 +733,262 @@ static void do_resync(struct userdata *u) {
     apply_diff_time(u, diff_time);
 }
 
-/* Called from input thread context */
+/* 1. Calculate drift at this point, pass to canceller
+ * 2. Push out playback samples in blocksize chunks
+ * 3. Push out capture samples in blocksize chunks
+ * 4. ???
+ * 5. Profit
+ *
+ * Called from source I/O thread context.
+ */
+static void do_push_drift_comp(struct userdata *u) {
+    size_t rlen, plen;
+    pa_memchunk rchunk, pchunk, cchunk;
+    uint8_t *rdata, *pdata, *cdata;
+    float drift;
+    int unused PA_GCC_UNUSED;
+
+    rlen = pa_memblockq_get_length(u->source_memblockq);
+    plen = pa_memblockq_get_length(u->sink_memblockq);
+
+    /* Estimate snapshot drift as follows:
+     *   pd: amount of data consumed since last time
+     *   rd: amount of data consumed since last time
+     *
+     *   drift = (pd - rd) / rd;
+     *
+     * We calculate pd and rd as the memblockq length less the number of
+     * samples left from the last iteration (to avoid double counting
+     * those remainder samples.
+     */
+    drift = ((float)(plen - u->sink_rem) - (rlen - u->source_rem)) / ((float)(rlen - u->source_rem));
+    u->sink_rem = plen % u->sink_blocksize;
+    u->source_rem = rlen % u->source_output_blocksize;
+
+    /* Now let the canceller work its drift compensation magic */
+    u->ec->set_drift(u->ec, drift);
+
+    if (u->save_aec) {
+        if (u->drift_file)
+            fprintf(u->drift_file, "d %a\n", drift);
+    }
+
+    /* Send in the playback samples first */
+    while (plen >= u->sink_blocksize) {
+        pa_memblockq_peek_fixed_size(u->sink_memblockq, u->sink_blocksize, &pchunk);
+        pdata = pa_memblock_acquire(pchunk.memblock);
+        pdata += pchunk.index;
+
+        u->ec->play(u->ec, pdata);
+
+        if (u->save_aec) {
+            if (u->drift_file)
+                fprintf(u->drift_file, "p %d\n", u->sink_blocksize);
+            if (u->played_file)
+                unused = fwrite(pdata, 1, u->sink_blocksize, u->played_file);
+        }
+
+        pa_memblock_release(pchunk.memblock);
+        pa_memblockq_drop(u->sink_memblockq, u->sink_blocksize);
+        pa_memblock_unref(pchunk.memblock);
+
+        plen -= u->sink_blocksize;
+    }
+
+    /* And now the capture samples */
+    while (rlen >= u->source_output_blocksize) {
+        pa_memblockq_peek_fixed_size(u->source_memblockq, u->source_output_blocksize, &rchunk);
+
+        rdata = pa_memblock_acquire(rchunk.memblock);
+        rdata += rchunk.index;
+
+        cchunk.index = 0;
+        cchunk.length = u->source_output_blocksize;
+        cchunk.memblock = pa_memblock_new(u->source->core->mempool, cchunk.length);
+        cdata = pa_memblock_acquire(cchunk.memblock);
+
+        u->ec->record(u->ec, rdata, cdata);
+
+        if (u->save_aec) {
+            if (u->drift_file)
+                fprintf(u->drift_file, "c %d\n", u->source_output_blocksize);
+            if (u->captured_file)
+                unused = fwrite(rdata, 1, u->source_output_blocksize, u->captured_file);
+            if (u->canceled_file)
+                unused = fwrite(cdata, 1, u->source_output_blocksize, u->canceled_file);
+        }
+
+        pa_memblock_release(cchunk.memblock);
+        pa_memblock_release(rchunk.memblock);
+
+        pa_memblock_unref(rchunk.memblock);
+
+        pa_source_post(u->source, &cchunk);
+        pa_memblock_unref(cchunk.memblock);
+
+        pa_memblockq_drop(u->source_memblockq, u->source_output_blocksize);
+        rlen -= u->source_output_blocksize;
+    }
+}
+
+/* This one's simpler than the drift compensation case -- we just iterate over
+ * the capture buffer, and pass the canceller blocksize bytes of playback and
+ * capture data.
+ *
+ * Called from source I/O thread context. */
+static void do_push(struct userdata *u) {
+    size_t rlen, plen;
+    pa_memchunk rchunk, pchunk, cchunk;
+    uint8_t *rdata, *pdata, *cdata;
+    int unused PA_GCC_UNUSED;
+
+    rlen = pa_memblockq_get_length(u->source_memblockq);
+    plen = pa_memblockq_get_length(u->sink_memblockq);
+
+    while (rlen >= u->source_output_blocksize) {
+
+        /* take fixed blocks from recorded and played samples */
+        pa_memblockq_peek_fixed_size(u->source_memblockq, u->source_output_blocksize, &rchunk);
+        pa_memblockq_peek_fixed_size(u->sink_memblockq, u->sink_blocksize, &pchunk);
+
+        /* we ran out of played data and pchunk has been filled with silence bytes */
+        if (plen < u->sink_blocksize)
+            pa_memblockq_seek(u->sink_memblockq, u->sink_blocksize - plen, PA_SEEK_RELATIVE, true);
+
+        rdata = pa_memblock_acquire(rchunk.memblock);
+        rdata += rchunk.index;
+        pdata = pa_memblock_acquire(pchunk.memblock);
+        pdata += pchunk.index;
+
+        cchunk.index = 0;
+        cchunk.length = u->source_blocksize;
+        cchunk.memblock = pa_memblock_new(u->source->core->mempool, cchunk.length);
+        cdata = pa_memblock_acquire(cchunk.memblock);
+
+        if (u->save_aec) {
+            if (u->captured_file)
+                unused = fwrite(rdata, 1, u->source_output_blocksize, u->captured_file);
+            if (u->played_file)
+                unused = fwrite(pdata, 1, u->sink_blocksize, u->played_file);
+        }
+
+        /* perform echo cancellation */
+        u->ec->run(u->ec, rdata, pdata, cdata);
+
+        if (u->save_aec) {
+            if (u->canceled_file)
+                unused = fwrite(cdata, 1, u->source_blocksize, u->canceled_file);
+        }
+
+        pa_memblock_release(cchunk.memblock);
+        pa_memblock_release(pchunk.memblock);
+        pa_memblock_release(rchunk.memblock);
+
+        /* drop consumed source samples */
+        pa_memblockq_drop(u->source_memblockq, u->source_output_blocksize);
+        pa_memblock_unref(rchunk.memblock);
+        rlen -= u->source_output_blocksize;
+
+        /* drop consumed sink samples */
+        pa_memblockq_drop(u->sink_memblockq, u->sink_blocksize);
+        pa_memblock_unref(pchunk.memblock);
+
+        if (plen >= u->sink_blocksize)
+            plen -= u->sink_blocksize;
+        else
+            plen = 0;
+
+        /* forward the (echo-canceled) data to the virtual source */
+        pa_source_post(u->source, &cchunk);
+        pa_memblock_unref(cchunk.memblock);
+    }
+}
+
+/* Called from source I/O thread context. */
 static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) {
     struct userdata *u;
-    size_t rlen, plen;
+    size_t rlen, plen, to_skip;
+    pa_memchunk rchunk;
 
     pa_source_output_assert_ref(o);
     pa_source_output_assert_io_context(o);
     pa_assert_se(u = o->userdata);
 
     if (!PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output))) {
-        pa_log("push when no link?");
+        pa_log("Push when no link?");
         return;
     }
 
-    /* handle queued messages */
-    u->in_push = TRUE;
+    if (PA_UNLIKELY(u->source->thread_info.state != PA_SOURCE_RUNNING ||
+                    u->sink->thread_info.state != PA_SINK_RUNNING)) {
+        pa_source_post(u->source, chunk);
+        return;
+    }
+
+    /* handle queued messages, do any message sending of our own */
     while (pa_asyncmsgq_process_one(u->asyncmsgq) > 0)
         ;
-    u->in_push = FALSE;
-
-    if (pa_atomic_cmpxchg (&u->request_resync, 1, 0)) {
-        do_resync (u);
-    }
 
     pa_memblockq_push_align(u->source_memblockq, chunk);
 
     rlen = pa_memblockq_get_length(u->source_memblockq);
     plen = pa_memblockq_get_length(u->sink_memblockq);
 
-    while (rlen >= u->blocksize) {
-        pa_memchunk rchunk, pchunk;
-
-        /* take fixed block from recorded samples */
-        pa_memblockq_peek_fixed_size(u->source_memblockq, u->blocksize, &rchunk);
-
-        if (plen > u->blocksize && u->source_skip == 0) {
-            uint8_t *rdata, *pdata, *cdata;
-            pa_memchunk cchunk;
-
-            if (u->sink_skip) {
-                size_t to_skip;
-
-                if (u->sink_skip > plen)
-                    to_skip = plen;
-                else
-                    to_skip = u->sink_skip;
+    /* Let's not do anything else till we have enough data to process */
+    if (rlen < u->source_output_blocksize)
+        return;
 
-                pa_memblockq_drop(u->sink_memblockq, to_skip);
-                plen -= to_skip;
+    /* See if we need to drop samples in order to sync */
+    if (pa_atomic_cmpxchg (&u->request_resync, 1, 0)) {
+        do_resync(u);
+    }
 
-                u->sink_skip -= to_skip;
-            }
+    /* Okay, skip cancellation for skipped source samples if needed. */
+    if (PA_UNLIKELY(u->source_skip)) {
+        /* The slightly tricky bit here is that we drop all but modulo
+         * blocksize bytes and then adjust for that last bit on the sink side.
+         * We do this because the source data is coming at a fixed rate, which
+         * means the only way to try to catch up is drop sink samples and let
+         * the canceller cope up with this. */
+        to_skip = rlen >= u->source_skip ? u->source_skip : rlen;
+        to_skip -= to_skip % u->source_output_blocksize;
+
+        if (to_skip) {
+            pa_memblockq_peek_fixed_size(u->source_memblockq, to_skip, &rchunk);
+            pa_source_post(u->source, &rchunk);
+
+            pa_memblock_unref(rchunk.memblock);
+            pa_memblockq_drop(u->source_memblockq, to_skip);
+
+            rlen -= to_skip;
+            u->source_skip -= to_skip;
+        }
 
-            if (plen > u->blocksize && u->sink_skip == 0) {
-                /* take fixed block from played samples */
-                pa_memblockq_peek_fixed_size(u->sink_memblockq, u->blocksize, &pchunk);
-
-                rdata = pa_memblock_acquire(rchunk.memblock);
-                rdata += rchunk.index;
-                pdata = pa_memblock_acquire(pchunk.memblock);
-                pdata += pchunk.index;
-
-                cchunk.index = 0;
-                cchunk.length = u->blocksize;
-                cchunk.memblock = pa_memblock_new(u->source->core->mempool, cchunk.length);
-                cdata = pa_memblock_acquire(cchunk.memblock);
-
-                /* perform echo cancelation */
-                u->ec->run(u->ec, rdata, pdata, cdata);
-
-                if (u->save_aec) {
-                    if (u->captured_file)
-                        fwrite(rdata, 1, u->blocksize, u->captured_file);
-                    if (u->played_file)
-                        fwrite(pdata, 1, u->blocksize, u->played_file);
-                    if (u->canceled_file)
-                        fwrite(cdata, 1, u->blocksize, u->canceled_file);
-                    pa_log_debug("AEC frame saved.");
-                }
-
-                pa_memblock_release(cchunk.memblock);
-                pa_memblock_release(pchunk.memblock);
-                pa_memblock_release(rchunk.memblock);
-
-                /* drop consumed sink samples */
-                pa_memblockq_drop(u->sink_memblockq, u->blocksize);
-                pa_memblock_unref(pchunk.memblock);
-
-                pa_memblock_unref(rchunk.memblock);
-                /* the filtered samples now become the samples from our
-                 * source */
-                rchunk = cchunk;
-
-                plen -= u->blocksize;
-            }
+        if (rlen && u->source_skip % u->source_output_blocksize) {
+            u->sink_skip += (uint64_t) (u->source_output_blocksize - (u->source_skip % u->source_output_blocksize)) * u->sink_blocksize / u->source_output_blocksize;
+            u->source_skip -= (u->source_skip % u->source_output_blocksize);
         }
+    }
 
-        /* forward the (echo-canceled) data to the virtual source */
-        pa_source_post(u->source, &rchunk);
-        pa_memblock_unref(rchunk.memblock);
+    /* And for the sink, these samples have been played back already, so we can
+     * just drop them and get on with it. */
+    if (PA_UNLIKELY(u->sink_skip)) {
+        to_skip = plen >= u->sink_skip ? u->sink_skip : plen;
 
-        pa_memblockq_drop(u->source_memblockq, u->blocksize);
-        rlen -= u->blocksize;
+        pa_memblockq_drop(u->sink_memblockq, to_skip);
 
-        if (u->source_skip) {
-            if (u->source_skip > u->blocksize) {
-                u->source_skip -= u->blocksize;
-            }
-            else {
-                u->sink_skip += (u->blocksize - u->source_skip);
-                u->source_skip = 0;
-            }
-        }
+        plen -= to_skip;
+        u->sink_skip -= to_skip;
     }
+
+    /* process and push out samples */
+    if (u->ec->params.drift_compensation)
+        do_push_drift_comp(u);
+    else
+        do_push(u);
 }
 
-/* Called from I/O thread context */
+/* Called from sink I/O thread context. */
 static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
     struct userdata *u;
 
@@ -770,7 +1003,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
 
     if (i->thread_info.underrun_for > 0) {
         pa_log_debug("Handling end of underrun.");
-        pa_atomic_store (&u->request_resync, 1);
+        pa_atomic_store(&u->request_resync, 1);
     }
 
     /* let source thread handle the chunk. pass the sample count as well so that
@@ -782,7 +1015,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
     return 0;
 }
 
-/* Called from input thread context */
+/* Called from source I/O thread context. */
 static void source_output_process_rewind_cb(pa_source_output *o, size_t nbytes) {
     struct userdata *u;
 
@@ -802,7 +1035,7 @@ static void source_output_process_rewind_cb(pa_source_output *o, size_t nbytes)
         (long long) pa_memblockq_get_length (u->source_memblockq));
 }
 
-/* Called from I/O thread context */
+/* Called from sink I/O thread context. */
 static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
     struct userdata *u;
 
@@ -817,6 +1050,7 @@ static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
     u->send_counter -= nbytes;
 }
 
+/* Called from source I/O thread context. */
 static void source_output_snapshot_within_thread(struct userdata *u, struct snapshot *snapshot) {
     size_t delay, rlen, plen;
     pa_usec_t now, latency;
@@ -837,8 +1071,7 @@ static void source_output_snapshot_within_thread(struct userdata *u, struct snap
     snapshot->plen = plen + u->source_skip;
 }
 
-
-/* Called from output thread context */
+/* Called from source I/O thread context. */
 static int source_output_process_msg_cb(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
     struct userdata *u = PA_SOURCE_OUTPUT(obj)->userdata;
 
@@ -848,7 +1081,7 @@ static int source_output_process_msg_cb(pa_msgobject *obj, int code, void *data,
 
             pa_source_output_assert_io_context(u->source_output);
 
-            if (PA_SOURCE_IS_OPENED(u->source_output->source->thread_info.state))
+            if (u->source_output->source->thread_info.state == PA_SOURCE_RUNNING)
                 pa_memblockq_push_align(u->sink_memblockq, chunk);
             else
                 pa_memblockq_flush_write(u->sink_memblockq, TRUE);
@@ -888,6 +1121,7 @@ static int source_output_process_msg_cb(pa_msgobject *obj, int code, void *data,
     return pa_source_output_process_msg(obj, code, data, offset, chunk);
 }
 
+/* Called from sink I/O thread context. */
 static int sink_input_process_msg_cb(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
     struct userdata *u = PA_SINK_INPUT(obj)->userdata;
 
@@ -917,7 +1151,7 @@ static int sink_input_process_msg_cb(pa_msgobject *obj, int code, void *data, in
     return pa_sink_input_process_msg(obj, code, data, offset, chunk);
 }
 
-/* Called from I/O thread context */
+/* Called from sink I/O thread context. */
 static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
     struct userdata *u;
 
@@ -926,11 +1160,13 @@ static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
 
     pa_log_debug("Sink input update max rewind %lld", (long long) nbytes);
 
-    pa_memblockq_set_maxrewind (u->sink_memblockq, nbytes);
+    /* FIXME: Too small max_rewind:
+     * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
+    pa_memblockq_set_maxrewind(u->sink_memblockq, nbytes);
     pa_sink_set_max_rewind_within_thread(u->sink, nbytes);
 }
 
-/* Called from I/O thread context */
+/* Called from source I/O thread context. */
 static void source_output_update_max_rewind_cb(pa_source_output *o, size_t nbytes) {
     struct userdata *u;
 
@@ -942,7 +1178,7 @@ static void source_output_update_max_rewind_cb(pa_source_output *o, size_t nbyte
     pa_source_set_max_rewind_within_thread(u->source, nbytes);
 }
 
-/* Called from I/O thread context */
+/* Called from sink I/O thread context. */
 static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) {
     struct userdata *u;
 
@@ -954,7 +1190,7 @@ static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) {
     pa_sink_set_max_request_within_thread(u->sink, nbytes);
 }
 
-/* Called from I/O thread context */
+/* Called from sink I/O thread context. */
 static void sink_input_update_sink_requested_latency_cb(pa_sink_input *i) {
     struct userdata *u;
     pa_usec_t latency;
@@ -967,7 +1203,7 @@ static void sink_input_update_sink_requested_latency_cb(pa_sink_input *i) {
     pa_log_debug("Sink input update requested latency %lld", (long long) latency);
 }
 
-/* Called from I/O thread context */
+/* Called from source I/O thread context. */
 static void source_output_update_source_requested_latency_cb(pa_source_output *o) {
     struct userdata *u;
     pa_usec_t latency;
@@ -977,10 +1213,10 @@ static void source_output_update_source_requested_latency_cb(pa_source_output *o
 
     latency = pa_source_get_requested_latency_within_thread(o->source);
 
-    pa_log_debug("source output update requested latency %lld", (long long) latency);
+    pa_log_debug("Source output update requested latency %lld", (long long) latency);
 }
 
-/* Called from I/O thread context */
+/* Called from sink I/O thread context. */
 static void sink_input_update_sink_latency_range_cb(pa_sink_input *i) {
     struct userdata *u;
 
@@ -994,7 +1230,7 @@ static void sink_input_update_sink_latency_range_cb(pa_sink_input *i) {
     pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
 }
 
-/* Called from I/O thread context */
+/* Called from source I/O thread context. */
 static void source_output_update_source_latency_range_cb(pa_source_output *o) {
     struct userdata *u;
 
@@ -1008,7 +1244,7 @@ static void source_output_update_source_latency_range_cb(pa_source_output *o) {
     pa_source_set_latency_range_within_thread(u->source, o->source->thread_info.min_latency, o->source->thread_info.max_latency);
 }
 
-/* Called from I/O thread context */
+/* Called from sink I/O thread context. */
 static void sink_input_update_sink_fixed_latency_cb(pa_sink_input *i) {
     struct userdata *u;
 
@@ -1021,7 +1257,7 @@ static void sink_input_update_sink_fixed_latency_cb(pa_sink_input *i) {
     pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
 }
 
-/* Called from I/O thread context */
+/* Called from source I/O thread context. */
 static void source_output_update_source_fixed_latency_cb(pa_source_output *o) {
     struct userdata *u;
 
@@ -1034,7 +1270,7 @@ static void source_output_update_source_fixed_latency_cb(pa_source_output *o) {
     pa_source_set_fixed_latency_within_thread(u->source, o->source->thread_info.fixed_latency);
 }
 
-/* Called from output thread context */
+/* Called from source I/O thread context. */
 static void source_output_attach_cb(pa_source_output *o) {
     struct userdata *u;
 
@@ -1047,7 +1283,7 @@ static void source_output_attach_cb(pa_source_output *o) {
     pa_source_set_fixed_latency_within_thread(u->source, o->source->thread_info.fixed_latency);
     pa_source_set_max_rewind_within_thread(u->source, pa_source_output_get_max_rewind(o));
 
-    pa_log_debug("Source output %p attach", o);
+    pa_log_debug("Source output %d attach", o->index);
 
     pa_source_attach_within_thread(u->source);
 
@@ -1057,7 +1293,7 @@ static void source_output_attach_cb(pa_source_output *o) {
             u->asyncmsgq);
 }
 
-/* Called from I/O thread context */
+/* Called from sink I/O thread context. */
 static void sink_input_attach_cb(pa_sink_input *i) {
     struct userdata *u;
 
@@ -1075,9 +1311,12 @@ static void sink_input_attach_cb(pa_sink_input *i) {
      * pa_sink_input_get_max_request(i) UP TO MULTIPLES OF IT
      * HERE. SEE (6) */
     pa_sink_set_max_request_within_thread(u->sink, pa_sink_input_get_max_request(i));
+
+    /* FIXME: Too small max_rewind:
+     * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
     pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i));
 
-    pa_log_debug("Sink input %p attach", i);
+    pa_log_debug("Sink input %d attach", i->index);
 
     u->rtpoll_item_write = pa_rtpoll_item_new_asyncmsgq_write(
             i->sink->thread_info.rtpoll,
@@ -1088,7 +1327,7 @@ static void sink_input_attach_cb(pa_sink_input *i) {
 }
 
 
-/* Called from output thread context */
+/* Called from source I/O thread context. */
 static void source_output_detach_cb(pa_source_output *o) {
     struct userdata *u;
 
@@ -1099,7 +1338,7 @@ static void source_output_detach_cb(pa_source_output *o) {
     pa_source_detach_within_thread(u->source);
     pa_source_set_rtpoll(u->source, NULL);
 
-    pa_log_debug("Source output %p detach", o);
+    pa_log_debug("Source output %d detach", o->index);
 
     if (u->rtpoll_item_read) {
         pa_rtpoll_item_free(u->rtpoll_item_read);
@@ -1107,7 +1346,7 @@ static void source_output_detach_cb(pa_source_output *o) {
     }
 }
 
-/* Called from I/O thread context */
+/* Called from sink I/O thread context. */
 static void sink_input_detach_cb(pa_sink_input *i) {
     struct userdata *u;
 
@@ -1118,7 +1357,7 @@ static void sink_input_detach_cb(pa_sink_input *i) {
 
     pa_sink_set_rtpoll(u->sink, NULL);
 
-    pa_log_debug("Sink input %p detach", i);
+    pa_log_debug("Sink input %d detach", i->index);
 
     if (u->rtpoll_item_write) {
         pa_rtpoll_item_free(u->rtpoll_item_write);
@@ -1126,7 +1365,7 @@ static void sink_input_detach_cb(pa_sink_input *i) {
     }
 }
 
-/* Called from output thread context */
+/* Called from source I/O thread context. */
 static void source_output_state_change_cb(pa_source_output *o, pa_source_output_state_t state) {
     struct userdata *u;
 
@@ -1134,17 +1373,17 @@ static void source_output_state_change_cb(pa_source_output *o, pa_source_output_
     pa_source_output_assert_io_context(o);
     pa_assert_se(u = o->userdata);
 
-    pa_log_debug("Source output %p state %d", o, state);
+    pa_log_debug("Source output %d state %d", o->index, state);
 }
 
-/* Called from IO thread context */
+/* Called from sink I/O thread context. */
 static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t state) {
     struct userdata *u;
 
     pa_sink_input_assert_ref(i);
     pa_assert_se(u = i->userdata);
 
-    pa_log_debug("Sink input %p state %d", i, state);
+    pa_log_debug("Sink input %d state %d", i->index, state);
 
     /* If we are added for the first time, ask for a rewinding so that
      * we are heard right-away. */
@@ -1155,7 +1394,7 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s
     }
 }
 
-/* Called from main thread */
+/* Called from main context. */
 static void source_output_kill_cb(pa_source_output *o) {
     struct userdata *u;
 
@@ -1163,6 +1402,8 @@ static void source_output_kill_cb(pa_source_output *o) {
     pa_assert_ctl_context();
     pa_assert_se(u = o->userdata);
 
+    u->dead = TRUE;
+
     /* The order here matters! We first kill the source output, followed
      * by the source. That means the source callbacks must be protected
      * against an unconnected source output! */
@@ -1175,7 +1416,7 @@ static void source_output_kill_cb(pa_source_output *o) {
     pa_source_unref(u->source);
     u->source = NULL;
 
-    pa_log_debug("Source output kill %p", o);
+    pa_log_debug("Source output kill %d", o->index);
 
     pa_module_unload_request(u->module, TRUE);
 }
@@ -1187,6 +1428,8 @@ static void sink_input_kill_cb(pa_sink_input *i) {
     pa_sink_input_assert_ref(i);
     pa_assert_se(u = i->userdata);
 
+    u->dead = TRUE;
+
     /* The order here matters! We first kill the sink input, followed
      * by the sink. That means the sink callbacks must be protected
      * against an unconnected sink input! */
@@ -1199,12 +1442,12 @@ static void sink_input_kill_cb(pa_sink_input *i) {
     pa_sink_unref(u->sink);
     u->sink = NULL;
 
-    pa_log_debug("Sink input kill %p", i);
+    pa_log_debug("Sink input kill %d", i->index);
 
     pa_module_unload_request(u->module, TRUE);
 }
 
-/* Called from main thread */
+/* Called from main context. */
 static pa_bool_t source_output_may_move_to_cb(pa_source_output *o, pa_source *dest) {
     struct userdata *u;
 
@@ -1212,6 +1455,9 @@ static pa_bool_t source_output_may_move_to_cb(pa_source_output *o, pa_source *de
     pa_assert_ctl_context();
     pa_assert_se(u = o->userdata);
 
+    if (u->dead || u->autoloaded)
+        return FALSE;
+
     return (u->source != dest) && (u->sink != dest->monitor_of);
 }
 
@@ -1222,10 +1468,13 @@ static pa_bool_t sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
     pa_sink_input_assert_ref(i);
     pa_assert_se(u = i->userdata);
 
+    if (u->dead || u->autoloaded)
+        return FALSE;
+
     return u->sink != dest;
 }
 
-/* Called from main thread */
+/* Called from main context. */
 static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
     struct userdata *u;
 
@@ -1240,13 +1489,14 @@ static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
         pa_source_set_asyncmsgq(u->source, NULL);
 
     if (u->source_auto_desc && dest) {
-        const char *z;
+        const char *y, *z;
         pa_proplist *pl;
 
         pl = pa_proplist_new();
+        y = pa_proplist_gets(u->sink_input->sink->proplist, PA_PROP_DEVICE_DESCRIPTION);
         z = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
-        pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "Echo-Cancel Source %s on %s",
-                         pa_proplist_gets(u->source->proplist, "device.echo-cancel.name"), z ? z : dest->name);
+        pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "%s (echo cancelled with %s)", z ? z : dest->name,
+                y ? y : u->sink_input->sink->name);
 
         pa_source_update_proplist(u->source, PA_UPDATE_REPLACE, pl);
         pa_proplist_free(pl);
@@ -1267,13 +1517,14 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
         pa_sink_set_asyncmsgq(u->sink, NULL);
 
     if (u->sink_auto_desc && dest) {
-        const char *z;
+        const char *y, *z;
         pa_proplist *pl;
 
         pl = pa_proplist_new();
+        y = pa_proplist_gets(u->source_output->source->proplist, PA_PROP_DEVICE_DESCRIPTION);
         z = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
-        pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "Echo-Cancel Sink %s on %s",
-                         pa_proplist_gets(u->sink->proplist, "device.echo-cancel.name"), z ? z : dest->name);
+        pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "%s (echo cancelled with %s)", z ? z : dest->name,
+                         y ? y : u->source_output->source->name);
 
         pa_sink_update_proplist(u->sink, PA_UPDATE_REPLACE, pl);
         pa_proplist_free(pl);
@@ -1300,20 +1551,212 @@ static void sink_input_mute_changed_cb(pa_sink_input *i) {
     pa_sink_mute_changed(u->sink, i->muted);
 }
 
-static pa_echo_canceller_method_t get_ec_method_from_string(const char *method)
-{
-    if (strcmp(method, "speex") == 0)
+/* Called from main context */
+static int canceller_process_msg_cb(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
+    struct pa_echo_canceller_msg *msg;
+    struct userdata *u;
+
+    pa_assert(o);
+
+    msg = PA_ECHO_CANCELLER_MSG(o);
+    u = msg->userdata;
+
+    switch (code) {
+        case ECHO_CANCELLER_MESSAGE_SET_VOLUME: {
+            pa_cvolume *v = (pa_cvolume *) userdata;
+
+            if (u->use_volume_sharing)
+                pa_source_set_volume(u->source, v, TRUE, FALSE);
+            else
+                pa_source_output_set_volume(u->source_output, v, FALSE, TRUE);
+
+            break;
+        }
+
+        default:
+            pa_assert_not_reached();
+            break;
+    }
+
+    return 0;
+}
+
+/* Called by the canceller, so source I/O thread context. */
+void pa_echo_canceller_get_capture_volume(pa_echo_canceller *ec, pa_cvolume *v) {
+    *v = ec->msg->userdata->thread_info.current_volume;
+}
+
+/* Called by the canceller, so source I/O thread context. */
+void pa_echo_canceller_set_capture_volume(pa_echo_canceller *ec, pa_cvolume *v) {
+    if (!pa_cvolume_equal(&ec->msg->userdata->thread_info.current_volume, v)) {
+        pa_cvolume *vol = pa_xnewdup(pa_cvolume, v, 1);
+
+        pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(ec->msg), ECHO_CANCELLER_MESSAGE_SET_VOLUME, vol, 0, NULL,
+                pa_xfree);
+    }
+}
+
+uint32_t pa_echo_canceller_blocksize_power2(unsigned rate, unsigned ms) {
+    unsigned nframes = (rate * ms) / 1000;
+    uint32_t y = 1 << ((8 * sizeof(uint32_t)) - 2);
+
+    assert(rate >= 4000);
+    assert(ms >= 1);
+
+    /* nframes should be a power of 2, round down to nearest power of two */
+    while (y > nframes)
+        y >>= 1;
+
+    assert(y >= 1);
+    return y;
+}
+
+static pa_echo_canceller_method_t get_ec_method_from_string(const char *method) {
+    if (pa_streq(method, "null"))
+        return PA_ECHO_CANCELLER_NULL;
+#ifdef HAVE_SPEEX
+    if (pa_streq(method, "speex"))
         return PA_ECHO_CANCELLER_SPEEX;
-    else if (strcmp(method, "adrian") == 0)
+#endif
+#ifdef HAVE_ADRIAN_EC
+    if (pa_streq(method, "adrian"))
         return PA_ECHO_CANCELLER_ADRIAN;
-    else
-        return PA_ECHO_CANCELLER_INVALID;
+#endif
+#ifdef HAVE_WEBRTC
+    if (pa_streq(method, "webrtc"))
+        return PA_ECHO_CANCELLER_WEBRTC;
+#endif
+    return PA_ECHO_CANCELLER_INVALID;
+}
+
+/* Common initialisation bits between module-echo-cancel and the standalone
+ * test program.
+ *
+ * Called from main context. */
+static int init_common(pa_modargs *ma, struct userdata *u, pa_sample_spec *source_ss, pa_channel_map *source_map) {
+    const char *ec_string;
+    pa_echo_canceller_method_t ec_method;
+
+    if (pa_modargs_get_sample_spec_and_channel_map(ma, source_ss, source_map, PA_CHANNEL_MAP_DEFAULT) < 0) {
+        pa_log("Invalid sample format specification or channel map");
+        goto fail;
+    }
+
+    u->ec = pa_xnew0(pa_echo_canceller, 1);
+    if (!u->ec) {
+        pa_log("Failed to alloc echo canceller");
+        goto fail;
+    }
+
+    ec_string = pa_modargs_get_value(ma, "aec_method", DEFAULT_ECHO_CANCELLER);
+    if ((ec_method = get_ec_method_from_string(ec_string)) < 0) {
+        pa_log("Invalid echo canceller implementation '%s'", ec_string);
+        goto fail;
+    }
+
+    pa_log_info("Using AEC engine: %s", ec_string);
+
+    u->ec->init = ec_table[ec_method].init;
+    u->ec->play = ec_table[ec_method].play;
+    u->ec->record = ec_table[ec_method].record;
+    u->ec->set_drift = ec_table[ec_method].set_drift;
+    u->ec->run = ec_table[ec_method].run;
+    u->ec->done = ec_table[ec_method].done;
+
+    u->ec->tx_agc = DEFAULT_AGC_ENABLED;
+    if (pa_modargs_get_value_boolean(ma, "agc", &u->ec->tx_agc) < 0) {
+        pa_log("Failed to parse agc value");
+        goto fail;
+    }
+
+    u->ec->tx_denoise = DEFAULT_DENOISE_ENABLED;
+    if (pa_modargs_get_value_boolean(ma, "denoise", &u->ec->tx_denoise) < 0) {
+        pa_log("Failed to parse denoise value");
+        goto fail;
+    }
+
+    u->ec->echo_suppress = DEFAULT_ECHO_SUPPRESS_ENABLED;
+    if (pa_modargs_get_value_boolean(ma, "echo_suppress", &u->ec->echo_suppress) < 0) {
+        pa_log("Failed to parse echo_suppress value");
+        goto fail;
+    }
+#ifdef HAVE_SPEEX
+    if (u->ec->echo_suppress && ec_method != PA_ECHO_CANCELLER_SPEEX) {
+        pa_log("Echo suppression is only useful with the speex canceller");
+        goto fail;
+    }
+#endif
+
+    u->ec->echo_suppress_attenuation = DEFAULT_ECHO_SUPPRESS_ATTENUATION;
+    if (pa_modargs_get_value_s32(ma, "echo_suppress_attenuation", &u->ec->echo_suppress_attenuation) < 0) {
+        pa_log("Failed to parse echo_suppress_attenuation value");
+        goto fail;
+    }
+    if (u->ec->echo_suppress_attenuation > 0) {
+        pa_log("echo_suppress_attenuation should be a negative dB value");
+        goto fail;
+    }
+
+    u->ec->echo_suppress_attenuation_active = DEFAULT_ECHO_SUPPRESS_ATTENUATION;
+    if (pa_modargs_get_value_s32(ma, "echo_suppress_attenuation_active", &u->ec->echo_suppress_attenuation_active) < 0) {
+        pa_log("Failed to parse echo_supress_attenuation_active value");
+        goto fail;
+    }
+    if (u->ec->echo_suppress_attenuation_active > 0) {
+        pa_log("echo_suppress_attenuation_active should be a negative dB value");
+        goto fail;
+    }
+    return 0;
+
+fail:
+    return -1;
+}
+
+static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
+       uint32_t command;
+       uint32_t value;
+       struct userdata *u = NULL;
+       pa_tagstruct *reply = NULL;
+       pa_assert(p);
+       pa_assert(m);
+       pa_assert(c);
+       pa_assert(t);
+
+       u = m->userdata;
+
+       if (pa_tagstruct_getu32(t, &command) < 0)
+       goto fail;
+
+       reply = pa_tagstruct_new(NULL, 0);
+       pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
+       pa_tagstruct_putu32(reply, tag);
+
+       switch (command) {
+               case AEC_SET_VOLUME: {
+                       pa_tagstruct_getu32(t,&value);
+                       pa_log_debug("AEC_SET_VOLUME in echo cancel = %d",value);
+               break;
+       }
+               case AEC_SET_DEVICE: {
+                       pa_tagstruct_getu32(t,&value);
+                       pa_log_debug("AEC_SET_DEVICE in echo cancel = %d",value);
+               break;
+       }
+       default:
+               goto fail;
+       }
+       pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply);
+       return 0;
+
+fail:
+       return -1;
 }
 
+/* Called from main context. */
 int pa__init(pa_module*m) {
     struct userdata *u;
-    pa_sample_spec source_ss, sink_ss;
-    pa_channel_map source_map, sink_map;
+    pa_sample_spec source_output_ss, source_ss, sink_ss;
+    pa_channel_map source_output_map, source_map, sink_map;
     pa_modargs *ma;
     pa_source *source_master=NULL;
     pa_sink *sink_master=NULL;
@@ -1322,8 +1765,8 @@ int pa__init(pa_module*m) {
     pa_source_new_data source_data;
     pa_sink_new_data sink_data;
     pa_memchunk silence;
-    pa_echo_canceller_method_t ec_method;
-    uint32_t adjust_time_sec;
+    uint32_t temp;
+    uint32_t nframes = 0;
 
     pa_assert(m);
 
@@ -1344,13 +1787,16 @@ int pa__init(pa_module*m) {
     }
     pa_assert(sink_master);
 
-    source_ss = source_master->sample_spec;
-    source_map = source_master->channel_map;
-    if (pa_modargs_get_sample_spec_and_channel_map(ma, &source_ss, &source_map, PA_CHANNEL_MAP_DEFAULT) < 0) {
-        pa_log("Invalid sample format specification or channel map");
+    if (source_master->monitor_of == sink_master) {
+        pa_log("Can't cancel echo between a sink and its monitor");
         goto fail;
     }
 
+    source_ss = source_master->sample_spec;
+    source_ss.rate = DEFAULT_RATE;
+    source_ss.channels = DEFAULT_CHANNELS;
+    pa_channel_map_init_auto(&source_map, source_ss.channels, PA_CHANNEL_MAP_DEFAULT);
+
     sink_ss = sink_master->sample_spec;
     sink_map = sink_master->channel_map;
 
@@ -1362,48 +1808,78 @@ int pa__init(pa_module*m) {
     u->core = m->core;
     u->module = m;
     m->userdata = u;
+    u->dead = FALSE;
 
-    u->ec = pa_xnew0(pa_echo_canceller, 1);
-    if (!u->ec) {
-        pa_log("Failed to alloc echo canceller");
+    u->use_volume_sharing = TRUE;
+    if (pa_modargs_get_value_boolean(ma, "use_volume_sharing", &u->use_volume_sharing) < 0) {
+        pa_log("use_volume_sharing= expects a boolean argument");
         goto fail;
     }
 
-    if ((ec_method = get_ec_method_from_string(pa_modargs_get_value(ma, "aec_method", DEFAULT_ECHO_CANCELLER))) < 0) {
-        pa_log("Invalid echo canceller implementation");
+    temp = DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC;
+    if (pa_modargs_get_value_u32(ma, "adjust_time", &temp) < 0) {
+        pa_log("Failed to parse adjust_time value");
         goto fail;
     }
 
-    u->ec->init = ec_table[ec_method].init;
-    u->ec->run = ec_table[ec_method].run;
-    u->ec->done = ec_table[ec_method].done;
+    if (temp != DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC)
+        u->adjust_time = temp * PA_USEC_PER_SEC;
+    else
+        u->adjust_time = DEFAULT_ADJUST_TIME_USEC;
 
-    adjust_time_sec = DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC;
-    if (pa_modargs_get_value_u32(ma, "adjust_time", &adjust_time_sec) < 0) {
-        pa_log("Failed to parse adjust_time value");
+    temp = DEFAULT_ADJUST_TOLERANCE / PA_USEC_PER_MSEC;
+    if (pa_modargs_get_value_u32(ma, "adjust_threshold", &temp) < 0) {
+        pa_log("Failed to parse adjust_threshold value");
         goto fail;
     }
 
-    if (adjust_time_sec != DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC)
-        u->adjust_time = adjust_time_sec * PA_USEC_PER_SEC;
+    if (temp != DEFAULT_ADJUST_TOLERANCE / PA_USEC_PER_MSEC)
+        u->adjust_threshold = temp * PA_USEC_PER_MSEC;
     else
-        u->adjust_time = DEFAULT_ADJUST_TIME_USEC;
+        u->adjust_threshold = DEFAULT_ADJUST_TOLERANCE;
 
     u->save_aec = DEFAULT_SAVE_AEC;
-    if (pa_modargs_get_value_u32(ma, "save_aec", &u->save_aec) < 0) {
+    if (pa_modargs_get_value_boolean(ma, "save_aec", &u->save_aec) < 0) {
         pa_log("Failed to parse save_aec value");
         goto fail;
     }
 
+    u->autoloaded = DEFAULT_AUTOLOADED;
+    if (pa_modargs_get_value_boolean(ma, "autoloaded", &u->autoloaded) < 0) {
+        pa_log("Failed to parse autoloaded value");
+        goto fail;
+    }
+
+    if (init_common(ma, u, &source_ss, &source_map) < 0)
+        goto fail;
+
     u->asyncmsgq = pa_asyncmsgq_new(0);
     u->need_realign = TRUE;
-    if (u->ec->init) {
-        if (!u->ec->init(u->core, u->ec, &source_ss, &source_map, &sink_ss, &sink_map, &u->blocksize, pa_modargs_get_value(ma, "aec_args", NULL))) {
-            pa_log("Failed to init AEC engine");
-            goto fail;
-        }
+
+    source_output_ss = source_ss;
+    source_output_map = source_map;
+
+    if (sink_ss.rate != source_ss.rate) {
+        pa_log_info("Sample rates of play and out stream differ. Adjusting rate of play stream.");
+        sink_ss.rate = source_ss.rate;
     }
 
+    pa_assert(u->ec->init);
+    if (!u->ec->init(u->core, u->ec, &source_output_ss, &source_output_map, &sink_ss, &sink_map, &source_ss, &source_map, &nframes, pa_modargs_get_value(ma, "aec_args", NULL))) {
+        pa_log("Failed to init AEC engine");
+        goto fail;
+    }
+
+    pa_assert(source_output_ss.rate == source_ss.rate);
+    pa_assert(sink_ss.rate == source_ss.rate);
+
+    u->source_output_blocksize = nframes * pa_frame_size(&source_output_ss);
+    u->source_blocksize = nframes * pa_frame_size(&source_ss);
+    u->sink_blocksize = nframes * pa_frame_size(&sink_ss);
+
+    if (u->ec->params.drift_compensation)
+        pa_assert(u->ec->set_drift);
+
     /* Create source */
     pa_source_new_data_init(&source_data);
     source_data.driver = __FILE__;
@@ -1414,8 +1890,8 @@ int pa__init(pa_module*m) {
     pa_source_new_data_set_channel_map(&source_data, &source_map);
     pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, source_master->name);
     pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
-    pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
-    pa_proplist_sets(source_data.proplist, "device.echo-cancel.name", source_data.name);
+    if (!u->autoloaded)
+        pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
 
     if (pa_modargs_get_proplist(ma, "source_properties", source_data.proplist, PA_UPDATE_REPLACE) < 0) {
         pa_log("Invalid properties");
@@ -1424,15 +1900,16 @@ int pa__init(pa_module*m) {
     }
 
     if ((u->source_auto_desc = !pa_proplist_contains(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
-        const char *z;
+        const char *y, *z;
 
+        y = pa_proplist_gets(sink_master->proplist, PA_PROP_DEVICE_DESCRIPTION);
         z = pa_proplist_gets(source_master->proplist, PA_PROP_DEVICE_DESCRIPTION);
-        pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Echo-Cancel Source %s on %s", source_data.name, z ? z : source_master->name);
+        pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "%s (echo cancelled with %s)",
+                z ? z : source_master->name, y ? y : sink_master->name);
     }
 
-    u->source = pa_source_new(m->core, &source_data,
-                          PA_SOURCE_HW_MUTE_CTRL|PA_SOURCE_HW_VOLUME_CTRL|PA_SOURCE_DECIBEL_VOLUME|
-                          (source_master->flags & (PA_SOURCE_LATENCY|PA_SOURCE_DYNAMIC_LATENCY)));
+    u->source = pa_source_new(m->core, &source_data, (source_master->flags & (PA_SOURCE_LATENCY | PA_SOURCE_DYNAMIC_LATENCY))
+                                                     | (u->use_volume_sharing ? PA_SOURCE_SHARE_VOLUME_WITH_MASTER : 0));
     pa_source_new_data_done(&source_data);
 
     if (!u->source) {
@@ -1443,10 +1920,13 @@ int pa__init(pa_module*m) {
     u->source->parent.process_msg = source_process_msg_cb;
     u->source->set_state = source_set_state_cb;
     u->source->update_requested_latency = source_update_requested_latency_cb;
-    u->source->set_volume = source_set_volume_cb;
-    u->source->set_mute = source_set_mute_cb;
-    u->source->get_volume = source_get_volume_cb;
-    u->source->get_mute = source_get_mute_cb;
+    pa_source_set_get_mute_callback(u->source, source_get_mute_cb);
+    pa_source_set_set_mute_callback(u->source, source_set_mute_cb);
+    if (!u->use_volume_sharing) {
+        pa_source_set_get_volume_callback(u->source, source_get_volume_cb);
+        pa_source_set_set_volume_callback(u->source, source_set_volume_cb);
+        pa_source_enable_decibel_volume(u->source, TRUE);
+    }
     u->source->userdata = u;
 
     pa_source_set_asyncmsgq(u->source, source_master->asyncmsgq);
@@ -1461,8 +1941,8 @@ int pa__init(pa_module*m) {
     pa_sink_new_data_set_channel_map(&sink_data, &sink_map);
     pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, sink_master->name);
     pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
-    pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
-    pa_proplist_sets(sink_data.proplist, "device.echo-cancel.name", sink_data.name);
+    if (!u->autoloaded)
+        pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
 
     if (pa_modargs_get_proplist(ma, "sink_properties", sink_data.proplist, PA_UPDATE_REPLACE) < 0) {
         pa_log("Invalid properties");
@@ -1471,15 +1951,16 @@ int pa__init(pa_module*m) {
     }
 
     if ((u->sink_auto_desc = !pa_proplist_contains(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
-        const char *z;
+        const char *y, *z;
 
+        y = pa_proplist_gets(source_master->proplist, PA_PROP_DEVICE_DESCRIPTION);
         z = pa_proplist_gets(sink_master->proplist, PA_PROP_DEVICE_DESCRIPTION);
-        pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Echo-Cancel Sink %s on %s", sink_data.name, z ? z : sink_master->name);
+        pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "%s (echo cancelled with %s)",
+                z ? z : sink_master->name, y ? y : source_master->name);
     }
 
-    u->sink = pa_sink_new(m->core, &sink_data,
-                          PA_SINK_HW_MUTE_CTRL|PA_SINK_HW_VOLUME_CTRL|PA_SINK_DECIBEL_VOLUME|
-                          (sink_master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY)));
+    u->sink = pa_sink_new(m->core, &sink_data, (sink_master->flags & (PA_SINK_LATENCY | PA_SINK_DYNAMIC_LATENCY))
+                                               | (u->use_volume_sharing ? PA_SINK_SHARE_VOLUME_WITH_MASTER : 0));
     pa_sink_new_data_done(&sink_data);
 
     if (!u->sink) {
@@ -1491,8 +1972,11 @@ int pa__init(pa_module*m) {
     u->sink->set_state = sink_set_state_cb;
     u->sink->update_requested_latency = sink_update_requested_latency_cb;
     u->sink->request_rewind = sink_request_rewind_cb;
-    u->sink->set_volume = sink_set_volume_cb;
-    u->sink->set_mute = sink_set_mute_cb;
+    pa_sink_set_set_mute_callback(u->sink, sink_set_mute_cb);
+    if (!u->use_volume_sharing) {
+        pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
+        pa_sink_enable_decibel_volume(u->sink, TRUE);
+    }
     u->sink->userdata = u;
 
     pa_sink_set_asyncmsgq(u->sink, sink_master->asyncmsgq);
@@ -1501,14 +1985,13 @@ int pa__init(pa_module*m) {
     pa_source_output_new_data_init(&source_output_data);
     source_output_data.driver = __FILE__;
     source_output_data.module = m;
-    source_output_data.source = source_master;
-    /* FIXME
-       source_output_data.flags = PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND; */
+    pa_source_output_new_data_set_source(&source_output_data, source_master, FALSE);
+    source_output_data.destination_source = u->source;
 
     pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_NAME, "Echo-Cancel Source Stream");
     pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
-    pa_source_output_new_data_set_sample_spec(&source_output_data, &source_ss);
-    pa_source_output_new_data_set_channel_map(&source_output_data, &source_map);
+    pa_source_output_new_data_set_sample_spec(&source_output_data, &source_output_ss);
+    pa_source_output_new_data_set_channel_map(&source_output_data, &source_output_map);
 
     pa_source_output_new(&u->source_output, m->core, &source_output_data);
     pa_source_output_new_data_done(&source_output_data);
@@ -1531,11 +2014,14 @@ int pa__init(pa_module*m) {
     u->source_output->moving = source_output_moving_cb;
     u->source_output->userdata = u;
 
+    u->source->output_from_master = u->source_output;
+
     /* Create sink input */
     pa_sink_input_new_data_init(&sink_input_data);
     sink_input_data.driver = __FILE__;
     sink_input_data.module = m;
-    sink_input_data.sink = sink_master;
+    pa_sink_input_new_data_set_sink(&sink_input_data, sink_master, FALSE);
+    sink_input_data.origin_sink = u->sink;
     pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Echo-Cancel Sink Stream");
     pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
     pa_sink_input_new_data_set_sample_spec(&sink_input_data, &sink_ss);
@@ -1562,16 +2048,19 @@ int pa__init(pa_module*m) {
     u->sink_input->state_change = sink_input_state_change_cb;
     u->sink_input->may_move_to = sink_input_may_move_to_cb;
     u->sink_input->moving = sink_input_moving_cb;
-    u->sink_input->volume_changed = sink_input_volume_changed_cb;
+    if (!u->use_volume_sharing)
+        u->sink_input->volume_changed = sink_input_volume_changed_cb;
     u->sink_input->mute_changed = sink_input_mute_changed_cb;
     u->sink_input->userdata = u;
 
+    u->sink->input_to_master = u->sink_input;
+
     pa_sink_input_get_silence(u->sink_input, &silence);
 
-    u->source_memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0,
-        pa_frame_size(&source_ss), 1, 1, 0, &silence);
-    u->sink_memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0,
-        pa_frame_size(&sink_ss), 1, 1, 0, &silence);
+    u->source_memblockq = pa_memblockq_new("module-echo-cancel source_memblockq", 0, MEMBLOCKQ_MAXLENGTH, 0,
+        &source_output_ss, 1, 1, 0, &silence);
+    u->sink_memblockq = pa_memblockq_new("module-echo-cancel sink_memblockq", 0, MEMBLOCKQ_MAXLENGTH, 0,
+        &sink_ss, 0, 1, 0, &silence);
 
     pa_memblock_unref(silence.memblock);
 
@@ -1580,11 +2069,14 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
-    /* our source and sink are not suspended when we create them */
-    u->active_mask = 3;
-
-    if (u->adjust_time > 0)
+    if (u->adjust_time > 0 && !u->ec->params.drift_compensation)
         u->time_event = pa_core_rttime_new(m->core, pa_rtclock_now() + u->adjust_time, time_callback, u);
+    else if (u->ec->params.drift_compensation) {
+        pa_log_info("Canceller does drift compensation -- built-in compensation will be disabled");
+        u->adjust_time = 0;
+        /* Perform resync just once to give the canceller a leg up */
+        pa_atomic_store(&u->request_resync, 1);
+    }
 
     if (u->save_aec) {
         pa_log("Creating AEC files in /tmp");
@@ -1597,19 +2089,31 @@ int pa__init(pa_module*m) {
         u->canceled_file = fopen("/tmp/aec_out.sw", "wb");
         if (u->canceled_file == NULL)
             perror ("fopen failed");
+        if (u->ec->params.drift_compensation) {
+            u->drift_file = fopen("/tmp/aec_drift.txt", "w");
+            if (u->drift_file == NULL)
+                perror ("fopen failed");
+        }
     }
+    u->protocol = pa_native_protocol_get(m->core);
+    pa_native_protocol_install_ext(u->protocol, m, extension_cb);
+
+    u->ec->msg = pa_msgobject_new(pa_echo_canceller_msg);
+    u->ec->msg->parent.process_msg = canceller_process_msg_cb;
+    u->ec->msg->userdata = u;
+
+    u->thread_info.current_volume = u->source->reference_volume;
 
     pa_sink_put(u->sink);
     pa_source_put(u->source);
 
     pa_sink_input_put(u->sink_input);
     pa_source_output_put(u->source_output);
-
     pa_modargs_free(ma);
 
     return 0;
 
- fail:
+fail:
     if (ma)
         pa_modargs_free(ma);
 
@@ -1618,15 +2122,17 @@ int pa__init(pa_module*m) {
     return -1;
 }
 
+/* Called from main context. */
 int pa__get_n_used(pa_module *m) {
     struct userdata *u;
 
     pa_assert(m);
     pa_assert_se(u = m->userdata);
 
-    return pa_sink_linked_by(u->sink) +  pa_source_linked_by(u->source);
+    return pa_sink_linked_by(u->sink) + pa_source_linked_by(u->source);
 }
 
+/* Called from main context. */
 void pa__done(pa_module*m) {
     struct userdata *u;
 
@@ -1635,6 +2141,8 @@ void pa__done(pa_module*m) {
     if (!(u = m->userdata))
         return;
 
+    u->dead = TRUE;
+
     /* See comments in source_output_kill_cb() above regarding
      * destruction order! */
 
@@ -1673,8 +2181,214 @@ void pa__done(pa_module*m) {
         pa_xfree(u->ec);
     }
 
+    if (u->protocol) {
+        pa_native_protocol_remove_ext(u->protocol, m);
+        pa_native_protocol_unref(u->protocol);
+    }
+
     if (u->asyncmsgq)
         pa_asyncmsgq_unref(u->asyncmsgq);
 
+    if (u->save_aec) {
+        if (u->played_file)
+            fclose(u->played_file);
+        if (u->captured_file)
+            fclose(u->captured_file);
+        if (u->canceled_file)
+            fclose(u->canceled_file);
+        if (u->drift_file)
+            fclose(u->drift_file);
+    }
+
     pa_xfree(u);
 }
+
+#ifdef ECHO_CANCEL_TEST
+/*
+ * Stand-alone test program for running in the canceller on pre-recorded files.
+ */
+int main(int argc, char* argv[]) {
+    struct userdata u;
+    pa_sample_spec source_output_ss, source_ss, sink_ss;
+    pa_channel_map source_output_map, source_map, sink_map;
+    pa_modargs *ma = NULL;
+    uint8_t *rdata = NULL, *pdata = NULL, *cdata = NULL;
+    int unused PA_GCC_UNUSED;
+    int ret = 0, i;
+    char c;
+    float drift;
+    uint32_t nframes;
+
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_DEBUG);
+
+    pa_memzero(&u, sizeof(u));
+
+    if (argc < 4 || argc > 7) {
+        goto usage;
+    }
+
+    u.captured_file = fopen(argv[2], "rb");
+    if (u.captured_file == NULL) {
+        perror ("Could not open capture file");
+        goto fail;
+    }
+    u.played_file = fopen(argv[1], "rb");
+    if (u.played_file == NULL) {
+        perror ("Could not open play file");
+        goto fail;
+    }
+    u.canceled_file = fopen(argv[3], "wb");
+    if (u.canceled_file == NULL) {
+        perror ("Could not open canceled file");
+        goto fail;
+    }
+
+    u.core = pa_xnew0(pa_core, 1);
+    u.core->cpu_info.cpu_type = PA_CPU_X86;
+    u.core->cpu_info.flags.x86 |= PA_CPU_X86_SSE;
+
+    if (!(ma = pa_modargs_new(argc > 4 ? argv[4] : NULL, valid_modargs))) {
+        pa_log("Failed to parse module arguments.");
+        goto fail;
+    }
+
+    source_ss.format = PA_SAMPLE_S16LE;
+    source_ss.rate = DEFAULT_RATE;
+    source_ss.channels = DEFAULT_CHANNELS;
+    pa_channel_map_init_auto(&source_map, source_ss.channels, PA_CHANNEL_MAP_DEFAULT);
+
+    sink_ss.format = PA_SAMPLE_S16LE;
+    sink_ss.rate = DEFAULT_RATE;
+    sink_ss.channels = DEFAULT_CHANNELS;
+    pa_channel_map_init_auto(&sink_map, sink_ss.channels, PA_CHANNEL_MAP_DEFAULT);
+
+    if (init_common(ma, &u, &source_ss, &source_map) < 0)
+        goto fail;
+
+    source_output_ss = source_ss;
+    source_output_map = source_map;
+
+    if (!u.ec->init(u.core, u.ec, &source_output_ss, &source_output_map, &sink_ss, &sink_map, &source_ss, &source_map, &nframes,
+                     pa_modargs_get_value(ma, "aec_args", NULL))) {
+        pa_log("Failed to init AEC engine");
+        goto fail;
+    }
+    u.source_output_blocksize = nframes * pa_frame_size(&source_output_ss);
+    u.source_blocksize = nframes * pa_frame_size(&source_ss);
+    u.sink_blocksize = nframes * pa_frame_size(&sink_ss);
+
+    if (u.ec->params.drift_compensation) {
+        if (argc < 6) {
+            pa_log("Drift compensation enabled but drift file not specified");
+            goto fail;
+        }
+
+        u.drift_file = fopen(argv[5], "rt");
+
+        if (u.drift_file == NULL) {
+            perror ("Could not open drift file");
+            goto fail;
+        }
+    }
+
+    rdata = pa_xmalloc(u.source_output_blocksize);
+    pdata = pa_xmalloc(u.sink_blocksize);
+    cdata = pa_xmalloc(u.source_blocksize);
+
+    if (!u.ec->params.drift_compensation) {
+        while (fread(rdata, u.source_output_blocksize, 1, u.captured_file) > 0) {
+            if (fread(pdata, u.sink_blocksize, 1, u.played_file) == 0) {
+                perror("Played file ended before captured file");
+                goto fail;
+            }
+
+            u.ec->run(u.ec, rdata, pdata, cdata);
+
+            unused = fwrite(cdata, u.source_blocksize, 1, u.canceled_file);
+        }
+    } else {
+        while (fscanf(u.drift_file, "%c", &c) > 0) {
+            switch (c) {
+                case 'd':
+                    if (!fscanf(u.drift_file, "%a", &drift)) {
+                        perror("Drift file incomplete");
+                        goto fail;
+                    }
+
+                    u.ec->set_drift(u.ec, drift);
+
+                    break;
+
+                case 'c':
+                    if (!fscanf(u.drift_file, "%d", &i)) {
+                        perror("Drift file incomplete");
+                        goto fail;
+                    }
+
+                    if (fread(rdata, i, 1, u.captured_file) <= 0) {
+                        perror("Captured file ended prematurely");
+                        goto fail;
+                    }
+
+                    u.ec->record(u.ec, rdata, cdata);
+
+                    unused = fwrite(cdata, i, 1, u.canceled_file);
+
+                    break;
+
+                case 'p':
+                    if (!fscanf(u.drift_file, "%d", &i)) {
+                        perror("Drift file incomplete");
+                        goto fail;
+                    }
+
+                    if (fread(pdata, i, 1, u.played_file) <= 0) {
+                        perror("Played file ended prematurely");
+                        goto fail;
+                    }
+
+                    u.ec->play(u.ec, pdata);
+
+                    break;
+            }
+        }
+
+        if (fread(rdata, i, 1, u.captured_file) > 0)
+            pa_log("All capture data was not consumed");
+        if (fread(pdata, i, 1, u.played_file) > 0)
+            pa_log("All playback data was not consumed");
+    }
+
+    u.ec->done(u.ec);
+
+out:
+    if (u.captured_file)
+        fclose(u.captured_file);
+    if (u.played_file)
+        fclose(u.played_file);
+    if (u.canceled_file)
+        fclose(u.canceled_file);
+    if (u.drift_file)
+        fclose(u.drift_file);
+
+    pa_xfree(rdata);
+    pa_xfree(pdata);
+    pa_xfree(cdata);
+
+    pa_xfree(u.ec);
+    pa_xfree(u.core);
+
+    if (ma)
+        pa_modargs_free(ma);
+
+    return ret;
+
+usage:
+    pa_log("Usage: %s play_file rec_file out_file [module args] [drift_file]", argv[0]);
+
+fail:
+    ret = -1;
+    goto out;
+}
+#endif /* ECHO_CANCEL_TEST */
diff --git a/src/modules/echo-cancel/null.c b/src/modules/echo-cancel/null.c
new file mode 100644 (file)
index 0000000..e89a4f4
--- /dev/null
@@ -0,0 +1,56 @@
+/***
+    Copyright 2012 Peter Meerwald <p.meerwald@bct-electronic.com>
+
+    PulseAudio is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.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.
+
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/cdecl.h>
+
+PA_C_DECL_BEGIN
+#include <pulsecore/core-util.h>
+#include <pulsecore/modargs.h>
+#include "echo-cancel.h"
+PA_C_DECL_END
+
+pa_bool_t pa_null_ec_init(pa_core *c, pa_echo_canceller *ec,
+                          pa_sample_spec *rec_ss, pa_channel_map *rec_map,
+                          pa_sample_spec *play_ss, pa_channel_map *play_map,
+                          pa_sample_spec *out_ss, pa_channel_map *out_map,
+                          uint32_t *nframes, const char *args) {
+    char strss_source[PA_SAMPLE_SPEC_SNPRINT_MAX];
+    char strss_sink[PA_SAMPLE_SPEC_SNPRINT_MAX];
+
+    *nframes = 256;
+    ec->params.priv.null.out_ss = *out_ss;
+
+    *rec_ss = *out_ss;
+    *rec_map = *out_map;
+
+    pa_log_debug("null AEC: nframes=%u, sample spec source=%s, sample spec sink=%s", *nframes,
+                 pa_sample_spec_snprint(strss_source, sizeof(strss_source), out_ss),
+                 pa_sample_spec_snprint(strss_sink, sizeof(strss_sink), play_ss));
+
+    return TRUE;
+}
+
+void pa_null_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out) {
+    /* The null implementation simply copies the recorded buffer to the output
+       buffer and ignores the play buffer. */
+    memcpy(out, rec, 256 * pa_frame_size(&ec->params.priv.null.out_ss));
+}
+
+void pa_null_ec_done(pa_echo_canceller *ec) {
+}
index 7851510..ddb09b5 100644 (file)
@@ -25,6 +25,7 @@
 #include <config.h>
 #endif
 
+#include <pulsecore/core-util.h>
 #include <pulsecore/modargs.h>
 #include "echo-cancel.h"
 
 #define DEFAULT_FRAME_SIZE_MS 20
 /* should be between 100-500 ms */
 #define DEFAULT_FILTER_SIZE_MS 200
+#define DEFAULT_AGC_ENABLED TRUE
+#define DEFAULT_DENOISE_ENABLED TRUE
+#define DEFAULT_ECHO_SUPPRESS_ENABLED TRUE
+#define DEFAULT_ECHO_SUPPRESS_ATTENUATION 0
 
 static const char* const valid_modargs[] = {
     "frame_size_ms",
     "filter_size_ms",
+    "agc",
+    "denoise",
+    "echo_suppress",
+    "echo_suppress_attenuation",
+    "echo_suppress_attenuation_active",
     NULL
 };
 
-static void pa_speex_ec_fixate_spec(pa_sample_spec *source_ss, pa_channel_map *source_map,
-                                   pa_sample_spec *sink_ss, pa_channel_map *sink_map)
+static void pa_speex_ec_fixate_spec(pa_sample_spec *rec_ss, pa_channel_map *rec_map,
+                                    pa_sample_spec *play_ss, pa_channel_map *play_map,
+                                    pa_sample_spec *out_ss, pa_channel_map *out_map)
 {
-    source_ss->format = PA_SAMPLE_S16NE;
+    out_ss->format = PA_SAMPLE_S16NE;
 
-    *sink_ss = *source_ss;
-    *sink_map = *source_map;
+    *play_ss = *out_ss;
+    *play_map = *out_map;
+    *rec_ss = *out_ss;
+    *rec_map = *out_map;
 }
 
+static pa_bool_t pa_speex_ec_preprocessor_init(pa_echo_canceller *ec, pa_sample_spec *out_ss, uint32_t nframes, pa_modargs *ma) {
+    pa_bool_t agc;
+    pa_bool_t denoise;
+    pa_bool_t echo_suppress;
+    int32_t echo_suppress_attenuation;
+    int32_t echo_suppress_attenuation_active;
+
+    agc = DEFAULT_AGC_ENABLED;
+    if (pa_modargs_get_value_boolean(ma, "agc", &agc) < 0) {
+        pa_log("Failed to parse agc value");
+        goto fail;
+    }
+
+    denoise = DEFAULT_DENOISE_ENABLED;
+    if (pa_modargs_get_value_boolean(ma, "denoise", &denoise) < 0) {
+        pa_log("Failed to parse denoise value");
+        goto fail;
+    }
+
+    echo_suppress = DEFAULT_ECHO_SUPPRESS_ENABLED;
+    if (pa_modargs_get_value_boolean(ma, "echo_suppress", &echo_suppress) < 0) {
+        pa_log("Failed to parse echo_suppress value");
+        goto fail;
+    }
+
+    echo_suppress_attenuation = DEFAULT_ECHO_SUPPRESS_ATTENUATION;
+    if (pa_modargs_get_value_s32(ma, "echo_suppress_attenuation", &echo_suppress_attenuation) < 0) {
+        pa_log("Failed to parse echo_suppress_attenuation value");
+        goto fail;
+    }
+    if (echo_suppress_attenuation > 0) {
+        pa_log("echo_suppress_attenuation should be a negative dB value");
+        goto fail;
+    }
+
+    echo_suppress_attenuation_active = DEFAULT_ECHO_SUPPRESS_ATTENUATION;
+    if (pa_modargs_get_value_s32(ma, "echo_suppress_attenuation_active", &echo_suppress_attenuation_active) < 0) {
+        pa_log("Failed to parse echo_suppress_attenuation_active value");
+        goto fail;
+    }
+    if (echo_suppress_attenuation_active > 0) {
+        pa_log("echo_suppress_attenuation_active should be a negative dB value");
+        goto fail;
+    }
+
+    if (agc || denoise || echo_suppress) {
+        spx_int32_t tmp;
+
+        if (out_ss->channels != 1) {
+            pa_log("AGC, denoising and echo suppression only work with channels=1");
+            goto fail;
+        }
+
+        ec->params.priv.speex.pp_state = speex_preprocess_state_init(nframes, out_ss->rate);
+
+        tmp = agc;
+        speex_preprocess_ctl(ec->params.priv.speex.pp_state, SPEEX_PREPROCESS_SET_AGC, &tmp);
+
+        tmp = denoise;
+        speex_preprocess_ctl(ec->params.priv.speex.pp_state, SPEEX_PREPROCESS_SET_DENOISE, &tmp);
+
+        if (echo_suppress) {
+            if (echo_suppress_attenuation)
+                speex_preprocess_ctl(ec->params.priv.speex.pp_state, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS,
+                                     &echo_suppress_attenuation);
+
+            if (echo_suppress_attenuation_active) {
+                speex_preprocess_ctl(ec->params.priv.speex.pp_state, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE,
+                                     &echo_suppress_attenuation_active);
+            }
+
+            speex_preprocess_ctl(ec->params.priv.speex.pp_state, SPEEX_PREPROCESS_SET_ECHO_STATE,
+                                 ec->params.priv.speex.state);
+        }
+
+        pa_log_info("Loaded speex preprocessor with params: agc=%s, denoise=%s, echo_suppress=%s", pa_yes_no(agc),
+                    pa_yes_no(denoise), pa_yes_no(echo_suppress));
+    } else
+        pa_log_info("All preprocessing options are disabled");
+
+    return TRUE;
+
+fail:
+    return FALSE;
+}
+
+
 pa_bool_t pa_speex_ec_init(pa_core *c, pa_echo_canceller *ec,
-                           pa_sample_spec *source_ss, pa_channel_map *source_map,
-                           pa_sample_spec *sink_ss, pa_channel_map *sink_map,
-                           uint32_t *blocksize, const char *args)
+                           pa_sample_spec *rec_ss, pa_channel_map *rec_map,
+                           pa_sample_spec *play_ss, pa_channel_map *play_map,
+                           pa_sample_spec *out_ss, pa_channel_map *out_map,
+                           uint32_t *nframes, const char *args)
 {
-    int framelen, y, rate;
+    int rate;
     uint32_t frame_size_ms, filter_size_ms;
     pa_modargs *ma;
 
@@ -74,43 +175,56 @@ pa_bool_t pa_speex_ec_init(pa_core *c, pa_echo_canceller *ec,
         goto fail;
     }
 
-    pa_speex_ec_fixate_spec(source_ss, source_map, sink_ss, sink_map);
-
-    rate = source_ss->rate;
-    framelen = (rate * frame_size_ms) / 1000;
-    /* framelen should be a power of 2, round down to nearest power of two */
-    y = 1 << ((8 * sizeof (int)) - 2);
-    while (y > framelen)
-      y >>= 1;
-    framelen = y;
+    pa_speex_ec_fixate_spec(rec_ss, rec_map, play_ss, play_map, out_ss, out_map);
 
-    *blocksize = framelen * pa_frame_size (source_ss);
+    rate = out_ss->rate;
+    *nframes = pa_echo_canceller_blocksize_power2(rate, frame_size_ms);
 
-    pa_log_debug ("Using framelen %d, blocksize %u, channels %d, rate %d", framelen, *blocksize, source_ss->channels, source_ss->rate);
-
-    ec->params.priv.speex.state = speex_echo_state_init_mc (framelen, (rate * filter_size_ms) / 1000, source_ss->channels, source_ss->channels);
+    pa_log_debug ("Using nframes %d, channels %d, rate %d", *nframes, out_ss->channels, out_ss->rate);
+    ec->params.priv.speex.state = speex_echo_state_init_mc(*nframes, (rate * filter_size_ms) / 1000, out_ss->channels, out_ss->channels);
 
     if (!ec->params.priv.speex.state)
-       goto fail;
+        goto fail;
 
     speex_echo_ctl(ec->params.priv.speex.state, SPEEX_ECHO_SET_SAMPLING_RATE, &rate);
 
+    if (!pa_speex_ec_preprocessor_init(ec, out_ss, *nframes, ma))
+        goto fail;
+
     pa_modargs_free(ma);
     return TRUE;
 
 fail:
     if (ma)
-       pa_modargs_free(ma);
+        pa_modargs_free(ma);
+    if (ec->params.priv.speex.pp_state) {
+        speex_preprocess_state_destroy(ec->params.priv.speex.pp_state);
+        ec->params.priv.speex.pp_state = NULL;
+    }
+    if (ec->params.priv.speex.state) {
+        speex_echo_state_destroy(ec->params.priv.speex.state);
+        ec->params.priv.speex.state = NULL;
+    }
     return FALSE;
 }
 
-void pa_speex_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out)
-{
-    speex_echo_cancellation(ec->params.priv.speex.state, (const spx_int16_t *) rec, (const spx_int16_t *) play, (spx_int16_t *) out);
+void pa_speex_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out) {
+    speex_echo_cancellation(ec->params.priv.speex.state, (const spx_int16_t *) rec, (const spx_int16_t *) play,
+                            (spx_int16_t *) out);
+
+    /* preprecessor is run after AEC. This is not a mistake! */
+    if (ec->params.priv.speex.pp_state)
+        speex_preprocess_run(ec->params.priv.speex.pp_state, (spx_int16_t *) out);
 }
 
-void pa_speex_ec_done(pa_echo_canceller *ec)
-{
-    speex_echo_state_destroy (ec->params.priv.speex.state);
-    ec->params.priv.speex.state = NULL;
+void pa_speex_ec_done(pa_echo_canceller *ec) {
+    if (ec->params.priv.speex.pp_state) {
+        speex_preprocess_state_destroy(ec->params.priv.speex.pp_state);
+        ec->params.priv.speex.pp_state = NULL;
+    }
+
+    if (ec->params.priv.speex.state) {
+        speex_echo_state_destroy(ec->params.priv.speex.state);
+        ec->params.priv.speex.state = NULL;
+    }
 }
diff --git a/src/modules/echo-cancel/webrtc.cc b/src/modules/echo-cancel/webrtc.cc
new file mode 100644 (file)
index 0000000..71f6ebb
--- /dev/null
@@ -0,0 +1,295 @@
+/***
+    This file is part of PulseAudio.
+
+    Copyright 2011 Collabora Ltd.
+
+    Contributor: Arun Raghavan <arun.raghavan@collabora.co.uk>
+
+    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, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+    USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/cdecl.h>
+
+PA_C_DECL_BEGIN
+#include <pulsecore/core-util.h>
+#include <pulsecore/modargs.h>
+
+#include <pulse/timeval.h>
+#include "echo-cancel.h"
+PA_C_DECL_END
+
+#include <audio_processing.h>
+#include <module_common_types.h>
+
+#define BLOCK_SIZE_US 10000
+
+#define DEFAULT_HIGH_PASS_FILTER TRUE
+#define DEFAULT_NOISE_SUPPRESSION TRUE
+#define DEFAULT_ANALOG_GAIN_CONTROL TRUE
+#define DEFAULT_DIGITAL_GAIN_CONTROL FALSE
+#define DEFAULT_MOBILE FALSE
+#define DEFAULT_ROUTING_MODE "speakerphone"
+#define DEFAULT_COMFORT_NOISE TRUE
+#define DEFAULT_DRIFT_COMPENSATION FALSE
+
+static const char* const valid_modargs[] = {
+    "high_pass_filter",
+    "noise_suppression",
+    "analog_gain_control",
+    "digital_gain_control",
+    "mobile",
+    "routing_mode",
+    "comfort_noise",
+    "drift_compensation",
+    NULL
+};
+
+static int routing_mode_from_string(const char *rmode) {
+    if (pa_streq(rmode, "quiet-earpiece-or-headset"))
+        return webrtc::EchoControlMobile::kQuietEarpieceOrHeadset;
+    else if (pa_streq(rmode, "earpiece"))
+        return webrtc::EchoControlMobile::kEarpiece;
+    else if (pa_streq(rmode, "loud-earpiece"))
+        return webrtc::EchoControlMobile::kLoudEarpiece;
+    else if (pa_streq(rmode, "speakerphone"))
+        return webrtc::EchoControlMobile::kSpeakerphone;
+    else if (pa_streq(rmode, "loud-speakerphone"))
+        return webrtc::EchoControlMobile::kLoudSpeakerphone;
+    else
+        return -1;
+}
+
+pa_bool_t pa_webrtc_ec_init(pa_core *c, pa_echo_canceller *ec,
+                            pa_sample_spec *rec_ss, pa_channel_map *rec_map,
+                            pa_sample_spec *play_ss, pa_channel_map *play_map,
+                            pa_sample_spec *out_ss, pa_channel_map *out_map,
+                            uint32_t *nframes, const char *args)
+{
+    webrtc::AudioProcessing *apm = NULL;
+    pa_bool_t hpf, ns, agc, dgc, mobile, cn;
+    int rm = -1;
+    pa_modargs *ma;
+
+    if (!(ma = pa_modargs_new(args, valid_modargs))) {
+        pa_log("Failed to parse submodule arguments.");
+        goto fail;
+    }
+
+
+    hpf = DEFAULT_HIGH_PASS_FILTER;
+    if (pa_modargs_get_value_boolean(ma, "high_pass_filter", &hpf) < 0) {
+        pa_log("Failed to parse high_pass_filter value");
+        goto fail;
+    }
+
+    ns = DEFAULT_NOISE_SUPPRESSION;
+    if (pa_modargs_get_value_boolean(ma, "noise_suppression", &ns) < 0) {
+        pa_log("Failed to parse noise_suppression value");
+        goto fail;
+    }
+
+    agc = DEFAULT_ANALOG_GAIN_CONTROL;
+    if (pa_modargs_get_value_boolean(ma, "analog_gain_control", &agc) < 0) {
+        pa_log("Failed to parse analog_gain_control value");
+        goto fail;
+    }
+
+    dgc = agc ? FALSE : DEFAULT_DIGITAL_GAIN_CONTROL;
+    if (pa_modargs_get_value_boolean(ma, "digital_gain_control", &dgc) < 0) {
+        pa_log("Failed to parse digital_gain_control value");
+        goto fail;
+    }
+
+    if (agc && dgc) {
+        pa_log("You must pick only one between analog and digital gain control");
+        goto fail;
+    }
+
+    mobile = DEFAULT_MOBILE;
+    if (pa_modargs_get_value_boolean(ma, "mobile", &mobile) < 0) {
+        pa_log("Failed to parse mobile value");
+        goto fail;
+    }
+
+    ec->params.drift_compensation = DEFAULT_DRIFT_COMPENSATION;
+    if (pa_modargs_get_value_boolean(ma, "drift_compensation", &ec->params.drift_compensation) < 0) {
+        pa_log("Failed to parse drift_compensation value");
+        goto fail;
+    }
+
+    if (mobile) {
+        if (ec->params.drift_compensation) {
+            pa_log("Can't use drift_compensation in mobile mode");
+            goto fail;
+        }
+
+        if ((rm = routing_mode_from_string(pa_modargs_get_value(ma, "routing_mode", DEFAULT_ROUTING_MODE))) < 0) {
+            pa_log("Failed to parse routing_mode value");
+            goto fail;
+        }
+
+        cn = DEFAULT_COMFORT_NOISE;
+        if (pa_modargs_get_value_boolean(ma, "comfort_noise", &cn) < 0) {
+            pa_log("Failed to parse cn value");
+            goto fail;
+        }
+    } else {
+        if (pa_modargs_get_value(ma, "comfort_noise", NULL) || pa_modargs_get_value(ma, "routing_mode", NULL)) {
+            pa_log("The routing_mode and comfort_noise options are only valid with mobile=true");
+            goto fail;
+        }
+    }
+
+    apm = webrtc::AudioProcessing::Create(0);
+
+    out_ss->format = PA_SAMPLE_S16NE;
+    *play_ss = *out_ss;
+    /* FIXME: the implementation actually allows a different number of
+     * source/sink channels. Do we want to support that? */
+    *play_map = *out_map;
+    *rec_ss = *out_ss;
+    *rec_map = *out_map;
+
+    apm->set_sample_rate_hz(out_ss->rate);
+
+    apm->set_num_channels(out_ss->channels, out_ss->channels);
+    apm->set_num_reverse_channels(play_ss->channels);
+
+    if (hpf)
+        apm->high_pass_filter()->Enable(true);
+
+    if (!mobile) {
+        if (ec->params.drift_compensation) {
+            apm->echo_cancellation()->set_device_sample_rate_hz(out_ss->rate);
+            apm->echo_cancellation()->enable_drift_compensation(true);
+        } else {
+            apm->echo_cancellation()->enable_drift_compensation(false);
+        }
+
+        apm->echo_cancellation()->Enable(true);
+    } else {
+        apm->echo_control_mobile()->set_routing_mode(static_cast<webrtc::EchoControlMobile::RoutingMode>(rm));
+        apm->echo_control_mobile()->enable_comfort_noise(cn);
+        apm->echo_control_mobile()->Enable(true);
+    }
+
+    if (ns) {
+        apm->noise_suppression()->set_level(webrtc::NoiseSuppression::kHigh);
+        apm->noise_suppression()->Enable(true);
+    }
+
+    if (agc || dgc) {
+        if (mobile && rm <= webrtc::EchoControlMobile::kEarpiece) {
+            /* Maybe this should be a knob, but we've got a lot of knobs already */
+            apm->gain_control()->set_mode(webrtc::GainControl::kFixedDigital);
+            ec->params.priv.webrtc.agc = FALSE;
+        } else if (dgc) {
+            apm->gain_control()->set_mode(webrtc::GainControl::kAdaptiveDigital);
+            ec->params.priv.webrtc.agc = FALSE;
+        } else {
+            apm->gain_control()->set_mode(webrtc::GainControl::kAdaptiveAnalog);
+            if (apm->gain_control()->set_analog_level_limits(0, PA_VOLUME_NORM-1) != apm->kNoError) {
+                pa_log("Failed to initialise AGC");
+                goto fail;
+            }
+            ec->params.priv.webrtc.agc = TRUE;
+        }
+
+        apm->gain_control()->Enable(true);
+    }
+
+    apm->voice_detection()->Enable(true);
+
+    ec->params.priv.webrtc.apm = apm;
+    ec->params.priv.webrtc.sample_spec = *out_ss;
+    ec->params.priv.webrtc.blocksize = (uint64_t)pa_bytes_per_second(out_ss) * BLOCK_SIZE_US / PA_USEC_PER_SEC;
+    *nframes = ec->params.priv.webrtc.blocksize / pa_frame_size(out_ss);
+
+    pa_modargs_free(ma);
+    return TRUE;
+
+fail:
+    if (ma)
+        pa_modargs_free(ma);
+    if (apm)
+        webrtc::AudioProcessing::Destroy(apm);
+
+    return FALSE;
+}
+
+void pa_webrtc_ec_play(pa_echo_canceller *ec, const uint8_t *play) {
+    webrtc::AudioProcessing *apm = (webrtc::AudioProcessing*)ec->params.priv.webrtc.apm;
+    webrtc::AudioFrame play_frame;
+    const pa_sample_spec *ss = &ec->params.priv.webrtc.sample_spec;
+
+    play_frame._audioChannel = ss->channels;
+    play_frame._frequencyInHz = ss->rate;
+    play_frame._payloadDataLengthInSamples = ec->params.priv.webrtc.blocksize / pa_frame_size(ss);
+    memcpy(play_frame._payloadData, play, ec->params.priv.webrtc.blocksize);
+
+    apm->AnalyzeReverseStream(&play_frame);
+}
+
+void pa_webrtc_ec_record(pa_echo_canceller *ec, const uint8_t *rec, uint8_t *out) {
+    webrtc::AudioProcessing *apm = (webrtc::AudioProcessing*)ec->params.priv.webrtc.apm;
+    webrtc::AudioFrame out_frame;
+    const pa_sample_spec *ss = &ec->params.priv.webrtc.sample_spec;
+    pa_cvolume v;
+
+    out_frame._audioChannel = ss->channels;
+    out_frame._frequencyInHz = ss->rate;
+    out_frame._payloadDataLengthInSamples = ec->params.priv.webrtc.blocksize / pa_frame_size(ss);
+    memcpy(out_frame._payloadData, rec, ec->params.priv.webrtc.blocksize);
+
+    if (ec->params.priv.webrtc.agc) {
+        pa_cvolume_init(&v);
+        pa_echo_canceller_get_capture_volume(ec, &v);
+        apm->gain_control()->set_stream_analog_level(pa_cvolume_avg(&v));
+    }
+
+    apm->set_stream_delay_ms(0);
+    apm->ProcessStream(&out_frame);
+
+    if (ec->params.priv.webrtc.agc) {
+        pa_cvolume_set(&v, ss->channels, apm->gain_control()->stream_analog_level());
+        pa_echo_canceller_set_capture_volume(ec, &v);
+    }
+
+    memcpy(out, out_frame._payloadData, ec->params.priv.webrtc.blocksize);
+}
+
+void pa_webrtc_ec_set_drift(pa_echo_canceller *ec, float drift) {
+    webrtc::AudioProcessing *apm = (webrtc::AudioProcessing*)ec->params.priv.webrtc.apm;
+    const pa_sample_spec *ss = &ec->params.priv.webrtc.sample_spec;
+
+    apm->echo_cancellation()->set_stream_drift_samples(drift * ec->params.priv.webrtc.blocksize / pa_frame_size(ss));
+}
+
+void pa_webrtc_ec_run(pa_echo_canceller *ec, const uint8_t *rec, const uint8_t *play, uint8_t *out) {
+    pa_webrtc_ec_play(ec, play);
+    pa_webrtc_ec_record(ec, rec, out);
+}
+
+void pa_webrtc_ec_done(pa_echo_canceller *ec) {
+    if (ec->params.priv.webrtc.apm) {
+        webrtc::AudioProcessing::Destroy((webrtc::AudioProcessing*)ec->params.priv.webrtc.apm);
+        ec->params.priv.webrtc.apm = NULL;
+    }
+}
diff --git a/src/modules/gconf/module-gconf-symdef.h b/src/modules/gconf/module-gconf-symdef.h
deleted file mode 100644 (file)
index 90d5c3a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulegconfsymdeffoo
-#define foomodulegconfsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_gconf_LTX_pa__init
-#define pa__done module_gconf_LTX_pa__done
-#define pa__get_author module_gconf_LTX_pa__get_author
-#define pa__get_description module_gconf_LTX_pa__get_description
-#define pa__get_usage module_gconf_LTX_pa__get_usage
-#define pa__get_version module_gconf_LTX_pa__get_version
-#define pa__get_deprecated module_gconf_LTX_pa__get_deprecated
-#define pa__load_once module_gconf_LTX_pa__load_once
-#define pa__get_n_used module_gconf_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 5f31d68..c60d0f0 100644 (file)
 #include <signal.h>
 #include <sys/types.h>
 #include <sys/wait.h>
-#include <fcntl.h>
 
 #include <pulse/xmalloc.h>
 #include <pulsecore/module.h>
 #include <pulsecore/core.h>
-#include <pulsecore/llist.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 #include <pulse/mainloop-api.h>
@@ -52,6 +50,8 @@ PA_MODULE_LOAD_ONCE(TRUE);
 #define MAX_MODULES 10
 #define BUF_MAX 2048
 
+struct userdata;
+
 struct module_item {
     char *name;
     char *args;
@@ -59,6 +59,7 @@ struct module_item {
 };
 
 struct module_info {
+    struct userdata *userdata;
     char *name;
 
     struct module_item items[MAX_MODULES];
@@ -130,11 +131,14 @@ static char *read_string(struct userdata *u) {
     }
 }
 
-static void unload_one_module(struct userdata *u, struct module_info*m, unsigned i) {
-    pa_assert(u);
+static void unload_one_module(struct module_info *m, unsigned i) {
+    struct userdata *u;
+
     pa_assert(m);
     pa_assert(i < m->n_items);
 
+    u = m->userdata;
+
     if (m->items[i].index == PA_INVALID_INDEX)
         return;
 
@@ -146,40 +150,40 @@ static void unload_one_module(struct userdata *u, struct module_info*m, unsigned
     m->items[i].name = m->items[i].args = NULL;
 }
 
-static void unload_all_modules(struct userdata *u, struct module_info*m) {
+static void unload_all_modules(struct module_info *m) {
     unsigned i;
 
-    pa_assert(u);
     pa_assert(m);
 
     for (i = 0; i < m->n_items; i++)
-        unload_one_module(u, m, i);
+        unload_one_module(m, i);
 
     m->n_items = 0;
 }
 
 static void load_module(
-        struct userdata *u,
         struct module_info *m,
         unsigned i,
         const char *name,
         const char *args,
         pa_bool_t is_new) {
 
+    struct userdata *u;
     pa_module *mod;
 
-    pa_assert(u);
     pa_assert(m);
     pa_assert(name);
     pa_assert(args);
 
+    u = m->userdata;
+
     if (!is_new) {
         if (m->items[i].index != PA_INVALID_INDEX &&
-            strcmp(m->items[i].name, name) == 0 &&
-            strcmp(m->items[i].args, args) == 0)
+            pa_streq(m->items[i].name, name) &&
+            pa_streq(m->items[i].args, args))
             return;
 
-        unload_one_module(u, m, i);
+        unload_one_module(m, i);
     }
 
     pa_log_debug("Loading module '%s' with args '%s' due to GConf configuration.", name, args);
@@ -196,14 +200,12 @@ static void load_module(
     m->items[i].index = mod->index;
 }
 
-static void module_info_free(void *p, void *userdata) {
+static void module_info_free(void *p) {
     struct module_info *m = p;
-    struct userdata *u = userdata;
 
     pa_assert(m);
-    pa_assert(u);
 
-    unload_all_modules(u, m);
+    unload_all_modules(m);
     pa_xfree(m->name);
     pa_xfree(m);
 }
@@ -235,6 +237,7 @@ static int handle_event(struct userdata *u) {
 
                 if (!(m = pa_hashmap_get(u->module_infos, name))) {
                     m = pa_xnew(struct module_info, 1);
+                    m->userdata = u;
                     m->name = name;
                     m->n_items = 0;
                     pa_hashmap_put(u->module_infos, m->name, m);
@@ -262,7 +265,7 @@ static int handle_event(struct userdata *u) {
                         goto fail;
                     }
 
-                    load_module(u, m, i, module, args, i >= m->n_items);
+                    load_module(m, i, module, args, i >= m->n_items);
 
                     i++;
 
@@ -272,7 +275,7 @@ static int handle_event(struct userdata *u) {
 
                 /* Unload all removed modules */
                 for (j = i; j < m->n_items; j++)
-                    unload_one_module(u, m, j);
+                    unload_one_module(m, j);
 
                 m->n_items = i;
 
@@ -288,7 +291,7 @@ static int handle_event(struct userdata *u) {
 
                 if ((m = pa_hashmap_get(u->module_infos, name))) {
                     pa_hashmap_remove(u->module_infos, name);
-                    module_info_free(m, u);
+                    module_info_free(m);
                 }
 
                 pa_xfree(name);
@@ -398,7 +401,7 @@ void pa__done(pa_module*m) {
         pa_close(u->fd);
 
     if (u->module_infos)
-        pa_hashmap_free(u->module_infos, module_info_free, u);
+        pa_hashmap_free(u->module_infos, (pa_free_cb_t) module_info_free);
 
     pa_xfree(u);
 }
diff --git a/src/modules/hal-util.c b/src/modules/hal-util.c
deleted file mode 100644 (file)
index 2d59f51..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2009 Lennart Poettering
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as
-  published by the Free Software Foundation; either version 2.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, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <pulsecore/log.h>
-#include <pulsecore/dbus-shared.h>
-
-#include <hal/libhal.h>
-
-#include "hal-util.h"
-
-int pa_hal_get_info(pa_core *core, pa_proplist *p, int card) {
-    pa_dbus_connection *c = NULL;
-    LibHalContext *hal = NULL;
-    DBusError error;
-    int r = -1;
-    char **udis = NULL, *t;
-    int n, i;
-
-    pa_assert(core);
-    pa_assert(p);
-    pa_assert(card >= 0);
-
-    dbus_error_init(&error);
-
-    if (!(c = pa_dbus_bus_get(core, DBUS_BUS_SYSTEM, &error)) || dbus_error_is_set(&error)) {
-        pa_log_error("Unable to contact DBUS system bus: %s: %s", error.name, error.message);
-        goto finish;
-    }
-
-
-    if (!(hal = libhal_ctx_new())) {
-        pa_log_error("libhal_ctx_new() finished");
-        goto finish;
-    }
-
-    if (!libhal_ctx_set_dbus_connection(hal, pa_dbus_connection_get(c))) {
-        pa_log_error("Error establishing DBUS connection: %s: %s", error.name, error.message);
-        goto finish;
-    }
-
-    if (!libhal_ctx_init(hal, &error)) {
-        pa_log_error("Couldn't connect to hald: %s: %s", error.name, error.message);
-        goto finish;
-    }
-
-    if (!(udis = libhal_find_device_by_capability(hal, "sound", &n, &error))) {
-        pa_log_error("Couldn't find devices: %s: %s", error.name, error.message);
-        goto finish;
-    }
-
-    for (i = 0; i < n; i++) {
-        dbus_int32_t this_card;
-
-        this_card = libhal_device_get_property_int(hal, udis[i], "sound.card", &error);
-        if (dbus_error_is_set(&error)) {
-            dbus_error_free(&error);
-            continue;
-        }
-
-        if (this_card == card)
-            break;
-
-    }
-
-    if (i >= n)
-        goto finish;
-
-    pa_proplist_sets(p, "hal.udi", udis[i]);
-
-    /* The data HAL stores in info.product is not actually a product
-     * string but simply the ALSA card name. We will hence not write
-     * it to PA_PROP_DEVICE_PRODUCT_NAME */
-    t = libhal_device_get_property_string(hal, udis[i], "info.product", &error);
-    if (dbus_error_is_set(&error))
-        dbus_error_free(&error);
-    if (t) {
-        pa_proplist_sets(p, "hal.product", t);
-        libhal_free_string(t);
-    }
-
-    t = libhal_device_get_property_string(hal, udis[i], "sound.card_id", &error);
-    if (dbus_error_is_set(&error))
-        dbus_error_free(&error);
-    if (t) {
-        pa_proplist_sets(p, "hal.card_id", t);
-        libhal_free_string(t);
-    }
-
-    r = 0;
-
-finish:
-
-    if (udis)
-        libhal_free_string_array(udis);
-
-    dbus_error_free(&error);
-
-    if (hal) {
-        libhal_ctx_shutdown(hal, &error);
-        libhal_ctx_free(hal);
-        dbus_error_free(&error);
-    }
-
-    if (c)
-        pa_dbus_connection_unref(c);
-
-    return r;
-}
diff --git a/src/modules/jack/module-jack-sink-symdef.h b/src/modules/jack/module-jack-sink-symdef.h
deleted file mode 100644 (file)
index 857d3f0..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulejacksinksymdeffoo
-#define foomodulejacksinksymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_jack_sink_LTX_pa__init
-#define pa__done module_jack_sink_LTX_pa__done
-#define pa__get_author module_jack_sink_LTX_pa__get_author
-#define pa__get_description module_jack_sink_LTX_pa__get_description
-#define pa__get_usage module_jack_sink_LTX_pa__get_usage
-#define pa__get_version module_jack_sink_LTX_pa__get_version
-#define pa__get_deprecated module_jack_sink_LTX_pa__get_deprecated
-#define pa__load_once module_jack_sink_LTX_pa__load_once
-#define pa__get_n_used module_jack_sink_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 9f3e071..1e34abd 100644 (file)
 #endif
 
 #include <stdlib.h>
-#include <sys/stat.h>
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
-#include <fcntl.h>
 #include <unistd.h>
-#include <limits.h>
 
 #include <jack/jack.h>
 
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/core-error.h>
 #include <pulsecore/sink.h>
 #include <pulsecore/module.h>
 #include <pulsecore/core-util.h>
@@ -51,7 +47,7 @@
 
 /* General overview:
  *
- * Because JACK has a very unflexible event loop management which
+ * Because JACK has a very inflexible event loop management which
  * doesn't allow us to add our own event sources to the event thread
  * we cannot use the JACK real-time thread for dispatching our PA
  * work. Instead, we run an additional RT thread which does most of
@@ -68,7 +64,7 @@ PA_MODULE_LOAD_ONCE(TRUE);
 PA_MODULE_VERSION(PACKAGE_VERSION);
 PA_MODULE_USAGE(
         "sink_name=<name for the sink> "
-        "sink_properties=<properties  for the card> "
+        "sink_properties=<properties for the card> "
         "server_name=<jack server name> "
         "client_name=<jack client name> "
         "channels=<number of channels> "
@@ -137,7 +133,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
 
                 pa_sink_render_full(u->sink, nbytes, &chunk);
 
-                p = (uint8_t*) pa_memblock_acquire(chunk.memblock) + chunk.index;
+                p = pa_memblock_acquire_chunk(&chunk);
                 pa_deinterleave(p, u->buffer, u->channels, sizeof(float), (unsigned) offset);
                 pa_memblock_release(chunk.memblock);
 
@@ -147,6 +143,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
                 pa_sample_spec ss;
 
                 /* Humm, we're not RUNNING, hence let's write some silence */
+                /* This can happen if we're paused, or during shutdown (when we're unlinked but jack is still running). */
 
                 ss = u->sink->sample_spec;
                 ss.channels = 1;
@@ -171,10 +168,12 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
 
         case PA_SINK_MESSAGE_GET_LATENCY: {
             jack_nframes_t l, ft, d;
+            jack_latency_range_t r;
             size_t n;
 
             /* This is the "worst-case" latency */
-            l = jack_port_get_total_latency(u->client, u->port[0]) + u->frames_in_buffer;
+            jack_port_get_latency_range(u->port[0], JackPlaybackLatency, &r);
+            l = r.max + u->frames_in_buffer;
 
             if (u->saved_frame_time_valid) {
                 /* Adjust the worst case latency by the time that
@@ -197,6 +196,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
     return pa_sink_process_msg(o, code, data, offset, memchunk);
 }
 
+/* JACK Callback: This is called when JACK needs some data */
 static int jack_process(jack_nframes_t nframes, void *arg) {
     struct userdata *u = arg;
     unsigned c;
@@ -229,9 +229,8 @@ static void thread_func(void *userdata) {
     for (;;) {
         int ret;
 
-        if (PA_SINK_IS_OPENED(u->sink->thread_info.state))
-            if (u->sink->thread_info.rewind_requested)
-                pa_sink_process_rewind(u->sink, 0);
+        if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
+            pa_sink_process_rewind(u->sink, 0);
 
         if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
             goto fail;
@@ -250,6 +249,7 @@ finish:
     pa_log_debug("Thread shutting down");
 }
 
+/* JACK Callback: This is called when JACK triggers an error */
 static void jack_error_func(const char*t) {
     char *s;
 
@@ -258,6 +258,7 @@ static void jack_error_func(const char*t) {
     pa_xfree(s);
 }
 
+/* JACK Callback: This is called when JACK is set up */
 static void jack_init(void *arg) {
     struct userdata *u = arg;
 
@@ -267,6 +268,7 @@ static void jack_init(void *arg) {
         pa_make_realtime(u->core->realtime_priority+4);
 }
 
+/* JACK Callback: This is called when JACK kicks us */
 static void jack_shutdown(void* arg) {
     struct userdata *u = arg;
 
@@ -274,6 +276,7 @@ static void jack_shutdown(void* arg) {
     pa_asyncmsgq_post(u->jack_msgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_ON_SHUTDOWN, NULL, 0, NULL, NULL);
 }
 
+/* JACK Callback: This is called when JACK changes the buffer size */
 static int jack_buffer_size(jack_nframes_t nframes, void *arg) {
     struct userdata *u = arg;
 
@@ -294,6 +297,8 @@ int pa__init(pa_module*m) {
     unsigned i;
     const char **ports = NULL, **p;
     pa_sink_new_data data;
+    jack_latency_range_t r;
+    size_t n;
 
     pa_assert(m);
 
@@ -337,8 +342,9 @@ int pa__init(pa_module*m) {
     ports = jack_get_ports(u->client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical|JackPortIsInput);
 
     channels = 0;
-    for (p = ports; *p; p++)
-        channels++;
+    if (ports)
+        for (p = ports; *p; p++)
+            channels++;
 
     if (!channels)
         channels = m->core->default_sample_spec.channels;
@@ -413,7 +419,7 @@ int pa__init(pa_module*m) {
     jack_set_thread_init_callback(u->client, jack_init, u);
     jack_set_buffer_size_callback(u->client, jack_buffer_size, u);
 
-    if (!(u->thread = pa_thread_new(thread_func, u))) {
+    if (!(u->thread = pa_thread_new("jack-sink", thread_func, u))) {
         pa_log("Failed to create thread.");
         goto fail;
     }
@@ -426,7 +432,7 @@ int pa__init(pa_module*m) {
     if (do_connect) {
         for (i = 0, p = ports; i < ss.channels; i++, p++) {
 
-            if (!*p) {
+            if (!p || !*p) {
                 pa_log("Not enough physical output ports, leaving unconnected.");
                 break;
             }
@@ -440,9 +446,13 @@ int pa__init(pa_module*m) {
         }
     }
 
+    jack_port_get_latency_range(u->port[0], JackPlaybackLatency, &r);
+    n = r.max * pa_frame_size(&u->sink->sample_spec);
+    pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(n, &u->sink->sample_spec));
     pa_sink_put(u->sink);
 
-    free(ports);
+    if (ports)
+        jack_free(ports);
     pa_modargs_free(ma);
 
     return 0;
@@ -451,7 +461,8 @@ fail:
     if (ma)
         pa_modargs_free(ma);
 
-    free(ports);
+    if (ports)
+        jack_free(ports);
 
     pa__done(m);
 
@@ -475,12 +486,12 @@ void pa__done(pa_module*m) {
     if (!(u = m->userdata))
         return;
 
-    if (u->client)
-        jack_client_close(u->client);
-
     if (u->sink)
         pa_sink_unlink(u->sink);
 
+    if (u->client)
+        jack_client_close(u->client);
+
     if (u->thread) {
         pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
         pa_thread_free(u->thread);
diff --git a/src/modules/jack/module-jack-source-symdef.h b/src/modules/jack/module-jack-source-symdef.h
deleted file mode 100644 (file)
index a5b3af1..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulejacksourcesymdeffoo
-#define foomodulejacksourcesymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_jack_source_LTX_pa__init
-#define pa__done module_jack_source_LTX_pa__done
-#define pa__get_author module_jack_source_LTX_pa__get_author
-#define pa__get_description module_jack_source_LTX_pa__get_description
-#define pa__get_usage module_jack_source_LTX_pa__get_usage
-#define pa__get_version module_jack_source_LTX_pa__get_version
-#define pa__get_deprecated module_jack_source_LTX_pa__get_deprecated
-#define pa__load_once module_jack_source_LTX_pa__load_once
-#define pa__get_n_used module_jack_source_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 6c68527..cf62882 100644 (file)
 #endif
 
 #include <stdlib.h>
-#include <sys/stat.h>
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
-#include <fcntl.h>
 #include <unistd.h>
-#include <limits.h>
 
 #include <jack/jack.h>
 
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/core-error.h>
 #include <pulsecore/source.h>
 #include <pulsecore/module.h>
 #include <pulsecore/core-util.h>
@@ -128,11 +124,13 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
             return 0;
 
         case PA_SOURCE_MESSAGE_GET_LATENCY: {
+            jack_latency_range_t r;
             jack_nframes_t l, ft, d;
             size_t n;
 
             /* This is the "worst-case" latency */
-            l = jack_port_get_total_latency(u->client, u->port[0]);
+            jack_port_get_latency_range(u->port[0], JackCaptureLatency, &r);
+            l = r.max;
 
             if (u->saved_frame_time_valid) {
                 /* Adjust the worst case latency by the time that
@@ -253,6 +251,8 @@ int pa__init(pa_module*m) {
     unsigned i;
     const char **ports = NULL, **p;
     pa_source_new_data data;
+    jack_latency_range_t r;
+    size_t n;
 
     pa_assert(m);
 
@@ -289,8 +289,9 @@ int pa__init(pa_module*m) {
     ports = jack_get_ports(u->client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical|JackPortIsOutput);
 
     channels = 0;
-    for (p = ports; *p; p++)
-        channels++;
+    if (ports)
+        for (p = ports; *p; p++)
+            channels++;
 
     if (!channels)
         channels = m->core->default_sample_spec.channels;
@@ -363,7 +364,7 @@ int pa__init(pa_module*m) {
     jack_on_shutdown(u->client, jack_shutdown, u);
     jack_set_thread_init_callback(u->client, jack_init, u);
 
-    if (!(u->thread = pa_thread_new(thread_func, u))) {
+    if (!(u->thread = pa_thread_new("jack-source", thread_func, u))) {
         pa_log("Failed to create thread.");
         goto fail;
     }
@@ -376,7 +377,7 @@ int pa__init(pa_module*m) {
     if (do_connect) {
         for (i = 0, p = ports; i < ss.channels; i++, p++) {
 
-            if (!*p) {
+            if (!p || !*p) {
                 pa_log("Not enough physical output ports, leaving unconnected.");
                 break;
             }
@@ -391,9 +392,13 @@ int pa__init(pa_module*m) {
 
     }
 
+    jack_port_get_latency_range(u->port[0], JackCaptureLatency, &r);
+    n = r.max * pa_frame_size(&u->source->sample_spec);
+    pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(n, &u->source->sample_spec));
     pa_source_put(u->source);
 
-    free(ports);
+    if (ports)
+        jack_free(ports);
     pa_modargs_free(ma);
 
     return 0;
@@ -402,7 +407,8 @@ fail:
     if (ma)
         pa_modargs_free(ma);
 
-    free(ports);
+    if (ports)
+        jack_free(ports);
 
     pa__done(m);
 
@@ -425,12 +431,12 @@ void pa__done(pa_module*m) {
     if (!(u = m->userdata))
         return;
 
-    if (u->client)
-        jack_client_close(u->client);
-
     if (u->source)
         pa_source_unlink(u->source);
 
+    if (u->client)
+        jack_client_close(u->client);
+
     if (u->thread) {
         pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
         pa_thread_free(u->thread);
diff --git a/src/modules/jack/module-jackdbus-detect.c b/src/modules/jack/module-jackdbus-detect.c
new file mode 100644 (file)
index 0000000..25ac495
--- /dev/null
@@ -0,0 +1,313 @@
+/***
+  This file is part of PulseAudio.
+
+  Written by David Henningsson <david.henningsson@canonical.com>
+  Copyright 2010 Canonical Ltd.
+
+  Some code taken from other parts of PulseAudio, these are
+  Copyright 2006-2009 Lennart Poettering
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/log.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-shared.h>
+
+#include "module-jackdbus-detect-symdef.h"
+
+PA_MODULE_AUTHOR("David Henningsson");
+PA_MODULE_DESCRIPTION("Adds JACK sink/source ports when JACK is started");
+PA_MODULE_LOAD_ONCE(TRUE);
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_USAGE(
+    "channels=<number of channels> "
+    "connect=<connect ports?>");
+
+#define JACK_SERVICE_NAME "org.jackaudio.service"
+#define JACK_INTERFACE_NAME "org.jackaudio.JackControl"
+#define JACK_INTERFACE_PATH "/org/jackaudio/Controller"
+
+#define SERVICE_FILTER                         \
+       "type='signal',"                        \
+       "sender='" DBUS_SERVICE_DBUS "',"       \
+       "interface='" DBUS_INTERFACE_DBUS "',"  \
+       "member='NameOwnerChanged',"            \
+       "arg0='" JACK_SERVICE_NAME "'"
+
+#define RUNNING_FILTER(_a)                     \
+       "type='signal',"                        \
+       "sender='" JACK_SERVICE_NAME "',"       \
+       "interface='" JACK_INTERFACE_NAME "',"  \
+       "member='" _a "'"
+
+static const char* const valid_modargs[] = {
+    "channels",
+    "connect",
+    NULL
+};
+
+#define JACK_SS_SINK 0
+#define JACK_SS_SOURCE 1
+#define JACK_SS_COUNT 2
+
+static const char* const modnames[JACK_SS_COUNT] = {
+    "module-jack-sink",
+    "module-jack-source"
+};
+
+
+struct userdata {
+    pa_module *module;
+    pa_core *core;
+    pa_dbus_connection *connection;
+    pa_bool_t filter_added, match_added;
+    pa_bool_t is_service_started;
+    pa_bool_t autoconnect_ports;
+    uint32_t channels;
+    /* Using index here protects us from module unloading without us knowing */
+    int jack_module_index[JACK_SS_COUNT];
+};
+
+
+static void ensure_ports_stopped(struct userdata* u) {
+    int i;
+    pa_assert(u);
+
+    for (i = 0; i < JACK_SS_COUNT; i++)
+        if (u->jack_module_index[i]) {
+            pa_module_unload_request_by_index(u->core, u->jack_module_index[i], TRUE);
+            u->jack_module_index[i] = 0;
+            pa_log_info("Stopped %s.", modnames[i]);
+        }
+}
+
+static void ensure_ports_started(struct userdata* u) {
+    int i;
+    pa_assert(u);
+
+    for (i = 0; i < JACK_SS_COUNT; i++)
+        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);
+            } else {
+                args = pa_sprintf_malloc("connect=%s", pa_yes_no(u->autoconnect_ports));
+            }
+            m = pa_module_load(u->core, modnames[i], args);
+            pa_xfree(args);
+
+            if (m) {
+                pa_log_info("Successfully started %s.", modnames[i]);
+                u->jack_module_index[i] = m->index;
+            }
+            else
+                pa_log_info("Failed to start %s.", modnames[i]);
+        }
+}
+
+
+static pa_bool_t check_service_started(struct userdata* u) {
+    DBusError error;
+    DBusMessage *m = NULL, *reply = NULL;
+    pa_bool_t new_status = FALSE;
+    dbus_bool_t call_result;
+    pa_assert(u);
+
+    dbus_error_init(&error);
+
+    /* Just a safety check; it isn't such a big deal if the name disappears just after the call. */
+    if (!dbus_bus_name_has_owner(pa_dbus_connection_get(u->connection),
+            JACK_SERVICE_NAME, &error)) {
+        pa_log_debug("jackdbus isn't running.");
+        goto finish;
+    }
+
+    if (!(m = dbus_message_new_method_call(JACK_SERVICE_NAME, JACK_INTERFACE_PATH, JACK_INTERFACE_NAME, "IsStarted"))) {
+        pa_log("Failed to allocate IsStarted() method call.");
+        goto finish;
+    }
+
+    if (!(reply = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(u->connection), m, -1, &error))) {
+        pa_log("IsStarted() call failed: %s: %s", error.name, error.message);
+        goto finish;
+    }
+
+    if (!dbus_message_get_args(reply, &error, DBUS_TYPE_BOOLEAN, &call_result, DBUS_TYPE_INVALID)) {
+        pa_log("IsStarted() call return failed: %s: %s", error.name, error.message);
+        goto finish;
+    }
+
+    new_status = call_result;
+
+finish:
+    if (m)
+        dbus_message_unref(m);
+    if (reply)
+        dbus_message_unref(reply);
+
+    dbus_error_free(&error);
+    if (new_status)
+        ensure_ports_started(u);
+    else
+        ensure_ports_stopped(u);
+    u->is_service_started = new_status;
+    return new_status;
+}
+
+static DBusHandlerResult dbus_filter_handler(DBusConnection *c, DBusMessage *s, void *userdata) {
+    struct userdata *u = NULL;
+    DBusError error;
+
+    pa_assert(userdata);
+    u = ((pa_module*) userdata)->userdata;
+    pa_assert(u);
+
+    dbus_error_init(&error);
+
+    if (dbus_message_is_signal(s, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) {
+        const char *name, *old, *new;
+        if (!dbus_message_get_args(s, &error,
+                                   DBUS_TYPE_STRING, &name,
+                                   DBUS_TYPE_STRING, &old,
+                                   DBUS_TYPE_STRING, &new,
+                                   DBUS_TYPE_INVALID))
+            goto finish;
+        if (!pa_streq(name, JACK_SERVICE_NAME))
+            goto finish;
+
+        ensure_ports_stopped(u);
+        check_service_started(u);
+    }
+
+    else if (dbus_message_is_signal(s, JACK_INTERFACE_NAME, "ServerStarted")) {
+        ensure_ports_stopped(u);
+        check_service_started(u);
+    }
+
+    else if (dbus_message_is_signal(s, JACK_INTERFACE_NAME, "ServerStopped")) {
+        ensure_ports_stopped(u);
+    }
+
+finish:
+    dbus_error_free(&error);
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+int pa__init(pa_module *m) {
+    DBusError error;
+    pa_dbus_connection *connection = NULL;
+    struct userdata *u = NULL;
+    pa_modargs *ma;
+
+    pa_assert(m);
+
+    dbus_error_init(&error);
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments");
+        goto fail;
+    }
+
+    m->userdata = u = pa_xnew0(struct userdata, 1);
+    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 || u->channels > PA_CHANNELS_MAX) {
+        pa_log("Failed to parse channels= argument.");
+        goto fail;
+    }
+
+    if (!(connection = pa_dbus_bus_get(m->core, DBUS_BUS_SESSION, &error)) || dbus_error_is_set(&error)) {
+
+        if (connection)
+            pa_dbus_connection_unref(connection);
+
+        pa_log_error("Unable to contact D-Bus session bus: %s: %s", error.name, error.message);
+        goto fail;
+    }
+    u->connection = connection;
+
+    if (!dbus_connection_add_filter(pa_dbus_connection_get(connection), dbus_filter_handler, m, NULL)) {
+        pa_log_error("Unable to add D-Bus filter");
+        goto fail;
+    }
+    u->filter_added = 1;
+
+    if (pa_dbus_add_matches(
+                pa_dbus_connection_get(connection), &error, SERVICE_FILTER,
+                RUNNING_FILTER("ServerStarted"), RUNNING_FILTER("ServerStopped"), NULL) < 0) {
+        pa_log_error("Unable to subscribe to signals: %s: %s", error.name, error.message);
+        goto fail;
+    }
+    u->match_added = 1;
+
+    check_service_started(u);
+
+    pa_modargs_free(ma);
+    return 0;
+
+fail:
+    if (ma)
+        pa_modargs_free(ma);
+
+    dbus_error_free(&error);
+    pa__done(m);
+
+    return -1;
+}
+
+void pa__done(pa_module *m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    ensure_ports_stopped(u);
+
+    if (u->match_added) {
+        pa_dbus_remove_matches(
+                pa_dbus_connection_get(u->connection), SERVICE_FILTER,
+                RUNNING_FILTER("ServerStarted"), RUNNING_FILTER("ServerStopped"), NULL);
+    }
+
+    if (u->filter_added) {
+        dbus_connection_remove_filter(pa_dbus_connection_get(u->connection), dbus_filter_handler, m);
+    }
+
+    if (u->connection) {
+        pa_dbus_connection_unref(u->connection);
+    }
+
+    pa_xfree(u);
+}
diff --git a/src/modules/macosx/module-bonjour-publish.c b/src/modules/macosx/module-bonjour-publish.c
new file mode 100644 (file)
index 0000000..d29d518
--- /dev/null
@@ -0,0 +1,513 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Daniel Mack
+  based on module-zeroconf-publish.c
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <dns_sd.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <pulse/xmalloc.h>
+#include <pulse/util.h>
+
+#include <pulsecore/parseaddr.h>
+#include <pulsecore/sink.h>
+#include <pulsecore/source.h>
+#include <pulsecore/native-common.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/log.h>
+#include <pulsecore/dynarray.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/protocol-native.h>
+
+#include "module-bonjour-publish-symdef.h"
+
+PA_MODULE_AUTHOR("Daniel Mack");
+PA_MODULE_DESCRIPTION("Mac OS X Bonjour Service Publisher");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(TRUE);
+
+#define SERVICE_TYPE_SINK "_pulse-sink._tcp"
+#define SERVICE_TYPE_SOURCE "_pulse-source._tcp"
+#define SERVICE_TYPE_SERVER "_pulse-server._tcp"
+
+static const char* const valid_modargs[] = {
+    NULL
+};
+
+enum service_subtype {
+    SUBTYPE_HARDWARE,
+    SUBTYPE_VIRTUAL,
+    SUBTYPE_MONITOR
+};
+
+struct service {
+    struct userdata *userdata;
+    DNSServiceRef service;
+    DNSRecordRef rec, rec2;
+    char *service_name;
+    pa_object *device;
+    enum service_subtype subtype;
+};
+
+struct userdata {
+    pa_core *core;
+    pa_module *module;
+
+    pa_hashmap *services;
+    char *service_name;
+
+    pa_hook_slot *sink_new_slot, *source_new_slot, *sink_unlink_slot, *source_unlink_slot, *sink_changed_slot, *source_changed_slot;
+
+    pa_native_protocol *native;
+    DNSServiceRef main_service;
+};
+
+static void get_service_data(struct service *s, pa_sample_spec *ret_ss, pa_channel_map *ret_map, const char **ret_name, pa_proplist **ret_proplist, enum service_subtype *ret_subtype) {
+    pa_assert(s);
+    pa_assert(ret_ss);
+    pa_assert(ret_proplist);
+    pa_assert(ret_subtype);
+
+    if (pa_sink_isinstance(s->device)) {
+        pa_sink *sink = PA_SINK(s->device);
+
+        *ret_ss = sink->sample_spec;
+        *ret_map = sink->channel_map;
+        *ret_name = sink->name;
+        *ret_proplist = sink->proplist;
+        *ret_subtype = sink->flags & PA_SINK_HARDWARE ? SUBTYPE_HARDWARE : SUBTYPE_VIRTUAL;
+
+    } else if (pa_source_isinstance(s->device)) {
+        pa_source *source = PA_SOURCE(s->device);
+
+        *ret_ss = source->sample_spec;
+        *ret_map = source->channel_map;
+        *ret_name = source->name;
+        *ret_proplist = source->proplist;
+        *ret_subtype = source->monitor_of ? SUBTYPE_MONITOR : (source->flags & PA_SOURCE_HARDWARE ? SUBTYPE_HARDWARE : SUBTYPE_VIRTUAL);
+
+    } else
+        pa_assert_not_reached();
+}
+
+static void txt_record_server_data(pa_core *c, TXTRecordRef *txt) {
+    char s[128];
+    char *t;
+
+    pa_assert(c);
+
+    TXTRecordSetValue(txt, "server-version", strlen(PACKAGE_NAME" "PACKAGE_VERSION), PACKAGE_NAME" "PACKAGE_VERSION);
+
+    t = pa_get_user_name_malloc();
+    TXTRecordSetValue(txt, "user-name", strlen(t), t);
+    pa_xfree(t);
+
+    t = pa_machine_id();
+    TXTRecordSetValue(txt, "machine-id", strlen(t), t);
+    pa_xfree(t);
+
+    t = pa_uname_string();
+    TXTRecordSetValue(txt, "uname", strlen(t), t);
+    pa_xfree(t);
+
+    t = pa_get_fqdn(s, sizeof(s));
+    TXTRecordSetValue(txt, "fqdn", strlen(t), t);
+
+    snprintf(s, sizeof(s), "0x%08x", c->cookie);
+    TXTRecordSetValue(txt, "cookie", strlen(s), s);
+}
+
+static void service_free(struct service *s);
+
+static void dns_service_register_reply(DNSServiceRef sdRef,
+                                       DNSServiceFlags flags,
+                                       DNSServiceErrorType errorCode,
+                                       const char *name,
+                                       const char *regtype,
+                                       const char *domain,
+                                       void *context) {
+    struct service *s = context;
+
+    pa_assert(s);
+
+    switch (errorCode) {
+    case kDNSServiceErr_NameConflict:
+        pa_log("DNS service reported kDNSServiceErr_NameConflict\n");
+        service_free(s);
+        break;
+
+    case kDNSServiceErr_NoError:
+    default:
+        break;
+    }
+}
+
+static uint16_t compute_port(struct userdata *u) {
+    pa_strlist *i;
+
+    pa_assert(u);
+
+    for (i = pa_native_protocol_servers(u->native); i; i = pa_strlist_next(i)) {
+        pa_parsed_address a;
+
+        if (pa_parse_address(pa_strlist_data(i), &a) >= 0 &&
+            (a.type == PA_PARSED_ADDRESS_TCP4 ||
+             a.type == PA_PARSED_ADDRESS_TCP6 ||
+             a.type == PA_PARSED_ADDRESS_TCP_AUTO) &&
+            a.port > 0) {
+
+            pa_xfree(a.path_or_host);
+            return a.port;
+        }
+
+        pa_xfree(a.path_or_host);
+    }
+
+    return PA_NATIVE_DEFAULT_PORT;
+}
+
+static int publish_service(struct service *s) {
+    int r = -1;
+    TXTRecordRef txt;
+    DNSServiceErrorType err;
+    const char *name = NULL, *t;
+    pa_proplist *proplist = NULL;
+    pa_sample_spec ss;
+    pa_channel_map map;
+    char cm[PA_CHANNEL_MAP_SNPRINT_MAX], tmp[64];
+    enum service_subtype subtype;
+
+    const char * const subtype_text[] = {
+        [SUBTYPE_HARDWARE] = "hardware",
+        [SUBTYPE_VIRTUAL] = "virtual",
+        [SUBTYPE_MONITOR] = "monitor"
+    };
+
+    pa_assert(s);
+
+    if (s->service) {
+        DNSServiceRefDeallocate(s->service);
+        s->service = NULL;
+    }
+
+    TXTRecordCreate(&txt, 0, NULL);
+
+    txt_record_server_data(s->userdata->core, &txt);
+
+    get_service_data(s, &ss, &map, &name, &proplist, &subtype);
+    TXTRecordSetValue(&txt, "device", strlen(name), name);
+
+    snprintf(tmp, sizeof(tmp), "%u", ss.rate);
+    TXTRecordSetValue(&txt, "rate", strlen(tmp), tmp);
+
+    snprintf(tmp, sizeof(tmp), "%u", ss.channels);
+    TXTRecordSetValue(&txt, "channels", strlen(tmp), tmp);
+
+    t = pa_sample_format_to_string(ss.format);
+    TXTRecordSetValue(&txt, "format", strlen(t), t);
+
+    t = pa_channel_map_snprint(cm, sizeof(cm), &map);
+    TXTRecordSetValue(&txt, "channel_map", strlen(t), t);
+
+    t = subtype_text[subtype];
+    TXTRecordSetValue(&txt, "subtype", strlen(t), t);
+
+    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_DESCRIPTION)))
+        TXTRecordSetValue(&txt, "description", strlen(t), t);
+    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_ICON_NAME)))
+        TXTRecordSetValue(&txt, "icon-name", strlen(t), t);
+    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_VENDOR_NAME)))
+        TXTRecordSetValue(&txt, "vendor-name", strlen(t), t);
+    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_PRODUCT_NAME)))
+        TXTRecordSetValue(&txt, "product-name", strlen(t), t);
+    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_CLASS)))
+        TXTRecordSetValue(&txt, "class", strlen(t), t);
+    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_FORM_FACTOR)))
+        TXTRecordSetValue(&txt, "form-factor", strlen(t), t);
+
+    err = DNSServiceRegister(&s->service,
+                             0,         /* flags */
+                             kDNSServiceInterfaceIndexAny,
+                             s->service_name,
+                             pa_sink_isinstance(s->device) ? SERVICE_TYPE_SINK : SERVICE_TYPE_SOURCE,
+                             NULL,      /* domain */
+                             NULL,      /* host */
+                             compute_port(s->userdata),
+                             TXTRecordGetLength(&txt),
+                             TXTRecordGetBytesPtr(&txt),
+                             dns_service_register_reply, s);
+
+    if (err != kDNSServiceErr_NoError) {
+        pa_log("DNSServiceRegister() returned err %d", err);
+        goto finish;
+    }
+
+    pa_log_debug("Successfully registered Bonjour services for >%s<.", s->service_name);
+    return 0;
+
+finish:
+
+    /* Remove this service */
+    if (r < 0)
+        service_free(s);
+
+    TXTRecordDeallocate(&txt);
+
+    return r;
+}
+
+static struct service *get_service(struct userdata *u, pa_object *device) {
+    struct service *s;
+    char *hn, *un;
+    const char *n;
+
+    pa_assert(u);
+    pa_object_assert_ref(device);
+
+    if ((s = pa_hashmap_get(u->services, device)))
+        return s;
+
+    s = pa_xnew0(struct service, 1);
+    s->userdata = u;
+    s->device = device;
+
+    if (pa_sink_isinstance(device)) {
+        if (!(n = pa_proplist_gets(PA_SINK(device)->proplist, PA_PROP_DEVICE_DESCRIPTION)))
+            n = PA_SINK(device)->name;
+    } else {
+        if (!(n = pa_proplist_gets(PA_SOURCE(device)->proplist, PA_PROP_DEVICE_DESCRIPTION)))
+            n = PA_SOURCE(device)->name;
+    }
+
+    hn = pa_get_host_name_malloc();
+    un = pa_get_user_name_malloc();
+
+    s->service_name = pa_truncate_utf8(pa_sprintf_malloc("%s@%s: %s", un, hn, n), kDNSServiceMaxDomainName-1);
+
+    pa_xfree(un);
+    pa_xfree(hn);
+
+    pa_hashmap_put(u->services, s->device, s);
+
+    return s;
+}
+
+static void service_free(struct service *s) {
+    pa_assert(s);
+
+    pa_hashmap_remove(s->userdata->services, s->device);
+
+    if (s->service)
+        DNSServiceRefDeallocate(s->service);
+
+    pa_xfree(s->service_name);
+    pa_xfree(s);
+}
+
+static pa_bool_t shall_ignore(pa_object *o) {
+    pa_object_assert_ref(o);
+
+    if (pa_sink_isinstance(o))
+        return !!(PA_SINK(o)->flags & PA_SINK_NETWORK);
+
+    if (pa_source_isinstance(o))
+        return PA_SOURCE(o)->monitor_of || (PA_SOURCE(o)->flags & PA_SOURCE_NETWORK);
+
+    pa_assert_not_reached();
+}
+
+static pa_hook_result_t device_new_or_changed_cb(pa_core *c, pa_object *o, struct userdata *u) {
+    pa_assert(c);
+    pa_object_assert_ref(o);
+
+    if (!shall_ignore(o))
+        publish_service(get_service(u, o));
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t device_unlink_cb(pa_core *c, pa_object *o, struct userdata *u) {
+    struct service *s;
+
+    pa_assert(c);
+    pa_object_assert_ref(o);
+
+    if ((s = pa_hashmap_get(u->services, o)))
+        service_free(s);
+
+    return PA_HOOK_OK;
+}
+
+static int publish_main_service(struct userdata *u) {
+    DNSServiceErrorType err;
+    TXTRecordRef txt;
+
+    pa_assert(u);
+
+    if (u->main_service) {
+        DNSServiceRefDeallocate(u->main_service);
+        u->main_service = NULL;
+    }
+
+    TXTRecordCreate(&txt, 0, NULL);
+    txt_record_server_data(u->core, &txt);
+
+    err = DNSServiceRegister(&u->main_service,
+                             0, /* flags */
+                             kDNSServiceInterfaceIndexAny,
+                             u->service_name,
+                             SERVICE_TYPE_SERVER,
+                             NULL, /* domain */
+                             NULL, /* host */
+                             compute_port(u),
+                             TXTRecordGetLength(&txt),
+                             TXTRecordGetBytesPtr(&txt),
+                             NULL, NULL);
+
+    if (err != kDNSServiceErr_NoError) {
+        pa_log("%s(): DNSServiceRegister() returned err %d", __func__, err);
+        return err;
+    }
+
+    TXTRecordDeallocate(&txt);
+
+    return 0;
+}
+
+static int publish_all_services(struct userdata *u) {
+    pa_sink *sink;
+    pa_source *source;
+    uint32_t idx;
+
+    pa_assert(u);
+
+    pa_log_debug("Publishing services in Bonjour");
+
+    for (sink = PA_SINK(pa_idxset_first(u->core->sinks, &idx)); sink; sink = PA_SINK(pa_idxset_next(u->core->sinks, &idx)))
+        if (!shall_ignore(PA_OBJECT(sink)))
+            publish_service(get_service(u, PA_OBJECT(sink)));
+
+    for (source = PA_SOURCE(pa_idxset_first(u->core->sources, &idx)); source; source = PA_SOURCE(pa_idxset_next(u->core->sources, &idx)))
+        if (!shall_ignore(PA_OBJECT(source)))
+            publish_service(get_service(u, PA_OBJECT(source)));
+
+    return publish_main_service(u);
+}
+
+static void unpublish_all_services(struct userdata *u) {
+    void *state = NULL;
+    struct service *s;
+
+    pa_assert(u);
+
+    pa_log_debug("Unpublishing services in Bonjour");
+
+    while ((s = pa_hashmap_iterate(u->services, &state, NULL)))
+        service_free(s);
+
+    if (u->main_service)
+        DNSServiceRefDeallocate(u->main_service);
+}
+
+int pa__init(pa_module*m) {
+
+    struct userdata *u;
+    pa_modargs *ma = NULL;
+    char *hn, *un;
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments.");
+        goto fail;
+    }
+
+    m->userdata = u = pa_xnew0(struct userdata, 1);
+    u->core = m->core;
+    u->module = m;
+    u->native = pa_native_protocol_get(u->core);
+
+    u->services = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+
+    u->sink_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE, (pa_hook_cb_t) device_new_or_changed_cb, u);
+    u->sink_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PROPLIST_CHANGED], PA_HOOK_LATE, (pa_hook_cb_t) device_new_or_changed_cb, u);
+    u->sink_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_LATE, (pa_hook_cb_t) device_unlink_cb, u);
+    u->source_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_LATE, (pa_hook_cb_t) device_new_or_changed_cb, u);
+    u->source_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_PROPLIST_CHANGED], PA_HOOK_LATE, (pa_hook_cb_t) device_new_or_changed_cb, u);
+    u->source_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_LATE, (pa_hook_cb_t) device_unlink_cb, u);
+
+    un = pa_get_user_name_malloc();
+    hn = pa_get_host_name_malloc();
+    u->service_name = pa_truncate_utf8(pa_sprintf_malloc("%s@%s", un, hn), kDNSServiceMaxDomainName-1);
+    pa_xfree(un);
+    pa_xfree(hn);
+
+    publish_all_services(u);
+    pa_modargs_free(ma);
+
+    return 0;
+
+fail:
+    pa__done(m);
+
+    if (ma)
+        pa_modargs_free(ma);
+
+    return -1;
+}
+
+void pa__done(pa_module*m) {
+    struct userdata*u;
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    unpublish_all_services(u);
+
+    if (u->services)
+        pa_hashmap_free(u->services, NULL);
+
+    if (u->sink_new_slot)
+        pa_hook_slot_free(u->sink_new_slot);
+    if (u->source_new_slot)
+        pa_hook_slot_free(u->source_new_slot);
+    if (u->sink_changed_slot)
+        pa_hook_slot_free(u->sink_changed_slot);
+    if (u->source_changed_slot)
+        pa_hook_slot_free(u->source_changed_slot);
+    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->native)
+        pa_native_protocol_unref(u->native);
+
+    pa_xfree(u->service_name);
+    pa_xfree(u);
+}
diff --git a/src/modules/macosx/module-coreaudio-detect.c b/src/modules/macosx/module-coreaudio-detect.c
new file mode 100644 (file)
index 0000000..4652e6f
--- /dev/null
@@ -0,0 +1,285 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009,2010 Daniel Mack <daniel@caiaq.de>
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/module.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/log.h>
+#include <pulsecore/llist.h>
+
+#include <CoreAudio/CoreAudio.h>
+
+#include "module-coreaudio-detect-symdef.h"
+
+#define DEVICE_MODULE_NAME "module-coreaudio-device"
+
+PA_MODULE_AUTHOR("Daniel Mack");
+PA_MODULE_DESCRIPTION("CoreAudio device detection");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(TRUE);
+PA_MODULE_USAGE("ioproc_frames=<passed on to module-coreaudio-device> ");
+
+static const char* const valid_modargs[] = {
+    "ioproc_frames",
+    NULL
+};
+
+typedef struct ca_device ca_device;
+
+struct ca_device {
+    AudioObjectID id;
+    unsigned int module_index;
+    PA_LLIST_FIELDS(ca_device);
+};
+
+struct userdata {
+    int detect_fds[2];
+    pa_io_event *detect_io;
+    unsigned int ioproc_frames;
+    PA_LLIST_HEAD(ca_device, devices);
+};
+
+static int ca_device_added(struct pa_module *m, AudioObjectID id) {
+    AudioObjectPropertyAddress property_address;
+    OSStatus err;
+    pa_module *mod;
+    struct userdata *u;
+    struct ca_device *dev;
+    char *args, tmp[64];
+    UInt32 size;
+
+    pa_assert(m);
+    pa_assert_se(u = m->userdata);
+
+    /* To prevent generating a black hole that will suck us in,
+       don't create sources/sinks for PulseAudio virtual devices */
+
+    property_address.mSelector = kAudioDevicePropertyDeviceManufacturer;
+    property_address.mScope = kAudioObjectPropertyScopeGlobal;
+    property_address.mElement = kAudioObjectPropertyElementMaster;
+
+    size = sizeof(tmp);
+    err = AudioObjectGetPropertyData(id, &property_address, 0, NULL, &size, tmp);
+
+    if (!err && pa_streq(tmp, "pulseaudio.org"))
+        return 0;
+
+    if (u->ioproc_frames)
+        args = pa_sprintf_malloc("object_id=%d ioproc_frames=%d", (int) id, u->ioproc_frames);
+    else
+        args = pa_sprintf_malloc("object_id=%d", (int) id);
+
+    pa_log_debug("Loading %s with arguments '%s'", DEVICE_MODULE_NAME, args);
+    mod = pa_module_load(m->core, DEVICE_MODULE_NAME, args);
+    pa_xfree(args);
+
+    if (!mod) {
+        pa_log_info("Failed to load module %s with arguments '%s'", DEVICE_MODULE_NAME, args);
+        return -1;
+    }
+
+    dev = pa_xnew0(ca_device, 1);
+    dev->module_index = mod->index;
+    dev->id = id;
+
+    PA_LLIST_INIT(ca_device, dev);
+    PA_LLIST_PREPEND(ca_device, u->devices, dev);
+
+    return 0;
+}
+
+static int ca_update_device_list(struct pa_module *m) {
+    AudioObjectPropertyAddress property_address;
+    OSStatus err;
+    UInt32 i, size, num_devices;
+    AudioDeviceID *device_id;
+    struct ca_device *dev;
+    struct userdata *u;
+
+    pa_assert(m);
+    pa_assert_se(u = m->userdata);
+
+    property_address.mSelector = kAudioHardwarePropertyDevices;
+    property_address.mScope = kAudioObjectPropertyScopeGlobal;
+    property_address.mElement = kAudioObjectPropertyElementMaster;
+
+    /* get the number of currently available audio devices */
+    err = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &property_address, 0, NULL, &size);
+    if (err) {
+        pa_log("Unable to get data size for kAudioHardwarePropertyDevices.");
+        return -1;
+    }
+
+    num_devices = size / sizeof(AudioDeviceID);
+    device_id = pa_xnew(AudioDeviceID, num_devices);
+
+    err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property_address, 0, NULL, &size, device_id);
+    if (err) {
+        pa_log("Unable to get kAudioHardwarePropertyDevices.");
+        pa_xfree(device_id);
+        return -1;
+    }
+
+    /* scan for devices which are reported but not in our cached list */
+    for (i = 0; i < num_devices; i++) {
+        bool found = FALSE;
+
+        PA_LLIST_FOREACH(dev, u->devices)
+            if (dev->id == device_id[i]) {
+                found = TRUE;
+                break;
+            }
+
+        if (!found)
+            ca_device_added(m, device_id[i]);
+    }
+
+    /* scan for devices which are in our cached list but are not reported */
+scan_removed:
+
+    PA_LLIST_FOREACH(dev, u->devices) {
+        bool found = FALSE;
+
+        for (i = 0; i < num_devices; i++)
+            if (dev->id == device_id[i]) {
+                found = TRUE;
+                break;
+            }
+
+        if (!found) {
+            pa_log_debug("object id %d has been removed (module index %d) %p", (unsigned int) dev->id, dev->module_index, dev);
+            pa_module_unload_request_by_index(m->core, dev->module_index, TRUE);
+            PA_LLIST_REMOVE(ca_device, u->devices, dev);
+            pa_xfree(dev);
+            /* the current list item pointer is not valid anymore, so start over. */
+            goto scan_removed;
+        }
+    }
+
+    pa_xfree(device_id);
+    return 0;
+}
+
+static OSStatus property_listener_proc(AudioObjectID objectID, UInt32 numberAddresses,
+                                       const AudioObjectPropertyAddress inAddresses[],
+                                       void *clientData)
+{
+    struct userdata *u = clientData;
+    char dummy = 1;
+
+    pa_assert(u);
+
+    /* dispatch module load/unload operations in main thread */
+    write(u->detect_fds[1], &dummy, 1);
+
+    return 0;
+}
+
+static void detect_handle(pa_mainloop_api *a, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
+    pa_module *m = userdata;
+    char dummy;
+
+    pa_assert(m);
+
+    read(fd, &dummy, 1);
+    ca_update_device_list(m);
+}
+
+int pa__init(pa_module *m) {
+    struct userdata *u = pa_xnew0(struct userdata, 1);
+    AudioObjectPropertyAddress property_address;
+    pa_modargs *ma;
+
+    pa_assert(m);
+
+    m->userdata = u;
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments.");
+        goto fail;
+    }
+
+    pa_modargs_get_value_u32(ma, "ioproc_frames", &u->ioproc_frames);
+
+    property_address.mSelector = kAudioHardwarePropertyDevices;
+    property_address.mScope = kAudioObjectPropertyScopeGlobal;
+    property_address.mElement = kAudioObjectPropertyElementMaster;
+
+    if (AudioObjectAddPropertyListener(kAudioObjectSystemObject, &property_address, property_listener_proc, u)) {
+        pa_log("AudioObjectAddPropertyListener() failed.");
+        goto fail;
+    }
+
+    if (ca_update_device_list(m))
+       goto fail;
+
+    pa_assert_se(pipe(u->detect_fds) == 0);
+    pa_assert_se(u->detect_io = m->core->mainloop->io_new(m->core->mainloop, u->detect_fds[0], PA_IO_EVENT_INPUT, detect_handle, m));
+
+    return 0;
+
+fail:
+    pa_xfree(u);
+    return -1;
+}
+
+void pa__done(pa_module *m) {
+    struct userdata *u;
+    struct ca_device *dev;
+    AudioObjectPropertyAddress property_address;
+
+    pa_assert(m);
+    pa_assert_se(u = m->userdata);
+
+    dev = u->devices;
+
+    property_address.mSelector = kAudioHardwarePropertyDevices;
+    property_address.mScope = kAudioObjectPropertyScopeGlobal;
+    property_address.mElement = kAudioObjectPropertyElementMaster;
+
+    AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &property_address, property_listener_proc, u);
+
+    while (dev) {
+        struct ca_device *next = dev->next;
+
+        pa_module_unload_request_by_index(m->core, dev->module_index, TRUE);
+        pa_xfree(dev);
+
+        dev = next;
+    }
+
+    if (u->detect_fds[0] >= 0)
+        close(u->detect_fds[0]);
+
+    if (u->detect_fds[1] >= 0)
+        close(u->detect_fds[1]);
+
+    if (u->detect_io)
+        m->core->mainloop->io_free(u->detect_io);
+
+    pa_xfree(u);
+}
diff --git a/src/modules/macosx/module-coreaudio-device.c b/src/modules/macosx/module-coreaudio-device.c
new file mode 100644 (file)
index 0000000..b1a5176
--- /dev/null
@@ -0,0 +1,904 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009,2010 Daniel Mack <daniel@caiaq.de>
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+/* TODO:
+    - implement hardware volume controls
+    - handle audio device stream format changes (will require changes to the core)
+    - add an "off" mode that removes all sinks and sources
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/sink.h>
+#include <pulsecore/source.h>
+#include <pulsecore/module.h>
+#include <pulsecore/sample-util.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/log.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/llist.h>
+#include <pulsecore/card.h>
+#include <pulsecore/strbuf.h>
+#include <pulsecore/thread.h>
+#include <pulsecore/thread-mq.h>
+#include <pulsecore/i18n.h>
+
+#include <CoreAudio/CoreAudio.h>
+#include <CoreAudio/CoreAudioTypes.h>
+#include <CoreAudio/AudioHardware.h>
+
+#include "module-coreaudio-device-symdef.h"
+
+#define DEFAULT_FRAMES_PER_IOPROC 512
+
+PA_MODULE_AUTHOR("Daniel Mack");
+PA_MODULE_DESCRIPTION("CoreAudio device");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(FALSE);
+PA_MODULE_USAGE("object_id=<the CoreAudio device id> "
+                "ioproc_frames=<audio frames per IOProc call> ");
+
+static const char* const valid_modargs[] = {
+    "object_id",
+    "ioproc_frames",
+    NULL
+};
+
+enum {
+    CA_MESSAGE_RENDER = PA_SINK_MESSAGE_MAX,
+};
+
+typedef struct coreaudio_sink coreaudio_sink;
+typedef struct coreaudio_source coreaudio_source;
+
+struct userdata {
+    AudioObjectID object_id;
+    AudioDeviceIOProcID proc_id;
+
+    pa_thread_mq thread_mq;
+    pa_asyncmsgq *async_msgq;
+
+    pa_rtpoll *rtpoll;
+    pa_thread *thread;
+
+    pa_module *module;
+    pa_card *card;
+    pa_bool_t running;
+
+    char *device_name, *vendor_name;
+
+    const AudioBufferList *render_input_data;
+    AudioBufferList       *render_output_data;
+
+    AudioStreamBasicDescription stream_description;
+
+    PA_LLIST_HEAD(coreaudio_sink, sinks);
+    PA_LLIST_HEAD(coreaudio_source, sources);
+};
+
+struct coreaudio_sink {
+    pa_sink *pa_sink;
+    struct userdata *userdata;
+
+    char *name;
+    unsigned int channel_idx;
+    pa_bool_t active;
+
+    pa_channel_map map;
+    pa_sample_spec ss;
+
+    PA_LLIST_FIELDS(coreaudio_sink);
+};
+
+struct coreaudio_source {
+    pa_source *pa_source;
+    struct userdata *userdata;
+
+    char *name;
+    unsigned int channel_idx;
+    pa_bool_t active;
+
+    pa_channel_map map;
+    pa_sample_spec ss;
+
+    PA_LLIST_FIELDS(coreaudio_source);
+};
+
+static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
+    return 0;
+}
+
+static OSStatus io_render_proc (AudioDeviceID          device,
+                                const AudioTimeStamp  *now,
+                                const AudioBufferList *inputData,
+                                const AudioTimeStamp  *inputTime,
+                                AudioBufferList       *outputData,
+                                const AudioTimeStamp  *outputTime,
+                                void                  *clientData)
+{
+    struct userdata *u = clientData;
+
+    pa_assert(u);
+    pa_assert(device == u->object_id);
+
+    u->render_input_data = inputData;
+    u->render_output_data = outputData;
+
+    if (u->sinks)
+        pa_assert_se(pa_asyncmsgq_send(u->async_msgq, PA_MSGOBJECT(u->sinks->pa_sink),
+                                        CA_MESSAGE_RENDER, NULL, 0, NULL) == 0);
+
+    if (u->sources)
+        pa_assert_se(pa_asyncmsgq_send(u->async_msgq, PA_MSGOBJECT(u->sources->pa_source),
+                                        CA_MESSAGE_RENDER, NULL, 0, NULL) == 0);
+
+    return 0;
+}
+
+static OSStatus ca_stream_format_changed(AudioObjectID objectID,
+                                         UInt32 numberAddresses,
+                                         const AudioObjectPropertyAddress addresses[],
+                                         void *clientData)
+{
+    struct userdata *u = clientData;
+    UInt32 i;
+
+    pa_assert(u);
+
+    /* REVISIT: PA can't currently handle external format change requests.
+     * Hence, we set the original format back in this callback to avoid horrible audio artefacts.
+     * The device settings will appear to be 'locked' for any application as long as the PA daemon is running.
+     * Once we're able to propagate such events up in the core, this needs to be changed. */
+
+    for (i = 0; i < numberAddresses; i++)
+        AudioObjectSetPropertyData(objectID, addresses + i, 0, NULL, sizeof(u->stream_description), &u->stream_description);
+
+    return 0;
+}
+
+static pa_usec_t get_latency_us(pa_object *o) {
+    struct userdata *u;
+    pa_sample_spec *ss;
+    bool is_source;
+    UInt32 v = 0, total = 0;
+    UInt32 err, size = sizeof(v);
+    AudioObjectPropertyAddress property_address;
+    AudioObjectID stream_id;
+
+    if (pa_sink_isinstance(o)) {
+        coreaudio_sink *sink = PA_SINK(o)->userdata;
+
+        u = sink->userdata;
+        ss = &sink->ss;
+        is_source = FALSE;
+    } else if (pa_source_isinstance(o)) {
+        coreaudio_source *source = PA_SOURCE(o)->userdata;
+
+        u = source->userdata;
+        ss = &source->ss;
+        is_source = TRUE;
+    } else
+        pa_assert_not_reached();
+
+    pa_assert(u);
+
+    property_address.mScope = is_source ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
+    property_address.mElement = kAudioObjectPropertyElementMaster;
+
+    /* get the device latency */
+    property_address.mSelector = kAudioDevicePropertyLatency;
+    size = sizeof(v);
+    err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, &v);
+    if (!err)
+        total += v;
+    else
+        pa_log_warn("Failed to get device latency: %i", err);
+
+    /* the IOProc buffer size */
+    property_address.mSelector = kAudioDevicePropertyBufferFrameSize;
+    size = sizeof(v);
+    err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, &v);
+    if (!err)
+        total += v;
+    else
+        pa_log_warn("Failed to get buffer frame size: %i", err);
+
+    /* IOProc safety offset - this value is the same for both directions, hence we divide it by 2 */
+    property_address.mSelector = kAudioDevicePropertySafetyOffset;
+    size = sizeof(v);
+    err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, &v);
+    if (!err)
+        total += v / 2;
+    else
+        pa_log_warn("Failed to get safety offset: %i", err);
+
+    /* get the stream latency.
+     * FIXME: this assumes the stream latency is the same for all streams */
+    property_address.mSelector = kAudioDevicePropertyStreams;
+    size = sizeof(stream_id);
+    err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, &stream_id);
+    if (!err) {
+        property_address.mSelector = kAudioStreamPropertyLatency;
+        property_address.mScope = kAudioObjectPropertyScopeGlobal;
+        size = sizeof(v);
+        err = AudioObjectGetPropertyData(stream_id, &property_address, 0, NULL, &size, &v);
+        if (!err)
+            total += v;
+        else
+            pa_log_warn("Failed to get stream latency: %i", err);
+    } else
+        pa_log_warn("Failed to get streams: %i", err);
+
+    return pa_bytes_to_usec(total * pa_frame_size(ss), ss);
+}
+
+static void ca_device_check_device_state(struct userdata *u) {
+    coreaudio_sink *ca_sink;
+    coreaudio_source *ca_source;
+    pa_bool_t active = FALSE;
+
+    pa_assert(u);
+
+    for (ca_sink = u->sinks; ca_sink; ca_sink = ca_sink->next)
+        if (ca_sink->active)
+            active = TRUE;
+
+    for (ca_source = u->sources; ca_source; ca_source = ca_source->next)
+        if (ca_source->active)
+            active = TRUE;
+
+    if (active && !u->running)
+        AudioDeviceStart(u->object_id, u->proc_id);
+    else if (!active && u->running)
+        AudioDeviceStop(u->object_id, u->proc_id);
+
+    u->running = active;
+}
+
+static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
+    coreaudio_sink *sink = PA_SINK(o)->userdata;
+    struct userdata *u = sink->userdata;
+    unsigned int i;
+    pa_memchunk audio_chunk;
+
+    switch (code) {
+        case CA_MESSAGE_RENDER: {
+            /* audio out */
+            for (i = 0; i < u->render_output_data->mNumberBuffers; i++) {
+                AudioBuffer *buf = u->render_output_data->mBuffers + i;
+
+                pa_assert(sink);
+
+                if (PA_SINK_IS_OPENED(sink->pa_sink->thread_info.state)) {
+                    audio_chunk.memblock = pa_memblock_new_fixed(u->module->core->mempool, buf->mData, buf->mDataByteSize, FALSE);
+                    audio_chunk.length = buf->mDataByteSize;
+                    audio_chunk.index = 0;
+
+                    pa_sink_render_into_full(sink->pa_sink, &audio_chunk);
+                    pa_memblock_unref_fixed(audio_chunk.memblock);
+                }
+
+                sink = sink->next;
+            }
+
+            return 0;
+        }
+
+        case PA_SINK_MESSAGE_GET_LATENCY: {
+            *((pa_usec_t *) data) = get_latency_us(PA_OBJECT(o));
+            return 0;
+        }
+    }
+
+    return pa_sink_process_msg(o, code, data, offset, chunk);
+}
+
+static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
+    coreaudio_source *source = PA_SOURCE(o)->userdata;
+    struct userdata *u = source->userdata;
+    unsigned int i;
+    pa_memchunk audio_chunk;
+
+    switch (code) {
+        case CA_MESSAGE_RENDER: {
+            /* audio in */
+            for (i = 0; i < u->render_input_data->mNumberBuffers; i++) {
+                const AudioBuffer *buf = u->render_input_data->mBuffers + i;
+
+                pa_assert(source);
+
+                if (PA_SOURCE_IS_OPENED(source->pa_source->thread_info.state)) {
+                    audio_chunk.memblock = pa_memblock_new_fixed(u->module->core->mempool, buf->mData, buf->mDataByteSize, TRUE);
+                    audio_chunk.length = buf->mDataByteSize;
+                    audio_chunk.index = 0;
+
+                    pa_source_post(source->pa_source, &audio_chunk);
+                    pa_memblock_unref_fixed(audio_chunk.memblock);
+                }
+
+                source = source->next;
+            }
+
+            return 0;
+        }
+
+        case PA_SOURCE_MESSAGE_GET_LATENCY: {
+            *((pa_usec_t *) data) = get_latency_us(PA_OBJECT(o));
+            return 0;
+        }
+    }
+
+    return pa_source_process_msg(o, code, data, offset, chunk);;
+}
+
+static int ca_sink_set_state(pa_sink *s, pa_sink_state_t state)
+{
+    coreaudio_sink *sink = s->userdata;
+
+    switch (state) {
+        case PA_SINK_SUSPENDED:
+        case PA_SINK_IDLE:
+            sink->active = FALSE;
+            break;
+
+        case PA_SINK_RUNNING:
+            sink->active = TRUE;
+            break;
+
+        case PA_SINK_UNLINKED:
+        case PA_SINK_INIT:
+        case PA_SINK_INVALID_STATE:
+            ;
+    }
+
+    ca_device_check_device_state(sink->userdata);
+
+    return 0;
+}
+
+static int ca_device_create_sink(pa_module *m, AudioBuffer *buf, int channel_idx) {
+    OSStatus err;
+    UInt32 size;
+    struct userdata *u = m->userdata;
+    pa_sink_new_data new_data;
+    pa_sink_flags_t flags = PA_SINK_LATENCY | PA_SINK_HARDWARE;
+    coreaudio_sink *ca_sink;
+    pa_sink *sink;
+    unsigned int i;
+    char tmp[255];
+    pa_strbuf *strbuf;
+    AudioObjectPropertyAddress property_address;
+
+    ca_sink = pa_xnew0(coreaudio_sink, 1);
+    ca_sink->map.channels = buf->mNumberChannels;
+    ca_sink->ss.channels = buf->mNumberChannels;
+    ca_sink->channel_idx = channel_idx;
+
+    /* build a name for this stream */
+    strbuf = pa_strbuf_new();
+
+    for (i = 0; i < buf->mNumberChannels; i++) {
+        property_address.mSelector = kAudioObjectPropertyElementName;
+        property_address.mScope = kAudioDevicePropertyScopeOutput;
+        property_address.mElement = channel_idx + i + 1;
+        size = sizeof(tmp);
+        err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, tmp);
+        if (err || !strlen(tmp))
+            snprintf(tmp, sizeof(tmp), "Channel %d", (int) property_address.mElement);
+
+        if (i > 0)
+            pa_strbuf_puts(strbuf, ", ");
+
+        pa_strbuf_puts(strbuf, tmp);
+    }
+
+    ca_sink->name = pa_strbuf_tostring_free(strbuf);
+
+    pa_log_debug("Stream name is >%s<", ca_sink->name);
+
+    /* default to mono streams */
+    for (i = 0; i < ca_sink->map.channels; i++)
+        ca_sink->map.map[i] = PA_CHANNEL_POSITION_MONO;
+
+    if (buf->mNumberChannels == 2) {
+        ca_sink->map.map[0] = PA_CHANNEL_POSITION_LEFT;
+        ca_sink->map.map[1] = PA_CHANNEL_POSITION_RIGHT;
+    }
+
+    ca_sink->ss.rate = u->stream_description.mSampleRate;
+    ca_sink->ss.format = PA_SAMPLE_FLOAT32LE;
+
+    pa_sink_new_data_init(&new_data);
+    new_data.card = u->card;
+    new_data.driver = __FILE__;
+    new_data.module = u->module;
+    new_data.namereg_fail = FALSE;
+    pa_sink_new_data_set_name(&new_data, ca_sink->name);
+    pa_sink_new_data_set_channel_map(&new_data, &ca_sink->map);
+    pa_sink_new_data_set_sample_spec(&new_data, &ca_sink->ss);
+    pa_proplist_sets(new_data.proplist, PA_PROP_DEVICE_STRING, u->device_name);
+    pa_proplist_sets(new_data.proplist, PA_PROP_DEVICE_PRODUCT_NAME, u->device_name);
+    pa_proplist_sets(new_data.proplist, PA_PROP_DEVICE_DESCRIPTION, u->device_name);
+    pa_proplist_sets(new_data.proplist, PA_PROP_DEVICE_ACCESS_MODE, "mmap");
+    pa_proplist_sets(new_data.proplist, PA_PROP_DEVICE_CLASS, "sound");
+    pa_proplist_sets(new_data.proplist, PA_PROP_DEVICE_API, "CoreAudio");
+    pa_proplist_setf(new_data.proplist, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE, "%lu", (unsigned long) buf->mDataByteSize);
+
+    if (u->vendor_name)
+        pa_proplist_sets(new_data.proplist, PA_PROP_DEVICE_VENDOR_NAME, u->vendor_name);
+
+    sink = pa_sink_new(m->core, &new_data, flags);
+    pa_sink_new_data_done(&new_data);
+
+    if (!sink) {
+        pa_log("unable to create sink.");
+        return -1;
+    }
+
+    sink->parent.process_msg = sink_process_msg;
+    sink->userdata = ca_sink;
+    sink->set_state = ca_sink_set_state;
+
+    pa_sink_set_asyncmsgq(sink, u->thread_mq.inq);
+    pa_sink_set_rtpoll(sink, u->rtpoll);
+
+    ca_sink->pa_sink = sink;
+    ca_sink->userdata = u;
+
+    PA_LLIST_PREPEND(coreaudio_sink, u->sinks, ca_sink);
+
+    return 0;
+}
+
+static int ca_source_set_state(pa_source *s, pa_source_state_t state)
+{
+    coreaudio_source *source = s->userdata;
+
+    switch (state) {
+        case PA_SOURCE_SUSPENDED:
+        case PA_SOURCE_IDLE:
+            source->active = FALSE;
+            break;
+
+        case PA_SOURCE_RUNNING:
+            source->active = TRUE;
+            break;
+
+        case PA_SOURCE_UNLINKED:
+        case PA_SOURCE_INIT:
+        case PA_SOURCE_INVALID_STATE:
+            ;
+    }
+
+    ca_device_check_device_state(source->userdata);
+
+    return 0;
+}
+
+static int ca_device_create_source(pa_module *m, AudioBuffer *buf, int channel_idx) {
+    OSStatus err;
+    UInt32 size;
+    struct userdata *u = m->userdata;
+    pa_source_new_data new_data;
+    pa_source_flags_t flags = PA_SOURCE_LATENCY | PA_SOURCE_HARDWARE;
+    coreaudio_source *ca_source;
+    pa_source *source;
+    unsigned int i;
+    char tmp[255];
+    pa_strbuf *strbuf;
+    AudioObjectPropertyAddress property_address;
+
+    ca_source = pa_xnew0(coreaudio_source, 1);
+    ca_source->map.channels = buf->mNumberChannels;
+    ca_source->ss.channels = buf->mNumberChannels;
+    ca_source->channel_idx = channel_idx;
+
+    /* build a name for this stream */
+    strbuf = pa_strbuf_new();
+
+    for (i = 0; i < buf->mNumberChannels; i++) {
+        property_address.mSelector = kAudioObjectPropertyElementName;
+        property_address.mScope = kAudioDevicePropertyScopeInput;
+        property_address.mElement = channel_idx + i + 1;
+        size = sizeof(tmp);
+        err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, tmp);
+        if (err || !strlen(tmp))
+            snprintf(tmp, sizeof(tmp), "Channel %d", (int) property_address.mElement);
+
+        if (i > 0)
+            pa_strbuf_puts(strbuf, ", ");
+
+        pa_strbuf_puts(strbuf, tmp);
+    }
+
+    ca_source->name = pa_strbuf_tostring_free(strbuf);
+
+    pa_log_debug("Stream name is >%s<", ca_source->name);
+
+    /* default to mono streams */
+    for (i = 0; i < ca_source->map.channels; i++)
+        ca_source->map.map[i] = PA_CHANNEL_POSITION_MONO;
+
+    if (buf->mNumberChannels == 2) {
+        ca_source->map.map[0] = PA_CHANNEL_POSITION_LEFT;
+        ca_source->map.map[1] = PA_CHANNEL_POSITION_RIGHT;
+    }
+
+    ca_source->ss.rate = u->stream_description.mSampleRate;
+    ca_source->ss.format = PA_SAMPLE_FLOAT32LE;
+
+    pa_source_new_data_init(&new_data);
+    new_data.card = u->card;
+    new_data.driver = __FILE__;
+    new_data.module = u->module;
+    new_data.namereg_fail = FALSE;
+    pa_source_new_data_set_name(&new_data, ca_source->name);
+    pa_source_new_data_set_channel_map(&new_data, &ca_source->map);
+    pa_source_new_data_set_sample_spec(&new_data, &ca_source->ss);
+    pa_proplist_sets(new_data.proplist, PA_PROP_DEVICE_STRING, u->device_name);
+    pa_proplist_sets(new_data.proplist, PA_PROP_DEVICE_PRODUCT_NAME, u->device_name);
+    pa_proplist_sets(new_data.proplist, PA_PROP_DEVICE_DESCRIPTION, u->device_name);
+    pa_proplist_sets(new_data.proplist, PA_PROP_DEVICE_ACCESS_MODE, "mmap");
+    pa_proplist_sets(new_data.proplist, PA_PROP_DEVICE_CLASS, "sound");
+    pa_proplist_sets(new_data.proplist, PA_PROP_DEVICE_API, "CoreAudio");
+    pa_proplist_setf(new_data.proplist, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE, "%lu", (unsigned long) buf->mDataByteSize);
+
+    if (u->vendor_name)
+        pa_proplist_sets(new_data.proplist, PA_PROP_DEVICE_VENDOR_NAME, u->vendor_name);
+
+    source = pa_source_new(m->core, &new_data, flags);
+    pa_source_new_data_done(&new_data);
+
+    if (!source) {
+        pa_log("unable to create source.");
+        return -1;
+    }
+
+    source->parent.process_msg = source_process_msg;
+    source->userdata = ca_source;
+    source->set_state = ca_source_set_state;
+
+    pa_source_set_asyncmsgq(source, u->thread_mq.inq);
+    pa_source_set_rtpoll(source, u->rtpoll);
+
+    ca_source->pa_source = source;
+    ca_source->userdata = u;
+
+    PA_LLIST_PREPEND(coreaudio_source, u->sources, ca_source);
+
+    return 0;
+}
+
+static int ca_device_create_streams(pa_module *m, bool direction_in) {
+    OSStatus err;
+    UInt32 size, i, channel_idx;
+    struct userdata *u = m->userdata;
+    AudioBufferList *buffer_list;
+    AudioObjectPropertyAddress property_address;
+
+    property_address.mScope = direction_in ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
+    property_address.mElement = kAudioObjectPropertyElementMaster;
+
+    /* get current stream format */
+    size = sizeof(AudioStreamBasicDescription);
+    property_address.mSelector = kAudioDevicePropertyStreamFormat;
+    err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, &u->stream_description);
+    if (err) {
+        /* no appropriate streams found - silently bail. */
+        return -1;
+    }
+
+    if (u->stream_description.mFormatID != kAudioFormatLinearPCM) {
+        pa_log("Unsupported audio format '%c%c%c%c'",
+            (char) (u->stream_description.mFormatID >> 24),
+            (char) (u->stream_description.mFormatID >> 16) & 0xff,
+            (char) (u->stream_description.mFormatID >> 8) & 0xff,
+            (char) (u->stream_description.mFormatID & 0xff));
+        return -1;
+    }
+
+    /* get stream configuration */
+    size = 0;
+    property_address.mSelector = kAudioDevicePropertyStreamConfiguration;
+    err = AudioObjectGetPropertyDataSize(u->object_id, &property_address, 0, NULL, &size);
+    if (err) {
+        pa_log("Failed to get kAudioDevicePropertyStreamConfiguration (%s).", direction_in ? "input" : "output");
+        return -1;
+    }
+
+    if (!size)
+        return 0;
+
+    buffer_list = (AudioBufferList *) pa_xmalloc(size);
+    err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, buffer_list);
+
+    if (!err) {
+        pa_log_debug("Sample rate: %f", u->stream_description.mSampleRate);
+        pa_log_debug("%d bytes per packet",   (unsigned int) u->stream_description.mBytesPerPacket);
+        pa_log_debug("%d frames per packet",  (unsigned int) u->stream_description.mFramesPerPacket);
+        pa_log_debug("%d bytes per frame",    (unsigned int) u->stream_description.mBytesPerFrame);
+        pa_log_debug("%d channels per frame", (unsigned int) u->stream_description.mChannelsPerFrame);
+        pa_log_debug("%d bits per channel",   (unsigned int) u->stream_description.mBitsPerChannel);
+
+        for (channel_idx = 0, i = 0; i < buffer_list->mNumberBuffers; i++) {
+            AudioBuffer *buf = buffer_list->mBuffers + i;
+
+            if (direction_in)
+                ca_device_create_source(m, buf, channel_idx);
+            else
+                ca_device_create_sink(m, buf, channel_idx);
+
+            channel_idx += buf->mNumberChannels;
+        }
+    }
+
+    pa_xfree(buffer_list);
+    return 0;
+}
+
+static void thread_func(void *userdata) {
+    struct userdata *u = userdata;
+
+    pa_assert(u);
+    pa_assert(u->module);
+    pa_assert(u->module->core);
+
+    pa_log_debug("Thread starting up");
+
+    if (u->module->core->realtime_scheduling)
+        pa_make_realtime(u->module->core->realtime_priority);
+
+    pa_thread_mq_install(&u->thread_mq);
+
+    for (;;) {
+        coreaudio_sink *ca_sink;
+        int ret;
+
+        PA_LLIST_FOREACH(ca_sink, u->sinks) {
+            if (PA_UNLIKELY(ca_sink->pa_sink->thread_info.rewind_requested))
+                pa_sink_process_rewind(ca_sink->pa_sink, 0);
+        }
+
+        ret = pa_rtpoll_run(u->rtpoll, TRUE);
+
+        if (ret < 0)
+            goto fail;
+
+        if (ret == 0)
+            goto finish;
+    }
+
+fail:
+    /* If this was no regular exit from the loop we have to continue
+     * processing messages until we received PA_MESSAGE_SHUTDOWN */
+    pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->module->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
+    pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
+
+finish:
+    pa_log_debug("Thread shutting down");
+}
+
+int pa__init(pa_module *m) {
+    OSStatus err;
+    UInt32 size, frames;
+    struct userdata *u = NULL;
+    pa_modargs *ma = NULL;
+    char tmp[64];
+    pa_card_new_data card_new_data;
+    pa_card_profile *p;
+    coreaudio_sink *ca_sink;
+    coreaudio_source *ca_source;
+    AudioObjectPropertyAddress property_address;
+
+    pa_assert(m);
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments.");
+        goto fail;
+    }
+
+    u = pa_xnew0(struct userdata, 1);
+    u->module = m;
+    m->userdata = u;
+
+    if (pa_modargs_get_value_u32(ma, "object_id", (unsigned int *) &u->object_id) != 0) {
+        pa_log("Failed to parse object_id argument.");
+        goto fail;
+    }
+
+    property_address.mScope = kAudioObjectPropertyScopeGlobal;
+    property_address.mElement = kAudioObjectPropertyElementMaster;
+
+    /* get device product name */
+    property_address.mSelector = kAudioDevicePropertyDeviceName;
+    size = sizeof(tmp);
+    err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, tmp);
+    if (err) {
+        pa_log("Failed to get kAudioDevicePropertyDeviceName (err = %08x).", (int) err);
+        goto fail;
+    }
+
+    u->device_name = pa_xstrdup(tmp);
+
+    pa_card_new_data_init(&card_new_data);
+    pa_proplist_sets(card_new_data.proplist, PA_PROP_DEVICE_STRING, tmp);
+    card_new_data.driver = __FILE__;
+    pa_card_new_data_set_name(&card_new_data, tmp);
+    pa_log_info("Initializing module for CoreAudio device '%s' (id %d)", tmp, (unsigned int) u->object_id);
+
+    /* get device vendor name (may fail) */
+    property_address.mSelector = kAudioDevicePropertyDeviceManufacturer;
+    size = sizeof(tmp);
+    err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, tmp);
+    if (!err)
+        u->vendor_name = pa_xstrdup(tmp);
+
+    /* add on profile */
+    p = pa_card_profile_new("on", _("On"), 0);
+    pa_hashmap_put(card_new_data.profiles, p->name, p);
+
+    /* create the card object */
+    u->card = pa_card_new(m->core, &card_new_data);
+    if (!u->card) {
+        pa_log("Unable to create card.\n");
+        goto fail;
+    }
+
+    pa_card_new_data_done(&card_new_data);
+    u->card->userdata = u;
+    u->card->set_profile = card_set_profile;
+
+    u->rtpoll = pa_rtpoll_new();
+    pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
+    u->async_msgq = pa_asyncmsgq_new(0);
+    pa_rtpoll_item_new_asyncmsgq_read(u->rtpoll, PA_RTPOLL_EARLY-1, u->async_msgq);
+
+    PA_LLIST_HEAD_INIT(coreaudio_sink, u->sinks);
+
+    /* create sinks */
+    ca_device_create_streams(m, FALSE);
+
+    /* create sources */
+    ca_device_create_streams(m, TRUE);
+
+    /* create the message thread */
+    if (!(u->thread = pa_thread_new(u->device_name, thread_func, u))) {
+        pa_log("Failed to create thread.");
+        goto fail;
+    }
+
+    /* register notification callback for stream format changes */
+    property_address.mSelector = kAudioDevicePropertyStreamFormat;
+    property_address.mScope = kAudioObjectPropertyScopeGlobal;
+    property_address.mElement = kAudioObjectPropertyElementMaster;
+
+    AudioObjectAddPropertyListener(u->object_id, &property_address, ca_stream_format_changed, u);
+
+    /* set number of frames in IOProc */
+    frames = DEFAULT_FRAMES_PER_IOPROC;
+    pa_modargs_get_value_u32(ma, "ioproc_frames", (unsigned int *) &frames);
+
+    property_address.mSelector = kAudioDevicePropertyBufferFrameSize;
+    AudioObjectSetPropertyData(u->object_id, &property_address, 0, NULL, sizeof(frames), &frames);
+    pa_log_debug("%u frames per IOProc\n", (unsigned int) frames);
+
+    /* create one ioproc for both directions */
+    err = AudioDeviceCreateIOProcID(u->object_id, io_render_proc, u, &u->proc_id);
+    if (err) {
+        pa_log("AudioDeviceCreateIOProcID() failed (err = %08x\n).", (int) err);
+        goto fail;
+    }
+
+    for (ca_sink = u->sinks; ca_sink; ca_sink = ca_sink->next)
+        pa_sink_put(ca_sink->pa_sink);
+
+    for (ca_source = u->sources; ca_source; ca_source = ca_source->next)
+        pa_source_put(ca_source->pa_source);
+
+    pa_modargs_free(ma);
+
+    return 0;
+
+fail:
+    if (u)
+        pa__done(m);
+
+    if (ma)
+        pa_modargs_free(ma);
+
+    return -1;
+}
+
+void pa__done(pa_module *m) {
+    struct userdata *u;
+    coreaudio_sink *ca_sink;
+    coreaudio_source *ca_source;
+    AudioObjectPropertyAddress property_address;
+
+    pa_assert(m);
+
+    u = m->userdata;
+    pa_assert(u);
+
+    /* unlink sinks */
+    for (ca_sink = u->sinks; ca_sink; ca_sink = ca_sink->next)
+        if (ca_sink->pa_sink)
+            pa_sink_unlink(ca_sink->pa_sink);
+
+    /* unlink sources */
+    for (ca_source = u->sources; ca_source; ca_source = ca_source->next)
+        if (ca_source->pa_source)
+            pa_source_unlink(ca_source->pa_source);
+
+    if (u->thread) {
+        pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
+        pa_thread_free(u->thread);
+        pa_thread_mq_done(&u->thread_mq);
+        pa_asyncmsgq_unref(u->async_msgq);
+    }
+
+    /* free sinks */
+    for (ca_sink = u->sinks; ca_sink;) {
+        coreaudio_sink *next = ca_sink->next;
+
+        if (ca_sink->pa_sink)
+            pa_sink_unref(ca_sink->pa_sink);
+
+        pa_xfree(ca_sink->name);
+        pa_xfree(ca_sink);
+        ca_sink = next;
+    }
+
+    /* free sources */
+    for (ca_source = u->sources; ca_source;) {
+        coreaudio_source *next = ca_source->next;
+
+        if (ca_source->pa_source)
+            pa_source_unref(ca_source->pa_source);
+
+        pa_xfree(ca_source->name);
+        pa_xfree(ca_source);
+        ca_source = next;
+    }
+
+    if (u->proc_id) {
+        AudioDeviceStop(u->object_id, u->proc_id);
+        AudioDeviceDestroyIOProcID(u->object_id, u->proc_id);
+    }
+
+    property_address.mSelector = kAudioDevicePropertyStreamFormat;
+    property_address.mScope = kAudioObjectPropertyScopeGlobal;
+    property_address.mElement = kAudioObjectPropertyElementMaster;
+
+    AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &property_address, ca_stream_format_changed, u);
+
+    pa_xfree(u->device_name);
+    pa_xfree(u->vendor_name);
+    pa_rtpoll_free(u->rtpoll);
+    pa_card_free(u->card);
+
+    pa_xfree(u);
+}
diff --git a/src/modules/module-always-sink-symdef.h b/src/modules/module-always-sink-symdef.h
deleted file mode 100644 (file)
index 3987aa2..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulealwayssinksymdeffoo
-#define foomodulealwayssinksymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_always_sink_LTX_pa__init
-#define pa__done module_always_sink_LTX_pa__done
-#define pa__get_author module_always_sink_LTX_pa__get_author
-#define pa__get_description module_always_sink_LTX_pa__get_description
-#define pa__get_usage module_always_sink_LTX_pa__get_usage
-#define pa__get_version module_always_sink_LTX_pa__get_version
-#define pa__get_deprecated module_always_sink_LTX_pa__get_deprecated
-#define pa__load_once module_always_sink_LTX_pa__load_once
-#define pa__get_n_used module_always_sink_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 3d7de9c..0df4890 100644 (file)
 #endif
 
 #include <pulse/xmalloc.h>
-#include <pulse/i18n.h>
 
 #include <pulsecore/core.h>
-#include <pulsecore/sink-input.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/i18n.h>
+#include <pulsecore/sink.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/log.h>
-#include <pulsecore/namereg.h>
-#include <pulsecore/core-util.h>
 
 #include "module-always-sink-symdef.h"
 
@@ -68,7 +67,7 @@ static void load_null_sink_if_needed(pa_core *c, pa_sink *sink, struct userdata*
 
     /* Loop through all sinks and check to see if we have *any*
      * sinks. Ignore the sink passed in (if it's not null) */
-    for (target = pa_idxset_first(c->sinks, &idx); target; target = pa_idxset_next(c->sinks, &idx))
+    PA_IDXSET_FOREACH(target, c->sinks, idx)
         if (!sink || target != sink)
             break;
 
diff --git a/src/modules/module-augment-properties-symdef.h b/src/modules/module-augment-properties-symdef.h
deleted file mode 100644 (file)
index c073ffb..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleaugmentpropertiessymdeffoo
-#define foomoduleaugmentpropertiessymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_augment_properties_LTX_pa__init
-#define pa__done module_augment_properties_LTX_pa__done
-#define pa__get_author module_augment_properties_LTX_pa__get_author
-#define pa__get_description module_augment_properties_LTX_pa__get_description
-#define pa__get_usage module_augment_properties_LTX_pa__get_usage
-#define pa__get_version module_augment_properties_LTX_pa__get_version
-#define pa__get_deprecated module_augment_properties_LTX_pa__get_deprecated
-#define pa__load_once module_augment_properties_LTX_pa__load_once
-#define pa__get_n_used module_augment_properties_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 15aa3a1..ee3b54c 100644 (file)
 #endif
 
 #include <sys/stat.h>
+#include <dirent.h>
+#include <time.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/volume.h>
-#include <pulse/channelmap.h>
 
-#include <pulsecore/core-error.h>
 #include <pulsecore/module.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/modargs.h>
@@ -79,19 +78,15 @@ static void rule_free(struct rule *r) {
     pa_xfree(r);
 }
 
-static int parse_properties(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    struct rule *r = userdata;
+static int parse_properties(pa_config_parser_state *state) {
+    struct rule *r;
     pa_proplist *n;
 
-    if (!(n = pa_proplist_from_string(rvalue)))
+    pa_assert(state);
+
+    r = state->userdata;
+
+    if (!(n = pa_proplist_from_string(state->rvalue)))
         return -1;
 
     if (r->proplist) {
@@ -103,20 +98,16 @@ static int parse_properties(
     return 0;
 }
 
-static int parse_categories(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
-    struct rule *r = userdata;
-    const char *state = NULL;
+static int parse_categories(pa_config_parser_state *state) {
+    struct rule *r;
+    const char *split_state = NULL;
     char *c;
 
-    while ((c = pa_split(rvalue, ";", &state))) {
+    pa_assert(state);
+
+    r = state->userdata;
+
+    while ((c = pa_split(state->rvalue, ";", &split_state))) {
 
         if (pa_streq(c, "Game")) {
             pa_xfree(r->role);
@@ -132,27 +123,13 @@ static int parse_categories(
     return 0;
 }
 
-static int check_type(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
+static int check_type(pa_config_parser_state *state) {
+    pa_assert(state);
 
-    return pa_streq(rvalue, "Application") ? 0 : -1;
+    return pa_streq(state->rvalue, "Application") ? 0 : -1;
 }
 
-static int catch_all(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const char *lvalue,
-        const char *rvalue,
-        void *data,
-        void *userdata) {
-
+static int catch_all(pa_config_parser_state *state) {
     return 0;
 }
 
@@ -168,20 +145,54 @@ static void update_rule(struct rule *r) {
         { NULL,  catch_all, NULL, NULL },
         { NULL, NULL, NULL, NULL },
     };
+    pa_bool_t found = FALSE;
 
     pa_assert(r);
     fn = pa_sprintf_malloc(DESKTOPFILEDIR PA_PATH_SEP "%s.desktop", r->process_name);
 
-    if (stat(fn, &st) < 0) {
+    if (stat(fn, &st) == 0)
+        found = TRUE;
+    else {
+#ifdef DT_DIR
+        DIR *desktopfiles_dir;
+        struct dirent *dir;
+
+        /* Let's try a more aggressive search, but only one level */
+        if ((desktopfiles_dir = opendir(DESKTOPFILEDIR))) {
+            while ((dir = readdir(desktopfiles_dir))) {
+                if (dir->d_type != DT_DIR
+                    || pa_streq(dir->d_name, ".")
+                    || pa_streq(dir->d_name, ".."))
+                    continue;
+
+                pa_xfree(fn);
+                fn = pa_sprintf_malloc(DESKTOPFILEDIR PA_PATH_SEP "%s" PA_PATH_SEP "%s.desktop", dir->d_name, r->process_name);
+
+                if (stat(fn, &st) == 0) {
+                    found = TRUE;
+                    break;
+                }
+            }
+            closedir(desktopfiles_dir);
+        }
+#endif
+    }
+    if (!found) {
         r->good = FALSE;
         pa_xfree(fn);
         return;
     }
 
-    if (r->good && st.st_mtime == r->mtime) {
-        pa_xfree(fn);
-        return;
-    }
+    if (r->good) {
+        if (st.st_mtime == r->mtime) {
+            /* Theoretically the filename could have changed, but if so
+               having the same mtime is very unlikely so not worth tracking it in r */
+            pa_xfree(fn);
+            return;
+        }
+        pa_log_debug("Found %s (which has been updated since we last checked).", fn);
+    } else
+        pa_log_debug("Found %s.", fn);
 
     r->good = TRUE;
     r->mtime = st.st_mtime;
@@ -195,7 +206,7 @@ static void update_rule(struct rule *r) {
     table[0].data = &r->application_name;
     table[1].data = &r->icon_name;
 
-    if (pa_config_parse(fn, NULL, table, r) < 0)
+    if (pa_config_parse(fn, NULL, table, NULL, r) < 0)
         pa_log_warn("Failed to parse .desktop file %s.", fn);
 
     pa_xfree(fn);
@@ -320,7 +331,7 @@ fail:
     if (ma)
         pa_modargs_free(ma);
 
-    return  -1;
+    return -1;
 }
 
 void pa__done(pa_module *m) {
@@ -336,14 +347,8 @@ void pa__done(pa_module *m) {
     if (u->client_proplist_changed_slot)
         pa_hook_slot_free(u->client_proplist_changed_slot);
 
-    if (u->cache) {
-        struct rule *r;
-
-        while ((r = pa_hashmap_steal_first(u->cache)))
-            rule_free(r);
-
-        pa_hashmap_free(u->cache, NULL, NULL);
-    }
+    if (u->cache)
+        pa_hashmap_free(u->cache, (pa_free_cb_t) rule_free);
 
     pa_xfree(u);
 }
diff --git a/src/modules/module-card-restore-symdef.h b/src/modules/module-card-restore-symdef.h
deleted file mode 100644 (file)
index fcb0680..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulecardrestoresymdeffoo
-#define foomodulecardrestoresymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_card_restore_LTX_pa__init
-#define pa__done module_card_restore_LTX_pa__done
-#define pa__get_author module_card_restore_LTX_pa__get_author
-#define pa__get_description module_card_restore_LTX_pa__get_description
-#define pa__get_usage module_card_restore_LTX_pa__get_usage
-#define pa__get_version module_card_restore_LTX_pa__get_version
-#define pa__get_deprecated module_card_restore_LTX_pa__get_deprecated
-#define pa__load_once module_card_restore_LTX_pa__load_once
-#define pa__get_n_used module_card_restore_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 7dea94f..2b3235c 100644 (file)
 #include <sys/types.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <ctype.h>
 
+#include <pulse/gccmacro.h>
 #include <pulse/xmalloc.h>
-#include <pulse/volume.h>
 #include <pulse/timeval.h>
-#include <pulse/util.h>
 #include <pulse/rtclock.h>
 
 #include <pulsecore/core-error.h>
@@ -46,6 +44,7 @@
 #include <pulsecore/card.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/database.h>
+#include <pulsecore/tagstruct.h>
 
 #include "module-card-restore-symdef.h"
 
@@ -63,18 +62,27 @@ static const char* const valid_modargs[] = {
 struct userdata {
     pa_core *core;
     pa_module *module;
-    pa_subscription *subscription;
     pa_hook_slot *card_new_hook_slot;
+    pa_hook_slot *card_put_hook_slot;
+    pa_hook_slot *card_profile_hook_slot;
+    pa_hook_slot *port_offset_hook_slot;
     pa_time_event *save_time_event;
     pa_database *database;
+    bool hooks_connected;
 };
 
-#define ENTRY_VERSION 1
+#define ENTRY_VERSION 2
+
+struct port_info {
+    char *name;
+    int64_t offset;
+};
 
 struct entry {
     uint8_t version;
-    char profile[PA_NAME_MAX];
-} PA_GCC_PACKED ;
+    char *profile;
+    pa_hashmap *ports; /* Port name -> struct port_info */
+};
 
 static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
     struct userdata *u = userdata;
@@ -91,11 +99,168 @@ static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct
     pa_log_info("Synced.");
 }
 
-static struct entry* read_entry(struct userdata *u, const char *name) {
+static void trigger_save(struct userdata *u) {
+    if (u->save_time_event)
+        return;
+
+    u->save_time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + SAVE_INTERVAL, save_time_callback, u);
+}
+
+static struct entry* entry_new(void) {
+    struct entry *r = pa_xnew0(struct entry, 1);
+    r->version = ENTRY_VERSION;
+    r->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    return r;
+}
+
+static struct port_info *port_info_new(pa_device_port *port) {
+    struct port_info *p_info;
+
+    if (port) {
+        p_info = pa_xnew(struct port_info, 1);
+        p_info->name = pa_xstrdup(port->name);
+        p_info->offset = port->latency_offset;
+    } else
+        p_info = pa_xnew0(struct port_info, 1);
+
+    return p_info;
+}
+
+static void port_info_free(struct port_info *p_info) {
+    pa_assert(p_info);
+
+    pa_xfree(p_info->name);
+    pa_xfree(p_info);
+}
+
+static void entry_free(struct entry* e) {
+    pa_assert(e);
+
+    pa_xfree(e->profile);
+    pa_hashmap_free(e->ports, (pa_free_cb_t) port_info_free);
+
+    pa_xfree(e);
+}
+
+static struct entry *entry_from_card(pa_card *card) {
+    struct port_info *p_info;
+    struct entry *entry;
+    pa_device_port *port;
+    void *state;
+
+    pa_assert(card);
+
+    entry = entry_new();
+    if (card->save_profile)
+        entry->profile = pa_xstrdup(card->active_profile->name);
+
+    PA_HASHMAP_FOREACH(port, card->ports, state) {
+        p_info = port_info_new(port);
+        pa_assert_se(pa_hashmap_put(entry->ports, p_info->name, p_info) >= 0);
+    }
+
+    return entry;
+}
+
+static bool entrys_equal(struct entry *a, struct entry *b) {
+    struct port_info *Ap_info, *Bp_info;
+    void *state;
+
+    pa_assert(a);
+    pa_assert(b);
+
+    if (!pa_streq(a->profile, b->profile) ||
+            pa_hashmap_size(a->ports) != pa_hashmap_size(b->ports))
+        return false;
+
+    PA_HASHMAP_FOREACH(Ap_info, a->ports, state) {
+        if ((Bp_info = pa_hashmap_get(b->ports, Ap_info->name))) {
+            if (Ap_info->offset != Bp_info->offset)
+                return false;
+        } else
+            return false;
+    }
+
+    return true;
+}
+
+static pa_bool_t entry_write(struct userdata *u, const char *name, const struct entry *e) {
+    pa_tagstruct *t;
     pa_datum key, data;
+    pa_bool_t r;
+    void *state;
+    struct port_info *p_info;
+
+    pa_assert(u);
+    pa_assert(name);
+    pa_assert(e);
+
+    t = pa_tagstruct_new(NULL, 0);
+    pa_tagstruct_putu8(t, e->version);
+    pa_tagstruct_puts(t, e->profile);
+    pa_tagstruct_putu32(t, pa_hashmap_size(e->ports));
+
+    PA_HASHMAP_FOREACH(p_info, e->ports, state) {
+        pa_tagstruct_puts(t, p_info->name);
+        pa_tagstruct_puts64(t, p_info->offset);
+    }
+
+    key.data = (char *) name;
+    key.size = strlen(name);
+
+    data.data = (void*)pa_tagstruct_data(t, &data.size);
+
+    r = (pa_database_set(u->database, &key, &data, TRUE) == 0);
+
+    pa_tagstruct_free(t);
+
+    return r;
+}
+
+#ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
+
+#define LEGACY_ENTRY_VERSION 1
+static struct entry* legacy_entry_read(struct userdata *u, pa_datum *data) {
+    struct legacy_entry {
+        uint8_t version;
+        char profile[PA_NAME_MAX];
+    } PA_GCC_PACKED ;
+    struct legacy_entry *le;
     struct entry *e;
 
     pa_assert(u);
+    pa_assert(data);
+
+    if (data->size != sizeof(struct legacy_entry)) {
+        pa_log_debug("Size does not match.");
+        return NULL;
+    }
+
+    le = (struct legacy_entry*)data->data;
+
+    if (le->version != LEGACY_ENTRY_VERSION) {
+        pa_log_debug("Version mismatch.");
+        return NULL;
+    }
+
+    if (!memchr(le->profile, 0, sizeof(le->profile))) {
+        pa_log_warn("Profile has missing NUL byte.");
+        return NULL;
+    }
+
+    e = entry_new();
+    e->profile = pa_xstrdup(le->profile);
+    return e;
+}
+#endif
+
+static struct entry* entry_read(struct userdata *u, const char *name) {
+    pa_datum key, data;
+    struct entry *e = NULL;
+    pa_tagstruct *t = NULL;
+    const char* profile;
+
+    pa_assert(u);
     pa_assert(name);
 
     key.data = (char*) name;
@@ -106,102 +271,201 @@ static struct entry* read_entry(struct userdata *u, const char *name) {
     if (!pa_database_get(u->database, &key, &data))
         goto fail;
 
-    if (data.size != sizeof(struct entry)) {
-        pa_log_debug("Database contains entry for card %s of wrong size %lu != %lu. Probably due to upgrade, ignoring.", name, (unsigned long) data.size, (unsigned long) sizeof(struct entry));
+    t = pa_tagstruct_new(data.data, data.size);
+    e = entry_new();
+
+    if (pa_tagstruct_getu8(t, &e->version) < 0 ||
+        e->version > ENTRY_VERSION ||
+        pa_tagstruct_gets(t, &profile) < 0) {
+
         goto fail;
     }
 
-    e = (struct entry*) data.data;
+    if (!profile)
+        profile = "";
 
-    if (e->version != ENTRY_VERSION) {
-        pa_log_debug("Version of database entry for card %s doesn't match our version. Probably due to upgrade, ignoring.", name);
-        goto fail;
+    e->profile = pa_xstrdup(profile);
+
+    if (e->version >= 2) {
+        uint32_t port_count = 0;
+        const char *port_name = NULL;
+        int64_t port_offset = 0;
+        struct port_info *p_info;
+        unsigned i;
+
+        if (pa_tagstruct_getu32(t, &port_count) < 0)
+            goto fail;
+
+        for (i = 0; i < port_count; i++) {
+            if (pa_tagstruct_gets(t, &port_name) < 0 ||
+                !port_name ||
+                pa_hashmap_get(e->ports, port_name) ||
+                pa_tagstruct_gets64(t, &port_offset) < 0)
+                goto fail;
+
+            p_info = port_info_new(NULL);
+            p_info->name = pa_xstrdup(port_name);
+            p_info->offset = port_offset;
+
+            pa_assert_se(pa_hashmap_put(e->ports, p_info->name, p_info) >= 0);
+        }
     }
 
-    if (!memchr(e->profile, 0, sizeof(e->profile))) {
-        pa_log_warn("Database contains entry for card %s with missing NUL byte in profile name", name);
+    if (!pa_tagstruct_eof(t))
         goto fail;
-    }
+
+    pa_tagstruct_free(t);
+    pa_datum_free(&data);
 
     return e;
 
 fail:
 
+    pa_log_debug("Database contains invalid data for key: %s (probably pre-v1.0 data)", name);
+
+    if (e)
+        entry_free(e);
+    if (t)
+        pa_tagstruct_free(t);
+
+#ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
+    pa_log_debug("Attempting to load legacy (pre-v1.0) data for key: %s", name);
+    if ((e = legacy_entry_read(u, &data))) {
+        pa_log_debug("Success. Saving new format for key: %s", name);
+        if (entry_write(u, name, e))
+            trigger_save(u);
+        pa_datum_free(&data);
+        return e;
+    } else
+        pa_log_debug("Unable to load legacy (pre-v1.0) data for key: %s. Ignoring.", name);
+#endif
+
     pa_datum_free(&data);
     return NULL;
 }
 
-static void trigger_save(struct userdata *u) {
-    if (u->save_time_event)
-        return;
+static void show_full_info(pa_card *card) {
+    pa_assert(card);
 
-    u->save_time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + SAVE_INTERVAL, save_time_callback, u);
+    if (card->save_profile)
+        pa_log_info("Storing profile and port latency offsets for card %s.", card->name);
+    else
+        pa_log_info("Storing port latency offsets for card %s.", card->name);
 }
 
-static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
-    struct userdata *u = userdata;
-    struct entry entry, *old;
-    pa_datum key, data;
-    pa_card *card;
+static pa_hook_result_t card_put_hook_callback(pa_core *c, pa_card *card, struct userdata *u) {
+    struct entry *entry, *old;
 
-    pa_assert(c);
-    pa_assert(u);
+    pa_assert(card);
 
-    if (t != (PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_NEW) &&
-        t != (PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE))
-        return;
+    entry = entry_from_card(card);
 
-    pa_zero(entry);
-    entry.version = ENTRY_VERSION;
+    if ((old = entry_read(u, card->name))) {
+        if (!card->save_profile)
+            entry->profile = pa_xstrdup(old->profile);
+        if (entrys_equal(entry, old))
+            goto finish;
+    }
 
-    if (!(card = pa_idxset_get_by_index(c->cards, idx)))
-        return;
+    show_full_info(card);
 
-    if (!card->save_profile)
-        return;
+    if (entry_write(u, card->name, entry))
+        trigger_save(u);
 
-    pa_strlcpy(entry.profile, card->active_profile ? card->active_profile->name : "", sizeof(entry.profile));
+finish:
+    entry_free(entry);
+    if (old)
+        entry_free(old);
 
-    if ((old = read_entry(u, card->name))) {
+    return PA_HOOK_OK;
+}
 
-        if (strncmp(old->profile, entry.profile, sizeof(entry.profile)) == 0) {
-            pa_xfree(old);
-            return;
-        }
+static pa_hook_result_t card_profile_change_callback(pa_core *c, pa_card *card, struct userdata *u) {
+    struct entry *entry;
+
+    pa_assert(card);
 
-        pa_xfree(old);
+    if (!card->save_profile)
+        return PA_HOOK_OK;
+
+    if ((entry = entry_read(u, card->name))) {
+        entry->profile = pa_xstrdup(card->active_profile->name);
+        pa_log_info("Storing card profile for card %s.", card->name);
+    } else {
+        entry = entry_from_card(card);
+        show_full_info(card);
     }
 
-    key.data = card->name;
-    key.size = strlen(card->name);
+    if (entry_write(u, card->name, entry))
+        trigger_save(u);
+
+    entry_free(entry);
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t port_offset_change_callback(pa_core *c, pa_device_port *port, struct userdata *u) {
+    struct entry *entry;
+    pa_card *card;
+
+    pa_assert(port);
+    card = port->card;
 
-    data.data = &entry;
-    data.size = sizeof(entry);
+    if ((entry = entry_read(u, card->name))) {
+        struct port_info *p_info;
 
-    pa_log_info("Storing profile for card %s.", card->name);
+        if ((p_info = pa_hashmap_get(entry->ports, port->name)))
+            p_info->offset = port->latency_offset;
+        else {
+            p_info = port_info_new(port);
+            pa_assert_se(pa_hashmap_put(entry->ports, p_info->name, p_info) >= 0);
+        }
 
-    pa_database_set(u->database, &key, &data, TRUE);
+        pa_log_info("Storing latency offset for port %s on card %s.", port->name, card->name);
 
-    trigger_save(u);
+    } else {
+        entry_from_card(card);
+        show_full_info(card);
+    }
+
+    if (entry_write(u, card->name, entry))
+        trigger_save(u);
+
+    entry_free(entry);
+    return PA_HOOK_OK;
 }
 
 static pa_hook_result_t card_new_hook_callback(pa_core *c, pa_card_new_data *new_data, struct userdata *u) {
     struct entry *e;
+    void *state;
+    pa_device_port *p;
+    struct port_info *p_info;
 
     pa_assert(new_data);
 
-    if ((e = read_entry(u, new_data->name)) && e->profile[0]) {
+    if (!(e = entry_read(u, new_data->name)))
+        return PA_HOOK_OK;
 
+    if (e->profile[0]) {
         if (!new_data->active_profile) {
-            pa_log_info("Restoring profile for card %s.", new_data->name);
             pa_card_new_data_set_profile(new_data, e->profile);
+            pa_log_info("Restored profile '%s' for card %s.", new_data->active_profile, new_data->name);
             new_data->save_profile = TRUE;
+
         } else
             pa_log_debug("Not restoring profile for card %s, because already set.", new_data->name);
-
-        pa_xfree(e);
     }
 
+    /* Always restore the latency offsets because their
+     * initial value is always 0 */
+
+    pa_log_info("Restoring port latency offsets for card %s.", new_data->name);
+
+    PA_HASHMAP_FOREACH(p_info, e->ports, state)
+        if ((p = pa_hashmap_get(new_data->ports, p_info->name)))
+            p->latency_offset = p_info->offset;
+
+    entry_free(e);
+
     return PA_HOOK_OK;
 }
 
@@ -209,8 +473,6 @@ int pa__init(pa_module*m) {
     pa_modargs *ma = NULL;
     struct userdata *u;
     char *fname;
-    pa_card *card;
-    uint32_t idx;
 
     pa_assert(m);
 
@@ -223,9 +485,11 @@ int pa__init(pa_module*m) {
     u->core = m->core;
     u->module = m;
 
-    u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_CARD, subscribe_callback, u);
-
     u->card_new_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_CARD_NEW], PA_HOOK_EARLY, (pa_hook_cb_t) card_new_hook_callback, u);
+    u->card_put_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_CARD_PUT], PA_HOOK_NORMAL, (pa_hook_cb_t) card_put_hook_callback, u);
+    u->card_profile_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_CARD_PROFILE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) card_profile_change_callback, u);
+    u->port_offset_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_PORT_LATENCY_OFFSET_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) port_offset_change_callback, u);
+    u->hooks_connected = true;
 
     if (!(fname = pa_state_path("card-database", TRUE)))
         goto fail;
@@ -236,12 +500,9 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
-    pa_log_info("Sucessfully opened database file '%s'.", fname);
+    pa_log_info("Successfully opened database file '%s'.", fname);
     pa_xfree(fname);
 
-    for (card = pa_idxset_first(m->core->cards, &idx); card; card = pa_idxset_next(m->core->cards, &idx))
-        subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_NEW, card->index, u);
-
     pa_modargs_free(ma);
     return 0;
 
@@ -251,7 +512,7 @@ fail:
     if (ma)
         pa_modargs_free(ma);
 
-    return  -1;
+    return -1;
 }
 
 void pa__done(pa_module*m) {
@@ -262,11 +523,12 @@ void pa__done(pa_module*m) {
     if (!(u = m->userdata))
         return;
 
-    if (u->subscription)
-        pa_subscription_free(u->subscription);
-
-    if (u->card_new_hook_slot)
+    if (u->hooks_connected) {
         pa_hook_slot_free(u->card_new_hook_slot);
+        pa_hook_slot_free(u->card_put_hook_slot);
+        pa_hook_slot_free(u->card_profile_hook_slot);
+        pa_hook_slot_free(u->port_offset_hook_slot);
+    }
 
     if (u->save_time_event)
         u->core->mainloop->time_free(u->save_time_event);
diff --git a/src/modules/module-cli-protocol-tcp-symdef.h b/src/modules/module-cli-protocol-tcp-symdef.h
deleted file mode 100644 (file)
index a839177..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulecliprotocoltcpsymdeffoo
-#define foomodulecliprotocoltcpsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_cli_protocol_tcp_LTX_pa__init
-#define pa__done module_cli_protocol_tcp_LTX_pa__done
-#define pa__get_author module_cli_protocol_tcp_LTX_pa__get_author
-#define pa__get_description module_cli_protocol_tcp_LTX_pa__get_description
-#define pa__get_usage module_cli_protocol_tcp_LTX_pa__get_usage
-#define pa__get_version module_cli_protocol_tcp_LTX_pa__get_version
-#define pa__get_deprecated module_cli_protocol_tcp_LTX_pa__get_deprecated
-#define pa__load_once module_cli_protocol_tcp_LTX_pa__load_once
-#define pa__get_n_used module_cli_protocol_tcp_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
diff --git a/src/modules/module-cli-protocol-unix-symdef.h b/src/modules/module-cli-protocol-unix-symdef.h
deleted file mode 100644 (file)
index add1e60..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulecliprotocolunixsymdeffoo
-#define foomodulecliprotocolunixsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_cli_protocol_unix_LTX_pa__init
-#define pa__done module_cli_protocol_unix_LTX_pa__done
-#define pa__get_author module_cli_protocol_unix_LTX_pa__get_author
-#define pa__get_description module_cli_protocol_unix_LTX_pa__get_description
-#define pa__get_usage module_cli_protocol_unix_LTX_pa__get_usage
-#define pa__get_version module_cli_protocol_unix_LTX_pa__get_version
-#define pa__get_deprecated module_cli_protocol_unix_LTX_pa__get_deprecated
-#define pa__load_once module_cli_protocol_unix_LTX_pa__load_once
-#define pa__get_n_used module_cli_protocol_unix_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
diff --git a/src/modules/module-cli-symdef.h b/src/modules/module-cli-symdef.h
deleted file mode 100644 (file)
index a7d7e3d..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleclisymdeffoo
-#define foomoduleclisymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_cli_LTX_pa__init
-#define pa__done module_cli_LTX_pa__done
-#define pa__get_author module_cli_LTX_pa__get_author
-#define pa__get_description module_cli_LTX_pa__get_description
-#define pa__get_usage module_cli_LTX_pa__get_usage
-#define pa__get_version module_cli_LTX_pa__get_version
-#define pa__get_deprecated module_cli_LTX_pa__get_deprecated
-#define pa__load_once module_cli_LTX_pa__load_once
-#define pa__get_n_used module_cli_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 421cb21..2a1d175 100644 (file)
@@ -36,7 +36,6 @@
 #include <pulsecore/modargs.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
-#include <pulsecore/core-error.h>
 
 #include "module-cli-symdef.h"
 
@@ -73,7 +72,9 @@ int pa__init(pa_module*m) {
     pa_iochannel *io;
     pa_modargs *ma;
     pa_bool_t exit_on_eof = FALSE;
+#ifndef OS_IS_WIN32
     int fd;
+#endif
 
     pa_assert(m);
 
@@ -105,11 +106,14 @@ int pa__init(pa_module*m) {
      * of log messages, particularly because if stdout and stderr are
      * dup'ed they share the same O_NDELAY, too. */
 
-    if ((fd = open("/dev/tty", O_RDWR|O_NONBLOCK)) >= 0) {
-        pa_make_fd_cloexec(fd);
+#ifndef OS_IS_WIN32
+    if ((fd = pa_open_cloexec("/dev/tty", O_RDWR|O_NONBLOCK, 0)) >= 0) {
         io = pa_iochannel_new(m->core->mainloop, fd, fd);
         pa_log_debug("Managed to open /dev/tty.");
-    } else {
+    }
+    else
+#endif
+    {
         io = pa_iochannel_new(m->core->mainloop, STDIN_FILENO, STDOUT_FILENO);
         pa_iochannel_set_noclose(io, TRUE);
         pa_log_debug("Failed to open /dev/tty, using stdin/stdout fds instead.");
diff --git a/src/modules/module-combine-sink.c b/src/modules/module-combine-sink.c
new file mode 100644 (file)
index 0000000..41272e4
--- /dev/null
@@ -0,0 +1,1431 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2008 Lennart Poettering
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+
+#include <pulse/rtclock.h>
+#include <pulse/timeval.h>
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/macro.h>
+#include <pulsecore/module.h>
+#include <pulsecore/llist.h>
+#include <pulsecore/sink.h>
+#include <pulsecore/sink-input.h>
+#include <pulsecore/memblockq.h>
+#include <pulsecore/log.h>
+#include <pulsecore/core-rtclock.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/namereg.h>
+#include <pulsecore/thread.h>
+#include <pulsecore/thread-mq.h>
+#include <pulsecore/rtpoll.h>
+#include <pulsecore/time-smoother.h>
+#include <pulsecore/strlist.h>
+
+#include "module-combine-sink-symdef.h"
+
+PA_MODULE_AUTHOR("Lennart Poettering");
+PA_MODULE_DESCRIPTION("Combine multiple sinks to one");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(FALSE);
+PA_MODULE_USAGE(
+        "sink_name=<name for the sink> "
+        "sink_properties=<properties for the sink> "
+        "slaves=<slave sinks> "
+        "adjust_time=<how often to readjust rates in s> "
+        "resample_method=<method> "
+        "format=<sample format> "
+        "rate=<sample rate> "
+        "channels=<number of channels> "
+        "channel_map=<channel map>");
+
+#define DEFAULT_SINK_NAME "combined"
+
+#define MEMBLOCKQ_MAXLENGTH (1024*1024*16)
+
+#define DEFAULT_ADJUST_TIME_USEC (10*PA_USEC_PER_SEC)
+
+#define BLOCK_USEC (PA_USEC_PER_MSEC * 200)
+
+static const char* const valid_modargs[] = {
+    "sink_name",
+    "sink_properties",
+    "slaves",
+    "adjust_time",
+    "resample_method",
+    "format",
+    "rate",
+    "channels",
+    "channel_map",
+    NULL
+};
+
+struct output {
+    struct userdata *userdata;
+
+    pa_sink *sink;
+    pa_sink_input *sink_input;
+    pa_bool_t ignore_state_change;
+
+    pa_asyncmsgq *inq,    /* Message queue from the sink thread to this sink input */
+                 *outq;   /* Message queue from this sink input to the sink thread */
+    pa_rtpoll_item *inq_rtpoll_item_read, *inq_rtpoll_item_write;
+    pa_rtpoll_item *outq_rtpoll_item_read, *outq_rtpoll_item_write;
+
+    pa_memblockq *memblockq;
+
+    /* For communication of the stream latencies to the main thread */
+    pa_usec_t total_latency;
+
+    /* For communication of the stream parameters to the sink thread */
+    pa_atomic_t max_request;
+    pa_atomic_t requested_latency;
+
+    PA_LLIST_FIELDS(struct output);
+};
+
+struct userdata {
+    pa_core *core;
+    pa_module *module;
+    pa_sink *sink;
+
+    pa_thread *thread;
+    pa_thread_mq thread_mq;
+    pa_rtpoll *rtpoll;
+
+    pa_time_event *time_event;
+    pa_usec_t adjust_time;
+
+    pa_bool_t automatic;
+    pa_bool_t auto_desc;
+
+    pa_strlist *unlinked_slaves;
+
+    pa_hook_slot *sink_put_slot, *sink_unlink_slot, *sink_state_changed_slot;
+
+    pa_resample_method_t resample_method;
+
+    pa_usec_t block_usec;
+
+    pa_idxset* outputs; /* managed in main context */
+
+    struct {
+        PA_LLIST_HEAD(struct output, active_outputs); /* managed in IO thread context */
+        pa_atomic_t running;  /* we cache that value here, so that every thread can query it cheaply */
+        pa_usec_t timestamp;
+        pa_bool_t in_null_mode;
+        pa_smoother *smoother;
+        uint64_t counter;
+    } thread_info;
+};
+
+enum {
+    SINK_MESSAGE_ADD_OUTPUT = PA_SINK_MESSAGE_MAX,
+    SINK_MESSAGE_REMOVE_OUTPUT,
+    SINK_MESSAGE_NEED,
+    SINK_MESSAGE_UPDATE_LATENCY,
+    SINK_MESSAGE_UPDATE_MAX_REQUEST,
+    SINK_MESSAGE_UPDATE_REQUESTED_LATENCY
+};
+
+enum {
+    SINK_INPUT_MESSAGE_POST = PA_SINK_INPUT_MESSAGE_MAX,
+};
+
+static void output_disable(struct output *o);
+static void output_enable(struct output *o);
+static void output_free(struct output *o);
+static int output_create_sink_input(struct output *o);
+
+static void adjust_rates(struct userdata *u) {
+    struct output *o;
+    pa_usec_t max_sink_latency = 0, min_total_latency = (pa_usec_t) -1, target_latency, avg_total_latency = 0;
+    uint32_t base_rate;
+    uint32_t idx;
+    unsigned n = 0;
+
+    pa_assert(u);
+    pa_sink_assert_ref(u->sink);
+
+    if (pa_idxset_size(u->outputs) <= 0)
+        return;
+
+    if (!PA_SINK_IS_OPENED(pa_sink_get_state(u->sink)))
+        return;
+
+    PA_IDXSET_FOREACH(o, u->outputs, idx) {
+        pa_usec_t sink_latency;
+
+        if (!o->sink_input || !PA_SINK_IS_OPENED(pa_sink_get_state(o->sink)))
+            continue;
+
+        o->total_latency = pa_sink_input_get_latency(o->sink_input, &sink_latency);
+        o->total_latency += sink_latency;
+
+        if (sink_latency > max_sink_latency)
+            max_sink_latency = sink_latency;
+
+        if (min_total_latency == (pa_usec_t) -1 || o->total_latency < min_total_latency)
+            min_total_latency = o->total_latency;
+
+        avg_total_latency += o->total_latency;
+        n++;
+
+        pa_log_debug("[%s] total=%0.2fms sink=%0.2fms ", o->sink->name, (double) o->total_latency / PA_USEC_PER_MSEC, (double) sink_latency / PA_USEC_PER_MSEC);
+
+        if (o->total_latency > 10*PA_USEC_PER_SEC)
+            pa_log_warn("[%s] Total latency of output is very high (%0.2fms), most likely the audio timing in one of your drivers is broken.", o->sink->name, (double) o->total_latency / PA_USEC_PER_MSEC);
+    }
+
+    if (min_total_latency == (pa_usec_t) -1)
+        return;
+
+    avg_total_latency /= n;
+
+    target_latency = max_sink_latency > min_total_latency ? max_sink_latency : min_total_latency;
+
+    pa_log_info("[%s] avg total latency is %0.2f msec.", u->sink->name, (double) avg_total_latency / PA_USEC_PER_MSEC);
+    pa_log_info("[%s] target latency is %0.2f msec.", u->sink->name, (double) target_latency / PA_USEC_PER_MSEC);
+
+    base_rate = u->sink->sample_spec.rate;
+
+    PA_IDXSET_FOREACH(o, u->outputs, idx) {
+        uint32_t new_rate = base_rate;
+        uint32_t current_rate;
+
+        if (!o->sink_input || !PA_SINK_IS_OPENED(pa_sink_get_state(o->sink)))
+            continue;
+
+        current_rate = o->sink_input->sample_spec.rate;
+
+        if (o->total_latency != target_latency)
+            new_rate += (uint32_t) (((double) o->total_latency - (double) target_latency) / (double) u->adjust_time * (double) new_rate);
+
+        if (new_rate < (uint32_t) (base_rate*0.8) || new_rate > (uint32_t) (base_rate*1.25)) {
+            pa_log_warn("[%s] sample rates too different, not adjusting (%u vs. %u).", o->sink_input->sink->name, base_rate, new_rate);
+            new_rate = base_rate;
+        } else {
+            if (base_rate < new_rate + 20 && new_rate < base_rate + 20)
+              new_rate = base_rate;
+            /* Do the adjustment in small steps; 2‰ can be considered inaudible */
+            if (new_rate < (uint32_t) (current_rate*0.998) || new_rate > (uint32_t) (current_rate*1.002)) {
+                pa_log_info("[%s] new rate of %u Hz not within 2‰ of %u Hz, forcing smaller adjustment", o->sink_input->sink->name, new_rate, current_rate);
+                new_rate = PA_CLAMP(new_rate, (uint32_t) (current_rate*0.998), (uint32_t) (current_rate*1.002));
+            }
+            pa_log_info("[%s] new rate is %u Hz; ratio is %0.3f; latency is %0.2f msec.", o->sink_input->sink->name, new_rate, (double) new_rate / base_rate, (double) o->total_latency / PA_USEC_PER_MSEC);
+        }
+        pa_sink_input_set_rate(o->sink_input, new_rate);
+    }
+
+    pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_UPDATE_LATENCY, NULL, (int64_t) avg_total_latency, NULL);
+}
+
+static void time_callback(pa_mainloop_api *a, pa_time_event *e, const struct timeval *t, void *userdata) {
+    struct userdata *u = userdata;
+
+    pa_assert(u);
+    pa_assert(a);
+    pa_assert(u->time_event == e);
+
+    adjust_rates(u);
+
+    if (pa_sink_get_state(u->sink) == PA_SINK_SUSPENDED) {
+        u->core->mainloop->time_free(e);
+        u->time_event = NULL;
+    } else
+        pa_core_rttime_restart(u->core, e, pa_rtclock_now() + u->adjust_time);
+}
+
+static void process_render_null(struct userdata *u, pa_usec_t now) {
+    size_t ate = 0;
+
+    pa_assert(u);
+    pa_assert(u->sink->thread_info.state == PA_SINK_RUNNING);
+
+    if (u->thread_info.in_null_mode)
+        u->thread_info.timestamp = now;
+
+    while (u->thread_info.timestamp < now + u->block_usec) {
+        pa_memchunk chunk;
+
+        pa_sink_render(u->sink, u->sink->thread_info.max_request, &chunk);
+        pa_memblock_unref(chunk.memblock);
+
+        u->thread_info.counter += chunk.length;
+
+/*         pa_log_debug("Ate %lu bytes.", (unsigned long) chunk.length); */
+        u->thread_info.timestamp += pa_bytes_to_usec(chunk.length, &u->sink->sample_spec);
+
+        ate += chunk.length;
+
+        if (ate >= u->sink->thread_info.max_request)
+            break;
+    }
+
+/*     pa_log_debug("Ate in sum %lu bytes (of %lu)", (unsigned long) ate, (unsigned long) nbytes); */
+
+    pa_smoother_put(u->thread_info.smoother, now,
+                    pa_bytes_to_usec(u->thread_info.counter, &u->sink->sample_spec) - (u->thread_info.timestamp - now));
+}
+
+static void thread_func(void *userdata) {
+    struct userdata *u = userdata;
+
+    pa_assert(u);
+
+    pa_log_debug("Thread starting up");
+
+    if (u->core->realtime_scheduling)
+        pa_make_realtime(u->core->realtime_priority+1);
+
+    pa_thread_mq_install(&u->thread_mq);
+
+    u->thread_info.timestamp = pa_rtclock_now();
+    u->thread_info.in_null_mode = FALSE;
+
+    for (;;) {
+        int ret;
+
+        if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
+            pa_sink_process_rewind(u->sink, 0);
+
+        /* If no outputs are connected, render some data and drop it immediately. */
+        if (u->sink->thread_info.state == PA_SINK_RUNNING && !u->thread_info.active_outputs) {
+            pa_usec_t now;
+
+            now = pa_rtclock_now();
+
+            if (!u->thread_info.in_null_mode || u->thread_info.timestamp <= now)
+                process_render_null(u, now);
+
+            pa_rtpoll_set_timer_absolute(u->rtpoll, u->thread_info.timestamp);
+            u->thread_info.in_null_mode = TRUE;
+        } else {
+            pa_rtpoll_set_timer_disabled(u->rtpoll);
+            u->thread_info.in_null_mode = FALSE;
+        }
+
+        /* Hmm, nothing to do. Let's sleep */
+        if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0) {
+            pa_log_info("pa_rtpoll_run() = %i", ret);
+            goto fail;
+        }
+
+        if (ret == 0)
+            goto finish;
+    }
+
+fail:
+    /* If this was no regular exit from the loop we have to continue
+     * processing messages until we received PA_MESSAGE_SHUTDOWN */
+    pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
+    pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
+
+finish:
+    pa_log_debug("Thread shutting down");
+}
+
+/* Called from I/O thread context */
+static void render_memblock(struct userdata *u, struct output *o, size_t length) {
+    pa_assert(u);
+    pa_assert(o);
+
+    /* We are run by the sink thread, on behalf of an output (o). The
+     * output is waiting for us, hence it is safe to access its
+     * mainblockq and asyncmsgq directly. */
+
+    /* If we are not running, we cannot produce any data */
+    if (!pa_atomic_load(&u->thread_info.running))
+        return;
+
+    /* Maybe there's some data in the requesting output's queue
+     * now? */
+    while (pa_asyncmsgq_process_one(o->inq) > 0)
+        ;
+
+    /* Ok, now let's prepare some data if we really have to */
+    while (!pa_memblockq_is_readable(o->memblockq)) {
+        struct output *j;
+        pa_memchunk chunk;
+
+        /* Render data! */
+        pa_sink_render(u->sink, length, &chunk);
+
+        u->thread_info.counter += chunk.length;
+
+        /* OK, let's send this data to the other threads */
+        PA_LLIST_FOREACH(j, u->thread_info.active_outputs) {
+            if (j == o)
+                continue;
+
+            pa_asyncmsgq_post(j->inq, PA_MSGOBJECT(j->sink_input), SINK_INPUT_MESSAGE_POST, NULL, 0, &chunk, NULL);
+        }
+
+        /* And place it directly into the requesting output's queue */
+        pa_memblockq_push_align(o->memblockq, &chunk);
+        pa_memblock_unref(chunk.memblock);
+    }
+}
+
+/* Called from I/O thread context */
+static void request_memblock(struct output *o, size_t length) {
+    pa_assert(o);
+    pa_sink_input_assert_ref(o->sink_input);
+    pa_sink_assert_ref(o->userdata->sink);
+
+    /* If another thread already prepared some data we received
+     * the data over the asyncmsgq, hence let's first process
+     * it. */
+    while (pa_asyncmsgq_process_one(o->inq) > 0)
+        ;
+
+    /* Check whether we're now readable */
+    if (pa_memblockq_is_readable(o->memblockq))
+        return;
+
+    /* OK, we need to prepare new data, but only if the sink is actually running */
+    if (pa_atomic_load(&o->userdata->thread_info.running))
+        pa_asyncmsgq_send(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_NEED, o, (int64_t) length, NULL);
+}
+
+/* Called from I/O thread context */
+static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
+    struct output *o;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(o = i->userdata);
+
+    /* If necessary, get some new data */
+    request_memblock(o, nbytes);
+
+    /* pa_log("%s q size is %u + %u (%u/%u)", */
+    /*        i->sink->name, */
+    /*        pa_memblockq_get_nblocks(o->memblockq), */
+    /*        pa_memblockq_get_nblocks(i->thread_info.render_memblockq), */
+    /*        pa_memblockq_get_maxrewind(o->memblockq), */
+    /*        pa_memblockq_get_maxrewind(i->thread_info.render_memblockq)); */
+
+    if (pa_memblockq_peek(o->memblockq, chunk) < 0)
+        return -1;
+
+    pa_memblockq_drop(o->memblockq, chunk->length);
+
+    return 0;
+}
+
+/* Called from I/O thread context */
+static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
+    struct output *o;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(o = i->userdata);
+
+    pa_memblockq_rewind(o->memblockq, nbytes);
+}
+
+/* Called from I/O thread context */
+static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
+    struct output *o;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(o = i->userdata);
+
+    pa_memblockq_set_maxrewind(o->memblockq, nbytes);
+}
+
+/* Called from I/O thread context */
+static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) {
+    struct output *o;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(o = i->userdata);
+
+    if (pa_atomic_load(&o->max_request) == (int) nbytes)
+        return;
+
+    pa_atomic_store(&o->max_request, (int) nbytes);
+    pa_asyncmsgq_post(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_UPDATE_MAX_REQUEST, NULL, 0, NULL, NULL);
+}
+
+/* Called from thread context */
+static void sink_input_update_sink_requested_latency_cb(pa_sink_input *i) {
+    struct output *o;
+    pa_usec_t c;
+
+    pa_assert(i);
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(o = i->userdata);
+
+    c = pa_sink_get_requested_latency_within_thread(i->sink);
+
+    if (c == (pa_usec_t) -1)
+        c = i->sink->thread_info.max_latency;
+
+    if (pa_atomic_load(&o->requested_latency) == (int) c)
+        return;
+
+    pa_atomic_store(&o->requested_latency, (int) c);
+    pa_asyncmsgq_post(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_UPDATE_REQUESTED_LATENCY, NULL, 0, NULL, NULL);
+}
+
+/* Called from I/O thread context */
+static void sink_input_attach_cb(pa_sink_input *i) {
+    struct output *o;
+    pa_usec_t c;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(o = i->userdata);
+
+    /* Set up the queue from the sink thread to us */
+    pa_assert(!o->inq_rtpoll_item_read && !o->outq_rtpoll_item_write);
+
+    o->inq_rtpoll_item_read = pa_rtpoll_item_new_asyncmsgq_read(
+            i->sink->thread_info.rtpoll,
+            PA_RTPOLL_LATE,  /* This one is not that important, since we check for data in _peek() anyway. */
+            o->inq);
+
+    o->outq_rtpoll_item_write = pa_rtpoll_item_new_asyncmsgq_write(
+            i->sink->thread_info.rtpoll,
+            PA_RTPOLL_EARLY,
+            o->outq);
+
+    pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
+
+    pa_atomic_store(&o->max_request, (int) pa_sink_input_get_max_request(i));
+
+    c = pa_sink_get_requested_latency_within_thread(i->sink);
+    pa_atomic_store(&o->requested_latency, (int) (c == (pa_usec_t) -1 ? 0 : c));
+
+    pa_asyncmsgq_post(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_UPDATE_MAX_REQUEST, NULL, 0, NULL, NULL);
+    pa_asyncmsgq_post(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_UPDATE_REQUESTED_LATENCY, NULL, 0, NULL, NULL);
+}
+
+/* Called from I/O thread context */
+static void sink_input_detach_cb(pa_sink_input *i) {
+    struct output *o;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(o = i->userdata);
+
+    if (o->inq_rtpoll_item_read) {
+        pa_rtpoll_item_free(o->inq_rtpoll_item_read);
+        o->inq_rtpoll_item_read = NULL;
+    }
+
+    if (o->outq_rtpoll_item_write) {
+        pa_rtpoll_item_free(o->outq_rtpoll_item_write);
+        o->outq_rtpoll_item_write = NULL;
+    }
+}
+
+/* Called from main context */
+static void sink_input_kill_cb(pa_sink_input *i) {
+    struct output *o;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(o = i->userdata);
+
+    pa_module_unload_request(o->userdata->module, TRUE);
+    pa_idxset_remove_by_data(o->userdata->outputs, o, NULL);
+    output_free(o);
+}
+
+/* Called from thread context */
+static int sink_input_process_msg(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
+    struct output *o = PA_SINK_INPUT(obj)->userdata;
+
+    switch (code) {
+
+        case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
+            pa_usec_t *r = data;
+
+            *r = pa_bytes_to_usec(pa_memblockq_get_length(o->memblockq), &o->sink_input->sample_spec);
+
+            /* Fall through, the default handler will add in the extra
+             * latency added by the resampler */
+            break;
+        }
+
+        case SINK_INPUT_MESSAGE_POST:
+
+            if (PA_SINK_IS_OPENED(o->sink_input->sink->thread_info.state))
+                pa_memblockq_push_align(o->memblockq, chunk);
+            else
+                pa_memblockq_flush_write(o->memblockq, TRUE);
+
+            return 0;
+    }
+
+    return pa_sink_input_process_msg(obj, code, data, offset, chunk);
+}
+
+/* Called from main context */
+static void suspend(struct userdata *u) {
+    struct output *o;
+    uint32_t idx;
+
+    pa_assert(u);
+
+    /* Let's suspend by unlinking all streams */
+    PA_IDXSET_FOREACH(o, u->outputs, idx)
+        output_disable(o);
+
+    pa_log_info("Device suspended...");
+}
+
+/* Called from main context */
+static void unsuspend(struct userdata *u) {
+    struct output *o;
+    uint32_t idx;
+
+    pa_assert(u);
+
+    /* Let's resume */
+    PA_IDXSET_FOREACH(o, u->outputs, idx)
+        output_enable(o);
+
+    if (!u->time_event)
+        u->time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + u->adjust_time, time_callback, u);
+
+    pa_log_info("Resumed successfully...");
+}
+
+/* Called from main context */
+static int sink_set_state(pa_sink *sink, pa_sink_state_t state) {
+    struct userdata *u;
+
+    pa_sink_assert_ref(sink);
+    pa_assert_se(u = sink->userdata);
+
+    /* Please note that in contrast to the ALSA modules we call
+     * suspend/unsuspend from main context here! */
+
+    switch (state) {
+        case PA_SINK_SUSPENDED:
+            pa_assert(PA_SINK_IS_OPENED(pa_sink_get_state(u->sink)));
+
+            suspend(u);
+            break;
+
+        case PA_SINK_IDLE:
+        case PA_SINK_RUNNING:
+
+            if (pa_sink_get_state(u->sink) == PA_SINK_SUSPENDED)
+                unsuspend(u);
+
+            break;
+
+        case PA_SINK_UNLINKED:
+        case PA_SINK_INIT:
+        case PA_SINK_INVALID_STATE:
+            ;
+    }
+
+    return 0;
+}
+
+/* Called from IO context */
+static void update_max_request(struct userdata *u) {
+    size_t max_request = 0;
+    struct output *o;
+
+    pa_assert(u);
+    pa_sink_assert_io_context(u->sink);
+
+    /* Collects the max_request values of all streams and sets the
+     * largest one locally */
+
+    PA_LLIST_FOREACH(o, u->thread_info.active_outputs) {
+        size_t mr = (size_t) pa_atomic_load(&o->max_request);
+
+        if (mr > max_request)
+            max_request = mr;
+    }
+
+    if (max_request <= 0)
+        max_request = pa_usec_to_bytes(u->block_usec, &u->sink->sample_spec);
+
+    pa_sink_set_max_request_within_thread(u->sink, max_request);
+}
+
+/* Called from IO context */
+static void update_fixed_latency(struct userdata *u) {
+    pa_usec_t fixed_latency = 0;
+    struct output *o;
+
+    pa_assert(u);
+    pa_sink_assert_io_context(u->sink);
+
+    /* Collects the requested_latency values of all streams and sets
+     * the largest one as fixed_latency locally */
+
+    PA_LLIST_FOREACH(o, u->thread_info.active_outputs) {
+        pa_usec_t rl = (size_t) pa_atomic_load(&o->requested_latency);
+
+        if (rl > fixed_latency)
+            fixed_latency = rl;
+    }
+
+    if (fixed_latency <= 0)
+        fixed_latency = u->block_usec;
+
+    pa_sink_set_fixed_latency_within_thread(u->sink, fixed_latency);
+}
+
+/* Called from thread context of the io thread */
+static void output_add_within_thread(struct output *o) {
+    pa_assert(o);
+    pa_sink_assert_io_context(o->sink);
+
+    PA_LLIST_PREPEND(struct output, o->userdata->thread_info.active_outputs, o);
+
+    pa_assert(!o->outq_rtpoll_item_read && !o->inq_rtpoll_item_write);
+
+    o->outq_rtpoll_item_read = pa_rtpoll_item_new_asyncmsgq_read(
+            o->userdata->rtpoll,
+            PA_RTPOLL_EARLY-1,  /* This item is very important */
+            o->outq);
+    o->inq_rtpoll_item_write = pa_rtpoll_item_new_asyncmsgq_write(
+            o->userdata->rtpoll,
+            PA_RTPOLL_EARLY,
+            o->inq);
+}
+
+/* Called from thread context of the io thread */
+static void output_remove_within_thread(struct output *o) {
+    pa_assert(o);
+    pa_sink_assert_io_context(o->sink);
+
+    PA_LLIST_REMOVE(struct output, o->userdata->thread_info.active_outputs, o);
+
+    if (o->outq_rtpoll_item_read) {
+        pa_rtpoll_item_free(o->outq_rtpoll_item_read);
+        o->outq_rtpoll_item_read = NULL;
+    }
+
+    if (o->inq_rtpoll_item_write) {
+        pa_rtpoll_item_free(o->inq_rtpoll_item_write);
+        o->inq_rtpoll_item_write = NULL;
+    }
+}
+
+/* Called from thread context of the io thread */
+static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
+    struct userdata *u = PA_SINK(o)->userdata;
+
+    switch (code) {
+
+        case PA_SINK_MESSAGE_SET_STATE: {
+            pa_bool_t running = (PA_PTR_TO_UINT(data) == PA_SINK_RUNNING);
+
+            pa_atomic_store(&u->thread_info.running, running);
+
+            if (running)
+                pa_smoother_resume(u->thread_info.smoother, pa_rtclock_now(), TRUE);
+            else
+                pa_smoother_pause(u->thread_info.smoother, pa_rtclock_now());
+
+            break;
+        }
+
+        case PA_SINK_MESSAGE_GET_LATENCY: {
+            pa_usec_t x, y, c, *delay = data;
+
+            x = pa_rtclock_now();
+            y = pa_smoother_get(u->thread_info.smoother, x);
+
+            c = pa_bytes_to_usec(u->thread_info.counter, &u->sink->sample_spec);
+
+            if (y < c)
+                *delay = c - y;
+            else
+                *delay = 0;
+
+            return 0;
+        }
+
+        case SINK_MESSAGE_ADD_OUTPUT:
+            output_add_within_thread(data);
+            update_max_request(u);
+            update_fixed_latency(u);
+            return 0;
+
+        case SINK_MESSAGE_REMOVE_OUTPUT:
+            output_remove_within_thread(data);
+            update_max_request(u);
+            update_fixed_latency(u);
+            return 0;
+
+        case SINK_MESSAGE_NEED:
+            render_memblock(u, (struct output*) data, (size_t) offset);
+            return 0;
+
+        case SINK_MESSAGE_UPDATE_LATENCY: {
+            pa_usec_t x, y, latency = (pa_usec_t) offset;
+
+            x = pa_rtclock_now();
+            y = pa_bytes_to_usec(u->thread_info.counter, &u->sink->sample_spec);
+
+            if (y > latency)
+                y -= latency;
+            else
+                y = 0;
+
+            pa_smoother_put(u->thread_info.smoother, x, y);
+            return 0;
+        }
+
+        case SINK_MESSAGE_UPDATE_MAX_REQUEST:
+            update_max_request(u);
+            break;
+
+        case SINK_MESSAGE_UPDATE_REQUESTED_LATENCY:
+            update_fixed_latency(u);
+            break;
+}
+
+    return pa_sink_process_msg(o, code, data, offset, chunk);
+}
+
+static void update_description(struct userdata *u) {
+    pa_bool_t first = TRUE;
+    char *t;
+    struct output *o;
+    uint32_t idx;
+
+    pa_assert(u);
+
+    if (!u->auto_desc)
+        return;
+
+    if (pa_idxset_isempty(u->outputs)) {
+        pa_sink_set_description(u->sink, "Simultaneous output");
+        return;
+    }
+
+    t = pa_xstrdup("Simultaneous output to");
+
+    PA_IDXSET_FOREACH(o, u->outputs, idx) {
+        char *e;
+
+        if (first) {
+            e = pa_sprintf_malloc("%s %s", t, pa_strnull(pa_proplist_gets(o->sink->proplist, PA_PROP_DEVICE_DESCRIPTION)));
+            first = FALSE;
+        } else
+            e = pa_sprintf_malloc("%s, %s", t, pa_strnull(pa_proplist_gets(o->sink->proplist, PA_PROP_DEVICE_DESCRIPTION)));
+
+        pa_xfree(t);
+        t = e;
+    }
+
+    pa_sink_set_description(u->sink, t);
+    pa_xfree(t);
+}
+
+static int output_create_sink_input(struct output *o) {
+    struct userdata *u;
+    pa_sink_input_new_data data;
+
+    pa_assert(o);
+
+    if (o->sink_input)
+        return 0;
+
+    u = o->userdata;
+
+    pa_sink_input_new_data_init(&data);
+    pa_sink_input_new_data_set_sink(&data, o->sink, FALSE);
+    data.driver = __FILE__;
+    pa_proplist_setf(data.proplist, PA_PROP_MEDIA_NAME, "Simultaneous output on %s", pa_strnull(pa_proplist_gets(o->sink->proplist, PA_PROP_DEVICE_DESCRIPTION)));
+    pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, "filter");
+    pa_sink_input_new_data_set_sample_spec(&data, &o->userdata->sink->sample_spec);
+    pa_sink_input_new_data_set_channel_map(&data, &o->userdata->sink->channel_map);
+    data.module = o->userdata->module;
+    data.resample_method = o->userdata->resample_method;
+    data.flags = PA_SINK_INPUT_VARIABLE_RATE|PA_SINK_INPUT_DONT_MOVE|PA_SINK_INPUT_NO_CREATE_ON_SUSPEND;
+
+    pa_sink_input_new(&o->sink_input, o->userdata->core, &data);
+
+    pa_sink_input_new_data_done(&data);
+
+    if (!o->sink_input)
+        return -1;
+
+    o->sink_input->parent.process_msg = sink_input_process_msg;
+    o->sink_input->pop = sink_input_pop_cb;
+    o->sink_input->process_rewind = sink_input_process_rewind_cb;
+    o->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
+    o->sink_input->update_max_request = sink_input_update_max_request_cb;
+    o->sink_input->update_sink_requested_latency = sink_input_update_sink_requested_latency_cb;
+    o->sink_input->attach = sink_input_attach_cb;
+    o->sink_input->detach = sink_input_detach_cb;
+    o->sink_input->kill = sink_input_kill_cb;
+    o->sink_input->userdata = o;
+
+    pa_sink_input_set_requested_latency(o->sink_input, pa_sink_get_requested_latency(u->sink));
+
+    return 0;
+}
+
+/* Called from main context */
+static struct output *output_new(struct userdata *u, pa_sink *sink) {
+    struct output *o;
+
+    pa_assert(u);
+    pa_assert(sink);
+    pa_assert(u->sink);
+
+    o = pa_xnew0(struct output, 1);
+    o->userdata = u;
+    o->inq = pa_asyncmsgq_new(0);
+    o->outq = pa_asyncmsgq_new(0);
+    o->sink = sink;
+    o->memblockq = pa_memblockq_new(
+            "module-combine-sink output memblockq",
+            0,
+            MEMBLOCKQ_MAXLENGTH,
+            MEMBLOCKQ_MAXLENGTH,
+            &u->sink->sample_spec,
+            1,
+            0,
+            0,
+            &u->sink->silence);
+
+    pa_assert_se(pa_idxset_put(u->outputs, o, NULL) == 0);
+    update_description(u);
+
+    return o;
+}
+
+/* Called from main context */
+static void output_free(struct output *o) {
+    pa_assert(o);
+
+    output_disable(o);
+
+    pa_assert_se(pa_idxset_remove_by_data(o->userdata->outputs, o, NULL));
+    update_description(o->userdata);
+
+    if (o->inq_rtpoll_item_read)
+        pa_rtpoll_item_free(o->inq_rtpoll_item_read);
+    if (o->inq_rtpoll_item_write)
+        pa_rtpoll_item_free(o->inq_rtpoll_item_write);
+
+    if (o->outq_rtpoll_item_read)
+        pa_rtpoll_item_free(o->outq_rtpoll_item_read);
+    if (o->outq_rtpoll_item_write)
+        pa_rtpoll_item_free(o->outq_rtpoll_item_write);
+
+    if (o->inq)
+        pa_asyncmsgq_unref(o->inq);
+
+    if (o->outq)
+        pa_asyncmsgq_unref(o->outq);
+
+    if (o->memblockq)
+        pa_memblockq_free(o->memblockq);
+
+    pa_xfree(o);
+}
+
+/* Called from main context */
+static void output_enable(struct output *o) {
+    pa_assert(o);
+
+    if (o->sink_input)
+        return;
+
+    /* This might cause the sink to be resumed. The state change hook
+     * of the sink might hence be called from here, which might then
+     * cause us to be called in a loop. Make sure that state changes
+     * for this output don't cause this loop by setting a flag here */
+    o->ignore_state_change = TRUE;
+
+    if (output_create_sink_input(o) >= 0) {
+
+        if (pa_sink_get_state(o->sink) != PA_SINK_INIT) {
+
+            /* First we register the output. That means that the sink
+             * will start to pass data to this output. */
+            pa_asyncmsgq_send(o->userdata->sink->asyncmsgq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_ADD_OUTPUT, o, 0, NULL);
+
+            /* Then we enable the sink input. That means that the sink
+             * is now asked for new data. */
+            pa_sink_input_put(o->sink_input);
+
+        } else
+            /* Hmm the sink is not yet started, do things right here */
+            output_add_within_thread(o);
+    }
+
+    o->ignore_state_change = FALSE;
+}
+
+/* Called from main context */
+static void output_disable(struct output *o) {
+    pa_assert(o);
+
+    if (!o->sink_input)
+        return;
+
+    /* First we disable the sink input. That means that the sink is
+     * not asked for new data anymore  */
+    pa_sink_input_unlink(o->sink_input);
+
+    /* Then we unregister the output. That means that the sink doesn't
+     * pass any further data to this output */
+    pa_asyncmsgq_send(o->userdata->sink->asyncmsgq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_REMOVE_OUTPUT, o, 0, NULL);
+
+    /* Now deallocate the stream */
+    pa_sink_input_unref(o->sink_input);
+    o->sink_input = NULL;
+
+    /* Finally, drop all queued data */
+    pa_memblockq_flush_write(o->memblockq, TRUE);
+    pa_asyncmsgq_flush(o->inq, FALSE);
+    pa_asyncmsgq_flush(o->outq, FALSE);
+}
+
+/* Called from main context */
+static void output_verify(struct output *o) {
+    pa_assert(o);
+
+    if (PA_SINK_IS_OPENED(pa_sink_get_state(o->userdata->sink)))
+        output_enable(o);
+    else
+        output_disable(o);
+}
+
+/* Called from main context */
+static pa_bool_t is_suitable_sink(struct userdata *u, pa_sink *s) {
+    const char *t;
+
+    pa_sink_assert_ref(s);
+
+    if (s == u->sink)
+        return FALSE;
+
+    if (!(s->flags & PA_SINK_HARDWARE))
+        return FALSE;
+
+    if (!(s->flags & PA_SINK_LATENCY))
+        return FALSE;
+
+    if ((t = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_CLASS)))
+        if (!pa_streq(t, "sound"))
+            return FALSE;
+
+    return TRUE;
+}
+
+/* Called from main context */
+static pa_hook_result_t sink_put_hook_cb(pa_core *c, pa_sink *s, struct userdata* u) {
+    struct output *o;
+
+    pa_core_assert_ref(c);
+    pa_sink_assert_ref(s);
+    pa_assert(u);
+
+    if (u->automatic) {
+        if (!is_suitable_sink(u, s))
+            return PA_HOOK_OK;
+    } else {
+        /* Check if the sink is a previously unlinked slave (non-automatic mode) */
+        pa_strlist *l = u->unlinked_slaves;
+
+        while (l && !pa_streq(pa_strlist_data(l), s->name))
+            l = pa_strlist_next(l);
+
+        if (!l)
+            return PA_HOOK_OK;
+
+        u->unlinked_slaves = pa_strlist_remove(u->unlinked_slaves, s->name);
+    }
+
+    pa_log_info("Configuring new sink: %s", s->name);
+    if (!(o = output_new(u, s))) {
+        pa_log("Failed to create sink input on sink '%s'.", s->name);
+        return PA_HOOK_OK;
+    }
+
+    output_verify(o);
+
+    return PA_HOOK_OK;
+}
+
+/* Called from main context */
+static struct output* find_output(struct userdata *u, pa_sink *s) {
+    struct output *o;
+    uint32_t idx;
+
+    pa_assert(u);
+    pa_assert(s);
+
+    if (u->sink == s)
+        return NULL;
+
+    PA_IDXSET_FOREACH(o, u->outputs, idx)
+        if (o->sink == s)
+            return o;
+
+    return NULL;
+}
+
+/* Called from main context */
+static pa_hook_result_t sink_unlink_hook_cb(pa_core *c, pa_sink *s, struct userdata* u) {
+    struct output *o;
+
+    pa_assert(c);
+    pa_sink_assert_ref(s);
+    pa_assert(u);
+
+    if (!(o = find_output(u, s)))
+        return PA_HOOK_OK;
+
+    pa_log_info("Unconfiguring sink: %s", s->name);
+
+    if (!u->automatic)
+        u->unlinked_slaves = pa_strlist_prepend(u->unlinked_slaves, s->name);
+
+    pa_idxset_remove_by_data(u->outputs, o, NULL);
+    output_free(o);
+
+    return PA_HOOK_OK;
+}
+
+/* Called from main context */
+static pa_hook_result_t sink_state_changed_hook_cb(pa_core *c, pa_sink *s, struct userdata* u) {
+    struct output *o;
+
+    if (!(o = find_output(u, s)))
+        return PA_HOOK_OK;
+
+    /* This state change might be triggered because we are creating a
+     * stream here, in that case we don't want to create it a second
+     * time here and enter a loop */
+    if (o->ignore_state_change)
+        return PA_HOOK_OK;
+
+    output_verify(o);
+
+    return PA_HOOK_OK;
+}
+
+int pa__init(pa_module*m) {
+    struct userdata *u;
+    pa_modargs *ma = NULL;
+    const char *slaves, *rm;
+    int resample_method = PA_RESAMPLER_TRIVIAL;
+    pa_sample_spec ss;
+    pa_channel_map map;
+    struct output *o;
+    uint32_t idx;
+    pa_sink_new_data data;
+    uint32_t adjust_time_sec;
+
+    pa_assert(m);
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("failed to parse module arguments");
+        goto fail;
+    }
+
+    if ((rm = pa_modargs_get_value(ma, "resample_method", NULL))) {
+        if ((resample_method = pa_parse_resample_method(rm)) < 0) {
+            pa_log("invalid resample method '%s'", rm);
+            goto fail;
+        }
+    }
+
+    m->userdata = u = pa_xnew0(struct userdata, 1);
+    u->core = m->core;
+    u->module = m;
+    u->rtpoll = pa_rtpoll_new();
+    pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
+    u->resample_method = resample_method;
+    u->outputs = pa_idxset_new(NULL, NULL);
+    u->thread_info.smoother = pa_smoother_new(
+            PA_USEC_PER_SEC,
+            PA_USEC_PER_SEC*2,
+            TRUE,
+            TRUE,
+            10,
+            pa_rtclock_now(),
+            TRUE);
+
+    adjust_time_sec = DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC;
+    if (pa_modargs_get_value_u32(ma, "adjust_time", &adjust_time_sec) < 0) {
+        pa_log("Failed to parse adjust_time value");
+        goto fail;
+    }
+
+    if (adjust_time_sec != DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC)
+        u->adjust_time = adjust_time_sec * PA_USEC_PER_SEC;
+    else
+        u->adjust_time = DEFAULT_ADJUST_TIME_USEC;
+
+    slaves = pa_modargs_get_value(ma, "slaves", NULL);
+    u->automatic = !slaves;
+
+    ss = m->core->default_sample_spec;
+    map = m->core->default_channel_map;
+
+    /* Check the specified slave sinks for sample_spec and channel_map to use for the combined sink */
+    if (!u->automatic) {
+        const char*split_state = NULL;
+        char *n = NULL;
+        pa_sample_spec slaves_spec;
+        pa_channel_map slaves_map;
+        pa_bool_t is_first_slave = TRUE;
+
+        pa_sample_spec_init(&slaves_spec);
+
+        while ((n = pa_split(slaves, ",", &split_state))) {
+            pa_sink *slave_sink;
+
+            if (!(slave_sink = pa_namereg_get(m->core, n, PA_NAMEREG_SINK))) {
+                pa_log("Invalid slave sink '%s'", n);
+                pa_xfree(n);
+                goto fail;
+            }
+
+            pa_xfree(n);
+
+            if (is_first_slave) {
+                slaves_spec = slave_sink->sample_spec;
+                slaves_map = slave_sink->channel_map;
+                is_first_slave = FALSE;
+            } else {
+                if (slaves_spec.format != slave_sink->sample_spec.format)
+                    slaves_spec.format = PA_SAMPLE_INVALID;
+
+                if (slaves_spec.rate < slave_sink->sample_spec.rate)
+                    slaves_spec.rate = slave_sink->sample_spec.rate;
+
+                if (!pa_channel_map_equal(&slaves_map, &slave_sink->channel_map))
+                    slaves_spec.channels = 0;
+            }
+        }
+
+        if (!is_first_slave) {
+            if (slaves_spec.format != PA_SAMPLE_INVALID)
+                ss.format = slaves_spec.format;
+
+            ss.rate = slaves_spec.rate;
+
+            if (slaves_spec.channels > 0) {
+                map = slaves_map;
+                ss.channels = slaves_map.channels;
+            }
+        }
+    }
+
+    if ((pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0)) {
+        pa_log("Invalid sample specification.");
+        goto fail;
+    }
+
+    pa_sink_new_data_init(&data);
+    data.namereg_fail = FALSE;
+    data.driver = __FILE__;
+    data.module = m;
+    pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME));
+    pa_sink_new_data_set_sample_spec(&data, &ss);
+    pa_sink_new_data_set_channel_map(&data, &map);
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "filter");
+
+    if (slaves)
+        pa_proplist_sets(data.proplist, "combine.slaves", slaves);
+
+    if (pa_modargs_get_proplist(ma, "sink_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
+        pa_log("Invalid properties");
+        pa_sink_new_data_done(&data);
+        goto fail;
+    }
+
+    /* Check proplist for a description & fill in a default value if not */
+    u->auto_desc = FALSE;
+    if (NULL == pa_proplist_gets(data.proplist, PA_PROP_DEVICE_DESCRIPTION)) {
+        u->auto_desc = TRUE;
+        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Simultaneous Output");
+    }
+
+    u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY);
+    pa_sink_new_data_done(&data);
+
+    if (!u->sink) {
+        pa_log("Failed to create sink");
+        goto fail;
+    }
+
+    u->sink->parent.process_msg = sink_process_msg;
+    u->sink->set_state = sink_set_state;
+    u->sink->userdata = u;
+
+    pa_sink_set_rtpoll(u->sink, u->rtpoll);
+    pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
+
+    u->block_usec = BLOCK_USEC;
+    pa_sink_set_max_request(u->sink, pa_usec_to_bytes(u->block_usec, &u->sink->sample_spec));
+
+    if (!u->automatic) {
+        const char*split_state;
+        char *n = NULL;
+        pa_assert(slaves);
+
+        /* The slaves have been specified manually */
+
+        split_state = NULL;
+        while ((n = pa_split(slaves, ",", &split_state))) {
+            pa_sink *slave_sink;
+
+            if (!(slave_sink = pa_namereg_get(m->core, n, PA_NAMEREG_SINK)) || slave_sink == u->sink) {
+                pa_log("Invalid slave sink '%s'", n);
+                pa_xfree(n);
+                goto fail;
+            }
+
+            pa_xfree(n);
+
+            if (!output_new(u, slave_sink)) {
+                pa_log("Failed to create slave sink input on sink '%s'.", slave_sink->name);
+                goto fail;
+            }
+        }
+
+        if (pa_idxset_size(u->outputs) <= 1)
+            pa_log_warn("No slave sinks specified.");
+
+        u->sink_put_slot = NULL;
+
+    } else {
+        pa_sink *s;
+
+        /* We're in automatic mode, we add every sink that matches our needs  */
+
+        PA_IDXSET_FOREACH(s, m->core->sinks, idx) {
+
+            if (!is_suitable_sink(u, s))
+                continue;
+
+            if (!output_new(u, s)) {
+                pa_log("Failed to create sink input on sink '%s'.", s->name);
+                goto fail;
+            }
+        }
+    }
+
+    u->sink_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE, (pa_hook_cb_t) sink_put_hook_cb, u);
+    u->sink_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) sink_unlink_hook_cb, u);
+    u->sink_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) sink_state_changed_hook_cb, u);
+
+    if (!(u->thread = pa_thread_new("combine", thread_func, u))) {
+        pa_log("Failed to create thread.");
+        goto fail;
+    }
+
+    /* Activate the sink and the sink inputs */
+    pa_sink_put(u->sink);
+
+    PA_IDXSET_FOREACH(o, u->outputs, idx)
+        output_verify(o);
+
+    if (u->adjust_time > 0)
+        u->time_event = pa_core_rttime_new(m->core, pa_rtclock_now() + u->adjust_time, time_callback, u);
+
+    pa_modargs_free(ma);
+
+    return 0;
+
+fail:
+
+    if (ma)
+        pa_modargs_free(ma);
+
+    pa__done(m);
+
+    return -1;
+}
+
+void pa__done(pa_module*m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    pa_strlist_free(u->unlinked_slaves);
+
+    if (u->sink_put_slot)
+        pa_hook_slot_free(u->sink_put_slot);
+
+    if (u->sink_unlink_slot)
+        pa_hook_slot_free(u->sink_unlink_slot);
+
+    if (u->sink_state_changed_slot)
+        pa_hook_slot_free(u->sink_state_changed_slot);
+
+#ifdef __TIZEN_BT__
+    if (u->outputs) {
+       struct output *o;
+        while ((o = pa_idxset_first(u->outputs, NULL)))
+            output_free(o);
+
+        pa_idxset_free(u->outputs, NULL);
+    }
+#else
+    if (u->outputs)
+        pa_idxset_free(u->outputs, (pa_free_cb_t) output_free);
+#endif
+
+    if (u->sink)
+        pa_sink_unlink(u->sink);
+
+    if (u->thread) {
+        pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
+        pa_thread_free(u->thread);
+    }
+
+    pa_thread_mq_done(&u->thread_mq);
+
+    if (u->sink)
+        pa_sink_unref(u->sink);
+
+    if (u->rtpoll)
+        pa_rtpoll_free(u->rtpoll);
+
+    if (u->time_event)
+        u->core->mainloop->time_free(u->time_event);
+
+    if (u->thread_info.smoother)
+        pa_smoother_free(u->thread_info.smoother);
+
+    pa_xfree(u);
+}
diff --git a/src/modules/module-combine-symdef.h b/src/modules/module-combine-symdef.h
deleted file mode 100644 (file)
index 8b10a42..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulecombinesymdeffoo
-#define foomodulecombinesymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_combine_LTX_pa__init
-#define pa__done module_combine_LTX_pa__done
-#define pa__get_author module_combine_LTX_pa__get_author
-#define pa__get_description module_combine_LTX_pa__get_description
-#define pa__get_usage module_combine_LTX_pa__get_usage
-#define pa__get_version module_combine_LTX_pa__get_version
-#define pa__get_deprecated module_combine_LTX_pa__get_deprecated
-#define pa__load_once module_combine_LTX_pa__load_once
-#define pa__get_n_used module_combine_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index cffb901..251df49 100644 (file)
@@ -1,7 +1,8 @@
 /***
   This file is part of PulseAudio.
 
-  Copyright 2004-2008 Lennart Poettering
+  Copyright 2009 Lennart Poettering
+  Copyright 2011 Colin Guthrie
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
 #include <config.h>
 #endif
 
-#include <stdio.h>
-#include <errno.h>
-
-#include <pulse/rtclock.h>
-#include <pulse/timeval.h>
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/macro.h>
 #include <pulsecore/module.h>
-#include <pulsecore/llist.h>
-#include <pulsecore/sink.h>
-#include <pulsecore/sink-input.h>
-#include <pulsecore/memblockq.h>
 #include <pulsecore/log.h>
-#include <pulsecore/core-rtclock.h>
-#include <pulsecore/core-util.h>
-#include <pulsecore/modargs.h>
-#include <pulsecore/namereg.h>
-#include <pulsecore/mutex.h>
-#include <pulsecore/thread.h>
-#include <pulsecore/thread-mq.h>
-#include <pulsecore/rtpoll.h>
-#include <pulsecore/core-error.h>
-#include <pulsecore/time-smoother.h>
 
 #include "module-combine-symdef.h"
 
-PA_MODULE_AUTHOR("Lennart Poettering");
-PA_MODULE_DESCRIPTION("Combine multiple sinks to one");
+PA_MODULE_AUTHOR("Colin Guthrie");
+PA_MODULE_DESCRIPTION("Compatibility module (module-combine rename)");
 PA_MODULE_VERSION(PACKAGE_VERSION);
 PA_MODULE_LOAD_ONCE(FALSE);
-PA_MODULE_USAGE(
-        "sink_name=<name for the sink> "
-        "sink_properties=<properties for the sink> "
-        "slaves=<slave sinks> "
-        "adjust_time=<how often to readjust rates in s> "
-        "resample_method=<method> "
-        "format=<sample format> "
-        "rate=<sample rate> "
-        "channels=<number of channels> "
-        "channel_map=<channel map>");
-
-#define DEFAULT_SINK_NAME "combined"
-
-#define MEMBLOCKQ_MAXLENGTH (1024*1024*16)
-
-#define DEFAULT_ADJUST_TIME_USEC (10*PA_USEC_PER_SEC)
-
-#define BLOCK_USEC (PA_USEC_PER_MSEC * 200)
-
-static const char* const valid_modargs[] = {
-    "sink_name",
-    "sink_properties",
-    "slaves",
-    "adjust_time",
-    "resample_method",
-    "format",
-    "rate",
-    "channels",
-    "channel_map",
-    NULL
-};
-
-struct output {
-    struct userdata *userdata;
-
-    pa_sink *sink;
-    pa_sink_input *sink_input;
-    pa_bool_t ignore_state_change;
-
-    pa_asyncmsgq *inq,    /* Message queue from the sink thread to this sink input */
-                 *outq;   /* Message queue from this sink input to the sink thread */
-    pa_rtpoll_item *inq_rtpoll_item_read, *inq_rtpoll_item_write;
-    pa_rtpoll_item *outq_rtpoll_item_read, *outq_rtpoll_item_write;
-
-    pa_memblockq *memblockq;
-
-    /* For communication of the stream latencies to the main thread */
-    pa_usec_t total_latency;
-
-    /* For coomunication of the stream parameters to the sink thread */
-    pa_atomic_t max_request;
-    pa_atomic_t requested_latency;
-
-    PA_LLIST_FIELDS(struct output);
-};
+PA_MODULE_DEPRECATED("Please use module-combine-sink instead of module-combine!");
 
 struct userdata {
-    pa_core *core;
-    pa_module *module;
-    pa_sink *sink;
-
-    pa_thread *thread;
-    pa_thread_mq thread_mq;
-    pa_rtpoll *rtpoll;
-
-    pa_time_event *time_event;
-    pa_usec_t adjust_time;
-
-    pa_bool_t automatic;
-    pa_bool_t auto_desc;
-
-    pa_hook_slot *sink_put_slot, *sink_unlink_slot, *sink_state_changed_slot;
-
-    pa_resample_method_t resample_method;
-
-    pa_usec_t block_usec;
-
-    pa_idxset* outputs; /* managed in main context */
-
-    struct {
-        PA_LLIST_HEAD(struct output, active_outputs); /* managed in IO thread context */
-        pa_atomic_t running;  /* we cache that value here, so that every thread can query it cheaply */
-        pa_usec_t timestamp;
-        pa_bool_t in_null_mode;
-        pa_smoother *smoother;
-        uint64_t counter;
-    } thread_info;
+    uint32_t module_index;
 };
 
-enum {
-    SINK_MESSAGE_ADD_OUTPUT = PA_SINK_MESSAGE_MAX,
-    SINK_MESSAGE_REMOVE_OUTPUT,
-    SINK_MESSAGE_NEED,
-    SINK_MESSAGE_UPDATE_LATENCY,
-    SINK_MESSAGE_UPDATE_MAX_REQUEST,
-    SINK_MESSAGE_UPDATE_REQUESTED_LATENCY
-};
-
-enum {
-    SINK_INPUT_MESSAGE_POST = PA_SINK_INPUT_MESSAGE_MAX,
-};
-
-static void output_disable(struct output *o);
-static void output_enable(struct output *o);
-static void output_free(struct output *o);
-static int output_create_sink_input(struct output *o);
-
-static void adjust_rates(struct userdata *u) {
-    struct output *o;
-    pa_usec_t max_sink_latency = 0, min_total_latency = (pa_usec_t) -1, target_latency, avg_total_latency = 0;
-    uint32_t base_rate;
-    uint32_t idx;
-    unsigned n = 0;
-
-    pa_assert(u);
-    pa_sink_assert_ref(u->sink);
-
-    if (pa_idxset_size(u->outputs) <= 0)
-        return;
-
-    if (!PA_SINK_IS_OPENED(pa_sink_get_state(u->sink)))
-        return;
-
-    PA_IDXSET_FOREACH(o, u->outputs, idx) {
-        pa_usec_t sink_latency;
-
-        if (!o->sink_input || !PA_SINK_IS_OPENED(pa_sink_get_state(o->sink)))
-            continue;
-
-        o->total_latency = pa_sink_input_get_latency(o->sink_input, &sink_latency);
-        o->total_latency += sink_latency;
-
-        if (sink_latency > max_sink_latency)
-            max_sink_latency = sink_latency;
-
-        if (min_total_latency == (pa_usec_t) -1 || o->total_latency < min_total_latency)
-            min_total_latency = o->total_latency;
-
-        avg_total_latency += o->total_latency;
-        n++;
-
-        pa_log_debug("[%s] total=%0.2fms sink=%0.2fms ", o->sink->name, (double) o->total_latency / PA_USEC_PER_MSEC, (double) sink_latency / PA_USEC_PER_MSEC);
-
-        if (o->total_latency > 10*PA_USEC_PER_SEC)
-            pa_log_warn("[%s] Total latency of output is very high (%0.2fms), most likely the audio timing in one of your drivers is broken.", o->sink->name, (double) o->total_latency / PA_USEC_PER_MSEC);
-    }
-
-    if (min_total_latency == (pa_usec_t) -1)
-        return;
-
-    avg_total_latency /= n;
-
-    target_latency = max_sink_latency > min_total_latency ? max_sink_latency : min_total_latency;
-
-    pa_log_info("[%s] avg total latency is %0.2f msec.", u->sink->name, (double) avg_total_latency / PA_USEC_PER_MSEC);
-    pa_log_info("[%s] target latency is %0.2f msec.", u->sink->name, (double) target_latency / PA_USEC_PER_MSEC);
-
-    base_rate = u->sink->sample_spec.rate;
-
-    PA_IDXSET_FOREACH(o, u->outputs, idx) {
-        uint32_t r = base_rate;
-
-        if (!o->sink_input || !PA_SINK_IS_OPENED(pa_sink_get_state(o->sink)))
-            continue;
-
-        if (o->total_latency < target_latency)
-            r -= (uint32_t) ((((double) (target_latency - o->total_latency))/(double)u->adjust_time)*(double)r);
-        else if (o->total_latency > target_latency)
-            r += (uint32_t) ((((double) (o->total_latency - target_latency))/(double)u->adjust_time)*(double)r);
-
-        if (r < (uint32_t) (base_rate*0.9) || r > (uint32_t) (base_rate*1.1)) {
-            pa_log_warn("[%s] sample rates too different, not adjusting (%u vs. %u).", o->sink_input->sink->name, base_rate, r);
-            pa_sink_input_set_rate(o->sink_input, base_rate);
-        } else {
-            pa_log_info("[%s] new rate is %u Hz; ratio is %0.3f; latency is %0.0f usec.", o->sink_input->sink->name, r, (double) r / base_rate, (float) o->total_latency);
-            pa_sink_input_set_rate(o->sink_input, r);
-        }
-    }
-
-    pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_UPDATE_LATENCY, NULL, (int64_t) avg_total_latency, NULL);
-}
-
-static void time_callback(pa_mainloop_api *a, pa_time_event *e, const struct timeval *t, void *userdata) {
-    struct userdata *u = userdata;
-
-    pa_assert(u);
-    pa_assert(a);
-    pa_assert(u->time_event == e);
-
-    adjust_rates(u);
-
-    pa_core_rttime_restart(u->core, e, pa_rtclock_now() + u->adjust_time);
-}
-
-static void process_render_null(struct userdata *u, pa_usec_t now) {
-    size_t ate = 0;
-    pa_assert(u);
-
-    if (u->thread_info.in_null_mode)
-        u->thread_info.timestamp = now;
-
-    while (u->thread_info.timestamp < now + u->block_usec) {
-        pa_memchunk chunk;
-
-        pa_sink_render(u->sink, u->sink->thread_info.max_request, &chunk);
-        pa_memblock_unref(chunk.memblock);
-
-        u->thread_info.counter += chunk.length;
-
-/*         pa_log_debug("Ate %lu bytes.", (unsigned long) chunk.length); */
-        u->thread_info.timestamp += pa_bytes_to_usec(chunk.length, &u->sink->sample_spec);
-
-        ate += chunk.length;
-
-        if (ate >= u->sink->thread_info.max_request)
-            break;
-    }
-
-/*     pa_log_debug("Ate in sum %lu bytes (of %lu)", (unsigned long) ate, (unsigned long) nbytes); */
-
-    pa_smoother_put(u->thread_info.smoother, now,
-                    pa_bytes_to_usec(u->thread_info.counter, &u->sink->sample_spec) - (u->thread_info.timestamp - now));
-}
-
-static void thread_func(void *userdata) {
-    struct userdata *u = userdata;
-
-    pa_assert(u);
-
-    pa_log_debug("Thread starting up");
-
-    if (u->core->realtime_scheduling)
-        pa_make_realtime(u->core->realtime_priority+1);
-
-    pa_thread_mq_install(&u->thread_mq);
-
-    u->thread_info.timestamp = pa_rtclock_now();
-    u->thread_info.in_null_mode = FALSE;
-
-    for (;;) {
-        int ret;
-
-        if (PA_SINK_IS_OPENED(u->sink->thread_info.state))
-            if (u->sink->thread_info.rewind_requested)
-                pa_sink_process_rewind(u->sink, 0);
-
-        /* If no outputs are connected, render some data and drop it immediately. */
-        if (PA_SINK_IS_OPENED(u->sink->thread_info.state) && !u->thread_info.active_outputs) {
-            pa_usec_t now;
-
-            now = pa_rtclock_now();
-
-            if (!u->thread_info.in_null_mode || u->thread_info.timestamp <= now)
-                process_render_null(u, now);
-
-            pa_rtpoll_set_timer_absolute(u->rtpoll, u->thread_info.timestamp);
-            u->thread_info.in_null_mode = TRUE;
-        } else {
-            pa_rtpoll_set_timer_disabled(u->rtpoll);
-            u->thread_info.in_null_mode = FALSE;
-        }
-
-        /* Hmm, nothing to do. Let's sleep */
-        if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0) {
-            pa_log_info("pa_rtpoll_run() = %i", ret);
-            goto fail;
-        }
-
-        if (ret == 0)
-            goto finish;
-    }
-
-fail:
-    /* If this was no regular exit from the loop we have to continue
-     * processing messages until we received PA_MESSAGE_SHUTDOWN */
-    pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
-    pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
-
-finish:
-    pa_log_debug("Thread shutting down");
-}
-
-/* Called from I/O thread context */
-static void render_memblock(struct userdata *u, struct output *o, size_t length) {
-    pa_assert(u);
-    pa_assert(o);
-
-    /* We are run by the sink thread, on behalf of an output (o). The
-     * output is waiting for us, hence it is safe to access its
-     * mainblockq and asyncmsgq directly. */
-
-    /* If we are not running, we cannot produce any data */
-    if (!pa_atomic_load(&u->thread_info.running))
-        return;
-
-    /* Maybe there's some data in the requesting output's queue
-     * now? */
-    while (pa_asyncmsgq_process_one(o->inq) > 0)
-        ;
-
-    /* Ok, now let's prepare some data if we really have to */
-    while (!pa_memblockq_is_readable(o->memblockq)) {
-        struct output *j;
-        pa_memchunk chunk;
-
-        /* Render data! */
-        pa_sink_render(u->sink, length, &chunk);
-
-        u->thread_info.counter += chunk.length;
-
-        /* OK, let's send this data to the other threads */
-        PA_LLIST_FOREACH(j, u->thread_info.active_outputs) {
-            if (j == o)
-                continue;
-
-            pa_asyncmsgq_post(j->inq, PA_MSGOBJECT(j->sink_input), SINK_INPUT_MESSAGE_POST, NULL, 0, &chunk, NULL);
-        }
-
-        /* And place it directly into the requesting output's queue */
-        pa_memblockq_push_align(o->memblockq, &chunk);
-        pa_memblock_unref(chunk.memblock);
-    }
-}
-
-/* Called from I/O thread context */
-static void request_memblock(struct output *o, size_t length) {
-    pa_assert(o);
-    pa_sink_input_assert_ref(o->sink_input);
-    pa_sink_assert_ref(o->userdata->sink);
-
-    /* If another thread already prepared some data we received
-     * the data over the asyncmsgq, hence let's first process
-     * it. */
-    while (pa_asyncmsgq_process_one(o->inq) > 0)
-        ;
-
-    /* Check whether we're now readable */
-    if (pa_memblockq_is_readable(o->memblockq))
-        return;
-
-    /* OK, we need to prepare new data, but only if the sink is actually running */
-    if (pa_atomic_load(&o->userdata->thread_info.running))
-        pa_asyncmsgq_send(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_NEED, o, (int64_t) length, NULL);
-}
-
-/* Called from I/O thread context */
-static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
-    struct output *o;
-
-    pa_sink_input_assert_ref(i);
-    pa_assert_se(o = i->userdata);
-
-    /* If necessary, get some new data */
-    request_memblock(o, nbytes);
-
-    /* pa_log("%s q size is %u + %u (%u/%u)", */
-    /*        i->sink->name, */
-    /*        pa_memblockq_get_nblocks(o->memblockq), */
-    /*        pa_memblockq_get_nblocks(i->thread_info.render_memblockq), */
-    /*        pa_memblockq_get_maxrewind(o->memblockq), */
-    /*        pa_memblockq_get_maxrewind(i->thread_info.render_memblockq)); */
-
-    if (pa_memblockq_peek(o->memblockq, chunk) < 0)
-        return -1;
-
-    pa_memblockq_drop(o->memblockq, chunk->length);
-
-    return 0;
-}
-
-/* Called from I/O thread context */
-static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
-    struct output *o;
-
-    pa_sink_input_assert_ref(i);
-    pa_assert_se(o = i->userdata);
-
-    pa_memblockq_rewind(o->memblockq, nbytes);
-}
-
-/* Called from I/O thread context */
-static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
-    struct output *o;
-
-    pa_sink_input_assert_ref(i);
-    pa_assert_se(o = i->userdata);
-
-    pa_memblockq_set_maxrewind(o->memblockq, nbytes);
-}
-
-/* Called from I/O thread context */
-static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) {
-    struct output *o;
-
-    pa_sink_input_assert_ref(i);
-    pa_assert_se(o = i->userdata);
-
-    if (pa_atomic_load(&o->max_request) == (int) nbytes)
-        return;
-
-    pa_atomic_store(&o->max_request, (int) nbytes);
-    pa_asyncmsgq_post(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_UPDATE_MAX_REQUEST, NULL, 0, NULL, NULL);
-}
-
-/* Called from thread context */
-static void sink_input_update_sink_requested_latency_cb(pa_sink_input *i) {
-    struct output *o;
-    pa_usec_t c;
-
-    pa_assert(i);
-
-    pa_sink_input_assert_ref(i);
-    pa_assert_se(o = i->userdata);
-
-    c = pa_sink_get_requested_latency_within_thread(i->sink);
-
-    if (c == (pa_usec_t) -1)
-        c = i->sink->thread_info.max_latency;
-
-    if (pa_atomic_load(&o->requested_latency) == (int) c)
-        return;
-
-    pa_atomic_store(&o->requested_latency, (int) c);
-    pa_asyncmsgq_post(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_UPDATE_REQUESTED_LATENCY, NULL, 0, NULL, NULL);
-}
-
-/* Called from I/O thread context */
-static void sink_input_attach_cb(pa_sink_input *i) {
-    struct output *o;
-    pa_usec_t c;
-
-    pa_sink_input_assert_ref(i);
-    pa_assert_se(o = i->userdata);
-
-    /* Set up the queue from the sink thread to us */
-    pa_assert(!o->inq_rtpoll_item_read && !o->outq_rtpoll_item_write);
-
-    o->inq_rtpoll_item_read = pa_rtpoll_item_new_asyncmsgq_read(
-            i->sink->thread_info.rtpoll,
-            PA_RTPOLL_LATE,  /* This one is not that important, since we check for data in _peek() anyway. */
-            o->inq);
-
-    o->outq_rtpoll_item_write = pa_rtpoll_item_new_asyncmsgq_write(
-            i->sink->thread_info.rtpoll,
-            PA_RTPOLL_EARLY,
-            o->outq);
-
-    pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
-
-    pa_atomic_store(&o->max_request, (int) pa_sink_input_get_max_request(i));
-
-    c = pa_sink_get_requested_latency_within_thread(i->sink);
-    pa_atomic_store(&o->requested_latency, (int) (c == (pa_usec_t) -1 ? 0 : c));
-
-    pa_asyncmsgq_post(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_UPDATE_MAX_REQUEST, NULL, 0, NULL, NULL);
-    pa_asyncmsgq_post(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_UPDATE_REQUESTED_LATENCY, NULL, 0, NULL, NULL);
-}
-
-/* Called from I/O thread context */
-static void sink_input_detach_cb(pa_sink_input *i) {
-    struct output *o;
-
-    pa_sink_input_assert_ref(i);
-    pa_assert_se(o = i->userdata);
-
-    if (o->inq_rtpoll_item_read) {
-        pa_rtpoll_item_free(o->inq_rtpoll_item_read);
-        o->inq_rtpoll_item_read = NULL;
-    }
-
-    if (o->outq_rtpoll_item_write) {
-        pa_rtpoll_item_free(o->outq_rtpoll_item_write);
-        o->outq_rtpoll_item_write = NULL;
-    }
-}
-
-/* Called from main context */
-static void sink_input_kill_cb(pa_sink_input *i) {
-    struct output *o;
-
-    pa_sink_input_assert_ref(i);
-    pa_assert_se(o = i->userdata);
-
-    pa_module_unload_request(o->userdata->module, TRUE);
-    output_free(o);
-}
-
-/* Called from thread context */
-static int sink_input_process_msg(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
-    struct output *o = PA_SINK_INPUT(obj)->userdata;
-
-    switch (code) {
-
-        case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
-             pa_usec_t *r = data;
-
-            *r = pa_bytes_to_usec(pa_memblockq_get_length(o->memblockq), &o->sink_input->sample_spec);
-
-            /* Fall through, the default handler will add in the extra
-             * latency added by the resampler */
-            break;
-        }
-
-        case SINK_INPUT_MESSAGE_POST:
-
-            if (PA_SINK_IS_OPENED(o->sink_input->sink->thread_info.state))
-                pa_memblockq_push_align(o->memblockq, chunk);
-            else
-                pa_memblockq_flush_write(o->memblockq, TRUE);
-
-            return 0;
-    }
-
-    return pa_sink_input_process_msg(obj, code, data, offset, chunk);
-}
-
-/* Called from main context */
-static void suspend(struct userdata *u) {
-    struct output *o;
-    uint32_t idx;
-
-    pa_assert(u);
-
-    /* Let's suspend by unlinking all streams */
-    PA_IDXSET_FOREACH(o, u->outputs, idx)
-        output_disable(o);
-
-    pa_log_info("Device suspended...");
-}
-
-/* Called from main context */
-static void unsuspend(struct userdata *u) {
-    struct output *o;
-    uint32_t idx;
-
-    pa_assert(u);
-
-    /* Let's resume */
-    PA_IDXSET_FOREACH(o, u->outputs, idx)
-        output_enable(o);
-
-    pa_log_info("Resumed successfully...");
-}
-
-/* Called from main context */
-static int sink_set_state(pa_sink *sink, pa_sink_state_t state) {
-    struct userdata *u;
-
-    pa_sink_assert_ref(sink);
-    pa_assert_se(u = sink->userdata);
-
-    /* Please note that in contrast to the ALSA modules we call
-     * suspend/unsuspend from main context here! */
-
-    switch (state) {
-        case PA_SINK_SUSPENDED:
-            pa_assert(PA_SINK_IS_OPENED(pa_sink_get_state(u->sink)));
-
-            suspend(u);
-            break;
-
-        case PA_SINK_IDLE:
-        case PA_SINK_RUNNING:
-
-            if (pa_sink_get_state(u->sink) == PA_SINK_SUSPENDED)
-                unsuspend(u);
-
-            break;
-
-        case PA_SINK_UNLINKED:
-        case PA_SINK_INIT:
-        case PA_SINK_INVALID_STATE:
-            ;
-    }
-
-    return 0;
-}
-
-/* Called from IO context */
-static void update_max_request(struct userdata *u) {
-    size_t max_request = 0;
-    struct output *o;
-
-    pa_assert(u);
-    pa_sink_assert_io_context(u->sink);
-
-    /* Collects the max_request values of all streams and sets the
-     * largest one locally */
-
-    PA_LLIST_FOREACH(o, u->thread_info.active_outputs) {
-        size_t mr = (size_t) pa_atomic_load(&o->max_request);
-
-        if (mr > max_request)
-            max_request = mr;
-    }
-
-    if (max_request <= 0)
-        max_request = pa_usec_to_bytes(u->block_usec, &u->sink->sample_spec);
-
-    pa_sink_set_max_request_within_thread(u->sink, max_request);
-}
-
-/* Called from IO context */
-static void update_fixed_latency(struct userdata *u) {
-    pa_usec_t fixed_latency = 0;
-    struct output *o;
-
-    pa_assert(u);
-    pa_sink_assert_io_context(u->sink);
-
-    /* Collects the requested_latency values of all streams and sets
-     * the largest one as fixed_latency locally */
-
-    PA_LLIST_FOREACH(o, u->thread_info.active_outputs) {
-        pa_usec_t rl = (size_t) pa_atomic_load(&o->requested_latency);
-
-        if (rl > fixed_latency)
-            fixed_latency = rl;
-    }
-
-    if (fixed_latency <= 0)
-        fixed_latency = u->block_usec;
-
-    pa_sink_set_fixed_latency_within_thread(u->sink, fixed_latency);
-}
-
-/* Called from thread context of the io thread */
-static void output_add_within_thread(struct output *o) {
-    pa_assert(o);
-    pa_sink_assert_io_context(o->sink);
-
-    PA_LLIST_PREPEND(struct output, o->userdata->thread_info.active_outputs, o);
-
-    pa_assert(!o->outq_rtpoll_item_read && !o->inq_rtpoll_item_write);
-
-    o->outq_rtpoll_item_read = pa_rtpoll_item_new_asyncmsgq_read(
-            o->userdata->rtpoll,
-            PA_RTPOLL_EARLY-1,  /* This item is very important */
-            o->outq);
-    o->inq_rtpoll_item_write = pa_rtpoll_item_new_asyncmsgq_write(
-            o->userdata->rtpoll,
-            PA_RTPOLL_EARLY,
-            o->inq);
-}
-
-/* Called from thread context of the io thread */
-static void output_remove_within_thread(struct output *o) {
-    pa_assert(o);
-    pa_sink_assert_io_context(o->sink);
-
-    PA_LLIST_REMOVE(struct output, o->userdata->thread_info.active_outputs, o);
-
-    if (o->outq_rtpoll_item_read) {
-        pa_rtpoll_item_free(o->outq_rtpoll_item_read);
-        o->outq_rtpoll_item_read = NULL;
-    }
-
-    if (o->inq_rtpoll_item_write) {
-        pa_rtpoll_item_free(o->inq_rtpoll_item_write);
-        o->inq_rtpoll_item_write = NULL;
-    }
-}
-
-/* Called from thread context of the io thread */
-static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
-    struct userdata *u = PA_SINK(o)->userdata;
-
-    switch (code) {
-
-        case PA_SINK_MESSAGE_SET_STATE:
-            pa_atomic_store(&u->thread_info.running, PA_PTR_TO_UINT(data) == PA_SINK_RUNNING);
-
-            if (PA_PTR_TO_UINT(data) == PA_SINK_SUSPENDED)
-                pa_smoother_pause(u->thread_info.smoother, pa_rtclock_now());
-            else
-                pa_smoother_resume(u->thread_info.smoother, pa_rtclock_now(), TRUE);
-
-            break;
-
-        case PA_SINK_MESSAGE_GET_LATENCY: {
-            pa_usec_t x, y, c, *delay = data;
-
-            x = pa_rtclock_now();
-            y = pa_smoother_get(u->thread_info.smoother, x);
-
-            c = pa_bytes_to_usec(u->thread_info.counter, &u->sink->sample_spec);
-
-            if (y < c)
-                *delay = c - y;
-            else
-                *delay = 0;
-
-            return 0;
-        }
-
-        case SINK_MESSAGE_ADD_OUTPUT:
-            output_add_within_thread(data);
-            update_max_request(u);
-            update_fixed_latency(u);
-            return 0;
-
-        case SINK_MESSAGE_REMOVE_OUTPUT:
-            output_remove_within_thread(data);
-            update_max_request(u);
-            update_fixed_latency(u);
-            return 0;
-
-        case SINK_MESSAGE_NEED:
-            render_memblock(u, (struct output*) data, (size_t) offset);
-            return 0;
-
-        case SINK_MESSAGE_UPDATE_LATENCY: {
-            pa_usec_t x, y, latency = (pa_usec_t) offset;
-
-            x = pa_rtclock_now();
-            y = pa_bytes_to_usec(u->thread_info.counter, &u->sink->sample_spec);
-
-            if (y > latency)
-                y -= latency;
-            else
-                y = 0;
-
-            pa_smoother_put(u->thread_info.smoother, x, y);
-            return 0;
-        }
-
-        case SINK_MESSAGE_UPDATE_MAX_REQUEST:
-            update_max_request(u);
-            break;
-
-        case SINK_MESSAGE_UPDATE_REQUESTED_LATENCY:
-            update_fixed_latency(u);
-            break;
-}
-
-    return pa_sink_process_msg(o, code, data, offset, chunk);
-}
-
-static void update_description(struct userdata *u) {
-    pa_bool_t first = TRUE;
-    char *t;
-    struct output *o;
-    uint32_t idx;
-
-    pa_assert(u);
-
-    if (!u->auto_desc)
-        return;
-
-    if (pa_idxset_isempty(u->outputs)) {
-        pa_sink_set_description(u->sink, "Simultaneous output");
-        return;
-    }
-
-    t = pa_xstrdup("Simultaneous output to");
-
-    PA_IDXSET_FOREACH(o, u->outputs, idx) {
-        char *e;
-
-        if (first) {
-            e = pa_sprintf_malloc("%s %s", t, pa_strnull(pa_proplist_gets(o->sink->proplist, PA_PROP_DEVICE_DESCRIPTION)));
-            first = FALSE;
-        } else
-            e = pa_sprintf_malloc("%s, %s", t, pa_strnull(pa_proplist_gets(o->sink->proplist, PA_PROP_DEVICE_DESCRIPTION)));
-
-        pa_xfree(t);
-        t = e;
-    }
-
-    pa_sink_set_description(u->sink, t);
-    pa_xfree(t);
-}
-
-static int output_create_sink_input(struct output *o) {
-    pa_sink_input_new_data data;
-
-    pa_assert(o);
-
-    if (o->sink_input)
-        return 0;
-
-    pa_sink_input_new_data_init(&data);
-    data.sink = o->sink;
-    data.driver = __FILE__;
-    pa_proplist_setf(data.proplist, PA_PROP_MEDIA_NAME, "Simultaneous output on %s", pa_strnull(pa_proplist_gets(o->sink->proplist, PA_PROP_DEVICE_DESCRIPTION)));
-    pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, "filter");
-    pa_sink_input_new_data_set_sample_spec(&data, &o->userdata->sink->sample_spec);
-    pa_sink_input_new_data_set_channel_map(&data, &o->userdata->sink->channel_map);
-    data.module = o->userdata->module;
-    data.resample_method = o->userdata->resample_method;
-    data.flags = PA_SINK_INPUT_VARIABLE_RATE|PA_SINK_INPUT_DONT_MOVE|PA_SINK_INPUT_NO_CREATE_ON_SUSPEND;
-
-    pa_sink_input_new(&o->sink_input, o->userdata->core, &data);
-
-    pa_sink_input_new_data_done(&data);
-
-    if (!o->sink_input)
-        return -1;
-
-    o->sink_input->parent.process_msg = sink_input_process_msg;
-    o->sink_input->pop = sink_input_pop_cb;
-    o->sink_input->process_rewind = sink_input_process_rewind_cb;
-    o->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
-    o->sink_input->update_max_request = sink_input_update_max_request_cb;
-    o->sink_input->update_sink_requested_latency = sink_input_update_sink_requested_latency_cb;
-    o->sink_input->attach = sink_input_attach_cb;
-    o->sink_input->detach = sink_input_detach_cb;
-    o->sink_input->kill = sink_input_kill_cb;
-    o->sink_input->userdata = o;
-
-    pa_sink_input_set_requested_latency(o->sink_input, BLOCK_USEC);
-
-    return 0;
-}
-
-/* Called from main context */
-static struct output *output_new(struct userdata *u, pa_sink *sink) {
-    struct output *o;
-
-    pa_assert(u);
-    pa_assert(sink);
-    pa_assert(u->sink);
-
-    o = pa_xnew0(struct output, 1);
-    o->userdata = u;
-    o->inq = pa_asyncmsgq_new(0);
-    o->outq = pa_asyncmsgq_new(0);
-    o->sink = sink;
-    o->memblockq = pa_memblockq_new(
-            0,
-            MEMBLOCKQ_MAXLENGTH,
-            MEMBLOCKQ_MAXLENGTH,
-            pa_frame_size(&u->sink->sample_spec),
-            1,
-            0,
-            0,
-            &u->sink->silence);
-
-    pa_assert_se(pa_idxset_put(u->outputs, o, NULL) == 0);
-    update_description(u);
-
-    return o;
-}
-
-/* Called from main context */
-static void output_free(struct output *o) {
-    pa_assert(o);
-
-    output_disable(o);
-
-    pa_assert_se(pa_idxset_remove_by_data(o->userdata->outputs, o, NULL));
-    update_description(o->userdata);
-
-    if (o->inq_rtpoll_item_read)
-        pa_rtpoll_item_free(o->inq_rtpoll_item_read);
-    if (o->inq_rtpoll_item_write)
-        pa_rtpoll_item_free(o->inq_rtpoll_item_write);
-
-    if (o->outq_rtpoll_item_read)
-        pa_rtpoll_item_free(o->outq_rtpoll_item_read);
-    if (o->outq_rtpoll_item_write)
-        pa_rtpoll_item_free(o->outq_rtpoll_item_write);
-
-    if (o->inq)
-        pa_asyncmsgq_unref(o->inq);
-
-    if (o->outq)
-        pa_asyncmsgq_unref(o->outq);
-
-    if (o->memblockq)
-        pa_memblockq_free(o->memblockq);
-
-    pa_xfree(o);
-}
-
-/* Called from main context */
-static void output_enable(struct output *o) {
-    pa_assert(o);
-
-    if (o->sink_input)
-        return;
-
-    /* This might cause the sink to be resumed. The state change hook
-     * of the sink might hence be called from here, which might then
-     * cause us to be called in a loop. Make sure that state changes
-     * for this output don't cause this loop by setting a flag here */
-    o->ignore_state_change = TRUE;
-
-    if (output_create_sink_input(o) >= 0) {
-
-        if (pa_sink_get_state(o->sink) != PA_SINK_INIT) {
-
-            /* First we register the output. That means that the sink
-             * will start to pass data to this output. */
-            pa_asyncmsgq_send(o->userdata->sink->asyncmsgq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_ADD_OUTPUT, o, 0, NULL);
-
-            /* Then we enable the sink input. That means that the sink
-             * is now asked for new data. */
-            pa_sink_input_put(o->sink_input);
-
-        } else
-            /* Hmm the sink is not yet started, do things right here */
-            output_add_within_thread(o);
-    }
-
-    o->ignore_state_change = FALSE;
-}
-
-/* Called from main context */
-static void output_disable(struct output *o) {
-    pa_assert(o);
-
-    if (!o->sink_input)
-        return;
-
-    /* First we disable the sink input. That means that the sink is
-     * not asked for new data anymore  */
-    pa_sink_input_unlink(o->sink_input);
-
-    /* Then we unregister the output. That means that the sink doesn't
-     * pass any further data to this output */
-    pa_asyncmsgq_send(o->userdata->sink->asyncmsgq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_REMOVE_OUTPUT, o, 0, NULL);
-
-    /* Now dellocate the stream */
-    pa_sink_input_unref(o->sink_input);
-    o->sink_input = NULL;
-
-    /* Finally, drop all queued data */
-    pa_memblockq_flush_write(o->memblockq, TRUE);
-    pa_asyncmsgq_flush(o->inq, FALSE);
-    pa_asyncmsgq_flush(o->outq, FALSE);
-}
-
-/* Called from main context */
-static void output_verify(struct output *o) {
-    pa_assert(o);
-
-    if (PA_SINK_IS_OPENED(pa_sink_get_state(o->userdata->sink)))
-        output_enable(o);
-    else
-        output_disable(o);
-}
-
-/* Called from main context */
-static pa_bool_t is_suitable_sink(struct userdata *u, pa_sink *s) {
-    const char *t;
-
-    pa_sink_assert_ref(s);
-
-    if (s == u->sink)
-        return FALSE;
-
-    if (!(s->flags & PA_SINK_HARDWARE))
-        return FALSE;
-
-    if (!(s->flags & PA_SINK_LATENCY))
-        return FALSE;
-
-    if ((t = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_CLASS)))
-        if (!pa_streq(t, "sound"))
-            return FALSE;
-
-    return TRUE;
-}
-
-/* Called from main context */
-static pa_hook_result_t sink_put_hook_cb(pa_core *c, pa_sink *s, struct userdata* u) {
-    struct output *o;
-
-    pa_core_assert_ref(c);
-    pa_sink_assert_ref(s);
-    pa_assert(u);
-    pa_assert(u->automatic);
-
-    if (!is_suitable_sink(u, s))
-        return PA_HOOK_OK;
-
-    pa_log_info("Configuring new sink: %s", s->name);
-    if (!(o = output_new(u, s))) {
-        pa_log("Failed to create sink input on sink '%s'.", s->name);
-        return PA_HOOK_OK;
-    }
-
-    output_verify(o);
-
-    return PA_HOOK_OK;
-}
-
-/* Called from main context */
-static struct output* find_output(struct userdata *u, pa_sink *s) {
-    struct output *o;
-    uint32_t idx;
-
-    pa_assert(u);
-    pa_assert(s);
-
-    if (u->sink == s)
-        return NULL;
-
-    PA_IDXSET_FOREACH(o, u->outputs, idx)
-        if (o->sink == s)
-            return o;
-
-    return NULL;
-}
-
-/* Called from main context */
-static pa_hook_result_t sink_unlink_hook_cb(pa_core *c, pa_sink *s, struct userdata* u) {
-    struct output *o;
-
-    pa_assert(c);
-    pa_sink_assert_ref(s);
-    pa_assert(u);
-
-    if (!(o = find_output(u, s)))
-        return PA_HOOK_OK;
-
-    pa_log_info("Unconfiguring sink: %s", s->name);
-    output_free(o);
-
-    return PA_HOOK_OK;
-}
-
-/* Called from main context */
-static pa_hook_result_t sink_state_changed_hook_cb(pa_core *c, pa_sink *s, struct userdata* u) {
-    struct output *o;
-
-    if (!(o = find_output(u, s)))
-        return PA_HOOK_OK;
-
-    /* This state change might be triggered because we are creating a
-     * stream here, in that case we don't want to create it a second
-     * time here and enter a loop */
-    if (o->ignore_state_change)
-        return PA_HOOK_OK;
-
-    output_verify(o);
-
-    return PA_HOOK_OK;
-}
-
 int pa__init(pa_module*m) {
     struct userdata *u;
-    pa_modargs *ma = NULL;
-    const char *slaves, *rm;
-    int resample_method = PA_RESAMPLER_TRIVIAL;
-    pa_sample_spec ss;
-    pa_channel_map map;
-    struct output *o;
-    uint32_t idx;
-    pa_sink_new_data data;
-    uint32_t adjust_time_sec;
+    pa_module *module;
 
     pa_assert(m);
+    pa_assert_se(m->userdata = u = pa_xnew0(struct userdata, 1));
 
-    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
-        pa_log("failed to parse module arguments");
-        goto fail;
-    }
-
-    if ((rm = pa_modargs_get_value(ma, "resample_method", NULL))) {
-        if ((resample_method = pa_parse_resample_method(rm)) < 0) {
-            pa_log("invalid resample method '%s'", rm);
-            goto fail;
-        }
-    }
-
-    m->userdata = u = pa_xnew0(struct userdata, 1);
-    u->core = m->core;
-    u->module = m;
-    u->rtpoll = pa_rtpoll_new();
-    pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
-    u->resample_method = resample_method;
-    u->outputs = pa_idxset_new(NULL, NULL);
-    u->thread_info.smoother = pa_smoother_new(
-            PA_USEC_PER_SEC,
-            PA_USEC_PER_SEC*2,
-            TRUE,
-            TRUE,
-            10,
-            0,
-            FALSE);
-
-    adjust_time_sec = DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC;
-    if (pa_modargs_get_value_u32(ma, "adjust_time", &adjust_time_sec) < 0) {
-        pa_log("Failed to parse adjust_time value");
-        goto fail;
-    }
-
-    if (adjust_time_sec != DEFAULT_ADJUST_TIME_USEC / PA_USEC_PER_SEC)
-        u->adjust_time = adjust_time_sec * PA_USEC_PER_SEC;
-    else
-        u->adjust_time = DEFAULT_ADJUST_TIME_USEC;
-
-    slaves = pa_modargs_get_value(ma, "slaves", NULL);
-    u->automatic = !slaves;
-
-    ss = m->core->default_sample_spec;
-    map = m->core->default_channel_map;
-
-    /* Check the specified slave sinks for sample_spec and channel_map to use for the combined sink */
-    if (!u->automatic) {
-        const char*split_state = NULL;
-        char *n = NULL;
-        pa_sample_spec slaves_spec;
-        pa_channel_map slaves_map;
-        pa_bool_t is_first_slave = TRUE;
-
-        pa_sample_spec_init(&slaves_spec);
-
-        while ((n = pa_split(slaves, ",", &split_state))) {
-            pa_sink *slave_sink;
-
-            if (!(slave_sink = pa_namereg_get(m->core, n, PA_NAMEREG_SINK))) {
-                pa_log("Invalid slave sink '%s'", n);
-                pa_xfree(n);
-                goto fail;
-            }
-
-            pa_xfree(n);
-
-            if (is_first_slave) {
-                slaves_spec = slave_sink->sample_spec;
-                slaves_map = slave_sink->channel_map;
-                is_first_slave = FALSE;
-            } else {
-                if (slaves_spec.format != slave_sink->sample_spec.format)
-                    slaves_spec.format = PA_SAMPLE_INVALID;
-
-                if (slaves_spec.rate < slave_sink->sample_spec.rate)
-                    slaves_spec.rate = slave_sink->sample_spec.rate;
-
-                if (!pa_channel_map_equal(&slaves_map, &slave_sink->channel_map))
-                    slaves_spec.channels = 0;
-            }
-        }
-
-        if (!is_first_slave) {
-            if (slaves_spec.format != PA_SAMPLE_INVALID)
-                ss.format = slaves_spec.format;
+    pa_log_warn("We will now load module-combine-sink. Please make sure to remove module-combine from your configuration.");
 
-            ss.rate = slaves_spec.rate;
+    module = pa_module_load(m->core, "module-combine-sink", m->argument);
+    u->module_index = module ? module->index : PA_INVALID_INDEX;
 
-            if (slaves_spec.channels > 0) {
-                map = slaves_map;
-                ss.channels = slaves_map.channels;
-            }
-        }
-    }
-
-    if ((pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0)) {
-        pa_log("Invalid sample specification.");
-        goto fail;
-    }
-
-    pa_sink_new_data_init(&data);
-    data.namereg_fail = FALSE;
-    data.driver = __FILE__;
-    data.module = m;
-    pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME));
-    pa_sink_new_data_set_sample_spec(&data, &ss);
-    pa_sink_new_data_set_channel_map(&data, &map);
-    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "filter");
-
-    if (slaves)
-        pa_proplist_sets(data.proplist, "combine.slaves", slaves);
-
-    if (pa_modargs_get_proplist(ma, "sink_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
-        pa_log("Invalid properties");
-        pa_sink_new_data_done(&data);
-        goto fail;
-    }
-
-    /* Check proplist for a description & fill in a default value if not */
-    u->auto_desc = FALSE;
-    if (NULL == pa_proplist_gets(data.proplist, PA_PROP_DEVICE_DESCRIPTION)) {
-        u->auto_desc = TRUE;
-        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Simultaneous Output");
-    }
-
-    u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY);
-    pa_sink_new_data_done(&data);
-
-    if (!u->sink) {
-        pa_log("Failed to create sink");
-        goto fail;
-    }
-
-    u->sink->parent.process_msg = sink_process_msg;
-    u->sink->set_state = sink_set_state;
-    u->sink->userdata = u;
-
-    pa_sink_set_rtpoll(u->sink, u->rtpoll);
-    pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
-
-    u->block_usec = BLOCK_USEC;
-    pa_sink_set_max_request(u->sink, pa_usec_to_bytes(u->block_usec, &u->sink->sample_spec));
-
-    if (!u->automatic) {
-        const char*split_state;
-        char *n = NULL;
-        pa_assert(slaves);
-
-        /* The slaves have been specified manually */
-
-        split_state = NULL;
-        while ((n = pa_split(slaves, ",", &split_state))) {
-            pa_sink *slave_sink;
-
-            if (!(slave_sink = pa_namereg_get(m->core, n, PA_NAMEREG_SINK)) || slave_sink == u->sink) {
-                pa_log("Invalid slave sink '%s'", n);
-                pa_xfree(n);
-                goto fail;
-            }
-
-            pa_xfree(n);
-
-            if (!output_new(u, slave_sink)) {
-                pa_log("Failed to create slave sink input on sink '%s'.", slave_sink->name);
-                goto fail;
-            }
-        }
-
-        if (pa_idxset_size(u->outputs) <= 1)
-            pa_log_warn("No slave sinks specified.");
-
-        u->sink_put_slot = NULL;
-
-    } else {
-        pa_sink *s;
-
-        /* We're in automatic mode, we add every sink that matches our needs  */
-
-        PA_IDXSET_FOREACH(s, m->core->sinks, idx) {
-
-            if (!is_suitable_sink(u, s))
-                continue;
-
-            if (!output_new(u, s)) {
-                pa_log("Failed to create sink input on sink '%s'.", s->name);
-                goto fail;
-            }
-        }
-
-        u->sink_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE, (pa_hook_cb_t) sink_put_hook_cb, u);
-    }
-
-    u->sink_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) sink_unlink_hook_cb, u);
-    u->sink_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) sink_state_changed_hook_cb, u);
-
-    if (!(u->thread = pa_thread_new(thread_func, u))) {
-        pa_log("Failed to create thread.");
-        goto fail;
-    }
-
-    /* Activate the sink and the sink inputs */
-    pa_sink_put(u->sink);
-
-    PA_IDXSET_FOREACH(o, u->outputs, idx)
-        output_verify(o);
-
-    if (u->adjust_time > 0)
-        u->time_event = pa_core_rttime_new(m->core, pa_rtclock_now() + u->adjust_time, time_callback, u);
-
-    pa_modargs_free(ma);
-
-    return 0;
-
-fail:
-
-    if (ma)
-        pa_modargs_free(ma);
-
-    pa__done(m);
-
-    return -1;
+    return module ? 0 : -1;
 }
 
+
 void pa__done(pa_module*m) {
     struct userdata *u;
-    struct output *o;
 
     pa_assert(m);
+    pa_assert(m->userdata);
 
-    if (!(u = m->userdata))
-        return;
-
-    if (u->sink_put_slot)
-        pa_hook_slot_free(u->sink_put_slot);
-
-    if (u->sink_unlink_slot)
-        pa_hook_slot_free(u->sink_unlink_slot);
-
-    if (u->sink_state_changed_slot)
-        pa_hook_slot_free(u->sink_state_changed_slot);
-
-    if (u->outputs) {
-        while ((o = pa_idxset_first(u->outputs, NULL)))
-            output_free(o);
-
-        pa_idxset_free(u->outputs, NULL, NULL);
-    }
-
-    if (u->sink)
-        pa_sink_unlink(u->sink);
-
-    if (u->thread) {
-        pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
-        pa_thread_free(u->thread);
-    }
-
-    pa_thread_mq_done(&u->thread_mq);
-
-    if (u->sink)
-        pa_sink_unref(u->sink);
-
-    if (u->rtpoll)
-        pa_rtpoll_free(u->rtpoll);
-
-    if (u->time_event)
-        u->core->mainloop->time_free(u->time_event);
+    u = m->userdata;
 
-    if (u->thread_info.smoother)
-        pa_smoother_free(u->thread_info.smoother);
+    if (u && PA_INVALID_INDEX != u->module_index)
+        pa_module_unload_by_index(m->core, u->module_index, TRUE);
 
     pa_xfree(u);
 }
diff --git a/src/modules/module-console-kit-symdef.h b/src/modules/module-console-kit-symdef.h
deleted file mode 100644 (file)
index cba6505..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleconsolekitsymdeffoo
-#define foomoduleconsolekitsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_console_kit_LTX_pa__init
-#define pa__done module_console_kit_LTX_pa__done
-#define pa__get_author module_console_kit_LTX_pa__get_author
-#define pa__get_description module_console_kit_LTX_pa__get_description
-#define pa__get_usage module_console_kit_LTX_pa__get_usage
-#define pa__get_version module_console_kit_LTX_pa__get_version
-#define pa__get_deprecated module_console_kit_LTX_pa__get_deprecated
-#define pa__load_once module_console_kit_LTX_pa__load_once
-#define pa__get_n_used module_console_kit_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 103f5c4..af1e02b 100644 (file)
 
 #include <stdio.h>
 #include <unistd.h>
-#include <string.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <sys/types.h>
-#include <sys/stat.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/timeval.h>
 
-#include <pulsecore/core-error.h>
 #include <pulsecore/module.h>
 #include <pulsecore/log.h>
 #include <pulsecore/hashmap.h>
 #include <pulsecore/idxset.h>
-#include <pulsecore/core-util.h>
-#include <pulsecore/namereg.h>
-#include <pulsecore/core-scache.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/dbus-shared.h>
 
@@ -67,6 +60,7 @@ struct userdata {
     pa_core *core;
     pa_dbus_connection *connection;
     pa_hashmap *sessions;
+    pa_bool_t filter_added;
 };
 
 static void add_session(struct userdata *u, const char *id) {
@@ -76,7 +70,7 @@ static void add_session(struct userdata *u, const char *id) {
     struct session *session;
     pa_client_new_data data;
 
-    dbus_error_init (&error);
+    dbus_error_init(&error);
 
     if (pa_hashmap_get(u->sessions, id)) {
         pa_log_warn("Duplicate session %s, ignoring.", id);
@@ -286,6 +280,11 @@ int pa__init(pa_module*m) {
 
     dbus_error_init(&error);
 
+    /* If systemd's logind service is running, we shouldn't watch ConsoleKit
+     * but login */
+    if (access("/run/systemd/seats/", F_OK) >= 0)
+        return 0;
+
     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
         pa_log("Failed to parse module arguments");
         goto fail;
@@ -300,7 +299,7 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
-    m->userdata = u = pa_xnew(struct userdata, 1);
+    m->userdata = u = pa_xnew0(struct userdata, 1);
     u->core = m->core;
     u->module = m;
     u->connection = connection;
@@ -311,6 +310,8 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
+    u->filter_added = TRUE;
+
     if (pa_dbus_add_matches(
                 pa_dbus_connection_get(connection), &error,
                 "type='signal',sender='org.freedesktop.ConsoleKit',interface='org.freedesktop.ConsoleKit.Seat',member='SessionAdded'",
@@ -339,19 +340,14 @@ fail:
 
 void pa__done(pa_module *m) {
     struct userdata *u;
-    struct session *session;
 
     pa_assert(m);
 
     if (!(u = m->userdata))
         return;
 
-    if (u->sessions) {
-        while ((session = pa_hashmap_steal_first(u->sessions)))
-            free_session(session);
-
-        pa_hashmap_free(u->sessions, NULL, NULL);
-    }
+    if (u->sessions)
+        pa_hashmap_free(u->sessions, (pa_free_cb_t) free_session);
 
     if (u->connection) {
         pa_dbus_remove_matches(
@@ -359,7 +355,9 @@ void pa__done(pa_module *m) {
                 "type='signal',sender='org.freedesktop.ConsoleKit',interface='org.freedesktop.ConsoleKit.Seat',member='SessionAdded'",
                 "type='signal',sender='org.freedesktop.ConsoleKit',interface='org.freedesktop.ConsoleKit.Seat',member='SessionRemoved'", NULL);
 
-        dbus_connection_remove_filter(pa_dbus_connection_get(u->connection), filter_cb, u);
+        if (u->filter_added)
+            dbus_connection_remove_filter(pa_dbus_connection_get(u->connection), filter_cb, u);
+
         pa_dbus_connection_unref(u->connection);
     }
 
diff --git a/src/modules/module-cork-music-on-phone-symdef.h b/src/modules/module-cork-music-on-phone-symdef.h
deleted file mode 100644 (file)
index a5c142f..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulecorkmusiconphonesymdeffoo
-#define foomodulecorkmusiconphonesymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_cork_music_on_phone_LTX_pa__init
-#define pa__done module_cork_music_on_phone_LTX_pa__done
-#define pa__get_author module_cork_music_on_phone_LTX_pa__get_author
-#define pa__get_description module_cork_music_on_phone_LTX_pa__get_description
-#define pa__get_usage module_cork_music_on_phone_LTX_pa__get_usage
-#define pa__get_version module_cork_music_on_phone_LTX_pa__get_version
-#define pa__get_deprecated module_cork_music_on_phone_LTX_pa__get_deprecated
-#define pa__load_once module_cork_music_on_phone_LTX_pa__load_once
-#define pa__get_n_used module_cork_music_on_phone_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
diff --git a/src/modules/module-default-device-restore-symdef.h b/src/modules/module-default-device-restore-symdef.h
deleted file mode 100644 (file)
index d78355c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduledefaultdevicerestoresymdeffoo
-#define foomoduledefaultdevicerestoresymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_default_device_restore_LTX_pa__init
-#define pa__done module_default_device_restore_LTX_pa__done
-#define pa__get_author module_default_device_restore_LTX_pa__get_author
-#define pa__get_description module_default_device_restore_LTX_pa__get_description
-#define pa__get_usage module_default_device_restore_LTX_pa__get_usage
-#define pa__get_version module_default_device_restore_LTX_pa__get_version
-#define pa__get_deprecated module_default_device_restore_LTX_pa__get_deprecated
-#define pa__load_once module_default_device_restore_LTX_pa__load_once
-#define pa__get_n_used module_default_device_restore_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 27ae60e..73a4c48 100644 (file)
@@ -28,7 +28,7 @@
 
 #include <pulse/rtclock.h>
 #include <pulse/timeval.h>
-#include <pulse/util.h>
+#include <pulse/xmalloc.h>
 
 #include <pulsecore/core-util.h>
 #include <pulsecore/module.h>
@@ -60,12 +60,12 @@ static void load(struct userdata *u) {
 
     if (u->core->default_sink)
         pa_log_info("Manually configured default sink, not overwriting.");
-    else if ((f = fopen(u->sink_filename, "r"))) {
+    else if ((f = pa_fopen_cloexec(u->sink_filename, "r"))) {
         char ln[256] = "";
         pa_sink *s;
 
-        (void) fgets(ln, sizeof(ln)-1, f);
-        pa_strip_nl(ln);
+        if (fgets(ln, sizeof(ln)-1, f))
+            pa_strip_nl(ln);
         fclose(f);
 
         if (!ln[0])
@@ -74,19 +74,19 @@ static void load(struct userdata *u) {
             pa_namereg_set_default_sink(u->core, s);
             pa_log_info("Restored default sink '%s'.", ln);
         } else
-            pa_log_info("Saved default sink '%s' not existant, not restoring default sink setting.", ln);
+            pa_log_info("Saved default sink '%s' not existent, not restoring default sink setting.", ln);
 
     } else if (errno != ENOENT)
         pa_log("Failed to load default sink: %s", pa_cstrerror(errno));
 
     if (u->core->default_source)
         pa_log_info("Manually configured default source, not overwriting.");
-    else if ((f = fopen(u->source_filename, "r"))) {
+    else if ((f = pa_fopen_cloexec(u->source_filename, "r"))) {
         char ln[256] = "";
         pa_source *s;
 
-        (void) fgets(ln, sizeof(ln)-1, f);
-        pa_strip_nl(ln);
+        if (fgets(ln, sizeof(ln)-1, f))
+            pa_strip_nl(ln);
         fclose(f);
 
         if (!ln[0])
@@ -95,7 +95,7 @@ static void load(struct userdata *u) {
             pa_namereg_set_default_source(u->core, s);
             pa_log_info("Restored default source '%s'.", ln);
         } else
-            pa_log_info("Saved default source '%s' not existant, not restoring default source setting.", ln);
+            pa_log_info("Saved default source '%s' not existent, not restoring default source setting.", ln);
 
     } else if (errno != ENOENT)
             pa_log("Failed to load default sink: %s", pa_cstrerror(errno));
@@ -108,7 +108,7 @@ static void save(struct userdata *u) {
         return;
 
     if (u->sink_filename) {
-        if ((f = fopen(u->sink_filename, "w"))) {
+        if ((f = pa_fopen_cloexec(u->sink_filename, "w"))) {
             pa_sink *s = pa_namereg_get_default_sink(u->core);
             fprintf(f, "%s\n", s ? s->name : "");
             fclose(f);
@@ -117,7 +117,7 @@ static void save(struct userdata *u) {
     }
 
     if (u->source_filename) {
-        if ((f = fopen(u->source_filename, "w"))) {
+        if ((f = pa_fopen_cloexec(u->source_filename, "w"))) {
             pa_source *s = pa_namereg_get_default_source(u->core);
             fprintf(f, "%s\n", s ? s->name : "");
             fclose(f);
diff --git a/src/modules/module-detect-symdef.h b/src/modules/module-detect-symdef.h
deleted file mode 100644 (file)
index ad8c08f..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduledetectsymdeffoo
-#define foomoduledetectsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_detect_LTX_pa__init
-#define pa__done module_detect_LTX_pa__done
-#define pa__get_author module_detect_LTX_pa__get_author
-#define pa__get_description module_detect_LTX_pa__get_description
-#define pa__get_usage module_detect_LTX_pa__get_usage
-#define pa__get_version module_detect_LTX_pa__get_version
-#define pa__get_deprecated module_detect_LTX_pa__get_deprecated
-#define pa__load_once module_detect_LTX_pa__load_once
-#define pa__get_n_used module_detect_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index b1f24e1..a16f7fe 100644 (file)
@@ -34,8 +34,6 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
-#include <pulse/xmalloc.h>
-
 #include <pulsecore/core-error.h>
 #include <pulsecore/module.h>
 #include <pulsecore/modargs.h>
@@ -63,7 +61,7 @@ static int detect_alsa(pa_core *c, int just_one) {
     FILE *f;
     int n = 0, n_sink = 0, n_source = 0;
 
-    if (!(f = fopen("/proc/asound/devices", "r"))) {
+    if (!(f = pa_fopen_cloexec("/proc/asound/devices", "r"))) {
 
         if (errno != ENOENT)
             pa_log_error("open(\"/proc/asound/devices\") failed: %s", pa_cstrerror(errno));
@@ -124,9 +122,9 @@ static int detect_oss(pa_core *c, int just_one) {
     FILE *f;
     int n = 0, b = 0;
 
-    if (!(f = fopen("/dev/sndstat", "r")) &&
-        !(f = fopen("/proc/sndstat", "r")) &&
-        !(f = fopen("/proc/asound/oss/sndstat", "r"))) {
+    if (!(f = pa_fopen_cloexec("/dev/sndstat", "r")) &&
+        !(f = pa_fopen_cloexec("/proc/sndstat", "r")) &&
+        !(f = pa_fopen_cloexec("/proc/asound/oss/sndstat", "r"))) {
 
         if (errno != ENOENT)
             pa_log_error("failed to open OSS sndstat device: %s", pa_cstrerror(errno));
@@ -144,7 +142,7 @@ static int detect_oss(pa_core *c, int just_one) {
         line[strcspn(line, "\r\n")] = 0;
 
         if (!b) {
-             b = strcmp(line, "Audio devices:") == 0 || strcmp(line, "Installed devices:") == 0;
+            b = pa_streq(line, "Audio devices:") || pa_streq(line, "Installed devices:");
             continue;
         }
 
diff --git a/src/modules/module-device-manager-symdef.h b/src/modules/module-device-manager-symdef.h
deleted file mode 100644 (file)
index 70edb51..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduledevicemanagersymdeffoo
-#define foomoduledevicemanagersymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_device_manager_LTX_pa__init
-#define pa__done module_device_manager_LTX_pa__done
-#define pa__get_author module_device_manager_LTX_pa__get_author
-#define pa__get_description module_device_manager_LTX_pa__get_description
-#define pa__get_usage module_device_manager_LTX_pa__get_usage
-#define pa__get_version module_device_manager_LTX_pa__get_version
-#define pa__get_deprecated module_device_manager_LTX_pa__get_deprecated
-#define pa__load_once module_device_manager_LTX_pa__load_once
-#define pa__get_n_used module_device_manager_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 3991043..5db5550 100644 (file)
 #include <sys/types.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <ctype.h>
 
+#include <pulse/gccmacro.h>
 #include <pulse/xmalloc.h>
-#include <pulse/volume.h>
 #include <pulse/timeval.h>
-#include <pulse/util.h>
 #include <pulse/rtclock.h>
 
 #include <pulsecore/core-error.h>
@@ -51,6 +49,7 @@
 #include <pulsecore/pstream.h>
 #include <pulsecore/pstream-util.h>
 #include <pulsecore/database.h>
+#include <pulsecore/tagstruct.h>
 
 #include "module-device-manager-symdef.h"
 
@@ -84,6 +83,7 @@ enum {
     ROLE_ANIMATION,
     ROLE_PRODUCTION,
     ROLE_A11Y,
+    ROLE_MAX
 };
 
 typedef uint32_t role_indexes_t[NUM_ROLES];
@@ -132,11 +132,11 @@ struct userdata {
 
 struct entry {
     uint8_t version;
-    char description[PA_NAME_MAX];
+    char *description;
     pa_bool_t user_set_description;
-    char icon[PA_NAME_MAX];
+    char *icon;
     role_indexes_t priority;
-} PA_GCC_PACKED;
+};
 
 enum {
     SUBCOMMAND_TEST,
@@ -150,11 +150,140 @@ enum {
 };
 
 
-static struct entry* read_entry(struct userdata *u, const char *name) {
+/* Forward declarations */
+#ifdef DUMP_DATABASE
+static void dump_database(struct userdata *);
+#endif
+static void notify_subscribers(struct userdata *);
+
+
+static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
+    struct userdata *u = userdata;
+
+    pa_assert(a);
+    pa_assert(e);
+    pa_assert(u);
+
+    pa_assert(e == u->save_time_event);
+    u->core->mainloop->time_free(u->save_time_event);
+    u->save_time_event = NULL;
+
+    pa_database_sync(u->database);
+    pa_log_info("Synced.");
+
+#ifdef DUMP_DATABASE
+    dump_database(u);
+#endif
+}
+
+static void trigger_save(struct userdata *u) {
+
+    pa_assert(u);
+
+    notify_subscribers(u);
+
+    if (u->save_time_event)
+        return;
+
+    u->save_time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + SAVE_INTERVAL, save_time_callback, u);
+}
+
+static struct entry* entry_new(void) {
+    struct entry *r = pa_xnew0(struct entry, 1);
+    r->version = ENTRY_VERSION;
+    return r;
+}
+
+static void entry_free(struct entry* e) {
+    pa_assert(e);
+
+    pa_xfree(e->description);
+    pa_xfree(e->icon);
+    pa_xfree(e);
+}
+
+static pa_bool_t entry_write(struct userdata *u, const char *name, const struct entry *e) {
+    pa_tagstruct *t;
     pa_datum key, data;
+    pa_bool_t r;
+
+    pa_assert(u);
+    pa_assert(name);
+    pa_assert(e);
+
+    t = pa_tagstruct_new(NULL, 0);
+    pa_tagstruct_putu8(t, e->version);
+    pa_tagstruct_puts(t, e->description);
+    pa_tagstruct_put_boolean(t, e->user_set_description);
+    pa_tagstruct_puts(t, e->icon);
+    for (uint8_t i=0; i<ROLE_MAX; ++i)
+        pa_tagstruct_putu32(t, e->priority[i]);
+
+    key.data = (char *) name;
+    key.size = strlen(name);
+
+    data.data = (void*)pa_tagstruct_data(t, &data.size);
+
+    r = (pa_database_set(u->database, &key, &data, TRUE) == 0);
+
+    pa_tagstruct_free(t);
+
+    return r;
+}
+
+#ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
+
+#define LEGACY_ENTRY_VERSION 1
+static struct entry* legacy_entry_read(struct userdata *u, pa_datum *data) {
+    struct legacy_entry {
+        uint8_t version;
+        char description[PA_NAME_MAX];
+        pa_bool_t user_set_description;
+        char icon[PA_NAME_MAX];
+        role_indexes_t priority;
+    } PA_GCC_PACKED;
+    struct legacy_entry *le;
     struct entry *e;
 
     pa_assert(u);
+    pa_assert(data);
+
+    if (data->size != sizeof(struct legacy_entry)) {
+        pa_log_debug("Size does not match.");
+        return NULL;
+    }
+
+    le = (struct legacy_entry*)data->data;
+
+    if (le->version != LEGACY_ENTRY_VERSION) {
+        pa_log_debug("Version mismatch.");
+        return NULL;
+    }
+
+    if (!memchr(le->description, 0, sizeof(le->description))) {
+        pa_log_warn("Description has missing NUL byte.");
+        return NULL;
+    }
+
+    if (!memchr(le->icon, 0, sizeof(le->icon))) {
+        pa_log_warn("Icon has missing NUL byte.");
+        return NULL;
+    }
+
+    e = entry_new();
+    e->description = pa_xstrdup(le->description);
+    e->icon = pa_xstrdup(le->icon);
+    return e;
+}
+#endif
+
+static struct entry* entry_read(struct userdata *u, const char *name) {
+    pa_datum key, data;
+    struct entry *e = NULL;
+    pa_tagstruct *t = NULL;
+    const char *description, *icon;
+
+    pa_assert(u);
     pa_assert(name);
 
     key.data = (char*) name;
@@ -165,31 +294,53 @@ static struct entry* read_entry(struct userdata *u, const char *name) {
     if (!pa_database_get(u->database, &key, &data))
         goto fail;
 
-    if (data.size != sizeof(struct entry)) {
-        pa_log_debug("Database contains entry for device %s of wrong size %lu != %lu. Probably due to upgrade, ignoring.", name, (unsigned long) data.size, (unsigned long) sizeof(struct entry));
-        goto fail;
-    }
+    t = pa_tagstruct_new(data.data, data.size);
+    e = entry_new();
 
-    e = (struct entry*) data.data;
+    if (pa_tagstruct_getu8(t, &e->version) < 0 ||
+        e->version > ENTRY_VERSION ||
+        pa_tagstruct_gets(t, &description) < 0 ||
+        pa_tagstruct_get_boolean(t, &e->user_set_description) < 0 ||
+        pa_tagstruct_gets(t, &icon) < 0) {
 
-    if (e->version != ENTRY_VERSION) {
-        pa_log_debug("Version of database entry for device %s doesn't match our version. Probably due to upgrade, ignoring.", name);
         goto fail;
     }
 
-    if (!memchr(e->description, 0, sizeof(e->description))) {
-        pa_log_warn("Database contains entry for device %s with missing NUL byte in description", name);
-        goto fail;
+    e->description = pa_xstrdup(description);
+    e->icon = pa_xstrdup(icon);
+
+    for (uint8_t i=0; i<ROLE_MAX; ++i) {
+        if (pa_tagstruct_getu32(t, &e->priority[i]) < 0)
+            goto fail;
     }
 
-    if (!memchr(e->icon, 0, sizeof(e->icon))) {
-        pa_log_warn("Database contains entry for device %s with missing NUL byte in icon", name);
+    if (!pa_tagstruct_eof(t))
         goto fail;
-    }
+
+    pa_tagstruct_free(t);
+    pa_datum_free(&data);
 
     return e;
 
 fail:
+    pa_log_debug("Database contains invalid data for key: %s (probably pre-v1.0 data)", name);
+
+    if (e)
+        entry_free(e);
+    if (t)
+        pa_tagstruct_free(t);
+
+#ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
+    pa_log_debug("Attempting to load legacy (pre-v1.0) data for key: %s", name);
+    if ((e = legacy_entry_read(u, &data))) {
+        pa_log_debug("Success. Saving new format for key: %s", name);
+        if (entry_write(u, name, e))
+            trigger_save(u);
+        pa_datum_free(&data);
+        return e;
+    } else
+        pa_log_debug("Unable to load legacy (pre-v1.0) data for key: %s. Ignoring.", name);
+#endif
 
     pa_datum_free(&data);
     return NULL;
@@ -233,14 +384,14 @@ static void dump_database(struct userdata *u) {
 
         name = pa_xstrndup(key.data, key.size);
 
-        if ((e = read_entry(u, name))) {
+        if ((e = entry_read(u, name))) {
             pa_log_debug(" Got entry: %s", name);
             pa_log_debug("  Description: %s", e->description);
             pa_log_debug("  Priorities: None:   %3u, Video: %3u, Music:  %3u, Game: %3u, Event: %3u",
                          e->priority[ROLE_NONE], e->priority[ROLE_VIDEO], e->priority[ROLE_MUSIC], e->priority[ROLE_GAME], e->priority[ROLE_EVENT]);
             pa_log_debug("              Phone:  %3u, Anim:  %3u, Prodtn: %3u, A11y: %3u",
                          e->priority[ROLE_PHONE], e->priority[ROLE_ANIMATION], e->priority[ROLE_PRODUCTION], e->priority[ROLE_A11Y]);
-            pa_xfree(e);
+            entry_free(e);
         }
 
         pa_xfree(name);
@@ -277,25 +428,6 @@ static void dump_database(struct userdata *u) {
 }
 #endif
 
-static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
-    struct userdata *u = userdata;
-
-    pa_assert(a);
-    pa_assert(e);
-    pa_assert(u);
-
-    pa_assert(e == u->save_time_event);
-    u->core->mainloop->time_free(u->save_time_event);
-    u->save_time_event = NULL;
-
-    pa_database_sync(u->database);
-    pa_log_info("Synced.");
-
-#ifdef DUMP_DATABASE
-    dump_database(u);
-#endif
-}
-
 static void notify_subscribers(struct userdata *u) {
 
     pa_native_connection *c;
@@ -303,7 +435,7 @@ static void notify_subscribers(struct userdata *u) {
 
     pa_assert(u);
 
-    for (c = pa_idxset_first(u->subscribed, &idx); c; c = pa_idxset_next(u->subscribed, &idx)) {
+    PA_IDXSET_FOREACH(c, u->subscribed, idx) {
         pa_tagstruct *t;
 
         t = pa_tagstruct_new(NULL, 0);
@@ -317,26 +449,14 @@ static void notify_subscribers(struct userdata *u) {
     }
 }
 
-static void trigger_save(struct userdata *u) {
-
-    pa_assert(u);
-
-    notify_subscribers(u);
-
-    if (u->save_time_event)
-        return;
-
-    u->save_time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + SAVE_INTERVAL, save_time_callback, u);
-}
-
 static pa_bool_t entries_equal(const struct entry *a, const struct entry *b) {
 
     pa_assert(a);
     pa_assert(b);
 
-    if (strncmp(a->description, b->description, sizeof(a->description))
+    if (!pa_streq(a->description, b->description)
         || a->user_set_description != b->user_set_description
-        || strncmp(a->icon, b->icon, sizeof(a->icon)))
+        || !pa_streq(a->icon, b->icon))
         return FALSE;
 
     for (int i=0; i < NUM_ROLES; ++i)
@@ -364,9 +484,11 @@ static inline struct entry *load_or_initialize_entry(struct userdata *u, struct
     pa_assert(name);
     pa_assert(prefix);
 
-    if ((old = read_entry(u, name)))
+    if ((old = entry_read(u, name))) {
         *entry = *old;
-    else {
+        entry->description = pa_xstrdup(old->description);
+        entry->icon = pa_xstrdup(old->icon);
+    } else {
         /* This is a new device, so make sure we write it's priority list correctly */
         role_indexes_t max_priority;
         pa_datum key;
@@ -387,12 +509,12 @@ static inline struct entry *load_or_initialize_entry(struct userdata *u, struct
 
                 name2 = pa_xstrndup(key.data, key.size);
 
-                if ((e = read_entry(u, name2))) {
+                if ((e = entry_read(u, name2))) {
                     for (uint32_t i = 0; i < NUM_ROLES; ++i) {
                         max_priority[i] = PA_MAX(max_priority[i], e->priority[i]);
                     }
 
-                    pa_xfree(e);
+                    entry_free(e);
                 }
 
                 pa_xfree(name2);
@@ -415,7 +537,7 @@ static uint32_t get_role_index(const char* role) {
     pa_assert(role);
 
     for (uint32_t i = ROLE_NONE; i < NUM_ROLES; ++i)
-        if (strcmp(role, role_names[i]) == 0)
+        if (pa_streq(role, role_names[i]))
             return i;
 
     return PA_INVALID_INDEX;
@@ -429,7 +551,7 @@ static void update_highest_priority_device_indexes(struct userdata *u, const cha
     pa_assert(u);
     pa_assert(prefix);
 
-    sink_mode = (strcmp(prefix, "sink:") == 0);
+    sink_mode = pa_streq(prefix, "sink:");
 
     if (sink_mode)
         indexes = &u->preferred_sinks;
@@ -454,9 +576,9 @@ static void update_highest_priority_device_indexes(struct userdata *u, const cha
             struct entry *e;
 
             name = pa_xstrndup(key.data, key.size);
-            device_name = get_name(name, prefix);
+            pa_assert_se(device_name = get_name(name, prefix));
 
-            if ((e = read_entry(u, name))) {
+            if ((e = entry_read(u, name))) {
                 for (uint32_t i = 0; i < NUM_ROLES; ++i) {
                     if (!highest_priority_available[i] || e->priority[i] < highest_priority_available[i]) {
                         /* We've found a device with a higher priority than that we've currently got,
@@ -470,7 +592,7 @@ static void update_highest_priority_device_indexes(struct userdata *u, const cha
                             PA_IDXSET_FOREACH(sink, u->core->sinks, idx) {
                                 if ((pa_sink*) ignore_device == sink)
                                     continue;
-                                if (strcmp(sink->name, device_name) == 0) {
+                                if (pa_streq(sink->name, device_name)) {
                                     found = TRUE;
                                     idx = sink->index; /* Is this needed? */
                                     break;
@@ -482,7 +604,7 @@ static void update_highest_priority_device_indexes(struct userdata *u, const cha
                             PA_IDXSET_FOREACH(source, u->core->sources, idx) {
                                 if ((pa_source*) ignore_device == source)
                                     continue;
-                                if (strcmp(source->name, device_name) == 0) {
+                                if (pa_streq(source->name, device_name)) {
                                     found = TRUE;
                                     idx = source->index; /* Is this needed? */
                                     break;
@@ -497,7 +619,7 @@ static void update_highest_priority_device_indexes(struct userdata *u, const cha
                     }
                 }
 
-                pa_xfree(e);
+                entry_free(e);
             }
 
             pa_xfree(name);
@@ -631,9 +753,8 @@ static pa_hook_result_t route_source_outputs(struct userdata *u, pa_source* igno
 
 static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
     struct userdata *u = userdata;
-    struct entry entry, *old = NULL;
+    struct entry *entry, *old = NULL;
     char *name = NULL;
-    pa_datum key, data;
 
     pa_assert(c);
     pa_assert(u);
@@ -649,9 +770,6 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
         t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE))
         return;
 
-    pa_zero(entry);
-    entry.version = ENTRY_VERSION;
-
     if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK_INPUT) {
         pa_sink_input *si;
 
@@ -682,23 +800,26 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
         if (!(sink = pa_idxset_get_by_index(c->sinks, idx)))
             return;
 
+        entry = entry_new();
         name = pa_sprintf_malloc("sink:%s", sink->name);
 
-        old = load_or_initialize_entry(u, &entry, name, "sink:");
+        old = load_or_initialize_entry(u, entry, name, "sink:");
 
-        if (!entry.user_set_description)
-            pa_strlcpy(entry.description, pa_strnull(pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_DESCRIPTION)), sizeof(entry.description));
-        else if (strncmp(entry.description, pa_strnull(pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_DESCRIPTION)), sizeof(entry.description)) != 0) {
+        if (!entry->user_set_description) {
+            pa_xfree(entry->description);
+            entry->description = pa_xstrdup(pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_DESCRIPTION));
+        } else if (!pa_streq(entry->description, pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_DESCRIPTION))) {
             /* Warning: If two modules fight over the description, this could cause an infinite loop.
                by changing the description here, we retrigger this subscription callback. The only thing stopping us from
                looping is the fact that the string comparison will fail on the second iteration. If another module tries to manage
                the description, this will fail... */
-            pa_sink_set_description(sink, entry.description);
+            pa_sink_set_description(sink, entry->description);
         }
 
-        pa_strlcpy(entry.icon, pa_strnull(pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_ICON_NAME)), sizeof(entry.icon));
+        pa_xfree(entry->icon);
+        entry->icon = pa_xstrdup(pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_ICON_NAME));
 
-    } else  if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE) {
+    } else if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE) {
         pa_source *source;
 
         pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE);
@@ -709,50 +830,51 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
         if (source->monitor_of)
             return;
 
+        entry = entry_new();
         name = pa_sprintf_malloc("source:%s", source->name);
 
-        old = load_or_initialize_entry(u, &entry, name, "source:");
+        old = load_or_initialize_entry(u, entry, name, "source:");
 
-        if (!entry.user_set_description)
-            pa_strlcpy(entry.description, pa_strnull(pa_proplist_gets(source->proplist, PA_PROP_DEVICE_DESCRIPTION)), sizeof(entry.description));
-        else if (strncmp(entry.description, pa_strnull(pa_proplist_gets(source->proplist, PA_PROP_DEVICE_DESCRIPTION)), sizeof(entry.description)) != 0) {
+        if (!entry->user_set_description) {
+            pa_xfree(entry->description);
+            entry->description = pa_xstrdup(pa_proplist_gets(source->proplist, PA_PROP_DEVICE_DESCRIPTION));
+        } else if (!pa_streq(entry->description, pa_proplist_gets(source->proplist, PA_PROP_DEVICE_DESCRIPTION))) {
             /* Warning: If two modules fight over the description, this could cause an infinite loop.
                by changing the description here, we retrigger this subscription callback. The only thing stopping us from
                looping is the fact that the string comparison will fail on the second iteration. If another module tries to manage
                the description, this will fail... */
-            pa_source_set_description(source, entry.description);
+            pa_source_set_description(source, entry->description);
         }
 
-        pa_strlcpy(entry.icon, pa_strnull(pa_proplist_gets(source->proplist, PA_PROP_DEVICE_ICON_NAME)), sizeof(entry.icon));
+        pa_xfree(entry->icon);
+        entry->icon = pa_xstrdup(pa_proplist_gets(source->proplist, PA_PROP_DEVICE_ICON_NAME));
+    } else {
+        pa_assert_not_reached();
     }
 
     pa_assert(name);
 
     if (old) {
 
-        if (entries_equal(old, &entry)) {
-            pa_xfree(old);
+        if (entries_equal(old, entry)) {
+            entry_free(old);
+            entry_free(entry);
             pa_xfree(name);
 
             return;
         }
 
-        pa_xfree(old);
+        entry_free(old);
     }
 
-    key.data = name;
-    key.size = strlen(name);
-
-    data.data = &entry;
-    data.size = sizeof(entry);
-
     pa_log_info("Storing device %s.", name);
 
-    if (pa_database_set(u->database, &key, &data, TRUE) == 0)
+    if (entry_write(u, name, entry))
         trigger_save(u);
     else
         pa_log_warn("Could not save device");;
 
+    entry_free(entry);
     pa_xfree(name);
 }
 
@@ -766,13 +888,13 @@ static pa_hook_result_t sink_new_hook_callback(pa_core *c, pa_sink_new_data *new
 
     name = pa_sprintf_malloc("sink:%s", new_data->name);
 
-    if ((e = read_entry(u, name))) {
-        if (e->user_set_description && strncmp(e->description, pa_proplist_gets(new_data->proplist, PA_PROP_DEVICE_DESCRIPTION), sizeof(e->description)) != 0) {
+    if ((e = entry_read(u, name))) {
+        if (e->user_set_description && !pa_safe_streq(e->description, pa_proplist_gets(new_data->proplist, PA_PROP_DEVICE_DESCRIPTION))) {
             pa_log_info("Restoring description for sink %s.", new_data->name);
             pa_proplist_sets(new_data->proplist, PA_PROP_DEVICE_DESCRIPTION, e->description);
         }
 
-        pa_xfree(e);
+        entry_free(e);
     }
 
     pa_xfree(name);
@@ -790,14 +912,14 @@ static pa_hook_result_t source_new_hook_callback(pa_core *c, pa_source_new_data
 
     name = pa_sprintf_malloc("source:%s", new_data->name);
 
-    if ((e = read_entry(u, name))) {
-        if (e->user_set_description && strncmp(e->description, pa_proplist_gets(new_data->proplist, PA_PROP_DEVICE_DESCRIPTION), sizeof(e->description)) != 0) {
+    if ((e = entry_read(u, name))) {
+        if (e->user_set_description && !pa_safe_streq(e->description, pa_proplist_gets(new_data->proplist, PA_PROP_DEVICE_DESCRIPTION))) {
             /* NB, We cannot detect if we are a monitor here... this could mess things up a bit... */
             pa_log_info("Restoring description for source %s.", new_data->name);
             pa_proplist_sets(new_data->proplist, PA_PROP_DEVICE_DESCRIPTION, e->description);
         }
 
-        pa_xfree(e);
+        entry_free(e);
     }
 
     pa_xfree(name);
@@ -832,8 +954,8 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
                 pa_sink *sink;
 
                 if ((sink = pa_idxset_get_by_index(u->core->sinks, device_index))) {
-                    new_data->sink = sink;
-                    new_data->save_sink = FALSE;
+                    if (!pa_sink_input_new_data_set_sink(new_data, sink, FALSE))
+                        pa_log_debug("Not restoring device for stream because no supported format was found");
                 }
             }
         }
@@ -871,10 +993,9 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou
             if (PA_INVALID_INDEX != device_index) {
                 pa_source *source;
 
-                if ((source = pa_idxset_get_by_index(u->core->sources, device_index))) {
-                    new_data->source = source;
-                    new_data->save_source = FALSE;
-                }
+                if ((source = pa_idxset_get_by_index(u->core->sources, device_index)))
+                    if (!pa_source_output_new_data_set_source(new_data, source, FALSE))
+                        pa_log_debug("Not restoring device for stream because no supported format was found");
             }
         }
     }
@@ -1030,29 +1151,29 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
         name = pa_xstrndup(key.data, key.size);
         pa_datum_free(&key);
 
-        if ((e = read_entry(u, name))) {
+        if ((e = entry_read(u, name))) {
             uint32_t idx;
-            char *devname;
+            char *device_name;
             uint32_t found_index = PA_INVALID_INDEX;
 
-            if ((devname = get_name(name, "sink:"))) {
+            if ((device_name = get_name(name, "sink:"))) {
                 pa_sink* s;
                 PA_IDXSET_FOREACH(s, u->core->sinks, idx) {
-                    if (strcmp(s->name, devname) == 0) {
+                    if (pa_streq(s->name, device_name)) {
                         found_index = s->index;
                         break;
                     }
                 }
-                pa_xfree(devname);
-            } else if ((devname = get_name(name, "source:"))) {
+                pa_xfree(device_name);
+            } else if ((device_name = get_name(name, "source:"))) {
                 pa_source* s;
                 PA_IDXSET_FOREACH(s, u->core->sources, idx) {
-                    if (strcmp(s->name, devname) == 0) {
+                    if (pa_streq(s->name, device_name)) {
                         found_index = s->index;
                         break;
                     }
                 }
-                pa_xfree(devname);
+                pa_xfree(device_name);
             }
 
             pa_tagstruct_puts(reply, name);
@@ -1066,7 +1187,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
                 pa_tagstruct_putu32(reply, e->priority[i]);
             }
 
-            pa_xfree(e);
+            entry_free(e);
         }
 
         pa_xfree(name);
@@ -1089,19 +1210,12 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
         if (!device || !*device || !description || !*description)
           goto fail;
 
-        if ((e = read_entry(u, device))) {
-            pa_datum key, data;
-
-            pa_strlcpy(e->description, description, sizeof(e->description));
+        if ((e = entry_read(u, device))) {
+            pa_xfree(e->description);
+            e->description = pa_xstrdup(description);
             e->user_set_description = TRUE;
 
-            key.data = (char *) device;
-            key.size = strlen(device);
-
-            data.data = e;
-            data.size = sizeof(*e);
-
-            if (pa_database_set(u->database, &key, &data, TRUE) == 0) {
+            if (entry_write(u, (char *)device, e)) {
                 apply_entry(u, device, e);
 
                 trigger_save(u);
@@ -1109,7 +1223,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
             else
                 pa_log_warn("Could not save device");
 
-            pa_xfree(e);
+            entry_free(e);
         }
         else
             pa_log_warn("Could not rename device %s, no entry in database", device);
@@ -1158,7 +1272,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
         const char *role;
         struct entry *e;
         uint32_t role_index, n_devices;
-        pa_datum key, data;
+        pa_datum key;
         pa_bool_t done, sink_mode = TRUE;
         struct device_t { uint32_t prio; char *device; };
         struct device_t *device;
@@ -1174,7 +1288,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
             goto fail;
 
         if (PA_INVALID_INDEX == (role_index = get_role_index(role)))
-           goto fail;
+            goto fail;
 
         /* Cycle through the devices given and make sure they exist */
         h = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
@@ -1188,41 +1302,39 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
                     pa_xfree(device);
                 }
 
-                pa_hashmap_free(h, NULL, NULL);
+                pa_hashmap_free(h, NULL);
                 pa_log_error("Protocol error on reorder");
                 goto fail;
             }
 
             /* Ensure this is a valid entry */
-            if (!(e = read_entry(u, s))) {
+            if (!(e = entry_read(u, s))) {
                 while ((device = pa_hashmap_steal_first(h))) {
                     pa_xfree(device->device);
                     pa_xfree(device);
                 }
 
-                pa_hashmap_free(h, NULL, NULL);
+                pa_hashmap_free(h, NULL);
                 pa_log_error("Client specified an unknown device in it's reorder list.");
                 goto fail;
             }
-            pa_xfree(e);
+            entry_free(e);
 
             if (first) {
                 first = FALSE;
                 sink_mode = (0 == strncmp("sink:", s, 5));
-            } else if ((sink_mode && 0 != strncmp("sink:", s, 5))
-                       || (!sink_mode && 0 != strncmp("source:", s, 7)))
-            {
+            } else if ((sink_mode && 0 != strncmp("sink:", s, 5)) || (!sink_mode && 0 != strncmp("source:", s, 7))) {
                 while ((device = pa_hashmap_steal_first(h))) {
                     pa_xfree(device->device);
                     pa_xfree(device);
                 }
 
-                pa_hashmap_free(h, NULL, NULL);
+                pa_hashmap_free(h, NULL);
                 pa_log_error("Attempted to reorder mixed devices (sinks and sources)");
                 goto fail;
             }
 
-            /* Add the device to our hashmap. If it's alredy in it, free it now and carry on */
+            /* Add the device to our hashmap. If it's already in it, free it now and carry on */
             device = pa_xnew(struct device_t, 1);
             device->device = pa_xstrdup(s);
             if (pa_hashmap_put(h, device->device, device) == 0) {
@@ -1240,7 +1352,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
         }*/
 
         /* Now cycle through our list and add all the devices.
-           This has the effect of addign in any in our DB,
+           This has the effect of adding in any in our DB,
            not specified in the device list (and thus will be
            tacked on at the end) */
         offset = idx;
@@ -1256,10 +1368,10 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
             if ((sink_mode && 0 == strncmp("sink:", device->device, 5))
                 || (!sink_mode && 0 == strncmp("source:", device->device, 7))) {
 
-                /* Add the device to our hashmap. If it's alredy in it, free it now and carry on */
+                /* Add the device to our hashmap. If it's already in it, free it now and carry on */
                 if (pa_hashmap_put(h, device->device, device) == 0
-                    && (e = read_entry(u, device->device))) {
-                    /* We add offset on to the existing priorirty so that when we order, the
+                    && (e = entry_read(u, device->device))) {
+                    /* We add offset on to the existing priority so that when we order, the
                        existing entries are always lower priority than the new ones. */
                     device->prio = (offset + e->priority[role_index]);
                     pa_xfree(e);
@@ -1290,7 +1402,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
         while ((device = pa_hashmap_steal_first(h))) {
             devices[idx++] = device;
         }
-        pa_hashmap_free(h, NULL, NULL);
+        pa_hashmap_free(h, NULL);
 
         /* Simple bubble sort */
         for (i = 0; i < n_devices; ++i) {
@@ -1313,19 +1425,13 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
         idx = 1;
         first = TRUE;
         for (i = 0; i < n_devices; ++i) {
-            if ((e = read_entry(u, devices[i]->device))) {
+            if ((e = entry_read(u, devices[i]->device))) {
                 if (e->priority[role_index] == idx)
                     idx++;
                 else {
                     e->priority[role_index] = idx;
 
-                    key.data = (char *) devices[i]->device;
-                    key.size = strlen(devices[i]->device);
-
-                    data.data = e;
-                    data.size = sizeof(*e);
-
-                    if (pa_database_set(u->database, &key, &data, TRUE) == 0) {
+                    if (entry_write(u, (char *) devices[i]->device, e)) {
                         first = FALSE;
                         idx++;
                     }
@@ -1337,6 +1443,8 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
             pa_xfree(devices[i]);
         }
 
+        pa_xfree(devices);
+
         if (!first) {
             trigger_save(u);
 
@@ -1389,6 +1497,11 @@ static pa_hook_result_t connection_unlink_hook_cb(pa_native_protocol *p, pa_nati
     return PA_HOOK_OK;
 }
 
+struct prioritised_indexes {
+    uint32_t index;
+    int32_t priority;
+};
+
 int pa__init(pa_module*m) {
     pa_modargs *ma = NULL;
     struct userdata *u;
@@ -1397,6 +1510,7 @@ int pa__init(pa_module*m) {
     pa_source *source;
     uint32_t idx;
     pa_bool_t do_routing = FALSE, on_hotplug = TRUE, on_rescue = TRUE;
+    uint32_t total_devices;
 
     pa_assert(m);
 
@@ -1457,15 +1571,63 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
-    pa_log_info("Sucessfully opened database file '%s'.", fname);
+    pa_log_info("Successfully opened database file '%s'.", fname);
     pa_xfree(fname);
 
-    /* We cycle over all the available sinks so that they are added to our database if they are not in it yet */
-    PA_IDXSET_FOREACH(sink, m->core->sinks, idx)
-        subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_NEW, sink->index, u);
+    /* Attempt to inject the devices into the list in priority order */
+    total_devices = PA_MAX(pa_idxset_size(m->core->sinks), pa_idxset_size(m->core->sources));
+    if (total_devices > 0 && total_devices < 128) {
+        uint32_t i;
+        struct prioritised_indexes p_i[128];
+
+        /* We cycle over all the available sinks so that they are added to our database if they are not in it yet */
+        i = 0;
+        PA_IDXSET_FOREACH(sink, m->core->sinks, idx) {
+            pa_log_debug("Found sink index %u", sink->index);
+            p_i[i  ].index = sink->index;
+            p_i[i++].priority = sink->priority;
+        }
+        /* Bubble sort it (only really useful for first time creation) */
+        if (i > 1)
+          for (uint32_t j = 0; j < i; ++j)
+              for (uint32_t k = 0; k < i; ++k)
+                  if (p_i[j].priority > p_i[k].priority) {
+                      struct prioritised_indexes tmp_pi = p_i[k];
+                      p_i[k] = p_i[j];
+                      p_i[j] = tmp_pi;
+                  }
+        /* Register it */
+        for (uint32_t j = 0; j < i; ++j)
+            subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_NEW, p_i[j].index, u);
+
+
+        /* We cycle over all the available sources so that they are added to our database if they are not in it yet */
+        i = 0;
+        PA_IDXSET_FOREACH(source, m->core->sources, idx) {
+            p_i[i  ].index = source->index;
+            p_i[i++].priority = source->priority;
+        }
+        /* Bubble sort it (only really useful for first time creation) */
+        if (i > 1)
+          for (uint32_t j = 0; j < i; ++j)
+              for (uint32_t k = 0; k < i; ++k)
+                  if (p_i[j].priority > p_i[k].priority) {
+                      struct prioritised_indexes tmp_pi = p_i[k];
+                      p_i[k] = p_i[j];
+                      p_i[j] = tmp_pi;
+                  }
+        /* Register it */
+        for (uint32_t j = 0; j < i; ++j)
+            subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_NEW, p_i[j].index, u);
+    }
+    else if (total_devices > 0) {
+        /* This user has a *lot* of devices... */
+        PA_IDXSET_FOREACH(sink, m->core->sinks, idx)
+            subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_NEW, sink->index, u);
 
-    PA_IDXSET_FOREACH(source, m->core->sources, idx)
-        subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_NEW, source->index, u);
+        PA_IDXSET_FOREACH(source, m->core->sources, idx)
+            subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_NEW, source->index, u);
+    }
 
     /* Perform the routing (if it's enabled) which will update our priority list cache too */
     for (uint32_t i = 0; i < NUM_ROLES; ++i) {
@@ -1488,7 +1650,7 @@ fail:
     if (ma)
         pa_modargs_free(ma);
 
-    return  -1;
+    return -1;
 }
 
 void pa__done(pa_module*m) {
@@ -1522,6 +1684,9 @@ void pa__done(pa_module*m) {
     if (u->source_unlink_hook_slot)
         pa_hook_slot_free(u->source_unlink_hook_slot);
 
+    if (u->connection_unlink_hook_slot)
+        pa_hook_slot_free(u->connection_unlink_hook_slot);
+
     if (u->save_time_event)
         u->core->mainloop->time_free(u->save_time_event);
 
@@ -1534,7 +1699,7 @@ void pa__done(pa_module*m) {
     }
 
     if (u->subscribed)
-        pa_idxset_free(u->subscribed, NULL, NULL);
+        pa_idxset_free(u->subscribed, NULL);
 
     pa_xfree(u);
 }
diff --git a/src/modules/module-device-restore-symdef.h b/src/modules/module-device-restore-symdef.h
deleted file mode 100644 (file)
index a97febf..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduledevicerestoresymdeffoo
-#define foomoduledevicerestoresymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_device_restore_LTX_pa__init
-#define pa__done module_device_restore_LTX_pa__done
-#define pa__get_author module_device_restore_LTX_pa__get_author
-#define pa__get_description module_device_restore_LTX_pa__get_description
-#define pa__get_usage module_device_restore_LTX_pa__get_usage
-#define pa__get_version module_device_restore_LTX_pa__get_version
-#define pa__get_deprecated module_device_restore_LTX_pa__get_deprecated
-#define pa__load_once module_device_restore_LTX_pa__load_once
-#define pa__get_n_used module_device_restore_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index da6c966..8360a05 100644 (file)
@@ -2,6 +2,7 @@
   This file is part of PulseAudio.
 
   Copyright 2006-2008 Lennart Poettering
+  Copyright 2011 Colin Guthrie
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
 #include <sys/types.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <ctype.h>
 
+#include <pulse/gccmacro.h>
 #include <pulse/xmalloc.h>
 #include <pulse/volume.h>
 #include <pulse/timeval.h>
-#include <pulse/util.h>
 #include <pulse/rtclock.h>
+#include <pulse/format.h>
+#include <pulse/internal.h>
 
 #include <pulsecore/core-error.h>
 #include <pulsecore/module.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/log.h>
 #include <pulsecore/core-subscribe.h>
-#include <pulsecore/sink-input.h>
-#include <pulsecore/source-output.h>
+#include <pulsecore/sink.h>
+#include <pulsecore/source.h>
 #include <pulsecore/namereg.h>
+#include <pulsecore/protocol-native.h>
+#include <pulsecore/pstream.h>
+#include <pulsecore/pstream-util.h>
 #include <pulsecore/database.h>
+#include <pulsecore/tagstruct.h>
 
 #include "module-device-restore-symdef.h"
 
@@ -57,7 +63,8 @@ PA_MODULE_LOAD_ONCE(TRUE);
 PA_MODULE_USAGE(
         "restore_port=<Save/restore port?> "
         "restore_volume=<Save/restore volumes?> "
-        "restore_muted=<Save/restore muted states?>");
+        "restore_muted=<Save/restore muted states?> "
+        "restore_formats=<Save/restore saved formats?>");
 
 #define SAVE_INTERVAL (10 * PA_USEC_PER_SEC)
 
@@ -65,6 +72,7 @@ static const char* const valid_modargs[] = {
     "restore_volume",
     "restore_muted",
     "restore_port",
+    "restore_formats",
     NULL
 };
 
@@ -75,26 +83,53 @@ struct userdata {
     pa_hook_slot
         *sink_new_hook_slot,
         *sink_fixate_hook_slot,
+        *sink_port_hook_slot,
+        *sink_put_hook_slot,
         *source_new_hook_slot,
-        *source_fixate_hook_slot;
+        *source_fixate_hook_slot,
+        *source_port_hook_slot,
+        *connection_unlink_hook_slot;
     pa_time_event *save_time_event;
     pa_database *database;
 
+    pa_native_protocol *protocol;
+    pa_idxset *subscribed;
+
     pa_bool_t restore_volume:1;
     pa_bool_t restore_muted:1;
     pa_bool_t restore_port:1;
+    pa_bool_t restore_formats:1;
+};
+
+/* Protocol extension commands */
+enum {
+    SUBCOMMAND_TEST,
+    SUBCOMMAND_SUBSCRIBE,
+    SUBCOMMAND_EVENT,
+    SUBCOMMAND_READ_FORMATS_ALL,
+    SUBCOMMAND_READ_FORMATS,
+    SUBCOMMAND_SAVE_FORMATS
 };
 
-#define ENTRY_VERSION 2
+
+#define ENTRY_VERSION 1
 
 struct entry {
     uint8_t version;
-    pa_bool_t muted_valid:1, volume_valid:1, port_valid:1;
-    pa_bool_t muted:1;
+    pa_bool_t port_valid;
+    char *port;
+};
+
+#define PERPORTENTRY_VERSION 1
+
+struct perportentry {
+    uint8_t version;
+    pa_bool_t muted_valid, volume_valid;
+    pa_bool_t muted;
     pa_channel_map channel_map;
     pa_cvolume volume;
-    char port[PA_NAME_MAX];
-} PA_GCC_PACKED;
+    pa_idxset *formats;
+};
 
 static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
     struct userdata *u = userdata;
@@ -111,9 +146,86 @@ static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct
     pa_log_info("Synced.");
 }
 
-static struct entry* read_entry(struct userdata *u, const char *name) {
+static void trigger_save(struct userdata *u, pa_device_type_t type, uint32_t sink_idx) {
+    pa_native_connection *c;
+    uint32_t idx;
+
+    if (sink_idx != PA_INVALID_INDEX) {
+        PA_IDXSET_FOREACH(c, u->subscribed, idx) {
+            pa_tagstruct *t;
+
+            t = pa_tagstruct_new(NULL, 0);
+            pa_tagstruct_putu32(t, PA_COMMAND_EXTENSION);
+            pa_tagstruct_putu32(t, 0);
+            pa_tagstruct_putu32(t, u->module->index);
+            pa_tagstruct_puts(t, u->module->name);
+            pa_tagstruct_putu32(t, SUBCOMMAND_EVENT);
+            pa_tagstruct_putu32(t, type);
+            pa_tagstruct_putu32(t, sink_idx);
+
+            pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), t);
+        }
+    }
+
+    if (u->save_time_event)
+        return;
+
+    u->save_time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + SAVE_INTERVAL, save_time_callback, u);
+}
+
+
+#ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
+/* Some forward declarations */
+static pa_bool_t legacy_entry_read(struct userdata *u, pa_datum *data, struct entry **entry, struct perportentry **perportentry);
+static struct perportentry* perportentry_read(struct userdata *u, const char *basekeyname, const char *port);
+static pa_bool_t perportentry_write(struct userdata *u, const char *basekeyname, const char *port, const struct perportentry *e);
+static void perportentry_free(struct perportentry* e);
+#endif
+
+static struct entry* entry_new(void) {
+    struct entry *r = pa_xnew0(struct entry, 1);
+    r->version = ENTRY_VERSION;
+    return r;
+}
+
+static void entry_free(struct entry* e) {
+    pa_assert(e);
+
+    pa_xfree(e->port);
+    pa_xfree(e);
+}
+
+static pa_bool_t entry_write(struct userdata *u, const char *name, const struct entry *e) {
+    pa_tagstruct *t;
     pa_datum key, data;
-    struct entry *e;
+    pa_bool_t r;
+
+    pa_assert(u);
+    pa_assert(name);
+    pa_assert(e);
+
+    t = pa_tagstruct_new(NULL, 0);
+    pa_tagstruct_putu8(t, e->version);
+    pa_tagstruct_put_boolean(t, e->port_valid);
+    pa_tagstruct_puts(t, e->port);
+
+    key.data = (char *) name;
+    key.size = strlen(name);
+
+    data.data = (void*)pa_tagstruct_data(t, &data.size);
+
+    r = (pa_database_set(u->database, &key, &data, TRUE) == 0);
+
+    pa_tagstruct_free(t);
+
+    return r;
+}
+
+static struct entry* entry_read(struct userdata *u, const char *name) {
+    pa_datum key, data;
+    struct entry *e = NULL;
+    pa_tagstruct *t = NULL;
+    const char* port;
 
     pa_assert(u);
     pa_assert(name);
@@ -126,23 +238,214 @@ static struct entry* read_entry(struct userdata *u, const char *name) {
     if (!pa_database_get(u->database, &key, &data))
         goto fail;
 
-    if (data.size != sizeof(struct entry)) {
-        pa_log_debug("Database contains entry for device %s of wrong size %lu != %lu. Probably due to upgrade, ignoring.", name, (unsigned long) data.size, (unsigned long) sizeof(struct entry));
+    t = pa_tagstruct_new(data.data, data.size);
+    e = entry_new();
+
+    if (pa_tagstruct_getu8(t, &e->version) < 0 ||
+        e->version > ENTRY_VERSION ||
+        pa_tagstruct_get_boolean(t, &e->port_valid) < 0 ||
+        pa_tagstruct_gets(t, &port) < 0) {
+
         goto fail;
     }
 
-    e = (struct entry*) data.data;
-
-    if (e->version != ENTRY_VERSION) {
-        pa_log_debug("Version of database entry for device %s doesn't match our version. Probably due to upgrade, ignoring.", name);
+    if (!pa_tagstruct_eof(t))
         goto fail;
+
+    e->port = pa_xstrdup(port);
+
+    pa_tagstruct_free(t);
+    pa_datum_free(&data);
+
+    return e;
+
+fail:
+
+    pa_log_debug("Database contains invalid data for key: %s (probably pre-v1.0 data)", name);
+
+    if (e)
+        entry_free(e);
+    if (t)
+        pa_tagstruct_free(t);
+
+#ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
+{
+    struct perportentry *ppe;
+    pa_log_debug("Attempting to load legacy (pre-v1.0) data for key: %s", name);
+    if (legacy_entry_read(u, &data, &e, &ppe)) {
+        pa_bool_t written = FALSE;
+
+        pa_log_debug("Success. Saving new format for key: %s", name);
+        written = entry_write(u, name, e);
+
+        /* Now convert the legacy entry into per-port entries */
+        if (0 == strncmp("sink:", name, 5)) {
+            pa_sink *sink;
+
+            if ((sink = pa_namereg_get(u->core, name+5, PA_NAMEREG_SINK))) {
+                /* Write a "null" port entry. The read code will automatically try this
+                 * if it cannot find a specific port-named entry. */
+                written = perportentry_write(u, name, NULL, ppe) || written;
+            }
+        } else if (0 == strncmp("source:", name, 7)) {
+            pa_source *source;
+
+            if ((source = pa_namereg_get(u->core, name+7, PA_NAMEREG_SOURCE))) {
+                /* Write a "null" port entry. The read code will automatically try this
+                 * if it cannot find a specific port-named entry. */
+                written = perportentry_write(u, name, NULL, ppe) || written;
+            }
+        }
+        perportentry_free(ppe);
+
+        if (written)
+            /* NB The device type doesn't matter when we pass in an invalid index. */
+            trigger_save(u, PA_DEVICE_TYPE_SINK, PA_INVALID_INDEX);
+
+        pa_datum_free(&data);
+        return e;
+    }
+    pa_log_debug("Unable to load legacy (pre-v1.0) data for key: %s. Ignoring.", name);
+}
+#endif
+
+    pa_datum_free(&data);
+    return NULL;
+}
+
+static struct entry* entry_copy(const struct entry *e) {
+    struct entry* r;
+
+    pa_assert(e);
+    r = entry_new();
+    r->version = e->version;
+    r->port_valid = e->port_valid;
+    r->port = pa_xstrdup(e->port);
+
+    return r;
+}
+
+static pa_bool_t entries_equal(const struct entry *a, const struct entry *b) {
+
+    pa_assert(a && b);
+
+    if (a->port_valid != b->port_valid ||
+        (a->port_valid && !pa_streq(a->port, b->port)))
+        return FALSE;
+
+    return TRUE;
+}
+
+static struct perportentry* perportentry_new(pa_bool_t add_pcm_format) {
+    struct perportentry *r = pa_xnew0(struct perportentry, 1);
+    r->version = PERPORTENTRY_VERSION;
+    r->formats = pa_idxset_new(NULL, NULL);
+    if (add_pcm_format) {
+        pa_format_info *f = pa_format_info_new();
+        f->encoding = PA_ENCODING_PCM;
+        pa_idxset_put(r->formats, f, NULL);
+    }
+    return r;
+}
+
+static void perportentry_free(struct perportentry* e) {
+    pa_assert(e);
+
+    pa_idxset_free(e->formats, (pa_free_cb_t) pa_format_info_free);
+    pa_xfree(e);
+}
+
+static pa_bool_t perportentry_write(struct userdata *u, const char *basekeyname, const char *port, const struct perportentry *e) {
+    pa_tagstruct *t;
+    pa_datum key, data;
+    pa_bool_t r;
+    uint32_t i;
+    pa_format_info *f;
+    uint8_t n_formats;
+    char *name;
+
+    pa_assert(u);
+    pa_assert(basekeyname);
+    pa_assert(e);
+
+    name = pa_sprintf_malloc("%s:%s", basekeyname, (port ? port : "null"));
+
+    n_formats = pa_idxset_size(e->formats);
+    pa_assert(n_formats > 0);
+
+    t = pa_tagstruct_new(NULL, 0);
+    pa_tagstruct_putu8(t, e->version);
+    pa_tagstruct_put_boolean(t, e->volume_valid);
+    pa_tagstruct_put_channel_map(t, &e->channel_map);
+    pa_tagstruct_put_cvolume(t, &e->volume);
+    pa_tagstruct_put_boolean(t, e->muted_valid);
+    pa_tagstruct_put_boolean(t, e->muted);
+    pa_tagstruct_putu8(t, n_formats);
+
+    PA_IDXSET_FOREACH(f, e->formats, i) {
+        pa_tagstruct_put_format_info(t, f);
     }
 
-    if (!memchr(e->port, 0, sizeof(e->port))) {
-        pa_log_warn("Database contains entry for device %s with missing NUL byte in port name", name);
+    key.data = (char *) name;
+    key.size = strlen(name);
+
+    data.data = (void*)pa_tagstruct_data(t, &data.size);
+
+    r = (pa_database_set(u->database, &key, &data, TRUE) == 0);
+
+    pa_tagstruct_free(t);
+    pa_xfree(name);
+
+    return r;
+}
+
+static struct perportentry* perportentry_read(struct userdata *u, const char *basekeyname, const char *port) {
+    pa_datum key, data;
+    struct perportentry *e = NULL;
+    pa_tagstruct *t = NULL;
+    uint8_t i, n_formats;
+    char *name;
+
+    pa_assert(u);
+    pa_assert(basekeyname);
+
+    name = pa_sprintf_malloc("%s:%s", basekeyname, (port ? port : "null"));
+
+    key.data = name;
+    key.size = strlen(name);
+
+    pa_zero(data);
+
+    if (!pa_database_get(u->database, &key, &data))
+        goto fail;
+
+    t = pa_tagstruct_new(data.data, data.size);
+    e = perportentry_new(FALSE);
+
+    if (pa_tagstruct_getu8(t, &e->version) < 0 ||
+        e->version > PERPORTENTRY_VERSION ||
+        pa_tagstruct_get_boolean(t, &e->volume_valid) < 0 ||
+        pa_tagstruct_get_channel_map(t, &e->channel_map) < 0 ||
+        pa_tagstruct_get_cvolume(t, &e->volume) < 0 ||
+        pa_tagstruct_get_boolean(t, &e->muted_valid) < 0 ||
+        pa_tagstruct_get_boolean(t, &e->muted) < 0 ||
+        pa_tagstruct_getu8(t, &n_formats) < 0 || n_formats < 1) {
+
         goto fail;
     }
 
+    for (i = 0; i < n_formats; ++i) {
+        pa_format_info *f = pa_format_info_new();
+        if (pa_tagstruct_get_format_info(t, f) < 0) {
+            pa_format_info_free(f);
+            goto fail;
+        }
+        pa_idxset_put(e->formats, f, NULL);
+    }
+
+    if (!pa_tagstruct_eof(t))
+        goto fail;
+
     if (e->volume_valid && !pa_channel_map_valid(&e->channel_map)) {
         pa_log_warn("Invalid channel map stored in database for device %s", name);
         goto fail;
@@ -153,27 +456,60 @@ static struct entry* read_entry(struct userdata *u, const char *name) {
         goto fail;
     }
 
+    pa_tagstruct_free(t);
+    pa_datum_free(&data);
+    pa_xfree(name);
+
     return e;
 
 fail:
 
+    if (e)
+        perportentry_free(e);
+    if (t)
+        pa_tagstruct_free(t);
+
     pa_datum_free(&data);
+
+#ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
+    /* Try again with a null port. This is used when dealing with migration from older versions */
+    if (port) {
+        pa_xfree(name);
+        return perportentry_read(u, basekeyname, NULL);
+    }
+#endif
+
+    pa_log_debug("Database contains invalid data for key: %s", name);
+
+    pa_xfree(name);
+
     return NULL;
 }
 
-static void trigger_save(struct userdata *u) {
-    if (u->save_time_event)
-        return;
+static struct perportentry* perportentry_copy(const struct perportentry *e) {
+    struct perportentry* r;
+    uint32_t idx;
+    pa_format_info *f;
 
-    u->save_time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + SAVE_INTERVAL, save_time_callback, u);
+    pa_assert(e);
+    r = perportentry_new(FALSE);
+    r->version = e->version;
+    r->muted_valid = e->muted_valid;
+    r->volume_valid = e->volume_valid;
+    r->muted = e->muted;
+    r->channel_map = e->channel_map;
+    r->volume = e->volume;
+
+    PA_IDXSET_FOREACH(f, e->formats, idx) {
+        pa_idxset_put(r->formats, pa_format_info_copy(f), NULL);
+    }
+    return r;
 }
 
-static pa_bool_t entries_equal(const struct entry *a, const struct entry *b) {
+static pa_bool_t perportentries_equal(const struct perportentry *a, const struct perportentry *b) {
     pa_cvolume t;
 
-    if (a->port_valid != b->port_valid ||
-        (a->port_valid && strncmp(a->port, b->port, sizeof(a->port))))
-        return FALSE;
+    pa_assert(a && b);
 
     if (a->muted_valid != b->muted_valid ||
         (a->muted_valid && (a->muted != b->muted)))
@@ -184,14 +520,83 @@ static pa_bool_t entries_equal(const struct entry *a, const struct entry *b) {
         (a->volume_valid && !pa_cvolume_equal(pa_cvolume_remap(&t, &b->channel_map, &a->channel_map), &a->volume)))
         return FALSE;
 
+    if (pa_idxset_size(a->formats) != pa_idxset_size(b->formats))
+        return FALSE;
+
+    /** TODO: Compare a bit better */
+
+    return TRUE;
+}
+
+#ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
+
+#define LEGACY_ENTRY_VERSION 2
+static pa_bool_t legacy_entry_read(struct userdata *u, pa_datum *data, struct entry **entry, struct perportentry **perportentry) {
+    struct legacy_entry {
+        uint8_t version;
+        pa_bool_t muted_valid:1, volume_valid:1, port_valid:1;
+        pa_bool_t muted:1;
+        pa_channel_map channel_map;
+        pa_cvolume volume;
+        char port[PA_NAME_MAX];
+    } PA_GCC_PACKED;
+    struct legacy_entry *le;
+
+    pa_assert(u);
+    pa_assert(data);
+    pa_assert(entry);
+    pa_assert(perportentry);
+
+    if (data->size != sizeof(struct legacy_entry)) {
+        pa_log_debug("Size does not match.");
+        return FALSE;
+    }
+
+    le = (struct legacy_entry*)data->data;
+
+    if (le->version != LEGACY_ENTRY_VERSION) {
+        pa_log_debug("Version mismatch.");
+        return FALSE;
+    }
+
+    if (!memchr(le->port, 0, sizeof(le->port))) {
+        pa_log_warn("Port has missing NUL byte.");
+        return FALSE;
+    }
+
+    if (le->volume_valid && !pa_channel_map_valid(&le->channel_map)) {
+        pa_log_warn("Invalid channel map.");
+        return FALSE;
+    }
+
+    if (le->volume_valid && (!pa_cvolume_valid(&le->volume) || !pa_cvolume_compatible_with_channel_map(&le->volume, &le->channel_map))) {
+        pa_log_warn("Volume and channel map don't match.");
+        return FALSE;
+    }
+
+    *entry = entry_new();
+    (*entry)->port_valid = le->port_valid;
+    (*entry)->port = pa_xstrdup(le->port);
+
+    *perportentry = perportentry_new(TRUE);
+    (*perportentry)->muted_valid = le->muted_valid;
+    (*perportentry)->volume_valid = le->volume_valid;
+    (*perportentry)->muted = le->muted;
+    (*perportentry)->channel_map = le->channel_map;
+    (*perportentry)->volume = le->volume;
+
     return TRUE;
 }
+#endif
 
 static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
     struct userdata *u = userdata;
-    struct entry entry, *old;
+    struct entry *e, *olde;
+    struct perportentry *ppe, *oldppe;
     char *name;
-    pa_datum key, data;
+    const char *port = NULL;
+    pa_device_type_t type;
+    pa_bool_t written = FALSE;
 
     pa_assert(c);
     pa_assert(u);
@@ -202,36 +607,43 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
         t != (PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE))
         return;
 
-    pa_zero(entry);
-    entry.version = ENTRY_VERSION;
-
     if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK) {
         pa_sink *sink;
 
         if (!(sink = pa_idxset_get_by_index(c->sinks, idx)))
             return;
 
+        type = PA_DEVICE_TYPE_SINK;
         name = pa_sprintf_malloc("sink:%s", sink->name);
+        if (sink->active_port)
+            port = sink->active_port->name;
 
-        if ((old = read_entry(u, name)))
-            entry = *old;
+        if ((olde = entry_read(u, name)))
+            e = entry_copy(olde);
+        else
+            e = entry_new();
 
-        if (sink->save_volume) {
-            entry.channel_map = sink->channel_map;
-            entry.volume = *pa_sink_get_volume(sink, FALSE);
-            entry.volume_valid = TRUE;
+        if (sink->save_port) {
+            pa_xfree(e->port);
+            e->port = pa_xstrdup(port ? port : "");
+            e->port_valid = TRUE;
         }
 
-        if (sink->save_muted) {
-            entry.muted = pa_sink_get_mute(sink, FALSE);
-            entry.muted_valid = TRUE;
-        }
+        if ((oldppe = perportentry_read(u, name, port)))
+            ppe = perportentry_copy(oldppe);
+        else
+            ppe = perportentry_new(TRUE);
 
-        if (sink->save_port) {
-            pa_strlcpy(entry.port, sink->active_port ? sink->active_port->name : "", sizeof(entry.port));
-            entry.port_valid = TRUE;
+        if (sink->save_volume) {
+            ppe->channel_map = sink->channel_map;
+            ppe->volume = *pa_sink_get_volume(sink, FALSE);
+            ppe->volume_valid = TRUE;
         }
 
+        if (sink->save_muted) {
+            ppe->muted = pa_sink_get_mute(sink, FALSE);
+            ppe->muted_valid = TRUE;
+        }
     } else {
         pa_source *source;
 
@@ -240,52 +652,84 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
         if (!(source = pa_idxset_get_by_index(c->sources, idx)))
             return;
 
+        type = PA_DEVICE_TYPE_SOURCE;
         name = pa_sprintf_malloc("source:%s", source->name);
+        if (source->active_port)
+            port = source->active_port->name;
+
+        if ((olde = entry_read(u, name)))
+            e = entry_copy(olde);
+        else
+            e = entry_new();
+
+        if (source->save_port) {
+            pa_xfree(e->port);
+            e->port = pa_xstrdup(port ? port : "");
+            e->port_valid = TRUE;
+        }
 
-        if ((old = read_entry(u, name)))
-            entry = *old;
+        if ((oldppe = perportentry_read(u, name, port)))
+            ppe = perportentry_copy(oldppe);
+        else
+            ppe = perportentry_new(TRUE);
 
         if (source->save_volume) {
-            entry.channel_map = source->channel_map;
-            entry.volume = *pa_source_get_volume(source, FALSE);
-            entry.volume_valid = TRUE;
+            ppe->channel_map = source->channel_map;
+            ppe->volume = *pa_source_get_volume(source, FALSE);
+            ppe->volume_valid = TRUE;
         }
 
         if (source->save_muted) {
-            entry.muted = pa_source_get_mute(source, FALSE);
-            entry.muted_valid = TRUE;
+            ppe->muted = pa_source_get_mute(source, FALSE);
+            ppe->muted_valid = TRUE;
         }
+    }
 
-        if (source->save_port) {
-            pa_strlcpy(entry.port, source->active_port ? source->active_port->name : "", sizeof(entry.port));
-            entry.port_valid = TRUE;
-        }
+
+    pa_assert(e);
+
+    if (olde) {
+
+        if (entries_equal(olde, e)) {
+            entry_free(olde);
+            entry_free(e);
+            e = NULL;
+        } else
+            entry_free(olde);
     }
 
-    if (old) {
+    if (e) {
+        pa_log_info("Storing port for device %s.", name);
 
-        if (entries_equal(old, &entry)) {
-            pa_xfree(old);
-            pa_xfree(name);
-            return;
-        }
+        written = entry_write(u, name, e);
 
-        pa_xfree(old);
+        entry_free(e);
     }
 
-    key.data = name;
-    key.size = strlen(name);
 
-    data.data = &entry;
-    data.size = sizeof(entry);
+    pa_assert(ppe);
 
-    pa_log_info("Storing volume/mute/port for device %s.", name);
+    if (oldppe) {
 
-    pa_database_set(u->database, &key, &data, TRUE);
+        if (perportentries_equal(oldppe, ppe)) {
+            perportentry_free(oldppe);
+            perportentry_free(ppe);
+            ppe = NULL;
+        } else
+            perportentry_free(oldppe);
+    }
+
+    if (ppe) {
+        pa_log_info("Storing volume/mute for device+port %s:%s.", name, (port ? port : "null"));
+
+        written = perportentry_write(u, name, port, ppe) || written;
 
+        perportentry_free(ppe);
+    }
     pa_xfree(name);
 
-    trigger_save(u);
+    if (written)
+        trigger_save(u, type, idx);
 }
 
 static pa_hook_result_t sink_new_hook_callback(pa_core *c, pa_sink_new_data *new_data, struct userdata *u) {
@@ -299,7 +743,7 @@ static pa_hook_result_t sink_new_hook_callback(pa_core *c, pa_sink_new_data *new
 
     name = pa_sprintf_malloc("sink:%s", new_data->name);
 
-    if ((e = read_entry(u, name))) {
+    if ((e = entry_read(u, name))) {
 
         if (e->port_valid) {
             if (!new_data->active_port) {
@@ -310,7 +754,7 @@ static pa_hook_result_t sink_new_hook_callback(pa_core *c, pa_sink_new_data *new
                 pa_log_debug("Not restoring port for sink %s, because already set.", name);
         }
 
-        pa_xfree(e);
+        entry_free(e);
     }
 
     pa_xfree(name);
@@ -320,7 +764,7 @@ static pa_hook_result_t sink_new_hook_callback(pa_core *c, pa_sink_new_data *new
 
 static pa_hook_result_t sink_fixate_hook_callback(pa_core *c, pa_sink_new_data *new_data, struct userdata *u) {
     char *name;
-    struct entry *e;
+    struct perportentry *e;
 
     pa_assert(c);
     pa_assert(new_data);
@@ -329,18 +773,19 @@ static pa_hook_result_t sink_fixate_hook_callback(pa_core *c, pa_sink_new_data *
 
     name = pa_sprintf_malloc("sink:%s", new_data->name);
 
-    if ((e = read_entry(u, name))) {
+    if ((e = perportentry_read(u, name, new_data->active_port))) {
 
         if (u->restore_volume && e->volume_valid) {
 
             if (!new_data->volume_is_set) {
                 pa_cvolume v;
+                char buf[PA_CVOLUME_SNPRINT_MAX];
 
                 pa_log_info("Restoring volume for sink %s.", new_data->name);
-
                 v = e->volume;
                 pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map);
                 pa_sink_new_data_set_volume(new_data, &v);
+                pa_log_info("Restored volume: %s", pa_cvolume_snprint(buf, PA_CVOLUME_SNPRINT_MAX, &new_data->volume));
 
                 new_data->save_volume = TRUE;
             } else
@@ -357,7 +802,72 @@ static pa_hook_result_t sink_fixate_hook_callback(pa_core *c, pa_sink_new_data *
                 pa_log_debug("Not restoring mute state for sink %s, because already set.", new_data->name);
         }
 
-        pa_xfree(e);
+        perportentry_free(e);
+    }
+
+    pa_xfree(name);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sink_port_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
+    char *name;
+    struct perportentry *e;
+
+    pa_assert(c);
+    pa_assert(sink);
+    pa_assert(u);
+    pa_assert(u->restore_volume || u->restore_muted);
+
+    name = pa_sprintf_malloc("sink:%s", sink->name);
+
+    if ((e = perportentry_read(u, name, (sink->active_port ? sink->active_port->name : NULL)))) {
+
+        if (u->restore_volume && e->volume_valid) {
+            pa_cvolume v;
+            char buf[PA_CVOLUME_SNPRINT_MAX];
+
+            pa_log_info("Restoring volume for sink %s.", sink->name);
+            v = e->volume;
+            pa_cvolume_remap(&v, &e->channel_map, &sink->channel_map);
+            pa_sink_set_volume(sink, &v, TRUE, FALSE);
+            pa_log_info("Restored volume: %s", pa_cvolume_snprint(buf, PA_CVOLUME_SNPRINT_MAX, &sink->reference_volume));
+
+            sink->save_volume = TRUE;
+        }
+
+        if (u->restore_muted && e->muted_valid) {
+
+            pa_log_info("Restoring mute state for sink %s.", sink->name);
+            pa_sink_set_mute(sink, e->muted, FALSE);
+            sink->save_muted = TRUE;
+        }
+
+        perportentry_free(e);
+    }
+
+    pa_xfree(name);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
+    char *name;
+    struct perportentry *e;
+
+    pa_assert(c);
+    pa_assert(sink);
+    pa_assert(u);
+    pa_assert(u->restore_formats);
+
+    name = pa_sprintf_malloc("sink:%s", sink->name);
+
+    if ((e = perportentry_read(u, name, (sink->active_port ? sink->active_port->name : NULL)))) {
+
+        if (!pa_sink_set_formats(sink, e->formats))
+            pa_log_debug("Could not set format on sink %s", sink->name);
+
+        perportentry_free(e);
     }
 
     pa_xfree(name);
@@ -376,7 +886,7 @@ static pa_hook_result_t source_new_hook_callback(pa_core *c, pa_source_new_data
 
     name = pa_sprintf_malloc("source:%s", new_data->name);
 
-    if ((e = read_entry(u, name))) {
+    if ((e = entry_read(u, name))) {
 
         if (e->port_valid) {
             if (!new_data->active_port) {
@@ -387,7 +897,7 @@ static pa_hook_result_t source_new_hook_callback(pa_core *c, pa_source_new_data
                 pa_log_debug("Not restoring port for source %s, because already set.", name);
         }
 
-        pa_xfree(e);
+        entry_free(e);
     }
 
     pa_xfree(name);
@@ -397,7 +907,7 @@ static pa_hook_result_t source_new_hook_callback(pa_core *c, pa_source_new_data
 
 static pa_hook_result_t source_fixate_hook_callback(pa_core *c, pa_source_new_data *new_data, struct userdata *u) {
     char *name;
-    struct entry *e;
+    struct perportentry *e;
 
     pa_assert(c);
     pa_assert(new_data);
@@ -406,18 +916,19 @@ static pa_hook_result_t source_fixate_hook_callback(pa_core *c, pa_source_new_da
 
     name = pa_sprintf_malloc("source:%s", new_data->name);
 
-    if ((e = read_entry(u, name))) {
+    if ((e = perportentry_read(u, name, new_data->active_port))) {
 
         if (u->restore_volume && e->volume_valid) {
 
             if (!new_data->volume_is_set) {
                 pa_cvolume v;
+                char buf[PA_CVOLUME_SNPRINT_MAX];
 
                 pa_log_info("Restoring volume for source %s.", new_data->name);
-
                 v = e->volume;
                 pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map);
                 pa_source_new_data_set_volume(new_data, &v);
+                pa_log_info("Restored volume: %s", pa_cvolume_snprint(buf, PA_CVOLUME_SNPRINT_MAX, &new_data->volume));
 
                 new_data->save_volume = TRUE;
             } else
@@ -434,7 +945,48 @@ static pa_hook_result_t source_fixate_hook_callback(pa_core *c, pa_source_new_da
                 pa_log_debug("Not restoring mute state for source %s, because already set.", new_data->name);
         }
 
-        pa_xfree(e);
+        perportentry_free(e);
+    }
+
+    pa_xfree(name);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t source_port_hook_callback(pa_core *c, pa_source *source, struct userdata *u) {
+    char *name;
+    struct perportentry *e;
+
+    pa_assert(c);
+    pa_assert(source);
+    pa_assert(u);
+    pa_assert(u->restore_volume || u->restore_muted);
+
+    name = pa_sprintf_malloc("source:%s", source->name);
+
+    if ((e = perportentry_read(u, name, (source->active_port ? source->active_port->name : NULL)))) {
+
+        if (u->restore_volume && e->volume_valid) {
+            pa_cvolume v;
+            char buf[PA_CVOLUME_SNPRINT_MAX];
+
+            pa_log_info("Restoring volume for source %s.", source->name);
+            v = e->volume;
+            pa_cvolume_remap(&v, &e->channel_map, &source->channel_map);
+            pa_source_set_volume(source, &v, TRUE, FALSE);
+            pa_log_info("Restored volume: %s", pa_cvolume_snprint(buf, PA_CVOLUME_SNPRINT_MAX, &source->reference_volume));
+
+            source->save_volume = TRUE;
+        }
+
+        if (u->restore_muted && e->muted_valid) {
+
+            pa_log_info("Restoring mute state for source %s.", source->name);
+            pa_source_set_mute(source, e->muted, FALSE);
+            source->save_muted = TRUE;
+        }
+
+        perportentry_free(e);
     }
 
     pa_xfree(name);
@@ -442,6 +994,219 @@ static pa_hook_result_t source_fixate_hook_callback(pa_core *c, pa_source_new_da
     return PA_HOOK_OK;
 }
 
+#define EXT_VERSION 1
+
+static void read_sink_format_reply(struct userdata *u, pa_tagstruct *reply, pa_sink *sink) {
+    struct perportentry *e;
+    char *name;
+
+    pa_assert(u);
+    pa_assert(reply);
+    pa_assert(sink);
+
+    pa_tagstruct_putu32(reply, PA_DEVICE_TYPE_SINK);
+    pa_tagstruct_putu32(reply, sink->index);
+
+    /* Read or create an entry */
+    name = pa_sprintf_malloc("sink:%s", sink->name);
+    if (!(e = perportentry_read(u, name, (sink->active_port ? sink->active_port->name : NULL)))) {
+        /* Fake a reply with PCM encoding supported */
+        pa_format_info *f = pa_format_info_new();
+
+        pa_tagstruct_putu8(reply, 1);
+        f->encoding = PA_ENCODING_PCM;
+        pa_tagstruct_put_format_info(reply, f);
+
+        pa_format_info_free(f);
+    } else {
+        uint32_t idx;
+        pa_format_info *f;
+
+        /* Write all the formats from the entry to the reply */
+        pa_tagstruct_putu8(reply, pa_idxset_size(e->formats));
+        PA_IDXSET_FOREACH(f, e->formats, idx) {
+            pa_tagstruct_put_format_info(reply, f);
+        }
+    }
+    pa_xfree(name);
+}
+
+static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
+    struct userdata *u;
+    uint32_t command;
+    pa_tagstruct *reply = NULL;
+
+    pa_assert(p);
+    pa_assert(m);
+    pa_assert(c);
+    pa_assert(t);
+
+    u = m->userdata;
+
+    if (pa_tagstruct_getu32(t, &command) < 0)
+        goto fail;
+
+    reply = pa_tagstruct_new(NULL, 0);
+    pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
+    pa_tagstruct_putu32(reply, tag);
+
+    switch (command) {
+        case SUBCOMMAND_TEST: {
+            if (!pa_tagstruct_eof(t))
+                goto fail;
+
+            pa_tagstruct_putu32(reply, EXT_VERSION);
+            break;
+        }
+
+        case SUBCOMMAND_SUBSCRIBE: {
+
+            pa_bool_t enabled;
+
+            if (pa_tagstruct_get_boolean(t, &enabled) < 0 ||
+                !pa_tagstruct_eof(t))
+                goto fail;
+
+            if (enabled)
+                pa_idxset_put(u->subscribed, c, NULL);
+            else
+                pa_idxset_remove_by_data(u->subscribed, c, NULL);
+
+            break;
+        }
+
+        case SUBCOMMAND_READ_FORMATS_ALL: {
+            pa_sink *sink;
+            uint32_t idx;
+
+            if (!pa_tagstruct_eof(t))
+                goto fail;
+
+            PA_IDXSET_FOREACH(sink, u->core->sinks, idx) {
+                read_sink_format_reply(u, reply, sink);
+            }
+
+            break;
+        }
+        case SUBCOMMAND_READ_FORMATS: {
+            pa_device_type_t type;
+            uint32_t sink_index;
+            pa_sink *sink;
+
+            pa_assert(reply);
+
+            /* Get the sink index and the number of formats from the tagstruct */
+            if (pa_tagstruct_getu32(t, &type) < 0 ||
+                pa_tagstruct_getu32(t, &sink_index) < 0)
+                goto fail;
+
+            if (type != PA_DEVICE_TYPE_SINK) {
+                pa_log("Device format reading is only supported on sinks");
+                goto fail;
+            }
+
+            if (!pa_tagstruct_eof(t))
+                goto fail;
+
+            /* Now find our sink */
+            if (!(sink = pa_idxset_get_by_index(u->core->sinks, sink_index)))
+                goto fail;
+
+            read_sink_format_reply(u, reply, sink);
+
+            break;
+        }
+
+        case SUBCOMMAND_SAVE_FORMATS: {
+
+            struct perportentry *e;
+            pa_device_type_t type;
+            uint32_t sink_index;
+            char *name;
+            pa_sink *sink;
+            uint8_t i, n_formats;
+
+            /* Get the sink index and the number of formats from the tagstruct */
+            if (pa_tagstruct_getu32(t, &type) < 0 ||
+                pa_tagstruct_getu32(t, &sink_index) < 0 ||
+                pa_tagstruct_getu8(t, &n_formats) < 0 || n_formats < 1) {
+
+                goto fail;
+            }
+
+            if (type != PA_DEVICE_TYPE_SINK) {
+                pa_log("Device format saving is only supported on sinks");
+                goto fail;
+            }
+
+            /* Now find our sink */
+            if (!(sink = pa_idxset_get_by_index(u->core->sinks, sink_index))) {
+                pa_log("Could not find sink #%d", sink_index);
+                goto fail;
+            }
+
+            /* Read or create an entry */
+            name = pa_sprintf_malloc("sink:%s", sink->name);
+            if (!(e = perportentry_read(u, name, (sink->active_port ? sink->active_port->name : NULL))))
+                e = perportentry_new(FALSE);
+            else {
+                /* Clean out any saved formats */
+                pa_idxset_free(e->formats, (pa_free_cb_t) pa_format_info_free);
+                e->formats = pa_idxset_new(NULL, NULL);
+            }
+
+            /* Read all the formats from our tagstruct */
+            for (i = 0; i < n_formats; ++i) {
+                pa_format_info *f = pa_format_info_new();
+                if (pa_tagstruct_get_format_info(t, f) < 0) {
+                    pa_format_info_free(f);
+                    pa_xfree(name);
+                    goto fail;
+                }
+                pa_idxset_put(e->formats, f, NULL);
+            }
+
+            if (!pa_tagstruct_eof(t)) {
+                perportentry_free(e);
+                pa_xfree(name);
+                goto fail;
+            }
+
+            if (pa_sink_set_formats(sink, e->formats) && perportentry_write(u, name, (sink->active_port ? sink->active_port->name : NULL), e))
+                trigger_save(u, type, sink_index);
+            else
+                pa_log_warn("Could not save format info for sink %s", sink->name);
+
+            pa_xfree(name);
+            perportentry_free(e);
+
+            break;
+        }
+
+        default:
+            goto fail;
+    }
+
+    pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply);
+    return 0;
+
+fail:
+
+    if (reply)
+        pa_tagstruct_free(reply);
+
+    return -1;
+}
+
+static pa_hook_result_t connection_unlink_hook_cb(pa_native_protocol *p, pa_native_connection *c, struct userdata *u) {
+    pa_assert(p);
+    pa_assert(c);
+    pa_assert(u);
+
+    pa_idxset_remove_by_data(u->subscribed, c, NULL);
+    return PA_HOOK_OK;
+}
+
 int pa__init(pa_module*m) {
     pa_modargs *ma = NULL;
     struct userdata *u;
@@ -449,7 +1214,7 @@ int pa__init(pa_module*m) {
     pa_sink *sink;
     pa_source *source;
     uint32_t idx;
-    pa_bool_t restore_volume = TRUE, restore_muted = TRUE, restore_port = TRUE;
+    pa_bool_t restore_volume = TRUE, restore_muted = TRUE, restore_port = TRUE, restore_formats = TRUE;
 
     pa_assert(m);
 
@@ -460,12 +1225,13 @@ int pa__init(pa_module*m) {
 
     if (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, "restore_port", &restore_port) < 0) {
-        pa_log("restore_port=, restore_volume= and restore_muted= expect boolean arguments");
+        pa_modargs_get_value_boolean(ma, "restore_port", &restore_port) < 0 ||
+        pa_modargs_get_value_boolean(ma, "restore_formats", &restore_formats) < 0) {
+        pa_log("restore_port, restore_volume, restore_muted and restore_formats expect boolean arguments");
         goto fail;
     }
 
-    if (!restore_muted && !restore_volume && !restore_port)
+    if (!restore_muted && !restore_volume && !restore_port && !restore_formats)
         pa_log_warn("Neither restoring volume, nor restoring muted, nor restoring port enabled!");
 
     m->userdata = u = pa_xnew0(struct userdata, 1);
@@ -474,6 +1240,14 @@ int pa__init(pa_module*m) {
     u->restore_volume = restore_volume;
     u->restore_muted = restore_muted;
     u->restore_port = restore_port;
+    u->restore_formats = restore_formats;
+
+    u->subscribed = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+
+    u->protocol = pa_native_protocol_get(m->core);
+    pa_native_protocol_install_ext(u->protocol, m, extension_cb);
+
+    u->connection_unlink_hook_slot = pa_hook_connect(&pa_native_protocol_hooks(u->protocol)[PA_NATIVE_HOOK_CONNECTION_UNLINK], PA_HOOK_NORMAL, (pa_hook_cb_t) connection_unlink_hook_cb, u);
 
     u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK|PA_SUBSCRIPTION_MASK_SOURCE, subscribe_callback, u);
 
@@ -485,8 +1259,14 @@ int pa__init(pa_module*m) {
     if (restore_muted || restore_volume) {
         u->sink_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) sink_fixate_hook_callback, u);
         u->source_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) source_fixate_hook_callback, u);
+
+        u->sink_port_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PORT_CHANGED], PA_HOOK_EARLY, (pa_hook_cb_t) sink_port_hook_callback, u);
+        u->source_port_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_PORT_CHANGED], PA_HOOK_EARLY, (pa_hook_cb_t) source_port_hook_callback, u);
     }
 
+    if (restore_formats)
+        u->sink_put_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_EARLY, (pa_hook_cb_t) sink_put_hook_callback, u);
+
     if (!(fname = pa_state_path("device-volumes", TRUE)))
         goto fail;
 
@@ -496,13 +1276,13 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
-    pa_log_info("Sucessfully opened database file '%s'.", fname);
+    pa_log_info("Successfully opened database file '%s'.", fname);
     pa_xfree(fname);
 
-    for (sink = pa_idxset_first(m->core->sinks, &idx); sink; sink = pa_idxset_next(m->core->sinks, &idx))
+    PA_IDXSET_FOREACH(sink, m->core->sinks, idx)
         subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_NEW, sink->index, u);
 
-    for (source = pa_idxset_first(m->core->sources, &idx); source; source = pa_idxset_next(m->core->sources, &idx))
+    PA_IDXSET_FOREACH(source, m->core->sources, idx)
         subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_NEW, source->index, u);
 
     pa_modargs_free(ma);
@@ -514,7 +1294,7 @@ fail:
     if (ma)
         pa_modargs_free(ma);
 
-    return  -1;
+    return -1;
 }
 
 void pa__done(pa_module*m) {
@@ -536,6 +1316,15 @@ void pa__done(pa_module*m) {
         pa_hook_slot_free(u->sink_new_hook_slot);
     if (u->source_new_hook_slot)
         pa_hook_slot_free(u->source_new_hook_slot);
+    if (u->sink_port_hook_slot)
+        pa_hook_slot_free(u->sink_port_hook_slot);
+    if (u->source_port_hook_slot)
+        pa_hook_slot_free(u->source_port_hook_slot);
+    if (u->sink_put_hook_slot)
+        pa_hook_slot_free(u->sink_put_hook_slot);
+
+    if (u->connection_unlink_hook_slot)
+        pa_hook_slot_free(u->connection_unlink_hook_slot);
 
     if (u->save_time_event)
         u->core->mainloop->time_free(u->save_time_event);
@@ -543,5 +1332,13 @@ void pa__done(pa_module*m) {
     if (u->database)
         pa_database_close(u->database);
 
+    if (u->protocol) {
+        pa_native_protocol_remove_ext(u->protocol, m);
+        pa_native_protocol_unref(u->protocol);
+    }
+
+    if (u->subscribed)
+        pa_idxset_free(u->subscribed, NULL);
+
     pa_xfree(u);
 }
diff --git a/src/modules/module-equalizer-sink.c b/src/modules/module-equalizer-sink.c
new file mode 100644 (file)
index 0000000..da4dd77
--- /dev/null
@@ -0,0 +1,2242 @@
+/***
+  This file is part of PulseAudio.
+
+  This module is based off Lennart Poettering's LADSPA sink and swaps out
+  LADSPA functionality for a dbus-aware STFT OLA based digital equalizer.
+  All new work is published under PulseAudio's original license.
+
+  Copyright 2009 Jason Newton <nevion@gmail.com>
+
+  Original Author:
+  Copyright 2004-2008 Lennart Poettering
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1 of the
+  License, or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <float.h>
+#include <math.h>
+#include <string.h>
+#include <stdint.h>
+
+//#undef __SSE2__
+#ifdef __SSE2__
+#include <xmmintrin.h>
+#include <emmintrin.h>
+#endif
+
+#include <fftw3.h>
+
+#include <pulse/xmalloc.h>
+#include <pulse/timeval.h>
+
+#include <pulsecore/core-rtclock.h>
+#include <pulsecore/i18n.h>
+#include <pulsecore/aupdate.h>
+#include <pulsecore/namereg.h>
+#include <pulsecore/sink.h>
+#include <pulsecore/module.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/log.h>
+#include <pulsecore/rtpoll.h>
+#include <pulsecore/sample-util.h>
+#include <pulsecore/shared.h>
+#include <pulsecore/idxset.h>
+#include <pulsecore/strlist.h>
+#include <pulsecore/database.h>
+#include <pulsecore/protocol-dbus.h>
+#include <pulsecore/dbus-util.h>
+
+#include "module-equalizer-sink-symdef.h"
+
+PA_MODULE_AUTHOR("Jason Newton");
+PA_MODULE_DESCRIPTION(_("General Purpose Equalizer"));
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(FALSE);
+PA_MODULE_USAGE(
+        _("sink_name=<name of the sink> "
+          "sink_properties=<properties for the sink> "
+          "sink_master=<sink to connect to> "
+          "format=<sample format> "
+          "rate=<sample rate> "
+          "channels=<number of channels> "
+          "channel_map=<channel map> "
+          "autoloaded=<set if this module is being loaded automatically> "
+          "use_volume_sharing=<yes or no> "
+         ));
+
+#define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
+#define DEFAULT_AUTOLOADED FALSE
+
+struct userdata {
+    pa_module *module;
+    pa_sink *sink;
+    pa_sink_input *sink_input;
+    pa_bool_t autoloaded;
+
+    size_t channels;
+    size_t fft_size;//length (res) of fft
+    size_t window_size;/*
+                        *sliding window size
+                        *effectively chooses R
+                        */
+    size_t R;/* the hop size between overlapping windows
+              * the latency of the filter, calculated from window_size
+              * based on constraints of COLA and window function
+              */
+    //for twiddling with pulseaudio
+    size_t overlap_size;//window_size-R
+    size_t samples_gathered;
+    size_t input_buffer_max;
+    //message
+    float *W;//windowing function (time domain)
+    float *work_buffer, **input, **overlap_accum;
+    fftwf_complex *output_window;
+    fftwf_plan forward_plan, inverse_plan;
+    //size_t samplings;
+
+    float **Xs;
+    float ***Hs;//thread updatable copies of the freq response filters (magnitude based)
+    pa_aupdate **a_H;
+    pa_memblockq *input_q;
+    char *output_buffer;
+    size_t output_buffer_length;
+    size_t output_buffer_max_length;
+    pa_memblockq *output_q;
+    pa_bool_t first_iteration;
+
+    pa_dbus_protocol *dbus_protocol;
+    char *dbus_path;
+
+    pa_database *database;
+    char **base_profiles;
+};
+
+static const char* const valid_modargs[] = {
+    "sink_name",
+    "sink_properties",
+    "sink_master",
+    "format",
+    "rate",
+    "channels",
+    "channel_map",
+    "autoloaded",
+    "use_volume_sharing",
+    NULL
+};
+
+#define v_size 4
+#define SINKLIST "equalized_sinklist"
+#define EQDB "equalizer_db"
+#define EQ_STATE_DB "equalizer-state"
+#define FILTER_SIZE(u) ((u)->fft_size / 2 + 1)
+#define CHANNEL_PROFILE_SIZE(u) (FILTER_SIZE(u) + 1)
+#define FILTER_STATE_SIZE(u) (CHANNEL_PROFILE_SIZE(u) * (u)->channels)
+
+static void dbus_init(struct userdata *u);
+static void dbus_done(struct userdata *u);
+
+static void hanning_window(float *W, size_t window_size){
+    /* h=.5*(1-cos(2*pi*j/(window_size+1)), COLA for R=(M+1)/2 */
+    for (size_t i = 0; i < window_size; ++i)
+        W[i] = (float).5 * (1 - cos(2*M_PI*i / (window_size+1)));
+}
+
+static void fix_filter(float *H, size_t fft_size){
+    /* divide out the fft gain */
+    for (size_t i = 0; i < fft_size / 2 + 1; ++i)
+        H[i] /= fft_size;
+}
+
+static void interpolate(float *samples, size_t length, uint32_t *xs, float *ys, size_t n_points){
+    /* Note that xs must be monotonically increasing! */
+    float x_range_lower, x_range_upper, c0;
+
+    pa_assert(n_points >= 2);
+    pa_assert(xs[0] == 0);
+    pa_assert(xs[n_points - 1] == length - 1);
+
+    for (size_t x = 0, x_range_lower_i = 0; x < length-1; ++x) {
+        pa_assert(x_range_lower_i < n_points-1);
+
+        x_range_lower = (float) xs[x_range_lower_i];
+        x_range_upper = (float) xs[x_range_lower_i+1];
+
+        pa_assert_se(x_range_lower < x_range_upper);
+        pa_assert_se(x >= x_range_lower);
+        pa_assert_se(x <= x_range_upper);
+
+        /* bilinear-interpolation of coefficients specified */
+        c0 = (x-x_range_lower) / (x_range_upper-x_range_lower);
+        pa_assert(c0 >= 0 && c0 <= 1.0);
+
+        samples[x] = ((1.0f - c0) * ys[x_range_lower_i] + c0 * ys[x_range_lower_i + 1]);
+        while(x >= xs[x_range_lower_i + 1])
+            x_range_lower_i++;
+    }
+
+    samples[length-1] = ys[n_points-1];
+}
+
+static pa_bool_t is_monotonic(const uint32_t *xs, size_t length) {
+    pa_assert(xs);
+
+    if (length < 2)
+        return TRUE;
+
+    for(size_t i = 1; i < length; ++i)
+        if (xs[i] <= xs[i-1])
+            return FALSE;
+
+    return TRUE;
+}
+
+/* ensures memory allocated is a multiple of v_size and aligned */
+static void * alloc(size_t x, size_t s){
+    size_t f;
+    float *t;
+
+    f = PA_ROUND_UP(x*s, sizeof(float)*v_size);
+    pa_assert_se(t = fftwf_malloc(f));
+    pa_memzero(t, f);
+
+    return t;
+}
+
+static void alloc_input_buffers(struct userdata *u, size_t min_buffer_length){
+    if (min_buffer_length <= u->input_buffer_max)
+        return;
+
+    pa_assert(min_buffer_length >= u->window_size);
+    for (size_t c = 0; c < u->channels; ++c) {
+        float *tmp = alloc(min_buffer_length, sizeof(float));
+        if (u->input[c]) {
+            if (!u->first_iteration)
+                memcpy(tmp, u->input[c], u->overlap_size * sizeof(float));
+            free(u->input[c]);
+        }
+        u->input[c] = tmp;
+    }
+    u->input_buffer_max = min_buffer_length;
+}
+
+/* Called from I/O thread context */
+static int sink_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
+    struct userdata *u = PA_SINK(o)->userdata;
+
+    switch (code) {
+
+        case PA_SINK_MESSAGE_GET_LATENCY: {
+            //size_t fs=pa_frame_size(&u->sink->sample_spec);
+
+            /* The sink is _put() before the sink input is, so let's
+             * make sure we don't access it in that time. Also, the
+             * sink input is first shut down, the sink second. */
+            if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
+                !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state)) {
+                *((pa_usec_t*) data) = 0;
+                return 0;
+            }
+
+            *((pa_usec_t*) data) =
+                /* Get the latency of the master sink */
+                pa_sink_get_latency_within_thread(u->sink_input->sink) +
+
+                /* Add the latency internal to our sink input on top */
+                pa_bytes_to_usec(pa_memblockq_get_length(u->output_q) +
+                                 pa_memblockq_get_length(u->input_q), &u->sink_input->sink->sample_spec) +
+                pa_bytes_to_usec(pa_memblockq_get_length(u->sink_input->thread_info.render_memblockq), &u->sink_input->sink->sample_spec);
+            //    pa_bytes_to_usec(u->samples_gathered * fs, &u->sink->sample_spec);
+            //+ pa_bytes_to_usec(u->latency * fs, ss)
+            return 0;
+        }
+    }
+
+    return pa_sink_process_msg(o, code, data, offset, chunk);
+}
+
+
+/* Called from main context */
+static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
+    struct userdata *u;
+
+    pa_sink_assert_ref(s);
+    pa_assert_se(u = s->userdata);
+
+    if (!PA_SINK_IS_LINKED(state) ||
+        !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
+        return 0;
+
+    pa_sink_input_cork(u->sink_input, state == PA_SINK_SUSPENDED);
+    return 0;
+}
+
+/* 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);
+
+    if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
+        !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
+        return;
+
+    /* Just hand this one over to the master sink */
+    pa_sink_input_request_rewind(u->sink_input, s->thread_info.rewind_nbytes+pa_memblockq_get_length(u->input_q), TRUE, FALSE, FALSE);
+}
+
+/* Called from I/O thread context */
+static void sink_update_requested_latency_cb(pa_sink *s) {
+    struct userdata *u;
+
+    pa_sink_assert_ref(s);
+    pa_assert_se(u = s->userdata);
+
+    if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
+        !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
+        return;
+
+    /* Just hand this one over to the master sink */
+    pa_sink_input_set_requested_latency_within_thread(
+            u->sink_input,
+            pa_sink_get_requested_latency_within_thread(s));
+}
+
+/* Called from main context */
+static void sink_set_volume_cb(pa_sink *s) {
+    struct userdata *u;
+
+    pa_sink_assert_ref(s);
+    pa_assert_se(u = s->userdata);
+
+    if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)) ||
+        !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
+        return;
+
+    pa_sink_input_set_volume(u->sink_input, &s->real_volume, s->save_volume, TRUE);
+}
+
+/* Called from main context */
+static void sink_set_mute_cb(pa_sink *s) {
+    struct userdata *u;
+
+    pa_sink_assert_ref(s);
+    pa_assert_se(u = s->userdata);
+
+    if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)) ||
+        !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
+        return;
+
+    pa_sink_input_set_mute(u->sink_input, s->muted, s->save_muted);
+}
+
+#if 1
+//reference implementation
+static void dsp_logic(
+    float * restrict dst,//used as a temp array too, needs to be fft_length!
+    float * restrict src,/*input data w/ overlap at start,
+                               *automatically cycled in routine
+                               */
+    float * restrict overlap,
+    const float X,//multiplier
+    const float * restrict H,//The freq. magnitude scalers filter
+    const float * restrict W,//The windowing function
+    fftwf_complex * restrict output_window,//The transformed windowed src
+    struct userdata *u){
+
+    //use a linear-phase sliding STFT and overlap-add method (for each channel)
+    //window the data
+    for(size_t j = 0; j < u->window_size; ++j){
+        dst[j] = X * W[j] * src[j];
+    }
+    //zero pad the remaining fft window
+    memset(dst + u->window_size, 0, (u->fft_size - u->window_size) * sizeof(float));
+    //Processing is done here!
+    //do fft
+    fftwf_execute_dft_r2c(u->forward_plan, dst, output_window);
+    //perform filtering
+    for(size_t j = 0; j < FILTER_SIZE(u); ++j){
+        u->output_window[j][0] *= H[j];
+        u->output_window[j][1] *= H[j];
+    }
+    //inverse fft
+    fftwf_execute_dft_c2r(u->inverse_plan, output_window, dst);
+    ////debug: tests overlapping add
+    ////and negates ALL PREVIOUS processing
+    ////yields a perfect reconstruction if COLA is held
+    //for(size_t j = 0; j < u->window_size; ++j){
+    //    u->work_buffer[j] = u->W[j] * u->input[c][j];
+    //}
+
+    //overlap add and preserve overlap component from this window (linear phase)
+    for(size_t j = 0; j < u->overlap_size; ++j){
+        u->work_buffer[j] += overlap[j];
+        overlap[j] = dst[u->R + j];
+    }
+    ////debug: tests if basic buffering works
+    ////shouldn't modify the signal AT ALL (beyond roundoff)
+    //for(size_t j = 0; j < u->window_size;++j){
+    //    u->work_buffer[j] = u->input[c][j];
+    //}
+
+    //preserve the needed input for the next window's overlap
+    memmove(src, src + u->R,
+        (u->samples_gathered - u->R) * sizeof(float)
+    );
+}
+#else
+typedef float v4sf __attribute__ ((__aligned__(v_size * sizeof(float))));
+typedef union float_vector {
+    float f[v_size];
+    v4sf v;
+    __m128 m;
+} float_vector_t;
+
+//regardless of sse enabled, the loops in here assume
+//16 byte aligned addresses and memory allocations divisible by v_size
+static void dsp_logic(
+    float * restrict dst,//used as a temp array too, needs to be fft_length!
+    float * restrict src,/*input data w/ overlap at start,
+                               *automatically cycled in routine
+                               */
+    float * restrict overlap,//The size of the overlap
+    const float X,//multiplier
+    const float * restrict H,//The freq. magnitude scalers filter
+    const float * restrict W,//The windowing function
+    fftwf_complex * restrict output_window,//The transformed windowed src
+    struct userdata *u){//Collection of constants
+    const size_t overlap_size = PA_ROUND_UP(u->overlap_size, v_size);
+    float_vector_t x;
+    x.f[0] = x.f[1] = x.f[2] = x.f[3] = X;
+
+    //assert(u->samples_gathered >= u->R);
+    //use a linear-phase sliding STFT and overlap-add method
+    for(size_t j = 0; j < u->window_size; j += v_size){
+        //dst[j] = W[j] * src[j];
+        float_vector_t *d = (float_vector_t*) (dst + j);
+        float_vector_t *w = (float_vector_t*) (W + j);
+        float_vector_t *s = (float_vector_t*) (src + j);
+//#if __SSE2__
+        d->m = _mm_mul_ps(x.m, _mm_mul_ps(w->m, s->m));
+//        d->v = x->v * w->v * s->v;
+//#endif
+    }
+    //zero pad the remaining fft window
+    memset(dst + u->window_size, 0, (u->fft_size - u->window_size) * sizeof(float));
+
+    //Processing is done here!
+    //do fft
+    fftwf_execute_dft_r2c(u->forward_plan, dst, output_window);
+    //perform filtering - purely magnitude based
+    for(size_t j = 0; j < FILTER_SIZE; j += v_size / 2){
+        //output_window[j][0]*=H[j];
+        //output_window[j][1]*=H[j];
+        float_vector_t *d = (float_vector_t*)( ((float *) output_window) + 2 * j);
+        float_vector_t h;
+        h.f[0] = h.f[1] = H[j];
+        h.f[2] = h.f[3] = H[j + 1];
+//#if __SSE2__
+        d->m = _mm_mul_ps(d->m, h.m);
+//#else
+//        d->v = d->v * h.v;
+//#endif
+    }
+
+    //inverse fft
+    fftwf_execute_dft_c2r(u->inverse_plan, output_window, dst);
+
+    ////debug: tests overlapping add
+    ////and negates ALL PREVIOUS processing
+    ////yields a perfect reconstruction if COLA is held
+    //for(size_t j = 0; j < u->window_size; ++j){
+    //    dst[j] = W[j] * src[j];
+    //}
+
+    //overlap add and preserve overlap component from this window (linear phase)
+    for(size_t j = 0; j < overlap_size; j += v_size){
+        //dst[j]+=overlap[j];
+        //overlap[j]+=dst[j+R];
+        float_vector_t *d = (float_vector_t*)(dst + j);
+        float_vector_t *o = (float_vector_t*)(overlap + j);
+//#if __SSE2__
+        d->m = _mm_add_ps(d->m, o->m);
+        o->m = ((float_vector_t*)(dst + u->R + j))->m;
+//#else
+//        d->v = d->v + o->v;
+//        o->v = ((float_vector_t*)(dst + u->R + j))->v;
+//#endif
+    }
+    //memcpy(overlap, dst+u->R, u->overlap_size * sizeof(float)); //overlap preserve (debug)
+    //zero out the bit beyond the real overlap so we don't add garbage next iteration
+    memset(overlap + u->overlap_size, 0, overlap_size - u->overlap_size);
+
+    ////debug: tests if basic buffering works
+    ////shouldn't modify the signal AT ALL (beyond roundoff)
+    //for(size_t j = 0; j < u->window_size; ++j){
+    //    dst[j] = src[j];
+    //}
+
+    //preserve the needed input for the next window's overlap
+    memmove(src, src + u->R,
+        (u->samples_gathered - u->R) * sizeof(float)
+    );
+}
+#endif
+
+static void flatten_to_memblockq(struct userdata *u){
+    size_t mbs = pa_mempool_block_size_max(u->sink->core->mempool);
+    pa_memchunk tchunk;
+    char *dst;
+    size_t i = 0;
+    while(i < u->output_buffer_length){
+        tchunk.index = 0;
+        tchunk.length = PA_MIN((u->output_buffer_length - i), mbs);
+        tchunk.memblock = pa_memblock_new(u->sink->core->mempool, tchunk.length);
+        //pa_log_debug("pushing %ld into the q", tchunk.length);
+        dst = pa_memblock_acquire(tchunk.memblock);
+        memcpy(dst, u->output_buffer + i, tchunk.length);
+        pa_memblock_release(tchunk.memblock);
+        pa_memblockq_push(u->output_q, &tchunk);
+        pa_memblock_unref(tchunk.memblock);
+        i += tchunk.length;
+    }
+}
+
+static void process_samples(struct userdata *u){
+    size_t fs = pa_frame_size(&(u->sink->sample_spec));
+    unsigned a_i;
+    float *H, X;
+    size_t iterations, offset;
+    pa_assert(u->samples_gathered >= u->window_size);
+    iterations = (u->samples_gathered - u->overlap_size) / u->R;
+    //make sure there is enough buffer memory allocated
+    if(iterations * u->R * fs > u->output_buffer_max_length){
+        u->output_buffer_max_length = iterations * u->R * fs;
+        pa_xfree(u->output_buffer);
+        u->output_buffer = pa_xmalloc(u->output_buffer_max_length);
+    }
+    u->output_buffer_length = iterations * u->R * fs;
+
+    for(size_t iter = 0; iter < iterations; ++iter){
+        offset = iter * u->R * fs;
+        for(size_t c = 0;c < u->channels; c++) {
+            a_i = pa_aupdate_read_begin(u->a_H[c]);
+            X = u->Xs[c][a_i];
+            H = u->Hs[c][a_i];
+            dsp_logic(
+                u->work_buffer,
+                u->input[c],
+                u->overlap_accum[c],
+                X,
+                H,
+                u->W,
+                u->output_window,
+                u
+            );
+            pa_aupdate_read_end(u->a_H[c]);
+            if(u->first_iteration){
+                /* The windowing function will make the audio ramped in, as a cheap fix we can
+                 * undo the windowing (for non-zero window values)
+                 */
+                for(size_t i = 0; i < u->overlap_size; ++i){
+                    u->work_buffer[i] = u->W[i] <= FLT_EPSILON ? u->work_buffer[i] : u->work_buffer[i] / u->W[i];
+                }
+            }
+            pa_sample_clamp(PA_SAMPLE_FLOAT32NE, (uint8_t *) (((float *)u->output_buffer) + c) + offset, fs, u->work_buffer, sizeof(float), u->R);
+        }
+        if(u->first_iteration){
+            u->first_iteration = FALSE;
+        }
+        u->samples_gathered -= u->R;
+    }
+    flatten_to_memblockq(u);
+}
+
+static void input_buffer(struct userdata *u, pa_memchunk *in){
+    size_t fs = pa_frame_size(&(u->sink->sample_spec));
+    size_t samples = in->length/fs;
+    float *src = pa_memblock_acquire_chunk(in);
+    pa_assert(u->samples_gathered + samples <= u->input_buffer_max);
+    for(size_t c = 0; c < u->channels; c++) {
+        //buffer with an offset after the overlap from previous
+        //iterations
+        pa_assert_se(
+            u->input[c] + u->samples_gathered + samples <= u->input[c] + u->input_buffer_max
+        );
+        pa_sample_clamp(PA_SAMPLE_FLOAT32NE, u->input[c] + u->samples_gathered, sizeof(float), src + c, fs, samples);
+    }
+    u->samples_gathered += samples;
+    pa_memblock_release(in->memblock);
+}
+
+/* Called from I/O thread context */
+static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
+    struct userdata *u;
+    size_t fs, target_samples;
+    size_t mbs;
+    //struct timeval start, end;
+    pa_memchunk tchunk;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+    pa_assert(chunk);
+    pa_assert(u->sink);
+
+    /* FIXME: Please clean this up. I see more commented code lines
+     * than uncommented code lines. I am sorry, but I am too dumb to
+     * understand this. */
+
+    fs = pa_frame_size(&(u->sink->sample_spec));
+    mbs = pa_mempool_block_size_max(u->sink->core->mempool);
+    if(pa_memblockq_get_length(u->output_q) > 0){
+        //pa_log_debug("qsize is %ld", pa_memblockq_get_length(u->output_q));
+        goto END;
+    }
+    //nbytes = PA_MIN(nbytes, pa_mempool_block_size_max(u->sink->core->mempool));
+    target_samples = PA_ROUND_UP(nbytes / fs, u->R);
+    ////pa_log_debug("vanilla mbs = %ld",mbs);
+    //mbs = PA_ROUND_DOWN(mbs / fs, u->R);
+    //mbs = PA_MAX(mbs, u->R);
+    //target_samples = PA_MAX(target_samples, mbs);
+    //pa_log_debug("target samples: %ld", target_samples);
+    if(u->first_iteration){
+        //allocate request_size
+        target_samples = PA_MAX(target_samples, u->window_size);
+    }else{
+        //allocate request_size + overlap
+        target_samples += u->overlap_size;
+    }
+    alloc_input_buffers(u, target_samples);
+    //pa_log_debug("post target samples: %ld", target_samples);
+    chunk->memblock = NULL;
+
+    /* Hmm, process any rewind request that might be queued up */
+    pa_sink_process_rewind(u->sink, 0);
+
+    //pa_log_debug("start output-buffered %ld, input-buffered %ld, requested %ld",buffered_samples,u->samples_gathered,samples_requested);
+    //pa_rtclock_get(&start);
+    do{
+        size_t input_remaining = target_samples - u->samples_gathered;
+       // pa_log_debug("input remaining %ld samples", input_remaining);
+        pa_assert(input_remaining > 0);
+        while (pa_memblockq_peek(u->input_q, &tchunk) < 0) {
+            //pa_sink_render(u->sink, input_remaining * fs, &tchunk);
+            pa_sink_render_full(u->sink, PA_MIN(input_remaining * fs, mbs), &tchunk);
+            pa_memblockq_push(u->input_q, &tchunk);
+            pa_memblock_unref(tchunk.memblock);
+        }
+        pa_assert(tchunk.memblock);
+
+        tchunk.length = PA_MIN(input_remaining * fs, tchunk.length);
+
+        pa_memblockq_drop(u->input_q, tchunk.length);
+        //pa_log_debug("asked for %ld input samples, got %ld samples",input_remaining,buffer->length/fs);
+        /* copy new input */
+        //pa_rtclock_get(start);
+       // pa_log_debug("buffering %ld bytes", tchunk.length);
+        input_buffer(u, &tchunk);
+        //pa_rtclock_get(&end);
+        //pa_log_debug("Took %0.5f seconds to setup", pa_timeval_diff(end, start) / (double) PA_USEC_PER_SEC);
+        pa_memblock_unref(tchunk.memblock);
+    } while(u->samples_gathered < target_samples);
+
+    //pa_rtclock_get(&end);
+    //pa_log_debug("Took %0.6f seconds to get data", (double) pa_timeval_diff(&end, &start) / PA_USEC_PER_SEC);
+
+    pa_assert(u->fft_size >= u->window_size);
+    pa_assert(u->R < u->window_size);
+    //pa_rtclock_get(&start);
+    /* process a block */
+    process_samples(u);
+    //pa_rtclock_get(&end);
+    //pa_log_debug("Took %0.6f seconds to process", (double) pa_timeval_diff(&end, &start) / PA_USEC_PER_SEC);
+END:
+    pa_assert_se(pa_memblockq_peek(u->output_q, chunk) >= 0);
+    pa_assert(chunk->memblock);
+    pa_memblockq_drop(u->output_q, chunk->length);
+
+    /** FIXME: Uh? you need to unref the chunk here! */
+
+    //pa_log_debug("gave %ld", chunk->length/fs);
+    //pa_log_debug("end pop");
+    return 0;
+}
+
+/* Called from main context */
+static void sink_input_volume_changed_cb(pa_sink_input *i) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    pa_sink_volume_changed(u->sink, &i->volume);
+}
+
+/* Called from main context */
+static void sink_input_mute_changed_cb(pa_sink_input *i) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    pa_sink_mute_changed(u->sink, i->muted);
+}
+
+#if 0
+static void reset_filter(struct userdata *u){
+    size_t fs = pa_frame_size(&u->sink->sample_spec);
+    size_t max_request;
+
+    u->samples_gathered = 0;
+
+    for(size_t i = 0; i < u->channels; ++i)
+        pa_memzero(u->overlap_accum[i], u->overlap_size * sizeof(float));
+
+    u->first_iteration = TRUE;
+    //set buffer size to max request, no overlap copy
+    max_request = PA_ROUND_UP(pa_sink_input_get_max_request(u->sink_input) / fs , u->R);
+    max_request = PA_MAX(max_request, u->window_size);
+    pa_sink_set_max_request_within_thread(u->sink, max_request * fs);
+}
+#endif
+
+/* Called from I/O thread context */
+static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
+    struct userdata *u;
+    size_t amount = 0;
+
+    pa_log_debug("Rewind callback!");
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    if (u->sink->thread_info.rewind_nbytes > 0) {
+        size_t max_rewrite;
+
+        //max_rewrite = nbytes;
+        max_rewrite = nbytes + pa_memblockq_get_length(u->input_q);
+        //PA_MIN(pa_memblockq_get_length(u->input_q), nbytes);
+        amount = PA_MIN(u->sink->thread_info.rewind_nbytes, max_rewrite);
+        u->sink->thread_info.rewind_nbytes = 0;
+
+        if (amount > 0) {
+            //invalidate the output q
+            pa_memblockq_seek(u->input_q, - (int64_t) amount, PA_SEEK_RELATIVE, TRUE);
+            pa_log("Resetting filter");
+            //reset_filter(u); //this is the "proper" thing to do...
+        }
+    }
+
+    pa_sink_process_rewind(u->sink, amount);
+    pa_memblockq_rewind(u->input_q, nbytes);
+}
+
+/* Called from I/O thread context */
+static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    /* FIXME: Too small max_rewind:
+     * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
+    pa_memblockq_set_maxrewind(u->input_q, nbytes);
+    pa_sink_set_max_rewind_within_thread(u->sink, nbytes);
+}
+
+/* Called from I/O thread context */
+static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) {
+    struct userdata *u;
+    size_t fs;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    fs = pa_frame_size(&u->sink_input->sample_spec);
+    pa_sink_set_max_request_within_thread(u->sink, PA_ROUND_UP(nbytes / fs, u->R) * fs);
+}
+
+/* Called from I/O thread context */
+static void sink_input_update_sink_latency_range_cb(pa_sink_input *i) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
+}
+
+/* Called from I/O thread context */
+static void sink_input_update_sink_fixed_latency_cb(pa_sink_input *i) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
+}
+
+/* Called from I/O thread context */
+static void sink_input_detach_cb(pa_sink_input *i) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    pa_sink_detach_within_thread(u->sink);
+
+    pa_sink_set_rtpoll(u->sink, NULL);
+}
+
+/* Called from I/O thread context */
+static void sink_input_attach_cb(pa_sink_input *i) {
+    struct userdata *u;
+    size_t fs, max_request;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    pa_sink_set_rtpoll(u->sink, i->sink->thread_info.rtpoll);
+    pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
+    pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
+
+    fs = pa_frame_size(&u->sink_input->sample_spec);
+    /* set buffer size to max request, no overlap copy */
+    max_request = PA_ROUND_UP(pa_sink_input_get_max_request(u->sink_input) / fs, u->R);
+    max_request = PA_MAX(max_request, u->window_size);
+
+    pa_sink_set_max_request_within_thread(u->sink, max_request * fs);
+
+    /* FIXME: Too small max_rewind:
+     * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
+    pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i));
+
+    pa_sink_attach_within_thread(u->sink);
+}
+
+/* Called from main context */
+static void sink_input_kill_cb(pa_sink_input *i) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    /* The order here matters! We first kill the sink input, followed
+     * by the sink. That means the sink callbacks must be protected
+     * against an unconnected sink input! */
+    pa_sink_input_unlink(u->sink_input);
+    pa_sink_unlink(u->sink);
+
+    pa_sink_input_unref(u->sink_input);
+    u->sink_input = NULL;
+
+    /* Leave u->sink alone for now, it will be cleaned up on module
+     * unload (and it is needed during unload as well). */
+
+    pa_module_unload_request(u->module, TRUE);
+}
+
+/* Called from IO thread context */
+static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t state) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    /* If we are added for the first time, ask for a rewinding so that
+     * we are heard right-away. */
+    if (PA_SINK_INPUT_IS_LINKED(state) &&
+        i->thread_info.state == PA_SINK_INPUT_INIT) {
+        pa_log_debug("Requesting rewind due to state change.");
+        pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
+    }
+}
+
+static void pack(char **strs, size_t len, char **packed, size_t *length){
+    size_t t_len = 0;
+    size_t headers = (1+len) * sizeof(uint16_t);
+    char *p;
+    for(size_t i = 0; i < len; ++i){
+        t_len += strlen(strs[i]);
+    }
+    *length = headers + t_len;
+    p = *packed = pa_xmalloc0(*length);
+    *((uint16_t *) p) = (uint16_t) len;
+    p += sizeof(uint16_t);
+    for(size_t i = 0; i < len; ++i){
+        uint16_t l = strlen(strs[i]);
+        *((uint16_t *) p) = (uint16_t) l;
+        p += sizeof(uint16_t);
+        memcpy(p, strs[i], l);
+        p += l;
+    }
+}
+static void unpack(char *str, size_t length, char ***strs, size_t *len){
+    char *p = str;
+    *len = *((uint16_t *) p);
+    p += sizeof(uint16_t);
+    *strs = pa_xnew(char *, *len);
+
+    for(size_t i = 0; i < *len; ++i){
+        size_t l = *((uint16_t *) p);
+        p += sizeof(uint16_t);
+        (*strs)[i] = pa_xnew(char, l + 1);
+        memcpy((*strs)[i], p, l);
+        (*strs)[i][l] = '\0';
+        p += l;
+    }
+}
+static void save_profile(struct userdata *u, size_t channel, char *name){
+    unsigned a_i;
+    const size_t profile_size = CHANNEL_PROFILE_SIZE(u) * sizeof(float);
+    float *H_n, *profile;
+    const float *H;
+    pa_datum key, data;
+    profile = pa_xnew0(float, profile_size);
+    a_i = pa_aupdate_read_begin(u->a_H[channel]);
+    profile[0] = u->Xs[a_i][channel];
+    H = u->Hs[channel][a_i];
+    H_n = profile + 1;
+    for(size_t i = 0 ; i < FILTER_SIZE(u); ++i){
+        H_n[i] = H[i] * u->fft_size;
+        //H_n[i] = H[i];
+    }
+    pa_aupdate_read_end(u->a_H[channel]);
+    key.data=name;
+    key.size = strlen(key.data);
+    data.data = profile;
+    data.size = profile_size;
+    pa_database_set(u->database, &key, &data, TRUE);
+    pa_database_sync(u->database);
+    if(u->base_profiles[channel]){
+        pa_xfree(u->base_profiles[channel]);
+    }
+    u->base_profiles[channel] = pa_xstrdup(name);
+}
+
+static void save_state(struct userdata *u){
+    unsigned a_i;
+    const size_t filter_state_size = FILTER_STATE_SIZE(u) * sizeof(float);
+    float *H_n, *state;
+    float *H;
+    pa_datum key, data;
+    pa_database *database;
+    char *dbname;
+    char *packed;
+    size_t packed_length;
+
+    pack(u->base_profiles, u->channels, &packed, &packed_length);
+    state = (float *) pa_xmalloc0(filter_state_size + packed_length);
+    memcpy(state + FILTER_STATE_SIZE(u), packed, packed_length);
+    pa_xfree(packed);
+
+    for(size_t c = 0; c < u->channels; ++c){
+        a_i = pa_aupdate_read_begin(u->a_H[c]);
+        state[c * CHANNEL_PROFILE_SIZE(u)] = u->Xs[c][a_i];
+        H = u->Hs[c][a_i];
+        H_n = &state[c * CHANNEL_PROFILE_SIZE(u) + 1];
+        memcpy(H_n, H, FILTER_SIZE(u) * sizeof(float));
+        pa_aupdate_read_end(u->a_H[c]);
+    }
+
+    key.data = u->sink->name;
+    key.size = strlen(key.data);
+    data.data = state;
+    data.size = filter_state_size + packed_length;
+    //thread safety for 0.9.17?
+    pa_assert_se(dbname = pa_state_path(EQ_STATE_DB, FALSE));
+    pa_assert_se(database = pa_database_open(dbname, TRUE));
+    pa_xfree(dbname);
+
+    pa_database_set(database, &key, &data, TRUE);
+    pa_database_sync(database);
+    pa_database_close(database);
+    pa_xfree(state);
+}
+
+static void remove_profile(pa_core *c, char *name){
+    pa_datum key;
+    pa_database *database;
+    key.data = name;
+    key.size = strlen(key.data);
+    pa_assert_se(database = pa_shared_get(c, EQDB));
+    pa_database_unset(database, &key);
+    pa_database_sync(database);
+}
+
+static const char* load_profile(struct userdata *u, size_t channel, char *name){
+    unsigned a_i;
+    pa_datum key, value;
+    const size_t profile_size = CHANNEL_PROFILE_SIZE(u) * sizeof(float);
+    key.data = name;
+    key.size = strlen(key.data);
+    if(pa_database_get(u->database, &key, &value) != NULL){
+        if(value.size == profile_size){
+            float *profile = (float *) value.data;
+            a_i = pa_aupdate_write_begin(u->a_H[channel]);
+            u->Xs[channel][a_i] = profile[0];
+            memcpy(u->Hs[channel][a_i], profile + 1, FILTER_SIZE(u) * sizeof(float));
+            fix_filter(u->Hs[channel][a_i], u->fft_size);
+            pa_aupdate_write_end(u->a_H[channel]);
+            pa_xfree(u->base_profiles[channel]);
+            u->base_profiles[channel] = pa_xstrdup(name);
+        }else{
+            return "incompatible size";
+        }
+        pa_datum_free(&value);
+    }else{
+        return "profile doesn't exist";
+    }
+    return NULL;
+}
+
+static void load_state(struct userdata *u){
+    unsigned a_i;
+    float *H;
+    pa_datum key, value;
+    pa_database *database;
+    char *dbname;
+    pa_assert_se(dbname = pa_state_path(EQ_STATE_DB, FALSE));
+    database = pa_database_open(dbname, FALSE);
+    pa_xfree(dbname);
+    if(!database){
+        pa_log("No resume state");
+        return;
+    }
+
+    key.data = u->sink->name;
+    key.size = strlen(key.data);
+
+    if(pa_database_get(database, &key, &value) != NULL){
+        if(value.size > FILTER_STATE_SIZE(u) * sizeof(float) + sizeof(uint16_t)){
+            float *state = (float *) value.data;
+            size_t n_profs;
+            char **names;
+            for(size_t c = 0; c < u->channels; ++c){
+                a_i = pa_aupdate_write_begin(u->a_H[c]);
+                H = state + c * CHANNEL_PROFILE_SIZE(u) + 1;
+                u->Xs[c][a_i] = state[c * CHANNEL_PROFILE_SIZE(u)];
+                memcpy(u->Hs[c][a_i], H, FILTER_SIZE(u) * sizeof(float));
+                pa_aupdate_write_end(u->a_H[c]);
+            }
+            unpack(((char *)value.data) + FILTER_STATE_SIZE(u) * sizeof(float), value.size - FILTER_STATE_SIZE(u) * sizeof(float), &names, &n_profs);
+            n_profs = PA_MIN(n_profs, u->channels);
+            for(size_t c = 0; c < n_profs; ++c){
+                pa_xfree(u->base_profiles[c]);
+                u->base_profiles[c] = names[c];
+            }
+            pa_xfree(names);
+        }
+        pa_datum_free(&value);
+    }else{
+        pa_log("resume state exists but is wrong size!");
+    }
+    pa_database_close(database);
+}
+
+/* Called from main context */
+static pa_bool_t sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    if (u->autoloaded)
+        return FALSE;
+
+    return u->sink != dest;
+}
+
+/* Called from main context */
+static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    if (dest) {
+        pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
+        pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
+    } else
+        pa_sink_set_asyncmsgq(u->sink, NULL);
+}
+
+int pa__init(pa_module*m) {
+    struct userdata *u;
+    pa_sample_spec ss;
+    pa_channel_map map;
+    pa_modargs *ma;
+    const char *z;
+    pa_sink *master;
+    pa_sink_input_new_data sink_input_data;
+    pa_sink_new_data sink_data;
+    size_t i;
+    unsigned c;
+    float *H;
+    unsigned a_i;
+    pa_bool_t use_volume_sharing = TRUE;
+
+    pa_assert(m);
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments.");
+        goto fail;
+    }
+
+    if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "sink_master", NULL), PA_NAMEREG_SINK))) {
+        pa_log("Master sink not found");
+        goto fail;
+    }
+
+    ss = master->sample_spec;
+    ss.format = PA_SAMPLE_FLOAT32;
+    map = master->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;
+    }
+
+    //fs = pa_frame_size(&ss);
+
+    if (pa_modargs_get_value_boolean(ma, "use_volume_sharing", &use_volume_sharing) < 0) {
+        pa_log("use_volume_sharing= expects a boolean argument");
+        goto fail;
+    }
+
+    u = pa_xnew0(struct userdata, 1);
+    u->module = m;
+    m->userdata = u;
+
+    u->channels = ss.channels;
+    u->fft_size = pow(2, ceil(log(ss.rate) / log(2)));//probably unstable near corner cases of powers of 2
+    pa_log_debug("fft size: %zd", u->fft_size);
+    u->window_size = 15999;
+    if (u->window_size % 2 == 0)
+        u->window_size--;
+    u->R = (u->window_size + 1) / 2;
+    u->overlap_size = u->window_size - u->R;
+    u->samples_gathered = 0;
+    u->input_buffer_max = 0;
+
+    u->a_H = pa_xnew0(pa_aupdate *, u->channels);
+    u->Xs = pa_xnew0(float *, u->channels);
+    u->Hs = pa_xnew0(float **, u->channels);
+
+    for (c = 0; c < u->channels; ++c) {
+        u->Xs[c] = pa_xnew0(float, 2);
+        u->Hs[c] = pa_xnew0(float *, 2);
+        for (i = 0; i < 2; ++i)
+            u->Hs[c][i] = alloc(FILTER_SIZE(u), sizeof(float));
+    }
+
+    u->W = alloc(u->window_size, sizeof(float));
+    u->work_buffer = alloc(u->fft_size, sizeof(float));
+    u->input = pa_xnew0(float *, u->channels);
+    u->overlap_accum = pa_xnew0(float *, u->channels);
+    for (c = 0; c < u->channels; ++c) {
+        u->a_H[c] = pa_aupdate_new();
+        u->input[c] = NULL;
+        u->overlap_accum[c] = alloc(u->overlap_size, sizeof(float));
+    }
+    u->output_window = alloc(FILTER_SIZE(u), sizeof(fftwf_complex));
+    u->forward_plan = fftwf_plan_dft_r2c_1d(u->fft_size, u->work_buffer, u->output_window, FFTW_ESTIMATE);
+    u->inverse_plan = fftwf_plan_dft_c2r_1d(u->fft_size, u->output_window, u->work_buffer, FFTW_ESTIMATE);
+
+    hanning_window(u->W, u->window_size);
+    u->first_iteration = TRUE;
+
+    u->base_profiles = pa_xnew0(char *, u->channels);
+    for (c = 0; c < u->channels; ++c)
+        u->base_profiles[c] = pa_xstrdup("default");
+
+    /* Create sink */
+    pa_sink_new_data_init(&sink_data);
+    sink_data.driver = __FILE__;
+    sink_data.module = m;
+    if (!(sink_data.name = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", NULL))))
+        sink_data.name = pa_sprintf_malloc("%s.equalizer", master->name);
+    pa_sink_new_data_set_sample_spec(&sink_data, &ss);
+    pa_sink_new_data_set_channel_map(&sink_data, &map);
+
+    z = pa_proplist_gets(master->proplist, PA_PROP_DEVICE_DESCRIPTION);
+    pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "FFT based equalizer on %s", z ? z : master->name);
+
+    pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, master->name);
+    pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
+
+    if (pa_modargs_get_proplist(ma, "sink_properties", sink_data.proplist, PA_UPDATE_REPLACE) < 0) {
+        pa_log("Invalid properties");
+        pa_sink_new_data_done(&sink_data);
+        goto fail;
+    }
+
+    u->autoloaded = DEFAULT_AUTOLOADED;
+    if (pa_modargs_get_value_boolean(ma, "autoloaded", &u->autoloaded) < 0) {
+        pa_log("Failed to parse autoloaded value");
+        goto fail;
+    }
+
+    u->sink = pa_sink_new(m->core, &sink_data, (master->flags & (PA_SINK_LATENCY | PA_SINK_DYNAMIC_LATENCY))
+                                               | (use_volume_sharing ? PA_SINK_SHARE_VOLUME_WITH_MASTER : 0));
+    pa_sink_new_data_done(&sink_data);
+
+    if (!u->sink) {
+        pa_log("Failed to create sink.");
+        goto fail;
+    }
+
+    u->sink->parent.process_msg = sink_process_msg_cb;
+    u->sink->set_state = sink_set_state_cb;
+    u->sink->update_requested_latency = sink_update_requested_latency_cb;
+    u->sink->request_rewind = sink_request_rewind_cb;
+    pa_sink_set_set_mute_callback(u->sink, sink_set_mute_cb);
+    if (!use_volume_sharing) {
+        pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
+        pa_sink_enable_decibel_volume(u->sink, TRUE);
+    }
+    u->sink->userdata = u;
+
+    u->input_q = pa_memblockq_new("module-equalizer-sink input_q", 0, MEMBLOCKQ_MAXLENGTH, 0, &ss, 1, 1, 0, &u->sink->silence);
+    u->output_q = pa_memblockq_new("module-equalizer-sink output_q", 0, MEMBLOCKQ_MAXLENGTH, 0, &ss, 1, 1, 0, NULL);
+    u->output_buffer = NULL;
+    u->output_buffer_length = 0;
+    u->output_buffer_max_length = 0;
+
+    pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq);
+    //pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(u->R*fs, &ss));
+
+    /* Create sink input */
+    pa_sink_input_new_data_init(&sink_input_data);
+    sink_input_data.driver = __FILE__;
+    sink_input_data.module = m;
+    pa_sink_input_new_data_set_sink(&sink_input_data, master, FALSE);
+    sink_input_data.origin_sink = u->sink;
+    pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Equalized Stream");
+    pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
+    pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss);
+    pa_sink_input_new_data_set_channel_map(&sink_input_data, &map);
+
+    pa_sink_input_new(&u->sink_input, m->core, &sink_input_data);
+    pa_sink_input_new_data_done(&sink_input_data);
+
+    if (!u->sink_input)
+        goto fail;
+
+    u->sink_input->pop = sink_input_pop_cb;
+    u->sink_input->process_rewind = sink_input_process_rewind_cb;
+    u->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
+    u->sink_input->update_max_request = sink_input_update_max_request_cb;
+    u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb;
+    u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb;
+    u->sink_input->kill = sink_input_kill_cb;
+    u->sink_input->attach = sink_input_attach_cb;
+    u->sink_input->detach = sink_input_detach_cb;
+    u->sink_input->state_change = sink_input_state_change_cb;
+    u->sink_input->may_move_to = sink_input_may_move_to_cb;
+    u->sink_input->moving = sink_input_moving_cb;
+    if (!use_volume_sharing)
+        u->sink_input->volume_changed = sink_input_volume_changed_cb;
+    u->sink_input->mute_changed = sink_input_mute_changed_cb;
+    u->sink_input->userdata = u;
+
+    u->sink->input_to_master = u->sink_input;
+
+    dbus_init(u);
+
+    /* default filter to these */
+    for (c = 0; c< u->channels; ++c) {
+        a_i = pa_aupdate_write_begin(u->a_H[c]);
+        H = u->Hs[c][a_i];
+        u->Xs[c][a_i] = 1.0f;
+
+        for(i = 0; i < FILTER_SIZE(u); ++i)
+            H[i] = 1.0 / sqrtf(2.0f);
+
+        fix_filter(H, u->fft_size);
+        pa_aupdate_write_end(u->a_H[c]);
+    }
+
+    /* load old parameters */
+    load_state(u);
+
+    pa_sink_put(u->sink);
+    pa_sink_input_put(u->sink_input);
+
+    pa_modargs_free(ma);
+
+    return 0;
+
+fail:
+    if (ma)
+        pa_modargs_free(ma);
+
+    pa__done(m);
+
+    return -1;
+}
+
+int pa__get_n_used(pa_module *m) {
+    struct userdata *u;
+
+    pa_assert(m);
+    pa_assert_se(u = m->userdata);
+
+    return pa_sink_linked_by(u->sink);
+}
+
+void pa__done(pa_module*m) {
+    struct userdata *u;
+    unsigned c;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    save_state(u);
+
+    dbus_done(u);
+
+    for(c = 0; c < u->channels; ++c)
+        pa_xfree(u->base_profiles[c]);
+    pa_xfree(u->base_profiles);
+
+    /* See comments in sink_input_kill_cb() above regarding
+     * destruction order! */
+
+    if (u->sink_input)
+        pa_sink_input_unlink(u->sink_input);
+
+    if (u->sink)
+        pa_sink_unlink(u->sink);
+
+    if (u->sink_input)
+        pa_sink_input_unref(u->sink_input);
+
+    if (u->sink)
+        pa_sink_unref(u->sink);
+
+    pa_xfree(u->output_buffer);
+    pa_memblockq_free(u->output_q);
+    pa_memblockq_free(u->input_q);
+
+    fftwf_destroy_plan(u->inverse_plan);
+    fftwf_destroy_plan(u->forward_plan);
+    pa_xfree(u->output_window);
+    for (c = 0; c < u->channels; ++c) {
+        pa_aupdate_free(u->a_H[c]);
+        pa_xfree(u->overlap_accum[c]);
+        pa_xfree(u->input[c]);
+    }
+    pa_xfree(u->a_H);
+    pa_xfree(u->overlap_accum);
+    pa_xfree(u->input);
+    pa_xfree(u->work_buffer);
+    pa_xfree(u->W);
+    for (c = 0; c < u->channels; ++c) {
+        pa_xfree(u->Xs[c]);
+        for (size_t i = 0; i < 2; ++i)
+            pa_xfree(u->Hs[c][i]);
+        pa_xfree(u->Hs[c]);
+    }
+    pa_xfree(u->Xs);
+    pa_xfree(u->Hs);
+
+    pa_xfree(u);
+}
+
+/*
+ * DBus Routines and Callbacks
+ */
+#define EXTNAME "org.PulseAudio.Ext.Equalizing1"
+#define MANAGER_PATH "/org/pulseaudio/equalizing1"
+#define MANAGER_IFACE EXTNAME ".Manager"
+#define EQUALIZER_IFACE EXTNAME ".Equalizer"
+static void manager_get_revision(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void manager_get_sinks(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void manager_get_profiles(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void manager_get_all(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void manager_handle_remove_profile(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void equalizer_get_revision(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void equalizer_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void equalizer_get_filter_rate(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void equalizer_get_n_coefs(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void equalizer_get_n_channels(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void equalizer_get_all(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void equalizer_handle_seed_filter(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void equalizer_handle_get_filter_points(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void equalizer_handle_get_filter(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void equalizer_handle_set_filter(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void equalizer_handle_save_profile(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void equalizer_handle_load_profile(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void equalizer_handle_save_state(DBusConnection *conn, DBusMessage *msg, void *_u);
+static void equalizer_handle_get_profile_name(DBusConnection *conn, DBusMessage *msg, void *_u);
+enum manager_method_index {
+    MANAGER_METHOD_REMOVE_PROFILE,
+    MANAGER_METHOD_MAX
+};
+
+pa_dbus_arg_info remove_profile_args[]={
+    {"name", "s","in"},
+};
+
+static pa_dbus_method_handler manager_methods[MANAGER_METHOD_MAX]={
+    [MANAGER_METHOD_REMOVE_PROFILE]={
+        .method_name="RemoveProfile",
+        .arguments=remove_profile_args,
+        .n_arguments=sizeof(remove_profile_args)/sizeof(pa_dbus_arg_info),
+        .receive_cb=manager_handle_remove_profile}
+};
+
+enum manager_handler_index {
+    MANAGER_HANDLER_REVISION,
+    MANAGER_HANDLER_EQUALIZED_SINKS,
+    MANAGER_HANDLER_PROFILES,
+    MANAGER_HANDLER_MAX
+};
+
+static pa_dbus_property_handler manager_handlers[MANAGER_HANDLER_MAX]={
+    [MANAGER_HANDLER_REVISION]={.property_name="InterfaceRevision",.type="u",.get_cb=manager_get_revision,.set_cb=NULL},
+    [MANAGER_HANDLER_EQUALIZED_SINKS]={.property_name="EqualizedSinks",.type="ao",.get_cb=manager_get_sinks,.set_cb=NULL},
+    [MANAGER_HANDLER_PROFILES]={.property_name="Profiles",.type="as",.get_cb=manager_get_profiles,.set_cb=NULL}
+};
+
+pa_dbus_arg_info sink_args[]={
+    {"sink", "o", NULL}
+};
+
+enum manager_signal_index{
+    MANAGER_SIGNAL_SINK_ADDED,
+    MANAGER_SIGNAL_SINK_REMOVED,
+    MANAGER_SIGNAL_PROFILES_CHANGED,
+    MANAGER_SIGNAL_MAX
+};
+
+static pa_dbus_signal_info manager_signals[MANAGER_SIGNAL_MAX]={
+    [MANAGER_SIGNAL_SINK_ADDED]={.name="SinkAdded", .arguments=sink_args, .n_arguments=sizeof(sink_args)/sizeof(pa_dbus_arg_info)},
+    [MANAGER_SIGNAL_SINK_REMOVED]={.name="SinkRemoved", .arguments=sink_args, .n_arguments=sizeof(sink_args)/sizeof(pa_dbus_arg_info)},
+    [MANAGER_SIGNAL_PROFILES_CHANGED]={.name="ProfilesChanged", .arguments=NULL, .n_arguments=0}
+};
+
+static pa_dbus_interface_info manager_info={
+    .name=MANAGER_IFACE,
+    .method_handlers=manager_methods,
+    .n_method_handlers=MANAGER_METHOD_MAX,
+    .property_handlers=manager_handlers,
+    .n_property_handlers=MANAGER_HANDLER_MAX,
+    .get_all_properties_cb=manager_get_all,
+    .signals=manager_signals,
+    .n_signals=MANAGER_SIGNAL_MAX
+};
+
+enum equalizer_method_index {
+    EQUALIZER_METHOD_FILTER_POINTS,
+    EQUALIZER_METHOD_SEED_FILTER,
+    EQUALIZER_METHOD_SAVE_PROFILE,
+    EQUALIZER_METHOD_LOAD_PROFILE,
+    EQUALIZER_METHOD_SET_FILTER,
+    EQUALIZER_METHOD_GET_FILTER,
+    EQUALIZER_METHOD_SAVE_STATE,
+    EQUALIZER_METHOD_GET_PROFILE_NAME,
+    EQUALIZER_METHOD_MAX
+};
+
+enum equalizer_handler_index {
+    EQUALIZER_HANDLER_REVISION,
+    EQUALIZER_HANDLER_SAMPLERATE,
+    EQUALIZER_HANDLER_FILTERSAMPLERATE,
+    EQUALIZER_HANDLER_N_COEFS,
+    EQUALIZER_HANDLER_N_CHANNELS,
+    EQUALIZER_HANDLER_MAX
+};
+
+pa_dbus_arg_info filter_points_args[]={
+    {"channel", "u","in"},
+    {"xs", "au","in"},
+    {"ys", "ad","out"},
+    {"preamp", "d","out"}
+};
+pa_dbus_arg_info seed_filter_args[]={
+    {"channel", "u","in"},
+    {"xs", "au","in"},
+    {"ys", "ad","in"},
+    {"preamp", "d","in"}
+};
+
+pa_dbus_arg_info set_filter_args[]={
+    {"channel", "u","in"},
+    {"ys", "ad","in"},
+    {"preamp", "d","in"}
+};
+pa_dbus_arg_info get_filter_args[]={
+    {"channel", "u","in"},
+    {"ys", "ad","out"},
+    {"preamp", "d","out"}
+};
+
+pa_dbus_arg_info save_profile_args[]={
+    {"channel", "u","in"},
+    {"name", "s","in"}
+};
+pa_dbus_arg_info load_profile_args[]={
+    {"channel", "u","in"},
+    {"name", "s","in"}
+};
+pa_dbus_arg_info base_profile_name_args[]={
+    {"channel", "u","in"},
+    {"name", "s","out"}
+};
+
+static pa_dbus_method_handler equalizer_methods[EQUALIZER_METHOD_MAX]={
+    [EQUALIZER_METHOD_SEED_FILTER]={
+        .method_name="SeedFilter",
+        .arguments=seed_filter_args,
+        .n_arguments=sizeof(seed_filter_args)/sizeof(pa_dbus_arg_info),
+        .receive_cb=equalizer_handle_seed_filter},
+    [EQUALIZER_METHOD_FILTER_POINTS]={
+        .method_name="FilterAtPoints",
+        .arguments=filter_points_args,
+        .n_arguments=sizeof(filter_points_args)/sizeof(pa_dbus_arg_info),
+        .receive_cb=equalizer_handle_get_filter_points},
+    [EQUALIZER_METHOD_SET_FILTER]={
+        .method_name="SetFilter",
+        .arguments=set_filter_args,
+        .n_arguments=sizeof(set_filter_args)/sizeof(pa_dbus_arg_info),
+        .receive_cb=equalizer_handle_set_filter},
+    [EQUALIZER_METHOD_GET_FILTER]={
+        .method_name="GetFilter",
+        .arguments=get_filter_args,
+        .n_arguments=sizeof(get_filter_args)/sizeof(pa_dbus_arg_info),
+        .receive_cb=equalizer_handle_get_filter},
+    [EQUALIZER_METHOD_SAVE_PROFILE]={
+        .method_name="SaveProfile",
+        .arguments=save_profile_args,
+        .n_arguments=sizeof(save_profile_args)/sizeof(pa_dbus_arg_info),
+        .receive_cb=equalizer_handle_save_profile},
+    [EQUALIZER_METHOD_LOAD_PROFILE]={
+        .method_name="LoadProfile",
+        .arguments=load_profile_args,
+        .n_arguments=sizeof(load_profile_args)/sizeof(pa_dbus_arg_info),
+        .receive_cb=equalizer_handle_load_profile},
+    [EQUALIZER_METHOD_SAVE_STATE]={
+        .method_name="SaveState",
+        .arguments=NULL,
+        .n_arguments=0,
+        .receive_cb=equalizer_handle_save_state},
+    [EQUALIZER_METHOD_GET_PROFILE_NAME]={
+        .method_name="BaseProfile",
+        .arguments=base_profile_name_args,
+        .n_arguments=sizeof(base_profile_name_args)/sizeof(pa_dbus_arg_info),
+        .receive_cb=equalizer_handle_get_profile_name}
+};
+
+static pa_dbus_property_handler equalizer_handlers[EQUALIZER_HANDLER_MAX]={
+    [EQUALIZER_HANDLER_REVISION]={.property_name="InterfaceRevision",.type="u",.get_cb=equalizer_get_revision,.set_cb=NULL},
+    [EQUALIZER_HANDLER_SAMPLERATE]={.property_name="SampleRate",.type="u",.get_cb=equalizer_get_sample_rate,.set_cb=NULL},
+    [EQUALIZER_HANDLER_FILTERSAMPLERATE]={.property_name="FilterSampleRate",.type="u",.get_cb=equalizer_get_filter_rate,.set_cb=NULL},
+    [EQUALIZER_HANDLER_N_COEFS]={.property_name="NFilterCoefficients",.type="u",.get_cb=equalizer_get_n_coefs,.set_cb=NULL},
+    [EQUALIZER_HANDLER_N_CHANNELS]={.property_name="NChannels",.type="u",.get_cb=equalizer_get_n_channels,.set_cb=NULL},
+};
+
+enum equalizer_signal_index{
+    EQUALIZER_SIGNAL_FILTER_CHANGED,
+    EQUALIZER_SIGNAL_SINK_RECONFIGURED,
+    EQUALIZER_SIGNAL_MAX
+};
+
+static pa_dbus_signal_info equalizer_signals[EQUALIZER_SIGNAL_MAX]={
+    [EQUALIZER_SIGNAL_FILTER_CHANGED]={.name="FilterChanged", .arguments=NULL, .n_arguments=0},
+    [EQUALIZER_SIGNAL_SINK_RECONFIGURED]={.name="SinkReconfigured", .arguments=NULL, .n_arguments=0},
+};
+
+static pa_dbus_interface_info equalizer_info={
+    .name=EQUALIZER_IFACE,
+    .method_handlers=equalizer_methods,
+    .n_method_handlers=EQUALIZER_METHOD_MAX,
+    .property_handlers=equalizer_handlers,
+    .n_property_handlers=EQUALIZER_HANDLER_MAX,
+    .get_all_properties_cb=equalizer_get_all,
+    .signals=equalizer_signals,
+    .n_signals=EQUALIZER_SIGNAL_MAX
+};
+
+void dbus_init(struct userdata *u){
+    uint32_t dummy;
+    DBusMessage *message = NULL;
+    pa_idxset *sink_list = NULL;
+    u->dbus_protocol=pa_dbus_protocol_get(u->sink->core);
+    u->dbus_path=pa_sprintf_malloc("/org/pulseaudio/core1/sink%d", u->sink->index);
+
+    pa_dbus_protocol_add_interface(u->dbus_protocol, u->dbus_path, &equalizer_info, u);
+    sink_list = pa_shared_get(u->sink->core, SINKLIST);
+    u->database = pa_shared_get(u->sink->core, EQDB);
+    if(sink_list == NULL){
+        char *dbname;
+        sink_list=pa_idxset_new(&pa_idxset_trivial_hash_func, &pa_idxset_trivial_compare_func);
+        pa_shared_set(u->sink->core, SINKLIST, sink_list);
+        pa_assert_se(dbname = pa_state_path("equalizer-presets", FALSE));
+        pa_assert_se(u->database = pa_database_open(dbname, TRUE));
+        pa_xfree(dbname);
+        pa_shared_set(u->sink->core, EQDB, u->database);
+        pa_dbus_protocol_add_interface(u->dbus_protocol, MANAGER_PATH, &manager_info, u->sink->core);
+        pa_dbus_protocol_register_extension(u->dbus_protocol, EXTNAME);
+    }
+    pa_idxset_put(sink_list, u, &dummy);
+
+    pa_assert_se((message = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_SINK_ADDED].name)));
+    dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &u->dbus_path, DBUS_TYPE_INVALID);
+    pa_dbus_protocol_send_signal(u->dbus_protocol, message);
+    dbus_message_unref(message);
+}
+
+void dbus_done(struct userdata *u){
+    pa_idxset *sink_list;
+    uint32_t dummy;
+
+    DBusMessage *message = NULL;
+    pa_assert_se((message = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_SINK_REMOVED].name)));
+    dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &u->dbus_path, DBUS_TYPE_INVALID);
+    pa_dbus_protocol_send_signal(u->dbus_protocol, message);
+    dbus_message_unref(message);
+
+    pa_assert_se(sink_list=pa_shared_get(u->sink->core,SINKLIST));
+    pa_idxset_remove_by_data(sink_list,u,&dummy);
+    if(pa_idxset_size(sink_list)==0){
+        pa_dbus_protocol_unregister_extension(u->dbus_protocol, EXTNAME);
+        pa_dbus_protocol_remove_interface(u->dbus_protocol, MANAGER_PATH, manager_info.name);
+        pa_shared_remove(u->sink->core, EQDB);
+        pa_database_close(u->database);
+        pa_shared_remove(u->sink->core, SINKLIST);
+        pa_xfree(sink_list);
+    }
+    pa_dbus_protocol_remove_interface(u->dbus_protocol, u->dbus_path, equalizer_info.name);
+    pa_xfree(u->dbus_path);
+    pa_dbus_protocol_unref(u->dbus_protocol);
+}
+
+void manager_handle_remove_profile(DBusConnection *conn, DBusMessage *msg, void *_u) {
+    DBusError error;
+    pa_core *c = (pa_core *)_u;
+    DBusMessage *message = NULL;
+    pa_dbus_protocol *dbus_protocol;
+    char *name;
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+    dbus_error_init(&error);
+    if(!dbus_message_get_args(msg, &error,
+                 DBUS_TYPE_STRING, &name,
+                DBUS_TYPE_INVALID)){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
+        dbus_error_free(&error);
+        return;
+    }
+    remove_profile(c,name);
+    pa_dbus_send_empty_reply(conn, msg);
+
+    pa_assert_se((message = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_PROFILES_CHANGED].name)));
+    dbus_protocol = pa_dbus_protocol_get(c);
+    pa_dbus_protocol_send_signal(dbus_protocol, message);
+    pa_dbus_protocol_unref(dbus_protocol);
+    dbus_message_unref(message);
+}
+
+void manager_get_revision(DBusConnection *conn, DBusMessage *msg, void *_u){
+    uint32_t rev=1;
+    pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_UINT32, &rev);
+}
+
+static void get_sinks(pa_core *u, char ***names, unsigned *n_sinks){
+    void *iter = NULL;
+    struct userdata *sink_u = NULL;
+    uint32_t dummy;
+    pa_idxset *sink_list;
+    pa_assert(u);
+    pa_assert(names);
+    pa_assert(n_sinks);
+
+    pa_assert_se(sink_list = pa_shared_get(u, SINKLIST));
+    *n_sinks = (unsigned) pa_idxset_size(sink_list);
+    *names = *n_sinks > 0 ? pa_xnew0(char *,*n_sinks) : NULL;
+    for(uint32_t i = 0; i < *n_sinks; ++i){
+        sink_u = (struct userdata *) pa_idxset_iterate(sink_list, &iter, &dummy);
+        (*names)[i] = pa_xstrdup(sink_u->dbus_path);
+    }
+}
+
+void manager_get_sinks(DBusConnection *conn, DBusMessage *msg, void *_u){
+    unsigned n;
+    char **names = NULL;
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(_u);
+
+    get_sinks((pa_core *) _u, &names, &n);
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, names, n);
+    for(unsigned i = 0; i < n; ++i){
+        pa_xfree(names[i]);
+    }
+    pa_xfree(names);
+}
+
+static void get_profiles(pa_core *c, char ***names, unsigned *n){
+    char *name;
+    pa_database *database;
+    pa_datum key, next_key;
+    pa_strlist *head=NULL, *iter;
+    pa_bool_t done;
+    pa_assert_se(database = pa_shared_get(c, EQDB));
+
+    pa_assert(c);
+    pa_assert(names);
+    pa_assert(n);
+    done = !pa_database_first(database, &key, NULL);
+    *n = 0;
+    while(!done){
+        done = !pa_database_next(database, &key, &next_key, NULL);
+        name=pa_xmalloc(key.size + 1);
+        memcpy(name, key.data, key.size);
+        name[key.size] = '\0';
+        pa_datum_free(&key);
+        head = pa_strlist_prepend(head, name);
+        pa_xfree(name);
+        key = next_key;
+        (*n)++;
+    }
+    (*names) = *n > 0 ? pa_xnew0(char *, *n) : NULL;
+    iter=head;
+    for(unsigned i = 0; i < *n; ++i){
+        (*names)[*n - 1 - i] = pa_xstrdup(pa_strlist_data(iter));
+        iter = pa_strlist_next(iter);
+    }
+    pa_strlist_free(head);
+}
+
+void manager_get_profiles(DBusConnection *conn, DBusMessage *msg, void *_u){
+    char **names;
+    unsigned n;
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(_u);
+
+    get_profiles((pa_core *)_u, &names, &n);
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_STRING, names, n);
+    for(unsigned i = 0; i < n; ++i){
+        pa_xfree(names[i]);
+    }
+    pa_xfree(names);
+}
+
+void manager_get_all(DBusConnection *conn, DBusMessage *msg, void *_u){
+    pa_core *c;
+    char **names = NULL;
+    unsigned n;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter, dict_iter;
+    uint32_t rev;
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert_se(c = _u);
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+
+    rev = 1;
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, manager_handlers[MANAGER_HANDLER_REVISION].property_name, DBUS_TYPE_UINT32, &rev);
+
+    get_sinks(c, &names, &n);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter,manager_handlers[MANAGER_HANDLER_EQUALIZED_SINKS].property_name, DBUS_TYPE_OBJECT_PATH, names, n);
+    for(unsigned i = 0; i < n; ++i){
+        pa_xfree(names[i]);
+    }
+    pa_xfree(names);
+
+    get_profiles(c, &names, &n);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, manager_handlers[MANAGER_HANDLER_PROFILES].property_name, DBUS_TYPE_STRING, names, n);
+    for(unsigned i = 0; i < n; ++i){
+        pa_xfree(names[i]);
+    }
+    pa_xfree(names);
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+}
+
+void equalizer_handle_seed_filter(DBusConnection *conn, DBusMessage *msg, void *_u) {
+    struct userdata *u = _u;
+    DBusError error;
+    DBusMessage *message = NULL;
+    float *ys;
+    uint32_t *xs, channel, r_channel;
+    double *_ys, preamp;
+    unsigned x_npoints, y_npoints, a_i;
+    float *H;
+    pa_bool_t points_good = TRUE;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(u);
+
+    dbus_error_init(&error);
+
+    if(!dbus_message_get_args(msg, &error,
+                DBUS_TYPE_UINT32, &channel,
+                DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &xs, &x_npoints,
+                DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &_ys, &y_npoints,
+                DBUS_TYPE_DOUBLE, &preamp,
+                DBUS_TYPE_INVALID)){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
+        dbus_error_free(&error);
+        return;
+    }
+    if(channel > u->channels){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
+        dbus_error_free(&error);
+        return;
+    }
+    for(size_t i = 0; i < x_npoints; ++i){
+        if(xs[i] >= FILTER_SIZE(u)){
+            points_good = FALSE;
+            break;
+        }
+    }
+    if(!is_monotonic(xs, x_npoints) || !points_good){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs must be monotonic and 0<=x<=%zd", u->fft_size / 2);
+        dbus_error_free(&error);
+        return;
+    }else if(x_npoints != y_npoints || x_npoints < 2 || x_npoints > FILTER_SIZE(u)){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs and ys must be the same length and 2<=l<=%zd!", FILTER_SIZE(u));
+        dbus_error_free(&error);
+        return;
+    }else if(xs[0] != 0 || xs[x_npoints - 1] != u->fft_size / 2){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs[0] must be 0 and xs[-1]=fft_size/2");
+        dbus_error_free(&error);
+        return;
+    }
+
+    ys = pa_xmalloc(x_npoints * sizeof(float));
+    for(uint32_t i = 0; i < x_npoints; ++i){
+        ys[i] = (float) _ys[i];
+    }
+    r_channel = channel == u->channels ? 0 : channel;
+    a_i = pa_aupdate_write_begin(u->a_H[r_channel]);
+    H = u->Hs[r_channel][a_i];
+    u->Xs[r_channel][a_i] = preamp;
+    interpolate(H, FILTER_SIZE(u), xs, ys, x_npoints);
+    fix_filter(H, u->fft_size);
+    if(channel == u->channels){
+        for(size_t c = 1; c < u->channels; ++c){
+            unsigned b_i = pa_aupdate_write_begin(u->a_H[c]);
+            float *H_p = u->Hs[c][b_i];
+            u->Xs[c][b_i] = preamp;
+            memcpy(H_p, H, FILTER_SIZE(u) * sizeof(float));
+            pa_aupdate_write_end(u->a_H[c]);
+        }
+    }
+    pa_aupdate_write_end(u->a_H[r_channel]);
+    pa_xfree(ys);
+
+
+    pa_dbus_send_empty_reply(conn, msg);
+
+    pa_assert_se((message = dbus_message_new_signal(u->dbus_path, EQUALIZER_IFACE, equalizer_signals[EQUALIZER_SIGNAL_FILTER_CHANGED].name)));
+    pa_dbus_protocol_send_signal(u->dbus_protocol, message);
+    dbus_message_unref(message);
+}
+
+void equalizer_handle_get_filter_points(DBusConnection *conn, DBusMessage *msg, void *_u) {
+    struct userdata *u = (struct userdata *) _u;
+    uint32_t *xs, channel, r_channel;
+    double *ys, preamp;
+    unsigned x_npoints, a_i;
+    float *H;
+    pa_bool_t points_good=TRUE;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+    DBusError error;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(u);
+
+    dbus_error_init(&error);
+    if(!dbus_message_get_args(msg, &error,
+                DBUS_TYPE_UINT32, &channel,
+                DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &xs, &x_npoints,
+                DBUS_TYPE_INVALID)){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
+        dbus_error_free(&error);
+        return;
+    }
+    if(channel > u->channels){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
+        dbus_error_free(&error);
+        return;
+    }
+
+    for(size_t i = 0; i < x_npoints; ++i){
+        if(xs[i] >= FILTER_SIZE(u)){
+            points_good=FALSE;
+            break;
+        }
+    }
+
+    if(x_npoints > FILTER_SIZE(u) || !points_good){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "xs indices/length must be <= %zd!", FILTER_SIZE(u));
+        dbus_error_free(&error);
+        return;
+    }
+
+    r_channel = channel == u->channels ? 0 : channel;
+    ys = pa_xmalloc(x_npoints * sizeof(double));
+    a_i = pa_aupdate_read_begin(u->a_H[r_channel]);
+    H = u->Hs[r_channel][a_i];
+    preamp = u->Xs[r_channel][a_i];
+    for(uint32_t i = 0; i < x_npoints; ++i){
+        ys[i] = H[xs[i]] * u->fft_size;
+    }
+    pa_aupdate_read_end(u->a_H[r_channel]);
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+    dbus_message_iter_init_append(reply, &msg_iter);
+
+    pa_dbus_append_basic_array(&msg_iter, DBUS_TYPE_DOUBLE, ys, x_npoints);
+    pa_dbus_append_basic_variant(&msg_iter, DBUS_TYPE_DOUBLE, &preamp);
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+    pa_xfree(ys);
+}
+
+static void get_filter(struct userdata *u, size_t channel, double **H_, double *preamp){
+    float *H;
+    unsigned a_i;
+    size_t r_channel = channel == u->channels ? 0 : channel;
+    *H_ = pa_xnew0(double, FILTER_SIZE(u));
+    a_i = pa_aupdate_read_begin(u->a_H[r_channel]);
+    H = u->Hs[r_channel][a_i];
+    for(size_t i = 0;i < FILTER_SIZE(u); ++i){
+        (*H_)[i] = H[i] * u->fft_size;
+    }
+    *preamp = u->Xs[r_channel][a_i];
+
+    pa_aupdate_read_end(u->a_H[r_channel]);
+}
+
+void equalizer_handle_get_filter(DBusConnection *conn, DBusMessage *msg, void *_u){
+    struct userdata *u;
+    unsigned n_coefs;
+    uint32_t channel;
+    double *H_, preamp;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+    DBusError error;
+    pa_assert_se(u = (struct userdata *) _u);
+    pa_assert(conn);
+    pa_assert(msg);
+
+    dbus_error_init(&error);
+    if(!dbus_message_get_args(msg, &error,
+                DBUS_TYPE_UINT32, &channel,
+                DBUS_TYPE_INVALID)){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
+        dbus_error_free(&error);
+        return;
+    }
+    if(channel > u->channels){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
+        dbus_error_free(&error);
+        return;
+    }
+
+    n_coefs = CHANNEL_PROFILE_SIZE(u);
+    pa_assert(conn);
+    pa_assert(msg);
+    get_filter(u, channel, &H_, &preamp);
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+    dbus_message_iter_init_append(reply, &msg_iter);
+
+    pa_dbus_append_basic_array(&msg_iter, DBUS_TYPE_DOUBLE, H_, n_coefs);
+    pa_dbus_append_basic_variant(&msg_iter, DBUS_TYPE_DOUBLE, &preamp);
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+    pa_xfree(H_);
+}
+
+static void set_filter(struct userdata *u, size_t channel, double *H_, double preamp){
+    unsigned a_i;
+    size_t r_channel = channel == u->channels ? 0 : channel;
+    float *H;
+    //all channels
+    a_i = pa_aupdate_write_begin(u->a_H[r_channel]);
+    u->Xs[r_channel][a_i] = (float) preamp;
+    H = u->Hs[r_channel][a_i];
+    for(size_t i = 0; i < FILTER_SIZE(u); ++i){
+        H[i] = (float) H_[i];
+    }
+    fix_filter(H, u->fft_size);
+    if(channel == u->channels){
+        for(size_t c = 1; c < u->channels; ++c){
+            unsigned b_i = pa_aupdate_write_begin(u->a_H[c]);
+            u->Xs[c][b_i] = u->Xs[r_channel][a_i];
+            memcpy(u->Hs[c][b_i], u->Hs[r_channel][a_i], FILTER_SIZE(u) * sizeof(float));
+            pa_aupdate_write_end(u->a_H[c]);
+        }
+    }
+    pa_aupdate_write_end(u->a_H[r_channel]);
+}
+
+void equalizer_handle_set_filter(DBusConnection *conn, DBusMessage *msg, void *_u){
+    struct userdata *u;
+    double *H, preamp;
+    uint32_t channel;
+    unsigned _n_coefs;
+    DBusMessage *message = NULL;
+    DBusError error;
+    pa_assert_se(u = (struct userdata *) _u);
+    pa_assert(conn);
+    pa_assert(msg);
+
+    dbus_error_init(&error);
+    if(!dbus_message_get_args(msg, &error,
+                DBUS_TYPE_UINT32, &channel,
+                DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &H, &_n_coefs,
+                DBUS_TYPE_DOUBLE, &preamp,
+                DBUS_TYPE_INVALID)){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
+        dbus_error_free(&error);
+        return;
+    }
+    if(channel > u->channels){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
+        dbus_error_free(&error);
+        return;
+    }
+    if(_n_coefs != FILTER_SIZE(u)){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "This filter takes exactly %zd coefficients, you gave %d", FILTER_SIZE(u), _n_coefs);
+        return;
+    }
+    set_filter(u, channel, H, preamp);
+
+    pa_dbus_send_empty_reply(conn, msg);
+
+    pa_assert_se((message = dbus_message_new_signal(u->dbus_path, EQUALIZER_IFACE, equalizer_signals[EQUALIZER_SIGNAL_FILTER_CHANGED].name)));
+    pa_dbus_protocol_send_signal(u->dbus_protocol, message);
+    dbus_message_unref(message);
+}
+
+void equalizer_handle_save_profile(DBusConnection *conn, DBusMessage *msg, void *_u) {
+    struct userdata *u = (struct userdata *) _u;
+    char *name;
+    uint32_t channel, r_channel;
+    DBusMessage *message = NULL;
+    DBusError error;
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(u);
+    dbus_error_init(&error);
+
+    if(!dbus_message_get_args(msg, &error,
+                DBUS_TYPE_UINT32, &channel,
+                DBUS_TYPE_STRING, &name,
+                DBUS_TYPE_INVALID)){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
+        dbus_error_free(&error);
+        return;
+    }
+    if(channel > u->channels){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
+        dbus_error_free(&error);
+        return;
+    }
+    r_channel = channel == u->channels ? 0 : channel;
+    save_profile(u, r_channel, name);
+    pa_dbus_send_empty_reply(conn, msg);
+
+    pa_assert_se((message = dbus_message_new_signal(MANAGER_PATH, MANAGER_IFACE, manager_signals[MANAGER_SIGNAL_PROFILES_CHANGED].name)));
+    pa_dbus_protocol_send_signal(u->dbus_protocol, message);
+    dbus_message_unref(message);
+}
+
+void equalizer_handle_load_profile(DBusConnection *conn, DBusMessage *msg, void *_u) {
+    struct userdata *u = (struct userdata *) _u;
+    char *name;
+    DBusError error;
+    uint32_t channel, r_channel;
+    const char *err_msg = NULL;
+    DBusMessage *message = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(u);
+    dbus_error_init(&error);
+
+    if(!dbus_message_get_args(msg, &error,
+                DBUS_TYPE_UINT32, &channel,
+                DBUS_TYPE_STRING, &name,
+                DBUS_TYPE_INVALID)){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
+        dbus_error_free(&error);
+        return;
+    }
+    if(channel > u->channels){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
+        dbus_error_free(&error);
+        return;
+    }
+    r_channel = channel == u->channels ? 0 : channel;
+
+    err_msg = load_profile(u, r_channel, name);
+    if(err_msg != NULL){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "error loading profile %s: %s", name, err_msg);
+        dbus_error_free(&error);
+        return;
+    }
+    if(channel == u->channels){
+        for(uint32_t c = 1; c < u->channels; ++c){
+            load_profile(u, c, name);
+        }
+    }
+    pa_dbus_send_empty_reply(conn, msg);
+
+    pa_assert_se((message = dbus_message_new_signal(u->dbus_path, EQUALIZER_IFACE, equalizer_signals[EQUALIZER_SIGNAL_FILTER_CHANGED].name)));
+    pa_dbus_protocol_send_signal(u->dbus_protocol, message);
+    dbus_message_unref(message);
+}
+
+void equalizer_handle_save_state(DBusConnection *conn, DBusMessage *msg, void *_u) {
+    struct userdata *u = (struct userdata *) _u;
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(u);
+
+    save_state(u);
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+void equalizer_handle_get_profile_name(DBusConnection *conn, DBusMessage *msg, void *_u){
+    struct userdata *u = (struct userdata *) _u;
+    DBusError error;
+    uint32_t channel, r_channel;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(u);
+    dbus_error_init(&error);
+
+    if(!dbus_message_get_args(msg, &error,
+                DBUS_TYPE_UINT32, &channel,
+                DBUS_TYPE_INVALID)){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message);
+        dbus_error_free(&error);
+        return;
+    }
+    if(channel > u->channels){
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "invalid channel: %d", channel);
+        dbus_error_free(&error);
+        return;
+    }
+    r_channel = channel == u->channels ? 0 : channel;
+    pa_assert(u->base_profiles[r_channel]);
+    pa_dbus_send_basic_value_reply(conn,msg, DBUS_TYPE_STRING, &u->base_profiles[r_channel]);
+}
+
+void equalizer_get_revision(DBusConnection *conn, DBusMessage *msg, void *_u){
+    uint32_t rev=1;
+    pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_UINT32, &rev);
+}
+
+void equalizer_get_n_channels(DBusConnection *conn, DBusMessage *msg, void *_u){
+    struct userdata *u;
+    uint32_t channels;
+    pa_assert_se(u = (struct userdata *) _u);
+    pa_assert(conn);
+    pa_assert(msg);
+
+    channels = (uint32_t) u->channels;
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &channels);
+}
+
+void equalizer_get_n_coefs(DBusConnection *conn, DBusMessage *msg, void *_u){
+    struct userdata *u;
+    uint32_t n_coefs;
+    pa_assert_se(u = (struct userdata *) _u);
+    pa_assert(conn);
+    pa_assert(msg);
+
+    n_coefs = (uint32_t) CHANNEL_PROFILE_SIZE(u);
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &n_coefs);
+}
+
+void equalizer_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *_u){
+    struct userdata *u;
+    uint32_t rate;
+    pa_assert_se(u = (struct userdata *) _u);
+    pa_assert(conn);
+    pa_assert(msg);
+
+    rate = (uint32_t) u->sink->sample_spec.rate;
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &rate);
+}
+
+void equalizer_get_filter_rate(DBusConnection *conn, DBusMessage *msg, void *_u){
+    struct userdata *u;
+    uint32_t fft_size;
+    pa_assert_se(u = (struct userdata *) _u);
+    pa_assert(conn);
+    pa_assert(msg);
+
+    fft_size = (uint32_t) u->fft_size;
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &fft_size);
+}
+
+void equalizer_get_all(DBusConnection *conn, DBusMessage *msg, void *_u){
+    struct userdata *u;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter, dict_iter;
+    uint32_t rev, n_coefs, rate, fft_size, channels;
+
+    pa_assert_se(u = _u);
+    pa_assert(msg);
+
+    rev = 1;
+    n_coefs = (uint32_t) CHANNEL_PROFILE_SIZE(u);
+    rate = (uint32_t) u->sink->sample_spec.rate;
+    fft_size = (uint32_t) u->fft_size;
+    channels = (uint32_t) u->channels;
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, equalizer_handlers[EQUALIZER_HANDLER_REVISION].property_name, DBUS_TYPE_UINT32, &rev);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, equalizer_handlers[EQUALIZER_HANDLER_SAMPLERATE].property_name, DBUS_TYPE_UINT32, &rate);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, equalizer_handlers[EQUALIZER_HANDLER_FILTERSAMPLERATE].property_name, DBUS_TYPE_UINT32, &fft_size);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, equalizer_handlers[EQUALIZER_HANDLER_N_COEFS].property_name, DBUS_TYPE_UINT32, &n_coefs);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, equalizer_handlers[EQUALIZER_HANDLER_N_CHANNELS].property_name, DBUS_TYPE_UINT32, &channels);
+
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+}
diff --git a/src/modules/module-esound-compat-spawnfd-symdef.h b/src/modules/module-esound-compat-spawnfd-symdef.h
deleted file mode 100644 (file)
index 8621a8c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleesoundcompatspawnfdsymdeffoo
-#define foomoduleesoundcompatspawnfdsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_esound_compat_spawnfd_LTX_pa__init
-#define pa__done module_esound_compat_spawnfd_LTX_pa__done
-#define pa__get_author module_esound_compat_spawnfd_LTX_pa__get_author
-#define pa__get_description module_esound_compat_spawnfd_LTX_pa__get_description
-#define pa__get_usage module_esound_compat_spawnfd_LTX_pa__get_usage
-#define pa__get_version module_esound_compat_spawnfd_LTX_pa__get_version
-#define pa__get_deprecated module_esound_compat_spawnfd_LTX_pa__get_deprecated
-#define pa__load_once module_esound_compat_spawnfd_LTX_pa__load_once
-#define pa__get_n_used module_esound_compat_spawnfd_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 56cda4d..e2488fc 100644 (file)
@@ -24,7 +24,6 @@
 #endif
 
 #include <unistd.h>
-#include <string.h>
 #include <errno.h>
 
 #include <pulsecore/core-error.h>
@@ -48,7 +47,8 @@ static const char* const valid_modargs[] = {
 
 int pa__init(pa_module*m) {
     pa_modargs *ma = NULL;
-    int ret = -1, fd = -1;
+    int ret = -1;
+    int32_t fd = -1;
     char x = 1;
 
     pa_assert(m);
diff --git a/src/modules/module-esound-compat-spawnpid-symdef.h b/src/modules/module-esound-compat-spawnpid-symdef.h
deleted file mode 100644 (file)
index bf173f0..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleesoundcompatspawnpidsymdeffoo
-#define foomoduleesoundcompatspawnpidsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_esound_compat_spawnpid_LTX_pa__init
-#define pa__done module_esound_compat_spawnpid_LTX_pa__done
-#define pa__get_author module_esound_compat_spawnpid_LTX_pa__get_author
-#define pa__get_description module_esound_compat_spawnpid_LTX_pa__get_description
-#define pa__get_usage module_esound_compat_spawnpid_LTX_pa__get_usage
-#define pa__get_version module_esound_compat_spawnpid_LTX_pa__get_version
-#define pa__get_deprecated module_esound_compat_spawnpid_LTX_pa__get_deprecated
-#define pa__load_once module_esound_compat_spawnpid_LTX_pa__load_once
-#define pa__get_n_used module_esound_compat_spawnpid_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 5925f59..94ebdaa 100644 (file)
 #endif
 
 #include <unistd.h>
-#include <string.h>
 #include <errno.h>
 #include <signal.h>
 
 #include <pulsecore/core-error.h>
 #include <pulsecore/module.h>
-#include <pulsecore/core-util.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/log.h>
 
diff --git a/src/modules/module-esound-protocol-tcp-symdef.h b/src/modules/module-esound-protocol-tcp-symdef.h
deleted file mode 100644 (file)
index 334eed3..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleesoundprotocoltcpsymdeffoo
-#define foomoduleesoundprotocoltcpsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_esound_protocol_tcp_LTX_pa__init
-#define pa__done module_esound_protocol_tcp_LTX_pa__done
-#define pa__get_author module_esound_protocol_tcp_LTX_pa__get_author
-#define pa__get_description module_esound_protocol_tcp_LTX_pa__get_description
-#define pa__get_usage module_esound_protocol_tcp_LTX_pa__get_usage
-#define pa__get_version module_esound_protocol_tcp_LTX_pa__get_version
-#define pa__get_deprecated module_esound_protocol_tcp_LTX_pa__get_deprecated
-#define pa__load_once module_esound_protocol_tcp_LTX_pa__load_once
-#define pa__get_n_used module_esound_protocol_tcp_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
diff --git a/src/modules/module-esound-protocol-unix-symdef.h b/src/modules/module-esound-protocol-unix-symdef.h
deleted file mode 100644 (file)
index 175c989..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleesoundprotocolunixsymdeffoo
-#define foomoduleesoundprotocolunixsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_esound_protocol_unix_LTX_pa__init
-#define pa__done module_esound_protocol_unix_LTX_pa__done
-#define pa__get_author module_esound_protocol_unix_LTX_pa__get_author
-#define pa__get_description module_esound_protocol_unix_LTX_pa__get_description
-#define pa__get_usage module_esound_protocol_unix_LTX_pa__get_usage
-#define pa__get_version module_esound_protocol_unix_LTX_pa__get_version
-#define pa__get_deprecated module_esound_protocol_unix_LTX_pa__get_deprecated
-#define pa__load_once module_esound_protocol_unix_LTX_pa__load_once
-#define pa__get_n_used module_esound_protocol_unix_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
diff --git a/src/modules/module-esound-sink-symdef.h b/src/modules/module-esound-sink-symdef.h
deleted file mode 100644 (file)
index 1a10885..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleesoundsinksymdeffoo
-#define foomoduleesoundsinksymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_esound_sink_LTX_pa__init
-#define pa__done module_esound_sink_LTX_pa__done
-#define pa__get_author module_esound_sink_LTX_pa__get_author
-#define pa__get_description module_esound_sink_LTX_pa__get_description
-#define pa__get_usage module_esound_sink_LTX_pa__get_usage
-#define pa__get_version module_esound_sink_LTX_pa__get_version
-#define pa__get_deprecated module_esound_sink_LTX_pa__get_deprecated
-#define pa__load_once module_esound_sink_LTX_pa__load_once
-#define pa__get_n_used module_esound_sink_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index d7c678c..40ef5bc 100644 (file)
 #endif
 
 #include <stdlib.h>
-#include <sys/stat.h>
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
-#include <fcntl.h>
 #include <unistd.h>
-#include <limits.h>
-#include <poll.h>
-#include <sys/socket.h>
+
+#ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
+#endif
+
+#ifdef HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
+#endif
+
+#ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
+#endif
 
 #ifdef HAVE_LINUX_SOCKIOS_H
 #include <linux/sockios.h>
 #include <pulse/timeval.h>
 #include <pulse/xmalloc.h>
 
+#include <pulsecore/socket.h>
 #include <pulsecore/core-error.h>
 #include <pulsecore/iochannel.h>
 #include <pulsecore/sink.h>
 #include <pulsecore/module.h>
-#include <pulsecore/core-rtclock.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/log.h>
@@ -60,6 +64,8 @@
 #include <pulsecore/thread.h>
 #include <pulsecore/time-smoother.h>
 #include <pulsecore/socket-util.h>
+#include <pulsecore/rtpoll.h>
+#include <pulsecore/poll.h>
 
 #include "module-esound-sink-symdef.h"
 
@@ -207,9 +213,8 @@ static void thread_func(void *userdata) {
     for (;;) {
         int ret;
 
-        if (PA_SINK_IS_OPENED(u->sink->thread_info.state))
-            if (u->sink->thread_info.rewind_requested)
-                pa_sink_process_rewind(u->sink, 0);
+        if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
+            pa_sink_process_rewind(u->sink, 0);
 
         if (u->rtpoll_item) {
             struct pollfd *pollfd;
@@ -371,7 +376,7 @@ static int do_write(struct userdata *u) {
 
         pa_make_tcp_socket_low_delay(u->fd);
 
-        if (getsockopt(u->fd, SOL_SOCKET, SO_SNDBUF, &so_sndbuf, &sl) < 0)
+        if (getsockopt(u->fd, SOL_SOCKET, SO_SNDBUF, (void *) &so_sndbuf, &sl) < 0)
             pa_log_warn("getsockopt(SO_SNDBUF) failed: %s", pa_cstrerror(errno));
         else {
             pa_log_debug("SO_SNDBUF is %zu.", (size_t) so_sndbuf);
@@ -617,7 +622,7 @@ int pa__init(pa_module*m) {
 
     /* Prepare the initial request */
     u->write_data = pa_xmalloc(u->write_length = ESD_KEY_LEN + sizeof(int32_t));
-    if (pa_authkey_load_auto(pa_modargs_get_value(ma, "cookie", ".esd_auth"), u->write_data, ESD_KEY_LEN) < 0) {
+    if (pa_authkey_load_auto(pa_modargs_get_value(ma, "cookie", ".esd_auth"), TRUE, u->write_data, ESD_KEY_LEN) < 0) {
         pa_log("Failed to load cookie");
         goto fail;
     }
@@ -628,7 +633,7 @@ int pa__init(pa_module*m) {
     /* Reserve space for the response */
     u->read_data = pa_xmalloc(u->read_length = sizeof(int32_t));
 
-    if (!(u->thread = pa_thread_new(thread_func, u))) {
+    if (!(u->thread = pa_thread_new("esound-sink", thread_func, u))) {
         pa_log("Failed to create thread.");
         goto fail;
     }
diff --git a/src/modules/module-filter-apply.c b/src/modules/module-filter-apply.c
new file mode 100644 (file)
index 0000000..4e85ea1
--- /dev/null
@@ -0,0 +1,754 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2011 Colin Guthrie
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/timeval.h>
+#include <pulse/rtclock.h>
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/core.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/i18n.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/hashmap.h>
+#include <pulsecore/hook-list.h>
+#include <pulsecore/sink-input.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/proplist-util.h>
+
+#include "module-filter-apply-symdef.h"
+
+#define PA_PROP_FILTER_APPLY_MOVING "filter.apply.moving"
+
+PA_MODULE_AUTHOR("Colin Guthrie");
+PA_MODULE_DESCRIPTION("Load filter sinks automatically when needed");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(TRUE);
+PA_MODULE_USAGE(_("autoclean=<automatically unload unused filters?>"));
+
+static const char* const valid_modargs[] = {
+    "autoclean",
+    NULL
+};
+
+#define DEFAULT_AUTOCLEAN TRUE
+#define HOUSEKEEPING_INTERVAL (10 * PA_USEC_PER_SEC)
+
+struct filter {
+    char *name;
+    uint32_t module_index;
+    pa_sink *sink;
+    pa_sink *sink_master;
+    pa_source *source;
+    pa_source *source_master;
+};
+
+struct userdata {
+    pa_core *core;
+    pa_hashmap *filters;
+    pa_hook_slot
+        *sink_input_put_slot,
+        *sink_input_move_finish_slot,
+        *sink_input_proplist_slot,
+        *sink_input_unlink_slot,
+        *sink_unlink_slot,
+        *source_output_put_slot,
+        *source_output_move_finish_slot,
+        *source_output_proplist_slot,
+        *source_output_unlink_slot,
+        *source_unlink_slot;
+    pa_bool_t autoclean;
+    pa_time_event *housekeeping_time_event;
+};
+
+static unsigned filter_hash(const void *p) {
+    const struct filter *f = p;
+
+    if (f->sink_master && !f->source_master)
+        return (unsigned) (f->sink_master->index + pa_idxset_string_hash_func(f->name));
+    else if (!f->sink_master && f->source_master)
+        return (unsigned) ((f->source_master->index << 16) + pa_idxset_string_hash_func(f->name));
+    else
+        return (unsigned) (f->sink_master->index + (f->source_master->index << 16) + pa_idxset_string_hash_func(f->name));
+}
+
+static int filter_compare(const void *a, const void *b) {
+    const struct filter *fa = a, *fb = b;
+    int r;
+
+    if (fa->sink_master != fb->sink_master || fa->source_master != fb->source_master)
+        return 1;
+    if ((r = strcmp(fa->name, fb->name)))
+        return r;
+
+    return 0;
+}
+
+static struct filter *filter_new(const char *name, pa_sink *sink, pa_source *source) {
+    struct filter *f;
+
+    pa_assert(sink || source);
+
+    f = pa_xnew(struct filter, 1);
+    f->name = pa_xstrdup(name);
+    f->sink_master = sink;
+    f->source_master = source;
+    f->module_index = PA_INVALID_INDEX;
+    f->sink = NULL;
+    f->source = NULL;
+
+    return f;
+}
+
+static void filter_free(struct filter *f) {
+    pa_assert(f);
+
+    pa_xfree(f->name);
+    pa_xfree(f);
+}
+
+static const char* should_filter(pa_object *o, pa_bool_t is_sink_input) {
+    const char *apply;
+    pa_proplist *pl;
+
+    if (is_sink_input)
+        pl = PA_SINK_INPUT(o)->proplist;
+    else
+        pl = PA_SOURCE_OUTPUT(o)->proplist;
+
+    /* If the stream doesn't what any filter, then let it be. */
+    if ((apply = pa_proplist_gets(pl, PA_PROP_FILTER_APPLY)) && !pa_streq(apply, "")) {
+        const char* suppress = pa_proplist_gets(pl, PA_PROP_FILTER_SUPPRESS);
+
+        if (!suppress || !pa_streq(suppress, apply))
+            return apply;
+    }
+
+    return NULL;
+}
+
+static pa_bool_t should_group_filter(struct filter *filter) {
+    return pa_streq(filter->name, "echo-cancel");
+}
+
+static char* get_group(pa_object *o, pa_bool_t is_sink_input) {
+    pa_proplist *pl;
+
+    if (is_sink_input)
+        pl = PA_SINK_INPUT(o)->proplist;
+    else
+        pl = PA_SOURCE_OUTPUT(o)->proplist;
+
+    /* There's a bit of cleverness here -- the second argument ensures that we
+     * only group streams that require the same filter */
+    return pa_proplist_get_stream_group(pl, pa_proplist_gets(pl, PA_PROP_FILTER_APPLY), NULL);
+}
+
+/* For filters that apply on a source-output/sink-input pair, this finds the
+ * master sink if we know the master source, or vice versa. It does this by
+ * looking up streams that belong to the same stream group as the original
+ * object. The idea is that streams from the sam group are always routed
+ * together. */
+static pa_bool_t find_paired_master(struct userdata *u, struct filter *filter, pa_object *o, pa_bool_t is_sink_input) {
+    char *group;
+
+    if ((group = get_group(o, is_sink_input))) {
+        uint32_t idx;
+        char *g;
+        char *module_name = pa_sprintf_malloc("module-%s", filter->name);
+
+        if (is_sink_input) {
+            pa_source_output *so;
+
+            PA_IDXSET_FOREACH(so, u->core->source_outputs, idx) {
+                g = get_group(PA_OBJECT(so), FALSE);
+
+                if (pa_streq(g, group)) {
+                    if (pa_streq(module_name, so->source->module->name)) {
+                        /* Make sure we're not routing to another instance of
+                         * the same filter. */
+                        filter->source_master = so->source->output_from_master->source;
+                    } else {
+                        filter->source_master = so->source;
+                    }
+
+                    pa_xfree(g);
+                    break;
+                }
+
+                pa_xfree (g);
+            }
+        } else {
+            pa_sink_input *si;
+
+            PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+                g = get_group(PA_OBJECT(si), TRUE);
+
+                if (pa_streq(g, group)) {
+                    if (pa_streq(module_name, si->sink->module->name)) {
+                        /* Make sure we're not routing to another instance of
+                         * the same filter. */
+                        filter->sink_master = si->sink->input_to_master->sink;
+                    } else {
+                        filter->sink_master = si->sink;
+                    }
+
+                    pa_xfree(g);
+                    break;
+                }
+
+                pa_xfree(g);
+            }
+        }
+
+        pa_xfree(group);
+        pa_xfree(module_name);
+
+        if (!filter->sink_master || !filter->source_master)
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+static pa_bool_t nothing_attached(struct filter *f) {
+    pa_bool_t no_si = TRUE, no_so = TRUE;
+
+    if (f->sink)
+        no_si = pa_idxset_isempty(f->sink->inputs);
+    if (f->source)
+        no_so = pa_idxset_isempty(f->source->outputs);
+
+    return no_si && no_so;
+}
+
+static void housekeeping_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
+    struct userdata *u = userdata;
+    struct filter *filter;
+    void *state;
+
+    pa_assert(a);
+    pa_assert(e);
+    pa_assert(u);
+
+    pa_assert(e == u->housekeeping_time_event);
+    u->core->mainloop->time_free(u->housekeeping_time_event);
+    u->housekeeping_time_event = NULL;
+
+    PA_HASHMAP_FOREACH(filter, u->filters, state) {
+        if (nothing_attached(filter)) {
+            uint32_t idx;
+
+            pa_log_debug("Detected filter %s as no longer used. Unloading.", filter->name);
+            idx = filter->module_index;
+            pa_hashmap_remove(u->filters, filter);
+            filter_free(filter);
+            pa_module_unload_request_by_index(u->core, idx, TRUE);
+        }
+    }
+
+    pa_log_info("Housekeeping Done.");
+}
+
+static void trigger_housekeeping(struct userdata *u) {
+    pa_assert(u);
+
+    if (!u->autoclean)
+        return;
+
+    if (u->housekeeping_time_event)
+        return;
+
+    u->housekeeping_time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + HOUSEKEEPING_INTERVAL, housekeeping_time_callback, u);
+}
+
+static int do_move(pa_object *obj, pa_object *parent, pa_bool_t restore, pa_bool_t is_input) {
+    if (is_input)
+        return pa_sink_input_move_to(PA_SINK_INPUT(obj), PA_SINK(parent), restore);
+    else
+        return pa_source_output_move_to(PA_SOURCE_OUTPUT(obj), PA_SOURCE(parent), restore);
+}
+
+static void move_object_for_filter(pa_object *o, struct filter* filter, pa_bool_t restore, pa_bool_t is_sink_input) {
+    pa_object *parent;
+    pa_proplist *pl;
+    const char *name;
+
+    pa_assert(o);
+    pa_assert(filter);
+
+    if (is_sink_input) {
+        pl = PA_SINK_INPUT(o)->proplist;
+        parent = PA_OBJECT(restore ? filter->sink_master : filter->sink);
+        if (!parent)
+            return;
+        name = PA_SINK(parent)->name;
+    } else {
+        pl = PA_SOURCE_OUTPUT(o)->proplist;
+        parent = PA_OBJECT(restore ? filter->source_master : filter->source);
+        if (!parent)
+            return;
+        name = PA_SOURCE(parent)->name;
+    }
+
+    pa_proplist_sets(pl, PA_PROP_FILTER_APPLY_MOVING, "1");
+
+    if (do_move(o, parent, FALSE, is_sink_input) < 0)
+        pa_log_info("Failed to move %s for \"%s\" to <%s>.", is_sink_input ? "sink-input" : "source-output",
+                    pa_strnull(pa_proplist_gets(pl, PA_PROP_APPLICATION_NAME)), name);
+    else
+        pa_log_info("Successfully moved %s for \"%s\" to <%s>.", is_sink_input ? "sink-input" : "source-output",
+                    pa_strnull(pa_proplist_gets(pl, PA_PROP_APPLICATION_NAME)), name);
+
+    pa_proplist_unset(pl, PA_PROP_FILTER_APPLY_MOVING);
+}
+
+static void move_objects_for_filter(struct userdata *u, pa_object *o, struct filter* filter, pa_bool_t restore,
+        pa_bool_t is_sink_input) {
+
+    if (!should_group_filter(filter))
+        move_object_for_filter(o, filter, restore, is_sink_input);
+    else {
+        pa_source_output *so;
+        pa_sink_input *si;
+        char *g, *group;
+        uint32_t idx;
+
+        group = get_group(o, is_sink_input);
+
+        PA_IDXSET_FOREACH(so, u->core->source_outputs, idx) {
+            g = get_group(PA_OBJECT(so), FALSE);
+
+            if (pa_streq(g, group))
+                move_object_for_filter(PA_OBJECT(so), filter, restore, FALSE);
+
+            pa_xfree(g);
+        }
+
+        PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+            g = get_group(PA_OBJECT(si), TRUE);
+
+            if (pa_streq(g, group))
+                move_object_for_filter(PA_OBJECT(si), filter, restore, TRUE);
+
+            pa_xfree(g);
+        }
+
+        pa_xfree(group);
+    }
+}
+
+/* Note that we assume a filter will provide at most one sink and at most one
+ * source (and at least one of either). */
+static void find_filters_for_module(struct userdata *u, pa_module *m, const char *name) {
+    uint32_t idx;
+    pa_sink *sink;
+    pa_source *source;
+    struct filter *fltr = NULL;
+
+    PA_IDXSET_FOREACH(sink, u->core->sinks, idx) {
+        if (sink->module == m) {
+            pa_assert(sink->input_to_master != NULL);
+
+            fltr = filter_new(name, sink->input_to_master->sink, NULL);
+            fltr->module_index = m->index;
+            fltr->sink = sink;
+
+            break;
+        }
+    }
+
+    PA_IDXSET_FOREACH(source, u->core->sources, idx) {
+        if (source->module == m && !source->monitor_of) {
+            pa_assert(source->output_from_master != NULL);
+
+            if (!fltr) {
+                fltr = filter_new(name, NULL, source->output_from_master->source);
+                fltr->module_index = m->index;
+                fltr->source = source;
+            } else {
+                fltr->source = source;
+                fltr->source_master = source->output_from_master->source;
+            }
+
+            break;
+        }
+    }
+
+    pa_hashmap_put(u->filters, fltr, fltr);
+}
+
+static pa_bool_t can_unload_module(struct userdata *u, uint32_t idx) {
+    void *state;
+    struct filter *filter;
+
+    /* Check if any other struct filters point to the same module */
+    PA_HASHMAP_FOREACH(filter, u->filters, state) {
+        if (filter->module_index == idx && !nothing_attached(filter))
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+static pa_hook_result_t process(struct userdata *u, pa_object *o, pa_bool_t is_sink_input) {
+    const char *want;
+    pa_bool_t done_something = FALSE;
+    pa_sink *sink = NULL;
+    pa_source *source = NULL;
+    pa_module *module = NULL;
+
+    if (is_sink_input) {
+        sink = PA_SINK_INPUT(o)->sink;
+
+        if (sink)
+            module = sink->module;
+    } else {
+        source = PA_SOURCE_OUTPUT(o)->source;
+
+        if (source)
+            module = source->module;
+    }
+
+    /* If there is no sink/source yet, we can't do much */
+    if ((is_sink_input && !sink) || (!is_sink_input && !source))
+        return PA_HOOK_OK;
+
+    /* If the stream doesn't what any filter, then let it be. */
+    if ((want = should_filter(o, is_sink_input))) {
+        char *module_name;
+        struct filter *fltr, *filter;
+
+        /* We need to ensure the SI is playing on a sink of this type
+         * attached to the sink it's "officially" playing on */
+
+        if (!module)
+            return PA_HOOK_OK;
+
+        module_name = pa_sprintf_malloc("module-%s", want);
+        if (pa_streq(module->name, module_name)) {
+            pa_log_debug("Stream appears to be playing on an appropriate sink already. Ignoring.");
+            pa_xfree(module_name);
+            return PA_HOOK_OK;
+        }
+
+        fltr = filter_new(want, sink, source);
+
+        if (should_group_filter(fltr) && !find_paired_master(u, fltr, o, is_sink_input)) {
+            pa_log_debug("Want group filtering but don't have enough streams.");
+            return PA_HOOK_OK;
+        }
+
+        if (!(filter = pa_hashmap_get(u->filters, fltr))) {
+            char *args;
+            pa_module *m;
+
+            args = pa_sprintf_malloc("autoloaded=1 %s%s %s%s",
+                    fltr->sink_master ? "sink_master=" : "",
+                    fltr->sink_master ? fltr->sink_master->name : "",
+                    fltr->source_master ? "source_master=" : "",
+                    fltr->source_master ? fltr->source_master->name : "");
+
+            pa_log_debug("Loading %s with arguments '%s'", module_name, args);
+
+            if ((m = pa_module_load(u->core, module_name, args))) {
+                find_filters_for_module(u, m, want);
+                filter = pa_hashmap_get(u->filters, fltr);
+                done_something = TRUE;
+            }
+            pa_xfree(args);
+        }
+
+        pa_xfree(fltr);
+
+        if (!filter) {
+            pa_log("Unable to load %s", module_name);
+            pa_xfree(module_name);
+            return PA_HOOK_OK;
+        }
+        pa_xfree(module_name);
+
+        /* We can move the stream now as we know the destination. If this
+         * isn't true, we will do it later when the sink appears. */
+        if ((is_sink_input && filter->sink) || (!is_sink_input && filter->source)) {
+            move_objects_for_filter(u, o, filter, FALSE, is_sink_input);
+            done_something = TRUE;
+        }
+    } else {
+        void *state;
+        struct filter *filter = NULL;
+
+        /* We do not want to filter... but are we already filtered?
+         * This can happen if an input's proplist changes */
+        PA_HASHMAP_FOREACH(filter, u->filters, state) {
+            if ((is_sink_input && sink == filter->sink) || (!is_sink_input && source == filter->source)) {
+                move_objects_for_filter(u, o, filter, TRUE, is_sink_input);
+                done_something = TRUE;
+                break;
+            }
+        }
+    }
+
+    if (done_something)
+        trigger_housekeeping(u);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sink_input_put_cb(pa_core *core, pa_sink_input *i, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_sink_input_assert_ref(i);
+
+    return process(u, PA_OBJECT(i), TRUE);
+}
+
+static pa_hook_result_t sink_input_move_finish_cb(pa_core *core, pa_sink_input *i, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_sink_input_assert_ref(i);
+
+    if (pa_proplist_gets(i->proplist, PA_PROP_FILTER_APPLY_MOVING))
+        return PA_HOOK_OK;
+
+    return process(u, PA_OBJECT(i), TRUE);
+}
+
+static pa_hook_result_t sink_input_proplist_cb(pa_core *core, pa_sink_input *i, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_sink_input_assert_ref(i);
+
+    return process(u, PA_OBJECT(i), TRUE);
+}
+
+static pa_hook_result_t sink_input_unlink_cb(pa_core *core, pa_sink_input *i, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_sink_input_assert_ref(i);
+
+    pa_assert(u);
+
+    if (pa_hashmap_size(u->filters) > 0)
+        trigger_housekeeping(u);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sink_unlink_cb(pa_core *core, pa_sink *sink, struct userdata *u) {
+    void *state;
+    struct filter *filter = NULL;
+
+    pa_core_assert_ref(core);
+    pa_sink_assert_ref(sink);
+    pa_assert(u);
+
+    /* If either the parent or the sink we've loaded disappears,
+     * we should remove it from our hashmap */
+    PA_HASHMAP_FOREACH(filter, u->filters, state) {
+        if (filter->sink_master == sink || filter->sink == sink) {
+            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 */
+            if (filter->sink == sink) {
+                pa_sink_input *i;
+
+                PA_IDXSET_FOREACH(i, sink->inputs, idx)
+                    move_objects_for_filter(u, PA_OBJECT(i), filter, TRUE, TRUE);
+            }
+
+            idx = filter->module_index;
+            pa_hashmap_remove(u->filters, filter);
+            filter_free(filter);
+
+            if (can_unload_module(u, idx))
+                pa_module_unload_request_by_index(u->core, idx, TRUE);
+        }
+    }
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t source_output_put_cb(pa_core *core, pa_source_output *o, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_source_output_assert_ref(o);
+
+    return process(u, PA_OBJECT(o), FALSE);
+}
+
+static pa_hook_result_t source_output_move_finish_cb(pa_core *core, pa_source_output *o, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_source_output_assert_ref(o);
+
+    if (pa_proplist_gets(o->proplist, PA_PROP_FILTER_APPLY_MOVING))
+        return PA_HOOK_OK;
+
+    return process(u, PA_OBJECT(o), FALSE);
+}
+
+static pa_hook_result_t source_output_proplist_cb(pa_core *core, pa_source_output *o, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_source_output_assert_ref(o);
+
+    return process(u, PA_OBJECT(o), FALSE);
+}
+
+static pa_hook_result_t source_output_unlink_cb(pa_core *core, pa_source_output *o, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_source_output_assert_ref(o);
+
+    pa_assert(u);
+
+    if (pa_hashmap_size(u->filters) > 0)
+        trigger_housekeeping(u);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t source_unlink_cb(pa_core *core, pa_source *source, struct userdata *u) {
+    void *state;
+    struct filter *filter = NULL;
+
+    pa_core_assert_ref(core);
+    pa_source_assert_ref(source);
+    pa_assert(u);
+
+    /* If either the parent or the source we've loaded disappears,
+     * we should remove it from our hashmap */
+    PA_HASHMAP_FOREACH(filter, u->filters, state) {
+        if (filter->source_master == source || filter->source == source) {
+            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 */
+            if (filter->source == source) {
+                pa_source_output *o;
+
+                PA_IDXSET_FOREACH(o, source->outputs, idx)
+                    move_objects_for_filter(u, PA_OBJECT(o), filter, TRUE, FALSE);
+            }
+
+            idx = filter->module_index;
+            pa_hashmap_remove(u->filters, filter);
+            filter_free(filter);
+
+            if (can_unload_module(u, idx))
+                pa_module_unload_request_by_index(u->core, idx, TRUE);
+        }
+    }
+
+    return PA_HOOK_OK;
+}
+
+int pa__init(pa_module *m) {
+    pa_modargs *ma = NULL;
+    struct userdata *u;
+
+    pa_assert(m);
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments");
+        goto fail;
+    }
+
+    m->userdata = u = pa_xnew0(struct userdata, 1);
+
+    u->core = m->core;
+
+    u->autoclean = DEFAULT_AUTOCLEAN;
+    if (pa_modargs_get_value_boolean(ma, "autoclean", &u->autoclean) < 0) {
+        pa_log("Failed to parse autoclean value");
+        goto fail;
+    }
+
+    u->filters = pa_hashmap_new(filter_hash, filter_compare);
+
+    u->sink_input_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_put_cb, u);
+    u->sink_input_move_finish_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_finish_cb, u);
+    u->sink_input_proplist_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_proplist_cb, u);
+    u->sink_input_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_unlink_cb, u);
+    u->sink_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_LATE-1, (pa_hook_cb_t) sink_unlink_cb, u);
+    u->source_output_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], PA_HOOK_LATE, (pa_hook_cb_t) source_output_put_cb, u);
+    u->source_output_move_finish_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FINISH], PA_HOOK_LATE, (pa_hook_cb_t) source_output_move_finish_cb, u);
+    u->source_output_proplist_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PROPLIST_CHANGED], PA_HOOK_LATE, (pa_hook_cb_t) source_output_proplist_cb, u);
+    u->source_output_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK], PA_HOOK_LATE, (pa_hook_cb_t) source_output_unlink_cb, u);
+    u->source_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_LATE-1, (pa_hook_cb_t) source_unlink_cb, u);
+
+    pa_modargs_free(ma);
+
+    return 0;
+
+fail:
+    pa__done(m);
+
+    if (ma)
+        pa_modargs_free(ma);
+
+    return -1;
+}
+
+void pa__done(pa_module *m) {
+    struct userdata* u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    if (u->sink_input_put_slot)
+        pa_hook_slot_free(u->sink_input_put_slot);
+    if (u->sink_input_move_finish_slot)
+        pa_hook_slot_free(u->sink_input_move_finish_slot);
+    if (u->sink_input_proplist_slot)
+        pa_hook_slot_free(u->sink_input_proplist_slot);
+    if (u->sink_input_unlink_slot)
+        pa_hook_slot_free(u->sink_input_unlink_slot);
+    if (u->sink_unlink_slot)
+        pa_hook_slot_free(u->sink_unlink_slot);
+    if (u->source_output_put_slot)
+        pa_hook_slot_free(u->source_output_put_slot);
+    if (u->source_output_move_finish_slot)
+        pa_hook_slot_free(u->source_output_move_finish_slot);
+    if (u->source_output_proplist_slot)
+        pa_hook_slot_free(u->source_output_proplist_slot);
+    if (u->source_output_unlink_slot)
+        pa_hook_slot_free(u->source_output_unlink_slot);
+    if (u->source_unlink_slot)
+        pa_hook_slot_free(u->source_unlink_slot);
+
+    if (u->housekeeping_time_event)
+        u->core->mainloop->time_free(u->housekeeping_time_event);
+
+    if (u->filters) {
+        struct filter *f;
+
+        while ((f = pa_hashmap_steal_first(u->filters))) {
+            pa_module_unload_request_by_index(u->core, f->module_index, TRUE);
+            filter_free(f);
+        }
+
+        pa_hashmap_free(u->filters, NULL);
+    }
+
+    pa_xfree(u);
+}
diff --git a/src/modules/module-filter-heuristics.c b/src/modules/module-filter-heuristics.c
new file mode 100644 (file)
index 0000000..e158b95
--- /dev/null
@@ -0,0 +1,191 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2011 Colin Guthrie
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/macro.h>
+#include <pulsecore/hook-list.h>
+#include <pulsecore/core.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/sink-input.h>
+#include <pulsecore/modargs.h>
+
+#include "module-filter-heuristics-symdef.h"
+
+#define PA_PROP_FILTER_APPLY_MOVING "filter.apply.moving"
+#define PA_PROP_FILTER_HEURISTICS "filter.heuristics"
+
+PA_MODULE_AUTHOR("Colin Guthrie");
+PA_MODULE_DESCRIPTION("Detect when various filters are desirable");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(TRUE);
+
+static const char* const valid_modargs[] = {
+    NULL
+};
+
+struct userdata {
+    pa_core *core;
+    pa_hook_slot
+        *sink_input_put_slot,
+        *sink_input_move_finish_slot,
+        *source_output_put_slot,
+        *source_output_move_finish_slot;
+};
+
+static pa_hook_result_t process(struct userdata *u, pa_object *o, pa_bool_t is_sink_input) {
+    const char *want;
+    pa_proplist *pl, *parent_pl;
+
+    if (is_sink_input) {
+        pl = PA_SINK_INPUT(o)->proplist;
+        parent_pl = PA_SINK_INPUT(o)->sink->proplist;
+    } else {
+        pl = PA_SOURCE_OUTPUT(o)->proplist;
+        parent_pl = PA_SOURCE_OUTPUT(o)->source->proplist;
+    }
+
+    /* If the stream already specifies what it must have, then let it be. */
+    if (!pa_proplist_gets(pl, PA_PROP_FILTER_HEURISTICS) && pa_proplist_gets(pl, PA_PROP_FILTER_APPLY))
+        return PA_HOOK_OK;
+
+    /* On phone sinks, make sure we're not applying echo cancellation */
+    if (pa_str_in_list_spaces(pa_proplist_gets(parent_pl, PA_PROP_DEVICE_INTENDED_ROLES), "phone")) {
+        const char *apply = pa_proplist_gets(pl, PA_PROP_FILTER_APPLY);
+
+        if (apply && pa_streq(apply, "echo-cancel")) {
+            pa_proplist_unset(pl, PA_PROP_FILTER_APPLY);
+            pa_proplist_unset(pl, PA_PROP_FILTER_HEURISTICS);
+        }
+
+        return PA_HOOK_OK;
+    }
+
+    want = pa_proplist_gets(pl, PA_PROP_FILTER_WANT);
+
+    if (want) {
+        /* There's a filter that we want, ask module-filter-apply to apply it, and remember that we're managing filter.apply */
+        pa_proplist_sets(pl, PA_PROP_FILTER_APPLY, want);
+        pa_proplist_sets(pl, PA_PROP_FILTER_HEURISTICS, "1");
+    }
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sink_input_put_cb(pa_core *core, pa_sink_input *i, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_sink_input_assert_ref(i);
+    pa_assert(u);
+
+    return process(u, PA_OBJECT(i), TRUE);
+}
+
+static pa_hook_result_t sink_input_move_finish_cb(pa_core *core, pa_sink_input *i, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_sink_input_assert_ref(i);
+    pa_assert(u);
+
+    /* module-filter-apply triggered this move, ignore */
+    if (pa_proplist_gets(i->proplist, PA_PROP_FILTER_APPLY_MOVING))
+        return PA_HOOK_OK;
+
+    return process(u, PA_OBJECT(i), TRUE);
+}
+
+static pa_hook_result_t source_output_put_cb(pa_core *core, pa_source_output *i, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_source_output_assert_ref(i);
+    pa_assert(u);
+
+    return process(u, PA_OBJECT(i), FALSE);
+}
+
+static pa_hook_result_t source_output_move_finish_cb(pa_core *core, pa_source_output *i, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_source_output_assert_ref(i);
+    pa_assert(u);
+
+    /* module-filter-apply triggered this move, ignore */
+    if (pa_proplist_gets(i->proplist, PA_PROP_FILTER_APPLY_MOVING))
+        return PA_HOOK_OK;
+
+    return process(u, PA_OBJECT(i), FALSE);
+}
+
+int pa__init(pa_module *m) {
+    pa_modargs *ma = NULL;
+    struct userdata *u;
+
+    pa_assert(m);
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments");
+        goto fail;
+    }
+
+    m->userdata = u = pa_xnew(struct userdata, 1);
+
+    u->core = m->core;
+
+    u->sink_input_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], PA_HOOK_LATE-1, (pa_hook_cb_t) sink_input_put_cb, u);
+    u->sink_input_move_finish_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], PA_HOOK_LATE-1, (pa_hook_cb_t) sink_input_move_finish_cb, u);
+    u->source_output_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], PA_HOOK_LATE-1, (pa_hook_cb_t) source_output_put_cb, u);
+    u->source_output_move_finish_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FINISH], PA_HOOK_LATE-1, (pa_hook_cb_t) source_output_move_finish_cb, u);
+
+    pa_modargs_free(ma);
+
+    return 0;
+
+fail:
+    pa__done(m);
+
+    if (ma)
+        pa_modargs_free(ma);
+
+    return -1;
+
+
+}
+
+void pa__done(pa_module *m) {
+    struct userdata* u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    if (u->sink_input_put_slot)
+        pa_hook_slot_free(u->sink_input_put_slot);
+    if (u->sink_input_move_finish_slot)
+        pa_hook_slot_free(u->sink_input_move_finish_slot);
+    if (u->source_output_put_slot)
+        pa_hook_slot_free(u->source_output_put_slot);
+    if (u->source_output_move_finish_slot)
+        pa_hook_slot_free(u->source_output_move_finish_slot);
+
+    pa_xfree(u);
+
+}
diff --git a/src/modules/module-hal-detect-symdef.h b/src/modules/module-hal-detect-symdef.h
deleted file mode 100644 (file)
index db92a45..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulehaldetectsymdeffoo
-#define foomodulehaldetectsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_hal_detect_LTX_pa__init
-#define pa__done module_hal_detect_LTX_pa__done
-#define pa__get_author module_hal_detect_LTX_pa__get_author
-#define pa__get_description module_hal_detect_LTX_pa__get_description
-#define pa__get_usage module_hal_detect_LTX_pa__get_usage
-#define pa__get_version module_hal_detect_LTX_pa__get_version
-#define pa__get_deprecated module_hal_detect_LTX_pa__get_deprecated
-#define pa__load_once module_hal_detect_LTX_pa__load_once
-#define pa__get_n_used module_hal_detect_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c
deleted file mode 100644 (file)
index 1851913..0000000
+++ /dev/null
@@ -1,864 +0,0 @@
-/***
-    This file is part of PulseAudio.
-
-    Copyright 2006 Lennart Poettering
-    Copyright 2006 Shams E. King
-
-    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, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-    USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <pulse/xmalloc.h>
-#include <pulse/timeval.h>
-
-#include <pulsecore/core-error.h>
-#include <pulsecore/module.h>
-#include <pulsecore/log.h>
-#include <pulsecore/hashmap.h>
-#include <pulsecore/idxset.h>
-#include <pulsecore/core-util.h>
-#include <pulsecore/namereg.h>
-#include <pulsecore/core-scache.h>
-#include <pulsecore/modargs.h>
-#include <pulsecore/dbus-shared.h>
-
-#include <hal/libhal.h>
-
-#include "module-hal-detect-symdef.h"
-
-PA_MODULE_AUTHOR("Shahms King");
-PA_MODULE_DESCRIPTION("Detect available audio hardware and load matching drivers");
-PA_MODULE_VERSION(PACKAGE_VERSION);
-PA_MODULE_LOAD_ONCE(TRUE);
-#if defined(HAVE_ALSA) && defined(HAVE_OSS_OUTPUT)
-PA_MODULE_USAGE("api=<alsa or oss> "
-                "tsched=<enable system timer based scheduling mode?>"
-                "subdevices=<init all subdevices>");
-#elif defined(HAVE_ALSA)
-PA_MODULE_USAGE("api=<alsa> "
-                "tsched=<enable system timer based scheduling mode?>");
-#elif defined(HAVE_OSS_OUTPUT)
-PA_MODULE_USAGE("api=<oss>"
-                "subdevices=<init all subdevices>");
-#endif
-PA_MODULE_DEPRECATED("Please use module-udev-detect instead of module-hal-detect!");
-
-struct device {
-    char *udi, *originating_udi;
-    char *card_name, *sink_name, *source_name;
-    uint32_t module;
-    pa_bool_t acl_race_fix;
-};
-
-struct userdata {
-    pa_core *core;
-    LibHalContext *context;
-    pa_dbus_connection *connection;
-    pa_hashmap *devices; /* Every entry is indexed twice in this table: by the udi we found the device with and by the originating device's udi */
-    const char *capability;
-#ifdef HAVE_ALSA
-    pa_bool_t use_tsched;
-#endif
-#ifdef HAVE_OSS_OUTPUT
-    pa_bool_t init_subdevs;
-#endif
-};
-
-#define CAPABILITY_ALSA "alsa"
-#define CAPABILITY_OSS "oss"
-
-static const char* const valid_modargs[] = {
-    "api",
-#ifdef HAVE_ALSA
-    "tsched",
-#endif
-#ifdef HAVE_OSS_OUTPUT
-    "subdevices",
-#endif
-    NULL
-};
-
-static void device_free(struct device* d) {
-    pa_assert(d);
-
-    pa_xfree(d->udi);
-    pa_xfree(d->originating_udi);
-    pa_xfree(d->sink_name);
-    pa_xfree(d->source_name);
-    pa_xfree(d->card_name);
-    pa_xfree(d);
-}
-
-static const char *strip_udi(const char *udi) {
-    const char *slash;
-
-    pa_assert(udi);
-
-    if ((slash = strrchr(udi, '/')))
-        return slash+1;
-
-    return udi;
-}
-
-#ifdef HAVE_ALSA
-
-enum alsa_type {
-    ALSA_TYPE_PLAYBACK,
-    ALSA_TYPE_CAPTURE,
-    ALSA_TYPE_CONTROL,
-    ALSA_TYPE_OTHER
-};
-
-static enum alsa_type hal_alsa_device_get_type(LibHalContext *context, const char *udi) {
-    char *type;
-    enum alsa_type t = ALSA_TYPE_OTHER;
-    DBusError error;
-
-    dbus_error_init(&error);
-
-    pa_assert(context);
-    pa_assert(udi);
-
-    if (!(type = libhal_device_get_property_string(context, udi, "alsa.type", &error)))
-        goto finish;
-
-    if (pa_streq(type, "playback"))
-        t = ALSA_TYPE_PLAYBACK;
-    else if (pa_streq(type, "capture"))
-        t = ALSA_TYPE_CAPTURE;
-    else if (pa_streq(type, "control"))
-        t = ALSA_TYPE_CONTROL;
-
-    libhal_free_string(type);
-
-finish:
-    if (dbus_error_is_set(&error)) {
-        pa_log_error("D-Bus error while parsing HAL ALSA data: %s: %s", error.name, error.message);
-        dbus_error_free(&error);
-    }
-
-    return t;
-}
-
-static pa_bool_t hal_alsa_device_is_modem(LibHalContext *context, const char *udi) {
-    char *class;
-    pa_bool_t r = FALSE;
-    DBusError error;
-
-    dbus_error_init(&error);
-
-    pa_assert(context);
-    pa_assert(udi);
-
-    if (!(class = libhal_device_get_property_string(context, udi, "alsa.pcm_class", &error)))
-        goto finish;
-
-    r = pa_streq(class, "modem");
-    libhal_free_string(class);
-
-finish:
-    if (dbus_error_is_set(&error)) {
-        if (!dbus_error_has_name(&error, "org.freedesktop.Hal.NoSuchProperty"))
-            pa_log_error("D-Bus error while parsing HAL ALSA data: %s: %s", error.name, error.message);
-        dbus_error_free(&error);
-    }
-
-    return r;
-}
-
-static int hal_device_load_alsa(struct userdata *u, const char *udi, struct device *d) {
-    enum alsa_type type;
-    int card;
-    DBusError error;
-    pa_module *m;
-    char *args, *originating_udi = NULL, *card_name = NULL;
-
-    dbus_error_init(&error);
-
-    pa_assert(u);
-    pa_assert(udi);
-    pa_assert(d);
-
-    /* We only care for PCM devices */
-    type = hal_alsa_device_get_type(u->context, udi);
-
-    /* For each ALSA card that appears the control device will be the
-     * last one to be created, this is considered part of the ALSA
-     * usperspace API. We rely on this and load our modules only when
-     * the control device is available assuming that *all* device
-     * nodes have been properly created and assigned the right ACLs at
-     * that time. Also see:
-     *
-     * http://mailman.alsa-project.org/pipermail/alsa-devel/2009-April/015958.html
-     *
-     * and the associated thread.*/
-
-    if (type != ALSA_TYPE_CONTROL)
-        goto fail;
-
-    /* We don't care for modems -- this is most likely not set for
-     * control devices, so kind of pointless here. */
-    if (hal_alsa_device_is_modem(u->context, udi))
-        goto fail;
-
-    /* We store only one entry per card, hence we look for the originating device */
-    originating_udi = libhal_device_get_property_string(u->context, udi, "alsa.originating_device", &error);
-    if (dbus_error_is_set(&error) || !originating_udi)
-        goto fail;
-
-    /* Make sure we only load one module per card */
-    if (pa_hashmap_get(u->devices, originating_udi))
-        goto fail;
-
-    /* We need the identifier */
-    card = libhal_device_get_property_int(u->context, udi, "alsa.card", &error);
-    if (dbus_error_is_set(&error))
-        goto fail;
-
-    card_name = pa_sprintf_malloc("alsa_card.%s", strip_udi(originating_udi));
-    args = pa_sprintf_malloc("device_id=%u name=\"%s\" card_name=\"%s\" tsched=%i card_properties=\"module-hal-detect.discovered=1\"", card, strip_udi(originating_udi), card_name, (int) u->use_tsched);
-
-    pa_log_debug("Loading module-alsa-card with arguments '%s'", args);
-    m = pa_module_load(u->core, "module-alsa-card", args);
-    pa_xfree(args);
-
-    if (!m)
-        goto fail;
-
-    d->originating_udi = originating_udi;
-    d->module = m->index;
-    d->card_name = card_name;
-
-    return 0;
-
-fail:
-    if (dbus_error_is_set(&error)) {
-        pa_log_error("D-Bus error while parsing HAL ALSA data: %s: %s", error.name, error.message);
-        dbus_error_free(&error);
-    }
-
-    pa_xfree(originating_udi);
-    pa_xfree(card_name);
-
-    return -1;
-}
-
-#endif
-
-#ifdef HAVE_OSS_OUTPUT
-
-static pa_bool_t hal_oss_device_is_pcm(LibHalContext *context, const char *udi, pa_bool_t init_subdevices) {
-    char *class = NULL, *dev = NULL, *e;
-    int device;
-    pa_bool_t r = FALSE;
-    DBusError error;
-
-    dbus_error_init(&error);
-
-    pa_assert(context);
-    pa_assert(udi);
-
-    /* We only care for PCM devices */
-    class = libhal_device_get_property_string(context, udi, "oss.type", &error);
-    if (dbus_error_is_set(&error) || !class)
-        goto finish;
-
-    if (!pa_streq(class, "pcm"))
-        goto finish;
-
-    /* We don't like /dev/audio */
-    dev = libhal_device_get_property_string(context, udi, "oss.device_file", &error);
-    if (dbus_error_is_set(&error) || !dev)
-        goto finish;
-
-    if ((e = strrchr(dev, '/')))
-        if (pa_startswith(e + 1, "audio"))
-            goto finish;
-
-    /* We only care for the main device */
-    device = libhal_device_get_property_int(context, udi, "oss.device", &error);
-    if (dbus_error_is_set(&error) || (device != 0 && init_subdevices == FALSE))
-        goto finish;
-
-    r = TRUE;
-
-finish:
-
-    if (dbus_error_is_set(&error)) {
-        pa_log_error("D-Bus error while parsing HAL OSS data: %s: %s", error.name, error.message);
-        dbus_error_free(&error);
-    }
-
-    libhal_free_string(class);
-    libhal_free_string(dev);
-
-    return r;
-}
-
-static int hal_device_load_oss(struct userdata *u, const char *udi, struct device *d) {
-    DBusError error;
-    pa_module *m;
-    char *args, *originating_udi = NULL, *device, *sink_name = NULL, *source_name = NULL;
-
-    dbus_error_init(&error);
-
-    pa_assert(u);
-    pa_assert(udi);
-    pa_assert(d);
-
-    /* We only care for OSS PCM devices */
-    if (!hal_oss_device_is_pcm(u->context, udi, u->init_subdevs))
-        goto fail;
-
-    /* We store only one entry per card, hence we look for the originating device */
-    originating_udi = libhal_device_get_property_string(u->context, udi, "oss.originating_device", &error);
-    if (dbus_error_is_set(&error) || !originating_udi)
-        goto fail;
-
-    /* Make sure we only load one module per card */
-    if (pa_hashmap_get(u->devices, originating_udi))
-        goto fail;
-
-    /* We need the device file */
-    device = libhal_device_get_property_string(u->context, udi, "oss.device_file", &error);
-    if (!device || dbus_error_is_set(&error))
-        goto fail;
-
-    sink_name = pa_sprintf_malloc("oss_output.%s", strip_udi(udi));
-    source_name = pa_sprintf_malloc("oss_input.%s", strip_udi(udi));
-    args = pa_sprintf_malloc("device=%s sink_name=%s source_name=%s", device, sink_name, source_name);
-
-    libhal_free_string(device);
-
-    pa_log_debug("Loading module-oss with arguments '%s'", args);
-    m = pa_module_load(u->core, "module-oss", args);
-    pa_xfree(args);
-
-    if (!m)
-        goto fail;
-
-    d->originating_udi = originating_udi;
-    d->module = m->index;
-    d->sink_name = sink_name;
-    d->source_name = source_name;
-
-    return 0;
-
-fail:
-    if (dbus_error_is_set(&error)) {
-        pa_log_error("D-Bus error while parsing OSS HAL data: %s: %s", error.name, error.message);
-        dbus_error_free(&error);
-    }
-
-    pa_xfree(originating_udi);
-    pa_xfree(source_name);
-    pa_xfree(sink_name);
-
-    return -1;
-}
-#endif
-
-static struct device* hal_device_add(struct userdata *u, const char *udi) {
-    struct device *d;
-    int r;
-
-    pa_assert(u);
-    pa_assert(u->capability);
-
-    d = pa_xnew(struct device, 1);
-    d->acl_race_fix = FALSE;
-    d->udi = pa_xstrdup(udi);
-    d->originating_udi = NULL;
-    d->module = PA_INVALID_INDEX;
-    d->sink_name = d->source_name = d->card_name = NULL;
-    r = -1;
-
-#ifdef HAVE_ALSA
-    if (pa_streq(u->capability, CAPABILITY_ALSA))
-        r = hal_device_load_alsa(u, udi,  d);
-#endif
-#ifdef HAVE_OSS_OUTPUT
-    if (pa_streq(u->capability, CAPABILITY_OSS))
-        r = hal_device_load_oss(u, udi, d);
-#endif
-
-    if (r < 0) {
-        device_free(d);
-        return NULL;
-    }
-
-    pa_hashmap_put(u->devices, d->udi, d);
-    pa_hashmap_put(u->devices, d->originating_udi, d);
-
-    return d;
-}
-
-static int hal_device_add_all(struct userdata *u) {
-    int n, count = 0;
-    char** udis;
-    DBusError error;
-
-    dbus_error_init(&error);
-
-    pa_assert(u);
-
-    udis = libhal_find_device_by_capability(u->context, u->capability, &n, &error);
-    if (dbus_error_is_set(&error) || !udis)
-        goto fail;
-
-    if (n > 0) {
-        int i;
-
-        for (i = 0; i < n; i++) {
-            if (hal_device_add(u, udis[i])) {
-                count++;
-                pa_log_debug("Loaded device %s", udis[i]);
-            } else
-                pa_log_debug("Not loaded device %s", udis[i]);
-        }
-    }
-
-    libhal_free_string_array(udis);
-
-    return count;
-
-fail:
-    if (dbus_error_is_set(&error)) {
-        pa_log_error("D-Bus error while parsing HAL data: %s: %s", error.name, error.message);
-        dbus_error_free(&error);
-    }
-
-    return -1;
-}
-
-static void device_added_cb(LibHalContext *context, const char *udi) {
-    DBusError error;
-    struct userdata *u;
-    pa_bool_t good = FALSE;
-
-    dbus_error_init(&error);
-
-    pa_assert(context);
-    pa_assert(udi);
-
-    pa_assert_se(u = libhal_ctx_get_user_data(context));
-
-    good = libhal_device_query_capability(context, udi, u->capability, &error);
-    if (dbus_error_is_set(&error) || !good)
-        goto finish;
-
-    if (!hal_device_add(u, udi))
-        pa_log_debug("Not loaded device %s", udi);
-    else
-        pa_log_debug("Loaded device %s", udi);
-
-finish:
-    if (dbus_error_is_set(&error)) {
-        if (!dbus_error_has_name(&error, "org.freedesktop.Hal.NoSuchProperty"))
-            pa_log_error("D-Bus error while parsing HAL data: %s: %s", error.name, error.message);
-        dbus_error_free(&error);
-    }
-}
-
-static void device_removed_cb(LibHalContext* context, const char *udi) {
-    struct device *d;
-    struct userdata *u;
-
-    pa_assert(context);
-    pa_assert(udi);
-
-    pa_assert_se(u = libhal_ctx_get_user_data(context));
-
-    if (!(d = pa_hashmap_get(u->devices, udi)))
-        return;
-
-    pa_hashmap_remove(u->devices, d->originating_udi);
-    pa_hashmap_remove(u->devices, d->udi);
-
-    pa_log_debug("Removing HAL device: %s", d->originating_udi);
-
-    pa_module_unload_request_by_index(u->core, d->module, TRUE);
-    device_free(d);
-}
-
-static void new_capability_cb(LibHalContext *context, const char *udi, const char* capability) {
-    struct userdata *u;
-
-    pa_assert(context);
-    pa_assert(udi);
-    pa_assert(capability);
-
-    pa_assert_se(u = libhal_ctx_get_user_data(context));
-
-    if (pa_streq(u->capability, capability))
-        /* capability we care about, pretend it's a new device */
-        device_added_cb(context, udi);
-}
-
-static void lost_capability_cb(LibHalContext *context, const char *udi, const char* capability) {
-    struct userdata *u;
-
-    pa_assert(context);
-    pa_assert(udi);
-    pa_assert(capability);
-
-    pa_assert_se(u = libhal_ctx_get_user_data(context));
-
-    if (pa_streq(u->capability, capability))
-        /* capability we care about, pretend it was removed */
-        device_removed_cb(context, udi);
-}
-
-static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata) {
-    struct userdata*u;
-    DBusError error;
-
-    pa_assert(bus);
-    pa_assert(message);
-    pa_assert_se(u = userdata);
-
-    dbus_error_init(&error);
-
-    pa_log_debug("dbus: interface=%s, path=%s, member=%s\n",
-                 dbus_message_get_interface(message),
-                 dbus_message_get_path(message),
-                 dbus_message_get_member(message));
-
-    if (dbus_message_is_signal(message, "org.freedesktop.Hal.Device.AccessControl", "ACLAdded") ||
-        dbus_message_is_signal(message, "org.freedesktop.Hal.Device.AccessControl", "ACLRemoved")) {
-        uint32_t uid;
-        pa_bool_t suspend = strcmp(dbus_message_get_member(message), "ACLRemoved") == 0;
-
-        if (!dbus_message_get_args(message, &error, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INVALID) || dbus_error_is_set(&error)) {
-            pa_log_error("Failed to parse ACL message: %s: %s", error.name, error.message);
-            goto finish;
-        }
-
-        /* Check if this is about us? */
-        if (uid == getuid() || uid == geteuid()) {
-            struct device *d;
-            const char *udi;
-
-            udi = dbus_message_get_path(message);
-
-            if ((d = pa_hashmap_get(u->devices, udi))) {
-                pa_bool_t send_acl_race_fix_message = FALSE;
-                d->acl_race_fix = FALSE;
-
-                if (d->sink_name) {
-                    pa_sink *sink;
-
-                    if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK))) {
-                        pa_bool_t success = pa_sink_suspend(sink, suspend, PA_SUSPEND_SESSION) >= 0;
-
-                        if (!success && !suspend)
-                            d->acl_race_fix = TRUE; /* resume failed, let's try again */
-                        else if (suspend)
-                            send_acl_race_fix_message = TRUE; /* suspend finished, let's tell everyone to try again */
-                    }
-                }
-
-                if (d->source_name) {
-                    pa_source *source;
-
-                    if ((source = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_SOURCE))) {
-                        pa_bool_t success = pa_source_suspend(source, suspend, PA_SUSPEND_SESSION) >= 0;
-
-                        if (!success && !suspend)
-                            d->acl_race_fix = TRUE; /* resume failed, let's try again */
-                        else if (suspend)
-                            send_acl_race_fix_message = TRUE; /* suspend finished, let's tell everyone to try again */
-                    }
-                }
-
-                if (d->card_name) {
-                    pa_card *card;
-
-                    if ((card = pa_namereg_get(u->core, d->card_name, PA_NAMEREG_CARD))) {
-                        pa_bool_t success = pa_card_suspend(card, suspend, PA_SUSPEND_SESSION) >= 0;
-
-                        if (!success && !suspend)
-                            d->acl_race_fix = TRUE; /* resume failed, let's try again */
-                        else if (suspend)
-                            send_acl_race_fix_message = TRUE; /* suspend finished, let's tell everyone to try again */
-                    }
-                }
-
-                if (send_acl_race_fix_message) {
-                    DBusMessage *msg;
-                    msg = dbus_message_new_signal(udi, "org.pulseaudio.Server", "DirtyGiveUpMessage");
-                    dbus_connection_send(pa_dbus_connection_get(u->connection), msg, NULL);
-                    dbus_message_unref(msg);
-                }
-
-            } else if (!suspend)
-                device_added_cb(u->context, udi);
-
-        }
-
-    } else if (dbus_message_is_signal(message, "org.pulseaudio.Server", "DirtyGiveUpMessage")) {
-        /* We use this message to avoid a dirty race condition when we
-           get an ACLAdded message before the previously owning PA
-           sever has closed the device. We can remove this as
-           soon as HAL learns frevoke() */
-
-        struct device *d;
-        const char *udi;
-
-        udi = dbus_message_get_path(message);
-
-        if ((d = pa_hashmap_get(u->devices, udi))) {
-
-            if (d->acl_race_fix) {
-                d->acl_race_fix = FALSE;
-                pa_log_debug("Got dirty give up message for '%s', trying resume ...", udi);
-
-                if (d->sink_name) {
-                    pa_sink *sink;
-
-                    if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK)))
-                        pa_sink_suspend(sink, FALSE, PA_SUSPEND_SESSION);
-                }
-
-                if (d->source_name) {
-                    pa_source *source;
-
-                    if ((source = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_SOURCE)))
-                        pa_source_suspend(source, FALSE, PA_SUSPEND_SESSION);
-                }
-
-                if (d->card_name) {
-                    pa_card *card;
-
-                    if ((card = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_CARD)))
-                        pa_card_suspend(card, FALSE, PA_SUSPEND_SESSION);
-                }
-            }
-
-        } else
-            /* Yes, we don't check the UDI for validity, but hopefully HAL will */
-            device_added_cb(u->context, udi);
-
-    }
-
-finish:
-    dbus_error_free(&error);
-
-    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-static void hal_context_free(LibHalContext* hal_context) {
-    DBusError error;
-
-    dbus_error_init(&error);
-
-    libhal_ctx_shutdown(hal_context, &error);
-    libhal_ctx_free(hal_context);
-
-    dbus_error_free(&error);
-}
-
-static LibHalContext* hal_context_new(DBusConnection *connection) {
-    DBusError error;
-    LibHalContext *hal_context = NULL;
-
-    dbus_error_init(&error);
-
-    pa_assert(connection);
-
-    if (!(hal_context = libhal_ctx_new())) {
-        pa_log_error("libhal_ctx_new() failed");
-        goto fail;
-    }
-
-    if (!libhal_ctx_set_dbus_connection(hal_context, connection)) {
-        pa_log_error("Error establishing DBUS connection: %s: %s", error.name, error.message);
-        goto fail;
-    }
-
-    if (!libhal_ctx_init(hal_context, &error)) {
-        pa_log_error("Couldn't connect to hald: %s: %s", error.name, error.message);
-        goto fail;
-    }
-
-    return hal_context;
-
-fail:
-    if (hal_context)
-        hal_context_free(hal_context);
-
-    dbus_error_free(&error);
-
-    return NULL;
-}
-
-int pa__init(pa_module*m) {
-    DBusError error;
-    struct userdata *u = NULL;
-    int n = 0;
-    pa_modargs *ma;
-    const char *api;
-
-    pa_assert(m);
-
-    dbus_error_init(&error);
-
-    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
-        pa_log("Failed to parse module arguments");
-        goto fail;
-    }
-
-    m->userdata = u = pa_xnew(struct userdata, 1);
-    u->core = m->core;
-    u->context = NULL;
-    u->connection = NULL;
-    u->devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-    u->capability = NULL;
-
-#ifdef HAVE_ALSA
-    u->use_tsched = TRUE;
-
-    if (pa_modargs_get_value_boolean(ma, "tsched", &u->use_tsched) < 0) {
-        pa_log("Failed to parse tsched argument.");
-        goto fail;
-    }
-
-    api = pa_modargs_get_value(ma, "api", "alsa");
-
-    if (pa_streq(api, "alsa"))
-        u->capability = CAPABILITY_ALSA;
-#else
-    api = pa_modargs_get_value(ma, "api", "oss");
-#endif
-
-#ifdef HAVE_OSS_OUTPUT
-    if (pa_streq(api, "oss"))
-        u->capability = CAPABILITY_OSS;
-#endif
-
-    if (!u->capability) {
-        pa_log_error("Invalid API specification.");
-        goto fail;
-    }
-
-#ifdef HAVE_OSS_OUTPUT
-    if (pa_modargs_get_value_boolean(ma, "subdevices", &u->init_subdevs) < 0) {
-        pa_log("Failed to parse subdevices= argument.");
-        goto fail;
-    }
-#endif
-
-    if (!(u->connection = pa_dbus_bus_get(m->core, DBUS_BUS_SYSTEM, &error)) || dbus_error_is_set(&error)) {
-        pa_log_error("Unable to contact DBUS system bus: %s: %s", error.name, error.message);
-        goto fail;
-    }
-
-    if (!(u->context = hal_context_new(pa_dbus_connection_get(u->connection)))) {
-        /* pa_hal_context_new() logs appropriate errors */
-        goto fail;
-    }
-
-    n = hal_device_add_all(u);
-
-    libhal_ctx_set_user_data(u->context, u);
-    libhal_ctx_set_device_added(u->context, device_added_cb);
-    libhal_ctx_set_device_removed(u->context, device_removed_cb);
-    libhal_ctx_set_device_new_capability(u->context, new_capability_cb);
-    libhal_ctx_set_device_lost_capability(u->context, lost_capability_cb);
-
-    if (!libhal_device_property_watch_all(u->context, &error)) {
-        pa_log_error("Error monitoring device list: %s: %s", error.name, error.message);
-        goto fail;
-    }
-
-    if (!dbus_connection_add_filter(pa_dbus_connection_get(u->connection), filter_cb, u, NULL)) {
-        pa_log_error("Failed to add filter function");
-        goto fail;
-    }
-
-    if (pa_dbus_add_matches(
-                pa_dbus_connection_get(u->connection), &error,
-                "type='signal',sender='org.freedesktop.Hal',interface='org.freedesktop.Hal.Device.AccessControl',member='ACLAdded'",
-                "type='signal',sender='org.freedesktop.Hal',interface='org.freedesktop.Hal.Device.AccessControl',member='ACLRemoved'",
-                "type='signal',interface='org.pulseaudio.Server',member='DirtyGiveUpMessage'", NULL) < 0) {
-        pa_log_error("Unable to subscribe to HAL ACL signals: %s: %s", error.name, error.message);
-        goto fail;
-    }
-
-    pa_log_info("Loaded %i modules.", n);
-
-    pa_modargs_free(ma);
-
-    return 0;
-
-fail:
-    if (ma)
-        pa_modargs_free(ma);
-
-    dbus_error_free(&error);
-    pa__done(m);
-
-    return -1;
-}
-
-void pa__done(pa_module *m) {
-    struct userdata *u;
-
-    pa_assert(m);
-
-    if (!(u = m->userdata))
-        return;
-
-    if (u->context)
-        hal_context_free(u->context);
-
-    if (u->devices) {
-        struct device *d;
-
-        while ((d = pa_hashmap_first(u->devices))) {
-            pa_hashmap_remove(u->devices, d->udi);
-            pa_hashmap_remove(u->devices, d->originating_udi);
-            device_free(d);
-        }
-
-        pa_hashmap_free(u->devices, NULL, NULL);
-    }
-
-    if (u->connection) {
-        pa_dbus_remove_matches(
-                pa_dbus_connection_get(u->connection),
-                "type='signal',sender='org.freedesktop.Hal',interface='org.freedesktop.Hal.Device.AccessControl',member='ACLAdded'",
-                "type='signal',sender='org.freedesktop.Hal',interface='org.freedesktop.Hal.Device.AccessControl',member='ACLRemoved'",
-                "type='signal',interface='org.pulseaudio.Server',member='DirtyGiveUpMessage'", NULL);
-
-        dbus_connection_remove_filter(pa_dbus_connection_get(u->connection), filter_cb, u);
-        pa_dbus_connection_unref(u->connection);
-    }
-
-    pa_xfree(u);
-}
diff --git a/src/modules/module-http-protocol-tcp-symdef.h b/src/modules/module-http-protocol-tcp-symdef.h
deleted file mode 100644 (file)
index 4f59137..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulehttpprotocoltcpsymdeffoo
-#define foomodulehttpprotocoltcpsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_http_protocol_tcp_LTX_pa__init
-#define pa__done module_http_protocol_tcp_LTX_pa__done
-#define pa__get_author module_http_protocol_tcp_LTX_pa__get_author
-#define pa__get_description module_http_protocol_tcp_LTX_pa__get_description
-#define pa__get_usage module_http_protocol_tcp_LTX_pa__get_usage
-#define pa__get_version module_http_protocol_tcp_LTX_pa__get_version
-#define pa__get_deprecated module_http_protocol_tcp_LTX_pa__get_deprecated
-#define pa__load_once module_http_protocol_tcp_LTX_pa__load_once
-#define pa__get_n_used module_http_protocol_tcp_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
diff --git a/src/modules/module-http-protocol-unix-symdef.h b/src/modules/module-http-protocol-unix-symdef.h
deleted file mode 100644 (file)
index d57aff0..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulehttpprotocolunixsymdeffoo
-#define foomodulehttpprotocolunixsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_http_protocol_unix_LTX_pa__init
-#define pa__done module_http_protocol_unix_LTX_pa__done
-#define pa__get_author module_http_protocol_unix_LTX_pa__get_author
-#define pa__get_description module_http_protocol_unix_LTX_pa__get_description
-#define pa__get_usage module_http_protocol_unix_LTX_pa__get_usage
-#define pa__get_version module_http_protocol_unix_LTX_pa__get_version
-#define pa__get_deprecated module_http_protocol_unix_LTX_pa__get_deprecated
-#define pa__load_once module_http_protocol_unix_LTX_pa__load_once
-#define pa__get_n_used module_http_protocol_unix_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
diff --git a/src/modules/module-intended-roles-symdef.h b/src/modules/module-intended-roles-symdef.h
deleted file mode 100644 (file)
index a3aa825..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleintendedrolessymdeffoo
-#define foomoduleintendedrolessymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_intended_roles_LTX_pa__init
-#define pa__done module_intended_roles_LTX_pa__done
-#define pa__get_author module_intended_roles_LTX_pa__get_author
-#define pa__get_description module_intended_roles_LTX_pa__get_description
-#define pa__get_usage module_intended_roles_LTX_pa__get_usage
-#define pa__get_version module_intended_roles_LTX_pa__get_version
-#define pa__get_deprecated module_intended_roles_LTX_pa__get_deprecated
-#define pa__load_once module_intended_roles_LTX_pa__load_once
-#define pa__get_n_used module_intended_roles_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index b9924df..d1e9b81 100644 (file)
 #endif
 
 #include <pulse/xmalloc.h>
-#include <pulse/volume.h>
-#include <pulse/timeval.h>
-#include <pulse/util.h>
 
-#include <pulsecore/core-error.h>
 #include <pulsecore/module.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/log.h>
-#include <pulsecore/core-subscribe.h>
 #include <pulsecore/sink-input.h>
 #include <pulsecore/source-output.h>
 #include <pulsecore/namereg.h>
@@ -71,24 +66,7 @@ struct userdata {
 };
 
 static pa_bool_t role_match(pa_proplist *proplist, const char *role) {
-    const char *ir;
-    char *r;
-    const char *state = NULL;
-
-    if (!(ir = pa_proplist_gets(proplist, PA_PROP_DEVICE_INTENDED_ROLES)))
-        return FALSE;
-
-    while ((r = pa_split_spaces(ir, &state))) {
-
-        if (pa_streq(role, r)) {
-            pa_xfree(r);
-            return TRUE;
-        }
-
-        pa_xfree(r);
-    }
-
-    return FALSE;
+    return pa_str_in_list_spaces(pa_proplist_gets(proplist, PA_PROP_DEVICE_INTENDED_ROLES), role);
 }
 
 static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u) {
@@ -117,12 +95,10 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
 
     /* Prefer the default sink over any other sink, just in case... */
     if ((def = pa_namereg_get_default_sink(c)))
-        if (role_match(def->proplist, role)) {
-            new_data->sink = def;
-            new_data->save_sink = FALSE;
+        if (role_match(def->proplist, role) && pa_sink_input_new_data_set_sink(new_data, def, FALSE))
             return PA_HOOK_OK;
-        }
 
+    /* @todo: favour the highest priority device, not the first one we find? */
     PA_IDXSET_FOREACH(s, c->sinks, idx) {
         if (s == def)
             continue;
@@ -130,11 +106,8 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
         if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)))
             continue;
 
-        if (role_match(s->proplist, role)) {
-            new_data->sink = s;
-            new_data->save_sink = FALSE;
+        if (role_match(s->proplist, role) && pa_sink_input_new_data_set_sink(new_data, s, FALSE))
             return PA_HOOK_OK;
-        }
     }
 
     return PA_HOOK_OK;
@@ -167,21 +140,23 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou
     /* Prefer the default source over any other source, just in case... */
     if ((def = pa_namereg_get_default_source(c)))
         if (role_match(def->proplist, role)) {
-            new_data->source = def;
-            new_data->save_source = FALSE;
+            pa_source_output_new_data_set_source(new_data, def, FALSE);
             return PA_HOOK_OK;
         }
 
     PA_IDXSET_FOREACH(s, c->sources, idx) {
+        if (s->monitor_of)
+            continue;
+
         if (s == def)
             continue;
 
         if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)))
             continue;
 
+        /* @todo: favour the highest priority device, not the first one we find? */
         if (role_match(s->proplist, role)) {
-            new_data->source = s;
-            new_data->save_source = FALSE;
+            pa_source_output_new_data_set_source(new_data, s, FALSE);
             return PA_HOOK_OK;
         }
     }
@@ -242,6 +217,9 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
     pa_assert(u);
     pa_assert(u->on_hotplug);
 
+    if (source->monitor_of)
+        return PA_HOOK_OK;
+
     PA_IDXSET_FOREACH(so, c->source_outputs, idx) {
         const char *role;
 
@@ -315,6 +293,7 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, str
                 continue;
 
         /* Try to find some other fitting sink */
+        /* @todo: favour the highest priority device, not the first one we find? */
         PA_IDXSET_FOREACH(d, c->sinks, jdx) {
             if (d == def || d == sink)
                 continue;
@@ -370,6 +349,7 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
         }
 
         /* Try to find some other fitting source */
+        /* @todo: favour the highest priority device, not the first one we find? */
         PA_IDXSET_FOREACH(d, c->sources, jdx) {
             if (d == def || d == source)
                 continue;
@@ -377,7 +357,8 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
             if (!PA_SOURCE_IS_LINKED(pa_source_get_state(d)))
                 continue;
 
-            if (role_match(d->proplist, role) && !source->monitor_of == !d->monitor_of) {
+            /* If moving from a monitor, move to another monitor */
+            if (!source->monitor_of == !d->monitor_of && role_match(d->proplist, role)) {
                 pa_source_output_move_to(so, d, FALSE);
                 break;
             }
@@ -436,7 +417,7 @@ fail:
     if (ma)
         pa_modargs_free(ma);
 
-    return  -1;
+    return -1;
 }
 
 void pa__done(pa_module*m) {
diff --git a/src/modules/module-ladspa-sink-symdef.h b/src/modules/module-ladspa-sink-symdef.h
deleted file mode 100644 (file)
index 688ec2b..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleladspasinksymdeffoo
-#define foomoduleladspasinksymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_ladspa_sink_LTX_pa__init
-#define pa__done module_ladspa_sink_LTX_pa__done
-#define pa__get_author module_ladspa_sink_LTX_pa__get_author
-#define pa__get_description module_ladspa_sink_LTX_pa__get_description
-#define pa__get_usage module_ladspa_sink_LTX_pa__get_usage
-#define pa__get_version module_ladspa_sink_LTX_pa__get_version
-#define pa__get_deprecated module_ladspa_sink_LTX_pa__get_deprecated
-#define pa__load_once module_ladspa_sink_LTX_pa__load_once
-#define pa__get_n_used module_ladspa_sink_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 994c778..6a757e4 100644 (file)
 #include <config.h>
 #endif
 
+#include <math.h>
+
 #include <pulse/xmalloc.h>
-#include <pulse/i18n.h>
 
-#include <pulsecore/core-error.h>
+#include <pulsecore/i18n.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/sink.h>
 #include <pulsecore/module.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/log.h>
-#include <pulsecore/thread.h>
-#include <pulsecore/thread-mq.h>
 #include <pulsecore/rtpoll.h>
 #include <pulsecore/sample-util.h>
 #include <pulsecore/ltdl-helper.h>
 
+#ifdef HAVE_DBUS
+#include <pulsecore/protocol-dbus.h>
+#include <pulsecore/dbus-util.h>
+#endif
+
 #include "module-ladspa-sink-symdef.h"
 #include "ladspa.h"
 
@@ -50,19 +54,24 @@ PA_MODULE_DESCRIPTION(_("Virtual LADSPA sink"));
 PA_MODULE_VERSION(PACKAGE_VERSION);
 PA_MODULE_LOAD_ONCE(FALSE);
 PA_MODULE_USAGE(
-        _("sink_name=<name for the sink> "
-          "sink_properties=<properties for the sink> "
-          "master=<name of sink to filter> "
-          "format=<sample format> "
-          "rate=<sample rate> "
-          "channels=<number of channels> "
-          "channel_map=<channel map> "
-          "plugin=<ladspa plugin name> "
-          "label=<ladspa plugin label> "
-          "control=<comma seperated list of input control values>"));
+    _("sink_name=<name for the sink> "
+      "sink_properties=<properties for the 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> "));
 
 #define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
 
+/* PLEASE NOTICE: The PortAudio ports and the LADSPA ports are two different concepts.
+They are not related and where possible the names of the LADSPA port variables contains "ladspa" to avoid confusion */
+
 struct userdata {
     pa_module *module;
 
@@ -70,19 +79,27 @@ struct userdata {
     pa_sink_input *sink_input;
 
     const LADSPA_Descriptor *descriptor;
-    unsigned channels;
     LADSPA_Handle handle[PA_CHANNELS_MAX];
-    LADSPA_Data *input, *output;
+    unsigned long max_ladspaport_count, input_count, output_count, channels;
+    LADSPA_Data **input, **output;
     size_t block_size;
-    unsigned long input_port, output_port;
     LADSPA_Data *control;
+    long unsigned n_control;
 
     /* This is a dummy buffer. Every port must be connected, but we don't care
-       about control out ports. We connect them all to this single buffer. */
+    about control out ports. We connect them all to this single buffer. */
     LADSPA_Data control_out;
 
     pa_memblockq *memblockq;
 
+    pa_bool_t *use_default;
+    pa_sample_spec ss;
+
+#ifdef HAVE_DBUS
+    pa_dbus_protocol *dbus_protocol;
+    char *dbus_path;
+#endif
+
     pa_bool_t auto_desc;
 };
 
@@ -97,35 +114,261 @@ static const char* const valid_modargs[] = {
     "plugin",
     "label",
     "control",
+    "input_ladspaport_map",
+    "output_ladspaport_map",
     NULL
 };
 
+/* The PA_SINK_MESSAGE types that extend the predefined messages. */
+enum {
+   LADSPA_SINK_MESSAGE_UPDATE_PARAMETERS = PA_SINK_MESSAGE_MAX
+};
+
+static int write_control_parameters(struct userdata *u, double *control_values, pa_bool_t *use_default);
+static void connect_control_ports(struct userdata *u);
+
+#ifdef HAVE_DBUS
+
+#define LADSPA_IFACE "org.PulseAudio.Ext.Ladspa1"
+#define LADSPA_ALGORITHM_PARAMETERS "AlgorithmParameters"
+
+/* TODO: add a PropertyChanged signal to tell that the algorithm parameters have been changed */
+
+enum ladspa_handler_index {
+    LADSPA_HANDLER_ALGORITHM_PARAMETERS,
+    LADSPA_HANDLER_MAX
+};
+
+static void get_algorithm_parameters(DBusConnection *conn, DBusMessage *msg, void *_u) {
+    struct userdata *u;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter, struct_iter;
+    unsigned long i;
+    double *control;
+    dbus_bool_t *use_default;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert_se(u = _u);
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+    dbus_message_iter_init_append(reply, &msg_iter);
+
+    dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter);
+
+    /* copying because of the D-Bus type mapping */
+    control = pa_xnew(double, u->n_control);
+    use_default = pa_xnew(dbus_bool_t, u->n_control);
+
+    for (i = 0; i < u->n_control; i++) {
+        control[i] = (double) u->control[i];
+        use_default[i] = u->use_default[i];
+    }
+
+    pa_dbus_append_basic_array(&struct_iter, DBUS_TYPE_DOUBLE, control, u->n_control);
+    pa_dbus_append_basic_array(&struct_iter, DBUS_TYPE_BOOLEAN, use_default, u->n_control);
+
+    dbus_message_iter_close_container(&msg_iter, &struct_iter);
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+
+    dbus_message_unref(reply);
+    pa_xfree(control);
+    pa_xfree(use_default);
+}
+
+static void set_algorithm_parameters(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *_u) {
+    struct userdata *u;
+    DBusMessageIter array_iter, struct_iter;
+    int n_control = 0, n_use_default;
+    unsigned n_dbus_control, n_dbus_use_default;
+    double *read_values = NULL;
+    dbus_bool_t *read_defaults = NULL;
+    pa_bool_t *use_defaults = NULL;
+    unsigned long i;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert_se(u = _u);
+
+    /* The property we are expecting has signature (adab), meaning that it's a
+       struct of two arrays, the first containing doubles and the second containing
+       booleans. The first array has the algorithm configuration values and the
+       second array has booleans indicating whether the matching algorithm
+       configuration value should use (or try to use) the default value provided by
+       the algorithm module. The PulseAudio D-Bus infrastructure will take care of
+       checking the argument types for us. */
+
+    dbus_message_iter_recurse(iter, &struct_iter);
+
+    dbus_message_iter_recurse(&struct_iter, &array_iter);
+    dbus_message_iter_get_fixed_array(&array_iter, &read_values, &n_control);
+
+    dbus_message_iter_next(&struct_iter);
+    dbus_message_iter_recurse(&struct_iter, &array_iter);
+    dbus_message_iter_get_fixed_array(&array_iter, &read_defaults, &n_use_default);
+
+    n_dbus_control = n_control; /* handle the unsignedness */
+    n_dbus_use_default = n_use_default;
+
+    if (n_dbus_control != u->n_control || n_dbus_use_default != u->n_control) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong number of array values (expected %lu)", u->n_control);
+        return;
+    }
+
+    use_defaults = pa_xnew(pa_bool_t, n_control);
+    for (i = 0; i < u->n_control; i++)
+        use_defaults[i] = read_defaults[i];
+
+    if (write_control_parameters(u, read_values, use_defaults) < 0) {
+        pa_log_warn("Failed writing control parameters");
+        goto error;
+    }
+
+    pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), LADSPA_SINK_MESSAGE_UPDATE_PARAMETERS, NULL, 0, NULL);
+
+    pa_dbus_send_empty_reply(conn, msg);
+
+    pa_xfree(use_defaults);
+    return;
+
+error:
+    pa_xfree(use_defaults);
+    pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Internal error");
+}
+
+static pa_dbus_property_handler ladspa_property_handlers[LADSPA_HANDLER_MAX] = {
+    [LADSPA_HANDLER_ALGORITHM_PARAMETERS] = {
+        .property_name = LADSPA_ALGORITHM_PARAMETERS,
+        .type = "(adab)",
+        .get_cb = get_algorithm_parameters,
+        .set_cb = set_algorithm_parameters
+    }
+};
+
+static void ladspa_get_all(DBusConnection *conn, DBusMessage *msg, void *_u) {
+    struct userdata *u;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter, dict_iter, dict_entry_iter, variant_iter, struct_iter;
+    const char *key = LADSPA_ALGORITHM_PARAMETERS;
+    double *control;
+    dbus_bool_t *use_default;
+    long unsigned i;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert_se(u = _u);
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    /* Currently, on this interface, only a single property is returned. */
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+    pa_assert_se(dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter));
+    pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &key));
+
+    pa_assert_se(dbus_message_iter_open_container(&dict_entry_iter, DBUS_TYPE_VARIANT, "(adab)", &variant_iter));
+    pa_assert_se(dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter));
+
+    control = pa_xnew(double, u->n_control);
+    use_default = pa_xnew(dbus_bool_t, u->n_control);
+
+    for (i = 0; i < u->n_control; i++) {
+        control[i] = (double) u->control[i];
+        use_default[i] = u->use_default[i];
+    }
+
+    pa_dbus_append_basic_array(&struct_iter, DBUS_TYPE_DOUBLE, control, u->n_control);
+    pa_dbus_append_basic_array(&struct_iter, DBUS_TYPE_BOOLEAN, use_default, u->n_control);
+
+    pa_assert_se(dbus_message_iter_close_container(&variant_iter, &struct_iter));
+    pa_assert_se(dbus_message_iter_close_container(&dict_entry_iter, &variant_iter));
+    pa_assert_se(dbus_message_iter_close_container(&dict_iter, &dict_entry_iter));
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+    pa_xfree(control);
+    pa_xfree(use_default);
+}
+
+static pa_dbus_interface_info ladspa_info = {
+    .name = LADSPA_IFACE,
+    .method_handlers = NULL,
+    .n_method_handlers = 0,
+    .property_handlers = ladspa_property_handlers,
+    .n_property_handlers = LADSPA_HANDLER_MAX,
+    .get_all_properties_cb = ladspa_get_all,
+    .signals = NULL,
+    .n_signals = 0
+};
+
+static void dbus_init(struct userdata *u) {
+    pa_assert_se(u);
+
+    u->dbus_protocol = pa_dbus_protocol_get(u->sink->core);
+    u->dbus_path = pa_sprintf_malloc("/org/pulseaudio/core1/sink%d", u->sink->index);
+
+    pa_dbus_protocol_add_interface(u->dbus_protocol, u->dbus_path, &ladspa_info, u);
+}
+
+static void dbus_done(struct userdata *u) {
+    pa_assert_se(u);
+
+    if (!u->dbus_protocol) {
+        pa_assert(!u->dbus_path);
+        return;
+    }
+
+    pa_dbus_protocol_remove_interface(u->dbus_protocol, u->dbus_path, ladspa_info.name);
+    pa_xfree(u->dbus_path);
+    pa_dbus_protocol_unref(u->dbus_protocol);
+
+    u->dbus_path = NULL;
+    u->dbus_protocol = NULL;
+}
+
+#endif /* HAVE_DBUS */
+
 /* Called from I/O thread context */
 static int sink_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
     struct userdata *u = PA_SINK(o)->userdata;
 
     switch (code) {
 
-        case PA_SINK_MESSAGE_GET_LATENCY:
+    case PA_SINK_MESSAGE_GET_LATENCY:
 
-            /* The sink is _put() before the sink input is, so let's
-             * make sure we don't access it in that time. Also, the
-             * sink input is first shut down, the sink second. */
-            if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
+        /* The sink is _put() before the sink input is, so let's
+         * make sure we don't access it in that time. Also, the
+         * sink input is first shut down, the sink second. */
+        if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
                 !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state)) {
-                *((pa_usec_t*) data) = 0;
-                return 0;
-            }
+            *((pa_usec_t*) data) = 0;
+            return 0;
+        }
 
-            *((pa_usec_t*) data) =
+        *((pa_usec_t*) data) =
 
-                /* Get the latency of the master sink */
-                pa_sink_get_latency_within_thread(u->sink_input->sink) +
+            /* Get the latency of the master sink */
+            pa_sink_get_latency_within_thread(u->sink_input->sink) +
 
-                /* Add the latency internal to our sink input on top */
-                pa_bytes_to_usec(pa_memblockq_get_length(u->sink_input->thread_info.render_memblockq), &u->sink_input->sink->sample_spec);
+            /* Add the latency internal to our sink input on top */
+            pa_bytes_to_usec(pa_memblockq_get_length(u->sink_input->thread_info.render_memblockq), &u->sink_input->sink->sample_spec);
 
-            return 0;
+        return 0;
+
+    case LADSPA_SINK_MESSAGE_UPDATE_PARAMETERS:
+
+        /* rewind the stream to throw away the previously rendered data */
+
+        pa_log_debug("Requesting rewind due to parameter update.");
+        pa_sink_request_rewind(u->sink, -1);
+
+        /* change the sink parameters */
+        connect_control_ports(u);
+
+        return 0;
     }
 
     return pa_sink_process_msg(o, code, data, offset, chunk);
@@ -139,7 +382,7 @@ static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
     pa_assert_se(u = s->userdata);
 
     if (!PA_SINK_IS_LINKED(state) ||
-        !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
+            !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
         return 0;
 
     pa_sink_input_cork(u->sink_input, state == PA_SINK_SUSPENDED);
@@ -154,11 +397,13 @@ static void sink_request_rewind_cb(pa_sink *s) {
     pa_assert_se(u = s->userdata);
 
     if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
-        !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
+            !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
         return;
 
     /* Just hand this one over to the master sink */
-    pa_sink_input_request_rewind(u->sink_input, s->thread_info.rewind_nbytes + pa_memblockq_get_length(u->memblockq), TRUE, FALSE, FALSE);
+    pa_sink_input_request_rewind(u->sink_input,
+                                 s->thread_info.rewind_nbytes +
+                                 pa_memblockq_get_length(u->memblockq), TRUE, FALSE, FALSE);
 }
 
 /* Called from I/O thread context */
@@ -169,27 +414,13 @@ static void sink_update_requested_latency_cb(pa_sink *s) {
     pa_assert_se(u = s->userdata);
 
     if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
-        !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
+            !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
         return;
 
     /* Just hand this one over to the master sink */
     pa_sink_input_set_requested_latency_within_thread(
-            u->sink_input,
-            pa_sink_get_requested_latency_within_thread(s));
-}
-
-/* Called from main context */
-static void sink_set_volume_cb(pa_sink *s) {
-    struct userdata *u;
-
-    pa_sink_assert_ref(s);
-    pa_assert_se(u = s->userdata);
-
-    if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)) ||
-        !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
-        return;
-
-    pa_sink_input_set_volume(u->sink_input, &s->real_volume, s->save_volume, TRUE);
+        u->sink_input,
+        pa_sink_get_requested_latency_within_thread(s));
 }
 
 /* Called from main context */
@@ -200,7 +431,7 @@ static void sink_set_mute_cb(pa_sink *s) {
     pa_assert_se(u = s->userdata);
 
     if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)) ||
-        !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
+            !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
         return;
 
     pa_sink_input_set_mute(u->sink_input, s->muted, s->save_muted);
@@ -211,7 +442,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
     struct userdata *u;
     float *src, *dst;
     size_t fs;
-    unsigned n, c;
+    unsigned n, h, c;
     pa_memchunk tchunk;
 
     pa_sink_input_assert_ref(i);
@@ -243,13 +474,15 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
 
     pa_memblockq_drop(u->memblockq, chunk->length);
 
-    src = (float*) ((uint8_t*) pa_memblock_acquire(tchunk.memblock) + tchunk.index);
-    dst = (float*) pa_memblock_acquire(chunk->memblock);
+    src = pa_memblock_acquire_chunk(&tchunk);
+    dst = pa_memblock_acquire(chunk->memblock);
 
-    for (c = 0; c < u->channels; c++) {
-        pa_sample_clamp(PA_SAMPLE_FLOAT32NE, u->input, sizeof(float), src+c, u->channels*sizeof(float), n);
-        u->descriptor->run(u->handle[c], n);
-        pa_sample_clamp(PA_SAMPLE_FLOAT32NE, dst+c, u->channels*sizeof(float), u->output, sizeof(float), n);
+    for (h = 0; h < (u->channels / u->max_ladspaport_count); h++) {
+        for (c = 0; c < u->input_count; c++)
+            pa_sample_clamp(PA_SAMPLE_FLOAT32NE, u->input[c], sizeof(float), src+ h*u->max_ladspaport_count + c, u->channels*sizeof(float), n);
+        u->descriptor->run(u->handle[h], n);
+        for (c = 0; c < u->output_count; c++)
+            pa_sample_clamp(PA_SAMPLE_FLOAT32NE, dst + h*u->max_ladspaport_count + c, u->channels*sizeof(float), u->output[c], sizeof(float), n);
     }
 
     pa_memblock_release(tchunk.memblock);
@@ -284,10 +517,10 @@ static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
 
             /* Reset the plugin */
             if (u->descriptor->deactivate)
-                for (c = 0; c < u->channels; c++)
+                for (c = 0; c < (u->channels / u->max_ladspaport_count); c++)
                     u->descriptor->deactivate(u->handle[c]);
             if (u->descriptor->activate)
-                for (c = 0; c < u->channels; c++)
+                for (c = 0; c < (u->channels / u->max_ladspaport_count); c++)
                     u->descriptor->activate(u->handle[c]);
         }
     }
@@ -303,6 +536,8 @@ static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
     pa_sink_input_assert_ref(i);
     pa_assert_se(u = i->userdata);
 
+    /* FIXME: Too small max_rewind:
+     * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
     pa_memblockq_set_maxrewind(u->memblockq, nbytes);
     pa_sink_set_max_rewind_within_thread(u->sink, nbytes);
 }
@@ -360,6 +595,9 @@ static void sink_input_attach_cb(pa_sink_input *i) {
     pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
     pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
     pa_sink_set_max_request_within_thread(u->sink, pa_sink_input_get_max_request(i));
+
+    /* FIXME: Too small max_rewind:
+     * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
     pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i));
 
     pa_sink_attach_within_thread(u->sink);
@@ -397,23 +635,13 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s
     /* If we are added for the first time, ask for a rewinding so that
      * we are heard right-away. */
     if (PA_SINK_INPUT_IS_LINKED(state) &&
-        i->thread_info.state == PA_SINK_INPUT_INIT) {
+            i->thread_info.state == PA_SINK_INPUT_INIT) {
         pa_log_debug("Requesting rewind due to state change.");
         pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
     }
 }
 
 /* Called from main context */
-static pa_bool_t sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
-    struct userdata *u;
-
-    pa_sink_input_assert_ref(i);
-    pa_assert_se(u = i->userdata);
-
-    return u->sink != dest;
-}
-
-/* Called from main context */
 static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
     struct userdata *u;
 
@@ -441,25 +669,282 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
 }
 
 /* Called from main context */
-static void sink_input_volume_changed_cb(pa_sink_input *i) {
+static void sink_input_mute_changed_cb(pa_sink_input *i) {
     struct userdata *u;
 
     pa_sink_input_assert_ref(i);
     pa_assert_se(u = i->userdata);
 
-    pa_sink_volume_changed(u->sink, &i->volume);
+    pa_sink_mute_changed(u->sink, i->muted);
 }
 
-/* Called from main context */
-static void sink_input_mute_changed_cb(pa_sink_input *i) {
-    struct userdata *u;
+static int parse_control_parameters(struct userdata *u, const char *cdata, double *read_values, pa_bool_t *use_default) {
+    unsigned long p = 0;
+    const char *state = NULL;
+    char *k;
 
-    pa_sink_input_assert_ref(i);
-    pa_assert_se(u = i->userdata);
+    pa_assert(read_values);
+    pa_assert(use_default);
+    pa_assert(u);
 
-    pa_sink_mute_changed(u->sink, i->muted);
+    pa_log_debug("Trying to read %lu control values", u->n_control);
+
+    if (!cdata && u->n_control > 0)
+        return -1;
+
+    pa_log_debug("cdata: '%s'", cdata);
+
+    while ((k = pa_split(cdata, ",", &state)) && p < u->n_control) {
+        double f;
+
+        if (*k == 0) {
+            pa_log_debug("Read empty config value (p=%lu)", p);
+            use_default[p++] = TRUE;
+            pa_xfree(k);
+            continue;
+        }
+
+        if (pa_atod(k, &f) < 0) {
+            pa_log_debug("Failed to parse control value '%s' (p=%lu)", k, p);
+            pa_xfree(k);
+            goto fail;
+        }
+
+        pa_xfree(k);
+
+        pa_log_debug("Read config value %f (p=%lu)", f, p);
+
+        use_default[p] = FALSE;
+        read_values[p++] = f;
+    }
+
+    /* The previous loop doesn't take the last control value into account
+       if it is left empty, so we do it here. */
+    if (*cdata == 0 || cdata[strlen(cdata) - 1] == ',') {
+        if (p < u->n_control)
+            use_default[p] = TRUE;
+        p++;
+    }
+
+    if (p > u->n_control || k) {
+        pa_log("Too many control values passed, %lu expected.", u->n_control);
+        pa_xfree(k);
+        goto fail;
+    }
+
+    if (p < u->n_control) {
+        pa_log("Not enough control values passed, %lu expected, %lu passed.", u->n_control, p);
+        goto fail;
+    }
+
+    return 0;
+
+fail:
+    return -1;
+}
+
+static void connect_control_ports(struct userdata *u) {
+    unsigned long p = 0, h = 0, c;
+    const LADSPA_Descriptor *d;
+
+    pa_assert(u);
+    pa_assert_se(d = u->descriptor);
+
+    for (p = 0; p < d->PortCount; p++) {
+        if (!LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p]))
+            continue;
+
+        if (LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p])) {
+            for (c = 0; c < (u->channels / u->max_ladspaport_count); c++)
+                d->connect_port(u->handle[c], p, &u->control_out);
+            continue;
+        }
+
+        /* input control port */
+
+        pa_log_debug("Binding %f to port %s", u->control[h], d->PortNames[p]);
+
+        for (c = 0; c < (u->channels / u->max_ladspaport_count); c++)
+            d->connect_port(u->handle[c], p, &u->control[h]);
+
+        h++;
+    }
+}
+
+static int validate_control_parameters(struct userdata *u, double *control_values, pa_bool_t *use_default) {
+    unsigned long p = 0, h = 0;
+    const LADSPA_Descriptor *d;
+    pa_sample_spec ss;
+
+    pa_assert(control_values);
+    pa_assert(use_default);
+    pa_assert(u);
+    pa_assert_se(d = u->descriptor);
+
+    ss = u->ss;
+
+    /* Iterate over all ports. Check for every control port that 1) it
+     * supports default values if a default value is provided and 2) the
+     * provided value is within the limits specified in the plugin. */
+
+    for (p = 0; p < d->PortCount; p++) {
+        LADSPA_PortRangeHintDescriptor hint = d->PortRangeHints[p].HintDescriptor;
+
+        if (!LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p]))
+            continue;
+
+        if (LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p]))
+            continue;
+
+        if (use_default[h]) {
+            /* User wants to use default value. Check if the plugin
+             * provides it. */
+            if (!LADSPA_IS_HINT_HAS_DEFAULT(hint)) {
+                pa_log_warn("Control port value left empty but plugin defines no default.");
+                return -1;
+            }
+        }
+        else {
+            /* Check if the user-provided value is within the bounds. */
+            LADSPA_Data lower = d->PortRangeHints[p].LowerBound;
+            LADSPA_Data upper = d->PortRangeHints[p].UpperBound;
+
+            if (LADSPA_IS_HINT_SAMPLE_RATE(hint)) {
+                upper *= (LADSPA_Data) ss.rate;
+                lower *= (LADSPA_Data) ss.rate;
+            }
+
+            if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint)) {
+                if (control_values[h] > upper) {
+                    pa_log_warn("Control value %lu over upper bound: %f (upper bound: %f)", h, control_values[h], upper);
+                    return -1;
+                }
+            }
+            if (LADSPA_IS_HINT_BOUNDED_BELOW(hint)) {
+                if (control_values[h] < lower) {
+                    pa_log_warn("Control value %lu below lower bound: %f (lower bound: %f)", h, control_values[h], lower);
+                    return -1;
+                }
+            }
+        }
+
+        h++;
+    }
+
+    return 0;
+}
+
+static int write_control_parameters(struct userdata *u, double *control_values, pa_bool_t *use_default) {
+    unsigned long p = 0, h = 0, c;
+    const LADSPA_Descriptor *d;
+    pa_sample_spec ss;
+
+    pa_assert(control_values);
+    pa_assert(use_default);
+    pa_assert(u);
+    pa_assert_se(d = u->descriptor);
+
+    ss = u->ss;
+
+    if (validate_control_parameters(u, control_values, use_default) < 0)
+        return -1;
+
+    /* p iterates over all ports, h is the control port iterator */
+
+    for (p = 0; p < d->PortCount; p++) {
+        LADSPA_PortRangeHintDescriptor hint = d->PortRangeHints[p].HintDescriptor;
+
+        if (!LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p]))
+            continue;
+
+        if (LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p])) {
+            for (c = 0; c < (u->channels / u->max_ladspaport_count); c++)
+                d->connect_port(u->handle[c], p, &u->control_out);
+            continue;
+        }
+
+        if (use_default[h]) {
+
+            LADSPA_Data lower, upper;
+
+            lower = d->PortRangeHints[p].LowerBound;
+            upper = d->PortRangeHints[p].UpperBound;
+
+            if (LADSPA_IS_HINT_SAMPLE_RATE(hint)) {
+                lower *= (LADSPA_Data) ss.rate;
+                upper *= (LADSPA_Data) ss.rate;
+            }
+
+            switch (hint & LADSPA_HINT_DEFAULT_MASK) {
+
+            case LADSPA_HINT_DEFAULT_MINIMUM:
+                u->control[h] = lower;
+                break;
+
+            case LADSPA_HINT_DEFAULT_MAXIMUM:
+                u->control[h] = upper;
+                break;
+
+            case LADSPA_HINT_DEFAULT_LOW:
+                if (LADSPA_IS_HINT_LOGARITHMIC(hint))
+                    u->control[h] = (LADSPA_Data) exp(log(lower) * 0.75 + log(upper) * 0.25);
+                else
+                    u->control[h] = (LADSPA_Data) (lower * 0.75 + upper * 0.25);
+                break;
+
+            case LADSPA_HINT_DEFAULT_MIDDLE:
+                if (LADSPA_IS_HINT_LOGARITHMIC(hint))
+                    u->control[h] = (LADSPA_Data) exp(log(lower) * 0.5 + log(upper) * 0.5);
+                else
+                    u->control[h] = (LADSPA_Data) (lower * 0.5 + upper * 0.5);
+                break;
+
+            case LADSPA_HINT_DEFAULT_HIGH:
+                if (LADSPA_IS_HINT_LOGARITHMIC(hint))
+                    u->control[h] = (LADSPA_Data) exp(log(lower) * 0.25 + log(upper) * 0.75);
+                else
+                    u->control[h] = (LADSPA_Data) (lower * 0.25 + upper * 0.75);
+                break;
+
+            case LADSPA_HINT_DEFAULT_0:
+                u->control[h] = 0;
+                break;
+
+            case LADSPA_HINT_DEFAULT_1:
+                u->control[h] = 1;
+                break;
+
+            case LADSPA_HINT_DEFAULT_100:
+                u->control[h] = 100;
+                break;
+
+            case LADSPA_HINT_DEFAULT_440:
+                u->control[h] = 440;
+                break;
+
+            default:
+                pa_assert_not_reached();
+            }
+        }
+        else {
+            if (LADSPA_IS_HINT_INTEGER(hint)) {
+                u->control[h] = roundf(control_values[h]);
+            }
+            else {
+                u->control[h] = control_values[h];
+            }
+        }
+
+        h++;
+    }
+
+    /* set the use_default array to the user data */
+    memcpy(u->use_default, use_default, u->n_control * sizeof(u->use_default[0]));
+
+    return 0;
 }
 
+
 int pa__init(pa_module*m) {
     struct userdata *u;
     pa_sample_spec ss;
@@ -469,13 +954,12 @@ int pa__init(pa_module*m) {
     pa_sink *master;
     pa_sink_input_new_data sink_input_data;
     pa_sink_new_data sink_data;
-    const char *plugin, *label;
+    const char *plugin, *label, *input_ladspaport_map, *output_ladspaport_map;
     LADSPA_Descriptor_Function descriptor_func;
+    unsigned long input_ladspaport[PA_CHANNELS_MAX], output_ladspaport[PA_CHANNELS_MAX];
     const char *e, *cdata;
     const LADSPA_Descriptor *d;
-    unsigned long input_port, output_port, p, j, n_control;
-    unsigned c;
-    pa_bool_t *use_default = NULL;
+    unsigned long p, h, j, n_control, c;
 
     pa_assert(m);
 
@@ -509,12 +993,23 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
+    if (!(input_ladspaport_map = pa_modargs_get_value(ma, "input_ladspaport_map", NULL)))
+        pa_log_debug("Using default input ladspa port mapping");
+
+    if (!(output_ladspaport_map = pa_modargs_get_value(ma, "output_ladspaport_map", NULL)))
+        pa_log_debug("Using default output ladspa port mapping");
+
     cdata = pa_modargs_get_value(ma, "control", NULL);
 
     u = pa_xnew0(struct userdata, 1);
     u->module = m;
     m->userdata = u;
-    u->memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, NULL);
+    u->memblockq = pa_memblockq_new("module-ladspa-sink memblockq", 0, MEMBLOCKQ_MAXLENGTH, 0, &ss, 1, 1, 0, NULL);
+    u->max_ladspaport_count = 1; /*to avoid division by zero etc. in pa__done when failing before this value has been set*/
+    u->channels = 0;
+    u->input = NULL;
+    u->output = NULL;
+    u->ss = ss;
 
     if (!(e = getenv("LADSPA_PATH")))
         e = LADSPA_PATH;
@@ -543,7 +1038,7 @@ int pa__init(pa_module*m) {
             goto fail;
         }
 
-        if (strcmp(d->Label, label) == 0)
+        if (pa_streq(d->Label, label))
             break;
     }
 
@@ -556,219 +1051,160 @@ int pa__init(pa_module*m) {
     pa_log_debug("Maker: %s", d->Maker);
     pa_log_debug("Copyright: %s", d->Copyright);
 
-    input_port = output_port = (unsigned long) -1;
     n_control = 0;
+    u->channels = ss.channels;
 
+    /*
+    * Enumerate ladspa ports
+    * Default mapping is in order given by the plugin
+    */
     for (p = 0; p < d->PortCount; p++) {
-
-        if (LADSPA_IS_PORT_INPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p])) {
-
-            if (strcmp(d->PortNames[p], "Input") == 0) {
-                pa_assert(input_port == (unsigned long) -1);
-                input_port = p;
-            } else {
-                pa_log("Found audio input port on plugin we cannot handle: %s", d->PortNames[p]);
-                goto fail;
+        if (LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p])) {
+            if (LADSPA_IS_PORT_INPUT(d->PortDescriptors[p])) {
+                pa_log_debug("Port %lu is input: %s", p, d->PortNames[p]);
+                input_ladspaport[u->input_count] = p;
+                u->input_count++;
+            } else if (LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p])) {
+                pa_log_debug("Port %lu is output: %s", p, d->PortNames[p]);
+                output_ladspaport[u->output_count] = p;
+                u->output_count++;
             }
-
-        } else if (LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p])) {
-
-            if (strcmp(d->PortNames[p], "Output") == 0) {
-                pa_assert(output_port == (unsigned long) -1);
-                output_port = p;
-            } else {
-                pa_log("Found audio output port on plugin we cannot handle: %s", d->PortNames[p]);
-                goto fail;
-            }
-
-        } else if (LADSPA_IS_PORT_INPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p]))
+        } else if (LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p]) && LADSPA_IS_PORT_INPUT(d->PortDescriptors[p])) {
+            pa_log_debug("Port %lu is control: %s", p, d->PortNames[p]);
             n_control++;
-        else {
-            pa_assert(LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p]));
-            pa_log_debug("Ignored control output port \"%s\".", d->PortNames[p]);
-        }
+        } else
+            pa_log_debug("Ignored port %s", d->PortNames[p]);
+        /* XXX: Has anyone ever seen an in-place plugin with non-equal number of input and output ports? */
+        /* Could be if the plugin is for up-mixing stereo to 5.1 channels */
+        /* Or if the plugin is down-mixing 5.1 to two channel stereo or binaural encoded signal */
+        if (u->input_count > u->max_ladspaport_count)
+            u->max_ladspaport_count = u->input_count;
+        else
+            u->max_ladspaport_count = u->output_count;
     }
 
-    if ((input_port == (unsigned long) -1) || (output_port == (unsigned long) -1)) {
-        pa_log("Failed to identify input and output ports. "
-               "Right now this module can only deal with plugins which provide an 'Input' and an 'Output' audio port. "
-               "Patches welcome!");
+    if (u->channels % u->max_ladspaport_count) {
+        pa_log("Cannot handle non-integral number of plugins required for given number of channels");
         goto fail;
     }
 
-    u->block_size = pa_frame_align(pa_mempool_block_size_max(m->core->mempool), &ss);
+    pa_log_debug("Will run %lu plugin instances", u->channels / u->max_ladspaport_count);
 
-    u->input = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size);
-    if (LADSPA_IS_INPLACE_BROKEN(d->Properties))
-        u->output = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size);
-    else
-        u->output = u->input;
-
-    u->channels = ss.channels;
+    /* Parse data for input ladspa port map */
+    if (input_ladspaport_map) {
+        const char *state = NULL;
+        char *pname;
+        c = 0;
+        while ((pname = pa_split(input_ladspaport_map, ",", &state))) {
+            if (c == u->input_count) {
+                pa_log("Too many ports in input ladspa port map");
+                pa_xfree(pname);
+                goto fail;
+            }
 
-    for (c = 0; c < ss.channels; c++) {
-        if (!(u->handle[c] = d->instantiate(d, ss.rate))) {
-            pa_log("Failed to instantiate plugin %s with label %s for channel %i", plugin, d->Label, c);
-            goto fail;
+            for (p = 0; p < d->PortCount; p++) {
+                if (pa_streq(d->PortNames[p], pname)) {
+                    if (LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p]) && LADSPA_IS_PORT_INPUT(d->PortDescriptors[p])) {
+                        input_ladspaport[c] = p;
+                    } else {
+                        pa_log("Port %s is not an audio input ladspa port", pname);
+                        pa_xfree(pname);
+                        goto fail;
+                    }
+                }
+            }
+            c++;
+            pa_xfree(pname);
         }
-
-        d->connect_port(u->handle[c], input_port, u->input);
-        d->connect_port(u->handle[c], output_port, u->output);
     }
 
-    if (!cdata && n_control > 0) {
-        pa_log("This plugin requires specification of %lu control parameters.", n_control);
-        goto fail;
-    }
-
-    if (n_control > 0) {
+    /* Parse data for output port map */
+    if (output_ladspaport_map) {
         const char *state = NULL;
-        char *k;
-        unsigned long h;
-
-        u->control = pa_xnew(LADSPA_Data, (unsigned) n_control);
-        use_default = pa_xnew(pa_bool_t, (unsigned) n_control);
-        p = 0;
-
-        while ((k = pa_split(cdata, ",", &state)) && p < n_control) {
-            double f;
-
-            if (*k == 0) {
-                use_default[p++] = TRUE;
-                pa_xfree(k);
-                continue;
-            }
-
-            if (pa_atod(k, &f) < 0) {
-                pa_log("Failed to parse control value '%s'", k);
-                pa_xfree(k);
+        char *pname;
+        c = 0;
+        while ((pname = pa_split(output_ladspaport_map, ",", &state))) {
+            if (c == u->output_count) {
+                pa_log("Too many ports in output ladspa port map");
+                pa_xfree(pname);
                 goto fail;
             }
-
-            pa_xfree(k);
-
-            use_default[p] = FALSE;
-            u->control[p++] = (LADSPA_Data) f;
+            for (p = 0; p < d->PortCount; p++) {
+                if (pa_streq(d->PortNames[p], pname)) {
+                    if (LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p]) && LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p])) {
+                        output_ladspaport[c] = p;
+                    } else {
+                        pa_log("Port %s is not an output ladspa port", pname);
+                        pa_xfree(pname);
+                        goto fail;
+                    }
+                }
+            }
+            c++;
+            pa_xfree(pname);
         }
+    }
 
-        /* The previous loop doesn't take the last control value into account
-           if it is left empty, so we do it here. */
-        if (*cdata == 0 || cdata[strlen(cdata) - 1] == ',') {
-            if (p < n_control)
-                use_default[p] = TRUE;
-            p++;
-        }
 
-        if (p > n_control || k) {
-            pa_log("Too many control values passed, %lu expected.", n_control);
-            pa_xfree(k);
-            goto fail;
-        }
+    u->block_size = pa_frame_align(pa_mempool_block_size_max(m->core->mempool), &ss);
 
-        if (p < n_control) {
-            pa_log("Not enough control values passed, %lu expected, %lu passed.", n_control, p);
+    /* Create buffers */
+    if (LADSPA_IS_INPLACE_BROKEN(d->Properties)) {
+        u->input = (LADSPA_Data**) pa_xnew(LADSPA_Data*, (unsigned) u->input_count);
+        for (c = 0; c < u->input_count; c++)
+            u->input[c] = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size);
+        u->output = (LADSPA_Data**) pa_xnew(LADSPA_Data*, (unsigned) u->output_count);
+        for (c = 0; c < u->output_count; c++)
+            u->output[c] = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size);
+    } else {
+        u->input = (LADSPA_Data**) pa_xnew(LADSPA_Data*, (unsigned) u->max_ladspaport_count);
+        for (c = 0; c < u->max_ladspaport_count; c++)
+            u->input[c] = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size);
+        u->output = u->input;
+    }
+    /* Initialize plugin instances */
+    for (h = 0; h < (u->channels / u->max_ladspaport_count); h++) {
+        if (!(u->handle[h] = d->instantiate(d, ss.rate))) {
+            pa_log("Failed to instantiate plugin %s with label %s", plugin, d->Label);
             goto fail;
         }
 
-        h = 0;
-        for (p = 0; p < d->PortCount; p++) {
-            LADSPA_PortRangeHintDescriptor hint = d->PortRangeHints[p].HintDescriptor;
-
-            if (!LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p]))
-                continue;
-
-            if (LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p])) {
-                for (c = 0; c < ss.channels; c++)
-                    d->connect_port(u->handle[c], p, &u->control_out);
-                continue;
-            }
-
-            pa_assert(h < n_control);
+        for (c = 0; c < u->input_count; c++)
+            d->connect_port(u->handle[h], input_ladspaport[c], u->input[c]);
+        for (c = 0; c < u->output_count; c++)
+            d->connect_port(u->handle[h], output_ladspaport[c], u->output[c]);
+    }
 
-            if (use_default[h]) {
-                LADSPA_Data lower, upper;
+    u->n_control = n_control;
 
-                if (!LADSPA_IS_HINT_HAS_DEFAULT(hint)) {
-                    pa_log("Control port value left empty but plugin defines no default.");
-                    goto fail;
-                }
+    if (u->n_control > 0) {
+        double *control_values;
+        pa_bool_t *use_default;
 
-                lower = d->PortRangeHints[p].LowerBound;
-                upper = d->PortRangeHints[p].UpperBound;
+        /* temporary storage for parser */
+        control_values = pa_xnew(double, (unsigned) u->n_control);
+        use_default = pa_xnew(pa_bool_t, (unsigned) u->n_control);
 
-                if (LADSPA_IS_HINT_SAMPLE_RATE(hint)) {
-                    lower *= (LADSPA_Data) ss.rate;
-                    upper *= (LADSPA_Data) ss.rate;
-                }
+        /* real storage */
+        u->control = pa_xnew(LADSPA_Data, (unsigned) u->n_control);
+        u->use_default = pa_xnew(pa_bool_t, (unsigned) u->n_control);
 
-                switch (hint & LADSPA_HINT_DEFAULT_MASK) {
-
-                    case LADSPA_HINT_DEFAULT_MINIMUM:
-                        u->control[h] = lower;
-                        break;
-
-                    case LADSPA_HINT_DEFAULT_MAXIMUM:
-                        u->control[h] = upper;
-                        break;
-
-                    case LADSPA_HINT_DEFAULT_LOW:
-                        if (LADSPA_IS_HINT_LOGARITHMIC(hint))
-                            u->control[h] = (LADSPA_Data) exp(log(lower) * 0.75 + log(upper) * 0.25);
-                        else
-                            u->control[h] = (LADSPA_Data) (lower * 0.75 + upper * 0.25);
-                        break;
-
-                    case LADSPA_HINT_DEFAULT_MIDDLE:
-                        if (LADSPA_IS_HINT_LOGARITHMIC(hint))
-                            u->control[h] = (LADSPA_Data) exp(log(lower) * 0.5 + log(upper) * 0.5);
-                        else
-                            u->control[h] = (LADSPA_Data) (lower * 0.5 + upper * 0.5);
-                        break;
-
-                    case LADSPA_HINT_DEFAULT_HIGH:
-                        if (LADSPA_IS_HINT_LOGARITHMIC(hint))
-                            u->control[h] = (LADSPA_Data) exp(log(lower) * 0.25 + log(upper) * 0.75);
-                        else
-                            u->control[h] = (LADSPA_Data) (lower * 0.25 + upper * 0.75);
-                        break;
-
-                    case LADSPA_HINT_DEFAULT_0:
-                        u->control[h] = 0;
-                        break;
-
-                    case LADSPA_HINT_DEFAULT_1:
-                        u->control[h] = 1;
-                        break;
-
-                    case LADSPA_HINT_DEFAULT_100:
-                        u->control[h] = 100;
-                        break;
-
-                    case LADSPA_HINT_DEFAULT_440:
-                        u->control[h] = 440;
-                        break;
-
-                    default:
-                        pa_assert_not_reached();
-                }
-            }
-
-            if (LADSPA_IS_HINT_INTEGER(hint))
-                u->control[h] = roundf(u->control[h]);
+        if ((parse_control_parameters(u, cdata, control_values, use_default) < 0) ||
+            (write_control_parameters(u, control_values, use_default) < 0)) {
+            pa_xfree(control_values);
+            pa_xfree(use_default);
 
-            pa_log_debug("Binding %f to port %s", u->control[h], d->PortNames[p]);
+            pa_log("Failed to parse, validate or set control parameters");
 
-            for (c = 0; c < ss.channels; c++)
-                d->connect_port(u->handle[c], p, &u->control[h]);
-
-            h++;
+            goto fail;
         }
-
-        pa_assert(h == n_control);
+        connect_control_ports(u);
+        pa_xfree(control_values);
+        pa_xfree(use_default);
     }
 
     if (d->activate)
-        for (c = 0; c < u->channels; c++)
+        for (c = 0; c < (u->channels / u->max_ladspaport_count); c++)
             d->activate(u->handle[c]);
 
     /* Create sink */
@@ -802,8 +1238,7 @@ int pa__init(pa_module*m) {
     }
 
     u->sink = pa_sink_new(m->core, &sink_data,
-                          PA_SINK_HW_MUTE_CTRL|PA_SINK_HW_VOLUME_CTRL|PA_SINK_DECIBEL_VOLUME|
-                          (master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY)));
+                          (master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY)) | PA_SINK_SHARE_VOLUME_WITH_MASTER);
     pa_sink_new_data_done(&sink_data);
 
     if (!u->sink) {
@@ -815,8 +1250,7 @@ int pa__init(pa_module*m) {
     u->sink->set_state = sink_set_state_cb;
     u->sink->update_requested_latency = sink_update_requested_latency_cb;
     u->sink->request_rewind = sink_request_rewind_cb;
-    u->sink->set_volume = sink_set_volume_cb;
-    u->sink->set_mute = sink_set_mute_cb;
+    pa_sink_set_set_mute_callback(u->sink, sink_set_mute_cb);
     u->sink->userdata = u;
 
     pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq);
@@ -825,7 +1259,8 @@ int pa__init(pa_module*m) {
     pa_sink_input_new_data_init(&sink_input_data);
     sink_input_data.driver = __FILE__;
     sink_input_data.module = m;
-    sink_input_data.sink = master;
+    pa_sink_input_new_data_set_sink(&sink_input_data, master, FALSE);
+    sink_input_data.origin_sink = u->sink;
     pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "LADSPA Stream");
     pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
     pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss);
@@ -847,18 +1282,20 @@ int pa__init(pa_module*m) {
     u->sink_input->attach = sink_input_attach_cb;
     u->sink_input->detach = sink_input_detach_cb;
     u->sink_input->state_change = sink_input_state_change_cb;
-    u->sink_input->may_move_to = sink_input_may_move_to_cb;
     u->sink_input->moving = sink_input_moving_cb;
-    u->sink_input->volume_changed = sink_input_volume_changed_cb;
     u->sink_input->mute_changed = sink_input_mute_changed_cb;
     u->sink_input->userdata = u;
 
+    u->sink->input_to_master = u->sink_input;
+
     pa_sink_put(u->sink);
     pa_sink_input_put(u->sink_input);
 
-    pa_modargs_free(ma);
+#ifdef HAVE_DBUS
+    dbus_init(u);
+#endif
 
-    pa_xfree(use_default);
+    pa_modargs_free(ma);
 
     return 0;
 
@@ -866,8 +1303,6 @@ fail:
     if (ma)
         pa_modargs_free(ma);
 
-    pa_xfree(use_default);
-
     pa__done(m);
 
     return -1;
@@ -892,7 +1327,11 @@ void pa__done(pa_module*m) {
         return;
 
     /* See comments in sink_input_kill_cb() above regarding
-     * destruction order! */
+    * destruction order! */
+
+#ifdef HAVE_DBUS
+    dbus_done(u);
+#endif
 
     if (u->sink_input)
         pa_sink_input_unlink(u->sink_input);
@@ -906,22 +1345,37 @@ void pa__done(pa_module*m) {
     if (u->sink)
         pa_sink_unref(u->sink);
 
-    for (c = 0; c < u->channels; c++)
+    for (c = 0; c < (u->channels / u->max_ladspaport_count); c++) {
         if (u->handle[c]) {
             if (u->descriptor->deactivate)
                 u->descriptor->deactivate(u->handle[c]);
             u->descriptor->cleanup(u->handle[c]);
         }
+    }
 
-    if (u->output != u->input)
-        pa_xfree(u->output);
+    if (u->output == u->input) {
+        if (u->input != NULL) {
+            for (c = 0; c < u->max_ladspaport_count; c++)
+                pa_xfree(u->input[c]);
+            pa_xfree(u->input);
+        }
+    } else {
+        if (u->input != NULL) {
+            for (c = 0; c < u->input_count; c++)
+                pa_xfree(u->input[c]);
+            pa_xfree(u->input);
+        }
+        if (u->output != NULL) {
+            for (c = 0; c < u->output_count; c++)
+                pa_xfree(u->output[c]);
+            pa_xfree(u->output);
+        }
+    }
 
     if (u->memblockq)
         pa_memblockq_free(u->memblockq);
 
-    pa_xfree(u->input);
-
     pa_xfree(u->control);
-
+    pa_xfree(u->use_default);
     pa_xfree(u);
 }
diff --git a/src/modules/module-lirc-symdef.h b/src/modules/module-lirc-symdef.h
deleted file mode 100644 (file)
index b499962..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulelircsymdeffoo
-#define foomodulelircsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_lirc_LTX_pa__init
-#define pa__done module_lirc_LTX_pa__done
-#define pa__get_author module_lirc_LTX_pa__get_author
-#define pa__get_description module_lirc_LTX_pa__get_description
-#define pa__get_usage module_lirc_LTX_pa__get_usage
-#define pa__get_version module_lirc_LTX_pa__get_version
-#define pa__get_deprecated module_lirc_LTX_pa__get_deprecated
-#define pa__load_once module_lirc_LTX_pa__load_once
-#define pa__get_n_used module_lirc_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index d0e902f..15f3442 100644 (file)
@@ -45,12 +45,14 @@ PA_MODULE_AUTHOR("Lennart Poettering");
 PA_MODULE_DESCRIPTION("LIRC volume control");
 PA_MODULE_VERSION(PACKAGE_VERSION);
 PA_MODULE_LOAD_ONCE(TRUE);
-PA_MODULE_USAGE("config=<config file> sink=<sink name> appname=<lirc application name>");
+PA_MODULE_USAGE("config=<config file> sink=<sink name> appname=<lirc application name> volume_limit=<volume limit> volume_step=<volume change step>");
 
 static const char* const valid_modargs[] = {
     "config",
     "sink",
     "appname",
+    "volume_limit",
+    "volume_step",
     NULL,
 };
 
@@ -61,10 +63,10 @@ struct userdata {
     char *sink_name;
     pa_module *module;
     float mute_toggle_save;
+    pa_volume_t volume_limit;
+    pa_volume_t volume_step;
 };
 
-#define DELTA (PA_VOLUME_NORM/20)
-
 static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
     struct userdata *u = userdata;
     char *name = NULL, *code = NULL;
@@ -125,12 +127,12 @@ static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event
 
                     switch (volchange) {
                         case UP:
-                            pa_cvolume_inc(&cv, DELTA);
+                            pa_cvolume_inc_clamp(&cv, u->volume_step, u->volume_limit);
                             pa_sink_set_volume(s, &cv, TRUE, TRUE);
                             break;
 
                         case DOWN:
-                            pa_cvolume_dec(&cv, DELTA);
+                            pa_cvolume_dec(&cv, u->volume_step);
                             pa_sink_set_volume(s, &cv, TRUE, TRUE);
                             break;
 
@@ -170,6 +172,8 @@ fail:
 int pa__init(pa_module*m) {
     pa_modargs *ma = NULL;
     struct userdata *u;
+    pa_volume_t volume_limit = PA_CLAMP_VOLUME(PA_VOLUME_NORM*3/2);
+    pa_volume_t volume_step = PA_VOLUME_NORM/20;
 
     pa_assert(m);
 
@@ -178,6 +182,16 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
+    if (pa_modargs_get_value_u32(ma, "volume_limit", &volume_limit) < 0) {
+        pa_log("Failed to parse volume limit");
+        goto fail;
+    }
+
+    if (pa_modargs_get_value_u32(ma, "volume_step", &volume_step) < 0) {
+        pa_log("Failed to parse volume step");
+        goto fail;
+    }
+
     m->userdata = u = pa_xnew(struct userdata, 1);
     u->module = m;
     u->io = NULL;
@@ -185,6 +199,8 @@ int pa__init(pa_module*m) {
     u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
     u->lirc_fd = -1;
     u->mute_toggle_save = 0;
+    u->volume_limit = PA_CLAMP_VOLUME(volume_limit);
+    u->volume_step = PA_CLAMP_VOLUME(volume_step);
 
     if ((u->lirc_fd = lirc_init((char*) pa_modargs_get_value(ma, "appname", "pulseaudio"), 1)) < 0) {
         pa_log("lirc_init() failed.");
diff --git a/src/modules/module-loopback-symdef.h b/src/modules/module-loopback-symdef.h
deleted file mode 100644 (file)
index 3311308..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleloopbacksymdeffoo
-#define foomoduleloopbacksymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_loopback_LTX_pa__init
-#define pa__done module_loopback_LTX_pa__done
-#define pa__get_author module_loopback_LTX_pa__get_author
-#define pa__get_description module_loopback_LTX_pa__get_description
-#define pa__get_usage module_loopback_LTX_pa__get_usage
-#define pa__get_version module_loopback_LTX_pa__get_version
-#define pa__get_deprecated module_loopback_LTX_pa__get_deprecated
-#define pa__load_once module_loopback_LTX_pa__load_once
-#define pa__get_n_used module_loopback_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index e70dbb0..6017891 100644 (file)
@@ -25,7 +25,6 @@
 #endif
 
 #include <stdio.h>
-#include <math.h>
 
 #include <pulse/xmalloc.h>
 
@@ -53,7 +52,12 @@ PA_MODULE_USAGE(
         "format=<sample format> "
         "rate=<sample rate> "
         "channels=<number of channels> "
-        "channel_map=<channel map>");
+        "channel_map=<channel map> "
+        "sink_input_properties=<proplist> "
+        "source_output_properties=<proplist> "
+        "source_dont_move=<boolean> "
+        "sink_dont_move=<boolean> "
+        "remix=<remix channels?> ");
 
 #define DEFAULT_LATENCY_MSEC 200
 
@@ -102,11 +106,17 @@ struct userdata {
 static const char* const valid_modargs[] = {
     "source",
     "sink",
+    "adjust_time",
     "latency_msec",
     "format",
     "rate",
     "channels",
     "channel_map",
+    "sink_input_properties",
+    "source_output_properties",
+    "source_dont_move",
+    "sink_dont_move",
+    "remix",
     NULL,
 };
 
@@ -121,26 +131,42 @@ enum {
     SOURCE_OUTPUT_MESSAGE_LATENCY_SNAPSHOT
 };
 
+static void enable_adjust_timer(struct userdata *u, bool enable);
+
 /* Called from main context */
 static void teardown(struct userdata *u) {
     pa_assert(u);
     pa_assert_ctl_context();
 
-    if (u->sink_input)
-        pa_sink_input_unlink(u->sink_input);
+    u->adjust_time = 0;
+    enable_adjust_timer(u, false);
+
+    /* Handling the asyncmsgq between the source output and the sink input
+     * requires some care. When the source output is unlinked, nothing needs
+     * to be done for the asyncmsgq, because the source output is the sending
+     * end. But when the sink input is unlinked, we should ensure that the
+     * asyncmsgq is emptied, because the messages in the queue hold references
+     * to the sink input. Also, we need to ensure that new messages won't be
+     * written to the queue after we have emptied it.
+     *
+     * Emptying the queue can be done in the state_changed() callback of the
+     * sink input, when the new state is "unlinked".
+     *
+     * Preventing new messages from being written to the queue can be achieved
+     * by unlinking the source output before unlinking the sink input. There
+     * are no other writers for that queue, so this is sufficient. */
 
-    if (u->source_output)
+    if (u->source_output) {
         pa_source_output_unlink(u->source_output);
+        pa_source_output_unref(u->source_output);
+        u->source_output = NULL;
+    }
 
     if (u->sink_input) {
+        pa_sink_input_unlink(u->sink_input);
         pa_sink_input_unref(u->sink_input);
         u->sink_input = NULL;
     }
-
-    if (u->source_output) {
-        pa_source_output_unref(u->source_output);
-        u->source_output = NULL;
-    }
 }
 
 /* Called from main context */
@@ -166,13 +192,13 @@ static void adjust_rates(struct userdata *u) {
 
     buffer_latency = pa_bytes_to_usec(buffer, &u->sink_input->sample_spec);
 
-    pa_log_info("Loopback overall latency is %0.2f ms + %0.2f ms + %0.2f ms = %0.2f ms",
+    pa_log_debug("Loopback overall latency is %0.2f ms + %0.2f ms + %0.2f ms = %0.2f ms",
                 (double) u->latency_snapshot.sink_latency / PA_USEC_PER_MSEC,
                 (double) buffer_latency / PA_USEC_PER_MSEC,
                 (double) u->latency_snapshot.source_latency / PA_USEC_PER_MSEC,
                 ((double) u->latency_snapshot.sink_latency + buffer_latency + u->latency_snapshot.source_latency) / PA_USEC_PER_MSEC);
 
-    pa_log_info("Should buffer %zu bytes, buffered at minimum %zu bytes",
+    pa_log_debug("Should buffer %zu bytes, buffered at minimum %zu bytes",
                 u->latency_snapshot.max_request*2,
                 u->latency_snapshot.min_memblockq_length);
 
@@ -185,9 +211,21 @@ static void adjust_rates(struct userdata *u) {
     else
         new_rate = base_rate + (((u->latency_snapshot.min_memblockq_length - u->latency_snapshot.max_request*2) / fs) *PA_USEC_PER_SEC)/u->adjust_time;
 
-    pa_log_info("Old rate %lu Hz, new rate %lu Hz", (unsigned long) old_rate, (unsigned long) new_rate);
+    if (new_rate < (uint32_t) (base_rate*0.8) || new_rate > (uint32_t) (base_rate*1.25)) {
+        pa_log_warn("Sample rates too different, not adjusting (%u vs. %u).", base_rate, new_rate);
+        new_rate = base_rate;
+    } else {
+        if (base_rate < new_rate + 20 && new_rate < base_rate + 20)
+          new_rate = base_rate;
+        /* Do the adjustment in small steps; 2‰ can be considered inaudible */
+        if (new_rate < (uint32_t) (old_rate*0.998) || new_rate > (uint32_t) (old_rate*1.002)) {
+            pa_log_info("New rate of %u Hz not within 2‰ of %u Hz, forcing smaller adjustment", new_rate, old_rate);
+            new_rate = PA_CLAMP(new_rate, (uint32_t) (old_rate*0.998), (uint32_t) (old_rate*1.002));
+        }
+    }
 
     pa_sink_input_set_rate(u->sink_input, new_rate);
+    pa_log_debug("[%s] Updated sampling rate to %lu Hz.", u->sink_input->sink->name, (unsigned long) new_rate);
 
     pa_core_rttime_restart(u->core, u->time_event, pa_rtclock_now() + u->adjust_time);
 }
@@ -203,6 +241,30 @@ static void time_callback(pa_mainloop_api *a, pa_time_event *e, const struct tim
     adjust_rates(u);
 }
 
+/* Called from main context */
+static void enable_adjust_timer(struct userdata *u, bool enable) {
+    if (enable) {
+        if (u->time_event || u->adjust_time <= 0)
+            return;
+
+        u->time_event = pa_core_rttime_new(u->module->core, pa_rtclock_now() + u->adjust_time, time_callback, u);
+    } else {
+        if (!u->time_event)
+            return;
+
+        u->core->mainloop->time_free(u->time_event);
+        u->time_event = NULL;
+    }
+}
+
+/* Called from main context */
+static void update_adjust_timer(struct userdata *u) {
+    if (u->sink_input->state == PA_SINK_INPUT_CORKED || u->source_output->state == PA_SOURCE_OUTPUT_CORKED)
+        enable_adjust_timer(u, false);
+    else
+        enable_adjust_timer(u, true);
+}
+
 /* Called from input thread context */
 static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) {
     struct userdata *u;
@@ -323,13 +385,16 @@ static void source_output_kill_cb(pa_source_output *o) {
 }
 
 /* Called from main thread */
-static pa_bool_t source_output_may_move_to_cb(pa_source_output *o, pa_source *dest) {
+static bool source_output_may_move_to_cb(pa_source_output *o, pa_source *dest) {
     struct userdata *u;
 
     pa_source_output_assert_ref(o);
     pa_assert_ctl_context();
     pa_assert_se(u = o->userdata);
 
+    if (!u->sink_input || !u->sink_input->sink)
+        return true;
+
     return dest != u->sink_input->sink->monitor_source;
 }
 
@@ -339,6 +404,9 @@ static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
     const char *n;
     struct userdata *u;
 
+    if (!dest)
+        return;
+
     pa_source_output_assert_ref(o);
     pa_assert_ctl_context();
     pa_assert_se(u = o->userdata);
@@ -353,6 +421,19 @@ static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
     pa_proplist_free(p);
 }
 
+/* Called from main thread */
+static void source_output_suspend_cb(pa_source_output *o, pa_bool_t suspended) {
+    struct userdata *u;
+
+    pa_source_output_assert_ref(o);
+    pa_assert_ctl_context();
+    pa_assert_se(u = o->userdata);
+
+    pa_sink_input_cork(u->sink_input, suspended);
+
+    update_adjust_timer(u);
+}
+
 /* Called from output thread context */
 static void update_min_memblockq_length(struct userdata *u) {
     size_t length;
@@ -382,7 +463,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
     u->in_pop = FALSE;
 
     if (pa_memblockq_peek(u->memblockq, chunk) < 0) {
-        pa_log_info("Coud not peek into queue");
+        pa_log_info("Could not peek into queue");
         return -1;
     }
 
@@ -412,9 +493,9 @@ static int sink_input_process_msg_cb(pa_msgobject *obj, int code, void *data, in
     switch (code) {
 
         case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
-             pa_usec_t *r = data;
+            pa_usec_t *r = data;
 
-             pa_sink_input_assert_io_context(u->sink_input);
+            pa_sink_input_assert_io_context(u->sink_input);
 
             *r = pa_bytes_to_usec(pa_memblockq_get_length(u->memblockq), &u->sink_input->sample_spec);
 
@@ -493,8 +574,8 @@ static int sink_input_process_msg_cb(pa_msgobject *obj, int code, void *data, in
 
             pa_assert_ctl_context();
 
-            if (u->adjust_time > 0)
-               adjust_rates(u);
+            if (u->time_event)
+                adjust_rates(u);
             return 0;
         }
     }
@@ -571,12 +652,26 @@ static void sink_input_kill_cb(pa_sink_input *i) {
     pa_module_unload_request(u->module, TRUE);
 }
 
+/* Called from the output thread context */
+static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t state) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    if (state == PA_SINK_INPUT_UNLINKED)
+        pa_asyncmsgq_flush(u->asyncmsgq, false);
+}
+
 /* Called from main thread */
 static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
     struct userdata *u;
     pa_proplist *p;
     const char *n;
 
+    if (!dest)
+        return;
+
     pa_sink_input_assert_ref(i);
     pa_assert_ctl_context();
     pa_assert_se(u = i->userdata);
@@ -592,32 +687,51 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
 }
 
 /* Called from main thread */
-static pa_bool_t sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
+static bool sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
     struct userdata *u;
 
     pa_sink_input_assert_ref(i);
     pa_assert_ctl_context();
     pa_assert_se(u = i->userdata);
 
-    if (!u->source_output->source->monitor_of)
-        return TRUE;
+    if (!u->source_output || !u->source_output->source)
+        return true;
 
     return dest != u->source_output->source->monitor_of;
 }
 
+/* Called from main thread */
+static void sink_input_suspend_cb(pa_sink_input *i, pa_bool_t suspended) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_ctl_context();
+    pa_assert_se(u = i->userdata);
+
+    pa_source_output_cork(u->source_output, suspended);
+
+    update_adjust_timer(u);
+}
+
 int pa__init(pa_module *m) {
     pa_modargs *ma = NULL;
     struct userdata *u;
-    pa_sink *sink;
+    pa_sink *sink = NULL;
     pa_sink_input_new_data sink_input_data;
-    pa_source *source;
+    pa_bool_t sink_dont_move;
+    pa_source *source = NULL;
     pa_source_output_new_data source_output_data;
+    pa_bool_t source_dont_move;
     uint32_t latency_msec;
     pa_sample_spec ss;
     pa_channel_map map;
+    bool format_set = false;
+    bool rate_set = false;
+    bool channels_set = false;
     pa_memchunk silence;
     uint32_t adjust_time_sec;
     const char *n;
+    pa_bool_t remix = TRUE;
 
     pa_assert(m);
 
@@ -626,23 +740,62 @@ int pa__init(pa_module *m) {
         goto fail;
     }
 
-    if (!(source = pa_namereg_get(m->core, pa_modargs_get_value(ma, "source", NULL), PA_NAMEREG_SOURCE))) {
+    n = pa_modargs_get_value(ma, "source", NULL);
+    if (n && !(source = pa_namereg_get(m->core, n, PA_NAMEREG_SOURCE))) {
         pa_log("No such source.");
         goto fail;
     }
 
-    if (!(sink = pa_namereg_get(m->core, pa_modargs_get_value(ma, "sink", NULL), PA_NAMEREG_SINK))) {
+    n = pa_modargs_get_value(ma, "sink", NULL);
+    if (n && !(sink = pa_namereg_get(m->core, n, PA_NAMEREG_SINK))) {
         pa_log("No such sink.");
         goto fail;
     }
 
-    ss = sink->sample_spec;
-    map = sink->channel_map;
+    if (pa_modargs_get_value_boolean(ma, "remix", &remix) < 0) {
+        pa_log("Invalid boolean remix parameter");
+        goto fail;
+    }
+
+    if (sink) {
+        ss = sink->sample_spec;
+        map = sink->channel_map;
+        format_set = true;
+        rate_set = true;
+        channels_set = true;
+    } else if (source) {
+        ss = source->sample_spec;
+        map = source->channel_map;
+        format_set = true;
+        rate_set = true;
+        channels_set = true;
+    } else {
+        /* FIXME: Dummy stream format, needed because pa_sink_input_new()
+         * requires valid sample spec and channel map even when all the FIX_*
+         * stream flags are specified. pa_sink_input_new() should be changed
+         * to ignore the sample spec and channel map when the FIX_* flags are
+         * present. */
+        ss.format = PA_SAMPLE_U8;
+        ss.rate = 8000;
+        ss.channels = 1;
+        map.channels = 1;
+        map.map[0] = PA_CHANNEL_POSITION_MONO;
+    }
+
     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;
     }
 
+    if (pa_modargs_get_value(ma, "format", NULL))
+        format_set = true;
+
+    if (pa_modargs_get_value(ma, "rate", NULL))
+        rate_set = true;
+
+    if (pa_modargs_get_value(ma, "channels", NULL) || pa_modargs_get_value(ma, "channel_map", NULL))
+        channels_set = true;
+
     latency_msec = DEFAULT_LATENCY_MSEC;
     if (pa_modargs_get_value_u32(ma, "latency_msec", &latency_msec) < 0 || latency_msec < 1 || latency_msec > 2000) {
         pa_log("Invalid latency specification");
@@ -668,16 +821,43 @@ int pa__init(pa_module *m) {
     pa_sink_input_new_data_init(&sink_input_data);
     sink_input_data.driver = __FILE__;
     sink_input_data.module = m;
-    sink_input_data.sink = sink;
 
-    pa_proplist_setf(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Loopback of %s",
-                     pa_strnull(pa_proplist_gets(source->proplist, PA_PROP_DEVICE_DESCRIPTION)));
-    if ((n = pa_proplist_gets(source->proplist, PA_PROP_DEVICE_ICON_NAME)))
-        pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ICON_NAME, n);
-    pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "abstract");
+    if (sink)
+        pa_sink_input_new_data_set_sink(&sink_input_data, sink, FALSE);
+
+    if (pa_modargs_get_proplist(ma, "sink_input_properties", sink_input_data.proplist, PA_UPDATE_REPLACE) < 0) {
+        pa_log("Failed to parse the sink_input_properties value.");
+        pa_sink_input_new_data_done(&sink_input_data);
+        goto fail;
+    }
+
+    if (!pa_proplist_contains(sink_input_data.proplist, PA_PROP_MEDIA_ROLE))
+        pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "abstract");
+
     pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss);
     pa_sink_input_new_data_set_channel_map(&sink_input_data, &map);
-    sink_input_data.flags = PA_SINK_INPUT_VARIABLE_RATE;
+    sink_input_data.flags = PA_SINK_INPUT_VARIABLE_RATE | PA_SINK_INPUT_START_CORKED;
+
+    if (!remix)
+        sink_input_data.flags |= PA_SINK_INPUT_NO_REMIX;
+
+    if (!format_set)
+        sink_input_data.flags |= PA_SINK_INPUT_FIX_FORMAT;
+
+    if (!rate_set)
+        sink_input_data.flags |= PA_SINK_INPUT_FIX_RATE;
+
+    if (!channels_set)
+        sink_input_data.flags |= PA_SINK_INPUT_FIX_CHANNELS;
+
+    sink_dont_move = FALSE;
+    if (pa_modargs_get_value_boolean(ma, "sink_dont_move", &sink_dont_move) < 0) {
+        pa_log("sink_dont_move= expects a boolean argument.");
+        goto fail;
+    }
+
+    if (sink_dont_move)
+        sink_input_data.flags |= PA_SINK_INPUT_DONT_MOVE;
 
     pa_sink_input_new(&u->sink_input, m->core, &sink_input_data);
     pa_sink_input_new_data_done(&sink_input_data);
@@ -685,16 +865,23 @@ int pa__init(pa_module *m) {
     if (!u->sink_input)
         goto fail;
 
+    /* If format, rate or channels were originally unset, they are set now
+     * after the pa_sink_input_new() call. */
+    ss = u->sink_input->sample_spec;
+    map = u->sink_input->channel_map;
+
     u->sink_input->parent.process_msg = sink_input_process_msg_cb;
     u->sink_input->pop = sink_input_pop_cb;
     u->sink_input->process_rewind = sink_input_process_rewind_cb;
     u->sink_input->kill = sink_input_kill_cb;
+    u->sink_input->state_change = sink_input_state_change_cb;
     u->sink_input->attach = sink_input_attach_cb;
     u->sink_input->detach = sink_input_detach_cb;
     u->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
     u->sink_input->update_max_request = sink_input_update_max_request_cb;
     u->sink_input->may_move_to = sink_input_may_move_to_cb;
     u->sink_input->moving = sink_input_moving_cb;
+    u->sink_input->suspend = sink_input_suspend_cb;
     u->sink_input->userdata = u;
 
     pa_sink_input_set_requested_latency(u->sink_input, u->latency/3);
@@ -702,14 +889,33 @@ int pa__init(pa_module *m) {
     pa_source_output_new_data_init(&source_output_data);
     source_output_data.driver = __FILE__;
     source_output_data.module = m;
-    source_output_data.source = source;
-    pa_proplist_setf(source_output_data.proplist, PA_PROP_MEDIA_NAME, "Loopback to %s",
-                     pa_strnull(pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_DESCRIPTION)));
-    if ((n = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_ICON_NAME)))
-        pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ICON_NAME, n);
-    pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ROLE, "abstract");
+    if (source)
+        pa_source_output_new_data_set_source(&source_output_data, source, FALSE);
+
+    if (pa_modargs_get_proplist(ma, "source_output_properties", source_output_data.proplist, PA_UPDATE_REPLACE) < 0) {
+        pa_log("Failed to parse the source_output_properties value.");
+        pa_source_output_new_data_done(&source_output_data);
+        goto fail;
+    }
+
+    if (!pa_proplist_contains(source_output_data.proplist, PA_PROP_MEDIA_ROLE))
+        pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ROLE, "abstract");
+
     pa_source_output_new_data_set_sample_spec(&source_output_data, &ss);
-    pa_sink_input_new_data_set_channel_map(&sink_input_data, &map);
+    pa_source_output_new_data_set_channel_map(&source_output_data, &map);
+    source_output_data.flags = PA_SOURCE_OUTPUT_START_CORKED;
+
+    if (!remix)
+        source_output_data.flags |= PA_SOURCE_OUTPUT_NO_REMIX;
+
+    source_dont_move = FALSE;
+    if (pa_modargs_get_value_boolean(ma, "source_dont_move", &source_dont_move) < 0) {
+        pa_log("source_dont_move= expects a boolean argument.");
+        goto fail;
+    }
+
+    if (source_dont_move)
+        source_output_data.flags |= PA_SOURCE_OUTPUT_DONT_MOVE;
 
     pa_source_output_new(&u->source_output, m->core, &source_output_data);
     pa_source_output_new_data_done(&source_output_data);
@@ -726,16 +932,18 @@ int pa__init(pa_module *m) {
     u->source_output->state_change = source_output_state_change_cb;
     u->source_output->may_move_to = source_output_may_move_to_cb;
     u->source_output->moving = source_output_moving_cb;
+    u->source_output->suspend = source_output_suspend_cb;
     u->source_output->userdata = u;
 
     pa_source_output_set_requested_latency(u->source_output, u->latency/3);
 
     pa_sink_input_get_silence(u->sink_input, &silence);
     u->memblockq = pa_memblockq_new(
+            "module-loopback memblockq",
             0,                      /* idx */
             MEMBLOCKQ_MAXLENGTH,    /* maxlength */
             MEMBLOCKQ_MAXLENGTH,    /* tlength */
-            pa_frame_size(&ss),     /* base */
+            &ss,                    /* sample_spec */
             0,                      /* prebuf */
             0,                      /* minreq */
             0,                      /* maxrewind */
@@ -744,11 +952,32 @@ int pa__init(pa_module *m) {
 
     u->asyncmsgq = pa_asyncmsgq_new(0);
 
+    if (!pa_proplist_contains(u->source_output->proplist, PA_PROP_MEDIA_NAME))
+        pa_proplist_setf(u->source_output->proplist, PA_PROP_MEDIA_NAME, "Loopback to %s",
+                         pa_strnull(pa_proplist_gets(u->sink_input->sink->proplist, PA_PROP_DEVICE_DESCRIPTION)));
+
+    if (!pa_proplist_contains(u->source_output->proplist, PA_PROP_MEDIA_ICON_NAME)
+            && (n = pa_proplist_gets(u->sink_input->sink->proplist, PA_PROP_DEVICE_ICON_NAME)))
+        pa_proplist_sets(u->source_output->proplist, PA_PROP_MEDIA_ICON_NAME, n);
+
+    if (!pa_proplist_contains(u->sink_input->proplist, PA_PROP_MEDIA_NAME))
+        pa_proplist_setf(u->sink_input->proplist, PA_PROP_MEDIA_NAME, "Loopback from %s",
+                         pa_strnull(pa_proplist_gets(u->source_output->source->proplist, PA_PROP_DEVICE_DESCRIPTION)));
+
+    if (source && !pa_proplist_contains(u->sink_input->proplist, PA_PROP_MEDIA_ICON_NAME)
+            && (n = pa_proplist_gets(u->source_output->source->proplist, PA_PROP_DEVICE_ICON_NAME)))
+        pa_proplist_sets(u->sink_input->proplist, PA_PROP_MEDIA_ICON_NAME, n);
+
     pa_sink_input_put(u->sink_input);
     pa_source_output_put(u->source_output);
 
-    if (u->adjust_time > 0)
-        u->time_event = pa_core_rttime_new(m->core, pa_rtclock_now() + u->adjust_time, time_callback, u);
+    if (pa_source_get_state(u->source_output->source) != PA_SOURCE_SUSPENDED)
+           pa_sink_input_cork(u->sink_input, FALSE);
+
+    if (pa_sink_get_state(u->sink_input->sink) != PA_SINK_SUSPENDED)
+           pa_source_output_cork(u->source_output, FALSE);
+
+    update_adjust_timer(u);
 
     pa_modargs_free(ma);
     return 0;
@@ -778,8 +1007,5 @@ void pa__done(pa_module*m) {
     if (u->asyncmsgq)
         pa_asyncmsgq_unref(u->asyncmsgq);
 
-    if (u->time_event)
-        u->core->mainloop->time_free(u->time_event);
-
     pa_xfree(u);
 }
diff --git a/src/modules/module-match-symdef.h b/src/modules/module-match-symdef.h
deleted file mode 100644 (file)
index ab7e290..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulematchsymdeffoo
-#define foomodulematchsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_match_LTX_pa__init
-#define pa__done module_match_LTX_pa__done
-#define pa__get_author module_match_LTX_pa__get_author
-#define pa__get_description module_match_LTX_pa__get_description
-#define pa__get_usage module_match_LTX_pa__get_usage
-#define pa__get_version module_match_LTX_pa__get_version
-#define pa__get_deprecated module_match_LTX_pa__get_deprecated
-#define pa__load_once module_match_LTX_pa__load_once
-#define pa__get_n_used module_match_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 0bd781d..e42f44e 100644 (file)
 #include <string.h>
 #include <errno.h>
 #include <sys/types.h>
-#include <regex.h>
 #include <stdio.h>
 #include <stdlib.h>
 
+#if defined(HAVE_REGEX_H)
+#include <regex.h>
+#elif defined(HAVE_PCREPOSIX_H)
+#include <pcreposix.h>
+#endif
+
 #include <pulse/xmalloc.h>
 
 #include <pulsecore/core-error.h>
@@ -38,7 +43,6 @@
 #include <pulsecore/core-util.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/log.h>
-#include <pulsecore/core-subscribe.h>
 #include <pulsecore/sink-input.h>
 #include <pulsecore/core-util.h>
 
@@ -56,6 +60,9 @@ PA_MODULE_USAGE("table=<filename> "
 #define DEFAULT_MATCH_TABLE_FILE PA_DEFAULT_CONFIG_DIR"/match.table"
 #define DEFAULT_MATCH_TABLE_FILE_USER "match.table"
 
+#define UPDATE_REPLACE "replace"
+#define UPDATE_MERGE "merge"
+
 static const char* const valid_modargs[] = {
     "table",
     "key",
@@ -66,13 +73,14 @@ struct rule {
     regex_t regex;
     pa_volume_t volume;
     pa_proplist *proplist;
+    pa_update_mode_t mode;
     struct rule *next;
 };
 
 struct userdata {
     struct rule *rules;
     char *property_key;
-    pa_subscription *subscription;
+    pa_hook_slot *sink_input_fixate_hook_slot;
 };
 
 static int load_rules(struct userdata *u, const char *filename) {
@@ -85,12 +93,11 @@ static int load_rules(struct userdata *u, const char *filename) {
     pa_assert(u);
 
     if (filename)
-        f = fopen(fn = pa_xstrdup(filename), "r");
+        f = pa_fopen_cloexec(fn = pa_xstrdup(filename), "r");
     else
         f = pa_open_config_file(DEFAULT_MATCH_TABLE_FILE, DEFAULT_MATCH_TABLE_FILE_USER, NULL, &fn);
 
     if (!f) {
-        pa_xfree(fn);
         pa_log("Failed to open file config file: %s", pa_cstrerror(errno));
         goto finish;
     }
@@ -98,13 +105,14 @@ static int load_rules(struct userdata *u, const char *filename) {
     pa_lock_fd(fileno(f), 1);
 
     while (!feof(f)) {
-        char *d, *v;
+        char *token_end, *value_str;
         pa_volume_t volume = PA_VOLUME_NORM;
         uint32_t k;
         regex_t regex;
         char ln[256];
         struct rule *rule;
         pa_proplist *proplist = NULL;
+        pa_update_mode_t mode = (pa_update_mode_t) -1;
 
         if (!fgets(ln, sizeof(ln), f))
             break;
@@ -116,51 +124,72 @@ static int load_rules(struct userdata *u, const char *filename) {
         if (ln[0] == '#' || !*ln )
             continue;
 
-        d = ln+strcspn(ln, WHITESPACE);
-        v = d+strspn(d, WHITESPACE);
+        token_end = ln + strcspn(ln, WHITESPACE);
+        value_str = token_end + strspn(token_end, WHITESPACE);
+        *token_end = 0;
 
+        if (!*ln) {
+            pa_log("[%s:%u] failed to parse line - missing regexp", fn, n);
+            goto finish;
+        }
 
-        if (!*v) {
-            pa_log(__FILE__ ": [%s:%u] failed to parse line - too few words", filename, n);
+        if (!*value_str) {
+            pa_log("[%s:%u] failed to parse line - too few words", fn, n);
             goto finish;
         }
 
-        *d = 0;
-        if (pa_atou(v, &k) >= 0) {
-            volume = (pa_volume_t) k;
-        } else if (*v == '"') {
-            char *e;
-
-            e = strchr(v+1, '"');
-            if (!e) {
-                pa_log(__FILE__ ": [%s:%u] failed to parse line - missing role closing quote", filename, n);
-                goto finish;
-            }
-
-            *e = '\0';
-            e = pa_sprintf_malloc("media.role=\"%s\"", v+1);
-            proplist = pa_proplist_from_string(e);
-            pa_xfree(e);
-        } else {
-            char *e;
-
-            e = v+strspn(v, WHITESPACE);
-            if (!*e) {
-                pa_log(__FILE__ ": [%s:%u] failed to parse line - missing end of property list", filename, n);
-                goto finish;
-            }
-            *e = '\0';
-            proplist = pa_proplist_from_string(v);
+        if (pa_atou(value_str, &k) >= 0)
+            volume = (pa_volume_t) PA_CLAMP_VOLUME(k);
+        else {
+            size_t len;
+
+            token_end = value_str + strcspn(value_str, WHITESPACE);
+
+            len = token_end - value_str;
+            if (len == (sizeof(UPDATE_REPLACE) - 1) && !strncmp(value_str, UPDATE_REPLACE, len))
+                mode = PA_UPDATE_REPLACE;
+            else if (len == (sizeof(UPDATE_MERGE) - 1) && !strncmp(value_str, UPDATE_MERGE, len))
+                mode = PA_UPDATE_MERGE;
+
+            if (mode != (pa_update_mode_t) -1) {
+                value_str = token_end + strspn(token_end, WHITESPACE);
+
+                if (!*value_str) {
+                    pa_log("[%s:%u] failed to parse line - too few words", fn, n);
+                    goto finish;
+                }
+            } else
+                mode = PA_UPDATE_MERGE;
+
+            if (*value_str == '"') {
+                value_str++;
+
+                token_end = strchr(value_str, '"');
+                if (!token_end) {
+                    pa_log("[%s:%u] failed to parse line - missing role closing quote", fn, n);
+                    goto finish;
+                }
+            } else
+                token_end = value_str + strcspn(value_str, WHITESPACE);
+
+            *token_end = 0;
+
+            value_str = pa_sprintf_malloc("media.role=\"%s\"", value_str);
+            proplist = pa_proplist_from_string(value_str);
+            pa_xfree(value_str);
         }
 
         if (regcomp(&regex, ln, REG_EXTENDED|REG_NOSUB) != 0) {
-            pa_log("[%s:%u] invalid regular expression", filename, n);
+            pa_log("[%s:%u] invalid regular expression", fn, n);
+            if (proplist)
+                pa_proplist_free(proplist);
             goto finish;
         }
 
         rule = pa_xnew(struct rule, 1);
         rule->regex = regex;
         rule->proplist = proplist;
+        rule->mode = mode;
         rule->volume = volume;
         rule->next = NULL;
 
@@ -169,8 +198,6 @@ static int load_rules(struct userdata *u, const char *filename) {
         else
             u->rules = rule;
         end = rule;
-
-        *d = 0;
     }
 
     ret = 0;
@@ -181,29 +208,20 @@ finish:
         fclose(f);
     }
 
-    if (fn)
-        pa_xfree(fn);
+    pa_xfree(fn);
 
     return ret;
 }
 
-static void callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
-    struct userdata *u =  userdata;
-    pa_sink_input *si;
+static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_input_new_data *si, struct userdata *u) {
     struct rule *r;
     const char *n;
 
     pa_assert(c);
     pa_assert(u);
 
-    if (t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW))
-        return;
-
-    if (!(si = pa_idxset_get_by_index(c->sink_inputs, idx)))
-        return;
-
     if (!(n = pa_proplist_gets(si->proplist, u->property_key)))
-        return;
+        return PA_HOOK_OK;
 
     pa_log_debug("Matching with %s", n);
 
@@ -211,15 +229,18 @@ static void callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, v
         if (!regexec(&r->regex, n, 0, NULL, 0)) {
             if (r->proplist) {
                 pa_log_debug("updating proplist of sink input '%s'", n);
-                pa_proplist_update(si->proplist, PA_UPDATE_MERGE, r->proplist);
-            } else {
+                pa_proplist_update(si->proplist, r->mode, r->proplist);
+            } else if (si->volume_writable) {
                 pa_cvolume cv;
                 pa_log_debug("changing volume of sink input '%s' to 0x%03x", n, r->volume);
                 pa_cvolume_set(&cv, si->sample_spec.channels, r->volume);
-                pa_sink_input_set_volume(si, &cv, TRUE, FALSE);
-            }
+                pa_sink_input_new_data_set_volume(si, &cv);
+            } else
+                pa_log_debug("the volume of sink input '%s' is not writable, can't change it", n);
         }
     }
+
+    return PA_HOOK_OK;
 }
 
 int pa__init(pa_module*m) {
@@ -233,9 +254,8 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
-    u = pa_xnew(struct userdata, 1);
+    u = pa_xnew0(struct userdata, 1);
     u->rules = NULL;
-    u->subscription = NULL;
     m->userdata = u;
 
     u->property_key = pa_xstrdup(pa_modargs_get_value(ma, "key", PA_PROP_MEDIA_NAME));
@@ -243,10 +263,8 @@ int pa__init(pa_module*m) {
     if (load_rules(u, pa_modargs_get_value(ma, "table", NULL)) < 0)
         goto fail;
 
-    /* FIXME: Doing this asynchronously is just broken. This needs to
-     * use a hook! */
-
-    u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK_INPUT, callback, u);
+    /* hook EARLY - 1, to match before stream-restore */
+    u->sink_input_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], PA_HOOK_EARLY - 1, (pa_hook_cb_t) sink_input_fixate_hook_callback, u);
 
     pa_modargs_free(ma);
     return 0;
@@ -256,7 +274,7 @@ fail:
 
     if (ma)
         pa_modargs_free(ma);
-    return  -1;
+    return -1;
 }
 
 void pa__done(pa_module*m) {
@@ -268,8 +286,8 @@ void pa__done(pa_module*m) {
     if (!(u = m->userdata))
         return;
 
-    if (u->subscription)
-        pa_subscription_free(u->subscription);
+    if (u->sink_input_fixate_hook_slot)
+        pa_hook_slot_free(u->sink_input_fixate_hook_slot);
 
     if (u->property_key)
         pa_xfree(u->property_key);
diff --git a/src/modules/module-mmkbd-evdev-symdef.h b/src/modules/module-mmkbd-evdev-symdef.h
deleted file mode 100644 (file)
index 094c51f..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulemmkbdevdevsymdeffoo
-#define foomodulemmkbdevdevsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_mmkbd_evdev_LTX_pa__init
-#define pa__done module_mmkbd_evdev_LTX_pa__done
-#define pa__get_author module_mmkbd_evdev_LTX_pa__get_author
-#define pa__get_description module_mmkbd_evdev_LTX_pa__get_description
-#define pa__get_usage module_mmkbd_evdev_LTX_pa__get_usage
-#define pa__get_version module_mmkbd_evdev_LTX_pa__get_version
-#define pa__get_deprecated module_mmkbd_evdev_LTX_pa__get_deprecated
-#define pa__load_once module_mmkbd_evdev_LTX_pa__load_once
-#define pa__get_n_used module_mmkbd_evdev_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 516bf41..4e89aed 100644 (file)
@@ -48,13 +48,15 @@ PA_MODULE_AUTHOR("Lennart Poettering");
 PA_MODULE_DESCRIPTION("Multimedia keyboard support via Linux evdev");
 PA_MODULE_VERSION(PACKAGE_VERSION);
 PA_MODULE_LOAD_ONCE(FALSE);
-PA_MODULE_USAGE("device=<evdev device> sink=<sink name>");
+PA_MODULE_USAGE("device=<evdev device> sink=<sink name> volume_limit=<volume limit> volume_step=<volume change step>");
 
 #define DEFAULT_DEVICE "/dev/input/event0"
 
 static const char* const valid_modargs[] = {
     "device",
     "sink",
+    "volume_limit",
+    "volume_step",
     NULL,
 };
 
@@ -63,10 +65,10 @@ struct userdata {
     pa_io_event *io;
     char *sink_name;
     pa_module *module;
+    pa_volume_t volume_limit;
+    pa_volume_t volume_step;
 };
 
-#define DELTA (PA_VOLUME_NORM/20)
-
 static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
     struct userdata *u = userdata;
 
@@ -120,12 +122,12 @@ static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event
 
                     switch (volchange) {
                         case UP:
-                            pa_cvolume_inc(&cv, DELTA);
+                            pa_cvolume_inc_clamp(&cv, u->volume_step, u->volume_limit);
                             pa_sink_set_volume(s, &cv, TRUE, TRUE);
                             break;
 
                         case DOWN:
-                            pa_cvolume_dec(&cv, DELTA);
+                            pa_cvolume_dec(&cv, u->volume_step);
                             pa_sink_set_volume(s, &cv, TRUE, TRUE);
                             break;
 
@@ -160,6 +162,8 @@ int pa__init(pa_module*m) {
     struct input_id input_id;
     char name[256];
     uint8_t evtype_bitmask[EV_MAX/8 + 1];
+    pa_volume_t volume_limit = PA_VOLUME_NORM*3/2;
+    pa_volume_t volume_step = PA_VOLUME_NORM/20;
 
     pa_assert(m);
 
@@ -168,14 +172,26 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
+    if (pa_modargs_get_value_u32(ma, "volume_limit", &volume_limit) < 0) {
+        pa_log("Failed to parse volume limit");
+        goto fail;
+    }
+
+    if (pa_modargs_get_value_u32(ma, "volume_step", &volume_step) < 0) {
+        pa_log("Failed to parse volume step");
+        goto fail;
+    }
+
     m->userdata = u = pa_xnew(struct userdata, 1);
     u->module = m;
     u->io = NULL;
     u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
     u->fd = -1;
     u->fd_type = 0;
+    u->volume_limit = PA_CLAMP_VOLUME(volume_limit);
+    u->volume_step = PA_CLAMP_VOLUME(volume_step);
 
-    if ((u->fd = open(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), O_RDONLY|O_NOCTTY)) < 0) {
+    if ((u->fd = pa_open_cloexec(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), O_RDONLY, 0)) < 0) {
         pa_log("Failed to open evdev device: %s", pa_cstrerror(errno));
         goto fail;
     }
diff --git a/src/modules/module-native-protocol-fd-symdef.h b/src/modules/module-native-protocol-fd-symdef.h
deleted file mode 100644 (file)
index c607c3f..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulenativeprotocolfdsymdeffoo
-#define foomodulenativeprotocolfdsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_native_protocol_fd_LTX_pa__init
-#define pa__done module_native_protocol_fd_LTX_pa__done
-#define pa__get_author module_native_protocol_fd_LTX_pa__get_author
-#define pa__get_description module_native_protocol_fd_LTX_pa__get_description
-#define pa__get_usage module_native_protocol_fd_LTX_pa__get_usage
-#define pa__get_version module_native_protocol_fd_LTX_pa__get_version
-#define pa__get_deprecated module_native_protocol_fd_LTX_pa__get_deprecated
-#define pa__load_once module_native_protocol_fd_LTX_pa__load_once
-#define pa__get_n_used module_native_protocol_fd_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index eed0505..7021a26 100644 (file)
@@ -48,7 +48,7 @@ static const char* const valid_modargs[] = {
 int pa__init(pa_module*m) {
     pa_iochannel *io;
     pa_modargs *ma;
-    int32_t fd;
+    int32_t fd = -1;
     int r = -1;
     pa_native_options *options = NULL;
 
@@ -59,7 +59,7 @@ int pa__init(pa_module*m) {
         goto finish;
     }
 
-    if (pa_modargs_get_value_s32(ma, "fd", &fd) < 0) {
+    if (pa_modargs_get_value_s32(ma, "fd", &fd) < 0 || fd < 0) {
         pa_log("Invalid file descriptor.");
         goto finish;
     }
diff --git a/src/modules/module-native-protocol-tcp-symdef.h b/src/modules/module-native-protocol-tcp-symdef.h
deleted file mode 100644 (file)
index 6a3a668..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulenativeprotocoltcpsymdeffoo
-#define foomodulenativeprotocoltcpsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_native_protocol_tcp_LTX_pa__init
-#define pa__done module_native_protocol_tcp_LTX_pa__done
-#define pa__get_author module_native_protocol_tcp_LTX_pa__get_author
-#define pa__get_description module_native_protocol_tcp_LTX_pa__get_description
-#define pa__get_usage module_native_protocol_tcp_LTX_pa__get_usage
-#define pa__get_version module_native_protocol_tcp_LTX_pa__get_version
-#define pa__get_deprecated module_native_protocol_tcp_LTX_pa__get_deprecated
-#define pa__load_once module_native_protocol_tcp_LTX_pa__load_once
-#define pa__get_n_used module_native_protocol_tcp_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
diff --git a/src/modules/module-native-protocol-unix-symdef.h b/src/modules/module-native-protocol-unix-symdef.h
deleted file mode 100644 (file)
index 5e237e1..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulenativeprotocolunixsymdeffoo
-#define foomodulenativeprotocolunixsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_native_protocol_unix_LTX_pa__init
-#define pa__done module_native_protocol_unix_LTX_pa__done
-#define pa__get_author module_native_protocol_unix_LTX_pa__get_author
-#define pa__get_description module_native_protocol_unix_LTX_pa__get_description
-#define pa__get_usage module_native_protocol_unix_LTX_pa__get_usage
-#define pa__get_version module_native_protocol_unix_LTX_pa__get_version
-#define pa__get_deprecated module_native_protocol_unix_LTX_pa__get_deprecated
-#define pa__load_once module_native_protocol_unix_LTX_pa__load_once
-#define pa__get_n_used module_native_protocol_unix_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
diff --git a/src/modules/module-null-sink-symdef.h b/src/modules/module-null-sink-symdef.h
deleted file mode 100644 (file)
index 0a52794..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulenullsinksymdeffoo
-#define foomodulenullsinksymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_null_sink_LTX_pa__init
-#define pa__done module_null_sink_LTX_pa__done
-#define pa__get_author module_null_sink_LTX_pa__get_author
-#define pa__get_description module_null_sink_LTX_pa__get_description
-#define pa__get_usage module_null_sink_LTX_pa__get_usage
-#define pa__get_version module_null_sink_LTX_pa__get_version
-#define pa__get_deprecated module_null_sink_LTX_pa__get_deprecated
-#define pa__load_once module_null_sink_LTX_pa__load_once
-#define pa__get_n_used module_null_sink_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 74a2ebb..10bc67f 100644 (file)
 #endif
 
 #include <stdlib.h>
-#include <sys/stat.h>
 #include <stdio.h>
 #include <errno.h>
-#include <string.h>
-#include <fcntl.h>
 #include <unistd.h>
-#include <limits.h>
 
 #include <pulse/rtclock.h>
 #include <pulse/timeval.h>
 #include <pulse/xmalloc.h>
-#include <pulse/i18n.h>
 
+#include <pulsecore/i18n.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/sink.h>
 #include <pulsecore/module.h>
-#include <pulsecore/core-rtclock.h>
 #include <pulsecore/core-util.h>
-#include <pulsecore/core-error.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/log.h>
 #include <pulsecore/thread.h>
@@ -86,7 +80,6 @@ static const char* const valid_modargs[] = {
     "rate",
     "channels",
     "channel_map",
-    "description", /* supported for compatibility reasons, made redundant by sink_properties= */
     NULL
 };
 
@@ -143,11 +136,11 @@ static void process_rewind(struct userdata *u, pa_usec_t now) {
 
     pa_assert(u);
 
-    /* Figure out how much we shall rewind and reset the counter */
     rewind_nbytes = u->sink->thread_info.rewind_nbytes;
-    u->sink->thread_info.rewind_nbytes = 0;
 
-    pa_assert(rewind_nbytes > 0);
+    if (!PA_SINK_IS_OPENED(u->sink->thread_info.state) || rewind_nbytes <= 0)
+        goto do_nothing;
+
     pa_log_debug("Requested to rewind %lu bytes.", (unsigned long) rewind_nbytes);
 
     if (u->timestamp <= now)
@@ -180,10 +173,10 @@ static void process_render(struct userdata *u, pa_usec_t now) {
 
     /* This is the configured latency. Sink inputs connected to us
     might not have a single frame more than the maxrequest value
-    queed. Hence: at maximum read this many bytes from the sink
+    queued. Hence: at maximum read this many bytes from the sink
     inputs. */
 
-    /* Fill the buffer up the the latency size */
+    /* Fill the buffer up the latency size */
     while (u->timestamp < now + u->block_usec) {
         pa_memchunk chunk;
 
@@ -214,21 +207,17 @@ static void thread_func(void *userdata) {
     u->timestamp = pa_rtclock_now();
 
     for (;;) {
+        pa_usec_t now = 0;
         int ret;
 
-        /* Render some data and drop it immediately */
-        if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
-            pa_usec_t now;
-
+        if (PA_SINK_IS_OPENED(u->sink->thread_info.state))
             now = pa_rtclock_now();
 
-            if (u->sink->thread_info.rewind_requested) {
-                if (u->sink->thread_info.rewind_nbytes > 0)
-                    process_rewind(u, now);
-                else
-                    pa_sink_process_rewind(u->sink, 0);
-            }
+        if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
+            process_rewind(u, now);
 
+        /* Render some data and drop it immediately */
+        if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
             if (u->timestamp <= now)
                 process_render(u, now);
 
@@ -288,7 +277,7 @@ int pa__init(pa_module*m) {
     pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME));
     pa_sink_new_data_set_sample_spec(&data, &ss);
     pa_sink_new_data_set_channel_map(&data, &map);
-    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, pa_modargs_get_value(ma, "description", _("Null Output")));
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, _("Null Output"));
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "abstract");
 
     if (pa_modargs_get_proplist(ma, "sink_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
@@ -317,11 +306,13 @@ int pa__init(pa_module*m) {
     pa_sink_set_max_rewind(u->sink, nbytes);
     pa_sink_set_max_request(u->sink, nbytes);
 
-    if (!(u->thread = pa_thread_new(thread_func, u))) {
+    if (!(u->thread = pa_thread_new("null-sink", thread_func, u))) {
         pa_log("Failed to create thread.");
         goto fail;
     }
 
+    pa_sink_set_latency_range(u->sink, 0, BLOCK_USEC);
+
     pa_sink_put(u->sink);
 
     pa_modargs_free(ma);
diff --git a/src/modules/module-null-source.c b/src/modules/module-null-source.c
new file mode 100644 (file)
index 0000000..b3ece7b
--- /dev/null
@@ -0,0 +1,289 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2008 Lennart Poettering
+  Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <pulse/rtclock.h>
+#include <pulse/timeval.h>
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/log.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/module.h>
+#include <pulsecore/rtpoll.h>
+#include <pulsecore/source.h>
+#include <pulsecore/thread-mq.h>
+#include <pulsecore/thread.h>
+
+#include "module-null-source-symdef.h"
+
+PA_MODULE_AUTHOR("Lennart Poettering & Marc-Andre Lureau");
+PA_MODULE_DESCRIPTION("Clocked NULL source");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(FALSE);
+PA_MODULE_USAGE(
+        "format=<sample format> "
+        "channels=<number of channels> "
+        "rate=<sample rate> "
+        "source_name=<name of source> "
+        "channel_map=<channel map> "
+        "description=<description for the source> "
+        "latency_time=<latency time in ms>");
+
+#define DEFAULT_SOURCE_NAME "source.null"
+#define DEFAULT_LATENCY_TIME 20
+#define MAX_LATENCY_USEC (PA_USEC_PER_SEC * 2)
+
+struct userdata {
+    pa_core *core;
+    pa_module *module;
+    pa_source *source;
+
+    pa_thread *thread;
+    pa_thread_mq thread_mq;
+    pa_rtpoll *rtpoll;
+
+    size_t block_size;
+
+    pa_usec_t block_usec;
+    pa_usec_t timestamp;
+    pa_usec_t latency_time;
+};
+
+static const char* const valid_modargs[] = {
+    "rate",
+    "format",
+    "channels",
+    "source_name",
+    "channel_map",
+    "description",
+    "latency_time",
+    NULL
+};
+
+static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
+    struct userdata *u = PA_SOURCE(o)->userdata;
+
+    switch (code) {
+        case PA_SOURCE_MESSAGE_SET_STATE:
+
+            if (PA_PTR_TO_UINT(data) == PA_SOURCE_RUNNING)
+                u->timestamp = pa_rtclock_now();
+
+            break;
+
+        case PA_SOURCE_MESSAGE_GET_LATENCY: {
+            pa_usec_t now;
+
+            now = pa_rtclock_now();
+            *((pa_usec_t*) data) = u->timestamp > now ? u->timestamp - now : 0;
+
+            return 0;
+        }
+    }
+
+    return pa_source_process_msg(o, code, data, offset, chunk);
+}
+
+static void source_update_requested_latency_cb(pa_source *s) {
+    struct userdata *u;
+
+    pa_source_assert_ref(s);
+    u = s->userdata;
+    pa_assert(u);
+
+    u->block_usec = pa_source_get_requested_latency_within_thread(s);
+}
+
+static void thread_func(void *userdata) {
+    struct userdata *u = userdata;
+
+    pa_assert(u);
+
+    pa_log_debug("Thread starting up");
+
+    pa_thread_mq_install(&u->thread_mq);
+
+    u->timestamp = pa_rtclock_now();
+
+    for (;;) {
+        int ret;
+
+        /* Generate some null data */
+        if (PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
+            pa_usec_t now;
+            pa_memchunk chunk;
+
+            now = pa_rtclock_now();
+
+            if ((chunk.length = pa_usec_to_bytes(now - u->timestamp, &u->source->sample_spec)) > 0) {
+
+                chunk.memblock = pa_memblock_new(u->core->mempool, (size_t) -1); /* or chunk.length? */
+                chunk.index = 0;
+                pa_source_post(u->source, &chunk);
+                pa_memblock_unref(chunk.memblock);
+
+                u->timestamp = now;
+            }
+
+            pa_rtpoll_set_timer_absolute(u->rtpoll, u->timestamp + u->latency_time * PA_USEC_PER_MSEC);
+        } else
+            pa_rtpoll_set_timer_disabled(u->rtpoll);
+
+        /* Hmm, nothing to do. Let's sleep */
+        if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
+            goto fail;
+
+        if (ret == 0)
+            goto finish;
+    }
+
+fail:
+    /* If this was no regular exit from the loop we have to continue
+     * processing messages until we received PA_MESSAGE_SHUTDOWN */
+    pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
+    pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
+
+finish:
+    pa_log_debug("Thread shutting down");
+}
+
+int pa__init(pa_module*m) {
+    struct userdata *u = NULL;
+    pa_sample_spec ss;
+    pa_channel_map map;
+    pa_modargs *ma = NULL;
+    pa_source_new_data data;
+    uint32_t latency_time = DEFAULT_LATENCY_TIME;
+
+    pa_assert(m);
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments.");
+        goto fail;
+    }
+
+    ss = m->core->default_sample_spec;
+    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;
+    }
+
+    m->userdata = u = pa_xnew0(struct userdata, 1);
+    u->core = m->core;
+    u->module = m;
+    u->rtpoll = pa_rtpoll_new();
+    pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
+
+    pa_source_new_data_init(&data);
+    data.driver = __FILE__;
+    data.module = m;
+    pa_source_new_data_set_name(&data, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME));
+    pa_source_new_data_set_sample_spec(&data, &ss);
+    pa_source_new_data_set_channel_map(&data, &map);
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, pa_modargs_get_value(ma, "description", "Null Input"));
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "abstract");
+
+    u->source = pa_source_new(m->core, &data, PA_SOURCE_LATENCY | PA_SOURCE_DYNAMIC_LATENCY);
+    pa_source_new_data_done(&data);
+
+    if (!u->source) {
+        pa_log("Failed to create source object.");
+        goto fail;
+    }
+
+    u->latency_time = DEFAULT_LATENCY_TIME;
+    if (pa_modargs_get_value_u32(ma, "latency_time", &latency_time) < 0) {
+        pa_log("Failed to parse latency_time value.");
+        goto fail;
+    }
+    u->latency_time = latency_time;
+
+    u->source->parent.process_msg = source_process_msg;
+    u->source->update_requested_latency = source_update_requested_latency_cb;
+    u->source->userdata = u;
+
+    pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
+    pa_source_set_rtpoll(u->source, u->rtpoll);
+
+    pa_source_set_latency_range(u->source, 0, MAX_LATENCY_USEC);
+    u->block_usec = u->source->thread_info.max_latency;
+
+    u->source->thread_info.max_rewind =
+        pa_usec_to_bytes(u->block_usec, &u->source->sample_spec);
+
+    if (!(u->thread = pa_thread_new("null-source", thread_func, u))) {
+        pa_log("Failed to create thread.");
+        goto fail;
+    }
+
+    pa_source_put(u->source);
+
+    pa_modargs_free(ma);
+
+    return 0;
+
+fail:
+    if (ma)
+        pa_modargs_free(ma);
+
+    pa__done(m);
+
+    return -1;
+}
+
+void pa__done(pa_module*m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    if (u->source)
+        pa_source_unlink(u->source);
+
+    if (u->thread) {
+        pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
+        pa_thread_free(u->thread);
+    }
+
+    pa_thread_mq_done(&u->thread_mq);
+
+    if (u->source)
+        pa_source_unref(u->source);
+
+    if (u->rtpoll)
+        pa_rtpoll_free(u->rtpoll);
+
+    pa_xfree(u);
+}
diff --git a/src/modules/module-pipe-sink-symdef.h b/src/modules/module-pipe-sink-symdef.h
deleted file mode 100644 (file)
index 76d2617..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulepipesinksymdeffoo
-#define foomodulepipesinksymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_pipe_sink_LTX_pa__init
-#define pa__done module_pipe_sink_LTX_pa__done
-#define pa__get_author module_pipe_sink_LTX_pa__get_author
-#define pa__get_description module_pipe_sink_LTX_pa__get_description
-#define pa__get_usage module_pipe_sink_LTX_pa__get_usage
-#define pa__get_version module_pipe_sink_LTX_pa__get_version
-#define pa__get_deprecated module_pipe_sink_LTX_pa__get_deprecated
-#define pa__load_once module_pipe_sink_LTX_pa__load_once
-#define pa__get_n_used module_pipe_sink_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 9c16932..54dceb4 100644 (file)
 #include <sys/stat.h>
 #include <stdio.h>
 #include <errno.h>
-#include <string.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <limits.h>
 #include <sys/ioctl.h>
-#include <poll.h>
+
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
 
 #include <pulse/xmalloc.h>
 
@@ -45,6 +46,7 @@
 #include <pulsecore/thread.h>
 #include <pulsecore/thread-mq.h>
 #include <pulsecore/rtpoll.h>
+#include <pulsecore/poll.h>
 
 #include "module-pipe-sink-symdef.h"
 
@@ -57,7 +59,7 @@ PA_MODULE_USAGE(
         "sink_properties=<properties for the sink> "
         "file=<path of the FIFO> "
         "format=<sample format> "
-        "rate=<sample rate>"
+        "rate=<sample rate> "
         "channels=<number of channels> "
         "channel_map=<channel map>");
 
@@ -101,9 +103,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
 
         case PA_SINK_MESSAGE_GET_LATENCY: {
             size_t n = 0;
-            int l;
 
 #ifdef FIONREAD
+            int l;
+
             if (ioctl(u->fd, FIONREAD, &l) >= 0 && l > 0)
                 n = (size_t) l;
 #endif
@@ -177,12 +180,11 @@ static void thread_func(void *userdata) {
 
         pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
 
+        if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
+            pa_sink_process_rewind(u->sink, 0);
+
         /* Render some data and write it to the fifo */
         if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
-
-            if (u->sink->thread_info.rewind_requested)
-                pa_sink_process_rewind(u->sink, 0);
-
             if (pollfd->revents) {
                 if (process_render(u) < 0)
                     goto fail;
@@ -218,7 +220,7 @@ finish:
     pa_log_debug("Thread shutting down");
 }
 
-int pa__init(pa_module*m) {
+int pa__init(pa_module *m) {
     struct userdata *u;
     struct stat st;
     pa_sample_spec ss;
@@ -252,13 +254,15 @@ int pa__init(pa_module*m) {
 
     u->filename = pa_runtime_path(pa_modargs_get_value(ma, "file", DEFAULT_FILE_NAME));
 
-    mkfifo(u->filename, 0666);
-    if ((u->fd = open(u->filename, O_RDWR|O_NOCTTY)) < 0) {
+    if (mkfifo(u->filename, 0666) < 0) {
+        pa_log("mkfifo('%s'): %s", u->filename, pa_cstrerror(errno));
+        goto fail;
+    }
+    if ((u->fd = pa_open_cloexec(u->filename, O_RDWR, 0)) < 0) {
         pa_log("open('%s'): %s", u->filename, pa_cstrerror(errno));
         goto fail;
     }
 
-    pa_make_fd_cloexec(u->fd);
     pa_make_fd_nonblock(u->fd);
 
     if (fstat(u->fd, &st) < 0) {
@@ -307,7 +311,7 @@ int pa__init(pa_module*m) {
     pollfd->fd = u->fd;
     pollfd->events = pollfd->revents = 0;
 
-    if (!(u->thread = pa_thread_new(thread_func, u))) {
+    if (!(u->thread = pa_thread_new("pipe-sink", thread_func, u))) {
         pa_log("Failed to create thread.");
         goto fail;
     }
@@ -336,7 +340,7 @@ int pa__get_n_used(pa_module *m) {
     return pa_sink_linked_by(u->sink);
 }
 
-void pa__done(pa_module*m) {
+void pa__done(pa_module *m) {
     struct userdata *u;
 
     pa_assert(m);
@@ -358,7 +362,7 @@ void pa__done(pa_module*m) {
         pa_sink_unref(u->sink);
 
     if (u->memchunk.memblock)
-       pa_memblock_unref(u->memchunk.memblock);
+        pa_memblock_unref(u->memchunk.memblock);
 
     if (u->rtpoll_item)
         pa_rtpoll_item_free(u->rtpoll_item);
diff --git a/src/modules/module-pipe-source-symdef.h b/src/modules/module-pipe-source-symdef.h
deleted file mode 100644 (file)
index d2a9baf..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulepipesourcesymdeffoo
-#define foomodulepipesourcesymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_pipe_source_LTX_pa__init
-#define pa__done module_pipe_source_LTX_pa__done
-#define pa__get_author module_pipe_source_LTX_pa__get_author
-#define pa__get_description module_pipe_source_LTX_pa__get_description
-#define pa__get_usage module_pipe_source_LTX_pa__get_usage
-#define pa__get_version module_pipe_source_LTX_pa__get_version
-#define pa__get_deprecated module_pipe_source_LTX_pa__get_deprecated
-#define pa__load_once module_pipe_source_LTX_pa__load_once
-#define pa__get_n_used module_pipe_source_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 49104f8..7a7dfb2 100644 (file)
 #include <sys/stat.h>
 #include <stdio.h>
 #include <errno.h>
-#include <string.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <limits.h>
 #include <sys/ioctl.h>
-#include <sys/poll.h>
+
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
 
 #include <pulse/xmalloc.h>
 
@@ -45,6 +46,7 @@
 #include <pulsecore/thread.h>
 #include <pulsecore/thread-mq.h>
 #include <pulsecore/rtpoll.h>
+#include <pulsecore/poll.h>
 
 #include "module-pipe-source-symdef.h"
 
@@ -105,9 +107,10 @@ static int source_process_msg(
 
         case PA_SOURCE_MESSAGE_GET_LATENCY: {
             size_t n = 0;
-            int l;
 
 #ifdef FIONREAD
+            int l;
+
             if (ioctl(u->fd, FIONREAD, &l) >= 0 && l > 0)
                 n = (size_t) l;
 #endif
@@ -159,7 +162,7 @@ static void thread_func(void *userdata) {
                 if (errno == EINTR)
                     continue;
                 else if (errno != EAGAIN) {
-                    pa_log("Faile to read data from FIFO: %s", pa_cstrerror(errno));
+                    pa_log("Failed to read data from FIFO: %s", pa_cstrerror(errno));
                     goto fail;
                 }
 
@@ -205,7 +208,7 @@ finish:
     pa_log_debug("Thread shutting down");
 }
 
-int pa__init(pa_module*m) {
+int pa__init(pa_module *m) {
     struct userdata *u;
     struct stat st;
     pa_sample_spec ss;
@@ -217,14 +220,14 @@ int pa__init(pa_module*m) {
     pa_assert(m);
 
     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
-        pa_log("failed to parse module arguments.");
+        pa_log("Failed to parse module arguments.");
         goto fail;
     }
 
     ss = m->core->default_sample_spec;
     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");
+        pa_log("Invalid sample format specification or channel map");
         goto fail;
     }
 
@@ -237,17 +240,19 @@ int pa__init(pa_module*m) {
 
     u->filename = pa_runtime_path(pa_modargs_get_value(ma, "file", DEFAULT_FILE_NAME));
 
-    mkfifo(u->filename, 0666);
-    if ((u->fd = open(u->filename, O_RDWR|O_NOCTTY)) < 0) {
+    if (mkfifo(u->filename, 0666) < 0) {
+        pa_log("mkfifo('%s'): %s", u->filename, pa_cstrerror(errno));
+        goto fail;
+    }
+    if ((u->fd = pa_open_cloexec(u->filename, O_RDWR, 0)) < 0) {
         pa_log("open('%s'): %s", u->filename, pa_cstrerror(errno));
         goto fail;
     }
 
-    pa_make_fd_cloexec(u->fd);
     pa_make_fd_nonblock(u->fd);
 
     if (fstat(u->fd, &st) < 0) {
-        pa_log("fstat('%s'): %s",u->filename, pa_cstrerror(errno));
+        pa_log("fstat('%s'): %s", u->filename, pa_cstrerror(errno));
         goto fail;
     }
 
@@ -284,14 +289,14 @@ int pa__init(pa_module*m) {
 
     pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
     pa_source_set_rtpoll(u->source, u->rtpoll);
-    pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(PIPE_BUF, &u->source->sample_spec));
+    pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(pa_pipe_buf(u->fd), &u->source->sample_spec));
 
     u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1);
     pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
     pollfd->fd = u->fd;
     pollfd->events = pollfd->revents = 0;
 
-    if (!(u->thread = pa_thread_new(thread_func, u))) {
+    if (!(u->thread = pa_thread_new("pipe-source", thread_func, u))) {
         pa_log("Failed to create thread.");
         goto fail;
     }
@@ -320,7 +325,7 @@ int pa__get_n_used(pa_module *m) {
     return pa_source_linked_by(u->source);
 }
 
-void pa__done(pa_module*m) {
+void pa__done(pa_module *m) {
     struct userdata *u;
 
     pa_assert(m);
diff --git a/src/modules/module-policy-symdef.h b/src/modules/module-policy-symdef.h
deleted file mode 100644 (file)
index 3d7d1cc..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulepolicysymdeffoo
-#define foomodulepolicysymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_policy_LTX_pa__init
-#define pa__done module_policy_LTX_pa__done
-#define pa__get_author module_policy_LTX_pa__get_author
-#define pa__get_description module_policy_LTX_pa__get_description
-#define pa__get_usage module_policy_LTX_pa__get_usage
-#define pa__get_version module_policy_LTX_pa__get_version
-#define pa__get_deprecated module_policy_LTX_pa__get_deprecated
-#define pa__load_once module_policy_LTX_pa__load_once
-#define pa__get_n_used module_policy_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
old mode 100644 (file)
new mode 100755 (executable)
index ecc786c..9765f7f
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2013 Seungbae Shin <seungbae.shin@samsung.com>
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
+#include <stdbool.h>
+#include <strings.h>
+#include <vconf.h> // for mono
+#include <iniparser.h>
+#include <dlfcn.h>
+#include <asoundlib.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include <pulse/proplist.h>
+#include <pulse/timeval.h>
+#include <pulse/util.h>
+#include <pulse/rtclock.h>
+
 #include <pulsecore/core.h>
 #include <pulsecore/module.h>
 #include <pulsecore/modargs.h>
+#include <pulsecore/core-error.h>
 #include <pulsecore/core-rtclock.h>
+#include <pulsecore/core-scache.h>
+#include <pulsecore/core-subscribe.h>
 #include <pulsecore/core-util.h>
+#include <pulsecore/mutex.h>
 #include <pulsecore/log.h>
-#include <stdbool.h>
-#include <strings.h>
-
-#include <pulsecore/log.h>
-#include <pulsecore/core-subscribe.h>
+#include <pulsecore/namereg.h>
 #include <pulsecore/sink-input.h>
 #include <pulsecore/source-output.h>
-#include <pulsecore/namereg.h>
-#include <pulsecore/core-error.h>
-
 #include <pulsecore/protocol-native.h>
 #include <pulsecore/pstream-util.h>
-#include <vconf.h> // for mono
+#include <pulsecore/strbuf.h>
+#include <pulsecore/sink-input.h>
+#include <pulsecore/sound-file.h>
+#include <pulsecore/play-memblockq.h>
+#include <pulsecore/shared.h>
 
 #include "module-policy-symdef.h"
+#include "tizen-audio.h"
+
+#define VCONFKEY_SOUND_HDMI_SUPPORT "memory/private/sound/hdmisupport"
+#ifdef PRIMARY_VOLUME
+#define VCONFKEY_SOUND_PRIMARY_VOLUME_TYPE "memory/private/sound/PrimaryVolumetype"
+#endif
 
 PA_MODULE_AUTHOR("Seungbae Shin");
 PA_MODULE_DESCRIPTION("Media Policy module");
 PA_MODULE_VERSION(PACKAGE_VERSION);
 PA_MODULE_LOAD_ONCE(TRUE);
 PA_MODULE_USAGE(
-        "on_hotplug=<When new device becomes available, recheck streams?> ");
+        "on_hotplug=<When new device becomes available, recheck streams?> "
+        "use_wideband_voice=<Set to 1 to enable wb voice. Default nb>"
+        "fragment_size=<fragment size>"
+        "tsched_buffer_size=<buffer size when using timer based scheduling> ");
 
 static const char* const valid_modargs[] = {
     "on_hotplug",
+    "use_wideband_voice",
+    "fragment_size",
+    "tsched_buffersize",
+    "tsched_buffer_size",
     NULL
 };
 
+/* Audio HAL library */
+#define LIB_TIZEN_AUDIO "libtizen-audio.so"
+
+/* Tunning Value */
+#define DEFAULT_TSCHED_BUFFER_SIZE 16384
+#define START_THRESHOLD    4096
+#ifdef TIZEN_MICRO
+#define DEFAULT_FRAGMENT_SIZE 4096
+#else
+#define DEFAULT_FRAGMENT_SIZE 8192
+#endif
+
+/* Sink & Source names */
+#define AEC_SINK            "alsa_output.0.analog-stereo.echo-cancel"
+#define AEC_SOURCE          "alsa_input.0.analog-stereo.echo-cancel"
+#define SINK_VOIP           "alsa_output.3.analog-stereo"
+#define SINK_VIRTUAL        "alsa_output.virtual.analog-stereo"
+#define ALSA_VIRTUAL_CARD   "VIRTUALAUDIO"
+#define SOURCE_ALSA         "alsa_input.0.analog-stereo"
+#define SOURCE_VIRTUAL      "alsa_input.virtual.analog-stereo"
+#define SOURCE_VOIP         "alsa_input.3.analog-stereo"
+#define SINK_ALSA           "alsa_output.0.analog-stereo"
+#define SINK_ALSA_UHQA      "alsa_output.0.analog-stereo-uhqa"
+#define SINK_COMBINED       "combined"
+#define SINK_HIGH_LATENCY   "alsa_output.4.analog-stereo"
+#define SINK_HIGH_LATENCY_UHQA   "alsa_output.4.analog-stereo-uhqa"
+#define SINK_HDMI           "alsa_output.1.analog-stereo"
+#define SINK_HDMI_UHQA           "alsa_output.1.analog-stereo-uhqa"
+#define SOURCE_MIRRORING    "alsa_input.8.analog-stereo"
+#define ALSA_MONITOR_SOURCE "alsa_output.0.analog-stereo.monitor"
+
+/* Policies */
+#define POLICY_AUTO         "auto"
+#define POLICY_AUTO_UHQA    "auto-uhqa"
+#define POLICY_PHONE        "phone"
+#define POLICY_ALL          "all"
+#define POLICY_VOIP         "voip"
+#define POLICY_HIGH_LATENCY "high-latency"
+#define POLICY_HIGH_LATENCY_UHQA "high-latency-uhqa"
+#define POLICY_MIRRORING    "mirroring"
+#define POLICY_LOOPBACK    "loopback"
+
+/* API */
+#define BLUEZ_API           "bluez"
+#define ALSA_API            "alsa"
+#define HIGH_LATENCY_API    "high-latency"
+#define NULL_SOURCE         "source.null"
+#define ALSA_SAUDIOVOIP_CARD "saudiovoip"
+
+
+/* Sink Identify Macros */
+#define sink_is_hdmi(sink) !strncmp(sink->name, SINK_HDMI, strlen(SINK_HDMI))
+#define sink_is_highlatency(sink) !strncmp(sink->name, SINK_HIGH_LATENCY, strlen(SINK_HIGH_LATENCY))
+#define sink_is_alsa(sink) !strncmp(sink->name, SINK_ALSA, strlen(SINK_ALSA))
+#define sink_is_voip(sink) !strncmp(sink->name, SINK_VOIP, strlen(SINK_VOIP))
+
+/* Channels */
+#define CH_5_1 6
+#define CH_7_1 8
+#define CH_STEREO 2
+
+/* UHQA */
+/**
+  * UHQA sampling rate vary from 96 KHz to 192 KHz, currently the plan is to configure sink with highest sampling
+  * rate possible i.e. 192 KHz. So that < 192 KHz will be resampled and played. This will avoid creating multiple sinks
+  * for multiple rates
+  */
+#define UHQA_SAMPLING_RATE 192000
+#define UHQA_BASE_SAMPLING_RATE 96000
+
+/* PCM Dump */
+#define PA_DUMP_INI_DEFAULT_PATH                "/usr/etc/mmfw_audio_pcm_dump.ini"
+#define PA_DUMP_INI_TEMP_PATH                   "/opt/system/mmfw_audio_pcm_dump.ini"
+#define PA_DUMP_VCONF_KEY                       "memory/private/sound/pcm_dump"
+#define PA_DUMP_PLAYBACK_DECODER_OUT            0x00000001
+#define PA_DUMP_PLAYBACK_RESAMPLER_IN           0x00000008
+#define PA_DUMP_PLAYBACK_RESAMPLER_OUT          0x00000010
+#define PA_DUMP_CAPTURE_ENCODER_IN              0x80000000
+
+/* check if this sink is bluez */
+
+/* Vconf Keys */
+#define DEFAULT_BOOTING_SOUND_PATH "/usr/share/keysound/poweron.wav"
+#define VCONF_BOOTING "memory/private/sound/booting"
+#ifdef BURST_SHOT
+#define VCONF_SOUND_BURSTSHOT "memory/private/sound/burstshot"
+#endif
+
+/* boot sound */
+#define BOOTING_SOUND_SAMPLE "booting"
+
+
+typedef enum pa_hal_event_type {
+    PA_HAL_EVENT_LOAD_DEVICE,
+    PA_HAL_EVENT_OPEN_DEVICE,
+    PA_HAL_EVENT_CLOSE_ALL_DEVICES,
+    PA_HAL_EVENT_CLOSE_DEVICE,
+    PA_HAL_EVENT_UNLOAD_DEVICE,
+} pa_hal_event_type_t;
+
+struct pa_hal_device_event_data {
+    audio_device_info_t device_info;
+    audio_device_param_info_t params[AUDIO_DEVICE_PARAM_MAX];
+};
+
+struct pa_hal_event {
+    struct userdata *userdata;
+
+    pa_hal_event_type_t event_type;
+    void *event_data;
+
+    pa_cond *cond;
+    pa_mutex *mutex;
+
+    PA_LLIST_FIELDS(struct pa_hal_event);
+};
+
+#ifdef PRIMARY_VOLUME
+struct pa_primary_volume_type_info {
+    void* key;
+    int volumetype;
+    int priority;
+    PA_LLIST_FIELDS(struct pa_primary_volume_type_info);
+};
+#endif
+
 struct userdata {
     pa_core *core;
     pa_module *module;
@@ -43,86 +218,334 @@ struct userdata {
     pa_hook_slot *sink_input_new_hook_slot,*sink_put_hook_slot;
 
     pa_hook_slot *sink_input_unlink_slot,*sink_unlink_slot;
+    pa_hook_slot *sink_input_put_slot;
     pa_hook_slot *sink_input_unlink_post_slot, *sink_unlink_post_slot;
     pa_hook_slot *sink_input_move_start_slot,*sink_input_move_finish_slot;
+    pa_hook_slot *source_output_new_hook_slot, *source_output_unlink_post_slot;
+    pa_hook_slot *source_output_put_slot;
+    pa_hook_slot *sink_state_changed_slot;
+    pa_hook_slot *sink_input_state_changed_slot;
+
+    pthread_t tid;
+    pa_defer_event *defer_event;
+    PA_LLIST_HEAD(struct pa_hal_event, hal_event_queue);
+    struct pa_hal_event *hal_event_last;
+
     pa_subscription *subscription;
 
     pa_bool_t on_hotplug:1;
-    int        bt_off_idx;
+    int bt_off_idx;
+
+    uint32_t session;
+    uint32_t subsession;
+    uint32_t subsession_opt;
+    uint32_t active_device_in;
+    uint32_t active_device_out;
+    uint32_t active_route_flag;
 
     int is_mono;
-    pa_module* module_mono_bt;
+    float balance;
+    int muteall;
+    int call_muted;
+    pa_bool_t wideband;
+    int fragment_size;
+    int tsched_buffer_size;
+
     pa_module* module_combined;
-    pa_module* module_mono_combined;
     pa_native_protocol *protocol;
+
+#ifdef PRIMARY_VOLUME
+    PA_LLIST_HEAD(struct pa_primary_volume_type_info, primary_volume);
+#endif
+
+    struct {
+        void *dl_handle;
+        void *data;
+        audio_interface_t intf;
+    } audio_mgr;
+
+    struct  { // for burst-shot
+        pa_bool_t is_running;
+        pa_mutex* mutex;
+        int count; /* loop count */
+        pa_time_event *time_event;
+        pa_scache_entry *e;
+        pa_sink_input *i;
+        pa_memblockq *q;
+        pa_usec_t time_interval;
+        pa_usec_t factor; /* timer boosting */
+    } audio_sample_userdata;
+};
+
+
+
+enum {
+    CUSTOM_EXT_3D_LEVEL,
+    CUSTOM_EXT_BASS_LEVEL,
+    CUSTOM_EXT_CONCERT_HALL_VOLUME,
+    CUSTOM_EXT_CONCERT_HALL_LEVEL,
+    CUSTOM_EXT_CLARITY_LEVEL,
+    CUSTOM_EXT_PARAM_MAX
 };
 
 enum {
     SUBCOMMAND_TEST,
+    SUBCOMMAND_PLAY_SAMPLE,
+    SUBCOMMAND_PLAY_SAMPLE_CONTINUOUSLY,
     SUBCOMMAND_MONO,
+    SUBCOMMAND_BALANCE,
+    SUBCOMMAND_MUTEALL,
+    SUBCOMMAND_SET_USE_CASE,
+    SUBCOMMAND_SET_SESSION,
+    SUBCOMMAND_SET_SUBSESSION,
+    SUBCOMMAND_SET_ACTIVE_DEVICE,
+    SUBCOMMAND_RESET,
+    SUBCOMMAND_GET_VOLUME_LEVEL_MAX,
+    SUBCOMMAND_GET_VOLUME_LEVEL,
+    SUBCOMMAND_SET_VOLUME_LEVEL,
+    SUBCOMMAND_UPDATE_VOLUME,
+    SUBCOMMAND_GET_MUTE,
+    SUBCOMMAND_SET_MUTE,
+    SUBCOMMAND_IS_AVAILABLE_HIGH_LATENCY,
+    SUBCOMMAND_UNLOAD_HDMI,
+
 };
 
-/* DEFINEs */
-#define        SINK_ALSA                       "alsa_output.0.analog-stereo"
-#define SINK_MONO_ALSA         "mono_alsa"
-#define SINK_MONO_BT           "mono_bt"
-#define SINK_COMBINED          "combined"
-#define SINK_MONO_COMBINED     "mono_combined"
-#define POLICY_AUTO                    "auto"
-#define POLICY_PHONE           "phone"
-#define POLICY_ALL                     "all"
-#define BLUEZ_API                      "bluez"
-#define MONO_KEY                       "db/setting/accessibility/mono_audio"
 
-/* check if this sink is bluez */
+typedef enum
+{
+    DOCK_NONE      = 0,
+    DOCK_DESKDOCK  = 1,
+    DOCK_CARDOCK   = 2,
+    DOCK_AUDIODOCK = 7,
+    DOCK_SMARTDOCK = 8
+} DOCK_STATUS;
+
+static pa_sink *__get_real_master_sink(pa_sink_input *si);
+static pa_source *__get_real_master_source(pa_source_output *so);
+static inline int __compare_device_info(audio_device_info_t *device_info1, audio_device_info_t *device_info2);
+static audio_return_t __fill_audio_playback_stream_info(pa_proplist *sink_input_proplist, pa_sample_spec *sample_spec, audio_info_t *audio_info);
+static audio_return_t __fill_audio_playback_device_info(pa_proplist *sink_proplist, audio_info_t *audio_info);
+static audio_return_t __fill_audio_playback_info(pa_sink_input *si, audio_info_t *audio_info);
+static audio_return_t __fill_audio_capture_device_info(pa_proplist *source_proplist, audio_info_t *audio_info);
+static audio_return_t policy_play_sample(struct userdata *u, pa_native_connection *c, const char *name, uint32_t volume_type, uint32_t gain_type, uint32_t volume_level, uint32_t *stream_idx);
+static audio_return_t policy_reset(struct userdata *u);
+static audio_return_t policy_set_session(struct userdata *u, uint32_t session, uint32_t start);
+static audio_return_t policy_set_active_device(struct userdata *u, uint32_t device_in, uint32_t device_out, uint32_t* need_update);
+static audio_return_t policy_get_volume_level_max(struct userdata *u, uint32_t volume_type, uint32_t *volume_level);
+static audio_return_t __update_volume(struct userdata *u, uint32_t stream_idx, uint32_t volume_type, uint32_t volume_level);
+#ifdef PRIMARY_VOLUME
+static int __set_primary_volume(struct userdata *u, void* key, int volumetype, int is_new);
+#endif
+static audio_return_t policy_get_volume_level(struct userdata *u, uint32_t stream_idx, uint32_t *volume_type, uint32_t *volume_level);
+static audio_return_t policy_set_volume_level(struct userdata *u, uint32_t stream_idx, uint32_t volume_type, uint32_t volume_level);
+static audio_return_t policy_get_mute(struct userdata *u, uint32_t stream_idx, uint32_t volume_type, uint32_t direction, uint32_t *mute);
+static audio_return_t policy_set_mute(struct userdata *u, uint32_t stream_idx, uint32_t volume_type, uint32_t direction, uint32_t mute);
+static pa_bool_t policy_is_filter (pa_proplist* proplit);
+
+static const char *__get_session_str(uint32_t session)
+{
+    switch (session) {
+        case AUDIO_SESSION_MEDIA:                       return "media";
+        case AUDIO_SESSION_VOICECALL:                   return "voicecall";
+        case AUDIO_SESSION_VIDEOCALL:                   return "videocall";
+        case AUDIO_SESSION_VOIP:                        return "voip";
+        case AUDIO_SESSION_FMRADIO:                     return "fmradio";
+        case AUDIO_SESSION_CAMCORDER:                   return "camcorder";
+        case AUDIO_SESSION_NOTIFICATION:                return "notification";
+        case AUDIO_SESSION_ALARM:                       return "alarm";
+        case AUDIO_SESSION_EMERGENCY:                   return "emergency";
+        case AUDIO_SESSION_VOICE_RECOGNITION:           return "vr";
+        default:                                        return "invalid";
+    }
+}
+
+static const char *__get_subsession_str(uint32_t subsession)
+{
+    switch (subsession) {
+        case AUDIO_SUBSESSION_NONE:                     return "none";
+        case AUDIO_SUBSESSION_VOICE:                    return "voice";
+        case AUDIO_SUBSESSION_RINGTONE:                 return "ringtone";
+        case AUDIO_SUBSESSION_MEDIA:                    return "media";
+        case AUDIO_SUBSESSION_INIT:                     return "init";
+        case AUDIO_SUBSESSION_VR_NORMAL:                return "vr_normal";
+        case AUDIO_SUBSESSION_VR_DRIVE:                 return "vr_drive";
+        case AUDIO_SUBSESSION_STEREO_REC:               return "stereo_rec";
+        case AUDIO_SUBSESSION_MONO_REC:                 return "mono_rec";
+        default:                                        return "invalid";
+    }
+}
+
+static const char *__get_device_in_str(uint32_t device_in)
+{
+    switch (device_in) {
+        case AUDIO_DEVICE_IN_NONE:                      return "none";
+        case AUDIO_DEVICE_IN_MIC:                       return "mic";
+        case AUDIO_DEVICE_IN_WIRED_ACCESSORY:           return "wired";
+        case AUDIO_DEVICE_IN_BT_SCO:                    return "bt_sco";
+        default:                                        return "invalid";
+    }
+}
+
+static const char *__get_device_out_str(uint32_t device_out)
+{
+    switch (device_out) {
+        case AUDIO_DEVICE_OUT_NONE:                     return "none";
+        case AUDIO_DEVICE_OUT_SPEAKER:                  return "spk";
+        case AUDIO_DEVICE_OUT_RECEIVER:                 return "recv";
+        case AUDIO_DEVICE_OUT_WIRED_ACCESSORY:          return "wired";
+        case AUDIO_DEVICE_OUT_BT_SCO:                   return "bt_sco";
+        case AUDIO_DEVICE_OUT_BT_A2DP:                  return "bt_a2dp";
+        case AUDIO_DEVICE_OUT_DOCK:                     return "dock";
+        case AUDIO_DEVICE_OUT_HDMI:                     return "hdmi";
+        case AUDIO_DEVICE_OUT_MIRRORING:                return "mirror";
+        case AUDIO_DEVICE_OUT_USB_AUDIO:                return "usb";
+        case AUDIO_DEVICE_OUT_MULTIMEDIA_DOCK:          return "multi_dock";
+        default:                                        return "invalid";
+    }
+}
+
+static void __load_dump_config(struct userdata *u)
+{
+    dictionary * dict = NULL;
+    int vconf_dump = 0;
+
+    dict = iniparser_load(PA_DUMP_INI_DEFAULT_PATH);
+    if (!dict) {
+        pa_log_debug("%s load failed. Use temporary file", PA_DUMP_INI_DEFAULT_PATH);
+        dict = iniparser_load(PA_DUMP_INI_TEMP_PATH);
+        if (!dict) {
+            pa_log_warn("%s load failed", PA_DUMP_INI_TEMP_PATH);
+            return;
+        }
+    }
+
+    vconf_dump |= iniparser_getboolean(dict, "pcm_dump:decoder_out", 0) ? PA_DUMP_PLAYBACK_DECODER_OUT : 0;
+    vconf_dump |= iniparser_getboolean(dict, "pcm_dump:resampler_in", 0) ? PA_DUMP_PLAYBACK_RESAMPLER_IN : 0;
+    vconf_dump |= iniparser_getboolean(dict, "pcm_dump:resampler_out", 0) ? PA_DUMP_PLAYBACK_RESAMPLER_OUT : 0;
+    vconf_dump |= iniparser_getboolean(dict, "pcm_dump:encoder_in", 0) ? PA_DUMP_CAPTURE_ENCODER_IN : 0;
+    u->core->dump_sink = (pa_bool_t)iniparser_getboolean(dict, "pcm_dump:pa_sink", 0);
+    u->core->dump_sink_input = (pa_bool_t)iniparser_getboolean(dict, "pcm_dump:pa_sink_input", 0);
+    u->core->dump_source = (pa_bool_t)iniparser_getboolean(dict, "pcm_dump:pa_source", 0);
+    u->core->dump_source_output = (pa_bool_t)iniparser_getboolean(dict, "pcm_dump:pa_source_output", 0);
+
+    iniparser_freedict(dict);
+
+    if (vconf_set_int(PA_DUMP_VCONF_KEY, vconf_dump)) {
+        pa_log_warn("vconf_set_int %s=%x failed", PA_DUMP_VCONF_KEY, vconf_dump);
+    }
+}
+
+static inline pa_bool_t __is_mute_policy(void)
+{
+    int sound_status = 1;
+
+    /* If sound is mute mode, force ringtone/notification path to headset */
+    if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sound_status)) {
+        pa_log_warn("vconf_get_bool for %s failed", VCONFKEY_SETAPPL_SOUND_STATUS_BOOL);
+    }
+
+    return (sound_status) ? FALSE : TRUE;
+}
+
+static inline pa_bool_t __is_recording(void)
+{
+    int capture_status = 0;
+
+    /* Check whether audio is recording */
+    if (vconf_get_int(VCONFKEY_SOUND_CAPTURE_STATUS, &capture_status)) {
+        pa_log_warn("vconf_get_bool for %s failed", VCONFKEY_SOUND_CAPTURE_STATUS);
+    }
+
+    return (capture_status) ? TRUE : FALSE;
+}
+
+static inline pa_bool_t __is_noise_reduction_on(void)
+{
+    int noise_reduction_on = 1;
+
+    if (vconf_get_bool(VCONFKEY_CALL_NOISE_REDUCTION_STATE_BOOL, &noise_reduction_on)) {
+        pa_log_warn("vconf_get_bool for %s failed", VCONFKEY_CALL_NOISE_REDUCTION_STATE_BOOL);
+    }
+
+    return (noise_reduction_on == 1) ? TRUE : FALSE;
+}
+
+static bool __is_extra_volume_on(void)
+{
+    int extra_volume_on = 1;
+
+    if (vconf_get_bool(VCONFKEY_CALL_EXTRA_VOLUME_STATE_BOOL, &extra_volume_on)) {
+        pa_log_warn("vconf_get_bool for %s failed", VCONFKEY_CALL_EXTRA_VOLUME_STATE_BOOL);
+    }
+
+    return (extra_volume_on == 1) ? TRUE : FALSE;
+}
+
+static bool __is_wideband(void)
+{
+    int wbamr = 1;
+
+    if (vconf_get_bool(VCONFKEY_CALL_WBAMR_STATE_BOOL, &wbamr)) {
+        pa_log_warn("vconf_get_bool for %s failed", VCONFKEY_CALL_WBAMR_STATE_BOOL);
+    }
+
+    return (wbamr == 1) ? TRUE : FALSE;
+}
+
 static pa_bool_t policy_is_bluez (pa_sink* sink)
 {
-       const char* api_name = NULL;
+    const char* api_name = NULL;
 
-       if (sink == NULL) {
-               pa_log_warn ("input param sink is null");
-               return FALSE;
-       }
+    if (sink == NULL) {
+        pa_log_warn ("input param sink is null");
+        return FALSE;
+    }
 
     api_name = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_API);
-       if (api_name) {
-               if (pa_streq (api_name, BLUEZ_API)) {
-#ifdef DEBUG_DETAIL
-                       pa_log_debug("[POLICY][%s] [%s] exists and it is [%s]...TRUE !!", __func__, PA_PROP_DEVICE_API, api_name);
-#endif
-                       return TRUE;
-               } else {
-#ifdef DEBUG_DETAIL
-                       pa_log_debug("[POLICY][%s] [%s] exists, but not bluez...FALSE !!", __func__, PA_PROP_DEVICE_API);
-#endif
-               }
-       } else {
-#ifdef DEBUG_DETAIL
-               pa_log_debug("[POLICY][%s] No [%s] exists...FALSE!!", __func__, PA_PROP_DEVICE_API);
-#endif
-       }
+    if (api_name) {
+        if (pa_streq (api_name, BLUEZ_API))
+            return TRUE;
+    }
 
-       return FALSE;
+    return FALSE;
 }
 
-/* Get sink by name */
-static pa_sink* policy_get_sink_by_name (pa_core *c, const char* sink_name)
+/* check if this sink is bluez */
+static pa_bool_t policy_is_usb_alsa (pa_sink* sink)
 {
-    pa_sink *s = NULL;
-    uint32_t idx;
+    const char* api_name = NULL;
+    const char* device_bus_name = NULL;
+
+    if (sink == NULL) {
+        pa_log_warn ("input param sink is null");
+        return FALSE;
+    }
 
-    if (c == NULL || sink_name == NULL) {
-               pa_log_warn ("input param is null");
-               return NULL;
+    api_name = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_API);
+    if (api_name) {
+        if (pa_streq (api_name, ALSA_API)) {
+            device_bus_name = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_BUS);
+            if (device_bus_name) {
+                if (pa_streq (device_bus_name, "usb"))
+                    return TRUE;
+            }
+        }
     }
 
-       PA_IDXSET_FOREACH(s, c->sinks, idx) {
-               if (pa_streq (s->name, sink_name)) {
-                       pa_log_debug ("[POLICY][%s] return [%p] for [%s]\n",  __func__, s, sink_name);
-                       return s;
-               }
-       }
-       return NULL;
+    return FALSE;
+}
+
+/* Get sink by name */
+static pa_sink* policy_get_sink_by_name (pa_core *c, const char* sink_name)
+{
+    return (pa_sink*)pa_namereg_get(c, sink_name, PA_NAMEREG_SINK);
+}
+
+/* Get source by name */
+static pa_source* policy_get_source_by_name (pa_core *c, const char* source_name)
+{
+return (pa_source*)pa_namereg_get(c, source_name, PA_NAMEREG_SOURCE);
 }
 
 /* Get bt sink if available */
@@ -132,228 +555,2746 @@ static pa_sink* policy_get_bt_sink (pa_core *c)
     uint32_t idx;
 
     if (c == NULL) {
-               pa_log_warn ("input param is null");
-               return NULL;
+        pa_log_warn ("input param is null");
+        return NULL;
+    }
+
+    PA_IDXSET_FOREACH(s, c->sinks, idx) {
+        if (policy_is_bluez (s)) {
+            pa_log_debug_verbose("return [%p] for [%s]\n", s, s->name);
+            return s;
+        }
+    }
+    return NULL;
+}
+
+/** This function chages the sink from normal sink to UHQA sink if UHQA sink is available*/
+static pa_sink* switch_to_uhqa_sink(struct userdata *u, const char* policy)
+{
+    pa_sink_input *si = NULL;
+    uint32_t idx;
+    pa_core *c = u->core;
+    pa_sink* sink = NULL;
+    pa_sink* uhqa_sink = NULL;
+    pa_sink* def = pa_namereg_get_default_sink(c);
+    /** If default sink is HDMI sink*/
+    if (def != NULL ? sink_is_hdmi(def) : false) {
+        uhqa_sink = policy_get_sink_by_name(c, SINK_HDMI_UHQA);
+        sink = policy_get_sink_by_name(c, SINK_HDMI);
+    /** If high latency UHQA policy means h:0,4 UHQA sink to be selected if h:0,4 UHQA sink already created*/
+    } else if (pa_streq(policy, POLICY_HIGH_LATENCY_UHQA)) {
+        uhqa_sink = policy_get_sink_by_name(c, SINK_HIGH_LATENCY_UHQA);
+        sink = policy_get_sink_by_name(c, SINK_HIGH_LATENCY);
+    } else if (pa_streq(policy, POLICY_AUTO_UHQA)) {   /** If UHQA policy choose UHQA sink*/
+        pa_log_info ("---------------------------------");
+
+        uhqa_sink = policy_get_sink_by_name(c, SINK_ALSA_UHQA);
+        sink = policy_get_sink_by_name(c, SINK_ALSA);
+    }
+    pa_log_info ("---------------------------------");
+    if (uhqa_sink != NULL) {
+        if (sink != NULL) {/** if the sink is null due to some reason ,it need to add protect code */
+
+            /** Check if normal sink is in not suspended state then suspend normal sik so that pcm handle is closed*/
+            if (PA_SINK_SUSPENDED != pa_sink_get_state(sink) ) {
+                pa_sink_suspend(sink, TRUE, PA_SUSPEND_USER);
+            }
+            pa_log_info ("---------------------------------");
+
+            /** Check any sink input connected to normal sink then move them to UHQA sink*/
+            PA_IDXSET_FOREACH (si, sink->inputs, idx) {
+
+                /* Get role (if role is filter, skip it) */
+                if (policy_is_filter(si->proplist)) {
+                    continue;
+                }
+                pa_sink_input_move_to(si, uhqa_sink, FALSE);
+            }
+        }
+        if (PA_SINK_SUSPENDED == pa_sink_get_state(uhqa_sink)) {
+            pa_sink_suspend(uhqa_sink, FALSE, PA_SUSPEND_USER);
+        }
+        sink = uhqa_sink;
+    }
+
+    return sink;
+}
+
+/** This function choose normal sink if UHQA sink is in suspended state*/
+static pa_sink* switch_to_normal_sink(struct userdata *u, const char* policy)
+{
+    pa_sink_input *si = NULL;
+    uint32_t idx;
+    pa_core *c = u->core;
+    pa_sink* sink = NULL;
+    pa_sink* uhqa_sink = NULL;
+    const char *sink_name  = SINK_ALSA;
+    pa_sink* def = NULL;
+
+    def = pa_namereg_get_default_sink(c);
+
+    if (pa_streq(policy, POLICY_PHONE) || pa_streq(policy, POLICY_ALL)) {
+      /** Get the UHQA sink */
+      uhqa_sink = policy_get_sink_by_name (c, SINK_ALSA_UHQA);
+    } else if (def != NULL ? sink_is_hdmi(def) : false) {    /** If default sink is HDMI sink*/
+        /** Get the UHQA sink handle, if it exists then suspend it if not in use*/
+        uhqa_sink = policy_get_sink_by_name (c, SINK_HDMI_UHQA);
+        sink_name  = SINK_HDMI;
+    } else if(pa_streq(policy, POLICY_HIGH_LATENCY)) {      /** Choose the normal sink based on policy*/
+        /** Get the UHQA sink handle, if it exists then suspend it if not in use*/
+        uhqa_sink =  policy_get_sink_by_name(c, SINK_HIGH_LATENCY_UHQA);
+        sink_name  = SINK_HIGH_LATENCY;
+    } else {
+        /** Get the UHQA sink */
+        uhqa_sink = policy_get_sink_by_name(c, SINK_ALSA_UHQA);
+    }
+    sink = uhqa_sink;
+
+    /**
+      * If UHQA sink is in used or any UHQA sink is connected to UHQA sink then return UHQA sink else return normal sink
+      */
+    if ((sink != NULL) && pa_sink_used_by(sink)) {
+        sink = uhqa_sink;
+    } else {
+        sink = policy_get_sink_by_name(c, sink_name);
+        if (sink != NULL) {/**if the sink is null ,it need to add protect code*/
+            /** Move all sink inputs from UHQA sink to normal sink*/
+            if (uhqa_sink != NULL) {
+                if (PA_SINK_SUSPENDED != pa_sink_get_state(uhqa_sink)) {
+                    pa_sink_suspend(uhqa_sink, TRUE, PA_SUSPEND_USER);
+                }
+                PA_IDXSET_FOREACH (si, uhqa_sink->inputs, idx) {
+                    /* Get role (if role is filter, skip it) */
+                    if (policy_is_filter(si->proplist)) {
+                       continue;
+                    }
+                   pa_sink_input_move_to(si, sink, FALSE);
+               }
+            }
+            if (PA_SINK_SUSPENDED == pa_sink_get_state(sink) ) {
+                /** unsuspend this sink */
+                pa_sink_suspend(sink, FALSE, PA_SUSPEND_USER);
+            }
+        } else {/** if sink is null,it can not move to the normal sink ,still use uhqa sink */
+            pa_log_warn ("The %s sink is null", sink_name);
+            sink = uhqa_sink;
+        }
+    }
+
+    return sink;
+}
+
+/* Select sink for given condition */
+static pa_sink* policy_select_proper_sink (struct userdata *u, const char* policy, pa_sink_input *sink_input, pa_bool_t check_bt)
+{
+    pa_core *c = u->core;
+    pa_sink *sink = NULL, *bt_sink = NULL, *def, *sink_null;
+    pa_sink_input *si = NULL;
+    uint32_t idx;
+    const char *si_policy_str;
+    char *args = NULL;
+
+    pa_assert (u);
+    c = u->core;
+    pa_assert (c);
+    if (policy == NULL) {
+        pa_log_warn ("input param is null");
+        return NULL;
+    }
+
+    if (check_bt)
+        bt_sink = policy_get_bt_sink(c);
+
+    def = pa_namereg_get_default_sink(c);
+    if (def == NULL) {
+        pa_log_warn ("pa_namereg_get_default_sink() returns null");
+        return NULL;
+    }
+
+    sink_null = (pa_sink *)pa_namereg_get(u->core, "null", PA_NAMEREG_SINK);
+    /* if default sink is set as null sink, we will use null sink */
+    if (def == sink_null)
+        return def;
+
+    /* Select sink to */
+    if (pa_streq(policy, POLICY_ALL)) {
+        /* all */
+        if (bt_sink) {
+            if (u->module_combined == NULL) {
+                pa_log_info ("combined sink is not prepared, now load-modules...");
+                /* load combine sink */
+                args = pa_sprintf_malloc("sink_name=%s slaves=\"%s,%s\"", SINK_COMBINED, bt_sink->name, SINK_ALSA);
+                u->module_combined = pa_module_load(u->module->core, "module-combine", args);
+                pa_xfree(args);
+            }
+            sink = policy_get_sink_by_name(c, SINK_COMBINED);
+        } else {
+#ifdef TIZEN_MICRO
+            sink = policy_get_sink_by_name (c, SINK_ALSA);
+#else
+            sink = switch_to_normal_sink(u, policy);
+#endif
+        }
+    } else if (pa_streq(policy, POLICY_PHONE)) {
+        /* phone */
+#ifdef TIZEN_MICRO
+        if (u->subsession == AUDIO_SUBSESSION_RINGTONE)
+            sink = policy_get_sink_by_name(c, AEC_SINK);
+        if (!sink)
+            sink = policy_get_sink_by_name (c, SINK_ALSA);
+#else
+        sink = switch_to_normal_sink(u, policy);
+#endif
+    } else if (pa_streq(policy, POLICY_VOIP)) {
+        /* VOIP */
+        /* NOTE: Check voip sink first, if not available, use AEC sink */
+        sink = policy_get_sink_by_name (c,SINK_VOIP);
+        if (sink == NULL) {
+            pa_log_info ("VOIP sink is not available, try to use AEC sink");
+            sink = policy_get_sink_by_name (c, AEC_SINK);
+            if (sink == NULL) {
+                pa_log_info ("AEC sink is not available, set to default sink");
+                sink = def;
+            }
+        }
+    } else {
+        /* auto */
+        if (check_bt && policy_is_bluez(def)) {
+            sink = def;
+        } else if (policy_is_usb_alsa(def)) {
+            sink = def;
+        } else if (sink_is_hdmi(def)) {
+#ifdef TIZEN_MICRO
+            sink = def;
+#else
+            if (pa_streq(policy, POLICY_AUTO_UHQA) || (pa_streq(policy, POLICY_HIGH_LATENCY_UHQA))) {
+                sink = switch_to_uhqa_sink(u,policy);
+            }
+            else {
+                sink = switch_to_normal_sink(u, policy);
+            }
+#endif
+        } else {
+            pa_bool_t highlatency_exist = 0;
+#ifdef TIZEN_MICRO
+            if(pa_streq(policy, POLICY_HIGH_LATENCY)) {
+#else
+            if ((pa_streq(policy, POLICY_HIGH_LATENCY)) || (pa_streq(policy, POLICY_HIGH_LATENCY_UHQA))) {
+#endif
+                PA_IDXSET_FOREACH(si, c->sink_inputs, idx) {
+                    if ((si_policy_str = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_POLICY))) {
+                        if (pa_streq(si_policy_str, POLICY_HIGH_LATENCY) && sink_is_highlatency(si->sink)
+                            && (sink_input == NULL || sink_input->index != si->index)) {
+                            highlatency_exist = 1;
+                            break;
+                        }
+                    }
+                }
+
+#ifdef TIZEN_MICRO
+                if (!highlatency_exist) {
+                    sink = policy_get_sink_by_name(c, SINK_HIGH_LATENCY);
+                }
+#else
+
+                /** If high latency UHQA policy means h:0,4 UHQA sink to be selected if h:0,4 UHQA sink already created*/
+                if (pa_streq(policy, POLICY_HIGH_LATENCY_UHQA)) {
+                    sink = switch_to_uhqa_sink(u,policy);
+                }
+
+                /**
+                  * If still sink is null means either policy is high-latency or UHQA sink does not exist
+                  * Normal sink need to be selected
+                  */
+                if (!highlatency_exist && (sink == NULL)) {
+                    sink = switch_to_normal_sink(u, policy);
+                }
+#endif
+            }
+#ifdef TIZEN_MICRO
+            if (!sink)
+                sink = policy_get_sink_by_name(c, SINK_ALSA);
+
+#else
+            /** If sink is still null then it is required to choose hw:0,0 UHQA sink or normal sink  based on policy*/
+            if (!sink) {
+                /** If UHQA policy choose UHQA sink*/
+                if (pa_streq(policy, POLICY_AUTO_UHQA)) {
+                    sink = switch_to_uhqa_sink(u,policy);
+                }
+
+                /** If still no sink selected then select hw:0,0 normal sink this is the default case*/
+                if (!sink) {
+                    sink = switch_to_normal_sink(u,POLICY_AUTO);
+                }
+             }
+#endif
+        }
+    }
+    pa_log_debug_verbose("policy[%s] current default[%s] bt_sink[%s] selected_sink[%s]\n",
+            policy, def->name, (bt_sink)? bt_sink->name:"null", (sink)? sink->name:"null");
+
+    return sink;
+}
+
+static pa_bool_t policy_is_filter (pa_proplist* proplist)
+{
+    const char* role = NULL;
+
+    if (proplist == NULL) {
+        pa_log_warn ("input param proplist is null");
+        return FALSE;
+    }
+
+    if ((role = pa_proplist_gets(proplist, PA_PROP_MEDIA_ROLE))) {
+        if (pa_streq(role, "filter"))
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+static pa_sink *__get_real_master_sink(pa_sink_input *si)
+{
+    const char *master_name;
+    pa_sink *s, *sink;
+
+    s = (si->origin_sink) ? si->origin_sink : si->sink;
+    master_name = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_MASTER_DEVICE);
+    if (master_name)
+        sink = pa_namereg_get(si->core, master_name, PA_NAMEREG_SINK);
+    else
+        sink = s;
+    return sink;
+}
+
+static pa_source *__get_real_master_source(pa_source_output *so)
+{
+    const char *master_name;
+    pa_source *s, *source;
+
+    s = (so->destination_source) ? so->destination_source : so->source;
+    master_name = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_MASTER_DEVICE);
+    if (master_name)
+        source = pa_namereg_get(so->core, master_name, PA_NAMEREG_SINK);
+    else
+        source = s;
+    return source;
+}
+
+static void __free_audio_stream_info (audio_info_t *audio_info)
+{
+    pa_xfree(audio_info->stream.name);
+}
+
+static void __free_audio_device_info (audio_info_t *audio_info)
+{
+    if (audio_info->device.api == AUDIO_DEVICE_API_ALSA) {
+        pa_xfree(audio_info->device.alsa.card_name);
+    } else if (audio_info->device.api == AUDIO_DEVICE_API_BLUEZ) {
+        pa_xfree(audio_info->device.bluez.protocol);
+    }
+    pa_xfree(audio_info->device.name);
+}
+
+static void __free_audio_info (audio_info_t *audio_info)
+{
+    __free_audio_stream_info(audio_info);
+    __free_audio_device_info(audio_info);
+}
+
+static audio_return_t __fill_audio_playback_stream_info(pa_proplist *sink_input_proplist, pa_sample_spec *sample_spec, audio_info_t *audio_info)
+{
+    const char *si_volume_type_str, *si_gain_type_str;
+
+    memset(&audio_info->stream, 0x00, sizeof(audio_stream_info_t));
+
+    if (!sink_input_proplist) {
+        return AUDIO_ERR_PARAMETER;
+    }
+
+    audio_info->stream.name = strdup(pa_strnull(pa_proplist_gets(sink_input_proplist, PA_PROP_MEDIA_NAME)));
+    audio_info->stream.samplerate = sample_spec->rate;
+    audio_info->stream.channels = sample_spec->channels;
+    audio_info->stream.gain_type = AUDIO_GAIN_TYPE_DEFAULT;
+
+    /* Get volume type of sink input */
+    if ((si_volume_type_str = pa_proplist_gets(sink_input_proplist, PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) {
+        pa_atou(si_volume_type_str, &audio_info->stream.volume_type);
+    } else {
+        pa_xfree(audio_info->stream.name);
+        return AUDIO_ERR_UNDEFINED;
+    }
+
+    /* Get gain type of sink input */
+    if ((si_gain_type_str = pa_proplist_gets(sink_input_proplist, PA_PROP_MEDIA_TIZEN_GAIN_TYPE))) {
+        pa_atou(si_gain_type_str, &audio_info->stream.gain_type);
+    }
+
+    return AUDIO_RET_OK;
+}
+
+static audio_return_t __fill_audio_playback_device_info(pa_proplist *sink_proplist, audio_info_t *audio_info)
+{
+    const char *s_device_api_str;
+
+    memset(&audio_info->device, 0x00, sizeof(audio_device_info_t));
+
+    if (!sink_proplist) {
+        return AUDIO_ERR_PARAMETER;
+    }
+
+    /* Get device api */
+    if ((s_device_api_str = pa_proplist_gets(sink_proplist, PA_PROP_DEVICE_API))) {
+        audio_info->device.name = strdup(pa_strnull(pa_proplist_gets(sink_proplist, PA_PROP_DEVICE_STRING)));
+        if (pa_streq(s_device_api_str, "alsa")) {
+            const char *card_idx_str, *device_idx_str;
+
+            audio_info->device.api = AUDIO_DEVICE_API_ALSA;
+            audio_info->device.direction = AUDIO_DIRECTION_OUT;
+            audio_info->device.alsa.card_name = strdup(pa_strnull(pa_proplist_gets(sink_proplist, "alsa.card_name")));
+            audio_info->device.alsa.card_idx = 0;
+            audio_info->device.alsa.device_idx = 0;
+            if ((card_idx_str = pa_proplist_gets(sink_proplist, "alsa.card")))
+                pa_atou(card_idx_str, &audio_info->device.alsa.card_idx);
+            if ((device_idx_str = pa_proplist_gets(sink_proplist, "alsa.device")))
+                pa_atou(device_idx_str, &audio_info->device.alsa.device_idx);
+        }
+        else if (pa_streq(s_device_api_str, "bluez")) {
+            const char *nrec_str;
+
+            audio_info->device.api = AUDIO_DEVICE_API_BLUEZ;
+            audio_info->device.bluez.nrec = 0;
+            audio_info->device.bluez.protocol = strdup(pa_strnull(pa_proplist_gets(sink_proplist, "bluetooth.protocol")));
+            if ((nrec_str = pa_proplist_gets(sink_proplist, "bluetooth.nrec")))
+                pa_atou(nrec_str, &audio_info->device.bluez.nrec);
+        }
+    }
+
+    return AUDIO_RET_OK;
+}
+
+static audio_return_t __fill_audio_playback_info(pa_sink_input *si, audio_info_t *audio_info)
+{
+    audio_return_t audio_ret = AUDIO_RET_OK;
+    pa_sink *sink;
+
+    sink = __get_real_master_sink(si);
+    if (AUDIO_IS_ERROR((audio_ret = __fill_audio_playback_stream_info(si->proplist, &si->sample_spec, audio_info)))) {
+        return audio_ret;
+    }
+    if (AUDIO_IS_ERROR((audio_ret = __fill_audio_playback_device_info(sink->proplist, audio_info)))) {
+        __free_audio_stream_info(audio_info);
+        return audio_ret;
+    }
+
+    return AUDIO_RET_OK;
+}
+
+static audio_return_t __fill_audio_capture_device_info(pa_proplist *source_proplist, audio_info_t *audio_info)
+{
+    const char *s_device_api_str;
+
+    if (!source_proplist) {
+        return AUDIO_ERR_PARAMETER;
+    }
+
+    memset(&audio_info->device, 0x00, sizeof(audio_device_info_t));
+
+    /* Get device api */
+    if ((s_device_api_str = pa_proplist_gets(source_proplist, PA_PROP_DEVICE_API))) {
+        audio_info->device.name = strdup(pa_strnull(pa_proplist_gets(source_proplist, PA_PROP_DEVICE_STRING)));
+        if (pa_streq(s_device_api_str, "alsa")) {
+            const char *card_idx_str, *device_idx_str;
+
+            audio_info->device.api = AUDIO_DEVICE_API_ALSA;
+            audio_info->device.direction = AUDIO_DIRECTION_IN;
+            audio_info->device.alsa.card_name = strdup(pa_strnull(pa_proplist_gets(source_proplist, "alsa.card_name")));
+            audio_info->device.alsa.card_idx = 0;
+            audio_info->device.alsa.device_idx = 0;
+            if ((card_idx_str = pa_proplist_gets(source_proplist, "alsa.card")))
+                pa_atou(card_idx_str, &audio_info->device.alsa.card_idx);
+            if ((device_idx_str = pa_proplist_gets(source_proplist, "alsa.device")))
+                pa_atou(device_idx_str, &audio_info->device.alsa.device_idx);
+        }
+        else if (pa_streq(s_device_api_str, "bluez")) {
+            const char *nrec_str;
+
+            audio_info->device.api = AUDIO_DEVICE_API_BLUEZ;
+            audio_info->device.bluez.nrec = 0;
+            audio_info->device.bluez.protocol = strdup(pa_strnull(pa_proplist_gets(source_proplist, "bluetooth.protocol")));
+            if ((nrec_str = pa_proplist_gets(source_proplist, "bluetooth.nrec")))
+                pa_atou(nrec_str, &audio_info->device.bluez.nrec);
+        }
+    }
+
+    return AUDIO_RET_OK;
+}
+
+#define PROP_POLICY_CORK "policy_cork_by_device_switch"
+
+static inline int __compare_device_info (audio_device_info_t *device_info1, audio_device_info_t *device_info2)
+{
+    if (device_info1->direction != device_info2->direction)
+        return FALSE;
+
+    if (device_info1->api == AUDIO_DEVICE_API_ALSA) {
+        if ((!strcmp(device_info1->alsa.card_name, device_info2->alsa.card_name) || (device_info1->alsa.card_idx == device_info2->alsa.card_idx))
+            && (device_info1->alsa.device_idx == device_info2->alsa.device_idx)) {
+            return TRUE;
+        }
     }
+    if (device_info1->api == AUDIO_DEVICE_API_BLUEZ) {
+        if (!strcmp(device_info1->bluez.protocol, device_info2->bluez.protocol) && (device_info1->bluez.nrec == device_info2->bluez.nrec)) {
+            return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
+static void __free_event (struct pa_hal_event *hal_event) {
+    pa_assert(hal_event);
+    pa_assert(hal_event->userdata);
+
+    pa_xfree(hal_event->event_data);
+    pa_mutex_free(hal_event->mutex);
+    pa_cond_free(hal_event->cond);
+    pa_xfree(hal_event);
+}
+
+static inline const char *__get_event_type_string (pa_hal_event_type_t hal_event_type)
+{
+    switch (hal_event_type) {
+        case PA_HAL_EVENT_LOAD_DEVICE:          return "load device";
+        case PA_HAL_EVENT_OPEN_DEVICE:          return "open device";
+        case PA_HAL_EVENT_CLOSE_ALL_DEVICES:    return "close all devices";
+        case PA_HAL_EVENT_CLOSE_DEVICE:         return "close device";
+        case PA_HAL_EVENT_UNLOAD_DEVICE:        return "unload device";
+        default:                                return "undefined";
+    }
+}
+
+static audio_return_t __load_n_open_device (struct userdata *u, audio_device_info_t *device_info, audio_device_param_info_t *params, pa_hal_event_type_t hal_event_type)
+{
+    audio_info_t audio_info;
+    bool is_module_loaded = false;
+    pa_strbuf *name_buf, *args_buf, *prop_buf;
+    char *name = NULL, *args = NULL, *prop = NULL;
+    pa_source *source;
+    pa_sink *sink;
+    const char *device_object_str = NULL, *dirction_str = NULL;
+    const char *is_manual_corked_str = NULL;
+    uint32_t is_manual_corked = 0;
+    int i;
+    bool is_param_set[AUDIO_DEVICE_PARAM_MAX] = {false, };
+    uint32_t idx;
+
+    pa_assert(u);
+    pa_assert(device_info);
+    pa_assert(device_info->direction == AUDIO_DIRECTION_IN || device_info->direction == AUDIO_DIRECTION_OUT);
+
+     if (device_info->direction == AUDIO_DIRECTION_IN) {
+        PA_IDXSET_FOREACH(source, u->core->sources, idx) {
+            if (!AUDIO_IS_ERROR(__fill_audio_capture_device_info(source->proplist, &audio_info))) {
+                if (__compare_device_info(&audio_info.device, device_info)) {
+                    is_module_loaded = true;
+                    __free_audio_device_info(&audio_info);
+                    break;
+                }
+                __free_audio_device_info(&audio_info);
+            }
+        }
+        device_object_str = "source";
+        dirction_str = "input";
+    } else {
+        PA_IDXSET_FOREACH(sink, u->core->sinks, idx) {
+            if (!AUDIO_IS_ERROR(__fill_audio_playback_device_info(sink->proplist, &audio_info))) {
+                if (__compare_device_info(&audio_info.device, device_info)) {
+                    is_module_loaded = true;
+                    __free_audio_device_info(&audio_info);
+                    break;
+                }
+                __free_audio_device_info(&audio_info);
+            }
+        }
+        device_object_str = "sink";
+        dirction_str = "output";
+    }
+
+    name_buf = pa_strbuf_new();
+    if (device_info->api == AUDIO_DEVICE_API_ALSA) {
+        if (device_info->alsa.card_name && !strncmp(device_info->alsa.card_name, ALSA_VIRTUAL_CARD, strlen(ALSA_VIRTUAL_CARD))) {
+            pa_strbuf_printf(name_buf, "%s", (device_info->direction == AUDIO_DIRECTION_OUT) ? SINK_VIRTUAL : SOURCE_VIRTUAL);
+        } else if (device_info->alsa.card_name && !strncmp(device_info->alsa.card_name, ALSA_SAUDIOVOIP_CARD, strlen(ALSA_SAUDIOVOIP_CARD))) {
+            pa_strbuf_printf(name_buf, "%s", (device_info->direction == AUDIO_DIRECTION_OUT) ? SINK_VOIP : SOURCE_VOIP);
+        } else {
+            pa_strbuf_printf(name_buf, "alsa_%s.%d.analog-stereo", dirction_str, device_info->alsa.device_idx);
+        }
+    } else if (device_info->api == AUDIO_DEVICE_API_BLUEZ) {
+        /* HAL_TODO : do we need to consider BLUEZ here? */
+        pa_strbuf_printf(name_buf, "bluez_%s.%s", device_object_str, device_info->bluez.protocol);
+    } else {
+        pa_strbuf_printf(name_buf, "unknown_%s", device_object_str);
+    }
+    name = pa_strbuf_tostring_free(name_buf);
+    if (!name) {
+        pa_log_error("invalid module name");
+        return AUDIO_ERR_PARAMETER;
+    }
+
+    /* load module if is not loaded */
+    if (is_module_loaded == false) {
+        args_buf = pa_strbuf_new();
+        prop_buf = pa_strbuf_new();
+
+        pa_strbuf_printf(args_buf, "%s_name=\"%s\" ", device_object_str, name);
+        if (device_info->name) {
+            pa_strbuf_printf(args_buf, "device=\"%s\" ", device_info->name);
+        }
+
+        for (i = 0; i < AUDIO_DEVICE_PARAM_MAX; i++) {
+            if (params[i].param == AUDIO_DEVICE_PARAM_NONE)
+                break;
+            is_param_set[params[i].param] = true;
+            if (params[i].param == AUDIO_DEVICE_PARAM_CHANNELS) {
+                pa_strbuf_printf(args_buf, "channels=\"%d\" ", params[i].u32_v);
+            } else if (params[i].param == AUDIO_DEVICE_PARAM_SAMPLERATE) {
+                pa_strbuf_printf(args_buf, "rate=\"%d\" ", params[i].u32_v);
+            } else if (params[i].param == AUDIO_DEVICE_PARAM_FRAGMENT_SIZE) {
+                pa_strbuf_printf(args_buf, "fragment_size=\"%d\" ", params[i].u32_v);
+            } else if (params[i].param == AUDIO_DEVICE_PARAM_FRAGMENT_NB) {
+                pa_strbuf_printf(args_buf, "fragments=\"%d\" ", params[i].u32_v);
+            } else if (params[i].param == AUDIO_DEVICE_PARAM_START_THRESHOLD) {
+                pa_strbuf_printf(args_buf, "start_threshold=\"%d\" ", params[i].s32_v);
+            } else if (params[i].param == AUDIO_DEVICE_PARAM_USE_MMAP) {
+                pa_strbuf_printf(args_buf, "mmap=\"%d\" ", params[i].u32_v);
+            } else if (params[i].param == AUDIO_DEVICE_PARAM_USE_TSCHED) {
+                pa_strbuf_printf(args_buf, "tsched=\"%d\" ", params[i].u32_v);
+            } else if (params[i].param == AUDIO_DEVICE_PARAM_TSCHED_BUF_SIZE) {
+                pa_strbuf_printf(args_buf, "tsched_buffer_size=\"%d\" ", params[i].u32_v);
+            } else if (params[i].param == AUDIO_DEVICE_PARAM_SUSPEND_TIMEOUT) {
+                pa_strbuf_printf(prop_buf, "module-suspend-on-idle.timeout=%d ", params[i].u32_v);
+            } else if (params[i].param == AUDIO_DEVICE_PARAM_ALTERNATE_RATE) {
+                pa_strbuf_printf(args_buf, "alternate_rate=\"%d\" ", params[i].u32_v);
+            }
+        }
+
+        if (device_info->direction == AUDIO_DIRECTION_IN) {
+            pa_module *module_source = NULL;
+
+            if (!is_param_set[AUDIO_DEVICE_PARAM_FRAGMENT_SIZE]) {
+                pa_strbuf_printf(args_buf, "fragment_size=\"%d\" ", (u->fragment_size) ? u->fragment_size : DEFAULT_FRAGMENT_SIZE);
+            }
+            if ((prop = pa_strbuf_tostring_free(prop_buf))) {
+                pa_strbuf_printf(args_buf, "source_properties=\"%s\" ", prop);
+            }
+
+            args = pa_strbuf_tostring_free(args_buf);
+
+            if (device_info->api == AUDIO_DEVICE_API_ALSA) {
+                module_source = pa_module_load(u->core, "module-alsa-source", args);
+            } else if (device_info->api == AUDIO_DEVICE_API_BLUEZ) {
+                module_source = pa_module_load(u->core, "module-bluez-source", args);
+            }
+
+            if (!module_source) {
+                pa_log_error("load source module failed. api:%d args:%s", device_info->api, args);
+            }
+        } else {
+            pa_module *module_sink = NULL;
+
+            if (!is_param_set[AUDIO_DEVICE_PARAM_TSCHED_BUF_SIZE]) {
+                pa_strbuf_printf(args_buf, "tsched_buffer_size=\"%d\" ", (u->tsched_buffer_size) ? u->tsched_buffer_size : DEFAULT_TSCHED_BUFFER_SIZE);
+            }
+            if ((prop = pa_strbuf_tostring_free(prop_buf))) {
+                pa_strbuf_printf(args_buf, "sink_properties=\"%s\" ", prop);
+            }
+
+            args = pa_strbuf_tostring_free(args_buf);
+
+            if (device_info->api == AUDIO_DEVICE_API_ALSA) {
+                module_sink = pa_module_load(u->core, "module-alsa-sink", args);
+            } else if (device_info->api == AUDIO_DEVICE_API_BLUEZ) {
+                module_sink = pa_module_load(u->core, "module-bluez-sink", args);
+            }
+
+            if (!module_sink) {
+                pa_log_error("load sink module failed. api:%d args:%s", device_info->api, args);
+            }
+        }
+    }
+
+    if (hal_event_type == PA_HAL_EVENT_LOAD_DEVICE) {
+        goto exit;
+    }
+
+    if (device_info->direction == AUDIO_DIRECTION_IN) {
+        /* set default source */
+        pa_source *source_default = pa_namereg_get_default_source(u->core);
+        pa_source *source_null = (pa_source *)pa_namereg_get(u->core, "null", PA_NAMEREG_SOURCE);
+
+        if (source_default == source_null || device_info->is_default_device) {
+            if ((source = pa_namereg_get(u->core, name, PA_NAMEREG_SOURCE))) {
+                pa_source_output *so;
+
+                if (source != source_default) {
+                    pa_namereg_set_default_source(u->core, source);
+                    pa_log_info("set %s as default source", name);
+                }
+
+                PA_IDXSET_FOREACH(so, u->core->source_outputs, idx) {
+                    if (!so->source)
+                        continue;
+                    /* Get role (if role is filter, skip it) */
+                    if (policy_is_filter(so->proplist))
+                        continue;
+
+                    pa_source_output_move_to(so, source, FALSE);
+
+                    /* UnCork if corked by manually */
+                    if ((is_manual_corked_str = pa_proplist_gets(so->proplist, PROP_POLICY_CORK))) {
+                        pa_atou(is_manual_corked_str, &is_manual_corked);
+                        if (is_manual_corked) {
+                            pa_proplist_sets(so->proplist, PROP_POLICY_CORK, "0");
+                            pa_source_output_cork(so, FALSE);
+                            pa_log_info("<UnCork> for source-input[%d]:source[%s]", so->index, so->source->name);
+                        }
+                    }
+                }
+            }
+        }
+    } else {
+        /* set default sink */
+        pa_sink *sink_default = pa_namereg_get_default_sink(u->core);
+        pa_sink *sink_null = (pa_sink *)pa_namereg_get(u->core, "null", PA_NAMEREG_SINK);
+
+        if ((sink_default == sink_null || device_info->is_default_device)
+            && !(device_info->api == AUDIO_DEVICE_API_ALSA && u->active_device_out == AUDIO_DEVICE_OUT_BT_A2DP)) {
+            if ((sink = pa_namereg_get(u->core, name, PA_NAMEREG_SINK))) {
+                pa_sink_input *si;
+
+                if (sink != sink_default) {
+                    pa_namereg_set_default_sink(u->core, sink);
+                    pa_log_info("set %s as default sink", name);
+                }
+
+                PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+                    if (!si->sink)
+                        continue;
+
+                    /* Get role (if role is filter, skip it) */
+                    if (policy_is_filter(si->proplist))
+                        continue;
+
+                    pa_sink_input_move_to(si, sink, FALSE);
+
+                    /* UnCork if corked by manually */
+                    if ((is_manual_corked_str = pa_proplist_gets(si->proplist, PROP_POLICY_CORK))) {
+                        pa_atou(is_manual_corked_str, &is_manual_corked);
+                        if (is_manual_corked) {
+                            pa_proplist_sets(si->proplist, PROP_POLICY_CORK, "0");
+                            pa_sink_input_cork(si, FALSE);
+                            pa_log_info("<UnCork> for sink-input[%d]:sink[%s]", si->index, si->sink->name);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+exit:
+    pa_xfree(name);
+    pa_xfree(args);
+    pa_xfree(prop);
+
+    return AUDIO_RET_OK;
+}
+
+static audio_return_t __load_n_open_device_callback (void *platform_data, audio_device_info_t *device_info, audio_device_param_info_t *params, pa_hal_event_type_t hal_event_type)
+{
+    struct userdata *u = (struct userdata *)platform_data;
+    struct pa_hal_event *hal_event;
+    struct pa_hal_device_event_data *event_data;
+
+    pa_assert(u);
+    pa_assert(device_info);
+    pa_assert(device_info->direction == AUDIO_DIRECTION_IN || device_info->direction == AUDIO_DIRECTION_OUT);
+    pa_assert(hal_event_type == PA_HAL_EVENT_LOAD_DEVICE || hal_event_type == PA_HAL_EVENT_OPEN_DEVICE);
+
+    if (u->tid != pthread_self()) {
+        /* called from thread */
+        pa_log_debug("%s is called within thread", __get_event_type_string(hal_event_type));
+
+        hal_event = pa_xmalloc(sizeof(struct pa_hal_event));
+        hal_event->userdata = u;
+        hal_event->event_type = hal_event_type;
+        event_data = pa_xmalloc(sizeof(struct pa_hal_device_event_data));
+        memcpy(&event_data->device_info, device_info, sizeof(audio_device_info_t));
+        memcpy(&event_data->params[0], params, sizeof(audio_device_param_info_t) * AUDIO_DEVICE_PARAM_MAX);
+        hal_event->event_data = (void *)event_data;
+
+        hal_event->mutex = pa_mutex_new(TRUE, TRUE);
+        hal_event->cond = pa_cond_new();
+
+        pa_mutex_lock(hal_event->mutex);
+
+        PA_LLIST_INSERT_AFTER(struct pa_hal_event, u->hal_event_queue, u->hal_event_last, hal_event);
+        u->hal_event_last = hal_event;
+
+        u->core->mainloop->defer_enable(u->defer_event, 1);
+
+        pa_cond_wait(hal_event->cond, hal_event->mutex);
+        pa_mutex_unlock(hal_event->mutex);
+
+        pa_log_info("%s is finished within thread", __get_event_type_string(hal_event_type));
+
+        __free_event(hal_event);
+    } else {
+        /* called from mainloop */
+        pa_log_debug("%s is called within mainloop", __get_event_type_string(hal_event_type));
+        __load_n_open_device(u, device_info, params, hal_event_type);
+        pa_log_info("%s is finished within mainloop", __get_event_type_string(hal_event_type));
+    }
+
+    return AUDIO_RET_OK;
+}
+
+static audio_return_t __load_device_callback (void *platform_data, audio_device_info_t *device_info, audio_device_param_info_t *params)
+{
+    return __load_n_open_device_callback(platform_data, device_info, params, PA_HAL_EVENT_LOAD_DEVICE);
+}
+
+static audio_return_t __open_device_callback (void *platform_data, audio_device_info_t *device_info, audio_device_param_info_t *params)
+{
+    return __load_n_open_device_callback(platform_data, device_info, params, PA_HAL_EVENT_OPEN_DEVICE);
+}
+
+
+static audio_return_t __close_all_devices (struct userdata *u)
+{
+    pa_source *source_null, *source;
+    pa_source_output *so;
+    pa_sink *sink_null, *sink;
+    pa_sink_input *si;
+    uint32_t idx;
+
+    pa_assert(u);
+
+    /* set default sink/src as null */
+    source_null = (pa_source *)pa_namereg_get(u->core, "null", PA_NAMEREG_SOURCE);
+    pa_namereg_set_default_source(u->core, source_null);
+    sink_null = (pa_sink *)pa_namereg_get(u->core, "null", PA_NAMEREG_SINK);
+    pa_namereg_set_default_sink(u->core, sink_null);
+
+    /* close input devices */
+    PA_IDXSET_FOREACH(so, u->core->source_outputs, idx) {
+        if (!so->source)
+            continue;
+        /* Get role (if role is filter, skip it) */
+        if (policy_is_filter(so->proplist))
+            continue;
+        /* Cork only if source-output was Running */
+        if (pa_source_output_get_state(so) == PA_SOURCE_OUTPUT_RUNNING) {
+            pa_proplist_sets(so->proplist, PROP_POLICY_CORK, "1");
+            pa_source_output_cork(so, TRUE);
+            pa_log_info("<Cork> for source-output[%d]:source[%s]", so->index, so->source->name);
+        }
+        if (source_null)
+            pa_source_output_move_to(so, source_null, FALSE);
+    }
+    PA_IDXSET_FOREACH(source, u->core->sources, idx) {
+        pa_source_suspend(source, TRUE, PA_SUSPEND_SWITCH);
+    }
+
+    /* close output devices */
+    PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+        if (!si->sink)
+            continue;
+        /* Get role (if role is filter, skip it) */
+        if (policy_is_filter(si->proplist))
+            continue;
+        /* Cork only if sink-input was Running */
+        if (pa_sink_input_get_state(si) == PA_SINK_INPUT_RUNNING) {
+            pa_proplist_sets(si->proplist, PROP_POLICY_CORK, "1");
+            pa_sink_input_cork(si, TRUE);
+            pa_log_info("<Cork> for sink-input[%d]:sink[%s]", si->index, si->sink->name);
+        }
+        if (sink_null)
+            pa_sink_input_move_to(si, sink_null, FALSE);
+    }
+    PA_IDXSET_FOREACH(sink, u->core->sinks, idx) {
+        pa_sink_suspend(sink, TRUE, PA_SUSPEND_SWITCH);
+    }
+
+    return AUDIO_RET_OK;
+}
+
+static audio_return_t __close_all_devices_callback (void *platform_data)
+{
+    struct userdata *u = (struct userdata *)platform_data;
+    struct pa_hal_event *hal_event;
+
+    pa_assert(u);
+
+    if (u->tid != pthread_self()) {
+        /* called from thread */
+        pa_log_debug("%s is called within thread", __get_event_type_string(PA_HAL_EVENT_CLOSE_ALL_DEVICES));
+
+        hal_event = pa_xmalloc(sizeof(struct pa_hal_event));
+        hal_event->userdata = u;
+        hal_event->event_type = PA_HAL_EVENT_CLOSE_ALL_DEVICES;
+        hal_event->event_data = NULL;
+
+        hal_event->mutex = pa_mutex_new(TRUE, TRUE);
+        hal_event->cond = pa_cond_new();
+
+        pa_mutex_lock(hal_event->mutex);
+
+        PA_LLIST_INSERT_AFTER(struct pa_hal_event, u->hal_event_queue, u->hal_event_last, hal_event);
+        u->hal_event_last = hal_event;
+
+        u->core->mainloop->defer_enable(u->defer_event, 1);
+
+        pa_cond_wait(hal_event->cond, hal_event->mutex);
+        pa_mutex_unlock(hal_event->mutex);
+
+        pa_log_info("%s is finished within thread", __get_event_type_string(PA_HAL_EVENT_CLOSE_ALL_DEVICES));
+
+        __free_event(hal_event);
+    } else {
+        /* called from mainloop */
+        pa_log_debug("%s is called within mainloop", __get_event_type_string(PA_HAL_EVENT_CLOSE_ALL_DEVICES));
+        __close_all_devices(u);
+        pa_log_info("%s is finished within mainloop", __get_event_type_string(PA_HAL_EVENT_CLOSE_ALL_DEVICES));
+    }
+
+    return AUDIO_RET_OK;
+}
+
+static audio_return_t __close_n_unload_device (struct userdata *u, audio_device_info_t *device_info, pa_hal_event_type_t hal_event_type)
+{
+    audio_info_t audio_info;
+    bool is_module_loaded = false;
+    pa_source *source_null, *source;
+    pa_source_output *so;
+    pa_sink *sink_null, *sink;
+    pa_sink_input *si;
+    uint32_t idx;
+
+    pa_assert(u);
+    pa_assert(device_info);
+    pa_assert(device_info->direction == AUDIO_DIRECTION_IN || device_info->direction == AUDIO_DIRECTION_OUT);
+
+     if (device_info->direction == AUDIO_DIRECTION_IN) {
+        PA_IDXSET_FOREACH(source, u->core->sources, idx) {
+            if (!AUDIO_IS_ERROR(__fill_audio_capture_device_info(source->proplist, &audio_info))) {
+                if (__compare_device_info(&audio_info.device, device_info)) {
+                    is_module_loaded = true;
+                    __free_audio_device_info(&audio_info);
+                    break;
+                }
+            }
+            __free_audio_device_info(&audio_info);
+        }
+
+        if (is_module_loaded) {
+            source_null = (pa_source *)pa_namereg_get(u->core, "null", PA_NAMEREG_SOURCE);
+            if (pa_namereg_get_default_source(u->core) == source) {
+                pa_namereg_set_default_source(u->core, source_null);
+            }
+
+            PA_IDXSET_FOREACH(so, u->core->source_outputs, idx) {
+                if (__get_real_master_source(so) != source)
+                    continue;
+                /* Get role (if role is filter, skip it) */
+                if (policy_is_filter(so->proplist))
+                    continue;
+                /* Cork only if source-output was Running */
+                if (pa_source_output_get_state(so) == PA_SOURCE_OUTPUT_RUNNING) {
+                    pa_proplist_sets(so->proplist, PROP_POLICY_CORK, "1");
+                    pa_source_output_cork(so, TRUE);
+                    pa_log_info("<Cork> for source-output[%d]:source[%s]", so->index, so->source->name);
+                }
+                if (source_null)
+                    pa_source_output_move_to(so, source_null, FALSE);
+            }
+            pa_source_suspend(source, TRUE, PA_SUSPEND_SWITCH);
+
+            if (hal_event_type == PA_HAL_EVENT_UNLOAD_DEVICE) {
+                pa_module_unload(u->core, source->module, TRUE);
+            }
+        }
+    } else {
+        PA_IDXSET_FOREACH(sink, u->core->sinks, idx) {
+            if (!AUDIO_IS_ERROR(__fill_audio_playback_device_info(sink->proplist, &audio_info))) {
+                if (__compare_device_info(&audio_info.device, device_info)) {
+                    is_module_loaded = true;
+                    __free_audio_device_info(&audio_info);
+                    break;
+                }
+            }
+            __free_audio_device_info(&audio_info);
+        }
+
+        if (is_module_loaded) {
+            sink_null = (pa_sink *)pa_namereg_get(u->core, "null", PA_NAMEREG_SINK);
+            if (pa_namereg_get_default_sink(u->core) == sink) {
+                pa_namereg_set_default_sink(u->core, sink_null);
+            }
+
+            PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+                if (__get_real_master_sink(si) != sink)
+                    continue;
+                /* Get role (if role is filter, skip it) */
+                if (policy_is_filter(si->proplist))
+                    continue;
+                /* Cork only if sink-input was Running */
+                if (pa_sink_input_get_state(si) == PA_SINK_INPUT_RUNNING) {
+                    pa_proplist_sets(si->proplist, PROP_POLICY_CORK, "1");
+                    pa_sink_input_cork(si, TRUE);
+                    pa_log_info("<Cork> for sink-input[%d]:sink[%s]", si->index, si->sink->name);
+                }
+                if (sink_null)
+                    pa_sink_input_move_to(si, sink_null, FALSE);
+            }
+            pa_sink_suspend(sink, TRUE, PA_SUSPEND_SWITCH);
+
+            if (hal_event_type == PA_HAL_EVENT_UNLOAD_DEVICE) {
+                pa_module_unload(u->core, sink->module, TRUE);
+            }
+        }
+    }
+
+    return AUDIO_RET_OK;
+}
+
+static audio_return_t __close_n_unload_device_callback (void *platform_data, audio_device_info_t *device_info, pa_hal_event_type_t hal_event_type)
+{
+    struct userdata *u = (struct userdata *)platform_data;
+    struct pa_hal_event *hal_event;
+    struct pa_hal_device_event_data *event_data;
+
+    pa_assert(u);
+    pa_assert(device_info);
+    pa_assert(device_info->direction == AUDIO_DIRECTION_IN || device_info->direction == AUDIO_DIRECTION_OUT);
+    pa_assert(hal_event_type == PA_HAL_EVENT_CLOSE_DEVICE || hal_event_type == PA_HAL_EVENT_UNLOAD_DEVICE);
+
+    if (u->tid != pthread_self()) {
+        /* called from thread */
+        pa_log_debug("%s is called within thread", __get_event_type_string(hal_event_type));
+
+        hal_event = pa_xmalloc(sizeof(struct pa_hal_event));
+        hal_event->userdata = u;
+        hal_event->event_type = hal_event_type;
+        event_data = pa_xmalloc(sizeof(struct pa_hal_device_event_data));
+        memcpy(&event_data->device_info, device_info, sizeof(audio_device_info_t));
+        hal_event->event_data = (void *)event_data;
+
+        hal_event->mutex = pa_mutex_new(TRUE, TRUE);
+        hal_event->cond = pa_cond_new();
+
+        pa_mutex_lock(hal_event->mutex);
+
+        PA_LLIST_INSERT_AFTER(struct pa_hal_event, u->hal_event_queue, u->hal_event_last, hal_event);
+        u->hal_event_last = hal_event;
+
+        u->core->mainloop->defer_enable(u->defer_event, 1);
+
+        pa_cond_wait(hal_event->cond, hal_event->mutex);
+        pa_mutex_unlock(hal_event->mutex);
+
+        pa_log_info("%s is finished within thread", __get_event_type_string(hal_event_type));
+
+        __free_event(hal_event);
+    } else {
+        /* called from mainloop */
+        pa_log_debug("%s is called within mainloop", __get_event_type_string(hal_event_type));
+        __close_n_unload_device(u, device_info, hal_event_type);
+        pa_log_info("%s is finished within mainloop", __get_event_type_string(hal_event_type));
+    }
+
+    return AUDIO_RET_OK;
+}
+
+static audio_return_t __close_device_callback (void *platform_data, audio_device_info_t *device_info)
+{
+    return __close_n_unload_device_callback(platform_data, device_info, PA_HAL_EVENT_CLOSE_DEVICE);
+}
+
+static audio_return_t __unload_device_callback (void *platform_data, audio_device_info_t *device_info)
+{
+    return __close_n_unload_device_callback(platform_data, device_info, PA_HAL_EVENT_UNLOAD_DEVICE);
+}
+
+static uint32_t __get_route_flag(struct userdata *u) {
+    uint32_t route_flag = 0;
+
+    if (u->session == AUDIO_SESSION_VOICECALL || u->session == AUDIO_SESSION_VIDEOCALL) {
+        if (u->subsession == AUDIO_SUBSESSION_RINGTONE) {
+            if (__is_mute_policy()) {
+                route_flag |= AUDIO_ROUTE_FLAG_MUTE_POLICY;
+            }
+            else if (!__is_recording()) {
+               route_flag |= AUDIO_ROUTE_FLAG_DUAL_OUT;
+            }
+        } else {
+            if (__is_noise_reduction_on())
+                route_flag |= AUDIO_ROUTE_FLAG_NOISE_REDUCTION;
+            if (__is_extra_volume_on())
+                route_flag |= AUDIO_ROUTE_FLAG_EXTRA_VOL;
+            if (__is_wideband())
+                route_flag |= AUDIO_ROUTE_FLAG_NETWORK_WB;
+        }
+    } else if (u->session == AUDIO_SESSION_NOTIFICATION) {
+        if (__is_mute_policy()) {
+            route_flag |= AUDIO_ROUTE_FLAG_MUTE_POLICY;
+        }
+        else if (!__is_recording()) {
+            route_flag |= AUDIO_ROUTE_FLAG_DUAL_OUT;
+        }
+    } else if(u->session == AUDIO_SESSION_ALARM) {
+        if (!__is_recording()) {
+            route_flag |= AUDIO_ROUTE_FLAG_DUAL_OUT;
+        }
+    }
+    if (u->session == AUDIO_SESSION_VOICE_RECOGNITION) {
+        /* add flag if needed */
+    }
+
+    return route_flag;
+}
+#ifdef BURST_SHOT
+
+#define BURST_SOUND_DEFAULT_TIME_INTERVAL (0.09 * PA_USEC_PER_SEC)
+static void __play_audio_sample_timeout_cb(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata)
+{
+    struct userdata* u = (struct userdata*)userdata;
+    pa_usec_t interval = u->audio_sample_userdata.time_interval;
+    pa_usec_t now = 0ULL;
+
+    pa_assert(m);
+    pa_assert(e);
+    pa_assert(u);
+
+    pa_mutex_lock(u->audio_sample_userdata.mutex);
+
+    /* These checks are added to avoid server crashed on unpredictable situation*/
+    if ((u->audio_sample_userdata.time_event == NULL) ||
+       (u->audio_sample_userdata.i == NULL) ||
+       (u->audio_sample_userdata.q == NULL)) {
+        pa_log_error("Timer should not have fired with this condition time_event=%p i=%p q=%p",
+            u->audio_sample_userdata.time_event, u->audio_sample_userdata.i, u->audio_sample_userdata.q);
+
+        if (u->audio_sample_userdata.time_event != NULL) {
+            pa_core_rttime_restart(u->core, e, PA_USEC_INVALID);
+            u->core->mainloop->time_free(u->audio_sample_userdata.time_event);
+            u->audio_sample_userdata.time_event = NULL;
+        }
+        if (u->audio_sample_userdata.count > 1) {
+            if (u->audio_sample_userdata.i != NULL) {
+                pa_sink_input_set_mute(u->audio_sample_userdata.i, TRUE, TRUE);
+                pa_sink_input_unlink(u->audio_sample_userdata.i);
+            }
+            if (u->audio_sample_userdata.q != NULL) {
+                pa_memblockq_free(u->audio_sample_userdata.q);
+                u->audio_sample_userdata.q = NULL;
+            }
+        }
+        if (u->audio_sample_userdata.i != NULL) {
+            pa_sink_input_unref(u->audio_sample_userdata.i);
+            u->audio_sample_userdata.i = NULL;
+        }
+        u->audio_sample_userdata.is_running = FALSE;
+    } else if (u->audio_sample_userdata.is_running) {
+        // calculate timer boosting
+        pa_log_info("- shot count = %d, memq len = %d ", u->audio_sample_userdata.count,
+                    pa_memblockq_get_length(u->audio_sample_userdata.q));
+        if (u->audio_sample_userdata.factor > 1ULL)
+            interval = u->audio_sample_userdata.time_interval / u->audio_sample_userdata.factor;
+
+        if (u->audio_sample_userdata.count == 0) {
+            // 5. first post data
+            pa_sink_input_put(u->audio_sample_userdata.i);
+        } else {
+            // 5. post data
+            if (pa_memblockq_push(u->audio_sample_userdata.q, &u->audio_sample_userdata.e->memchunk) < 0) {
+                pa_log_error("memory push fail cnt(%d), factor(%llu), interval(%llu)",
+                    u->audio_sample_userdata.count, u->audio_sample_userdata.factor, u->audio_sample_userdata.time_interval);
+                pa_assert(0);
+            }
+        }
+        u->audio_sample_userdata.count++;
+
+        pa_rtclock_now_args(&now);
+        pa_core_rttime_restart(u->core, e, now + interval);
+        if (u->audio_sample_userdata.factor > 1ULL)
+            u->audio_sample_userdata.factor -= 1ULL;
+    } else {
+        pa_core_rttime_restart(u->core, e, PA_USEC_INVALID);
+        u->core->mainloop->time_free(u->audio_sample_userdata.time_event);
+        u->audio_sample_userdata.time_event = NULL;
+
+        /* FIXME: How memblockq is freed when count is 1? */
+        // fading. but should be emitted first shutter sound totally.
+        if (u->audio_sample_userdata.count > 1) {
+            pa_sink_input_set_mute(u->audio_sample_userdata.i, TRUE, TRUE);
+            pa_sink_input_unlink(u->audio_sample_userdata.i);
+
+            pa_memblockq_free(u->audio_sample_userdata.q);
+            u->audio_sample_userdata.q = NULL;
+        }
+        pa_sink_input_unref(u->audio_sample_userdata.i);
+        u->audio_sample_userdata.i = NULL;
+        pa_log_info("sample shot clear!!");
+
+        /* Clear Burst vconf */
+        vconf_set_int (VCONF_SOUND_BURSTSHOT, 0);
+    }
+    pa_mutex_unlock(u->audio_sample_userdata.mutex);
+}
+
+static audio_return_t policy_play_sample_continuously(struct userdata *u, pa_native_connection *c, const char *name, pa_usec_t interval,
+    uint32_t volume_type, uint32_t gain_type, uint32_t volume_level, uint32_t *stream_idx)
+{
+    audio_return_t audio_ret = AUDIO_RET_OK;
+    pa_proplist *p = 0;
+    pa_sink *sink = NULL;
+    audio_info_t audio_info;
+    double volume_linear = 1.0f;
+    pa_client *client = pa_native_connection_get_client(c);
+
+    pa_scache_entry *e;
+    pa_bool_t pass_volume = TRUE;
+    pa_proplist *merged =0;
+    pa_sink_input *i = NULL;
+    pa_memblockq *q = NULL;
+    pa_memchunk silence;
+    pa_cvolume r;
+    pa_usec_t now = 0ULL;
+
+    if (!u->audio_sample_userdata.mutex)
+        u->audio_sample_userdata.mutex = pa_mutex_new(FALSE, FALSE);
+
+    pa_mutex_lock(u->audio_sample_userdata.mutex);
+
+    pa_assert(u->audio_sample_userdata.is_running == FALSE); // allow one instace.
+
+    memset(&audio_info, 0x00, sizeof(audio_info_t));
+
+    p = pa_proplist_new();
+
+    /* Set volume type of stream */
+    pa_proplist_setf(p, PA_PROP_MEDIA_TIZEN_VOLUME_TYPE, "%d", volume_type);
+    /* Set gain type of stream */
+    pa_proplist_setf(p, PA_PROP_MEDIA_TIZEN_GAIN_TYPE, "%d", gain_type);
+    /* Set policy */
+    pa_proplist_setf(p, PA_PROP_MEDIA_POLICY, "%s", volume_type == AUDIO_VOLUME_TYPE_FIXED ? POLICY_PHONE : POLICY_AUTO);
+
+    pa_proplist_update(p, PA_UPDATE_MERGE, client->proplist);
+
+    if (!(sink = pa_namereg_get_default_sink(u->core)))
+        goto exit;
+
+    /* FIXME : Add gain_type parameter to API like volume_type */
+    audio_info.stream.gain_type = gain_type;
+
+    if (AUDIO_IS_ERROR((audio_ret = u->audio_mgr.intf.get_volume_value(u->audio_mgr.data, &audio_info, volume_type, volume_level, &volume_linear)))) {
+        pa_log_warn("get_volume_value returns error:0x%x", audio_ret);
+        goto exit;
+    }
+
+   /*
+    1. load cam-shutter sample
+    2. create memchunk using sample.
+    3. create sink_input(cork mode)
+    4. set timer
+    5. post data(sink-input put or push memblockq)
+    */
+
+    //  1. load cam-shutter sample
+    merged = pa_proplist_new();
+
+    if (!(e = pa_namereg_get(u->core, name, PA_NAMEREG_SAMPLE)))
+        goto exit;
+
+    pa_proplist_sets(merged, PA_PROP_MEDIA_NAME, name);
+    pa_proplist_sets(merged, PA_PROP_EVENT_ID, name);
+    /* Set policy for selecting sink */
+    pa_proplist_sets(merged, PA_PROP_MEDIA_POLICY_IGNORE_PRESET_SINK, "yes");
+
+    if (e->lazy && !e->memchunk.memblock) {
+        pa_channel_map old_channel_map = e->channel_map;
+
+        if (pa_sound_file_load(u->core->mempool, e->filename, &e->sample_spec, &e->channel_map, &e->memchunk, merged) < 0)
+            goto exit;
+
+        pa_subscription_post(u->core, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index);
+
+        if (e->volume_is_set) {
+            if (pa_cvolume_valid(&e->volume))
+                pa_cvolume_remap(&e->volume, &old_channel_map, &e->channel_map);
+            else
+                pa_cvolume_reset(&e->volume, e->sample_spec.channels);
+        }
+    }
+
+    if (!e->memchunk.memblock)
+        goto exit;
+
+    if (e->volume_is_set && PA_VOLUME_IS_VALID(pa_sw_volume_from_linear(volume_linear))) {
+        pa_cvolume_set(&r, e->sample_spec.channels, pa_sw_volume_from_linear(volume_linear));
+        pa_sw_cvolume_multiply(&r, &r, &e->volume);
+    } else if (e->volume_is_set)
+        r = e->volume;
+    else if (PA_VOLUME_IS_VALID(pa_sw_volume_from_linear(volume_linear)))
+        pa_cvolume_set(&r, e->sample_spec.channels, pa_sw_volume_from_linear(volume_linear));
+    else
+        pass_volume = FALSE;
+
+    pa_proplist_update(merged, PA_UPDATE_MERGE, e->proplist);
+    pa_proplist_update(p, PA_UPDATE_MERGE, merged);
+
+    if (e->lazy)
+        time(&e->last_used_time);
+
+    // 2. create memchunk using sample.
+    pa_silence_memchunk_get(&sink->core->silence_cache, sink->core->mempool, &silence, &e->sample_spec, 0);
+    q = pa_memblockq_new("pa_play_memchunk() q", 0, e->memchunk.length * 35, 0, &e->sample_spec, 1, 1, 0, &silence);
+    pa_memblock_unref(silence.memblock);
+
+    pa_assert_se(pa_memblockq_push(q, &e->memchunk) >= 0);
+
+    // 3. create sink_input(cork mode)
+    if (!(i = pa_memblockq_sink_input_new(sink, &e->sample_spec, &e->channel_map, q, pass_volume ? &r : NULL,
+        p, PA_SINK_INPUT_NO_CREATE_ON_SUSPEND|PA_SINK_INPUT_KILL_ON_SUSPEND)))
+        goto exit;
+
+    // 4. set timer
+    u->audio_sample_userdata.e = e;
+    u->audio_sample_userdata.i = i;
+    u->audio_sample_userdata.q = q;
+    u->audio_sample_userdata.time_interval = interval == (pa_usec_t)0 ? BURST_SOUND_DEFAULT_TIME_INTERVAL : interval;
+    u->audio_sample_userdata.is_running = TRUE;
+    u->audio_sample_userdata.factor = 4ULL; // for memory block boosting
+    u->audio_sample_userdata.count = 0;
+
+    pa_rtclock_now_args(&now); // doesn't use arm barrel shiter. SBF
+    pa_log_warn("now(%llu), start interval(%llu)", now, interval / u->audio_sample_userdata.factor);
+    u->audio_sample_userdata.factor -= 1ULL;
+    u->audio_sample_userdata.time_event = pa_core_rttime_new(u->core, now, __play_audio_sample_timeout_cb, u);
+
+exit:
+    if (p)
+        pa_proplist_free(p);
+    if (merged)
+        pa_proplist_free(merged);
+    if (q && (u->audio_sample_userdata.is_running == FALSE))
+        pa_memblockq_free(q);
+
+    pa_mutex_unlock(u->audio_sample_userdata.mutex);
+
+    return audio_ret;
+}
+
+static void  policy_stop_sample_continuously(struct userdata *u)
+{
+    if (u->audio_sample_userdata.time_event) {
+        pa_mutex_lock(u->audio_sample_userdata.mutex);
+        pa_assert(u->audio_sample_userdata.is_running);
+        u->audio_sample_userdata.is_running = FALSE;
+        pa_mutex_unlock(u->audio_sample_userdata.mutex);
+        pa_log_info("timeout_cb called (%d) times", u->audio_sample_userdata.count);
+    }
+}
+
+#endif
+static audio_return_t policy_play_sample(struct userdata *u, pa_native_connection *c, const char *name, uint32_t volume_type, uint32_t gain_type, uint32_t volume_level, uint32_t *stream_idx)
+{
+    audio_return_t audio_ret = AUDIO_RET_OK;
+    pa_proplist *p;
+    pa_sink *sink = NULL;
+    audio_info_t audio_info;
+    double volume_linear = 1.0f;
+    pa_client *client = pa_native_connection_get_client(c);
+    pa_bool_t is_boot_sound;
+    uint32_t sample_idx = 0;
+    char* booting = NULL;
+    const char* file_to_add = NULL;
+    int sample_ret = 0;
+
+    memset(&audio_info, 0x00, sizeof(audio_info_t));
+
+    p = pa_proplist_new();
+
+    /* Set volume type of stream */
+    pa_proplist_setf(p, PA_PROP_MEDIA_TIZEN_VOLUME_TYPE, "%d", volume_type);
+    /* Set gain type of stream */
+    pa_proplist_setf(p, PA_PROP_MEDIA_TIZEN_GAIN_TYPE, "%d", gain_type);
+    /* Set policy */
+    pa_proplist_setf(p, PA_PROP_MEDIA_POLICY, "%s", volume_type == AUDIO_VOLUME_TYPE_FIXED ? POLICY_PHONE : POLICY_AUTO);
+
+    pa_proplist_update(p, PA_UPDATE_MERGE, client->proplist);
+
+    /* Set policy for selecting sink */
+    pa_proplist_sets(p, PA_PROP_MEDIA_POLICY_IGNORE_PRESET_SINK, "yes");
+    sink = pa_namereg_get_default_sink(u->core);
+
+    /* FIXME : Add gain_type parameter to API like volume_type */
+    audio_info.stream.gain_type = gain_type;
+
+    if (AUDIO_IS_ERROR((audio_ret = u->audio_mgr.intf.get_volume_value(u->audio_mgr.data, &audio_info, volume_type, volume_level, &volume_linear)))) {
+        pa_log_warn("get_volume_value returns error:0x%x", audio_ret);
+        goto exit;
+    }
+
+    pa_log_debug("play_sample volume_type:%d gain_type:%d volume_linear:%f", volume_type, gain_type, volume_linear);
+
+    is_boot_sound = pa_streq(name, BOOTING_SOUND_SAMPLE);
+    if (is_boot_sound && pa_namereg_get(u->core, name, PA_NAMEREG_SAMPLE) == NULL) {
+        booting = vconf_get_str(VCONF_BOOTING);
+        file_to_add = (booting)? booting : (char *)DEFAULT_BOOTING_SOUND_PATH;
+        if ((sample_ret = pa_scache_add_file(u->core, name, file_to_add, &sample_idx)) != 0) {
+            pa_log_error("failed to add sample [%s][%s]", name, file_to_add);
+        } else {
+            pa_log_info("success to add sample [%s][%s]", name, file_to_add);
+        }
+        if (booting)
+            free(booting);
+    }
+
+    if (pa_scache_play_item(u->core, name, sink, pa_sw_volume_from_linear(volume_linear), p, stream_idx) < 0) {
+        pa_log_error("pa_scache_play_item fail");
+        audio_ret = AUDIO_ERR_UNDEFINED;
+        goto exit;
+    }
+
+    if (is_boot_sound && sample_ret == 0) {
+        if (pa_scache_remove_item(u->core, name) != 0) {
+            pa_log_error("failed to remove sample [%s]", name);
+        } else {
+            pa_log_info("success to remove sample [%s]", name);
+        }
+    }
+
+exit:
+    pa_proplist_free(p);
+
+    return audio_ret;
+}
+
+static audio_return_t policy_reset(struct userdata *u)
+{
+    audio_return_t audio_ret = AUDIO_RET_OK;
+
+    pa_log_debug("reset");
+
+    __load_dump_config(u);
+
+    if (u->audio_mgr.intf.reset) {
+        if (AUDIO_IS_ERROR((audio_ret = u->audio_mgr.intf.reset(&u->audio_mgr.data)))) {
+            pa_log_error("audio_mgr reset failed");
+            return audio_ret;
+        }
+    }
+
+    return audio_ret;
+}
+
+static audio_return_t policy_set_session(struct userdata *u, uint32_t session, uint32_t start) {
+    uint32_t prev_session = u->session;
+    uint32_t prev_subsession = u->subsession;
+    pa_bool_t need_route = false;
+
+    pa_log_info("set_session:%s %s (current:%s,%s)",
+            __get_session_str(session), (start) ? "start" : "end", __get_session_str(u->session), __get_subsession_str(u->subsession));
+
+    if (start) {
+        u->session = session;
+
+        if ((u->session == AUDIO_SESSION_VOICECALL) || (u->session == AUDIO_SESSION_VIDEOCALL)) {
+            u->subsession = AUDIO_SUBSESSION_MEDIA;
+            u->call_muted = 0;
+        } else if (u->session == AUDIO_SESSION_VOIP) {
+            u->subsession = AUDIO_SUBSESSION_VOICE;
+        } else if (u->session == AUDIO_SESSION_VOICE_RECOGNITION) {
+            u->subsession = AUDIO_SUBSESSION_INIT;
+        } else {
+            u->subsession = AUDIO_SUBSESSION_NONE;
+        }
+        if (u->audio_mgr.intf.set_session) {
+            u->audio_mgr.intf.set_session(u->audio_mgr.data, session, u->subsession, AUDIO_SESSION_CMD_START);
+        }
+    } else {
+        if (u->audio_mgr.intf.set_session) {
+            u->audio_mgr.intf.set_session(u->audio_mgr.data, session, u->subsession, AUDIO_SESSION_CMD_END);
+        }
+        u->session = AUDIO_SESSION_MEDIA;
+        u->subsession = AUDIO_SUBSESSION_NONE;
+    }
+    if (prev_session != session) {
+        if ((session == AUDIO_SESSION_ALARM) || (session == AUDIO_SESSION_NOTIFICATION)) {
+            pa_log_info("switch route to dual output due to new session");
+            need_route = true;
+        } else if ((prev_session == AUDIO_SESSION_ALARM) || (prev_session == AUDIO_SESSION_NOTIFICATION)
+            || (((prev_session == AUDIO_SESSION_VOICECALL) || (prev_session == AUDIO_SESSION_VIDEOCALL)) && (prev_subsession == AUDIO_SUBSESSION_RINGTONE))) {
+            pa_log_info("switch route from dual output due to previous session");
+            need_route = true;
+        }
+    }
+
+
+    if (need_route) {
+        uint32_t route_flag = __get_route_flag(u);
+
+        if (u->audio_mgr.intf.set_route) {
+            u->audio_mgr.intf.set_route(u->audio_mgr.data, u->session, u->subsession, u->active_device_in, u->active_device_out, route_flag);
+        }
+        u->active_route_flag = route_flag;
+    } else {
+        /* route should be updated */
+        u->active_route_flag = (uint32_t)-1;
+    }
+
+    return AUDIO_RET_OK;
+}
+
+static audio_return_t policy_set_subsession(struct userdata *u, uint32_t subsession, uint32_t subsession_opt) {
+    uint32_t prev_subsession = u->subsession;
+    pa_bool_t need_route = false;
+
+    pa_log_info("set_subsession:%s->%s opt:%x->%x (session:%s)",
+            __get_subsession_str(u->subsession), __get_subsession_str(subsession), u->subsession_opt, subsession_opt,
+            __get_session_str(u->session));
+
+    if (u->subsession == subsession && u->subsession_opt == subsession_opt) {
+        pa_log_debug("duplicated request is ignored subsession(%d) opt(0x%x)", subsession, subsession_opt);
+        return AUDIO_RET_OK;
+    }
+
+    u->subsession = subsession;
+#ifndef _TIZEN_PUBLIC_
+    if (u->subsession == AUDIO_SUBSESSION_VR_NORMAL || u->subsession == AUDIO_SUBSESSION_VR_DRIVE)
+        u->subsession_opt = subsession_opt;
+    else
+        u->subsession_opt = 0;
+#else
+    u->subsession_opt = subsession_opt;
+#endif
+
+    if (u->audio_mgr.intf.set_session) {
+        u->audio_mgr.intf.set_session(u->audio_mgr.data, u->session, u->subsession, AUDIO_SESSION_CMD_SUBSESSION);
+    }
+
+    if (prev_subsession!= subsession) {
+        if ((u->session == AUDIO_SESSION_VOICECALL) || (u->session == AUDIO_SESSION_VIDEOCALL)) {
+            if (subsession == AUDIO_SUBSESSION_RINGTONE) {
+                pa_log_info("switch route to dual output due to new subsession");
+                need_route = true;
+            } else if (prev_subsession == AUDIO_SUBSESSION_RINGTONE) {
+                pa_log_info("switch route from dual output due to previous subsession");
+                need_route = true;
+            }
+        }
+    }
+
+    if (need_route) {
+        uint32_t route_flag = __get_route_flag(u);
+
+        if (u->audio_mgr.intf.set_route) {
+            u->audio_mgr.intf.set_route(u->audio_mgr.data, u->session, u->subsession, u->active_device_in, u->active_device_out, route_flag);
+        }
+        u->active_route_flag = route_flag;
+    } else {
+        /* route should be updated */
+        u->active_route_flag = (uint32_t)-1;
+    }
+    return AUDIO_RET_OK;
+
+}
+
+static audio_return_t policy_set_active_device(struct userdata *u, uint32_t device_in, uint32_t device_out, uint32_t* need_update) {
+    pa_sink_input *si = NULL;
+    uint32_t idx;
+    uint32_t route_flag = 0;
+
+#ifndef TIZEN_MICRO
+    *need_update = TRUE;
+#endif
+    route_flag = __get_route_flag(u);
+
+    pa_log_info("set_active_device session:%s,%s in:%s->%s out:%s->%s flag:%x->%x muteall:%d call_muted:%d",
+            __get_session_str(u->session), __get_subsession_str(u->subsession),
+            __get_device_in_str(u->active_device_in), __get_device_in_str(device_in),
+            __get_device_out_str(u->active_device_out), __get_device_out_str(device_out),
+            u->active_route_flag, route_flag, u->muteall, u->call_muted);
+
+    /* Skip duplicated request */
+    if ((device_in == AUDIO_DEVICE_IN_NONE || u->active_device_in == device_in) &&
+        (device_out == AUDIO_DEVICE_OUT_NONE || u->active_device_out == device_out) &&
+        u->active_route_flag == route_flag) {
+#ifdef TIZEN_MICRO
+        pa_log_debug("duplicated request is ignored device_in(%d) device_out(%d) flag(0x%x)", device_in, device_out, route_flag);
+#else
+        pa_log_debug("duplicated request is ignored device_in(%d) device_out(%d) flag(0x%x) need_update(%d)", device_in, device_out, route_flag, *need_update);
+#endif
+        return AUDIO_RET_OK;
+    }
+
+#ifdef TIZEN_MICRO
+    if (u->audio_mgr.intf.set_route) {
+        u->audio_mgr.intf.set_route(u->audio_mgr.data, u->session, u->subsession, device_in, device_out, route_flag);
+    }
+#else
+
+    /* skip volume changed callback */
+    if(u->active_device_out == device_out) {
+        *need_update = FALSE;
+    }
+    if (u->audio_mgr.intf.set_route) {
+        audio_return_t audio_ret = AUDIO_RET_OK;
+        const char *device_switching_str;
+        uint32_t device_switching = 0;
+#ifdef PA_SLEEP_DURING_UCM
+        uint32_t need_sleep_for_ucm = 0;
+#endif
+
+        /* Mute sink inputs which are unmuted */
+        PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+            if ((device_switching_str = pa_proplist_gets(si->proplist, "module-policy.device_switching"))) {
+                pa_atou(device_switching_str, &device_switching);
+                if (device_switching) {
+                    if (AUDIO_IS_ERROR((audio_ret = policy_set_mute(u, si->index, (uint32_t)-1, AUDIO_DIRECTION_OUT, 1)))) {
+                        pa_log_warn("policy_set_mute(1) for stream[%d] returns error:0x%x", si->index, audio_ret);
+                    }
+#ifdef PA_SLEEP_DURING_UCM
+                    need_sleep_for_ucm = 1;
+#endif
+                }
+            }
+        }
+
+#ifdef PA_SLEEP_DURING_UCM
+        /* FIXME : sleep for ucm. Will enable if needed */
+        if (need_sleep_for_ucm) {
+            usleep(150000);
+        }
+#endif
+
+        u->audio_mgr.intf.set_route(u->audio_mgr.data, u->session, u->subsession, device_in, device_out, route_flag);
+        /* Unmute sink inputs which are muted due to device switching */
+        PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+            if ((device_switching_str = pa_proplist_gets(si->proplist, "module-policy.device_switching"))) {
+                pa_atou(device_switching_str, &device_switching);
+                if (device_switching) {
+                    pa_proplist_sets(si->proplist, "module-policy.device_switching", "0");
+                    if (AUDIO_IS_ERROR((audio_ret = __update_volume(u, si->index, (uint32_t)-1, (uint32_t)-1)))) {
+                        pa_log_warn("__update_volume for stream[%d] returns error:0x%x", si->index, audio_ret);
+                    }
+                    if (AUDIO_IS_ERROR((audio_ret = policy_set_mute(u, si->index, (uint32_t)-1, AUDIO_DIRECTION_OUT, 0)))) {
+                        pa_log_warn("policy_set_mute(0) for stream[%d] returns error:0x%x", si->index, audio_ret);
+                    }
+                }
+            }
+        }
+    }
+#endif
+
+    /* sleep for avoiding sound leak during UCM switching
+       this is just a workaround, we should synchronize in future */
+    if (device_out != AUDIO_DEVICE_OUT_NONE && u->active_device_out != device_out &&
+        u->session != AUDIO_SESSION_VOICECALL && u->session != AUDIO_SESSION_VIDEOCALL) {
+        /* Mute sink inputs which are unmuted */
+        PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+            if (!pa_sink_input_get_mute(si)) {
+                pa_proplist_sets(si->proplist, "module-policy.device_switching", "1");
+            }
+        }
+    }
+
+    /* Update active devices */
+    if (device_in != AUDIO_DEVICE_IN_NONE)
+        u->active_device_in = device_in;
+    if (device_out != AUDIO_DEVICE_OUT_NONE)
+        u->active_device_out = device_out;
+    u->active_route_flag = route_flag;
+
+    if (u->session == AUDIO_SESSION_VOICECALL) {
+        if (u->muteall) {
+            policy_set_mute(u, (-1), AUDIO_VOLUME_TYPE_CALL, AUDIO_DIRECTION_OUT, 1);
+        }
+        /* workaround for keeping call mute setting */
+        policy_set_mute(u, (-1), AUDIO_VOLUME_TYPE_CALL, AUDIO_DIRECTION_IN, u->call_muted);
+    }
+
+    return AUDIO_RET_OK;
+}
+
+static audio_return_t policy_get_volume_level_max(struct userdata *u, uint32_t volume_type, uint32_t *volume_level) {
+    audio_return_t audio_ret = AUDIO_RET_OK;
+
+    /* Call HAL function if exists */
+    if (u->audio_mgr.intf.get_volume_level_max) {
+        if (AUDIO_IS_ERROR((audio_ret = u->audio_mgr.intf.get_volume_level_max(u->audio_mgr.data, volume_type, volume_level)))) {
+            pa_log_error("get_volume_level_max returns error:0x%x", audio_ret);
+            return audio_ret;
+        }
+    }
+    pa_log_info("get volume level max type:%d level:%d", volume_type, *volume_level);
+    return AUDIO_RET_OK;
+}
+
+static audio_return_t __update_volume(struct userdata *u, uint32_t stream_idx, uint32_t volume_type, uint32_t volume_level)
+{
+    audio_return_t audio_ret = AUDIO_RET_OK;
+    pa_sink_input *si = NULL;
+    uint32_t idx;
+    audio_info_t audio_info;
+
+    pa_log_info_verbose("stream[%d], volume_type(%d), volume_level(%d)", stream_idx, volume_type, volume_level);
+
+    /* Update volume as current level if volume_level has -1 */
+    if (volume_level == (uint32_t)-1 && stream_idx != (uint32_t)-1) {
+        /* Skip updating if stream doesn't have volume type */
+        if (policy_get_volume_level(u, stream_idx, &volume_type, &volume_level) == AUDIO_ERR_UNDEFINED) {
+            return AUDIO_RET_OK;
+        }
+    }
+
+    if (u->muteall && (volume_type != AUDIO_VOLUME_TYPE_FIXED)) {
+        pa_log_debug("set_mute is called from __update_volume by muteall stream_idx:%d type:%d", stream_idx, volume_type);
+
+        if (policy_set_mute(u, stream_idx, volume_type, AUDIO_DIRECTION_OUT, 1) == AUDIO_RET_USE_HW_CONTROL) {
+            return AUDIO_RET_USE_HW_CONTROL;
+        }
+    }
+
+    /* Call HAL function if exists */
+    if (u->audio_mgr.intf.set_volume_level && (stream_idx == PA_INVALID_INDEX)) {
+        if (AUDIO_IS_ERROR((audio_ret = u->audio_mgr.intf.set_volume_level(u->audio_mgr.data, NULL, volume_type, volume_level)))) {
+            pa_log_error("set_volume_level returns error:0x%x", audio_ret);
+            return audio_ret;
+        }
+    }
+
+    PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+
+        if (AUDIO_IS_ERROR(__fill_audio_playback_info(si, &audio_info))) {
+            /* skip mono sink-input */
+            continue;
+        }
+
+        /* Update volume of stream if it has requested volume type */
+        if ((stream_idx == idx) || ((stream_idx == PA_INVALID_INDEX) && (audio_info.stream.volume_type == volume_type))) {
+            double volume_linear = 1.0f;
+            pa_cvolume cv;
+
+            /* Call HAL function if exists */
+            if (u->audio_mgr.intf.set_volume_level) {
+                if (AUDIO_IS_ERROR((audio_ret = u->audio_mgr.intf.set_volume_level(u->audio_mgr.data, &audio_info, audio_info.stream.volume_type, volume_level)))) {
+                    pa_log_error("set_volume_level for sink-input[%d] returns error:0x%x", idx, audio_ret);
+                    __free_audio_info(&audio_info);
+                    return audio_ret;
+                }
+            }
+
+            /* Get volume value by type & level */
+            if (u->audio_mgr.intf.get_volume_value && (audio_ret != AUDIO_RET_USE_HW_CONTROL)) {
+                if (AUDIO_IS_ERROR((audio_ret = u->audio_mgr.intf.get_volume_value(u->audio_mgr.data, &audio_info, audio_info.stream.volume_type, volume_level, &volume_linear)))) {
+                    pa_log_warn("get_volume_value for sink-input[%d] returns error:0x%x", idx, audio_ret);
+                    __free_audio_info(&audio_info);
+                    return audio_ret;
+                }
+            }
+            pa_cvolume_set(&cv, si->sample_spec.channels, pa_sw_volume_from_linear(volume_linear));
+
+            pa_sink_input_set_volume(si, &cv, TRUE, TRUE);
+            if (idx == stream_idx) {
+                __free_audio_info(&audio_info);
+                break;
+            }
+        }
+        __free_audio_info(&audio_info);
+    }
+
+    return audio_ret;
+}
+
+static audio_return_t __update_volume_by_value(struct userdata *u, uint32_t stream_idx, uint32_t volume_type, double* value)
+{
+    audio_return_t audio_ret = AUDIO_RET_OK;
+    pa_sink_input *si = NULL;
+    uint32_t idx;
+    audio_info_t audio_info;
+
+    double volume = *value;
+    double gain = 1.0f;
+
+    PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+
+        if (AUDIO_IS_ERROR(__fill_audio_playback_info(si, &audio_info))) {
+            /* skip mono sink-input */
+            continue;
+        }
+
+        /* Update volume of stream if it has requested volume type */
+        if ((stream_idx == idx) || ((stream_idx == PA_INVALID_INDEX) && (audio_info.stream.volume_type == volume_type))) {
+            double volume_linear = 1.0f;
+            pa_cvolume cv;
+
+            // 1. get gain first
+            if (u->audio_mgr.intf.get_gain_value) {
+                if (AUDIO_IS_ERROR((audio_ret = u->audio_mgr.intf.get_gain_value(u->audio_mgr.data, &audio_info, audio_info.stream.volume_type, &gain)))) {
+                    pa_log_warn("get_gain_value for sink-input[%d] volume_type(%d), returns error:0x%x", idx, audio_info.stream.volume_type, audio_ret);
+                    __free_audio_info(&audio_info);
+                    return audio_ret;
+                }
+            }
+
+            // 2. mul gain value
+            volume *= gain;
+
+            /* 3. adjust hw volume(LPA), Call HAL function if exists */
+            if (u->audio_mgr.intf.set_volume_value) {
+                if (AUDIO_IS_ERROR((audio_ret = u->audio_mgr.intf.set_volume_value(u->audio_mgr.data, &audio_info, audio_info.stream.volume_type, &volume)))) {
+                    pa_log_error("set_volume_level for sink-input[%d] returns error:0x%x", idx, audio_ret);
+                    __free_audio_info(&audio_info);
+                    return audio_ret;
+                }
+            }
+
+            // 4. adjust sw volume.
+            if(audio_ret != AUDIO_RET_USE_HW_CONTROL)
+                pa_cvolume_set(&cv, si->sample_spec.channels, pa_sw_volume_from_linear(volume));
+            else
+                pa_cvolume_set(&cv, si->sample_spec.channels, pa_sw_volume_from_linear(volume_linear));
+
+            pa_sink_input_set_volume(si, &cv, TRUE, TRUE);
+
+            if (idx == stream_idx) {
+                __free_audio_info(&audio_info);
+                break;
+            }
+        }
+        __free_audio_info(&audio_info);
+    }
+
+    return audio_ret;
+}
+
+#ifdef PRIMARY_VOLUME
+static int __set_primary_volume(struct userdata *u, void* key, int volumetype, int is_new)
+{
+    const int NO_INSTANCE = -1;
+    const int CAPURE_ONLY = -2; // check mm_sound.c
+
+    int ret = -1;
+    int default_primary_vol = NO_INSTANCE;
+    int default_primary_vol_prio = NO_INSTANCE;
+
+    struct pa_primary_volume_type_info* p_volume = NULL;
+    struct pa_primary_volume_type_info* n_p_volume = NULL;
+    struct pa_primary_volume_type_info* new_volume = NULL;
+
+    // descending order
+    int priority[] = {
+        AUDIO_PRIMARY_VOLUME_TYPE_SYSTEM,
+        AUDIO_PRIMARY_VOLUME_TYPE_NOTIFICATION,
+        AUDIO_PRIMARY_VOLUME_TYPE_ALARM,
+        AUDIO_PRIMARY_VOLUME_TYPE_RINGTONE,
+        AUDIO_PRIMARY_VOLUME_TYPE_MEDIA,
+        AUDIO_PRIMARY_VOLUME_TYPE_VOICE,
+        AUDIO_PRIMARY_VOLUME_TYPE_CALL,
+        AUDIO_PRIMARY_VOLUME_TYPE_VOIP,
+        AUDIO_PRIMARY_VOLUME_TYPE_FIXED,
+        AUDIO_PRIMARY_VOLUME_TYPE_MAX // for capture handle
+    };
+
+    if(is_new) {
+        new_volume = pa_xnew0(struct pa_primary_volume_type_info, 1);
+        new_volume->key = key;
+        new_volume->volumetype = volumetype;
+        new_volume->priority = priority[volumetype];
+
+        // no items.
+        if(u->primary_volume == NULL) {
+            PA_LLIST_PREPEND(struct pa_primary_volume_type_info, u->primary_volume, new_volume);
+        } else {
+            // already added
+            PA_LLIST_FOREACH_SAFE(p_volume, n_p_volume, u->primary_volume) {
+                if(p_volume->key == key) {
+                    ret = 0;
+                    pa_xfree(new_volume);
+                    goto exit;
+                }
+            }
+
+            // add item.
+            PA_LLIST_FOREACH_SAFE(p_volume, n_p_volume, u->primary_volume) {
+                if(p_volume->priority <= priority[volumetype]) {
+                    PA_LLIST_INSERT_AFTER(struct pa_primary_volume_type_info, u->primary_volume, p_volume, new_volume);
+                    break;
+                } else if(p_volume->priority > priority[volumetype]) {
+                    PA_LLIST_PREPEND(struct pa_primary_volume_type_info, u->primary_volume, new_volume);
+                    break;
+                }
+            }
+        }
+        pa_log_info("add volume data to primary volume list. volumetype(%d), priority(%d)", new_volume->volumetype, new_volume->priority);
+    } else { // remove(unlink)
+        PA_LLIST_FOREACH_SAFE(p_volume, n_p_volume, u->primary_volume) {
+            if(p_volume->key == key) {
+                PA_LLIST_REMOVE(struct pa_primary_volume_type_info, u->primary_volume, p_volume);
+                pa_log_info("remove volume data from primary volume list. volumetype(%d), priority(%d)", p_volume->volumetype, p_volume->priority);
+                pa_xfree(p_volume);
+                break;
+            }
+        }
+    }
+
+    if(u->primary_volume) {
+        if(u->primary_volume->volumetype == AUDIO_PRIMARY_VOLUME_TYPE_MAX) {
+            default_primary_vol = CAPURE_ONLY;
+            default_primary_vol_prio = CAPURE_ONLY;
+        } else {
+            default_primary_vol = u->primary_volume->volumetype;
+            default_primary_vol_prio = u->primary_volume->priority;
+        }
+    }
+    pa_log_info("current primary volumetype(%d), priority(%d)", default_primary_vol, default_primary_vol_prio);
+
+    if(vconf_set_int(VCONFKEY_SOUND_PRIMARY_VOLUME_TYPE, default_primary_vol) < 0) {
+        ret = -1;
+        pa_log_info("VCONFKEY_SOUND_PRIMARY_VOLUME_TYPE set failed default_primary_vol(%d)", default_primary_vol);
+    }
+
+exit:
+
+    return ret;
+}
+#endif
+
+
+static audio_return_t policy_get_volume_level(struct userdata *u, uint32_t stream_idx, uint32_t *volume_type, uint32_t *volume_level) {
+    pa_sink_input *si = NULL;
+    const char *si_volume_type_str;
+
+    if (*volume_type == (uint32_t)-1 && stream_idx != (uint32_t)-1) {
+        if ((si = pa_idxset_get_by_index(u->core->sink_inputs, stream_idx))) {
+            if ((si_volume_type_str = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) {
+                pa_atou(si_volume_type_str, volume_type);
+            } else {
+                pa_log_debug_verbose("stream[%d] doesn't have volume type", stream_idx);
+                return AUDIO_ERR_UNDEFINED;
+            }
+        } else {
+            pa_log_warn("stream[%d] doesn't exist", stream_idx);
+            return AUDIO_ERR_PARAMETER;
+        }
+    }
+
+    if (*volume_type >= AUDIO_VOLUME_TYPE_MAX) {
+        pa_log_warn("volume_type (%d) invalid", *volume_type);
+        return AUDIO_ERR_PARAMETER;
+    }
+    if (u->audio_mgr.intf.get_volume_level) {
+        u->audio_mgr.intf.get_volume_level(u->audio_mgr.data, *volume_type, volume_level);
+    }
+
+    pa_log_info("get_volume_level stream_idx:%d type:%d level:%d", stream_idx, *volume_type, *volume_level);
+    return AUDIO_RET_OK;
+}
+
+static audio_return_t policy_get_volume_value(struct userdata *u, uint32_t stream_idx, uint32_t *volume_type, uint32_t *volume_level, double* volume_linear) {
+    audio_return_t audio_ret = AUDIO_RET_OK;
+    audio_info_t audio_info;
+    pa_sink_input *si = NULL;
+
+    *volume_linear = 1.0f;
+
+    si = pa_idxset_get_by_index(u->core->sink_inputs, stream_idx);
+    if (si != NULL) {
+        if (AUDIO_IS_ERROR(__fill_audio_playback_info(si, &audio_info))) {
+            pa_log_debug("fill info failed. stream_idx[%d]", stream_idx);
+            return AUDIO_ERR_UNDEFINED;
+        }
+
+        if(u->audio_mgr.intf.get_volume_value) {
+            if (AUDIO_IS_ERROR((audio_ret = u->audio_mgr.intf.get_volume_value(u->audio_mgr.data, &audio_info, audio_info.stream.volume_type, *volume_level, volume_linear)))) {
+                pa_log_warn("get_volume_value for stream_idx[%d] returns error:0x%x", stream_idx, audio_ret);
+                return audio_ret;
+            }
+        }
+        __free_audio_info(&audio_info);
+   }
+    return audio_ret;
+}
+
+static audio_return_t policy_set_volume_level(struct userdata *u, uint32_t stream_idx, uint32_t volume_type, uint32_t volume_level) {
+
+    pa_log_info("set_volume_level stream_idx:%d type:%d level:%d", stream_idx, volume_type, volume_level);
+
+    /* Store volume level of type */
+    if (volume_type != (uint32_t)-1) {
+        if (u->audio_mgr.intf.set_volume_level) {
+            u->audio_mgr.intf.set_volume_level(u->audio_mgr.data, NULL, volume_type, volume_level);
+        }
+    }
+
+    return __update_volume(u, stream_idx, volume_type, volume_level);
+}
+
+static audio_return_t policy_set_volume_value(struct userdata *u, uint32_t stream_idx, uint32_t volume_type, double* value) {
+
+    pa_log_info("set_volume_value stream_idx:%d type:%d value:%f", stream_idx, volume_type, *value);
+
+    return __update_volume_by_value(u, stream_idx, volume_type, value);
+}
+
+static audio_return_t policy_update_volume(struct userdata *u) {
+    uint32_t volume_type;
+    uint32_t volume_level = 0;
+
+    pa_log_info("update_volume");
+
+    for (volume_type = 0; volume_type < AUDIO_VOLUME_TYPE_MAX; volume_type++) {
+        if (u->audio_mgr.intf.get_volume_level) {
+            u->audio_mgr.intf.get_volume_level(u->audio_mgr.data, volume_type, &volume_level);
+        }
+        __update_volume(u, (uint32_t)-1, volume_type, volume_level);
+#ifdef WEARABLE_FIX // commit : update call mute status after changing audio pathupdate call mute status after changing audio path
+        /* workaround for updating call mute after setting call path */
+        if (u->session == AUDIO_SESSION_VOICECALL) {
+            uint32_t call_muted = 0;
+
+            if (u->audio_mgr.intf.get_mute) {
+                u->audio_mgr.intf.get_mute(u->audio_mgr.data, NULL, AUDIO_VOLUME_TYPE_CALL, AUDIO_DIRECTION_IN, &call_muted);
+                if (u->call_muted != (int)call_muted && u->audio_mgr.intf.set_mute) {
+                    u->audio_mgr.intf.set_mute(u->audio_mgr.data, NULL, AUDIO_VOLUME_TYPE_CALL, AUDIO_DIRECTION_IN, u->call_muted);
+                }
+            }
+        }
+#endif
+    }
+
+    return AUDIO_RET_OK;
+}
+
+static audio_return_t policy_get_mute(struct userdata *u, uint32_t stream_idx, uint32_t volume_type, uint32_t direction, uint32_t *mute) {
+    audio_return_t audio_ret = AUDIO_RET_OK;
+    pa_sink_input *si = NULL;
+    uint32_t idx;
+    audio_info_t audio_info;
+
+    if (u->audio_mgr.intf.get_mute && (stream_idx == PA_INVALID_INDEX)) {
+        audio_ret = u->audio_mgr.intf.get_mute(u->audio_mgr.data, NULL, volume_type, direction, mute);
+        if (audio_ret == AUDIO_RET_USE_HW_CONTROL) {
+            return audio_ret;
+        } else {
+            pa_log_error("get_mute returns error:0x%x", audio_ret);
+            return audio_ret;
+        }
+    }
+
+    if (direction == AUDIO_DIRECTION_OUT) {
+        PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+            if (AUDIO_IS_ERROR(__fill_audio_playback_info(si, &audio_info))) {
+                /* skip mono sink-input */
+                continue;
+            }
+
+            /* Update mute of stream if it has requested stream or volume type */
+            if ((stream_idx == idx) || ((stream_idx == PA_INVALID_INDEX) && (audio_info.stream.volume_type == volume_type))) {
+
+                /* Call HAL function if exists */
+                if (u->audio_mgr.intf.get_mute) {
+                    audio_ret = u->audio_mgr.intf.get_mute(u->audio_mgr.data, &audio_info, audio_info.stream.volume_type, direction, mute);
+                    if (audio_ret == AUDIO_RET_USE_HW_CONTROL) {
+                        return audio_ret;
+                    } else if (AUDIO_IS_ERROR(audio_ret)) {
+                        pa_log_error("get_mute for sink-input[%d] returns error:0x%x", idx, audio_ret);
+                        return audio_ret;
+                    }
+                }
+
+                *mute = (uint32_t)pa_sink_input_get_mute(si);
+                break;
+            }
+            __free_audio_info(&audio_info);
+        }
+    }
+
+    pa_log_info("get mute stream_idx:%d type:%d direction:%d mute:%d", stream_idx, volume_type, direction, *mute);
+    return audio_ret;
+}
+
+static audio_return_t policy_set_mute(struct userdata *u, uint32_t stream_idx, uint32_t volume_type, uint32_t direction, uint32_t mute) {
+    audio_return_t audio_ret = AUDIO_RET_OK;
+    pa_sink_input *si = NULL;
+    uint32_t idx;
+    audio_info_t audio_info;
+    const char *si_volume_type_str;
+
+    pa_log_info("set_mute stream_idx:%d type:%d direction:%d mute:%d", stream_idx, volume_type, direction, mute);
+
+    if (volume_type == (uint32_t)-1 && stream_idx != (uint32_t)-1) {
+        if ((si = pa_idxset_get_by_index(u->core->sink_inputs, stream_idx))) {
+            if ((si_volume_type_str = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) {
+                pa_atou(si_volume_type_str, &volume_type);
+            } else {
+                pa_log_debug_verbose("stream[%d] doesn't have volume type", stream_idx);
+                return AUDIO_ERR_UNDEFINED;
+            }
+        } else {
+            pa_log_warn("stream[%d] doesn't exist", stream_idx);
+            return AUDIO_ERR_PARAMETER;
+        }
+    }
+
+    /* workaround for keeping call mute setting */
+    if ((volume_type == AUDIO_VOLUME_TYPE_CALL) && (direction == AUDIO_DIRECTION_IN)) {
+        u->call_muted = mute;
+    }
+
+    if (u->muteall && !mute && (direction == AUDIO_DIRECTION_OUT) && (volume_type != AUDIO_VOLUME_TYPE_FIXED)) {
+        pa_log_info("set_mute is ignored by muteall");
+        return audio_ret;
+    }
+
+    /* Call HAL function if exists */
+    if (u->audio_mgr.intf.set_mute && (stream_idx == PA_INVALID_INDEX)) {
+        audio_ret = u->audio_mgr.intf.set_mute(u->audio_mgr.data, NULL, volume_type, direction, mute);
+        if (audio_ret == AUDIO_RET_USE_HW_CONTROL) {
+            pa_log_info("set_mute(call) returns error:0x%x mute:%d", audio_ret, mute);
+            return audio_ret;
+        } else if (AUDIO_IS_ERROR(audio_ret)) {
+            pa_log_error("set_mute returns error:0x%x", audio_ret);
+            return audio_ret;
+        }
+    }
+
+    if (direction == AUDIO_DIRECTION_OUT) {
+        PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+            if (AUDIO_IS_ERROR(__fill_audio_playback_info(si, &audio_info))) {
+                /* skip mono sink-input */
+                continue;
+            }
+
+            /* Update mute of stream if it has requested stream or volume type */
+            if ((stream_idx == idx) || ((stream_idx == PA_INVALID_INDEX) && (audio_info.stream.volume_type == volume_type))) {
+
+                /* Call HAL function if exists */
+                if (u->audio_mgr.intf.set_mute) {
+                    audio_ret = u->audio_mgr.intf.set_mute(u->audio_mgr.data, &audio_info, audio_info.stream.volume_type, direction, mute);
+                    if (AUDIO_IS_ERROR(audio_ret)) {
+                        pa_log_error("set_mute for sink-input[%d] returns error:0x%x", idx, audio_ret);
+                        return audio_ret;
+                    }
+                }
+
+                pa_sink_input_set_mute(si, (pa_bool_t)mute, TRUE);
+                if (idx == stream_idx)
+                    break;
+            }
+            __free_audio_info(&audio_info);
+        }
+    }
+
+    return audio_ret;
+}
+
+static pa_bool_t policy_is_available_high_latency(struct userdata *u)
+{
+    pa_sink_input *si = NULL;
+    uint32_t idx;
+    const char *si_policy_str;
+
+    PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+        if ((si_policy_str = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_POLICY))) {
+            if (pa_streq(si_policy_str, POLICY_HIGH_LATENCY) && sink_is_highlatency(si->sink)) {
+                pa_log_info("high latency is exists");
+                return FALSE;
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+#define EXT_VERSION 1
+
+static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
+    struct userdata *u = NULL;
+    uint32_t command;
+    pa_tagstruct *reply = NULL;
+
+    pa_sink_input *si = NULL;
+    pa_sink *s = NULL;
+    uint32_t idx;
+
+    pa_assert(p);
+    pa_assert(m);
+    pa_assert(c);
+    pa_assert(t);
+
+    u = m->userdata;
+
+    if (pa_tagstruct_getu32(t, &command) < 0)
+        goto fail;
+
+    reply = pa_tagstruct_new(NULL, 0);
+    pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
+    pa_tagstruct_putu32(reply, tag);
+
+    switch (command) {
+        case SUBCOMMAND_TEST: {
+            if (!pa_tagstruct_eof(t))
+                goto fail;
+
+            pa_tagstruct_putu32(reply, EXT_VERSION);
+            break;
+        }
+
+        case SUBCOMMAND_PLAY_SAMPLE: {
+            const char *name;
+            uint32_t volume_type = 0;
+            uint32_t gain_type = 0;
+            uint32_t volume_level = 0;
+            uint32_t stream_idx = PA_INVALID_INDEX;
+
+            if (pa_tagstruct_gets(t, &name) < 0 ||
+                pa_tagstruct_getu32(t, &volume_type) < 0 ||
+                pa_tagstruct_getu32(t, &gain_type) < 0 ||
+                pa_tagstruct_getu32(t, &volume_level) < 0 ||
+                !pa_tagstruct_eof(t)) {
+                pa_log_error("protocol error");
+                goto fail;
+            }
+
+            policy_play_sample(u, c, name, volume_type, gain_type, volume_level, &stream_idx);
+
+            pa_tagstruct_putu32(reply, stream_idx);
+            break;
+        }
+#ifdef BURST_SHOT
+
+        case SUBCOMMAND_PLAY_SAMPLE_CONTINUOUSLY: {
+            const char *name;
+            pa_bool_t start;
+            uint32_t volume_type = 0;
+            uint32_t gain_type = 0;
+            uint32_t volume_level = 0;
+            uint32_t stream_idx = PA_INVALID_INDEX;
+            pa_usec_t interval;
+
+            if (pa_tagstruct_gets(t, &name) < 0 ||
+                pa_tagstruct_get_boolean(t, &start) < 0 ||
+                pa_tagstruct_getu32(t, &volume_type) < 0 ||
+                pa_tagstruct_getu32(t, &gain_type) < 0 ||
+                pa_tagstruct_getu32(t, &volume_level) < 0 ||
+                pa_tagstruct_get_usec(t, &interval) < 0 ||
+                !pa_tagstruct_eof(t)) {
+                pa_log_error("protocol error");
+                goto fail;
+            }
+            /*When play sample continuous is in running state another instance is not allowed*/
+            if (start == TRUE) {
+                if (u->audio_sample_userdata.is_running == FALSE) {
+                    /* Now it is time to prepare burstshot...set burstshot vconf */
+                    vconf_set_int (VCONF_SOUND_BURSTSHOT, 1);
+
+                    pa_log_warn("play_sample_continuously start. name(%s), vol_type(%d), gain_type(%d), vol_level(%d), interval(%lu ms)",
+                        name, volume_type, gain_type, volume_level, (unsigned long) (interval / PA_USEC_PER_MSEC));
+                    policy_play_sample_continuously(u, c, name, interval, volume_type, gain_type, volume_level, &stream_idx);
+
+                    /* Running false after start means, start failed....unset burstshot vconf */
+                    if (u->audio_sample_userdata.is_running == FALSE) {
+                        vconf_set_int (VCONF_SOUND_BURSTSHOT, 0);
+                    }
+                } else {
+                    pa_log_warn("play_sample_continuously is in running state - do nothing");
+                }
+            } else if ((start == FALSE) && (u->audio_sample_userdata.is_running == TRUE)) {
+                pa_log_warn("play_sample_continuously end.");
+                policy_stop_sample_continuously(u);
+            } else {
+                pa_log_error("play sample continuously unknown command. name(%s), start(%d)", name, start);
+            }
+
+            pa_tagstruct_putu32(reply, stream_idx);
+            break;
+        }
+
+#endif
+        case SUBCOMMAND_MONO: {
+
+            pa_bool_t enable;
+
+            if (pa_tagstruct_get_boolean(t, &enable) < 0)
+                goto fail;
+
+            pa_log_debug ("new mono value = %d\n", enable);
+            if (enable == u->is_mono) {
+                pa_log_debug ("No changes in mono value = %d", u->is_mono);
+                break;
+            }
+
+            u->is_mono = enable;
+            /* To DO */
+            break;
+        }
+
+        case SUBCOMMAND_BALANCE: {
+            unsigned i;
+            float balance;
+            float x;
+            const float EPSINON= 0.00000001;
+            pa_cvolume cvol;
+            const pa_cvolume *scvol;
+            pa_channel_map map;
+
+            if (pa_tagstruct_get_cvolume(t, &cvol) < 0)
+                goto fail;
+
+            pa_channel_map_init_stereo(&map);
+            balance = pa_cvolume_get_balance(&cvol, &map);
+
+            pa_log_debug ("new balance value = [%f]\n", balance);
+
+            x = u->balance - balance;
+            if ((x >= - EPSINON)&& (x <= EPSINON)) {
+                pa_log_debug ("No changes in balance value = [%f]", u->balance);
+                break;
+            }
+
+            u->balance = balance;
+
+            /* Apply balance value to each Sinks */
+            PA_IDXSET_FOREACH(s, u->core->sinks, idx) {
+                scvol = pa_sink_get_volume(s, FALSE);
+                for (i = 0; i < scvol->channels; i++) {
+                    cvol.values[i] = scvol->values[i];
+                }
+                cvol.channels = scvol->channels;
+
+                pa_cvolume_set_balance(&cvol, &s->channel_map, u->balance);
+                pa_sink_set_volume(s, &cvol, TRUE, TRUE);
+            }
+            break;
+        }
+        case SUBCOMMAND_MUTEALL: {
+            const char *si_gain_type_str;
+            pa_bool_t enable;
+            unsigned i;
+            uint32_t gain_type;
+#if 0
+            pa_cvolume cvol ;
+            pa_cvolume* scvol ;
+#endif
+
+            if (pa_tagstruct_get_boolean(t, &enable) < 0)
+                goto fail;
+
+            pa_log_debug ("new muteall value = %d\n", enable);
+            if (enable == u->muteall) {
+                pa_log_debug ("No changes in muteall value = %d", u->muteall);
+                break;
+            }
+
+            u->muteall = enable;
+
+/* Use mute instead of volume for muteall */
+#if 1
+#ifdef TIZEM_MICRO
+            /* Special case. Set mute for call volume type in B3. */
+            policy_set_mute(u, (-1), AUDIO_VOLUME_TYPE_CALL, AUDIO_DIRECTION_OUT, u->muteall);
+#else
+            for (i = 0; i < AUDIO_VOLUME_TYPE_MAX; i++) {
+                policy_set_mute(u, (-1), i, AUDIO_DIRECTION_OUT, u->muteall);
+            }
+#endif
+            PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+                /* Skip booting sound for power off mute streams policy. */
+                if (u->muteall && (si_gain_type_str = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_TIZEN_GAIN_TYPE))) {
+                    pa_atou(si_gain_type_str, &gain_type);
+                    if (gain_type == AUDIO_GAIN_TYPE_BOOTING)
+                        continue;
+                }
+                pa_sink_input_set_mute(si, u->muteall, TRUE);
+            }
+#else
+            /* Apply new volume  value to each Sink_input */
+            if (u->muteall) {
+                PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+                    scvol = pa_sink_input_get_volume (si, &cvol,TRUE);
+                    for (i = 0; i < scvol->channels; i++) {
+                        scvol->values[i] = 0;
+                    }
+                    pa_sink_input_set_volume(si,scvol,TRUE,TRUE);
+                }
+            } else {
+                PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
+                    if (pa_streq(si->module->name,"module-remap-sink")) {
+                        scvol = pa_sink_input_get_volume (si, &cvol,TRUE);
+                        for (i = 0; i < scvol->channels; i++) {
+                            scvol->values[i] = MAX_VOLUME_FOR_MONO;
+                        }
+                        pa_sink_input_set_volume(si,scvol,TRUE,TRUE);
+                    }
+                }
+            }
+#endif
+            break;
+        }
+
+        case SUBCOMMAND_SET_USE_CASE: {
+            break;
+        }
+
+        case SUBCOMMAND_SET_SESSION: {
+            uint32_t session = 0;
+            uint32_t start = 0;
+
+            pa_tagstruct_getu32(t, &session);
+            pa_tagstruct_getu32(t, &start);
+
+            policy_set_session(u, session, start);
+            break;
+        }
+
+        case SUBCOMMAND_SET_SUBSESSION: {
+            uint32_t subsession = 0;
+            uint32_t subsession_opt = 0;
+
+            pa_tagstruct_getu32(t, &subsession);
+            pa_tagstruct_getu32(t, &subsession_opt);
 
-       PA_IDXSET_FOREACH(s, c->sinks, idx) {
-               if (policy_is_bluez (s)) {
-                       pa_log_debug ("[POLICY][%s] return [%p] for [%s]\n", __func__, s, s->name);
-                       return s;
-               }
-       }
-       return NULL;
-}
+            policy_set_subsession(u, subsession, subsession_opt);
+            break;
+        }
 
-/* Select sink for given condition */
-static pa_sink* policy_select_proper_sink (pa_core *c, const char* policy, int is_mono)
-{
-       pa_sink* sink = NULL;
-       pa_sink* bt_sink = NULL;
-       pa_sink* def = NULL;
-
-       if (c == NULL || policy == NULL) {
-               pa_log_warn ("input param is null");
-               return NULL;
-       }
-
-       pa_assert (c);
-
-       bt_sink = policy_get_bt_sink(c);
-       def = pa_namereg_get_default_sink(c);
-       pa_log_debug ("[POLICY][%s] policy[%s], is_mono[%d], current default[%s], bt sink[%s]\n",
-                       __func__, policy, is_mono, def->name, (bt_sink)? bt_sink->name:"null");
-
-       /* Select sink to */
-       if (pa_streq(policy, POLICY_ALL)) {
-               /* all */
-               if (bt_sink) {
-                       sink = policy_get_sink_by_name(c, (is_mono)? SINK_MONO_COMBINED : SINK_COMBINED);
-               } else {
-                       sink = policy_get_sink_by_name (c, (is_mono)? SINK_MONO_ALSA : SINK_ALSA);
-               }
-
-       } else if (pa_streq(policy, POLICY_PHONE)) {
-               /* phone */
-               sink = policy_get_sink_by_name (c, (is_mono)? SINK_MONO_ALSA : SINK_ALSA);
-       } else {
-               /* auto */
-               if (pa_streq (def->name, SINK_ALSA)) {
-                       sink = (is_mono)? policy_get_sink_by_name (c, SINK_MONO_ALSA) : def;
-               } else {
-                       sink = (is_mono)? policy_get_sink_by_name (c, SINK_MONO_BT) : def;
-               }
-       }
-
-       pa_log_debug ("[POLICY][%s] selected sink : [%s]\n", __func__, (sink)? sink->name : "null");
-       return sink;
-}
-
-static pa_bool_t policy_is_filter (pa_sink_input* si)
-{
-       const char* role = NULL;
-
-       if (si == NULL) {
-               pa_log_warn ("input param sink-input is null");
-               return FALSE;
-       }
-
-       if ((role = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_ROLE))) {
-#ifdef DEBUG_DETAIL
-               pa_log_debug("[POLICY][%s] Role of sink input [%d] = %s", __func__, si->index, role);
-#endif
-               if (pa_streq(role, "filter")) {
-#ifdef DEBUG_DETAIL
-                       pa_log_debug("[POLICY] no need to change of sink for %s", role);
-#endif
-                       return TRUE;
-               }
-       }
+        case SUBCOMMAND_SET_ACTIVE_DEVICE: {
+            uint32_t device_in = 0;
+            uint32_t device_out = 0;
+            uint32_t need_update = FALSE;
 
-       return FALSE;
-}
+            pa_tagstruct_getu32(t, &device_in);
+            pa_tagstruct_getu32(t, &device_out);
 
+            policy_set_active_device(u, device_in, device_out, &need_update);
+            pa_tagstruct_putu32(reply, need_update);
+            break;
+        }
 
+        case SUBCOMMAND_RESET: {
 
-#define EXT_VERSION 1
+            policy_reset(u);
 
-static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
-  struct userdata *u = NULL;
-  uint32_t command;
-  pa_tagstruct *reply = NULL;
+            break;
+        }
 
-  pa_sink_input *si = NULL;
-  uint32_t idx;
-  pa_sink* sink_to_move  = NULL;
+        case SUBCOMMAND_GET_VOLUME_LEVEL_MAX: {
+            uint32_t volume_type = 0;
+            uint32_t volume_level = 0;
 
-  pa_assert(p);
-  pa_assert(m);
-  pa_assert(c);
-  pa_assert(t);
+            pa_tagstruct_getu32(t, &volume_type);
 
-  u = m->userdata;
+            policy_get_volume_level_max(u, volume_type, &volume_level);
 
-  if (pa_tagstruct_getu32(t, &command) < 0)
-    goto fail;
+            pa_tagstruct_putu32(reply, volume_level);
+            break;
+        }
 
-  reply = pa_tagstruct_new(NULL, 0);
-  pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
-  pa_tagstruct_putu32(reply, tag);
+        case SUBCOMMAND_GET_VOLUME_LEVEL: {
+            uint32_t stream_idx = PA_INVALID_INDEX;
+            uint32_t volume_type = 0;
+            uint32_t volume_level = 0;
 
-  switch (command) {
-    case SUBCOMMAND_TEST: {
-               if (!pa_tagstruct_eof(t))
-                       goto fail;
+            pa_tagstruct_getu32(t, &stream_idx);
+            pa_tagstruct_getu32(t, &volume_type);
 
-               pa_tagstruct_putu32(reply, EXT_VERSION);
-               break;
-    }
+            policy_get_volume_level(u, stream_idx, &volume_type, &volume_level);
 
-    case SUBCOMMAND_MONO: {
+            pa_tagstruct_putu32(reply, volume_level);
+            break;
+        }
 
-        pa_bool_t enable;
+        case SUBCOMMAND_SET_VOLUME_LEVEL: {
+            uint32_t stream_idx = PA_INVALID_INDEX;
+            uint32_t volume_type = 0;
+            uint32_t volume_level = 0;
 
-        if (pa_tagstruct_get_boolean(t, &enable) < 0)
-            goto fail;
+            pa_tagstruct_getu32(t, &stream_idx);
+            pa_tagstruct_getu32(t, &volume_type);
+            pa_tagstruct_getu32(t, &volume_level);
 
-        pa_log_debug ("[POLICY][%s] new mono value = %d\n", __func__, enable);
-        if (enable == u->is_mono) {
-                       pa_log_debug ("[POLICY][%s] No changes in mono value = %d", __func__, u->is_mono);
-                       break;
+            policy_set_volume_level(u, stream_idx, volume_type, volume_level);
+            break;
         }
 
-        u->is_mono = enable;
+        case SUBCOMMAND_UPDATE_VOLUME: {
+            policy_update_volume(u);
+            break;
+        }
+
+        case SUBCOMMAND_GET_MUTE: {
+            uint32_t stream_idx = PA_INVALID_INDEX;
+            uint32_t volume_type = 0;
+            uint32_t direction = 0;
+            uint32_t mute = 0;
+
+            pa_tagstruct_getu32(t, &stream_idx);
+            pa_tagstruct_getu32(t, &volume_type);
+            pa_tagstruct_getu32(t, &direction);
+
+            policy_get_mute(u, stream_idx, volume_type, direction, &mute);
 
-               /* Move current sink-input to proper mono sink */
-               PA_IDXSET_FOREACH(si, u->core->sink_inputs, idx) {
-                       const char *policy = NULL;
+            pa_tagstruct_putu32(reply, mute);
+            break;
+        }
+
+        case SUBCOMMAND_SET_MUTE: {
+            uint32_t stream_idx = PA_INVALID_INDEX;
+            uint32_t volume_type = 0;
+            uint32_t direction = 0;
+            uint32_t mute = 0;
 
-                       /* Skip this if it is already in the process of being moved
-                        * anyway */
-                       if (!si->sink)
-                               continue;
+            pa_tagstruct_getu32(t, &stream_idx);
+            pa_tagstruct_getu32(t, &volume_type);
+            pa_tagstruct_getu32(t, &direction);
+            pa_tagstruct_getu32(t, &mute);
 
-                       /* 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(pa_sink_input_get_state(si)))
-                               continue;
+            policy_set_mute(u, stream_idx, volume_type, direction, mute);
+            break;
+        }
+        case SUBCOMMAND_IS_AVAILABLE_HIGH_LATENCY: {
+            pa_bool_t available = FALSE;
 
-                       /* Get role (if role is filter, skip it) */
-                       if (policy_is_filter(si))
-                               continue;
+            available = policy_is_available_high_latency(u);
 
-                       /* Check policy, if no policy exists, treat as AUTO */
-                       if (!(policy = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_POLICY))) {
-                               pa_log_debug("[POLICY] set policy of sink-input[%d] from [%s] to [auto]", si->index, "null");
-                               policy  = POLICY_AUTO;
-                       }
-                       pa_log_debug("[POLICY] Policy of sink input [%d] = %s", si->index, policy);
+            pa_tagstruct_putu32(reply, (uint32_t)available);
+            break;
+        }
+        case SUBCOMMAND_UNLOAD_HDMI: {
+            break;
+        }
 
-                       /* Select sink to move and move to it */
-                       sink_to_move = policy_select_proper_sink (u->core, policy, u->is_mono);
-                       if (sink_to_move) {
-                               pa_log_debug("[POLICY][%s] Moving sink-input[%d] from [%s] to [%s]", __func__, si->index, si->sink->name, sink_to_move->name);
-                               pa_sink_input_move_to(si, sink_to_move, FALSE);
-                       } else {
-                               pa_log_debug("[POLICY][%s] Can't move sink-input....", __func__);
-                       }
-               }
-        break;
+        default:
+            goto fail;
     }
 
-    default:
-      goto fail;
-  }
+    pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply);
+    return 0;
 
-  pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply);
-  return 0;
+    fail:
 
-  fail:
+    if (reply)
+        pa_tagstruct_free(reply);
+
+    return -1;
+}
 
-  if (reply)
-         pa_tagstruct_free(reply);
+static void __set_sink_input_role_type(pa_proplist *p, int gain_type)
+{
+    const char* role = NULL;
+
+    if ((role = pa_proplist_gets(p, PA_PROP_MEDIA_ROLE))) {
+        /* "solo" has priority over other roles */
+        if (pa_streq(role, "solo")) {
+            pa_log_info_verbose("already set role to [%s]", role);
+            return;
+        } else {
+            if(gain_type == AUDIO_GAIN_TYPE_SHUTTER1 || gain_type == AUDIO_GAIN_TYPE_SHUTTER2)
+                role = "camera";
+            else
+                role = "normal";
+        }
+    } else {
+        role = "normal";
+    }
+    pa_proplist_sets (p, PA_PROP_MEDIA_ROLE, role);
+    pa_log_info_verbose("set role [%s]", role);
 
-  return -1;
+    return;
 }
 
 /*  Called when new sink-input is creating  */
 static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u)
 {
+    audio_return_t audio_ret = AUDIO_RET_OK;
+    audio_info_t audio_info;
     const char *policy = NULL;
+    const char *ignore_preset_sink = NULL;
+    const char *master_name = NULL;
+    pa_sink *realsink = NULL;
+    uint32_t volume_level = 0;
+    pa_strbuf *s = NULL;
+    const char *rate_str = NULL;
+    const char *ch_str = NULL;
+    char *s_info = NULL;
 
     pa_assert(c);
     pa_assert(new_data);
     pa_assert(u);
 
     if (!new_data->proplist) {
-        pa_log_debug("[POLICY] New stream lacks property data.");
+        pa_log_debug(" New stream lacks property data.");
+        return PA_HOOK_OK;
+    }
+
+    /* If no policy exists, skip */
+    if (!(policy = pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_POLICY))) {
+        pa_log_debug("Not setting device for stream [%s], because it lacks policy.",
+                pa_strnull(pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_NAME)));
         return PA_HOOK_OK;
     }
 
+    /* Parse request formats for samplerate & channel infomation */
+    if (new_data->req_formats) {
+        pa_format_info* req_format = pa_idxset_first(new_data->req_formats, NULL);
+        if (req_format && req_format->plist) {
+            rate_str = pa_proplist_gets(req_format->plist, PA_PROP_FORMAT_RATE);
+            ch_str = pa_proplist_gets(req_format->plist, PA_PROP_FORMAT_CHANNELS);
+            pa_log_info("req rate = %s, req ch = %s", rate_str, ch_str);
+
+            if (ch_str)
+                new_data->sample_spec.channels = atoi (ch_str);
+            if (rate_str)
+                new_data->sample_spec.rate = atoi (rate_str);
+        }
+    } else {
+        pa_log_debug("no request formats available");
+    }
+
+    /* Check if this input want to be played via the sink selected by module-policy */
+    if ((ignore_preset_sink = pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_POLICY_IGNORE_PRESET_SINK))) {
+        pa_log_debug_verbose("ignore_preset_sink is enabled. module-policy will judge a proper sink for stream [%s]",
+                pa_strnull(pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_NAME)));
+    } else {
+        ignore_preset_sink = "no";
+    }
+
     /* If sink-input has already sink, skip */
-    if (new_data->sink) {
-       /* sink-input with filter role will be also here because sink is already set */
+    if (new_data->sink && (strncmp("yes", ignore_preset_sink, strlen("yes")))) {
+        /* sink-input with filter role will be also here because sink is already set */
 #ifdef DEBUG_DETAIL
-        pa_log_debug("[POLICY] Not setting device for stream [%s], because already set.",
-                       pa_strnull(pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_NAME)));
+        pa_log_debug(" Not setting device for stream [%s], because already set.",
+                pa_strnull(pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_NAME)));
 #endif
-        return PA_HOOK_OK;
+    } else {
+
+        /* Set proper sink to sink-input */
+        new_data->save_sink = FALSE;
+            new_data->sink = policy_select_proper_sink (u, policy, NULL, TRUE);
+
+        if (new_data->sink == NULL) {
+            pa_log_error("new_data->sink is null");
+            goto exit;
+        }
     }
 
-    /* If no policy exists, skip */
-    if (!(policy = pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_POLICY))) {
-        pa_log_debug("[POLICY][%s] Not setting device for stream [%s], because it lacks policy.",
-                       __func__, pa_strnull(pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_NAME)));
-        return PA_HOOK_OK;
+    s = pa_strbuf_new();
+    master_name = pa_proplist_gets(new_data->sink->proplist, PA_PROP_DEVICE_MASTER_DEVICE);
+    if (master_name)
+        realsink = pa_namereg_get(c, master_name, PA_NAMEREG_SINK);
+
+    if (AUDIO_IS_ERROR((audio_ret = __fill_audio_playback_stream_info(new_data->proplist, &new_data->sample_spec, &audio_info)))) {
+        pa_log_debug("__fill_audio_playback_stream_info returns 0x%x", audio_ret);
+    } else if (AUDIO_IS_ERROR((audio_ret = __fill_audio_playback_device_info(realsink? realsink->proplist : new_data->sink->proplist, &audio_info)))) {
+        pa_log_debug("__fill_audio_playback_device_info returns 0x%x", audio_ret);
+    } else {
+        double volume_linear = 1.0f;
+
+        // set role type
+        __set_sink_input_role_type(new_data->proplist, audio_info.stream.gain_type);
+
+        if (u->audio_mgr.intf.get_volume_level) {
+            u->audio_mgr.intf.get_volume_level(u->audio_mgr.data, audio_info.stream.volume_type, &volume_level);
+        }
+
+        pa_strbuf_printf(s, "[%s] policy[%s] ch[%d] rate[%d] volume&gain[%d,%d] level[%d]",
+                audio_info.stream.name, policy, audio_info.stream.channels, audio_info.stream.samplerate,
+                audio_info.stream.volume_type, audio_info.stream.gain_type, volume_level);
+
+        if (audio_info.device.api == AUDIO_DEVICE_API_ALSA) {
+            pa_strbuf_printf(s, " device:ALSA[%d,%d]", audio_info.device.alsa.card_idx, audio_info.device.alsa.device_idx);
+        } else if (audio_info.device.api == AUDIO_DEVICE_API_BLUEZ) {
+            pa_strbuf_printf(s, " device:BLUEZ[%s] nrec[%d]", audio_info.device.bluez.protocol, audio_info.device.bluez.nrec);
+        }
+        pa_strbuf_printf(s, " sink[%s]", (new_data->sink)? new_data->sink->name : "null");
+
+        /* Call HAL function if exists */
+        if (u->audio_mgr.intf.set_volume_level) {
+            if (AUDIO_IS_ERROR((audio_ret = u->audio_mgr.intf.set_volume_level(u->audio_mgr.data, &audio_info, audio_info.stream.volume_type, volume_level)))) {
+                pa_log_warn("set_volume_level for new sink-input returns error:0x%x", audio_ret);
+                goto exit;
+            }
+        }
+
+        /* Get volume value by type & level */
+        if (u->audio_mgr.intf.get_volume_value && (audio_ret != AUDIO_RET_USE_HW_CONTROL)) {
+            if (AUDIO_IS_ERROR((audio_ret = u->audio_mgr.intf.get_volume_value(u->audio_mgr.data, &audio_info, audio_info.stream.volume_type, volume_level, &volume_linear)))) {
+                pa_log_warn("get_volume_value for new sink-input returns error:0x%x", audio_ret);
+                goto exit;
+            }
+        }
+
+        pa_cvolume_init(&new_data->volume);
+        pa_cvolume_set(&new_data->volume, new_data->sample_spec.channels, pa_sw_volume_from_linear(volume_linear));
+
+        new_data->volume_is_set = TRUE;
+
+        if(u->muteall && audio_info.stream.volume_type != AUDIO_VOLUME_TYPE_FIXED) {
+            pa_sink_input_new_data_set_muted(new_data, TRUE); // pa_simpe api use muted stream always. for play_sample_xxx apis
+        }
+        __free_audio_info(&audio_info);
+    }
+
+exit:
+    if (s) {
+        s_info = pa_strbuf_tostring_free(s);
+        pa_log_info("new %s", s_info);
+        pa_xfree(s_info);
     }
-    pa_log_debug("[POLICY][%s] Policy for stream [%s] = [%s]",
-               __func__, pa_strnull(pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_NAME)), policy);
 
-    /* Set proper sink to sink-input */
-       new_data->save_sink = FALSE;
-       new_data->sink = policy_select_proper_sink (c, policy, u->is_mono);
-       pa_log_debug("[POLICY][%s] set sink of sink-input to [%s]", __func__, (new_data->sink)? new_data->sink->name : "null");
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sink_input_unlink_post_hook_callback(pa_core *c, pa_sink_input *i, struct userdata *u)
+{
+    uint32_t volume_type = 0;
+    const char *si_volume_type_str;
+
+    pa_assert(c);
+    pa_assert(i);
+    pa_assert(u);
+
+#ifdef PRIMARY_VOLUME
+    if((si_volume_type_str = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) {
+        pa_atou(si_volume_type_str, &volume_type);
+        __set_primary_volume(u, (void*)i, volume_type, false);
+    }
+#endif
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sink_input_put_callback(pa_core *core, pa_sink_input *i, struct userdata *u)
+{
+    uint32_t volume_type = 0;
+    const char *si_volume_type_str;
+
+    pa_core_assert_ref(core);
+    pa_sink_input_assert_ref(i);
+    pa_assert(u);
+
+#ifdef PRIMARY_VOLUME
+    if ((si_volume_type_str = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_TIZEN_VOLUME_TYPE)) &&
+        pa_sink_input_get_state(i) != PA_SINK_INPUT_CORKED /* if sink-input is created by pulsesink, sink-input init state is cork.*/) {
+        pa_atou(si_volume_type_str, &volume_type);
+        __set_primary_volume(u, (void*)i, volume_type, true);
+    }
+#endif
 
     return PA_HOOK_OK;
 }
@@ -364,7 +3305,14 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct
     pa_sink_input *si;
     pa_sink *sink_to_move;
     uint32_t idx;
-    char *args = NULL;
+    unsigned i;
+    pa_cvolume cvol;
+    const pa_cvolume *scvol;
+    pa_bool_t is_bt;
+    pa_bool_t is_usb_alsa;
+    pa_bool_t is_need_to_move = true;
+    int dock_status;
+    uint32_t device_out = AUDIO_DEVICE_OUT_BT_A2DP;
 
     pa_assert(c);
     pa_assert(sink);
@@ -373,71 +3321,185 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct
 
     /* If connected sink is BLUETOOTH, set as default */
     /* we are checking with device.api property */
-       if (policy_is_bluez(sink)) {
-               pa_log_debug("[POLICY][%s] set default sink to sink[%s][%d]", __func__, sink->name, sink->index);
-               pa_namereg_set_default_sink (c,sink);
-       } else {
-               pa_log_debug("[POLICY][%s] this sink [%s][%d] is not a bluez....return", __func__, sink->name, sink->index);
-               return PA_HOOK_OK;
-       }
-
-       /* Load mono_bt sink */
-       args = pa_sprintf_malloc("sink_name=%s master=%s channels=1", SINK_MONO_BT, sink->name);
-       u->module_mono_bt = pa_module_load(u->module->core, "module-remap-sink", args);
-       pa_xfree(args);
-
-       /* load combine sink */
-       args = pa_sprintf_malloc("sink_name=%s slaves=\"%s,%s\"", SINK_COMBINED, sink->name, SINK_ALSA);
-       u->module_combined = pa_module_load(u->module->core, "module-combine", args);
-       pa_xfree(args);
-
-       /* load mono_combine sink */
-       args = pa_sprintf_malloc("sink_name=%s master=%s channels=1", SINK_MONO_COMBINED, SINK_COMBINED);
-       u->module_mono_combined = pa_module_load(u->module->core, "module-remap-sink", args);
-       pa_xfree(args);
-
-
-       /* Iterate each sink inputs to decide whether we should move to new sink */
-    PA_IDXSET_FOREACH(si, c->sink_inputs, idx) {
-        const char *policy = NULL;
+    is_bt = policy_is_bluez(sink);
+    is_usb_alsa = policy_is_usb_alsa(sink);
+
+    if (is_bt || is_usb_alsa) {
+        if (u->session == AUDIO_SESSION_VOICECALL || u->session == AUDIO_SESSION_VIDEOCALL || u->session == AUDIO_SESSION_VOIP) {
+            pa_log_info("current session is communication mode [%d], no need to move", u->session);
+            is_need_to_move = false;
+        } else if (is_usb_alsa) {
+            vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &dock_status);
+            if ((dock_status == DOCK_DESKDOCK) || (dock_status == DOCK_CARDOCK)) {
+                device_out = AUDIO_DEVICE_OUT_DOCK;
+            } else if (dock_status == DOCK_AUDIODOCK) {
+                device_out = AUDIO_DEVICE_OUT_MULTIMEDIA_DOCK;
+            } else if (dock_status == DOCK_SMARTDOCK) {
+                is_need_to_move = false;
+            } else {
+                device_out = AUDIO_DEVICE_OUT_USB_AUDIO;
+                pa_log_info ("This device might be general USB Headset");
+            }
+        }
+    } else {
+        pa_log_debug("this sink [%s][%d] is not a bluez....return", sink->name, sink->index);
+        return PA_HOOK_OK;
+    }
 
-        if (si->sink == sink)
-               continue;
+    if (is_bt) {
+/*
+        pa_log_info("new bluetooth sink(card) is detected. volume level and route will be changed by sound_server a2dp_on function");
+        is_need_to_move = false;
+        */
+    }
 
-        /* Skip this if it is already in the process of being moved
-         * anyway */
-        if (!si->sink)
-            continue;
+    if (is_need_to_move) {
+        int ret = 0;
+        uint32_t route_flag = 0;
 
-        /* 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(pa_sink_input_get_state(si)))
-            continue;
+        /* Set active device out */
+        if (u->active_device_out != device_out) {
+            route_flag = __get_route_flag(u);
+            if (u->audio_mgr.intf.set_route) {
+                ret = u->audio_mgr.intf.set_route(u->audio_mgr.data, u->session, u->subsession, u->active_device_in, device_out, route_flag);
+            }
+        }
 
-               /* Get role (if role is filter, skip it) */
-        if (policy_is_filter(si))
-               continue;
+        if(ret >= 0) {
+            pa_log_info("set default sink to sink[%s][%d], active_device_out(%d), device_out(%d)",
+                sink->name, sink->index, u->active_device_out, device_out);
+            pa_namereg_set_default_sink (c,sink);
+
+            u->active_device_out = device_out;
+            u->active_route_flag = route_flag;
+
+            /* Iterate each sink inputs to decide whether we should move to new sink */
+            PA_IDXSET_FOREACH(si, c->sink_inputs, idx) {
+                const char *policy = NULL;
+
+                if (si->sink == sink)
+                    continue;
+
+                /* Skip this if it is already in the process of being moved
+                        * anyway */
+                if (!si->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(pa_sink_input_get_state(si)))
+                    continue;
+
+                /* Get role (if role is filter, skip it) */
+                if (policy_is_filter(si->proplist))
+                    continue;
+
+                /* Check policy */
+                if (!(policy = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_POLICY))) {
+                    /* No policy exists, this means auto */
+                    pa_log_debug("set policy of sink-input[%d] from [%s] to [auto]", si->index, "null");
+                    policy = POLICY_AUTO;
+                }
+#ifdef TIZEN_MICRO
+            sink_to_move = policy_select_proper_sink (u, policy, si, TRUE);
+#else
+                 /** If UHQA sink input then connect the sink inpu to UHQA sink*/
+                if ((si->sample_spec.rate >= UHQA_BASE_SAMPLING_RATE)
+                     && (pa_streq(policy, POLICY_HIGH_LATENCY) || pa_streq(policy, POLICY_AUTO))) {
+
+                    char tmp_policy[100] = {0};
+
+                    sprintf(tmp_policy, "%s-uhqa", policy);
+
+                    pa_log_info ("------------------------------------");
+                    sink_to_move = policy_select_proper_sink (u, tmp_policy, si, TRUE);
+                } else {
+                    pa_log_info ("------------------------------------");
+                    sink_to_move = policy_select_proper_sink (u, policy, si, TRUE);
+                }
+#endif
 
-               /* Check policy */
-               if (!(policy = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_POLICY))) {
-                       /* No policy exists, this means auto */
-                       pa_log_debug("[POLICY][%s] set policy of sink-input[%d] from [%s] to [auto]", __func__, si->index, "null");
-                       policy = POLICY_AUTO;
-               }
+                if (sink_to_move) {
+                    pa_log_debug("Moving sink-input[%d] from [%s] to [%s]", si->index, si->sink->name, sink_to_move->name);
+                    pa_sink_input_move_to(si, sink_to_move, FALSE);
+                } else {
+                    pa_log_debug("Can't move sink-input....");
+                }
+            }
+        } else
+            pa_log_debug("route failed(normal operation). session(%d), subsession(%d), active_device_out(%d), device_out(%d)\n",
+                u->session, u->subsession, u->active_device_out, device_out);
+    }
 
-               sink_to_move = policy_select_proper_sink (c, policy, u->is_mono);
-               if (sink_to_move) {
-                       pa_log_debug("[POLICY][%s] Moving sink-input[%d] from [%s] to [%s]", __func__, si->index, si->sink->name, sink_to_move->name);
-                       pa_sink_input_move_to(si, sink_to_move, FALSE);
-               } else {
-                       pa_log_debug("[POLICY][%s] Can't move sink-input....",__func__);
-               }
+    /* Reset sink volume with balance from userdata */
+    scvol = pa_sink_get_volume(sink, FALSE);
+    for (i = 0; i < scvol->channels; i++) {
+        cvol.values[i] = scvol->values[i];
     }
+    cvol.channels = scvol->channels;
+
+    pa_cvolume_set_balance(&cvol, &sink->channel_map, u->balance);
+    pa_sink_set_volume(sink, &cvol, TRUE, TRUE);
+
+    /* Reset sink muteall from userdata */
+//    pa_sink_set_mute(sink,u->muteall,TRUE);
 
     return PA_HOOK_OK;
 }
 
+static void defer_event_cb (pa_mainloop_api *m, pa_defer_event *e, void *userdata)
+{
+    struct userdata *u = userdata;
+
+    pa_assert(m);
+    pa_assert(e);
+    pa_assert(u);
+
+    m->defer_enable(u->defer_event, 0);
+
+    /* Dispatch queued events */
+
+    while (u->hal_event_queue) {
+        struct pa_hal_event *hal_event = u->hal_event_queue;
+
+        if ((hal_event->event_type == PA_HAL_EVENT_LOAD_DEVICE) || (hal_event->event_type == PA_HAL_EVENT_OPEN_DEVICE)) {
+            struct pa_hal_device_event_data *event_data = (struct pa_hal_device_event_data *)hal_event->event_data;
+
+            pa_log_info("dispatch %s event", __get_event_type_string(hal_event->event_type));
+
+            __load_n_open_device(hal_event->userdata, &event_data->device_info, &event_data->params[0], hal_event->event_type);
+
+            pa_log_debug("completed %s event", __get_event_type_string(hal_event->event_type));
+        } else if (hal_event->event_type == PA_HAL_EVENT_CLOSE_ALL_DEVICES) {
+            pa_log_info("dispatch %s event", __get_event_type_string(PA_HAL_EVENT_CLOSE_ALL_DEVICES));
+
+            __close_all_devices(hal_event->userdata);
+
+            pa_log_debug("completed %s event", __get_event_type_string(PA_HAL_EVENT_CLOSE_ALL_DEVICES));
+        } else if ((hal_event->event_type == PA_HAL_EVENT_CLOSE_DEVICE) || (hal_event->event_type == PA_HAL_EVENT_UNLOAD_DEVICE)) {
+            struct pa_hal_device_event_data *event_data = (struct pa_hal_device_event_data *)hal_event->event_data;
+
+            pa_log_info("dispatch %s event", __get_event_type_string(hal_event->event_type));
+
+            __close_n_unload_device(hal_event->userdata, &event_data->device_info, hal_event->event_type);
+
+            pa_log_debug("completed %s event", __get_event_type_string(hal_event->event_type));
+        }
+
+        if (!hal_event->next)
+            hal_event->userdata->hal_event_last = hal_event->prev;
+
+        PA_LLIST_REMOVE(struct pa_hal_event, hal_event->userdata->hal_event_queue, hal_event);
+
+        if (hal_event->cond) {
+            pa_mutex_lock(hal_event->mutex);
+            pa_cond_signal(hal_event->cond, 0);
+            pa_mutex_unlock(hal_event->mutex);
+        }
+    }
+}
+
 static void subscribe_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata)
 {
     struct userdata *u = userdata;
@@ -445,41 +3507,111 @@ static void subscribe_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t id
     pa_sink_input *si;
     uint32_t idx2;
     pa_sink *sink_to_move = NULL;
+    pa_sink *sink_cur = NULL;
+    pa_source *source_cur = NULL;
+    pa_source_state_t source_state;
+    int vconf_source_status = 0;
+    uint32_t si_index;
+    int audio_ret;
+
     pa_assert(u);
 
-    pa_log_debug("[POLICY][%s] subscribe_cb() t=[0x%x], idx=[%d]", __func__, t, idx);
+    pa_log_debug_verbose("t=[0x%x], idx=[%d]", t, idx);
 
-    /* We only handle server changes */
     if (t == (PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE)) {
 
-       def = pa_namereg_get_default_sink(c);
-       pa_log_debug("[POLICY][%s] trying to move stream to current default sink = [%s]", __func__, def->name);
+        def = pa_namereg_get_default_sink(c);
+        if (def == NULL) {
+            pa_log_warn("pa_namereg_get_default_sink() returns null");
+            return;
+        }
+        pa_log_info("default sink is now [%s]", def->name);
 
-       /* Iterate each sink inputs to decide whether we should move to new DEFAULT sink */
-       PA_IDXSET_FOREACH(si, c->sink_inputs, idx2) {
-                       const char *policy = NULL;
+        /* Iterate each sink inputs to decide whether we should move to new DEFAULT sink */
+        PA_IDXSET_FOREACH(si, c->sink_inputs, idx2) {
+            const char *policy = NULL;
 
-                       if (!si->sink)
-                               continue;
+            if (!si->sink)
+                continue;
 
-                       /* Get role (if role is filter, skip it) */
-                       if (policy_is_filter(si))
-                               continue;
+            /* Get role (if role is filter, skip it) */
+            if (policy_is_filter(si->proplist))
+                continue;
 
-                       /* Get policy */
-                       if (!(policy = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_POLICY))) {
-                               /* No policy exists, this means auto */
-                               pa_log_debug("[POLICY][%s] set policy of sink-input[%d] from [%s] to [auto]", __func__, si->index, "null");
-                               policy = POLICY_AUTO;
-                       }
+            if (pa_streq (def->name, "null")) {
+#ifdef TIZEN_MICRO
+                /* alarm is not comming via speaker after disconnect bluetooth. */
+                if(pa_streq(si->sink->name, "null")) {
+                    pa_log_warn("try to move sink-input from null-sink to null-sink(something wrong state). sink-input[%d] will move to proper sink", si->index);
+                } else {
+#endif
+                    pa_log_debug("Moving sink-input[%d] from [%s] to [%s]", si->index, si->sink->name, def->name);
+                    pa_sink_input_move_to(si, def, FALSE);
+                    continue;
+#ifdef TIZEN_MICRO
+                }
+#endif
+            }
+
+            /* Get policy */
+            if (!(policy = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_POLICY))) {
+                /* No policy exists, this means auto */
+                pa_log_debug("set policy of sink-input[%d] from [%s] to [auto]", si->index, "null");
+                policy = POLICY_AUTO;
+            }
+#ifdef TIZEN_MICRO
+            sink_to_move = policy_select_proper_sink (u, policy, si, TRUE);
+#else
+            /** If sink input is an UHQA sink then connect the sink to UHQA sink*/
+            if ((si->sample_spec.rate >= UHQA_BASE_SAMPLING_RATE)
+                 && (pa_streq(policy, POLICY_HIGH_LATENCY) || pa_streq(policy, POLICY_AUTO))) {
+                char tmp_policy[100] = {0};
+
+                sprintf(tmp_policy, "%s-uhqa", policy);
+                sink_to_move = policy_select_proper_sink (u, tmp_policy, si, TRUE);
+            } else {
+                sink_to_move = policy_select_proper_sink (u, policy, si, TRUE);
+            }
+#endif
 
-                       sink_to_move = policy_select_proper_sink (c, policy, u->is_mono);
-                       if (sink_to_move) {
-                               /* Move sink-input to new DEFAULT sink */
-                               pa_log_debug("[POLICY][%s] Moving sink-input[%d] from [%s] to [%s]", __func__, si->index, si->sink->name, sink_to_move->name);
-                               pa_sink_input_move_to(si, sink_to_move, FALSE);
-                       }
-       }
+            if (sink_to_move) {
+                /* Move sink-input to new DEFAULT sink */
+                pa_log_debug("Moving sink-input[%d] from [%s] to [%s]", si->index, si->sink->name, sink_to_move->name);
+                pa_sink_input_move_to(si, sink_to_move, FALSE);
+            }
+        }
+        pa_log_info("All moved to proper sink finished!!!!");
+    } else if (t == (PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE)) {
+        if ((sink_cur = pa_idxset_get_by_index(c->sinks, idx))) {
+            pa_sink_state_t state = pa_sink_get_state(sink_cur);
+            pa_log_debug_verbose("sink[%s] changed to state[%d]", sink_cur->name, state);
+
+            if (pa_streq (sink_cur->name, SINK_HIGH_LATENCY) && state == PA_SINK_RUNNING) {
+                PA_IDXSET_FOREACH(si, c->sink_inputs, si_index) {
+                    if (!si->sink)
+                        continue;
+                    if (pa_streq (si->sink->name, SINK_HIGH_LATENCY)) {
+                        if (AUDIO_IS_ERROR((audio_ret = __update_volume(u, si->index, (uint32_t)-1, (uint32_t)-1)))) {
+                            pa_log_debug("__update_volume for stream[%d] returns error:0x%x", si->index, audio_ret);
+                        }
+                    }
+                }
+            }
+        }
+    } else if (t == (PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE)) {
+        if ((source_cur = pa_idxset_get_by_index(c->sources, idx))) {
+            if (pa_streq (source_cur->name, SOURCE_ALSA)) {
+                source_state = pa_source_get_state(source_cur);
+                pa_log_debug_verbose("source[%s] changed to state[%d]", source_cur->name, source_state);
+                if (source_state == PA_SOURCE_RUNNING) {
+                    vconf_set_int (VCONFKEY_SOUND_CAPTURE_STATUS, 1);
+                } else {
+                    vconf_get_int (VCONFKEY_SOUND_CAPTURE_STATUS, &vconf_source_status);
+                    if (vconf_source_status)
+                        vconf_set_int (VCONFKEY_SOUND_CAPTURE_STATUS, 0);
+                }
+            }
+        }
     }
 }
 
@@ -487,7 +3619,10 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, voi
     struct userdata *u = userdata;
     uint32_t idx;
     pa_sink *sink_to_move;
-    pa_sink_input      *si;
+    pa_sink_input *si;
+
+    const char *si_volume_type_str;
+    uint32_t volume_type = AUDIO_VOLUME_TYPE_SYSTEM;
 
     pa_assert(c);
     pa_assert(sink);
@@ -498,60 +3633,59 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, voi
         return PA_HOOK_OK;
 
     /* if unloading sink is not bt, just return */
-       if (!policy_is_bluez (sink)) {
-               pa_log_debug("[POLICY][%s] sink[%s][%d] unlinked but not a bluez....return\n", __func__,  sink->name, sink->index);
-               return PA_HOOK_OK;
-       }
-
-       pa_log_debug ("[POLICY][%s] SINK unlinked ================================ sink [%s][%d], bt_off_idx was [%d]",
-                       __func__, sink->name, sink->index,u->bt_off_idx);
-
-       u->bt_off_idx = sink->index;
-       pa_log_debug ("[POLICY][%s] bt_off_idx is set to [%d]", __func__, u->bt_off_idx);
-
-       /* BT sink is unloading, move sink-input to proper sink */
-       PA_IDXSET_FOREACH(si, c->sink_inputs, idx) {
+    if (!policy_is_bluez (sink)) {
+        pa_log_debug("sink[%s][%d] unlinked but not a bluez....return\n", sink->name, sink->index);
+        return PA_HOOK_OK;
+    }
 
-               if (!si->sink)
-                       continue;
+    pa_log_debug ("========= sink [%s][%d], bt_off_idx was [%d], now set to [%d]", sink->name, sink->index,u->bt_off_idx, sink->index);
+    u->bt_off_idx = sink->index;
 
-               /* Get role (if role is filter, skip it) */
-               if (policy_is_filter(si))
-                       continue;
+    sink_to_move = pa_namereg_get(c, "null", PA_NAMEREG_SINK);
 
-               /* Find who were using bt sink or bt related sink and move them to proper sink (alsa/mono_alsa) */
-               if (pa_streq (si->sink->name, SINK_MONO_BT) ||
-                       pa_streq (si->sink->name, SINK_MONO_COMBINED) ||
-                       pa_streq (si->sink->name, SINK_COMBINED) ||
-                       policy_is_bluez (si->sink)) {
+    /* BT sink is unloading, move sink-input to proper sink */
+    PA_IDXSET_FOREACH(si, c->sink_inputs, idx) {
+        const char *policy = NULL;
 
-                       /* Move sink-input to proper sink : only alsa related sink is available now */
-                       sink_to_move = policy_get_sink_by_name (c, (u->is_mono)? SINK_MONO_ALSA : SINK_ALSA);
-                       pa_log_debug("[POLICY][%s] Moving sink-input[%d] from [%s] to [%s]", __func__, si->index, si->sink->name, sink_to_move->name);
-                       pa_sink_input_move_to(si, sink_to_move, FALSE);
-               }
-       }
+        if (!si->sink)
+            continue;
 
-       pa_log_debug ("[POLICY][%s] unload sink in dependencies", __func__);
+        /* Get role (if role is filter, skip it) */
+        if (policy_is_filter(si->proplist))
+            continue;
 
-    /* Unload mono_combine sink */
-    if (u->module_mono_combined) {
-       pa_module_unload(u->module->core, u->module_mono_combined, TRUE);
-       u->module_mono_combined = NULL;
+        /* Find who were using bt sink or bt related sink and move them to proper sink (alsa) */
+        if(policy_is_bluez (si->sink)) {
+#ifdef TIZEN_MICRO
+            /* FIXME : stupid code. BT headset is disconnected during playing alarm. should be moved to proper sink.
+                    sound_server can't route sound path on alarm/noti/emergeny session */
+            if ((si_volume_type_str = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) {
+                pa_atou(si_volume_type_str, &volume_type);
+                if(volume_type == AUDIO_VOLUME_TYPE_ALARM) {
+                    pa_sink* s = policy_select_proper_sink (u, "auto", si, FALSE);
+                    pa_sink_input_move_to(si, s, FALSE);
+                    pa_log_info("device changed on alarm session. will move to proper sink. stream[%d], policy[%s]. stream move sink[%s] =====> sink[%s]",
+                        idx, policy, si->sink->name, s->name);
+                    continue;
+                }
+            } else {
+                pa_log_debug("sink-input does't have volume type");
+            }
+
+            pa_log_info("stream[%d], policy[%s]. stream move sink[%s] =====> sink[%s]", idx, policy, si->sink->name, sink_to_move->name);
+#else
+            pa_log_info("[%d] Moving sink-input[%d][%s] from [%s] to [%s]", idx, si->index, policy, si->sink->name, sink_to_move->name);
+#endif
+            pa_sink_input_move_to(si, sink_to_move, FALSE);
+        }
     }
 
-       /* Unload combine sink */
+    pa_log_debug ("unload sink in dependencies");
+    /* Unload combine sink */
     if (u->module_combined) {
-       pa_module_unload(u->module->core, u->module_combined, TRUE);
-       u->module_combined = NULL;
+        pa_module_unload(u->module->core, u->module_combined, TRUE);
+        u->module_combined = NULL;
     }
-
-    /* Unload mono_bt sink */
-       if (u->module_mono_bt) {
-               pa_module_unload(u->module->core, u->module_mono_bt, TRUE);
-               u->module_mono_bt = NULL;
-       }
-
     return PA_HOOK_OK;
 }
 
@@ -562,25 +3696,27 @@ static pa_hook_result_t sink_unlink_post_hook_callback(pa_core *c, pa_sink *sink
     pa_assert(sink);
     pa_assert(u);
 
-    pa_log_debug("[POLICY][%s] SINK unlinked POST ================================ sink [%s][%d]", __func__, sink->name, sink->index);
+    pa_log_debug("========= sink [%s][%d]", sink->name, sink->index);
 
      /* 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 unloading sink is not bt, just return */
-       if (!policy_is_bluez (sink)) {
-               pa_log_debug("[POLICY][%s] not a bluez....return\n", __func__);
-               return PA_HOOK_OK;
-       }
+    if (!policy_is_bluez (sink)) {
+        pa_log_debug("not a bluez....return\n");
+        return PA_HOOK_OK;
+    }
 
     u->bt_off_idx = -1;
-    pa_log_debug ("[POLICY][%s] bt_off_idx is cleared to [%d]", __func__, u->bt_off_idx);
+    pa_log_debug ("bt_off_idx is cleared to [%d]", u->bt_off_idx);
 
     return PA_HOOK_OK;
 }
 
 static pa_hook_result_t sink_input_move_start_cb(pa_core *core, pa_sink_input *i, struct userdata *u) {
+    audio_return_t audio_ret = AUDIO_RET_OK;
+
     pa_core_assert_ref(core);
     pa_sink_input_assert_ref(i);
 
@@ -588,98 +3724,393 @@ static pa_hook_result_t sink_input_move_start_cb(pa_core *core, pa_sink_input *i
    if (core->state == PA_CORE_SHUTDOWN)
        return PA_HOOK_OK;
 
-    pa_log_debug ("[POLICY][%s]  sink_input_move_start_cb -------------------------------------- sink-input [%d] was sink [%s][%d] : Trying to mute!!!",
-               __func__, i->index, i->sink->name, i->sink->index);
-    pa_sink_input_set_mute(i, TRUE, FALSE);
+    pa_log_debug ("------- sink-input [%d] was sink [%s][%d] : Trying to mute!!!",
+            i->index, i->sink->name, i->sink->index);
+
+    if (AUDIO_IS_ERROR((audio_ret = policy_set_mute(u, i->index, (uint32_t)-1, AUDIO_DIRECTION_OUT, 1)))) {
+        pa_log_warn("policy_set_mute(1) for stream[%d] returns error:0x%x", i->index, audio_ret);
+    }
 
     return PA_HOOK_OK;
 }
 
 static pa_hook_result_t sink_input_move_finish_cb(pa_core *core, pa_sink_input *i, struct userdata *u) {
+    audio_return_t audio_ret = AUDIO_RET_OK;
+
     pa_core_assert_ref(core);
     pa_sink_input_assert_ref(i);
 
     /* There's no point in doing anything if the core is shut down anyway */
-   if (core->state == PA_CORE_SHUTDOWN)
-       return PA_HOOK_OK;
+    if (core->state == PA_CORE_SHUTDOWN)
+        return PA_HOOK_OK;
 
-    pa_log_debug("[POLICY][%s] sink_input_move_finish_cb -------------------------------------- sink-input [%d], sink [%s][%d], bt_off_idx [%d] : %s",
-               __func__, i->index, i->sink->name, i->sink->index, u->bt_off_idx,
-               (u->bt_off_idx == -1)? "Trying to un-mute!!!!" : "skip un-mute...");
+    pa_log_debug("------- sink-input [%d], sink [%s][%d], bt_off_idx [%d] : %s",
+            i->index, i->sink->name, i->sink->index, u->bt_off_idx,
+            (u->bt_off_idx == -1)? "Trying to un-mute!!!!" : "skip un-mute...");
 
     /* If sink input move is caused by bt sink unlink, then skip un-mute operation */
-    if (u->bt_off_idx == -1) {
-               pa_sink_input_set_mute(i, FALSE, FALSE);
+    if (u->bt_off_idx == -1 && !u->muteall) {
+        if (AUDIO_IS_ERROR((audio_ret = __update_volume(u, i->index, (uint32_t)-1, (uint32_t)-1)))) {
+            pa_log_debug("__update_volume for stream[%d] returns error:0x%x", i->index, audio_ret);
+        }
+        if (AUDIO_IS_ERROR((audio_ret = policy_set_mute(u, i->index, (uint32_t)-1, AUDIO_DIRECTION_OUT, 0)))) {
+            pa_log_debug("policy_set_mute(0) for stream[%d] returns error:0x%x", i->index, audio_ret);
+        }
     }
 
     return PA_HOOK_OK;
 }
 
-int pa__init(pa_module *m)
+static pa_hook_result_t sink_input_state_changed_hook_cb(pa_core *core, pa_sink_input *i, struct userdata *u)
+{
+    pa_sink* sink_to_move = NULL;
+    pa_sink* sink_default = NULL;
+    const char * policy = NULL;
+
+    uint32_t volume_type = 0;
+    const char *si_volume_type_str = NULL;
+    const char *si_policy_str = NULL;
+    pa_sink_input_state_t state;
+
+    pa_assert(i);
+    pa_assert(u);
+
+    if((si_volume_type_str = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) {
+        pa_atou(si_volume_type_str, &volume_type);
+
+        state = pa_sink_input_get_state(i);
+
+        switch(state) {
+            case PA_SINK_INPUT_CORKED:
+                si_policy_str = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_POLICY);
+
+                /* special case. media volume should be set using fake sink-input by fmradio*/
+                if(si_policy_str && pa_streq(si_policy_str, "fmradio"))
+                    break;
+
+#ifdef PRIMARY_VOLUME
+                __set_primary_volume(u, (void*)i, volume_type, false);
+#endif
+                break;
+            case PA_SINK_INPUT_DRAINED:
+            case PA_SINK_INPUT_RUNNING:
+#ifdef PRIMARY_VOLUME
+                __set_primary_volume(u, (void*)i, volume_type, true);
+#endif
+                break;
+            default:
+                break;
+        }
+    }
+
+    if(i->state == PA_SINK_INPUT_RUNNING) {
+        policy = pa_proplist_gets (i->proplist, PA_PROP_MEDIA_POLICY);
+
+        pa_log_info("---------------------------------------------");
+
+        /** If sink input is an UHQA sink sink input then connect it to UHQA sink if not connected to UHQA sink*/
+        if ( ( i->sample_spec.rate >= UHQA_BASE_SAMPLING_RATE) && (policy != NULL) &&
+             ( pa_streq (policy, POLICY_HIGH_LATENCY) || pa_streq (policy, POLICY_AUTO) )) {
+            char tmp_policy[100] = {0};
+
+            pa_log_info ("------------------------------------");
+
+            sprintf(tmp_policy, "%s-uhqa", policy);
+            sink_to_move = policy_select_proper_sink (u, tmp_policy, i, TRUE);
+
+            if (i->sink != sink_to_move) {
+                 if (sink_to_move) {
+                    pa_log_debug("Moving sink-input[%d] from [%s] to [%s]", i->index, i->sink->name, sink_to_move->name);
+                    pa_sink_input_move_to(i, sink_to_move, FALSE);
+                }
+            }
+        }
+
+        /** Get the normal sink and move all sink input from normal sink to UHQA sink if normal sink and UHQA sink are different*/
+        sink_default = policy_select_proper_sink (u, policy, i, TRUE);
+        if ((sink_to_move != NULL) && (sink_default != NULL) && (sink_to_move != sink_default)) {
+            pa_sink_input *si = NULL;
+            uint32_t idx;
+
+            /** Check any sink input connected to normal sink then move them to UHQA sink*/
+            PA_IDXSET_FOREACH (si, sink_default->inputs, idx) {
+                pa_log_info ("------------------------------------");
+                /* Get role (if role is filter, skip it) */
+                if (policy_is_filter (si->proplist)) {
+                    continue;
+                }
+                pa_sink_input_move_to (si,  sink_to_move, FALSE);
+            }
+        }
+    }
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sink_state_changed_hook_cb(pa_core *c, pa_object *o, struct userdata *u) {
+    return PA_HOOK_OK;
+}
+
+/* Select source for given condition */
+static pa_source* policy_select_proper_source (struct userdata *u, const char* policy)
 {
-       pa_modargs *ma = NULL;
-       struct userdata *u;
-       pa_bool_t on_hotplug = TRUE, on_rescue = TRUE;
+    pa_core *c;
+    pa_source *source = NULL, *def, *source_null;
+
+    pa_assert (u);
+    c = u->core;
+    pa_assert (c);
+    if (policy == NULL) {
+        pa_log_warn ("input param is null");
+        return NULL;
+    }
 
-       pa_assert(m);
+    def = pa_namereg_get_default_source(c);
+    if (def == NULL) {
+        pa_log_warn ("pa_namereg_get_default_source() returns null");
+        return NULL;
+    }
+
+    source_null = (pa_source *)pa_namereg_get(u->core, "null", PA_NAMEREG_SOURCE);
+    /* if default source is set as null source, we will use it */
+    if (def == source_null)
+        return def;
+
+
+    /* Select source  to */
+    if (pa_streq(policy, POLICY_VOIP)) {
+        /* NOTE: Check voip source first, if not available, use AEC source  */
+        source = policy_get_source_by_name (c, SOURCE_VOIP);
+        if (source == NULL) {
+            pa_log_info ("VOIP source is not available, try to use AEC source");
+            source = policy_get_source_by_name (c, AEC_SOURCE);
+            if (source == NULL) {
+                pa_log_warn ("AEC source is not available, set to default source");
+                source = def;
+            }
+        }
+    } else if (pa_streq(policy, POLICY_MIRRORING)) {
+        source = policy_get_source_by_name (c, SOURCE_MIRRORING);
+        if (source == NULL) {
+            pa_log_info ("MIRRORING source is not available, try to use ALSA MONITOR SOURCE");
+            source = policy_get_source_by_name (c, ALSA_MONITOR_SOURCE);
+            if (source == NULL) {
+                pa_log_warn (" ALSA MONITOR SOURCE source is not available, set to default source");
+                source = def;
+            }
+        }
+    } else if (pa_streq(policy, POLICY_LOOPBACK)) {
+        source = policy_get_source_by_name (c, ALSA_MONITOR_SOURCE);
+        if (source == NULL) {
+            pa_log_warn (" ALSA MONITOR SOURCE source is not available, set to default source");
+            source = def;
+        }
+    } else {
+        source = def;
+    }
+
+    pa_log_debug ("selected source : [%s]\n", (source)? source->name : "null");
+    return source;
+}
+
+
+/*  Called when new source-output is creating  */
+static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_output_new_data *new_data, struct userdata *u) {
+    const char *policy = NULL;
+    pa_assert(c);
+    pa_assert(new_data);
+    pa_assert(u);
+
+    if (!new_data->proplist) {
+        pa_log_debug("New stream lacks property data.");
+        return PA_HOOK_OK;
+    }
+
+    if (new_data->source) {
+        pa_log_debug("Not setting device for stream %s, because already set.", pa_strnull(pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_NAME)));
+        return PA_HOOK_OK;
+    }
+
+    /* If no policy exists, skip */
+    if (!(policy = pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_POLICY))) {
+        pa_log_debug("Not setting device for stream [%s], because it lacks policy.",
+                pa_strnull(pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_NAME)));
+        return PA_HOOK_OK;
+    }
+    pa_log_debug("Policy for stream [%s] = [%s]",
+            pa_strnull(pa_proplist_gets(new_data->proplist, PA_PROP_MEDIA_NAME)), policy);
+
+    /* Set proper source to source-output */
+    new_data->save_source= FALSE;
+    new_data->source= policy_select_proper_source (u, policy);
+
+    pa_log_debug("set source of source-input to [%s]", (new_data->source)? new_data->source->name : "null");
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t source_output_put_callback(pa_core *c, pa_source_output *o, struct userdata *u)
+{
+    pa_core_assert_ref(c);
+    pa_source_output_assert_ref(o);
+    pa_assert(u);
 
-       if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
-               pa_log("Failed to parse module arguments");
-               goto fail;
-       }
+#ifdef PRIMARY_VOLUME
+    __set_primary_volume(u, (void*)o, AUDIO_PRIMARY_VOLUME_TYPE_MAX/*source-output use PRIMARY_MAX*/, true);
+#endif
+    return PA_HOOK_OK;
+}
 
-       if (pa_modargs_get_value_boolean(ma, "on_hotplug", &on_hotplug) < 0 ||
-               pa_modargs_get_value_boolean(ma, "on_rescue", &on_rescue) < 0) {
-               pa_log("on_hotplug= and on_rescue= expect boolean arguments");
-               goto fail;
-       }
+static pa_hook_result_t source_output_unlink_post_hook_callback(pa_core *c, pa_source_output *o, struct userdata *u)
+{
+#ifdef PRIMARY_VOLUME
+    __set_primary_volume(u, (void*)o, AUDIO_PRIMARY_VOLUME_TYPE_MAX/*source-output use PRIMARY_MAX*/, false);
+#endif
+    return PA_HOOK_OK;
+}
 
-       m->userdata = u = pa_xnew0(struct userdata, 1);
-       u->core = m->core;
-       u->module = m;
-       u->on_hotplug = on_hotplug;
+int pa__init(pa_module *m)
+{
+    pa_modargs *ma = NULL;
+    struct userdata *u;
+    pa_bool_t on_hotplug = TRUE, on_rescue = TRUE, wideband = FALSE;
+    uint32_t frag_size = 0, tsched_size = 0;
 
+    pa_assert(m);
 
-       /* A little bit later than module-stream-restore */
-       u->sink_input_new_hook_slot =
-                       pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], PA_HOOK_EARLY+10, (pa_hook_cb_t) sink_input_new_hook_callback, u);
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments");
+        goto fail;
+    }
 
-       if (on_hotplug) {
-               /* A little bit later than module-stream-restore */
-               u->sink_put_hook_slot =
-                       pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE+10, (pa_hook_cb_t) sink_put_hook_callback, u);
-       }
+    if (pa_modargs_get_value_boolean(ma, "on_hotplug", &on_hotplug) < 0 ||
+        pa_modargs_get_value_boolean(ma, "on_rescue", &on_rescue) < 0) {
+        pa_log("on_hotplug= and on_rescue= expect boolean arguments");
+        goto fail;
+    }
 
-       /* sink unlink comes before sink-input unlink */
-       u->sink_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) sink_unlink_hook_callback, u);
-       u->sink_unlink_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK_POST], PA_HOOK_EARLY, (pa_hook_cb_t) sink_unlink_post_hook_callback, u);
+        if (pa_modargs_get_value_boolean(ma, "use_wideband_voice", &wideband) < 0 ||
+        pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0 ||
+        pa_modargs_get_value_u32(ma, "tsched_buffer_size", &tsched_size) < 0) {
+        pa_log("Failed to parse module arguments buffer info");
+        goto fail;
+    }
+    m->userdata = u = pa_xnew0(struct userdata, 1);
+    u->core = m->core;
+    u->module = m;
+    u->on_hotplug = on_hotplug;
+    u->wideband = wideband;
+    u->fragment_size = frag_size;
+    u->tsched_buffer_size = tsched_size;
+
+    /* A little bit later than module-stream-restore */
+    u->sink_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t)sink_state_changed_hook_cb, u);
+
+    u->sink_input_new_hook_slot =
+            pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], PA_HOOK_EARLY+10, (pa_hook_cb_t) sink_input_new_hook_callback, u);
+    u->sink_input_unlink_post_slot =
+            pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST], PA_HOOK_EARLY+10, (pa_hook_cb_t) sink_input_unlink_post_hook_callback, u);
+    u->sink_input_put_slot =
+            pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], PA_HOOK_EARLY+10, (pa_hook_cb_t) sink_input_put_callback, u);
+    u->sink_input_state_changed_slot =
+             pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], PA_HOOK_EARLY+10, (pa_hook_cb_t) sink_input_state_changed_hook_cb, u);
+
+    u->source_output_new_hook_slot =
+            pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NEW], PA_HOOK_EARLY+10, (pa_hook_cb_t) source_output_new_hook_callback, u);
+    u->source_output_unlink_post_slot =
+            pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK_POST], PA_HOOK_EARLY+10, (pa_hook_cb_t) source_output_unlink_post_hook_callback, u);
+    u->source_output_put_slot =
+            pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], PA_HOOK_EARLY+10, (pa_hook_cb_t) source_output_put_callback, u);
+
+    if (on_hotplug) {
+        /* A little bit later than module-stream-restore */
+        u->sink_put_hook_slot =
+            pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE+10, (pa_hook_cb_t) sink_put_hook_callback, u);
+    }
 
-       u->sink_input_move_start_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_start_cb, u);
-       u->sink_input_move_finish_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_finish_cb, u);
+    /* sink unlink comes before sink-input unlink */
+    u->sink_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) sink_unlink_hook_callback, u);
+    u->sink_unlink_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK_POST], PA_HOOK_EARLY, (pa_hook_cb_t) sink_unlink_post_hook_callback, u);
 
-       u->subscription = pa_subscription_new(u->core, PA_SUBSCRIPTION_MASK_SERVER, subscribe_cb, u);
+    u->sink_input_move_start_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_start_cb, u);
+    u->sink_input_move_finish_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_finish_cb, u);
 
+    u->tid = pthread_self();
+    u->defer_event = u->core->mainloop->defer_new(u->core->mainloop, defer_event_cb, u);
 
-       u->bt_off_idx = -1;     /* initial bt off sink index */
+    u->subscription = pa_subscription_new(u->core, PA_SUBSCRIPTION_MASK_SERVER | PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE, subscribe_cb, u);
 
-       u->module_mono_bt = NULL;
-       u->module_combined = NULL;
-       u->module_mono_combined = NULL;
+    pa_log_debug("subscription done");
 
+    u->bt_off_idx = -1;    /* initial bt off sink index */
+    u->module_combined = NULL;
     u->protocol = pa_native_protocol_get(m->core);
     pa_native_protocol_install_ext(u->protocol, m, extension_cb);
 
-    /* Get mono key value for init */
-       vconf_get_bool(MONO_KEY, &u->is_mono);
+#ifdef PRIMARY_VOLUME
+    vconf_set_int (VCONFKEY_SOUND_PRIMARY_VOLUME_TYPE, -1);
+#endif
+
+    /* Load library & init audio mgr */
+    u->audio_mgr.dl_handle = dlopen(LIB_TIZEN_AUDIO, RTLD_NOW);
+    if (u->audio_mgr.dl_handle) {
+        u->audio_mgr.intf.init = dlsym(u->audio_mgr.dl_handle, "audio_init");
+        u->audio_mgr.intf.deinit = dlsym(u->audio_mgr.dl_handle, "audio_deinit");
+        u->audio_mgr.intf.reset = dlsym(u->audio_mgr.dl_handle, "audio_reset");
+        u->audio_mgr.intf.set_callback = dlsym(u->audio_mgr.dl_handle, "audio_set_callback");
+        u->audio_mgr.intf.get_volume_level_max = dlsym(u->audio_mgr.dl_handle, "audio_get_volume_level_max");
+        u->audio_mgr.intf.get_volume_level = dlsym(u->audio_mgr.dl_handle, "audio_get_volume_level");
+        u->audio_mgr.intf.get_volume_value = dlsym(u->audio_mgr.dl_handle, "audio_get_volume_value");
+        u->audio_mgr.intf.set_volume_level = dlsym(u->audio_mgr.dl_handle, "audio_set_volume_level");
+        u->audio_mgr.intf.set_volume_value = dlsym(u->audio_mgr.dl_handle, "audio_set_volume_value");
+        u->audio_mgr.intf.get_gain_value = dlsym(u->audio_mgr.dl_handle, "audio_get_gain_value");
+        u->audio_mgr.intf.get_mute = dlsym(u->audio_mgr.dl_handle, "audio_get_mute");
+        u->audio_mgr.intf.set_mute = dlsym(u->audio_mgr.dl_handle, "audio_set_mute");
+        u->audio_mgr.intf.alsa_pcm_open = dlsym(u->audio_mgr.dl_handle, "audio_alsa_pcm_open");
+        u->audio_mgr.intf.alsa_pcm_close = dlsym(u->audio_mgr.dl_handle, "audio_alsa_pcm_close");
+        u->audio_mgr.intf.set_session = dlsym(u->audio_mgr.dl_handle, "audio_set_session");
+        u->audio_mgr.intf.set_route = dlsym(u->audio_mgr.dl_handle, "audio_set_route");
+        u->audio_mgr.intf.set_mixer_value_string = dlsym(u->audio_mgr.dl_handle, "audio_set_mixer_value_string");
+
+        if (u->audio_mgr.intf.init) {
+            if (u->audio_mgr.intf.init(&u->audio_mgr.data, (void *)u) != AUDIO_RET_OK) {
+                pa_log_error("audio_mgr init failed");
+            }
+        }
+
+        pa_shared_set(u->core, "tizen-audio-data", u->audio_mgr.data);
+        pa_shared_set(u->core, "tizen-audio-interface", &u->audio_mgr.intf);
+
+        if (u->audio_mgr.intf.set_callback) {
+            audio_cb_interface_t cb_interface;
+
+            cb_interface.load_device = __load_device_callback;
+            cb_interface.open_device = __open_device_callback;
+            cb_interface.close_all_devices = __close_all_devices_callback;
+            cb_interface.close_device = __close_device_callback;
+            cb_interface.unload_device = __unload_device_callback;
+            u->audio_mgr.intf.set_callback(u->audio_mgr.data, &cb_interface);
+        }
+        
+    } else {
+        pa_log_error("open audio_mgr failed :%s", dlerror());
+    }
 
-       pa_log_info("policy module is loaded\n");
+    __load_dump_config(u);
 
-       return 0;
+    pa_log_info("policy module is loaded\n");
+
+    if (ma)
+        pa_modargs_free(ma);
+
+    return 0;
 
 fail:
-       pa__done(m);
+    if (ma)
+        pa_modargs_free(ma);
 
-       return -1;
+    pa__done(m);
+
+    return -1;
 }
 
 void pa__done(pa_module *m)
@@ -695,15 +4126,28 @@ void pa__done(pa_module *m)
         pa_hook_slot_free(u->sink_input_new_hook_slot);
     if (u->sink_put_hook_slot)
         pa_hook_slot_free(u->sink_put_hook_slot);
+    if(u->sink_input_state_changed_slot)
+         pa_hook_slot_free(u->sink_input_state_changed_slot);
     if (u->subscription)
         pa_subscription_free(u->subscription);
     if (u->protocol) {
         pa_native_protocol_remove_ext(u->protocol, m);
         pa_native_protocol_unref(u->protocol);
     }
+    if (u->source_output_new_hook_slot)
+        pa_hook_slot_free(u->source_output_new_hook_slot);
 
-    pa_xfree(u);
+    /* Deinit audio mgr & unload library */
+    if (u->audio_mgr.intf.deinit) {
+        if (u->audio_mgr.intf.deinit(&u->audio_mgr.data) != AUDIO_RET_OK) {
+            pa_log_error("audio_mgr deinit failed");
+        }
+    }
+    if (u->audio_mgr.dl_handle) {
+        dlclose(u->audio_mgr.dl_handle);
+    }
 
+    pa_xfree(u);
 
-       pa_log_info("policy module is unloaded\n");
+    pa_log_info("policy module is unloaded\n");
 }
diff --git a/src/modules/module-position-event-sounds-symdef.h b/src/modules/module-position-event-sounds-symdef.h
deleted file mode 100644 (file)
index ea60485..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulepositioneventsoundssymdeffoo
-#define foomodulepositioneventsoundssymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_position_event_sounds_LTX_pa__init
-#define pa__done module_position_event_sounds_LTX_pa__done
-#define pa__get_author module_position_event_sounds_LTX_pa__get_author
-#define pa__get_description module_position_event_sounds_LTX_pa__get_description
-#define pa__get_usage module_position_event_sounds_LTX_pa__get_usage
-#define pa__get_version module_position_event_sounds_LTX_pa__get_version
-#define pa__get_deprecated module_position_event_sounds_LTX_pa__get_deprecated
-#define pa__load_once module_position_event_sounds_LTX_pa__load_once
-#define pa__get_n_used module_position_event_sounds_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index ee4c8c8..c298e74 100644 (file)
 #endif
 
 #include <unistd.h>
-#include <string.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <ctype.h>
 
 #include <pulse/xmalloc.h>
 #include <pulse/volume.h>
 #include <pulse/channelmap.h>
 
-#include <pulsecore/core-error.h>
 #include <pulsecore/module.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/modargs.h>
@@ -55,6 +52,7 @@ static const char* const valid_modargs[] = {
 
 struct userdata {
     pa_hook_slot *sink_input_fixate_hook_slot;
+    const char *name;
 };
 
 static int parse_pos(const char *pos, double *f) {
@@ -90,7 +88,7 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *core, pa_sink_i
     if ((id = pa_proplist_gets(data->proplist, PA_PROP_EVENT_ID))) {
 
         /* The test sounds should never be positioned in space, since
-         * they might be trigered themselves to configure the speakers
+         * they might be triggered themselves to configure the speakers
          * in space, which we don't want to mess up. */
 
         if (pa_startswith(id, "audio-channel-"))
@@ -135,7 +133,7 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *core, pa_sink_i
     }
 
     pa_log_debug("Final volume factor %s.", pa_cvolume_snprint(t, sizeof(t), &v));
-    pa_sink_input_new_data_apply_volume_factor_sink(data, &v);
+    pa_sink_input_new_data_add_volume_factor_sink(data, u->name, &v);
 
     return PA_HOOK_OK;
 }
@@ -155,6 +153,7 @@ int pa__init(pa_module*m) {
     u->sink_input_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_fixate_hook_callback, u);
 
     pa_modargs_free(ma);
+    u->name = m->name;
 
     return 0;
 
@@ -164,7 +163,7 @@ fail:
     if (ma)
         pa_modargs_free(ma);
 
-    return  -1;
+    return -1;
 }
 
 void pa__done(pa_module*m) {
index 5b351d1..1b7f6ed 100644 (file)
 #include <config.h>
 #endif
 
-#include <string.h>
 #include <errno.h>
 #include <stdio.h>
 #include <unistd.h>
-#include <limits.h>
 
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
 
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/winsock.h>
 #include <pulsecore/core-error.h>
 #include <pulsecore/module.h>
+#include <pulsecore/socket.h>
 #include <pulsecore/socket-server.h>
 #include <pulsecore/socket-util.h>
 #include <pulsecore/core-util.h>
@@ -52,6 +44,7 @@
 #include <pulsecore/log.h>
 #include <pulsecore/native-common.h>
 #include <pulsecore/creds.h>
+#include <pulsecore/arpa-inet.h>
 
 #ifdef USE_TCP_SOCKETS
 #define SOCKET_DESCRIPTION "(TCP sockets)"
   PA_MODULE_DESCRIPTION("Native protocol "SOCKET_DESCRIPTION);
   PA_MODULE_USAGE("auth-anonymous=<don't check for cookies?> "
                   "auth-cookie=<path to cookie file> "
-                  "auth-cookie-enabled=<enable cookie authentification? "
+                  "auth-cookie-enabled=<enable cookie authentication?> "
                   AUTH_USAGE
                   SOCKET_USAGE);
 #elif defined(USE_PROTOCOL_ESOUND)
                   "source=<source to connect to> "
                   "auth-anonymous=<don't verify cookies?> "
                   "auth-cookie=<path to cookie file> "
-                  "auth-cookie-enabled=<enable cookie authentification? "
+                  "auth-cookie-enabled=<enable cookie authentication?> "
                   AUTH_USAGE
                   SOCKET_USAGE);
 #else
@@ -246,6 +239,7 @@ int pa__init(pa_module*m) {
 
 #if defined(USE_TCP_SOCKETS)
     uint32_t port = IPV4_PORT;
+    pa_bool_t port_fallback = TRUE;
     const char *listen_on;
 #else
     int r;
@@ -293,6 +287,10 @@ int pa__init(pa_module*m) {
 #endif
 
 #if defined(USE_TCP_SOCKETS)
+
+    if (pa_in_system_mode() || pa_modargs_get_value(ma, "port", NULL))
+        port_fallback = FALSE;
+
     if (pa_modargs_get_value_u32(ma, "port", &port) < 0 || port < 1 || port > 0xFFFF) {
         pa_log("port= expects a numerical argument between 1 and 65535.");
         goto fail;
@@ -302,14 +300,14 @@ int pa__init(pa_module*m) {
 
     if (listen_on) {
 #  ifdef HAVE_IPV6
-        u->socket_server_ipv6 = pa_socket_server_new_ipv6_string(m->core->mainloop, listen_on, (uint16_t) port, TCPWRAP_SERVICE);
+        u->socket_server_ipv6 = pa_socket_server_new_ipv6_string(m->core->mainloop, listen_on, (uint16_t) port, port_fallback, TCPWRAP_SERVICE);
 #  endif
-        u->socket_server_ipv4 = pa_socket_server_new_ipv4_string(m->core->mainloop, listen_on, (uint16_t) port, TCPWRAP_SERVICE);
+        u->socket_server_ipv4 = pa_socket_server_new_ipv4_string(m->core->mainloop, listen_on, (uint16_t) port, port_fallback, TCPWRAP_SERVICE);
     } else {
 #  ifdef HAVE_IPV6
-        u->socket_server_ipv6 = pa_socket_server_new_ipv6_any(m->core->mainloop, (uint16_t) port, TCPWRAP_SERVICE);
+        u->socket_server_ipv6 = pa_socket_server_new_ipv6_any(m->core->mainloop, (uint16_t) port, port_fallback, TCPWRAP_SERVICE);
 #  endif
-        u->socket_server_ipv4 = pa_socket_server_new_ipv4_any(m->core->mainloop, (uint16_t) port, TCPWRAP_SERVICE);
+        u->socket_server_ipv4 = pa_socket_server_new_ipv4_any(m->core->mainloop, (uint16_t) port, port_fallback, TCPWRAP_SERVICE);
     }
 
 #  ifdef HAVE_IPV6
@@ -339,7 +337,7 @@ int pa__init(pa_module*m) {
     /* This socket doesn't reside in our own runtime dir but in
      * /tmp/.esd/, hence we have to create the dir first */
 
-    if (pa_make_secure_parent_dir(u->socket_path, pa_in_system_mode() ? 0755U : 0700U, (uid_t)-1, (gid_t)-1) < 0) {
+    if (pa_make_secure_parent_dir(u->socket_path, pa_in_system_mode() ? 0755U : 0700U, (uid_t)-1, (gid_t)-1, FALSE) < 0) {
         pa_log("Failed to create socket directory '%s': %s\n", u->socket_path, pa_cstrerror(errno));
         goto fail;
     }
diff --git a/src/modules/module-remap-sink-symdef.h b/src/modules/module-remap-sink-symdef.h
deleted file mode 100644 (file)
index 01c2161..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleremapsinksymdeffoo
-#define foomoduleremapsinksymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_remap_sink_LTX_pa__init
-#define pa__done module_remap_sink_LTX_pa__done
-#define pa__get_author module_remap_sink_LTX_pa__get_author
-#define pa__get_description module_remap_sink_LTX_pa__get_description
-#define pa__get_usage module_remap_sink_LTX_pa__get_usage
-#define pa__get_version module_remap_sink_LTX_pa__get_version
-#define pa__get_deprecated module_remap_sink_LTX_pa__get_deprecated
-#define pa__load_once module_remap_sink_LTX_pa__load_once
-#define pa__get_n_used module_remap_sink_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 43748bd..3d9567b 100644 (file)
 
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/core-error.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/sink.h>
 #include <pulsecore/module.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/log.h>
-#include <pulsecore/thread.h>
-#include <pulsecore/thread-mq.h>
 #include <pulsecore/rtpoll.h>
 
 #include "module-remap-sink-symdef.h"
@@ -188,6 +185,8 @@ static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
     pa_sink_input_assert_ref(i);
     pa_assert_se(u = i->userdata);
 
+    /* FIXME: Too small max_rewind:
+     * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
     pa_sink_set_max_rewind_within_thread(u->sink, nbytes);
 }
 
@@ -244,6 +243,9 @@ static void sink_input_attach_cb(pa_sink_input *i) {
     pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
     pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
     pa_sink_set_max_request_within_thread(u->sink, pa_sink_input_get_max_request(i));
+
+    /* FIXME: Too small max_rewind:
+     * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
     pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i));
 
     pa_sink_attach_within_thread(u->sink);
@@ -288,16 +290,6 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s
 }
 
 /* Called from main context */
-static pa_bool_t sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
-    struct userdata *u;
-
-    pa_sink_input_assert_ref(i);
-    pa_assert_se(u = i->userdata);
-
-    return u->sink != dest;
-}
-
-/* Called from main context */
 static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
     struct userdata *u;
 
@@ -419,7 +411,8 @@ int pa__init(pa_module*m) {
     pa_sink_input_new_data_init(&sink_input_data);
     sink_input_data.driver = __FILE__;
     sink_input_data.module = m;
-    sink_input_data.sink = master;
+    pa_sink_input_new_data_set_sink(&sink_input_data, master, FALSE);
+    sink_input_data.origin_sink = u->sink;
     pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Remapped Stream");
     pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
     pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss);
@@ -442,10 +435,11 @@ int pa__init(pa_module*m) {
     u->sink_input->detach = sink_input_detach_cb;
     u->sink_input->kill = sink_input_kill_cb;
     u->sink_input->state_change = sink_input_state_change_cb;
-    u->sink_input->may_move_to = sink_input_may_move_to_cb;
     u->sink_input->moving = sink_input_moving_cb;
     u->sink_input->userdata = u;
 
+    u->sink->input_to_master = u->sink_input;
+
     pa_sink_put(u->sink);
     pa_sink_input_put(u->sink_input);
 
diff --git a/src/modules/module-remap-source.c b/src/modules/module-remap-source.c
new file mode 100644 (file)
index 0000000..c47d9b0
--- /dev/null
@@ -0,0 +1,435 @@
+/***
+    This file is part of PulseAudio.
+
+    Copyright 2013 bct electronic GmbH
+    Contributor: Stefan Huber <s.huber@bct-electronic.com>
+
+
+    PulseAudio is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.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, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+    USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/i18n.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/namereg.h>
+#include <pulsecore/module.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/log.h>
+#include <pulsecore/rtpoll.h>
+#include <pulsecore/sample-util.h>
+#include <pulsecore/ltdl-helper.h>
+#include <pulsecore/mix.h>
+
+#include "module-remap-source-symdef.h"
+
+PA_MODULE_AUTHOR("Stefan Huber");
+PA_MODULE_DESCRIPTION("Virtual channel remapping source");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(false);
+PA_MODULE_USAGE(
+        "source_name=<name for the source> "
+        "source_properties=<properties for the source> "
+        "master=<name of source to filter> "
+        "master_channel_map=<channel map> "
+        "format=<sample format> "
+        "rate=<sample rate> "
+        "channels=<number of channels> "
+        "channel_map=<channel map> "
+        "remix=<remix channels?>");
+
+struct userdata {
+    pa_module *module;
+
+    pa_source *source;
+    pa_source_output *source_output;
+
+    bool auto_desc;
+};
+
+static const char* const valid_modargs[] = {
+    "source_name",
+    "source_properties",
+    "master",
+    "master_channel_map",
+    "format",
+    "rate",
+    "channels",
+    "channel_map",
+    "remix",
+    NULL
+};
+
+/* 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;
+
+    switch (code) {
+
+        case PA_SOURCE_MESSAGE_GET_LATENCY:
+
+            /* The source is _put() before the source output is, so let's
+             * make sure we don't access it in that time. Also, the
+             * source output is first shut down, the source second. */
+            if (!PA_SOURCE_IS_LINKED(u->source->thread_info.state) ||
+                !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->thread_info.state)) {
+                *((pa_usec_t*) data) = 0;
+                return 0;
+            }
+
+            *((pa_usec_t*) data) =
+
+                /* Get the latency of the master source */
+                pa_source_get_latency_within_thread(u->source_output->source) +
+                /* Add the latency internal to our source output on top */
+                pa_bytes_to_usec(pa_memblockq_get_length(u->source_output->thread_info.delay_memblockq), &u->source_output->source->sample_spec);
+
+            return 0;
+    }
+
+    return pa_source_process_msg(o, code, data, offset, chunk);
+}
+
+/* Called from main context */
+static int source_set_state_cb(pa_source *s, pa_source_state_t state) {
+    struct userdata *u;
+
+    pa_source_assert_ref(s);
+    pa_assert_se(u = s->userdata);
+
+    if (!PA_SOURCE_IS_LINKED(state) ||
+        !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
+        return 0;
+
+    pa_source_output_cork(u->source_output, state == PA_SOURCE_SUSPENDED);
+    return 0;
+}
+
+/* Called from I/O thread context */
+static void source_update_requested_latency_cb(pa_source *s) {
+    struct userdata *u;
+
+    pa_source_assert_ref(s);
+    pa_assert_se(u = s->userdata);
+
+    if (!PA_SOURCE_IS_LINKED(u->source->thread_info.state) ||
+        !PA_SOURCE_OUTPUT_IS_LINKED(u->source_output->thread_info.state))
+        return;
+
+    pa_log_debug("Source update requested latency.");
+
+    /* Just hand this one over to the master source */
+    pa_source_output_set_requested_latency_within_thread(
+            u->source_output,
+            pa_source_get_requested_latency_within_thread(s));
+}
+
+/* Called from output thread context */
+static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) {
+    struct userdata *u;
+
+    pa_source_output_assert_ref(o);
+    pa_source_output_assert_io_context(o);
+    pa_assert_se(u = o->userdata);
+
+    if (!PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output))) {
+        pa_log("push when no link?");
+        return;
+    }
+
+    pa_source_post(u->source, chunk);
+}
+
+/* Called from output thread context */
+static void source_output_process_rewind_cb(pa_source_output *o, size_t nbytes) {
+    struct userdata *u;
+
+    pa_source_output_assert_ref(o);
+    pa_source_output_assert_io_context(o);
+    pa_assert_se(u = o->userdata);
+
+    pa_source_process_rewind(u->source, nbytes);
+}
+
+/* Called from output thread context */
+static void source_output_detach_cb(pa_source_output *o) {
+    struct userdata *u;
+
+    pa_source_output_assert_ref(o);
+    pa_source_output_assert_io_context(o);
+    pa_assert_se(u = o->userdata);
+
+    pa_source_detach_within_thread(u->source);
+
+    pa_source_set_rtpoll(u->source, NULL);
+}
+
+/* Called from output thread context */
+static void source_output_attach_cb(pa_source_output *o) {
+    struct userdata *u;
+
+    pa_source_output_assert_ref(o);
+    pa_source_output_assert_io_context(o);
+    pa_assert_se(u = o->userdata);
+
+    pa_source_set_rtpoll(u->source, o->source->thread_info.rtpoll);
+    pa_source_set_latency_range_within_thread(u->source, o->source->thread_info.min_latency, o->source->thread_info.max_latency);
+    pa_source_set_fixed_latency_within_thread(u->source, o->source->thread_info.fixed_latency);
+    pa_source_set_max_rewind_within_thread(u->source, pa_source_output_get_max_rewind(o));
+
+    pa_source_attach_within_thread(u->source);
+}
+
+/* Called from main thread */
+static void source_output_kill_cb(pa_source_output *o) {
+    struct userdata *u;
+
+    pa_source_output_assert_ref(o);
+    pa_assert_ctl_context();
+    pa_assert_se(u = o->userdata);
+
+    /* The order here matters! We first kill the source output, followed
+     * by the source. That means the source callbacks must be protected
+     * against an unconnected source output! */
+    pa_source_output_unlink(u->source_output);
+    pa_source_unlink(u->source);
+
+    pa_source_output_unref(u->source_output);
+    u->source_output = NULL;
+
+    pa_source_unref(u->source);
+    u->source = NULL;
+
+    pa_module_unload_request(u->module, true);
+}
+
+/* Called from output thread context */
+static void source_output_state_change_cb(pa_source_output *o, pa_source_output_state_t state) {
+    struct userdata *u;
+
+    pa_source_output_assert_ref(o);
+    pa_source_output_assert_io_context(o);
+    pa_assert_se(u = o->userdata);
+
+    pa_log_debug("Source output %d state %d.", o->index, state);
+}
+
+/* Called from main thread */
+static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
+    struct userdata *u;
+
+    pa_source_output_assert_ref(o);
+    pa_assert_ctl_context();
+    pa_assert_se(u = o->userdata);
+
+    if (dest) {
+        pa_source_set_asyncmsgq(u->source, dest->asyncmsgq);
+        pa_source_update_flags(u->source, PA_SOURCE_LATENCY|PA_SOURCE_DYNAMIC_LATENCY, dest->flags);
+    } else
+        pa_source_set_asyncmsgq(u->source, NULL);
+
+    if (u->auto_desc && dest) {
+        const char *k;
+        pa_proplist *pl;
+
+        pl = pa_proplist_new();
+        k = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
+        pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "Remapped %s", k ? k : dest->name);
+
+        pa_source_update_proplist(u->source, PA_UPDATE_REPLACE, pl);
+        pa_proplist_free(pl);
+    }
+}
+
+int pa__init(pa_module*m) {
+    struct userdata *u;
+    pa_sample_spec ss;
+    pa_channel_map source_map, stream_map;
+    pa_modargs *ma;
+    pa_source *master;
+    pa_source_output_new_data source_output_data;
+    pa_source_new_data source_data;
+    bool remix = true;
+
+    pa_assert(m);
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments.");
+        goto fail;
+    }
+
+    if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "master", NULL), PA_NAMEREG_SOURCE))) {
+        pa_log("Master source not found.");
+        goto fail;
+    }
+
+    ss = master->sample_spec;
+    source_map = master->channel_map;
+    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &source_map, PA_CHANNEL_MAP_DEFAULT) < 0) {
+        pa_log("Invalid sample format specification or channel map.");
+        goto fail;
+    }
+
+    stream_map = source_map;
+    if (pa_modargs_get_channel_map(ma, "master_channel_map", &stream_map) < 0) {
+        pa_log("Invalid master channel map.");
+        goto fail;
+    }
+
+    if (stream_map.channels != ss.channels) {
+        pa_log("Number of channels doesn't match.");
+        goto fail;
+    }
+
+    if (pa_channel_map_equal(&stream_map, &master->channel_map))
+        pa_log_warn("No remapping configured, proceeding nonetheless!");
+
+    if (pa_modargs_get_value_boolean(ma, "remix", &remix) < 0) {
+        pa_log("Invalid boolean remix parameter.");
+        goto fail;
+    }
+
+    u = pa_xnew0(struct userdata, 1);
+    u->module = m;
+    m->userdata = u;
+
+    /* Create source */
+    pa_source_new_data_init(&source_data);
+    source_data.driver = __FILE__;
+    source_data.module = m;
+    if (!(source_data.name = pa_xstrdup(pa_modargs_get_value(ma, "source_name", NULL))))
+        source_data.name = pa_sprintf_malloc("%s.remapped", master->name);
+    pa_source_new_data_set_sample_spec(&source_data, &ss);
+    pa_source_new_data_set_channel_map(&source_data, &source_map);
+    pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, master->name);
+    pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
+
+    if (pa_modargs_get_proplist(ma, "source_properties", source_data.proplist, PA_UPDATE_REPLACE) < 0) {
+        pa_log("Invalid properties.");
+        pa_source_new_data_done(&source_data);
+        goto fail;
+    }
+
+    if ((u->auto_desc = !pa_proplist_contains(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
+        const char *k;
+
+        k = pa_proplist_gets(master->proplist, PA_PROP_DEVICE_DESCRIPTION);
+        pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Remapped %s", k ? k : master->name);
+    }
+
+    u->source = pa_source_new(m->core, &source_data, master->flags & (PA_SOURCE_LATENCY|PA_SOURCE_DYNAMIC_LATENCY));
+    pa_source_new_data_done(&source_data);
+
+    if (!u->source) {
+        pa_log("Failed to create source.");
+        goto fail;
+    }
+
+    u->source->parent.process_msg = source_process_msg_cb;
+    u->source->set_state = source_set_state_cb;
+    u->source->update_requested_latency = source_update_requested_latency_cb;
+
+    u->source->userdata = u;
+
+    pa_source_set_asyncmsgq(u->source, master->asyncmsgq);
+
+    /* Create source output */
+    pa_source_output_new_data_init(&source_output_data);
+    source_output_data.driver = __FILE__;
+    source_output_data.module = m;
+    pa_source_output_new_data_set_source(&source_output_data, master, false);
+    source_output_data.destination_source = u->source;
+
+    pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_NAME, "Remapped Stream");
+    pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
+    pa_source_output_new_data_set_sample_spec(&source_output_data, &ss);
+    pa_source_output_new_data_set_channel_map(&source_output_data, &stream_map);
+    source_output_data.flags = remix ? 0 : PA_SOURCE_OUTPUT_NO_REMIX;
+
+    pa_source_output_new(&u->source_output, m->core, &source_output_data);
+    pa_source_output_new_data_done(&source_output_data);
+
+    if (!u->source_output)
+        goto fail;
+
+    u->source_output->push = source_output_push_cb;
+    u->source_output->process_rewind = source_output_process_rewind_cb;
+    u->source_output->kill = source_output_kill_cb;
+    u->source_output->attach = source_output_attach_cb;
+    u->source_output->detach = source_output_detach_cb;
+    u->source_output->state_change = source_output_state_change_cb;
+    u->source_output->moving = source_output_moving_cb;
+    u->source_output->userdata = u;
+
+    u->source->output_from_master = u->source_output;
+
+    pa_source_put(u->source);
+    pa_source_output_put(u->source_output);
+
+    pa_modargs_free(ma);
+
+    return 0;
+
+fail:
+    if (ma)
+        pa_modargs_free(ma);
+
+    pa__done(m);
+
+    return -1;
+}
+
+int pa__get_n_used(pa_module *m) {
+    struct userdata *u;
+
+    pa_assert(m);
+    pa_assert_se(u = m->userdata);
+
+    return pa_source_linked_by(u->source);
+}
+
+void pa__done(pa_module*m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    /* See comments in source_output_kill_cb() above regarding
+     * destruction order! */
+
+    if (u->source_output)
+        pa_source_output_unlink(u->source_output);
+
+    if (u->source)
+        pa_source_unlink(u->source);
+
+    if (u->source_output)
+        pa_source_output_unref(u->source_output);
+
+    if (u->source)
+        pa_source_unref(u->source);
+
+    pa_xfree(u);
+}
diff --git a/src/modules/module-rescue-streams-symdef.h b/src/modules/module-rescue-streams-symdef.h
deleted file mode 100644 (file)
index c38bd1f..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulerescuestreamssymdeffoo
-#define foomodulerescuestreamssymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_rescue_streams_LTX_pa__init
-#define pa__done module_rescue_streams_LTX_pa__done
-#define pa__get_author module_rescue_streams_LTX_pa__get_author
-#define pa__get_description module_rescue_streams_LTX_pa__get_description
-#define pa__get_usage module_rescue_streams_LTX_pa__get_usage
-#define pa__get_version module_rescue_streams_LTX_pa__get_version
-#define pa__get_deprecated module_rescue_streams_LTX_pa__get_deprecated
-#define pa__load_once module_rescue_streams_LTX_pa__load_once
-#define pa__get_n_used module_rescue_streams_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 722d84b..8b35809 100644 (file)
@@ -108,7 +108,7 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, voi
             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("Sucessfully moved sink input %u \"%s\" to %s.", i->index,
+            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);
     }
 
@@ -134,7 +134,7 @@ static pa_hook_result_t sink_input_move_fail_hook_callback(pa_core *c, pa_sink_i
         return PA_HOOK_OK;
 
     } else {
-        pa_log_info("Sucessfully moved sink input %u \"%s\" to %s.", i->index,
+        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;
     }
@@ -159,7 +159,7 @@ static pa_source* find_evacuation_source(pa_core *c, pa_source_output *o, pa_sou
         if (target == skip)
             continue;
 
-        if (!target->monitor_of != !skip->monitor_of)
+        if (skip && !target->monitor_of != !skip->monitor_of)
             continue;
 
         if (!PA_SOURCE_IS_LINKED(pa_source_get_state(target)))
@@ -199,7 +199,7 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
             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("Sucessfully moved source output %u \"%s\" to %s.", o->index,
+            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);
     }
 
@@ -225,7 +225,7 @@ static pa_hook_result_t source_output_move_fail_hook_callback(pa_core *c, pa_sou
         return PA_HOOK_OK;
 
     } else {
-        pa_log_info("Sucessfully moved source input %u \"%s\" to %s.", i->index,
+        pa_log_info("Successfully moved source input %u \"%s\" to %s.", i->index,
                     pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), target->name);
         return PA_HOOK_STOP;
     }
similarity index 57%
rename from src/modules/module-cork-music-on-phone.c
rename to src/modules/module-role-cork.c
index d3a2b00..6e6ea72 100644 (file)
@@ -23,6 +23,8 @@
 #include <config.h>
 #endif
 
+#include <pulse/xmalloc.h>
+
 #include <pulsecore/macro.h>
 #include <pulsecore/hashmap.h>
 #include <pulsecore/hook-list.h>
 #include <pulsecore/sink-input.h>
 #include <pulsecore/modargs.h>
 
-#include "module-cork-music-on-phone-symdef.h"
+#include "module-role-cork-symdef.h"
 
 PA_MODULE_AUTHOR("Lennart Poettering");
-PA_MODULE_DESCRIPTION("Mute or cork music while a phone stream exists");
+PA_MODULE_DESCRIPTION("Mute & cork streams with certain roles while others exist");
 PA_MODULE_VERSION(PACKAGE_VERSION);
 PA_MODULE_LOAD_ONCE(TRUE);
+PA_MODULE_USAGE(
+        "trigger_roles=<Comma separated list of roles which will trigger a cork> "
+        "cork_roles=<Comma separated list of roles which will be corked> "
+        "global=<Should we operate globally or only inside the same device?>");
 
 static const char* const valid_modargs[] = {
+    "trigger_roles",
+    "cork_roles",
+    "global",
     NULL
 };
 
 struct userdata {
     pa_core *core;
     pa_hashmap *cork_state;
+    pa_idxset *trigger_roles;
+    pa_idxset *cork_roles;
+    pa_bool_t global:1;
     pa_hook_slot
         *sink_input_put_slot,
         *sink_input_unlink_slot,
@@ -52,9 +64,12 @@ struct userdata {
         *sink_input_move_finish_slot;
 };
 
-static pa_bool_t shall_cork(pa_sink *s, pa_sink_input *ignore) {
+static pa_bool_t shall_cork(struct userdata *u, pa_sink *s, pa_sink_input *ignore) {
     pa_sink_input *j;
-    uint32_t idx;
+    uint32_t idx, role_idx;
+    const char *trigger_role;
+
+    pa_assert(u);
     pa_sink_assert_ref(s);
 
     for (j = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); j; j = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx))) {
@@ -66,22 +81,28 @@ static pa_bool_t shall_cork(pa_sink *s, pa_sink_input *ignore) {
         if (!(role = pa_proplist_gets(j->proplist, PA_PROP_MEDIA_ROLE)))
             continue;
 
-        if (pa_streq(role, "phone"))
-            return TRUE;
+        PA_IDXSET_FOREACH(trigger_role, u->trigger_roles, role_idx) {
+            if (pa_streq(role, trigger_role)) {
+                pa_log_debug("Found a '%s' stream that will trigger the auto-cork.", trigger_role);
+                return TRUE;
+            }
+        }
     }
 
     return FALSE;
 }
 
-static void apply_cork(struct userdata *u, pa_sink *s, pa_sink_input *ignore, pa_bool_t cork) {
+static inline void apply_cork_to_sink(struct userdata *u, pa_sink *s, pa_sink_input *ignore, pa_bool_t cork) {
     pa_sink_input *j;
-    uint32_t idx;
+    uint32_t idx, role_idx;
+    const char *cork_role;
+    pa_bool_t trigger = FALSE;
 
     pa_assert(u);
     pa_sink_assert_ref(s);
 
     for (j = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); j; j = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx))) {
-        pa_bool_t corked;
+        pa_bool_t corked, muted, corked_here;
         const char *role;
 
         if (j == ignore)
@@ -90,27 +111,48 @@ static void apply_cork(struct userdata *u, pa_sink *s, pa_sink_input *ignore, pa
         if (!(role = pa_proplist_gets(j->proplist, PA_PROP_MEDIA_ROLE)))
             continue;
 
-        if (!pa_streq(role, "video") &&
-            !pa_streq(role, "music"))
+        PA_IDXSET_FOREACH(cork_role, u->cork_roles, role_idx) {
+            if ((trigger = pa_streq(role, cork_role)))
+                break;
+        }
+        if (!trigger)
             continue;
 
-        corked = !!pa_hashmap_get(u->cork_state, j);
+        corked = (pa_sink_input_get_state(j) == PA_SINK_INPUT_CORKED);
+        muted = pa_sink_input_get_mute(j);
+        corked_here = !!pa_hashmap_get(u->cork_state, j);
 
-        if (cork && !corked) {
-            pa_hashmap_put(u->cork_state, j, PA_INT_TO_PTR(1));
+        if (cork && !corked && !muted) {
+            pa_log_debug("Found a '%s' stream that should be corked/muted.", cork_role);
+            if (!corked_here)
+                pa_hashmap_put(u->cork_state, j, PA_INT_TO_PTR(1));
             pa_sink_input_set_mute(j, TRUE, FALSE);
             pa_sink_input_send_event(j, PA_STREAM_EVENT_REQUEST_CORK, NULL);
         } else if (!cork) {
             pa_hashmap_remove(u->cork_state, j);
 
-            if (corked) {
-                pa_sink_input_set_mute(j, FALSE, FALSE);
-                pa_sink_input_send_event(j, PA_STREAM_EVENT_REQUEST_UNCORK, NULL);
+            if (corked_here && (corked || muted)) {
+                pa_log_debug("Found a '%s' stream that should be uncorked/unmuted.", cork_role);
+                if (muted)
+                    pa_sink_input_set_mute(j, FALSE, FALSE);
+                if (corked)
+                    pa_sink_input_send_event(j, PA_STREAM_EVENT_REQUEST_UNCORK, NULL);
             }
         }
     }
 }
 
+static void apply_cork(struct userdata *u, pa_sink *s, pa_sink_input *ignore, pa_bool_t cork) {
+    pa_assert(u);
+
+    if (u->global) {
+        uint32_t idx;
+        PA_IDXSET_FOREACH(s, u->core->sinks, idx)
+            apply_cork_to_sink(u, s, ignore, cork);
+    } else
+        apply_cork_to_sink(u, s, ignore, cork);
+}
+
 static pa_hook_result_t process(struct userdata *u, pa_sink_input *i, pa_bool_t create) {
     pa_bool_t cork = FALSE;
     const char *role;
@@ -124,12 +166,10 @@ static pa_hook_result_t process(struct userdata *u, pa_sink_input *i, pa_bool_t
     if (!(role = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_ROLE)))
         return PA_HOOK_OK;
 
-    if (!pa_streq(role, "phone") &&
-        !pa_streq(role, "music") &&
-        !pa_streq(role, "video"))
+    if (!i->sink)
         return PA_HOOK_OK;
 
-    cork = shall_cork(i->sink, create ? NULL : i);
+    cork = shall_cork(u, i->sink, create ? NULL : i);
     apply_cork(u, i->sink, create ? NULL : i, cork);
 
     return PA_HOOK_OK;
@@ -165,6 +205,8 @@ static pa_hook_result_t sink_input_move_finish_cb(pa_core *core, pa_sink_input *
 int pa__init(pa_module *m) {
     pa_modargs *ma = NULL;
     struct userdata *u;
+    const char *roles;
+    pa_bool_t global = FALSE;
 
     pa_assert(m);
 
@@ -178,6 +220,47 @@ int pa__init(pa_module *m) {
     u->core = m->core;
     u->cork_state = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
 
+    u->trigger_roles = pa_idxset_new(NULL, NULL);
+    roles = pa_modargs_get_value(ma, "trigger_roles", NULL);
+    if (roles) {
+        const char *split_state = NULL;
+        char *n = NULL;
+        while ((n = pa_split(roles, ",", &split_state))) {
+            if (n[0] != '\0')
+                pa_idxset_put(u->trigger_roles, n, NULL);
+            else
+                pa_xfree(n);
+        }
+    }
+    if (pa_idxset_isempty(u->trigger_roles)) {
+        pa_log_debug("Using role 'phone' as trigger role.");
+        pa_idxset_put(u->trigger_roles, pa_xstrdup("phone"), NULL);
+    }
+
+    u->cork_roles = pa_idxset_new(NULL, NULL);
+    roles = pa_modargs_get_value(ma, "cork_roles", NULL);
+    if (roles) {
+        const char *split_state = NULL;
+        char *n = NULL;
+        while ((n = pa_split(roles, ",", &split_state))) {
+            if (n[0] != '\0')
+                pa_idxset_put(u->cork_roles, n, NULL);
+            else
+                pa_xfree(n);
+        }
+    }
+    if (pa_idxset_isempty(u->cork_roles)) {
+        pa_log_debug("Using roles 'music' and 'video' as cork roles.");
+        pa_idxset_put(u->cork_roles, pa_xstrdup("music"), NULL);
+        pa_idxset_put(u->cork_roles, pa_xstrdup("video"), NULL);
+    }
+
+    if (pa_modargs_get_value_boolean(ma, "global", &global) < 0) {
+        pa_log("Invalid boolean parameter: global");
+        goto fail;
+    }
+    u->global = global;
+
     u->sink_input_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_put_cb, u);
     u->sink_input_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_unlink_cb, u);
     u->sink_input_move_start_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_start_cb, u);
@@ -193,7 +276,7 @@ fail:
     if (ma)
         pa_modargs_free(ma);
 
-    return  -1;
+    return -1;
 
 
 }
@@ -206,6 +289,12 @@ void pa__done(pa_module *m) {
     if (!(u = m->userdata))
         return;
 
+    if (u->trigger_roles)
+        pa_idxset_free(u->trigger_roles, pa_xfree);
+
+    if (u->cork_roles)
+        pa_idxset_free(u->cork_roles, pa_xfree);
+
     if (u->sink_input_put_slot)
         pa_hook_slot_free(u->sink_input_put_slot);
     if (u->sink_input_unlink_slot)
@@ -216,7 +305,7 @@ void pa__done(pa_module *m) {
         pa_hook_slot_free(u->sink_input_move_finish_slot);
 
     if (u->cork_state)
-        pa_hashmap_free(u->cork_state, NULL, NULL);
+        pa_hashmap_free(u->cork_state, NULL);
 
     pa_xfree(u);
 
diff --git a/src/modules/module-role-ducking.c b/src/modules/module-role-ducking.c
new file mode 100644 (file)
index 0000000..9947871
--- /dev/null
@@ -0,0 +1,318 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2012 Flavio Ceolin <flavio.ceolin@profusion.mobi>
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/volume.h>
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/macro.h>
+#include <pulsecore/hashmap.h>
+#include <pulsecore/hook-list.h>
+#include <pulsecore/core.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/sink-input.h>
+#include <pulsecore/modargs.h>
+
+#include "module-role-ducking-symdef.h"
+
+PA_MODULE_AUTHOR("Flavio Ceolin <flavio.ceolin@profusion.mobi>");
+PA_MODULE_DESCRIPTION("Apply a ducking effect based on streams roles");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(true);
+PA_MODULE_USAGE(
+        "trigger_roles=<Comma separated list of roles which will trigger a ducking> "
+        "ducking_roles=<Comma separated list of roles which will be ducked> "
+        "global=<Should we operate globally or only inside the same device?>"
+        "volume=<Volume for the attenuated streams. Default: -20dB"
+);
+
+static const char* const valid_modargs[] = {
+    "trigger_roles",
+    "ducking_roles",
+    "global",
+    "volume",
+    NULL
+};
+
+struct userdata {
+    pa_core *core;
+    const char *name;
+    pa_idxset *trigger_roles;
+    pa_idxset *ducking_roles;
+    pa_idxset *ducked_inputs;
+    bool global;
+    pa_volume_t volume;
+    pa_hook_slot
+        *sink_input_put_slot,
+        *sink_input_unlink_slot,
+        *sink_input_move_start_slot,
+        *sink_input_move_finish_slot;
+};
+
+static bool sink_has_trigger_streams(struct userdata *u, pa_sink *s, pa_sink_input *ignore) {
+    pa_sink_input *j;
+    uint32_t idx, role_idx;
+    const char *trigger_role;
+
+    pa_assert(u);
+    pa_sink_assert_ref(s);
+
+    PA_IDXSET_FOREACH(j, s->inputs, idx) {
+        const char *role;
+
+        if (j == ignore)
+            continue;
+
+        if (!(role = pa_proplist_gets(j->proplist, PA_PROP_MEDIA_ROLE)))
+            continue;
+
+        PA_IDXSET_FOREACH(trigger_role, u->trigger_roles, role_idx) {
+            if (pa_streq(role, trigger_role)) {
+                pa_log_debug("Found a '%s' stream that will trigger the ducking.", trigger_role);
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+static void apply_ducking_to_sink(struct userdata *u, pa_sink *s, pa_sink_input *ignore, bool duck) {
+    pa_sink_input *j;
+    uint32_t idx, role_idx;
+    const char *ducking_role;
+    bool trigger = false;
+
+    pa_assert(u);
+    pa_sink_assert_ref(s);
+
+    PA_IDXSET_FOREACH(j, s->inputs, idx) {
+        const char *role;
+        pa_sink_input *i;
+
+        if (j == ignore)
+            continue;
+
+        if (!(role = pa_proplist_gets(j->proplist, PA_PROP_MEDIA_ROLE)))
+            continue;
+
+        PA_IDXSET_FOREACH(ducking_role, u->ducking_roles, role_idx) {
+            if ((trigger = pa_streq(role, ducking_role)))
+                break;
+        }
+        if (!trigger)
+            continue;
+
+        i = pa_idxset_get_by_data(u->ducked_inputs, j, NULL);
+        if (duck && !i) {
+            pa_cvolume vol;
+            vol.channels = 1;
+            vol.values[0] = u->volume;
+
+            pa_log_debug("Found a '%s' stream that should be ducked.", ducking_role);
+            pa_sink_input_add_volume_factor(j, u->name, &vol);
+            pa_idxset_put(u->ducked_inputs, j, NULL);
+        } else if (!duck && i) { /* This stream should not longer be ducked */
+            pa_log_debug("Found a '%s' stream that should be unducked", ducking_role);
+            pa_idxset_remove_by_data(u->ducked_inputs, j, NULL);
+            pa_sink_input_remove_volume_factor(j, u->name);
+        }
+    }
+}
+
+static void apply_ducking(struct userdata *u, pa_sink *s, pa_sink_input *ignore, bool duck) {
+    pa_assert(u);
+
+    if (u->global) {
+        uint32_t idx;
+        PA_IDXSET_FOREACH(s, u->core->sinks, idx)
+            apply_ducking_to_sink(u, s, ignore, duck);
+    } else
+        apply_ducking_to_sink(u, s, ignore, duck);
+}
+
+static pa_hook_result_t process(struct userdata *u, pa_sink_input *i, bool duck) {
+    bool should_duck = false;
+    const char *role;
+
+    pa_assert(u);
+    pa_sink_input_assert_ref(i);
+
+    if (!(role = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_ROLE)))
+        return PA_HOOK_OK;
+
+    if (!i->sink)
+        return PA_HOOK_OK;
+
+    should_duck = sink_has_trigger_streams(u, i->sink, duck ? NULL : i);
+    apply_ducking(u, i->sink, duck ? NULL : i, should_duck);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sink_input_put_cb(pa_core *core, pa_sink_input *i, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_sink_input_assert_ref(i);
+
+    return process(u, i, true);
+}
+
+static pa_hook_result_t sink_input_unlink_cb(pa_core *core, pa_sink_input *i, struct userdata *u) {
+    pa_sink_input_assert_ref(i);
+
+    pa_idxset_remove_by_data(u->ducked_inputs, i, NULL);
+    return process(u, i, false);
+}
+
+static pa_hook_result_t sink_input_move_start_cb(pa_core *core, pa_sink_input *i, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_sink_input_assert_ref(i);
+
+    return process(u, i, false);
+}
+
+static pa_hook_result_t sink_input_move_finish_cb(pa_core *core, pa_sink_input *i, struct userdata *u) {
+    pa_core_assert_ref(core);
+    pa_sink_input_assert_ref(i);
+
+    return process(u, i, true);
+}
+
+int pa__init(pa_module *m) {
+    pa_modargs *ma = NULL;
+    struct userdata *u;
+    const char *roles;
+
+    pa_assert(m);
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments");
+        goto fail;
+    }
+
+    m->userdata = u = pa_xnew0(struct userdata, 1);
+
+    u->core = m->core;
+    u->name = m->name;
+
+    u->ducked_inputs = pa_idxset_new(NULL, NULL);
+
+    u->trigger_roles = pa_idxset_new(NULL, NULL);
+    roles = pa_modargs_get_value(ma, "trigger_roles", NULL);
+    if (roles) {
+        const char *split_state = NULL;
+        char *n = NULL;
+        while ((n = pa_split(roles, ",", &split_state))) {
+            if (n[0] != '\0')
+                pa_idxset_put(u->trigger_roles, n, NULL);
+            else
+                pa_xfree(n);
+        }
+    }
+    if (pa_idxset_isempty(u->trigger_roles)) {
+        pa_log_debug("Using role 'phone' as trigger role.");
+        pa_idxset_put(u->trigger_roles, pa_xstrdup("phone"), NULL);
+    }
+
+    u->ducking_roles = pa_idxset_new(NULL, NULL);
+    roles = pa_modargs_get_value(ma, "ducking_roles", NULL);
+    if (roles) {
+        const char *split_state = NULL;
+        char *n = NULL;
+        while ((n = pa_split(roles, ",", &split_state))) {
+            if (n[0] != '\0')
+                pa_idxset_put(u->ducking_roles, n, NULL);
+            else
+                pa_xfree(n);
+        }
+    }
+    if (pa_idxset_isempty(u->ducking_roles)) {
+        pa_log_debug("Using roles 'music' and 'video' as ducking roles.");
+        pa_idxset_put(u->ducking_roles, pa_xstrdup("music"), NULL);
+        pa_idxset_put(u->ducking_roles, pa_xstrdup("video"), NULL);
+    }
+
+    u->global = false;
+    if (pa_modargs_get_value_boolean(ma, "global", &u->global) < 0) {
+        pa_log("Failed to parse a boolean parameter: global");
+        goto fail;
+    }
+
+    u->volume = pa_sw_volume_from_dB(-20);
+    if (pa_modargs_get_value_volume(ma, "volume", &u->volume) < 0) {
+        pa_log("Failed to parse a volume parameter: volume");
+        goto fail;
+    }
+
+    u->sink_input_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_put_cb, u);
+    u->sink_input_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_unlink_cb, u);
+    u->sink_input_move_start_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_start_cb, u);
+    u->sink_input_move_finish_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_move_finish_cb, u);
+
+    pa_modargs_free(ma);
+
+    return 0;
+
+fail:
+    pa__done(m);
+
+    if (ma)
+        pa_modargs_free(ma);
+
+    return -1;
+}
+
+void pa__done(pa_module *m) {
+    struct userdata* u;
+    pa_sink_input *i;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    if (u->trigger_roles)
+        pa_idxset_free(u->trigger_roles, pa_xfree);
+
+    if (u->ducking_roles)
+        pa_idxset_free(u->ducking_roles, pa_xfree);
+
+    if (u->ducked_inputs) {
+        while ((i = pa_idxset_steal_first(u->ducked_inputs, NULL)))
+            pa_sink_input_remove_volume_factor(i, u->name);
+
+        pa_idxset_free(u->ducked_inputs, NULL);
+    }
+
+    if (u->sink_input_put_slot)
+        pa_hook_slot_free(u->sink_input_put_slot);
+    if (u->sink_input_unlink_slot)
+        pa_hook_slot_free(u->sink_input_unlink_slot);
+    if (u->sink_input_move_start_slot)
+        pa_hook_slot_free(u->sink_input_move_start_slot);
+    if (u->sink_input_move_finish_slot)
+        pa_hook_slot_free(u->sink_input_move_finish_slot);
+
+    pa_xfree(u);
+}
diff --git a/src/modules/module-rygel-media-server-symdef.h b/src/modules/module-rygel-media-server-symdef.h
deleted file mode 100644 (file)
index 8645fa6..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulerygelmediaserversymdeffoo
-#define foomodulerygelmediaserversymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_rygel_media_server_LTX_pa__init
-#define pa__done module_rygel_media_server_LTX_pa__done
-#define pa__get_author module_rygel_media_server_LTX_pa__get_author
-#define pa__get_description module_rygel_media_server_LTX_pa__get_description
-#define pa__get_usage module_rygel_media_server_LTX_pa__get_usage
-#define pa__get_version module_rygel_media_server_LTX_pa__get_version
-#define pa__get_deprecated module_rygel_media_server_LTX_pa__get_deprecated
-#define pa__load_once module_rygel_media_server_LTX_pa__load_once
-#define pa__get_n_used module_rygel_media_server_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 82bcd14..855d7bb 100644 (file)
 #include <string.h>
 #include <unistd.h>
 
+#include <pulse/gccmacro.h>
 #include <pulse/xmalloc.h>
-#include <pulse/util.h>
-#include <pulse/i18n.h>
 #include <pulse/utf8.h>
 
+#include <pulsecore/i18n.h>
 #include <pulsecore/sink.h>
 #include <pulsecore/source.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
+#include <pulsecore/macro.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/dbus-shared.h>
-#include <pulsecore/endianmacros.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/mime-type.h>
 #include <pulsecore/strbuf.h>
@@ -52,33 +52,52 @@ PA_MODULE_AUTHOR("Lennart Poettering");
 PA_MODULE_DESCRIPTION("UPnP MediaServer Plugin for Rygel");
 PA_MODULE_VERSION(PACKAGE_VERSION);
 PA_MODULE_LOAD_ONCE(TRUE);
-PA_MODULE_USAGE(
-        "display_name=<UPnP Media Server name>");
+PA_MODULE_USAGE("display_name=<UPnP Media Server name>");
 
-/* This implements http://live.gnome.org/Rygel/MediaServerSpec */
+/* This implements http://live.gnome.org/Rygel/MediaServer2Spec */
 
-#define SERVICE_NAME "org.gnome.UPnP.MediaServer1.PulseAudio"
+#define SERVICE_NAME "org.gnome.UPnP.MediaServer2.PulseAudio"
 
-#define OBJECT_ROOT "/org/gnome/UPnP/MediaServer1/PulseAudio"
-#define OBJECT_SINKS "/org/gnome/UPnP/MediaServer1/PulseAudio/Sinks"
-#define OBJECT_SOURCES "/org/gnome/UPnP/MediaServer1/PulseAudio/Sources"
+#define OBJECT_ROOT "/org/gnome/UPnP/MediaServer2/PulseAudio"
+#define OBJECT_SINKS "/org/gnome/UPnP/MediaServer2/PulseAudio/Sinks"
+#define OBJECT_SOURCES "/org/gnome/UPnP/MediaServer2/PulseAudio/Sources"
 
 #define CONTAINER_INTROSPECT_XML_PREFIX                                 \
     DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                           \
     "<node>"                                                            \
     " <!-- If you are looking for documentation make sure to check out" \
-    "      http://live.gnome.org/Rygel/MediaServerSpec -->"             \
-    " <interface name=\"org.gnome.UPnP.MediaContainer1\">"              \
+    "      http://live.gnome.org/Rygel/MediaServer2Spec -->"            \
+    " <interface name=\"org.gnome.UPnP.MediaContainer2\">"              \
+    "  <method name='ListChildren'>"                                    \
+    "   <arg direction='in' name='offset' type='u' />"                  \
+    "   <arg direction='in' name='max' type='u' />"                     \
+    "   <arg direction='in' name='filter' type='as' />"                 \
+    "   <arg direction='out' type='aa{sv}' />"                          \
+    "  </method>"                                                       \
+    "  <method name='ListContainers'>"                                  \
+    "   <arg direction='in' name='offset' type='u' />"                  \
+    "   <arg direction='in' name='max' type='u' />"                     \
+    "   <arg direction='in' name='filter' type='as' />"                 \
+    "   <arg direction='out' type='aa{sv}' />"                          \
+    "  </method>"                                                       \
+    "  <method name='ListItems'>"                                       \
+    "   <arg direction='in' name='offset' type='u' />"                  \
+    "   <arg direction='in' name='max' type='u' />"                     \
+    "   <arg direction='in' name='filter' type='as' />"                 \
+    "   <arg direction='out' type='aa{sv}' />"                          \
+    "  </method>"                                                       \
     "  <signal name=\"Updated\">"                                       \
     "   <arg name=\"path\" type=\"o\"/>"                                \
     "  </signal>"                                                       \
-    "  <property name=\"Items\" type=\"ao\" access=\"read\"/>"          \
+    "  <property name=\"ChildCount\" type=\"u\" access=\"read\"/>"      \
     "  <property name=\"ItemCount\" type=\"u\" access=\"read\"/>"       \
-    "  <property name=\"Containers\" type=\"ao\" access=\"read\"/>"     \
     "  <property name=\"ContainerCount\" type=\"u\" access=\"read\"/>"  \
+    "  <property name=\"Searchable\" type=\"b\" access=\"read\"/>"      \
     " </interface>"                                                     \
-    " <interface name=\"org.gnome.UPnP.MediaObject1\">"                 \
+    " <interface name=\"org.gnome.UPnP.MediaObject2\">"                 \
     "  <property name=\"Parent\" type=\"s\" access=\"read\"/>"          \
+    "  <property name=\"Type\" type=\"s\" access=\"read\"/>"            \
+    "  <property name=\"Path\" type=\"s\" access=\"read\"/>"            \
     "  <property name=\"DisplayName\" type=\"s\" access=\"read\"/>"     \
     " </interface>"                                                     \
     " <interface name=\"org.freedesktop.DBus.Properties\">"             \
@@ -111,14 +130,16 @@ PA_MODULE_USAGE(
     DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                           \
     "<node>"                                                            \
     " <!-- If you are looking for documentation make sure to check out" \
-    "      http://live.gnome.org/Rygel/MediaProviderSpec -->"           \
-    " <interface name=\"org.gnome.UPnP.MediaItem1\">"                   \
+    "      http://live.gnome.org/Rygel/MediaProvider2Spec -->"          \
+    " <interface name=\"org.gnome.UPnP.MediaItem2\">"                   \
     "  <property name=\"URLs\" type=\"as\" access=\"read\"/>"           \
     "  <property name=\"MIMEType\" type=\"s\" access=\"read\"/>"        \
-    "  <property name=\"Type\" type=\"s\" access=\"read\"/>"            \
+    "  <property name=\"DLNAProfile\" type=\"s\" access=\"read\"/>"        \
     " </interface>"                                                     \
-    " <interface name=\"org.gnome.UPnP.MediaObject1\">"                 \
+    " <interface name=\"org.gnome.UPnP.MediaObject2\">"                 \
     "  <property name=\"Parent\" type=\"s\" access=\"read\"/>"          \
+    "  <property name=\"Type\" type=\"s\" access=\"read\"/>"            \
+    "  <property name=\"Path\" type=\"s\" access=\"read\"/>"            \
     "  <property name=\"DisplayName\" type=\"s\" access=\"read\"/>"     \
     " </interface>"                                                     \
     " <interface name=\"org.freedesktop.DBus.Properties\">"             \
@@ -159,6 +180,8 @@ struct userdata {
     pa_http_protocol *http;
 };
 
+static char *compute_url(const struct userdata *u, const char *name);
+
 static void send_signal(struct userdata *u, pa_source *s) {
     DBusMessage *m;
     const char *parent;
@@ -174,7 +197,7 @@ static void send_signal(struct userdata *u, pa_source *s) {
     else
         parent = OBJECT_SOURCES;
 
-    pa_assert_se(m = dbus_message_new_signal(parent, "org.gnome.UPnP.MediaContainer1", "Updated"));
+    pa_assert_se(m = dbus_message_new_signal(parent, "org.gnome.UPnP.MediaContainer2", "Updated"));
     pa_assert_se(dbus_connection_send(pa_dbus_connection_get(u->bus), m, NULL));
 
     dbus_message_unref(m);
@@ -296,6 +319,70 @@ static void append_variant_unsigned(DBusMessage *m, DBusMessageIter *iter, unsig
     pa_assert_se(dbus_message_iter_close_container(iter, &sub));
 }
 
+static void append_variant_boolean(DBusMessage *m, DBusMessageIter *iter, dbus_bool_t b) {
+    DBusMessageIter _iter, sub;
+
+    pa_assert(m);
+
+    if (!iter) {
+        dbus_message_iter_init_append(m, &_iter);
+        iter = &_iter;
+    }
+
+    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "b", &sub));
+    pa_assert_se(dbus_message_iter_append_basic(&sub, DBUS_TYPE_BOOLEAN, &b));
+    pa_assert_se(dbus_message_iter_close_container(iter, &sub));
+}
+
+static void append_variant_urls(DBusMessage *m, DBusMessageIter *iter, const struct userdata *u, pa_sink *sink, pa_source *source) {
+    DBusMessageIter _iter, sub, array;
+    char *url;
+
+    pa_assert(m);
+    pa_assert(u);
+    pa_assert(sink || source);
+
+    if (!iter) {
+        dbus_message_iter_init_append(m, &_iter);
+        iter = &_iter;
+    }
+
+    url = compute_url(u, sink ? sink->monitor_source->name : source->name);
+
+    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "as", &sub));
+    pa_assert_se(dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "s", &array));
+    pa_assert_se(dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &url));
+    pa_assert_se(dbus_message_iter_close_container(&sub, &array));
+    pa_assert_se(dbus_message_iter_close_container(iter, &sub));
+
+    pa_xfree(url);
+}
+
+static void append_variant_mime_type(DBusMessage *m, DBusMessageIter *iter, pa_sink *sink, pa_source *source) {
+    char *mime_type;
+
+    pa_assert(sink || source);
+
+    if (sink)
+        mime_type = pa_sample_spec_to_mime_type_mimefy(&sink->sample_spec, &sink->channel_map);
+    else
+        mime_type = pa_sample_spec_to_mime_type_mimefy(&source->sample_spec, &source->channel_map);
+
+    append_variant_string(m, iter, mime_type);
+
+    pa_xfree(mime_type);
+}
+
+static void append_variant_item_display_name(DBusMessage *m, DBusMessageIter *iter, pa_sink *sink, pa_source *source) {
+    const char *display_name;
+
+    pa_assert(sink || source);
+
+    display_name = pa_strna(pa_proplist_gets(sink ? sink->proplist : source->proplist, PA_PROP_DEVICE_DESCRIPTION));
+    append_variant_string(m, iter, display_name);
+}
+
+PA_GCC_UNUSED
 static void append_property_dict_entry_object_array(DBusMessage *m, DBusMessageIter *iter, const char *name, const char *path[], unsigned n) {
     DBusMessageIter sub;
 
@@ -340,6 +427,199 @@ static void append_property_dict_entry_unsigned(DBusMessage *m, DBusMessageIter
     pa_assert_se(dbus_message_iter_close_container(iter, &sub));
 }
 
+static void append_property_dict_entry_boolean(DBusMessage *m, DBusMessageIter *iter, const char *name, dbus_bool_t b) {
+    DBusMessageIter sub;
+
+    pa_assert(iter);
+
+    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL, &sub));
+    pa_assert_se(dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &name));
+    append_variant_boolean(m, &sub, b);
+    pa_assert_se(dbus_message_iter_close_container(iter, &sub));
+}
+
+static void append_property_dict_entry_urls(DBusMessage *m, DBusMessageIter *iter, const struct userdata *u, pa_sink *sink, pa_source *source) {
+    DBusMessageIter sub;
+    const char *property_name = "URLs";
+
+    pa_assert(iter);
+
+    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL, &sub));
+    pa_assert_se(dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &property_name));
+    append_variant_urls(m, &sub, u, sink, source);
+    pa_assert_se(dbus_message_iter_close_container(iter, &sub));
+}
+
+static void append_property_dict_entry_mime_type(DBusMessage *m, DBusMessageIter *iter, pa_sink *sink, pa_source *source) {
+    DBusMessageIter sub;
+    const char *property_name = "MIMEType";
+
+    pa_assert(iter);
+
+    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL, &sub));
+    pa_assert_se(dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &property_name));
+    append_variant_mime_type(m, &sub, sink, source);
+    pa_assert_se(dbus_message_iter_close_container(iter, &sub));
+}
+
+static void append_property_dict_entry_item_display_name(DBusMessage *m, DBusMessageIter *iter, pa_sink *sink, pa_source *source) {
+    DBusMessageIter sub;
+    const char *property_name = "DisplayName";
+
+    pa_assert(iter);
+
+    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL, &sub));
+    pa_assert_se(dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &property_name));
+    append_variant_item_display_name(m, &sub, sink, source);
+    pa_assert_se(dbus_message_iter_close_container(iter, &sub));
+}
+
+static pa_bool_t get_mediacontainer2_list_args(DBusMessage *m, unsigned *offset, unsigned *max_entries, char ***filter, int *filter_len) {
+    DBusError error;
+
+    dbus_error_init(&error);
+
+    pa_assert(m);
+    pa_assert(offset);
+    pa_assert(max_entries);
+    pa_assert(filter);
+
+    if (!dbus_message_get_args(m, &error, DBUS_TYPE_UINT32, offset, DBUS_TYPE_UINT32, max_entries, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, filter, filter_len, DBUS_TYPE_INVALID) || dbus_error_is_set(&error)) {
+        dbus_error_free(&error);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static unsigned get_sinks_or_sources_count(const char *path, const struct userdata *u) {
+    unsigned n, k;
+
+    n = pa_idxset_size(u->core->sinks);
+    k = pa_idxset_size(u->core->sources);
+    pa_assert(k >= n);
+
+    return pa_streq(path, OBJECT_SINKS) ? n : k - n;
+}
+
+static void append_sink_or_source_container_mediaobject2_properties(DBusMessage *r, DBusMessageIter *sub, const char *path) {
+    append_property_dict_entry_object(r, sub, "Parent", OBJECT_ROOT);
+    append_property_dict_entry_string(r, sub, "Type", "container");
+    append_property_dict_entry_object(r, sub, "Path", path);
+    append_property_dict_entry_string(r, sub, "DisplayName",
+                                      pa_streq(path, OBJECT_SINKS) ?
+                                      _("Output Devices") :
+                                      _("Input Devices"));
+}
+
+static void append_sink_or_source_container_properties(
+    DBusMessage *r, DBusMessageIter *iter,
+    const char *path, const struct userdata *user_data,
+    char * const * filter, int filter_len) {
+
+    DBusMessageIter sub;
+
+    pa_assert(r);
+    pa_assert(iter);
+    pa_assert(path);
+    pa_assert(filter);
+
+    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{sv}", &sub));
+
+    if (filter_len == 1 && (*filter)[0] == '*' && (*filter)[1] == '\0') {
+        append_sink_or_source_container_mediaobject2_properties(r, &sub, path);
+        append_property_dict_entry_unsigned(r, &sub, "ChildCount", get_sinks_or_sources_count(path, user_data));
+        append_property_dict_entry_boolean(r, &sub, "Searchable", FALSE);
+    }
+    else {
+        for (int i = 0; i < filter_len; ++i) {
+            const char *property_name = filter[i];
+            if (pa_streq(property_name, "Parent")) {
+                append_property_dict_entry_object(r, &sub, "Parent", OBJECT_ROOT);
+            }
+            else if (pa_streq(property_name, "Type")) {
+                append_property_dict_entry_string(r, &sub, "Type", "container");
+            }
+            else if (pa_streq(property_name, "Path")) {
+                append_property_dict_entry_object(r, &sub, "Path", path);
+            }
+            else if (pa_streq(property_name, "DisplayName")) {
+                append_property_dict_entry_string(r, &sub, "DisplayName",
+                                                  pa_streq(path, OBJECT_SINKS) ?
+                                                  _("Output Devices") :
+                                                  _("Input Devices"));
+            }
+            else if (pa_streq(property_name, "ChildCount")) {
+                append_property_dict_entry_unsigned(r, &sub, "ChildCount", get_sinks_or_sources_count(path, user_data));
+            }
+            else if (pa_streq(property_name, "Searchable")) {
+                append_property_dict_entry_boolean(r, &sub, "Searchable", FALSE);
+            }
+        }
+    }
+
+    pa_assert_se(dbus_message_iter_close_container(iter, &sub));
+}
+
+static void append_sink_or_source_item_mediaobject2_properties(DBusMessage *r, DBusMessageIter *sub, const char *path, pa_sink *sink, pa_source *source) {
+    append_property_dict_entry_object(r, sub, "Parent", sink ? OBJECT_SINKS : OBJECT_SOURCES);
+    append_property_dict_entry_string(r, sub, "Type", "audio");
+    append_property_dict_entry_object(r, sub, "Path", path);
+    append_property_dict_entry_item_display_name(r, sub, sink, source);
+}
+
+static void append_sink_or_source_item_properties(
+    DBusMessage *r, DBusMessageIter *iter,
+    const char *path, const struct userdata *user_data,
+    pa_sink *sink, pa_source *source,
+    char * const * filter, int filter_len) {
+
+    DBusMessageIter sub;
+
+    pa_assert(r);
+    pa_assert(iter);
+    pa_assert(path);
+    pa_assert(filter);
+    pa_assert(sink || source);
+
+    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{sv}", &sub));
+
+    if (filter_len == 1 && (*filter)[0] == '*' && (*filter)[1] == '\0') {
+        append_sink_or_source_item_mediaobject2_properties(r, &sub, path, sink, source);
+        append_property_dict_entry_urls(r, &sub, user_data, sink, source);
+        append_property_dict_entry_mime_type(r, &sub, sink, source);
+        append_property_dict_entry_string(r, &sub, "DLNAProfile", "LPCM");
+    }
+    else {
+        for (int i = 0; i < filter_len; ++i) {
+            const char *property_name = filter[i];
+            if (pa_streq(property_name, "Parent")) {
+                append_property_dict_entry_object(r, &sub, "Parent", sink ? OBJECT_SINKS : OBJECT_SOURCES);
+            }
+            else if (pa_streq(property_name, "Type")) {
+                append_property_dict_entry_string(r, &sub, "Type", "audio");
+            }
+            else if (pa_streq(property_name, "Path")) {
+                append_property_dict_entry_object(r, &sub, "Path", path);
+            }
+            else if (pa_streq(property_name, "DisplayName")) {
+                append_property_dict_entry_item_display_name(r, &sub, sink, source);
+            }
+            else if (pa_streq(property_name, "URLs")) {
+                append_property_dict_entry_urls(r, &sub, user_data, sink, source);
+            }
+            else if (pa_streq(property_name, "MIMEType")) {
+                append_property_dict_entry_mime_type(r, &sub, sink, source);
+            }
+            else if (pa_streq(property_name, "DLNAProfile")) {
+                append_property_dict_entry_string(r, &sub, "DLNAProfile", "LPCM");
+            }
+        }
+    }
+
+    pa_assert_se(dbus_message_iter_close_container(iter, &sub));
+}
+
 static const char *array_root_containers[] = { OBJECT_SINKS, OBJECT_SOURCES };
 static const char *array_no_children[] = { };
 
@@ -349,50 +629,100 @@ static DBusHandlerResult root_handler(DBusConnection *c, DBusMessage *m, void *u
 
     pa_assert(u);
 
-    if (message_is_property_get(m, "org.gnome.UPnP.MediaContainer1", "Containers")) {
+    if (message_is_property_get(m, "org.gnome.UPnP.MediaContainer2", "ChildCount")) {
         pa_assert_se(r = dbus_message_new_method_return(m));
-        append_variant_object_array(r, NULL, (const char**) array_root_containers, PA_ELEMENTSOF(array_root_containers));
+        append_variant_unsigned(r, NULL, PA_ELEMENTSOF(array_root_containers));
 
-    } else if (message_is_property_get(m, "org.gnome.UPnP.MediaContainer1", "ContainerCount")) {
+    } else if (message_is_property_get(m, "org.gnome.UPnP.MediaContainer2", "ItemCount")) {
         pa_assert_se(r = dbus_message_new_method_return(m));
-        append_variant_unsigned(r, NULL, PA_ELEMENTSOF(array_root_containers));
+        append_variant_unsigned(r, NULL, PA_ELEMENTSOF(array_no_children));
 
-    } else if (message_is_property_get(m, "org.gnome.UPnP.MediaContainer1", "Items")) {
+    } else if (message_is_property_get(m, "org.gnome.UPnP.MediaContainer2", "ContainerCount")) {
         pa_assert_se(r = dbus_message_new_method_return(m));
-        append_variant_object_array(r, NULL, array_no_children, PA_ELEMENTSOF(array_no_children));
+        append_variant_unsigned(r, NULL, PA_ELEMENTSOF(array_root_containers));
 
-    } else if (message_is_property_get(m, "org.gnome.UPnP.MediaContainer1", "ItemCount")) {
+    } else if (message_is_property_get(m, "org.gnome.UPnP.MediaContainer2", "Searchable")) {
         pa_assert_se(r = dbus_message_new_method_return(m));
-        append_variant_unsigned(r, NULL, PA_ELEMENTSOF(array_no_children));
+        append_variant_boolean(r, NULL, FALSE);
 
-    } else if (message_is_property_get_all(m, "org.gnome.UPnP.MediaContainer1")) {
+    } else if (message_is_property_get_all(m, "org.gnome.UPnP.MediaContainer2")) {
         DBusMessageIter iter, sub;
 
         pa_assert_se(r = dbus_message_new_method_return(m));
         dbus_message_iter_init_append(r, &iter);
 
         pa_assert_se(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub));
-        append_property_dict_entry_object_array(r, &sub, "Containers", array_root_containers, PA_ELEMENTSOF(array_root_containers));
-        append_property_dict_entry_unsigned(r, &sub, "ContainerCount", PA_ELEMENTSOF(array_root_containers));
-        append_property_dict_entry_object_array(r, &sub, "Items", array_no_children, PA_ELEMENTSOF(array_no_children));
+        append_property_dict_entry_unsigned(r, &sub, "ChildCount", PA_ELEMENTSOF(array_root_containers));
         append_property_dict_entry_unsigned(r, &sub, "ItemCount", PA_ELEMENTSOF(array_no_children));
+        append_property_dict_entry_unsigned(r, &sub, "ContainerCount", PA_ELEMENTSOF(array_root_containers));
+        append_property_dict_entry_boolean(r, &sub, "Searchable", FALSE);
         pa_assert_se(dbus_message_iter_close_container(&iter, &sub));
 
-    } else if (message_is_property_get(m, "org.gnome.UPnP.MediaObject1", "Parent")) {
+    } else if (dbus_message_is_method_call(m, "org.gnome.UPnP.MediaContainer2", "ListChildren")
+        || dbus_message_is_method_call(m, "org.gnome.UPnP.MediaContainer2", "ListContainers")) {
+        DBusMessageIter iter, sub;
+        unsigned offset, max;
+        char ** filter;
+        int filter_len;
+
+        pa_assert_se(r = dbus_message_new_method_return(m));
+
+        dbus_message_iter_init_append(r, &iter);
+        pa_assert_se(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "a{sv}", &sub));
+
+        if (get_mediacontainer2_list_args(m, &offset, &max, &filter, &filter_len)) {
+            unsigned end = (max != 0 && offset + max < PA_ELEMENTSOF(array_root_containers))
+                                ? max + offset
+                                : PA_ELEMENTSOF(array_root_containers);
+
+            for (unsigned i = offset; i < end; ++i) {
+                const char *container_path = array_root_containers[i];
+                append_sink_or_source_container_properties(r, &sub, container_path, u, filter, filter_len);
+            }
+
+            dbus_free_string_array(filter);
+        }
+
+        pa_assert_se(dbus_message_iter_close_container(&iter, &sub));
+
+    } else if (dbus_message_is_method_call(m, "org.gnome.UPnP.MediaContainer2", "ListItems")) {
+        DBusMessageIter iter, sub;
+
+        pa_assert_se(r = dbus_message_new_method_return(m));
+
+        dbus_message_iter_init_append(r, &iter);
+        pa_assert_se(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "a{sv}", &sub));
+        pa_assert_se(dbus_message_iter_close_container(&iter, &sub));
+
+    } else if (message_is_property_get(m, "org.gnome.UPnP.MediaObject2", "Parent")) {
         pa_assert_se(r = dbus_message_new_method_return(m));
         append_variant_object(r, NULL, OBJECT_ROOT);
 
-    } else if (message_is_property_get(m, "org.gnome.UPnP.MediaObject1", "DisplayName")) {
+    } else if (message_is_property_get(m, "org.gnome.UPnP.MediaObject2", "Type")) {
+        pa_assert_se(r = dbus_message_new_method_return(m));
+        append_variant_string(r, NULL, "container");
+
+    } else if (message_is_property_get(m, "org.gnome.UPnP.MediaObject2", "Path")) {
+        const char *path = dbus_message_get_path(m);
+
+        pa_assert_se(r = dbus_message_new_method_return(m));
+        append_variant_object(r, NULL, path);
+
+    } else if (message_is_property_get(m, "org.gnome.UPnP.MediaObject2", "DisplayName")) {
         pa_assert_se(r = dbus_message_new_method_return(m));
         append_variant_string(r, NULL, u->display_name);
 
-    } else if (message_is_property_get_all(m, "org.gnome.UPnP.MediaObject1")) {
+    } else if (message_is_property_get_all(m, "org.gnome.UPnP.MediaObject2")) {
         DBusMessageIter iter, sub;
+        const char *path = dbus_message_get_path(m);
 
         pa_assert_se(r = dbus_message_new_method_return(m));
         dbus_message_iter_init_append(r, &iter);
 
         pa_assert_se(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub));
+        append_property_dict_entry_object(r, &sub, "Parent", OBJECT_ROOT);
+        append_property_dict_entry_string(r, &sub, "Type", "container");
+        append_property_dict_entry_object(r, &sub, "Path", path);
         append_property_dict_entry_string(r, &sub, "DisplayName", u->display_name);
         pa_assert_se(dbus_message_iter_close_container(&iter, &sub));
 
@@ -400,10 +730,7 @@ static DBusHandlerResult root_handler(DBusConnection *c, DBusMessage *m, void *u
         const char *xml = ROOT_INTROSPECT_XML;
 
         pa_assert_se(r = dbus_message_new_method_return(m));
-        pa_assert_se(dbus_message_append_args(
-                             r,
-                             DBUS_TYPE_STRING, &xml,
-                             DBUS_TYPE_INVALID));
+        pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID));
 
     } else
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -416,7 +743,7 @@ static DBusHandlerResult root_handler(DBusConnection *c, DBusMessage *m, void *u
     return DBUS_HANDLER_RESULT_HANDLED;
 }
 
-static char *compute_url(struct userdata *u, const char *name) {
+static char *compute_url(const struct userdata *u, const char *name) {
     pa_strlist *i;
 
     pa_assert(u);
@@ -453,65 +780,6 @@ static char *compute_url(struct userdata *u, const char *name) {
     return pa_sprintf_malloc("http://@ADDRESS@:4714/listen/source/%s", name);
 }
 
-static char **child_array(struct userdata *u, const char *path, unsigned *n) {
-    unsigned m;
-    uint32_t idx;
-    char **array;
-
-    pa_assert(u);
-    pa_assert(path);
-    pa_assert(n);
-
-    if (pa_streq(path, OBJECT_SINKS))
-        m = pa_idxset_size(u->core->sinks);
-    else {
-        unsigned k;
-
-        m = pa_idxset_size(u->core->sources);
-        k = pa_idxset_size(u->core->sinks);
-
-        pa_assert(m >= k);
-
-        /* Subtract the monitor sources from the numbers of
-         * sources. There is one monitor source for each sink */
-        m -= k;
-    }
-
-    array = pa_xnew(char*, m);
-    *n = 0;
-
-    if (pa_streq(path, OBJECT_SINKS)) {
-        pa_sink *sink;
-
-        PA_IDXSET_FOREACH(sink, u->core->sinks, idx) {
-            pa_assert((*n) < m);
-            array[(*n)++] = pa_sprintf_malloc(OBJECT_SINKS "/%u", sink->index);
-        }
-    } else {
-        pa_source *source;
-
-        PA_IDXSET_FOREACH(source, u->core->sources, idx) {
-
-            if (!source->monitor_of) {
-                pa_assert((*n) < m);
-                array[(*n)++] = pa_sprintf_malloc(OBJECT_SOURCES "/%u", source->index);
-            }
-        }
-    }
-
-    pa_assert((*n) <= m);
-
-    return array;
-}
-
-static void free_child_array(char **array, unsigned n) {
-
-    for (; n >= 1; n--)
-        pa_xfree(array[n-1]);
-
-    pa_xfree(array);
-}
-
 static DBusHandlerResult sinks_and_sources_handler(DBusConnection *c, DBusMessage *m, void *userdata) {
     struct userdata *u = userdata;
     DBusMessage *r = NULL;
@@ -525,66 +793,114 @@ static DBusHandlerResult sinks_and_sources_handler(DBusConnection *c, DBusMessag
 
         /* Container nodes */
 
-        if (message_is_property_get(m, "org.gnome.UPnP.MediaContainer1", "Containers")) {
+        if (message_is_property_get(m, "org.gnome.UPnP.MediaContainer2", "ChildCount")
+            || message_is_property_get(m, "org.gnome.UPnP.MediaContainer2", "ItemCount")) {
             pa_assert_se(r = dbus_message_new_method_return(m));
-            append_variant_object_array(r, NULL, array_no_children, PA_ELEMENTSOF(array_no_children));
+            append_variant_unsigned(r, NULL, get_sinks_or_sources_count(path, u));
 
-        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaContainer1", "ContainerCount")) {
+        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaContainer2", "ContainerCount")) {
             pa_assert_se(r = dbus_message_new_method_return(m));
-            append_variant_unsigned(r, NULL, PA_ELEMENTSOF(array_no_children));
+            append_variant_unsigned(r, NULL, 0);
 
-        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaContainer1", "Items")) {
-            char ** array;
-            unsigned n;
+        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaContainer2", "Searchable")) {
+            pa_assert_se(r = dbus_message_new_method_return(m));
+            append_variant_boolean(r, NULL, FALSE);
 
-            array = child_array(u, path, &n);
+        } else if (message_is_property_get_all(m, "org.gnome.UPnP.MediaContainer2")) {
+            DBusMessageIter iter, sub;
+            unsigned item_count;
 
             pa_assert_se(r = dbus_message_new_method_return(m));
-            append_variant_object_array(r, NULL, (const char**) array, n);
+            dbus_message_iter_init_append(r, &iter);
 
-            free_child_array(array, n);
+            pa_assert_se(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub));
 
-        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaContainer1", "ItemCount")) {
-            unsigned n, k;
+            item_count = get_sinks_or_sources_count(path, u);
 
-            n = pa_idxset_size(u->core->sinks);
-            k = pa_idxset_size(u->core->sources);
-            pa_assert(k >= n);
+            append_property_dict_entry_unsigned(r, &sub, "ChildCount", item_count);
+            append_property_dict_entry_unsigned(r, &sub, "ItemCount", item_count);
+            append_property_dict_entry_unsigned(r, &sub, "ContainerCount", 0);
+            append_property_dict_entry_boolean(r, &sub, "Searchable", FALSE);
 
-            pa_assert_se(r = dbus_message_new_method_return(m));
-            append_variant_unsigned(r, NULL,
-                                    pa_streq(path, OBJECT_SINKS) ? n : k - n);
+            pa_assert_se(dbus_message_iter_close_container(&iter, &sub));
 
-        } else if (message_is_property_get_all(m, "org.gnome.UPnP.MediaContainer1")) {
+        } else if (dbus_message_is_method_call(m, "org.gnome.UPnP.MediaContainer2", "ListChildren")
+            || dbus_message_is_method_call(m, "org.gnome.UPnP.MediaContainer2", "ListItems")) {
             DBusMessageIter iter, sub;
-            char **array;
-            unsigned n, k;
+            unsigned offset, max;
+            char **filter;
+            int filter_len;
 
             pa_assert_se(r = dbus_message_new_method_return(m));
-            dbus_message_iter_init_append(r, &iter);
 
-            pa_assert_se(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub));
-            append_property_dict_entry_object_array(r, &sub, "Containers", array_no_children, PA_ELEMENTSOF(array_no_children));
-            append_property_dict_entry_unsigned(r, &sub, "ContainerCount", 0);
+            dbus_message_iter_init_append(r, &iter);
+            pa_assert_se(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "a{sv}", &sub));
+
+            if (get_mediacontainer2_list_args(m, &offset, &max, &filter, &filter_len)) {
+                unsigned end = (max != 0) ? max + offset : UINT_MAX;
+
+                if (pa_streq(path, OBJECT_SINKS)) {
+                    pa_sink *sink;
+                    char sink_path[sizeof(OBJECT_SINKS) + 32];
+                    char *path_end = sink_path + sizeof(OBJECT_SINKS);
+                    unsigned item_index = 0;
+                    uint32_t idx;
+
+                    strcpy(sink_path, OBJECT_SINKS "/");
+
+                    PA_IDXSET_FOREACH(sink, u->core->sinks, idx) {
+                        if (item_index >= offset && item_index < end) {
+                            sprintf(path_end, "%u", sink->index);
+                            append_sink_or_source_item_properties(r, &sub, sink_path, u, sink, NULL, filter, filter_len);
+                        }
+                        ++item_index;
+                    }
+                } else {
+                    pa_source *source;
+                    char source_path[sizeof(OBJECT_SOURCES) + 32];
+                    char *path_end = source_path + sizeof(OBJECT_SOURCES);
+                    unsigned item_index = 0;
+                    uint32_t idx;
+
+                    strcpy(source_path, OBJECT_SOURCES "/");
+
+                    PA_IDXSET_FOREACH(source, u->core->sources, idx)
+                        if (!source->monitor_of) {
+                            if (item_index >= offset && item_index < end) {
+                                sprintf(path_end, "%u", source->index);
+                                append_sink_or_source_item_properties(r, &sub, source_path, u, NULL, source, filter, filter_len);
+                            }
+                            ++item_index;
+                        }
+                }
+
+                dbus_free_string_array(filter);
+            }
 
-            array = child_array(u, path, &n);
-            append_property_dict_entry_object_array(r, &sub, "Items", (const char**) array, n);
-            free_child_array(array, n);
+            pa_assert_se(dbus_message_iter_close_container(&iter, &sub));
 
-            n = pa_idxset_size(u->core->sinks);
-            k = pa_idxset_size(u->core->sources);
-            pa_assert(k >= n);
+        } else if (dbus_message_is_method_call(m, "org.gnome.UPnP.MediaContainer2", "ListContainers")) {
+            DBusMessageIter iter, sub;
 
-            append_property_dict_entry_unsigned(r, &sub, "ItemCount",
-                                                pa_streq(path, OBJECT_SINKS) ? n : k - n);
+            pa_assert_se(r = dbus_message_new_method_return(m));
 
+            dbus_message_iter_init_append(r, &iter);
+            pa_assert_se(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "a{sv}", &sub));
             pa_assert_se(dbus_message_iter_close_container(&iter, &sub));
 
-        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaObject1", "Parent")) {
+        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaObject2", "Parent")) {
             pa_assert_se(r = dbus_message_new_method_return(m));
             append_variant_object(r, NULL, OBJECT_ROOT);
 
-        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaObject1", "DisplayName")) {
+        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaObject2", "Type")) {
+            pa_assert_se(r = dbus_message_new_method_return(m));
+            append_variant_string(r, NULL, "container");
+
+        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaObject2", "Path")) {
+            pa_assert_se(r = dbus_message_new_method_return(m));
+            append_variant_object(r, NULL, path);
+
+        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaObject2", "DisplayName")) {
             pa_assert_se(r = dbus_message_new_method_return(m));
             append_variant_string(r,
                                   NULL,
@@ -592,19 +908,14 @@ static DBusHandlerResult sinks_and_sources_handler(DBusConnection *c, DBusMessag
                                   _("Output Devices") :
                                   _("Input Devices"));
 
-        } else if (message_is_property_get_all(m, "org.gnome.UPnP.MediaObject1")) {
+        } else if (message_is_property_get_all(m, "org.gnome.UPnP.MediaObject2")) {
             DBusMessageIter iter, sub;
 
             pa_assert_se(r = dbus_message_new_method_return(m));
 
             dbus_message_iter_init_append(r, &iter);
-
             pa_assert_se(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub));
-            append_property_dict_entry_object(m, &sub, "Parent", OBJECT_ROOT);
-            append_property_dict_entry_string(m, &sub, "DisplayName",
-                                              pa_streq(path, OBJECT_SINKS) ?
-                                              _("Output Devices") :
-                                              _("Input Devices"));
+            append_sink_or_source_container_mediaobject2_properties(r, &sub, path);
             pa_assert_se(dbus_message_iter_close_container(&iter, &sub));
 
         } else if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
@@ -632,10 +943,7 @@ static DBusHandlerResult sinks_and_sources_handler(DBusConnection *c, DBusMessag
             xml = pa_strbuf_tostring_free(sb);
 
             pa_assert_se(r = dbus_message_new_method_return(m));
-            pa_assert_se(dbus_message_append_args(
-                                 r,
-                                 DBUS_TYPE_STRING, &xml,
-                                 DBUS_TYPE_INVALID));
+            pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID));
 
             pa_xfree(xml);
         } else
@@ -655,91 +963,55 @@ static DBusHandlerResult sinks_and_sources_handler(DBusConnection *c, DBusMessag
         if (!sink && !source)
             return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
-        if (message_is_property_get(m, "org.gnome.UPnP.MediaObject1", "Parent")) {
+        if (message_is_property_get(m, "org.gnome.UPnP.MediaObject2", "Parent")) {
             pa_assert_se(r = dbus_message_new_method_return(m));
             append_variant_object(r, NULL, sink ? OBJECT_SINKS : OBJECT_SOURCES);
 
-        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaObject1", "DisplayName")) {
+        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaObject2", "Type")) {
             pa_assert_se(r = dbus_message_new_method_return(m));
-            append_variant_string(r, NULL, pa_strna(pa_proplist_gets(sink ? sink->proplist : source->proplist, PA_PROP_DEVICE_DESCRIPTION)));
+            append_variant_string(r, NULL, "audio");
 
-        } else if (message_is_property_get_all(m, "org.gnome.UPnP.MediaObject1")) {
+        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaObject2", "Path")) {
+            pa_assert_se(r = dbus_message_new_method_return(m));
+            append_variant_object(r, NULL, path);
+
+        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaObject2", "DisplayName")) {
+            pa_assert_se(r = dbus_message_new_method_return(m));
+            append_variant_item_display_name(r, NULL, sink, source);
+
+        } else if (message_is_property_get_all(m, "org.gnome.UPnP.MediaObject2")) {
             DBusMessageIter iter, sub;
 
             pa_assert_se(r = dbus_message_new_method_return(m));
             dbus_message_iter_init_append(r, &iter);
 
             pa_assert_se(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub));
-            append_property_dict_entry_object(r, &sub, "Parent", sink ? OBJECT_SINKS : OBJECT_SOURCES);
-            append_property_dict_entry_string(r, &sub, "DisplayName", pa_strna(pa_proplist_gets(sink ? sink->proplist : source->proplist, PA_PROP_DEVICE_DESCRIPTION)));
+            append_sink_or_source_item_mediaobject2_properties(r, &sub, path, sink, source);
             pa_assert_se(dbus_message_iter_close_container(&iter, &sub));
 
-        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaItem1", "Type")) {
+        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaItem2", "MIMEType")) {
             pa_assert_se(r = dbus_message_new_method_return(m));
-            append_variant_string(r, NULL, "audio");
-
-        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaItem1", "MIMEType")) {
-            char *t;
-
-            if (sink)
-                t = pa_sample_spec_to_mime_type_mimefy(&sink->sample_spec, &sink->channel_map);
-            else
-                t = pa_sample_spec_to_mime_type_mimefy(&source->sample_spec, &source->channel_map);
+            append_variant_mime_type(r, NULL, sink, source);
 
+        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaItem2", "DLNAProfile")) {
             pa_assert_se(r = dbus_message_new_method_return(m));
-            append_variant_string(r, NULL, t);
-            pa_xfree(t);
-
-        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaItem1", "URLs")) {
-            DBusMessageIter iter, sub, array;
-            char *url;
+            append_variant_string(r, NULL, "LPCM");
 
+        } else if (message_is_property_get(m, "org.gnome.UPnP.MediaItem2", "URLs")) {
             pa_assert_se(r = dbus_message_new_method_return(m));
+            append_variant_urls(r, NULL, u, sink, source);
 
-            dbus_message_iter_init_append(r, &iter);
-
-            url = compute_url(u, sink ? sink->monitor_source->name : source->name);
-
-            pa_assert_se(dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, "as", &sub));
-            pa_assert_se(dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "s", &array));
-            pa_assert_se(dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &url));
-            pa_assert_se(dbus_message_iter_close_container(&sub, &array));
-            pa_assert_se(dbus_message_iter_close_container(&iter, &sub));
-
-            pa_xfree(url);
-
-        } else if (message_is_property_get_all(m, "org.gnome.UPnP.MediaItem1")) {
-            DBusMessageIter iter, sub, dict, variant, array;
-            char *url, *t;
-            const char *un = "URLs";
+        } else if (message_is_property_get_all(m, "org.gnome.UPnP.MediaItem2")) {
+            DBusMessageIter iter, sub;
 
             pa_assert_se(r = dbus_message_new_method_return(m));
             dbus_message_iter_init_append(r, &iter);
 
             pa_assert_se(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub));
-            append_property_dict_entry_string(r, &sub, "Type", "audio");
-
-            if (sink)
-                t = pa_sample_spec_to_mime_type_mimefy(&sink->sample_spec, &sink->channel_map);
-            else
-                t = pa_sample_spec_to_mime_type_mimefy(&source->sample_spec, &source->channel_map);
-
-            append_property_dict_entry_string(r, &sub, "MIMEType", t);
-            pa_xfree(t);
-
-            pa_assert_se(dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, NULL, &dict));
-            pa_assert_se(dbus_message_iter_append_basic(&dict, DBUS_TYPE_STRING, &un));
-
-            url = compute_url(u, sink ? sink->monitor_source->name : source->name);
-
-            pa_assert_se(dbus_message_iter_open_container(&dict, DBUS_TYPE_VARIANT, "as", &variant));
-            pa_assert_se(dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY, "s", &array));
-            pa_assert_se(dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &url));
-            pa_assert_se(dbus_message_iter_close_container(&variant, &array));
-            pa_assert_se(dbus_message_iter_close_container(&dict, &variant));
-            pa_assert_se(dbus_message_iter_close_container(&sub, &dict));
 
-            pa_xfree(url);
+            append_property_dict_entry_mime_type(r, &sub, sink, source);
+            append_property_dict_entry_string(r, &sub, "DLNAProfile", "LPCM");
+            append_property_dict_entry_urls(r, &sub, u, sink, source);
 
             pa_assert_se(dbus_message_iter_close_container(&iter, &sub));
 
@@ -748,10 +1020,7 @@ static DBusHandlerResult sinks_and_sources_handler(DBusConnection *c, DBusMessag
                 ITEM_INTROSPECT_XML;
 
             pa_assert_se(r = dbus_message_new_method_return(m));
-            pa_assert_se(dbus_message_append_args(
-                                 r,
-                                 DBUS_TYPE_STRING, &xml,
-                                 DBUS_TYPE_INVALID));
+            pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID));
 
         } else
             return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
diff --git a/src/modules/module-simple-protocol-tcp-symdef.h b/src/modules/module-simple-protocol-tcp-symdef.h
deleted file mode 100644 (file)
index 3fcef40..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulesimpleprotocoltcpsymdeffoo
-#define foomodulesimpleprotocoltcpsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_simple_protocol_tcp_LTX_pa__init
-#define pa__done module_simple_protocol_tcp_LTX_pa__done
-#define pa__get_author module_simple_protocol_tcp_LTX_pa__get_author
-#define pa__get_description module_simple_protocol_tcp_LTX_pa__get_description
-#define pa__get_usage module_simple_protocol_tcp_LTX_pa__get_usage
-#define pa__get_version module_simple_protocol_tcp_LTX_pa__get_version
-#define pa__get_deprecated module_simple_protocol_tcp_LTX_pa__get_deprecated
-#define pa__load_once module_simple_protocol_tcp_LTX_pa__load_once
-#define pa__get_n_used module_simple_protocol_tcp_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
diff --git a/src/modules/module-simple-protocol-unix-symdef.h b/src/modules/module-simple-protocol-unix-symdef.h
deleted file mode 100644 (file)
index 5f30433..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulesimpleprotocolunixsymdeffoo
-#define foomodulesimpleprotocolunixsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_simple_protocol_unix_LTX_pa__init
-#define pa__done module_simple_protocol_unix_LTX_pa__done
-#define pa__get_author module_simple_protocol_unix_LTX_pa__get_author
-#define pa__get_description module_simple_protocol_unix_LTX_pa__get_description
-#define pa__get_usage module_simple_protocol_unix_LTX_pa__get_usage
-#define pa__get_version module_simple_protocol_unix_LTX_pa__get_version
-#define pa__get_deprecated module_simple_protocol_unix_LTX_pa__get_deprecated
-#define pa__load_once module_simple_protocol_unix_LTX_pa__load_once
-#define pa__get_n_used module_simple_protocol_unix_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
diff --git a/src/modules/module-sine-source-symdef.h b/src/modules/module-sine-source-symdef.h
deleted file mode 100644 (file)
index f35f742..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulesinesourcesymdeffoo
-#define foomodulesinesourcesymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_sine_source_LTX_pa__init
-#define pa__done module_sine_source_LTX_pa__done
-#define pa__get_author module_sine_source_LTX_pa__get_author
-#define pa__get_description module_sine_source_LTX_pa__get_description
-#define pa__get_usage module_sine_source_LTX_pa__get_usage
-#define pa__get_version module_sine_source_LTX_pa__get_version
-#define pa__get_deprecated module_sine_source_LTX_pa__get_deprecated
-#define pa__load_once module_sine_source_LTX_pa__load_once
-#define pa__get_n_used module_sine_source_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 9826e5f..20a6868 100644 (file)
 #endif
 
 #include <stdlib.h>
-#include <sys/stat.h>
 #include <stdio.h>
 #include <errno.h>
-#include <string.h>
-#include <fcntl.h>
 #include <unistd.h>
-#include <limits.h>
-#include <sys/ioctl.h>
-#include <sys/poll.h>
 
 #include <pulse/rtclock.h>
 #include <pulse/timeval.h>
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/core-error.h>
 #include <pulsecore/source.h>
 #include <pulsecore/module.h>
-#include <pulsecore/core-rtclock.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/log.h>
@@ -274,7 +266,7 @@ int pa__init(pa_module*m) {
     pa_source_set_rtpoll(u->source, u->rtpoll);
     pa_source_set_fixed_latency(u->source, u->block_usec);
 
-    if (!(u->thread = pa_thread_new(thread_func, u))) {
+    if (!(u->thread = pa_thread_new("sine-source", thread_func, u))) {
         pa_log("Failed to create thread.");
         goto fail;
     }
diff --git a/src/modules/module-sine-symdef.h b/src/modules/module-sine-symdef.h
deleted file mode 100644 (file)
index 6a51f03..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulesinesymdeffoo
-#define foomodulesinesymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_sine_LTX_pa__init
-#define pa__done module_sine_LTX_pa__done
-#define pa__get_author module_sine_LTX_pa__get_author
-#define pa__get_description module_sine_LTX_pa__get_description
-#define pa__get_usage module_sine_LTX_pa__get_usage
-#define pa__get_version module_sine_LTX_pa__get_version
-#define pa__get_deprecated module_sine_LTX_pa__get_deprecated
-#define pa__load_once module_sine_LTX_pa__load_once
-#define pa__get_n_used module_sine_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 69b2002..c6d7303 100644 (file)
@@ -24,7 +24,6 @@
 #endif
 
 #include <stdio.h>
-#include <math.h>
 
 #include <pulse/xmalloc.h>
 
@@ -33,7 +32,6 @@
 #include <pulsecore/modargs.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/log.h>
-#include <pulsecore/core-util.h>
 
 #include "module-sine-symdef.h"
 
@@ -157,7 +155,7 @@ int pa__init(pa_module*m) {
     pa_sink_input_new_data_init(&data);
     data.driver = __FILE__;
     data.module = m;
-    data.sink = sink;
+    pa_sink_input_new_data_set_sink(&data, sink, FALSE);
     pa_proplist_setf(data.proplist, PA_PROP_MEDIA_NAME, "%u Hz Sine", frequency);
     pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, "abstract");
     pa_proplist_setf(data.proplist, "sine.hz", "%u", frequency);
diff --git a/src/modules/module-solaris-symdef.h b/src/modules/module-solaris-symdef.h
deleted file mode 100644 (file)
index 0ee6a00..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulesolarissymdeffoo
-#define foomodulesolarissymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_solaris_LTX_pa__init
-#define pa__done module_solaris_LTX_pa__done
-#define pa__get_author module_solaris_LTX_pa__get_author
-#define pa__get_description module_solaris_LTX_pa__get_description
-#define pa__get_usage module_solaris_LTX_pa__get_usage
-#define pa__get_version module_solaris_LTX_pa__get_version
-#define pa__get_deprecated module_solaris_LTX_pa__get_deprecated
-#define pa__load_once module_solaris_LTX_pa__load_once
-#define pa__get_n_used module_solaris_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index b0d4db4..7f3342f 100644 (file)
 #include <stdlib.h>
 #include <stdio.h>
 #include <errno.h>
-#include <string.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <limits.h>
 #include <sys/ioctl.h>
-#include <sys/stat.h>
 #include <sys/types.h>
 
 #include <signal.h>
 #include <sys/conf.h>
 #include <sys/audio.h>
 
-#include <pulse/error.h>
 #include <pulse/mainloop-signal.h>
 #include <pulse/xmalloc.h>
 #include <pulse/timeval.h>
 #include <pulse/util.h>
 #include <pulse/rtclock.h>
 
-#include <pulsecore/iochannel.h>
 #include <pulsecore/sink.h>
 #include <pulsecore/source.h>
 #include <pulsecore/module.h>
@@ -168,7 +163,10 @@ static uint64_t get_playback_buffered_bytes(struct userdata *u) {
 
     pa_smoother_put(u->smoother, pa_rtclock_now(), pa_bytes_to_usec(played_bytes, &u->sink->sample_spec));
 
-    return u->written_bytes - played_bytes;
+    if (u->written_bytes > played_bytes)
+        return u->written_bytes - played_bytes;
+    else
+        return 0;
 }
 
 static pa_usec_t sink_get_latency(struct userdata *u, pa_sample_spec *ss) {
@@ -307,8 +305,8 @@ static int auto_format(int fd, int mode, pa_sample_spec *ss) {
             info.record.encoding = AUDIO_ENCODING_LINEAR;
             break;
         default:
-             pa_log("AUDIO_SETINFO: Unsupported sample format.");
-             return -1;
+            pa_log("AUDIO_SETINFO: Unsupported sample format.");
+            return -1;
         }
     }
 
@@ -327,7 +325,7 @@ static int open_audio_device(struct userdata *u, pa_sample_spec *ss) {
     pa_assert(u);
     pa_assert(ss);
 
-    if ((u->fd = open(u->device_name, u->mode | O_NONBLOCK)) < 0) {
+    if ((u->fd = pa_open_cloexec(u->device_name, u->mode | O_NONBLOCK, 0)) < 0) {
         pa_log_warn("open %s failed (%s)", u->device_name, pa_cstrerror(errno));
         return -1;
     }
@@ -353,7 +351,7 @@ static int suspend(struct userdata *u) {
 
     pa_log_info("Suspending...");
 
-    ioctl(u->fd, AUDIO_DRAIN, NULL);
+    ioctl(u->fd, I_FLUSH, FLUSHRW);
     pa_close(u->fd);
     u->fd = -1;
 
@@ -531,7 +529,7 @@ static void source_set_volume(pa_source *s) {
     if (u->fd >= 0) {
         AUDIO_INITINFO(&info);
 
-        info.play.gain = pa_cvolume_max(&s->volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM;
+        info.play.gain = pa_cvolume_max(&s->real_volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM;
         assert(info.play.gain <= AUDIO_MAX_GAIN);
 
         if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) {
@@ -553,7 +551,7 @@ static void source_get_volume(pa_source *s) {
         if (ioctl(u->fd, AUDIO_GETINFO, &info) < 0)
             pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
         else
-            pa_cvolume_set(&s->volume, s->sample_spec.channels, info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN);
+            pa_cvolume_set(&s->real_volume, s->sample_spec.channels, info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN);
     }
 }
 
@@ -592,9 +590,12 @@ static void process_rewind(struct userdata *u) {
 
     pa_assert(u);
 
-    /* Figure out how much we shall rewind and reset the counter */
+    if (!PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
+        pa_sink_process_rewind(u->sink, 0);
+        return;
+    }
+
     rewind_nbytes = u->sink->thread_info.rewind_nbytes;
-    u->sink->thread_info.rewind_nbytes = 0;
 
     if (rewind_nbytes > 0) {
         pa_log_debug("Requested to rewind %lu bytes.", (unsigned long) rewind_nbytes);
@@ -630,13 +631,13 @@ static void thread_func(void *userdata) {
     for (;;) {
         /* Render some data and write it to the dsp */
 
+        if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
+            process_rewind(u);
+
         if (u->sink && PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
             pa_usec_t xtime0, ysleep_interval, xsleep_interval;
             uint64_t buffered_bytes;
 
-            if (u->sink->thread_info.rewind_requested)
-                process_rewind(u);
-
             err = ioctl(u->fd, AUDIO_GETINFO, &info);
             if (err < 0) {
                 pa_log("AUDIO_GETINFO ioctl failed: %s", pa_cstrerror(errno));
@@ -938,7 +939,7 @@ int pa__init(pa_module *m) {
             goto fail;
         }
 
-        u->source = pa_source_new(m->core, &source_new_data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY|PA_SOURCE_HW_VOLUME_CTRL);
+        u->source = pa_source_new(m->core, &source_new_data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
         pa_source_new_data_done(&source_new_data);
         pa_xfree(name_buf);
 
@@ -954,8 +955,8 @@ int pa__init(pa_module *m) {
         pa_source_set_rtpoll(u->source, u->rtpoll);
         pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->buffer_size, &u->source->sample_spec));
 
-        u->source->get_volume = source_get_volume;
-        u->source->set_volume = source_set_volume;
+        pa_source_set_get_volume_callback(u->source, source_get_volume);
+        pa_source_set_set_volume_callback(u->source, source_set_volume);
         u->source->refresh_volume = TRUE;
     } else
         u->source = NULL;
@@ -986,7 +987,7 @@ int pa__init(pa_module *m) {
             goto fail;
         }
 
-        u->sink = pa_sink_new(m->core, &sink_new_data, PA_SINK_HARDWARE|PA_SINK_LATENCY|PA_SINK_HW_VOLUME_CTRL|PA_SINK_HW_MUTE_CTRL);
+        u->sink = pa_sink_new(m->core, &sink_new_data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
         pa_sink_new_data_done(&sink_new_data);
 
         pa_assert(u->sink);
@@ -999,10 +1000,10 @@ int pa__init(pa_module *m) {
         pa_sink_set_max_request(u->sink, u->buffer_size);
         pa_sink_set_max_rewind(u->sink, u->buffer_size);
 
-        u->sink->get_volume = sink_get_volume;
-        u->sink->set_volume = sink_set_volume;
-        u->sink->get_mute = sink_get_mute;
-        u->sink->set_mute = sink_set_mute;
+        pa_sink_set_get_volume_callback(u->sink, sink_get_volume);
+        pa_sink_set_set_volume_callback(u->sink, sink_set_volume);
+        pa_sink_set_get_mute_callback(u->sink, sink_get_mute);
+        pa_sink_set_set_mute_callback(u->sink, sink_set_mute);
         u->sink->refresh_volume = u->sink->refresh_muted = TRUE;
     } else
         u->sink = NULL;
@@ -1015,7 +1016,7 @@ int pa__init(pa_module *m) {
     else
         pa_log_warn("Could not register SIGPOLL handler");
 
-    if (!(u->thread = pa_thread_new(thread_func, u))) {
+    if (!(u->thread = pa_thread_new("solaris", thread_func, u))) {
         pa_log("Failed to create thread.");
         goto fail;
     }
diff --git a/src/modules/module-stream-mgr.c b/src/modules/module-stream-mgr.c
new file mode 100644 (file)
index 0000000..de9628b
--- /dev/null
@@ -0,0 +1,312 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2005-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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/module.h>
+#include <pulsecore/log.h>
+#include <pulsecore/namereg.h>
+#include <pulsecore/sink.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/macro.h>
+#ifdef HAVE_DBUS
+#include <pulsecore/protocol-dbus.h>
+#include <pulsecore/dbus-util.h>
+#endif
+
+#include "module-stream-mgr-symdef.h"
+#include "tizen-audio.h"
+
+PA_MODULE_AUTHOR("Sangchul Lee");
+PA_MODULE_DESCRIPTION("Stream Manager module using IPC");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(TRUE);
+PA_MODULE_USAGE("ipc_type=<pipe or dbus>");
+
+static void io_event_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata);
+
+static const char* const valid_modargs[] = {
+    "ipc_type",
+    NULL,
+};
+
+struct userdata {
+    int fd;
+    pa_io_event *io;
+    pa_module *module;
+    pa_usec_t before;
+    pa_usec_t now;
+#ifdef HAVE_DBUS
+    pa_dbus_protocol *dbus_protocol;
+#endif
+};
+
+#define FILE_FULL_PATH 1024        /* File path lenth */
+
+struct ipc_data {
+    char filename[FILE_FULL_PATH];
+    int volume_config;
+};
+
+#define KEYTONE_PATH        "/tmp/keytone"  /* Keytone pipe path */
+#define KEYTONE_GROUP       6526            /* Keytone group : assigned by security */
+#define DEFAULT_IPC_TYPE    IPC_TYPE_PIPE
+#define AUDIO_VOLUME_CONFIG_TYPE(vol) (vol & 0x00FF)
+#define AUDIO_VOLUME_CONFIG_GAIN(vol) (vol & 0xFF00)
+
+static int init_ipc (struct userdata *u, const char *type) {
+
+    pa_assert(u);
+    pa_assert(type);
+
+    pa_log_info("Initialization for IPC, type:[%s]", type);
+
+    if(!strncmp(type, "pipe", 4)) {
+        int pre_mask;
+
+        pre_mask = umask(0);
+        if (mknod(KEYTONE_PATH,S_IFIFO|0660,0)<0) {
+            pa_log_warn("mknod failed. errno=[%d][%s]", errno, strerror(errno));
+        }
+        umask(pre_mask);
+
+        u->fd = open(KEYTONE_PATH, O_RDWR);
+        if (u->fd == -1) {
+            pa_log_warn("Check ipc node %s\n", KEYTONE_PATH);
+            return -1;
+        }
+
+        /* change access mode so group can use keytone pipe */
+        if (fchmod (u->fd, 0666) == -1) {
+            pa_log_warn("Changing keytone access mode is failed. errno=[%d][%s]", errno, strerror(errno));
+        }
+
+        /* change group due to security request */
+        if (fchown (u->fd, -1, KEYTONE_GROUP) == -1) {
+            pa_log_warn("Changing keytone group is failed. errno=[%d][%s]", errno, strerror(errno));
+        }
+
+        u->io = u->module->core->mainloop->io_new(u->module->core->mainloop, u->fd, PA_IO_EVENT_INPUT|PA_IO_EVENT_HANGUP, io_event_callback, u);
+        pa_rtclock_now_args(&u->before);
+        pa_rtclock_now_args(&u->now);
+    } else if (!strncmp(type, "dbus", 4)) {
+        /* NOTE : need implementation for DBUS work */
+#ifdef HAVE_DBUS
+        /* TODO : need to add codes for initialization of dbus */
+#else
+        pa_log_error("DBUS is not supported\n");
+        return -1;
+#endif
+
+    } else {
+        pa_log_error("Unknown type(%s) for IPC", type);
+        return -1;
+    }
+
+    return 0;
+}
+
+static void deinit_ipc (struct userdata *u) {
+
+    pa_assert(u);
+
+    if (u->io)
+        u->module->core->mainloop->io_free(u->io);
+
+    if (u->fd > -1)
+        close(u->fd);
+
+#ifdef HAVE_DBUS
+    /* TODO : need to add codes for de-initialization of dbus */
+#endif
+}
+
+#define MAX_GAIN_TYPE  4
+static const char* get_str_gain_type[MAX_GAIN_TYPE] =
+{
+    "GAIN_TYPE_DEFAULT",
+    "GAIN_TYPE_DIALER",
+    "GAIN_TYPE_TOUCH",
+    "GAIN_TYPE_OTHERS"
+};
+
+#define MAX_NAME_LEN 256
+static int _simple_play(struct userdata *u, const char *file_path, uint32_t volume_config) {
+    int ret = 0;
+    pa_sink *sink = NULL;
+    pa_proplist *p;
+    const char *name_prefix = "SIMPLE_PLAY";
+    double volume_linear = 1.0f;
+    int volume_type =  AUDIO_VOLUME_CONFIG_TYPE(volume_config);
+    int volume_gain =  AUDIO_VOLUME_CONFIG_GAIN(volume_config)>>8;
+    char name[MAX_NAME_LEN] = {0};
+
+    uint32_t stream_idx;
+    uint32_t play_idx = 0;
+
+    p = pa_proplist_new();
+
+    /* Set volume type of stream */
+    pa_proplist_setf(p, PA_PROP_MEDIA_TIZEN_VOLUME_TYPE, "%d", volume_type);
+    /* Set gain type of stream */
+    pa_proplist_setf(p, PA_PROP_MEDIA_TIZEN_GAIN_TYPE, "%d", volume_gain);
+    /* Set policy type of stream */
+    pa_proplist_sets(p, PA_PROP_MEDIA_POLICY, "auto");
+    /* Set policy for selecting sink */
+    pa_proplist_sets(p, PA_PROP_MEDIA_POLICY_IGNORE_PRESET_SINK, "yes");
+    sink = pa_namereg_get_default_sink(u->module->core);
+
+    pa_log_debug_verbose("volume_config[type:0x%x,gain:0x%x[%s]]", volume_type, volume_gain,
+                 volume_gain > (MAX_GAIN_TYPE-2) ? get_str_gain_type[MAX_GAIN_TYPE-1]: get_str_gain_type[volume_gain]);
+    snprintf(name, sizeof(name)-1, "%s_%s", name_prefix, file_path);
+    play_idx = pa_scache_get_id_by_name(u->module->core, name);
+    if (play_idx != PA_IDXSET_INVALID) {
+        pa_log_debug_verbose("found cached index [%u] for name [%s]", play_idx, file_path);
+    } else {
+        if ((ret = pa_scache_add_file_lazy(u->module->core, name, file_path, &play_idx)) != 0) {
+            pa_log_error("failed to add file [%s]", file_path);
+            goto exit;
+        } else {
+            pa_log_debug_verbose("success to add file [%s], index [%u]", file_path, play_idx);
+        }
+    }
+
+    pa_log_debug_verbose("pa_scache_play_item() start");
+    if ((ret = pa_scache_play_item(u->module->core, name, sink, PA_VOLUME_NORM, p, &stream_idx) < 0)) {
+        pa_log_error("pa_scache_play_item fail");
+        goto exit;
+    }
+    pa_log_debug_verbose("pa_scache_play_item() end");
+
+exit:
+    pa_proplist_free(p);
+    return ret;
+}
+
+
+static void io_event_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
+    struct userdata *u = userdata;
+    struct ipc_data data;
+    int ret = 0;
+    int size = 0;
+
+    pa_usec_t diff = 0ULL;
+    int gain = 0;
+
+    pa_assert(io);
+    pa_assert(u);
+
+    if (events & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) {
+        pa_log_warn("Lost connection to client side");
+        goto fail;
+    }
+
+    if (events & PA_IO_EVENT_INPUT) {
+        size = sizeof(data);
+        memset(&data, 0, size);
+        ret = read(fd, (void *)&data, size);
+        if(ret != -1) {
+            gain = AUDIO_VOLUME_CONFIG_GAIN(data.volume_config)>>8;
+            pa_rtclock_now_args(&u->now);
+            diff = u->now - u->before;
+            u->before = u->now;
+
+            /* volume is increased sometime if client request to play tone quickly. 25mss*/
+            if(gain==AUDIO_GAIN_TYPE_TOUCH && 25000ULL > diff) {
+                pa_log_warn("skip playing keytone. becuase client requested to play tone quickly.");
+                return;
+            }
+
+            pa_log_info("name(%s), volume_config(0x%x), diff(%llu) from the event", data.filename, data.volume_config, diff);
+            _simple_play(u, data.filename, data.volume_config);
+
+        } else {
+            pa_log_warn("Fail to read file");
+        }
+    }
+
+    return;
+
+fail:
+    u->module->core->mainloop->io_free(u->io);
+    u->io = NULL;
+
+    pa_module_unload_request(u->module, TRUE);
+}
+
+
+int pa__init(pa_module*m) {
+    struct userdata *u;
+    pa_modargs *ma = NULL;
+    const char *ipc_type = NULL;
+
+    pa_assert(m);
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments");
+        goto fail;
+    }
+
+    ipc_type = pa_modargs_get_value(ma, "ipc_type", "pipe");
+
+    m->userdata = u = pa_xnew(struct userdata, 1);
+    u->module = m;
+    u->io = NULL;
+    u->fd = -1;
+
+    if (init_ipc(u, ipc_type))
+        goto fail;
+
+    pa_modargs_free(ma);
+
+    return 0;
+
+fail:
+
+    pa_modargs_free(ma);
+    pa__done(m);
+    return -1;
+}
+
+
+void pa__done(pa_module*m) {
+    struct userdata *u;
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    deinit_ipc(u);
+
+    pa_xfree(u);
+}
diff --git a/src/modules/module-stream-restore-symdef.h b/src/modules/module-stream-restore-symdef.h
deleted file mode 100644 (file)
index 8752d0a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulestreamrestoresymdeffoo
-#define foomodulestreamrestoresymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_stream_restore_LTX_pa__init
-#define pa__done module_stream_restore_LTX_pa__done
-#define pa__get_author module_stream_restore_LTX_pa__get_author
-#define pa__get_description module_stream_restore_LTX_pa__get_description
-#define pa__get_usage module_stream_restore_LTX_pa__get_usage
-#define pa__get_version module_stream_restore_LTX_pa__get_version
-#define pa__get_deprecated module_stream_restore_LTX_pa__get_deprecated
-#define pa__load_once module_stream_restore_LTX_pa__load_once
-#define pa__get_n_used module_stream_restore_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 153873c..23f4780 100644 (file)
@@ -2,6 +2,7 @@
   This file is part of PulseAudio.
 
   Copyright 2008 Lennart Poettering
+  Copyright 2009 Tanu Kaskinen
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
 #include <sys/types.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <ctype.h>
 
+#include <pulse/gccmacro.h>
 #include <pulse/xmalloc.h>
 #include <pulse/volume.h>
 #include <pulse/timeval.h>
-#include <pulse/util.h>
 #include <pulse/rtclock.h>
 
 #include <pulsecore/core-error.h>
 #include <pulsecore/pstream.h>
 #include <pulsecore/pstream-util.h>
 #include <pulsecore/database.h>
+#include <pulsecore/tagstruct.h>
+#include <pulsecore/proplist-util.h>
+
+#ifdef HAVE_DBUS
+#include <pulsecore/dbus-util.h>
+#include <pulsecore/protocol-dbus.h>
+#endif
 
 #include "module-stream-restore-symdef.h"
 
@@ -62,17 +69,24 @@ PA_MODULE_USAGE(
         "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_rescue=<When device becomes unavailable, recheck streams?> "
+        "fallback_table=<filename>");
 
 #define SAVE_INTERVAL (10 * PA_USEC_PER_SEC)
 #define IDENTIFICATION_PROPERTY "module-stream-restore.id"
 
+#define DEFAULT_FALLBACK_FILE PA_DEFAULT_CONFIG_DIR"/stream-restore.table"
+#define DEFAULT_FALLBACK_FILE_USER "stream-restore.table"
+
+#define WHITESPACE "\n\r \t"
+
 static const char* const valid_modargs[] = {
     "restore_device",
     "restore_volume",
     "restore_muted",
     "on_hotplug",
     "on_rescue",
+    "fallback_table",
     NULL
 };
 
@@ -84,6 +98,7 @@ struct userdata {
         *sink_input_new_hook_slot,
         *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,
@@ -100,72 +115,1007 @@ struct userdata {
 
     pa_native_protocol *protocol;
     pa_idxset *subscribed;
+
+#ifdef HAVE_DBUS
+    pa_dbus_protocol *dbus_protocol;
+    pa_hashmap *dbus_entries;
+    uint32_t next_index; /* For generating object paths for entries. */
+#endif
 };
 
-#define ENTRY_VERSION 3
+#define ENTRY_VERSION 1
 
 struct entry {
     uint8_t version;
-    pa_bool_t muted_valid:1, volume_valid:1, device_valid:1, card_valid:1;
-    pa_bool_t muted:1;
+    pa_bool_t muted_valid, volume_valid, device_valid, card_valid;
+    pa_bool_t muted;
     pa_channel_map channel_map;
     pa_cvolume volume;
-    char device[PA_NAME_MAX];
-    char card[PA_NAME_MAX];
-} PA_GCC_PACKED;
+    char* device;
+    char* card;
+};
+
+enum {
+    SUBCOMMAND_TEST,
+    SUBCOMMAND_READ,
+    SUBCOMMAND_WRITE,
+    SUBCOMMAND_DELETE,
+    SUBCOMMAND_SUBSCRIBE,
+    SUBCOMMAND_EVENT
+};
+
+
+static struct entry* entry_new(void);
+static void entry_free(struct entry *e);
+static struct entry *entry_read(struct userdata *u, const char *name);
+static pa_bool_t entry_write(struct userdata *u, const char *name, const struct entry *e, pa_bool_t replace);
+static struct entry* entry_copy(const struct entry *e);
+static void entry_apply(struct userdata *u, const char *name, struct entry *e);
+static void trigger_save(struct userdata *u);
+
+#ifdef HAVE_DBUS
+
+#define OBJECT_PATH "/org/pulseaudio/stream_restore1"
+#define ENTRY_OBJECT_NAME "entry"
+#define INTERFACE_STREAM_RESTORE "org.PulseAudio.Ext.StreamRestore1"
+#define INTERFACE_ENTRY INTERFACE_STREAM_RESTORE ".RestoreEntry"
+
+#define DBUS_INTERFACE_REVISION 0
+
+struct dbus_entry {
+    struct userdata *userdata;
+
+    char *entry_name;
+    uint32_t index;
+    char *object_path;
+};
+
+static void handle_get_interface_revision(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_entries(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_add_entry(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_entry_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_entry_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_entry_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_entry_get_device(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_entry_set_device(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+static void handle_entry_get_volume(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_entry_set_volume(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+static void handle_entry_get_mute(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_entry_set_mute(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+
+static void handle_entry_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+static void handle_entry_remove(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+enum property_handler_index {
+    PROPERTY_HANDLER_INTERFACE_REVISION,
+    PROPERTY_HANDLER_ENTRIES,
+    PROPERTY_HANDLER_MAX
+};
+
+enum entry_property_handler_index {
+    ENTRY_PROPERTY_HANDLER_INDEX,
+    ENTRY_PROPERTY_HANDLER_NAME,
+    ENTRY_PROPERTY_HANDLER_DEVICE,
+    ENTRY_PROPERTY_HANDLER_VOLUME,
+    ENTRY_PROPERTY_HANDLER_MUTE,
+    ENTRY_PROPERTY_HANDLER_MAX
+};
+
+static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = {
+    [PROPERTY_HANDLER_INTERFACE_REVISION] = { .property_name = "InterfaceRevision", .type = "u",  .get_cb = handle_get_interface_revision, .set_cb = NULL },
+    [PROPERTY_HANDLER_ENTRIES]            = { .property_name = "Entries",           .type = "ao", .get_cb = handle_get_entries,            .set_cb = NULL }
+};
+
+static pa_dbus_property_handler entry_property_handlers[ENTRY_PROPERTY_HANDLER_MAX] = {
+    [ENTRY_PROPERTY_HANDLER_INDEX]    = { .property_name = "Index",   .type = "u",     .get_cb = handle_entry_get_index,    .set_cb = NULL },
+    [ENTRY_PROPERTY_HANDLER_NAME]     = { .property_name = "Name",    .type = "s",     .get_cb = handle_entry_get_name,     .set_cb = NULL },
+    [ENTRY_PROPERTY_HANDLER_DEVICE]   = { .property_name = "Device",  .type = "s",     .get_cb = handle_entry_get_device,   .set_cb = handle_entry_set_device },
+    [ENTRY_PROPERTY_HANDLER_VOLUME]   = { .property_name = "Volume",  .type = "a(uu)", .get_cb = handle_entry_get_volume,   .set_cb = handle_entry_set_volume },
+    [ENTRY_PROPERTY_HANDLER_MUTE]     = { .property_name = "Mute",    .type = "b",     .get_cb = handle_entry_get_mute,     .set_cb = handle_entry_set_mute }
+};
+
+enum method_handler_index {
+    METHOD_HANDLER_ADD_ENTRY,
+    METHOD_HANDLER_GET_ENTRY_BY_NAME,
+    METHOD_HANDLER_MAX
+};
+
+enum entry_method_handler_index {
+    ENTRY_METHOD_HANDLER_REMOVE,
+    ENTRY_METHOD_HANDLER_MAX
+};
+
+static pa_dbus_arg_info add_entry_args[] = { { "name",              "s",     "in" },
+                                             { "device",            "s",     "in" },
+                                             { "volume",            "a(uu)", "in" },
+                                             { "mute",              "b",     "in" },
+                                             { "apply_immediately", "b",     "in" },
+                                             { "entry",             "o",     "out" } };
+static pa_dbus_arg_info get_entry_by_name_args[] = { { "name", "s", "in" }, { "entry", "o", "out" } };
+
+static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
+    [METHOD_HANDLER_ADD_ENTRY] = {
+        .method_name = "AddEntry",
+        .arguments = add_entry_args,
+        .n_arguments = sizeof(add_entry_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_add_entry },
+    [METHOD_HANDLER_GET_ENTRY_BY_NAME] = {
+        .method_name = "GetEntryByName",
+        .arguments = get_entry_by_name_args,
+        .n_arguments = sizeof(get_entry_by_name_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_get_entry_by_name }
+};
+
+static pa_dbus_method_handler entry_method_handlers[ENTRY_METHOD_HANDLER_MAX] = {
+    [ENTRY_METHOD_HANDLER_REMOVE] = {
+        .method_name = "Remove",
+        .arguments = NULL,
+        .n_arguments = 0,
+        .receive_cb = handle_entry_remove }
+};
+
+enum signal_index {
+    SIGNAL_NEW_ENTRY,
+    SIGNAL_ENTRY_REMOVED,
+    SIGNAL_MAX
+};
+
+enum entry_signal_index {
+    ENTRY_SIGNAL_DEVICE_UPDATED,
+    ENTRY_SIGNAL_VOLUME_UPDATED,
+    ENTRY_SIGNAL_MUTE_UPDATED,
+    ENTRY_SIGNAL_MAX
+};
+
+static pa_dbus_arg_info new_entry_args[]     = { { "entry", "o", NULL } };
+static pa_dbus_arg_info entry_removed_args[] = { { "entry", "o", NULL } };
+
+static pa_dbus_arg_info entry_device_updated_args[] = { { "device", "s",     NULL } };
+static pa_dbus_arg_info entry_volume_updated_args[] = { { "volume", "a(uu)", NULL } };
+static pa_dbus_arg_info entry_mute_updated_args[]   = { { "muted",  "b",     NULL } };
+
+static pa_dbus_signal_info signals[SIGNAL_MAX] = {
+    [SIGNAL_NEW_ENTRY]     = { .name = "NewEntry",     .arguments = new_entry_args,     .n_arguments = 1 },
+    [SIGNAL_ENTRY_REMOVED] = { .name = "EntryRemoved", .arguments = entry_removed_args, .n_arguments = 1 }
+};
+
+static pa_dbus_signal_info entry_signals[ENTRY_SIGNAL_MAX] = {
+    [ENTRY_SIGNAL_DEVICE_UPDATED] = { .name = "DeviceUpdated", .arguments = entry_device_updated_args, .n_arguments = 1 },
+    [ENTRY_SIGNAL_VOLUME_UPDATED] = { .name = "VolumeUpdated", .arguments = entry_volume_updated_args, .n_arguments = 1 },
+    [ENTRY_SIGNAL_MUTE_UPDATED]   = { .name = "MuteUpdated",   .arguments = entry_mute_updated_args,   .n_arguments = 1 }
+};
+
+static pa_dbus_interface_info stream_restore_interface_info = {
+    .name = INTERFACE_STREAM_RESTORE,
+    .method_handlers = method_handlers,
+    .n_method_handlers = METHOD_HANDLER_MAX,
+    .property_handlers = property_handlers,
+    .n_property_handlers = PROPERTY_HANDLER_MAX,
+    .get_all_properties_cb = handle_get_all,
+    .signals = signals,
+    .n_signals = SIGNAL_MAX
+};
+
+static pa_dbus_interface_info entry_interface_info = {
+    .name = INTERFACE_ENTRY,
+    .method_handlers = entry_method_handlers,
+    .n_method_handlers = ENTRY_METHOD_HANDLER_MAX,
+    .property_handlers = entry_property_handlers,
+    .n_property_handlers = ENTRY_PROPERTY_HANDLER_MAX,
+    .get_all_properties_cb = handle_entry_get_all,
+    .signals = entry_signals,
+    .n_signals = ENTRY_SIGNAL_MAX
+};
+
+static struct dbus_entry *dbus_entry_new(struct userdata *u, const char *entry_name) {
+    struct dbus_entry *de;
+
+    pa_assert(u);
+    pa_assert(entry_name);
+    pa_assert(*entry_name);
+
+    de = pa_xnew(struct dbus_entry, 1);
+    de->userdata = u;
+    de->entry_name = pa_xstrdup(entry_name);
+    de->index = u->next_index++;
+    de->object_path = pa_sprintf_malloc("%s/%s%u", OBJECT_PATH, ENTRY_OBJECT_NAME, de->index);
+
+    pa_assert_se(pa_dbus_protocol_add_interface(u->dbus_protocol, de->object_path, &entry_interface_info, de) >= 0);
+
+    return de;
+}
+
+static void dbus_entry_free(struct dbus_entry *de) {
+    pa_assert(de);
+
+    pa_assert_se(pa_dbus_protocol_remove_interface(de->userdata->dbus_protocol, de->object_path, entry_interface_info.name) >= 0);
+
+    pa_xfree(de->entry_name);
+    pa_xfree(de->object_path);
+    pa_xfree(de);
+}
+
+/* Reads an array [(UInt32, UInt32)] from the iterator. The struct items are
+ * are a channel position and a volume value, respectively. The result is
+ * stored in the map and vol arguments. The iterator must point to a "a(uu)"
+ * element. If the data is invalid, an error reply is sent and a negative
+ * number is returned. In case of a failure we make no guarantees about the
+ * state of map and vol. In case of an empty array the channels field of both
+ * map and vol are set to 0. This function calls dbus_message_iter_next(iter)
+ * before returning. */
+static int get_volume_arg(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, pa_channel_map *map, pa_cvolume *vol) {
+    DBusMessageIter array_iter;
+    DBusMessageIter struct_iter;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(pa_streq(dbus_message_iter_get_signature(iter), "a(uu)"));
+    pa_assert(map);
+    pa_assert(vol);
+
+    pa_channel_map_init(map);
+    pa_cvolume_init(vol);
+
+    map->channels = 0;
+    vol->channels = 0;
+
+    dbus_message_iter_recurse(iter, &array_iter);
+
+    while (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID) {
+        dbus_uint32_t chan_pos;
+        dbus_uint32_t chan_vol;
+
+        dbus_message_iter_recurse(&array_iter, &struct_iter);
+
+        dbus_message_iter_get_basic(&struct_iter, &chan_pos);
+
+        if (chan_pos >= PA_CHANNEL_POSITION_MAX) {
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid channel position: %u", chan_pos);
+            return -1;
+        }
+
+        pa_assert_se(dbus_message_iter_next(&struct_iter));
+        dbus_message_iter_get_basic(&struct_iter, &chan_vol);
+
+        if (!PA_VOLUME_IS_VALID(chan_vol)) {
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid volume: %u", chan_vol);
+            return -1;
+        }
+
+        if (map->channels < PA_CHANNELS_MAX) {
+            map->map[map->channels] = chan_pos;
+            vol->values[map->channels] = chan_vol;
+        }
+        ++map->channels;
+        ++vol->channels;
+
+        dbus_message_iter_next(&array_iter);
+    }
+
+    if (map->channels > PA_CHANNELS_MAX) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too many channels: %u. The maximum is %u.", map->channels, PA_CHANNELS_MAX);
+        return -1;
+    }
+
+    dbus_message_iter_next(iter);
+
+    return 0;
+}
+
+static void append_volume(DBusMessageIter *iter, struct entry *e) {
+    DBusMessageIter array_iter;
+    DBusMessageIter struct_iter;
+    unsigned i;
+
+    pa_assert(iter);
+    pa_assert(e);
+
+    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "(uu)", &array_iter));
+
+    if (!e->volume_valid) {
+        pa_assert_se(dbus_message_iter_close_container(iter, &array_iter));
+        return;
+    }
+
+    for (i = 0; i < e->channel_map.channels; ++i) {
+        pa_assert_se(dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter));
+
+        pa_assert_se(dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT32, &e->channel_map.map[i]));
+        pa_assert_se(dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT32, &e->volume.values[i]));
+
+        pa_assert_se(dbus_message_iter_close_container(&array_iter, &struct_iter));
+    }
+
+    pa_assert_se(dbus_message_iter_close_container(iter, &array_iter));
+}
+
+static void append_volume_variant(DBusMessageIter *iter, struct entry *e) {
+    DBusMessageIter variant_iter;
+
+    pa_assert(iter);
+    pa_assert(e);
+
+    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a(uu)", &variant_iter));
+
+    append_volume(&variant_iter, e);
+
+    pa_assert_se(dbus_message_iter_close_container(iter, &variant_iter));
+}
+
+static void send_new_entry_signal(struct dbus_entry *entry) {
+    DBusMessage *signal_msg;
+
+    pa_assert(entry);
+
+    pa_assert_se(signal_msg = dbus_message_new_signal(OBJECT_PATH, INTERFACE_STREAM_RESTORE, signals[SIGNAL_NEW_ENTRY].name));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &entry->object_path, DBUS_TYPE_INVALID));
+    pa_dbus_protocol_send_signal(entry->userdata->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+}
+
+static void send_entry_removed_signal(struct dbus_entry *entry) {
+    DBusMessage *signal_msg;
+
+    pa_assert(entry);
+
+    pa_assert_se(signal_msg = dbus_message_new_signal(OBJECT_PATH, INTERFACE_STREAM_RESTORE, signals[SIGNAL_ENTRY_REMOVED].name));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &entry->object_path, DBUS_TYPE_INVALID));
+    pa_dbus_protocol_send_signal(entry->userdata->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+}
+
+static void send_device_updated_signal(struct dbus_entry *de, struct entry *e) {
+    DBusMessage *signal_msg;
+    const char *device;
+
+    pa_assert(de);
+    pa_assert(e);
+
+    device = e->device_valid ? e->device : "";
+
+    pa_assert_se(signal_msg = dbus_message_new_signal(de->object_path, INTERFACE_ENTRY, entry_signals[ENTRY_SIGNAL_DEVICE_UPDATED].name));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_STRING, &device, DBUS_TYPE_INVALID));
+    pa_dbus_protocol_send_signal(de->userdata->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+}
+
+static void send_volume_updated_signal(struct dbus_entry *de, struct entry *e) {
+    DBusMessage *signal_msg;
+    DBusMessageIter msg_iter;
+
+    pa_assert(de);
+    pa_assert(e);
+
+    pa_assert_se(signal_msg = dbus_message_new_signal(de->object_path, INTERFACE_ENTRY, entry_signals[ENTRY_SIGNAL_VOLUME_UPDATED].name));
+    dbus_message_iter_init_append(signal_msg, &msg_iter);
+    append_volume(&msg_iter, e);
+    pa_dbus_protocol_send_signal(de->userdata->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+}
+
+static void send_mute_updated_signal(struct dbus_entry *de, struct entry *e) {
+    DBusMessage *signal_msg;
+    dbus_bool_t muted;
+
+    pa_assert(de);
+    pa_assert(e);
+
+    pa_assert(e->muted_valid);
+
+    muted = e->muted;
+
+    pa_assert_se(signal_msg = dbus_message_new_signal(de->object_path, INTERFACE_ENTRY, entry_signals[ENTRY_SIGNAL_MUTE_UPDATED].name));
+    pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_BOOLEAN, &muted, DBUS_TYPE_INVALID));
+    pa_dbus_protocol_send_signal(de->userdata->dbus_protocol, signal_msg);
+    dbus_message_unref(signal_msg);
+}
+
+static void handle_get_interface_revision(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    dbus_uint32_t interface_revision = DBUS_INTERFACE_REVISION;
+
+    pa_assert(conn);
+    pa_assert(msg);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &interface_revision);
+}
+
+/* The caller frees the array, but not the strings. */
+static const char **get_entries(struct userdata *u, unsigned *n) {
+    const char **entries;
+    unsigned i = 0;
+    void *state = NULL;
+    struct dbus_entry *de;
+
+    pa_assert(u);
+    pa_assert(n);
+
+    *n = pa_hashmap_size(u->dbus_entries);
+
+    if (*n == 0)
+        return NULL;
+
+    entries = pa_xnew(const char *, *n);
+
+    PA_HASHMAP_FOREACH(de, u->dbus_entries, state)
+        entries[i++] = de->object_path;
+
+    return entries;
+}
+
+static void handle_get_entries(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    struct userdata *u = userdata;
+    const char **entries;
+    unsigned n;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(u);
+
+    entries = get_entries(u, &n);
+
+    pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, entries, n);
+
+    pa_xfree(entries);
+}
+
+static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    struct userdata *u = userdata;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+    DBusMessageIter dict_iter;
+    dbus_uint32_t interface_revision;
+    const char **entries;
+    unsigned n_entries;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(u);
+
+    interface_revision = DBUS_INTERFACE_REVISION;
+    entries = get_entries(u, &n_entries);
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_INTERFACE_REVISION].property_name, DBUS_TYPE_UINT32, &interface_revision);
+    pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_ENTRIES].property_name, DBUS_TYPE_OBJECT_PATH, entries, n_entries);
+
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+
+    dbus_message_unref(reply);
+
+    pa_xfree(entries);
+}
+
+static void handle_add_entry(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    struct userdata *u = userdata;
+    DBusMessageIter msg_iter;
+    const char *name = NULL;
+    const char *device = NULL;
+    pa_channel_map map;
+    pa_cvolume vol;
+    dbus_bool_t muted = FALSE;
+    dbus_bool_t apply_immediately = FALSE;
+    struct dbus_entry *dbus_entry = NULL;
+    struct entry *e = NULL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(u);
+
+    pa_assert_se(dbus_message_iter_init(msg, &msg_iter));
+    dbus_message_iter_get_basic(&msg_iter, &name);
+
+    pa_assert_se(dbus_message_iter_next(&msg_iter));
+    dbus_message_iter_get_basic(&msg_iter, &device);
+
+    pa_assert_se(dbus_message_iter_next(&msg_iter));
+    if (get_volume_arg(conn, msg, &msg_iter, &map, &vol) < 0)
+        return;
+
+    dbus_message_iter_get_basic(&msg_iter, &muted);
+
+    pa_assert_se(dbus_message_iter_next(&msg_iter));
+    dbus_message_iter_get_basic(&msg_iter, &apply_immediately);
+
+    if (!*name) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "An empty string was given as the entry name.");
+        return;
+    }
+
+    if ((dbus_entry = pa_hashmap_get(u->dbus_entries, name))) {
+        pa_bool_t mute_updated = FALSE;
+        pa_bool_t volume_updated = FALSE;
+        pa_bool_t device_updated = FALSE;
+
+        pa_assert_se(e = entry_read(u, name));
+        mute_updated = e->muted != muted;
+        e->muted = muted;
+        e->muted_valid = TRUE;
+
+        volume_updated = (e->volume_valid != !!map.channels) || !pa_cvolume_equal(&e->volume, &vol);
+        e->volume = vol;
+        e->channel_map = map;
+        e->volume_valid = !!map.channels;
+
+        device_updated = (e->device_valid != !!device[0]) || !pa_streq(e->device, device);
+        pa_xfree(e->device);
+        e->device = pa_xstrdup(device);
+        e->device_valid = !!device[0];
+
+        if (mute_updated)
+            send_mute_updated_signal(dbus_entry, e);
+        if (volume_updated)
+            send_volume_updated_signal(dbus_entry, e);
+        if (device_updated)
+            send_device_updated_signal(dbus_entry, e);
+
+    } else {
+        dbus_entry = dbus_entry_new(u, name);
+        pa_assert_se(pa_hashmap_put(u->dbus_entries, dbus_entry->entry_name, dbus_entry) == 0);
+
+        e = entry_new();
+        e->muted_valid = TRUE;
+        e->volume_valid = !!map.channels;
+        e->device_valid = !!device[0];
+        e->muted = muted;
+        e->volume = vol;
+        e->channel_map = map;
+        e->device = pa_xstrdup(device);
+
+        send_new_entry_signal(dbus_entry);
+    }
+
+    pa_assert_se(entry_write(u, name, e, TRUE));
+
+    if (apply_immediately)
+        entry_apply(u, name, e);
+
+    trigger_save(u);
+
+    pa_dbus_send_empty_reply(conn, msg);
+
+    entry_free(e);
+}
+
+static void handle_get_entry_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    struct userdata *u = userdata;
+    const char *name;
+    struct dbus_entry *de;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(u);
+
+    pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID));
+
+    if (!(de = pa_hashmap_get(u->dbus_entries, name))) {
+        pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such stream restore entry.");
+        return;
+    }
+
+    pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &de->object_path);
+}
+
+static void handle_entry_get_index(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    struct dbus_entry *de = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(de);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &de->index);
+}
+
+static void handle_entry_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    struct dbus_entry *de = userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(de);
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &de->entry_name);
+}
+
+static void handle_entry_get_device(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    struct dbus_entry *de = userdata;
+    struct entry *e;
+    const char *device;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(de);
+
+    pa_assert_se(e = entry_read(de->userdata, de->entry_name));
+
+    device = e->device_valid ? e->device : "";
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &device);
+
+    entry_free(e);
+}
+
+static void handle_entry_set_device(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
+    struct dbus_entry *de = userdata;
+    const char *device;
+    struct entry *e;
+    pa_bool_t updated;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(de);
+
+    dbus_message_iter_get_basic(iter, &device);
+
+    pa_assert_se(e = entry_read(de->userdata, de->entry_name));
+
+    updated = (e->device_valid != !!device[0]) || !pa_streq(e->device, device);
+
+    if (updated) {
+        pa_xfree(e->device);
+        e->device = pa_xstrdup(device);
+        e->device_valid = !!device[0];
+
+        pa_assert_se(entry_write(de->userdata, de->entry_name, e, TRUE));
+
+        entry_apply(de->userdata, de->entry_name, e);
+        send_device_updated_signal(de, e);
+        trigger_save(de->userdata);
+    }
+
+    pa_dbus_send_empty_reply(conn, msg);
+
+    entry_free(e);
+}
+
+static void handle_entry_get_volume(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    struct dbus_entry *de = userdata;
+    DBusMessage *reply;
+    DBusMessageIter msg_iter;
+    struct entry *e;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(de);
+
+    pa_assert_se(e = entry_read(de->userdata, de->entry_name));
+
+    pa_assert_se(reply = dbus_message_new_method_return(msg));
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    append_volume_variant(&msg_iter, e);
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+
+    entry_free(e);
+}
+
+static void handle_entry_set_volume(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
+    struct dbus_entry *de = userdata;
+    pa_channel_map map;
+    pa_cvolume vol;
+    struct entry *e = NULL;
+    pa_bool_t updated = FALSE;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(de);
+
+    if (get_volume_arg(conn, msg, iter, &map, &vol) < 0)
+        return;
+
+    pa_assert_se(e = entry_read(de->userdata, de->entry_name));
+
+    updated = (e->volume_valid != !!map.channels) || !pa_cvolume_equal(&e->volume, &vol);
+
+    if (updated) {
+        e->volume = vol;
+        e->channel_map = map;
+        e->volume_valid = !!map.channels;
+
+        pa_assert_se(entry_write(de->userdata, de->entry_name, e, TRUE));
+
+        entry_apply(de->userdata, de->entry_name, e);
+        send_volume_updated_signal(de, e);
+        trigger_save(de->userdata);
+    }
+
+    pa_dbus_send_empty_reply(conn, msg);
+
+    entry_free(e);
+}
+
+static void handle_entry_get_mute(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    struct dbus_entry *de = userdata;
+    struct entry *e;
+    dbus_bool_t mute;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(de);
+
+    pa_assert_se(e = entry_read(de->userdata, de->entry_name));
+
+    mute = e->muted_valid ? e->muted : FALSE;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &mute);
+
+    entry_free(e);
+}
+
+static void handle_entry_set_mute(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
+    struct dbus_entry *de = userdata;
+    dbus_bool_t mute;
+    struct entry *e;
+    pa_bool_t updated;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(de);
+
+    dbus_message_iter_get_basic(iter, &mute);
+
+    pa_assert_se(e = entry_read(de->userdata, de->entry_name));
+
+    updated = !e->muted_valid || e->muted != mute;
+
+    if (updated) {
+        e->muted = mute;
+        e->muted_valid = TRUE;
+
+        pa_assert_se(entry_write(de->userdata, de->entry_name, e, TRUE));
+
+        entry_apply(de->userdata, de->entry_name, e);
+        send_mute_updated_signal(de, e);
+        trigger_save(de->userdata);
+    }
+
+    pa_dbus_send_empty_reply(conn, msg);
+
+    entry_free(e);
+}
+
+static void handle_entry_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    struct dbus_entry *de = userdata;
+    struct entry *e;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+    DBusMessageIter dict_iter;
+    DBusMessageIter dict_entry_iter;
+    const char *device;
+    dbus_bool_t mute;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(de);
+
+    pa_assert_se(e = entry_read(de->userdata, de->entry_name));
+
+    device = e->device_valid ? e->device : "";
+    mute = e->muted_valid ? e->muted : FALSE;
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, entry_property_handlers[ENTRY_PROPERTY_HANDLER_INDEX].property_name, DBUS_TYPE_UINT32, &de->index);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, entry_property_handlers[ENTRY_PROPERTY_HANDLER_NAME].property_name, DBUS_TYPE_STRING, &de->entry_name);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, entry_property_handlers[ENTRY_PROPERTY_HANDLER_DEVICE].property_name, DBUS_TYPE_STRING, &device);
+
+    pa_assert_se(dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter));
+
+    pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &entry_property_handlers[ENTRY_PROPERTY_HANDLER_VOLUME].property_name));
+    append_volume_variant(&dict_entry_iter, e);
+
+    pa_assert_se(dbus_message_iter_close_container(&dict_iter, &dict_entry_iter));
+
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, entry_property_handlers[ENTRY_PROPERTY_HANDLER_MUTE].property_name, DBUS_TYPE_BOOLEAN, &mute);
+
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+
+    dbus_message_unref(reply);
+
+    entry_free(e);
+}
+
+static void handle_entry_remove(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    struct dbus_entry *de = userdata;
+    pa_datum key;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(de);
+
+    key.data = de->entry_name;
+    key.size = strlen(de->entry_name);
+
+    pa_assert_se(pa_database_unset(de->userdata->database, &key) == 0);
+
+    send_entry_removed_signal(de);
+    trigger_save(de->userdata);
+
+    pa_assert_se(pa_hashmap_remove(de->userdata->dbus_entries, de->entry_name));
+    dbus_entry_free(de);
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
+#endif /* HAVE_DBUS */
+
+static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
+    struct userdata *u = userdata;
+
+    pa_assert(a);
+    pa_assert(e);
+    pa_assert(u);
+
+    pa_assert(e == u->save_time_event);
+    u->core->mainloop->time_free(u->save_time_event);
+    u->save_time_event = NULL;
+
+    pa_database_sync(u->database);
+    pa_log_info("Synced.");
+}
+
+static struct entry* entry_new(void) {
+    struct entry *r = pa_xnew0(struct entry, 1);
+    r->version = ENTRY_VERSION;
+    return r;
+}
+
+static void entry_free(struct entry* e) {
+    pa_assert(e);
+
+    pa_xfree(e->device);
+    pa_xfree(e->card);
+    pa_xfree(e);
+}
+
+static pa_bool_t entry_write(struct userdata *u, const char *name, const struct entry *e, pa_bool_t replace) {
+    pa_tagstruct *t;
+    pa_datum key, data;
+    pa_bool_t r;
+
+    pa_assert(u);
+    pa_assert(name);
+    pa_assert(e);
+
+    t = pa_tagstruct_new(NULL, 0);
+    pa_tagstruct_putu8(t, e->version);
+    pa_tagstruct_put_boolean(t, e->volume_valid);
+    pa_tagstruct_put_channel_map(t, &e->channel_map);
+    pa_tagstruct_put_cvolume(t, &e->volume);
+    pa_tagstruct_put_boolean(t, e->muted_valid);
+    pa_tagstruct_put_boolean(t, e->muted);
+    pa_tagstruct_put_boolean(t, e->device_valid);
+    pa_tagstruct_puts(t, e->device);
+    pa_tagstruct_put_boolean(t, e->card_valid);
+    pa_tagstruct_puts(t, e->card);
+
+    key.data = (char *) name;
+    key.size = strlen(name);
+
+    data.data = (void*)pa_tagstruct_data(t, &data.size);
+
+    r = (pa_database_set(u->database, &key, &data, replace) == 0);
+
+    pa_tagstruct_free(t);
+
+    return r;
+}
+
+#ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
+
+#define LEGACY_ENTRY_VERSION 3
+static struct entry *legacy_entry_read(struct userdata *u, const char *name) {
+    struct legacy_entry {
+        uint8_t version;
+        pa_bool_t muted_valid:1, volume_valid:1, device_valid:1, card_valid:1;
+        pa_bool_t muted:1;
+        pa_channel_map channel_map;
+        pa_cvolume volume;
+        char device[PA_NAME_MAX];
+        char card[PA_NAME_MAX];
+    } PA_GCC_PACKED;
+
+    pa_datum key;
+    pa_datum data;
+    struct legacy_entry *le;
+    struct entry *e;
+
+    pa_assert(u);
+    pa_assert(name);
+
+    key.data = (char *) name;
+    key.size = strlen(name);
+
+    pa_zero(data);
+
+    if (!pa_database_get(u->database, &key, &data))
+        goto fail;
+
+    if (data.size != sizeof(struct legacy_entry)) {
+        pa_log_debug("Size does not match.");
+        goto fail;
+    }
+
+    le = (struct legacy_entry *) data.data;
+
+    if (le->version != LEGACY_ENTRY_VERSION) {
+        pa_log_debug("Version mismatch.");
+        goto fail;
+    }
 
-enum {
-    SUBCOMMAND_TEST,
-    SUBCOMMAND_READ,
-    SUBCOMMAND_WRITE,
-    SUBCOMMAND_DELETE,
-    SUBCOMMAND_SUBSCRIBE,
-    SUBCOMMAND_EVENT
-};
+    if (!memchr(le->device, 0, sizeof(le->device))) {
+        pa_log_warn("Device has missing NUL byte.");
+        goto fail;
+    }
 
-static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
-    struct userdata *u = userdata;
+    if (!memchr(le->card, 0, sizeof(le->card))) {
+        pa_log_warn("Card has missing NUL byte.");
+        goto fail;
+    }
 
-    pa_assert(a);
-    pa_assert(e);
-    pa_assert(u);
+    if (le->device_valid && !pa_namereg_is_valid_name(le->device)) {
+        pa_log_warn("Invalid device name stored in database for legacy stream");
+        goto fail;
+    }
 
-    pa_assert(e == u->save_time_event);
-    u->core->mainloop->time_free(u->save_time_event);
-    u->save_time_event = NULL;
+    if (le->card_valid && !pa_namereg_is_valid_name(le->card)) {
+        pa_log_warn("Invalid card name stored in database for legacy stream");
+        goto fail;
+    }
 
-    pa_database_sync(u->database);
-    pa_log_info("Synced.");
-}
+    if (le->volume_valid && !pa_channel_map_valid(&le->channel_map)) {
+        pa_log_warn("Invalid channel map stored in database for legacy stream");
+        goto fail;
+    }
 
-static char *get_name(pa_proplist *p, const char *prefix) {
-    const char *r;
-    char *t;
+    if (le->volume_valid && (!pa_cvolume_valid(&le->volume) || !pa_cvolume_compatible_with_channel_map(&le->volume, &le->channel_map))) {
+        pa_log_warn("Invalid volume stored in database for legacy stream");
+        goto fail;
+    }
 
-    if (!p)
-        return NULL;
+    e = entry_new();
+    e->muted_valid = le->muted_valid;
+    e->muted = le->muted;
+    e->volume_valid = le->volume_valid;
+    e->channel_map = le->channel_map;
+    e->volume = le->volume;
+    e->device_valid = le->device_valid;
+    e->device = pa_xstrdup(le->device);
+    e->card_valid = le->card_valid;
+    e->card = pa_xstrdup(le->card);
+    return e;
 
-    if ((r = pa_proplist_gets(p, IDENTIFICATION_PROPERTY)))
-        return pa_xstrdup(r);
-
-    if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_ROLE)))
-        t = pa_sprintf_malloc("%s-by-media-role:%s", prefix, r);
-    else if ((r = pa_proplist_gets(p, PA_PROP_APPLICATION_ID)))
-        t = pa_sprintf_malloc("%s-by-application-id:%s", prefix, r);
-    else if ((r = pa_proplist_gets(p, PA_PROP_APPLICATION_NAME)))
-        t = pa_sprintf_malloc("%s-by-application-name:%s", prefix, r);
-    else if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_NAME)))
-        t = pa_sprintf_malloc("%s-by-media-name:%s", prefix, r);
-    else
-        t = pa_sprintf_malloc("%s-fallback:%s", prefix, r);
+fail:
+    pa_datum_free(&data);
 
-    pa_proplist_sets(p, IDENTIFICATION_PROPERTY, t);
-    return t;
+    return NULL;
 }
+#endif
 
-static struct entry* read_entry(struct userdata *u, const char *name) {
+static struct entry *entry_read(struct userdata *u, const char *name) {
     pa_datum key, data;
-    struct entry *e;
+    struct entry *e = NULL;
+    pa_tagstruct *t = NULL;
+    const char *device, *card;
 
     pa_assert(u);
     pa_assert(name);
@@ -178,29 +1128,29 @@ static struct entry* read_entry(struct userdata *u, const char *name) {
     if (!pa_database_get(u->database, &key, &data))
         goto fail;
 
-    if (data.size != sizeof(struct entry)) {
-        /* This is probably just a database upgrade, hence let's not
-         * consider this more than a debug message */
-        pa_log_debug("Database contains entry for stream %s of wrong size %lu != %lu. Probably due to uprade, ignoring.", name, (unsigned long) data.size, (unsigned long) sizeof(struct entry));
-        goto fail;
-    }
-
-    e = (struct entry*) data.data;
+    t = pa_tagstruct_new(data.data, data.size);
+    e = entry_new();
+
+    if (pa_tagstruct_getu8(t, &e->version) < 0 ||
+        e->version > ENTRY_VERSION ||
+        pa_tagstruct_get_boolean(t, &e->volume_valid) < 0 ||
+        pa_tagstruct_get_channel_map(t, &e->channel_map) < 0 ||
+        pa_tagstruct_get_cvolume(t, &e->volume) < 0 ||
+        pa_tagstruct_get_boolean(t, &e->muted_valid) < 0 ||
+        pa_tagstruct_get_boolean(t, &e->muted) < 0 ||
+        pa_tagstruct_get_boolean(t, &e->device_valid) < 0 ||
+        pa_tagstruct_gets(t, &device) < 0 ||
+        pa_tagstruct_get_boolean(t, &e->card_valid) < 0 ||
+        pa_tagstruct_gets(t, &card) < 0) {
 
-    if (e->version != ENTRY_VERSION) {
-        pa_log_debug("Version of database entry for stream %s doesn't match our version. Probably due to upgrade, ignoring.", name);
         goto fail;
     }
 
-    if (!memchr(e->device, 0, sizeof(e->device))) {
-        pa_log_warn("Database contains entry for stream %s with missing NUL byte in device name", name);
-        goto fail;
-    }
+    e->device = pa_xstrdup(device);
+    e->card = pa_xstrdup(card);
 
-    if (!memchr(e->card, 0, sizeof(e->card))) {
-        pa_log_warn("Database contains entry for stream %s with missing NUL byte in card name", name);
+    if (!pa_tagstruct_eof(t))
         goto fail;
-    }
 
     if (e->device_valid && !pa_namereg_is_valid_name(e->device)) {
         pa_log_warn("Invalid device name stored in database for stream %s", name);
@@ -222,19 +1172,37 @@ static struct entry* read_entry(struct userdata *u, const char *name) {
         goto fail;
     }
 
+    pa_tagstruct_free(t);
+    pa_datum_free(&data);
+
     return e;
 
 fail:
+    if (e)
+        entry_free(e);
+    if (t)
+        pa_tagstruct_free(t);
 
     pa_datum_free(&data);
     return NULL;
 }
 
+static struct entry* entry_copy(const struct entry *e) {
+    struct entry* r;
+
+    pa_assert(e);
+    r = entry_new();
+    *r = *e;
+    r->device = pa_xstrdup(e->device);
+    r->card = pa_xstrdup(e->card);
+    return r;
+}
+
 static void trigger_save(struct userdata *u) {
     pa_native_connection *c;
     uint32_t idx;
 
-    for (c = pa_idxset_first(u->subscribed, &idx); c; c = pa_idxset_next(u->subscribed, &idx)) {
+    PA_IDXSET_FOREACH(c, u->subscribed, idx) {
         pa_tagstruct *t;
 
         t = pa_tagstruct_new(NULL, 0);
@@ -260,11 +1228,11 @@ static pa_bool_t entries_equal(const struct entry *a, const struct entry *b) {
     pa_assert(b);
 
     if (a->device_valid != b->device_valid ||
-        (a->device_valid && strncmp(a->device, b->device, sizeof(a->device))))
+        (a->device_valid && !pa_streq(a->device, b->device)))
         return FALSE;
 
     if (a->card_valid != b->card_valid ||
-        (a->card_valid && strncmp(a->card, b->card, sizeof(a->card))))
+        (a->card_valid && !pa_streq(a->card, b->card)))
         return FALSE;
 
     if (a->muted_valid != b->muted_valid ||
@@ -281,9 +1249,19 @@ static pa_bool_t entries_equal(const struct entry *a, const struct entry *b) {
 
 static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
     struct userdata *u = userdata;
-    struct entry entry, *old;
-    char *name;
-    pa_datum key, data;
+    struct entry *entry, *old = NULL;
+    char *name = NULL;
+
+    /* These are only used when D-Bus is enabled, but in order to reduce ifdef
+     * clutter these are defined here unconditionally. */
+    pa_bool_t created_new_entry = TRUE;
+    pa_bool_t device_updated = FALSE;
+    pa_bool_t volume_updated = FALSE;
+    pa_bool_t mute_updated = FALSE;
+
+#ifdef HAVE_DBUS
+    struct dbus_entry *de = NULL;
+#endif
 
     pa_assert(c);
     pa_assert(u);
@@ -294,39 +1272,51 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
         t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE))
         return;
 
-    pa_zero(entry);
-    entry.version = ENTRY_VERSION;
-
     if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK_INPUT) {
         pa_sink_input *sink_input;
 
         if (!(sink_input = pa_idxset_get_by_index(c->sink_inputs, idx)))
             return;
 
-        if (!(name = get_name(sink_input->proplist, "sink-input")))
+        if (!(name = pa_proplist_get_stream_group(sink_input->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
             return;
 
-        if ((old = read_entry(u, name)))
-            entry = *old;
+        if ((old = entry_read(u, name))) {
+            entry = entry_copy(old);
+            created_new_entry = FALSE;
+        } else
+            entry = entry_new();
+
+        if (sink_input->save_volume && pa_sink_input_is_volume_readable(sink_input)) {
+            pa_assert(sink_input->volume_writable);
 
-        if (sink_input->save_volume) {
-            entry.channel_map = sink_input->channel_map;
-            pa_sink_input_get_volume(sink_input, &entry.volume, FALSE);
-            entry.volume_valid = TRUE;
+            entry->channel_map = sink_input->channel_map;
+            pa_sink_input_get_volume(sink_input, &entry->volume, FALSE);
+            entry->volume_valid = TRUE;
+
+            volume_updated = !created_new_entry
+                             && (!old->volume_valid
+                                 || !pa_channel_map_equal(&entry->channel_map, &old->channel_map)
+                                 || !pa_cvolume_equal(&entry->volume, &old->volume));
         }
 
         if (sink_input->save_muted) {
-            entry.muted = pa_sink_input_get_mute(sink_input);
-            entry.muted_valid = TRUE;
+            entry->muted = pa_sink_input_get_mute(sink_input);
+            entry->muted_valid = TRUE;
+
+            mute_updated = !created_new_entry && (!old->muted_valid || entry->muted != old->muted);
         }
 
         if (sink_input->save_sink) {
-            pa_strlcpy(entry.device, sink_input->sink->name, sizeof(entry.device));
-            entry.device_valid = TRUE;
+            pa_xfree(entry->device);
+            entry->device = pa_xstrdup(sink_input->sink->name);
+            entry->device_valid = TRUE;
 
+            device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry->device, old->device));
             if (sink_input->sink->card) {
-                pa_strlcpy(entry.card, sink_input->sink->card->name, sizeof(entry.card));
-                entry.card_valid = TRUE;
+                pa_xfree(entry->card);
+                entry->card = pa_xstrdup(sink_input->sink->card->name);
+                entry->card_valid = TRUE;
             }
         }
 
@@ -338,47 +1328,88 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
         if (!(source_output = pa_idxset_get_by_index(c->source_outputs, idx)))
             return;
 
-        if (!(name = get_name(source_output->proplist, "source-output")))
+        if (!(name = pa_proplist_get_stream_group(source_output->proplist, "source-output", IDENTIFICATION_PROPERTY)))
             return;
 
-        if ((old = read_entry(u, name)))
-            entry = *old;
+        if ((old = entry_read(u, name))) {
+            entry = entry_copy(old);
+            created_new_entry = FALSE;
+        } else
+            entry = entry_new();
+
+        if (source_output->save_volume && pa_source_output_is_volume_readable(source_output)) {
+            pa_assert(source_output->volume_writable);
+
+            entry->channel_map = source_output->channel_map;
+            pa_source_output_get_volume(source_output, &entry->volume, FALSE);
+            entry->volume_valid = TRUE;
+
+            volume_updated = !created_new_entry
+                             && (!old->volume_valid
+                                 || !pa_channel_map_equal(&entry->channel_map, &old->channel_map)
+                                 || !pa_cvolume_equal(&entry->volume, &old->volume));
+        }
+
+        if (source_output->save_muted) {
+            entry->muted = pa_source_output_get_mute(source_output);
+            entry->muted_valid = TRUE;
+
+            mute_updated = !created_new_entry && (!old->muted_valid || entry->muted != old->muted);
+        }
 
         if (source_output->save_source) {
-            pa_strlcpy(entry.device, source_output->source->name, sizeof(entry.device));
-            entry.device_valid = source_output->save_source;
+            pa_xfree(entry->device);
+            entry->device = pa_xstrdup(source_output->source->name);
+            entry->device_valid = TRUE;
+
+            device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry->device, old->device));
 
             if (source_output->source->card) {
-                pa_strlcpy(entry.card, source_output->source->card->name, sizeof(entry.card));
-                entry.card_valid = TRUE;
+                pa_xfree(entry->card);
+                entry->card = pa_xstrdup(source_output->source->card->name);
+                entry->card_valid = TRUE;
             }
         }
     }
 
+    pa_assert(entry);
+
     if (old) {
 
-        if (entries_equal(old, &entry)) {
-            pa_xfree(old);
+        if (entries_equal(old, entry)) {
+            entry_free(old);
+            entry_free(entry);
             pa_xfree(name);
             return;
         }
 
-        pa_xfree(old);
+        entry_free(old);
     }
 
-    key.data = name;
-    key.size = strlen(name);
-
-    data.data = &entry;
-    data.size = sizeof(entry);
-
     pa_log_info("Storing volume/mute/device for stream %s.", name);
 
-    pa_database_set(u->database, &key, &data, TRUE);
+    if (entry_write(u, name, entry, TRUE))
+        trigger_save(u);
 
-    pa_xfree(name);
+#ifdef HAVE_DBUS
+    if (created_new_entry) {
+        de = dbus_entry_new(u, name);
+        pa_assert_se(pa_hashmap_put(u->dbus_entries, de->entry_name, de) == 0);
+        send_new_entry_signal(de);
+    } else {
+        pa_assert_se(de = pa_hashmap_get(u->dbus_entries, name));
+
+        if (device_updated)
+            send_device_updated_signal(de, entry);
+        if (volume_updated)
+            send_volume_updated_signal(de, entry);
+        if (mute_updated)
+            send_mute_updated_signal(de, entry);
+    }
+#endif
 
-    trigger_save(u);
+    entry_free(entry);
+    pa_xfree(name);
 }
 
 static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_new_data *new_data, struct userdata *u) {
@@ -390,12 +1421,12 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
     pa_assert(u);
     pa_assert(u->restore_device);
 
-    if (!(name = get_name(new_data->proplist, "sink-input")))
+    if (!(name = pa_proplist_get_stream_group(new_data->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
         return PA_HOOK_OK;
 
     if (new_data->sink)
-        pa_log_debug("Not restoring device for stream %s, because already set.", name);
-    else if ((e = read_entry(u, name))) {
+        pa_log_debug("Not restoring device for stream %s, because already set to '%s'.", name, new_data->sink->name);
+    else if ((e = entry_read(u, name))) {
         pa_sink *s = NULL;
 
         if (e->device_valid)
@@ -411,13 +1442,11 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
         /* 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 (s && PA_SINK_IS_LINKED(pa_sink_get_state(s))) {
-            pa_log_info("Restoring device for stream %s.", name);
-            new_data->sink = s;
-            new_data->save_sink = TRUE;
-        }
+        if (s && PA_SINK_IS_LINKED(pa_sink_get_state(s)))
+            if (pa_sink_input_new_data_set_sink(new_data, s, TRUE))
+                pa_log_info("Restoring device for stream %s.", name);
 
-        pa_xfree(e);
+        entry_free(e);
     }
 
     pa_xfree(name);
@@ -434,14 +1463,17 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu
     pa_assert(u);
     pa_assert(u->restore_volume || u->restore_muted);
 
-    if (!(name = get_name(new_data->proplist, "sink-input")))
+    if (!(name = pa_proplist_get_stream_group(new_data->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
         return PA_HOOK_OK;
 
-    if ((e = read_entry(u, name))) {
+    if ((e = entry_read(u, name))) {
 
         if (u->restore_volume && e->volume_valid) {
-
-            if (!new_data->volume_is_set) {
+            if (!new_data->volume_writable)
+                pa_log_debug("Not restoring volume for sink input %s, because its volume can't be changed.", name);
+            else if (new_data->volume_is_set)
+                pa_log_debug("Not restoring volume for sink input %s, because already set.", name);
+            else {
                 pa_cvolume v;
 
                 pa_log_info("Restoring volume for sink input %s.", name);
@@ -452,8 +1484,7 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu
 
                 new_data->volume_is_absolute = FALSE;
                 new_data->save_volume = TRUE;
-            } else
-                pa_log_debug("Not restoring volume for sink input %s, because already set.", name);
+            }
         }
 
         if (u->restore_muted && e->muted_valid) {
@@ -466,7 +1497,7 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu
                 pa_log_debug("Not restoring mute state for sink input %s, because already set.", name);
         }
 
-        pa_xfree(e);
+        entry_free(e);
     }
 
     pa_xfree(name);
@@ -486,12 +1517,12 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou
     if (new_data->direct_on_input)
         return PA_HOOK_OK;
 
-    if (!(name = get_name(new_data->proplist, "source-output")))
+    if (!(name = pa_proplist_get_stream_group(new_data->proplist, "source-output", IDENTIFICATION_PROPERTY)))
         return PA_HOOK_OK;
 
     if (new_data->source)
         pa_log_debug("Not restoring device for stream %s, because already set", name);
-    else if ((e = read_entry(u, name))) {
+    else if ((e = entry_read(u, name))) {
         pa_source *s = NULL;
 
         if (e->device_valid)
@@ -509,11 +1540,61 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou
            interfere with that */
         if (s && PA_SOURCE_IS_LINKED(pa_source_get_state(s))) {
             pa_log_info("Restoring device for stream %s.", name);
-            new_data->source = s;
-            new_data->save_source = TRUE;
+            pa_source_output_new_data_set_source(new_data, s, TRUE);
+        }
+
+        entry_free(e);
+    }
+
+    pa_xfree(name);
+
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t source_output_fixate_hook_callback(pa_core *c, pa_source_output_new_data *new_data, struct userdata *u) {
+    char *name;
+    struct entry *e;
+
+    pa_assert(c);
+    pa_assert(new_data);
+    pa_assert(u);
+    pa_assert(u->restore_volume || u->restore_muted);
+
+    if (!(name = pa_proplist_get_stream_group(new_data->proplist, "source-output", IDENTIFICATION_PROPERTY)))
+        return PA_HOOK_OK;
+
+    if ((e = entry_read(u, name))) {
+
+        if (u->restore_volume && e->volume_valid) {
+            if (!new_data->volume_writable)
+                pa_log_debug("Not restoring volume for source output %s, because its volume can't be changed.", name);
+            else if (new_data->volume_is_set)
+                pa_log_debug("Not restoring volume for source output %s, because already set.", name);
+            else {
+                pa_cvolume v;
+
+                pa_log_info("Restoring volume for source output %s.", name);
+
+                v = e->volume;
+                pa_cvolume_remap(&v, &e->channel_map, &new_data->channel_map);
+                pa_source_output_new_data_set_volume(new_data, &v);
+
+                new_data->volume_is_absolute = FALSE;
+                new_data->save_volume = TRUE;
+            }
+        }
+
+        if (u->restore_muted && e->muted_valid) {
+
+            if (!new_data->muted_is_set) {
+                pa_log_info("Restoring mute state for source output %s.", name);
+                pa_source_output_new_data_set_muted(new_data, e->muted);
+                new_data->save_muted = TRUE;
+            } else
+                pa_log_debug("Not restoring mute state for source output %s, because already set.", name);
         }
 
-        pa_xfree(e);
+        entry_free(e);
     }
 
     pa_xfree(name);
@@ -551,14 +1632,14 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct
         if (!PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(si)))
             continue;
 
-        if (!(name = get_name(si->proplist, "sink-input")))
+        if (!(name = pa_proplist_get_stream_group(si->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
             continue;
 
-        if ((e = read_entry(u, name))) {
+        if ((e = entry_read(u, name))) {
             if (e->device_valid && pa_streq(e->device, sink->name))
                 pa_sink_input_move_to(si, sink, TRUE);
 
-            pa_xfree(e);
+            entry_free(e);
         }
 
         pa_xfree(name);
@@ -599,14 +1680,14 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
         if (!PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(so)))
             continue;
 
-        if (!(name = get_name(so->proplist, "source-output")))
+        if (!(name = pa_proplist_get_stream_group(so->proplist, "source-output", IDENTIFICATION_PROPERTY)))
             continue;
 
-        if ((e = read_entry(u, name))) {
+        if ((e = entry_read(u, name))) {
             if (e->device_valid && pa_streq(e->device, source->name))
                 pa_source_output_move_to(so, source, TRUE);
 
-            pa_xfree(e);
+            entry_free(e);
         }
 
         pa_xfree(name);
@@ -635,10 +1716,10 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, str
         if (!si->sink)
             continue;
 
-        if (!(name = get_name(si->proplist, "sink-input")))
+        if (!(name = pa_proplist_get_stream_group(si->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
             continue;
 
-        if ((e = read_entry(u, name))) {
+        if ((e = entry_read(u, name))) {
 
             if (e->device_valid) {
                 pa_sink *d;
@@ -649,7 +1730,7 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, str
                     pa_sink_input_move_to(si, d, TRUE);
             }
 
-            pa_xfree(e);
+            entry_free(e);
         }
 
         pa_xfree(name);
@@ -681,10 +1762,10 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
         if (!so->source)
             continue;
 
-        if (!(name = get_name(so->proplist, "source-output")))
+        if (!(name = pa_proplist_get_stream_group(so->proplist, "source-output", IDENTIFICATION_PROPERTY)))
             continue;
 
-        if ((e = read_entry(u, name))) {
+        if ((e = entry_read(u, name))) {
 
             if (e->device_valid) {
                 pa_source *d;
@@ -695,7 +1776,7 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
                     pa_source_output_move_to(so, d, TRUE);
             }
 
-            pa_xfree(e);
+            entry_free(e);
         }
 
         pa_xfree(name);
@@ -704,9 +1785,90 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc
     return PA_HOOK_OK;
 }
 
-#define EXT_VERSION 1
+static int fill_db(struct userdata *u, const char *filename) {
+    FILE *f;
+    int n = 0;
+    int ret = -1;
+    char *fn = NULL;
+
+    pa_assert(u);
+
+    if (filename)
+        f = fopen(fn = pa_xstrdup(filename), "r");
+    else
+        f = pa_open_config_file(DEFAULT_FALLBACK_FILE, DEFAULT_FALLBACK_FILE_USER, NULL, &fn);
+
+    if (!f) {
+        if (filename)
+            pa_log("Failed to open %s: %s", filename, pa_cstrerror(errno));
+        else
+            ret = 0;
+
+        goto finish;
+    }
 
-static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
+    while (!feof(f)) {
+        char ln[256];
+        char *d, *v;
+        double db;
+
+        if (!fgets(ln, sizeof(ln), f))
+            break;
+
+        n++;
+
+        pa_strip_nl(ln);
+
+        if (!*ln || ln[0] == '#' || ln[0] == ';')
+            continue;
+
+        d = ln+strcspn(ln, WHITESPACE);
+        v = d+strspn(d, WHITESPACE);
+
+        if (!*v) {
+            pa_log("[%s:%u] failed to parse line - too few words", fn, n);
+            goto finish;
+        }
+
+        *d = 0;
+        if (pa_atod(v, &db) >= 0) {
+            if (db <= 0.0) {
+                pa_datum key, data;
+                struct entry e;
+
+                pa_zero(e);
+                e.version = ENTRY_VERSION;
+                e.volume_valid = TRUE;
+                pa_cvolume_set(&e.volume, 1, pa_sw_volume_from_dB(db));
+                pa_channel_map_init_mono(&e.channel_map);
+
+                key.data = (void *) ln;
+                key.size = strlen(ln);
+
+                data.data = (void *) &e;
+                data.size = sizeof(e);
+
+                if (pa_database_set(u->database, &key, &data, FALSE) == 0)
+                    pa_log_debug("Setting %s to %0.2f dB.", ln, db);
+            } else
+                pa_log_warn("[%s:%u] Positive dB values are not allowed, not setting entry %s.", fn, n, ln);
+        } else
+            pa_log_warn("[%s:%u] Couldn't parse '%s' as a double, not setting entry %s.", fn, n, v, ln);
+    }
+
+    trigger_save(u);
+    ret = 0;
+
+finish:
+    if (f)
+        fclose(f);
+
+    pa_xfree(fn);
+
+    return ret;
+}
+
+static void entry_apply(struct userdata *u, const char *name, struct entry *e) {
     pa_sink_input *si;
     pa_source_output *so;
     uint32_t idx;
@@ -719,7 +1881,7 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
         char *n;
         pa_sink *s;
 
-        if (!(n = get_name(si->proplist, "sink-input")))
+        if (!(n = pa_proplist_get_stream_group(si->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
             continue;
 
         if (!pa_streq(name, n)) {
@@ -728,7 +1890,7 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
         }
         pa_xfree(n);
 
-        if (u->restore_volume && e->volume_valid) {
+        if (u->restore_volume && e->volume_valid && si->volume_writable) {
             pa_cvolume v;
 
             v = e->volume;
@@ -742,12 +1904,24 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
             pa_sink_input_set_mute(si, e->muted, TRUE);
         }
 
-        if (u->restore_device &&
-            e->device_valid &&
-            (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);
+        if (u->restore_device) {
+            if (!e->device_valid) {
+                if (si->save_sink) {
+                    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
+                       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 it's 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);
+                }
+            } 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);
+            }
         }
     }
 
@@ -755,7 +1929,7 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
         char *n;
         pa_source *s;
 
-        if (!(n = get_name(so->proplist, "source-output")))
+        if (!(n = pa_proplist_get_stream_group(so->proplist, "source-output", IDENTIFICATION_PROPERTY)))
             continue;
 
         if (!pa_streq(name, n)) {
@@ -764,18 +1938,44 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
         }
         pa_xfree(n);
 
-        if (u->restore_device &&
-            e->device_valid &&
-            (s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE))) {
+        if (u->restore_volume && e->volume_valid && so->volume_writable) {
+            pa_cvolume v;
 
-            pa_log_info("Restoring device for stream %s.", name);
-            pa_source_output_move_to(so, s, TRUE);
+            v = e->volume;
+            pa_log_info("Restoring volume for source output %s.", name);
+            pa_cvolume_remap(&v, &e->channel_map, &so->channel_map);
+            pa_source_output_set_volume(so, &v, TRUE, FALSE);
+        }
+
+        if (u->restore_muted && e->muted_valid) {
+            pa_log_info("Restoring mute state for source output %s.", name);
+            pa_source_output_set_mute(so, e->muted, TRUE);
+        }
+
+        if (u->restore_device) {
+            if (!e->device_valid) {
+                if (so->save_source) {
+                    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
+                       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 it's 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);
+                }
+            } 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);
+            }
         }
     }
 }
 
-#if 0
-static void dump_database(struct userdata *u) {
+#ifdef DEBUG_VOLUME
+PA_GCC_UNUSED static void stream_restore_dump_database(struct userdata *u) {
     pa_datum key;
     pa_bool_t done;
 
@@ -791,14 +1991,14 @@ static void dump_database(struct userdata *u) {
         name = pa_xstrndup(key.data, key.size);
         pa_datum_free(&key);
 
-        if ((e = read_entry(u, name))) {
+        if ((e = entry_read(u, name))) {
             char t[256];
             pa_log("name=%s", name);
             pa_log("device=%s %s", e->device, pa_yes_no(e->device_valid));
             pa_log("channel_map=%s", pa_channel_map_snprint(t, sizeof(t), &e->channel_map));
             pa_log("volume=%s %s", pa_cvolume_snprint(t, sizeof(t), &e->volume), pa_yes_no(e->volume_valid));
             pa_log("mute=%s %s", pa_yes_no(e->muted), pa_yes_no(e->volume_valid));
-            pa_xfree(e);
+            entry_free(e);
         }
 
         pa_xfree(name);
@@ -808,6 +2008,8 @@ static void dump_database(struct userdata *u) {
 }
 #endif
 
+#define EXT_VERSION 1
+
 static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
     struct userdata *u;
     uint32_t command;
@@ -855,7 +2057,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
                 name = pa_xstrndup(key.data, key.size);
                 pa_datum_free(&key);
 
-                if ((e = read_entry(u, name))) {
+                if ((e = entry_read(u, name))) {
                     pa_cvolume r;
                     pa_channel_map cm;
 
@@ -865,7 +2067,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
                     pa_tagstruct_puts(reply, e->device_valid ? e->device : NULL);
                     pa_tagstruct_put_boolean(reply, e->muted_valid ? e->muted : FALSE);
 
-                    pa_xfree(e);
+                    entry_free(e);
                 }
 
                 pa_xfree(name);
@@ -889,58 +2091,103 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
                 mode != PA_UPDATE_SET)
                 goto fail;
 
-            if (mode == PA_UPDATE_SET)
+            if (mode == PA_UPDATE_SET) {
+#ifdef HAVE_DBUS
+                struct dbus_entry *de;
+                void *state = NULL;
+
+                PA_HASHMAP_FOREACH(de, u->dbus_entries, state) {
+                    send_entry_removed_signal(de);
+                    dbus_entry_free(pa_hashmap_remove(u->dbus_entries, de->entry_name));
+                }
+#endif
                 pa_database_clear(u->database);
+            }
 
             while (!pa_tagstruct_eof(t)) {
                 const char *name, *device;
                 pa_bool_t muted;
-                struct entry entry;
-                pa_datum key, data;
+                struct entry *entry;
+#ifdef HAVE_DBUS
+                struct entry *old;
+#endif
 
-                pa_zero(entry);
-                entry.version = ENTRY_VERSION;
+                entry = entry_new();
 
                 if (pa_tagstruct_gets(t, &name) < 0 ||
-                    pa_tagstruct_get_channel_map(t, &entry.channel_map) ||
-                    pa_tagstruct_get_cvolume(t, &entry.volume) < 0 ||
+                    pa_tagstruct_get_channel_map(t, &entry->channel_map) ||
+                    pa_tagstruct_get_cvolume(t, &entry->volume) < 0 ||
                     pa_tagstruct_gets(t, &device) < 0 ||
                     pa_tagstruct_get_boolean(t, &muted) < 0)
                     goto fail;
 
-                if (!name || !*name)
+                if (!name || !*name) {
+                    entry_free(entry);
                     goto fail;
+                }
 
-                entry.volume_valid = entry.volume.channels > 0;
+                entry->volume_valid = entry->volume.channels > 0;
 
-                if (entry.volume_valid)
-                    if (!pa_cvolume_compatible_with_channel_map(&entry.volume, &entry.channel_map))
+                if (entry->volume_valid)
+                    if (!pa_cvolume_compatible_with_channel_map(&entry->volume, &entry->channel_map)) {
+                        entry_free(entry);
                         goto fail;
+                    }
 
-                entry.muted = muted;
-                entry.muted_valid = TRUE;
+                entry->muted = muted;
+                entry->muted_valid = TRUE;
 
-                if (device)
-                    pa_strlcpy(entry.device, device, sizeof(entry.device));
-                entry.device_valid = !!entry.device[0];
+                entry->device = pa_xstrdup(device);
+                entry->device_valid = device && !!entry->device[0];
 
-                if (entry.device_valid &&
-                    !pa_namereg_is_valid_name(entry.device))
+                if (entry->device_valid && !pa_namereg_is_valid_name(entry->device)) {
+                    entry_free(entry);
                     goto fail;
+                }
 
-                key.data = (char*) name;
-                key.size = strlen(name);
-
-                data.data = &entry;
-                data.size = sizeof(entry);
+#ifdef HAVE_DBUS
+                old = entry_read(u, name);
+#endif
 
                 pa_log_debug("Client %s changes entry %s.",
                              pa_strnull(pa_proplist_gets(pa_native_connection_get_client(c)->proplist, PA_PROP_APPLICATION_PROCESS_BINARY)),
                              name);
 
-                if (pa_database_set(u->database, &key, &data, mode == PA_UPDATE_REPLACE) == 0)
+                if (entry_write(u, name, entry, mode == PA_UPDATE_REPLACE)) {
+#ifdef HAVE_DBUS
+                    struct dbus_entry *de;
+
+                    if (old) {
+                        pa_assert_se((de = pa_hashmap_get(u->dbus_entries, name)));
+
+                        if ((old->device_valid != entry->device_valid)
+                            || (entry->device_valid && !pa_streq(entry->device, old->device)))
+                            send_device_updated_signal(de, entry);
+
+                        if ((old->volume_valid != entry->volume_valid)
+                            || (entry->volume_valid && (!pa_cvolume_equal(&entry->volume, &old->volume)
+                                                       || !pa_channel_map_equal(&entry->channel_map, &old->channel_map))))
+                            send_volume_updated_signal(de, entry);
+
+                        if (!old->muted_valid || (entry->muted != old->muted))
+                            send_mute_updated_signal(de, entry);
+
+                    } else {
+                        de = dbus_entry_new(u, name);
+                        pa_assert_se(pa_hashmap_put(u->dbus_entries, de->entry_name, de) == 0);
+                        send_new_entry_signal(de);
+                    }
+#endif
+
                     if (apply_immediately)
-                        apply_entry(u, name, &entry);
+                        entry_apply(u, name, entry);
+                }
+
+#ifdef HAVE_DBUS
+                if (old)
+                    entry_free(old);
+#endif
+                entry_free(entry);
             }
 
             trigger_save(u);
@@ -953,10 +2200,20 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
             while (!pa_tagstruct_eof(t)) {
                 const char *name;
                 pa_datum key;
+#ifdef HAVE_DBUS
+                struct dbus_entry *de;
+#endif
 
                 if (pa_tagstruct_gets(t, &name) < 0)
                     goto fail;
 
+#ifdef HAVE_DBUS
+                if ((de = pa_hashmap_get(u->dbus_entries, name))) {
+                    send_entry_removed_signal(de);
+                    dbus_entry_free(pa_hashmap_remove(u->dbus_entries, name));
+                }
+#endif
+
                 key.data = (char*) name;
                 key.size = strlen(name);
 
@@ -1007,6 +2264,101 @@ static pa_hook_result_t connection_unlink_hook_cb(pa_native_protocol *p, pa_nati
     return PA_HOOK_OK;
 }
 
+static void clean_up_db(struct userdata *u) {
+    struct clean_up_item {
+        PA_LLIST_FIELDS(struct clean_up_item);
+        char *entry_name;
+        struct entry *entry;
+    };
+
+    PA_LLIST_HEAD(struct clean_up_item, to_be_removed);
+#ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
+    PA_LLIST_HEAD(struct clean_up_item, to_be_converted);
+#endif
+    pa_bool_t done = FALSE;
+    pa_datum key;
+    struct clean_up_item *item = NULL;
+    struct clean_up_item *next = NULL;
+
+    pa_assert(u);
+
+    /* It would be convenient to remove or replace the entries in the database
+     * in the same loop that iterates through the database, but modifying the
+     * database is not supported while iterating through it. That's why we
+     * collect the entries that need to be removed or replaced to these
+     * lists. */
+    PA_LLIST_HEAD_INIT(struct clean_up_item, to_be_removed);
+#ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
+    PA_LLIST_HEAD_INIT(struct clean_up_item, to_be_converted);
+#endif
+
+    done = !pa_database_first(u->database, &key, NULL);
+    while (!done) {
+        pa_datum next_key;
+        char *entry_name = NULL;
+        struct entry *e = NULL;
+
+        entry_name = pa_xstrndup(key.data, key.size);
+
+        /* Use entry_read() to check whether this entry is valid. */
+        if (!(e = entry_read(u, entry_name))) {
+            item = pa_xnew0(struct clean_up_item, 1);
+            PA_LLIST_INIT(struct clean_up_item, item);
+            item->entry_name = entry_name;
+
+#ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
+            /* entry_read() failed, but what about legacy_entry_read()? */
+            if (!(e = legacy_entry_read(u, entry_name)))
+                /* Not a legacy entry either, let's remove this. */
+                PA_LLIST_PREPEND(struct clean_up_item, to_be_removed, item);
+            else {
+                /* Yay, it's valid after all! Now let's convert the entry to the current format. */
+                item->entry = e;
+                PA_LLIST_PREPEND(struct clean_up_item, to_be_converted, item);
+            }
+#else
+            /* Invalid entry, let's remove this. */
+            PA_LLIST_PREPEND(struct clean_up_item, to_be_removed, item);
+#endif
+        } else {
+            pa_xfree(entry_name);
+            entry_free(e);
+        }
+
+        done = !pa_database_next(u->database, &key, &next_key, NULL);
+        pa_datum_free(&key);
+        key = next_key;
+    }
+
+    PA_LLIST_FOREACH_SAFE(item, next, to_be_removed) {
+        key.data = item->entry_name;
+        key.size = strlen(item->entry_name);
+
+        pa_log_debug("Removing an invalid entry: %s", item->entry_name);
+
+        pa_assert_se(pa_database_unset(u->database, &key) >= 0);
+        trigger_save(u);
+
+        PA_LLIST_REMOVE(struct clean_up_item, to_be_removed, item);
+        pa_xfree(item->entry_name);
+        pa_xfree(item);
+    }
+
+#ifdef ENABLE_LEGACY_DATABASE_ENTRY_FORMAT
+    PA_LLIST_FOREACH_SAFE(item, next, to_be_converted) {
+        pa_log_debug("Upgrading a legacy entry to the current format: %s", item->entry_name);
+
+        pa_assert_se(entry_write(u, item->entry_name, item->entry, TRUE) >= 0);
+        trigger_save(u);
+
+        PA_LLIST_REMOVE(struct clean_up_item, to_be_converted, item);
+        pa_xfree(item->entry_name);
+        entry_free(item->entry);
+        pa_xfree(item);
+    }
+#endif
+}
+
 int pa__init(pa_module*m) {
     pa_modargs *ma = NULL;
     struct userdata *u;
@@ -1015,6 +2367,10 @@ int pa__init(pa_module*m) {
     pa_source_output *so;
     uint32_t idx;
     pa_bool_t restore_device = TRUE, restore_volume = TRUE, restore_muted = TRUE, on_hotplug = TRUE, on_rescue = TRUE;
+#ifdef HAVE_DBUS
+    pa_datum key;
+    pa_bool_t done;
+#endif
 
     pa_assert(m);
 
@@ -1070,8 +2426,10 @@ int pa__init(pa_module*m) {
         u->source_unlink_hook_slot = pa_hook_connect(&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)
+    if (restore_volume || restore_muted) {
         u->sink_input_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_fixate_hook_callback, u);
+        u->source_output_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) source_output_fixate_hook_callback, u);
+    }
 
     if (!(fname = pa_state_path("stream-volumes", TRUE)))
         goto fail;
@@ -1082,9 +2440,39 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
-    pa_log_info("Sucessfully opened database file '%s'.", fname);
+    pa_log_info("Successfully opened database file '%s'.", fname);
     pa_xfree(fname);
 
+    clean_up_db(u);
+
+    if (fill_db(u, pa_modargs_get_value(ma, "fallback_table", NULL)) < 0)
+        goto fail;
+
+#ifdef HAVE_DBUS
+    u->dbus_protocol = pa_dbus_protocol_get(u->core);
+    u->dbus_entries = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+
+    pa_assert_se(pa_dbus_protocol_add_interface(u->dbus_protocol, OBJECT_PATH, &stream_restore_interface_info, u) >= 0);
+    pa_assert_se(pa_dbus_protocol_register_extension(u->dbus_protocol, INTERFACE_STREAM_RESTORE) >= 0);
+
+    /* Create the initial dbus entries. */
+    done = !pa_database_first(u->database, &key, NULL);
+    while (!done) {
+        pa_datum next_key;
+        char *name;
+        struct dbus_entry *de;
+
+        name = pa_xstrndup(key.data, key.size);
+        de = dbus_entry_new(u, name);
+        pa_assert_se(pa_hashmap_put(u->dbus_entries, de->entry_name, de) == 0);
+        pa_xfree(name);
+
+        done = !pa_database_next(u->database, &key, &next_key, NULL);
+        pa_datum_free(&key);
+        key = next_key;
+    }
+#endif
+
     PA_IDXSET_FOREACH(si, m->core->sink_inputs, idx)
         subscribe_callback(m->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, si->index, u);
 
@@ -1100,7 +2488,7 @@ fail:
     if (ma)
         pa_modargs_free(ma);
 
-    return  -1;
+    return -1;
 }
 
 void pa__done(pa_module*m) {
@@ -1111,6 +2499,19 @@ void pa__done(pa_module*m) {
     if (!(u = m->userdata))
         return;
 
+#ifdef HAVE_DBUS
+    if (u->dbus_protocol) {
+        pa_assert(u->dbus_entries);
+
+        pa_assert_se(pa_dbus_protocol_unregister_extension(u->dbus_protocol, INTERFACE_STREAM_RESTORE) >= 0);
+        pa_assert_se(pa_dbus_protocol_remove_interface(u->dbus_protocol, OBJECT_PATH, stream_restore_interface_info.name) >= 0);
+
+        pa_hashmap_free(u->dbus_entries, (pa_free_cb_t) dbus_entry_free);
+
+        pa_dbus_protocol_unref(u->dbus_protocol);
+    }
+#endif
+
     if (u->subscription)
         pa_subscription_free(u->subscription);
 
@@ -1120,6 +2521,8 @@ void pa__done(pa_module*m) {
         pa_hook_slot_free(u->sink_input_fixate_hook_slot);
     if (u->source_output_new_hook_slot)
         pa_hook_slot_free(u->source_output_new_hook_slot);
+    if (u->source_output_fixate_hook_slot)
+        pa_hook_slot_free(u->source_output_fixate_hook_slot);
 
     if (u->sink_put_hook_slot)
         pa_hook_slot_free(u->sink_put_hook_slot);
@@ -1146,7 +2549,7 @@ void pa__done(pa_module*m) {
     }
 
     if (u->subscribed)
-        pa_idxset_free(u->subscribed, NULL, NULL);
+        pa_idxset_free(u->subscribed, NULL);
 
     pa_xfree(u);
 }
diff --git a/src/modules/module-suspend-on-idle-symdef.h b/src/modules/module-suspend-on-idle-symdef.h
deleted file mode 100644 (file)
index 781725c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulesuspendonidlesymdeffoo
-#define foomodulesuspendonidlesymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_suspend_on_idle_LTX_pa__init
-#define pa__done module_suspend_on_idle_LTX_pa__done
-#define pa__get_author module_suspend_on_idle_LTX_pa__get_author
-#define pa__get_description module_suspend_on_idle_LTX_pa__get_description
-#define pa__get_usage module_suspend_on_idle_LTX_pa__get_usage
-#define pa__get_version module_suspend_on_idle_LTX_pa__get_version
-#define pa__get_deprecated module_suspend_on_idle_LTX_pa__get_deprecated
-#define pa__load_once module_suspend_on_idle_LTX_pa__load_once
-#define pa__get_n_used module_suspend_on_idle_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
old mode 100644 (file)
new mode 100755 (executable)
index c5d999b..1f1bf22
@@ -34,9 +34,7 @@
 #include <pulsecore/modargs.h>
 #include <pulsecore/log.h>
 #include <pulsecore/namereg.h>
-
-#include <power.h>
-
+#include <pulsecore/strbuf.h>
 #include "module-suspend-on-idle-symdef.h"
 
 PA_MODULE_AUTHOR("Lennart Poettering");
@@ -44,17 +42,26 @@ PA_MODULE_DESCRIPTION("When a sink/source is idle for too long, suspend it");
 PA_MODULE_VERSION(PACKAGE_VERSION);
 PA_MODULE_LOAD_ONCE(TRUE);
 
-static const char* const valid_modargs[] = {
-    "timeout",
-    NULL,
+#define USE_PM_LOCK /* Enable as default */
+#ifdef USE_PM_LOCK
+#include "pm-util.h"
+#include <pulsecore/mutex.h>
+
+typedef struct pa_pm_list pa_pm_list;
+
+struct pa_pm_list {
+    uint32_t index;
+    pa_bool_t is_sink;
+    PA_LLIST_FIELDS(pa_pm_list);
 };
 
-#define PM_TYPE_SINK   0x01
-#define PM_TYPE_SOURCE 0x02
+#endif
 
-#define UPDATE_PM_LOCK(current,type)   (current |= type)
-#define UPDATE_PM_UNLOCK(current,type) (current &= ~type)
 
+static const char* const valid_modargs[] = {
+    "timeout",
+    NULL,
+};
 
 struct userdata {
     pa_core *core;
@@ -79,7 +86,11 @@ struct userdata {
         *source_output_move_finish_slot,
         *sink_input_state_changed_slot,
         *source_output_state_changed_slot;
-    uint32_t pm_state;
+#ifdef USE_PM_LOCK
+    pa_mutex* pm_mutex;
+    PA_LLIST_HEAD(pa_pm_list, pm_list);
+    pa_bool_t is_pm_locked;
+#endif /* USE_PM_LOCK */
 };
 
 struct device_info {
@@ -90,47 +101,193 @@ struct device_info {
     pa_time_event *time_event;
 };
 
+
+#ifdef USE_PM_LOCK
+
+enum {
+    PM_SUSPEND = 0,
+    PM_RESUME
+};
+
+enum {
+    PM_SOURCE = 0,
+    PM_SINK
+};
+
+#define GET_STR(s) ((s)? "sink":"source")
+#define USE_DEVICE_DEFAULT_TIMEOUT         -1
+#ifdef PRODUCT_FEATURE
+#define SINK_VIRTUAL        "alsa_output.virtual.analog-stereo"
+#define SINK_VOIP           "alsa_output.3.analog-stereo"
+#define SOURCE_VOIP         "alsa_input.3.analog-stereo"
+#define SINK_ALSA    "alsa_output.0.analog-stereo"
+#define SOURCE_ALSA    "alsa_input.0.analog-stereo"
+#endif
+static void _pm_list_add_if_not_exist(struct userdata *u, int is_sink, uint32_t index_to_add)
+{
+    struct pa_pm_list *item_info = NULL;
+    struct pa_pm_list *item_info_n = NULL;
+
+    /* Search if exists */
+    PA_LLIST_FOREACH_SAFE(item_info, item_info_n, u->pm_list) {
+        if (item_info->is_sink == is_sink && item_info->index == index_to_add) {
+        pa_log_debug_verbose("[PM] Already index (%s:%d) exists on list[%p], return",
+                GET_STR(is_sink), index_to_add, u->pm_list);
+        return;
+        }
+    }
+
+    /* Add new index */
+    item_info = pa_xnew0(pa_pm_list, 1);
+    item_info->is_sink = is_sink;
+    item_info->index = index_to_add;
+
+    PA_LLIST_PREPEND(pa_pm_list, u->pm_list, item_info);
+
+    pa_log_debug_verbose("[PM] Added (%s:%d) to list[%p]", GET_STR(is_sink), index_to_add, u->pm_list);
+}
+
+static void _pm_list_remove_if_exist(struct userdata *u, int is_sink, uint32_t index_to_remove)
+{
+    struct pa_pm_list *item_info = NULL;
+    struct pa_pm_list *item_info_n = NULL;
+
+    /* Remove if exists */
+    PA_LLIST_FOREACH_SAFE(item_info, item_info_n, u->pm_list) {
+        if (item_info->is_sink == is_sink && item_info->index == index_to_remove) {
+            pa_log_debug_verbose("[PM] Found index (%s:%d) exists on list[%p], Remove it",
+                    GET_STR(is_sink), index_to_remove, u->pm_list);
+
+            PA_LLIST_REMOVE(struct pa_pm_list, u->pm_list, item_info);
+            pa_xfree (item_info);
+        }
+    }
+}
+
+static void _pm_list_dump(struct userdata *u, pa_strbuf *s)
+{
+    struct pa_pm_list *list_info = NULL;
+    struct pa_pm_list *list_info_n = NULL;
+
+    if (u->pm_list) {
+        PA_LLIST_FOREACH_SAFE(list_info, list_info_n, u->pm_list) {
+            pa_strbuf_printf(s, "[%s:%d]", GET_STR(list_info->is_sink), list_info->index);
+        }
+    }
+    if (pa_strbuf_isempty(s)) {
+        pa_strbuf_puts(s, "empty");
+    }
+}
+
+static void update_pm_status (struct userdata *u, int is_sink, int index, int is_resume)
+{
+    int ret = -1;
+    pa_strbuf *before, *after;
+    char *b = NULL, *a = NULL;
+
+    pa_mutex_lock(u->pm_mutex);
+
+    before = pa_strbuf_new();
+    _pm_list_dump(u, before);
+
+    if (is_resume) {
+        _pm_list_add_if_not_exist(u, is_sink, index);
+
+        if (u->pm_list) {
+            if (!u->is_pm_locked) {
+                ret = pm_display_lock();
+                if (ret < 0)
+                    pa_log_warn("pm_lock_state failed");
+                else
+                    u->is_pm_locked = TRUE;
+            } else {
+                pa_log_debug_verbose("already locked state, skip lock");
+                goto exit;
+            }
+        }
+    } else {
+        _pm_list_remove_if_exist(u, is_sink, index);
+
+        if (u->pm_list == NULL) {
+            if (u->is_pm_locked) {
+                ret = pm_display_unlock();
+                if (ret < 0)
+                    pa_log_warn("pm_unlock_state failed");
+                else
+                    u->is_pm_locked = FALSE;
+            } else {
+                pa_log_debug_verbose("already unlocked state, skip unlock");
+                goto exit;
+            }
+        }
+    }
+
+    after = pa_strbuf_new();
+    _pm_list_dump(u, after);
+
+    b = pa_strbuf_tostring_free(before);
+    a = pa_strbuf_tostring_free(after);
+    pa_log_info("[PM] %s [%s:%d] ret[%d] list[%p] before:%s after:%s",
+            (is_resume) ? "resume" : "suspend", GET_STR(is_sink), index, ret, u->pm_list,
+            b, a);
+    pa_xfree(b);
+    pa_xfree(a);
+    after = NULL;
+    before = NULL;
+
+exit:
+    if (after)
+        pa_strbuf_free(after);
+
+    if (before)
+        pa_strbuf_free(before);
+
+    pa_mutex_unlock(u->pm_mutex);
+}
+#endif /* USE_PM_LOCK */
+
+static pa_bool_t _is_audio_pm_needed (pa_proplist *p)
+{
+    char* value = pa_proplist_gets (p, "need_audio_pm");
+    if (value) {
+        return atoi (value);
+    }
+    return 0;
+}
+
 static void timeout_cb(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
     struct device_info *d = userdata;
     int ret = -1;
+    const char *s = NULL;
 
     pa_assert(d);
 
     d->userdata->core->mainloop->time_restart(d->time_event, NULL);
 
+
+    /* SINK */
     if (d->sink && pa_sink_check_suspend(d->sink) <= 0 && !(d->sink->suspend_cause & PA_SUSPEND_IDLE)) {
-        pa_log_info("Sink %s idle for too long, suspending ...", d->sink->name);
+        pa_log_info_verbose("Sink %s idle for too long, suspending ...", d->sink->name);
         pa_sink_suspend(d->sink, TRUE, PA_SUSPEND_IDLE);
+#ifdef USE_PM_LOCK
+        update_pm_status(d->userdata, PM_SINK, d->sink->index, PM_SUSPEND);
+#endif /* USE_PM_LOCK */
+    }
 
-               UPDATE_PM_UNLOCK(d->userdata->pm_state, PM_TYPE_SINK);
-               if(!(d->userdata->pm_state)) {
-                       ret = power_unlock_state(POWER_STATE_SCREEN_OFF);
-                       if(!ret)
-                               pa_log_info("sink pm_unlock_state success");
-                       else
-                               pa_log_error("sink pm_unlock_state failed [%d]", ret);
-               }
-       }
-
+    /* SOURCE */
     if (d->source && pa_source_check_suspend(d->source) <= 0 && !(d->source->suspend_cause & PA_SUSPEND_IDLE)) {
         pa_log_info("Source %s idle for too long, suspending ...", d->source->name);
         pa_source_suspend(d->source, TRUE, PA_SUSPEND_IDLE);
-
-        UPDATE_PM_UNLOCK(d->userdata->pm_state, PM_TYPE_SOURCE);
-        if(!(d->userdata->pm_state)) {
-                       ret = power_unlock_state(POWER_STATE_SCREEN_OFF);
-                       if(!ret)
-                               pa_log_info("source pm_unlock_state success");
-                       else
-                               pa_log_error("source pm_unlock_state failed [%d]", ret);
-               }
+#ifdef USE_PM_LOCK
+        update_pm_status(d->userdata, PM_SOURCE, d->source->index, PM_SUSPEND);
+#endif /* USE_PM_LOCK */
     }
 }
 
-static void restart(struct device_info *d) {
+static void restart(struct device_info *d, int input_timeout) {
     pa_usec_t now;
-    const char *s;
-    uint32_t timeout;
+    const char *s = NULL;
+    uint32_t timeout = d->userdata->timeout;
 
     pa_assert(d);
     pa_assert(d->sink || d->source);
@@ -138,52 +295,84 @@ static void restart(struct device_info *d) {
     d->last_use = now = pa_rtclock_now();
 
     s = pa_proplist_gets(d->sink ? d->sink->proplist : d->source->proplist, "module-suspend-on-idle.timeout");
-    if (!s || pa_atou(s, &timeout) < 0)
-        timeout = d->userdata->timeout;
+    if (!s || pa_atou(s, &timeout) < 0) {
+        if (input_timeout >= 0)
+            timeout = (uint32_t)input_timeout;
+    }
+
+#ifdef __TIZEN__
+    /* Assume that timeout is milli seconds unit if large (>=100) enough */
+    if (timeout >= 100) {
+        pa_core_rttime_restart(d->userdata->core, d->time_event, now + timeout * PA_USEC_PER_MSEC);
 
+        if (d->sink)
+            pa_log_debug_verbose("Sink %s becomes idle, timeout in %u msec.", d->sink->name, timeout);
+        if (d->source)
+            pa_log_debug_verbose("Source %s becomes idle, timeout in %u msec.", d->source->name, timeout);
+    } else {
+        pa_core_rttime_restart(d->userdata->core, d->time_event, now + timeout * PA_USEC_PER_SEC);
+
+        if (d->sink)
+            pa_log_debug_verbose("Sink %s becomes idle, timeout in %u seconds.", d->sink->name, timeout);
+        if (d->source)
+            pa_log_debug_verbose("Source %s becomes idle, timeout in %u seconds.", d->source->name, timeout);
+    }
+#else
     pa_core_rttime_restart(d->userdata->core, d->time_event, now + timeout * PA_USEC_PER_SEC);
 
     if (d->sink)
-        pa_log_debug("Sink %s becomes idle, timeout in %u seconds.", d->sink->name, timeout);
+        pa_log_debug_verbose("Sink %s becomes idle, timeout in %u seconds.", d->sink->name, timeout);
     if (d->source)
-        pa_log_debug("Source %s becomes idle, timeout in %u seconds.", d->source->name, timeout);
+        pa_log_debug_verbose("Source %s becomes idle, timeout in %u seconds.", d->source->name, timeout);
+#endif
 }
 
 static void resume(struct device_info *d) {
+    int ret = 0;
     pa_assert(d);
 
-    int ret = -1;
-
     d->userdata->core->mainloop->time_restart(d->time_event, NULL);
 
     if (d->sink) {
-
-               UPDATE_PM_LOCK(d->userdata->pm_state, PM_TYPE_SINK);
-               ret = power_lock_state(POWER_STATE_SCREEN_OFF, 0);
-               if(!ret) {
-                       pa_log_info("sink pm_lock_state success");
-               } else {
-                       pa_log_error("sink pm_lock_state failed [%d]", ret);
-               }
-
-       pa_sink_suspend(d->sink, FALSE, PA_SUSPEND_IDLE);
-
-        pa_log_debug("Sink %s becomes busy.", d->sink->name);
+#ifdef USE_PM_LOCK
+        update_pm_status(d->userdata, PM_SINK, d->sink->index, PM_RESUME);
+#endif /* USE_PM_LOCK */
+
+#ifdef __TIZEN__
+        ret = pa_sink_suspend(d->sink, FALSE, PA_SUSPEND_IDLE);
+        if (ret < 0) {
+            pa_log_error("pa_sink_suspend(IDLE) sink:%d return error:%d", d->sink->index, ret);
+#ifdef USE_PM_LOCK
+            update_pm_status(d->userdata, PM_SINK, d->sink->index, PM_SUSPEND);
+#endif /* USE_PM_LOCK */
+        } else {
+            pa_log_debug_verbose("Sink %s becomes busy.", d->sink->name);
+        }
+#else
+        pa_sink_suspend(d->sink, FALSE, PA_SUSPEND_IDLE);
+        pa_log_debug_verbose("Sink %s becomes busy.", d->sink->name);
+#endif
     }
 
     if (d->source) {
-
-               UPDATE_PM_LOCK(d->userdata->pm_state, PM_TYPE_SOURCE);
-               ret = power_lock_state(POWER_STATE_SCREEN_OFF, 0);
-               if(!ret) {
-                       pa_log_info("source pm_lock_state success");
-               } else {
-                       pa_log_error("source pm_lock_state failed [%d]", ret);
-               }
-
+#ifdef USE_PM_LOCK
+        update_pm_status(d->userdata, PM_SOURCE, d->source->index, PM_RESUME);
+#endif /* USE_PM_LOCK */
+
+#ifdef __TIZEN__
+        ret = pa_source_suspend(d->source, FALSE, PA_SUSPEND_IDLE);
+        if (ret < 0) {
+            pa_log_error("pa_source_suspend(IDLE) source:%d return error:%d", d->source->index, ret);
+#ifdef USE_PM_LOCK
+            update_pm_status(d->userdata, PM_SOURCE, d->source->index, PM_SUSPEND);
+#endif /* USE_PM_LOCK */
+        } else {
+            pa_log_debug_verbose("Source %s becomes busy.", d->source->name);
+        }
+#else
         pa_source_suspend(d->source, FALSE, PA_SUSPEND_IDLE);
-
-        pa_log_debug("Source %s becomes busy.", d->source->name);
+        pa_log_debug_verbose("Source %s becomes busy.", d->source->name);
+#endif
     }
 }
 
@@ -194,8 +383,9 @@ static pa_hook_result_t sink_input_fixate_hook_cb(pa_core *c, pa_sink_input_new_
     pa_assert(data);
     pa_assert(u);
 
-    if (data->flags & PA_SINK_INPUT_START_CORKED)
-        return PA_HOOK_OK;
+    /* We need to resume the audio device here even for
+     * PA_SINK_INPUT_START_CORKED, since we need the device parameters
+     * to be fully available while the stream is set up. */
 
     if ((d = pa_hashmap_get(u->device_infos, data->sink)))
         resume(d);
@@ -210,9 +400,6 @@ static pa_hook_result_t source_output_fixate_hook_cb(pa_core *c, pa_source_outpu
     pa_assert(data);
     pa_assert(u);
 
-    if (data->flags & PA_SOURCE_OUTPUT_START_CORKED)
-        return PA_HOOK_OK;
-
     if (data->source->monitor_of)
         d = pa_hashmap_get(u->device_infos, data->source->monitor_of);
     else
@@ -235,7 +422,7 @@ static pa_hook_result_t sink_input_unlink_hook_cb(pa_core *c, pa_sink_input *s,
     if (pa_sink_check_suspend(s->sink) <= 0) {
         struct device_info *d;
         if ((d = pa_hashmap_get(u->device_infos, s->sink)))
-            restart(d);
+            restart(d, USE_DEVICE_DEFAULT_TIMEOUT);
     }
 
     return PA_HOOK_OK;
@@ -243,6 +430,9 @@ static pa_hook_result_t sink_input_unlink_hook_cb(pa_core *c, pa_sink_input *s,
 
 static pa_hook_result_t source_output_unlink_hook_cb(pa_core *c, pa_source_output *s, struct userdata *u) {
     struct device_info *d = NULL;
+    int n_source_output = 0;
+    int timeout = USE_DEVICE_DEFAULT_TIMEOUT;
+    const int nothing = 0;
 
     pa_assert(c);
     pa_source_output_assert_ref(s);
@@ -259,8 +449,15 @@ static pa_hook_result_t source_output_unlink_hook_cb(pa_core *c, pa_source_outpu
             d = pa_hashmap_get(u->device_infos, s->source);
     }
 
+    n_source_output = pa_source_linked_by(s->source);
+    if(n_source_output == nothing) {
+        timeout = 0; // set timeout 0, should be called immediately.
+        pa_log_error("source outputs does't exist anymore. enter suspend state. name(%s), count(%d)",
+            s->source->name, n_source_output);
+    }
+
     if (d)
-        restart(d);
+        restart(d, timeout);
 
     return PA_HOOK_OK;
 }
@@ -274,7 +471,7 @@ static pa_hook_result_t sink_input_move_start_hook_cb(pa_core *c, pa_sink_input
 
     if (pa_sink_check_suspend(s->sink) <= 1)
         if ((d = pa_hashmap_get(u->device_infos, s->sink)))
-            restart(d);
+            restart(d, USE_DEVICE_DEFAULT_TIMEOUT);
 
     return PA_HOOK_OK;
 }
@@ -313,7 +510,7 @@ static pa_hook_result_t source_output_move_start_hook_cb(pa_core *c, pa_source_o
     }
 
     if (d)
-        restart(d);
+        restart(d, USE_DEVICE_DEFAULT_TIMEOUT);
 
     return PA_HOOK_OK;
 }
@@ -390,7 +587,15 @@ static pa_hook_result_t device_new_hook_cb(pa_core *c, pa_object *o, struct user
     /* Never suspend monitors */
     if (source && source->monitor_of)
         return PA_HOOK_OK;
-
+#ifdef PRODUCT_FEATURE
+    if ((sink && (pa_streq (sink->name, SINK_VOIP) )) || (source && (pa_streq (source->name, SOURCE_VOIP) ))) {
+        if (sink)
+            pa_log_warn("Sink %s **********", sink->name);
+        if (source)
+            pa_log_warn("Source %s **********", source->name);
+        return PA_HOOK_OK;
+    }
+#endif
     pa_assert(source || sink);
 
     d = pa_xnew(struct device_info, 1);
@@ -402,7 +607,7 @@ static pa_hook_result_t device_new_hook_cb(pa_core *c, pa_object *o, struct user
 
     if ((d->sink && pa_sink_check_suspend(d->sink) <= 0) ||
         (d->source && pa_source_check_suspend(d->source) <= 0))
-        restart(d);
+        restart(d, USE_DEVICE_DEFAULT_TIMEOUT);
 
     return PA_HOOK_OK;
 }
@@ -422,11 +627,28 @@ static void device_info_free(struct device_info *d) {
 
 static pa_hook_result_t device_unlink_hook_cb(pa_core *c, pa_object *o, struct userdata *u) {
     struct device_info *d;
+    pa_sink *sink = NULL;
+    pa_source *source = NULL;
+
+#ifdef PRODUCT_FEATURE
+    pa_sink *sink_alsa = NULL;
+    pa_source *source_alsa = NULL;
+#endif
 
     pa_assert(c);
     pa_object_assert_ref(o);
     pa_assert(u);
 
+    if (pa_sink_isinstance(o)) {
+        sink = PA_SINK(o);
+        pa_log_info ("sink [%p][%d] is unlinked, now update pm", sink, (sink)? sink->index : -1);
+        update_pm_status(u, PM_SINK, sink->index, PM_SUSPEND);
+    } else if (pa_source_isinstance(o)) {
+        source = PA_SOURCE(o);
+        pa_log_info ("source [%p][%d] is unlinked, now update pm", source, (source)? source->index : -1);
+        update_pm_status(u, PM_SOURCE, source->index, PM_SUSPEND);
+    }
+
     if ((d = pa_hashmap_remove(u->device_infos, o)))
         device_info_free(d);
 
@@ -447,9 +669,13 @@ static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, s
         pa_sink *s = PA_SINK(o);
         pa_sink_state_t state = pa_sink_get_state(s);
 
+#ifdef USE_PM_LOCK
+        if(state == PA_SINK_SUSPENDED && (s->suspend_cause & PA_SUSPEND_USER))
+            update_pm_status(d->userdata, PM_SINK, d->sink->index, PM_SUSPEND);
+#endif
         if (pa_sink_check_suspend(s) <= 0)
             if (PA_SINK_IS_OPENED(state))
-                restart(d);
+                restart(d, USE_DEVICE_DEFAULT_TIMEOUT);
 
     } else if (pa_source_isinstance(o)) {
         pa_source *s = PA_SOURCE(o);
@@ -457,7 +683,7 @@ static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, s
 
         if (pa_source_check_suspend(s) <= 0)
             if (PA_SOURCE_IS_OPENED(state))
-                restart(d);
+                restart(d, USE_DEVICE_DEFAULT_TIMEOUT);
     }
 
     return PA_HOOK_OK;
@@ -487,7 +713,9 @@ int pa__init(pa_module*m) {
     u->core = m->core;
     u->timeout = timeout;
     u->device_infos = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
-    u->pm_state = 0x00;
+#ifdef USE_PM_LOCK
+    PA_LLIST_HEAD_INIT(pa_pm_list, u->pm_list);
+#endif /* USE_PM_LOCK */
 
     for (sink = pa_idxset_first(m->core->sinks, &idx); sink; sink = pa_idxset_next(m->core->sinks, &idx))
         device_new_hook_cb(m->core, PA_OBJECT(sink), u);
@@ -512,6 +740,10 @@ int pa__init(pa_module*m) {
     u->source_output_move_finish_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FINISH], PA_HOOK_NORMAL, (pa_hook_cb_t) source_output_move_finish_hook_cb, u);
     u->sink_input_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) sink_input_state_changed_hook_cb, u);
     u->source_output_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) source_output_state_changed_hook_cb, u);
+#ifdef USE_PM_LOCK
+    u->pm_mutex = pa_mutex_new(FALSE, FALSE);
+    u->is_pm_locked = FALSE;
+#endif
 
     pa_modargs_free(ma);
     return 0;
@@ -574,7 +806,13 @@ void pa__done(pa_module*m) {
     while ((d = pa_hashmap_steal_first(u->device_infos)))
         device_info_free(d);
 
-    pa_hashmap_free(u->device_infos, NULL, NULL);
+    pa_hashmap_free(u->device_infos, NULL);
 
+#ifdef USE_PM_LOCK
+    if (u->pm_mutex) {
+        pa_mutex_free(u->pm_mutex);
+        u->pm_mutex = NULL;
+    }
+#endif
     pa_xfree(u);
 }
diff --git a/src/modules/module-switch-on-connect.c b/src/modules/module-switch-on-connect.c
new file mode 100644 (file)
index 0000000..efe1270
--- /dev/null
@@ -0,0 +1,192 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2006 Lennart Poettering
+  Copyright 2009 Canonical Ltd
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/core.h>
+#include <pulsecore/sink-input.h>
+#include <pulsecore/source-output.h>
+#include <pulsecore/source.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/log.h>
+#include <pulsecore/namereg.h>
+#include <pulsecore/core-util.h>
+
+#include "module-switch-on-connect-symdef.h"
+
+PA_MODULE_AUTHOR("Michael Terry");
+PA_MODULE_DESCRIPTION("When a sink/source is added, switch to it");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(TRUE);
+
+static const char* const valid_modargs[] = {
+    NULL,
+};
+
+struct userdata {
+    pa_hook_slot
+        *sink_put_slot,
+        *source_put_slot;
+};
+
+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 *def;
+    const char *s;
+
+    pa_assert(c);
+    pa_assert(sink);
+
+    /* Don't want to run during startup or shutdown */
+    if (c->state != PA_CORE_RUNNING)
+        return PA_HOOK_OK;
+
+    /* Don't switch to any internal devices */
+    if ((s = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_BUS))) {
+        if (pa_streq(s, "pci"))
+            return PA_HOOK_OK;
+        else if (pa_streq(s, "isa"))
+            return PA_HOOK_OK;
+    }
+
+    def = pa_namereg_get_default_sink(c);
+    if (def == sink)
+        return PA_HOOK_OK;
+
+    /* Actually do the switch to the new sink */
+    pa_namereg_set_default_sink(c, sink);
+
+    /* Now move all old inputs over */
+    if (pa_idxset_size(def->inputs) <= 0) {
+        pa_log_debug("No sink inputs to move away.");
+        return PA_HOOK_OK;
+    }
+
+    PA_IDXSET_FOREACH(i, def->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 *def;
+    const char *s;
+
+    pa_assert(c);
+    pa_assert(source);
+
+    /* Don't want to run during startup or shutdown */
+    if (c->state != PA_CORE_RUNNING)
+        return PA_HOOK_OK;
+
+    /* Don't switch to a monitoring source */
+    if (source->monitor_of)
+        return PA_HOOK_OK;
+
+    /* Don't switch to any internal devices */
+    if ((s = pa_proplist_gets(source->proplist, PA_PROP_DEVICE_BUS))) {
+        if (pa_streq(s, "pci"))
+            return PA_HOOK_OK;
+        else if (pa_streq(s, "isa"))
+            return PA_HOOK_OK;
+    }
+
+    def = pa_namereg_get_default_source(c);
+    if (def == source)
+        return PA_HOOK_OK;
+
+    /* Actually do the switch to the new source */
+    pa_namereg_set_default_source(c, source);
+
+    /* Now move all old outputs over */
+    if (pa_idxset_size(def->outputs) <= 0) {
+        pa_log_debug("No source outputs to move away.");
+        return PA_HOOK_OK;
+    }
+
+    PA_IDXSET_FOREACH(o, def->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;
+}
+
+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-rescue-streams... */
+    u->sink_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE+30, (pa_hook_cb_t) sink_put_hook_callback, u);
+    u->source_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_LATE+20, (pa_hook_cb_t) source_put_hook_callback, u);
+
+    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_put_slot)
+        pa_hook_slot_free(u->sink_put_slot);
+    if (u->source_put_slot)
+        pa_hook_slot_free(u->source_put_slot);
+
+    pa_xfree(u);
+}
diff --git a/src/modules/module-switch-on-port-available.c b/src/modules/module-switch-on-port-available.c
new file mode 100644 (file)
index 0000000..abd8777
--- /dev/null
@@ -0,0 +1,305 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2006 Lennart Poettering
+  Copyright 2011 Canonical Ltd
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulsecore/core.h>
+#include <pulsecore/device-port.h>
+#include <pulsecore/hashmap.h>
+
+#include "module-switch-on-port-available-symdef.h"
+
+struct userdata {
+     pa_hook_slot *available_slot;
+     pa_hook_slot *sink_new_slot;
+     pa_hook_slot *source_new_slot;
+};
+
+static pa_device_port* find_best_port(pa_hashmap *ports) {
+    void *state;
+    pa_device_port* port, *result = NULL;
+
+    PA_HASHMAP_FOREACH(port, ports, state) {
+        if (result == NULL ||
+            result->available == PA_AVAILABLE_NO ||
+            (port->available != PA_AVAILABLE_NO && port->priority > result->priority)) {
+            result = port;
+        }
+    }
+
+    return result;
+}
+
+static pa_bool_t try_to_switch_profile(pa_card *card, pa_device_port *port) {
+    pa_card_profile *best_profile = NULL, *profile;
+    void *state;
+
+    pa_log_debug("Finding best profile");
+
+    PA_HASHMAP_FOREACH(profile, port->profiles, state) {
+        if (best_profile && best_profile->priority >= profile->priority)
+            continue;
+
+        /* We make a best effort to keep other direction unchanged */
+        if (!port->is_input) {
+            if (card->active_profile->n_sources != profile->n_sources)
+                continue;
+
+            if (card->active_profile->max_source_channels != profile->max_source_channels)
+                continue;
+        }
+
+        if (!port->is_output) {
+            if (card->active_profile->n_sinks != profile->n_sinks)
+                continue;
+
+            if (card->active_profile->max_sink_channels != profile->max_sink_channels)
+                continue;
+        }
+
+        if (port->is_output) {
+            /* Try not to switch to HDMI sinks from analog when HDMI is becoming available */
+            uint32_t state2;
+            pa_sink *sink;
+            pa_bool_t found_active_port = FALSE;
+
+            PA_IDXSET_FOREACH(sink, card->sinks, state2) {
+                if (!sink->active_port)
+                    continue;
+                if (sink->active_port->available != PA_AVAILABLE_NO)
+                    found_active_port = TRUE;
+            }
+
+            if (found_active_port)
+                continue;
+        }
+
+        best_profile = profile;
+    }
+
+    if (!best_profile) {
+        pa_log_debug("No suitable profile found");
+        return FALSE;
+    }
+
+    if (pa_card_set_profile(card, best_profile->name, FALSE) != 0) {
+        pa_log_debug("Could not set profile %s", best_profile->name);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static void find_sink_and_source(pa_card *card, pa_device_port *port, pa_sink **si, pa_source **so)
+{
+    pa_sink *sink = NULL;
+    pa_source *source = NULL;
+    uint32_t state;
+
+    if (port->is_output)
+        PA_IDXSET_FOREACH(sink, card->sinks, state)
+            if (port == pa_hashmap_get(sink->ports, port->name))
+                break;
+
+    if (port->is_input)
+        PA_IDXSET_FOREACH(source, card->sources, state)
+            if (port == pa_hashmap_get(source->ports, port->name))
+                break;
+
+    *si = sink;
+    *so = source;
+}
+
+static pa_hook_result_t port_available_hook_callback(pa_core *c, pa_device_port *port, void* userdata) {
+    uint32_t state;
+    pa_card* card;
+    pa_sink *sink;
+    pa_source *source;
+    pa_bool_t is_active_profile, is_active_port;
+
+    if (port->available == PA_AVAILABLE_UNKNOWN)
+        return PA_HOOK_OK;
+
+    pa_log_debug("finding port %s", port->name);
+
+    PA_IDXSET_FOREACH(card, c->cards, state)
+        if (port == pa_hashmap_get(card->ports, port->name))
+            break;
+
+    if (!card) {
+        pa_log_warn("Did not find port %s in array of cards", port->name);
+        return PA_HOOK_OK;
+    }
+
+    find_sink_and_source(card, port, &sink, &source);
+
+    is_active_profile = card->active_profile == pa_hashmap_get(port->profiles, card->active_profile->name);
+    is_active_port = (sink && sink->active_port == port) || (source && source->active_port == port);
+
+    if (port->available == PA_AVAILABLE_NO && !is_active_port)
+        return PA_HOOK_OK;
+
+    if (port->available == PA_AVAILABLE_YES) {
+        if (is_active_port)
+            return PA_HOOK_OK;
+
+        if (!is_active_profile) {
+            if (!try_to_switch_profile(card, port))
+                return PA_HOOK_OK;
+
+            pa_assert(card->active_profile == pa_hashmap_get(port->profiles, card->active_profile->name));
+
+            /* Now that profile has changed, our sink and source pointers must be updated */
+            find_sink_and_source(card, port, &sink, &source);
+        }
+
+        if (source)
+            pa_source_set_port(source, port->name, FALSE);
+        if (sink)
+            pa_sink_set_port(sink, port->name, FALSE);
+    }
+
+    if (port->available == PA_AVAILABLE_NO) {
+        if (sink) {
+            pa_device_port *p2 = find_best_port(sink->ports);
+
+            if (p2 && p2->available != PA_AVAILABLE_NO)
+                pa_sink_set_port(sink, p2->name, FALSE);
+            else {
+                /* Maybe try to switch to another profile? */
+            }
+        }
+
+        if (source) {
+            pa_device_port *p2 = find_best_port(source->ports);
+
+            if (p2 && p2->available != PA_AVAILABLE_NO)
+                pa_source_set_port(source, p2->name, FALSE);
+            else {
+                /* Maybe try to switch to another profile? */
+            }
+        }
+    }
+
+    return PA_HOOK_OK;
+}
+
+static void handle_all_unavailable(pa_core *core) {
+    pa_card *card;
+    uint32_t state;
+
+    PA_IDXSET_FOREACH(card, core->cards, state) {
+        pa_device_port *port;
+        void *state2;
+
+        PA_HASHMAP_FOREACH(port, card->ports, state2) {
+            if (port->available == PA_AVAILABLE_NO)
+                port_available_hook_callback(core, port, NULL);
+        }
+    }
+}
+
+static pa_device_port *new_sink_source(pa_hashmap *ports, const char *name) {
+
+    void *state;
+    pa_device_port *i, *p = NULL;
+
+    if (!ports)
+        return NULL;
+    if (name)
+        p = pa_hashmap_get(ports, name);
+    if (!p)
+        PA_HASHMAP_FOREACH(i, ports, state)
+            if (!p || i->priority > p->priority)
+                p = i;
+    if (!p)
+        return NULL;
+    if (p->available != PA_AVAILABLE_NO)
+        return NULL;
+
+    pa_assert_se(p = find_best_port(ports));
+    return p;
+}
+
+static pa_hook_result_t sink_new_hook_callback(pa_core *c, pa_sink_new_data *new_data, struct userdata *u) {
+
+    pa_device_port *p = new_sink_source(new_data->ports, new_data->active_port);
+
+    if (p) {
+        pa_log_debug("Switching initial port for sink '%s' to '%s'", new_data->name, p->name);
+        pa_sink_new_data_set_port(new_data, p->name);
+    }
+    return PA_HOOK_OK;
+}
+
+static pa_hook_result_t source_new_hook_callback(pa_core *c, pa_source_new_data *new_data, struct userdata *u) {
+
+    pa_device_port *p = new_sink_source(new_data->ports, new_data->active_port);
+
+    if (p) {
+        pa_log_debug("Switching initial port for source '%s' to '%s'", new_data->name,
+                     new_data->active_port);
+        pa_source_new_data_set_port(new_data, p->name);
+    }
+    return PA_HOOK_OK;
+}
+
+
+int pa__init(pa_module*m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    m->userdata = u = pa_xnew(struct userdata, 1);
+
+    /* Make sure we are after module-device-restore, so we can overwrite that suggestion if necessary */
+    u->sink_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_NEW],
+                                       PA_HOOK_NORMAL, (pa_hook_cb_t) sink_new_hook_callback, u);
+    u->source_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_NEW],
+                                         PA_HOOK_NORMAL, (pa_hook_cb_t) source_new_hook_callback, u);
+    u->available_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_PORT_AVAILABLE_CHANGED],
+                                        PA_HOOK_LATE, (pa_hook_cb_t) port_available_hook_callback, u);
+
+    handle_all_unavailable(m->core);
+
+    return 0;
+}
+
+void pa__done(pa_module*m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    if (u->available_slot)
+        pa_hook_slot_free(u->available_slot);
+    if (u->sink_new_slot)
+        pa_hook_slot_free(u->sink_new_slot);
+    if (u->source_new_slot)
+        pa_hook_slot_free(u->source_new_slot);
+
+    pa_xfree(u);
+}
diff --git a/src/modules/module-systemd-login.c b/src/modules/module-systemd-login.c
new file mode 100644 (file)
index 0000000..72de47f
--- /dev/null
@@ -0,0 +1,233 @@
+/***
+    This file is part of PulseAudio.
+
+    Copyright 2012 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, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+    USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include <systemd/sd-login.h>
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/module.h>
+#include <pulsecore/log.h>
+#include <pulsecore/hashmap.h>
+#include <pulsecore/idxset.h>
+#include <pulsecore/modargs.h>
+
+#include "module-systemd-login-symdef.h"
+
+PA_MODULE_AUTHOR("Lennart Poettering");
+PA_MODULE_DESCRIPTION("Create a client for each login session of this user");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(TRUE);
+
+static const char* const valid_modargs[] = {
+    NULL
+};
+
+struct session {
+    char *id;
+    pa_client *client;
+};
+
+struct userdata {
+    pa_module *module;
+    pa_core *core;
+    pa_hashmap *sessions, *previous_sessions;
+    sd_login_monitor *monitor;
+    pa_io_event *io;
+};
+
+static int add_session(struct userdata *u, const char *id) {
+    struct session *session;
+    pa_client_new_data data;
+
+    session = pa_xnew(struct session, 1);
+    session->id = pa_xstrdup(id);
+
+    pa_client_new_data_init(&data);
+    data.module = u->module;
+    data.driver = __FILE__;
+    pa_proplist_setf(data.proplist, PA_PROP_APPLICATION_NAME, "Login Session %s", id);
+    pa_proplist_sets(data.proplist, "systemd-login.session", id);
+    session->client = pa_client_new(u->core, &data);
+    pa_client_new_data_done(&data);
+
+    if (!session->client) {
+        pa_xfree(session->id);
+        pa_xfree(session);
+        return -1;
+    }
+
+    pa_hashmap_put(u->sessions, session->id, session);
+
+    pa_log_debug("Added new session %s", id);
+    return 0;
+}
+
+static void free_session(struct session *session) {
+    pa_assert(session);
+
+    pa_log_debug("Removing session %s", session->id);
+
+    pa_client_free(session->client);
+    pa_xfree(session->id);
+    pa_xfree(session);
+}
+
+static int get_session_list(struct userdata *u) {
+    int r;
+    char **sessions;
+    pa_hashmap *h;
+    struct session *o;
+
+    pa_assert(u);
+
+    r = sd_uid_get_sessions(getuid(), 0, &sessions);
+    if (r < 0)
+        return -1;
+
+    /* We copy all sessions that still exist from one hashmap to the
+     * other and then flush the remaining ones */
+
+    h = u->previous_sessions;
+    u->previous_sessions = u->sessions;
+    u->sessions = h;
+
+    if (sessions) {
+        char **s;
+
+        /* Note that the sessions array is allocated with libc's
+         * malloc()/free() calls, hence do not use pa_xfree() to free
+         * this here. */
+
+        for (s = sessions; *s; s++) {
+            o = pa_hashmap_remove(u->previous_sessions, *s);
+            if (o)
+                pa_hashmap_put(u->sessions, o->id, o);
+            else
+                add_session(u, *s);
+
+            free(*s);
+        }
+
+        free(sessions);
+    }
+
+    pa_hashmap_remove_all(u->previous_sessions, (pa_free_cb_t) free_session);
+
+    return 0;
+}
+
+static void monitor_cb(
+        pa_mainloop_api*a,
+        pa_io_event* e,
+        int fd,
+        pa_io_event_flags_t events,
+        void *userdata) {
+
+    struct userdata *u = userdata;
+
+    pa_assert(u);
+
+    sd_login_monitor_flush(u->monitor);
+    get_session_list(u);
+}
+
+int pa__init(pa_module *m) {
+    struct userdata *u = NULL;
+    pa_modargs *ma;
+    sd_login_monitor *monitor = NULL;
+    int r;
+
+    pa_assert(m);
+
+    /* If we are not actually running logind become a NOP */
+    if (access("/run/systemd/seats/", F_OK) < 0)
+        return 0;
+
+    ma = pa_modargs_new(m->argument, valid_modargs);
+    if (!ma) {
+        pa_log("Failed to parse module arguments");
+        goto fail;
+    }
+
+    r = sd_login_monitor_new("session", &monitor);
+    if (r < 0) {
+        pa_log("Failed to create session monitor: %s", strerror(-r));
+        goto fail;
+    }
+
+    m->userdata = u = pa_xnew0(struct userdata, 1);
+    u->core = m->core;
+    u->module = m;
+    u->sessions = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    u->previous_sessions = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    u->monitor = monitor;
+
+    u->io = u->core->mainloop->io_new(u->core->mainloop, sd_login_monitor_get_fd(monitor), PA_IO_EVENT_INPUT, monitor_cb, u);
+
+    if (get_session_list(u) < 0)
+        goto fail;
+
+    pa_modargs_free(ma);
+
+    return 0;
+
+fail:
+    if (ma)
+        pa_modargs_free(ma);
+
+    pa__done(m);
+
+    return -1;
+}
+
+void pa__done(pa_module *m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    u = m->userdata;
+    if (!u)
+        return;
+
+    if (u->sessions) {
+        pa_hashmap_free(u->sessions, (pa_free_cb_t) free_session);
+        pa_hashmap_free(u->previous_sessions, (pa_free_cb_t) free_session);
+    }
+
+    if (u->io)
+        m->core->mainloop->io_free(u->io);
+
+    if (u->monitor)
+        sd_login_monitor_unref(u->monitor);
+
+    pa_xfree(u);
+}
diff --git a/src/modules/module-tunnel-sink-symdef.h b/src/modules/module-tunnel-sink-symdef.h
deleted file mode 100644 (file)
index 875b4ba..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduletunnelsinksymdeffoo
-#define foomoduletunnelsinksymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_tunnel_sink_LTX_pa__init
-#define pa__done module_tunnel_sink_LTX_pa__done
-#define pa__get_author module_tunnel_sink_LTX_pa__get_author
-#define pa__get_description module_tunnel_sink_LTX_pa__get_description
-#define pa__get_usage module_tunnel_sink_LTX_pa__get_usage
-#define pa__get_version module_tunnel_sink_LTX_pa__get_version
-#define pa__get_deprecated module_tunnel_sink_LTX_pa__get_deprecated
-#define pa__load_once module_tunnel_sink_LTX_pa__load_once
-#define pa__get_n_used module_tunnel_sink_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
diff --git a/src/modules/module-tunnel-source-symdef.h b/src/modules/module-tunnel-source-symdef.h
deleted file mode 100644 (file)
index 1d273cf..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduletunnelsourcesymdeffoo
-#define foomoduletunnelsourcesymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_tunnel_source_LTX_pa__init
-#define pa__done module_tunnel_source_LTX_pa__done
-#define pa__get_author module_tunnel_source_LTX_pa__get_author
-#define pa__get_description module_tunnel_source_LTX_pa__get_description
-#define pa__get_usage module_tunnel_source_LTX_pa__get_usage
-#define pa__get_version module_tunnel_source_LTX_pa__get_version
-#define pa__get_deprecated module_tunnel_source_LTX_pa__get_deprecated
-#define pa__load_once module_tunnel_source_LTX_pa__load_once
-#define pa__get_n_used module_tunnel_source_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index c97de3a..66b9617 100644 (file)
 #include <pulsecore/modargs.h>
 #include <pulsecore/log.h>
 #include <pulsecore/core-subscribe.h>
-#include <pulsecore/sink-input.h>
 #include <pulsecore/pdispatch.h>
 #include <pulsecore/pstream.h>
 #include <pulsecore/pstream-util.h>
 #include <pulsecore/socket-client.h>
-#include <pulsecore/socket-util.h>
 #include <pulsecore/time-smoother.h>
 #include <pulsecore/thread.h>
 #include <pulsecore/thread-mq.h>
@@ -379,7 +377,7 @@ static void command_stream_buffer_attr_changed(pa_pdispatch *pd, uint32_t comman
 
 /* Called from main context */
 static void command_started(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
-   struct userdata *u = userdata;
+    struct userdata *u = userdata;
 
     pa_assert(pd);
     pa_assert(t);
@@ -393,7 +391,7 @@ static void command_started(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa
 #endif
 
 /* Called from IO thread context */
-static void check_smoother_status(struct userdata *u, pa_bool_t past)  {
+static void check_smoother_status(struct userdata *u, pa_bool_t past) {
     pa_usec_t x;
 
     pa_assert(u);
@@ -487,7 +485,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
         case PA_SINK_MESSAGE_SET_STATE: {
             int r;
 
-            /* First, change the state, because otherwide pa_sink_render() would fail */
+            /* First, change the state, because otherwise pa_sink_render() would fail */
             if ((r = pa_sink_process_msg(o, code, data, offset, chunk)) >= 0) {
 
                 stream_cork_within_thread(u, u->sink->state == PA_SINK_SUSPENDED);
@@ -700,9 +698,8 @@ static void thread_func(void *userdata) {
         int ret;
 
 #ifdef TUNNEL_SINK
-        if (PA_SINK_IS_OPENED(u->sink->thread_info.state))
-            if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
-                pa_sink_process_rewind(u->sink, 0);
+        if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
+            pa_sink_process_rewind(u->sink, 0);
 #endif
 
         if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
@@ -973,8 +970,7 @@ static void server_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag, pa
         pa_tagstruct_gets(t, &default_sink_name) < 0 ||
         pa_tagstruct_gets(t, &default_source_name) < 0 ||
         pa_tagstruct_getu32(t, &cookie) < 0 ||
-        (u->version >= 15 &&
-         pa_tagstruct_get_channel_map(t, &cm) < 0)) {
+        (u->version >= 15 && pa_tagstruct_get_channel_map(t, &cm) < 0)) {
 
         pa_log("Parse failure");
         goto fail;
@@ -999,6 +995,63 @@ fail:
     pa_module_unload_request(u->module, TRUE);
 }
 
+static int read_ports(struct userdata *u, pa_tagstruct *t)
+{
+    if (u->version >= 16) {
+        uint32_t n_ports;
+        const char *s;
+
+        if (pa_tagstruct_getu32(t, &n_ports)) {
+            pa_log("Parse failure");
+            return -PA_ERR_PROTOCOL;
+        }
+
+        for (uint32_t j = 0; j < n_ports; j++) {
+            uint32_t priority;
+
+            if (pa_tagstruct_gets(t, &s) < 0 || /* name */
+                pa_tagstruct_gets(t, &s) < 0 || /* description */
+                pa_tagstruct_getu32(t, &priority) < 0) {
+
+                pa_log("Parse failure");
+                return -PA_ERR_PROTOCOL;
+            }
+            if (u->version >= 24 && pa_tagstruct_getu32(t, &priority) < 0) { /* available */
+                pa_log("Parse failure");
+                return -PA_ERR_PROTOCOL;
+            }
+        }
+
+        if (pa_tagstruct_gets(t, &s) < 0) { /* active port */
+            pa_log("Parse failure");
+            return -PA_ERR_PROTOCOL;
+        }
+    }
+    return 0;
+}
+
+
+static int read_formats(struct userdata *u, pa_tagstruct *t) {
+    uint8_t n_formats;
+    pa_format_info *format;
+
+    if (pa_tagstruct_getu8(t, &n_formats) < 0) { /* no. of formats */
+        pa_log("Parse failure");
+        return -PA_ERR_PROTOCOL;
+    }
+
+    for (uint8_t j = 0; j < n_formats; j++) {
+        format = pa_format_info_new();
+        if (pa_tagstruct_get_format_info(t, format)) { /* format info */
+            pa_format_info_free(format);
+            pa_log("Parse failure");
+            return -PA_ERR_PROTOCOL;
+        }
+        pa_format_info_free(format);
+    }
+    return 0;
+}
+
 #ifdef TUNNEL_SINK
 
 /* Called from main context */
@@ -1011,13 +1064,10 @@ static void sink_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag, pa_t
     pa_cvolume volume;
     pa_bool_t mute;
     pa_usec_t latency;
-    pa_proplist *pl;
 
     pa_assert(pd);
     pa_assert(u);
 
-    pl = pa_proplist_new();
-
     if (command != PA_COMMAND_REPLY) {
         if (command == PA_COMMAND_ERROR)
             pa_log("Failed to get info.");
@@ -1047,7 +1097,7 @@ static void sink_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag, pa_t
     if (u->version >= 13) {
         pa_usec_t configured_latency;
 
-        if (pa_tagstruct_get_proplist(t, pl) < 0 ||
+        if (pa_tagstruct_get_proplist(t, NULL) < 0 ||
             pa_tagstruct_get_usec(t, &configured_latency) < 0) {
 
             pa_log("Parse failure");
@@ -1069,41 +1119,18 @@ static void sink_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag, pa_t
         }
     }
 
-    if (u->version >= 16) {
-        uint32_t n_ports;
-        const char *s;
-
-        if (pa_tagstruct_getu32(t, &n_ports)) {
-            pa_log("Parse failure");
-            goto fail;
-        }
-
-        for (uint32_t j = 0; j < n_ports; j++) {
-            uint32_t priority;
-
-            if (pa_tagstruct_gets(t, &s) < 0 || /* name */
-                pa_tagstruct_gets(t, &s) < 0 || /* description */
-                pa_tagstruct_getu32(t, &priority) < 0) {
-
-                pa_log("Parse failure");
-                goto fail;
-            }
-        }
+    if (read_ports(u, t) < 0)
+        goto fail;
 
-        if (pa_tagstruct_gets(t, &s) < 0) { /* active port */
-            pa_log("Parse failure");
-            goto fail;
-        }
-    }
+    if (u->version >= 21 && read_formats(u, t) < 0)
+        goto fail;
 
     if (!pa_tagstruct_eof(t)) {
         pa_log("Packet too long");
         goto fail;
     }
 
-    pa_proplist_free(pl);
-
-    if (!u->sink_name || strcmp(name, u->sink_name))
+    if (!u->sink_name || !pa_streq(name, u->sink_name))
         return;
 
     pa_xfree(u->device_description);
@@ -1115,7 +1142,6 @@ static void sink_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag, pa_t
 
 fail:
     pa_module_unload_request(u->module, TRUE);
-    pa_proplist_free(pl);
 }
 
 /* Called from main context */
@@ -1128,13 +1154,11 @@ static void sink_input_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
     pa_cvolume volume;
-    pa_proplist *pl;
+    pa_bool_t b;
 
     pa_assert(pd);
     pa_assert(u);
 
-    pl = pa_proplist_new();
-
     if (command != PA_COMMAND_REPLY) {
         if (command == PA_COMMAND_ERROR)
             pa_log("Failed to get info.");
@@ -1169,11 +1193,39 @@ static void sink_input_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag
     }
 
     if (u->version >= 13) {
-        if (pa_tagstruct_get_proplist(t, pl) < 0) {
+        if (pa_tagstruct_get_proplist(t, NULL) < 0) {
+
+            pa_log("Parse failure");
+            goto fail;
+        }
+    }
+
+    if (u->version >= 19) {
+        if (pa_tagstruct_get_boolean(t, &b) < 0) {
+
+            pa_log("Parse failure");
+            goto fail;
+        }
+    }
+
+    if (u->version >= 20) {
+        if (pa_tagstruct_get_boolean(t, &b) < 0 ||
+            pa_tagstruct_get_boolean(t, &b) < 0) {
+
+            pa_log("Parse failure");
+            goto fail;
+        }
+    }
+
+    if (u->version >= 21) {
+        pa_format_info *format = pa_format_info_new();
 
+        if (pa_tagstruct_get_format_info(t, format) < 0) {
+            pa_format_info_free(format);
             pa_log("Parse failure");
             goto fail;
         }
+        pa_format_info_free(format);
     }
 
     if (!pa_tagstruct_eof(t)) {
@@ -1181,8 +1233,6 @@ static void sink_input_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag
         goto fail;
     }
 
-    pa_proplist_free(pl);
-
     if (idx != u->device_index)
         return;
 
@@ -1201,7 +1251,6 @@ static void sink_input_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag
 
 fail:
     pa_module_unload_request(u->module, TRUE);
-    pa_proplist_free(pl);
 }
 
 #else
@@ -1216,13 +1265,10 @@ static void source_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag, pa
     pa_cvolume volume;
     pa_bool_t mute;
     pa_usec_t latency, configured_latency;
-    pa_proplist *pl;
 
     pa_assert(pd);
     pa_assert(u);
 
-    pl = pa_proplist_new();
-
     if (command != PA_COMMAND_REPLY) {
         if (command == PA_COMMAND_ERROR)
             pa_log("Failed to get info.");
@@ -1250,7 +1296,7 @@ static void source_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag, pa
     }
 
     if (u->version >= 13) {
-        if (pa_tagstruct_get_proplist(t, pl) < 0 ||
+        if (pa_tagstruct_get_proplist(t, NULL) < 0 ||
             pa_tagstruct_get_usec(t, &configured_latency) < 0) {
 
             pa_log("Parse failure");
@@ -1272,41 +1318,18 @@ static void source_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag, pa
         }
     }
 
-    if (u->version >= 16) {
-        uint32_t n_ports;
-        const char *s;
-
-        if (pa_tagstruct_getu32(t, &n_ports)) {
-            pa_log("Parse failure");
-            goto fail;
-        }
-
-        for (uint32_t j = 0; j < n_ports; j++) {
-            uint32_t priority;
-
-            if (pa_tagstruct_gets(t, &s) < 0 || /* name */
-                pa_tagstruct_gets(t, &s) < 0 || /* description */
-                pa_tagstruct_getu32(t, &priority) < 0) {
-
-                pa_log("Parse failure");
-                goto fail;
-            }
-        }
+    if (read_ports(u, t) < 0)
+        goto fail;
 
-        if (pa_tagstruct_gets(t, &s) < 0) { /* active port */
-            pa_log("Parse failure");
-            goto fail;
-        }
-    }
+    if (u->version >= 22 && read_formats(u, t) < 0)
+        goto fail;
 
     if (!pa_tagstruct_eof(t)) {
         pa_log("Packet too long");
         goto fail;
     }
 
-    pa_proplist_free(pl);
-
-    if (!u->source_name || strcmp(name, u->source_name))
+    if (!u->source_name || !pa_streq(name, u->source_name))
         return;
 
     pa_xfree(u->device_description);
@@ -1318,7 +1341,6 @@ static void source_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag, pa
 
 fail:
     pa_module_unload_request(u->module, TRUE);
-    pa_proplist_free(pl);
 }
 
 #endif
@@ -1492,6 +1514,17 @@ static void create_stream_callback(pa_pdispatch *pd, uint32_t command,  uint32_t
 /* #endif */
     }
 
+    if (u->version >= 21) {
+        pa_format_info *format = pa_format_info_new();
+
+        if (pa_tagstruct_get_format_info(t, format) < 0) {
+            pa_format_info_free(format);
+            goto parse_error;
+        }
+
+        pa_format_info_free(format);
+    }
+
     if (!pa_tagstruct_eof(t))
         goto parse_error;
 
@@ -1524,9 +1557,7 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
     struct userdata *u = userdata;
     pa_tagstruct *reply;
     char name[256], un[128], hn[128];
-#ifdef TUNNEL_SINK
     pa_cvolume volume;
-#endif
 
     pa_assert(pd);
     pa_assert(u);
@@ -1686,6 +1717,33 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
         pa_tagstruct_put_boolean(reply, FALSE); /* fail on suspend */
     }
 
+#ifdef TUNNEL_SINK
+    if (u->version >= 17)
+        pa_tagstruct_put_boolean(reply, FALSE); /* relative volume */
+
+    if (u->version >= 18)
+        pa_tagstruct_put_boolean(reply, FALSE); /* passthrough stream */
+#endif
+
+#ifdef TUNNEL_SINK
+    if (u->version >= 21) {
+        /* We're not using the extended API, so n_formats = 0 and that's that */
+        pa_tagstruct_putu8(reply, 0);
+    }
+#else
+    if (u->version >= 22) {
+        /* We're not using the extended API, so n_formats = 0 and that's that */
+        pa_tagstruct_putu8(reply, 0);
+        pa_cvolume_reset(&volume, u->source->sample_spec.channels);
+        pa_tagstruct_put_cvolume(reply, &volume);
+        pa_tagstruct_put_boolean(reply, FALSE); /* muted */
+        pa_tagstruct_put_boolean(reply, FALSE); /* volume_set */
+        pa_tagstruct_put_boolean(reply, FALSE); /* muted_set */
+        pa_tagstruct_put_boolean(reply, FALSE); /* relative volume */
+        pa_tagstruct_put_boolean(reply, FALSE); /* passthrough stream */
+    }
+#endif
+
     pa_pstream_send_tagstruct(u->pstream, reply);
     pa_pdispatch_register_reply(u->pdispatch, tag, DEFAULT_TIMEOUT, create_stream_callback, u, NULL);
 
@@ -1767,9 +1825,9 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata
     u->pdispatch = pa_pdispatch_new(u->core->mainloop, TRUE, command_table, PA_COMMAND_MAX);
 
     pa_pstream_set_die_callback(u->pstream, pstream_die_callback, u);
-    pa_pstream_set_recieve_packet_callback(u->pstream, pstream_packet_callback, u);
+    pa_pstream_set_receive_packet_callback(u->pstream, pstream_packet_callback, u);
 #ifndef TUNNEL_SINK
-    pa_pstream_set_recieve_memblock_callback(u->pstream, pstream_memblock_callback, u);
+    pa_pstream_set_receive_memblock_callback(u->pstream, pstream_memblock_callback, u);
 #endif
 
     t = pa_tagstruct_new(NULL, 0);
@@ -1894,7 +1952,7 @@ int pa__init(pa_module*m) {
     u->rtpoll = pa_rtpoll_new();
     pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
 
-    if (!(u->auth_cookie = pa_auth_cookie_get(u->core, pa_modargs_get_value(ma, "cookie", PA_NATIVE_COOKIE_FILE), PA_NATIVE_COOKIE_LENGTH)))
+    if (!(u->auth_cookie = pa_auth_cookie_get(u->core, pa_modargs_get_value(ma, "cookie", PA_NATIVE_COOKIE_FILE), TRUE, PA_NATIVE_COOKIE_LENGTH)))
         goto fail;
 
     if (!(u->server_name = pa_xstrdup(pa_modargs_get_value(ma, "server", NULL)))) {
@@ -1919,7 +1977,7 @@ int pa__init(pa_module*m) {
 #ifdef TUNNEL_SINK
 
     if (!(dn = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", NULL))))
-        dn = pa_sprintf_malloc("tunnel.%s", u->server_name);
+        dn = pa_sprintf_malloc("tunnel-sink.%s", u->server_name);
 
     pa_sink_new_data_init(&data);
     data.driver = __FILE__;
@@ -1939,7 +1997,7 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
-    u->sink = pa_sink_new(m->core, &data, PA_SINK_NETWORK|PA_SINK_LATENCY|PA_SINK_HW_VOLUME_CTRL|PA_SINK_HW_MUTE_CTRL);
+    u->sink = pa_sink_new(m->core, &data, PA_SINK_NETWORK|PA_SINK_LATENCY);
     pa_sink_new_data_done(&data);
 
     if (!u->sink) {
@@ -1950,8 +2008,8 @@ int pa__init(pa_module*m) {
     u->sink->parent.process_msg = sink_process_msg;
     u->sink->userdata = u;
     u->sink->set_state = sink_set_state;
-    u->sink->set_volume = sink_set_volume;
-    u->sink->set_mute = sink_set_mute;
+    pa_sink_set_set_volume_callback(u->sink, sink_set_volume);
+    pa_sink_set_set_mute_callback(u->sink, sink_set_mute);
 
     u->sink->refresh_volume = u->sink->refresh_muted = FALSE;
 
@@ -1963,7 +2021,7 @@ int pa__init(pa_module*m) {
 #else
 
     if (!(dn = pa_xstrdup(pa_modargs_get_value(ma, "source_name", NULL))))
-        dn = pa_sprintf_malloc("tunnel.%s", u->server_name);
+        dn = pa_sprintf_malloc("tunnel-source.%s", u->server_name);
 
     pa_source_new_data_init(&data);
     data.driver = __FILE__;
@@ -2014,7 +2072,7 @@ int pa__init(pa_module*m) {
     u->fragsize = (uint32_t) -1;
 #endif
 
-    if (!(u->thread = pa_thread_new(thread_func, u))) {
+    if (!(u->thread = pa_thread_new("module-tunnel", thread_func, u))) {
         pa_log("Failed to create thread.");
         goto fail;
     }
@@ -2037,7 +2095,7 @@ fail:
 
     pa_xfree(dn);
 
-    return  -1;
+    return -1;
 }
 
 void pa__done(pa_module*m) {
diff --git a/src/modules/module-udev-detect-symdef.h b/src/modules/module-udev-detect-symdef.h
deleted file mode 100644 (file)
index 6912e0f..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleudevdetectsymdeffoo
-#define foomoduleudevdetectsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_udev_detect_LTX_pa__init
-#define pa__done module_udev_detect_LTX_pa__done
-#define pa__get_author module_udev_detect_LTX_pa__get_author
-#define pa__get_description module_udev_detect_LTX_pa__get_description
-#define pa__get_usage module_udev_detect_LTX_pa__get_usage
-#define pa__get_version module_udev_detect_LTX_pa__get_version
-#define pa__get_deprecated module_udev_detect_LTX_pa__get_deprecated
-#define pa__load_once module_udev_detect_LTX_pa__load_once
-#define pa__get_n_used module_udev_detect_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 1b1e9c1..03a7920 100644 (file)
@@ -36,6 +36,7 @@
 #include <pulsecore/core-util.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/ratelimit.h>
+#include <pulsecore/strbuf.h>
 
 #include "module-udev-detect-symdef.h"
 
@@ -45,7 +46,11 @@ PA_MODULE_VERSION(PACKAGE_VERSION);
 PA_MODULE_LOAD_ONCE(TRUE);
 PA_MODULE_USAGE(
         "tsched=<enable system timer based scheduling mode?> "
-        "ignore_dB=<ignore dB information from the device?>");
+        "tsched_buffer_size=<buffer size when using timer based scheduling> "
+        "fixed_latency_range=<disable latency range changes on underrun?> "
+        "ignore_dB=<ignore dB information from the device?> "
+        "deferred_volume=<syncronize sw and hw volume changes in IO-thread?> "
+        "use_ucm=<use ALSA UCM for card configuration?>");
 
 struct device {
     char *path;
@@ -61,7 +66,13 @@ struct userdata {
     pa_hashmap *devices;
 
     pa_bool_t use_tsched:1;
+    bool tsched_buffer_size_valid:1;
+    pa_bool_t fixed_latency_range:1;
     pa_bool_t ignore_dB:1;
+    pa_bool_t deferred_volume:1;
+    bool use_ucm:1;
+
+    uint32_t tsched_buffer_size;
 
     struct udev* udev;
     struct udev_monitor *monitor;
@@ -73,7 +84,11 @@ struct userdata {
 
 static const char* const valid_modargs[] = {
     "tsched",
+    "tsched_buffer_size",
+    "fixed_latency_range",
     "ignore_dB",
+    "deferred_volume",
+    "use_ucm",
     NULL
 };
 
@@ -103,6 +118,63 @@ static const char *path_get_card_id(const char *path) {
     return e + 5;
 }
 
+static char *card_get_sysattr(const char *card_idx, const char *name) {
+    struct udev *udev;
+    struct udev_device *card = NULL;
+    char *t, *r = NULL;
+    const char *v;
+
+    pa_assert(card_idx);
+    pa_assert(name);
+
+    if (!(udev = udev_new())) {
+        pa_log_error("Failed to allocate udev context.");
+        goto finish;
+    }
+
+    t = pa_sprintf_malloc("/sys/class/sound/card%s", card_idx);
+    card = udev_device_new_from_syspath(udev, t);
+    pa_xfree(t);
+
+    if (!card) {
+        pa_log_error("Failed to get card object.");
+        goto finish;
+    }
+
+    if ((v = udev_device_get_sysattr_value(card, name)) && *v)
+        r = pa_xstrdup(v);
+
+finish:
+
+    if (card)
+        udev_device_unref(card);
+
+    if (udev)
+        udev_unref(udev);
+
+    return r;
+}
+
+static pa_bool_t pcm_is_modem(const char *card_idx, const char *pcm) {
+    char *sysfs_path, *pcm_class;
+    pa_bool_t is_modem;
+
+    pa_assert(card_idx);
+    pa_assert(pcm);
+
+    /* Check /sys/class/sound/card.../pcmC...../pcm_class. An HDA
+     * modem can be used simultaneously with generic
+     * playback/record. */
+
+    sysfs_path = pa_sprintf_malloc("pcmC%sD%s/pcm_class", card_idx, pcm);
+    pcm_class = card_get_sysattr(card_idx, sysfs_path);
+    is_modem = pcm_class && pa_streq(pcm_class, "modem");
+    pa_xfree(pcm_class);
+    pa_xfree(sysfs_path);
+
+    return is_modem;
+}
+
 static pa_bool_t is_card_busy(const char *id) {
     char *card_path = NULL, *pcm_path = NULL, *sub_status = NULL;
     DIR *card_dir = NULL, *pcm_dir = NULL;
@@ -141,6 +213,9 @@ static pa_bool_t is_card_busy(const char *id) {
         if (!pa_startswith(de->d_name, "pcm"))
             continue;
 
+        if (pcm_is_modem(id, de->d_name + 3))
+            continue;
+
         pa_xfree(pcm_path);
         pcm_path = pa_sprintf_malloc("%s/%s", card_path, de->d_name);
 
@@ -172,7 +247,7 @@ static pa_bool_t is_card_busy(const char *id) {
             if (status_file)
                 fclose(status_file);
 
-            if (!(status_file = fopen(sub_status, "r"))) {
+            if (!(status_file = pa_fopen_cloexec(sub_status, "r"))) {
                 pa_log_warn("Failed to open %s: %s", sub_status, pa_cstrerror(errno));
                 continue;
             }
@@ -216,7 +291,7 @@ static void verify_access(struct userdata *u, struct device *d) {
     pa_assert(u);
     pa_assert(d);
 
-    cd = pa_sprintf_malloc("%s/snd/controlC%s", udev_get_dev_path(u->udev), path_get_card_id(d->path));
+    cd = pa_sprintf_malloc("/dev/snd/controlC%s", path_get_card_id(d->path));
     accessible = access(cd, R_OK|W_OK) >= 0;
     pa_log_debug("%s is accessible: %s", cd, pa_yes_no(accessible));
 
@@ -255,13 +330,13 @@ static void verify_access(struct userdata *u, struct device *d) {
                  * A clean fix would be if we would be able to ignore
                  * our own inotify close events. However, inotify
                  * lacks such functionality. Also, during probing of
-                 * the device we cannot really distuingish between
+                 * the device we cannot really distinguish between
                  * other processes causing EBUSY or ourselves, which
                  * means we have no way to figure out if the probing
                  * during opening was canceled by a "try again"
                  * failure or a "fatal" failure. */
 
-                if (pa_ratelimit_test(&d->ratelimit)) {
+                if (pa_ratelimit_test(&d->ratelimit, PA_LOG_DEBUG)) {
                     pa_log_debug("Loading module-alsa-card with arguments '%s'", d->args);
                     m = pa_module_load(u->core, "module-alsa-card", d->args);
 
@@ -284,8 +359,10 @@ static void verify_access(struct userdata *u, struct device *d) {
         /* If we are already loaded update suspend status with
          * accessible boolean */
 
-        if ((card = pa_namereg_get(u->core, d->card_name, PA_NAMEREG_CARD)))
+        if ((card = pa_namereg_get(u->core, d->card_name, PA_NAMEREG_CARD))) {
+            pa_log_debug("%s all sinks and sources of card %s.", accessible ? "Resuming" : "Suspending", d->card_name);
             pa_card_suspend(card, !accessible, PA_SUSPEND_SESSION);
+        }
     }
 }
 
@@ -294,6 +371,7 @@ static void card_changed(struct userdata *u, struct udev_device *dev) {
     const char *path;
     const char *t;
     char *n;
+    pa_strbuf *args_buf;
 
     pa_assert(u);
     pa_assert(dev);
@@ -320,19 +398,33 @@ static void card_changed(struct userdata *u, struct udev_device *dev) {
 
     n = pa_namereg_make_valid_name(t);
     d->card_name = pa_sprintf_malloc("alsa_card.%s", n);
-    d->args = pa_sprintf_malloc("device_id=\"%s\" "
-                                "name=\"%s\" "
-                                "card_name=\"%s\" "
-                                "tsched=%s "
-                                "ignore_dB=%s "
-                                "card_properties=\"module-udev-detect.discovered=1\"",
-                                path_get_card_id(path),
-                                n,
-                                d->card_name,
-                                pa_yes_no(u->use_tsched),
-                                pa_yes_no(u->ignore_dB));
+    args_buf = pa_strbuf_new();
+    pa_strbuf_printf(args_buf,
+                     "device_id=\"%s\" "
+                     "name=\"%s\" "
+                     "card_name=\"%s\" "
+                     "namereg_fail=false "
+                     "tsched=%s "
+                     "fixed_latency_range=%s "
+                     "ignore_dB=%s "
+                     "deferred_volume=%s "
+                     "use_ucm=%s "
+                     "card_properties=\"module-udev-detect.discovered=1\"",
+                     path_get_card_id(path),
+                     n,
+                     d->card_name,
+                     pa_yes_no(u->use_tsched),
+                     pa_yes_no(u->fixed_latency_range),
+                     pa_yes_no(u->ignore_dB),
+                     pa_yes_no(u->deferred_volume),
+                     pa_yes_no(u->use_ucm));
     pa_xfree(n);
 
+    if (u->tsched_buffer_size_valid)
+        pa_strbuf_printf(args_buf, " tsched_buffer_size=%" PRIu32, u->tsched_buffer_size);
+
+    d->args = pa_strbuf_tostring_free(args_buf);
+
     pa_hashmap_put(u->devices, d->path, d);
 
     verify_access(u, d);
@@ -355,8 +447,14 @@ static void remove_card(struct userdata *u, struct udev_device *dev) {
     device_free(d);
 }
 
+#define STR_USB "usb"
+#define STR_SOUND "sound"
+
 static void process_device(struct userdata *u, struct udev_device *dev) {
     const char *action, *ff;
+    char *str_parent_subsystem = NULL;
+    char *str_tmp = NULL;
+    pa_bool_t skip = false;
 
     pa_assert(u);
     pa_assert(dev);
@@ -366,18 +464,44 @@ static void process_device(struct userdata *u, struct udev_device *dev) {
         return;
     }
 
-    if ((ff = udev_device_get_property_value(dev, "SOUND_FORM_FACTOR")) &&
+    if ((ff = udev_device_get_property_value(dev, "SOUND_CLASS")) &&
         pa_streq(ff, "modem")) {
         pa_log_debug("Ignoring %s, because it is a modem.", udev_device_get_devpath(dev));
         return;
     }
 
+    pa_log_info ("devpath = %s", udev_device_get_devpath(dev));
+    pa_log_debug ("subsystem = %s", udev_device_get_subsystem(dev));
+    pa_log_debug ("devtype = %s", udev_device_get_devtype(dev));
+    pa_log_info ("syspath = %s", udev_device_get_syspath(dev));
+    pa_log_debug ("sysname = %s", udev_device_get_sysname(dev));
+    pa_log_debug ("sysnum = %s", udev_device_get_sysnum(dev));
+    pa_log_debug ("devnode = %s", udev_device_get_devnode(dev));
+    str_parent_subsystem = udev_device_get_subsystem(udev_device_get_parent(dev));
+    pa_log_info ("parent subsystem = %s", str_parent_subsystem);
+
+    /* NOTE: Only USB audio is handled for now,
+     *       If parent's subsystem doesn't exist or exist but not USB, skip handle it */
+    if (str_parent_subsystem) {
+        skip = (!pa_streq(str_parent_subsystem, STR_USB));
+    } else {
+        str_tmp = udev_device_get_devpath(dev);
+        skip = (str_tmp != NULL && ((!strstr (str_tmp, STR_USB)) || (!strstr (str_tmp, STR_SOUND))));
+
+        str_tmp = udev_device_get_syspath(dev);
+        skip = (str_tmp != NULL && ((!strstr (str_tmp, STR_USB)) || (!strstr (str_tmp, STR_SOUND))));
+    }
+
+    if (skip) {
+        pa_log_warn("Ignoring %s, this might not be USB SOUND.", udev_device_get_devpath(dev));
+        return;
+    }
+
     action = udev_device_get_action(dev);
 
     if (action && pa_streq(action, "remove"))
         remove_card(u, dev);
-    else if ((!action || pa_streq(action, "change")) &&
-             udev_device_get_property_value(dev, "SOUND_INITIALIZED"))
+    else if ((!action || pa_streq(action, "change")) && udev_device_get_property_value(dev, "SOUND_INITIALIZED"))
         card_changed(u, dev);
 
     /* For an explanation why we don't look for 'add' events here
@@ -416,8 +540,10 @@ static void monitor_cb(
         goto fail;
     }
 
-    if (!path_get_card_id(udev_device_get_devpath(dev)))
+    if (!path_get_card_id(udev_device_get_devpath(dev))) {
+        udev_device_unref(dev);
         return;
+    }
 
     process_device(u, dev);
     udev_device_unref(dev);
@@ -549,7 +675,6 @@ fail:
 }
 
 static int setup_inotify(struct userdata *u) {
-    char *dev_snd;
     int r;
 
     if (u->inotify_fd >= 0)
@@ -560,9 +685,7 @@ static int setup_inotify(struct userdata *u) {
         return -1;
     }
 
-    dev_snd = pa_sprintf_malloc("%s/snd", udev_get_dev_path(u->udev));
-    r = inotify_add_watch(u->inotify_fd, dev_snd, IN_ATTRIB|IN_CLOSE_WRITE|IN_DELETE_SELF|IN_MOVE_SELF);
-    pa_xfree(dev_snd);
+    r = inotify_add_watch(u->inotify_fd, "/dev/snd", IN_ATTRIB|IN_CLOSE_WRITE|IN_DELETE_SELF|IN_MOVE_SELF);
 
     if (r < 0) {
         int saved_errno = errno;
@@ -598,7 +721,8 @@ int pa__init(pa_module *m) {
     struct udev_enumerate *enumerate = NULL;
     struct udev_list_entry *item = NULL, *first = NULL;
     int fd;
-    pa_bool_t use_tsched = TRUE, ignore_dB = FALSE;
+    pa_bool_t use_tsched = TRUE, fixed_latency_range = FALSE, ignore_dB = FALSE, deferred_volume = m->core->deferred_volume;
+    bool use_ucm = true;
 
     pa_assert(m);
 
@@ -618,12 +742,39 @@ int pa__init(pa_module *m) {
     }
     u->use_tsched = use_tsched;
 
+    if (pa_modargs_get_value(ma, "tsched_buffer_size", NULL)) {
+        if (pa_modargs_get_value_u32(ma, "tsched_buffer_size", &u->tsched_buffer_size) < 0) {
+            pa_log("Failed to parse tsched_buffer_size= argument.");
+            goto fail;
+        }
+
+        u->tsched_buffer_size_valid = true;
+    }
+
+    if (pa_modargs_get_value_boolean(ma, "fixed_latency_range", &fixed_latency_range) < 0) {
+        pa_log("Failed to parse fixed_latency_range= argument.");
+        goto fail;
+    }
+    u->fixed_latency_range = fixed_latency_range;
+
     if (pa_modargs_get_value_boolean(ma, "ignore_dB", &ignore_dB) < 0) {
         pa_log("Failed to parse ignore_dB= argument.");
         goto fail;
     }
     u->ignore_dB = ignore_dB;
 
+    if (pa_modargs_get_value_boolean(ma, "deferred_volume", &deferred_volume) < 0) {
+        pa_log("Failed to parse deferred_volume= argument.");
+        goto fail;
+    }
+    u->deferred_volume = deferred_volume;
+
+    if (pa_modargs_get_value_boolean(ma, "use_ucm", &use_ucm) < 0) {
+        pa_log("Failed to parse use_ucm= argument.");
+        goto fail;
+    }
+    u->use_ucm = use_ucm;
+
     if (!(u->udev = udev_new())) {
         pa_log("Failed to initialize udev library.");
         goto fail;
@@ -637,12 +788,17 @@ int pa__init(pa_module *m) {
         goto fail;
     }
 
+    if (udev_monitor_filter_add_match_subsystem_devtype(u->monitor, "sound", NULL) < 0) {
+        pa_log("Failed to subscribe to sound devices.");
+        goto fail;
+    }
+
     errno = 0;
     if (udev_monitor_enable_receiving(u->monitor) < 0) {
         pa_log("Failed to enable monitor: %s", pa_cstrerror(errno));
         if (errno == EPERM)
             pa_log_info("Most likely your kernel is simply too old and "
-                        "allows only priviliged processes to listen to device events. "
+                        "allows only privileged processes to listen to device events. "
                         "Please upgrade your kernel to at least 2.6.30.");
         goto fail;
     }
@@ -717,14 +873,8 @@ void pa__done(pa_module *m) {
     if (u->inotify_fd >= 0)
         pa_close(u->inotify_fd);
 
-    if (u->devices) {
-        struct device *d;
-
-        while ((d = pa_hashmap_steal_first(u->devices)))
-            device_free(d);
-
-        pa_hashmap_free(u->devices, NULL, NULL);
-    }
+    if (u->devices)
+        pa_hashmap_free(u->devices, (pa_free_cb_t) device_free);
 
     pa_xfree(u);
 }
diff --git a/src/modules/module-virtual-sink-symdef.h b/src/modules/module-virtual-sink-symdef.h
deleted file mode 100644 (file)
index 139106f..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulevirtualsinksymdeffoo
-#define foomodulevirtualsinksymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_virtual_sink_LTX_pa__init
-#define pa__done module_virtual_sink_LTX_pa__done
-#define pa__get_author module_virtual_sink_LTX_pa__get_author
-#define pa__get_description module_virtual_sink_LTX_pa__get_description
-#define pa__get_usage module_virtual_sink_LTX_pa__get_usage
-#define pa__get_version module_virtual_sink_LTX_pa__get_version
-#define pa__get_deprecated module_virtual_sink_LTX_pa__get_deprecated
-#define pa__load_once module_virtual_sink_LTX_pa__load_once
-#define pa__get_n_used module_virtual_sink_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index fac204d..4f91fe0 100644 (file)
     USA.
 ***/
 
-/* TODO: Some plugins cause latency, and some even report it by using a control
-   out port. We don't currently use the latency information. */
-
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
+#include <pulse/gccmacro.h>
 #include <pulse/xmalloc.h>
-#include <pulse/i18n.h>
 
-#include <pulsecore/core-error.h>
+#include <pulsecore/i18n.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/sink.h>
 #include <pulsecore/module.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/log.h>
-#include <pulsecore/thread.h>
-#include <pulsecore/thread-mq.h>
 #include <pulsecore/rtpoll.h>
 #include <pulsecore/sample-util.h>
 #include <pulsecore/ltdl-helper.h>
@@ -53,10 +48,11 @@ PA_MODULE_USAGE(
         _("sink_name=<name for the sink> "
           "sink_properties=<properties for the sink> "
           "master=<name of sink to filter> "
-          "format=<sample format> "
           "rate=<sample rate> "
           "channels=<number of channels> "
           "channel_map=<channel map> "
+          "use_volume_sharing=<yes or no> "
+          "force_flat_volume=<yes or no> "
         ));
 
 #define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
@@ -64,6 +60,9 @@ PA_MODULE_USAGE(
 struct userdata {
     pa_module *module;
 
+    /* FIXME: Uncomment this and take "autoloaded" as a modarg if this is a filter */
+    /* pa_bool_t autoloaded; */
+
     pa_sink *sink;
     pa_sink_input *sink_input;
 
@@ -77,10 +76,11 @@ static const char* const valid_modargs[] = {
     "sink_name",
     "sink_properties",
     "master",
-    "format",
     "rate",
     "channels",
     "channel_map",
+    "use_volume_sharing",
+    "force_flat_volume",
     NULL
 };
 
@@ -199,7 +199,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
     size_t fs;
     unsigned n, c;
     pa_memchunk tchunk;
-    pa_usec_t current_latency;
+    pa_usec_t current_latency PA_GCC_UNUSED;
 
     pa_sink_input_assert_ref(i);
     pa_assert(chunk);
@@ -236,8 +236,8 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
 
     pa_memblockq_drop(u->memblockq, chunk->length);
 
-    src = (float*) ((uint8_t*) pa_memblock_acquire(tchunk.memblock) + tchunk.index);
-    dst = (float*) pa_memblock_acquire(chunk->memblock);
+    src = pa_memblock_acquire_chunk(&tchunk);
+    dst = pa_memblock_acquire(chunk->memblock);
 
     /* (3) PUT YOUR CODE HERE TO DO SOMETHING WITH THE DATA */
 
@@ -298,6 +298,8 @@ static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
     pa_sink_input_assert_ref(i);
     pa_assert_se(u = i->userdata);
 
+    /* FIXME: Too small max_rewind:
+     * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
     pa_memblockq_set_maxrewind(u->memblockq, nbytes);
     pa_sink_set_max_rewind_within_thread(u->sink, nbytes);
 }
@@ -369,6 +371,9 @@ static void sink_input_attach_cb(pa_sink_input *i) {
      * pa_sink_input_get_max_request(i) UP TO MULTIPLES OF IT
      * HERE. SEE (6) */
     pa_sink_set_max_request_within_thread(u->sink, pa_sink_input_get_max_request(i));
+
+    /* FIXME: Too small max_rewind:
+     * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
     pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i));
 
     pa_sink_attach_within_thread(u->sink);
@@ -413,16 +418,6 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s
 }
 
 /* Called from main context */
-static pa_bool_t sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
-    struct userdata *u;
-
-    pa_sink_input_assert_ref(i);
-    pa_assert_se(u = i->userdata);
-
-    return u->sink != dest;
-}
-
-/* Called from main context */
 static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
     struct userdata *u;
 
@@ -477,7 +472,9 @@ int pa__init(pa_module*m) {
     pa_sink *master=NULL;
     pa_sink_input_new_data sink_input_data;
     pa_sink_new_data sink_data;
-    pa_bool_t *use_default = NULL;
+    pa_bool_t use_volume_sharing = TRUE;
+    pa_bool_t force_flat_volume = FALSE;
+    pa_memchunk silence;
 
     pa_assert(m);
 
@@ -501,6 +498,21 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
+    if (pa_modargs_get_value_boolean(ma, "use_volume_sharing", &use_volume_sharing) < 0) {
+        pa_log("use_volume_sharing= expects a boolean argument");
+        goto fail;
+    }
+
+    if (pa_modargs_get_value_boolean(ma, "force_flat_volume", &force_flat_volume) < 0) {
+        pa_log("force_flat_volume= expects a boolean argument");
+        goto fail;
+    }
+
+    if (use_volume_sharing && force_flat_volume) {
+        pa_log("Flat volume can't be forced when using volume sharing.");
+        goto fail;
+    }
+
     u = pa_xnew0(struct userdata, 1);
     u->module = m;
     m->userdata = u;
@@ -531,9 +543,8 @@ int pa__init(pa_module*m) {
         pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Virtual Sink %s on %s", sink_data.name, z ? z : master->name);
     }
 
-    u->sink = pa_sink_new(m->core, &sink_data,
-                          PA_SINK_HW_MUTE_CTRL|PA_SINK_HW_VOLUME_CTRL|PA_SINK_DECIBEL_VOLUME|
-                          (master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY)));
+    u->sink = pa_sink_new(m->core, &sink_data, (master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY))
+                                               | (use_volume_sharing ? PA_SINK_SHARE_VOLUME_WITH_MASTER : 0));
     pa_sink_new_data_done(&sink_data);
 
     if (!u->sink) {
@@ -545,8 +556,14 @@ int pa__init(pa_module*m) {
     u->sink->set_state = sink_set_state_cb;
     u->sink->update_requested_latency = sink_update_requested_latency_cb;
     u->sink->request_rewind = sink_request_rewind_cb;
-    u->sink->set_volume = sink_set_volume_cb;
-    u->sink->set_mute = sink_set_mute_cb;
+    pa_sink_set_set_mute_callback(u->sink, sink_set_mute_cb);
+    if (!use_volume_sharing) {
+        pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
+        pa_sink_enable_decibel_volume(u->sink, TRUE);
+    }
+    /* Normally this flag would be enabled automatically be we can force it. */
+    if (force_flat_volume)
+        u->sink->flags |= PA_SINK_FLAT_VOLUME;
     u->sink->userdata = u;
 
     pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq);
@@ -555,8 +572,9 @@ int pa__init(pa_module*m) {
     pa_sink_input_new_data_init(&sink_input_data);
     sink_input_data.driver = __FILE__;
     sink_input_data.module = m;
-    sink_input_data.sink = master;
-    pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Sink Stream");
+    pa_sink_input_new_data_set_sink(&sink_input_data, master, FALSE);
+    sink_input_data.origin_sink = u->sink;
+    pa_proplist_setf(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Sink Stream from %s", pa_proplist_gets(u->sink->proplist, PA_PROP_DEVICE_DESCRIPTION));
     pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
     pa_sink_input_new_data_set_sample_spec(&sink_input_data, &ss);
     pa_sink_input_new_data_set_channel_map(&sink_input_data, &map);
@@ -577,34 +595,30 @@ int pa__init(pa_module*m) {
     u->sink_input->attach = sink_input_attach_cb;
     u->sink_input->detach = sink_input_detach_cb;
     u->sink_input->state_change = sink_input_state_change_cb;
-    u->sink_input->may_move_to = sink_input_may_move_to_cb;
     u->sink_input->moving = sink_input_moving_cb;
-    u->sink_input->volume_changed = sink_input_volume_changed_cb;
+    u->sink_input->volume_changed = use_volume_sharing ? NULL : sink_input_volume_changed_cb;
     u->sink_input->mute_changed = sink_input_mute_changed_cb;
     u->sink_input->userdata = u;
 
-    /* (9) IF YOU REQUIRE A FIXED BLOCK SIZE MAKE SURE TO PASS A
-     * SILENCE MEMBLOCK AS LAST PARAMETER
-     * HERE. pa_sink_input_get_silence() IS USEFUL HERE. */
-    u->memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, NULL);
+    u->sink->input_to_master = u->sink_input;
 
-    /* (10) INITIALIZE ANYTHING ELSE YOU NEED HERE */
+    pa_sink_input_get_silence(u->sink_input, &silence);
+    u->memblockq = pa_memblockq_new("module-virtual-sink memblockq", 0, MEMBLOCKQ_MAXLENGTH, 0, &ss, 1, 1, 0, &silence);
+    pa_memblock_unref(silence.memblock);
+
+    /* (9) INITIALIZE ANYTHING ELSE YOU NEED HERE */
 
     pa_sink_put(u->sink);
     pa_sink_input_put(u->sink_input);
 
     pa_modargs_free(ma);
 
-    pa_xfree(use_default);
-
     return 0;
 
- fail:
+fail:
     if (ma)
         pa_modargs_free(ma);
 
-    pa_xfree(use_default);
-
     pa__done(m);
 
     return -1;
diff --git a/src/modules/module-virtual-source-symdef.h b/src/modules/module-virtual-source-symdef.h
deleted file mode 100644 (file)
index 0a16ae5..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulevirtualsourcesymdeffoo
-#define foomodulevirtualsourcesymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_virtual_source_LTX_pa__init
-#define pa__done module_virtual_source_LTX_pa__done
-#define pa__get_author module_virtual_source_LTX_pa__get_author
-#define pa__get_description module_virtual_source_LTX_pa__get_description
-#define pa__get_usage module_virtual_source_LTX_pa__get_usage
-#define pa__get_version module_virtual_source_LTX_pa__get_version
-#define pa__get_deprecated module_virtual_source_LTX_pa__get_deprecated
-#define pa__load_once module_virtual_source_LTX_pa__load_once
-#define pa__get_n_used module_virtual_source_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index fdf89b0..58041e7 100644 (file)
 #endif
 
 #include <stdio.h>
-#include <math.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/i18n.h>
 
+#include <pulsecore/i18n.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/core-error.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/sink.h>
 #include <pulsecore/module.h>
-#include <pulsecore/core-rtclock.h>
 #include <pulsecore/core-util.h>
-#include <pulsecore/core-error.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/log.h>
-#include <pulsecore/thread.h>
-#include <pulsecore/thread-mq.h>
 #include <pulsecore/rtpoll.h>
 #include <pulsecore/sample-util.h>
 #include <pulsecore/ltdl-helper.h>
+#include <pulsecore/mix.h>
 
 #include "module-virtual-source-symdef.h"
 
@@ -61,6 +56,8 @@ PA_MODULE_USAGE(
           "rate=<sample rate> "
           "channels=<number of channels> "
           "channel_map=<channel map> "
+          "use_volume_sharing=<yes or no> "
+          "force_flat_volume=<yes or no> "
         ));
 
 #define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
@@ -69,6 +66,9 @@ PA_MODULE_USAGE(
 struct userdata {
     pa_module *module;
 
+    /* FIXME: Uncomment this and take "autoloaded" as a modarg if this is a filter */
+    /* pa_bool_t autoloaded; */
+
     pa_source *source;
     pa_source_output *source_output;
 
@@ -93,6 +93,8 @@ static const char* const valid_modargs[] = {
     "rate",
     "channels",
     "channel_map",
+    "use_volume_sharing",
+    "force_flat_volume",
     NULL
 };
 
@@ -125,6 +127,7 @@ static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
 
     if (state == PA_SINK_RUNNING) {
         /* need to wake-up source if it was suspended */
+        pa_log_debug("Resuming source %s, because its uplink sink became active.", u->source->name);
         pa_source_suspend(u->source, FALSE, PA_SUSPEND_ALL);
 
         /* FIXME: if there's no client connected, the source will suspend
@@ -238,32 +241,9 @@ static void source_set_volume_cb(pa_source *s) {
         !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
         return;
 
-    /* FIXME, no volume control in source_output, set volume at the master */
-    pa_source_set_volume(u->source_output->source, &s->volume, TRUE);
-}
-
-static void source_get_volume_cb(pa_source *s) {
-    struct userdata *u;
-
-    pa_source_assert_ref(s);
-    pa_assert_se(u = s->userdata);
-
-    if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)) ||
-        !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
-        return;
-
-    /* FIXME, no volume control in source_output, get the info from the master */
-    pa_source_get_volume(u->source_output->source, TRUE);
-
-    if (pa_cvolume_equal(&s->volume,&u->source_output->source->volume))
-        /* no change */
-        return;
-
-    s->volume = u->source_output->source->volume;
-    pa_source_set_soft_volume(s, NULL);
+    pa_source_output_set_volume(u->source_output, &s->real_volume, s->save_volume, TRUE);
 }
 
-
 /* Called from main context */
 static void source_set_mute_cb(pa_source *s) {
     struct userdata *u;
@@ -275,23 +255,7 @@ static void source_set_mute_cb(pa_source *s) {
         !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
         return;
 
-    /* FIXME, no volume control in source_output, set mute at the master */
-    pa_source_set_mute(u->source_output->source, TRUE, TRUE);
-}
-
-/* Called from main context */
-static void source_get_mute_cb(pa_source *s) {
-    struct userdata *u;
-
-    pa_source_assert_ref(s);
-    pa_assert_se(u = s->userdata);
-
-    if (!PA_SOURCE_IS_LINKED(pa_source_get_state(s)) ||
-        !PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_get_state(u->source_output)))
-        return;
-
-    /* FIXME, no volume control in source_output, get the info from the master */
-    pa_source_get_mute(u->source_output->source, TRUE);
+    pa_source_output_set_mute(u->source_output, s->muted, s->save_muted);
 }
 
 /* Called from input thread context */
@@ -349,8 +313,7 @@ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk)
         pa_assert( target_chunk.memblock );
 
         /* get target pointer */
-        target = (void*)((uint8_t*)pa_memblock_acquire(target_chunk.memblock)
-                         + target_chunk.index);
+        target = pa_memblock_acquire_chunk(&target_chunk);
 
         /* set-up mixing structure
            volume was taken care of in sink and source already */
@@ -405,14 +368,6 @@ static void source_output_process_rewind_cb(pa_source_output *o, size_t nbytes)
 }
 
 /* Called from output thread context */
-static int source_output_process_msg_cb(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
-
-    /* FIXME, nothing to do here ? */
-
-    return pa_source_output_process_msg(obj, code, data, offset, chunk);
-}
-
-/* Called from output thread context */
 static void source_output_attach_cb(pa_source_output *o) {
     struct userdata *u;
 
@@ -485,20 +440,6 @@ static void source_output_kill_cb(pa_source_output *o) {
 }
 
 /* Called from main thread */
-static pa_bool_t source_output_may_move_to_cb(pa_source_output *o, pa_source *dest) {
-    struct userdata *u;
-
-    pa_source_output_assert_ref(o);
-    pa_assert_ctl_context();
-    pa_assert_se(u = o->userdata);
-
-    /* FIXME */
-    //return dest != u->source_input->source->monitor_source;
-
-    return TRUE;
-}
-
-/* Called from main thread */
 static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
     struct userdata *u;
 
@@ -535,7 +476,8 @@ int pa__init(pa_module*m) {
     pa_source *master=NULL;
     pa_source_output_new_data source_output_data;
     pa_source_new_data source_data;
-    pa_bool_t *use_default = NULL;
+    pa_bool_t use_volume_sharing = TRUE;
+    pa_bool_t force_flat_volume = FALSE;
 
     /* optional for uplink_sink */
     pa_sink_new_data sink_data;
@@ -563,15 +505,25 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
+    if (pa_modargs_get_value_boolean(ma, "use_volume_sharing", &use_volume_sharing) < 0) {
+        pa_log("use_volume_sharing= expects a boolean argument");
+        goto fail;
+    }
 
-    u = pa_xnew0(struct userdata, 1);
-    if (!u) {
-        pa_log("Failed to alloc userdata");
+    if (pa_modargs_get_value_boolean(ma, "force_flat_volume", &force_flat_volume) < 0) {
+        pa_log("force_flat_volume= expects a boolean argument");
         goto fail;
     }
+
+    if (use_volume_sharing && force_flat_volume) {
+        pa_log("Flat volume can't be forced when using volume sharing.");
+        goto fail;
+    }
+
+    u = pa_xnew0(struct userdata, 1);
     u->module = m;
     m->userdata = u;
-    u->memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, NULL);
+    u->memblockq = pa_memblockq_new("module-virtual-source memblockq", 0, MEMBLOCKQ_MAXLENGTH, 0, &ss, 1, 1, 0, NULL);
     if (!u->memblockq) {
         pa_log("Failed to create source memblockq.");
         goto fail;
@@ -603,9 +555,9 @@ int pa__init(pa_module*m) {
         pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Virtual Source %s on %s", source_data.name, z ? z : master->name);
     }
 
-    u->source = pa_source_new(m->core, &source_data,
-                          PA_SOURCE_HW_MUTE_CTRL|PA_SOURCE_HW_VOLUME_CTRL|PA_SOURCE_DECIBEL_VOLUME|
-                          (master->flags & (PA_SOURCE_LATENCY|PA_SOURCE_DYNAMIC_LATENCY)));
+    u->source = pa_source_new(m->core, &source_data, (master->flags & (PA_SOURCE_LATENCY|PA_SOURCE_DYNAMIC_LATENCY))
+                                                     | (use_volume_sharing ? PA_SOURCE_SHARE_VOLUME_WITH_MASTER : 0));
+
     pa_source_new_data_done(&source_data);
 
     if (!u->source) {
@@ -616,10 +568,14 @@ int pa__init(pa_module*m) {
     u->source->parent.process_msg = source_process_msg_cb;
     u->source->set_state = source_set_state_cb;
     u->source->update_requested_latency = source_update_requested_latency_cb;
-    u->source->set_volume = source_set_volume_cb;
-    u->source->set_mute = source_set_mute_cb;
-    u->source->get_volume = source_get_volume_cb;
-    u->source->get_mute = source_get_mute_cb;
+    pa_source_set_set_mute_callback(u->source, source_set_mute_cb);
+    if (!use_volume_sharing) {
+        pa_source_set_set_volume_callback(u->source, source_set_volume_cb);
+        pa_source_enable_decibel_volume(u->source, TRUE);
+    }
+    /* Normally this flag would be enabled automatically be we can force it. */
+    if (force_flat_volume)
+        u->source->flags |= PA_SOURCE_FLAT_VOLUME;
     u->source->userdata = u;
 
     pa_source_set_asyncmsgq(u->source, master->asyncmsgq);
@@ -628,11 +584,10 @@ int pa__init(pa_module*m) {
     pa_source_output_new_data_init(&source_output_data);
     source_output_data.driver = __FILE__;
     source_output_data.module = m;
-    source_output_data.source = master;
-    /* FIXME
-       source_output_data.flags = PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND; */
+    pa_source_output_new_data_set_source(&source_output_data, master, FALSE);
+    source_output_data.destination_source = u->source;
 
-    pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Source Stream");
+    pa_proplist_setf(source_output_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Source Stream of %s", pa_proplist_gets(u->source->proplist, PA_PROP_DEVICE_DESCRIPTION));
     pa_proplist_sets(source_output_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
     pa_source_output_new_data_set_sample_spec(&source_output_data, &ss);
     pa_source_output_new_data_set_channel_map(&source_output_data, &map);
@@ -643,17 +598,17 @@ int pa__init(pa_module*m) {
     if (!u->source_output)
         goto fail;
 
-    u->source_output->parent.process_msg = source_output_process_msg_cb;
     u->source_output->push = source_output_push_cb;
     u->source_output->process_rewind = source_output_process_rewind_cb;
     u->source_output->kill = source_output_kill_cb;
     u->source_output->attach = source_output_attach_cb;
     u->source_output->detach = source_output_detach_cb;
     u->source_output->state_change = source_output_state_change_cb;
-    u->source_output->may_move_to = source_output_may_move_to_cb;
     u->source_output->moving = source_output_moving_cb;
     u->source_output->userdata = u;
 
+    u->source->output_from_master = u->source_output;
+
     pa_source_put(u->source);
     pa_source_output_put(u->source_output);
 
@@ -675,8 +630,9 @@ int pa__init(pa_module*m) {
             pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Uplink Sink %s on %s", sink_data.name, z ? z : master->name);
         }
 
-        u->sink_memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, NULL);
+        u->sink_memblockq = pa_memblockq_new("module-virtual-source sink_memblockq", 0, MEMBLOCKQ_MAXLENGTH, 0, &ss, 1, 1, 0, NULL);
         if (!u->sink_memblockq) {
+            pa_sink_new_data_done(&sink_data);
             pa_log("Failed to create sink memblockq.");
             goto fail;
         }
@@ -705,22 +661,19 @@ int pa__init(pa_module*m) {
 
         pa_sink_put(u->sink);
     } else {
+        pa_sink_new_data_done(&sink_data);
         /* optional uplink sink not enabled */
         u->sink = NULL;
     }
 
     pa_modargs_free(ma);
 
-    pa_xfree(use_default);
-
     return 0;
 
- fail:
+fail:
     if (ma)
         pa_modargs_free(ma);
 
-    pa_xfree(use_default);
-
     pa__done(m);
 
     return -1;
@@ -765,7 +718,7 @@ void pa__done(pa_module*m) {
         pa_memblockq_free(u->memblockq);
 
     if (u->sink_memblockq)
-         pa_memblockq_free(u->sink_memblockq);
+        pa_memblockq_free(u->sink_memblockq);
 
     pa_xfree(u);
 }
diff --git a/src/modules/module-virtual-surround-sink.c b/src/modules/module-virtual-surround-sink.c
new file mode 100644 (file)
index 0000000..bcca8d0
--- /dev/null
@@ -0,0 +1,880 @@
+/***
+    This file is part of PulseAudio.
+
+    Copyright 2010 Intel Corporation
+    Contributor: Pierre-Louis Bossart <pierre-louis.bossart@intel.com>
+    Copyright 2012 Niels Ole Salscheider <niels_ole@salscheider-online.de>
+
+    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, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+    USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/gccmacro.h>
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/i18n.h>
+#include <pulsecore/namereg.h>
+#include <pulsecore/sink.h>
+#include <pulsecore/module.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/log.h>
+#include <pulsecore/rtpoll.h>
+#include <pulsecore/sample-util.h>
+#include <pulsecore/ltdl-helper.h>
+#include <pulsecore/sound-file.h>
+#include <pulsecore/resampler.h>
+
+#include <math.h>
+
+#include "module-virtual-surround-sink-symdef.h"
+
+PA_MODULE_AUTHOR("Niels Ole Salscheider");
+PA_MODULE_DESCRIPTION(_("Virtual surround sink"));
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(FALSE);
+PA_MODULE_USAGE(
+        _("sink_name=<name for the sink> "
+          "sink_properties=<properties for the sink> "
+          "master=<name of sink to filter> "
+          "format=<sample format> "
+          "rate=<sample rate> "
+          "channels=<number of channels> "
+          "channel_map=<channel map> "
+          "use_volume_sharing=<yes or no> "
+          "force_flat_volume=<yes or no> "
+          "hrir=/path/to/left_hrir.wav "
+        ));
+
+#define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
+
+struct userdata {
+    pa_module *module;
+
+    /* FIXME: Uncomment this and take "autoloaded" as a modarg if this is a filter */
+    /* pa_bool_t autoloaded; */
+
+    pa_sink *sink;
+    pa_sink_input *sink_input;
+
+    pa_memblockq *memblockq;
+
+    pa_bool_t auto_desc;
+    unsigned channels;
+    unsigned hrir_channels;
+
+    unsigned fs, sink_fs;
+
+    unsigned *mapping_left;
+    unsigned *mapping_right;
+
+    unsigned hrir_samples;
+    float *hrir_data;
+
+    float *input_buffer;
+    int input_buffer_offset;
+};
+
+static const char* const valid_modargs[] = {
+    "sink_name",
+    "sink_properties",
+    "master",
+    "format",
+    "rate",
+    "channels",
+    "channel_map",
+    "use_volume_sharing",
+    "force_flat_volume",
+    "hrir",
+    NULL
+};
+
+/* Called from I/O thread context */
+static int sink_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
+    struct userdata *u = PA_SINK(o)->userdata;
+
+    switch (code) {
+
+        case PA_SINK_MESSAGE_GET_LATENCY:
+
+            /* The sink is _put() before the sink input is, so let's
+             * make sure we don't access it in that time. Also, the
+             * sink input is first shut down, the sink second. */
+            if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
+                !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state)) {
+                *((pa_usec_t*) data) = 0;
+                return 0;
+            }
+
+            *((pa_usec_t*) data) =
+
+                /* Get the latency of the master sink */
+                pa_sink_get_latency_within_thread(u->sink_input->sink) +
+
+                /* Add the latency internal to our sink input on top */
+                pa_bytes_to_usec(pa_memblockq_get_length(u->sink_input->thread_info.render_memblockq), &u->sink_input->sink->sample_spec);
+
+            return 0;
+    }
+
+    return pa_sink_process_msg(o, code, data, offset, chunk);
+}
+
+/* Called from main context */
+static int sink_set_state_cb(pa_sink *s, pa_sink_state_t state) {
+    struct userdata *u;
+
+    pa_sink_assert_ref(s);
+    pa_assert_se(u = s->userdata);
+
+    if (!PA_SINK_IS_LINKED(state) ||
+        !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
+        return 0;
+
+    pa_sink_input_cork(u->sink_input, state == PA_SINK_SUSPENDED);
+    return 0;
+}
+
+/* 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);
+
+    if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
+        !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
+        return;
+
+    /* Just hand this one over to the master sink */
+    pa_sink_input_request_rewind(u->sink_input,
+                                 s->thread_info.rewind_nbytes +
+                                 pa_memblockq_get_length(u->memblockq), TRUE, FALSE, FALSE);
+}
+
+/* Called from I/O thread context */
+static void sink_update_requested_latency_cb(pa_sink *s) {
+    struct userdata *u;
+
+    pa_sink_assert_ref(s);
+    pa_assert_se(u = s->userdata);
+
+    if (!PA_SINK_IS_LINKED(u->sink->thread_info.state) ||
+        !PA_SINK_INPUT_IS_LINKED(u->sink_input->thread_info.state))
+        return;
+
+    /* Just hand this one over to the master sink */
+    pa_sink_input_set_requested_latency_within_thread(
+            u->sink_input,
+            pa_sink_get_requested_latency_within_thread(s));
+}
+
+/* Called from main context */
+static void sink_set_volume_cb(pa_sink *s) {
+    struct userdata *u;
+
+    pa_sink_assert_ref(s);
+    pa_assert_se(u = s->userdata);
+
+    if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)) ||
+        !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
+        return;
+
+    pa_sink_input_set_volume(u->sink_input, &s->real_volume, s->save_volume, TRUE);
+}
+
+/* Called from main context */
+static void sink_set_mute_cb(pa_sink *s) {
+    struct userdata *u;
+
+    pa_sink_assert_ref(s);
+    pa_assert_se(u = s->userdata);
+
+    if (!PA_SINK_IS_LINKED(pa_sink_get_state(s)) ||
+        !PA_SINK_INPUT_IS_LINKED(pa_sink_input_get_state(u->sink_input)))
+        return;
+
+    pa_sink_input_set_mute(u->sink_input, s->muted, s->save_muted);
+}
+
+/* Called from I/O thread context */
+static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
+    struct userdata *u;
+    float *src, *dst;
+    unsigned n;
+    pa_memchunk tchunk;
+
+    unsigned j, k, l;
+    float sum_right, sum_left;
+    float current_sample;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert(chunk);
+    pa_assert_se(u = i->userdata);
+
+    /* Hmm, process any rewind request that might be queued up */
+    pa_sink_process_rewind(u->sink, 0);
+
+    while (pa_memblockq_peek(u->memblockq, &tchunk) < 0) {
+        pa_memchunk nchunk;
+
+        pa_sink_render(u->sink, nbytes * u->sink_fs / u->fs, &nchunk);
+        pa_memblockq_push(u->memblockq, &nchunk);
+        pa_memblock_unref(nchunk.memblock);
+    }
+
+    tchunk.length = PA_MIN(nbytes * u->sink_fs / u->fs, tchunk.length);
+    pa_assert(tchunk.length > 0);
+
+    n = (unsigned) (tchunk.length / u->sink_fs);
+
+    pa_assert(n > 0);
+
+    chunk->index = 0;
+    chunk->length = n * u->fs;
+    chunk->memblock = pa_memblock_new(i->sink->core->mempool, chunk->length);
+
+    pa_memblockq_drop(u->memblockq, n * u->sink_fs);
+
+    src = pa_memblock_acquire_chunk(&tchunk);
+    dst = pa_memblock_acquire(chunk->memblock);
+
+    for (l = 0; l < n; l++) {
+        memcpy(((char*) u->input_buffer) + u->input_buffer_offset * u->sink_fs, ((char *) src) + l * u->sink_fs, u->sink_fs);
+
+        sum_right = 0;
+        sum_left = 0;
+
+        /* fold the input buffer with the impulse response */
+        for (j = 0; j < u->hrir_samples; j++) {
+            for (k = 0; k < u->channels; k++) {
+                current_sample = u->input_buffer[((u->input_buffer_offset + j) % u->hrir_samples) * u->channels + k];
+
+                sum_left += current_sample * u->hrir_data[j * u->hrir_channels + u->mapping_left[k]];
+                sum_right += current_sample * u->hrir_data[j * u->hrir_channels + u->mapping_right[k]];
+            }
+        }
+
+        dst[2 * l] = PA_CLAMP_UNLIKELY(sum_left, -1.0f, 1.0f);
+        dst[2 * l + 1] = PA_CLAMP_UNLIKELY(sum_right, -1.0f, 1.0f);
+
+        u->input_buffer_offset--;
+        if (u->input_buffer_offset < 0)
+            u->input_buffer_offset += u->hrir_samples;
+    }
+
+    pa_memblock_release(tchunk.memblock);
+    pa_memblock_release(chunk->memblock);
+
+    pa_memblock_unref(tchunk.memblock);
+
+    return 0;
+}
+
+/* Called from I/O thread context */
+static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
+    struct userdata *u;
+    size_t amount = 0;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    if (u->sink->thread_info.rewind_nbytes > 0) {
+        size_t max_rewrite;
+
+        max_rewrite = nbytes * u->sink_fs / u->fs + pa_memblockq_get_length(u->memblockq);
+        amount = PA_MIN(u->sink->thread_info.rewind_nbytes * u->sink_fs / u->fs, max_rewrite);
+        u->sink->thread_info.rewind_nbytes = 0;
+
+        if (amount > 0) {
+            pa_memblockq_seek(u->memblockq, - (int64_t) amount, PA_SEEK_RELATIVE, TRUE);
+
+            /* Reset the input buffer */
+            memset(u->input_buffer, 0, u->hrir_samples * u->sink_fs);
+            u->input_buffer_offset = 0;
+        }
+    }
+
+    pa_sink_process_rewind(u->sink, amount);
+    pa_memblockq_rewind(u->memblockq, nbytes * u->sink_fs / u->fs);
+}
+
+/* Called from I/O thread context */
+static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    /* FIXME: Too small max_rewind:
+     * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
+    pa_memblockq_set_maxrewind(u->memblockq, nbytes * u->sink_fs / u->fs);
+    pa_sink_set_max_rewind_within_thread(u->sink, nbytes * u->sink_fs / u->fs);
+}
+
+/* Called from I/O thread context */
+static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    pa_sink_set_max_request_within_thread(u->sink, nbytes * u->sink_fs / u->fs);
+}
+
+/* Called from I/O thread context */
+static void sink_input_update_sink_latency_range_cb(pa_sink_input *i) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
+}
+
+/* Called from I/O thread context */
+static void sink_input_update_sink_fixed_latency_cb(pa_sink_input *i) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
+}
+
+/* Called from I/O thread context */
+static void sink_input_detach_cb(pa_sink_input *i) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    pa_sink_detach_within_thread(u->sink);
+
+    pa_sink_set_rtpoll(u->sink, NULL);
+}
+
+/* Called from I/O thread context */
+static void sink_input_attach_cb(pa_sink_input *i) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    pa_sink_set_rtpoll(u->sink, i->sink->thread_info.rtpoll);
+    pa_sink_set_latency_range_within_thread(u->sink, i->sink->thread_info.min_latency, i->sink->thread_info.max_latency);
+
+    pa_sink_set_fixed_latency_within_thread(u->sink, i->sink->thread_info.fixed_latency);
+
+    pa_sink_set_max_request_within_thread(u->sink, pa_sink_input_get_max_request(i) * u->sink_fs / u->fs);
+
+    /* FIXME: Too small max_rewind:
+     * https://bugs.freedesktop.org/show_bug.cgi?id=53709 */
+    pa_sink_set_max_rewind_within_thread(u->sink, pa_sink_input_get_max_rewind(i) * u->sink_fs / u->fs);
+
+    pa_sink_attach_within_thread(u->sink);
+}
+
+/* Called from main context */
+static void sink_input_kill_cb(pa_sink_input *i) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    /* The order here matters! We first kill the sink input, followed
+     * by the sink. That means the sink callbacks must be protected
+     * against an unconnected sink input! */
+    pa_sink_input_unlink(u->sink_input);
+    pa_sink_unlink(u->sink);
+
+    pa_sink_input_unref(u->sink_input);
+    u->sink_input = NULL;
+
+    pa_sink_unref(u->sink);
+    u->sink = NULL;
+
+    pa_module_unload_request(u->module, TRUE);
+}
+
+/* Called from IO thread context */
+static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t state) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    /* If we are added for the first time, ask for a rewinding so that
+     * we are heard right-away. */
+    if (PA_SINK_INPUT_IS_LINKED(state) &&
+        i->thread_info.state == PA_SINK_INPUT_INIT) {
+        pa_log_debug("Requesting rewind due to state change.");
+        pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
+    }
+}
+
+/* Called from main context */
+static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    if (dest) {
+        pa_sink_set_asyncmsgq(u->sink, dest->asyncmsgq);
+        pa_sink_update_flags(u->sink, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY, dest->flags);
+    } else
+        pa_sink_set_asyncmsgq(u->sink, NULL);
+
+    if (u->auto_desc && dest) {
+        const char *z;
+        pa_proplist *pl;
+
+        pl = pa_proplist_new();
+        z = pa_proplist_gets(dest->proplist, PA_PROP_DEVICE_DESCRIPTION);
+        pa_proplist_setf(pl, PA_PROP_DEVICE_DESCRIPTION, "Virtual Surround Sink %s on %s",
+                         pa_proplist_gets(u->sink->proplist, "device.vsurroundsink.name"), z ? z : dest->name);
+
+        pa_sink_update_proplist(u->sink, PA_UPDATE_REPLACE, pl);
+        pa_proplist_free(pl);
+    }
+}
+
+/* Called from main context */
+static void sink_input_volume_changed_cb(pa_sink_input *i) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    pa_sink_volume_changed(u->sink, &i->volume);
+}
+
+/* Called from main context */
+static void sink_input_mute_changed_cb(pa_sink_input *i) {
+    struct userdata *u;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_se(u = i->userdata);
+
+    pa_sink_mute_changed(u->sink, i->muted);
+}
+
+static pa_channel_position_t mirror_channel(pa_channel_position_t channel) {
+    switch (channel) {
+        case PA_CHANNEL_POSITION_FRONT_LEFT:
+            return PA_CHANNEL_POSITION_FRONT_RIGHT;
+
+        case PA_CHANNEL_POSITION_FRONT_RIGHT:
+            return PA_CHANNEL_POSITION_FRONT_LEFT;
+
+        case PA_CHANNEL_POSITION_REAR_LEFT:
+            return PA_CHANNEL_POSITION_REAR_RIGHT;
+
+        case PA_CHANNEL_POSITION_REAR_RIGHT:
+            return PA_CHANNEL_POSITION_REAR_LEFT;
+
+        case PA_CHANNEL_POSITION_SIDE_LEFT:
+            return PA_CHANNEL_POSITION_SIDE_RIGHT;
+
+        case PA_CHANNEL_POSITION_SIDE_RIGHT:
+            return PA_CHANNEL_POSITION_SIDE_LEFT;
+
+        case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER:
+            return PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER;
+
+        case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER:
+            return PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER;
+
+        case PA_CHANNEL_POSITION_TOP_FRONT_LEFT:
+            return PA_CHANNEL_POSITION_TOP_FRONT_RIGHT;
+
+        case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT:
+            return PA_CHANNEL_POSITION_TOP_FRONT_LEFT;
+
+        case PA_CHANNEL_POSITION_TOP_REAR_LEFT:
+            return PA_CHANNEL_POSITION_TOP_REAR_RIGHT;
+
+        case PA_CHANNEL_POSITION_TOP_REAR_RIGHT:
+            return PA_CHANNEL_POSITION_TOP_REAR_LEFT;
+
+        default:
+            return channel;
+    }
+}
+
+int pa__init(pa_module*m) {
+    struct userdata *u;
+    pa_sample_spec ss, sink_input_ss;
+    pa_channel_map map, sink_input_map;
+    pa_modargs *ma;
+    pa_sink *master=NULL;
+    pa_sink_input_new_data sink_input_data;
+    pa_sink_new_data sink_data;
+    pa_bool_t use_volume_sharing = TRUE;
+    pa_bool_t force_flat_volume = FALSE;
+    pa_memchunk silence;
+
+    const char *hrir_file;
+    unsigned i, j, found_channel_left, found_channel_right;
+    float hrir_sum, hrir_max;
+    float *hrir_data;
+
+    pa_sample_spec hrir_ss;
+    pa_channel_map hrir_map;
+
+    pa_sample_spec hrir_temp_ss;
+    pa_memchunk hrir_temp_chunk, hrir_temp_chunk_resampled;
+    pa_resampler *resampler;
+
+    size_t hrir_copied_length, hrir_total_length;
+
+    hrir_temp_chunk.memblock = NULL;
+    hrir_temp_chunk_resampled.memblock = NULL;
+
+    pa_assert(m);
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments.");
+        goto fail;
+    }
+
+    if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "master", NULL), PA_NAMEREG_SINK))) {
+        pa_log("Master sink not found");
+        goto fail;
+    }
+
+    pa_assert(master);
+
+    u = pa_xnew0(struct userdata, 1);
+    u->module = m;
+    m->userdata = u;
+
+    /* Initialize hrir and input buffer */
+    /* this is the hrir file for the left ear! */
+    hrir_file = pa_modargs_get_value(ma, "hrir", NULL);
+
+    if (!(hrir_file = pa_modargs_get_value(ma, "hrir", NULL))) {
+        pa_log("The mandatory 'hrir' module argument is missing.");
+        goto fail;
+    }
+
+    if (pa_sound_file_load(master->core->mempool, hrir_file, &hrir_temp_ss, &hrir_map, &hrir_temp_chunk, NULL) < 0) {
+        pa_log("Cannot load hrir file.");
+        goto fail;
+    }
+
+    /* sample spec / map of hrir */
+    hrir_ss.format = PA_SAMPLE_FLOAT32;
+    hrir_ss.rate = master->sample_spec.rate;
+    hrir_ss.channels = hrir_temp_ss.channels;
+
+    /* sample spec of sink */
+    ss = hrir_ss;
+    map = hrir_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;
+    }
+    ss.format = PA_SAMPLE_FLOAT32;
+    hrir_ss.rate = ss.rate;
+    u->channels = ss.channels;
+
+    if (pa_modargs_get_value_boolean(ma, "use_volume_sharing", &use_volume_sharing) < 0) {
+        pa_log("use_volume_sharing= expects a boolean argument");
+        goto fail;
+    }
+
+    if (pa_modargs_get_value_boolean(ma, "force_flat_volume", &force_flat_volume) < 0) {
+        pa_log("force_flat_volume= expects a boolean argument");
+        goto fail;
+    }
+
+    if (use_volume_sharing && force_flat_volume) {
+        pa_log("Flat volume can't be forced when using volume sharing.");
+        goto fail;
+    }
+
+    /* sample spec / map of sink input */
+    pa_channel_map_init_stereo(&sink_input_map);
+    sink_input_ss.channels = 2;
+    sink_input_ss.format = PA_SAMPLE_FLOAT32;
+    sink_input_ss.rate = ss.rate;
+
+    u->sink_fs = pa_frame_size(&ss);
+    u->fs = pa_frame_size(&sink_input_ss);
+
+    /* Create sink */
+    pa_sink_new_data_init(&sink_data);
+    sink_data.driver = __FILE__;
+    sink_data.module = m;
+    if (!(sink_data.name = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", NULL))))
+        sink_data.name = pa_sprintf_malloc("%s.vsurroundsink", master->name);
+    pa_sink_new_data_set_sample_spec(&sink_data, &ss);
+    pa_sink_new_data_set_channel_map(&sink_data, &map);
+    pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_MASTER_DEVICE, master->name);
+    pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_CLASS, "filter");
+    pa_proplist_sets(sink_data.proplist, "device.vsurroundsink.name", sink_data.name);
+
+    if (pa_modargs_get_proplist(ma, "sink_properties", sink_data.proplist, PA_UPDATE_REPLACE) < 0) {
+        pa_log("Invalid properties");
+        pa_sink_new_data_done(&sink_data);
+        goto fail;
+    }
+
+    if ((u->auto_desc = !pa_proplist_contains(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION))) {
+        const char *z;
+
+        z = pa_proplist_gets(master->proplist, PA_PROP_DEVICE_DESCRIPTION);
+        pa_proplist_setf(sink_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Virtual Surround Sink %s on %s", sink_data.name, z ? z : master->name);
+    }
+
+    u->sink = pa_sink_new(m->core, &sink_data, (master->flags & (PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY))
+                                               | (use_volume_sharing ? PA_SINK_SHARE_VOLUME_WITH_MASTER : 0));
+    pa_sink_new_data_done(&sink_data);
+
+    if (!u->sink) {
+        pa_log("Failed to create sink.");
+        goto fail;
+    }
+
+    u->sink->parent.process_msg = sink_process_msg_cb;
+    u->sink->set_state = sink_set_state_cb;
+    u->sink->update_requested_latency = sink_update_requested_latency_cb;
+    u->sink->request_rewind = sink_request_rewind_cb;
+    pa_sink_set_set_mute_callback(u->sink, sink_set_mute_cb);
+    if (!use_volume_sharing) {
+        pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
+        pa_sink_enable_decibel_volume(u->sink, TRUE);
+    }
+    /* Normally this flag would be enabled automatically be we can force it. */
+    if (force_flat_volume)
+        u->sink->flags |= PA_SINK_FLAT_VOLUME;
+    u->sink->userdata = u;
+
+    pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq);
+
+    /* Create sink input */
+    pa_sink_input_new_data_init(&sink_input_data);
+    sink_input_data.driver = __FILE__;
+    sink_input_data.module = m;
+    pa_sink_input_new_data_set_sink(&sink_input_data, master, FALSE);
+    sink_input_data.origin_sink = u->sink;
+    pa_proplist_setf(sink_input_data.proplist, PA_PROP_MEDIA_NAME, "Virtual Surround Sink Stream from %s", pa_proplist_gets(u->sink->proplist, PA_PROP_DEVICE_DESCRIPTION));
+    pa_proplist_sets(sink_input_data.proplist, PA_PROP_MEDIA_ROLE, "filter");
+    pa_sink_input_new_data_set_sample_spec(&sink_input_data, &sink_input_ss);
+    pa_sink_input_new_data_set_channel_map(&sink_input_data, &sink_input_map);
+
+    pa_sink_input_new(&u->sink_input, m->core, &sink_input_data);
+    pa_sink_input_new_data_done(&sink_input_data);
+
+    if (!u->sink_input)
+        goto fail;
+
+    u->sink_input->pop = sink_input_pop_cb;
+    u->sink_input->process_rewind = sink_input_process_rewind_cb;
+    u->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
+    u->sink_input->update_max_request = sink_input_update_max_request_cb;
+    u->sink_input->update_sink_latency_range = sink_input_update_sink_latency_range_cb;
+    u->sink_input->update_sink_fixed_latency = sink_input_update_sink_fixed_latency_cb;
+    u->sink_input->kill = sink_input_kill_cb;
+    u->sink_input->attach = sink_input_attach_cb;
+    u->sink_input->detach = sink_input_detach_cb;
+    u->sink_input->state_change = sink_input_state_change_cb;
+    u->sink_input->moving = sink_input_moving_cb;
+    u->sink_input->volume_changed = use_volume_sharing ? NULL : sink_input_volume_changed_cb;
+    u->sink_input->mute_changed = sink_input_mute_changed_cb;
+    u->sink_input->userdata = u;
+
+    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);
+    pa_memblock_unref(silence.memblock);
+
+    /* resample hrir */
+    resampler = pa_resampler_new(u->sink->core->mempool, &hrir_temp_ss, &hrir_map, &hrir_ss, &hrir_map,
+                                 PA_RESAMPLER_SRC_SINC_BEST_QUALITY, PA_RESAMPLER_NO_REMAP);
+
+    u->hrir_samples = hrir_temp_chunk.length / pa_frame_size(&hrir_temp_ss) * hrir_ss.rate / hrir_temp_ss.rate;
+    if (u->hrir_samples > 64) {
+        u->hrir_samples = 64;
+        pa_log("The (resampled) hrir contains more than 64 samples. Only the first 64 samples will be used to limit processor usage.");
+    }
+
+    hrir_total_length = u->hrir_samples * pa_frame_size(&hrir_ss);
+    u->hrir_channels = hrir_ss.channels;
+
+    u->hrir_data = (float *) pa_xmalloc(hrir_total_length);
+    hrir_copied_length = 0;
+
+    /* add silence to the hrir until we get enough samples out of the resampler */
+    while (hrir_copied_length < hrir_total_length) {
+        pa_resampler_run(resampler, &hrir_temp_chunk, &hrir_temp_chunk_resampled);
+        if (hrir_temp_chunk.memblock != hrir_temp_chunk_resampled.memblock) {
+            /* Silence input block */
+            pa_silence_memblock(hrir_temp_chunk.memblock, &hrir_temp_ss);
+        }
+
+        if (hrir_temp_chunk_resampled.memblock) {
+            /* Copy hrir data */
+            hrir_data = (float *) pa_memblock_acquire(hrir_temp_chunk_resampled.memblock);
+
+            if (hrir_total_length - hrir_copied_length >= hrir_temp_chunk_resampled.length) {
+                memcpy(u->hrir_data + hrir_copied_length, hrir_data, hrir_temp_chunk_resampled.length);
+                hrir_copied_length += hrir_temp_chunk_resampled.length;
+            } else {
+                memcpy(u->hrir_data + hrir_copied_length, hrir_data, hrir_total_length - hrir_copied_length);
+                hrir_copied_length = hrir_total_length;
+            }
+
+            pa_memblock_release(hrir_temp_chunk_resampled.memblock);
+            pa_memblock_unref(hrir_temp_chunk_resampled.memblock);
+            hrir_temp_chunk_resampled.memblock = NULL;
+        }
+    }
+
+    pa_resampler_free(resampler);
+
+    pa_memblock_unref(hrir_temp_chunk.memblock);
+    hrir_temp_chunk.memblock = NULL;
+
+    if (hrir_map.channels < map.channels) {
+        pa_log("hrir file does not have enough channels!");
+        goto fail;
+    }
+
+    /* normalize hrir to avoid clipping */
+    hrir_max = 0;
+    for (i = 0; i < u->hrir_samples; i++) {
+        hrir_sum = 0;
+        for (j = 0; j < u->hrir_channels; j++)
+            hrir_sum += fabs(u->hrir_data[i * u->hrir_channels + j]);
+
+        if (hrir_sum > hrir_max)
+            hrir_max = hrir_sum;
+    }
+    if (hrir_max > 1) {
+        for (i = 0; i < u->hrir_samples; i++) {
+            for (j = 0; j < u->hrir_channels; j++)
+                u->hrir_data[i * u->hrir_channels + j] /= hrir_max * 1.2;
+        }
+    }
+
+    /* create mapping between hrir and input */
+    u->mapping_left = (unsigned *) pa_xnew0(unsigned, u->channels);
+    u->mapping_right = (unsigned *) pa_xnew0(unsigned, u->channels);
+    for (i = 0; i < map.channels; i++) {
+        found_channel_left = 0;
+        found_channel_right = 0;
+
+        for (j = 0; j < hrir_map.channels; j++) {
+            if (hrir_map.map[j] == map.map[i]) {
+                u->mapping_left[i] = j;
+                found_channel_left = 1;
+            }
+
+            if (hrir_map.map[j] == mirror_channel(map.map[i])) {
+                u->mapping_right[i] = j;
+                found_channel_right = 1;
+            }
+        }
+
+        if (!found_channel_left) {
+            pa_log("Cannot find mapping for channel %s", pa_channel_position_to_string(map.map[i]));
+            goto fail;
+        }
+        if (!found_channel_right) {
+            pa_log("Cannot find mapping for channel %s", pa_channel_position_to_string(mirror_channel(map.map[i])));
+            goto fail;
+        }
+    }
+
+    u->input_buffer = pa_xmalloc0(u->hrir_samples * u->sink_fs);
+    u->input_buffer_offset = 0;
+
+    pa_sink_put(u->sink);
+    pa_sink_input_put(u->sink_input);
+
+    pa_modargs_free(ma);
+    return 0;
+
+fail:
+    if (hrir_temp_chunk.memblock)
+        pa_memblock_unref(hrir_temp_chunk.memblock);
+
+    if (hrir_temp_chunk_resampled.memblock)
+        pa_memblock_unref(hrir_temp_chunk_resampled.memblock);
+
+    if (ma)
+        pa_modargs_free(ma);
+
+    pa__done(m);
+
+    return -1;
+}
+
+int pa__get_n_used(pa_module *m) {
+    struct userdata *u;
+
+    pa_assert(m);
+    pa_assert_se(u = m->userdata);
+
+    return pa_sink_linked_by(u->sink);
+}
+
+void pa__done(pa_module*m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    /* See comments in sink_input_kill_cb() above regarding
+     * destruction order! */
+
+    if (u->sink_input)
+        pa_sink_input_unlink(u->sink_input);
+
+    if (u->sink)
+        pa_sink_unlink(u->sink);
+
+    if (u->sink_input)
+        pa_sink_input_unref(u->sink_input);
+
+    if (u->sink)
+        pa_sink_unref(u->sink);
+
+    if (u->memblockq)
+        pa_memblockq_free(u->memblockq);
+
+    if (u->hrir_data)
+        pa_xfree(u->hrir_data);
+
+    if (u->input_buffer)
+        pa_xfree(u->input_buffer);
+
+    if (u->mapping_left)
+        pa_xfree(u->mapping_left);
+    if (u->mapping_right)
+        pa_xfree(u->mapping_right);
+
+    pa_xfree(u);
+}
diff --git a/src/modules/module-volume-restore-symdef.h b/src/modules/module-volume-restore-symdef.h
deleted file mode 100644 (file)
index 08e98a5..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulevolumerestoresymdeffoo
-#define foomodulevolumerestoresymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_volume_restore_LTX_pa__init
-#define pa__done module_volume_restore_LTX_pa__done
-#define pa__get_author module_volume_restore_LTX_pa__get_author
-#define pa__get_description module_volume_restore_LTX_pa__get_description
-#define pa__get_usage module_volume_restore_LTX_pa__get_usage
-#define pa__get_version module_volume_restore_LTX_pa__get_version
-#define pa__get_deprecated module_volume_restore_LTX_pa__get_deprecated
-#define pa__load_once module_volume_restore_LTX_pa__load_once
-#define pa__get_n_used module_volume_restore_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 6e484ea..a344c5e 100644 (file)
@@ -81,5 +81,5 @@ fail:
     if (ma)
         pa_modargs_free(ma);
 
-    return  -1;
+    return -1;
 }
diff --git a/src/modules/module-waveout-symdef.h b/src/modules/module-waveout-symdef.h
deleted file mode 100644 (file)
index 25259e9..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulewaveoutsymdeffoo
-#define foomodulewaveoutsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_waveout_LTX_pa__init
-#define pa__done module_waveout_LTX_pa__done
-#define pa__get_author module_waveout_LTX_pa__get_author
-#define pa__get_description module_waveout_LTX_pa__get_description
-#define pa__get_usage module_waveout_LTX_pa__get_usage
-#define pa__get_version module_waveout_LTX_pa__get_version
-#define pa__get_deprecated module_waveout_LTX_pa__get_deprecated
-#define pa__load_once module_waveout_LTX_pa__load_once
-#define pa__get_n_used module_waveout_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
diff --git a/src/modules/module-waveout.c b/src/modules/module-waveout.c
new file mode 100644 (file)
index 0000000..39c2ab4
--- /dev/null
@@ -0,0 +1,774 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2006 Lennart Poettering
+  Copyright 2006-2007 Pierre Ossman <ossman@cendio.se> for Cendio AB
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <windows.h>
+#include <mmsystem.h>
+
+#include <pulse/xmalloc.h>
+#include <pulse/timeval.h>
+
+#include <pulsecore/sink.h>
+#include <pulsecore/source.h>
+#include <pulsecore/module.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/sample-util.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/log.h>
+#include <pulsecore/thread.h>
+#include <pulsecore/thread-mq.h>
+
+#include "module-waveout-symdef.h"
+
+PA_MODULE_AUTHOR("Pierre Ossman");
+PA_MODULE_DESCRIPTION("Windows waveOut Sink/Source");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_USAGE(
+    "sink_name=<name for the sink> "
+    "source_name=<name for the source> "
+    "device=<device number> "
+    "device_name=<name of the device> "
+    "record=<enable source?> "
+    "playback=<enable sink?> "
+    "format=<sample format> "
+    "rate=<sample rate> "
+    "channels=<number of channels> "
+    "channel_map=<channel map> "
+    "fragments=<number of fragments> "
+    "fragment_size=<fragment size>");
+
+#define DEFAULT_SINK_NAME "wave_output"
+#define DEFAULT_SOURCE_NAME "wave_input"
+
+#define WAVEOUT_MAX_VOLUME 0xFFFF
+
+struct userdata {
+    pa_sink *sink;
+    pa_source *source;
+    pa_core *core;
+    pa_usec_t poll_timeout;
+
+    pa_thread *thread;
+    pa_thread_mq thread_mq;
+    pa_rtpoll *rtpoll;
+
+    uint32_t fragments, fragment_size;
+
+    uint32_t free_ofrags, free_ifrags;
+
+    DWORD written_bytes;
+    int sink_underflow;
+
+    int cur_ohdr, cur_ihdr;
+    WAVEHDR *ohdrs, *ihdrs;
+
+    HWAVEOUT hwo;
+    HWAVEIN hwi;
+    pa_module *module;
+
+    CRITICAL_SECTION crit;
+};
+
+static const char* const valid_modargs[] = {
+    "sink_name",
+    "source_name",
+    "device",
+    "device_name",
+    "record",
+    "playback",
+    "fragments",
+    "fragment_size",
+    "format",
+    "rate",
+    "channels",
+    "channel_map",
+    NULL
+};
+
+static void do_write(struct userdata *u) {
+    uint32_t free_frags;
+    pa_memchunk memchunk;
+    WAVEHDR *hdr;
+    MMRESULT res;
+    void *p;
+
+    if (!u->sink)
+        return;
+
+    if (!PA_SINK_IS_LINKED(u->sink->state))
+        return;
+
+    EnterCriticalSection(&u->crit);
+    free_frags = u->free_ofrags;
+    LeaveCriticalSection(&u->crit);
+
+    if (!u->sink_underflow && (free_frags == u->fragments))
+        pa_log_debug("WaveOut underflow!");
+
+    while (free_frags) {
+        hdr = &u->ohdrs[u->cur_ohdr];
+        if (hdr->dwFlags & WHDR_PREPARED)
+            waveOutUnprepareHeader(u->hwo, hdr, sizeof(WAVEHDR));
+
+        hdr->dwBufferLength = 0;
+        while (hdr->dwBufferLength < u->fragment_size) {
+            size_t len;
+
+            len = u->fragment_size - hdr->dwBufferLength;
+
+            pa_sink_render(u->sink, len, &memchunk);
+
+            pa_assert(memchunk.memblock);
+            pa_assert(memchunk.length);
+
+            if (memchunk.length < len)
+                len = memchunk.length;
+
+            p = pa_memblock_acquire(memchunk.memblock);
+            memcpy(hdr->lpData + hdr->dwBufferLength, (char*) p + memchunk.index, len);
+            pa_memblock_release(memchunk.memblock);
+
+            hdr->dwBufferLength += len;
+
+            pa_memblock_unref(memchunk.memblock);
+            memchunk.memblock = NULL;
+        }
+
+        /* Underflow detection */
+        if (hdr->dwBufferLength == 0) {
+            u->sink_underflow = 1;
+            break;
+        }
+        u->sink_underflow = 0;
+
+        res = waveOutPrepareHeader(u->hwo, hdr, sizeof(WAVEHDR));
+        if (res != MMSYSERR_NOERROR)
+            pa_log_error("Unable to prepare waveOut block: %d", res);
+
+        res = waveOutWrite(u->hwo, hdr, sizeof(WAVEHDR));
+        if (res != MMSYSERR_NOERROR)
+            pa_log_error("Unable to write waveOut block: %d", res);
+
+        u->written_bytes += hdr->dwBufferLength;
+
+        EnterCriticalSection(&u->crit);
+        u->free_ofrags--;
+        LeaveCriticalSection(&u->crit);
+
+        free_frags--;
+        u->cur_ohdr++;
+        u->cur_ohdr %= u->fragments;
+    }
+}
+
+static void do_read(struct userdata *u) {
+    uint32_t free_frags;
+    pa_memchunk memchunk;
+    WAVEHDR *hdr;
+    MMRESULT res;
+    void *p;
+
+    if (!u->source)
+        return;
+
+    if (!PA_SOURCE_IS_LINKED(u->source->state))
+        return;
+
+    EnterCriticalSection(&u->crit);
+    free_frags = u->free_ifrags;
+    u->free_ifrags = 0;
+    LeaveCriticalSection(&u->crit);
+
+    if (free_frags == u->fragments)
+        pa_log_debug("WaveIn overflow!");
+
+    while (free_frags) {
+        hdr = &u->ihdrs[u->cur_ihdr];
+        if (hdr->dwFlags & WHDR_PREPARED)
+            waveInUnprepareHeader(u->hwi, hdr, sizeof(WAVEHDR));
+
+        if (hdr->dwBytesRecorded) {
+            memchunk.memblock = pa_memblock_new(u->core->mempool, hdr->dwBytesRecorded);
+            pa_assert(memchunk.memblock);
+
+            p = pa_memblock_acquire(memchunk.memblock);
+            memcpy((char*) p, hdr->lpData, hdr->dwBytesRecorded);
+            pa_memblock_release(memchunk.memblock);
+
+            memchunk.length = hdr->dwBytesRecorded;
+            memchunk.index = 0;
+
+            pa_source_post(u->source, &memchunk);
+            pa_memblock_unref(memchunk.memblock);
+        }
+
+        res = waveInPrepareHeader(u->hwi, hdr, sizeof(WAVEHDR));
+        if (res != MMSYSERR_NOERROR)
+            pa_log_error("Unable to prepare waveIn block: %d", res);
+
+        res = waveInAddBuffer(u->hwi, hdr, sizeof(WAVEHDR));
+        if (res != MMSYSERR_NOERROR)
+            pa_log_error("Unable to add waveIn block: %d", res);
+
+        free_frags--;
+        u->cur_ihdr++;
+        u->cur_ihdr %= u->fragments;
+    }
+}
+
+static void thread_func(void *userdata) {
+    struct userdata *u = userdata;
+
+    pa_assert(u);
+    pa_assert(u->sink || u->source);
+
+    pa_log_debug("Thread starting up");
+
+    if (u->core->realtime_scheduling)
+        pa_make_realtime(u->core->realtime_priority);
+
+    pa_thread_mq_install(&u->thread_mq);
+
+    for (;;) {
+        int ret;
+        pa_bool_t need_timer = FALSE;
+
+        if (u->sink) {
+            if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
+                pa_sink_process_rewind(u->sink, 0);
+
+            if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
+                do_write(u);
+                need_timer = TRUE;
+            }
+        }
+
+        if (u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
+            do_read(u);
+            need_timer = TRUE;
+        }
+
+        if (need_timer)
+            pa_rtpoll_set_timer_relative(u->rtpoll, u->poll_timeout);
+        else
+            pa_rtpoll_set_timer_disabled(u->rtpoll);
+
+        /* Hmm, nothing to do. Let's sleep */
+        if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
+            goto fail;
+
+        if (ret == 0)
+            goto finish;
+    }
+
+fail:
+    /* If this was no regular exit from the loop we have to continue
+     * processing messages until we received PA_MESSAGE_SHUTDOWN */
+    pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
+    pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
+
+finish:
+    pa_log_debug("Thread shutting down");
+}
+
+static void CALLBACK chunk_done_cb(HWAVEOUT hwo, UINT msg, DWORD_PTR inst, DWORD param1, DWORD param2) {
+    struct userdata *u = (struct userdata*) inst;
+
+    if (msg == WOM_OPEN)
+        pa_log_debug("WaveOut subsystem opened.");
+    if (msg == WOM_CLOSE)
+        pa_log_debug("WaveOut subsystem closed.");
+    if (msg != WOM_DONE)
+        return;
+
+    EnterCriticalSection(&u->crit);
+    u->free_ofrags++;
+    pa_assert(u->free_ofrags <= u->fragments);
+    LeaveCriticalSection(&u->crit);
+}
+
+static void CALLBACK chunk_ready_cb(HWAVEIN hwi, UINT msg, DWORD_PTR inst, DWORD param1, DWORD param2) {
+    struct userdata *u = (struct userdata*) inst;
+
+    if (msg == WIM_OPEN)
+        pa_log_debug("WaveIn subsystem opened.");
+    if (msg == WIM_CLOSE)
+        pa_log_debug("WaveIn subsystem closed.");
+    if (msg != WIM_DATA)
+        return;
+
+    EnterCriticalSection(&u->crit);
+    u->free_ifrags++;
+    pa_assert(u->free_ifrags <= u->fragments);
+    LeaveCriticalSection(&u->crit);
+}
+
+static pa_usec_t sink_get_latency(struct userdata *u) {
+    uint32_t free_frags;
+    MMTIME mmt;
+    pa_assert(u);
+    pa_assert(u->sink);
+
+    memset(&mmt, 0, sizeof(mmt));
+    mmt.wType = TIME_BYTES;
+    if (waveOutGetPosition(u->hwo, &mmt, sizeof(mmt)) == MMSYSERR_NOERROR)
+        return pa_bytes_to_usec(u->written_bytes - mmt.u.cb, &u->sink->sample_spec);
+    else {
+        EnterCriticalSection(&u->crit);
+        free_frags = u->free_ofrags;
+        LeaveCriticalSection(&u->crit);
+
+        return pa_bytes_to_usec((u->fragments - free_frags) * u->fragment_size, &u->sink->sample_spec);
+    }
+}
+
+static pa_usec_t source_get_latency(struct userdata *u) {
+    pa_usec_t r = 0;
+    uint32_t free_frags;
+    pa_assert(u);
+    pa_assert(u->source);
+
+    EnterCriticalSection(&u->crit);
+    free_frags = u->free_ifrags;
+    LeaveCriticalSection(&u->crit);
+
+    r += pa_bytes_to_usec((free_frags + 1) * u->fragment_size, &u->source->sample_spec);
+
+    return r;
+}
+
+static int process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
+    struct userdata *u;
+
+    if (pa_sink_isinstance(o)) {
+        u = PA_SINK(o)->userdata;
+
+        switch (code) {
+
+            case PA_SINK_MESSAGE_GET_LATENCY: {
+                pa_usec_t r = 0;
+                if (u->hwo)
+                    r = sink_get_latency(u);
+                *((pa_usec_t*) data) = r;
+                return 0;
+            }
+
+        }
+
+        return pa_sink_process_msg(o, code, data, offset, chunk);
+    }
+
+    if (pa_source_isinstance(o)) {
+        u = PA_SOURCE(o)->userdata;
+
+        switch (code) {
+
+            case PA_SOURCE_MESSAGE_GET_LATENCY: {
+                pa_usec_t r = 0;
+                if (u->hwi)
+                    r = source_get_latency(u);
+                *((pa_usec_t*) data) = r;
+                return 0;
+            }
+
+        }
+
+        return pa_source_process_msg(o, code, data, offset, chunk);
+    }
+
+    return -1;
+}
+
+static void sink_get_volume_cb(pa_sink *s) {
+    struct userdata *u = s->userdata;
+    WAVEOUTCAPS caps;
+    DWORD vol;
+    pa_volume_t left, right;
+
+    if (waveOutGetDevCaps(u->hwo, &caps, sizeof(caps)) != MMSYSERR_NOERROR)
+        return;
+    if (!(caps.dwSupport & WAVECAPS_VOLUME))
+        return;
+
+    if (waveOutGetVolume(u->hwo, &vol) != MMSYSERR_NOERROR)
+        return;
+
+    left = PA_CLAMP_VOLUME((vol & 0xFFFF) * PA_VOLUME_NORM / WAVEOUT_MAX_VOLUME);
+    if (caps.dwSupport & WAVECAPS_LRVOLUME)
+        right = PA_CLAMP_VOLUME(((vol >> 16) & 0xFFFF) * PA_VOLUME_NORM / WAVEOUT_MAX_VOLUME);
+    else
+        right = left;
+
+    /* Windows supports > 2 channels, except for volume control */
+    if (s->real_volume.channels > 2)
+        pa_cvolume_set(&s->real_volume, s->real_volume.channels, (left + right)/2);
+
+    s->real_volume.values[0] = left;
+    if (s->real_volume.channels > 1)
+        s->real_volume.values[1] = right;
+}
+
+static void sink_set_volume_cb(pa_sink *s) {
+    struct userdata *u = s->userdata;
+    WAVEOUTCAPS caps;
+    DWORD vol;
+
+    if (waveOutGetDevCaps(u->hwo, &caps, sizeof(caps)) != MMSYSERR_NOERROR)
+        return;
+    if (!(caps.dwSupport & WAVECAPS_VOLUME))
+        return;
+
+    if (s->real_volume.channels == 2 && caps.dwSupport & WAVECAPS_LRVOLUME) {
+        vol = (s->real_volume.values[0] * WAVEOUT_MAX_VOLUME / PA_VOLUME_NORM)
+            | (s->real_volume.values[1] * WAVEOUT_MAX_VOLUME / PA_VOLUME_NORM) << 16;
+    } else {
+        vol = (pa_cvolume_avg(&(s->real_volume)) * WAVEOUT_MAX_VOLUME / PA_VOLUME_NORM)
+            | (pa_cvolume_avg(&(s->real_volume)) * WAVEOUT_MAX_VOLUME / PA_VOLUME_NORM) << 16;
+    }
+
+    if (waveOutSetVolume(u->hwo, vol) != MMSYSERR_NOERROR)
+        return;
+}
+
+static int ss_to_waveformat(pa_sample_spec *ss, LPWAVEFORMATEX wf) {
+    wf->wFormatTag = WAVE_FORMAT_PCM;
+
+    if (ss->channels > 2) {
+        pa_log_error("More than two channels not supported.");
+        return -1;
+    }
+
+    wf->nChannels = ss->channels;
+
+    wf->nSamplesPerSec = ss->rate;
+
+    if (ss->format == PA_SAMPLE_U8)
+        wf->wBitsPerSample = 8;
+    else if (ss->format == PA_SAMPLE_S16NE)
+        wf->wBitsPerSample = 16;
+    else {
+        pa_log_error("Unsupported sample format, only u8 and s16 are supported.");
+        return -1;
+    }
+
+    wf->nBlockAlign = wf->nChannels * wf->wBitsPerSample/8;
+    wf->nAvgBytesPerSec = wf->nSamplesPerSec * wf->nBlockAlign;
+
+    wf->cbSize = 0;
+
+    return 0;
+}
+
+int pa__get_n_used(pa_module *m) {
+    struct userdata *u;
+    pa_assert(m);
+    pa_assert(m->userdata);
+    u = (struct userdata*) m->userdata;
+
+    return (u->sink ? pa_sink_used_by(u->sink) : 0) +
+           (u->source ? pa_source_used_by(u->source) : 0);
+}
+
+int pa__init(pa_module *m) {
+    struct userdata *u = NULL;
+    HWAVEOUT hwo = INVALID_HANDLE_VALUE;
+    HWAVEIN hwi = INVALID_HANDLE_VALUE;
+    WAVEFORMATEX wf;
+    WAVEOUTCAPS pwoc;
+    MMRESULT result;
+    int nfrags, frag_size;
+    pa_bool_t record = TRUE, playback = TRUE;
+    unsigned int device;
+    pa_sample_spec ss;
+    pa_channel_map map;
+    pa_modargs *ma = NULL;
+    const char *device_name = NULL;
+    unsigned int i;
+
+    pa_assert(m);
+    pa_assert(m->core);
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("failed to parse module arguments.");
+        goto fail;
+    }
+
+    if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) {
+        pa_log("record= and playback= expect boolean argument.");
+        goto fail;
+    }
+
+    if (!playback && !record) {
+        pa_log("neither playback nor record enabled for device.");
+        goto fail;
+    }
+
+    /* Set the device to be opened.  If set device_name is used,
+     * else device if set and lastly WAVE_MAPPER is the default */
+    device = WAVE_MAPPER;
+    if (pa_modargs_get_value_u32(ma, "device", &device) < 0) {
+        pa_log("failed to parse device argument");
+        goto fail;
+    }
+    if ((device_name = pa_modargs_get_value(ma, "device_name", NULL)) != NULL) {
+        unsigned int num_devices = waveOutGetNumDevs();
+        for (i = 0; i < num_devices; i++) {
+            if (waveOutGetDevCaps(i, &pwoc, sizeof(pwoc)) == MMSYSERR_NOERROR)
+                if (_stricmp(device_name, pwoc.szPname) == 0)
+                    break;
+        }
+        if (i < num_devices)
+            device = i;
+        else {
+            pa_log("device not found: %s", device_name);
+            goto fail;
+        }
+    }
+    if (waveOutGetDevCaps(device, &pwoc, sizeof(pwoc)) == MMSYSERR_NOERROR)
+        device_name = pwoc.szPname;
+    else
+        device_name = "unknown";
+
+    nfrags = 5;
+    frag_size = 8192;
+    if (pa_modargs_get_value_s32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_s32(ma, "fragment_size", &frag_size) < 0) {
+        pa_log("failed to parse fragments arguments");
+        goto fail;
+    }
+
+    ss = m->core->default_sample_spec;
+    if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_WAVEEX) < 0) {
+        pa_log("failed to parse sample specification");
+        goto fail;
+    }
+
+    if (ss_to_waveformat(&ss, &wf) < 0)
+        goto fail;
+
+    u = pa_xmalloc(sizeof(struct userdata));
+
+    if (record) {
+        result = waveInOpen(&hwi, device, &wf, 0, 0, WAVE_FORMAT_DIRECT | WAVE_FORMAT_QUERY);
+        if (result != MMSYSERR_NOERROR) {
+            pa_log_warn("Sample spec not supported by WaveIn, falling back to default sample rate.");
+            ss.rate = wf.nSamplesPerSec = m->core->default_sample_spec.rate;
+        }
+        result = waveInOpen(&hwi, device, &wf, (DWORD_PTR) chunk_ready_cb, (DWORD_PTR) u, CALLBACK_FUNCTION);
+        if (result != MMSYSERR_NOERROR) {
+            char errortext[MAXERRORLENGTH];
+            pa_log("Failed to open WaveIn.");
+            if (waveInGetErrorText(result, errortext, sizeof(errortext)) == MMSYSERR_NOERROR)
+                pa_log("Error: %s", errortext);
+            goto fail;
+        }
+        if (waveInStart(hwi) != MMSYSERR_NOERROR) {
+            pa_log("failed to start waveIn");
+            goto fail;
+        }
+    }
+
+    if (playback) {
+        result = waveOutOpen(&hwo, device, &wf, 0, 0, WAVE_FORMAT_DIRECT | WAVE_FORMAT_QUERY);
+        if (result != MMSYSERR_NOERROR) {
+            pa_log_warn("Sample spec not supported by WaveOut, falling back to default sample rate.");
+            ss.rate = wf.nSamplesPerSec = m->core->default_sample_spec.rate;
+        }
+        result = waveOutOpen(&hwo, device, &wf, (DWORD_PTR) chunk_done_cb, (DWORD_PTR) u, CALLBACK_FUNCTION);
+        if (result != MMSYSERR_NOERROR) {
+            char errortext[MAXERRORLENGTH];
+            pa_log("Failed to open WaveOut.");
+            if (waveOutGetErrorText(result, errortext, sizeof(errortext)) == MMSYSERR_NOERROR)
+                pa_log("Error: %s", errortext);
+            goto fail;
+        }
+    }
+
+    InitializeCriticalSection(&u->crit);
+
+    if (hwi != INVALID_HANDLE_VALUE) {
+        char *description = pa_sprintf_malloc("WaveIn on %s", device_name);
+        pa_source_new_data data;
+        pa_source_new_data_init(&data);
+        data.driver = __FILE__;
+        data.module = m;
+        pa_source_new_data_set_sample_spec(&data, &ss);
+        pa_source_new_data_set_channel_map(&data, &map);
+        pa_source_new_data_set_name(&data, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME));
+        u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
+        pa_source_new_data_done(&data);
+
+        pa_assert(u->source);
+        u->source->userdata = u;
+        pa_source_set_description(u->source, description);
+        u->source->parent.process_msg = process_msg;
+        pa_xfree(description);
+    } else
+        u->source = NULL;
+
+    if (hwo != INVALID_HANDLE_VALUE) {
+        char *description = pa_sprintf_malloc("WaveOut on %s", device_name);
+        pa_sink_new_data data;
+        pa_sink_new_data_init(&data);
+        data.driver = __FILE__;
+        data.module = m;
+        pa_sink_new_data_set_sample_spec(&data, &ss);
+        pa_sink_new_data_set_channel_map(&data, &map);
+        pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME));
+        u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
+        pa_sink_new_data_done(&data);
+
+        pa_assert(u->sink);
+        pa_sink_set_get_volume_callback(u->sink, sink_get_volume_cb);
+        pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
+        u->sink->userdata = u;
+        pa_sink_set_description(u->sink, description);
+        u->sink->parent.process_msg = process_msg;
+        pa_xfree(description);
+    } else
+        u->sink = NULL;
+
+    pa_assert(u->source || u->sink);
+    pa_modargs_free(ma);
+
+    u->core = m->core;
+    u->hwi = hwi;
+    u->hwo = hwo;
+
+    u->fragments = nfrags;
+    u->free_ifrags = u->fragments;
+    u->free_ofrags = u->fragments;
+    u->fragment_size = frag_size - (frag_size % pa_frame_size(&ss));
+
+    u->written_bytes = 0;
+    u->sink_underflow = 1;
+
+    u->poll_timeout = pa_bytes_to_usec(u->fragments * u->fragment_size / 10, &ss);
+    pa_log_debug("Poll timeout = %.1f ms", (double) u->poll_timeout / PA_USEC_PER_MSEC);
+
+    u->cur_ihdr = 0;
+    u->cur_ohdr = 0;
+    u->ihdrs = pa_xmalloc0(sizeof(WAVEHDR) * u->fragments);
+    pa_assert(u->ihdrs);
+    u->ohdrs = pa_xmalloc0(sizeof(WAVEHDR) * u->fragments);
+    pa_assert(u->ohdrs);
+    for (i = 0; i < u->fragments; i++) {
+        u->ihdrs[i].dwBufferLength = u->fragment_size;
+        u->ohdrs[i].dwBufferLength = u->fragment_size;
+        u->ihdrs[i].lpData = pa_xmalloc(u->fragment_size);
+        pa_assert(u->ihdrs);
+        u->ohdrs[i].lpData = pa_xmalloc(u->fragment_size);
+        pa_assert(u->ohdrs);
+    }
+
+    u->module = m;
+    m->userdata = u;
+
+    /* Read mixer settings */
+    if (u->sink)
+        sink_get_volume_cb(u->sink);
+
+    u->rtpoll = pa_rtpoll_new();
+    pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
+
+    if (u->sink) {
+        pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
+        pa_sink_set_rtpoll(u->sink, u->rtpoll);
+    }
+    if (u->source) {
+        pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
+        pa_source_set_rtpoll(u->source, u->rtpoll);
+    }
+
+    if (!(u->thread = pa_thread_new("waveout", thread_func, u))) {
+        pa_log("Failed to create thread.");
+        goto fail;
+    }
+
+    if (u->sink)
+        pa_sink_put(u->sink);
+    if (u->source)
+        pa_source_put(u->source);
+
+    return 0;
+
+fail:
+    if (ma)
+        pa_modargs_free(ma);
+
+    pa__done(m);
+
+    return -1;
+}
+
+void pa__done(pa_module *m) {
+    struct userdata *u;
+    unsigned int i;
+
+    pa_assert(m);
+    pa_assert(m->core);
+
+    if (!(u = m->userdata))
+        return;
+
+    if (u->sink)
+        pa_sink_unlink(u->sink);
+    if (u->source)
+        pa_source_unlink(u->source);
+
+    pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
+    if (u->thread)
+        pa_thread_free(u->thread);
+    pa_thread_mq_done(&u->thread_mq);
+
+    if (u->sink)
+        pa_sink_unref(u->sink);
+    if (u->source)
+        pa_source_unref(u->source);
+
+    if (u->rtpoll)
+        pa_rtpoll_free(u->rtpoll);
+
+    if (u->hwi != INVALID_HANDLE_VALUE) {
+        waveInReset(u->hwi);
+        waveInClose(u->hwi);
+    }
+
+    if (u->hwo != INVALID_HANDLE_VALUE) {
+        waveOutReset(u->hwo);
+        waveOutClose(u->hwo);
+    }
+
+    for (i = 0; i < u->fragments; i++) {
+        pa_xfree(u->ihdrs[i].lpData);
+        pa_xfree(u->ohdrs[i].lpData);
+    }
+
+    pa_xfree(u->ihdrs);
+    pa_xfree(u->ohdrs);
+
+    DeleteCriticalSection(&u->crit);
+
+    pa_xfree(u);
+}
diff --git a/src/modules/module-zeroconf-discover-symdef.h b/src/modules/module-zeroconf-discover-symdef.h
deleted file mode 100644 (file)
index 7d3a601..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulezeroconfdiscoversymdeffoo
-#define foomodulezeroconfdiscoversymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_zeroconf_discover_LTX_pa__init
-#define pa__done module_zeroconf_discover_LTX_pa__done
-#define pa__get_author module_zeroconf_discover_LTX_pa__get_author
-#define pa__get_description module_zeroconf_discover_LTX_pa__get_description
-#define pa__get_usage module_zeroconf_discover_LTX_pa__get_usage
-#define pa__get_version module_zeroconf_discover_LTX_pa__get_version
-#define pa__get_deprecated module_zeroconf_discover_LTX_pa__get_deprecated
-#define pa__load_once module_zeroconf_discover_LTX_pa__load_once
-#define pa__get_n_used module_zeroconf_discover_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 1fdc1f4..4887510 100644 (file)
 #include <avahi-common/malloc.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/util.h>
 
-#include <pulsecore/sink.h>
-#include <pulsecore/source.h>
-#include <pulsecore/native-common.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
-#include <pulsecore/core-subscribe.h>
 #include <pulsecore/hashmap.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/namereg.h>
@@ -168,17 +163,17 @@ static void resolver_cb(
             char *key, *value;
             pa_assert_se(avahi_string_list_get_pair(l, &key, &value, NULL) == 0);
 
-            if (strcmp(key, "device") == 0) {
+            if (pa_streq(key, "device")) {
                 pa_xfree(device);
                 device = value;
                 value = NULL;
-            } else if (strcmp(key, "rate") == 0)
+            } else if (pa_streq(key, "rate"))
                 ss.rate = (uint32_t) atoi(value);
-            else if (strcmp(key, "channels") == 0)
+            else if (pa_streq(key, "channels"))
                 ss.channels = (uint8_t) atoi(value);
-            else if (strcmp(key, "format") == 0)
+            else if (pa_streq(key, "format"))
                 ss.format = pa_parse_sample_format(value);
-            else if (strcmp(key, "channel_map") == 0) {
+            else if (pa_streq(key, "channel_map")) {
                 pa_channel_map_parse(&cm, value);
                 channel_map_set = TRUE;
             }
@@ -431,7 +426,7 @@ void pa__done(pa_module*m) {
             tunnel_free(t);
         }
 
-        pa_hashmap_free(u->tunnels, NULL, NULL);
+        pa_hashmap_free(u->tunnels, NULL);
     }
 
     pa_xfree(u);
diff --git a/src/modules/module-zeroconf-publish-symdef.h b/src/modules/module-zeroconf-publish-symdef.h
deleted file mode 100644 (file)
index 22c428a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulezeroconfpublishsymdeffoo
-#define foomodulezeroconfpublishsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_zeroconf_publish_LTX_pa__init
-#define pa__done module_zeroconf_publish_LTX_pa__done
-#define pa__get_author module_zeroconf_publish_LTX_pa__get_author
-#define pa__get_description module_zeroconf_publish_LTX_pa__get_description
-#define pa__get_usage module_zeroconf_publish_LTX_pa__get_usage
-#define pa__get_version module_zeroconf_publish_LTX_pa__get_version
-#define pa__get_deprecated module_zeroconf_publish_LTX_pa__get_deprecated
-#define pa__load_once module_zeroconf_publish_LTX_pa__load_once
-#define pa__get_n_used module_zeroconf_publish_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index d72d264..c21ff3e 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 #include <unistd.h>
 
 #include <avahi-client/client.h>
 #include <pulsecore/native-common.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
-#include <pulsecore/core-subscribe.h>
 #include <pulsecore/dynarray.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/avahi-wrap.h>
-#include <pulsecore/endianmacros.h>
 #include <pulsecore/protocol-native.h>
 
 #include "module-zeroconf-publish-symdef.h"
@@ -329,8 +326,10 @@ static int publish_service(struct service *s) {
 finish:
 
     /* Remove this service */
-    if (r < 0)
+    if (r < 0) {
+        pa_hashmap_remove(s->userdata->services, s->device);
         service_free(s);
+    }
 
     avahi_string_list_free(txt);
 
@@ -377,8 +376,6 @@ static struct service *get_service(struct userdata *u, pa_object *device) {
 static void service_free(struct service *s) {
     pa_assert(s);
 
-    pa_hashmap_remove(s->userdata->services, s->device);
-
     if (s->entry_group) {
         pa_log_debug("Removing entry group for %s.", s->service_name);
         avahi_entry_group_free(s->entry_group);
@@ -416,7 +413,7 @@ static pa_hook_result_t device_unlink_cb(pa_core *c, pa_object *o, struct userda
     pa_assert(c);
     pa_object_assert_ref(o);
 
-    if ((s = pa_hashmap_get(u->services, o)))
+    if ((s = pa_hashmap_remove(u->services, o)))
         service_free(s);
 
     return PA_HOOK_OK;
@@ -664,14 +661,8 @@ void pa__done(pa_module*m) {
     if (!(u = m->userdata))
         return;
 
-    if (u->services) {
-        struct service *s;
-
-        while ((s = pa_hashmap_first(u->services)))
-            service_free(s);
-
-        pa_hashmap_free(u->services, NULL, NULL);
-    }
+    if (u->services)
+        pa_hashmap_free(u->services, (pa_free_cb_t) service_free);
 
     if (u->sink_new_slot)
         pa_hook_slot_free(u->sink_new_slot);
diff --git a/src/modules/oss/module-oss-symdef.h b/src/modules/oss/module-oss-symdef.h
deleted file mode 100644 (file)
index 19b4842..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleosssymdeffoo
-#define foomoduleosssymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_oss_LTX_pa__init
-#define pa__done module_oss_LTX_pa__done
-#define pa__get_author module_oss_LTX_pa__get_author
-#define pa__get_description module_oss_LTX_pa__get_description
-#define pa__get_usage module_oss_LTX_pa__get_usage
-#define pa__get_version module_oss_LTX_pa__get_version
-#define pa__get_deprecated module_oss_LTX_pa__get_deprecated
-#define pa__load_once module_oss_LTX_pa__load_once
-#define pa__get_n_used module_oss_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 7153626..fbf0d7c 100644 (file)
@@ -27,7 +27,7 @@
  *   We make no difference between IDLE and RUNNING in our handling.
  *
  *   As long as we are in RUNNING/IDLE state we will *always* write data to
- *   the device. If none is avilable from the inputs, we write silence
+ *   the device. If none is available from the inputs, we write silence
  *   instead.
  *
  *   If power should be saved on IDLE module-suspend-on-idle should be used.
 #include <sys/soundcard.h>
 #include <sys/ioctl.h>
 #include <stdlib.h>
-#include <sys/stat.h>
 #include <stdio.h>
 #include <errno.h>
-#include <string.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <limits.h>
-#include <signal.h>
-#include <poll.h>
 
 #include <pulse/xmalloc.h>
 #include <pulse/util.h>
@@ -70,6 +65,7 @@
 #include <pulsecore/macro.h>
 #include <pulsecore/thread-mq.h>
 #include <pulsecore/rtpoll.h>
+#include <pulsecore/poll.h>
 
 #if defined(__NetBSD__) && !defined(SNDCTL_DSP_GETODELAY)
 #include <sys/audioio.h>
@@ -161,15 +157,15 @@ static const char* const valid_modargs[] = {
     NULL
 };
 
-static void trigger(struct userdata *u, pa_bool_t quick) {
+static int trigger(struct userdata *u, pa_bool_t quick) {
     int enable_bits = 0, zero = 0;
 
     pa_assert(u);
 
     if (u->fd < 0)
-        return;
+        return 0;
 
-     pa_log_debug("trigger");
+    pa_log_debug("trigger");
 
     if (u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state))
         enable_bits |= PCM_ENABLE_INPUT;
@@ -214,11 +210,19 @@ static void trigger(struct userdata *u, pa_bool_t quick) {
 
             if (u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
                 uint8_t *buf = pa_xnew(uint8_t, u->in_fragment_size);
-                pa_read(u->fd, buf, u->in_fragment_size, NULL);
+
+                if (pa_read(u->fd, buf, u->in_fragment_size, NULL) < 0) {
+                    pa_log("pa_read() failed: %s", pa_cstrerror(errno));
+                    pa_xfree(buf);
+                    return -1;
+                }
+
                 pa_xfree(buf);
             }
         }
     }
+
+    return 0;
 }
 
 static void mmap_fill_memblocks(struct userdata *u, unsigned n) {
@@ -718,8 +722,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
 
     ret = pa_sink_process_msg(o, code, data, offset, chunk);
 
-    if (do_trigger)
-        trigger(u, quick);
+    if (ret >= 0 && do_trigger) {
+        if (trigger(u, quick) < 0)
+            return -1;
+    }
 
     return ret;
 }
@@ -798,8 +804,10 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
 
     ret = pa_source_process_msg(o, code, data, offset, chunk);
 
-    if (do_trigger)
-        trigger(u, quick);
+    if (ret >= 0 && do_trigger) {
+        if (trigger(u, quick) < 0)
+            return -1;
+    }
 
     return ret;
 }
@@ -848,11 +856,11 @@ static void source_get_volume(pa_source *s) {
     pa_assert(u->mixer_devmask & (SOUND_MASK_IGAIN|SOUND_MASK_RECLEV));
 
     if (u->mixer_devmask & SOUND_MASK_IGAIN)
-        if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_IGAIN, &s->sample_spec, &s->volume) >= 0)
+        if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_IGAIN, &s->sample_spec, &s->real_volume) >= 0)
             return;
 
     if (u->mixer_devmask & SOUND_MASK_RECLEV)
-        if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_RECLEV, &s->sample_spec, &s->volume) >= 0)
+        if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_RECLEV, &s->sample_spec, &s->real_volume) >= 0)
             return;
 
     pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno));
@@ -866,11 +874,11 @@ static void source_set_volume(pa_source *s) {
     pa_assert(u->mixer_devmask & (SOUND_MASK_IGAIN|SOUND_MASK_RECLEV));
 
     if (u->mixer_devmask & SOUND_MASK_IGAIN)
-        if (pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_IGAIN, &s->sample_spec, &s->volume) >= 0)
+        if (pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_IGAIN, &s->sample_spec, &s->real_volume) >= 0)
             return;
 
     if (u->mixer_devmask & SOUND_MASK_RECLEV)
-        if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_WRITE_RECLEV, &s->sample_spec, &s->volume) >= 0)
+        if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_WRITE_RECLEV, &s->sample_spec, &s->real_volume) >= 0)
             return;
 
     pa_log_info("Device doesn't support writing mixer settings: %s", pa_cstrerror(errno));
@@ -895,9 +903,8 @@ static void thread_func(void *userdata) {
 
 /*        pa_log("loop");    */
 
-        if (u->sink && PA_SINK_IS_OPENED(u->sink->thread_info.state))
-            if (u->sink->thread_info.rewind_requested)
-                pa_sink_process_rewind(u->sink, 0);
+        if (PA_UNLIKELY(u->sink && u->sink->thread_info.rewind_requested))
+            pa_sink_process_rewind(u->sink, 0);
 
         /* Render some data and write it to the dsp */
 
@@ -1422,22 +1429,19 @@ int pa__init(pa_module*m) {
 
         if (ioctl(fd, SOUND_MIXER_READ_DEVMASK, &u->mixer_devmask) < 0)
             pa_log_warn("SOUND_MIXER_READ_DEVMASK failed: %s", pa_cstrerror(errno));
-
         else {
             if (u->sink && (u->mixer_devmask & (SOUND_MASK_VOLUME|SOUND_MASK_PCM))) {
                 pa_log_debug("Found hardware mixer track for playback.");
-                u->sink->flags |= PA_SINK_HW_VOLUME_CTRL;
-                u->sink->get_volume = sink_get_volume;
-                u->sink->set_volume = sink_set_volume;
+                pa_sink_set_get_volume_callback(u->sink, sink_get_volume);
+                pa_sink_set_set_volume_callback(u->sink, sink_set_volume);
                 u->sink->n_volume_steps = 101;
                 do_close = FALSE;
             }
 
             if (u->source && (u->mixer_devmask & (SOUND_MASK_RECLEV|SOUND_MASK_IGAIN))) {
                 pa_log_debug("Found hardware mixer track for recording.");
-                u->source->flags |= PA_SOURCE_HW_VOLUME_CTRL;
-                u->source->get_volume = source_get_volume;
-                u->source->set_volume = source_set_volume;
+                pa_source_set_get_volume_callback(u->source, source_get_volume);
+                pa_source_set_set_volume_callback(u->source, source_set_volume);
                 u->source->n_volume_steps = 101;
                 do_close = FALSE;
             }
@@ -1456,7 +1460,7 @@ go_on:
 
     pa_memchunk_reset(&u->memchunk);
 
-    if (!(u->thread = pa_thread_new(thread_func, u))) {
+    if (!(u->thread = pa_thread_new("oss", thread_func, u))) {
         pa_log("Failed to create thread.");
         goto fail;
     }
index 5a109ae..3c7f0eb 100644 (file)
@@ -31,7 +31,6 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/types.h>
-#include <sys/stat.h>
 #include <fcntl.h>
 
 #include <pulse/xmalloc.h>
@@ -55,7 +54,7 @@ int pa_oss_open(const char *device, int *mode, int* pcaps) {
         pcaps = &caps;
 
     if (*mode == O_RDWR) {
-        if ((fd = open(device, O_RDWR|O_NDELAY|O_NOCTTY)) >= 0) {
+        if ((fd = pa_open_cloexec(device, O_RDWR|O_NDELAY, 0)) >= 0) {
             ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
 
             if (ioctl(fd, SNDCTL_DSP_GETCAPS, pcaps) < 0) {
@@ -71,14 +70,14 @@ int pa_oss_open(const char *device, int *mode, int* pcaps) {
             pa_close(fd);
         }
 
-        if ((fd = open(device, (*mode = O_WRONLY)|O_NDELAY|O_NOCTTY)) < 0) {
-            if ((fd = open(device, (*mode = O_RDONLY)|O_NDELAY|O_NOCTTY)) < 0) {
+        if ((fd = pa_open_cloexec(device, (*mode = O_WRONLY)|O_NDELAY, 0)) < 0) {
+            if ((fd = pa_open_cloexec(device, (*mode = O_RDONLY)|O_NDELAY, 0)) < 0) {
                 pa_log("open('%s'): %s", device, pa_cstrerror(errno));
                 goto fail;
             }
         }
     } else {
-        if ((fd = open(device, *mode|O_NDELAY|O_NOCTTY)) < 0) {
+        if ((fd = pa_open_cloexec(device, *mode|O_NDELAY, 0)) < 0) {
             pa_log("open('%s'): %s", device, pa_cstrerror(errno));
             goto fail;
         }
@@ -145,8 +144,6 @@ success:
     pa_log_debug("capabilities:%s", t);
     pa_xfree(t);
 
-    pa_make_fd_cloexec(fd);
-
     return fd;
 
 fail:
@@ -234,23 +231,14 @@ int pa_oss_auto_format(int fd, pa_sample_spec *ss) {
     return 0;
 }
 
-static int simple_log2(int v) {
-    int k = 0;
-
-    for (;;) {
-        v >>= 1;
-        if (!v) break;
-        k++;
-    }
-
-    return k;
-}
-
 int pa_oss_set_fragments(int fd, int nfrags, int frag_size) {
     int arg;
-    arg = ((int) nfrags << 16) | simple_log2(frag_size);
 
-    pa_log_debug("Asking for %i fragments of size %i (requested %i)", nfrags, 1 << simple_log2(frag_size), frag_size);
+    pa_assert(frag_size >= 0);
+
+    arg = ((int) nfrags << 16) | pa_ulog2(frag_size);
+
+    pa_log_debug("Asking for %i fragments of size %i (requested %i)", nfrags, 1 << pa_ulog2(frag_size), frag_size);
 
     if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &arg) < 0) {
         pa_log("SNDCTL_DSP_SETFRAGMENT: %s", pa_cstrerror(errno));
@@ -273,10 +261,10 @@ int pa_oss_get_volume(int fd, unsigned long mixer, const pa_sample_spec *ss, pa_
 
     pa_cvolume_reset(volume, ss->channels);
 
-    volume->values[0] = ((vol & 0xFF) * PA_VOLUME_NORM) / 100;
+    volume->values[0] = PA_CLAMP_VOLUME(((vol & 0xFF) * PA_VOLUME_NORM) / 100);
 
     if (volume->channels >= 2)
-        volume->values[1] = (((vol >> 8) & 0xFF) * PA_VOLUME_NORM) / 100;
+        volume->values[1] = PA_CLAMP_VOLUME((((vol >> 8) & 0xFF) * PA_VOLUME_NORM) / 100);
 
     pa_log_debug("Read mixer settings: %s", pa_cvolume_snprint(cv, sizeof(cv), volume));
     return 0;
@@ -351,9 +339,9 @@ int pa_oss_get_hw_description(const char *dev, char *name, size_t l) {
     if ((n = get_device_number(dev)) < 0)
         return -1;
 
-    if (!(f = fopen("/dev/sndstat", "r")) &&
-        !(f = fopen("/proc/sndstat", "r")) &&
-        !(f = fopen("/proc/asound/oss/sndstat", "r"))) {
+    if (!(f = pa_fopen_cloexec("/dev/sndstat", "r")) &&
+        !(f = pa_fopen_cloexec("/proc/sndstat", "r")) &&
+        !(f = pa_fopen_cloexec("/proc/asound/oss/sndstat", "r"))) {
 
         if (errno != ENOENT)
             pa_log_warn("failed to open OSS sndstat device: %s", pa_cstrerror(errno));
@@ -371,7 +359,7 @@ int pa_oss_get_hw_description(const char *dev, char *name, size_t l) {
         line[strcspn(line, "\r\n")] = 0;
 
         if (!b) {
-            b = strcmp(line, "Audio devices:") == 0;
+            b = pa_streq(line, "Audio devices:");
             continue;
         }
 
@@ -403,7 +391,7 @@ int pa_oss_get_hw_description(const char *dev, char *name, size_t l) {
 static int open_mixer(const char *mixer) {
     int fd;
 
-    if ((fd = open(mixer, O_RDWR|O_NDELAY|O_NOCTTY)) >= 0)
+    if ((fd = pa_open_cloexec(mixer, O_RDWR|O_NDELAY, 0)) >= 0)
         return fd;
 
     return -1;
diff --git a/src/modules/pm-util.c b/src/modules/pm-util.c
new file mode 100644 (file)
index 0000000..9a6065a
--- /dev/null
@@ -0,0 +1,330 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2013 Seungbae Shin <seungbae.shin@samsung.com>
+  Copyright 2013 Seunghun Pi <sh.pi@samsung.com>
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <dbus/dbus.h>
+
+#include "pm-util.h"
+
+#include <pulsecore/log.h>
+
+#define BUS_NAME       "org.tizen.system.deviced"
+#define OBJECT_PATH    "/Org/Tizen/System/DeviceD"
+#define INTERFACE_NAME BUS_NAME
+
+#define DEVICED_PATH_DISPLAY           OBJECT_PATH"/Display"
+#define DEVICED_INTERFACE_DISPLAY      INTERFACE_NAME".display"
+
+#define METHOD_LOCK_STATE              "lockstate"
+#define METHOD_UNLOCK_STATE            "unlockstate"
+#define METHOD_CHANGE_STATE            "changestate"
+
+#define STR_LCD_OFF   "lcdoff"
+#define STR_LCD_DIM   "lcddim"
+#define STR_LCD_ON    "lcdon"
+#define STR_SUSPEND   "suspend"
+
+#define STR_STAYCURSTATE "staycurstate"
+#define STR_GOTOSTATENOW "gotostatenow"
+
+#define STR_HOLDKEYBLOCK "holdkeyblock"
+#define STR_STANDBYMODE  "standbymode"
+#define STR_NULL         "NULL"
+
+#define STR_SLEEP_MARGIN "sleepmargin"
+#define STR_RESET_TIMER  "resettimer"
+#define STR_KEEP_TIMER   "keeptimer"
+
+#define DBG(fmt, argc...)   pa_log_debug_verbose(fmt"\n", ##argc)
+#define ERR(fmt, argc...)   pa_log_error(fmt"\n", ##argc)
+
+#define DBUS_REPLY_TIMEOUT (120 * 1000)
+
+static int append_variant(DBusMessageIter *iter, const char *sig, char *param[])
+{
+    char *ch;
+    int i;
+    int int_type;
+    uint64_t int64_type;
+
+    if (!sig || !param)
+        return 0;
+
+    for (ch = (char*)sig, i = 0; *ch != '\0'; ++i, ++ch) {
+        switch (*ch) {
+        case 'i':
+            int_type = atoi(param[i]);
+            dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int_type);
+            break;
+        case 'u':
+            int_type = atoi(param[i]);
+            dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &int_type);
+            break;
+        case 't':
+            int64_type = atoi(param[i]);
+            dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &int64_type);
+            break;
+        case 's':
+            dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &param[i]);
+            break;
+        default:
+            return -EINVAL;
+        }
+    }
+
+    return 0;
+}
+
+static DBusMessage *invoke_dbus_method_sync(const char *dest, const char *path,
+        const char *interface, const char *method,
+        const char *sig, char *param[])
+{
+    DBusConnection *conn;
+    DBusMessage *msg;
+    DBusMessageIter iter;
+    DBusMessage *reply;
+    DBusError err;
+    int r;
+
+    conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+    if (!conn) {
+        ERR("dbus_bus_get error");
+        return NULL;
+    }
+
+    msg = dbus_message_new_method_call(dest, path, interface, method);
+    if (!msg) {
+        ERR("dbus_message_new_method_call(%s:%s-%s)", path, interface, method);
+        return NULL;
+    }
+
+    dbus_message_iter_init_append(msg, &iter);
+    r = append_variant(&iter, sig, param);
+    if (r < 0) {
+        ERR("append_variant error(%d)", r);
+        return NULL;
+    }
+
+    dbus_error_init(&err);
+
+    reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_REPLY_TIMEOUT, &err);
+    if (!reply) {
+        ERR("dbus_connection_send error(No reply)");
+    }
+
+    if (dbus_error_is_set(&err)) {
+        ERR("dbus_connection_send error(%s:%s)", err.name, err.message);
+        reply = NULL;
+    }
+
+    dbus_message_unref(msg);
+    dbus_error_free(&err);
+
+    return reply;
+}
+
+#ifdef PM_ASYNC
+/*Async functions are added because sync functions take about 600ms sometimes*/
+static bool invoke_dbus_method_async(const char *dest, const char *path,
+        const char *interface, const char *method,
+        const char *sig, char *param[])
+{
+    DBusConnection *conn;
+    DBusMessage *msg;
+    DBusMessageIter iter;
+    DBusError err;
+    bool result;
+    int r;
+
+    conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+    if (!conn) {
+        ERR("dbus_bus_get error");
+        return NULL;
+    }
+
+    msg = dbus_message_new_method_call(dest, path, interface, method);
+    if (!msg) {
+        ERR("dbus_message_new_method_call(%s:%s-%s)", path, interface, method);
+        return NULL;
+    }
+
+    dbus_message_iter_init_append(msg, &iter);
+    r = append_variant(&iter, sig, param);
+    if (r < 0) {
+        ERR("append_variant error(%d)", r);
+        return NULL;
+    }
+
+    dbus_error_init(&err);
+
+    result= dbus_connection_send(conn, msg, NULL);
+    if (!result) {
+        ERR("dbus_connection_send error");
+    }
+
+    if (dbus_error_is_set(&err)) {
+        ERR("dbus_connection_send error(%s:%s)", err.name, err.message);
+    }
+
+    dbus_message_unref(msg);
+
+    return result;
+}
+#endif
+
+static int display_lock_state(char *state, char *flag, unsigned int timeout)
+{
+    DBusError err;
+    DBusMessage *msg;
+    char *pa[4];
+    char str_timeout[32];
+    int ret, val;
+
+    pa[0] = state;
+    pa[1] = flag;
+    pa[2] = STR_NULL;
+    snprintf(str_timeout, sizeof(str_timeout), "%d", timeout);
+    pa[3] = str_timeout;
+
+    msg = invoke_dbus_method_sync(BUS_NAME, DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+            METHOD_LOCK_STATE, "sssi", pa);
+    if (!msg)
+        return -EBADMSG;
+
+    dbus_error_init(&err);
+
+    ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+    if (!ret) {
+        ERR("no message : [%s:%s]", err.name, err.message);
+        val = -EBADMSG;
+    }
+    dbus_message_unref(msg);
+    dbus_error_free(&err);
+
+    DBG("%s-%s : %d", DEVICED_INTERFACE_DISPLAY, METHOD_LOCK_STATE, val);
+    return val;
+}
+
+#ifdef PM_ASYNC
+/*Async functions are added because sync functions take about 600ms sometimes*/
+static int display_lock_state_async(char *state, char *flag, unsigned int timeout)
+{
+    char *pa[4];
+    char str_timeout[32];
+    int ret = 0, val = 0;
+
+    pa[0] = state;
+    pa[1] = flag;
+    pa[2] = STR_NULL;
+    snprintf(str_timeout, sizeof(str_timeout), "%d", timeout);
+    pa[3] = str_timeout;
+    ret = invoke_dbus_method_async(BUS_NAME, DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+            METHOD_LOCK_STATE, "sssi", pa);
+
+    if (!ret) {
+        ERR("invoke_dbus_method_async failed");
+        val = -ECOMM;
+    }
+
+    return val;
+}
+#endif
+
+static int display_unlock_state(char *state, char *flag)
+{
+    DBusError err;
+    DBusMessage *msg;
+    char *pa[2];
+    int ret, val;
+
+    pa[0] = state;
+    pa[1] = flag;
+
+    msg = invoke_dbus_method_sync(BUS_NAME, DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+            METHOD_UNLOCK_STATE, "ss", pa);
+    if (!msg)
+        return -EBADMSG;
+
+    dbus_error_init(&err);
+
+    ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+    if (!ret) {
+        ERR("no message : [%s:%s]", err.name, err.message);
+        val = -EBADMSG;
+    }
+
+    dbus_message_unref(msg);
+    dbus_error_free(&err);
+
+    DBG("%s-%s : %d", DEVICED_INTERFACE_DISPLAY, METHOD_UNLOCK_STATE, val);
+    return val;
+
+}
+
+#ifdef PM_ASYNC
+/*Async functions are added because sync functions take about 600ms sometimes*/
+static int display_unlock_state_async(char *state, char *flag)
+{
+    char *pa[2];
+    int ret = 0, val = 0;
+
+    pa[0] = state;
+    pa[1] = flag;
+
+    ret = invoke_dbus_method_async(BUS_NAME, DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+            METHOD_UNLOCK_STATE, "ss", pa);
+
+    if (!ret) {
+        ERR("invoke_dbus_method_async failed");
+        val = -ECOMM;
+    }
+
+    return val;
+}
+#endif
+
+/* EXPORT Functions */
+int pm_display_lock (void)
+{
+#ifdef PM_ASYNC
+    return display_lock_state_async(STR_LCD_OFF, STR_STAYCURSTATE, 0);
+#else
+    return display_lock_state(STR_LCD_OFF, STR_STAYCURSTATE, 0);
+#endif
+}
+
+int pm_display_unlock (void)
+{
+#ifdef PM_ASYNC
+    return display_unlock_state_async(STR_LCD_OFF, STR_SLEEP_MARGIN);
+#else
+    return display_unlock_state(STR_LCD_OFF, STR_SLEEP_MARGIN);
+#endif
+}
similarity index 81%
rename from src/modules/hal-util.h
rename to src/modules/pm-util.h
index 19e41d7..3b4de34 100644 (file)
@@ -1,10 +1,10 @@
-#ifndef foohalutilhfoo
-#define foohalutilhfoo
+#ifndef foopmutilhfoo
+#define foopmutilhfoo
 
 /***
   This file is part of PulseAudio.
 
-  Copyright 2009 Lennart Poettering
+  Copyright 2013 Seungbae Shin <seungbae.shin@samsung.com>
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   USA.
 ***/
-
-
-#include <pulsecore/core.h>
-
-int pa_hal_get_info(pa_core *core, pa_proplist *p, int card);
+int pm_display_lock (void);
+int pm_display_unlock (void);
 
 #endif
index 5b06103..37e4762 100644 (file)
@@ -38,8 +38,7 @@
 static const char base64_chars[] =
     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
-static int pos(char c)
-{
+static int pos(char c) {
     if (c >= 'A' && c <= 'Z') return c - 'A' + 0;
     if (c >= 'a' && c <= 'z') return c - 'a' + 26;
     if (c >= '0' && c <= '9') return c - '0' + 52;
@@ -48,8 +47,7 @@ static int pos(char c)
     return -1;
 }
 
-int pa_base64_encode(const void *data, int size, char **str)
-{
+int pa_base64_encode(const void *data, int size, char **str) {
     char *s, *p;
     int i;
     int c;
@@ -84,8 +82,7 @@ int pa_base64_encode(const void *data, int size, char **str)
 
 #define DECODE_ERROR 0xffffffff
 
-static unsigned int token_decode(const char *token)
-{
+static unsigned int token_decode(const char *token) {
     int i;
     unsigned int val = 0;
     int marker = 0;
@@ -109,8 +106,7 @@ static unsigned int token_decode(const char *token)
     return (marker << 24) | val;
 }
 
-int pa_base64_decode(const char *str, void *data)
-{
+int pa_base64_decode(const char *str, void *data) {
     const char *p;
     unsigned char *q;
 
diff --git a/src/modules/raop/module-raop-discover-symdef.h b/src/modules/raop/module-raop-discover-symdef.h
deleted file mode 100644 (file)
index cdeeb9b..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleraopdiscoversymdeffoo
-#define foomoduleraopdiscoversymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_raop_discover_LTX_pa__init
-#define pa__done module_raop_discover_LTX_pa__done
-#define pa__get_author module_raop_discover_LTX_pa__get_author
-#define pa__get_description module_raop_discover_LTX_pa__get_description
-#define pa__get_usage module_raop_discover_LTX_pa__get_usage
-#define pa__get_version module_raop_discover_LTX_pa__get_version
-#define pa__get_deprecated module_raop_discover_LTX_pa__get_deprecated
-#define pa__load_once module_raop_discover_LTX_pa__load_once
-#define pa__get_n_used module_raop_discover_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index adba8e4..3db2c0e 100644 (file)
 #include <avahi-common/malloc.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/util.h>
 
-#include <pulsecore/sink.h>
-#include <pulsecore/source.h>
-#include <pulsecore/native-common.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
-#include <pulsecore/core-subscribe.h>
 #include <pulsecore/hashmap.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/namereg.h>
@@ -161,7 +156,9 @@ static void resolver_cb(
             ++nicename;
             if (strlen(nicename) > 0) {
                 pa_log_debug("Found RAOP: %s", nicename);
-            }
+                nicename = pa_escape(nicename, "\"'");
+            } else
+                nicename = NULL;
         }
 
         for (l = txt; l; l = l->next) {
@@ -169,7 +166,7 @@ static void resolver_cb(
             pa_assert_se(avahi_string_list_get_pair(l, &key, &value, NULL) == 0);
 
             pa_log_debug("Found key: '%s' with value: '%s'", key, value);
-            if (strcmp(key, "device") == 0) {
+            if (pa_streq(key, "device")) {
                 pa_xfree(device);
                 device = value;
                 value = NULL;
@@ -191,24 +188,18 @@ static void resolver_cb(
         }
         pa_xfree(dname);
 
-        /*
-         TODO: allow this syntax of server name in things....
-        args = pa_sprintf_malloc("server=[%s]:%u "
-                                 "sink_name=%s",
-                                 avahi_address_snprint(at, sizeof(at), a), port,
-                                 vname);*/
         if (nicename) {
-            args = pa_sprintf_malloc("server=%s "
+            args = pa_sprintf_malloc("server=[%s]:%u "
                                      "sink_name=%s "
-                                     "description=\"%s\"",
-                                     avahi_address_snprint(at, sizeof(at), a),
+                                     "sink_properties='device.description=\"%s\"'",
+                                     avahi_address_snprint(at, sizeof(at), a), port,
                                      vname,
                                      nicename);
-
+            pa_xfree(nicename);
         } else {
-            args = pa_sprintf_malloc("server=%s "
+            args = pa_sprintf_malloc("server=[%s]:%u "
                                      "sink_name=%s",
-                                     avahi_address_snprint(at, sizeof(at), a),
+                                     avahi_address_snprint(at, sizeof(at), a), port,
                                      vname);
         }
 
@@ -390,7 +381,7 @@ void pa__done(pa_module*m) {
             tunnel_free(t);
         }
 
-        pa_hashmap_free(u->tunnels, NULL, NULL);
+        pa_hashmap_free(u->tunnels, NULL);
     }
 
     pa_xfree(u);
diff --git a/src/modules/raop/module-raop-sink-symdef.h b/src/modules/raop/module-raop-sink-symdef.h
deleted file mode 100644 (file)
index 3ccf4d7..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomoduleraopsinksymdeffoo
-#define foomoduleraopsinksymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_raop_sink_LTX_pa__init
-#define pa__done module_raop_sink_LTX_pa__done
-#define pa__get_author module_raop_sink_LTX_pa__get_author
-#define pa__get_description module_raop_sink_LTX_pa__get_description
-#define pa__get_usage module_raop_sink_LTX_pa__get_usage
-#define pa__get_version module_raop_sink_LTX_pa__get_version
-#define pa__get_deprecated module_raop_sink_LTX_pa__get_deprecated
-#define pa__load_once module_raop_sink_LTX_pa__load_once
-#define pa__get_n_used module_raop_sink_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index ac48ab1..1816fee 100644 (file)
 #endif
 
 #include <stdlib.h>
-#include <sys/stat.h>
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
-#include <fcntl.h>
 #include <unistd.h>
-#include <limits.h>
-#include <poll.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <pulse/xmalloc.h>
 
 #include <pulsecore/core-error.h>
-#include <pulsecore/iochannel.h>
 #include <pulsecore/sink.h>
 #include <pulsecore/module.h>
-#include <pulsecore/core-rtclock.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/modargs.h>
 #include <pulsecore/log.h>
 #include <pulsecore/socket-client.h>
-#include <pulsecore/authkey.h>
 #include <pulsecore/thread-mq.h>
 #include <pulsecore/thread.h>
 #include <pulsecore/time-smoother.h>
-#include <pulsecore/socket-util.h>
+#include <pulsecore/poll.h>
 
 #include "module-raop-sink-symdef.h"
 #include "rtp.h"
@@ -125,7 +118,6 @@ static const char* const valid_modargs[] = {
     "format",
     "rate",
     "channels",
-    "description", /* supported for compatibility reasons, made redundant by sink_properties= */
     NULL
 };
 
@@ -243,10 +235,12 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
         }
 
         case SINK_MESSAGE_RIP_SOCKET: {
-            pa_assert(u->fd >= 0);
-
-            pa_close(u->fd);
-            u->fd = -1;
+            if (u->fd >= 0) {
+                pa_close(u->fd);
+                u->fd = -1;
+            } else
+                /* FIXME */
+                pa_log("We should not get to this state. Cannot rip socket if not connected.");
 
             if (u->sink->thread_info.state == PA_SINK_SUSPENDED) {
 
@@ -256,7 +250,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
                     pa_rtpoll_item_free(u->rtpoll_item);
                 u->rtpoll_item = NULL;
             } else {
-                /* Quesiton: is this valid here: or should we do some sort of:
+                /* Question: is this valid here: or should we do some sort of:
                    return pa_sink_process_msg(PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL);
                    ?? */
                 pa_module_unload_request(u->module, TRUE);
@@ -295,7 +289,7 @@ static void sink_set_volume_cb(pa_sink *s) {
     pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &hw));
     pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->soft_volume));
 
-    /* Any necessary software volume manipulateion is done so set
+    /* Any necessary software volume manipulation is done so set
        our hw volume (or v as a single value) on the device */
     pa_raop_client_set_volume(u->raop, v);
 }
@@ -333,9 +327,8 @@ static void thread_func(void *userdata) {
     for (;;) {
         int ret;
 
-        if (PA_SINK_IS_OPENED(u->sink->thread_info.state))
-            if (u->sink->thread_info.rewind_requested)
-                pa_sink_process_rewind(u->sink, 0);
+        if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
+            pa_sink_process_rewind(u->sink, 0);
 
         if (u->rtpoll_item) {
             struct pollfd *pollfd;
@@ -514,7 +507,7 @@ int pa__init(pa_module*m) {
     struct userdata *u = NULL;
     pa_sample_spec ss;
     pa_modargs *ma = NULL;
-    const char *server, *desc;
+    const char *server;
     pa_sink_new_data data;
 
     pa_assert(m);
@@ -584,10 +577,7 @@ int pa__init(pa_module*m) {
     pa_sink_new_data_set_sample_spec(&data, &ss);
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, server);
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "music");
-    if ((desc = pa_modargs_get_value(ma, "description", NULL)))
-        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, desc);
-    else
-        pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "RAOP sink '%s'", server);
+    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "RAOP sink '%s'", server);
 
     if (pa_modargs_get_proplist(ma, "sink_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
         pa_log("Invalid properties");
@@ -605,9 +595,9 @@ int pa__init(pa_module*m) {
 
     u->sink->parent.process_msg = sink_process_msg;
     u->sink->userdata = u;
-    u->sink->set_volume = sink_set_volume_cb;
-    u->sink->set_mute = sink_set_mute_cb;
-    u->sink->flags = PA_SINK_LATENCY|PA_SINK_NETWORK|PA_SINK_HW_VOLUME_CTRL;
+    pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
+    pa_sink_set_set_mute_callback(u->sink, sink_set_mute_cb);
+    u->sink->flags = PA_SINK_LATENCY|PA_SINK_NETWORK;
 
     pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
     pa_sink_set_rtpoll(u->sink, u->rtpoll);
@@ -620,7 +610,7 @@ int pa__init(pa_module*m) {
     pa_raop_client_set_callback(u->raop, on_connection, u);
     pa_raop_client_set_closed_callback(u->raop, on_close, u);
 
-    if (!(u->thread = pa_thread_new(thread_func, u))) {
+    if (!(u->thread = pa_thread_new("raop-sink", thread_func, u))) {
         pa_log("Failed to create thread.");
         goto fail;
     }
index c4b0237..b11cafb 100644 (file)
 #include <config.h>
 #endif
 
-#include <fcntl.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <arpa/inet.h>
 #include <unistd.h>
 #include <sys/ioctl.h>
 
 
 #include <pulsecore/core-error.h>
 #include <pulsecore/core-util.h>
+#include <pulsecore/iochannel.h>
 #include <pulsecore/socket-util.h>
 #include <pulsecore/log.h>
+#include <pulsecore/parseaddr.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/strbuf.h>
+#include <pulsecore/memchunk.h>
 #include <pulsecore/random.h>
 
-#ifdef HAVE_POLL_H
-#include <poll.h>
-#else
-#include <pulsecore/poll.h>
-#endif
-
 #include "raop_client.h"
 #include "rtsp_client.h"
 #include "base64.h"
 #define VOLUME_MIN -144
 #define VOLUME_MAX 0
 
+#define RAOP_PORT 5000
+
 
 struct pa_raop_client {
     pa_core *core;
     char *host;
+    uint16_t port;
     char *sid;
     pa_rtsp_client *rtsp;
 
@@ -117,7 +114,7 @@ static inline void bit_writer(uint8_t **buffer, uint8_t *bit_pos, int *size, uin
     if (!data_bit_len)
         return;
 
-    /* If bit pos is zero, we will definatly use at least one bit from the current byte so size increments. */
+    /* If bit pos is zero, we will definately use at least one bit from the current byte so size increments. */
     if (!*bit_pos)
         *size += 1;
 
@@ -135,7 +132,7 @@ static inline void bit_writer(uint8_t **buffer, uint8_t *bit_pos, int *size, uin
             **buffer = bit_data;
         /* If our data fits exactly into the current byte, we need to increment our pointer */
         if (0 == bit_overflow) {
-            /* Do not increment size as it will be incremeneted on next call as bit_pos is zero */
+            /* Do not increment size as it will be incremented on next call as bit_pos is zero */
             *buffer += 1;
             *bit_pos = 0;
         } else {
@@ -179,8 +176,7 @@ static int rsa_encrypt(uint8_t *text, int len, uint8_t *res) {
     return size;
 }
 
-static int aes_encrypt(pa_raop_client* c, uint8_t *data, int size)
-{
+static int aes_encrypt(pa_raop_client* c, uint8_t *data, int size) {
     uint8_t *buf;
     int i=0, j;
 
@@ -199,8 +195,7 @@ static int aes_encrypt(pa_raop_client* c, uint8_t *data, int size)
     return i;
 }
 
-static inline void rtrimchar(char *str, char rc)
-{
+static inline void rtrimchar(char *str, char rc) {
     char *sp = str + strlen(str) - 1;
     while (sp >= str && *sp == rc) {
         *sp = '\0';
@@ -228,7 +223,6 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata
     c->fd = pa_iochannel_get_send_fd(io);
 
     pa_iochannel_set_noclose(io, TRUE);
-    pa_iochannel_socket_set_sndbuf(io, 1024);
     pa_iochannel_free(io);
 
     pa_make_tcp_socket_low_delay(c->fd);
@@ -237,8 +231,7 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata
     c->callback(c->fd, c->userdata);
 }
 
-static void rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist* headers, void *userdata)
-{
+static void rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist* headers, void *userdata) {
     pa_raop_client* c = userdata;
     pa_assert(c);
     pa_assert(rtsp);
@@ -310,11 +303,11 @@ static void rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist* he
                 while ((token = pa_split(aj, delimiters, &token_state))) {
                     if ((pc = strstr(token, "="))) {
                       *pc = 0;
-                      if (!strcmp(token, "type") && !strcmp(pc+1, "digital")) {
+                      if (pa_streq(token, "type") && pa_streq(pc+1, "digital")) {
                           c->jack_type = JACK_TYPE_DIGITAL;
                       }
                     } else {
-                        if (!strcmp(token,"connected"))
+                        if (pa_streq(token, "connected"))
                             c->jack_status = JACK_STATUS_CONNECTED;
                     }
                     pa_xfree(token);
@@ -373,16 +366,24 @@ static void rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist* he
     }
 }
 
-pa_raop_client* pa_raop_client_new(pa_core *core, const char* host)
-{
+pa_raop_client* pa_raop_client_new(pa_core *core, const char* host) {
+    pa_parsed_address a;
     pa_raop_client* c = pa_xnew0(pa_raop_client, 1);
 
     pa_assert(core);
     pa_assert(host);
 
+    if (pa_parse_address(host, &a) < 0 || a.type == PA_PARSED_ADDRESS_UNIX)
+        return NULL;
+
     c->core = core;
     c->fd = -1;
-    c->host = pa_xstrdup(host);
+
+    c->host = pa_xstrdup(a.path_or_host);
+    if (a.port)
+        c->port = a.port;
+    else
+        c->port = RAOP_PORT;
 
     if (pa_raop_connect(c)) {
         pa_raop_client_free(c);
@@ -392,19 +393,19 @@ pa_raop_client* pa_raop_client_new(pa_core *core, const char* host)
 }
 
 
-void pa_raop_client_free(pa_raop_client* c)
-{
+void pa_raop_client_free(pa_raop_client* c) {
     pa_assert(c);
 
     if (c->rtsp)
         pa_rtsp_client_free(c->rtsp);
+    if (c->sid)
+        pa_xfree(c->sid);
     pa_xfree(c->host);
     pa_xfree(c);
 }
 
 
-int pa_raop_connect(pa_raop_client* c)
-{
+int pa_raop_connect(pa_raop_client* c) {
     char *sci;
     struct {
         uint32_t a;
@@ -419,7 +420,7 @@ int pa_raop_connect(pa_raop_client* c)
         return 0;
     }
 
-    c->rtsp = pa_rtsp_client_new(c->core->mainloop, c->host, 5000, "iTunes/4.6 (Macintosh; U; PPC Mac OS X 10.3)");
+    c->rtsp = pa_rtsp_client_new(c->core->mainloop, c->host, c->port, "iTunes/4.6 (Macintosh; U; PPC Mac OS X 10.3)");
 
     /* Initialise the AES encryption system */
     pa_random(c->aes_iv, sizeof(c->aes_iv));
@@ -438,8 +439,7 @@ int pa_raop_connect(pa_raop_client* c)
 }
 
 
-int pa_raop_flush(pa_raop_client* c)
-{
+int pa_raop_flush(pa_raop_client* c) {
     pa_assert(c);
 
     pa_rtsp_flush(c->rtsp, c->seq, c->rtptime);
@@ -447,8 +447,7 @@ int pa_raop_flush(pa_raop_client* c)
 }
 
 
-int pa_raop_client_set_volume(pa_raop_client* c, pa_volume_t volume)
-{
+int pa_raop_client_set_volume(pa_raop_client* c, pa_volume_t volume) {
     int rv;
     double db;
     char *param;
@@ -470,8 +469,7 @@ int pa_raop_client_set_volume(pa_raop_client* c, pa_volume_t volume)
 }
 
 
-int pa_raop_client_encode_sample(pa_raop_client* c, pa_memchunk* raw, pa_memchunk* encoded)
-{
+int pa_raop_client_encode_sample(pa_raop_client* c, pa_memchunk* raw, pa_memchunk* encoded) {
     uint16_t len;
     size_t bufmax;
     uint8_t *bp, bpos;
@@ -538,7 +536,7 @@ int pa_raop_client_encode_sample(pa_raop_client* c, pa_memchunk* raw, pa_memchun
     pa_memblock_release(raw->memblock);
     encoded->length = header_size + size;
 
-    /* store the lenght (endian swapped: make this better) */
+    /* store the length (endian swapped: make this better) */
     len = size + header_size - 4;
     *(b + 2) = len >> 8;
     *(b + 3) = len & 0xff;
@@ -553,16 +551,14 @@ int pa_raop_client_encode_sample(pa_raop_client* c, pa_memchunk* raw, pa_memchun
 }
 
 
-void pa_raop_client_set_callback(pa_raop_client* c, pa_raop_client_cb_t callback, void *userdata)
-{
+void pa_raop_client_set_callback(pa_raop_client* c, pa_raop_client_cb_t callback, void *userdata) {
     pa_assert(c);
 
     c->callback = callback;
     c->userdata = userdata;
 }
 
-void pa_raop_client_set_closed_callback(pa_raop_client* c, pa_raop_client_closed_cb_t callback, void *userdata)
-{
+void pa_raop_client_set_closed_callback(pa_raop_client* c, pa_raop_client_closed_cb_t callback, void *userdata) {
     pa_assert(c);
 
     c->closed_callback = callback;
index 5ad3e3f..ce81f39 100644 (file)
@@ -22,8 +22,6 @@
   USA.
 ***/
 
-#include <pulse/mainloop-api.h>
-#include <pulsecore/iochannel.h>
 #include <pulsecore/core.h>
 
 typedef struct pa_raop_client pa_raop_client;
index ab453e6..70de870 100644 (file)
@@ -32,6 +32,7 @@
 #include <assert.h>
 
 #include "reserve-monitor.h"
+#include "reserve.h"
 
 struct rm_monitor {
        int ref;
@@ -59,6 +60,23 @@ struct rm_monitor {
        "member='NameOwnerChanged',"            \
        "arg0='%s'"
 
+static unsigned get_busy(
+       DBusConnection *c,
+       const char *name_owner) {
+
+       const char *un;
+
+       if (!name_owner || !*name_owner)
+               return FALSE;
+
+       /* If we ourselves own the device, then don't consider this 'busy' */
+       if ((un = dbus_bus_get_unique_name(c)))
+               if (strcmp(name_owner, un) == 0)
+                       return FALSE;
+
+       return TRUE;
+}
+
 static DBusHandlerResult filter_handler(
        DBusConnection *c,
        DBusMessage *s,
@@ -85,18 +103,11 @@ static DBusHandlerResult filter_handler(
                        goto invalid;
 
                if (strcmp(name, m->service_name) == 0) {
-                       m->busy = !!(new && *new);
+                       unsigned old_busy = m->busy;
 
-                       /* If we ourselves own the device, then don't consider this 'busy' */
-                       if (m->busy) {
-                               const char *un;
+                       m->busy = get_busy(c, new);
 
-                               if ((un = dbus_bus_get_unique_name(c)))
-                                       if (strcmp(new, un) == 0)
-                                               m->busy = FALSE;
-                       }
-
-                       if (m->change_cb) {
+                       if (m->busy != old_busy && m->change_cb) {
                                m->ref++;
                                m->change_cb(m);
                                rm_release(m);
@@ -113,11 +124,12 @@ invalid:
 int rm_watch(
        rm_monitor **_m,
        DBusConnection *connection,
-       const char*device_name,
+       const char *device_name,
        rm_change_cb_t change_cb,
        DBusError *error)  {
 
        rm_monitor *m = NULL;
+       char *name_owner;
        int r;
        DBusError _error;
 
@@ -176,12 +188,11 @@ int rm_watch(
 
        m->matching = 1;
 
-       m->busy = dbus_bus_name_has_owner(m->connection, m->service_name, error);
-
-       if (dbus_error_is_set(error)) {
-               r = -EIO;
+       if ((r = rd_dbus_get_name_owner(m->connection, m->service_name, &name_owner, error)) < 0)
                goto fail;
-       }
+
+       m->busy = get_busy(m->connection, name_owner);
+       free(name_owner);
 
        *_m = m;
        return 0;
index 421a52e..85a7ebb 100644 (file)
@@ -28,7 +28,6 @@
 ***/
 
 #include <dbus/dbus.h>
-#include <inttypes.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -46,7 +45,7 @@ typedef void (*rm_change_cb_t)(rm_monitor *m);
  * DBus error might be set as well if the error was caused D-Bus. */
 int rm_watch(
        rm_monitor **m,              /* On success a pointer to the newly allocated rm_device object will be filled in here */
-       DBusConnection *connection,  /* Session bus (when D-Bus learns about user busses we should switchg to user busses) */
+       DBusConnection *connection,  /* Session bus (when D-Bus learns about user busses we should switch to user busses) */
        const char *device_name,     /* The device to monitor, e.g. "Audio0" */
        rm_change_cb_t change_cb,    /* Will be called whenever the lock status changes. May be NULL */
        DBusError *error);           /* If we fail due to a D-Bus related issue the error will be filled in here. May be NULL. */
index 4be19c7..1411d27 100644 (file)
 #include <errno.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/i18n.h>
 
 #include <pulsecore/core-error.h>
 #include <pulsecore/core-util.h>
+#include <pulsecore/i18n.h>
 #include <pulsecore/shared.h>
 
 #ifdef HAVE_DBUS
@@ -105,9 +105,9 @@ static int request_cb(rd_device *d, int forced) {
 
 pa_reserve_wrapper* pa_reserve_wrapper_get(pa_core *c, const char *device_name) {
     pa_reserve_wrapper *r;
-    int k;
     char *t;
 #ifdef HAVE_DBUS
+    int k;
     DBusError error;
 
     dbus_error_init(&error);
@@ -248,9 +248,9 @@ static void change_cb(rm_monitor *m) {
 
 pa_reserve_monitor_wrapper* pa_reserve_monitor_wrapper_get(pa_core *c, const char *device_name) {
     pa_reserve_monitor_wrapper *w;
-    int k;
     char *t;
 #ifdef HAVE_DBUS
+    int k;
     DBusError error;
 
     dbus_error_init(&error);
index b4c168c..f78805e 100644 (file)
@@ -293,6 +293,7 @@ static DBusHandlerResult filter_handler(
 
        rd_device *d;
        DBusError error;
+       char *name_owner = NULL;
 
        dbus_error_init(&error);
 
@@ -310,6 +311,21 @@ static DBusHandlerResult filter_handler(
                        goto invalid;
 
                if (strcmp(name, d->service_name) == 0 && d->owning) {
+                       /* Verify the actual owner of the name to avoid leaked NameLost
+                        * signals from previous reservations. The D-Bus daemon will send
+                        * all messages asynchronously in the correct order, but we could
+                        * potentially process them too late due to the pseudo-blocking
+                        * call mechanism used during both acquisition and release. This
+                        * can happen if we release the device and immediately after
+                        * reacquire it before NameLost is processed. */
+                       if (!d->gave_up) {
+                               const char *un;
+
+                               if ((un = dbus_bus_get_unique_name(c)) && rd_dbus_get_name_owner(c, d->service_name, &name_owner, &error) == 0)
+                                       if (strcmp(name_owner, un) == 0)
+                                               goto invalid; /* Name still owned by us */
+                       }
+
                        d->owning = 0;
 
                        if (!d->gave_up)  {
@@ -326,6 +342,7 @@ static DBusHandlerResult filter_handler(
        }
 
 invalid:
+       free(name_owner);
        dbus_error_free(&error);
 
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -606,3 +623,59 @@ void* rd_get_userdata(rd_device *d) {
 
        return d->userdata;
 }
+
+int rd_dbus_get_name_owner(
+       DBusConnection *connection,
+       const char *name,
+       char **name_owner,
+       DBusError *error) {
+
+       DBusMessage *msg, *reply;
+       int r;
+
+       *name_owner = NULL;
+
+       if (!(msg = dbus_message_new_method_call(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "GetNameOwner"))) {
+               r = -ENOMEM;
+               goto fail;
+       }
+
+       if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) {
+               r = -ENOMEM;
+               goto fail;
+       }
+
+       reply = dbus_connection_send_with_reply_and_block(connection, msg, DBUS_TIMEOUT_USE_DEFAULT, error);
+       dbus_message_unref(msg);
+       msg = NULL;
+
+       if (reply) {
+               if (!dbus_message_get_args(reply, error, DBUS_TYPE_STRING, name_owner, DBUS_TYPE_INVALID)) {
+                       dbus_message_unref(reply);
+                       r = -EIO;
+                       goto fail;
+               }
+
+               *name_owner = strdup(*name_owner);
+               dbus_message_unref(reply);
+
+               if (!*name_owner) {
+                       r = -ENOMEM;
+                       goto fail;
+               }
+
+       } else if (dbus_error_has_name(error, "org.freedesktop.DBus.Error.NameHasNoOwner"))
+               dbus_error_free(error);
+       else {
+               r = -EIO;
+               goto fail;
+       }
+
+       return 0;
+
+fail:
+       if (msg)
+               dbus_message_unref(msg);
+
+       return r;
+}
index 9ae49cf..6527bd7 100644 (file)
@@ -51,7 +51,7 @@ typedef int (*rd_request_cb_t)(
  * the error was caused D-Bus. */
 int rd_acquire(
        rd_device **d,                /* On success a pointer to the newly allocated rd_device object will be filled in here */
-       DBusConnection *connection,   /* Session bus (when D-Bus learns about user busses we should switchg to user busses) */
+       DBusConnection *connection,   /* Session bus (when D-Bus learns about user busses we should switch to user busses) */
        const char *device_name,      /* The device to lock, e.g. "Audio0" */
        const char *application_name, /* A human readable name of the application, e.g. "PulseAudio Sound Server" */
        int32_t priority,             /* The priority for this application. If unsure use 0 */
@@ -72,6 +72,15 @@ void rd_set_userdata(rd_device *d, void *userdata);
  * userdata was set. */
 void* rd_get_userdata(rd_device *d);
 
+/* Helper function to get the unique connection name owning a given
+ * name. Returns 0 on success, a negative errno style return value on
+ * error. */
+int rd_dbus_get_name_owner(
+       DBusConnection *connection,
+       const char *name,
+       char **name_owner,
+       DBusError *error);
+
 #ifdef __cplusplus
 }
 #endif
index 0fef835..3007518 100644 (file)
@@ -56,12 +56,7 @@ pa_headerlist* pa_headerlist_new(void) {
 }
 
 void pa_headerlist_free(pa_headerlist* p) {
-    struct header *hdr;
-
-    while ((hdr = pa_hashmap_steal_first(MAKE_HASHMAP(p))))
-        header_free(hdr);
-
-    pa_hashmap_free(MAKE_HASHMAP(p), NULL, NULL);
+    pa_hashmap_free(MAKE_HASHMAP(p), (pa_free_cb_t) header_free);
 }
 
 int pa_headerlist_puts(pa_headerlist *p, const char *key, const char *value) {
diff --git a/src/modules/rtp/module-rtp-recv-symdef.h b/src/modules/rtp/module-rtp-recv-symdef.h
deleted file mode 100644 (file)
index bd4c77c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulertprecvsymdeffoo
-#define foomodulertprecvsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_rtp_recv_LTX_pa__init
-#define pa__done module_rtp_recv_LTX_pa__done
-#define pa__get_author module_rtp_recv_LTX_pa__get_author
-#define pa__get_description module_rtp_recv_LTX_pa__get_description
-#define pa__get_usage module_rtp_recv_LTX_pa__get_usage
-#define pa__get_version module_rtp_recv_LTX_pa__get_version
-#define pa__get_deprecated module_rtp_recv_LTX_pa__get_deprecated
-#define pa__load_once module_rtp_recv_LTX_pa__load_once
-#define pa__get_n_used module_rtp_recv_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 1a05f57..45d03f5 100644 (file)
 #include <stdio.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
-#include <arpa/inet.h>
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
-#include <poll.h>
+#include <math.h>
 
 #include <pulse/rtclock.h>
 #include <pulse/timeval.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/sample-util.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/atomic.h>
-#include <pulsecore/atomic.h>
-#include <pulsecore/time-smoother.h>
 #include <pulsecore/socket-util.h>
+#include <pulsecore/atomic.h>
 #include <pulsecore/once.h>
+#include <pulsecore/poll.h>
+#include <pulsecore/arpa-inet.h>
 
 #include "module-rtp-recv-symdef.h"
 
@@ -104,11 +103,13 @@ struct session {
 
     pa_atomic_t timestamp;
 
-    pa_smoother *smoother;
     pa_usec_t intended_latency;
     pa_usec_t sink_latency;
 
     pa_usec_t last_rate_update;
+    pa_usec_t last_latency;
+    double estimated_rate;
+    double avg_estimated_rate;
 };
 
 struct userdata {
@@ -185,6 +186,7 @@ static void sink_input_kill(pa_sink_input* i) {
     pa_sink_input_assert_ref(i);
     pa_assert_se(s = i->userdata);
 
+    pa_hashmap_remove(s->userdata->by_origin, s->sdp_info.origin);
     session_free(s);
 }
 
@@ -194,10 +196,9 @@ static void sink_input_suspend_within_thread(pa_sink_input* i, pa_bool_t b) {
     pa_sink_input_assert_ref(i);
     pa_assert_se(s = i->userdata);
 
-    if (b) {
-        pa_smoother_pause(s->smoother, pa_rtclock_now());
+    if (b)
         pa_memblockq_flush_read(s->memblockq);
-    else
+    else
         s->first_packet = FALSE;
 }
 
@@ -266,11 +267,6 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
     } else
         pa_rtclock_from_wallclock(&now);
 
-    pa_smoother_put(s->smoother, pa_timeval_load(&now), pa_bytes_to_usec((uint64_t) pa_memblockq_get_write_index(s->memblockq), &s->sink_input->sample_spec));
-
-    /* Tell the smoother that we are rolling now, in case it is still paused */
-    pa_smoother_resume(s->smoother, pa_timeval_load(&now), TRUE);
-
     if (pa_memblockq_push(s->memblockq, &chunk) < 0) {
         pa_log_warn("Queue overrun");
         pa_memblockq_seek(s->memblockq, (int64_t) chunk.length, PA_SEEK_RELATIVE, TRUE);
@@ -286,12 +282,15 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
     pa_atomic_store(&s->timestamp, (int) now.tv_sec);
 
     if (s->last_rate_update + RATE_UPDATE_INTERVAL < pa_timeval_load(&now)) {
-        pa_usec_t wi, ri, render_delay, sink_delay = 0, latency, fix;
-        unsigned fix_samples;
+        pa_usec_t wi, ri, render_delay, sink_delay = 0, latency;
+        uint32_t base_rate = s->sink_input->sink->sample_spec.rate;
+        uint32_t current_rate = s->sink_input->sample_spec.rate;
+        uint32_t new_rate;
+        double estimated_rate, alpha = 0.02;
 
         pa_log_debug("Updating sample rate");
 
-        wi = pa_smoother_get(s->smoother, pa_timeval_load(&now));
+        wi = pa_bytes_to_usec((uint64_t) pa_memblockq_get_write_index(s->memblockq), &s->sink_input->sample_spec);
         ri = pa_bytes_to_usec((uint64_t) pa_memblockq_get_read_index(s->memblockq), &s->sink_input->sample_spec);
 
         pa_log_debug("wi=%lu ri=%lu", (unsigned long) wi, (unsigned long) ri);
@@ -309,30 +308,61 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
         else
             latency = wi - ri;
 
-        pa_log_debug("Write index deviates by %0.2f ms, expected %0.2f ms", (double) latency/PA_USEC_PER_MSEC, (double)  s->intended_latency/PA_USEC_PER_MSEC);
-
-        /* Calculate deviation */
-        if (latency < s->intended_latency)
-            fix = s->intended_latency - latency;
-        else
-            fix = latency - s->intended_latency;
-
-        /* How many samples is this per second? */
-        fix_samples = (unsigned) (fix * (pa_usec_t) s->sink_input->thread_info.sample_spec.rate / (pa_usec_t) RATE_UPDATE_INTERVAL);
-
-        /* Check if deviation is in bounds */
-        if (fix_samples > s->sink_input->sample_spec.rate*.50)
-            pa_log_debug("Hmmm, rate fix is too large (%lu Hz), not applying.", (unsigned long) fix_samples);
-        else {
-            /* Fix up rate */
-            if (latency < s->intended_latency)
-                s->sink_input->sample_spec.rate -= fix_samples;
-            else
-                s->sink_input->sample_spec.rate += fix_samples;
-
-            if (s->sink_input->sample_spec.rate > PA_RATE_MAX)
-                s->sink_input->sample_spec.rate = PA_RATE_MAX;
+        pa_log_debug("Write index deviates by %0.2f ms, expected %0.2f ms", (double) latency/PA_USEC_PER_MSEC, (double) s->intended_latency/PA_USEC_PER_MSEC);
+
+        /* The buffer is filling with some unknown rate R̂ samples/second. If the rate of reading in
+         * the last T seconds was Rⁿ, then the increase in buffer latency ΔLⁿ = Lⁿ - Lⁿ⁻ⁱ in that
+         * same period is ΔLⁿ = (TR̂ - TRⁿ) / R̂, giving the estimated target rate
+         *                                           T
+         *                                 R̂ = ─────────────── Rⁿ .                             (1)
+         *                                     T - (Lⁿ - Lⁿ⁻ⁱ)
+         *
+         * Setting the sample rate to R̂ results in the latency being constant (if the estimate of R̂
+         * is correct).  But there is also the requirement to keep the buffer at a predefined target
+         * latency L̂.  So instead of setting Rⁿ⁺ⁱ to R̂ immediately, the strategy will be to reduce R
+         * from Rⁿ⁺ⁱ to R̂ in a steps of T seconds, where Rⁿ⁺ⁱ is chosen such that in the total time
+         * aT the latency is reduced from Lⁿ to L̂.  This strategy translates to the requirements
+         *            ₐ      R̂ - Rⁿ⁺ʲ                            a-j+1         j-1
+         *            Σ  T ────────── = L̂ - Lⁿ    with    Rⁿ⁺ʲ = ───── Rⁿ⁺ⁱ + ───── R̂ .
+         *           ʲ⁼ⁱ        R̂                                  a            a
+         * Solving for Rⁿ⁺ⁱ gives
+         *                                     T - ²∕ₐ₊₁(L̂ - Lⁿ)
+         *                              Rⁿ⁺ⁱ = ───────────────── R̂ .                            (2)
+         *                                            T
+         * In the code below a = 7 is used.
+         *
+         * Equation (1) is not directly used in (2), but instead an exponentially weighted average
+         * of the estimated rate R̂ is used.  This average R̅ is defined as
+         *                                R̅ⁿ = α R̂ⁿ + (1-α) R̅ⁿ⁻ⁱ .
+         * Because it is difficult to find a fixed value for the coefficient α such that the
+         * averaging is without significant lag but oscillations are filtered out, a heuristic is
+         * used.  When the successive estimates R̂ⁿ do not change much then α→1, but when there is a
+         * sudden spike in the estimated rate α→0, such that the deviation is given little weight.
+         */
+        estimated_rate = (double) current_rate * (double) RATE_UPDATE_INTERVAL / (double) (RATE_UPDATE_INTERVAL + s->last_latency - latency);
+        if (fabs(s->estimated_rate - s->avg_estimated_rate) > 1) {
+          double ratio = (estimated_rate + s->estimated_rate - 2*s->avg_estimated_rate) / (s->estimated_rate - s->avg_estimated_rate);
+          alpha = PA_CLAMP(2 * (ratio + fabs(ratio)) / (4 + ratio*ratio), 0.02, 0.8);
+        }
+        s->avg_estimated_rate = alpha * estimated_rate + (1-alpha) * s->avg_estimated_rate;
+        s->estimated_rate = estimated_rate;
+        pa_log_debug("Estimated target rate: %.0f Hz, using average of %.0f Hz  (α=%.3f)", estimated_rate, s->avg_estimated_rate, alpha);
+        new_rate = (uint32_t) ((double) (RATE_UPDATE_INTERVAL + latency/4 - s->intended_latency/4) / (double) RATE_UPDATE_INTERVAL * s->avg_estimated_rate);
+        s->last_latency = latency;
+
+        if (new_rate < (uint32_t) (base_rate*0.8) || new_rate > (uint32_t) (base_rate*1.25)) {
+            pa_log_warn("Sample rates too different, not adjusting (%u vs. %u).", base_rate, new_rate);
+            new_rate = base_rate;
+        } else {
+            if (base_rate < new_rate + 20 && new_rate < base_rate + 20)
+              new_rate = base_rate;
+            /* Do the adjustment in small steps; 2‰ can be considered inaudible */
+            if (new_rate < (uint32_t) (current_rate*0.998) || new_rate > (uint32_t) (current_rate*1.002)) {
+                pa_log_info("New rate of %u Hz not within 2‰ of %u Hz, forcing smaller adjustment", new_rate, current_rate);
+                new_rate = PA_CLAMP(new_rate, (uint32_t) (current_rate*0.998), (uint32_t) (current_rate*1.002));
+            }
         }
+        s->sink_input->sample_spec.rate = new_rate;
 
         pa_assert(pa_sample_spec_valid(&s->sink_input->sample_spec));
 
@@ -346,7 +376,9 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
     if (pa_memblockq_is_readable(s->memblockq) &&
         s->sink_input->thread_info.underrun_for > 0) {
         pa_log_debug("Requesting rewind due to end of underrun");
-        pa_sink_input_request_rewind(s->sink_input, 0, FALSE, TRUE, FALSE);
+        pa_sink_input_request_rewind(s->sink_input,
+                                     (size_t) (s->sink_input->thread_info.underrun_for == (uint64_t) -1 ? 0 : s->sink_input->thread_info.underrun_for),
+                                     FALSE, TRUE, FALSE);
     }
 
     return 1;
@@ -390,18 +422,23 @@ static int mcast_socket(const struct sockaddr* sa, socklen_t salen) {
     pa_assert(salen > 0);
 
     af = sa->sa_family;
-    if ((fd = socket(af, SOCK_DGRAM, 0)) < 0) {
+    if ((fd = pa_socket_cloexec(af, SOCK_DGRAM, 0)) < 0) {
         pa_log("Failed to create socket: %s", pa_cstrerror(errno));
         goto fail;
     }
 
     pa_make_udp_socket_low_delay(fd);
 
+#ifdef SO_TIMESTAMP
     one = 1;
     if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one)) < 0) {
         pa_log("SO_TIMESTAMP failed: %s", pa_cstrerror(errno));
         goto fail;
     }
+#else
+    pa_log("SO_TIMESTAMP unsupported on this platform");
+    goto fail;
+#endif
 
     one = 1;
     if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) {
@@ -415,13 +452,14 @@ static int mcast_socket(const struct sockaddr* sa, socklen_t salen) {
         mr4.imr_multiaddr = ((const struct sockaddr_in*) sa)->sin_addr;
         r = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mr4, sizeof(mr4));
 #ifdef HAVE_IPV6
-    } else {
+    } else if (af == AF_INET6) {
         struct ipv6_mreq mr6;
         memset(&mr6, 0, sizeof(mr6));
         mr6.ipv6mr_multiaddr = ((const struct sockaddr_in6*) sa)->sin6_addr;
         r = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mr6, sizeof(mr6));
 #endif
-    }
+    } else
+        pa_assert_not_reached();
 
     if (r < 0) {
         pa_log_info("Joining mcast group failed: %s", pa_cstrerror(errno));
@@ -471,22 +509,17 @@ static struct session *session_new(struct userdata *u, const pa_sdp_info *sdp_in
     s->sdp_info = *sdp_info;
     s->rtpoll_item = NULL;
     s->intended_latency = LATENCY_USEC;
-    s->smoother = pa_smoother_new(
-            PA_USEC_PER_SEC*5,
-            PA_USEC_PER_SEC*2,
-            TRUE,
-            TRUE,
-            10,
-            pa_timeval_load(&now),
-            TRUE);
     s->last_rate_update = pa_timeval_load(&now);
+    s->last_latency = LATENCY_USEC;
+    s->estimated_rate = (double) sink->sample_spec.rate;
+    s->avg_estimated_rate = (double) sink->sample_spec.rate;
     pa_atomic_store(&s->timestamp, (int) now.tv_sec);
 
     if ((fd = mcast_socket((const struct sockaddr*) &sdp_info->sa, sdp_info->salen)) < 0)
         goto fail;
 
     pa_sink_input_new_data_init(&data);
-    data.sink = sink;
+    pa_sink_input_new_data_set_sink(&data, sink, FALSE);
     data.driver = __FILE__;
     pa_proplist_sets(data.proplist, PA_PROP_MEDIA_ROLE, "stream");
     pa_proplist_setf(data.proplist, PA_PROP_MEDIA_NAME,
@@ -530,10 +563,11 @@ static struct session *session_new(struct userdata *u, const pa_sdp_info *sdp_in
         s->intended_latency = s->sink_latency*2;
 
     s->memblockq = pa_memblockq_new(
+            "module-rtp-recv memblockq",
             0,
             MEMBLOCKQ_MAXLENGTH,
             MEMBLOCKQ_MAXLENGTH,
-            pa_frame_size(&s->sink_input->sample_spec),
+            &s->sink_input->sample_spec,
             pa_usec_to_bytes(s->intended_latency - s->sink_latency, &s->sink_input->sample_spec),
             0,
             0,
@@ -573,14 +607,11 @@ static void session_free(struct session *s) {
     PA_LLIST_REMOVE(struct session, s->userdata->sessions, s);
     pa_assert(s->userdata->n_sessions >= 1);
     s->userdata->n_sessions--;
-    pa_hashmap_remove(s->userdata->by_origin, s->sdp_info.origin);
 
     pa_memblockq_free(s->memblockq);
     pa_sdp_info_destroy(&s->sdp_info);
     pa_rtp_context_destroy(&s->rtp_context);
 
-    pa_smoother_free(s->smoother);
-
     pa_xfree(s);
 }
 
@@ -604,7 +635,7 @@ static void sap_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event
 
     if (goodbye) {
 
-        if ((s = pa_hashmap_get(u->by_origin, info.origin)))
+        if ((s = pa_hashmap_remove(u->by_origin, info.origin)))
             session_free(s);
 
         pa_sdp_info_destroy(&info);
@@ -643,8 +674,10 @@ static void check_death_event_cb(pa_mainloop_api *m, pa_time_event *t, const str
 
         k = pa_atomic_load(&s->timestamp);
 
-        if (k + DEATH_TIMEOUT < now.tv_sec)
+        if (k + DEATH_TIMEOUT < now.tv_sec) {
+            pa_hashmap_remove(u->by_origin, s->sdp_info.origin);
             session_free(s);
+        }
     }
 
     /* Restart timer */
@@ -722,7 +755,6 @@ fail:
 
 void pa__done(pa_module*m) {
     struct userdata *u;
-    struct session *s;
 
     pa_assert(m);
 
@@ -737,12 +769,8 @@ void pa__done(pa_module*m) {
 
     pa_sap_context_destroy(&u->sap_context);
 
-    if (u->by_origin) {
-        while ((s = pa_hashmap_first(u->by_origin)))
-            session_free(s);
-
-        pa_hashmap_free(u->by_origin, NULL, NULL);
-    }
+    if (u->by_origin)
+        pa_hashmap_free(u->by_origin, (pa_free_cb_t) session_free);
 
     pa_xfree(u->sink_name);
     pa_xfree(u);
diff --git a/src/modules/rtp/module-rtp-send-symdef.h b/src/modules/rtp/module-rtp-send-symdef.h
deleted file mode 100644 (file)
index 54a1124..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulertpsendsymdeffoo
-#define foomodulertpsendsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_rtp_send_LTX_pa__init
-#define pa__done module_rtp_send_LTX_pa__done
-#define pa__get_author module_rtp_send_LTX_pa__get_author
-#define pa__get_description module_rtp_send_LTX_pa__get_description
-#define pa__get_usage module_rtp_send_LTX_pa__get_usage
-#define pa__get_version module_rtp_send_LTX_pa__get_version
-#define pa__get_deprecated module_rtp_send_LTX_pa__get_deprecated
-#define pa__load_once module_rtp_send_LTX_pa__load_once
-#define pa__get_n_used module_rtp_send_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 8e1cfe3..acabcf5 100644 (file)
@@ -26,9 +26,7 @@
 #include <stdio.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
-#include <arpa/inet.h>
 #include <errno.h>
-#include <string.h>
 #include <unistd.h>
 
 #include <pulse/rtclock.h>
@@ -38,7 +36,6 @@
 
 #include <pulsecore/core-error.h>
 #include <pulsecore/module.h>
-#include <pulsecore/llist.h>
 #include <pulsecore/source.h>
 #include <pulsecore/source-output.h>
 #include <pulsecore/memblockq.h>
@@ -49,6 +46,7 @@
 #include <pulsecore/sample-util.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/socket-util.h>
+#include <pulsecore/arpa-inet.h>
 
 #include "module-rtp-send-symdef.h"
 
@@ -65,7 +63,8 @@ PA_MODULE_USAGE(
         "format=<sample format> "
         "channels=<number of channels> "
         "rate=<sample rate> "
-        "destination=<destination IP address> "
+        "destination_ip=<destination IP address> "
+        "source_ip=<source IP address> "
         "port=<port number> "
         "mtu=<maximum transfer unit> "
         "loop=<loopback to local host?> "
@@ -75,7 +74,8 @@ PA_MODULE_USAGE(
 #define DEFAULT_PORT 46000
 #define DEFAULT_TTL 1
 #define SAP_PORT 9875
-#define DEFAULT_DESTINATION "224.0.0.56"
+#define DEFAULT_SOURCE_IP "0.0.0.0"
+#define DEFAULT_DESTINATION_IP "224.0.0.56"
 #define MEMBLOCKQ_MAXLENGTH (1024*170)
 #define DEFAULT_MTU 1280
 #define SAP_INTERVAL (5*PA_USEC_PER_SEC)
@@ -85,7 +85,9 @@ static const char* const valid_modargs[] = {
     "format",
     "channels",
     "rate",
-    "destination",
+    "destination", /* Compatbility */
+    "destination_ip",
+    "source_ip",
     "port",
     "mtu" ,
     "loop",
@@ -165,7 +167,8 @@ static void sap_event_cb(pa_mainloop_api *m, pa_time_event *t, const struct time
 int pa__init(pa_module*m) {
     struct userdata *u;
     pa_modargs *ma = NULL;
-    const char *dest;
+    const char *dst_addr;
+    const char *src_addr;
     uint32_t port = DEFAULT_PORT, mtu;
     uint32_t ttl = DEFAULT_TTL;
     sa_family_t af;
@@ -173,9 +176,9 @@ int pa__init(pa_module*m) {
     pa_source *s;
     pa_sample_spec ss;
     pa_channel_map cm;
-    struct sockaddr_in sa4, sap_sa4;
+    struct sockaddr_in dst_sa4, dst_sap_sa4, src_sa4, src_sap_sa4;
 #ifdef HAVE_IPV6
-    struct sockaddr_in6 sa6, sap_sa6;
+    struct sockaddr_in6 dst_sa6, dst_sap_sa6, src_sa6, src_sap_sa6;
 #endif
     struct sockaddr_storage sa_dst;
     pa_source_output *o = NULL;
@@ -243,50 +246,89 @@ int pa__init(pa_module*m) {
         goto fail;
     }
 
-    dest = pa_modargs_get_value(ma, "destination", DEFAULT_DESTINATION);
+    src_addr = pa_modargs_get_value(ma, "source_ip", DEFAULT_SOURCE_IP);
 
-    if (inet_pton(AF_INET, dest, &sa4.sin_addr) > 0) {
-        sa4.sin_family = af = AF_INET;
-        sa4.sin_port = htons((uint16_t) port);
-        sap_sa4 = sa4;
-        sap_sa4.sin_port = htons(SAP_PORT);
+    if (inet_pton(AF_INET, src_addr, &src_sa4.sin_addr) > 0) {
+        src_sa4.sin_family = af = AF_INET;
+        src_sa4.sin_port = htons(0);
+        src_sap_sa4 = src_sa4;
 #ifdef HAVE_IPV6
-    } else if (inet_pton(AF_INET6, dest, &sa6.sin6_addr) > 0) {
-        sa6.sin6_family = af = AF_INET6;
-        sa6.sin6_port = htons((uint16_t) port);
-        sap_sa6 = sa6;
-        sap_sa6.sin6_port = htons(SAP_PORT);
+    } else if (inet_pton(AF_INET6, src_addr, &src_sa6.sin6_addr) > 0) {
+        src_sa6.sin6_family = af = AF_INET6;
+        src_sa6.sin6_port = htons(0);
+        src_sap_sa6 = src_sa6;
 #endif
     } else {
-        pa_log("Invalid destination '%s'", dest);
+        pa_log("Invalid source address '%s'", src_addr);
         goto fail;
     }
 
-    if ((fd = socket(af, SOCK_DGRAM, 0)) < 0) {
+    dst_addr = pa_modargs_get_value(ma, "destination", NULL);
+    if (dst_addr == NULL)
+        dst_addr = pa_modargs_get_value(ma, "destination_ip", DEFAULT_DESTINATION_IP);
+
+    if (inet_pton(AF_INET, dst_addr, &dst_sa4.sin_addr) > 0) {
+        dst_sa4.sin_family = af = AF_INET;
+        dst_sa4.sin_port = htons((uint16_t) port);
+        dst_sap_sa4 = dst_sa4;
+        dst_sap_sa4.sin_port = htons(SAP_PORT);
+#ifdef HAVE_IPV6
+    } else if (inet_pton(AF_INET6, dst_addr, &dst_sa6.sin6_addr) > 0) {
+        dst_sa6.sin6_family = af = AF_INET6;
+        dst_sa6.sin6_port = htons((uint16_t) port);
+        dst_sap_sa6 = dst_sa6;
+        dst_sap_sa6.sin6_port = htons(SAP_PORT);
+#endif
+    } else {
+        pa_log("Invalid destination '%s'", dst_addr);
+        goto fail;
+    }
+
+    if ((fd = pa_socket_cloexec(af, SOCK_DGRAM, 0)) < 0) {
         pa_log("socket() failed: %s", pa_cstrerror(errno));
         goto fail;
     }
 
-    if (af == AF_INET && connect(fd, (struct sockaddr*) &sa4, sizeof(sa4)) < 0) {
+    if (af == AF_INET && bind(fd, (struct sockaddr*) &src_sa4, sizeof(src_sa4)) < 0) {
+        pa_log("bind() failed: %s", pa_cstrerror(errno));
+        goto fail;
+#ifdef HAVE_IPV6
+    } else if (af == AF_INET6 && bind(fd, (struct sockaddr*) &src_sa6, sizeof(src_sa6)) < 0) {
+        pa_log("bind() failed: %s", pa_cstrerror(errno));
+        goto fail;
+#endif
+    }
+
+    if (af == AF_INET && connect(fd, (struct sockaddr*) &dst_sa4, sizeof(dst_sa4)) < 0) {
         pa_log("connect() failed: %s", pa_cstrerror(errno));
         goto fail;
 #ifdef HAVE_IPV6
-    } else if (af == AF_INET6 && connect(fd, (struct sockaddr*) &sa6, sizeof(sa6)) < 0) {
+    } else if (af == AF_INET6 && connect(fd, (struct sockaddr*) &dst_sa6, sizeof(dst_sa6)) < 0) {
         pa_log("connect() failed: %s", pa_cstrerror(errno));
         goto fail;
 #endif
     }
 
-    if ((sap_fd = socket(af, SOCK_DGRAM, 0)) < 0) {
+    if ((sap_fd = pa_socket_cloexec(af, SOCK_DGRAM, 0)) < 0) {
         pa_log("socket() failed: %s", pa_cstrerror(errno));
         goto fail;
     }
 
-    if (af == AF_INET && connect(sap_fd, (struct sockaddr*) &sap_sa4, sizeof(sap_sa4)) < 0) {
+    if (af == AF_INET && bind(sap_fd, (struct sockaddr*) &src_sap_sa4, sizeof(src_sap_sa4)) < 0) {
+        pa_log("bind() failed: %s", pa_cstrerror(errno));
+        goto fail;
+#ifdef HAVE_IPV6
+    } else if (af == AF_INET6 && bind(sap_fd, (struct sockaddr*) &src_sap_sa6, sizeof(src_sap_sa6)) < 0) {
+        pa_log("bind() failed: %s", pa_cstrerror(errno));
+        goto fail;
+#endif
+    }
+
+    if (af == AF_INET && connect(sap_fd, (struct sockaddr*) &dst_sap_sa4, sizeof(dst_sap_sa4)) < 0) {
         pa_log("connect() failed: %s", pa_cstrerror(errno));
         goto fail;
 #ifdef HAVE_IPV6
-    } else if (af == AF_INET6 && connect(sap_fd, (struct sockaddr*) &sap_sa6, sizeof(sap_sa6)) < 0) {
+    } else if (af == AF_INET6 && connect(sap_fd, (struct sockaddr*) &dst_sap_sa6, sizeof(dst_sap_sa6)) < 0) {
         pa_log("connect() failed: %s", pa_cstrerror(errno));
         goto fail;
 #endif
@@ -316,18 +358,17 @@ int pa__init(pa_module*m) {
     /* If the socket queue is full, let's drop packets */
     pa_make_fd_nonblock(fd);
     pa_make_udp_socket_low_delay(fd);
-    pa_make_fd_cloexec(fd);
-    pa_make_fd_cloexec(sap_fd);
 
     pa_source_output_new_data_init(&data);
     pa_proplist_sets(data.proplist, PA_PROP_MEDIA_NAME, "RTP Monitor Stream");
-    pa_proplist_sets(data.proplist, "rtp.destination", dest);
+    pa_proplist_sets(data.proplist, "rtp.source", src_addr);
+    pa_proplist_sets(data.proplist, "rtp.destination", dst_addr);
     pa_proplist_setf(data.proplist, "rtp.mtu", "%lu", (unsigned long) mtu);
     pa_proplist_setf(data.proplist, "rtp.port", "%lu", (unsigned long) port);
     pa_proplist_setf(data.proplist, "rtp.ttl", "%lu", (unsigned long) ttl);
     data.driver = __FILE__;
     data.module = m;
-    data.source = s;
+    pa_source_output_new_data_set_source(&data, s, FALSE);
     pa_source_output_new_data_set_sample_spec(&data, &ss);
     pa_source_output_new_data_set_channel_map(&data, &cm);
     data.flags = PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND;
@@ -352,10 +393,11 @@ int pa__init(pa_module*m) {
     u->source_output = o;
 
     u->memblockq = pa_memblockq_new(
+            "module-rtp-send memblockq",
             0,
             MEMBLOCKQ_MAXLENGTH,
             MEMBLOCKQ_MAXLENGTH,
-            pa_frame_size(&ss),
+            &ss,
             1,
             0,
             0,
@@ -371,13 +413,13 @@ int pa__init(pa_module*m) {
     if (af == AF_INET) {
         p = pa_sdp_build(af,
                      (void*) &((struct sockaddr_in*) &sa_dst)->sin_addr,
-                     (void*) &sa4.sin_addr,
+                     (void*) &dst_sa4.sin_addr,
                      n, (uint16_t) port, payload, &ss);
 #ifdef HAVE_IPV6
     } else {
         p = pa_sdp_build(af,
                      (void*) &((struct sockaddr_in6*) &sa_dst)->sin6_addr,
-                     (void*) &sa6.sin6_addr,
+                     (void*) &dst_sa6.sin6_addr,
                      n, (uint16_t) port, payload, &ss);
 #endif
     }
@@ -387,7 +429,7 @@ int pa__init(pa_module*m) {
     pa_rtp_context_init_send(&u->rtp_context, fd, m->core->cookie, payload, pa_frame_size(&ss));
     pa_sap_context_init_send(&u->sap_context, sap_fd, p);
 
-    pa_log_info("RTP stream initialized with mtu %u on %s:%u ttl=%u, SSRC=0x%08x, payload=%u, initial sequence #%u", mtu, dest, port, ttl, u->rtp_context.ssrc, payload, u->rtp_context.sequence);
+    pa_log_info("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("SDP-Data:\n%s\nEOF", p);
 
     pa_sap_send(&u->sap_context, 0);
index 6706a10..9195493 100644 (file)
 #include <config.h>
 #endif
 
-#include <fcntl.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <arpa/inet.h>
 #include <unistd.h>
 #include <sys/ioctl.h>
 
@@ -43,6 +41,7 @@
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
+#include <pulsecore/arpa-inet.h>
 
 #include "rtp.h"
 
@@ -89,7 +88,7 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) {
 
             pa_assert(chunk.memblock);
 
-            iov[iov_idx].iov_base = ((uint8_t*) pa_memblock_acquire(chunk.memblock) + chunk.index);
+            iov[iov_idx].iov_base = pa_memblock_acquire_chunk(&chunk);
             iov[iov_idx].iov_len = k;
             mb[iov_idx] = chunk.memblock;
             iov_idx ++;
@@ -204,7 +203,7 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool, struct
     chunk->memblock = pa_memblock_ref(c->memchunk.memblock);
     chunk->index = c->memchunk.index;
 
-    iov.iov_base = (uint8_t*) pa_memblock_acquire(chunk->memblock) + chunk->index;
+    iov.iov_base = pa_memblock_acquire_chunk(chunk);
     iov.iov_len = (size_t) size;
 
     m.msg_name = NULL;
@@ -278,16 +277,16 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool, struct
         pa_memchunk_reset(&c->memchunk);
     }
 
-    for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm)) {
-        if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SO_TIMESTAMP)
+    for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
+        if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_TIMESTAMP) {
             memcpy(tstamp, CMSG_DATA(cm), sizeof(struct timeval));
             found_tstamp = TRUE;
             break;
         }
 
     if (!found_tstamp) {
-        pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() data!");
-        memset(tstamp, 0, sizeof(tstamp));
+        pa_log_warn("Couldn't find SCM_TIMESTAMP data in auxiliary recvmsg() data!");
+        pa_zero(*tstamp);
     }
 
     return 0;
@@ -399,13 +398,13 @@ const char* pa_rtp_format_to_string(pa_sample_format_t f) {
 pa_sample_format_t pa_rtp_string_to_format(const char *s) {
     pa_assert(s);
 
-    if (!(strcmp(s, "L16")))
+    if (pa_streq(s, "L16"))
         return PA_SAMPLE_S16BE;
-    else if (!strcmp(s, "L8"))
+    else if (pa_streq(s, "L8"))
         return PA_SAMPLE_U8;
-    else if (!strcmp(s, "PCMA"))
+    else if (pa_streq(s, "PCMA"))
         return PA_SAMPLE_ALAW;
-    else if (!strcmp(s, "PCMU"))
+    else if (pa_streq(s, "PCMU"))
         return PA_SAMPLE_ULAW;
     else
         return PA_SAMPLE_INVALID;
index b197e82..e975e75 100644 (file)
@@ -40,6 +40,9 @@ typedef struct pa_rtp_context {
 } 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);
+
+/* 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);
 
 pa_rtp_context* pa_rtp_context_init_recv(pa_rtp_context *c, int fd, size_t frame_size);
index 5961806..90521fe 100644 (file)
 #include <config.h>
 #endif
 
-#include <fcntl.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <arpa/inet.h>
 #include <unistd.h>
 #include <sys/ioctl.h>
 #include <netinet/in.h>
 
 #include <pulsecore/core-error.h>
 #include <pulsecore/core-util.h>
-#include <pulsecore/socket-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/strbuf.h>
 #include <pulsecore/ioline.h>
-
-#ifdef HAVE_POLL_H
-#include <poll.h>
-#else
-#include <pulsecore/poll.h>
-#endif
+#include <pulsecore/arpa-inet.h>
 
 #include "rtsp_client.h"
 
@@ -151,9 +143,17 @@ static void headers_read(pa_rtsp_client *c) {
 
         /* Now parse out the server port component of the response. */
         while ((token = pa_split(c->transport, delimiters, &token_state))) {
-            if ((pc = strstr(token, "="))) {
+            if ((pc = strchr(token, '='))) {
                 if (0 == strncmp(token, "server_port", 11)) {
-                    pa_atou(pc+1, (uint32_t*)(&c->rtp_port));
+                    uint32_t p;
+
+                    if (pa_atou(pc + 1, &p) < 0 || p <= 0 || p > 0xffff) {
+                        pa_log("Invalid SETUP response (invalid server_port).");
+                        pa_xfree(token);
+                        return;
+                    }
+
+                    c->rtp_port = p;
                     pa_xfree(token);
                     break;
                 }
@@ -195,7 +195,7 @@ static void line_callback(pa_ioline *line, const char *s, void *userdata) {
         *s2p = '\0';
         s2p -= 1;
     }
-    if (c->waiting && 0 == strcmp("RTSP/1.0 200 OK", s2)) {
+    if (c->waiting && pa_streq(s2, "RTSP/1.0 200 OK")) {
         c->waiting = 0;
         if (c->response_headers)
             pa_headerlist_free(c->response_headers);
@@ -332,6 +332,7 @@ int pa_rtsp_connect(pa_rtsp_client *c) {
     pa_xfree(c->session);
     c->session = NULL;
 
+    pa_log_debug("Attempting to connect to server '%s:%d'", c->hostname, c->port);
     if (!(c->sc = pa_socket_client_new_string(c->mainloop, TRUE, c->hostname, c->port))) {
         pa_log("failed to connect to server '%s:%d'", c->hostname, c->port);
         return -1;
@@ -377,8 +378,7 @@ void pa_rtsp_set_url(pa_rtsp_client* c, const char* url) {
     c->url = pa_xstrdup(url);
 }
 
-void pa_rtsp_add_header(pa_rtsp_client *c, const char* key, const char* value)
-{
+void pa_rtsp_add_header(pa_rtsp_client *c, const char* key, const char* value) {
     pa_assert(c);
     pa_assert(key);
     pa_assert(value);
@@ -386,8 +386,7 @@ void pa_rtsp_add_header(pa_rtsp_client *c, const char* key, const char* value)
     pa_headerlist_puts(c->headers, key, value);
 }
 
-void pa_rtsp_remove_header(pa_rtsp_client *c, const char* key)
-{
+void pa_rtsp_remove_header(pa_rtsp_client *c, const char* key) {
     pa_assert(c);
     pa_assert(key);
 
index b229f26..a56b932 100644 (file)
@@ -27,8 +27,6 @@
 #include <sys/types.h>
 #include <netdb.h>
 
-#include <pulsecore/memblockq.h>
-#include <pulsecore/memchunk.h>
 #include <pulsecore/socket-client.h>
 #include <pulse/mainloop-api.h>
 
index adde16d..f02d53f 100644 (file)
 #include <config.h>
 #endif
 
-#include <time.h>
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
-#include <arpa/inet.h>
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
@@ -48,6 +46,7 @@
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
+#include <pulsecore/arpa-inet.h>
 
 #include "sap.h"
 #include "sdp.h"
@@ -213,7 +212,7 @@ int pa_sap_recv(pa_sap_context *c, pa_bool_t *goodbye) {
     e = buf + k;
     size -= (int) k;
 
-    if ((unsigned) size >= sizeof(MIME_TYPE) && !strcmp(e, MIME_TYPE)) {
+    if ((unsigned) size >= sizeof(MIME_TYPE) && pa_streq(e, MIME_TYPE)) {
         e += sizeof(MIME_TYPE);
         size -= (int) sizeof(MIME_TYPE);
     } else if ((unsigned) size < sizeof(PA_SDP_HEADER)-1 || strncmp(e, PA_SDP_HEADER, sizeof(PA_SDP_HEADER)-1)) {
index 7fc7e38..3e61d9b 100644 (file)
@@ -28,7 +28,6 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
-#include <arpa/inet.h>
 #include <string.h>
 
 #include <pulse/xmalloc.h>
@@ -37,6 +36,7 @@
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
+#include <pulsecore/arpa-inet.h>
 
 #include "sdp.h"
 #include "rtp.h"
diff --git a/src/modules/tizen-audio.h b/src/modules/tizen-audio.h
new file mode 100755 (executable)
index 0000000..33b6801
--- /dev/null
@@ -0,0 +1,292 @@
+#ifndef foopulsetizenaudiofoo
+#define foopulsetizenaudiofoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2013 Hyunseok Lee <hs7388.lee@samsung.com>
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+/* FIXME : This file should be separated from PA in future */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#define AUDIO_REVISION                  1
+
+/* Error code */
+
+#define AUDIO_IS_ERROR(ret)             (ret < 0)
+
+typedef enum audio_return {
+    AUDIO_RET_OK                        = 0,
+    AUDIO_RET_USE_HW_CONTROL            = (int32_t)0x40001000,
+    AUDIO_ERR_UNDEFINED                 = (int32_t)0x80001000,
+    AUDIO_ERR_RESOURCE                  = (int32_t)0x80001001,
+    AUDIO_ERR_PARAMETER                 = (int32_t)0x80001002,
+    AUDIO_ERR_IOCTL                     = (int32_t)0x80001003,
+    AUDIO_ERR_NOT_IMPLEMENTED           = (int32_t)0x80001004,
+} audio_return_t ;
+
+
+/* Session */
+typedef enum audio_session {
+    AUDIO_SESSION_MEDIA,
+    AUDIO_SESSION_VOICECALL,
+    AUDIO_SESSION_VIDEOCALL,
+    AUDIO_SESSION_VOIP,
+    AUDIO_SESSION_FMRADIO,
+    AUDIO_SESSION_CAMCORDER,
+    AUDIO_SESSION_NOTIFICATION,
+    AUDIO_SESSION_ALARM,
+    AUDIO_SESSION_EMERGENCY,
+    AUDIO_SESSION_VOICE_RECOGNITION,
+    AUDIO_SESSION_MAX
+} audio_session_t;
+
+/* Sub session */
+typedef enum audio_subsession {
+    AUDIO_SUBSESSION_NONE,
+    AUDIO_SUBSESSION_VOICE,
+    AUDIO_SUBSESSION_RINGTONE,
+    AUDIO_SUBSESSION_MEDIA,
+    AUDIO_SUBSESSION_INIT,
+    AUDIO_SUBSESSION_VR_NORMAL,
+    AUDIO_SUBSESSION_VR_DRIVE,
+    AUDIO_SUBSESSION_STEREO_REC,
+    AUDIO_SUBSESSION_MONO_REC,
+    AUDIO_SUBSESSION_MAX
+} audio_subsession_t;
+
+/* Session command */
+typedef enum audio_session_command {
+    AUDIO_SESSION_CMD_START,
+    AUDIO_SESSION_CMD_SUBSESSION,
+    AUDIO_SESSION_CMD_END,
+} audio_session_command_t;
+
+
+/* Direction */
+typedef enum audio_direction {
+    AUDIO_DIRECTION_NONE,
+    AUDIO_DIRECTION_IN,                 /**< Capture */
+    AUDIO_DIRECTION_OUT,                /**< Playback */
+} audio_direction_t;
+
+
+/* Device */
+
+typedef enum audio_device_in {
+    AUDIO_DEVICE_IN_NONE,
+    AUDIO_DEVICE_IN_MIC,                /**< Device builtin mic. */
+    AUDIO_DEVICE_IN_WIRED_ACCESSORY,    /**< Wired input devices */
+    AUDIO_DEVICE_IN_BT_SCO,             /**< Bluetooth SCO device */
+    AUDIO_DEVICE_IN_MAX,
+} audio_device_in_t;
+
+typedef enum audio_device_out {
+    AUDIO_DEVICE_OUT_NONE,
+    AUDIO_DEVICE_OUT_SPEAKER,           /**< Device builtin speaker */
+    AUDIO_DEVICE_OUT_RECEIVER,          /**< Device builtin receiver */
+    AUDIO_DEVICE_OUT_WIRED_ACCESSORY,   /**< Wired output devices such as headphone, headset, and so on. */
+    AUDIO_DEVICE_OUT_BT_SCO,            /**< Bluetooth SCO device */
+    AUDIO_DEVICE_OUT_BT_A2DP,           /**< Bluetooth A2DP device */
+    AUDIO_DEVICE_OUT_DOCK,              /**< DOCK device */
+    AUDIO_DEVICE_OUT_HDMI,              /**< HDMI device */
+    AUDIO_DEVICE_OUT_MIRRORING,         /**< MIRRORING device */
+    AUDIO_DEVICE_OUT_USB_AUDIO,         /**< USB Audio device */
+    AUDIO_DEVICE_OUT_MULTIMEDIA_DOCK,   /**< Multimedia DOCK device */
+    AUDIO_DEVICE_OUT_MAX,
+} audio_device_out_t;
+
+typedef enum audio_route_flag {
+    AUDIO_ROUTE_FLAG_NONE               = 0,
+    AUDIO_ROUTE_FLAG_MUTE_POLICY        = 0x00000001,
+    AUDIO_ROUTE_FLAG_DUAL_OUT           = 0x00000002,
+    AUDIO_ROUTE_FLAG_NOISE_REDUCTION    = 0x00000010,
+    AUDIO_ROUTE_FLAG_EXTRA_VOL          = 0x00000020,
+    AUDIO_ROUTE_FLAG_NETWORK_WB         = 0x00000040,
+    AUDIO_ROUTE_FLAG_BT_WB              = 0x00000100,
+    AUDIO_ROUTE_FLAG_BT_NREC            = 0x00000200,
+    AUDIO_ROUTE_FLAG_VOICE_COMMAND      = 0x00040000,
+} audio_route_flag_t;
+
+typedef enum audio_device_api {
+    AUDIO_DEVICE_API_UNKNOWN,
+    AUDIO_DEVICE_API_ALSA,
+    AUDIO_DEVICE_API_BLUEZ,
+} audio_device_api_t;
+
+typedef enum audio_device_param {
+    AUDIO_DEVICE_PARAM_NONE,
+    AUDIO_DEVICE_PARAM_CHANNELS,
+    AUDIO_DEVICE_PARAM_SAMPLERATE,
+    AUDIO_DEVICE_PARAM_FRAGMENT_SIZE,
+    AUDIO_DEVICE_PARAM_FRAGMENT_NB,
+    AUDIO_DEVICE_PARAM_START_THRESHOLD,
+    AUDIO_DEVICE_PARAM_USE_MMAP,
+    AUDIO_DEVICE_PARAM_USE_TSCHED,
+    AUDIO_DEVICE_PARAM_TSCHED_BUF_SIZE,
+    AUDIO_DEVICE_PARAM_SUSPEND_TIMEOUT,
+    AUDIO_DEVICE_PARAM_ALTERNATE_RATE,
+    AUDIO_DEVICE_PARAM_MAX,
+} audio_device_param_t;
+
+typedef struct audio_device_param_info {
+    audio_device_param_t param;
+    union {
+        int64_t s64_v;
+        uint64_t u64_v;
+        int32_t s32_v;
+        uint32_t u32_v;
+    };
+} audio_device_param_info_t;
+
+typedef struct audio_device_alsa_info {
+    char *card_name;
+    uint32_t card_idx;
+    uint32_t device_idx;
+} audio_device_alsa_info_t;
+
+typedef struct audio_device_bluz_info {
+    char *protocol;
+    uint32_t nrec;
+} audio_device_bluez_info_t;
+
+typedef struct audio_device_info {
+    audio_device_api_t api;
+    audio_direction_t direction;
+    char *name;
+    uint8_t is_default_device;
+    union {
+        audio_device_alsa_info_t alsa;
+        audio_device_bluez_info_t bluez;
+    };
+} audio_device_info_t;
+
+
+/* Stream */
+
+typedef enum audio_volume {
+    AUDIO_VOLUME_TYPE_SYSTEM,           /**< System volume type */
+    AUDIO_VOLUME_TYPE_NOTIFICATION,     /**< Notification volume type */
+    AUDIO_VOLUME_TYPE_ALARM,            /**< Alarm volume type */
+    AUDIO_VOLUME_TYPE_RINGTONE,         /**< Ringtone volume type */
+    AUDIO_VOLUME_TYPE_MEDIA,            /**< Media volume type */
+    AUDIO_VOLUME_TYPE_CALL,             /**< Call volume type */
+    AUDIO_VOLUME_TYPE_VOIP,             /**< VOIP volume type */
+    AUDIO_VOLUME_TYPE_VOICE,            /**< Voice volume type */
+    AUDIO_VOLUME_TYPE_FIXED,            /**< Volume type for fixed acoustic level */
+    AUDIO_VOLUME_TYPE_MAX,              /**< Volume type count */
+} audio_volume_t;
+
+#ifdef PRIMARY_VOLUME
+typedef enum audio_primary_volume {
+    AUDIO_PRIMARY_VOLUME_TYPE_CALL,             /**< Call volume type */
+    AUDIO_PRIMARY_VOLUME_TYPE_VOIP,             /**< VOIP volume type */
+    AUDIO_PRIMARY_VOLUME_TYPE_RINGTONE,         /**< Ringtone volume type */
+    AUDIO_PRIMARY_VOLUME_TYPE_VOICE,            /**< Voice volume type */
+    AUDIO_PRIMARY_VOLUME_TYPE_MEDIA,            /**< Media volume type */
+    AUDIO_PRIMARY_VOLUME_TYPE_ALARM,            /**< Alarm volume type */
+    AUDIO_PRIMARY_VOLUME_TYPE_NOTIFICATION,     /**< Notification volume type */
+    AUDIO_PRIMARY_VOLUME_TYPE_SYSTEM,           /**< System volume type */
+    AUDIO_PRIMARY_VOLUME_TYPE_FIXED,            /**< Volume type for fixed acoustic level */
+    AUDIO_PRIMARY_VOLUME_TYPE_MAX,              /**< Volume type count */
+} audio_primary_volume_t;
+#endif
+
+typedef enum audio_gain {
+    AUDIO_GAIN_TYPE_DEFAULT,
+    AUDIO_GAIN_TYPE_DIALER,
+    AUDIO_GAIN_TYPE_TOUCH,
+    AUDIO_GAIN_TYPE_AF,
+    AUDIO_GAIN_TYPE_SHUTTER1,
+    AUDIO_GAIN_TYPE_SHUTTER2,
+    AUDIO_GAIN_TYPE_CAMCODING,
+    AUDIO_GAIN_TYPE_MIDI,
+    AUDIO_GAIN_TYPE_BOOTING,
+    AUDIO_GAIN_TYPE_VIDEO,
+    AUDIO_GAIN_TYPE_TTS,
+    AUDIO_GAIN_TYPE_MAX,
+} audio_gain_t;
+
+typedef struct audio_stream_info {
+    char *name;
+    uint32_t samplerate;
+    uint8_t channels;
+    uint32_t volume_type;
+    uint32_t gain_type;
+} audio_stream_info_t ;
+
+
+/* Overall */
+
+typedef struct audio_info {
+    audio_device_info_t device;
+    audio_stream_info_t stream;
+} audio_info_t;
+
+typedef struct audio_cb_interface {
+    audio_return_t (*load_device)(void *platform_data, audio_device_info_t *device_info, audio_device_param_info_t *params);
+    audio_return_t (*open_device)(void *platform_data, audio_device_info_t *device_info, audio_device_param_info_t *params);
+    audio_return_t (*close_all_devices)(void *platform_data);
+    audio_return_t (*close_device)(void *platform_data, audio_device_info_t *device_info);
+    audio_return_t (*unload_device)(void *platform_data, audio_device_info_t *device_info);
+} audio_cb_interface_t;
+
+typedef struct audio_interface {
+    audio_return_t (*init)(void **userdata, void *platform_data);
+    audio_return_t (*deinit)(void **userdata);
+    audio_return_t (*reset)(void **userdata);
+    audio_return_t (*set_callback)(void *userdata, audio_cb_interface_t *cb_interface);
+    audio_return_t (*get_volume_level_max)(void *userdata, uint32_t volume_type, uint32_t *level);
+    audio_return_t (*get_volume_level)(void *userdata, uint32_t volume_type, uint32_t *level);
+    audio_return_t (*get_volume_value)(void *userdata, audio_info_t *info, uint32_t volume_type, uint32_t level, double *value);
+    audio_return_t (*set_volume_level)(void *userdata, audio_info_t *info, uint32_t volume_type, uint32_t level);
+    audio_return_t (*set_volume_value)(void *userdata, audio_info_t *info, uint32_t volume_type, double* value);
+    audio_return_t (*get_gain_value)(void *userdata, audio_info_t *info, uint32_t volume_type, double *value);
+    audio_return_t (*get_mute)(void *userdata, audio_info_t *info, uint32_t volume_type, uint32_t direction, uint32_t *mute);
+    audio_return_t (*set_mute)(void *userdata, audio_info_t *info, uint32_t volume_type, uint32_t direction, uint32_t mute);
+    audio_return_t (*set_session)(void *userdata, uint32_t session, uint32_t subsession, uint32_t cmd);
+    audio_return_t (*set_route)(void *userdata, uint32_t session, uint32_t subsession, uint32_t device_in, uint32_t device_out, uint32_t route_flag);
+    audio_return_t (*alsa_pcm_open)(void *userdata, void **pcm_handle, char *device_name, uint32_t direction, int mode);
+    audio_return_t (*alsa_pcm_close)(void *userdata, void *pcm_handle);
+    audio_return_t (*set_mixer_value_string)(void *userdata, const char* ctl, const char* value);
+
+} audio_interface_t;
+
+int audio_get_revision (void);
+audio_return_t audio_init (void **userdata, void *platform_data);
+audio_return_t audio_deinit (void **userdata);
+audio_return_t audio_reset (void **userdata);
+audio_return_t audio_set_callback (void *userdata, audio_cb_interface_t *cb_interface);
+audio_return_t audio_get_volume_level_max (void *userdata, uint32_t volume_type, uint32_t *level);
+audio_return_t audio_get_volume_level (void *userdata, uint32_t volume_type, uint32_t *level);
+audio_return_t audio_get_volume_value (void *userdata, audio_info_t *info, uint32_t volume_type, uint32_t level, double *value);
+audio_return_t audio_set_volume_level (void *userdata, audio_info_t *info, uint32_t volume_type, uint32_t level);
+audio_return_t audio_set_volume_value (void *userdata, audio_info_t *info, uint32_t volume_type, double* value);
+audio_return_t audio_get_gain_value (void *userdata, audio_info_t *info, uint32_t volume_type, double *value);
+audio_return_t audio_get_mute (void *userdata, audio_info_t *info, uint32_t volume_type, uint32_t direction, uint32_t *mute);
+audio_return_t audio_set_mute (void *userdata, audio_info_t *info, uint32_t volume_type, uint32_t direction, uint32_t mute);
+audio_return_t audio_set_session (void *userdata, uint32_t session, uint32_t subsession, uint32_t cmd);
+audio_return_t audio_alsa_pcm_open (void *userdata, void **pcm_handle, char *device_name, uint32_t direction, int mode);
+audio_return_t audio_alsa_pcm_close (void *userdata, void *pcm_handle);
+audio_return_t audio_set_route (void *userdata, uint32_t session, uint32_t subsession, uint32_t device_in, uint32_t device_out, uint32_t route_flag);
+
+#endif
index cc82446..b0bb17d 100644 (file)
@@ -58,6 +58,112 @@ static int read_id(struct udev_device *d, const char *n) {
     return u;
 }
 
+static int dehex(char x) {
+    if (x >= '0' && x <= '9')
+        return x - '0';
+
+    if (x >= 'A' && x <= 'F')
+        return x - 'A' + 10;
+
+    if (x >= 'a' && x <= 'f')
+        return x - 'a' + 10;
+
+    return -1;
+}
+
+static void proplist_sets_unescape(pa_proplist *p, const char *prop, const char *s) {
+    const char *f;
+    char *t, *r;
+    int c = 0;
+
+    enum {
+        TEXT,
+        BACKSLASH,
+        EX,
+        FIRST
+    } state = TEXT;
+
+    /* The resulting string is definitely shorter than the source string */
+    r = pa_xnew(char, strlen(s)+1);
+
+    for (f = s, t = r; *f; f++) {
+
+        switch (state) {
+
+            case TEXT:
+                if (*f == '\\')
+                    state = BACKSLASH;
+                else
+                    *(t++) = *f;
+                break;
+
+            case BACKSLASH:
+                if (*f == 'x')
+                    state = EX;
+                else {
+                    *(t++) = '\\';
+                    *(t++) = *f;
+                    state = TEXT;
+                }
+                break;
+
+            case EX:
+                c = dehex(*f);
+
+                if (c < 0) {
+                    *(t++) = '\\';
+                    *(t++) = 'x';
+                    *(t++) = *f;
+                    state = TEXT;
+                } else
+                    state = FIRST;
+
+                break;
+
+            case FIRST: {
+                int d = dehex(*f);
+
+                if (d < 0) {
+                    *(t++) = '\\';
+                    *(t++) = 'x';
+                    *(t++) = *(f-1);
+                    *(t++) = *f;
+                } else
+                    *(t++) = (char) (c << 4) | d;
+
+                state = TEXT;
+                break;
+            }
+        }
+    }
+
+    switch (state) {
+
+        case TEXT:
+            break;
+
+        case BACKSLASH:
+            *(t++) = '\\';
+            break;
+
+        case EX:
+            *(t++) = '\\';
+            *(t++) = 'x';
+            break;
+
+        case FIRST:
+            *(t++) = '\\';
+            *(t++) = 'x';
+            *(t++) = *(f-1);
+            break;
+    }
+
+    *t = 0;
+
+    pa_proplist_sets(p, prop, r);
+    pa_xfree(r);
+}
+
 int pa_udev_get_info(int card_idx, pa_proplist *p) {
     int r = -1;
     struct udev *udev;
@@ -74,7 +180,7 @@ int pa_udev_get_info(int card_idx, pa_proplist *p) {
         goto finish;
     }
 
-    t = pa_sprintf_malloc("%s/class/sound/card%i", udev_get_sys_path(udev), card_idx);
+    t = pa_sprintf_malloc("/sys/class/sound/card%i", card_idx);
     card = udev_device_new_from_syspath(udev, t);
     pa_xfree(t);
 
@@ -107,6 +213,8 @@ int pa_udev_get_info(int card_idx, pa_proplist *p) {
     if (!pa_proplist_contains(p, PA_PROP_DEVICE_VENDOR_NAME)) {
         if ((v = udev_device_get_property_value(card, "ID_VENDOR_FROM_DATABASE")) && *v)
             pa_proplist_sets(p, PA_PROP_DEVICE_VENDOR_NAME, v);
+        else if ((v = udev_device_get_property_value(card, "ID_VENDOR_ENC")) && *v)
+            proplist_sets_unescape(p, PA_PROP_DEVICE_VENDOR_NAME, v);
         else if ((v = udev_device_get_property_value(card, "ID_VENDOR")) && *v)
             pa_proplist_sets(p, PA_PROP_DEVICE_VENDOR_NAME, v);
     }
@@ -118,6 +226,8 @@ int pa_udev_get_info(int card_idx, pa_proplist *p) {
     if (!pa_proplist_contains(p, PA_PROP_DEVICE_PRODUCT_NAME)) {
         if ((v = udev_device_get_property_value(card, "ID_MODEL_FROM_DATABASE")) && *v)
             pa_proplist_sets(p, PA_PROP_DEVICE_PRODUCT_NAME, v);
+        else if ((v = udev_device_get_property_value(card, "ID_MODEL_ENC")) && *v)
+            proplist_sets_unescape(p, PA_PROP_DEVICE_PRODUCT_NAME, v);
         else if ((v = udev_device_get_property_value(card, "ID_MODEL")) && *v)
             pa_proplist_sets(p, PA_PROP_DEVICE_PRODUCT_NAME, v);
     }
@@ -134,7 +244,7 @@ int pa_udev_get_info(int card_idx, pa_proplist *p) {
         if ((v = udev_device_get_property_value(card, "SOUND_FORM_FACTOR")) && *v)
             pa_proplist_sets(p, PA_PROP_DEVICE_FORM_FACTOR, v);
 
-    /* This is normaly not set by the udev rules but may be useful to
+    /* This is normally not set by the udev rules but may be useful to
      * allow administrators to overwrite the device description.*/
     if (!pa_proplist_contains(p, PA_PROP_DEVICE_DESCRIPTION))
         if ((v = udev_device_get_property_value(card, "SOUND_DESCRIPTION")) && *v)
@@ -167,7 +277,7 @@ char* pa_udev_get_property(int card_idx, const char *name) {
         goto finish;
     }
 
-    t = pa_sprintf_malloc("%s/class/sound/card%i", udev_get_sys_path(udev), card_idx);
+    t = pa_sprintf_malloc("/sys/class/sound/card%i", card_idx);
     card = udev_device_new_from_syspath(udev, t);
     pa_xfree(t);
 
index 8523bc4..a978178 100644 (file)
@@ -23,7 +23,7 @@
 ***/
 
 
-#include <pulsecore/core.h>
+#include <pulse/proplist.h>
 
 int pa_udev_get_info(int card_idx, pa_proplist *p);
 char* pa_udev_get_property(int card_idx, const char *name);
diff --git a/src/modules/x11/module-x11-bell-symdef.h b/src/modules/x11/module-x11-bell-symdef.h
deleted file mode 100644 (file)
index 16afe33..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulex11bellsymdeffoo
-#define foomodulex11bellsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_x11_bell_LTX_pa__init
-#define pa__done module_x11_bell_LTX_pa__done
-#define pa__get_author module_x11_bell_LTX_pa__get_author
-#define pa__get_description module_x11_bell_LTX_pa__get_description
-#define pa__get_usage module_x11_bell_LTX_pa__get_usage
-#define pa__get_version module_x11_bell_LTX_pa__get_version
-#define pa__get_deprecated module_x11_bell_LTX_pa__get_deprecated
-#define pa__load_once module_x11_bell_LTX_pa__load_once
-#define pa__get_n_used module_x11_bell_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index ac303c3..37ab2e7 100644 (file)
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 
 #include <X11/Xlib.h>
 #include <X11/XKBlib.h>
 
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/iochannel.h>
-#include <pulsecore/sink.h>
 #include <pulsecore/core-scache.h>
 #include <pulsecore/modargs.h>
-#include <pulsecore/namereg.h>
 #include <pulsecore/log.h>
 #include <pulsecore/x11wrap.h>
 
diff --git a/src/modules/x11/module-x11-cork-request-symdef.h b/src/modules/x11/module-x11-cork-request-symdef.h
deleted file mode 100644 (file)
index f6b01b7..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulex11corkrequestsymdeffoo
-#define foomodulex11corkrequestsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_x11_cork_request_LTX_pa__init
-#define pa__done module_x11_cork_request_LTX_pa__done
-#define pa__get_author module_x11_cork_request_LTX_pa__get_author
-#define pa__get_description module_x11_cork_request_LTX_pa__get_description
-#define pa__get_usage module_x11_cork_request_LTX_pa__get_usage
-#define pa__get_version module_x11_cork_request_LTX_pa__get_version
-#define pa__get_deprecated module_x11_cork_request_LTX_pa__get_deprecated
-#define pa__load_once module_x11_cork_request_LTX_pa__load_once
-#define pa__get_n_used module_x11_cork_request_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index c1380c2..0e67db0 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 #include <unistd.h>
 
 #include <X11/Xlib.h>
@@ -33,7 +32,6 @@
 #include <X11/XF86keysym.h>
 #include <X11/keysym.h>
 
-#include <pulse/util.h>
 #include <pulse/xmalloc.h>
 
 #include <pulsecore/module.h>
diff --git a/src/modules/x11/module-x11-publish-symdef.h b/src/modules/x11/module-x11-publish-symdef.h
deleted file mode 100644 (file)
index b29f16e..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulex11publishsymdeffoo
-#define foomodulex11publishsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_x11_publish_LTX_pa__init
-#define pa__done module_x11_publish_LTX_pa__done
-#define pa__get_author module_x11_publish_LTX_pa__get_author
-#define pa__get_description module_x11_publish_LTX_pa__get_description
-#define pa__get_usage module_x11_publish_LTX_pa__get_usage
-#define pa__get_version module_x11_publish_LTX_pa__get_version
-#define pa__get_deprecated module_x11_publish_LTX_pa__get_deprecated
-#define pa__load_once module_x11_publish_LTX_pa__load_once
-#define pa__get_n_used module_x11_publish_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 7ee1b6d..16ea977 100644 (file)
 #include <string.h>
 #include <unistd.h>
 
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
+#include <xcb/xcb.h>
 
-#include <pulse/util.h>
 #include <pulse/xmalloc.h>
 
 #include <pulsecore/module.h>
-#include <pulsecore/sink.h>
-#include <pulsecore/core-scache.h>
 #include <pulsecore/modargs.h>
-#include <pulsecore/namereg.h>
 #include <pulsecore/log.h>
 #include <pulsecore/x11wrap.h>
 #include <pulsecore/core-util.h>
@@ -46,7 +41,6 @@
 #include <pulsecore/auth-cookie.h>
 #include <pulsecore/x11prop.h>
 #include <pulsecore/strlist.h>
-#include <pulsecore/shared.h>
 #include <pulsecore/protocol-native.h>
 
 #include "module-x11-publish-symdef.h"
@@ -85,6 +79,8 @@ struct userdata {
 
 static void publish_servers(struct userdata *u, pa_strlist *l) {
 
+    int screen = DefaultScreen(pa_x11_wrapper_get_display(u->x11_wrapper));
+
     if (l) {
         char *s;
 
@@ -92,20 +88,22 @@ static void publish_servers(struct userdata *u, pa_strlist *l) {
         s = pa_strlist_tostring(l);
         pa_strlist_reverse(l);
 
-        pa_x11_set_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_SERVER", s);
+        pa_x11_set_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_SERVER", s);
         pa_xfree(s);
     } else
-        pa_x11_del_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_SERVER");
+        pa_x11_del_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_SERVER");
 }
 
 static pa_hook_result_t servers_changed_cb(void *hook_data, void *call_data, void *slot_data) {
     pa_strlist *servers = call_data;
     struct userdata *u = slot_data;
     char t[256];
+    int screen;
 
     pa_assert(u);
 
-    if (!pa_x11_get_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_ID", t, sizeof(t)) || strcmp(t, u->id)) {
+    screen = DefaultScreen(pa_x11_wrapper_get_display(u->x11_wrapper));
+    if (!pa_x11_get_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_ID", t, sizeof(t)) || !pa_streq(t, u->id)) {
         pa_log_warn("PulseAudio information vanished from X11!");
         return PA_HOOK_OK;
     }
@@ -139,6 +137,7 @@ int pa__init(pa_module*m) {
     char *mid, *sid;
     char hx[PA_NATIVE_COOKIE_LENGTH*2+1];
     const char *t;
+    int screen;
 
     pa_assert(m);
 
@@ -158,32 +157,33 @@ int pa__init(pa_module*m) {
 
     u->hook_slot = pa_hook_connect(&pa_native_protocol_hooks(u->protocol)[PA_NATIVE_HOOK_SERVERS_CHANGED], PA_HOOK_NORMAL, servers_changed_cb, u);
 
-    if (!(u->auth_cookie = pa_auth_cookie_get(m->core, pa_modargs_get_value(ma, "cookie", PA_NATIVE_COOKIE_FILE), PA_NATIVE_COOKIE_LENGTH)))
+    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 (!(u->x11_wrapper = pa_x11_wrapper_get(m->core, pa_modargs_get_value(ma, "display", NULL))))
         goto fail;
 
+    screen = DefaultScreen(pa_x11_wrapper_get_display(u->x11_wrapper));
     mid = pa_machine_id();
     u->id = pa_sprintf_malloc("%lu@%s/%lu", (unsigned long) getuid(), mid, (unsigned long) getpid());
     pa_xfree(mid);
 
-    pa_x11_set_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_ID", u->id);
+    pa_x11_set_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_ID", u->id);
 
     if ((sid = pa_session_id())) {
-        pa_x11_set_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_SESSION_ID", sid);
+        pa_x11_set_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_SESSION_ID", sid);
         pa_xfree(sid);
     }
 
     publish_servers(u, pa_native_protocol_servers(u->protocol));
 
     if ((t = pa_modargs_get_value(ma, "source", NULL)))
-        pa_x11_set_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_SOURCE", t);
+        pa_x11_set_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_SOURCE", t);
 
     if ((t = pa_modargs_get_value(ma, "sink", NULL)))
-        pa_x11_set_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_SINK", t);
+        pa_x11_set_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_SINK", t);
 
-    pa_x11_set_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_COOKIE",
+    pa_x11_set_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_COOKIE",
                     pa_hexstr(pa_auth_cookie_read(u->auth_cookie, PA_NATIVE_COOKIE_LENGTH), PA_NATIVE_COOKIE_LENGTH, hx, sizeof(hx)));
 
     u->x11_client = pa_x11_client_new(u->x11_wrapper, NULL, x11_kill_cb, u);
@@ -214,18 +214,19 @@ void pa__done(pa_module*m) {
 
     if (u->x11_wrapper) {
         char t[256];
+        int screen = DefaultScreen(pa_x11_wrapper_get_display(u->x11_wrapper));
 
         /* Yes, here is a race condition */
-        if (!pa_x11_get_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_ID", t, sizeof(t)) || strcmp(t, u->id))
+        if (!pa_x11_get_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_ID", t, sizeof(t)) || !pa_streq(t, u->id))
             pa_log_warn("PulseAudio information vanished from X11!");
         else {
-            pa_x11_del_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_ID");
-            pa_x11_del_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_SERVER");
-            pa_x11_del_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_SINK");
-            pa_x11_del_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_SOURCE");
-            pa_x11_del_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_COOKIE");
-            pa_x11_del_prop(pa_x11_wrapper_get_display(u->x11_wrapper), "PULSE_SESSION_ID");
-            XSync(pa_x11_wrapper_get_display(u->x11_wrapper), False);
+            pa_x11_del_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_ID");
+            pa_x11_del_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_SERVER");
+            pa_x11_del_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_SINK");
+            pa_x11_del_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_SOURCE");
+            pa_x11_del_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_COOKIE");
+            pa_x11_del_prop(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper), screen, "PULSE_SESSION_ID");
+            xcb_flush(pa_x11_wrapper_get_xcb_connection(u->x11_wrapper));
         }
 
         pa_x11_wrapper_unref(u->x11_wrapper);
diff --git a/src/modules/x11/module-x11-xsmp-symdef.h b/src/modules/x11/module-x11-xsmp-symdef.h
deleted file mode 100644 (file)
index 27dac60..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef foomodulex11xsmpsymdeffoo
-#define foomodulex11xsmpsymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-#include <pulsecore/macro.h>
-
-#define pa__init module_x11_xsmp_LTX_pa__init
-#define pa__done module_x11_xsmp_LTX_pa__done
-#define pa__get_author module_x11_xsmp_LTX_pa__get_author
-#define pa__get_description module_x11_xsmp_LTX_pa__get_description
-#define pa__get_usage module_x11_xsmp_LTX_pa__get_usage
-#define pa__get_version module_x11_xsmp_LTX_pa__get_version
-#define pa__get_deprecated module_x11_xsmp_LTX_pa__get_deprecated
-#define pa__load_once module_x11_xsmp_LTX_pa__load_once
-#define pa__get_n_used module_x11_xsmp_LTX_pa__get_n_used
-
-int pa__init(pa_module*m);
-void pa__done(pa_module*m);
-int pa__get_n_used(pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-const char* pa__get_deprecated(void);
-pa_bool_t pa__load_once(void);
-
-#endif
index 28fd373..765eff0 100644 (file)
 #include <pulse/xmalloc.h>
 #include <pulse/util.h>
 
-#include <pulsecore/iochannel.h>
-#include <pulsecore/sink.h>
-#include <pulsecore/core-scache.h>
 #include <pulsecore/modargs.h>
-#include <pulsecore/namereg.h>
 #include <pulsecore/log.h>
-#include <pulsecore/core-util.h>
 #include <pulsecore/x11wrap.h>
 
 #include "module-x11-xsmp-symdef.h"
@@ -101,7 +96,7 @@ static void ice_io_cb(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_fla
 }
 
 static void new_ice_connection(IceConn connection, IcePointer client_data, Bool opening, IcePointer *watch_data) {
-    struct pa_core *c = client_data;
+    pa_core *c = client_data;
 
     if (opening)
         *watch_data = c->mainloop->io_new(
@@ -129,7 +124,7 @@ int pa__init(pa_module*m) {
     pa_assert(m);
 
     if (ice_in_use) {
-        pa_log("module-x11-xsmp may no be loaded twice.");
+        pa_log("module-x11-xsmp may not be loaded twice.");
         return -1;
     }
 
diff --git a/src/modules/xen/gntalloc.h b/src/modules/xen/gntalloc.h
new file mode 100644 (file)
index 0000000..4a9921c
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * This file is copied from the linux kernel headers. It defines the standard
+ * interface to the xen/gntalloc device.
+ *
+ */
+
+/******************************************************************************
+ * gntalloc.h
+ *
+ * Interface to /dev/xen/gntalloc.
+ *
+ * Author: Daniel De Graaf <dgdegra@tycho.nsa.gov>
+ *
+ * This file is in the public domain.
+ */
+
+#ifndef __LINUX_PUBLIC_GNTALLOC_H__
+#define __LINUX_PUBLIC_GNTALLOC_H__
+
+/*
+ * Allocates a new page and creates a new grant reference.
+ */
+#define IOCTL_GNTALLOC_ALLOC_GREF \
+_IOC(_IOC_NONE, 'G', 5, sizeof(struct ioctl_gntalloc_alloc_gref))
+struct ioctl_gntalloc_alloc_gref {
+       /* IN parameters */
+       /* The ID of the domain to be given access to the grants. */
+       uint16_t domid;
+       /* Flags for this mapping */
+       uint16_t flags;
+       /* Number of pages to map */
+       uint32_t count;
+       /* OUT parameters */
+       /* The offset to be used on a subsequent call to mmap(). */
+       uint64_t index;
+       /* The grant references of the newly created grant, one per page */
+       /* Variable size, depending on count */
+       uint32_t gref_ids[1];
+};
+
+#define GNTALLOC_FLAG_WRITABLE 1
+
+/*
+ * Deallocates the grant reference, allowing the associated page to be freed if
+ * no other domains are using it.
+ */
+#define IOCTL_GNTALLOC_DEALLOC_GREF \
+_IOC(_IOC_NONE, 'G', 6, sizeof(struct ioctl_gntalloc_dealloc_gref))
+struct ioctl_gntalloc_dealloc_gref {
+       /* IN parameters */
+       /* The offset returned in the map operation */
+       uint64_t index;
+       /* Number of references to unmap */
+       uint32_t count;
+};
+
+/*
+ * Sets up an unmap notification within the page, so that the other side can do
+ * cleanup if this side crashes. Required to implement cross-domain robust
+ * mutexes or close notification on communication channels.
+ *
+ * Each mapped page only supports one notification; multiple calls referring to
+ * the same page overwrite the previous notification. You must clear the
+ * notification prior to the IOCTL_GNTALLOC_DEALLOC_GREF if you do not want it
+ * to occur.
+ */
+#define IOCTL_GNTALLOC_SET_UNMAP_NOTIFY \
+_IOC(_IOC_NONE, 'G', 7, sizeof(struct ioctl_gntalloc_unmap_notify))
+struct ioctl_gntalloc_unmap_notify {
+       /* IN parameters */
+       /* Offset in the file descriptor for a byte within the page (same as
+        * used in mmap). If using UNMAP_NOTIFY_CLEAR_BYTE, this is the byte to
+        * be cleared. Otherwise, it can be any byte in the page whose
+        * notification we are adjusting.
+        */
+       uint64_t index;
+       /* Action(s) to take on unmap */
+       uint32_t action;
+       /* Event channel to notify */
+       uint32_t event_channel_port;
+};
+
+/* Clear (set to zero) the byte specified by index */
+#define UNMAP_NOTIFY_CLEAR_BYTE 0x1
+/* Send an interrupt on the indicated event channel */
+#define UNMAP_NOTIFY_SEND_EVENT 0x2
+
+#endif /* __LINUX_PUBLIC_GNTALLOC_H__ */
diff --git a/src/modules/xen/gntdev.h b/src/modules/xen/gntdev.h
new file mode 100644 (file)
index 0000000..7f65a38
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * This file is copied from the linux kernel headers. It defines the standard
+ * interface to the xen/gntdev device.
+ *
+ */
+
+/******************************************************************************
+ * gntdev.h
+ *
+ * Interface to /dev/xen/gntdev.
+ *
+ * Copyright (c) 2007, D G Murray
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __LINUX_PUBLIC_GNTDEV_H__
+#define __LINUX_PUBLIC_GNTDEV_H__
+
+struct ioctl_gntdev_grant_ref {
+       /* The domain ID of the grant to be mapped. */
+       uint32_t domid;
+       /* The grant reference of the grant to be mapped. */
+       uint32_t ref;
+};
+
+/*
+ * Inserts the grant references into the mapping table of an instance
+ * of gntdev. N.B. This does not perform the mapping, which is deferred
+ * until mmap() is called with @index as the offset.
+ */
+#define IOCTL_GNTDEV_MAP_GRANT_REF \
+_IOC(_IOC_NONE, 'G', 0, sizeof(struct ioctl_gntdev_map_grant_ref))
+struct ioctl_gntdev_map_grant_ref {
+       /* IN parameters */
+       /* The number of grants to be mapped. */
+       uint32_t count;
+       uint32_t pad;
+       /* OUT parameters */
+       /* The offset to be used on a subsequent call to mmap(). */
+       uint64_t index;
+       /* Variable IN parameter. */
+       /* Array of grant references, of size @count. */
+       struct ioctl_gntdev_grant_ref refs[1];
+};
+
+/*
+ * Removes the grant references from the mapping table of an instance of
+ * of gntdev. N.B. munmap() must be called on the relevant virtual address(es)
+ * before this ioctl is called, or an error will result.
+ */
+#define IOCTL_GNTDEV_UNMAP_GRANT_REF \
+_IOC(_IOC_NONE, 'G', 1, sizeof(struct ioctl_gntdev_unmap_grant_ref))
+struct ioctl_gntdev_unmap_grant_ref {
+       /* IN parameters */
+       /* The offset was returned by the corresponding map operation. */
+       uint64_t index;
+       /* The number of pages to be unmapped. */
+       uint32_t count;
+       uint32_t pad;
+};
+
+/*
+ * Returns the offset in the driver's address space that corresponds
+ * to @vaddr. This can be used to perform a munmap(), followed by an
+ * UNMAP_GRANT_REF ioctl, where no state about the offset is retained by
+ * the caller. The number of pages that were allocated at the same time as
+ * @vaddr is returned in @count.
+ *
+ * N.B. Where more than one page has been mapped into a contiguous range, the
+ *      supplied @vaddr must correspond to the start of the range; otherwise
+ *      an error will result. It is only possible to munmap() the entire
+ *      contiguously-allocated range at once, and not any subrange thereof.
+ */
+#define IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR \
+_IOC(_IOC_NONE, 'G', 2, sizeof(struct ioctl_gntdev_get_offset_for_vaddr))
+struct ioctl_gntdev_get_offset_for_vaddr {
+       /* IN parameters */
+       /* The virtual address of the first mapped page in a range. */
+       uint64_t vaddr;
+       /* OUT parameters */
+       /* The offset that was used in the initial mmap() operation. */
+       uint64_t offset;
+       /* The number of pages mapped in the VM area that begins at @vaddr. */
+       uint32_t count;
+       uint32_t pad;
+};
+
+/*
+ * Sets the maximum number of grants that may mapped at once by this gntdev
+ * instance.
+ *
+ * N.B. This must be called before any other ioctl is performed on the device.
+ */
+#define IOCTL_GNTDEV_SET_MAX_GRANTS \
+_IOC(_IOC_NONE, 'G', 3, sizeof(struct ioctl_gntdev_set_max_grants))
+struct ioctl_gntdev_set_max_grants {
+       /* IN parameter */
+       /* The maximum number of grants that may be mapped at once. */
+       uint32_t count;
+};
+
+/*
+ * Sets up an unmap notification within the page, so that the other side can do
+ * cleanup if this side crashes. Required to implement cross-domain robust
+ * mutexes or close notification on communication channels.
+ *
+ * Each mapped page only supports one notification; multiple calls referring to
+ * the same page overwrite the previous notification. You must clear the
+ * notification prior to the IOCTL_GNTALLOC_DEALLOC_GREF if you do not want it
+ * to occur.
+ */
+#define IOCTL_GNTDEV_SET_UNMAP_NOTIFY \
+_IOC(_IOC_NONE, 'G', 7, sizeof(struct ioctl_gntdev_unmap_notify))
+struct ioctl_gntdev_unmap_notify {
+       /* IN parameters */
+       /* Offset in the file descriptor for a byte within the page (same as
+        * used in mmap). If using UNMAP_NOTIFY_CLEAR_BYTE, this is the byte to
+        * be cleared. Otherwise, it can be any byte in the page whose
+        * notification we are adjusting.
+        */
+       uint64_t index;
+       /* Action(s) to take on unmap */
+       uint32_t action;
+       /* Event channel to notify */
+       uint32_t event_channel_port;
+};
+
+/* Clear (set to zero) the byte specified by index */
+#define UNMAP_NOTIFY_CLEAR_BYTE 0x1
+/* Send an interrupt on the indicated event channel */
+#define UNMAP_NOTIFY_SEND_EVENT 0x2
+
+#endif /* __LINUX_PUBLIC_GNTDEV_H__ */
diff --git a/src/modules/xen/module-xenpv-sink.c b/src/modules/xen/module-xenpv-sink.c
new file mode 100644 (file)
index 0000000..6f82ff4
--- /dev/null
@@ -0,0 +1,804 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2011 George Boutsioukis for Xen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/ioctl.h>
+#include <poll.h>
+#include <time.h>
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/core-error.h>
+#include <pulsecore/sink.h>
+#include <pulsecore/module.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/log.h>
+#include <pulsecore/thread.h>
+#include <pulsecore/thread-mq.h>
+#include <pulsecore/rtpoll.h>
+
+#include <sys/select.h>
+#include <sys/mman.h>
+#include <xenctrl.h>
+#include <xs.h>
+
+#include "module-xenpv-sink-symdef.h"
+#include "gntalloc.h"
+#include "gntdev.h"
+
+PA_MODULE_AUTHOR("Giorgos Boutsioukis");
+PA_MODULE_DESCRIPTION("Xen PV audio sink");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(FALSE);
+PA_MODULE_USAGE(
+        "sink_name=<name for the sink> "
+        "sink_properties=<properties for the sink> "
+        "format=<sample format> "
+        "rate=<sample rate>"
+        "channels=<number of channels> "
+        "channel_map=<channel map>");
+
+#define DEFAULT_SINK_NAME "xenpv_output"
+#define DEFAULT_FILE_NAME "xenpv_output"
+
+#define STATE_UNDEFINED 9999
+
+int device_id = -1;
+enum xenbus_state {
+       XenbusStateUnknown      = 0,
+       XenbusStateInitialising = 1,
+       XenbusStateInitWait     = 2,
+       XenbusStateInitialised  = 3,
+       XenbusStateConnected    = 4,
+       XenbusStateClosing      = 5,
+       XenbusStateClosed       = 6,
+       XenbusStateReconfiguring = 7,
+       XenbusStateReconfigured  = 8
+};
+
+static const char* xenbus_names[] = {
+    "XenbusStateUnknown",
+    "XenbusStateInitialising",
+    "XenbusStateInitWait",
+    "XenbusStateInitialised",
+    "XenbusStateConnected",
+    "XenbusStateClosing",
+    "XenbusStateClosed",
+    "XenbusStateReconfiguring",
+    "XenbusStateReconfigured"
+};
+
+struct userdata {
+    pa_core *core;
+    pa_module *module;
+    pa_sink *sink;
+
+    pa_thread *thread;
+    pa_thread_mq thread_mq;
+    pa_rtpoll *rtpoll;
+
+    pa_memchunk memchunk;
+
+    pa_rtpoll_item *rtpoll_item;
+
+    int write_type;
+};
+
+pa_sample_spec ss;
+pa_channel_map map;
+
+/* just to test non- frame-aligned size */
+#define BUFSIZE 2047
+
+struct ring {
+    uint32_t cons_indx, prod_indx;
+    uint32_t usable_buffer_space; /* kept here for convenience */
+    uint8_t buffer[BUFSIZE];
+} *ioring;
+
+static const char* const valid_modargs[] = {
+    "sink_name",
+    "sink_properties",
+    "file",
+    "format",
+    "rate",
+    "channels",
+    "channel_map",
+    NULL
+};
+
+/* Xen globals*/
+xc_interface* xch;
+xc_evtchn* xce;
+evtchn_port_or_error_t xen_evtchn_port;
+static struct xs_handle *xsh;
+struct ioctl_gntalloc_alloc_gref gref;
+
+static int register_backend_state_watch(void);
+static int wait_for_backend_state_change(void);
+static int alloc_gref(struct ioctl_gntalloc_alloc_gref *gref, void **addr);
+static int ring_write(struct ring *r, void *src, int length);
+static int publish_spec(pa_sample_spec *ss);
+static int read_backend_default_spec(pa_sample_spec *ss);
+static int publish_param(const char *paramname, const char *value);
+static int publish_param_int(const char *paramname, const int value);
+static char* read_param(const char *paramname);
+
+static int set_state(int state) {
+    static int current_state = 0;
+    pa_log_debug("State transition %s->%s\n",
+            xenbus_names[current_state], xenbus_names[state]);
+
+    publish_param_int("state", state);
+    current_state = state;
+    return state;
+}
+#define NEGOTIATION_ERROR 2
+#define NEGOTIATION_OK 1
+
+/* negotiation callbacks */
+static int state_unknown_cb() {
+    pa_log_debug("Xen audio sink: Backend state was XenbusStateUnknown\n");
+    set_state(XenbusStateInitialising);
+
+    return 0;
+}
+
+static int state_initialising_cb() {
+    pa_log_debug("Xen audio sink: Backend state was XenbusStateInitialising\n");
+    set_state(XenbusStateInitialised);
+    return 0;
+}
+
+static int state_initwait_cb() {
+    pa_log_debug("Xen audio sink: Backend state was XenbusStateInitWait\n");
+    return 0;
+}
+
+static int state_initialised_cb() {
+    pa_log_debug("Xen audio sink: Backend state was XenbusStateInitialised\n");
+    /*Remind the backend we are ready*/
+    set_state(XenbusStateInitialised);
+    return 0;
+}
+
+static int state_connected_cb() {
+    /* The backend accepted our parameters, sweet! */
+    set_state(XenbusStateConnected);
+    pa_log_debug("Xen audio sink: Backend state was XenbusStateConnected\n");
+    return NEGOTIATION_OK;
+}
+
+static int state_closing_cb() {
+    pa_log_debug("Xen audio sink: Backend state was XenbusStateClosing\n");
+    return 0;
+}
+
+static int state_closed_cb() {
+    pa_log_debug("Xen audio sink: Backend state was XenbusStateClosed\n");
+    return 0;
+}
+
+static int state_reconfiguring_cb() {
+    /* The backend rejected our sample spec */
+    pa_log_debug("Xen audio sink: Backend state was XenbusStateReconfiguring\n");
+    /* fall back to the backend's default parameters*/
+    read_backend_default_spec(&ss);
+    /* backend should accept these now */
+    publish_spec(&ss);
+    set_state(XenbusStateInitialised);
+    return 0;
+}
+
+static int state_reconfigured_cb() {
+    pa_log_debug("Xen audio sink: Backend state was XenbusStateReconfigured\n");
+    return 0;
+}
+
+int (*state_callbacks[9])(void) = {
+    state_unknown_cb,
+    state_initialising_cb,
+    state_initwait_cb,
+    state_initialised_cb,
+    state_connected_cb,
+    state_closing_cb,
+    state_closed_cb,
+    state_reconfiguring_cb,
+    state_reconfigured_cb
+};
+
+static void xen_cleanup() {
+    char keybuf[64];
+    /*XXX hardcoded*/
+    munmap((void*)gref.index, 4096);
+
+    set_state(XenbusStateClosing);
+    /* send one last event to unblock the backend */
+    xc_evtchn_notify(xce, xen_evtchn_port);
+    /* close xen interfaces */
+    xc_evtchn_close(xce);
+    xc_interface_close(xch);
+
+    /* delete xenstore keys */
+    publish_param_int("state", XenbusStateClosed);
+    snprintf(keybuf, sizeof(keybuf), "device/audio/%d", device_id);
+    xs_rm(xsh, 0, keybuf);
+    xs_daemon_close(xsh);
+}
+
+static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
+    struct userdata *u = PA_SINK(o)->userdata;
+
+    switch (code) {
+
+        case PA_SINK_MESSAGE_GET_LATENCY: {
+            size_t n = 0;
+
+            n += u->memchunk.length;
+
+            *((pa_usec_t*) data) = pa_bytes_to_usec(n, &u->sink->sample_spec);
+            return 0;
+        }
+    }
+
+    return pa_sink_process_msg(o, code, data, offset, chunk);
+}
+
+static int process_render(struct userdata *u) {
+    pa_assert(u);
+
+
+    if (u->memchunk.length <= 0)
+        pa_sink_render(u->sink, ioring->usable_buffer_space, &u->memchunk);
+
+
+    pa_assert(u->memchunk.length > 0);
+
+    xc_evtchn_notify(xce, xen_evtchn_port);
+    for (;;) {
+        ssize_t l;
+        void *p;
+
+        p = pa_memblock_acquire(u->memchunk.memblock);
+           /* xen: write data to ring buffer & notify backend */
+        l = ring_write(ioring, (uint8_t*)p + u->memchunk.index, u->memchunk.length);
+
+        pa_memblock_release(u->memchunk.memblock);
+
+        pa_assert(l != 0);
+
+        if (l < 0) {
+            if (errno == EINTR)
+                continue;
+            else if (errno == EAGAIN)
+                return 0;
+            else {
+                pa_log("Failed to write data to FIFO: %s", pa_cstrerror(errno));
+                return -1;
+            }
+
+        } else {
+
+            u->memchunk.index += (size_t) l;
+            u->memchunk.length -= (size_t) l;
+
+            if (u->memchunk.length <= 0) {
+                pa_memblock_unref(u->memchunk.memblock);
+                pa_memchunk_reset(&u->memchunk);
+            }
+        }
+
+        return 0;
+    }
+}
+
+static void thread_func(void *userdata) {
+    struct userdata *u = userdata;
+
+    pa_assert(u);
+
+    pa_log_debug("Thread starting up");
+
+    pa_thread_mq_install(&u->thread_mq);
+
+    for(;;){
+        struct pollfd *pollfd;
+        int ret;
+
+        pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
+
+        if (PA_UNLIKELY(u->sink->thread_info.rewind_requested))
+            pa_sink_process_rewind(u->sink, 0);
+
+        /* Render some data and write it to the fifo */
+        if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
+            if (pollfd->revents) {
+                if (process_render(u) < 0)
+                    goto fail;
+
+                pollfd->revents = 0;
+            }
+        }
+
+        /* Hmm, nothing to do. Let's sleep */
+
+        pollfd->events = (short) (u->sink->thread_info.state == PA_SINK_RUNNING ? POLLOUT : 0);
+
+        if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
+            goto fail;
+
+        if (ret == 0)
+            goto finish;
+
+        pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
+
+        if (pollfd->revents & ~POLLOUT) {
+            pa_log("FIFO shutdown.");
+            goto fail;
+        }
+    }
+
+fail:
+    /* If this was no regular exit from the loop we have to continue
+     * processing messages until we received PA_MESSAGE_SHUTDOWN */
+    pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
+    pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
+    pa_log_debug("Shutting down Xen...");
+    xen_cleanup();
+finish:
+    pa_log_debug("Thread shutting down");
+}
+
+int pa__init(pa_module*m) {
+
+    struct userdata *u;
+    pa_modargs *ma;
+    pa_sink_new_data data;
+    int backend_state;
+    int ret;
+    char strbuf[100];
+
+    pa_assert(m);
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log("Failed to parse module arguments.");
+        goto fail;
+    }
+
+    ss = m->core->default_sample_spec;
+    map = m->core->default_channel_map;
+
+    /* user arguments override these */
+    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");
+        return 1;
+    }
+
+    /* Xen Basic init */
+    xsh = xs_domain_open();
+    if (xsh==NULL) {
+        pa_log("xs_domain_open failed");
+        goto fail;
+    }
+    set_state(XenbusStateUnknown);
+
+    xch = xc_interface_open(NULL, NULL, 0);
+    if (xch==0) {
+        pa_log("xc_interface_open failed");
+        goto fail;
+    }
+
+    xce = xc_evtchn_open(NULL, 0);
+    if (xce==0) {
+        pa_log("xc_evtchn_open failed");
+        goto fail;
+    }
+
+    /* use only dom0 as the backend for now */
+    xen_evtchn_port = xc_evtchn_bind_unbound_port(xce, 0);
+    if (xen_evtchn_port == 0) {
+        pa_log("xc_evtchn_bind_unbound_port failed");
+    }
+
+    /* get grant reference & map locally */
+    if (alloc_gref(&gref, (void**)&ioring)) {
+       pa_log("alloc_gref failed");
+    };
+    device_id = 0; /* hardcoded for now */
+
+    if (register_backend_state_watch()) {
+        pa_log("Xen sink: register xenstore watch failed");
+    };
+
+    publish_param_int("event-channel", xen_evtchn_port);
+    publish_param_int("ring-ref", gref.gref_ids[0]);
+
+    /* let's ask for something absurd and deal with rejection */
+    ss.rate = 192000;
+
+    publish_spec(&ss);
+
+    ret=0;
+    while (!ret) {
+        backend_state = wait_for_backend_state_change();
+        if (backend_state == STATE_UNDEFINED) {
+            pa_log("Xen Backend is taking long to respond, still waiting...");
+            continue;
+        } else if (backend_state == -1) {
+            pa_log("Error while waiting for backend: %s", strerror(errno));
+            break;
+            goto fail;
+        }
+        ret = state_callbacks[backend_state]();
+    }
+    if (ret!=NEGOTIATION_OK) {
+        pa_log("Negotiation with Xen backend failed!");
+        return 1;
+    }
+
+    pa_sample_spec_snprint(strbuf, 100, &ss);
+    pa_log_debug("Negotiation ended, the result was: %s", strbuf);
+
+    /* End of Phase 2, begin playback cycle */
+
+    u = pa_xnew0(struct userdata, 1);
+    u->core = m->core;
+    u->module = m;
+    m->userdata = u;
+    pa_memchunk_reset(&u->memchunk);
+    u->rtpoll = pa_rtpoll_new();
+    pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
+    u->write_type = 0;
+
+    /* init ring buffer */
+    ioring->prod_indx = ioring->cons_indx = 0;
+    ioring->usable_buffer_space = BUFSIZE - BUFSIZE % pa_frame_size(&ss);
+
+    pa_sink_new_data_init(&data);
+    data.driver = __FILE__;
+    data.module = m;
+    pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME));
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, "xensink");
+    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Xen PV audio sink");
+    pa_sink_new_data_set_sample_spec(&data, &ss);
+    pa_sink_new_data_set_channel_map(&data, &map);
+
+    if (pa_modargs_get_proplist(ma, "sink_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
+        pa_log("Invalid properties");
+        pa_sink_new_data_done(&data);
+        goto fail;
+    }
+
+    u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY);
+    pa_sink_new_data_done(&data);
+
+    if (!u->sink) {
+        pa_log("Failed to create sink.");
+        goto fail;
+    }
+
+    u->sink->parent.process_msg = sink_process_msg;
+    u->sink->userdata = u;
+
+    pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
+    pa_sink_set_rtpoll(u->sink, u->rtpoll);
+    pa_sink_set_max_request(u->sink, ioring->usable_buffer_space);
+    pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(ioring->usable_buffer_space, &u->sink->sample_spec));
+
+    u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1);
+
+    if (!(u->thread = pa_thread_new("xenpv-sink", thread_func, u))) {
+        pa_log("Failed to create thread.");
+        goto fail;
+    }
+
+    pa_sink_put(u->sink);
+
+    pa_modargs_free(ma);
+
+    return 0;
+
+fail:
+    if (ma)
+        pa_modargs_free(ma);
+
+    pa__done(m);
+
+    return -1;
+}
+
+int pa__get_n_used(pa_module *m) {
+    struct userdata *u;
+
+    pa_assert(m);
+    pa_assert_se(u = m->userdata);
+
+    return pa_sink_linked_by(u->sink);
+}
+
+void pa__done(pa_module*m) {
+    struct userdata *u;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    if (u->sink)
+        pa_sink_unlink(u->sink);
+
+    if (u->thread) {
+        pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
+        pa_thread_free(u->thread);
+    }
+
+    pa_thread_mq_done(&u->thread_mq);
+
+    if (u->sink)
+        pa_sink_unref(u->sink);
+
+    if (u->memchunk.memblock)
+       pa_memblock_unref(u->memchunk.memblock);
+
+    if (u->rtpoll_item)
+        pa_rtpoll_item_free(u->rtpoll_item);
+
+    if (u->rtpoll)
+        pa_rtpoll_free(u->rtpoll);
+
+    pa_xfree(u);
+
+    xen_cleanup();
+
+}
+
+
+static int alloc_gref(struct ioctl_gntalloc_alloc_gref *gref_, void **addr) {
+    int alloc_fd, dev_fd, rv;
+
+    alloc_fd = open("/dev/xen/gntalloc", O_RDWR);
+    if (alloc_fd<=0) {
+        perror("Could not open /dev/xen/gntalloc! Have you loaded the xen_gntalloc module?");
+        return 1;
+    }
+
+    dev_fd = open("/dev/xen/gntdev", O_RDWR);
+    if (dev_fd<=0) {
+        perror("Could not open /dev/xen/gntdev! Have you loaded the xen_gntdev module?");
+        return 1;
+    }
+
+    /* use dom0 */
+    gref_->domid = 0;
+    gref_->flags = GNTALLOC_FLAG_WRITABLE;
+    gref_->count = 1;
+
+    rv = ioctl(alloc_fd, IOCTL_GNTALLOC_ALLOC_GREF, gref_);
+    if (rv) {
+        pa_log_debug("Xen audio sink: src-add error: %s (rv=%d)\n", strerror(errno), rv);
+        return rv;
+    }
+
+    /*addr=NULL(default),length, prot,             flags,    fd,         offset*/
+    *addr = mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, alloc_fd, gref_->index);
+    if (*addr == MAP_FAILED) {
+        *addr = 0;
+        pa_log_debug("Xen audio sink: mmap'ing shared page failed\n");
+        return rv;
+    }
+
+    pa_log_debug("Xen audio sink: Got grant #%d. Mapped locally at %Ld=%p\n",
+            gref_->gref_ids[0], (long long)gref_->index, *addr);
+
+    /* skip this for now
+       struct ioctl_gntalloc_unmap_notify uarg = {
+       .index = gref->index + offsetof(struct shr_page, notifies[0]),
+       .action = UNMAP_NOTIFY_CLEAR_BYTE
+       };
+
+       rv = ioctl(a_fd, IOCTL_GNTALLOC_SET_UNMAP_NOTIFY, &uarg);
+       if (rv)
+       pa_log_debug("gntalloc unmap notify error: %s (rv=%d)\n", strerror(errno), rv);
+       */
+
+    close(alloc_fd);
+    close(dev_fd);
+
+    return rv;
+}
+
+#define RING_FREE_BYTES ((r->usable_buffer_space - (r->prod_indx-r->cons_indx) -1) % r->usable_buffer_space)
+static int ring_write(struct ring *r, void *src, int length) {
+    int full = 0;
+    for (;;) {
+        /* free space may be split over the end of the buffer */
+        int first_chunk_size = (r->usable_buffer_space-r->prod_indx);
+        int second_chunk_size = (r->cons_indx>=r->prod_indx)? (r->cons_indx) : 0;
+        int l, fl, sl;
+
+        /* full? */
+        if (RING_FREE_BYTES==0) {
+            /*XXX hardcoded*/
+            if (full>=100) {
+                errno = EINTR;
+                return -1;
+            }
+            /*XXX hardcoded */
+            usleep(1000);
+            /* should return in 100ms max; definitely not midstream */
+            full++;
+            continue;
+        }
+
+        /* calculate lengths in case of a split buffer */
+        l = PA_MIN((int)RING_FREE_BYTES, length);
+        fl = PA_MIN(l, first_chunk_size);
+        sl = PA_MIN(l-fl, second_chunk_size);
+
+        memcpy(r->buffer+r->prod_indx, src, fl);
+        if (sl)
+            memcpy(r->buffer, ((char*)src)+fl, sl);
+        r->prod_indx = (r->prod_indx+fl+sl) % r->usable_buffer_space;
+
+        return sl+fl;
+    }
+}
+
+static int publish_param(const char *paramname, const char *value) {
+    char keybuf[128], valbuf[32];
+
+    snprintf(keybuf, sizeof keybuf, "device/audio/%d/%s", device_id, paramname);
+    snprintf(valbuf, sizeof valbuf, "%s", value);
+    return xs_write(xsh, 0, keybuf, valbuf, strlen(valbuf));
+}
+
+static int publish_param_int(const char *paramname, const int value) {
+    char keybuf[128], valbuf[32];
+    snprintf(keybuf, sizeof keybuf, "device/audio/%d/%s", device_id, paramname);
+    snprintf(valbuf, sizeof valbuf, "%d", value);
+    return xs_write(xsh, 0, keybuf, valbuf, strlen(valbuf));
+}
+
+static char* read_param(const char *paramname) {
+    char keybuf[128];
+    unsigned int len;
+    int my_domid;
+
+    my_domid = atoi(xs_read(xsh, 0, "domid", &len));
+    snprintf(keybuf, sizeof(keybuf), "/local/domain/0/backend/audio/%d/%d/%s", my_domid, device_id, paramname);
+    /* remember to free lvalue! */
+    return xs_read(xsh, 0, keybuf, &len);
+}
+
+
+static int publish_spec(pa_sample_spec *sample_spec) {
+    /* Publish spec and set state to XenbusStateInitWait*/
+    int ret;
+
+    ret = publish_param("format", pa_sample_format_to_string(sample_spec->format));
+    ret += publish_param_int("rate", sample_spec->rate);
+    ret += publish_param_int("channels", sample_spec->channels);
+
+    return ret;
+}
+
+
+static int read_backend_default_spec(pa_sample_spec *sample_spec) {
+    /* Read spec from backend */
+    char *out;
+
+    out = read_param("default-format");
+    sample_spec->format = pa_parse_sample_format(out);
+    free(out);
+
+    out = read_param("default-rate");
+    sample_spec->rate = atoi(out);
+    free(out);
+
+    out = read_param("default-channels");
+    sample_spec->channels = atoi(out);
+    free(out);
+
+    return 0;
+}
+
+static int register_backend_state_watch() {
+    char keybuf[128];
+    int my_domid;
+    unsigned int len;
+
+    my_domid = atoi(xs_read(xsh, 0, "domid", &len));
+    snprintf(keybuf, sizeof(keybuf), "/local/domain/0/backend/audio/%d/%d/state", my_domid, device_id);
+    if (!xs_watch(xsh, keybuf, "xenpvaudiofrontendsinktoken")) {
+        perror("xs_watch failed");
+        return -EINVAL;
+    }
+    return 0;
+}
+
+static int wait_for_backend_state_change() {
+    char keybuf[128];
+    int my_domid;
+    unsigned int len;
+
+    int backend_state;
+    int seconds;
+    char *buf, **vec;
+    int ret;
+
+    int xs_fd;
+    struct timeval tv;
+       fd_set watch_fdset;
+    int start, now;
+
+    backend_state = STATE_UNDEFINED;
+    xs_fd = xs_fileno(xsh);
+    start = now = time(NULL);
+
+    my_domid = atoi(xs_read(xsh, 0, "domid", &len));
+    snprintf(keybuf, sizeof(keybuf), "/local/domain/0/backend/audio/%d/%d/state", my_domid, device_id);
+
+    /*XXX: hardcoded */
+    seconds = 10;
+       do {
+               tv.tv_usec = 0;
+               tv.tv_sec = (start + seconds) - now;
+               FD_ZERO(&watch_fdset);
+               FD_SET(xs_fd, &watch_fdset);
+        ret=select(xs_fd + 1, &watch_fdset, NULL, NULL, &tv);
+
+        if (ret==-1)
+            /* error */
+            return -1;
+        else if (ret) {
+
+                       /* Read the watch to drain the buffer */
+                       vec = xs_read_watch(xsh, &len);
+
+            buf = xs_read(xsh, XBT_NULL, vec[0], &len);
+            if (buf == 0) {
+                /* usually means that the backend isn't there yet */
+                continue;
+            };
+            backend_state = atoi(buf);
+
+            free(buf);
+            free(vec);
+               }
+        /* else: timeout */
+       } while (backend_state == STATE_UNDEFINED && \
+            (now = time(NULL)) < start + seconds);
+
+    return backend_state;
+}
diff --git a/src/pulse/.gitignore b/src/pulse/.gitignore
new file mode 100644 (file)
index 0000000..6702033
--- /dev/null
@@ -0,0 +1 @@
+version.h
diff --git a/src/pulse/browser.c b/src/pulse/browser.c
deleted file mode 100644 (file)
index 4cf5d0c..0000000
+++ /dev/null
@@ -1,464 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2004-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, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-#include <avahi-client/lookup.h>
-#include <avahi-common/domain.h>
-#include <avahi-common/error.h>
-
-#include <pulse/xmalloc.h>
-
-#include <pulsecore/log.h>
-#include <pulsecore/core-util.h>
-#include <pulsecore/avahi-wrap.h>
-#include <pulsecore/refcnt.h>
-#include <pulsecore/macro.h>
-
-#include "browser.h"
-
-#define SERVICE_TYPE_SINK "_pulse-sink._tcp."
-#define SERVICE_TYPE_SOURCE "_pulse-source._tcp."
-#define SERVICE_TYPE_SERVER "_pulse-server._tcp."
-
-struct pa_browser {
-    PA_REFCNT_DECLARE;
-
-    pa_mainloop_api *mainloop;
-    AvahiPoll* avahi_poll;
-
-    pa_browse_cb_t callback;
-    void *userdata;
-
-    pa_browser_error_cb_t error_callback;
-    void *error_userdata;
-
-    AvahiClient *client;
-    AvahiServiceBrowser *server_browser, *sink_browser, *source_browser;
-
-};
-
-static int map_to_opcode(const char *type, int new) {
-
-    if (avahi_domain_equal(type, SERVICE_TYPE_SINK))
-        return new ? PA_BROWSE_NEW_SINK : PA_BROWSE_REMOVE_SINK;
-    else if (avahi_domain_equal(type, SERVICE_TYPE_SOURCE))
-        return new ? PA_BROWSE_NEW_SOURCE : PA_BROWSE_REMOVE_SOURCE;
-    else if (avahi_domain_equal(type, SERVICE_TYPE_SERVER))
-        return new ? PA_BROWSE_NEW_SERVER : PA_BROWSE_REMOVE_SERVER;
-
-    return -1;
-}
-
-static void resolve_callback(
-        AvahiServiceResolver *r,
-        AvahiIfIndex interface,
-        AvahiProtocol protocol,
-        AvahiResolverEvent event,
-        const char *name,
-        const char *type,
-        const char *domain,
-        const char *host_name,
-        const AvahiAddress *aa,
-        uint16_t port,
-        AvahiStringList *txt,
-        AvahiLookupResultFlags flags,
-        void *userdata) {
-
-    pa_browser *b = userdata;
-    pa_browse_info i;
-    char ip[256], a[256];
-    int opcode;
-    int device_found = 0;
-    uint32_t cookie;
-    pa_sample_spec ss;
-    int ss_valid = 0;
-    char *key = NULL, *value = NULL;
-
-    pa_assert(b);
-    pa_assert(PA_REFCNT_VALUE(b) >= 1);
-
-    memset(&i, 0, sizeof(i));
-    i.name = name;
-
-    if (event != AVAHI_RESOLVER_FOUND)
-        goto fail;
-
-    if (!b->callback)
-        goto fail;
-
-    opcode = map_to_opcode(type, 1);
-    pa_assert(opcode >= 0);
-
-    if (aa->proto == AVAHI_PROTO_INET)
-        pa_snprintf(a, sizeof(a), "tcp:%s:%u", avahi_address_snprint(ip, sizeof(ip), aa), port);
-    else {
-        pa_assert(aa->proto == AVAHI_PROTO_INET6);
-        pa_snprintf(a, sizeof(a), "tcp6:%s:%u", avahi_address_snprint(ip, sizeof(ip), aa), port);
-    }
-    i.server = a;
-
-
-    while (txt) {
-
-        if (avahi_string_list_get_pair(txt, &key, &value, NULL) < 0)
-            break;
-
-        if (!strcmp(key, "device")) {
-            device_found = 1;
-            pa_xfree((char*) i.device);
-            i.device = value;
-            value = NULL;
-        } else if (!strcmp(key, "server-version")) {
-            pa_xfree((char*) i.server_version);
-            i.server_version = value;
-            value = NULL;
-        } else if (!strcmp(key, "user-name")) {
-            pa_xfree((char*) i.user_name);
-            i.user_name = value;
-            value = NULL;
-        } else if (!strcmp(key, "fqdn")) {
-            size_t l;
-
-            pa_xfree((char*) i.fqdn);
-            i.fqdn = value;
-            value = NULL;
-
-            l = strlen(a);
-            pa_assert(l+1 <= sizeof(a));
-            strncat(a, " ", sizeof(a)-l-1);
-            strncat(a, i.fqdn, sizeof(a)-l-2);
-        } else if (!strcmp(key, "cookie")) {
-
-            if (pa_atou(value, &cookie) < 0)
-                goto fail;
-
-            i.cookie = &cookie;
-        } else if (!strcmp(key, "description")) {
-            pa_xfree((char*) i.description);
-            i.description = value;
-            value = NULL;
-        } else if (!strcmp(key, "channels")) {
-            uint32_t ch;
-
-            if (pa_atou(value, &ch) < 0 || ch <= 0 || ch > 255)
-                goto fail;
-
-            ss.channels = (uint8_t) ch;
-            ss_valid |= 1;
-
-        } else if (!strcmp(key, "rate")) {
-            if (pa_atou(value, &ss.rate) < 0)
-                goto fail;
-            ss_valid |= 2;
-        } else if (!strcmp(key, "format")) {
-
-            if ((ss.format = pa_parse_sample_format(value)) == PA_SAMPLE_INVALID)
-                goto fail;
-
-            ss_valid |= 4;
-        }
-
-        pa_xfree(key);
-        pa_xfree(value);
-        key = value = NULL;
-
-        txt = avahi_string_list_get_next(txt);
-    }
-
-    /* No device txt record was sent for a sink or source service */
-    if (opcode != PA_BROWSE_NEW_SERVER && !device_found)
-        goto fail;
-
-    if (ss_valid == 7)
-        i.sample_spec = &ss;
-
-    b->callback(b, opcode, &i, b->userdata);
-
-fail:
-    pa_xfree((void*) i.device);
-    pa_xfree((void*) i.fqdn);
-    pa_xfree((void*) i.server_version);
-    pa_xfree((void*) i.user_name);
-    pa_xfree((void*) i.description);
-
-    pa_xfree(key);
-    pa_xfree(value);
-
-    avahi_service_resolver_free(r);
-}
-
-static void handle_failure(pa_browser *b) {
-    const char *e = NULL;
-
-    pa_assert(b);
-    pa_assert(PA_REFCNT_VALUE(b) >= 1);
-
-    if (b->sink_browser)
-        avahi_service_browser_free(b->sink_browser);
-    if (b->source_browser)
-        avahi_service_browser_free(b->source_browser);
-    if (b->server_browser)
-        avahi_service_browser_free(b->server_browser);
-
-    b->sink_browser = b->source_browser = b->server_browser = NULL;
-
-    if (b->client) {
-        e = avahi_strerror(avahi_client_errno(b->client));
-        avahi_client_free(b->client);
-    }
-
-    b->client = NULL;
-
-    if (b->error_callback)
-        b->error_callback(b, e, b->error_userdata);
-}
-
-static void browse_callback(
-        AvahiServiceBrowser *sb,
-        AvahiIfIndex interface,
-        AvahiProtocol protocol,
-        AvahiBrowserEvent event,
-        const char *name,
-        const char *type,
-        const char *domain,
-        AvahiLookupResultFlags flags,
-        void *userdata) {
-
-    pa_browser *b = userdata;
-
-    pa_assert(b);
-    pa_assert(PA_REFCNT_VALUE(b) >= 1);
-
-    switch (event) {
-        case AVAHI_BROWSER_NEW: {
-
-            if (!avahi_service_resolver_new(
-                          b->client,
-                          interface,
-                          protocol,
-                          name,
-                          type,
-                          domain,
-                          AVAHI_PROTO_UNSPEC,
-                          0,
-                          resolve_callback,
-                          b))
-                handle_failure(b);
-
-            break;
-        }
-
-        case AVAHI_BROWSER_REMOVE: {
-
-            if (b->callback) {
-                pa_browse_info i;
-                int opcode;
-
-                memset(&i, 0, sizeof(i));
-                i.name = name;
-
-                opcode = map_to_opcode(type, 0);
-                pa_assert(opcode >= 0);
-
-                b->callback(b, opcode, &i, b->userdata);
-            }
-            break;
-        }
-
-        case AVAHI_BROWSER_FAILURE: {
-            handle_failure(b);
-            break;
-        }
-
-        default:
-            ;
-    }
-}
-
-static void client_callback(AvahiClient *s, AvahiClientState state, void *userdata) {
-    pa_browser *b = userdata;
-
-    pa_assert(s);
-    pa_assert(b);
-    pa_assert(PA_REFCNT_VALUE(b) >= 1);
-
-    if (state == AVAHI_CLIENT_FAILURE)
-        handle_failure(b);
-}
-
-static void browser_free(pa_browser *b);
-
-
-PA_WARN_REFERENCE(pa_browser_new, "libpulse-browse is being phased out.");
-
-pa_browser *pa_browser_new(pa_mainloop_api *mainloop) {
-    return pa_browser_new_full(mainloop, PA_BROWSE_FOR_SERVERS|PA_BROWSE_FOR_SINKS|PA_BROWSE_FOR_SOURCES, NULL);
-}
-
-PA_WARN_REFERENCE(pa_browser_new_full, "libpulse-browse is being phased out.");
-
-pa_browser *pa_browser_new_full(pa_mainloop_api *mainloop, pa_browse_flags_t flags, const char **error_string) {
-    pa_browser *b;
-    int error;
-
-    pa_assert(mainloop);
-
-    if (flags & ~(PA_BROWSE_FOR_SERVERS|PA_BROWSE_FOR_SINKS|PA_BROWSE_FOR_SOURCES) || flags == 0)
-        return NULL;
-
-    b = pa_xnew(pa_browser, 1);
-    b->mainloop = mainloop;
-    PA_REFCNT_INIT(b);
-    b->callback = NULL;
-    b->userdata = NULL;
-    b->error_callback = NULL;
-    b->error_userdata = NULL;
-    b->sink_browser = b->source_browser = b->server_browser = NULL;
-
-    b->avahi_poll = pa_avahi_poll_new(mainloop);
-
-    if (!(b->client = avahi_client_new(b->avahi_poll, 0, client_callback, b, &error))) {
-        if (error_string)
-            *error_string = avahi_strerror(error);
-        goto fail;
-    }
-
-    if ((flags & PA_BROWSE_FOR_SERVERS) &&
-        !(b->server_browser = avahi_service_browser_new(
-                  b->client,
-                  AVAHI_IF_UNSPEC,
-                  AVAHI_PROTO_INET,
-                  SERVICE_TYPE_SERVER,
-                  NULL,
-                  0,
-                  browse_callback,
-                  b))) {
-
-        if (error_string)
-            *error_string = avahi_strerror(avahi_client_errno(b->client));
-        goto fail;
-    }
-
-    if ((flags & PA_BROWSE_FOR_SINKS) &&
-        !(b->sink_browser = avahi_service_browser_new(
-                  b->client,
-                  AVAHI_IF_UNSPEC,
-                  AVAHI_PROTO_UNSPEC,
-                  SERVICE_TYPE_SINK,
-                  NULL,
-                  0,
-                  browse_callback,
-                  b))) {
-
-        if (error_string)
-            *error_string = avahi_strerror(avahi_client_errno(b->client));
-        goto fail;
-    }
-
-    if ((flags & PA_BROWSE_FOR_SOURCES) &&
-        !(b->source_browser = avahi_service_browser_new(
-                  b->client,
-                  AVAHI_IF_UNSPEC,
-                  AVAHI_PROTO_UNSPEC,
-                  SERVICE_TYPE_SOURCE,
-                  NULL,
-                  0,
-                  browse_callback,
-                  b))) {
-
-        if (error_string)
-            *error_string = avahi_strerror(avahi_client_errno(b->client));
-        goto fail;
-    }
-
-    return b;
-
-fail:
-    if (b)
-        browser_free(b);
-
-    return NULL;
-}
-
-static void browser_free(pa_browser *b) {
-    pa_assert(b);
-    pa_assert(b->mainloop);
-
-    if (b->sink_browser)
-        avahi_service_browser_free(b->sink_browser);
-    if (b->source_browser)
-        avahi_service_browser_free(b->source_browser);
-    if (b->server_browser)
-        avahi_service_browser_free(b->server_browser);
-
-    if (b->client)
-        avahi_client_free(b->client);
-
-    if (b->avahi_poll)
-        pa_avahi_poll_free(b->avahi_poll);
-
-    pa_xfree(b);
-}
-
-PA_WARN_REFERENCE(pa_browser_ref, "libpulse-browse is being phased out.");
-
-pa_browser *pa_browser_ref(pa_browser *b) {
-    pa_assert(b);
-    pa_assert(PA_REFCNT_VALUE(b) >= 1);
-
-    PA_REFCNT_INC(b);
-    return b;
-}
-
-PA_WARN_REFERENCE(pa_browser_unref, "libpulse-browse is being phased out.");
-
-void pa_browser_unref(pa_browser *b) {
-    pa_assert(b);
-    pa_assert(PA_REFCNT_VALUE(b) >= 1);
-
-    if (PA_REFCNT_DEC(b) <= 0)
-        browser_free(b);
-}
-
-PA_WARN_REFERENCE(pa_browser_set_callback, "libpulse-browse is being phased out.");
-
-void pa_browser_set_callback(pa_browser *b, pa_browse_cb_t cb, void *userdata) {
-    pa_assert(b);
-    pa_assert(PA_REFCNT_VALUE(b) >= 1);
-
-    b->callback = cb;
-    b->userdata = userdata;
-}
-
-PA_WARN_REFERENCE(pa_browser_set_error_callback, "libpulse-browse is being phased out.");
-
-void pa_browser_set_error_callback(pa_browser *b, pa_browser_error_cb_t cb, void *userdata) {
-    pa_assert(b);
-    pa_assert(PA_REFCNT_VALUE(b) >= 1);
-
-    b->error_callback = cb;
-    b->error_userdata = userdata;
-}
diff --git a/src/pulse/browser.h b/src/pulse/browser.h
deleted file mode 100644 (file)
index c843e2a..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-#ifndef foobrowserhfoo
-#define foobrowserhfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2004-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, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <pulse/mainloop-api.h>
-#include <pulse/sample.h>
-#include <pulse/channelmap.h>
-#include <pulse/cdecl.h>
-#include <pulse/version.h>
-
-/** \file
- * An abstract interface for Zeroconf browsing of PulseAudio servers */
-
-PA_C_DECL_BEGIN
-
-/** An opaque Zeroconf service browser object */
-typedef struct pa_browser pa_browser;
-
-/** Opcodes for pa_browser_cb_t callbacks */
-typedef enum pa_browse_opcode {
-    PA_BROWSE_NEW_SERVER = 0, /**< New server found */
-    PA_BROWSE_NEW_SINK,       /**< New sink found */
-    PA_BROWSE_NEW_SOURCE,     /**< New source found */
-    PA_BROWSE_REMOVE_SERVER,  /**< Server disappeared */
-    PA_BROWSE_REMOVE_SINK,    /**< Sink disappeared */
-    PA_BROWSE_REMOVE_SOURCE   /**< Source disappeared */
-} pa_browse_opcode_t;
-
-typedef enum pa_browse_flags {
-    PA_BROWSE_FOR_SERVERS = 1, /**< Browse for servers */
-    PA_BROWSE_FOR_SINKS = 2, /**< Browse for sinks */
-    PA_BROWSE_FOR_SOURCES = 4 /** Browse for sources */
-} pa_browse_flags_t;
-
-/** Create a new browser object on the specified main loop */
-pa_browser *pa_browser_new(pa_mainloop_api *mainloop);
-
-/** Same pa_browser_new, but pass additional flags parameter. */
-pa_browser *pa_browser_new_full(pa_mainloop_api *mainloop, pa_browse_flags_t flags, const char **error_string);
-
-/** Increase reference counter of the specified browser object */
-pa_browser *pa_browser_ref(pa_browser *z);
-
-/** Decrease reference counter of the specified browser object */
-void pa_browser_unref(pa_browser *z);
-
-/** Information about a sink/source/server found with Zeroconf */
-typedef struct pa_browse_info {
-    const char *name;  /**< Unique service name; always available */
-
-    const char *server; /**< Server name; always available */
-    const char *server_version; /**< Server version string; optional */
-    const char *user_name; /**< User name of the server process; optional */
-    const char *fqdn; /* Server version; optional */
-    const uint32_t *cookie;  /* Server cookie; optional */
-
-    const char *device; /* Device name; always available when this information is of a sink/source */
-    const char *description;  /* Device description; optional */
-    const pa_sample_spec *sample_spec;  /* Sample specification of the device; optional */
-} pa_browse_info;
-
-/** Callback prototype */
-typedef void (*pa_browse_cb_t)(pa_browser *z, pa_browse_opcode_t c, const pa_browse_info *i, void *userdata);
-
-/** Set the callback pointer for the browser object */
-void pa_browser_set_callback(pa_browser *z, pa_browse_cb_t cb, void *userdata);
-
-/** Callback prototype for errors */
-typedef void (*pa_browser_error_cb_t)(pa_browser *z, const char *error_string, void *userdata);
-
-/** Set a callback function that is called whenever the browser object
- * becomes invalid due to an error. After this function has been
- * called the browser object has become invalid and should be
- * freed. */
-void pa_browser_set_error_callback(pa_browser *z, pa_browser_error_cb_t, void *userdata);
-
-PA_C_DECL_END
-
-#endif
index 9b51626..c578ff4 100644 (file)
@@ -29,8 +29,8 @@
 #include <string.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/i18n.h>
 
+#include <pulsecore/i18n.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/bitset.h>
@@ -112,7 +112,7 @@ const char *const pretty_table[PA_CHANNEL_POSITION_MAX] = {
     [PA_CHANNEL_POSITION_REAR_LEFT] = N_("Rear Left"),
     [PA_CHANNEL_POSITION_REAR_RIGHT] = N_("Rear Right"),
 
-    [PA_CHANNEL_POSITION_LFE] = N_("Low Frequency Emmiter"),
+    [PA_CHANNEL_POSITION_LFE] = N_("Subwoofer"),
 
     [PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = N_("Front Left-of-center"),
     [PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = N_("Front Right-of-center"),
@@ -262,22 +262,31 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p
                     return m;
 
                 case 8:
+                    m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
+                    m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
+                    m->map[2] = PA_CHANNEL_POSITION_LFE;
+                    m->map[3] = PA_CHANNEL_POSITION_FRONT_CENTER;
+                    m->map[4] = PA_CHANNEL_POSITION_REAR_LEFT;
+                    m->map[5] = PA_CHANNEL_POSITION_REAR_RIGHT;
                     m->map[6] = PA_CHANNEL_POSITION_SIDE_LEFT;
                     m->map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT;
-                    /* Fall through */
+                    return m;
 
                 case 6:
-                    m->map[5] = PA_CHANNEL_POSITION_LFE;
-                    /* Fall through */
+                    m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
+                    m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
+                    m->map[2] = PA_CHANNEL_POSITION_FRONT_CENTER;
+                    m->map[3] = PA_CHANNEL_POSITION_LFE;
+                    m->map[4] = PA_CHANNEL_POSITION_REAR_LEFT;
+                    m->map[5] = PA_CHANNEL_POSITION_REAR_RIGHT;
+                    return m;
 
                 case 5:
                     m->map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
-                    /* Fall through */
 
                 case 4:
                     m->map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
                     m->map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
-                    /* Fall through */
 
                 case 2:
                     m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
index 469effc..97e919d 100644 (file)
  */
 
 /** \file
- * Constants and routines for channel mapping handling */
+ * Constants and routines for channel mapping handling
+ *
+ * See also \subpage channelmap
+ */
 
 PA_C_DECL_BEGIN
 
@@ -74,9 +77,9 @@ typedef enum pa_channel_position {
     PA_CHANNEL_POSITION_INVALID = -1,
     PA_CHANNEL_POSITION_MONO = 0,
 
-    PA_CHANNEL_POSITION_FRONT_LEFT,               /* Apple calls this 'Left' */
-    PA_CHANNEL_POSITION_FRONT_RIGHT,              /* Apple calls this 'Right' */
-    PA_CHANNEL_POSITION_FRONT_CENTER,             /* Apple calls this 'Center' */
+    PA_CHANNEL_POSITION_FRONT_LEFT,               /**< Apple, Dolby call this 'Left' */
+    PA_CHANNEL_POSITION_FRONT_RIGHT,              /**< Apple, Dolby call this 'Right' */
+    PA_CHANNEL_POSITION_FRONT_CENTER,             /**< Apple, Dolby call this 'Center' */
 
 /** \cond fulldocs */
     PA_CHANNEL_POSITION_LEFT = PA_CHANNEL_POSITION_FRONT_LEFT,
@@ -84,20 +87,20 @@ typedef enum pa_channel_position {
     PA_CHANNEL_POSITION_CENTER = PA_CHANNEL_POSITION_FRONT_CENTER,
 /** \endcond */
 
-    PA_CHANNEL_POSITION_REAR_CENTER,              /* Microsoft calls this 'Back Center', Apple calls this 'Center Surround' */
-    PA_CHANNEL_POSITION_REAR_LEFT,                /* Microsoft calls this 'Back Left', Apple calls this 'Left Surround' */
-    PA_CHANNEL_POSITION_REAR_RIGHT,               /* Microsoft calls this 'Back Right', Apple calls this 'Right Surround' */
+    PA_CHANNEL_POSITION_REAR_CENTER,              /**< Microsoft calls this 'Back Center', Apple calls this 'Center Surround', Dolby calls this 'Surround Rear Center' */
+    PA_CHANNEL_POSITION_REAR_LEFT,                /**< Microsoft calls this 'Back Left', Apple calls this 'Left Surround' (!), Dolby calls this 'Surround Rear Left'  */
+    PA_CHANNEL_POSITION_REAR_RIGHT,               /**< Microsoft calls this 'Back Right', Apple calls this 'Right Surround' (!), Dolby calls this 'Surround Rear Right'  */
 
-    PA_CHANNEL_POSITION_LFE,                      /* Microsoft calls this 'Low Frequency', Apple calls this 'LFEScreen' */
+    PA_CHANNEL_POSITION_LFE,                      /**< Microsoft calls this 'Low Frequency', Apple calls this 'LFEScreen' */
 /** \cond fulldocs */
     PA_CHANNEL_POSITION_SUBWOOFER = PA_CHANNEL_POSITION_LFE,
 /** \endcond */
 
-    PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,     /* Apple calls this 'Left Center' */
-    PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,    /* Apple calls this 'Right Center */
+    PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,     /**< Apple, Dolby call this 'Left Center' */
+    PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,    /**< Apple, Dolby call this 'Right Center */
 
-    PA_CHANNEL_POSITION_SIDE_LEFT,                /* Apple calls this 'Left Surround Direct' */
-    PA_CHANNEL_POSITION_SIDE_RIGHT,               /* Apple calls this 'Right Surround Direct' */
+    PA_CHANNEL_POSITION_SIDE_LEFT,                /**< Apple calls this 'Left Surround Direct', Dolby calls this 'Surround Left' (!) */
+    PA_CHANNEL_POSITION_SIDE_RIGHT,               /**< Apple calls this 'Right Surround Direct', Dolby calls this 'Surround Right' (!) */
 
     PA_CHANNEL_POSITION_AUX0,
     PA_CHANNEL_POSITION_AUX1,
@@ -132,15 +135,15 @@ typedef enum pa_channel_position {
     PA_CHANNEL_POSITION_AUX30,
     PA_CHANNEL_POSITION_AUX31,
 
-    PA_CHANNEL_POSITION_TOP_CENTER,               /* Apple calls this 'Top Center Surround' */
+    PA_CHANNEL_POSITION_TOP_CENTER,               /**< Apple calls this 'Top Center Surround' */
 
-    PA_CHANNEL_POSITION_TOP_FRONT_LEFT,           /* Apple calls this 'Vertical Height Left' */
-    PA_CHANNEL_POSITION_TOP_FRONT_RIGHT,          /* Apple calls this 'Vertical Height Right' */
-    PA_CHANNEL_POSITION_TOP_FRONT_CENTER,         /* Apple calls this 'Vertical Height Center' */
+    PA_CHANNEL_POSITION_TOP_FRONT_LEFT,           /**< Apple calls this 'Vertical Height Left' */
+    PA_CHANNEL_POSITION_TOP_FRONT_RIGHT,          /**< Apple calls this 'Vertical Height Right' */
+    PA_CHANNEL_POSITION_TOP_FRONT_CENTER,         /**< Apple calls this 'Vertical Height Center' */
 
-    PA_CHANNEL_POSITION_TOP_REAR_LEFT,            /* Microsoft and Apple call this 'Top Back Left' */
-    PA_CHANNEL_POSITION_TOP_REAR_RIGHT,           /* Microsoft and Apple call this 'Top Back Right' */
-    PA_CHANNEL_POSITION_TOP_REAR_CENTER,          /* Microsoft and Apple call this 'Top Back Center' */
+    PA_CHANNEL_POSITION_TOP_REAR_LEFT,            /**< Microsoft and Apple call this 'Top Back Left' */
+    PA_CHANNEL_POSITION_TOP_REAR_RIGHT,           /**< Microsoft and Apple call this 'Top Back Right' */
+    PA_CHANNEL_POSITION_TOP_REAR_CENTER,          /**< Microsoft and Apple call this 'Top Back Center' */
 
     PA_CHANNEL_POSITION_MAX
 } pa_channel_position_t;
@@ -328,23 +331,23 @@ int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *s
 int pa_channel_map_superset(const pa_channel_map *a, const pa_channel_map *b) PA_GCC_PURE;
 
 /** Returns non-zero if it makes sense to apply a volume 'balance'
- * with this mapping, i.e. if there are left/right channels
+ * with this mapping, i.e.\ if there are left/right channels
  * available. \since 0.9.15 */
 int pa_channel_map_can_balance(const pa_channel_map *map) PA_GCC_PURE;
 
 /** Returns non-zero if it makes sense to apply a volume 'fade'
- * (i.e. 'balance' between front and rear) with this mapping, i.e. if
+ * (i.e.\ 'balance' between front and rear) with this mapping, i.e.\ if
  * there are front/rear channels available. \since 0.9.15 */
 int pa_channel_map_can_fade(const pa_channel_map *map) PA_GCC_PURE;
 
 /** Tries to find a well-known channel mapping name for this channel
- * mapping. I.e. "stereo", "surround-71" and so on. If the channel
+ * mapping, i.e.\ "stereo", "surround-71" and so on. If the channel
  * mapping is unknown NULL will be returned. This name can be parsed
  * with pa_channel_map_parse() \since 0.9.15 */
 const char* pa_channel_map_to_name(const pa_channel_map *map) PA_GCC_PURE;
 
 /** Tries to find a human readable text label for this channel
-mapping. I.e. "Stereo", "Surround 7.1" and so on. If the channel
+mapping, i.e.\ "Stereo", "Surround 7.1" and so on. If the channel
 mapping is unknown NULL will be returned. \since 0.9.15 */
 const char* pa_channel_map_to_pretty_name(const pa_channel_map *map) PA_GCC_PURE;
 
index 4970363..76b9f6f 100644 (file)
 
 #include <string.h>
 
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
+#include <xcb/xcb.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/i18n.h>
 
+#include <pulsecore/i18n.h>
 #include <pulsecore/x11prop.h>
 #include <pulsecore/log.h>
 #include <pulsecore/core-util.h>
@@ -39,8 +38,8 @@
 #include "client-conf-x11.h"
 
 int pa_client_conf_from_x11(pa_client_conf *c, const char *dname) {
-    Display *d = NULL;
-    int ret = -1;
+    xcb_connection_t *xcb = NULL;
+    int ret = -1, screen = 0;
     char t[1024];
 
     pa_assert(c);
@@ -51,18 +50,23 @@ int pa_client_conf_from_x11(pa_client_conf *c, const char *dname) {
     if (*dname == 0)
         goto finish;
 
-    if (!(d = XOpenDisplay(dname))) {
-        pa_log(_("XOpenDisplay() failed"));
+    if (!(xcb = xcb_connect(dname, NULL))) {
+        pa_log(_("xcb_connect() failed"));
         goto finish;
     }
 
-    if (pa_x11_get_prop(d, "PULSE_SERVER", t, sizeof(t))) {
+    if (xcb_connection_has_error(xcb)) {
+        pa_log(_("xcb_connection_has_error() returned true"));
+        goto finish;
+    }
+
+    if (pa_x11_get_prop(xcb, screen, "PULSE_SERVER", t, sizeof(t))) {
         pa_bool_t disable_autospawn = TRUE;
 
         pa_xfree(c->default_server);
         c->default_server = pa_xstrdup(t);
 
-        if (pa_x11_get_prop(d, "PULSE_SESSION_ID", t, sizeof(t))) {
+        if (pa_x11_get_prop(xcb, screen, "PULSE_SESSION_ID", t, sizeof(t))) {
             char *id;
 
             if ((id = pa_session_id())) {
@@ -76,17 +80,17 @@ int pa_client_conf_from_x11(pa_client_conf *c, const char *dname) {
             c->autospawn = FALSE;
     }
 
-    if (pa_x11_get_prop(d, "PULSE_SINK", t, sizeof(t))) {
+    if (pa_x11_get_prop(xcb, screen, "PULSE_SINK", t, sizeof(t))) {
         pa_xfree(c->default_sink);
         c->default_sink = pa_xstrdup(t);
     }
 
-    if (pa_x11_get_prop(d, "PULSE_SOURCE", t, sizeof(t))) {
+    if (pa_x11_get_prop(xcb, screen, "PULSE_SOURCE", t, sizeof(t))) {
         pa_xfree(c->default_source);
         c->default_source = pa_xstrdup(t);
     }
 
-    if (pa_x11_get_prop(d, "PULSE_COOKIE", t, sizeof(t))) {
+    if (pa_x11_get_prop(xcb, screen, "PULSE_COOKIE", t, sizeof(t))) {
         uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
 
         if (pa_parsehex(t, cookie, sizeof(cookie)) != sizeof(cookie)) {
@@ -106,8 +110,8 @@ int pa_client_conf_from_x11(pa_client_conf *c, const char *dname) {
     ret = 0;
 
 finish:
-    if (d)
-        XCloseDisplay(d);
+    if (xcb)
+        xcb_disconnect(xcb);
 
     return ret;
 
index 4aa4ba1..8988daf 100644 (file)
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
-#include <string.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/i18n.h>
 
+#include <pulsecore/i18n.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-error.h>
 #include <pulsecore/log.h>
@@ -57,11 +56,14 @@ static const pa_client_conf default_conf = {
     .default_sink = NULL,
     .default_source = NULL,
     .default_server = NULL,
+    .default_dbus_server = NULL,
     .autospawn = TRUE,
     .disable_shm = FALSE,
     .cookie_file = NULL,
     .cookie_valid = FALSE,
-    .shm_size = 0
+    .shm_size = 0,
+    .auto_connect_localhost = FALSE,
+    .auto_connect_display = FALSE
 };
 
 pa_client_conf *pa_client_conf_new(void) {
@@ -69,7 +71,7 @@ pa_client_conf *pa_client_conf_new(void) {
 
     c->daemon_binary = pa_xstrdup(PA_BINARY);
     c->extra_arguments = pa_xstrdup("--log-target=syslog");
-    c->cookie_file = pa_xstrdup(PA_NATIVE_COOKIE_FILE);
+    c->cookie_file = NULL;
 
     return c;
 }
@@ -81,6 +83,7 @@ void pa_client_conf_free(pa_client_conf *c) {
     pa_xfree(c->default_sink);
     pa_xfree(c->default_source);
     pa_xfree(c->default_server);
+    pa_xfree(c->default_dbus_server);
     pa_xfree(c->cookie_file);
     pa_xfree(c);
 }
@@ -97,17 +100,20 @@ int pa_client_conf_load(pa_client_conf *c, const char *filename) {
         { "default-sink",           pa_config_parse_string,   &c->default_sink, NULL },
         { "default-source",         pa_config_parse_string,   &c->default_source, NULL },
         { "default-server",         pa_config_parse_string,   &c->default_server, NULL },
+        { "default-dbus-server",    pa_config_parse_string,   &c->default_dbus_server, NULL },
         { "autospawn",              pa_config_parse_bool,     &c->autospawn, NULL },
         { "cookie-file",            pa_config_parse_string,   &c->cookie_file, NULL },
         { "disable-shm",            pa_config_parse_bool,     &c->disable_shm, NULL },
         { "enable-shm",             pa_config_parse_not_bool, &c->disable_shm, NULL },
         { "shm-size-bytes",         pa_config_parse_size,     &c->shm_size, NULL },
+        { "auto-connect-localhost", pa_config_parse_bool,     &c->auto_connect_localhost, NULL },
+        { "auto-connect-display",   pa_config_parse_bool,     &c->auto_connect_display, NULL },
         { NULL,                     NULL,                     NULL, NULL },
     };
 
     if (filename) {
 
-        if (!(f = fopen(filename, "r"))) {
+        if (!(f = pa_fopen_cloexec(filename, "r"))) {
             pa_log(_("Failed to open configuration file '%s': %s"), fn, pa_cstrerror(errno));
             goto finish;
         }
@@ -121,7 +127,7 @@ int pa_client_conf_load(pa_client_conf *c, const char *filename) {
                 goto finish;
     }
 
-    r = f ? pa_config_parse(fn, f, table, NULL) : 0;
+    r = f ? pa_config_parse(fn, f, table, NULL, NULL) : 0;
 
     if (!r)
         r = pa_client_conf_load_cookie(c);
@@ -172,15 +178,27 @@ int pa_client_conf_env(pa_client_conf *c) {
 }
 
 int pa_client_conf_load_cookie(pa_client_conf* c) {
-    pa_assert(c);
+    int k;
 
-    if (!c->cookie_file)
-        return -1;
+    pa_assert(c);
 
     c->cookie_valid = FALSE;
 
-    if (pa_authkey_load_auto(c->cookie_file, c->cookie, sizeof(c->cookie)) < 0)
-        return -1;
+    if (c->cookie_file)
+        k = pa_authkey_load_auto(c->cookie_file, TRUE, c->cookie, sizeof(c->cookie));
+    else {
+        k = pa_authkey_load_auto(PA_NATIVE_COOKIE_FILE, FALSE, c->cookie, sizeof(c->cookie));
+
+        if (k < 0) {
+            k = pa_authkey_load_auto(PA_NATIVE_COOKIE_FILE_FALLBACK, FALSE, c->cookie, sizeof(c->cookie));
+
+            if (k < 0)
+                k = pa_authkey_load_auto(PA_NATIVE_COOKIE_FILE, TRUE, c->cookie, sizeof(c->cookie));
+        }
+    }
+
+    if (k < 0)
+        return k;
 
     c->cookie_valid = TRUE;
     return 0;
index ab97dc6..f281f4e 100644 (file)
   USA.
 ***/
 
+#include <pulsecore/macro.h>
 #include <pulsecore/native-common.h>
 
 /* A structure containing configuration data for PulseAudio clients. */
 
 typedef struct pa_client_conf {
-    char *daemon_binary, *extra_arguments, *default_sink, *default_source, *default_server, *cookie_file;
-    pa_bool_t autospawn, disable_shm;
+    char *daemon_binary, *extra_arguments, *default_sink, *default_source, *default_server, *default_dbus_server, *cookie_file;
+    pa_bool_t autospawn, disable_shm, auto_connect_localhost, auto_connect_display;
     uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
     pa_bool_t cookie_valid; /* non-zero, when cookie is valid */
     size_t shm_size;
index 6c8d371..17753b0 100644 (file)
 # USA.
 
 ## Configuration file for PulseAudio clients. See pulse-client.conf(5) for
-## more information. Default values a commented out.  Use either ; or # for
+## more information. Default values are commented out.  Use either ; or # for
 ## commenting.
 
 ; default-sink =
 ; default-source =
 ; default-server =
+; default-dbus-server =
 
 ; autospawn = yes
 ; daemon-binary = @PA_BINARY@
@@ -31,3 +32,6 @@
 
 ; enable-shm = yes
 ; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
+
+; auto-connect-localhost = no
+; auto-connect-display = no
index 7468d0a..9429949 100644 (file)
 #include <sys/stat.h>
 #include <errno.h>
 #include <signal.h>
-#include <limits.h>
-#include <locale.h>
 
 #ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
 #endif
 
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_SYS_UN_H
-#include <sys/un.h>
-#endif
 #ifdef HAVE_NETDB_H
 #include <netdb.h>
 #endif
 
 #include <pulse/version.h>
 #include <pulse/xmalloc.h>
-#include <pulse/utf8.h>
 #include <pulse/util.h>
-#include <pulse/i18n.h>
 #include <pulse/mainloop.h>
 #include <pulse/timeval.h>
+#include <pulse/fork-detect.h>
+#include <pulse/client-conf.h>
+#ifdef HAVE_X11
+#include <pulse/client-conf-x11.h>
+#endif
 
-#include <pulsecore/winsock.h>
 #include <pulsecore/core-error.h>
-
+#include <pulsecore/i18n.h>
 #include <pulsecore/native-common.h>
 #include <pulsecore/pdispatch.h>
 #include <pulsecore/pstream.h>
-#include <pulsecore/dynarray.h>
+#include <pulsecore/hashmap.h>
 #include <pulsecore/socket-client.h>
 #include <pulsecore/pstream-util.h>
 #include <pulsecore/core-rtclock.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
-#include <pulsecore/socket-util.h>
+#include <pulsecore/socket.h>
 #include <pulsecore/creds.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/proplist-util.h>
 
 #include "internal.h"
-
-#include "client-conf.h"
-#include "fork-detect.h"
-
-#ifdef HAVE_X11
-#include "client-conf-x11.h"
-#endif
-
 #include "context.h"
 
 void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
@@ -131,6 +117,9 @@ static void reset_callbacks(pa_context *c) {
     c->ext_device_manager.callback = NULL;
     c->ext_device_manager.userdata = NULL;
 
+    c->ext_device_restore.callback = NULL;
+    c->ext_device_restore.userdata = NULL;
+
     c->ext_stream_restore.callback = NULL;
     c->ext_stream_restore.userdata = NULL;
 }
@@ -145,7 +134,7 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *
 
     pa_init_i18n();
 
-    c = pa_xnew(pa_context, 1);
+    c = pa_xnew0(pa_context, 1);
     PA_REFCNT_INIT(c);
 
     c->proplist = p ? pa_proplist_copy(p) : pa_proplist_new();
@@ -157,11 +146,8 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *
     c->system_bus = c->session_bus = NULL;
 #endif
     c->mainloop = mainloop;
-    c->client = NULL;
-    c->pstream = NULL;
-    c->pdispatch = NULL;
-    c->playback_streams = pa_dynarray_new();
-    c->record_streams = pa_dynarray_new();
+    c->playback_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+    c->record_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
     c->client_index = PA_INVALID_INDEX;
     c->use_rtclock = pa_mainloop_is_our_api(mainloop);
 
@@ -170,22 +156,9 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *
 
     c->error = PA_OK;
     c->state = PA_CONTEXT_UNCONNECTED;
-    c->ctag = 0;
-    c->csyncid = 0;
 
     reset_callbacks(c);
 
-    c->is_local = FALSE;
-    c->server_list = NULL;
-    c->server = NULL;
-
-    c->do_shm = FALSE;
-
-    c->server_specified = FALSE;
-    c->no_fail = FALSE;
-    c->do_autospawn = FALSE;
-    memset(&c->spawn_api, 0, sizeof(c->spawn_api));
-
 #ifndef MSG_NOSIGNAL
 #ifdef SIGPIPE
     pa_check_signal_is_blocked(SIGPIPE);
@@ -255,20 +228,22 @@ static void context_free(pa_context *c) {
 
 #ifdef HAVE_DBUS
     if (c->system_bus) {
-        dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->system_bus), filter_cb, c);
+        if (c->filter_added)
+            dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->system_bus), filter_cb, c);
         pa_dbus_wrap_connection_free(c->system_bus);
     }
 
     if (c->session_bus) {
-        dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->session_bus), filter_cb, c);
+        if (c->filter_added)
+            dbus_connection_remove_filter(pa_dbus_wrap_connection_get(c->session_bus), filter_cb, c);
         pa_dbus_wrap_connection_free(c->session_bus);
     }
 #endif
 
     if (c->record_streams)
-        pa_dynarray_free(c->record_streams, NULL, NULL);
+        pa_hashmap_free(c->record_streams, NULL);
     if (c->playback_streams)
-        pa_dynarray_free(c->playback_streams, NULL, NULL);
+        pa_hashmap_free(c->playback_streams, NULL);
 
     if (c->mempool)
         pa_mempool_free(c->mempool);
@@ -375,7 +350,7 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o
 
     pa_context_ref(c);
 
-    if ((s = pa_dynarray_get(c->record_streams, channel))) {
+    if ((s = pa_hashmap_get(c->record_streams, PA_UINT32_TO_PTR(channel)))) {
 
         if (chunk->memblock) {
             pa_memblockq_seek(s->record_memblockq, offset, seek, TRUE);
@@ -543,8 +518,8 @@ static void setup_context(pa_context *c, pa_iochannel *io) {
     c->pstream = pa_pstream_new(c->mainloop, io, c->mempool);
 
     pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c);
-    pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c);
-    pa_pstream_set_recieve_memblock_callback(c->pstream, pstream_memblock_callback, c);
+    pa_pstream_set_receive_packet_callback(c->pstream, pstream_packet_callback, c);
+    pa_pstream_set_receive_memblock_callback(c->pstream, pstream_memblock_callback, c);
 
     pa_assert(!c->pdispatch);
     c->pdispatch = pa_pdispatch_new(c->mainloop, c->use_rtclock, command_table, PA_COMMAND_MAX);
@@ -588,75 +563,9 @@ static void setup_context(pa_context *c, pa_iochannel *io) {
     pa_context_unref(c);
 }
 
-#ifdef ENABLE_LEGACY_RUNTIME_DIR
-static char *get_old_legacy_runtime_dir(void) {
-    char *p, u[128];
-    struct stat st;
-
-    if (!pa_get_user_name(u, sizeof(u)))
-        return NULL;
-
-    p = pa_sprintf_malloc("/tmp/pulse-%s", u);
-
-    if (stat(p, &st) < 0) {
-        pa_xfree(p);
-        return NULL;
-    }
-
-    if (st.st_uid != getuid()) {
-        pa_xfree(p);
-        return NULL;
-    }
-
-    return p;
-}
-
-static char *get_very_old_legacy_runtime_dir(void) {
-    char *p, h[128];
-    struct stat st;
-
-    if (!pa_get_home_dir(h, sizeof(h)))
-        return NULL;
-
-    p = pa_sprintf_malloc("%s/.pulse", h);
-
-    if (stat(p, &st) < 0) {
-        pa_xfree(p);
-        return NULL;
-    }
-
-    if (st.st_uid != getuid()) {
-        pa_xfree(p);
-        return NULL;
-    }
-
-    return p;
-}
-#endif
-
 static pa_strlist *prepend_per_user(pa_strlist *l) {
     char *ufn;
 
-#ifdef ENABLE_LEGACY_RUNTIME_DIR
-    static char *legacy_dir;
-
-    /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
-    if ((legacy_dir = get_very_old_legacy_runtime_dir())) {
-        char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
-        l = pa_strlist_prepend(l, p);
-        pa_xfree(p);
-        pa_xfree(legacy_dir);
-    }
-
-    /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
-    if ((legacy_dir = get_old_legacy_runtime_dir())) {
-        char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
-        l = pa_strlist_prepend(l, p);
-        pa_xfree(p);
-        pa_xfree(legacy_dir);
-    }
-#endif
-
     /* The per-user instance */
     if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
         l = pa_strlist_prepend(l, ufn);
@@ -681,7 +590,11 @@ static int context_autospawn(pa_context *c) {
         goto fail;
     }
 
+#ifdef SA_NOCLDWAIT
     if ((sa.sa_flags & SA_NOCLDWAIT) || sa.sa_handler == SIG_IGN) {
+#else
+    if (sa.sa_handler == SIG_IGN) {
+#endif
         pa_log_debug("Process disabled waitpid(), cannot autospawn.");
         pa_context_fail(c, PA_ERR_CONNECTIONREFUSED);
         goto fail;
@@ -794,6 +707,7 @@ static void track_pulseaudio_on_dbus(pa_context *c, DBusBusType type, pa_dbus_wr
         pa_log_warn("Failed to add filter function");
         goto fail;
     }
+    c->filter_added = TRUE;
 
     if (pa_dbus_add_matches(
                 pa_dbus_wrap_connection_get(*conn), &error,
@@ -987,18 +901,22 @@ int pa_context_connect(
         /* Prepend in reverse order */
 
         /* Follow the X display */
-        if ((d = getenv("DISPLAY"))) {
-            d = pa_xstrndup(d, strcspn(d, ":"));
+        if (c->conf->auto_connect_display) {
+            if ((d = getenv("DISPLAY"))) {
+                d = pa_xstrndup(d, strcspn(d, ":"));
 
-            if (*d)
-                c->server_list = pa_strlist_prepend(c->server_list, d);
+                if (*d)
+                    c->server_list = pa_strlist_prepend(c->server_list, d);
 
-            pa_xfree(d);
+                pa_xfree(d);
+            }
         }
 
         /* Add TCP/IP on the localhost */
-        c->server_list = pa_strlist_prepend(c->server_list, "tcp6:[::1]");
-        c->server_list = pa_strlist_prepend(c->server_list, "tcp4:127.0.0.1");
+        if (c->conf->auto_connect_localhost) {
+            c->server_list = pa_strlist_prepend(c->server_list, "tcp6:[::1]");
+            c->server_list = pa_strlist_prepend(c->server_list, "tcp4:127.0.0.1");
+        }
 
         /* The system wide instance via PF_LOCAL */
         c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
@@ -1010,6 +928,7 @@ int pa_context_connect(
     /* Set up autospawning */
     if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) {
 
+#ifdef HAVE_GETUID
         if (getuid() == 0)
             pa_log_debug("Not doing autospawn since we are root.");
         else {
@@ -1018,6 +937,7 @@ int pa_context_connect(
             if (api)
                 c->spawn_api = *api;
         }
+#endif
     }
 
     pa_context_set_state(c, PA_CONTEXT_CONNECTING);
@@ -1234,6 +1154,69 @@ pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_co
     return o;
 }
 
+#ifdef __TIZEN__
+pa_operation* pa_context_set_cork_all(pa_context *c, int b, pa_context_success_cb_t cb, void *userdata) {
+    pa_tagstruct *t;
+    pa_operation *o;
+    uint32_t tag;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+    t = pa_tagstruct_command(c, PA_COMMAND_CORK_PLAYBACK_STREAM_ALL, &tag);
+    pa_tagstruct_put_boolean(t, !!b);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT,  pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation* pa_context_set_default_sink_by_api_bus(pa_context *c, const char *api, const char *bus, pa_context_success_cb_t cb, void *userdata) {
+    pa_tagstruct *t;
+    pa_operation *o;
+    uint32_t tag;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+    t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SINK_BY_API_BUS, &tag);
+    pa_tagstruct_puts(t, api);
+    pa_tagstruct_puts(t, bus);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT,  pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation* pa_context_set_default_sink_for_usb(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
+    pa_tagstruct *t;
+    pa_operation *o;
+    uint32_t tag;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+    t = pa_tagstruct_command(c, PA_COMMAND_SET_DEFAULT_SINK_FOR_USB, &tag);
+    pa_tagstruct_puts(t, name);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT,  pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+#endif /* __TIZEN__ */
+
 pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata) {
     pa_tagstruct *t;
     pa_operation *o;
@@ -1295,7 +1278,7 @@ pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_su
 }
 
 const char* pa_get_library_version(void) {
-    return PACKAGE_VERSION;
+    return pa_get_headers_version();
 }
 
 const char* pa_context_get_server(pa_context *c) {
@@ -1435,10 +1418,12 @@ void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_t
         goto finish;
     }
 
-    if (!strcmp(name, "module-stream-restore"))
-        pa_ext_stream_restore_command(c, tag, t);
-    else if (!strcmp(name, "module-device-manager"))
+    if (pa_streq(name, "module-device-manager"))
         pa_ext_device_manager_command(c, tag, t);
+    else if (pa_streq(name, "module-device-restore"))
+        pa_ext_device_restore_command(c, tag, t);
+    else if (pa_streq(name, "module-stream-restore"))
+        pa_ext_stream_restore_command(c, tag, t);
     else
         pa_log(_("Received message for unknown extension '%s'"), name);
 
@@ -1488,6 +1473,7 @@ pa_time_event* pa_context_rttime_new(pa_context *c, pa_usec_t usec, pa_time_even
     struct timeval tv;
 
     pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
     pa_assert(c->mainloop);
 
     if (usec == PA_USEC_INVALID)
@@ -1502,8 +1488,10 @@ void pa_context_rttime_restart(pa_context *c, pa_time_event *e, pa_usec_t usec)
     struct timeval tv;
 
     pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
     pa_assert(c->mainloop);
 
+
     if (usec == PA_USEC_INVALID)
         c->mainloop->time_restart(e, NULL);
     else {
@@ -1511,3 +1499,17 @@ void pa_context_rttime_restart(pa_context *c, pa_time_event *e, pa_usec_t usec)
         c->mainloop->time_restart(e, &tv);
     }
 }
+
+size_t pa_context_get_tile_size(pa_context *c, const pa_sample_spec *ss) {
+    size_t fs, mbs;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, (size_t) -1);
+    PA_CHECK_VALIDITY_RETURN_ANY(c, !ss || pa_sample_spec_valid(ss), PA_ERR_INVALID, (size_t) -1);
+
+    fs = ss ? pa_frame_size(ss) : 1;
+    mbs = PA_ROUND_DOWN(pa_mempool_block_size_max(c->mempool), fs);
+    return PA_MAX(mbs, fs);
+}
index ecff58d..9ded483 100644 (file)
  *                       that some implementations may block all other events
  *                       when a deferred event is active.
  * \li I/O events - Events that trigger on file descriptor activities.
- * \li Times events - Events that trigger after a fixed ammount of time.
+ * \li Times events - Events that trigger after a fixed amount of time.
  *
  * The abstraction is represented as a number of function pointers in the
  * pa_mainloop_api structure.
  *
  * To actually be able to use these functions, an implementation needs to
  * be coupled to the abstraction. There are three of these shipped with
- * PulseAudio, but any other can be used with a minimal ammount of work,
+ * PulseAudio, but any other can be used with a minimal amount of work,
  * provided it supports the three basic events listed above.
  *
  * The implementations shipped with PulseAudio are:
  */
 
 /** \file
- * Connection contexts for asynchrononous communication with a
+ * Connection contexts for asynchronous communication with a
  * server. A pa_context object wraps a connection to a PulseAudio
- * server using its native protocol. */
+ * server using its native protocol.
+ *
+ * See also \subpage async
+ */
 
 PA_C_DECL_BEGIN
 
@@ -171,7 +174,7 @@ typedef void (*pa_context_event_cb_t)(pa_context *c, const char *name, pa_propli
 pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name);
 
 /** Instantiate a new connection context with an abstract mainloop API
- * and an application name, and specify the the initial client property
+ * and an application name, and specify the initial client property
  * list. \since 0.9.11 */
 pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, pa_proplist *proplist);
 
@@ -184,7 +187,7 @@ pa_context* pa_context_ref(pa_context *c);
 /** Set a callback function that is called whenever the context status changes */
 void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata);
 
-/** Set a callback function that is called whenver a meta/policy
+/** Set a callback function that is called whenever a meta/policy
  * control event is received. \since 0.9.15 */
 void pa_context_set_event_callback(pa_context *p, pa_context_event_cb_t cb, void *userdata);
 
@@ -214,13 +217,25 @@ void pa_context_disconnect(pa_context *c);
 pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata);
 
 /** Tell the daemon to exit. The returned operation is unlikely to
- * complete succesfully, since the daemon probably died before
+ * complete successfully, since the daemon probably died before
  * returning a success notification */
 pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, void *userdata);
 
 /** Set the name of the default sink. */
 pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata);
 
+#ifdef __TIZEN__
+/** Set the api&bus of the default sink. */
+pa_operation* pa_context_set_default_sink_by_api_bus(pa_context *c, const char *api, const char *bus, pa_context_success_cb_t cb, void *userdata);
+
+/** Set the name of the default sink for USB */
+pa_operation* pa_context_set_default_sink_for_usb(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata);
+
+/** Cork all playback stream and suspend sink manually for device switching */
+pa_operation* pa_context_set_cork_all(pa_context *c, int b, pa_context_success_cb_t cb, void *userdata);
+
+#endif /* __TIZEN__ */
+
 /** Set the name of the default source. */
 pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_context_success_cb_t cb, void *userdata);
 
@@ -255,12 +270,28 @@ pa_operation *pa_context_proplist_remove(pa_context *c, const char *const keys[]
 uint32_t pa_context_get_index(pa_context *s);
 
 /** Create a new timer event source for the specified time (wrapper
   for mainloop->time_new). \since 0.9.16 */
* for mainloop->time_new). \since 0.9.16 */
 pa_time_event* pa_context_rttime_new(pa_context *c, pa_usec_t usec, pa_time_event_cb_t cb, void *userdata);
-/** Restart a running or expired timer event source (wrapper
-    for mainloop->time_restart). \since 0.9.16 */
+
+/** Restart a running or expired timer event source (wrapper for
+ * mainloop->time_restart). \since 0.9.16 */
 void pa_context_rttime_restart(pa_context *c, pa_time_event *e, pa_usec_t usec);
 
+/** Return the optimal block size for passing around audio buffers. It
+ * is recommended to allocate buffers of the size returned here when
+ * writing audio data to playback streams, if the latency constraints
+ * permit this. It is not recommended writing larger blocks than this
+ * because usually they will then be split up internally into chunks
+ * of this size. It is not recommended writing smaller blocks than
+ * this (unless required due to latency demands) because this
+ * increases CPU usage. If ss is NULL you will be returned the
+ * byte-exact tile size. If you pass a valid ss, then the tile size
+ * will be rounded down to multiple of the frame size. This is
+ * supposed to be used in a construct such as
+ * pa_context_get_tile_size(pa_stream_get_context(s),
+ * pa_stream_get_sample_spec(ss)); \since 0.9.20 */
+size_t pa_context_get_tile_size(pa_context *c, const pa_sample_spec *ss);
+
 PA_C_DECL_END
 
 #endif
index 5d0a0b4..57dd552 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <inttypes.h>
 #include <sys/time.h>
-#include <time.h>
 
 #include <pulse/cdecl.h>
 #include <pulse/sample.h>
@@ -63,6 +62,7 @@ static inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x) {
 #define PA_CONTEXT_SETTING_NAME PA_CONTEXT_SETTING_NAME
 #define PA_CONTEXT_READY PA_CONTEXT_READY
 #define PA_CONTEXT_FAILED PA_CONTEXT_FAILED
+#define PA_CONTEXT_TERMINATED PA_CONTEXT_TERMINATED
 #define PA_CONTEXT_IS_GOOD PA_CONTEXT_IS_GOOD
 /** \endcond */
 
@@ -93,9 +93,14 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) {
 
 /** The state of an operation */
 typedef enum pa_operation_state {
-    PA_OPERATION_RUNNING,      /**< The operation is still running */
-    PA_OPERATION_DONE,         /**< The operation has been completed */
-    PA_OPERATION_CANCELLED     /**< The operation has been cancelled. Before 0.9.18 this was called PA_OPERATION_CANCELED. That name is still available for compatibility. */
+    PA_OPERATION_RUNNING,
+    /**< The operation is still running */
+    PA_OPERATION_DONE,
+    /**< The operation has completed */
+    PA_OPERATION_CANCELLED
+    /**< The operation has been cancelled. Operations may get cancelled by the
+     * application, or as a result of the context getting disconneted while the
+     * operation is pending. */
 } pa_operation_state_t;
 
 /** \cond fulldocs */
@@ -124,6 +129,31 @@ typedef enum pa_context_flags {
 #define PA_CONTEXT_NOFAIL PA_CONTEXT_NOFAIL
 /** \endcond */
 
+/** Direction bitfield - while we currently do not expose anything bidirectional,
+  one should test against the bit instead of the value (e.g.\ if (d & PA_DIRECTION_OUTPUT)),
+  because we might add bidirectional stuff in the future. \since 2.0
+*/
+typedef enum pa_direction {
+    PA_DIRECTION_OUTPUT = 0x0001U,  /**< Output direction */
+    PA_DIRECTION_INPUT = 0x0002U    /**< Input direction */
+} pa_direction_t;
+
+/** \cond fulldocs */
+#define PA_DIRECTION_OUTPUT PA_DIRECTION_OUTPUT
+#define PA_DIRECTION_INPUT PA_DIRECTION_INPUT
+/** \endcond */
+
+/** The type of device we are dealing with */
+typedef enum pa_device_type {
+    PA_DEVICE_TYPE_SINK,     /**< Playback device */
+    PA_DEVICE_TYPE_SOURCE    /**< Recording device */
+} pa_device_type_t;
+
+/** \cond fulldocs */
+#define PA_DEVICE_TYPE_SINK PA_DEVICE_TYPE_SINK
+#define PA_DEVICE_TYPE_SOURCE PA_DEVICE_TYPE_SOURCE
+/** \endcond */
+
 /** The direction of a pa_stream object */
 typedef enum pa_stream_direction {
     PA_STREAM_NODIRECTION,   /**< Invalid direction */
@@ -276,11 +306,24 @@ typedef enum pa_stream_flags {
      * whether to create the stream in muted or in unmuted
      * state. \since 0.9.15 */
 
-    PA_STREAM_FAIL_ON_SUSPEND = 0x20000U
+    PA_STREAM_FAIL_ON_SUSPEND = 0x20000U,
     /**< If the sink/source this stream is connected to is suspended
      * during the creation of this stream, cause it to fail. If the
      * sink/source is being suspended during creation of this stream,
      * make sure this stream is terminated. \since 0.9.15 */
+
+    PA_STREAM_RELATIVE_VOLUME = 0x40000U,
+    /**< If a volume is passed when this stream is created, consider
+     * it relative to the sink's current volume, never as absolute
+     * device volume. If this is not specified the volume will be
+     * consider absolute when the sink is in flat volume mode,
+     * relative otherwise. \since 0.9.20 */
+
+    PA_STREAM_PASSTHROUGH = 0x80000U
+    /**< Used to tag content that will be rendered by passthrough sinks.
+     * The data will be left as is and not reformatted, resampled.
+     * \since 1.0 */
+
 } pa_stream_flags_t;
 
 /** \cond fulldocs */
@@ -307,15 +350,23 @@ typedef enum pa_stream_flags {
 #define PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND
 #define PA_STREAM_START_UNMUTED PA_STREAM_START_UNMUTED
 #define PA_STREAM_FAIL_ON_SUSPEND PA_STREAM_FAIL_ON_SUSPEND
+#define PA_STREAM_RELATIVE_VOLUME PA_STREAM_RELATIVE_VOLUME
+#define PA_STREAM_PASSTHROUGH PA_STREAM_PASSTHROUGH
 
 /** \endcond */
 
 /** Playback and record buffer metrics */
 typedef struct pa_buffer_attr {
     uint32_t maxlength;
-    /**< Maximum length of the buffer. Setting this to (uint32_t) -1
+    /**< Maximum length of the buffer in bytes. Setting this to (uint32_t) -1
      * will initialize this to the maximum value supported by server,
-     * which is recommended. */
+     * which is recommended.
+     *
+     * In strict low-latency playback scenarios you might want to set this to
+     * a lower value, likely together with the PA_STREAM_ADJUST_LATENCY flag.
+     * If you do so, you ensure that the latency doesn't grow beyond what is
+     * acceptable for the use case, at the cost of getting more underruns if
+     * the latency is lower than what the server can reliably handle. */
 
     uint32_t tlength;
     /**< Playback only: target length of the buffer. The server tries
@@ -343,7 +394,7 @@ typedef struct pa_buffer_attr {
      * that may be. Initialize to 0 to enable manual start/stop
      * control of the stream. This means that playback will not stop
      * on underrun and playback will not start automatically. Instead
-     * pa_stream_corked() needs to be called explicitly. If you set
+     * pa_stream_cork() needs to be called explicitly. If you set
      * this value to 0 you should also set PA_STREAM_START_CORKED. */
 
     uint32_t minreq;
@@ -373,7 +424,7 @@ typedef struct pa_buffer_attr {
 } pa_buffer_attr;
 
 /** Error values as used by pa_context_errno(). Use pa_strerror() to convert these values to human readable strings */
-enum {
+typedef enum pa_error_code {
     PA_OK = 0,                     /**< No error */
     PA_ERR_ACCESS,                 /**< Access failure */
     PA_ERR_COMMAND,                /**< Unknown command */
@@ -401,8 +452,11 @@ enum {
     PA_ERR_FORKED,                 /**< The caller forked without calling execve() and tried to reuse the context. \since 0.9.15 */
     PA_ERR_IO,                     /**< An IO error happened. \since 0.9.16 */
     PA_ERR_BUSY,                   /**< Device or resource busy. \since 0.9.17 */
+#ifdef __TIZEN__
+    PA_ERR_ACCESS_BY_SECURITY,     /**< Access failure by security */
+#endif
     PA_ERR_MAX                     /**< Not really an error but the first invalid error code */
-};
+} pa_error_code_t;
 
 /** \cond fulldocs */
 #define PA_OK PA_OK
@@ -430,6 +484,9 @@ enum {
 #define PA_ERR_OBSOLETE PA_ERR_OBSOLETE
 #define PA_ERR_NOTIMPLEMENTED PA_ERR_NOTIMPLEMENTED
 #define PA_ERR_FORKED PA_ERR_FORKED
+#ifdef __TIZEN__
+#define PA_ERR_ACCESS_BY_SECURITY PA_ERR_ACCESS_BY_SECURITY
+#endif
 #define PA_ERR_MAX PA_ERR_MAX
 /** \endcond */
 
@@ -697,7 +754,8 @@ typedef enum pa_sink_flags {
     /**< Flag to pass when no specific options are needed (used to avoid casting)  \since 0.9.19 */
 
     PA_SINK_HW_VOLUME_CTRL = 0x0001U,
-    /**< Supports hardware volume control */
+    /**< Supports hardware volume control. This is a dynamic flag and may
+     * change at runtime after the sink has initialized */
 
     PA_SINK_LATENCY = 0x0002U,
     /**< Supports latency querying */
@@ -710,19 +768,42 @@ typedef enum pa_sink_flags {
     /**< Is a networked sink of some kind. \since 0.9.7 */
 
     PA_SINK_HW_MUTE_CTRL = 0x0010U,
-    /**< Supports hardware mute control \since 0.9.11 */
+    /**< Supports hardware mute control. This is a dynamic flag and may
+     * change at runtime after the sink has initialized \since 0.9.11 */
 
     PA_SINK_DECIBEL_VOLUME = 0x0020U,
-    /**< Volume can be translated to dB with pa_sw_volume_to_dB()
+    /**< Volume can be translated to dB with pa_sw_volume_to_dB(). This is a
+     * dynamic flag and may change at runtime after the sink has initialized
      * \since 0.9.11 */
 
     PA_SINK_FLAT_VOLUME = 0x0040U,
-    /**< This sink is in flat volume mode, i.e. always the maximum of
+    /**< This sink is in flat volume mode, i.e.\ always the maximum of
      * the volume of all connected inputs. \since 0.9.15 */
 
-    PA_SINK_DYNAMIC_LATENCY = 0x0080U
+    PA_SINK_DYNAMIC_LATENCY = 0x0080U,
     /**< The latency can be adjusted dynamically depending on the
      * needs of the connected streams. \since 0.9.15 */
+
+    PA_SINK_SET_FORMATS = 0x0100U,
+    /**< The sink allows setting what formats are supported by the connected
+     * hardware. The actual functionality to do this might be provided by an
+     * extension. \since 1.0 */
+
+#ifdef __INCLUDED_FROM_PULSE_AUDIO
+/** \cond fulldocs */
+    /* PRIVATE: Server-side values -- do not try to use these at client-side.
+     * The server will filter out these flags anyway, so you should never see
+     * these flags in sinks. */
+
+    PA_SINK_SHARE_VOLUME_WITH_MASTER = 0x1000000U,
+    /**< This sink shares the volume with the master sink (used by some filter
+     * sinks). */
+
+    PA_SINK_DEFERRED_VOLUME = 0x2000000U,
+    /**< The HW volume changes are syncronized with SW volume. */
+/** \endcond */
+#endif
+
 } pa_sink_flags_t;
 
 /** \cond fulldocs */
@@ -734,6 +815,11 @@ typedef enum pa_sink_flags {
 #define PA_SINK_DECIBEL_VOLUME PA_SINK_DECIBEL_VOLUME
 #define PA_SINK_FLAT_VOLUME PA_SINK_FLAT_VOLUME
 #define PA_SINK_DYNAMIC_LATENCY PA_SINK_DYNAMIC_LATENCY
+#define PA_SINK_SET_FORMATS PA_SINK_SET_FORMATS
+#ifdef __INCLUDED_FROM_PULSE_AUDIO
+#define PA_SINK_CLIENT_FLAGS_MASK 0xFFFFFF
+#endif
+
 /** \endcond */
 
 /** Sink state. \since 0.9.15 */
@@ -771,6 +857,11 @@ static inline int PA_SINK_IS_OPENED(pa_sink_state_t x) {
     return x == PA_SINK_RUNNING || x == PA_SINK_IDLE;
 }
 
+/** Returns non-zero if sink is running. \since 1.0 */
+static inline int PA_SINK_IS_RUNNING(pa_sink_state_t x) {
+    return x == PA_SINK_RUNNING;
+}
+
 /** \cond fulldocs */
 #define PA_SINK_INVALID_STATE PA_SINK_INVALID_STATE
 #define PA_SINK_RUNNING PA_SINK_RUNNING
@@ -787,7 +878,8 @@ typedef enum pa_source_flags {
     /**< Flag to pass when no specific options are needed (used to avoid casting)  \since 0.9.19 */
 
     PA_SOURCE_HW_VOLUME_CTRL = 0x0001U,
-    /**< Supports hardware volume control */
+    /**< Supports hardware volume control. This is a dynamic flag and may
+     * change at runtime after the source has initialized */
 
     PA_SOURCE_LATENCY = 0x0002U,
     /**< Supports latency querying */
@@ -800,15 +892,35 @@ typedef enum pa_source_flags {
     /**< Is a networked source of some kind. \since 0.9.7 */
 
     PA_SOURCE_HW_MUTE_CTRL = 0x0010U,
-    /**< Supports hardware mute control \since 0.9.11 */
+    /**< Supports hardware mute control. This is a dynamic flag and may
+     * change at runtime after the source has initialized \since 0.9.11 */
 
     PA_SOURCE_DECIBEL_VOLUME = 0x0020U,
-    /**< Volume can be translated to dB with pa_sw_volume_to_dB()
+    /**< Volume can be translated to dB with pa_sw_volume_to_dB(). This is a
+     * dynamic flag and may change at runtime after the source has initialized
      * \since 0.9.11 */
 
-    PA_SOURCE_DYNAMIC_LATENCY = 0x0040U
+    PA_SOURCE_DYNAMIC_LATENCY = 0x0040U,
     /**< The latency can be adjusted dynamically depending on the
      * needs of the connected streams. \since 0.9.15 */
+
+    PA_SOURCE_FLAT_VOLUME = 0x0080U,
+    /**< This source is in flat volume mode, i.e.\ always the maximum of
+     * the volume of all connected outputs. \since 1.0 */
+
+#ifdef __INCLUDED_FROM_PULSE_AUDIO
+/** \cond fulldocs */
+    /* PRIVATE: Server-side values -- do not try to use these at client-side.
+     * The server will filter out these flags anyway, so you should never see
+     * these flags in sources. */
+
+    PA_SOURCE_SHARE_VOLUME_WITH_MASTER = 0x1000000U,
+    /**< This source shares the volume with the master source (used by some filter
+     * sources). */
+
+    PA_SOURCE_DEFERRED_VOLUME = 0x2000000U,
+    /**< The HW volume changes are syncronized with SW volume. */
+#endif
 } pa_source_flags_t;
 
 /** \cond fulldocs */
@@ -819,6 +931,11 @@ typedef enum pa_source_flags {
 #define PA_SOURCE_HW_MUTE_CTRL PA_SOURCE_HW_MUTE_CTRL
 #define PA_SOURCE_DECIBEL_VOLUME PA_SOURCE_DECIBEL_VOLUME
 #define PA_SOURCE_DYNAMIC_LATENCY PA_SOURCE_DYNAMIC_LATENCY
+#define PA_SOURCE_FLAT_VOLUME PA_SOURCE_FLAT_VOLUME
+#ifdef __INCLUDED_FROM_PULSE_AUDIO
+#define PA_SOURCE_CLIENT_FLAGS_MASK 0xFFFFFF
+#endif
+
 /** \endcond */
 
 /** Source state. \since 0.9.15 */
@@ -856,6 +973,11 @@ static inline int PA_SOURCE_IS_OPENED(pa_source_state_t x) {
     return x == PA_SOURCE_RUNNING || x == PA_SOURCE_IDLE;
 }
 
+/** Returns non-zero if source is running \since 1.0 */
+static inline int PA_SOURCE_IS_RUNNING(pa_source_state_t x) {
+    return x == PA_SOURCE_RUNNING;
+}
+
 /** \cond fulldocs */
 #define PA_SOURCE_INVALID_STATE PA_SOURCE_INVALID_STATE
 #define PA_SOURCE_RUNNING PA_SOURCE_RUNNING
@@ -871,7 +993,7 @@ typedef void (*pa_free_cb_t)(void *p);
 
 /** A stream policy/meta event requesting that an application should
  * cork a specific stream. See pa_stream_event_cb_t for more
- * information, \since 0.9.15 */
+ * information. \since 0.9.15 */
 #define PA_STREAM_EVENT_REQUEST_CORK "request-cork"
 
 /** A stream policy/meta event requesting that an application should
@@ -879,6 +1001,30 @@ typedef void (*pa_free_cb_t)(void *p);
  * information, \since 0.9.15 */
 #define PA_STREAM_EVENT_REQUEST_UNCORK "request-uncork"
 
+/** A stream event notifying that the stream is going to be
+ * disconnected because the underlying sink changed and no longer
+ * supports the format that was originally negotiated. Clients need
+ * to connect a new stream to renegotiate a format and continue
+ * playback. \since 1.0 */
+#define PA_STREAM_EVENT_FORMAT_LOST "format-lost"
+
+#ifndef __INCLUDED_FROM_PULSE_AUDIO
+/** Port availability / jack detection status
+ * \since 2.0 */
+typedef enum pa_port_available {
+    PA_PORT_AVAILABLE_UNKNOWN = 0, /**< This port does not support jack detection \since 2.0 */
+    PA_PORT_AVAILABLE_NO = 1,      /**< This port is not available, likely because the jack is not plugged in. \since 2.0 */
+    PA_PORT_AVAILABLE_YES = 2,     /**< This port is available, likely because the jack is plugged in. \since 2.0 */
+} pa_port_available_t;
+
+/** \cond fulldocs */
+#define PA_PORT_AVAILABLE_UNKNOWN PA_PORT_AVAILABLE_UNKNOWN
+#define PA_PORT_AVAILABLE_NO PA_PORT_AVAILABLE_NO
+#define PA_PORT_AVAILABLE_YES PA_PORT_AVAILABLE_YES
+
+/** \endcond */
+#endif
+
 PA_C_DECL_END
 
 #endif
index e827699..2ca6309 100644 (file)
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 
-#include <pulse/xmalloc.h>
-#include <pulse/i18n.h>
+#include <pulse/def.h>
 
-#include <pulsecore/core-util.h>
-#include <pulsecore/native-common.h>
+#include <pulsecore/i18n.h>
 
 #include "error.h"
 
@@ -54,7 +51,7 @@ const char*pa_strerror(int error) {
         [PA_ERR_CONNECTIONTERMINATED] = N_("Connection terminated"),
         [PA_ERR_KILLED] = N_("Entity killed"),
         [PA_ERR_INVALIDSERVER] = N_("Invalid server"),
-        [PA_ERR_MODINITFAILED] = N_("Module initalization failed"),
+        [PA_ERR_MODINITFAILED] = N_("Module initialization failed"),
         [PA_ERR_BADSTATE] = N_("Bad state"),
         [PA_ERR_NODATA] = N_("No data"),
         [PA_ERR_VERSION] = N_("Incompatible protocol version"),
@@ -67,6 +64,9 @@ const char*pa_strerror(int error) {
         [PA_ERR_FORKED] = N_("Client forked"),
         [PA_ERR_IO] = N_("Input/Output error"),
         [PA_ERR_BUSY] = N_("Device or resource busy")
+#ifdef __TIZEN__
+        ,[PA_ERR_ACCESS_BY_SECURITY] = N_("Access denied by security check")
+#endif
     };
 
     pa_init_i18n();
index ea53560..788db84 100644 (file)
@@ -23,7 +23,6 @@
   USA.
 ***/
 
-#include <inttypes.h>
 #include <pulse/cdecl.h>
 #include <pulse/version.h>
 
index 57cb57c..f2ea63a 100644 (file)
 #endif
 
 #include <pulse/context.h>
-#include <pulse/gccmacro.h>
 #include <pulse/xmalloc.h>
+#include <pulse/fork-detect.h>
+#include <pulse/operation.h>
 
 #include <pulsecore/macro.h>
 #include <pulsecore/pstream-util.h>
 
 #include "internal.h"
-#include "operation.h"
-#include "fork-detect.h"
-
 #include "ext-device-manager.h"
 
 enum {
index df0ab92..1e41ebd 100644 (file)
@@ -23,6 +23,7 @@
   USA.
 ***/
 
+#include <pulse/cdecl.h>
 #include <pulse/context.h>
 #include <pulse/version.h>
 
diff --git a/src/pulse/ext-device-restore.c b/src/pulse/ext-device-restore.c
new file mode 100644 (file)
index 0000000..25d33d1
--- /dev/null
@@ -0,0 +1,375 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2008 Lennart Poettering
+  Copyright 2011 Colin Guthrie
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/context.h>
+#include <pulse/gccmacro.h>
+#include <pulse/xmalloc.h>
+#include <pulse/fork-detect.h>
+#include <pulse/operation.h>
+#include <pulse/format.h>
+
+#include <pulsecore/macro.h>
+#include <pulsecore/pstream-util.h>
+
+#include "internal.h"
+#include "ext-device-restore.h"
+
+/* Protocol extension commands */
+enum {
+    SUBCOMMAND_TEST,
+    SUBCOMMAND_SUBSCRIBE,
+    SUBCOMMAND_EVENT,
+    SUBCOMMAND_READ_FORMATS_ALL,
+    SUBCOMMAND_READ_FORMATS,
+    SUBCOMMAND_SAVE_FORMATS
+};
+
+static void ext_device_restore_test_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+    pa_operation *o = userdata;
+    uint32_t version = PA_INVALID_INDEX;
+
+    pa_assert(pd);
+    pa_assert(o);
+    pa_assert(PA_REFCNT_VALUE(o) >= 1);
+
+    if (!o->context)
+        goto finish;
+
+    if (command != PA_COMMAND_REPLY) {
+        if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
+            goto finish;
+
+    } else if (pa_tagstruct_getu32(t, &version) < 0 ||
+               !pa_tagstruct_eof(t)) {
+
+        pa_context_fail(o->context, PA_ERR_PROTOCOL);
+        goto finish;
+    }
+
+    if (o->callback) {
+        pa_ext_device_restore_test_cb_t cb = (pa_ext_device_restore_test_cb_t) o->callback;
+        cb(o->context, version, o->userdata);
+    }
+
+finish:
+    pa_operation_done(o);
+    pa_operation_unref(o);
+}
+
+pa_operation *pa_ext_device_restore_test(
+        pa_context *c,
+        pa_ext_device_restore_test_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o;
+    pa_tagstruct *t;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-device-restore");
+    pa_tagstruct_putu32(t, SUBCOMMAND_TEST);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_device_restore_test_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation *pa_ext_device_restore_subscribe(
+        pa_context *c,
+        int enable,
+        pa_context_success_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o;
+    pa_tagstruct *t;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-device-restore");
+    pa_tagstruct_putu32(t, SUBCOMMAND_SUBSCRIBE);
+    pa_tagstruct_put_boolean(t, enable);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+void pa_ext_device_restore_set_subscribe_cb(
+        pa_context *c,
+        pa_ext_device_restore_subscribe_cb_t cb,
+        void *userdata) {
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    if (pa_detect_fork())
+        return;
+
+    c->ext_device_restore.callback = cb;
+    c->ext_device_restore.userdata = userdata;
+}
+
+static void ext_device_restore_read_device_formats_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+    pa_operation *o = userdata;
+    int eol = 1;
+
+    pa_assert(pd);
+    pa_assert(o);
+    pa_assert(PA_REFCNT_VALUE(o) >= 1);
+
+    if (!o->context)
+        goto finish;
+
+    if (command != PA_COMMAND_REPLY) {
+        if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
+            goto finish;
+
+        eol = -1;
+    } else {
+        uint8_t j;
+
+        while (!pa_tagstruct_eof(t)) {
+            pa_ext_device_restore_info i;
+            pa_zero(i);
+
+            if (pa_tagstruct_getu32(t, &i.type) < 0 ||
+                pa_tagstruct_getu32(t, &i.index) < 0 ||
+                pa_tagstruct_getu8(t, &i.n_formats) < 0) {
+
+                pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                goto finish;
+            }
+
+            if (PA_DEVICE_TYPE_SINK != i.type && PA_DEVICE_TYPE_SOURCE != i.type) {
+                pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                goto finish;
+            }
+
+            if (i.index == PA_INVALID_INDEX) {
+                pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                goto finish;
+            }
+
+            if (i.n_formats > 0) {
+                i.formats = pa_xnew0(pa_format_info*, i.n_formats);
+
+                for (j = 0; j < i.n_formats; j++) {
+
+                    pa_format_info *f = i.formats[j] = pa_format_info_new();
+                    if (pa_tagstruct_get_format_info(t, f) < 0) {
+                        uint8_t k;
+
+                        pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                        for (k = 0; k < j+1; k++)
+                            pa_format_info_free(i.formats[k]);
+                        pa_xfree(i.formats);
+                        goto finish;
+                    }
+                }
+            }
+
+            if (o->callback) {
+                pa_ext_device_restore_read_device_formats_cb_t cb = (pa_ext_device_restore_read_device_formats_cb_t) o->callback;
+                cb(o->context, &i, 0, o->userdata);
+            }
+
+            for (j = 0; j < i.n_formats; j++)
+                pa_format_info_free(i.formats[j]);
+            pa_xfree(i.formats);
+        }
+    }
+
+    if (o->callback) {
+        pa_ext_device_restore_read_device_formats_cb_t cb = (pa_ext_device_restore_read_device_formats_cb_t) o->callback;
+        cb(o->context, NULL, eol, o->userdata);
+    }
+
+finish:
+    pa_operation_done(o);
+    pa_operation_unref(o);
+}
+
+pa_operation *pa_ext_device_restore_read_formats_all(
+        pa_context *c,
+        pa_ext_device_restore_read_device_formats_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o;
+    pa_tagstruct *t;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-device-restore");
+    pa_tagstruct_putu32(t, SUBCOMMAND_READ_FORMATS_ALL);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_device_restore_read_device_formats_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation *pa_ext_device_restore_read_formats(
+        pa_context *c,
+        pa_device_type_t type,
+        uint32_t idx,
+        pa_ext_device_restore_read_device_formats_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o;
+    pa_tagstruct *t;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+    pa_assert(idx != PA_INVALID_INDEX);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-device-restore");
+    pa_tagstruct_putu32(t, SUBCOMMAND_READ_FORMATS);
+    pa_tagstruct_putu32(t, type);
+    pa_tagstruct_putu32(t, idx);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_device_restore_read_device_formats_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation *pa_ext_device_restore_save_formats(
+        pa_context *c,
+        pa_device_type_t type,
+        uint32_t idx,
+        uint8_t n_formats,
+        pa_format_info **formats,
+        pa_context_success_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o;
+    pa_tagstruct *t;
+    uint8_t j;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+    pa_assert(idx != PA_INVALID_INDEX);
+    pa_assert(n_formats > 0);
+    pa_assert(formats && *formats);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-device-restore");
+    pa_tagstruct_putu32(t, SUBCOMMAND_SAVE_FORMATS);
+
+    pa_tagstruct_putu32(t, type);
+    pa_tagstruct_putu32(t, idx);
+    pa_tagstruct_putu8(t, n_formats);
+    for (j = 0; j < n_formats; j++)
+        pa_tagstruct_put_format_info(t, formats[j]);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+/* Command function defined in internal.h */
+void pa_ext_device_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t) {
+    uint32_t subcommand;
+    pa_device_type_t type;
+    uint32_t idx;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+    pa_assert(t);
+
+    if (pa_tagstruct_getu32(t, &subcommand) < 0 ||
+        pa_tagstruct_getu32(t, &type) < 0 ||
+        pa_tagstruct_getu32(t, &idx) < 0 ||
+        !pa_tagstruct_eof(t)) {
+
+        pa_context_fail(c, PA_ERR_PROTOCOL);
+        return;
+    }
+
+    if (subcommand != SUBCOMMAND_EVENT) {
+        pa_context_fail(c, PA_ERR_PROTOCOL);
+        return;
+    }
+
+    if (PA_DEVICE_TYPE_SINK != type && PA_DEVICE_TYPE_SOURCE != type) {
+        pa_context_fail(c, PA_ERR_PROTOCOL);
+        return;
+    }
+
+    if (idx == PA_INVALID_INDEX) {
+        pa_context_fail(c, PA_ERR_PROTOCOL);
+        return;
+    }
+
+    if (c->ext_device_restore.callback)
+        c->ext_device_restore.callback(c, type, idx, c->ext_device_restore.userdata);
+}
diff --git a/src/pulse/ext-device-restore.h b/src/pulse/ext-device-restore.h
new file mode 100644 (file)
index 0000000..e6857f4
--- /dev/null
@@ -0,0 +1,112 @@
+#ifndef foopulseextdevicerestorehfoo
+#define foopulseextdevicerestorehfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2008 Lennart Poettering
+  Copyright 2011 Colin Guthrie
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <pulse/context.h>
+#include <pulse/format.h>
+#include <pulse/version.h>
+
+/** \file
+ *
+ * Routines for controlling module-device-restore
+ */
+
+PA_C_DECL_BEGIN
+
+/** Stores information about one device in the device database that is
+ * maintained by module-device-manager. \since 1.0 */
+typedef struct pa_ext_device_restore_info {
+    pa_device_type_t type;       /**< Device type sink or source? */
+    uint32_t index;              /**< The device index */
+    uint8_t n_formats;           /**< How many formats do we have? */
+    pa_format_info **formats;    /**< An array of formats (may be NULL if n_formats == 0) */
+} pa_ext_device_restore_info;
+
+/** Callback prototype for pa_ext_device_restore_test(). \since 1.0 */
+typedef void (*pa_ext_device_restore_test_cb_t)(
+        pa_context *c,
+        uint32_t version,
+        void *userdata);
+
+/** Test if this extension module is available in the server. \since 1.0 */
+pa_operation *pa_ext_device_restore_test(
+        pa_context *c,
+        pa_ext_device_restore_test_cb_t cb,
+        void *userdata);
+
+/** Subscribe to changes in the device database. \since 1.0 */
+pa_operation *pa_ext_device_restore_subscribe(
+        pa_context *c,
+        int enable,
+        pa_context_success_cb_t cb,
+        void *userdata);
+
+/** Callback prototype for pa_ext_device_restore_set_subscribe_cb(). \since 1.0 */
+typedef void (*pa_ext_device_restore_subscribe_cb_t)(
+        pa_context *c,
+        pa_device_type_t type,
+        uint32_t idx,
+        void *userdata);
+
+/** Set the subscription callback that is called when
+ * pa_ext_device_restore_subscribe() was called. \since 1.0 */
+void pa_ext_device_restore_set_subscribe_cb(
+        pa_context *c,
+        pa_ext_device_restore_subscribe_cb_t cb,
+        void *userdata);
+
+/** Callback prototype for pa_ext_device_restore_read_formats(). \since 1.0 */
+typedef void (*pa_ext_device_restore_read_device_formats_cb_t)(
+        pa_context *c,
+        const pa_ext_device_restore_info *info,
+        int eol,
+        void *userdata);
+
+/** Read the formats for all present devices from the device database. \since 1.0 */
+pa_operation *pa_ext_device_restore_read_formats_all(
+        pa_context *c,
+        pa_ext_device_restore_read_device_formats_cb_t cb,
+        void *userdata);
+
+/** Read an entry from the device database. \since 1.0 */
+pa_operation *pa_ext_device_restore_read_formats(
+        pa_context *c,
+        pa_device_type_t type,
+        uint32_t idx,
+        pa_ext_device_restore_read_device_formats_cb_t cb,
+        void *userdata);
+
+/** Read an entry from the device database. \since 1.0 */
+pa_operation *pa_ext_device_restore_save_formats(
+        pa_context *c,
+        pa_device_type_t type,
+        uint32_t idx,
+        uint8_t n_formats,
+        pa_format_info **formats,
+        pa_context_success_cb_t cb,
+        void *userdata);
+
+PA_C_DECL_END
+
+#endif
diff --git a/src/pulse/ext-echo-cancel.c b/src/pulse/ext-echo-cancel.c
new file mode 100644 (file)
index 0000000..9339939
--- /dev/null
@@ -0,0 +1,100 @@
+/***
+  This file is part of PulseAudio.
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/context.h>
+#include <pulse/gccmacro.h>
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/macro.h>
+#include <pulsecore/pstream-util.h>
+#include <pulsecore/log.h>
+#include "internal.h"
+#include "operation.h"
+#include "fork-detect.h"
+
+#include "ext-echo-cancel.h"
+
+enum {
+       AEC_SET_VOLUME,
+       AEC_SET_DEVICE,
+};
+
+pa_operation *pa_ext_echo_cancel_set_device (
+                               pa_context *c,
+                               int device,
+                               pa_context_success_cb_t cb,
+                               void *userdata) {
+
+       uint32_t tag;
+       pa_operation *o = NULL;
+       pa_tagstruct *t = NULL;
+
+       pa_assert(c);
+       pa_assert(PA_REFCNT_VALUE(c) >= 1);
+       PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+       PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+       PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+       o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+       t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+       pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+       pa_tagstruct_puts(t, "module-echo-cancel");
+       pa_tagstruct_putu32(t, AEC_SET_DEVICE);
+       pa_tagstruct_putu32(t, device);
+
+       pa_pstream_send_tagstruct(c->pstream, t);
+       pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+       return o;
+}
+
+
+pa_operation *pa_ext_echo_cancel_set_volume (
+                               pa_context *c,
+                               int volume,
+                               pa_context_success_cb_t cb,
+                               void *userdata) {
+
+       uint32_t tag;
+       pa_operation *o = NULL;
+       pa_tagstruct *t = NULL;
+
+       pa_assert(c);
+       pa_assert(PA_REFCNT_VALUE(c) >= 1);
+       PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+       PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+       PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+       o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+       t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+       pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+       pa_tagstruct_puts(t, "module-echo-cancel");
+       pa_tagstruct_putu32(t, AEC_SET_VOLUME);
+       pa_tagstruct_putu32(t, volume);
+
+       pa_pstream_send_tagstruct(c->pstream, t);
+       pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+       return o;
+}
diff --git a/src/pulse/ext-echo-cancel.h b/src/pulse/ext-echo-cancel.h
new file mode 100644 (file)
index 0000000..12e4eeb
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef foopulseechocancelfoo
+#define foopulseechocancelfoo
+
+/***
+  This file is part of PulseAudio.
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <pulse/context.h>
+#include <pulse/version.h>
+
+/** \file
+ *
+ * Routines for controlling module-echo-cancel
+ */
+
+PA_C_DECL_BEGIN
+
+/** Set volume to AEC module */
+pa_operation *pa_ext_echo_cancel_set_volume (
+        pa_context *c,
+        int volume,
+        pa_context_success_cb_t cb,
+        void *userdata);
+
+pa_operation *pa_ext_echo_cancel_set_device (
+        pa_context *c,
+        int device,
+        pa_context_success_cb_t cb,
+        void *userdata);
+
+
+PA_C_DECL_END
+
+#endif
old mode 100644 (file)
new mode 100755 (executable)
index b65fc92..77fe4a6
 
 enum {
     SUBCOMMAND_TEST,
+    SUBCOMMAND_PLAY_SAMPLE,
+    SUBCOMMAND_PLAY_SAMPLE_CONTINUOUSLY,
     SUBCOMMAND_MONO,
+    SUBCOMMAND_BALANCE,
+    SUBCOMMAND_MUTEALL,
+    SUBCOMMAND_SET_USE_CASE,
+    SUBCOMMAND_SET_SESSION,
+    SUBCOMMAND_SET_SUBSESSION,
+    SUBCOMMAND_SET_ACTIVE_DEVICE,
+    SUBCOMMAND_RESET,
+    SUBCOMMAND_GET_VOLUME_LEVEL_MAX,
+    SUBCOMMAND_GET_VOLUME_LEVEL,
+    SUBCOMMAND_SET_VOLUME_LEVEL,
+    SUBCOMMAND_UPDATE_VOLUME,
+    SUBCOMMAND_GET_MUTE,
+    SUBCOMMAND_SET_MUTE,
+    SUBCOMMAND_IS_AVAILABLE_HIGH_LATENCY,
+    SUBCOMMAND_UNLOAD_HDMI,
+
 };
 
 static void ext_policy_test_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
@@ -99,6 +117,125 @@ pa_operation *pa_ext_policy_test(
     return o;
 }
 
+static void ext_policy_play_sample_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata)
+{
+    pa_operation *o = userdata;
+    uint32_t stream_index = 0;
+
+    pa_assert(pd);
+    pa_assert(o);
+    pa_assert(PA_REFCNT_VALUE(o) >= 1);
+
+    if (!o->context)
+        goto finish;
+
+    if (command != PA_COMMAND_REPLY) {
+        if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
+            goto finish;
+
+    } else {
+        while (!pa_tagstruct_eof(t)) {
+            if (pa_tagstruct_getu32(t, &stream_index) < 0) {
+                pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                pa_log_error("play_sample : context fail");
+                goto finish;
+            }
+        }
+    }
+
+    if (o->callback) {
+        pa_ext_policy_play_sample_cb_t cb = (pa_ext_policy_play_sample_cb_t) o->callback;
+        cb(o->context, stream_index, o->userdata);
+    }
+
+finish:
+    pa_operation_done(o);
+    pa_operation_unref(o);
+}
+
+pa_operation *pa_ext_policy_play_sample (
+        pa_context *c,
+        const char *name,
+        uint32_t volume_type,
+        uint32_t gain_type,
+        uint32_t volume_level,
+        pa_ext_policy_play_sample_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_PLAY_SAMPLE);
+
+    pa_tagstruct_puts(t, name);
+    pa_tagstruct_putu32(t, volume_type);
+    pa_tagstruct_putu32(t, (gain_type >> 8));
+    pa_tagstruct_putu32(t, volume_level);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_policy_play_sample_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+#ifdef BURST_SHOT
+pa_operation *pa_ext_policy_play_sample_continuously (
+        pa_context *c,
+        const char *name,
+        int start,
+        uint32_t volume_type,
+        uint32_t gain_type,
+        uint32_t volume_level,
+        pa_usec_t interval,
+        pa_ext_policy_play_sample_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_PLAY_SAMPLE_CONTINUOUSLY);
+
+    pa_tagstruct_puts(t, name);
+    pa_tagstruct_put_boolean(t, !!start);
+    pa_tagstruct_putu32(t, volume_type);
+    pa_tagstruct_putu32(t, (gain_type >> 8));
+    pa_tagstruct_putu32(t, volume_level);
+    pa_tagstruct_put_usec(t, interval);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_policy_play_sample_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+#endif
+
 pa_operation *pa_ext_policy_set_mono (
         pa_context *c,
         int enable,
@@ -129,3 +266,707 @@ pa_operation *pa_ext_policy_set_mono (
 
     return o;
 }
+
+pa_operation *pa_ext_policy_set_balance (
+        pa_context *c,
+        double *balance,
+        pa_context_success_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+    pa_cvolume cvol;
+    pa_channel_map map;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_BALANCE);
+
+    /* Prepare cvolume for transfer */
+    pa_channel_map_init_stereo(&map);
+    pa_cvolume_set(&cvol, map.channels, 65535);
+
+    pa_log_error ("balance = %f", *balance);
+
+    pa_cvolume_set_balance(&cvol, &map, *balance);
+
+    pa_log_error ("balance get = %f", pa_cvolume_get_balance(&cvol, &map));
+
+    pa_tagstruct_put_cvolume(t, &cvol);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation *pa_ext_policy_set_muteall (
+        pa_context *c,
+        int enable,
+        pa_context_success_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_MUTEALL);
+    pa_tagstruct_put_boolean(t, !!enable);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+
+pa_operation *pa_ext_policy_set_use_case (
+        pa_context *c,
+        const char *verb,
+        const char *devices[],
+        const int num_devices,
+        const char *modifiers[],
+        const int num_modifiers,
+        pa_context_success_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+    int i = 0;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_SET_USE_CASE);
+
+    pa_tagstruct_puts(t, verb);
+
+    pa_log_info("verb: %s", verb);
+    pa_tagstruct_putu32(t, num_devices);
+
+    for(i = 0; i < num_devices; i++) {
+        pa_tagstruct_puts(t, devices[i]);
+        pa_log_error("device: %s", devices[i]);
+    }
+
+    pa_tagstruct_putu32(t, num_modifiers);
+    for(i = 0; i < num_modifiers; i++) {
+        pa_tagstruct_puts(t, modifiers[i]);
+        pa_log_error("modifier: %s", modifiers[i]);
+    }
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation *pa_ext_policy_set_session (
+        pa_context *c,
+        uint32_t session,
+        uint32_t start,
+        pa_context_success_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_SET_SESSION);
+
+    pa_tagstruct_putu32(t, session);
+    pa_tagstruct_putu32(t, start);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation *pa_ext_policy_set_subsession (
+        pa_context *c,
+        uint32_t subsession,
+        uint32_t subsession_opt,
+        pa_context_success_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_SET_SUBSESSION);
+
+    pa_tagstruct_putu32(t, subsession);
+    pa_tagstruct_putu32(t, subsession_opt);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+static void ext_policy_set_active_device_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata)
+{
+    pa_operation *o = userdata;
+    int success = 1;
+    uint32_t need_update = 0;
+    uint32_t index = 0;
+
+    pa_assert(pd);
+    pa_assert(o);
+    pa_assert(PA_REFCNT_VALUE(o) >= 1);
+
+    if (!o->context)
+        goto finish;
+
+    if (command != PA_COMMAND_REPLY) {
+        if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
+            goto finish;
+
+        success = 0;
+    } else {
+        while (!pa_tagstruct_eof(t)) {
+            if (pa_tagstruct_getu32(t, &need_update) < 0) {
+                pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                pa_log_error("get_mute : context fail");
+                goto finish;
+            }
+            index++;
+        }
+    }
+
+    if (o->callback) {
+        pa_ext_policy_set_active_device_cb_t cb = (pa_ext_policy_get_mute_cb_t) o->callback;
+        cb(o->context, success, need_update, o->userdata);
+    }
+
+finish:
+    pa_operation_done(o);
+    pa_operation_unref(o);
+}
+
+pa_operation *pa_ext_policy_set_active_device (
+        pa_context *c,
+        uint32_t device_in,
+        uint32_t device_out,
+        pa_ext_policy_set_active_device_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_SET_ACTIVE_DEVICE);
+
+    pa_tagstruct_putu32(t, device_in);
+    pa_tagstruct_putu32(t, device_out);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_policy_set_active_device_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation *pa_ext_policy_reset (
+        pa_context *c,
+        pa_context_success_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_RESET);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+static void ext_policy_get_volume_level_max_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata)
+{
+    pa_operation *o = userdata;
+    uint32_t volume_level = 0;
+
+    pa_assert(pd);
+    pa_assert(o);
+    pa_assert(PA_REFCNT_VALUE(o) >= 1);
+
+    if (!o->context)
+        goto finish;
+
+    if (command != PA_COMMAND_REPLY) {
+        if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
+            goto finish;
+
+    } else {
+        while (!pa_tagstruct_eof(t)) {
+            if (pa_tagstruct_getu32(t, &volume_level) < 0) {
+                pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                pa_log_error("get_volume_level_max : context fail");
+                goto finish;
+            }
+        }
+    }
+
+    if (o->callback) {
+        pa_ext_policy_get_volume_level_max_cb_t cb = (pa_ext_policy_get_volume_level_max_cb_t) o->callback;
+        cb(o->context, volume_level, o->userdata);
+    }
+
+finish:
+    pa_operation_done(o);
+    pa_operation_unref(o);
+}
+
+pa_operation *pa_ext_policy_get_volume_level_max (
+        pa_context *c,
+        uint32_t volume_type,
+        pa_ext_policy_get_volume_level_max_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_GET_VOLUME_LEVEL_MAX);
+
+    pa_tagstruct_putu32(t, volume_type);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_policy_get_volume_level_max_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+static void ext_policy_get_volume_level_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata)
+{
+    pa_operation *o = userdata;
+    uint32_t volume_level = 0;
+
+    pa_assert(pd);
+    pa_assert(o);
+    pa_assert(PA_REFCNT_VALUE(o) >= 1);
+
+    if (!o->context)
+        goto finish;
+
+    if (command != PA_COMMAND_REPLY) {
+        if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
+            goto finish;
+
+    } else {
+        while (!pa_tagstruct_eof(t)) {
+            if (pa_tagstruct_getu32(t, &volume_level) < 0) {
+                pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                pa_log_error("get_volume_level : context fail");
+                goto finish;
+            }
+        }
+    }
+
+    if (o->callback) {
+        pa_ext_policy_get_volume_level_cb_t cb = (pa_ext_policy_get_volume_level_cb_t) o->callback;
+        cb(o->context, volume_level, o->userdata);
+    }
+
+finish:
+    pa_operation_done(o);
+    pa_operation_unref(o);
+}
+
+pa_operation *pa_ext_policy_get_volume_level (
+        pa_context *c,
+        uint32_t stream_idx,
+        uint32_t volume_type,
+        pa_ext_policy_get_volume_level_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_GET_VOLUME_LEVEL);
+
+    pa_tagstruct_putu32(t, stream_idx);
+    pa_tagstruct_putu32(t, volume_type);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_policy_get_volume_level_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation *pa_ext_policy_set_volume_level (
+        pa_context *c,
+        uint32_t stream_idx,
+        uint32_t volume_type,
+        uint32_t volume_level,
+        pa_context_success_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_SET_VOLUME_LEVEL);
+
+    pa_tagstruct_putu32(t, stream_idx);
+    pa_tagstruct_putu32(t, volume_type);
+    pa_tagstruct_putu32(t, volume_level);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation *pa_ext_policy_update_volume (
+        pa_context *c,
+        pa_context_success_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_UPDATE_VOLUME);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+static void ext_policy_get_mute_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata)
+{
+    pa_operation *o = userdata;
+    uint32_t mute = 0;
+
+    pa_assert(pd);
+    pa_assert(o);
+    pa_assert(PA_REFCNT_VALUE(o) >= 1);
+
+    if (!o->context)
+        goto finish;
+
+    if (command != PA_COMMAND_REPLY) {
+        if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
+            goto finish;
+
+    } else {
+        while (!pa_tagstruct_eof(t)) {
+            if (pa_tagstruct_getu32(t, &mute) < 0) {
+                pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                pa_log_error("get_mute : context fail");
+                goto finish;
+            }
+        }
+    }
+
+    if (o->callback) {
+        pa_ext_policy_get_mute_cb_t cb = (pa_ext_policy_get_mute_cb_t) o->callback;
+        cb(o->context, mute, o->userdata);
+    }
+
+finish:
+    pa_operation_done(o);
+    pa_operation_unref(o);
+}
+
+pa_operation *pa_ext_policy_get_mute (
+        pa_context *c,
+        uint32_t stream_idx,
+        uint32_t volume_type,
+        uint32_t direction,
+        pa_ext_policy_get_mute_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_GET_MUTE);
+
+    pa_tagstruct_putu32(t, stream_idx);
+    pa_tagstruct_putu32(t, volume_type);
+    pa_tagstruct_putu32(t, direction);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_policy_get_mute_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation *pa_ext_policy_set_mute (
+        pa_context *c,
+        uint32_t stream_idx,
+        uint32_t volume_type,
+        uint32_t direction,
+        uint32_t mute,
+        pa_context_success_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_SET_MUTE);
+
+    pa_tagstruct_putu32(t, stream_idx);
+    pa_tagstruct_putu32(t, volume_type);
+    pa_tagstruct_putu32(t, direction);
+    pa_tagstruct_putu32(t, mute);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+static void ext_policy_is_available_high_latency_cb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata)
+{
+    pa_operation *o = userdata;
+    uint32_t available = 0;
+
+    pa_assert(pd);
+    pa_assert(o);
+    pa_assert(PA_REFCNT_VALUE(o) >= 1);
+
+    if (!o->context)
+        goto finish;
+
+    if (command != PA_COMMAND_REPLY) {
+        if (pa_context_handle_error(o->context, command, t, FALSE) < 0)
+            goto finish;
+
+    } else {
+        while (!pa_tagstruct_eof(t)) {
+            if (pa_tagstruct_getu32(t, &available) < 0) {
+                pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                pa_log_error("is_available_high_latency : context fail");
+                goto finish;
+            }
+        }
+    }
+
+    if (o->callback) {
+        pa_ext_policy_is_available_high_latency_cb_t cb = (pa_ext_policy_is_available_high_latency_cb_t) o->callback;
+        cb(o->context, available, o->userdata);
+    }
+
+finish:
+    pa_operation_done(o);
+    pa_operation_unref(o);
+}
+
+pa_operation *pa_ext_policy_is_available_high_latency (
+        pa_context *c,
+        pa_ext_policy_is_available_high_latency_cb_t cb,
+        void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_IS_AVAILABLE_HIGH_LATENCY);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, ext_policy_is_available_high_latency_cb, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation *pa_ext_policy_unload_hdmi (
+        pa_context *c,
+        pa_context_success_cb_t cb,
+        void *userdata)
+{
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-policy");
+    pa_tagstruct_putu32(t, SUBCOMMAND_UNLOAD_HDMI);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
old mode 100644 (file)
new mode 100755 (executable)
index 16dda07..5a36c30
 
 PA_C_DECL_BEGIN
 
+typedef enum {
+    PA_TIZEN_SESSION_MEDIA,
+    PA_TIZEN_SESSION_VOICECALL,
+    PA_TIZEN_SESSION_VIDEOCALL,
+    PA_TIZEN_SESSION_VOIP,
+    PA_TIZEN_SESSION_FMRADIO,
+    PA_TIZEN_SESSION_CAMCORDER,
+    PA_TIZEN_SESSION_NOTIFICATION,
+    PA_TIZEN_SESSION_ALARM,
+    PA_TIZEN_SESSION_EMERGENCY,
+    PA_TIZEN_SESSION_VOICE_RECOGNITION,
+    PA_TIZEN_SESSION_MAX
+} pa_tizen_session_t;
+
+typedef enum {
+    PA_TIZEN_SUBSESSION_NONE,
+    PA_TIZEN_SUBSESSION_VOICE,
+    PA_TIZEN_SUBSESSION_RINGTONE,
+    PA_TIZEN_SUBSESSION_MEDIA,
+    PA_TIZEN_SUBSESSION_VR_INIT,
+    PA_TIZEN_SUBSESSION_VR_NORMAL,
+    PA_TIZEN_SUBSESSION_VR_DRIVE,
+    PA_TIZEN_SUBSESSION_STEREO_REC,
+    PA_TIZEN_SUBSESSION_MONO_REC,
+    PA_TIZEN_SUBSESSION_MAX
+} pa_tizen_subsession_t;
+
+typedef enum {
+    PA_TIZEN_DEVICE_IN_NONE,
+    PA_TIZEN_DEVICE_IN_MIC,                 /**< Device builtin mic. */
+    PA_TIZEN_DEVICE_IN_WIRED_ACCESSORY,     /**< Wired input devices */
+    PA_TIZEN_DEVICE_IN_BT_SCO,              /**< Bluetooth SCO device */
+} pa_tizen_device_in_t;
+
+typedef enum pa_tizen_device_out {
+    PA_TIZEN_DEVICE_OUT_NONE,
+    PA_TIZEN_DEVICE_OUT_SPEAKER,            /**< Device builtin speaker */
+    PA_TIZEN_DEVICE_OUT_RECEIVER,           /**< Device builtin receiver */
+    PA_TIZEN_DEVICE_OUT_WIRED_ACCESSORY,    /**< Wired output devices such as headphone, headset, and so on. */
+    PA_TIZEN_DEVICE_OUT_BT_SCO,             /**< Bluetooth SCO device */
+    PA_TIZEN_DEVICE_OUT_BT_A2DP,            /**< Bluetooth A2DP device */
+    PA_TIZEN_DEVICE_OUT_DOCK,               /**< DOCK device */
+    PA_TIZEN_DEVICE_OUT_HDMI,               /**< HDMI device */
+    PA_TIZEN_DEVICE_OUT_MIRRORING,          /**< MIRRORING device */
+    PA_TIZEN_DEVICE_OUT_USB_AUDIO,          /**< USB Audio device */
+    PA_TIZEN_DEVICE_OUT_MULTIMEDIA_DOCK,    /**< Multimedia DOCK device */
+} pa_tizen_device_out_t;
+
+typedef enum pa_tizen_volume_type {
+    PA_TIZEN_VOLUME_TYPE_SYSTEM,            /**< System volume type */
+    PA_TIZEN_VOLUME_TYPE_NOTIFICATION,      /**< Notification volume type */
+    PA_TIZEN_VOLUME_TYPE_ALARM,             /**< Alarm volume type */
+    PA_TIZEN_VOLUME_TYPE_RINGTONE,          /**< Ringtone volume type */
+    PA_TIZEN_VOLUME_TYPE_MEDIA,             /**< Media volume type */
+    PA_TIZEN_VOLUME_TYPE_CALL,              /**< Call volume type */
+    PA_TIZEN_VOLUME_TYPE_VOIP,              /**< VOIP volume type */
+    PA_TIZEN_VOLUME_TYPE_VOICE,             /**< VOICE volume type */
+    PA_TIZEN_VOLUME_TYPE_FIXED,             /**< Volume type for fixed acoustic level */
+    PA_TIZEN_VOLUME_TYPE_MAX,               /**< Volume type count */
+    PA_TIZEN_VOLUME_TYPE_DEFAULT = PA_TIZEN_VOLUME_TYPE_SYSTEM,
+} pa_tizen_volume_type_t;
+
+typedef enum pa_tizen_gain_type {
+    PA_TIZEN_GAIN_TYPE_DEFAULT,
+    PA_TIZEN_GAIN_TYPE_DIALER,
+    PA_TIZEN_GAIN_TYPE_TOUCH,
+    PA_TIZEN_GAIN_TYPE_AF,
+    PA_TIZEN_GAIN_TYPE_SHUTTER1,
+    PA_TIZEN_GAIN_TYPE_SHUTTER2,
+    PA_TIZEN_GAIN_TYPE_CAMCODING,
+    PA_TIZEN_GAIN_TYPE_MIDI,
+    PA_TIZEN_GAIN_TYPE_BOOTING,
+    PA_TIZEN_GAIN_TYPE_VIDEO,
+    PA_TIZEN_GAIN_TYPE_MAX,
+} pa_tizen_gain_type_t;
+
+#define PA_TIZEN_VOLUME_TYPE_LEVEL_MAX           15
+
 /** Callback prototype for pa_ext_policy_test(). \since 0.9.21 */
 typedef void (*pa_ext_policy_test_cb_t)(
         pa_context *c,
@@ -42,6 +120,36 @@ pa_operation *pa_ext_policy_test(
         pa_ext_policy_test_cb_t cb,
         void *userdata);
 
+/** Callback prototype for pa_ext_policy_play_sample(). \since 0.9.21 */
+typedef void (*pa_ext_policy_play_sample_cb_t)(
+        pa_context *c,
+        uint32_t stream_index,
+        void *userdata);
+
+/* Similar with pa_context_play_sample, but can apply volume type */
+pa_operation *pa_ext_policy_play_sample (
+        pa_context *c,
+        const char *name,
+        uint32_t volume_type,
+        uint32_t gain_type,
+        uint32_t volume_level,
+        pa_ext_policy_play_sample_cb_t cb,
+        void *userdata);
+
+#ifdef BURST_SHOT
+/* make one sink-input and then push burst cam-shutter sound. */
+pa_operation *pa_ext_policy_play_sample_continuously (
+        pa_context *c,
+        const char *name,
+        int start, /* start/stop */
+        uint32_t volume_type,
+        uint32_t gain_type,
+        uint32_t volume_level,
+        pa_usec_t interval, /* timeout_cb interval */
+        pa_ext_policy_play_sample_cb_t cb,
+        void *userdata);
+#endif
+
 /** Enable the mono mode. \since 0.9.21 */
 pa_operation *pa_ext_policy_set_mono (
         pa_context *c,
@@ -49,6 +157,139 @@ pa_operation *pa_ext_policy_set_mono (
         pa_context_success_cb_t cb,
         void *userdata);
 
+/** Enable the balance mode. \since 0.9.21 */
+pa_operation *pa_ext_policy_set_balance (
+        pa_context *c,
+        double *balance,
+        pa_context_success_cb_t cb,
+        void *userdata);
+
+/** Enable the muteall mode. \since 0.9.21 */
+pa_operation *pa_ext_policy_set_muteall (
+        pa_context *c,
+        int enable,
+        pa_context_success_cb_t cb,
+        void *userdata);
+
+pa_operation *pa_ext_policy_set_use_case (
+        pa_context *c,
+        const char *verb,
+        const char *devices[],
+        const int num_devices,
+        const char *modifiers[],
+        const int num_modifiers,
+        pa_context_success_cb_t cb,
+        void *userdata);
+
+pa_operation *pa_ext_policy_set_session (
+        pa_context *c,
+        uint32_t session,
+        uint32_t start,
+        pa_context_success_cb_t cb,
+        void *userdata);
+
+pa_operation *pa_ext_policy_set_subsession (
+        pa_context *c,
+        uint32_t subsession,
+        uint32_t subsession_opt,
+        pa_context_success_cb_t cb,
+        void *userdata);
+
+typedef void (*pa_ext_policy_set_active_device_cb_t)(
+        pa_context *c,
+        int success,
+        uint32_t need_update,
+        void *userdata);
+
+pa_operation *pa_ext_policy_set_active_device (
+        pa_context *c,
+        uint32_t device_in,
+        uint32_t device_out,
+        pa_ext_policy_set_active_device_cb_t cb,
+        void *userdata);
+
+pa_operation *pa_ext_policy_reset (
+        pa_context *c,
+        pa_context_success_cb_t cb,
+        void *userdata);
+
+/** Callback prototype for pa_ext_policy_get_volume_level_max(). \since 0.9.21 */
+typedef void (*pa_ext_policy_get_volume_level_max_cb_t)(
+        pa_context *c,
+        uint32_t volume_level,
+        void *userdata);
+
+pa_operation *pa_ext_policy_get_volume_level_max (
+        pa_context *c,
+        uint32_t volume_type,
+        pa_ext_policy_get_volume_level_max_cb_t cb,
+        void *userdata);
+
+/** Callback prototype for pa_ext_policy_get_volume_level(). \since 0.9.21 */
+typedef void (*pa_ext_policy_get_volume_level_cb_t)(
+        pa_context *c,
+        uint32_t volume_level,
+        void *userdata);
+
+pa_operation *pa_ext_policy_get_volume_level (
+        pa_context *c,
+        uint32_t stream_idx,
+        uint32_t volume_type,
+        pa_ext_policy_get_volume_level_max_cb_t cb,
+        void *userdata);
+
+pa_operation *pa_ext_policy_set_volume_level (
+        pa_context *c,
+        uint32_t stream_idx,
+        uint32_t volume_type,
+        uint32_t volume_level,
+        pa_context_success_cb_t cb,
+        void *userdata);
+
+pa_operation *pa_ext_policy_update_volume (
+        pa_context *c,
+        pa_context_success_cb_t cb,
+        void *userdata);
+
+/** Callback prototype for pa_ext_policy_get_mute(). \since 0.9.21 */
+typedef void (*pa_ext_policy_get_mute_cb_t)(
+        pa_context *c,
+        uint32_t mute,
+        void *userdata);
+
+pa_operation *pa_ext_policy_get_mute (
+        pa_context *c,
+        uint32_t stream_idx,
+        uint32_t volume_type,
+        uint32_t direction,
+        pa_ext_policy_get_mute_cb_t cb,
+        void *userdata);
+
+pa_operation *pa_ext_policy_set_mute (
+        pa_context *c,
+        uint32_t stream_idx,
+        uint32_t volume_type,
+        uint32_t direction,
+        uint32_t mute,
+        pa_context_success_cb_t cb,
+        void *userdata);
+
+/** Callback prototype for pa_ext_policy_get_mute(). \since 0.9.21 */
+typedef void (*pa_ext_policy_is_available_high_latency_cb_t)(
+        pa_context *c,
+        uint32_t available,
+        void *userdata);
+
+pa_operation *pa_ext_policy_is_available_high_latency (
+        pa_context *c,
+        pa_ext_policy_is_available_high_latency_cb_t cb,
+        void *userdata);
+
+pa_operation *pa_ext_policy_unload_hdmi (
+        pa_context *c,
+        pa_context_success_cb_t cb,
+        void *userdata);
+
 PA_C_DECL_END
 
 #endif
index 10e9fd5..1f72c1c 100644 (file)
 #endif
 
 #include <pulse/context.h>
-#include <pulse/gccmacro.h>
+#include <pulse/fork-detect.h>
+#include <pulse/operation.h>
 
 #include <pulsecore/macro.h>
 #include <pulsecore/pstream-util.h>
 
 #include "internal.h"
-#include "operation.h"
-#include "fork-detect.h"
-
 #include "ext-stream-restore.h"
 
 enum {
index 54516f6..acb16a8 100644 (file)
@@ -22,6 +22,7 @@
   USA.
 ***/
 
+#include <pulse/cdecl.h>
 #include <pulse/context.h>
 #include <pulse/version.h>
 #include <pulse/volume.h>
diff --git a/src/pulse/ext-suspend-on-idle.c b/src/pulse/ext-suspend-on-idle.c
new file mode 100644 (file)
index 0000000..bdac214
--- /dev/null
@@ -0,0 +1,96 @@
+/***
+  This file is part of PulseAudio.
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/context.h>
+#include <pulse/gccmacro.h>
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/macro.h>
+#include <pulsecore/pstream-util.h>
+#include <pulsecore/log.h>
+#include "internal.h"
+#include "operation.h"
+#include "fork-detect.h"
+
+#include "ext-suspend-on-idle.h"
+
+enum {
+    SET_INFO,
+    UPDATE_SCN,
+};
+
+pa_operation *pa_ext_suspend_on_idle_set_info (
+                pa_context *c,
+                int info,
+                pa_context_success_cb_t cb,
+                void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-suspend-on-idle");
+    pa_tagstruct_putu32(t, SET_INFO);
+    pa_tagstruct_putu32(t, info);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+    return o;
+}
+
+pa_operation *pa_ext_suspend_on_idle_update_scn (
+                pa_context *c,
+                pa_context_success_cb_t cb,
+                void *userdata) {
+
+    uint32_t tag;
+    pa_operation *o = NULL;
+    pa_tagstruct *t = NULL;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 14, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_EXTENSION, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, "module-suspend-on-idle");
+    pa_tagstruct_putu32(t, UPDATE_SCN);
+
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+    return o;
+}
diff --git a/src/pulse/ext-suspend-on-idle.h b/src/pulse/ext-suspend-on-idle.h
new file mode 100644 (file)
index 0000000..2d7b348
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef foopulsesuspendonidlefoo
+#define foopulsesuspendonidlefoo
+
+/***
+  This file is part of PulseAudio.
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <pulse/context.h>
+#include <pulse/version.h>
+
+/** \file
+ *
+ * Routines for controlling module-suspend-on-idle
+ */
+
+PA_C_DECL_BEGIN
+
+/** Set XXXX module */
+pa_operation *pa_ext_suspend_on_idle_set_info (
+        pa_context *c,
+        int info,
+        pa_context_success_cb_t cb,
+        void *userdata);
+
+pa_operation *pa_ext_suspend_on_idle_update_scn (
+        pa_context *c,
+        pa_context_success_cb_t cb,
+        void *userdata);
+
+
+PA_C_DECL_END
+
+#endif
diff --git a/src/pulse/format.c b/src/pulse/format.c
new file mode 100644 (file)
index 0000000..05a99a2
--- /dev/null
@@ -0,0 +1,731 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2011 Intel Corporation
+  Copyright 2011 Collabora Multimedia
+  Copyright 2011 Arun Raghavan <arun.raghavan@collabora.co.uk>
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <json.h>
+
+#include <pulse/internal.h>
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/i18n.h>
+#include <pulsecore/macro.h>
+
+#include "format.h"
+
+#define PA_JSON_MIN_KEY "min"
+#define PA_JSON_MAX_KEY "max"
+
+static int pa_format_info_prop_compatible(const char *one, const char *two);
+
+static const char* const _encoding_str_table[]= {
+    [PA_ENCODING_PCM] = "pcm",
+    [PA_ENCODING_AC3_IEC61937] = "ac3-iec61937",
+    [PA_ENCODING_EAC3_IEC61937] = "eac3-iec61937",
+    [PA_ENCODING_MPEG_IEC61937] = "mpeg-iec61937",
+    [PA_ENCODING_DTS_IEC61937] = "dts-iec61937",
+    [PA_ENCODING_MPEG2_AAC_IEC61937] = "mpeg2-aac-iec61937",
+    [PA_ENCODING_ANY] = "any",
+};
+
+const char *pa_encoding_to_string(pa_encoding_t e) {
+    if (e < 0 || e >= PA_ENCODING_MAX)
+        return NULL;
+
+    return _encoding_str_table[e];
+}
+
+pa_encoding_t pa_encoding_from_string(const char *encoding) {
+    pa_encoding_t e;
+
+    for (e = PA_ENCODING_ANY; e < PA_ENCODING_MAX; e++)
+        if (pa_streq(_encoding_str_table[e], encoding))
+            return e;
+
+    return PA_ENCODING_INVALID;
+}
+
+pa_format_info* pa_format_info_new(void) {
+    pa_format_info *f = pa_xnew(pa_format_info, 1);
+
+    f->encoding = PA_ENCODING_INVALID;
+    f->plist = pa_proplist_new();
+
+    return f;
+}
+
+pa_format_info* pa_format_info_copy(const pa_format_info *src) {
+    pa_format_info *dest;
+
+    pa_assert(src);
+
+    dest = pa_xnew(pa_format_info, 1);
+
+    dest->encoding = src->encoding;
+
+    if (src->plist)
+        dest->plist = pa_proplist_copy(src->plist);
+    else
+        dest->plist = NULL;
+
+    return dest;
+}
+
+void pa_format_info_free(pa_format_info *f) {
+    pa_assert(f);
+
+    pa_proplist_free(f->plist);
+    pa_xfree(f);
+}
+
+int pa_format_info_valid(const pa_format_info *f) {
+    return (f->encoding >= 0 && f->encoding < PA_ENCODING_MAX && f->plist != NULL);
+}
+
+int pa_format_info_is_pcm(const pa_format_info *f) {
+    return f->encoding == PA_ENCODING_PCM;
+}
+
+char *pa_format_info_snprint(char *s, size_t l, const pa_format_info *f) {
+    char *tmp;
+
+    pa_assert(s);
+    pa_assert(l > 0);
+    pa_assert(f);
+
+    pa_init_i18n();
+
+    if (!pa_format_info_valid(f))
+        pa_snprintf(s, l, _("(invalid)"));
+    else {
+        tmp = pa_proplist_to_string_sep(f->plist, "  ");
+        if (tmp[0])
+            pa_snprintf(s, l, "%s, %s", pa_encoding_to_string(f->encoding), tmp);
+        else
+            pa_snprintf(s, l, "%s", pa_encoding_to_string(f->encoding));
+        pa_xfree(tmp);
+    }
+
+    return s;
+}
+
+pa_format_info* pa_format_info_from_string(const char *str) {
+    pa_format_info *f = pa_format_info_new();
+    char *encoding = NULL, *properties = NULL;
+    size_t pos;
+
+    pos = strcspn(str, ",");
+
+    encoding = pa_xstrndup(str, pos);
+    f->encoding = pa_encoding_from_string(pa_strip(encoding));
+    if (f->encoding == PA_ENCODING_INVALID)
+        goto error;
+
+    if (pos != strlen(str)) {
+        pa_proplist *plist;
+
+        properties = pa_xstrdup(&str[pos+1]);
+        plist = pa_proplist_from_string(properties);
+
+        if (!plist)
+            goto error;
+
+        pa_proplist_free(f->plist);
+        f->plist = plist;
+    }
+
+out:
+    if (encoding)
+        pa_xfree(encoding);
+    if (properties)
+        pa_xfree(properties);
+    return f;
+
+error:
+    pa_format_info_free(f);
+    f = NULL;
+    goto out;
+}
+
+int pa_format_info_is_compatible(pa_format_info *first, pa_format_info *second) {
+    const char *key;
+    void *state = NULL;
+
+    pa_assert(first);
+    pa_assert(second);
+
+    if (first->encoding != second->encoding)
+        return FALSE;
+
+    while ((key = pa_proplist_iterate(first->plist, &state))) {
+        const char *value_one, *value_two;
+
+        value_one = pa_proplist_gets(first->plist, key);
+        value_two = pa_proplist_gets(second->plist, key);
+
+        if (!value_two || !pa_format_info_prop_compatible(value_one, value_two))
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+pa_format_info* pa_format_info_from_sample_spec(pa_sample_spec *ss, pa_channel_map *map) {
+    char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
+    pa_format_info *f;
+
+    pa_assert(ss && pa_sample_spec_valid(ss));
+    pa_assert(!map || pa_channel_map_valid(map));
+
+    f = pa_format_info_new();
+    f->encoding = PA_ENCODING_PCM;
+
+    pa_format_info_set_sample_format(f, ss->format);
+    pa_format_info_set_rate(f, ss->rate);
+    pa_format_info_set_channels(f, ss->channels);
+
+    if (map) {
+        pa_channel_map_snprint(cm, sizeof(cm), map);
+        pa_format_info_set_prop_string(f, PA_PROP_FORMAT_CHANNEL_MAP, cm);
+    }
+
+    return f;
+}
+
+/* For compressed streams */
+static int pa_format_info_to_sample_spec_fake(pa_format_info *f, pa_sample_spec *ss) {
+    int rate;
+
+    pa_assert(f);
+    pa_assert(ss);
+
+    /* Note: When we add support for non-IEC61937 encapsulated compressed
+     * formats, this function should return a non-zero values for these. */
+
+    ss->format = PA_SAMPLE_S16LE;
+    ss->channels = 2;
+
+    pa_return_val_if_fail(pa_format_info_get_prop_int(f, PA_PROP_FORMAT_RATE, &rate) == 0, -PA_ERR_INVALID);
+    ss->rate = (uint32_t) rate;
+
+    if (f->encoding == PA_ENCODING_EAC3_IEC61937)
+        ss->rate *= 4;
+
+    return 0;
+}
+
+/* For PCM streams */
+int pa_format_info_to_sample_spec(pa_format_info *f, pa_sample_spec *ss, pa_channel_map *map) {
+    char *sf = NULL, *m = NULL;
+    int rate, channels;
+    int ret = -PA_ERR_INVALID;
+
+    pa_assert(f);
+    pa_assert(ss);
+
+    if (!pa_format_info_is_pcm(f))
+        return pa_format_info_to_sample_spec_fake(f, ss);
+
+    if (pa_format_info_get_prop_string(f, PA_PROP_FORMAT_SAMPLE_FORMAT, &sf))
+        goto out;
+    if (pa_format_info_get_prop_int(f, PA_PROP_FORMAT_RATE, &rate))
+        goto out;
+    if (pa_format_info_get_prop_int(f, PA_PROP_FORMAT_CHANNELS, &channels))
+        goto out;
+
+    if ((ss->format = pa_parse_sample_format(sf)) == PA_SAMPLE_INVALID)
+        goto out;
+
+    ss->rate = (uint32_t) rate;
+    ss->channels = (uint8_t) channels;
+
+    if (map) {
+        pa_channel_map_init(map);
+
+        if (pa_format_info_get_prop_string(f, PA_PROP_FORMAT_CHANNEL_MAP, &m) == 0)
+            if (pa_channel_map_parse(map, m) == NULL)
+                goto out;
+    }
+
+    ret = 0;
+
+out:
+    if (sf)
+        pa_xfree(sf);
+    if (m)
+        pa_xfree(m);
+
+    return ret;
+}
+
+pa_prop_type_t pa_format_info_get_prop_type(pa_format_info *f, const char *key) {
+    const char *str;
+    json_object *o, *o1;
+    pa_prop_type_t type;
+
+    pa_assert(f);
+    pa_assert(key);
+
+    str = pa_proplist_gets(f->plist, key);
+    if (!str)
+        return PA_PROP_TYPE_INVALID;
+
+    o = json_tokener_parse(str);
+    if (is_error(o))
+        return PA_PROP_TYPE_INVALID;
+
+    switch (json_object_get_type(o)) {
+        case json_type_int:
+            type = PA_PROP_TYPE_INT;
+            break;
+
+        case json_type_string:
+            type = PA_PROP_TYPE_STRING;
+            break;
+
+        case json_type_array:
+            if (json_object_array_length(o) == 0) {
+                /* Unlikely, but let's account for this anyway. We need at
+                 * least one element to figure out the array type. */
+                type = PA_PROP_TYPE_INVALID;
+                break;
+            }
+
+            o1 = json_object_array_get_idx(o, 1);
+
+            if (json_object_get_type(o1) == json_type_int)
+                type = PA_PROP_TYPE_INT_ARRAY;
+            else if (json_object_get_type(o1) == json_type_string)
+                type = PA_PROP_TYPE_STRING_ARRAY;
+            else
+                type = PA_PROP_TYPE_INVALID;
+
+            json_object_put(o1);
+            break;
+
+        case json_type_object:
+            /* We actually know at this point that it's a int range, but let's
+             * confirm. */
+            o1 = json_object_object_get(o, PA_JSON_MIN_KEY);
+            if (!o1) {
+                type = PA_PROP_TYPE_INVALID;
+                break;
+            }
+            json_object_put(o1);
+
+            o1 = json_object_object_get(o, PA_JSON_MAX_KEY);
+            if (!o1) {
+                type = PA_PROP_TYPE_INVALID;
+                break;
+            }
+            json_object_put(o1);
+
+            type = PA_PROP_TYPE_INT_RANGE;
+            break;
+
+        default:
+            type = PA_PROP_TYPE_INVALID;
+            break;
+    }
+
+    json_object_put(o);
+    return type;
+}
+
+int pa_format_info_get_prop_int(pa_format_info *f, const char *key, int *v) {
+    const char *str;
+    json_object *o;
+
+    pa_assert(f);
+    pa_assert(key);
+    pa_assert(v);
+
+    str = pa_proplist_gets(f->plist, key);
+    if (!str)
+        return -PA_ERR_NOENTITY;
+
+    o = json_tokener_parse(str);
+    if (is_error(o))
+        return -PA_ERR_INVALID;
+
+    if (json_object_get_type(o) != json_type_int) {
+        json_object_put(o);
+        return -PA_ERR_INVALID;
+    }
+
+    *v = json_object_get_int(o);
+    json_object_put(o);
+
+    return 0;
+}
+
+int pa_format_info_get_prop_int_range(pa_format_info *f, const char *key, int *min, int *max) {
+    const char *str;
+    json_object *o, *o1;
+    int ret = -PA_ERR_INVALID;
+
+    pa_assert(f);
+    pa_assert(key);
+    pa_assert(min);
+    pa_assert(max);
+
+    str = pa_proplist_gets(f->plist, key);
+    if (!str)
+        return -PA_ERR_NOENTITY;
+
+    o = json_tokener_parse(str);
+    if (is_error(o))
+        return -PA_ERR_INVALID;
+
+    if (json_object_get_type(o) != json_type_object)
+        goto out;
+
+    if (!(o1 = json_object_object_get(o, PA_JSON_MIN_KEY)))
+        goto out;
+
+    *min = json_object_get_int(o1);
+    json_object_put(o1);
+
+    if (!(o1 = json_object_object_get(o, PA_JSON_MAX_KEY)))
+        goto out;
+
+    *max = json_object_get_int(o1);
+    json_object_put(o1);
+
+    ret = 0;
+
+out:
+    json_object_put(o);
+    return ret;
+}
+
+int pa_format_info_get_prop_int_array(pa_format_info *f, const char *key, int **values, int *n_values)
+{
+    const char *str;
+    json_object *o, *o1;
+    int i, ret = -PA_ERR_INVALID;
+
+    pa_assert(f);
+    pa_assert(key);
+    pa_assert(values);
+    pa_assert(n_values);
+
+    str = pa_proplist_gets(f->plist, key);
+    if (!str)
+        return -PA_ERR_NOENTITY;
+
+    o = json_tokener_parse(str);
+    if (is_error(o))
+        return -PA_ERR_INVALID;
+
+    if (json_object_get_type(o) != json_type_array)
+        goto out;
+
+    *n_values = json_object_array_length(o);
+    *values = pa_xnew(int, *n_values);
+
+    for (i = 0; i < *n_values; i++) {
+        o1 = json_object_array_get_idx(o, i);
+
+        if (json_object_get_type(o1) != json_type_int) {
+            json_object_put(o1);
+            goto out;
+        }
+
+        (*values)[i] = json_object_get_int(o1);
+        json_object_put(o1);
+    }
+
+    ret = 0;
+
+out:
+    json_object_put(o);
+    return ret;
+}
+
+int pa_format_info_get_prop_string(pa_format_info *f, const char *key, char **v) {
+    const char *str = NULL;
+    json_object *o;
+
+    pa_assert(f);
+    pa_assert(key);
+    pa_assert(v);
+
+    str = pa_proplist_gets(f->plist, key);
+    if (!str)
+        return -PA_ERR_NOENTITY;
+
+    o = json_tokener_parse(str);
+    if (is_error(o))
+        return -PA_ERR_INVALID;
+
+    if (json_object_get_type(o) != json_type_string) {
+        json_object_put(o);
+        return -PA_ERR_INVALID;
+    }
+
+    *v = pa_xstrdup(json_object_get_string(o));
+    json_object_put(o);
+
+    return 0;
+}
+
+int pa_format_info_get_prop_string_array(pa_format_info *f, const char *key, char ***values, int *n_values)
+{
+    const char *str;
+    json_object *o, *o1;
+    int i, ret = -PA_ERR_INVALID;
+
+    pa_assert(f);
+    pa_assert(key);
+    pa_assert(values);
+    pa_assert(n_values);
+
+    str = pa_proplist_gets(f->plist, key);
+    if (!str)
+        return -PA_ERR_NOENTITY;
+
+    o = json_tokener_parse(str);
+    if (is_error(o))
+        return -PA_ERR_INVALID;
+
+    if (json_object_get_type(o) != json_type_array)
+        goto out;
+
+    *n_values = json_object_array_length(o);
+    *values = pa_xnew(char *, *n_values);
+
+    for (i = 0; i < *n_values; i++) {
+        o1 = json_object_array_get_idx(o, i);
+
+        if (json_object_get_type(o1) != json_type_string) {
+            json_object_put(o1);
+            goto out;
+        }
+
+        (*values)[i] = pa_xstrdup(json_object_get_string(o1));
+        json_object_put(o1);
+    }
+
+    ret = 0;
+
+out:
+    json_object_put(o);
+    return ret;
+}
+
+void pa_format_info_free_string_array(char **values, int n_values) {
+    int i;
+
+    for (i = 0; i < n_values; i++)
+        pa_xfree(values[i]);
+
+    pa_xfree(values);
+}
+
+void pa_format_info_set_sample_format(pa_format_info *f, pa_sample_format_t sf) {
+    pa_format_info_set_prop_string(f, PA_PROP_FORMAT_SAMPLE_FORMAT, pa_sample_format_to_string(sf));
+}
+
+void pa_format_info_set_rate(pa_format_info *f, int rate) {
+    pa_format_info_set_prop_int(f, PA_PROP_FORMAT_RATE, rate);
+}
+
+void pa_format_info_set_channels(pa_format_info *f, int channels) {
+    pa_format_info_set_prop_int(f, PA_PROP_FORMAT_CHANNELS, channels);
+}
+
+void pa_format_info_set_channel_map(pa_format_info *f, const pa_channel_map *map) {
+    char map_str[PA_CHANNEL_MAP_SNPRINT_MAX];
+
+    pa_channel_map_snprint(map_str, sizeof(map_str), map);
+
+    pa_format_info_set_prop_string(f, PA_PROP_FORMAT_CHANNEL_MAP, map_str);
+}
+
+void pa_format_info_set_prop_int(pa_format_info *f, const char *key, int value) {
+    json_object *o;
+
+    pa_assert(f);
+    pa_assert(key);
+
+    o = json_object_new_int(value);
+
+    pa_proplist_sets(f->plist, key, json_object_to_json_string(o));
+
+    json_object_put(o);
+}
+
+void pa_format_info_set_prop_int_array(pa_format_info *f, const char *key, const int *values, int n_values) {
+    json_object *o;
+    int i;
+
+    pa_assert(f);
+    pa_assert(key);
+
+    o = json_object_new_array();
+
+    for (i = 0; i < n_values; i++)
+        json_object_array_add(o, json_object_new_int(values[i]));
+
+    pa_proplist_sets(f->plist, key, json_object_to_json_string(o));
+
+    json_object_put(o);
+}
+
+void pa_format_info_set_prop_int_range(pa_format_info *f, const char *key, int min, int max) {
+    json_object *o;
+
+    pa_assert(f);
+    pa_assert(key);
+
+    o = json_object_new_object();
+
+    json_object_object_add(o, PA_JSON_MIN_KEY, json_object_new_int(min));
+    json_object_object_add(o, PA_JSON_MAX_KEY, json_object_new_int(max));
+
+    pa_proplist_sets(f->plist, key, json_object_to_json_string(o));
+
+    json_object_put(o);
+}
+
+void pa_format_info_set_prop_string(pa_format_info *f, const char *key, const char *value) {
+    json_object *o;
+
+    pa_assert(f);
+    pa_assert(key);
+
+    o = json_object_new_string(value);
+
+    pa_proplist_sets(f->plist, key, json_object_to_json_string(o));
+
+    json_object_put(o);
+}
+
+void pa_format_info_set_prop_string_array(pa_format_info *f, const char *key, const char **values, int n_values) {
+    json_object *o;
+    int i;
+
+    pa_assert(f);
+    pa_assert(key);
+
+    o = json_object_new_array();
+
+    for (i = 0; i < n_values; i++)
+        json_object_array_add(o, json_object_new_string(values[i]));
+
+    pa_proplist_sets(f->plist, key, json_object_to_json_string(o));
+
+    json_object_put(o);
+}
+
+static pa_bool_t pa_json_is_fixed_type(json_object *o)
+{
+    switch(json_object_get_type(o)) {
+        case json_type_object:
+        case json_type_array:
+            return FALSE;
+
+        default:
+            return TRUE;
+    }
+}
+
+static int pa_json_value_equal(json_object *o1, json_object *o2) {
+    return (json_object_get_type(o1) == json_object_get_type(o2)) &&
+        pa_streq(json_object_to_json_string(o1), json_object_to_json_string(o2));
+}
+
+static int pa_format_info_prop_compatible(const char *one, const char *two) {
+    json_object *o1 = NULL, *o2 = NULL;
+    int i, ret = 0;
+
+    o1 = json_tokener_parse(one);
+    if (is_error(o1))
+        goto out;
+
+    o2 = json_tokener_parse(two);
+    if (is_error(o2))
+        goto out;
+
+    /* We don't deal with both values being non-fixed - just because there is no immediate need (FIXME) */
+    pa_return_val_if_fail(pa_json_is_fixed_type(o1) || pa_json_is_fixed_type(o2), FALSE);
+
+    if (pa_json_is_fixed_type(o1) && pa_json_is_fixed_type(o2)) {
+        ret = pa_json_value_equal(o1, o2);
+        goto out;
+    }
+
+    if (pa_json_is_fixed_type(o1)) {
+        json_object *tmp = o2;
+        o2 = o1;
+        o1 = tmp;
+    }
+
+    /* o2 is now a fixed type, and o1 is not */
+
+    if (json_object_get_type(o1) == json_type_array) {
+        for (i = 0; i < json_object_array_length(o1); i++) {
+            if (pa_json_value_equal(json_object_array_get_idx(o1, i), o2)) {
+                ret = 1;
+                break;
+            }
+        }
+    } else if (json_object_get_type(o1) == json_type_object) {
+        /* o1 should be a range type */
+        int min, max, v;
+        json_object *o_min = NULL, *o_max = NULL;
+
+        if (json_object_get_type(o2) != json_type_int) {
+            /* We don't support non-integer ranges */
+            goto out;
+        }
+
+        o_min = json_object_object_get(o1, PA_JSON_MIN_KEY);
+        if (!o_min || json_object_get_type(o_min) != json_type_int)
+            goto out;
+
+        o_max = json_object_object_get(o1, PA_JSON_MAX_KEY);
+        if (!o_max || json_object_get_type(o_max) != json_type_int)
+            goto out;
+
+        v = json_object_get_int(o2);
+        min = json_object_get_int(o_min);
+        max = json_object_get_int(o_max);
+
+        ret = v >= min && v <= max;
+    } else {
+        pa_log_warn("Got a format type that we don't support");
+    }
+
+out:
+    if (o1)
+        json_object_put(o1);
+    if (o2)
+        json_object_put(o2);
+
+    return ret;
+}
diff --git a/src/pulse/format.h b/src/pulse/format.h
new file mode 100644 (file)
index 0000000..4184bee
--- /dev/null
@@ -0,0 +1,218 @@
+#ifndef fooformathfoo
+#define fooformathfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2011 Intel Corporation
+  Copyright 2011 Collabora Multimedia
+  Copyright 2011 Arun Raghavan <arun.raghavan@collabora.co.uk>
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <pulse/cdecl.h>
+#include <pulse/gccmacro.h>
+#include <pulse/proplist.h>
+#include <pulse/sample.h>
+#include <pulse/channelmap.h>
+
+/** \file
+ * Utility functions for handling a stream or sink format. */
+
+PA_C_DECL_BEGIN
+
+/** Represents the type of encoding used in a stream or accepted by a sink. \since 1.0 */
+typedef enum pa_encoding {
+    PA_ENCODING_ANY,
+    /**< Any encoding format, PCM or compressed */
+
+    PA_ENCODING_PCM,
+    /**< Any PCM format */
+
+    PA_ENCODING_AC3_IEC61937,
+    /**< AC3 data encapsulated in IEC 61937 header/padding */
+
+    PA_ENCODING_EAC3_IEC61937,
+    /**< EAC3 data encapsulated in IEC 61937 header/padding */
+
+    PA_ENCODING_MPEG_IEC61937,
+    /**< MPEG-1 or MPEG-2 (Part 3, not AAC) data encapsulated in IEC 61937 header/padding */
+
+    PA_ENCODING_DTS_IEC61937,
+    /**< DTS data encapsulated in IEC 61937 header/padding */
+
+    PA_ENCODING_MPEG2_AAC_IEC61937,
+    /**< MPEG-2 AAC data encapsulated in IEC 61937 header/padding. \since 4.0 */
+
+    PA_ENCODING_MAX,
+    /**< Valid encoding types must be less than this value */
+
+    PA_ENCODING_INVALID = -1,
+    /**< Represents an invalid encoding */
+} pa_encoding_t;
+
+/** \cond fulldocs */
+#define PA_ENCODING_ANY PA_ENCODING_ANY
+#define PA_ENCODING_PCM PA_ENCODING_PCM
+#define PA_ENCODING_AC3_IEC61937 PA_ENCODING_AC3_IEC61937
+#define PA_ENCODING_EAC3_IEC61937 PA_ENCODING_EAC3_IEC61937
+#define PA_ENCODING_MPEG_IEC61937 PA_ENCODING_MPEG_IEC61937
+#define PA_ENCODING_DTS_IEC61937 PA_ENCODING_DTS_IEC61937
+#define PA_ENCODING_MPEG2_AAC_IEC61937 PA_ENCODING_MPEG2_AAC_IEC61937
+#define PA_ENCODING_MAX PA_ENCODING_MAX
+#define PA_ENCODING_INVALID PA_ENCODING_INVALID
+/** \endcond */
+
+/** Returns a printable string representing the given encoding type. \since 1.0 */
+const char *pa_encoding_to_string(pa_encoding_t e) PA_GCC_CONST;
+
+/** Converts a string of the form returned by \a pa_encoding_to_string() back to a \a pa_encoding_t. \since 1.0 */
+pa_encoding_t pa_encoding_from_string(const char *encoding);
+
+/** Represents the format of data provided in a stream or processed by a sink. \since 1.0 */
+typedef struct pa_format_info {
+    pa_encoding_t encoding;
+    /**< The encoding used for the format */
+
+    pa_proplist *plist;
+    /**< Additional encoding-specific properties such as sample rate, bitrate, etc. */
+} pa_format_info;
+
+/** Allocates a new \a pa_format_info structure. Clients must initialise at least the encoding field themselves. \since 1.0 */
+pa_format_info* pa_format_info_new(void);
+
+/** Returns a new \a pa_format_info struct and representing the same format as \a src. \since 1.0 */
+pa_format_info* pa_format_info_copy(const pa_format_info *src);
+
+/** Frees a \a pa_format_info structure. \since 1.0 */
+void pa_format_info_free(pa_format_info *f);
+
+/** Returns non-zero when the format info structure is valid. \since 1.0 */
+int pa_format_info_valid(const pa_format_info *f);
+
+/** Returns non-zero when the format info structure represents a PCM (i.e.\ uncompressed data) format. \since 1.0 */
+int pa_format_info_is_pcm(const pa_format_info *f);
+
+/** Returns non-zero if the format represented by \a first is a subset of
+ * the format represented by \a second. This means that \a second must
+ * have all the fields that \a first does, but the reverse need not
+ * be true. This is typically expected to be used to check if a
+ * stream's format is compatible with a given sink. In such a case,
+ * \a first would be the sink's format and \a second would be the
+ * stream's. \since 1.0 */
+int pa_format_info_is_compatible(pa_format_info *first, pa_format_info *second);
+
+/** Maximum required string length for
+ * pa_format_info_snprint(). Please note that this value can change
+ * with any release without warning and without being considered API
+ * or ABI breakage. You should not use this definition anywhere where
+ * it might become part of an ABI. \since 1.0 */
+#define PA_FORMAT_INFO_SNPRINT_MAX 256
+
+/** Return a human-readable string representing the given format. \since 1.0 */
+char *pa_format_info_snprint(char *s, size_t l, const pa_format_info *f);
+
+/** Parse a human-readable string of the form generated by
+ * \a pa_format_info_snprint() into a pa_format_info structure. \since 1.0 */
+pa_format_info* pa_format_info_from_string(const char *str);
+
+/** Utility function to take a \a pa_sample_spec and generate the corresponding \a pa_format_info. \since 2.0 */
+pa_format_info* pa_format_info_from_sample_spec(pa_sample_spec *ss, pa_channel_map *map);
+
+/** Utility function to generate a \a pa_sample_spec and \a pa_channel_map corresponding to a given \a pa_format_info. The
+ * conversion for PCM formats is straight-forward. For non-PCM formats, if there is a fixed size-time conversion (i.e. all
+ * IEC61937-encapsulated formats), a "fake" sample spec whose size-time conversion corresponds to this format is provided and
+ * the channel map argument is ignored. For formats with variable size-time conversion, this function will fail. Returns a
+ * negative integer if conversion failed and 0 on success. \since 2.0 */
+int pa_format_info_to_sample_spec(pa_format_info *f, pa_sample_spec *ss, pa_channel_map *map);
+
+/** Represents the type of value type of a property on a \ref pa_format_info. \since 2.0 */
+typedef enum pa_prop_type_t {
+    PA_PROP_TYPE_INT,
+    /**< Integer property */
+
+    PA_PROP_TYPE_INT_RANGE,
+    /**< Integer range property */
+
+    PA_PROP_TYPE_INT_ARRAY,
+    /**< Integer array property */
+
+    PA_PROP_TYPE_STRING,
+    /**< String property */
+
+    PA_PROP_TYPE_STRING_ARRAY,
+    /**< String array property */
+
+    PA_PROP_TYPE_INVALID = -1,
+    /**< Represents an invalid type */
+} pa_prop_type_t;
+
+/** \cond fulldocs */
+#define PA_PROP_TYPE_INT PA_PROP_TYPE_INT
+#define PA_PROP_TYPE_INT_RANGE PA_PROP_TYPE_INT_RANGE
+#define PA_PROP_TYPE_INT_ARRAY PA_PROP_TYPE_INT_ARRAY
+#define PA_PROP_TYPE_STRING PA_PROP_TYPE_STRING
+#define PA_PROP_TYPE_STRING_ARRAY PA_PROP_TYPE_STRING_ARRAY
+#define PA_PROP_TYPE_INVALID PA_PROP_TYPE_INVALID
+/** \endcond */
+
+/** Gets the type of property \a key in a given \ref pa_format_info. \since 2.0 */
+pa_prop_type_t pa_format_info_get_prop_type(pa_format_info *f, const char *key);
+
+/** Gets an integer property from the given format info. Returns 0 on success and a negative integer on failure. \since 2.0 */
+int pa_format_info_get_prop_int(pa_format_info *f, const char *key, int *v);
+/** Gets an integer range property from the given format info. Returns 0 on success and a negative integer on failure.
+ * \since 2.0 */
+int pa_format_info_get_prop_int_range(pa_format_info *f, const char *key, int *min, int *max);
+/** Gets an integer array property from the given format info. \a values contains the values and \a n_values contains the
+ * number of elements. The caller must free \a values using \ref pa_xfree. Returns 0 on success and a negative integer on
+ * failure. \since 2.0 */
+int pa_format_info_get_prop_int_array(pa_format_info *f, const char *key, int **values, int *n_values);
+/** Gets a string property from the given format info.  The caller must free the returned string using \ref pa_xfree. Returns
+ * 0 on success and a negative integer on failure. \since 2.0 */
+int pa_format_info_get_prop_string(pa_format_info *f, const char *key, char **v);
+/** Gets a string array property from the given format info. \a values contains the values and \a n_values contains
+ * the number of elements. The caller must free \a values using \ref pa_format_info_free_string_array. Returns 0 on success and
+ * a negative integer on failure. \since 2.0 */
+int pa_format_info_get_prop_string_array(pa_format_info *f, const char *key, char ***values, int *n_values);
+
+/** Frees a string array returned by \ref pa_format_info_get_prop_string_array. \since 2.0 */
+void pa_format_info_free_string_array(char **values, int n_values);
+
+/** Sets an integer property on the given format info. \since 1.0 */
+void pa_format_info_set_prop_int(pa_format_info *f, const char *key, int value);
+/** Sets a property with a list of integer values on the given format info. \since 1.0 */
+void pa_format_info_set_prop_int_array(pa_format_info *f, const char *key, const int *values, int n_values);
+/** Sets a property which can have any value in a given integer range on the given format info. \since 1.0 */
+void pa_format_info_set_prop_int_range(pa_format_info *f, const char *key, int min, int max);
+/** Sets a string property on the given format info. \since 1.0 */
+void pa_format_info_set_prop_string(pa_format_info *f, const char *key, const char *value);
+/** Sets a property with a list of string values on the given format info. \since 1.0 */
+void pa_format_info_set_prop_string_array(pa_format_info *f, const char *key, const char **values, int n_values);
+
+/** Convenience method to set the sample format as a property on the given format. \since 1.0 */
+void pa_format_info_set_sample_format(pa_format_info *f, pa_sample_format_t sf);
+/** Convenience method to set the sampling rate as a property on the given format. \since 1.0 */
+void pa_format_info_set_rate(pa_format_info *f, int rate);
+/** Convenience method to set the number of channels as a property on the given format. \since 1.0 */
+void pa_format_info_set_channels(pa_format_info *f, int channels);
+/** Convenience method to set the channel map as a property on the given format. \since 1.0 */
+void pa_format_info_set_channel_map(pa_format_info *f, const pa_channel_map *map);
+
+PA_C_DECL_END
+
+#endif
index 57e8050..e906f59 100644 (file)
 /** \file
  * GCC attribute macros */
 
-#ifdef __GNUC__
+#if defined(__GNUC__)
+#ifdef __MINGW32__
+/* libintl overrides printf with a #define. As this breaks this attribute,
+ * it has a workaround. However the workaround isn't enabled for MINGW
+ * builds (only cygwin) */
+#define PA_GCC_PRINTF_ATTR(a,b) __attribute__ ((format (__printf__, a, b)))
+#else
 #define PA_GCC_PRINTF_ATTR(a,b) __attribute__ ((format (printf, a, b)))
+#endif
 #else
 /** If we're in GNU C, use some magic for detecting invalid format strings */
 #define PA_GCC_PRINTF_ATTR(a,b)
@@ -49,7 +56,7 @@
 #ifdef __GNUC__
 #define PA_GCC_UNUSED __attribute__ ((unused))
 #else
-/** Macro for not used parameter */
+/** Macro for not used function, variable or parameter */
 #define PA_GCC_UNUSED
 #endif
 
 
 #ifndef PA_GCC_WEAKREF
 #if defined(__GNUC__) && defined(__ELF__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ > 1)) || (__GNUC__ > 4))
-/** Macro for usgae of GCC's weakref attribute */
-#define PA_GCC_WEAKREF(x) __attribute__((weakref(#x)));
+/** Macro for usage of GCC's weakref attribute */
+#define PA_GCC_WEAKREF(x) __attribute__((weakref(#x)))
 #endif
 #endif
 
index 6afb7a2..bd24913 100644 (file)
@@ -26,7 +26,6 @@
 #include <pulse/xmalloc.h>
 #include <pulse/timeval.h>
 
-#include <pulsecore/idxset.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/llist.h>
@@ -34,7 +33,7 @@
 #include <glib.h>
 #include "glib-mainloop.h"
 
-struct pa_io_event  {
+struct pa_io_event {
     pa_glib_mainloop *mainloop;
     int dead;
 
@@ -336,7 +335,7 @@ static void glib_time_restart(pa_time_event*e, const struct timeval *tv) {
             e->mainloop->cached_next_time_event = e;
     } else if (e->mainloop->cached_next_time_event == e)
         e->mainloop->cached_next_time_event = NULL;
- }
+}
 
 static void glib_time_free(pa_time_event *e) {
     g_assert(e);
@@ -490,7 +489,7 @@ static gboolean prepare_func(GSource *source, gint *timeout) {
         t = find_next_time_event(g);
         g_assert(t);
 
-        g_source_get_current_time(source, &now);
+        g_get_current_time(&now);
         tvnow.tv_sec = now.tv_sec;
         tvnow.tv_usec = now.tv_usec;
 
@@ -521,7 +520,7 @@ static gboolean check_func(GSource *source) {
         t = find_next_time_event(g);
         g_assert(t);
 
-        g_source_get_current_time(source, &now);
+        g_get_current_time(&now);
         tvnow.tv_sec = now.tv_sec;
         tvnow.tv_usec = now.tv_usec;
 
@@ -566,7 +565,7 @@ static gboolean dispatch_func(GSource *source, GSourceFunc callback, gpointer us
         t = find_next_time_event(g);
         g_assert(t);
 
-        g_source_get_current_time(source, &now);
+        g_get_current_time(&now);
         tvnow.tv_sec = now.tv_sec;
         tvnow.tv_usec = now.tv_usec;
 
index 67aba27..805d746 100644 (file)
  */
 
 /** \file
- * GLIB main loop support */
+ * GLIB main loop support
+ *
+ * See also \subpage glib-mainloop
+ */
 
 PA_C_DECL_BEGIN
 
@@ -57,8 +60,8 @@ pa_glib_mainloop *pa_glib_mainloop_new(GMainContext *c);
 void pa_glib_mainloop_free(pa_glib_mainloop* g);
 
 /** Return the abstract main loop API vtable for the GLIB main loop
-    object. No need of freeing the API as it is owned by the loop and
-    it is destroyed when this dies */
+    object. No need to free the API as it is owned by the loop
+    and is destroyed when the loop is freed. */
 pa_mainloop_api* pa_glib_mainloop_get_api(pa_glib_mainloop *g);
 
 PA_C_DECL_END
index b371bfc..e72e285 100644 (file)
 #include <pulse/operation.h>
 #include <pulse/subscribe.h>
 #include <pulse/ext-device-manager.h>
+#include <pulse/ext-device-restore.h>
 #include <pulse/ext-stream-restore.h>
 
 #include <pulsecore/socket-client.h>
 #include <pulsecore/pstream.h>
 #include <pulsecore/pdispatch.h>
-#include <pulsecore/dynarray.h>
 #include <pulsecore/llist.h>
 #include <pulsecore/native-common.h>
 #include <pulsecore/strlist.h>
@@ -66,7 +66,7 @@ struct pa_context {
     pa_pstream *pstream;
     pa_pdispatch *pdispatch;
 
-    pa_dynarray *record_streams, *playback_streams;
+    pa_hashmap *record_streams, *playback_streams;
     PA_LLIST_HEAD(pa_stream, streams);
     PA_LLIST_HEAD(pa_operation, operations);
 
@@ -91,6 +91,7 @@ struct pa_context {
     pa_bool_t no_fail:1;
     pa_bool_t do_autospawn:1;
     pa_bool_t use_rtclock:1;
+    pa_bool_t filter_added:1;
     pa_spawn_api spawn_api;
 
     pa_strlist *server_list;
@@ -107,6 +108,10 @@ struct pa_context {
         void *userdata;
     } ext_device_manager;
     struct {
+        pa_ext_device_restore_subscribe_cb_t callback;
+        void *userdata;
+    } ext_device_restore;
+    struct {
         pa_ext_stream_restore_subscribe_cb_t callback;
         void *userdata;
     } ext_stream_restore;
@@ -122,6 +127,8 @@ typedef struct pa_index_correction {
     pa_bool_t corrupt:1;
 } pa_index_correction;
 
+#define PA_MAX_FORMATS (PA_ENCODING_MAX)
+
 struct pa_stream {
     PA_REFCNT_DECLARE;
     PA_LLIST_FIELDS(pa_stream);
@@ -137,6 +144,9 @@ struct pa_stream {
 
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
+    uint8_t n_formats;
+    pa_format_info *req_formats[PA_MAX_FORMATS];
+    pa_format_info *format;
 
     pa_proplist *proplist;
 
@@ -159,6 +169,7 @@ struct pa_stream {
     /* playback */
     pa_memblock *write_memblock;
     void *write_data;
+    int64_t latest_underrun_at_index;
 
     /* recording */
     pa_memchunk peek_memchunk;
@@ -223,6 +234,8 @@ struct pa_operation {
     pa_operation_state_t state;
     void *userdata;
     pa_operation_cb_t callback;
+    void *state_userdata;
+    pa_operation_notify_cb_t state_callback;
 
     void *private; /* some operations might need this */
 };
@@ -289,6 +302,7 @@ pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *ta
     PA_FAIL_RETURN_ANY(context, error, NULL)
 
 void pa_ext_device_manager_command(pa_context *c, uint32_t tag, pa_tagstruct *t);
+void pa_ext_device_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t);
 void pa_ext_stream_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t);
 
 pa_bool_t pa_mainloop_is_our_api(pa_mainloop_api*m);
index 100413e..9ca3fd3 100644 (file)
 #include <config.h>
 #endif
 
-#include <string.h>
-
 #include <pulse/context.h>
-#include <pulse/gccmacro.h>
 #include <pulse/xmalloc.h>
+#include <pulse/fork-detect.h>
 
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/pstream-util.h>
 
 #include "internal.h"
-#include "fork-detect.h"
-
 #include "introspect.h"
 
 /*** Statistics ***/
@@ -141,11 +137,16 @@ pa_operation* pa_context_get_server_info(pa_context *c, pa_server_info_cb_t cb,
 static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
     pa_operation *o = userdata;
     int eol = 1;
+    pa_sink_info i;
+    uint32_t j;
 
     pa_assert(pd);
     pa_assert(o);
     pa_assert(PA_REFCNT_VALUE(o) >= 1);
 
+    /* For safety in case someone use fail: outside the while loop below */
+    pa_zero(i);
+
     if (!o->context)
         goto finish;
 
@@ -157,11 +158,9 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, u
     } else {
 
         while (!pa_tagstruct_eof(t)) {
-            pa_sink_info i;
             pa_bool_t mute;
             uint32_t flags;
             uint32_t state;
-            uint32_t j;
             const char *ap = NULL;
 
             pa_zero(i);
@@ -196,9 +195,7 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, u
                 (o->context->version >= 16 &&
                  (pa_tagstruct_getu32(t, &i.n_ports)))) {
 
-                pa_context_fail(o->context, PA_ERR_PROTOCOL);
-                pa_proplist_free(i.proplist);
-                goto finish;
+                goto fail;
             }
 
             if (o->context->version >= 16) {
@@ -207,30 +204,29 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, u
                     i.ports[0] = pa_xnew(pa_sink_port_info, i.n_ports);
 
                     for (j = 0; j < i.n_ports; j++) {
-                        if (pa_tagstruct_gets(t, &i.ports[0][j].name) < 0 ||
-                            pa_tagstruct_gets(t, &i.ports[0][j].description) < 0 ||
-                            pa_tagstruct_getu32(t, &i.ports[0][j].priority) < 0) {
-
-                            pa_context_fail(o->context, PA_ERR_PROTOCOL);
-                            pa_xfree(i.ports[0]);
-                            pa_xfree(i.ports);
-                            pa_proplist_free(i.proplist);
-                            goto finish;
+                        i.ports[j] = &i.ports[0][j];
+
+                        if (pa_tagstruct_gets(t, &i.ports[j]->name) < 0 ||
+                            pa_tagstruct_gets(t, &i.ports[j]->description) < 0 ||
+                            pa_tagstruct_getu32(t, &i.ports[j]->priority) < 0) {
+
+                            goto fail;
                         }
 
-                        i.ports[j] = &i.ports[0][j];
+                        i.ports[j]->available = PA_PORT_AVAILABLE_UNKNOWN;
+                        if (o->context->version >= 24) {
+                            uint32_t av;
+                            if (pa_tagstruct_getu32(t, &av) < 0 || av > PA_PORT_AVAILABLE_YES)
+                                goto fail;
+                            i.ports[j]->available = av;
+                        }
                     }
 
                     i.ports[j] = NULL;
                 }
 
-                if (pa_tagstruct_gets(t, &ap) < 0) {
-                    pa_context_fail(o->context, PA_ERR_PROTOCOL);
-                    pa_xfree(i.ports[0]);
-                    pa_xfree(i.ports);
-                    pa_proplist_free(i.proplist);
-                    goto finish;
-                }
+                if (pa_tagstruct_gets(t, &ap) < 0)
+                    goto fail;
 
                 if (ap) {
                     for (j = 0; j < i.n_ports; j++)
@@ -241,6 +237,22 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, u
                 }
             }
 
+            if (o->context->version >= 21) {
+                uint8_t n_formats;
+                if (pa_tagstruct_getu8(t, &n_formats) < 0 || n_formats < 1)
+                    goto fail;
+
+                i.formats = pa_xnew0(pa_format_info*, n_formats);
+
+                for (j = 0; j < n_formats; j++) {
+                    i.n_formats++;
+                    i.formats[j] = pa_format_info_new();
+
+                    if (pa_tagstruct_get_format_info(t, i.formats[j]) < 0)
+                        goto fail;
+                }
+            }
+
             i.mute = (int) mute;
             i.flags = (pa_sink_flags_t) flags;
             i.state = (pa_sink_state_t) state;
@@ -250,6 +262,11 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, u
                 cb(o->context, &i, 0, o->userdata);
             }
 
+            if (i.formats) {
+                for (j = 0; j < i.n_formats; j++)
+                    pa_format_info_free(i.formats[j]);
+                pa_xfree(i.formats);
+            }
             if (i.ports) {
                 pa_xfree(i.ports[0]);
                 pa_xfree(i.ports);
@@ -266,6 +283,25 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, u
 finish:
     pa_operation_done(o);
     pa_operation_unref(o);
+    return;
+
+fail:
+    pa_assert(i.proplist);
+
+    pa_context_fail(o->context, PA_ERR_PROTOCOL);
+
+    if (i.formats) {
+        for (j = 0; j < i.n_formats; j++)
+            pa_format_info_free(i.formats[j]);
+        pa_xfree(i.formats);
+    }
+    if (i.ports) {
+        pa_xfree(i.ports[0]);
+        pa_xfree(i.ports);
+    }
+    pa_proplist_free(i.proplist);
+
+    goto finish;
 }
 
 pa_operation* pa_context_get_sink_info_list(pa_context *c, pa_sink_info_cb_t cb, void *userdata) {
@@ -374,11 +410,16 @@ pa_operation* pa_context_set_sink_port_by_name(pa_context *c, const char *name,
 static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
     pa_operation *o = userdata;
     int eol = 1;
+    pa_source_info i;
+    uint32_t j;
 
     pa_assert(pd);
     pa_assert(o);
     pa_assert(PA_REFCNT_VALUE(o) >= 1);
 
+    /* For safety in case someone use fail: outside the while loop below */
+    pa_zero(i);
+
     if (!o->context)
         goto finish;
 
@@ -390,11 +431,9 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command,
     } else {
 
         while (!pa_tagstruct_eof(t)) {
-            pa_source_info i;
             pa_bool_t mute;
             uint32_t flags;
             uint32_t state;
-            unsigned j;
             const char *ap;
 
             pa_zero(i);
@@ -429,9 +468,7 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command,
                 (o->context->version >= 16 &&
                  (pa_tagstruct_getu32(t, &i.n_ports)))) {
 
-                pa_context_fail(o->context, PA_ERR_PROTOCOL);
-                pa_proplist_free(i.proplist);
-                goto finish;
+                goto fail;
             }
 
             if (o->context->version >= 16) {
@@ -440,30 +477,29 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command,
                     i.ports[0] = pa_xnew(pa_source_port_info, i.n_ports);
 
                     for (j = 0; j < i.n_ports; j++) {
-                        if (pa_tagstruct_gets(t, &i.ports[0][j].name) < 0 ||
-                            pa_tagstruct_gets(t, &i.ports[0][j].description) < 0 ||
-                            pa_tagstruct_getu32(t, &i.ports[0][j].priority) < 0) {
-
-                            pa_context_fail(o->context, PA_ERR_PROTOCOL);
-                            pa_xfree(i.ports[0]);
-                            pa_xfree(i.ports);
-                            pa_proplist_free(i.proplist);
-                            goto finish;
+                        i.ports[j] = &i.ports[0][j];
+
+                        if (pa_tagstruct_gets(t, &i.ports[j]->name) < 0 ||
+                            pa_tagstruct_gets(t, &i.ports[j]->description) < 0 ||
+                            pa_tagstruct_getu32(t, &i.ports[j]->priority) < 0) {
+
+                            goto fail;
                         }
 
-                        i.ports[j] = &i.ports[0][j];
+                        i.ports[j]->available = PA_PORT_AVAILABLE_UNKNOWN;
+                        if (o->context->version >= 24) {
+                            uint32_t av;
+                            if (pa_tagstruct_getu32(t, &av) < 0 || av > PA_PORT_AVAILABLE_YES)
+                                goto fail;
+                            i.ports[j]->available = av;
+                        }
                     }
 
                     i.ports[j] = NULL;
                 }
 
-                if (pa_tagstruct_gets(t, &ap) < 0) {
-                    pa_context_fail(o->context, PA_ERR_PROTOCOL);
-                    pa_xfree(i.ports[0]);
-                    pa_xfree(i.ports);
-                    pa_proplist_free(i.proplist);
-                    goto finish;
-                }
+                if (pa_tagstruct_gets(t, &ap) < 0)
+                    goto fail;
 
                 if (ap) {
                     for (j = 0; j < i.n_ports; j++)
@@ -474,6 +510,22 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command,
                 }
             }
 
+            if (o->context->version >= 22) {
+                uint8_t n_formats;
+                if (pa_tagstruct_getu8(t, &n_formats) < 0 || n_formats < 1)
+                    goto fail;
+
+                i.formats = pa_xnew0(pa_format_info*, n_formats);
+
+                for (j = 0; j < n_formats; j++) {
+                    i.n_formats++;
+                    i.formats[j] = pa_format_info_new();
+
+                    if (pa_tagstruct_get_format_info(t, i.formats[j]) < 0)
+                        goto fail;
+                }
+            }
+
             i.mute = (int) mute;
             i.flags = (pa_source_flags_t) flags;
             i.state = (pa_source_state_t) state;
@@ -483,6 +535,11 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command,
                 cb(o->context, &i, 0, o->userdata);
             }
 
+            if (i.formats) {
+                for (j = 0; j < i.n_formats; j++)
+                    pa_format_info_free(i.formats[j]);
+                pa_xfree(i.formats);
+            }
             if (i.ports) {
                 pa_xfree(i.ports[0]);
                 pa_xfree(i.ports);
@@ -499,6 +556,25 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command,
 finish:
     pa_operation_done(o);
     pa_operation_unref(o);
+    return;
+
+fail:
+    pa_assert(i.proplist);
+
+    pa_context_fail(o->context, PA_ERR_PROTOCOL);
+
+    if (i.formats) {
+        for (j = 0; j < i.n_formats; j++)
+            pa_format_info_free(i.formats[j]);
+        pa_xfree(i.formats);
+    }
+    if (i.ports) {
+        pa_xfree(i.ports[0]);
+        pa_xfree(i.ports);
+    }
+    pa_proplist_free(i.proplist);
+
+    goto finish;
 }
 
 pa_operation* pa_context_get_source_info_list(pa_context *c, pa_source_info_cb_t cb, void *userdata) {
@@ -687,9 +763,104 @@ pa_operation* pa_context_get_client_info_list(pa_context *c, pa_client_info_cb_t
 
 /*** Card info ***/
 
+static void card_info_free(pa_card_info* i) {
+    if (i->proplist)
+        pa_proplist_free(i->proplist);
+
+    pa_xfree(i->profiles);
+
+    if (i->ports) {
+        uint32_t j;
+
+        for (j = 0; j < i->n_ports; j++) {
+            if (i->ports[j]) {
+                if (i->ports[j]->profiles)
+                    pa_xfree(i->ports[j]->profiles);
+                if (i->ports[j]->proplist)
+                    pa_proplist_free(i->ports[j]->proplist);
+            }
+        }
+
+        pa_xfree(i->ports[0]);
+        pa_xfree(i->ports);
+    }
+}
+
+static int fill_card_port_info(pa_context *context, pa_tagstruct* t, pa_card_info* i) {
+    uint32_t j, k, l;
+
+    if (pa_tagstruct_getu32(t, &i->n_ports) < 0)
+        return -PA_ERR_PROTOCOL;
+
+    if (i->n_ports == 0) {
+        i->ports = NULL;
+        return 0;
+    }
+
+    i->ports = pa_xnew0(pa_card_port_info*, i->n_ports+1);
+    i->ports[0] = pa_xnew0(pa_card_port_info, i->n_ports);
+
+    for (j = 0; j < i->n_ports; j++) {
+        uint8_t direction;
+        uint32_t available;
+        pa_card_port_info* port = i->ports[j] = &i->ports[0][j];
+
+        port->proplist = pa_proplist_new();
+
+        if (pa_tagstruct_gets(t, &port->name) < 0 ||
+            pa_tagstruct_gets(t, &port->description) < 0 ||
+            pa_tagstruct_getu32(t, &port->priority) < 0 ||
+            pa_tagstruct_getu32(t, &available) < 0 ||
+            pa_tagstruct_getu8(t, &direction) < 0 ||
+            pa_tagstruct_get_proplist(t, port->proplist) < 0 ||
+            pa_tagstruct_getu32(t, &port->n_profiles) < 0) {
+
+            return -PA_ERR_PROTOCOL;
+        }
+
+        if (available > PA_PORT_AVAILABLE_YES ||
+            direction > PA_DIRECTION_OUTPUT + PA_DIRECTION_INPUT) {
+
+            return -PA_ERR_PROTOCOL;
+        }
+
+        port->direction = direction;
+        port->available = available;
+
+        if (port->n_profiles > 0) {
+            port->profiles = pa_xnew0(pa_card_profile_info*, i->n_profiles+1);
+
+            for (k = 0; k < port->n_profiles; k++) {
+                const char* profilename;
+
+                if (pa_tagstruct_gets(t, &profilename) < 0)
+                    return -PA_ERR_PROTOCOL;
+
+                for (l = 0; l < i->n_profiles; l++) {
+                    if (pa_streq(i->profiles[l].name, profilename)) {
+                        port->profiles[k] = &i->profiles[l];
+                        break;
+                    }
+                }
+
+                if (l >= i->n_profiles)
+                    return -PA_ERR_PROTOCOL;
+            }
+        }
+        if (context->version >= 27) {
+            if (pa_tagstruct_gets64(t, &port->latency_offset) < 0)
+                return -PA_ERR_PROTOCOL;
+        } else
+            port->latency_offset = 0;
+    }
+
+    return 0;
+}
+
 static void context_get_card_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
     pa_operation *o = userdata;
     int eol = 1;
+    pa_card_info i;
 
     pa_assert(pd);
     pa_assert(o);
@@ -706,7 +877,6 @@ static void context_get_card_info_callback(pa_pdispatch *pd, uint32_t command, u
     } else {
 
         while (!pa_tagstruct_eof(t)) {
-            pa_card_info i;
             uint32_t j;
             const char*ap;
 
@@ -719,6 +889,7 @@ static void context_get_card_info_callback(pa_pdispatch *pd, uint32_t command, u
                 pa_tagstruct_getu32(t, &i.n_profiles) < 0) {
 
                 pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                card_info_free(&i);
                 goto finish;
             }
 
@@ -734,7 +905,7 @@ static void context_get_card_info_callback(pa_pdispatch *pd, uint32_t command, u
                         pa_tagstruct_getu32(t, &i.profiles[j].priority) < 0) {
 
                         pa_context_fail(o->context, PA_ERR_PROTOCOL);
-                        pa_xfree(i.profiles);
+                        card_info_free(&i);
                         goto finish;
                     }
                 }
@@ -750,8 +921,7 @@ static void context_get_card_info_callback(pa_pdispatch *pd, uint32_t command, u
                 pa_tagstruct_get_proplist(t, i.proplist) < 0) {
 
                 pa_context_fail(o->context, PA_ERR_PROTOCOL);
-                pa_xfree(i.profiles);
-                pa_proplist_free(i.proplist);
+                card_info_free(&i);
                 goto finish;
             }
 
@@ -763,13 +933,20 @@ static void context_get_card_info_callback(pa_pdispatch *pd, uint32_t command, u
                     }
             }
 
+            if (o->context->version >= 26) {
+                if (fill_card_port_info(o->context, t, &i) < 0) {
+                    pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                    card_info_free(&i);
+                    goto finish;
+                }
+            }
+
             if (o->callback) {
                 pa_card_info_cb_t cb = (pa_card_info_cb_t) o->callback;
                 cb(o->context, &i, 0, o->userdata);
             }
 
-            pa_proplist_free(i.proplist);
-            pa_xfree(i.profiles);
+            card_info_free(&i);
         }
     }
 
@@ -996,10 +1173,11 @@ static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t comm
 
         while (!pa_tagstruct_eof(t)) {
             pa_sink_input_info i;
-            pa_bool_t mute = FALSE;
+            pa_bool_t mute = FALSE, corked = FALSE, has_volume = FALSE, volume_writable = TRUE;
 
             pa_zero(i);
             i.proplist = pa_proplist_new();
+            i.format = pa_format_info_new();
 
             if (pa_tagstruct_getu32(t, &i.index) < 0 ||
                 pa_tagstruct_gets(t, &i.name) < 0 ||
@@ -1014,14 +1192,22 @@ static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t comm
                 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
                 pa_tagstruct_gets(t, &i.driver) < 0 ||
                 (o->context->version >= 11 && pa_tagstruct_get_boolean(t, &mute) < 0) ||
-                (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0)) {
+                (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0) ||
+                (o->context->version >= 19 && pa_tagstruct_get_boolean(t, &corked) < 0) ||
+                (o->context->version >= 20 && (pa_tagstruct_get_boolean(t, &has_volume) < 0 ||
+                                               pa_tagstruct_get_boolean(t, &volume_writable) < 0)) ||
+                (o->context->version >= 21 && pa_tagstruct_get_format_info(t, i.format) < 0)) {
 
                 pa_context_fail(o->context, PA_ERR_PROTOCOL);
                 pa_proplist_free(i.proplist);
+                pa_format_info_free(i.format);
                 goto finish;
             }
 
             i.mute = (int) mute;
+            i.corked = (int) corked;
+            i.has_volume = (int) has_volume;
+            i.volume_writable = (int) volume_writable;
 
             if (o->callback) {
                 pa_sink_input_info_cb_t cb = (pa_sink_input_info_cb_t) o->callback;
@@ -1029,6 +1215,7 @@ static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t comm
             }
 
             pa_proplist_free(i.proplist);
+            pa_format_info_free(i.format);
         }
     }
 
@@ -1091,9 +1278,11 @@ static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t c
 
         while (!pa_tagstruct_eof(t)) {
             pa_source_output_info i;
+            pa_bool_t mute = FALSE, corked = FALSE, has_volume = FALSE, volume_writable = TRUE;
 
             pa_zero(i);
             i.proplist = pa_proplist_new();
+            i.format = pa_format_info_new();
 
             if (pa_tagstruct_getu32(t, &i.index) < 0 ||
                 pa_tagstruct_gets(t, &i.name) < 0 ||
@@ -1106,19 +1295,32 @@ static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t c
                 pa_tagstruct_get_usec(t, &i.source_usec) < 0 ||
                 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
                 pa_tagstruct_gets(t, &i.driver) < 0 ||
-                (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0)) {
+                (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0) ||
+                (o->context->version >= 19 && pa_tagstruct_get_boolean(t, &corked) < 0) ||
+                (o->context->version >= 22 && (pa_tagstruct_get_cvolume(t, &i.volume) < 0 ||
+                                               pa_tagstruct_get_boolean(t, &mute) < 0 ||
+                                               pa_tagstruct_get_boolean(t, &has_volume) < 0 ||
+                                               pa_tagstruct_get_boolean(t, &volume_writable) < 0 ||
+                                               pa_tagstruct_get_format_info(t, i.format) < 0))) {
 
                 pa_context_fail(o->context, PA_ERR_PROTOCOL);
                 pa_proplist_free(i.proplist);
+                pa_format_info_free(i.format);
                 goto finish;
             }
 
+            i.mute = (int) mute;
+            i.corked = (int) corked;
+            i.has_volume = (int) has_volume;
+            i.volume_writable = (int) volume_writable;
+
             if (o->callback) {
                 pa_source_output_info_cb_t cb = (pa_source_output_info_cb_t) o->callback;
                 cb(o->context, &i, 0, o->userdata);
             }
 
             pa_proplist_free(i.proplist);
+            pa_format_info_free(i.format);
         }
     }
 
@@ -1410,6 +1612,56 @@ pa_operation* pa_context_set_source_mute_by_name(pa_context *c, const char *name
     return o;
 }
 
+pa_operation* pa_context_set_source_output_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) {
+    pa_operation *o;
+    pa_tagstruct *t;
+    uint32_t tag;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+    pa_assert(volume);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 22, PA_ERR_NOTSUPPORTED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_OUTPUT_VOLUME, &tag);
+    pa_tagstruct_putu32(t, idx);
+    pa_tagstruct_put_cvolume(t, volume);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation* pa_context_set_source_output_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata) {
+    pa_operation *o;
+    pa_tagstruct *t;
+    uint32_t tag;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 22, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_OUTPUT_MUTE, &tag);
+    pa_tagstruct_putu32(t, idx);
+    pa_tagstruct_put_boolean(t, mute);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
 /** Sample Cache **/
 
 static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
@@ -1619,6 +1871,33 @@ pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_s
     return command_kill(c, PA_COMMAND_UNLOAD_MODULE, idx, cb, userdata);
 }
 
+pa_operation* pa_context_set_port_latency_offset(pa_context *c, const char *card_name, const char *port_name, int64_t offset, pa_context_success_cb_t cb, void *userdata) {
+    pa_operation *o;
+    pa_tagstruct *t;
+    uint32_t tag;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, card_name && *card_name, PA_ERR_INVALID);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, port_name && *port_name, PA_ERR_INVALID);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 27, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_SET_PORT_LATENCY_OFFSET, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, card_name);
+    pa_tagstruct_puts(t, port_name);
+    pa_tagstruct_puts64(t, offset);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
 /*** Autoload stuff ***/
 
 PA_WARN_REFERENCE(pa_context_get_autoload_info_by_name, "Module auto-loading no longer supported.");
index 68cfc87..a833471 100644 (file)
@@ -32,6 +32,7 @@
 #include <pulse/channelmap.h>
 #include <pulse/volume.h>
 #include <pulse/proplist.h>
+#include <pulse/format.h>
 #include <pulse/version.h>
 
 /** \page introspect Server Query and Control
  *
  * \section query_sec Querying
  *
- * All querying is done through callbacks. This design is necessary to
+ * All querying is done through callbacks. This approach is necessary to
  * maintain an asynchronous design. The client will request the information
  * and some time later, the server will respond with the desired data.
  *
- * Some objects can have multiple entries at the server. When requesting all
+ * Some objects can have multiple instances on the server. When requesting all
  * of these at once, the callback will be called multiple times, once for
  * each object. When the list has been exhausted, the callback will be called
  * without an information structure and the eol parameter set to a positive
  * Note that even if a single object is requested, and not the entire list,
  * the terminating call will still be made.
  *
- * If an error occurs, the callback will be called without and information
+ * If an error occurs, the callback will be invoked without an information
  * structure and eol set to a negative value..
  *
  * Data members in the information structures are only valid during the
  * duration of the callback. If they are required after the callback is
- * finished, a deep copy must be performed.
+ * finished, a deep copy of the information structure must be performed.
  *
  * \subsection server_subsec Server Information
  *
  * The server can be queried about its name, the environment it's running on
  * and the currently active global defaults. Calling
- * pa_context_get_server_info() will get access to a pa_server_info structure
+ * pa_context_get_server_info() provides access to a pa_server_info structure
  * containing all of these.
  *
  * \subsection memstat_subsec Memory Usage
@@ -81,7 +82,7 @@
  * \subsection sinksrc_subsec Sinks and Sources
  *
  * The server can have an arbitrary number of sinks and sources. Each sink
- * and source have both an index and a name associated with it. As such
+ * and source have both an index and a name associated with it. As such,
  * there are three ways to get access to them:
  *
  * \li By index - pa_context_get_sink_info_by_index() /
  *
  * \subsection sinksrc_subsec Sinks and Sources
  *
- * The most common change one would want to do to sinks and sources is to
- * modify the volume of the audio. Identical to how sinks and sources can
+ * The most common change one would want to apply to sinks and sources is to
+ * modify the volume of the audio. Identically to how sinks and sources can
  * be queried, there are two ways of identifying them:
  *
  * \li By index - pa_context_set_sink_volume_by_index() /
  *
  * If an application desires to modify the volume of just a single stream
  * (commonly one of its own streams), this can be done by setting the volume
- * of its associated sink input, using pa_context_set_sink_input_volume().
- *
- * There is no support for modifying the volume of source outputs.
+ * of its associated sink input or source output, using
+ * pa_context_set_sink_input_volume() or pa_context_set_source_output_volume().
  *
  * It is also possible to remove sink inputs and source outputs, terminating
  * the streams associated with them:
  *
  * \subsection client_subsec Clients
  *
- * The only operation supported on clients, is the possibility of kicking
+ * The only operation supported on clients is the possibility of kicking
  * them off the server using pa_context_kill_client().
  */
 
 /** \file
  *
  * Routines for daemon introspection.
+ *
+ * See also \subpage introspect
  */
 
 PA_C_DECL_BEGIN
@@ -199,7 +201,8 @@ PA_C_DECL_BEGIN
 typedef struct pa_sink_port_info {
     const char *name;                   /**< Name of this port */
     const char *description;            /**< Description of this port */
-    uint32_t priority;                  /**< The higher this value is the more useful this port is as a default */
+    uint32_t priority;                  /**< The higher this value is, the more useful this port is as a default. */
+    int available;                      /**< A flags (see #pa_port_available), indicating availability status of this port. \since 2.0 */
 } pa_sink_port_info;
 
 /** Stores information about sinks. Please note that this structure
@@ -211,13 +214,13 @@ typedef struct pa_sink_info {
     const char *description;           /**< Description of this sink */
     pa_sample_spec sample_spec;        /**< Sample spec of this sink */
     pa_channel_map channel_map;        /**< Channel map */
-    uint32_t owner_module;             /**< Index of the owning module of this sink, or PA_INVALID_INDEX */
+    uint32_t owner_module;             /**< Index of the owning module of this sink, or PA_INVALID_INDEX. */
     pa_cvolume volume;                 /**< Volume of the sink */
     int mute;                          /**< Mute switch of the sink */
-    uint32_t monitor_source;           /**< Index of the monitor source connected to this sink */
-    const char *monitor_source_name;   /**< The name of the monitor source */
+    uint32_t monitor_source;           /**< Index of the monitor source connected to this sink. */
+    const char *monitor_source_name;   /**< The name of the monitor source. */
     pa_usec_t latency;                 /**< Length of queued audio in the output buffer. */
-    const char *driver;                /**< Driver name. */
+    const char *driver;                /**< Driver name */
     pa_sink_flags_t flags;             /**< Flags */
     pa_proplist *proplist;             /**< Property list \since 0.9.11 */
     pa_usec_t configured_latency;      /**< The latency this device has been configured to. \since 0.9.11 */
@@ -226,8 +229,10 @@ typedef struct pa_sink_info {
     uint32_t n_volume_steps;           /**< Number of volume steps for sinks which do not support arbitrary volumes. \since 0.9.15 */
     uint32_t card;                     /**< Card index, or PA_INVALID_INDEX. \since 0.9.15 */
     uint32_t n_ports;                  /**< Number of entries in port array \since 0.9.16 */
-    pa_sink_port_info** ports;         /**< Array of available ports, or NULL. Array is terminated by an entry set to NULL. The number of entries is stored in n_ports \since 0.9.16 */
-    pa_sink_port_info* active_port;    /**< Pointer to active port in the array, or NULL \since 0.9.16 */
+    pa_sink_port_info** ports;         /**< Array of available ports, or NULL. Array is terminated by an entry set to NULL. The number of entries is stored in n_ports. \since 0.9.16 */
+    pa_sink_port_info* active_port;    /**< Pointer to active port in the array, or NULL. \since 0.9.16 */
+    uint8_t n_formats;                 /**< Number of formats supported by the sink. \since 1.0 */
+    pa_format_info **formats;          /**< Array of formats supported by the sink. \since 1.0 */
 } pa_sink_info;
 
 /** Callback prototype for pa_context_get_sink_info_by_name() and friends */
@@ -276,7 +281,8 @@ pa_operation* pa_context_set_sink_port_by_name(pa_context *c, const char*name, c
 typedef struct pa_source_port_info {
     const char *name;                   /**< Name of this port */
     const char *description;            /**< Description of this port */
-    uint32_t priority;                  /**< The higher this value is the more useful this port is as a default */
+    uint32_t priority;                  /**< The higher this value is, the more useful this port is as a default. */
+    int available;                      /**< A flags (see #pa_port_available), indicating availability status of this port. \since 2.0 */
 } pa_source_port_info;
 
 /** Stores information about sources. Please note that this structure
@@ -288,11 +294,11 @@ typedef struct pa_source_info {
     const char *description;            /**< Description of this source */
     pa_sample_spec sample_spec;         /**< Sample spec of this source */
     pa_channel_map channel_map;         /**< Channel map */
-    uint32_t owner_module;              /**< Owning module index, or PA_INVALID_INDEX */
+    uint32_t owner_module;              /**< Owning module index, or PA_INVALID_INDEX. */
     pa_cvolume volume;                  /**< Volume of the source */
     int mute;                           /**< Mute switch of the sink */
-    uint32_t monitor_of_sink;           /**< If this is a monitor source the index of the owning sink, otherwise PA_INVALID_INDEX */
-    const char *monitor_of_sink_name;   /**< Name of the owning sink, or PA_INVALID_INDEX */
+    uint32_t monitor_of_sink;           /**< If this is a monitor source, the index of the owning sink, otherwise PA_INVALID_INDEX. */
+    const char *monitor_of_sink_name;   /**< Name of the owning sink, or PA_INVALID_INDEX. */
     pa_usec_t latency;                  /**< Length of filled record buffer of this source. */
     const char *driver;                 /**< Driver name */
     pa_source_flags_t flags;            /**< Flags */
@@ -303,8 +309,10 @@ typedef struct pa_source_info {
     uint32_t n_volume_steps;            /**< Number of volume steps for sources which do not support arbitrary volumes. \since 0.9.15 */
     uint32_t card;                      /**< Card index, or PA_INVALID_INDEX. \since 0.9.15 */
     uint32_t n_ports;                   /**< Number of entries in port array \since 0.9.16 */
-    pa_source_port_info** ports;        /**< Array of available ports, or NULL. Array is terminated by an entry set to NULL. The number of entries is stored in n_ports \since 0.9.16  */
-    pa_source_port_info* active_port;   /**< Pointer to active port in the array, or NULL \since 0.9.16  */
+    pa_source_port_info** ports;        /**< Array of available ports, or NULL. Array is terminated by an entry set to NULL. The number of entries is stored in n_ports. \since 0.9.16  */
+    pa_source_port_info* active_port;   /**< Pointer to active port in the array, or NULL. \since 0.9.16  */
+    uint8_t n_formats;                  /**< Number of formats supported by the source. \since 1.0 */
+    pa_format_info **formats;           /**< Array of formats supported by the source. \since 1.0 */
 } pa_source_info;
 
 /** Callback prototype for pa_context_get_source_info_by_name() and friends */
@@ -334,7 +342,7 @@ pa_operation* pa_context_set_source_mute_by_name(pa_context *c, const char *name
 /** Suspend/Resume a source. \since 0.9.7 */
 pa_operation* pa_context_suspend_source_by_name(pa_context *c, const char *source_name, int suspend, pa_context_success_cb_t cb, void* userdata);
 
-/** Suspend/Resume a source. If idx is PA_INVALID_INDEX all sources will be suspended. \since 0.9.7 */
+/** Suspend/Resume a source. If idx is PA_INVALID_INDEX, all sources will be suspended. \since 0.9.7 */
 pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata);
 
 /** Change the profile of a source. \since 0.9.16 */
@@ -357,7 +365,7 @@ typedef struct pa_server_info {
     const char *server_name;            /**< Server package name (usually "pulseaudio") */
     pa_sample_spec sample_spec;         /**< Default sample specification */
     const char *default_sink_name;      /**< Name of default sink. */
-    const char *default_source_name;    /**< Name of default sink. */
+    const char *default_source_name;    /**< Name of default source. */
     uint32_t cookie;                    /**< A random cookie for identifying this instance of PulseAudio. */
     pa_channel_map channel_map;         /**< Default channel map. \since 0.9.15 */
 } pa_server_info;
@@ -381,12 +389,12 @@ typedef struct pa_module_info {
         *argument;                      /**< Argument string of the module */
     uint32_t n_used;                    /**< Usage counter or PA_INVALID_INDEX */
 /** \cond fulldocs */
-    int auto_unload;                    /**< \deprecated Non-zero if this is an autoloaded module */
+    int auto_unload;                    /**< \deprecated Non-zero if this is an autoloaded module. */
 /** \endcond */
     pa_proplist *proplist;              /**< Property list \since 0.9.15 */
 } pa_module_info;
 
-/** Callback prototype for pa_context_get_module_info() and friends*/
+/** Callback prototype for pa_context_get_module_info() and friends */
 typedef void (*pa_module_info_cb_t) (pa_context *c, const pa_module_info*i, int eol, void *userdata);
 
 /** Get some information about a module by its index */
@@ -414,12 +422,12 @@ pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_s
 typedef struct pa_client_info {
     uint32_t index;                      /**< Index of this client */
     const char *name;                    /**< Name of this client */
-    uint32_t owner_module;               /**< Index of the owning module, or PA_INVALID_INDEX */
+    uint32_t owner_module;               /**< Index of the owning module, or PA_INVALID_INDEX. */
     const char *driver;                  /**< Driver name */
     pa_proplist *proplist;               /**< Property list \since 0.9.11 */
 } pa_client_info;
 
-/** Callback prototype for pa_context_get_client_info() and friends*/
+/** Callback prototype for pa_context_get_client_info() and friends */
 typedef void (*pa_client_info_cb_t) (pa_context *c, const pa_client_info*i, int eol, void *userdata);
 
 /** Get information about a client by its index */
@@ -443,24 +451,41 @@ typedef struct pa_card_profile_info {
     const char *description;            /**< Description of this profile */
     uint32_t n_sinks;                   /**< Number of sinks this profile would create */
     uint32_t n_sources;                 /**< Number of sources this profile would create */
-    uint32_t priority;                  /**< The higher this value is the more useful this profile is as a default */
+    uint32_t priority;                  /**< The higher this value is, the more useful this profile is as a default. */
 } pa_card_profile_info;
 
+/** Stores information about a specific port of a card.  Please
+ * note that this structure can be extended as part of evolutionary
+ * API updates at any time in any new release. \since 2.0 */
+typedef struct pa_card_port_info {
+    const char *name;                   /**< Name of this port */
+    const char *description;            /**< Description of this port */
+    uint32_t priority;                  /**< The higher this value is, the more useful this port is as a default. */
+    int available;                      /**< A #pa_port_available enum, indicating availability status of this port. */
+    int direction;                      /**< A #pa_direction enum, indicating the direction of this port. */
+    uint32_t n_profiles;                /**< Number of entries in profile array */
+    pa_card_profile_info** profiles;    /**< Array of pointers to available profiles, or NULL. Array is terminated by an entry set to NULL. */
+    pa_proplist *proplist;              /**< Property list */
+    int64_t latency_offset;             /**< Latency offset of the port that gets added to the sink/source latency when the port is active. \since 3.0 */
+} pa_card_port_info;
+
 /** Stores information about cards. Please note that this structure
  * can be extended as part of evolutionary API updates at any time in
  * any new release.  \since 0.9.15 */
 typedef struct pa_card_info {
     uint32_t index;                      /**< Index of this card */
     const char *name;                    /**< Name of this card */
-    uint32_t owner_module;               /**< Index of the owning module, or PA_INVALID_INDEX */
+    uint32_t owner_module;               /**< Index of the owning module, or PA_INVALID_INDEX. */
     const char *driver;                  /**< Driver name */
     uint32_t n_profiles;                 /**< Number of entries in profile array */
-    pa_card_profile_info* profiles;      /**< Array of available profile, or NULL. Array is terminated by an entry with name set to NULL. Number of entries is stored in n_profiles */
-    pa_card_profile_info* active_profile; /**< Pointer to active profile in the array, or NULL */
+    pa_card_profile_info* profiles;      /**< Array of available profile, or NULL. Array is terminated by an entry with name set to NULL. Number of entries is stored in n_profiles. */
+    pa_card_profile_info* active_profile; /**< Pointer to active profile in the array, or NULL. */
     pa_proplist *proplist;               /**< Property list */
+    uint32_t n_ports;                    /**< Number of entries in port array */
+    pa_card_port_info **ports;           /**< Array of pointers to ports, or NULL. Array is terminated by an entry set to NULL. */
 } pa_card_info;
 
-/** Callback prototype for pa_context_get_card_info() and friends \since 0.9.15 */
+/** Callback prototype for pa_context_get_card_info_...() \since 0.9.15 */
 typedef void (*pa_card_info_cb_t) (pa_context *c, const pa_card_info*i, int eol, void *userdata);
 
 /** Get information about a card by its index \since 0.9.15 */
@@ -478,6 +503,9 @@ pa_operation* pa_context_set_card_profile_by_index(pa_context *c, uint32_t idx,
 /** Change the profile of a card. \since 0.9.15 */
 pa_operation* pa_context_set_card_profile_by_name(pa_context *c, const char*name, const char*profile, pa_context_success_cb_t cb, void *userdata);
 
+/** Set the latency offset of a port. \since 3.0 */
+pa_operation* pa_context_set_port_latency_offset(pa_context *c, const char *card_name, const char *port_name, int64_t offset, pa_context_success_cb_t cb, void *userdata);
+
 /** @} */
 
 /** @{ \name Sink Inputs */
@@ -488,21 +516,25 @@ pa_operation* pa_context_set_card_profile_by_name(pa_context *c, const char*name
 typedef struct pa_sink_input_info {
     uint32_t index;                      /**< Index of the sink input */
     const char *name;                    /**< Name of the sink input */
-    uint32_t owner_module;               /**< Index of the module this sink input belongs to, or PA_INVALID_INDEX when it does not belong to any module */
-    uint32_t client;                     /**< Index of the client this sink input belongs to, or PA_INVALID_INDEX when it does not belong to any client */
+    uint32_t owner_module;               /**< Index of the module this sink input belongs to, or PA_INVALID_INDEX when it does not belong to any module. */
+    uint32_t client;                     /**< Index of the client this sink input belongs to, or PA_INVALID_INDEX when it does not belong to any client. */
     uint32_t sink;                       /**< Index of the connected sink */
-    pa_sample_spec sample_spec;          /**< The sample specification of the sink input */
+    pa_sample_spec sample_spec;          /**< The sample specification of the sink input. */
     pa_channel_map channel_map;          /**< Channel map */
-    pa_cvolume volume;                   /**< The volume of this sink input */
-    pa_usec_t buffer_usec;               /**< Latency due to buffering in sink input, see pa_latency_info for details */
-    pa_usec_t sink_usec;                 /**< Latency of the sink device, see pa_latency_info for details */
+    pa_cvolume volume;                   /**< The volume of this sink input. */
+    pa_usec_t buffer_usec;               /**< Latency due to buffering in sink input, see pa_timing_info for details. */
+    pa_usec_t sink_usec;                 /**< Latency of the sink device, see pa_timing_info for details. */
     const char *resample_method;         /**< The resampling method used by this sink input. */
     const char *driver;                  /**< Driver name */
     int mute;                            /**< Stream muted \since 0.9.7 */
     pa_proplist *proplist;               /**< Property list \since 0.9.11 */
+    int corked;                          /**< Stream corked \since 1.0 */
+    int has_volume;                      /**< Stream has volume. If not set, then the meaning of this struct's volume member is unspecified. \since 1.0 */
+    int volume_writable;                 /**< The volume can be set. If not set, the volume can still change even though clients can't control the volume. \since 1.0 */
+    pa_format_info *format;              /**< Stream format information. \since 1.0 */
 } pa_sink_input_info;
 
-/** Callback prototype for pa_context_get_sink_input_info() and friends*/
+/** Callback prototype for pa_context_get_sink_input_info() and friends */
 typedef void (*pa_sink_input_info_cb_t) (pa_context *c, const pa_sink_input_info *i, int eol, void *userdata);
 
 /** Get some information about a sink input by its index */
@@ -534,21 +566,27 @@ pa_operation* pa_context_kill_sink_input(pa_context *c, uint32_t idx, pa_context
  * can be extended as part of evolutionary API updates at any time in
  * any new release. */
 typedef struct pa_source_output_info {
-    uint32_t index;                      /**< Index of the sink input */
-    const char *name;                    /**< Name of the sink input */
-    uint32_t owner_module;               /**< Index of the module this sink input belongs to, or PA_INVALID_INDEX when it does not belong to any module */
-    uint32_t client;                     /**< Index of the client this sink input belongs to, or PA_INVALID_INDEX when it does not belong to any client */
+    uint32_t index;                      /**< Index of the source output */
+    const char *name;                    /**< Name of the source output */
+    uint32_t owner_module;               /**< Index of the module this source output belongs to, or PA_INVALID_INDEX when it does not belong to any module. */
+    uint32_t client;                     /**< Index of the client this source output belongs to, or PA_INVALID_INDEX when it does not belong to any client. */
     uint32_t source;                     /**< Index of the connected source */
     pa_sample_spec sample_spec;          /**< The sample specification of the source output */
     pa_channel_map channel_map;          /**< Channel map */
-    pa_usec_t buffer_usec;               /**< Latency due to buffering in the source output, see pa_latency_info for details. */
-    pa_usec_t source_usec;               /**< Latency of the source device, see pa_latency_info for details. */
+    pa_usec_t buffer_usec;               /**< Latency due to buffering in the source output, see pa_timing_info for details. */
+    pa_usec_t source_usec;               /**< Latency of the source device, see pa_timing_info for details. */
     const char *resample_method;         /**< The resampling method used by this source output. */
     const char *driver;                  /**< Driver name */
     pa_proplist *proplist;               /**< Property list \since 0.9.11 */
+    int corked;                          /**< Stream corked \since 1.0 */
+    pa_cvolume volume;                   /**< The volume of this source output \since 1.0 */
+    int mute;                            /**< Stream muted \since 1.0 */
+    int has_volume;                      /**< Stream has volume. If not set, then the meaning of this struct's volume member is unspecified. \since 1.0 */
+    int volume_writable;                 /**< The volume can be set. If not set, the volume can still change even though clients can't control the volume. \since 1.0 */
+    pa_format_info *format;              /**< Stream format information. \since 1.0 */
 } pa_source_output_info;
 
-/** Callback prototype for pa_context_get_source_output_info() and friends*/
+/** Callback prototype for pa_context_get_source_output_info() and friends */
 typedef void (*pa_source_output_info_cb_t) (pa_context *c, const pa_source_output_info *i, int eol, void *userdata);
 
 /** Get information about a source output by its index */
@@ -563,6 +601,12 @@ pa_operation* pa_context_move_source_output_by_name(pa_context *c, uint32_t idx,
 /** Move the specified source output to a different source. \since 0.9.5 */
 pa_operation* pa_context_move_source_output_by_index(pa_context *c, uint32_t idx, uint32_t source_idx, pa_context_success_cb_t cb, void* userdata);
 
+/** Set the volume of a source output stream \since 1.0 */
+pa_operation* pa_context_set_source_output_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata);
+
+/** Set the mute switch of a source output stream \since 1.0 */
+pa_operation* pa_context_set_source_output_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata);
+
 /** Kill a source output. */
 pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_context_success_cb_t cb, void *userdata);
 
@@ -576,8 +620,8 @@ pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_cont
 typedef struct pa_stat_info {
     uint32_t memblock_total;           /**< Currently allocated memory blocks */
     uint32_t memblock_total_size;      /**< Current total size of allocated memory blocks */
-    uint32_t memblock_allocated;       /**< Allocated memory blocks during the whole lifetime of the daemon */
-    uint32_t memblock_allocated_size;  /**< Total size of all memory blocks allocated during the whole lifetime of the daemon */
+    uint32_t memblock_allocated;       /**< Allocated memory blocks during the whole lifetime of the daemon. */
+    uint32_t memblock_allocated_size;  /**< Total size of all memory blocks allocated during the whole lifetime of the daemon. */
     uint32_t scache_size;              /**< Total size of all sample cache entries. */
 } pa_stat_info;
 
index 4b862f9..45539cc 100644 (file)
@@ -26,9 +26,8 @@
 #include <stdlib.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/gccmacro.h>
-#include <pulse/i18n.h>
 
+#include <pulsecore/i18n.h>
 #include <pulsecore/macro.h>
 
 #include "mainloop-api.h"
index aa0d5e7..018ae19 100644 (file)
 ***/
 
 #include <sys/time.h>
-#include <time.h>
 
 #include <pulse/cdecl.h>
-#include <pulse/sample.h>
 #include <pulse/version.h>
 
 /** \file
  * Main loop abstraction layer. Both the PulseAudio core and the
  * PulseAudio client library use a main loop abstraction layer. Due to
  * this it is possible to embed PulseAudio into other
- * applications easily. Two main loop implemenations are
+ * applications easily. Two main loop implementations are
  * currently available:
  * \li A minimal implementation based on the C library's poll() function (See \ref mainloop.h)
  * \li A wrapper around the GLIB main loop. Use this to embed PulseAudio into your GLIB/GTK+/GNOME programs (See \ref glib-mainloop.h)
  *
  * The structure pa_mainloop_api is used as vtable for the main loop abstraction.
  *
- * This mainloop abstraction layer has no direct support for UNIX signals. Generic, mainloop implementation agnostic support is available throught \ref mainloop-signal.h.
+ * This mainloop abstraction layer has no direct support for UNIX signals. Generic, mainloop implementation agnostic support is available through \ref mainloop-signal.h.
  * */
 
 PA_C_DECL_BEGIN
@@ -61,7 +59,7 @@ typedef enum pa_io_event_flags {
 
 /** An opaque IO event source object */
 typedef struct pa_io_event pa_io_event;
-/** An IO event callback protoype \since 0.9.3 */
+/** An IO event callback prototype \since 0.9.3 */
 typedef void (*pa_io_event_cb_t)(pa_mainloop_api*ea, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata);
 /** A IO event destroy callback prototype \ since 0.9.3 */
 typedef void (*pa_io_event_destroy_cb_t)(pa_mainloop_api*a, pa_io_event *e, void *userdata);
@@ -75,13 +73,13 @@ typedef void (*pa_time_event_destroy_cb_t)(pa_mainloop_api*a, pa_time_event *e,
 
 /** An opaque deferred event source object. Events of this type are triggered once in every main loop iteration */
 typedef struct pa_defer_event pa_defer_event;
-/** A defer event callback protoype \since 0.9.3 */
+/** A defer event callback prototype \since 0.9.3 */
 typedef void (*pa_defer_event_cb_t)(pa_mainloop_api*a, pa_defer_event* e, void *userdata);
 /** A defer event destroy callback prototype \ since 0.9.3 */
 typedef void (*pa_defer_event_destroy_cb_t)(pa_mainloop_api*a, pa_defer_event *e, void *userdata);
 
 /** An abstract mainloop API vtable */
-struct pa_mainloop_api  {
+struct pa_mainloop_api {
     /** A pointer to some private, arbitrary data of the main loop implementation */
     void *userdata;
 
@@ -112,7 +110,7 @@ struct pa_mainloop_api  {
     /** Set a function that is called when the deferred event source is destroyed. Use this to free the userdata argument if required */
     void (*defer_set_destroy)(pa_defer_event *e, pa_defer_event_destroy_cb_t cb);
 
-    /** Exit the main loop and return the specfied retval*/
+    /** Exit the main loop and return the specified retval*/
     void (*quit)(pa_mainloop_api*a, int retval);
 };
 
index 3dc7439..89aafcb 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <fcntl.h>
 
 #ifdef HAVE_WINDOWS_H
 #include <windows.h>
 #endif
 
 #include <pulse/xmalloc.h>
-#include <pulse/gccmacro.h>
-#include <pulse/i18n.h>
 
 #include <pulsecore/core-error.h>
 #include <pulsecore/core-util.h>
+#include <pulsecore/i18n.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 
@@ -74,7 +72,8 @@ static void signal_handler(int sig) {
     signal(sig, signal_handler);
 #endif
 
-    pa_write(signal_pipe[1], &sig, sizeof(sig), NULL);
+    /* XXX: If writing fails, there's nothing we can do? */
+    (void) pa_write(signal_pipe[1], &sig, sizeof(sig), NULL);
 
     errno = saved_errno;
 }
@@ -124,15 +123,13 @@ int pa_signal_init(pa_mainloop_api *a) {
     pa_assert(signal_pipe[1] == -1);
     pa_assert(!io_event);
 
-    if (pipe(signal_pipe) < 0) {
+    if (pa_pipe_cloexec(signal_pipe) < 0) {
         pa_log("pipe(): %s", pa_cstrerror(errno));
         return -1;
     }
 
     pa_make_fd_nonblock(signal_pipe[0]);
     pa_make_fd_nonblock(signal_pipe[1]);
-    pa_make_fd_cloexec(signal_pipe[0]);
-    pa_make_fd_cloexec(signal_pipe[1]);
 
     api = a;
 
index 090ac8c..a3d7715 100644 (file)
 #endif
 
 #include <stdio.h>
-#include <signal.h>
 #include <unistd.h>
 #include <stdlib.h>
-#include <string.h>
 #include <fcntl.h>
 #include <errno.h>
 
-#ifdef HAVE_POLL_H
-#include <poll.h>
-#else
-#include <pulsecore/poll.h>
-#endif
-
 #ifndef HAVE_PIPE
 #include <pulsecore/pipe.h>
 #endif
 
-#include <pulse/i18n.h>
 #include <pulse/rtclock.h>
 #include <pulse/timeval.h>
 #include <pulse/xmalloc.h>
 
+#include <pulsecore/poll.h>
 #include <pulsecore/core-rtclock.h>
 #include <pulsecore/core-util.h>
+#include <pulsecore/i18n.h>
 #include <pulsecore/llist.h>
 #include <pulsecore/log.h>
 #include <pulsecore/core-error.h>
-#include <pulsecore/winsock.h>
+#include <pulsecore/socket.h>
 #include <pulsecore/macro.h>
 
 #include "mainloop.h"
@@ -121,7 +114,7 @@ struct pa_mainloop {
     int retval;
     pa_bool_t quit:1;
 
-    pa_bool_t wakeup_requested:1;
+    pa_atomic_t wakeup_requested;
     int wakeup_pipe[2];
     int wakeup_pipe_type;
 
@@ -156,7 +149,7 @@ static pa_io_event_flags_t map_flags_from_libc(short flags) {
 
 /* IO events */
 static pa_io_event* mainloop_io_new(
-        pa_mainloop_api*a,
+        pa_mainloop_api *a,
         int fd,
         pa_io_event_flags_t events,
         pa_io_event_cb_t callback,
@@ -182,26 +175,6 @@ static pa_io_event* mainloop_io_new(
     e->callback = callback;
     e->userdata = userdata;
 
-#ifdef OS_IS_WIN32
-    {
-        fd_set xset;
-        struct timeval tv;
-
-        tv.tv_sec = 0;
-        tv.tv_usec = 0;
-
-        FD_ZERO (&xset);
-        FD_SET (fd, &xset);
-
-        if ((select((SELECT_TYPE_ARG1) fd, NULL, NULL, SELECT_TYPE_ARG234 &xset,
-                    SELECT_TYPE_ARG5 &tv) == -1) &&
-             (WSAGetLastError() == WSAENOTSOCK)) {
-            pa_log_warn("Cannot monitor non-socket file descriptors.");
-            e->dead = TRUE;
-        }
-    }
-#endif
-
     PA_LLIST_PREPEND(pa_io_event, m->io_events, e);
     m->rebuild_pollfds = TRUE;
     m->n_io_events ++;
@@ -249,7 +222,7 @@ static void mainloop_io_set_destroy(pa_io_event *e, pa_io_event_destroy_cb_t cal
 
 /* Defer events */
 static pa_defer_event* mainloop_defer_new(
-        pa_mainloop_api*a,
+        pa_mainloop_api *a,
         pa_defer_event_cb_t callback,
         void *userdata) {
 
@@ -336,7 +309,7 @@ static pa_usec_t make_rt(const struct timeval *tv, pa_bool_t *use_rtclock) {
 }
 
 static pa_time_event* mainloop_time_new(
-        pa_mainloop_api*a,
+        pa_mainloop_api *a,
         const struct timeval *tv,
         pa_time_event_cb_t callback,
         void *userdata) {
@@ -360,7 +333,7 @@ static pa_time_event* mainloop_time_new(
 
     if ((e->enabled = (t != PA_USEC_INVALID))) {
         e->time = t;
-        e->use_rtclock= use_rtclock;
+        e->use_rtclock = use_rtclock;
 
         m->n_enabled_time_events++;
 
@@ -443,7 +416,7 @@ static void mainloop_time_set_destroy(pa_time_event *e, pa_time_event_destroy_cb
 
 /* quit() */
 
-static void mainloop_quit(pa_mainloop_api*a, int retval) {
+static void mainloop_quit(pa_mainloop_api *a, int retval) {
     pa_mainloop *m;
 
     pa_assert(a);
@@ -482,7 +455,7 @@ pa_mainloop *pa_mainloop_new(void) {
 
     m = pa_xnew0(pa_mainloop, 1);
 
-    if (pipe(m->wakeup_pipe) < 0) {
+    if (pa_pipe_cloexec(m->wakeup_pipe) < 0) {
         pa_log_error("ERROR: cannot create wakeup pipe");
         pa_xfree(m);
         return NULL;
@@ -490,8 +463,6 @@ pa_mainloop *pa_mainloop_new(void) {
 
     pa_make_fd_nonblock(m->wakeup_pipe[0]);
     pa_make_fd_nonblock(m->wakeup_pipe[1]);
-    pa_make_fd_cloexec(m->wakeup_pipe[0]);
-    pa_make_fd_cloexec(m->wakeup_pipe[1]);
 
     m->rebuild_pollfds = TRUE;
 
@@ -598,7 +569,7 @@ static void cleanup_defer_events(pa_mainloop *m, pa_bool_t force) {
 }
 
 
-void pa_mainloop_free(pa_mainloopm) {
+void pa_mainloop_free(pa_mainloop *m) {
     pa_assert(m);
 
     cleanup_io_events(m, TRUE);
@@ -640,13 +611,11 @@ static void rebuild_pollfds(pa_mainloop *m) {
     m->n_pollfds = 0;
     p = m->pollfds;
 
-    if (m->wakeup_pipe[0] >= 0) {
-        m->pollfds[0].fd = m->wakeup_pipe[0];
-        m->pollfds[0].events = POLLIN;
-        m->pollfds[0].revents = 0;
-        p++;
-        m->n_pollfds++;
-    }
+    m->pollfds[0].fd = m->wakeup_pipe[0];
+    m->pollfds[0].events = POLLIN;
+    m->pollfds[0].revents = 0;
+    p++;
+    m->n_pollfds++;
 
     PA_LLIST_FOREACH(e, m->io_events) {
         if (e->dead) {
@@ -801,10 +770,11 @@ void pa_mainloop_wakeup(pa_mainloop *m) {
     char c = 'W';
     pa_assert(m);
 
-    if (m->wakeup_pipe[1] >= 0 && m->state == STATE_POLLING) {
-        pa_write(m->wakeup_pipe[1], &c, sizeof(c), &m->wakeup_pipe_type);
-        m->wakeup_requested++;
-    }
+    if (pa_write(m->wakeup_pipe[1], &c, sizeof(c), &m->wakeup_pipe_type) < 0)
+        /* Not much options for recovering from the error. Let's at least log something. */
+        pa_log("pa_write() failed while trying to wake up the mainloop: %s", pa_cstrerror(errno));
+
+    pa_atomic_store(&m->wakeup_requested, TRUE);
 }
 
 static void clear_wakeup(pa_mainloop *m) {
@@ -812,13 +782,9 @@ static void clear_wakeup(pa_mainloop *m) {
 
     pa_assert(m);
 
-    if (m->wakeup_pipe[0] < 0)
-        return;
-
-    if (m->wakeup_requested) {
+    if (pa_atomic_cmpxchg(&m->wakeup_requested, TRUE, FALSE)) {
         while (pa_read(m->wakeup_pipe[0], &c, sizeof(c), &m->wakeup_pipe_type) == sizeof(c))
             ;
-        m->wakeup_requested = 0;
     }
 }
 
@@ -855,10 +821,15 @@ quit:
 }
 
 static int usec_to_timeout(pa_usec_t u) {
+    int timeout;
+
     if (u == PA_USEC_INVALID)
         return -1;
 
-    return (u + PA_USEC_PER_MSEC - 1) / PA_USEC_PER_MSEC;
+    timeout = (u + PA_USEC_PER_MSEC - 1) / PA_USEC_PER_MSEC;
+    pa_assert(timeout >= 0);
+
+    return timeout;
 }
 
 int pa_mainloop_poll(pa_mainloop *m) {
@@ -889,7 +860,7 @@ int pa_mainloop_poll(pa_mainloop *m) {
                     m->prepared_timeout == PA_USEC_INVALID ? NULL : pa_timespec_store(&ts, m->prepared_timeout),
                     NULL);
 #else
-            m->poll_func_ret = poll(
+            m->poll_func_ret = pa_poll(
                     m->pollfds, m->n_pollfds,
                     usec_to_timeout(m->prepared_timeout));
 #endif
@@ -995,7 +966,7 @@ void pa_mainloop_quit(pa_mainloop *m, int retval) {
     pa_mainloop_wakeup(m);
 }
 
-pa_mainloop_api* pa_mainloop_get_api(pa_mainloop*m) {
+pa_mainloop_api* pa_mainloop_get_api(pa_mainloop *m) {
     pa_assert(m);
 
     return &m->api;
@@ -1008,7 +979,7 @@ void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *use
     m->poll_func_userdata = userdata;
 }
 
-pa_bool_t pa_mainloop_is_our_api(pa_mainloop_api*m) {
+pa_bool_t pa_mainloop_is_our_api(pa_mainloop_api *m) {
     pa_assert(m);
 
     return m->io_new == mainloop_io_new;
index 63abd58..19b17fa 100644 (file)
@@ -71,7 +71,10 @@ struct pollfd;
  * function. Using the routines defined herein you may create a simple
  * main loop supporting the generic main loop abstraction layer as
  * defined in \ref mainloop-api.h. This implementation is thread safe
- * as long as you access the main loop object from a single thread only.*/
+ * as long as you access the main loop object from a single thread only.
+ *
+ * See also \subpage mainloop
+ */
 
 /** An opaque main loop object */
 typedef struct pa_mainloop pa_mainloop;
@@ -109,8 +112,8 @@ int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval);
 int pa_mainloop_run(pa_mainloop *m, int *retval);
 
 /** Return the abstract main loop abstraction layer vtable for this
-    main loop. No need of freeing the API as it is owned by the loop
-    and it is destroyed when this dies */
+    main loop. No need to free the API as it is owned by the loop
+    and is destroyed when the loop is freed. */
 pa_mainloop_api* pa_mainloop_get_api(pa_mainloop*m);
 
 /** Shutdown the main loop */
index fe160a3..917a8a9 100644 (file)
@@ -26,6 +26,7 @@
 #include <pulse/xmalloc.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/flist.h>
+#include <pulse/fork-detect.h>
 
 #include "internal.h"
 #include "operation.h"
@@ -39,10 +40,11 @@ pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t cb
     if (!(o = pa_flist_pop(PA_STATIC_FLIST_GET(operations))))
         o = pa_xnew(pa_operation, 1);
 
+    pa_zero(*o);
+
     PA_REFCNT_INIT(o);
     o->context = c;
     o->stream = s;
-    o->private = NULL;
 
     o->state = PA_OPERATION_RUNNING;
     o->callback = cb;
@@ -91,6 +93,8 @@ static void operation_unlink(pa_operation *o) {
     o->stream = NULL;
     o->callback = NULL;
     o->userdata = NULL;
+    o->state_callback = NULL;
+    o->state_userdata = NULL;
 }
 
 static void operation_set_state(pa_operation *o, pa_operation_state_t st) {
@@ -104,6 +108,9 @@ static void operation_set_state(pa_operation *o, pa_operation_state_t st) {
 
     o->state = st;
 
+    if (o->state_callback)
+        o->state_callback(o, o->state_userdata);
+
     if ((o->state == PA_OPERATION_DONE) || (o->state == PA_OPERATION_CANCELED))
         operation_unlink(o);
 
@@ -130,3 +137,17 @@ pa_operation_state_t pa_operation_get_state(pa_operation *o) {
 
     return o->state;
 }
+
+void pa_operation_set_state_callback(pa_operation *o, pa_operation_notify_cb_t cb, void *userdata) {
+    pa_assert(o);
+    pa_assert(PA_REFCNT_VALUE(o) >= 1);
+
+    if (pa_detect_fork())
+        return;
+
+    if (o->state == PA_OPERATION_DONE || o->state == PA_OPERATION_CANCELED)
+        return;
+
+    o->state_callback = cb;
+    o->state_userdata = userdata;
+}
index b6b5691..82e97c9 100644 (file)
@@ -34,6 +34,9 @@ PA_C_DECL_BEGIN
 /** An asynchronous operation object */
 typedef struct pa_operation pa_operation;
 
+/** A callback for operation state changes */
+typedef void (*pa_operation_notify_cb_t) (pa_operation *o, void *userdata);
+
 /** Increase the reference count by one */
 pa_operation *pa_operation_ref(pa_operation *o);
 
@@ -50,6 +53,14 @@ void pa_operation_cancel(pa_operation *o);
 /** Return the current status of the operation */
 pa_operation_state_t pa_operation_get_state(pa_operation *o);
 
+/** Set the callback function that is called when the operation state
+ * changes. Usually this is not necessary, since the functions that
+ * create pa_operation objects already take a callback that is called
+ * when the operation finishes. Registering a state change callback is
+ * mainly useful, if you want to get called back also if the operation
+ * gets cancelled. \since 4.0 */
+void pa_operation_set_state_callback(pa_operation *o, pa_operation_notify_cb_t cb, void *userdata);
+
 PA_C_DECL_END
 
 #endif
index 048b241..abd551b 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <pulse/xmalloc.h>
 #include <pulse/utf8.h>
-#include <pulse/i18n.h>
 
 #include <pulsecore/hashmap.h>
 #include <pulsecore/strbuf.h>
@@ -45,15 +44,15 @@ struct property {
 #define MAKE_HASHMAP(p) ((pa_hashmap*) (p))
 #define MAKE_PROPLIST(p) ((pa_proplist*) (p))
 
-static pa_bool_t property_name_valid(const char *key) {
+int pa_proplist_key_valid(const char *key) {
 
     if (!pa_ascii_valid(key))
-        return FALSE;
+        return 0;
 
     if (strlen(key) <= 0)
-        return FALSE;
+        return 0;
 
-    return TRUE;
+    return 1;
 }
 
 static void property_free(struct property *prop) {
@@ -71,8 +70,7 @@ pa_proplist* pa_proplist_new(void) {
 void pa_proplist_free(pa_proplist* p) {
     pa_assert(p);
 
-    pa_proplist_clear(p);
-    pa_hashmap_free(MAKE_HASHMAP(p), NULL, NULL);
+    pa_hashmap_free(MAKE_HASHMAP(p), (pa_free_cb_t) property_free);
 }
 
 /** Will accept only valid UTF-8 */
@@ -84,7 +82,7 @@ int pa_proplist_sets(pa_proplist *p, const char *key, const char *value) {
     pa_assert(key);
     pa_assert(value);
 
-    if (!property_name_valid(key) || !pa_utf8_valid(value))
+    if (!pa_proplist_key_valid(key) || !pa_utf8_valid(value))
         return -1;
 
     if (!(prop = pa_hashmap_get(MAKE_HASHMAP(p), key))) {
@@ -116,7 +114,7 @@ static int proplist_setn(pa_proplist *p, const char *key, size_t key_length, con
     k = pa_xstrndup(key, key_length);
     v = pa_xstrndup(value, value_length);
 
-    if (!property_name_valid(k) || !pa_utf8_valid(v)) {
+    if (!pa_proplist_key_valid(k) || !pa_utf8_valid(v)) {
         pa_xfree(k);
         pa_xfree(v);
         return -1;
@@ -168,7 +166,7 @@ static int proplist_sethex(pa_proplist *p, const char *key, size_t key_length, c
 
     k = pa_xstrndup(key, key_length);
 
-    if (!property_name_valid(k)) {
+    if (!pa_proplist_key_valid(k)) {
         pa_xfree(k);
         return -1;
     }
@@ -215,7 +213,7 @@ int pa_proplist_setf(pa_proplist *p, const char *key, const char *format, ...) {
     pa_assert(key);
     pa_assert(format);
 
-    if (!property_name_valid(key) || !pa_utf8_valid(format))
+    if (!pa_proplist_key_valid(key) || !pa_utf8_valid(format))
         return -1;
 
     va_start(ap, format);
@@ -253,7 +251,7 @@ int pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t nb
     pa_assert(key);
     pa_assert(data || nbytes == 0);
 
-    if (!property_name_valid(key))
+    if (!pa_proplist_key_valid(key))
         return -1;
 
     if (!(prop = pa_hashmap_get(MAKE_HASHMAP(p), key))) {
@@ -281,7 +279,7 @@ const char *pa_proplist_gets(pa_proplist *p, const char *key) {
     pa_assert(p);
     pa_assert(key);
 
-    if (!property_name_valid(key))
+    if (!pa_proplist_key_valid(key))
         return NULL;
 
     if (!(prop = pa_hashmap_get(MAKE_HASHMAP(p), key)))
@@ -310,7 +308,7 @@ int pa_proplist_get(pa_proplist *p, const char *key, const void **data, size_t *
     pa_assert(data);
     pa_assert(nbytes);
 
-    if (!property_name_valid(key))
+    if (!pa_proplist_key_valid(key))
         return -1;
 
     if (!(prop = pa_hashmap_get(MAKE_HASHMAP(p), key)))
@@ -322,7 +320,7 @@ int pa_proplist_get(pa_proplist *p, const char *key, const void **data, size_t *
     return 0;
 }
 
-void pa_proplist_update(pa_proplist *p, pa_update_mode_t mode, pa_proplist *other) {
+void pa_proplist_update(pa_proplist *p, pa_update_mode_t mode, const pa_proplist *other) {
     struct property *prop;
     void *state = NULL;
 
@@ -333,6 +331,8 @@ void pa_proplist_update(pa_proplist *p, pa_update_mode_t mode, pa_proplist *othe
     if (mode == PA_UPDATE_SET)
         pa_proplist_clear(p);
 
+    /* MAKE_HASHMAP turns the const pointer into a non-const pointer, but
+     * that's ok, because we don't modify the hashmap contents. */
     while ((prop = pa_hashmap_iterate(MAKE_HASHMAP(other), &state, NULL))) {
 
         if (mode == PA_UPDATE_MERGE && pa_proplist_contains(p, prop->key))
@@ -348,7 +348,7 @@ int pa_proplist_unset(pa_proplist *p, const char *key) {
     pa_assert(p);
     pa_assert(key);
 
-    if (!property_name_valid(key))
+    if (!pa_proplist_key_valid(key))
         return -1;
 
     if (!(prop = pa_hashmap_remove(MAKE_HASHMAP(p), key)))
@@ -366,7 +366,7 @@ int pa_proplist_unset_many(pa_proplist *p, const char * const keys[]) {
     pa_assert(keys);
 
     for (k = keys; *k; k++)
-        if (!property_name_valid(*k))
+        if (!pa_proplist_key_valid(*k))
             return -1;
 
     for (k = keys; *k; k++)
@@ -642,7 +642,7 @@ int pa_proplist_contains(pa_proplist *p, const char *key) {
     pa_assert(p);
     pa_assert(key);
 
-    if (!property_name_valid(key))
+    if (!pa_proplist_key_valid(key))
         return -1;
 
     if (!(pa_hashmap_get(MAKE_HASHMAP(p), key)))
@@ -652,22 +652,20 @@ int pa_proplist_contains(pa_proplist *p, const char *key) {
 }
 
 void pa_proplist_clear(pa_proplist *p) {
-    struct property *prop;
     pa_assert(p);
 
-    while ((prop = pa_hashmap_steal_first(MAKE_HASHMAP(p))))
-        property_free(prop);
+    pa_hashmap_remove_all(MAKE_HASHMAP(p), (pa_free_cb_t) property_free);
 }
 
-pa_proplist* pa_proplist_copy(pa_proplist *template) {
-    pa_proplist *p;
+pa_proplist* pa_proplist_copy(const pa_proplist *p) {
+    pa_proplist *copy;
 
-    pa_assert_se(p = pa_proplist_new());
+    pa_assert_se(copy = pa_proplist_new());
 
-    if (template)
-        pa_proplist_update(p, PA_UPDATE_REPLACE, template);
+    if (p)
+        pa_proplist_update(copy, PA_UPDATE_REPLACE, p);
 
-    return p;
+    return copy;
 }
 
 unsigned pa_proplist_size(pa_proplist *p) {
@@ -681,3 +679,32 @@ int pa_proplist_isempty(pa_proplist *p) {
 
     return pa_hashmap_isempty(MAKE_HASHMAP(p));
 }
+
+int pa_proplist_equal(pa_proplist *a, pa_proplist *b) {
+    const void *key = NULL;
+    struct property *a_prop = NULL;
+    struct property *b_prop = NULL;
+    void *state = NULL;
+
+    pa_assert(a);
+    pa_assert(b);
+
+    if (a == b)
+        return 1;
+
+    if (pa_proplist_size(a) != pa_proplist_size(b))
+        return 0;
+
+    while ((a_prop = pa_hashmap_iterate(MAKE_HASHMAP(a), &state, &key))) {
+        if (!(b_prop = pa_hashmap_get(MAKE_HASHMAP(b), key)))
+            return 0;
+
+        if (a_prop->nbytes != b_prop->nbytes)
+            return 0;
+
+        if (memcmp(a_prop->value, b_prop->value, a_prop->nbytes) != 0)
+            return 0;
+    }
+
+    return 1;
+}
index 71a9fd0..50ba7ad 100644 (file)
 #include <pulse/gccmacro.h>
 #include <pulse/version.h>
 
+/** \file
+ * Property list constants and functions */
+
 PA_C_DECL_BEGIN
 
-/** For streams: localized media name, formatted as UTF-8. e.g. "Guns'N'Roses: Civil War".*/
+/** For streams: localized media name, formatted as UTF-8. E.g. "Guns'N'Roses: Civil War".*/
 #define PA_PROP_MEDIA_NAME                     "media.name"
 
-/** For streams: localized media title if applicable, formatted as UTF-8. e.g. "Civil War" */
+/** For streams: localized media title if applicable, formatted as UTF-8. E.g. "Civil War" */
 #define PA_PROP_MEDIA_TITLE                    "media.title"
 
-/** For streams: localized media artist if applicable, formatted as UTF-8. e.g. "Guns'N'Roses" */
+/** For streams: localized media artist if applicable, formatted as UTF-8. E.g. "Guns'N'Roses" */
 #define PA_PROP_MEDIA_ARTIST                   "media.artist"
 
-/** For streams: localized media copyright string if applicable, formatted as UTF-8. e.g. "Evil Record Corp." */
+/** For streams: localized media copyright string if applicable, formatted as UTF-8. E.g. "Evil Record Corp." */
 #define PA_PROP_MEDIA_COPYRIGHT                "media.copyright"
 
-/** For streams: localized media generator software string if applicable, formatted as UTF-8. e.g. "Foocrop AudioFrobnicator" */
+/** For streams: localized media generator software string if applicable, formatted as UTF-8. E.g. "Foocrop AudioFrobnicator" */
 #define PA_PROP_MEDIA_SOFTWARE                 "media.software"
 
-/** For streams: media language if applicable, in standard POSIX format. e.g. "de_DE" */
+/** For streams: media language if applicable, in standard POSIX format. E.g. "de_DE" */
 #define PA_PROP_MEDIA_LANGUAGE                 "media.language"
 
-/** For streams: source filename if applicable, in URI format or local path. e.g. "/home/lennart/music/foobar.ogg" */
+/** For streams: source filename if applicable, in URI format or local path. E.g. "/home/lennart/music/foobar.ogg" */
 #define PA_PROP_MEDIA_FILENAME                 "media.filename"
 
 /** \cond fulldocs */
@@ -56,40 +59,59 @@ PA_C_DECL_BEGIN
 #define PA_PROP_MEDIA_ICON                     "media.icon"
 /** \endcond */
 
-/** For streams: an XDG icon name for the media. e.g. "audio-x-mp3" */
+/** For streams: an XDG icon name for the media. E.g. "audio-x-mp3" */
 #define PA_PROP_MEDIA_ICON_NAME                "media.icon_name"
 
-/** For streams: logic role of this media. One of the strings "video", "music", "game", "event", "phone", "animation", "production", "a11y" */
+/** For streams: logic role of this media. One of the strings "video", "music", "game", "event", "phone", "animation", "production", "a11y", "test" */
 #define PA_PROP_MEDIA_ROLE                     "media.role"
 
+/** For streams: the name of a filter that is desired, e.g.\ "echo-cancel" or "equalizer-sink". PulseAudio may choose to not apply the filter if it does not make sense (for example, applying echo-cancellation on a Bluetooth headset probably does not make sense. \since 1.0 */
+#define PA_PROP_FILTER_WANT                    "filter.want"
+
+/** For streams: the name of a filter that is desired, e.g.\ "echo-cancel" or "equalizer-sink". Differs from PA_PROP_FILTER_WANT in that it forces PulseAudio to apply the filter, regardless of whether PulseAudio thinks it makes sense to do so or not. If this is set, PA_PROP_FILTER_WANT is ignored. In other words, you almost certainly do not want to use this. \since 1.0 */
+#define PA_PROP_FILTER_APPLY                   "filter.apply"
+
+/** For streams: the name of a filter that should specifically suppressed (i.e.\ overrides PA_PROP_FILTER_WANT). Useful for the times that PA_PROP_FILTER_WANT is automatically added (e.g. echo-cancellation for phone streams when $VOIP_APP does it's own, internal AEC) \since 1.0 */
+#define PA_PROP_FILTER_SUPPRESS                "filter.suppress"
+
 /** For streams: logic role of this media. One of the strings "auto", "phone" */
 #define PA_PROP_MEDIA_POLICY                "media.policy"
 
-/** For event sound streams: XDG event sound name. e.g. "message-new-email" (Event sound streams are those with media.role set to "event") */
+/** For streams: the policy to ignore the preset sink rather use a sink picked by module-policy. One of the strings "yes", "no" */
+#define PA_PROP_MEDIA_POLICY_IGNORE_PRESET_SINK  "media.policy.ignore_preset_sink"
+
+#ifdef __TIZEN__
+#define PA_PROP_MEDIA_TIZEN_VOLUME_TYPE        "media.tizen_volume_type"
+#define PA_PROP_MEDIA_TIZEN_GAIN_TYPE          "media.tizen_gain_type"
+#define PA_PROP_MEDIA_TIZEN_FADE_STATUS        "media.tizen_fade_status"
+#define PA_PROP_MEDIA_TIZEN_FADE_RETURN_VOLUME "media.tizen_fade_return_volume"
+#endif
+
+/** For event sound streams: XDG event sound name. e.g.\ "message-new-email" (Event sound streams are those with media.role set to "event") */
 #define PA_PROP_EVENT_ID                       "event.id"
 
-/** For event sound streams: localized human readable one-line description of the event, formatted as UTF-8. e.g. "Email from lennart@example.com received." */
+/** For event sound streams: localized human readable one-line description of the event, formatted as UTF-8. E.g. "Email from lennart@example.com received." */
 #define PA_PROP_EVENT_DESCRIPTION              "event.description"
 
-/** For event sound streams: absolute horizontal mouse position on the screen if the event sound was triggered by a mouse click, integer formatted as text string. e.g. "865" */
+/** For event sound streams: absolute horizontal mouse position on the screen if the event sound was triggered by a mouse click, integer formatted as text string. E.g. "865" */
 #define PA_PROP_EVENT_MOUSE_X                  "event.mouse.x"
 
-/** For event sound streams: absolute vertical mouse position on the screen if the event sound was triggered by a mouse click, integer formatted as text string. e.g. "432" */
+/** For event sound streams: absolute vertical mouse position on the screen if the event sound was triggered by a mouse click, integer formatted as text string. E.g. "432" */
 #define PA_PROP_EVENT_MOUSE_Y                  "event.mouse.y"
 
-/** For event sound streams: relative horizontal mouse position on the screen if the event sound was triggered by a mouse click, float formatted as text string, ranging from 0.0 (left side of the screen) to 1.0 (right side of the screen). e.g. "0.65" */
+/** For event sound streams: relative horizontal mouse position on the screen if the event sound was triggered by a mouse click, float formatted as text string, ranging from 0.0 (left side of the screen) to 1.0 (right side of the screen). E.g. "0.65" */
 #define PA_PROP_EVENT_MOUSE_HPOS               "event.mouse.hpos"
 
-/** For event sound streams: relative vertical mouse position on the screen if the event sound was triggered by a mouse click, float formatted as text string, ranging from 0.0 (top of the screen) to 1.0 (bottom of the screen). e.g. "0.43" */
+/** For event sound streams: relative vertical mouse position on the screen if the event sound was triggered by a mouse click, float formatted as text string, ranging from 0.0 (top of the screen) to 1.0 (bottom of the screen). E.g. "0.43" */
 #define PA_PROP_EVENT_MOUSE_VPOS               "event.mouse.vpos"
 
-/** For event sound streams: mouse button that triggered the event if applicable, integer formatted as string with 0=left, 1=middle, 2=right. e.g. "0" */
+/** For event sound streams: mouse button that triggered the event if applicable, integer formatted as string with 0=left, 1=middle, 2=right. E.g. "0" */
 #define PA_PROP_EVENT_MOUSE_BUTTON             "event.mouse.button"
 
-/** For streams that belong to a window on the screen: localized window title. e.g. "Totem Music Player" */
+/** For streams that belong to a window on the screen: localized window title. E.g. "Totem Music Player" */
 #define PA_PROP_WINDOW_NAME                    "window.name"
 
-/** For streams that belong to a window on the screen: a textual id for identifying a window logically. e.g. "org.gnome.Totem.MainWindow" */
+/** For streams that belong to a window on the screen: a textual id for identifying a window logically. E.g. "org.gnome.Totem.MainWindow" */
 #define PA_PROP_WINDOW_ID                      "window.id"
 
 /** \cond fulldocs */
@@ -97,49 +119,49 @@ PA_C_DECL_BEGIN
 #define PA_PROP_WINDOW_ICON                    "window.icon"
 /** \endcond */
 
-/** For streams that belong to a window on the screen: an XDG icon name for the window. e.g. "totem" */
+/** For streams that belong to a window on the screen: an XDG icon name for the window. E.g. "totem" */
 #define PA_PROP_WINDOW_ICON_NAME               "window.icon_name"
 
-/** For streams that belong to a window on the screen: absolute horizontal window position on the screen, integer formatted as text string. e.g. "865". \since 0.9.17 */
+/** For streams that belong to a window on the screen: absolute horizontal window position on the screen, integer formatted as text string. E.g. "865". \since 0.9.17 */
 #define PA_PROP_WINDOW_X                       "window.x"
 
-/** For streams that belong to a window on the screen: absolute vertical window position on the screen, integer formatted as text string. e.g. "343". \since 0.9.17 */
+/** For streams that belong to a window on the screen: absolute vertical window position on the screen, integer formatted as text string. E.g. "343". \since 0.9.17 */
 #define PA_PROP_WINDOW_Y                       "window.y"
 
 /** For streams that belong to a window on the screen: window width on the screen, integer formatted as text string. e.g. "365". \since 0.9.17 */
 #define PA_PROP_WINDOW_WIDTH                   "window.width"
 
-/** For streams that belong to a window on the screen: window height on the screen, integer formatted as text string. e.g. "643". \since 0.9.17 */
+/** For streams that belong to a window on the screen: window height on the screen, integer formatted as text string. E.g. "643". \since 0.9.17 */
 #define PA_PROP_WINDOW_HEIGHT                  "window.height"
 
-/** For streams that belong to a window on the screen: relative position of the window center on the screen, float formatted as text string, ranging from 0.0 (left side of the screen) to 1.0 (right side of the screen). e.g. "0.65". \since 0.9.17 */
+/** For streams that belong to a window on the screen: relative position of the window center on the screen, float formatted as text string, ranging from 0.0 (left side of the screen) to 1.0 (right side of the screen). E.g. "0.65". \since 0.9.17 */
 #define PA_PROP_WINDOW_HPOS                    "window.hpos"
 
-/** For streams that belong to a window on the screen: relative position of the window center on the screen, float formatted as text string, ranging from 0.0 (top of the screen) to 1.0 (bottom of the screen). e.g. "0.43". \since 0.9.17 */
+/** For streams that belong to a window on the screen: relative position of the window center on the screen, float formatted as text string, ranging from 0.0 (top of the screen) to 1.0 (bottom of the screen). E.g. "0.43". \since 0.9.17 */
 #define PA_PROP_WINDOW_VPOS                    "window.vpos"
 
-/** For streams that belong to a window on the screen: if the windowing system supports multiple desktops, a comma seperated list of indexes of the desktops this window is visible on. If this property is an empty string, it is visible on all desktops (i.e. 'sticky'). The first desktop is 0. e.g. "0,2,3" \since 0.9.18 */
+/** For streams that belong to a window on the screen: if the windowing system supports multiple desktops, a comma separated list of indexes of the desktops this window is visible on. If this property is an empty string, it is visible on all desktops (i.e. 'sticky'). The first desktop is 0. E.g. "0,2,3" \since 0.9.18 */
 #define PA_PROP_WINDOW_DESKTOP                 "window.desktop"
 
-/** For streams that belong to an X11 window on the screen: the X11 display string. e.g. ":0.0" */
+/** For streams that belong to an X11 window on the screen: the X11 display string. E.g. ":0.0" */
 #define PA_PROP_WINDOW_X11_DISPLAY             "window.x11.display"
 
-/** For streams that belong to an X11 window on the screen: the X11 screen the window is on, an integer formatted as string. e.g. "0" */
+/** For streams that belong to an X11 window on the screen: the X11 screen the window is on, an integer formatted as string. E.g. "0" */
 #define PA_PROP_WINDOW_X11_SCREEN              "window.x11.screen"
 
-/** For streams that belong to an X11 window on the screen: the X11 monitor the window is on, an integer formatted as string. e.g. "0" */
+/** For streams that belong to an X11 window on the screen: the X11 monitor the window is on, an integer formatted as string. E.g. "0" */
 #define PA_PROP_WINDOW_X11_MONITOR             "window.x11.monitor"
 
-/** For streams that belong to an X11 window on the screen: the window XID, an integer formatted as string. e.g. "25632" */
+/** For streams that belong to an X11 window on the screen: the window XID, an integer formatted as string. E.g. "25632" */
 #define PA_PROP_WINDOW_X11_XID                 "window.x11.xid"
 
-/** For clients/streams: localized human readable application name. e.g. "Totem Music Player" */
+/** For clients/streams: localized human readable application name. E.g. "Totem Music Player" */
 #define PA_PROP_APPLICATION_NAME               "application.name"
 
-/** For clients/streams: a textual id for identifying an application logically. e.g. "org.gnome.Totem" */
+/** For clients/streams: a textual id for identifying an application logically. E.g. "org.gnome.Totem" */
 #define PA_PROP_APPLICATION_ID                 "application.id"
 
-/** For clients/streams: a version string e.g. "0.6.88" */
+/** For clients/streams: a version string, e.g.\ "0.6.88" */
 #define PA_PROP_APPLICATION_VERSION            "application.version"
 
 /** \cond fulldocs */
@@ -147,55 +169,55 @@ PA_C_DECL_BEGIN
 #define PA_PROP_APPLICATION_ICON               "application.icon"
 /** \endcond */
 
-/** For clients/streams: an XDG icon name for the application. e.g. "totem" */
+/** For clients/streams: an XDG icon name for the application. E.g. "totem" */
 #define PA_PROP_APPLICATION_ICON_NAME          "application.icon_name"
 
-/** For clients/streams: application language if applicable, in standard POSIX format. e.g. "de_DE" */
+/** For clients/streams: application language if applicable, in standard POSIX format. E.g. "de_DE" */
 #define PA_PROP_APPLICATION_LANGUAGE           "application.language"
 
-/** For clients/streams on UNIX: application process PID, an integer formatted as string. e.g. "4711" */
+/** For clients/streams on UNIX: application process PID, an integer formatted as string. E.g. "4711" */
 #define PA_PROP_APPLICATION_PROCESS_ID         "application.process.id"
 
-/** For clients/streams: application process name. e.g. "totem" */
+/** For clients/streams: application process name. E.g. "totem" */
 #define PA_PROP_APPLICATION_PROCESS_BINARY     "application.process.binary"
 
-/** For clients/streams: application user name. e.g. "lennart" */
+/** For clients/streams: application user name. E.g. "lennart" */
 #define PA_PROP_APPLICATION_PROCESS_USER       "application.process.user"
 
-/** For clients/streams: host name the application runs on. e.g. "omega" */
+/** For clients/streams: host name the application runs on. E.g. "omega" */
 #define PA_PROP_APPLICATION_PROCESS_HOST       "application.process.host"
 
-/** For clients/streams: the D-Bus host id the application runs on. e.g. "543679e7b01393ed3e3e650047d78f6e" */
+/** For clients/streams: the D-Bus host id the application runs on. E.g. "543679e7b01393ed3e3e650047d78f6e" */
 #define PA_PROP_APPLICATION_PROCESS_MACHINE_ID "application.process.machine_id"
 
-/** For clients/streams: an id for the login session the application runs in. On Unix the value of $XDG_SESSION_COOKIE. e.g. "543679e7b01393ed3e3e650047d78f6e-1235159798.76193-190367717" */
+/** For clients/streams: an id for the login session the application runs in. On Unix the value of $XDG_SESSION_ID. E.g. "5" */
 #define PA_PROP_APPLICATION_PROCESS_SESSION_ID "application.process.session_id"
 
-/** For devices: device string in the underlying audio layer's format. e.g. "surround51:0" */
+/** For devices: device string in the underlying audio layer's format. E.g. "surround51:0" */
 #define PA_PROP_DEVICE_STRING                  "device.string"
 
-/** For devices: API this device is access with. e.g. "alsa" */
+/** For devices: API this device is access with. E.g. "alsa" */
 #define PA_PROP_DEVICE_API                     "device.api"
 
-/** For devices: localized human readable device one-line description, e.g. "Foobar Industries USB Headset 2000+ Ultra" */
+/** For devices: localized human readable device one-line description. E.g. "Foobar Industries USB Headset 2000+ Ultra" */
 #define PA_PROP_DEVICE_DESCRIPTION             "device.description"
 
-/** For devices: bus path to the device in the OS' format. e.g. "/sys/bus/pci/devices/0000:00:1f.2" */
+/** For devices: bus path to the device in the OS' format. E.g. "/sys/bus/pci/devices/0000:00:1f.2" */
 #define PA_PROP_DEVICE_BUS_PATH                "device.bus_path"
 
-/** For devices: serial number if applicable. e.g. "4711-0815-1234" */
+/** For devices: serial number if applicable. E.g. "4711-0815-1234" */
 #define PA_PROP_DEVICE_SERIAL                  "device.serial"
 
-/** For devices: vendor ID if applicable. e.g. 1274 */
+/** For devices: vendor ID if applicable. E.g. 1274 */
 #define PA_PROP_DEVICE_VENDOR_ID               "device.vendor.id"
 
-/** For devices: vendor name if applicable. e.g. "Foocorp Heavy Industries" */
+/** For devices: vendor name if applicable. E.g. "Foocorp Heavy Industries" */
 #define PA_PROP_DEVICE_VENDOR_NAME             "device.vendor.name"
 
-/** For devices: product ID if applicable. e.g. 4565 */
+/** For devices: product ID if applicable. E.g. 4565 */
 #define PA_PROP_DEVICE_PRODUCT_ID              "device.product.id"
 
-/** For devices: product name if applicable. e.g. "SuperSpeakers 2000 Pro" */
+/** For devices: product name if applicable. E.g. "SuperSpeakers 2000 Pro" */
 #define PA_PROP_DEVICE_PRODUCT_NAME            "device.product.name"
 
 /** For devices: device class. One of "sound", "modem", "monitor", "filter" */
@@ -212,7 +234,7 @@ PA_C_DECL_BEGIN
 #define PA_PROP_DEVICE_ICON                    "device.icon"
 /** \endcond */
 
-/** For devices: an XDG icon name for the device. e.g. "sound-card-speakers-usb" */
+/** For devices: an XDG icon name for the device. E.g. "sound-card-speakers-usb" */
 #define PA_PROP_DEVICE_ICON_NAME               "device.icon_name"
 
 /** For devices: access mode of the device if applicable. One of "mmap", "mmap_rewrite", "serial" */
@@ -227,27 +249,38 @@ PA_C_DECL_BEGIN
 /** For devices: fragment size in bytes, integer formatted as string. */
 #define PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE "device.buffering.fragment_size"
 
-/** For devices: profile identifier for the profile this devices is in. e.g. "analog-stereo", "analog-surround-40", "iec958-stereo", ...*/
+/** For devices: profile identifier for the profile this devices is in. E.g. "analog-stereo", "analog-surround-40", "iec958-stereo", ...*/
 #define PA_PROP_DEVICE_PROFILE_NAME            "device.profile.name"
 
-/** For devices: intended use. A comma seperated list of roles (see PA_PROP_MEDIA_ROLE) this device is particularly well suited for, due to latency, quality or form factor. \since 0.9.16 */
+/** For devices: intended use. A space separated list of roles (see PA_PROP_MEDIA_ROLE) this device is particularly well suited for, due to latency, quality or form factor. \since 0.9.16 */
 #define PA_PROP_DEVICE_INTENDED_ROLES          "device.intended_roles"
 
-/** For devices: human readable one-line description of the profile this device is in. e.g. "Analog Stereo", ... */
+/** For devices: human readable one-line description of the profile this device is in. E.g. "Analog Stereo", ... */
 #define PA_PROP_DEVICE_PROFILE_DESCRIPTION     "device.profile.description"
 
-/** For modules: the author's name, formatted as UTF-8 string. e.g. "Lennart Poettering" */
+/** For modules: the author's name, formatted as UTF-8 string. E.g. "Lennart Poettering" */
 #define PA_PROP_MODULE_AUTHOR                  "module.author"
 
-/** For modules: a human readable one-line description of the module's purpose formatted as UTF-8. e.g. "Frobnicate sounds with a flux compensator" */
+/** For modules: a human readable one-line description of the module's purpose formatted as UTF-8. E.g. "Frobnicate sounds with a flux compensator" */
 #define PA_PROP_MODULE_DESCRIPTION             "module.description"
 
 /** For modules: a human readable usage description of the module's arguments formatted as UTF-8. */
 #define PA_PROP_MODULE_USAGE                   "module.usage"
 
-/** For modules: a version string for the module. e.g. "0.9.15" */
+/** For modules: a version string for the module. E.g. "0.9.15" */
 #define PA_PROP_MODULE_VERSION                 "module.version"
 
+/** For PCM formats: the sample format used as returned by pa_sample_format_to_string() \since 1.0 */
+#define PA_PROP_FORMAT_SAMPLE_FORMAT           "format.sample_format"
+
+/** For all formats: the sample rate (unsigned integer) \since 1.0 */
+#define PA_PROP_FORMAT_RATE                    "format.rate"
+
+/** For all formats: the number of channels (unsigned integer) \since 1.0 */
+#define PA_PROP_FORMAT_CHANNELS                "format.channels"
+
+/** For PCM formats: the channel map of the stream as returned by pa_channel_map_snprint() \since 1.0 */
+#define PA_PROP_FORMAT_CHANNEL_MAP             "format.channel_map"
 
 /** A property list object. Basically a dictionary with ASCII strings
  * as keys and arbitrary data as values. \since 0.9.11 */
@@ -259,6 +292,9 @@ pa_proplist* pa_proplist_new(void);
 /** Free the property list. \since 0.9.11 */
 void pa_proplist_free(pa_proplist* p);
 
+/** Returns a non-zero value if the key is valid. \since 3.0 */
+int pa_proplist_key_valid(const char *key);
+
 /** Append a new string entry to the property list, possibly
  * overwriting an already existing entry with the same key. An
  * internal copy of the data passed is made. Will accept only valid
@@ -291,8 +327,8 @@ int pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t nb
  * the data before accessing the property list again. \since 0.9.11 */
 const char *pa_proplist_gets(pa_proplist *p, const char *key);
 
-/** Return the the value for the specified key. Will return a
- * NUL-terminated string for string entries. The pointer returned will
+/** Store the value for the specified key in \a data. Will store a
+ * NUL-terminated string for string entries. The \a data pointer returned will
  * point to an internally allocated buffer. The caller should make a
  * copy of the data before the property list is accessed again. \since
  * 0.9.11 */
@@ -302,7 +338,7 @@ int pa_proplist_get(pa_proplist *p, const char *key, const void **data, size_t *
 typedef enum pa_update_mode {
     PA_UPDATE_SET
     /**< Replace the entire property list with the new one. Don't keep
-     *  any of the old data around */,
+     *  any of the old data around. */,
 
     PA_UPDATE_MERGE
     /**< Merge new property list into the existing one, not replacing
@@ -323,16 +359,16 @@ typedef enum pa_update_mode {
 
 /** Merge property list "other" into "p", adhering the merge mode as
  * specified in "mode". \since 0.9.11 */
-void pa_proplist_update(pa_proplist *p, pa_update_mode_t mode, pa_proplist *other);
+void pa_proplist_update(pa_proplist *p, pa_update_mode_t mode, const pa_proplist *other);
 
 /** Removes a single entry from the property list, identified be the
  * specified key name. \since 0.9.11 */
 int pa_proplist_unset(pa_proplist *p, const char *key);
 
-/** Similar to pa_proplist_remove() but takes an array of keys to
- * remove. The array should be terminated by a NULL pointer. Return -1
+/** Similar to pa_proplist_unset() but takes an array of keys to
+ * remove. The array should be terminated by a NULL pointer. Returns -1
  * on failure, otherwise the number of entries actually removed (which
- * might even be 0, if there where no matching entries to
+ * might even be 0, if there were no matching entries to
  * remove). \since 0.9.11 */
 int pa_proplist_unset_many(pa_proplist *p, const char * const keys[]);
 
@@ -341,20 +377,20 @@ int pa_proplist_unset_many(pa_proplist *p, const char * const keys[]);
  * to this variable should then be passed to pa_proplist_iterate()
  * which should be called in a loop until it returns NULL which
  * signifies EOL. The property list should not be modified during
- * iteration through the list -- except for deleting the current
- * looked at entry. On each invication this function will return the
+ * iteration through the list -- with the exception of deleting the
+ * current entry. On each invocation this function will return the
  * key string for the next entry. The keys in the property list do not
  * have any particular order. \since 0.9.11 */
 const char *pa_proplist_iterate(pa_proplist *p, void **state);
 
 /** Format the property list nicely as a human readable string. This
  * works very much like pa_proplist_to_string_sep() and uses a newline
- * as seperator and appends one final one. Call pa_xfree() on the
+ * as separator and appends one final one. Call pa_xfree() on the
  * result. \since 0.9.11 */
 char *pa_proplist_to_string(pa_proplist *p);
 
 /** Format the property list nicely as a human readable string and
- * choose the seperator. Call pa_xfree() on the result. \since
+ * choose the separator. Call pa_xfree() on the result. \since
  * 0.9.15 */
 char *pa_proplist_to_string_sep(pa_proplist *p, const char *sep);
 
@@ -362,7 +398,7 @@ char *pa_proplist_to_string_sep(pa_proplist *p, const char *sep);
  * readable string. \since 0.9.15 */
 pa_proplist *pa_proplist_from_string(const char *str);
 
-  /** Returns 1 if an entry for the specified key is existant in the
+/** Returns 1 if an entry for the specified key exists in the
  * property list. \since 0.9.11 */
 int pa_proplist_contains(pa_proplist *p, const char *key);
 
@@ -370,14 +406,18 @@ int pa_proplist_contains(pa_proplist *p, const char *key);
 void pa_proplist_clear(pa_proplist *p);
 
 /** Allocate a new property list and copy over every single entry from
- * the specific list. \since 0.9.11 */
-pa_proplist* pa_proplist_copy(pa_proplist *t);
+ * the specified list. \since 0.9.11 */
+pa_proplist* pa_proplist_copy(const pa_proplist *p);
 
-/** Return the number of entries on the property list. \since 0.9.15 */
-unsigned pa_proplist_size(pa_proplist *t);
+/** Return the number of entries in the property list. \since 0.9.15 */
+unsigned pa_proplist_size(pa_proplist *p);
 
 /** Returns 0 when the proplist is empty, positive otherwise \since 0.9.15 */
-int pa_proplist_isempty(pa_proplist *t);
+int pa_proplist_isempty(pa_proplist *p);
+
+/** Return non-zero when a and b have the same keys and values.
+ * \since 0.9.16 */
+int pa_proplist_equal(pa_proplist *a, pa_proplist *b);
 
 PA_C_DECL_END
 
index 793ba9b..21b7213 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <pulse/mainloop-api.h>
 #include <pulse/sample.h>
+#include <pulse/format.h>
 #include <pulse/def.h>
 #include <pulse/context.h>
 #include <pulse/stream.h>
@@ -84,7 +85,7 @@
  * based style or if you want to use the advanced features of the
  * PulseAudio API. A guide can be found in \subpage async.
  *
- * By using the built-in threaded main loop, it is possible to acheive a
+ * By using the built-in threaded main loop, it is possible to achieve a
  * pseudo-synchronous API, which can be useful in synchronous applications
  * where the simple API is insufficient. See the \ref async page for
  * details.
  * to make sure event objects are not manipulated when any other code is
  * using the main loop.
  *
+ * \section error_sec Error Handling
+ *
+ * Every function should explicitly document how errors are reported to
+ * the caller. Unfortunately, currently a lot of that documentation is
+ * missing. Here is an overview of the general conventions used.
+ *
+ * The PulseAudio API indicates error conditions by returning a negative
+ * integer value or a NULL pointer. On success, zero or a positive integer
+ * value or a valid pointer is returned.
+ *
+ * Functions of the \ref simple generally return -1 or NULL on failure and
+ * can optionally store an error code (see ::pa_error_code) using a pointer
+ * argument.
+ *
+ * Functions of the \ref async return an negative error code or NULL on
+ * failure (see ::pa_error_code). In the later case, pa_context_errno()
+ * can be used to obtain the error code of the last failed operation.
+ *
+ * An error code can be turned into a human readable message using
+ * pa_strerror().
+ *
  * \section pkgconfig pkg-config
  *
  * The PulseAudio libraries provide pkg-config snippets for the different
index 49ff6aa..20dcb9c 100644 (file)
 #include <config.h>
 #endif
 
+#include <sys/time.h>
+
+#include <pulse/timeval.h>
+
 #include <pulsecore/core-rtclock.h>
 
 #include "rtclock.h"
-#include "timeval.h"
 
 pa_usec_t pa_rtclock_now(void) {
     struct timeval tv;
 
     return pa_timeval_load(pa_rtclock_get(&tv));
 }
+
+pa_usec_t pa_rtclock_now_args(pa_usec_t* usec) {
+    struct timeval tv;
+
+    *usec = pa_timeval_load(pa_rtclock_get(&tv));
+
+    return *usec;
+}
index 6459d92..347f277 100644 (file)
@@ -23,8 +23,7 @@
 ***/
 
 #include <pulse/cdecl.h>
-#include <pulse/def.h>
-#include <pulse/gccmacro.h>
+#include <pulse/sample.h>
 
 /** \file
  *  Monotonic clock utilities. */
@@ -35,6 +34,7 @@ PA_C_DECL_BEGIN
  * is available.  If it is not available this will return the
  * wallclock time instead.  \since 0.9.16 */
 pa_usec_t pa_rtclock_now(void);
+pa_usec_t pa_rtclock_now_args(pa_usec_t* usec);
 
 PA_C_DECL_END
 
index 9698d8a..b613612 100644 (file)
 #endif
 
 #include <stdio.h>
-#include <math.h>
 #include <string.h>
 
 #include <pulse/timeval.h>
-#include <pulse/i18n.h>
 
 #include <pulsecore/core-util.h>
+#include <pulsecore/i18n.h>
 #include <pulsecore/macro.h>
 
 #include "sample.h"
@@ -242,7 +241,7 @@ pa_sample_format_t pa_parse_sample_format(const char *format) {
     else if (strcasecmp(format, "s24-32re") == 0)
         return PA_SAMPLE_S24_32RE;
 
-    return -1;
+    return PA_SAMPLE_INVALID;
 }
 
 int pa_sample_format_is_le(pa_sample_format_t f) {
index 7a4a55a..9eb4df0 100644 (file)
@@ -26,7 +26,6 @@
 #include <inttypes.h>
 #include <sys/types.h>
 #include <sys/param.h>
-#include <math.h>
 
 #include <pulse/gccmacro.h>
 #include <pulse/cdecl.h>
@@ -72,7 +71,7 @@
  * \section chan_sec Channels
  *
  * PulseAudio supports up to 32 individual channels. The order of the
- * channels is up to the application, but they must be continous. To map
+ * channels is up to the application, but they must be continuous. To map
  * channels to speakers, see \ref channelmap.
  *
  * \section calc_sec Calculations
  */
 
 /** \file
- * Constants and routines for sample type handling */
+ * Constants and routines for sample type handling
+ *
+ * See also \subpage sample
+ */
 
 PA_C_DECL_BEGIN
 
 #if !defined(WORDS_BIGENDIAN)
+
 #if defined(__BYTE_ORDER)
 #if __BYTE_ORDER == __BIG_ENDIAN
 #define WORDS_BIGENDIAN
 #endif
 #endif
+
+/* On Sparc, WORDS_BIGENDIAN needs to be set if _BIG_ENDIAN is defined. */
+#ifdef _BIG_ENDIAN
+#define WORDS_BIGENDIAN
+#endif
+
 #endif
 
 /** Maximum number of allowed channels */
@@ -309,15 +318,15 @@ char* pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec);
  * ABI. \since 0.9.16 */
 #define PA_BYTES_SNPRINT_MAX 11
 
-/** Pretty print a byte size value. (i.e. "2.5 MiB") */
+/** Pretty print a byte size value (i.e.\ "2.5 MiB") */
 char* pa_bytes_snprint(char *s, size_t l, unsigned v);
 
 /** Return 1 when the specified format is little endian, return -1
- * when endianess does not apply to this format. \since 0.9.16 */
+ * when endianness does not apply to this format. \since 0.9.16 */
 int pa_sample_format_is_le(pa_sample_format_t f) PA_GCC_PURE;
 
 /** Return 1 when the specified format is big endian, return -1 when
- * endianess does not apply to this format. \since 0.9.16 */
+ * endianness does not apply to this format. \since 0.9.16 */
 int pa_sample_format_is_be(pa_sample_format_t f) PA_GCC_PURE;
 
 #ifdef WORDS_BIGENDIAN
@@ -325,10 +334,10 @@ int pa_sample_format_is_be(pa_sample_format_t f) PA_GCC_PURE;
 #define pa_sample_format_is_re(f) pa_sample_format_is_le(f)
 #else
 /** Return 1 when the specified format is native endian, return -1
- * when endianess does not apply to this format. \since 0.9.16 */
+ * when endianness does not apply to this format. \since 0.9.16 */
 #define pa_sample_format_is_ne(f) pa_sample_format_is_le(f)
 /** Return 1 when the specified format is reverse endian, return -1
- * when endianess does not apply to this format. \since 0.9.16 */
+ * when endianness does not apply to this format. \since 0.9.16 */
 #define pa_sample_format_is_re(f) pa_sample_format_is_be(f)
 #endif
 
index 27da688..3fad82a 100644 (file)
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <string.h>
 
 #include <pulse/utf8.h>
+#include <pulse/fork-detect.h>
 
 #include <pulsecore/pstream-util.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/proplist-util.h>
 
 #include "internal.h"
-
 #include "scache.h"
 
 int pa_stream_connect_upload(pa_stream *s, size_t length) {
@@ -45,9 +44,11 @@ int pa_stream_connect_upload(pa_stream *s, size_t length) {
     pa_assert(s);
     pa_assert(PA_REFCNT_VALUE(s) >= 1);
 
+    PA_CHECK_VALIDITY(s->context, !pa_detect_fork(), PA_ERR_FORKED);
     PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_UNCONNECTED, PA_ERR_BADSTATE);
     PA_CHECK_VALIDITY(s->context, length > 0, PA_ERR_INVALID);
     PA_CHECK_VALIDITY(s->context, length == (size_t) (uint32_t) length, PA_ERR_INVALID);
+    PA_CHECK_VALIDITY(s->context, s->context->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
 
     if (!(name = pa_proplist_gets(s->proplist, PA_PROP_EVENT_ID)))
         name = pa_proplist_gets(s->proplist, PA_PROP_MEDIA_NAME);
@@ -85,6 +86,7 @@ int pa_stream_finish_upload(pa_stream *s) {
     pa_assert(s);
     pa_assert(PA_REFCNT_VALUE(s) >= 1);
 
+    PA_CHECK_VALIDITY(s->context, !pa_detect_fork(), PA_ERR_FORKED);
     PA_CHECK_VALIDITY(s->context, s->channel_valid, PA_ERR_BADSTATE);
     PA_CHECK_VALIDITY(s->context, s->context->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
 
@@ -174,6 +176,7 @@ pa_operation *pa_context_play_sample(pa_context *c, const char *name, const char
     pa_assert(c);
     pa_assert(PA_REFCNT_VALUE(c) >= 1);
 
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
     PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
     PA_CHECK_VALIDITY_RETURN_NULL(c, !dev || *dev, PA_ERR_INVALID);
@@ -187,7 +190,7 @@ pa_operation *pa_context_play_sample(pa_context *c, const char *name, const char
     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
     pa_tagstruct_puts(t, dev);
 
-    if (volume == PA_VOLUME_INVALID && c->version < 15)
+    if (!PA_VOLUME_IS_VALID(volume) && c->version < 15)
         volume = PA_VOLUME_NORM;
 
     pa_tagstruct_putu32(t, volume);
@@ -213,6 +216,7 @@ pa_operation *pa_context_play_sample_with_proplist(pa_context *c, const char *na
     pa_assert(c);
     pa_assert(PA_REFCNT_VALUE(c) >= 1);
 
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
     PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
     PA_CHECK_VALIDITY_RETURN_NULL(c, !dev || *dev, PA_ERR_INVALID);
@@ -227,7 +231,7 @@ pa_operation *pa_context_play_sample_with_proplist(pa_context *c, const char *na
     pa_tagstruct_putu32(t, PA_INVALID_INDEX);
     pa_tagstruct_puts(t, dev);
 
-    if (volume == PA_VOLUME_INVALID && c->version < 15)
+    if (!PA_VOLUME_IS_VALID(volume) && c->version < 15)
         volume = PA_VOLUME_NORM;
 
     pa_tagstruct_putu32(t, volume);
@@ -255,6 +259,7 @@ pa_operation* pa_context_remove_sample(pa_context *c, const char *name, pa_conte
     pa_assert(c);
     pa_assert(PA_REFCNT_VALUE(c) >= 1);
 
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
     PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
     PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID);
 
index 31cf7b0..b4fcbd0 100644 (file)
  */
 
 /** \file
- * All sample cache related routines */
+ * All sample cache related routines
+ *
+ * See also \subpage scache
+ */
 
 PA_C_DECL_BEGIN
 
old mode 100644 (file)
new mode 100755 (executable)
index be4f62f..c704159
@@ -335,7 +335,9 @@ pa_simple* pa_simple_new_proplist(
         r = pa_stream_connect_playback(p->stream, dev, attr,
                                        PA_STREAM_INTERPOLATE_TIMING
                                        |PA_STREAM_ADJUST_LATENCY
-                                       |PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);
+                                       |PA_STREAM_AUTO_TIMING_UPDATE
+                                       |PA_STREAM_START_MUTED
+                                       , NULL, NULL);
     else
         r = pa_stream_connect_record(p->stream, dev, attr,
                                      PA_STREAM_INTERPOLATE_TIMING
@@ -407,6 +409,9 @@ int pa_simple_write(pa_simple *p, const void*data, size_t length, int *rerror) {
     CHECK_VALIDITY_RETURN_ANY(rerror, length > 0, PA_ERR_INVALID, -1);
 
     pa_threaded_mainloop_lock(p->mainloop);
+#ifdef MUTEX_LOCK_COUNT
+    mutex_lock_count++;
+#endif
 
     CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
 
@@ -432,10 +437,16 @@ int pa_simple_write(pa_simple *p, const void*data, size_t length, int *rerror) {
     }
 
     pa_threaded_mainloop_unlock(p->mainloop);
+#ifdef MUTEX_LOCK_COUNT
+    mutex_lock_count--;
+#endif
     return 0;
 
 unlock_and_fail:
     pa_threaded_mainloop_unlock(p->mainloop);
+#ifdef MUTEX_LOCK_COUNT
+    mutex_lock_count--;
+#endif
     return -1;
 }
 
@@ -459,9 +470,14 @@ int pa_simple_read(pa_simple *p, void*data, size_t length, int *rerror) {
             r = pa_stream_peek(p->stream, &p->read_data, &p->read_length);
             CHECK_SUCCESS_GOTO(p, rerror, r == 0, unlock_and_fail);
 
-            if (!p->read_data) {
+            if (p->read_length <= 0) {
                 pa_threaded_mainloop_wait(p->mainloop);
                 CHECK_DEAD_GOTO(p, rerror, unlock_and_fail);
+            } else if (!p->read_data) {
+                /* There's a hole in the stream, skip it. We could generate
+                 * silence, but that wouldn't work for compressed streams. */
+                r = pa_stream_drop(p->stream);
+                CHECK_SUCCESS_GOTO(p, rerror, r == 0, unlock_and_fail);
             } else
                 p->read_index = 0;
         }
@@ -617,6 +633,7 @@ unlock_and_fail:
     return -1;
 }
 
+#ifdef __TIZEN__
 int pa_simple_get_stream_index(pa_simple *p, unsigned int *idx, int *rerror) {
     pa_assert(p);
     CHECK_VALIDITY_RETURN_ANY(rerror, idx != NULL, PA_ERR_INVALID, -1);
@@ -683,6 +700,7 @@ unlock_and_fail:
     pa_threaded_mainloop_unlock(p->mainloop);
     return -1;
 }
+#endif
 
 pa_usec_t pa_simple_get_latency(pa_simple *p, int *rerror) {
     pa_usec_t t;
@@ -714,6 +732,32 @@ unlock_and_fail:
     return (pa_usec_t) -1;
 }
 
+pa_usec_t pa_simple_get_final_latency(pa_simple *p, int *rerror) {
+       pa_usec_t t;
+
+       pa_assert(p);
+
+       CHECK_DEAD_GOTO(p, rerror, fail);
+
+       if (p->context->version >= 13) {
+               if (p->direction == PA_STREAM_PLAYBACK) {
+                       t = (pa_bytes_to_usec(p->stream->buffer_attr.tlength, &p->stream->sample_spec) + p->stream->timing_info.configured_sink_usec);
+               } else if (p->direction == PA_STREAM_RECORD) {
+                       t = (pa_bytes_to_usec(p->stream->buffer_attr.fragsize, &p->stream->sample_spec) + p->stream->timing_info.configured_source_usec);
+               } else {
+                       t = (pa_usec_t) -1;
+               }
+       } else {
+               t = (pa_usec_t) -1;
+       }
+
+       return t;
+
+fail:
+       return (pa_usec_t) -1;
+}
+
+#ifdef __TIZEN__
 int pa_simple_cork(pa_simple *p, int cork, int *rerror) {
     pa_operation *o = NULL;
 
@@ -760,3 +804,4 @@ int pa_simple_is_corked(pa_simple *p) {
 
     return is_cork;
 }
+#endif
index 2872178..be924af 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef foosimplehfoo
 #define foosimplehfoo
-
+#define MUTEX_LOCK_COUNT
 /***
   This file is part of PulseAudio.
 
@@ -39,9 +39,9 @@
  *
  * The simple API is designed for applications with very basic sound
  * playback or capture needs. It can only support a single stream per
- * connection and has no handling of complex features like events, channel
- * mappings and volume control. It is, however, very simple to use and
- * quite sufficent for many programs.
+ * connection and has no support for handling of complex features like
+ * events, channel mappings and volume control. It is, however, very simple
+ * to use and quite sufficient for many programs.
  *
  * \section conn_sec Connecting
  *
@@ -75,7 +75,7 @@
  *
  * Once the connection is established to the server, data can start flowing.
  * Using the connection is very similar to the normal read() and write()
- * system calls. The main difference is that they're call pa_simple_read()
+ * system calls. The main difference is that they're called pa_simple_read()
  * and pa_simple_write(). Note that these operations always block.
  *
  * \section ctrl_sec Buffer control
@@ -84,8 +84,8 @@
  *
  * \li pa_simple_drain() - Will wait for all sent data to finish playing.
  * \li pa_simple_flush() - Will throw away all data currently in buffers.
- * \li pa_simple_get_playback_latency() - Will return the total latency of
- *                                        the playback pipeline.
+ * \li pa_simple_get_latency() - Will return the total latency of
+ *                               the playback pipeline.
  *
  * \section cleanup_sec Cleanup
  *
 /** \file
  * A simple but limited synchronous playback and recording
  * API. This is a synchronous, simplified wrapper around the standard
- * asynchronous API. */
+ * asynchronous API.
+ *
+ * See also \subpage simple
+ */
 
 /** \example pacat-simple.c
  * A simple playback tool using the simple API */
@@ -114,20 +117,20 @@ PA_C_DECL_BEGIN
  * An opaque simple connection object */
 typedef struct pa_simple pa_simple;
 
-/** create a new connection to the server */
+/** Create a new connection to the server. */
 pa_simple* pa_simple_new(
     const char *server,                 /**< Server name, or NULL for default */
     const char *name,                   /**< A descriptive name for this client (application name, ...) */
     pa_stream_direction_t dir,          /**< Open this stream for recording or playback? */
     const char *dev,                    /**< Sink (resp. source) name, or NULL for default */
-    const char *stream_name,            /**< A descriptive name for this client (application name, song title, ...) */
+    const char *stream_name,            /**< A descriptive name for this stream (application name, song title, ...) */
     const pa_sample_spec *ss,           /**< The sample type to use */
     const pa_channel_map *map,          /**< The channel map to use, or NULL for default */
     const pa_buffer_attr *attr,         /**< Buffering attributes, or NULL for default */
     int *error                          /**< A pointer where the error code is stored when the routine returns NULL. It is OK to pass NULL here. */
     );
 
-/** create a new connection to the server with proplist */
+/** Create a new connection to the server with proplist */
 pa_simple* pa_simple_new_proplist(
     const char *server,                 /**< Server name, or NULL for default */
     const char *name,                   /**< A descriptive name for this client (application name, ...) */
@@ -141,39 +144,47 @@ pa_simple* pa_simple_new_proplist(
     int *error                          /**< A pointer where the error code is stored when the routine returns NULL. It is OK to pass NULL here. */
     );
 
-/** Close and free the connection to the server. The connection objects becomes invalid when this is called. */
+/** Close and free the connection to the server. The connection object becomes invalid when this is called. */
 void pa_simple_free(pa_simple *s);
 
-/** Write some data to the server */
-int pa_simple_write(pa_simple *s, const void*data, size_t bytes, int *error);
+/** Write some data to the server. */
+int pa_simple_write(pa_simple *s, const void *data, size_t bytes, int *error);
 
-/** Wait until all data already written is played by the daemon */
+/** Wait until all data already written is played by the daemon. */
 int pa_simple_drain(pa_simple *s, int *error);
 
-/** Read some data from the server */
-int pa_simple_read(pa_simple *s, void*data, size_t bytes, int *error);
+/** Read some data from the server. */
+int pa_simple_read(pa_simple *s, void *data, size_t bytes, int *error);
 
 /** Return the playback latency. */
 pa_usec_t pa_simple_get_latency(pa_simple *s, int *error);
 
-/** Flush the playback buffer. */
+/** Return the final latency. */
+pa_usec_t pa_simple_get_final_latency(pa_simple *s, int *error);
+
+/** Flush the playback buffer. This discards any audio in the buffer. */
 int pa_simple_flush(pa_simple *s, int *error);
 
 /** Mute the playback stream */
 int pa_simple_mute(pa_simple *p, int mute, int *rerror);
 
-/** Volume control the playback stream */
-int pa_simple_set_volume(pa_simple *p, int volume, int *rerror);
-
-/** Get stream index */
+#ifdef __TIZEN__
+/** Return the index of the stream*/
 int pa_simple_get_stream_index(pa_simple *p, unsigned int *idx, int *rerror);
 
-/** Cork on=1/off=0 stream */
+/** Cork the stream*/
 int pa_simple_cork(pa_simple *p, int cork, int *rerror);
 
-/** Check whether stream is corked or not */
+/** Set volume of  stream*/
+int pa_simple_set_volume(pa_simple *p, int volume, int *rerror);
+
+/** Check whether the  stream is corked*/
 int pa_simple_is_corked(pa_simple *p);
+#endif
 
+#ifdef MUTEX_LOCK_COUNT
+int mutex_lock_count;
+#endif
 PA_C_DECL_END
 
 #endif
index d01985b..ca5ea0d 100644 (file)
 #include <pulse/timeval.h>
 #include <pulse/rtclock.h>
 #include <pulse/xmalloc.h>
+#include <pulse/fork-detect.h>
 
 #include <pulsecore/pstream-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/hashmap.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-rtclock.h>
+#include <pulsecore/core-util.h>
 
-#include "fork-detect.h"
 #include "internal.h"
+#include "stream.h"
+
+/* #define STREAM_DEBUG */
 
 #define AUTO_TIMING_INTERVAL_START_USEC (10*PA_USEC_PER_MSEC)
 #define AUTO_TIMING_INTERVAL_END_USEC (1500*PA_USEC_PER_MSEC)
@@ -78,31 +82,26 @@ static void reset_callbacks(pa_stream *s) {
     s->buffer_attr_userdata = NULL;
 }
 
-pa_stream *pa_stream_new_with_proplist(
+static pa_stream *pa_stream_new_with_proplist_internal(
         pa_context *c,
         const char *name,
         const pa_sample_spec *ss,
         const pa_channel_map *map,
+        pa_format_info * const *formats,
+        unsigned int n_formats,
         pa_proplist *p) {
 
     pa_stream *s;
-    int i;
-    pa_channel_map tmap;
+    unsigned int i;
 
     pa_assert(c);
     pa_assert(PA_REFCNT_VALUE(c) >= 1);
+    pa_assert((ss == NULL && map == NULL) || (formats == NULL && n_formats == 0));
+    pa_assert(n_formats < PA_MAX_FORMATS);
 
     PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
-    PA_CHECK_VALIDITY_RETURN_NULL(c, ss && pa_sample_spec_valid(ss), PA_ERR_INVALID);
-    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 12 || (ss->format != PA_SAMPLE_S32LE && ss->format != PA_SAMPLE_S32BE), PA_ERR_NOTSUPPORTED);
-    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15 || (ss->format != PA_SAMPLE_S24LE && ss->format != PA_SAMPLE_S24BE), PA_ERR_NOTSUPPORTED);
-    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15 || (ss->format != PA_SAMPLE_S24_32LE && ss->format != PA_SAMPLE_S24_32BE), PA_ERR_NOTSUPPORTED);
-    PA_CHECK_VALIDITY_RETURN_NULL(c, !map || (pa_channel_map_valid(map) && map->channels == ss->channels), PA_ERR_INVALID);
     PA_CHECK_VALIDITY_RETURN_NULL(c, name || (p && pa_proplist_contains(p, PA_PROP_MEDIA_NAME)), PA_ERR_INVALID);
 
-    if (!map)
-        PA_CHECK_VALIDITY_RETURN_NULL(c, map = pa_channel_map_init_auto(&tmap, ss->channels, PA_CHANNEL_MAP_DEFAULT), PA_ERR_INVALID);
-
     s = pa_xnew(pa_stream, 1);
     PA_REFCNT_INIT(s);
     s->context = c;
@@ -112,8 +111,25 @@ pa_stream *pa_stream_new_with_proplist(
     s->state = PA_STREAM_UNCONNECTED;
     s->flags = 0;
 
-    s->sample_spec = *ss;
-    s->channel_map = *map;
+    if (ss)
+        s->sample_spec = *ss;
+    else
+        pa_sample_spec_init(&s->sample_spec);
+
+    if (map)
+        s->channel_map = *map;
+    else
+        pa_channel_map_init(&s->channel_map);
+
+    s->n_formats = 0;
+    if (formats) {
+        s->n_formats = n_formats;
+        for (i = 0; i < n_formats; i++)
+            s->req_formats[i] = pa_format_info_copy(formats[i]);
+    }
+
+    /* We'll get the final negotiated format after connecting */
+    s->format = NULL;
 
     s->direct_on_input = PA_INVALID_INDEX;
 
@@ -129,12 +145,23 @@ pa_stream *pa_stream_new_with_proplist(
     s->requested_bytes = 0;
     memset(&s->buffer_attr, 0, sizeof(s->buffer_attr));
 
-    /* We initialize der target length here, so that if the user
+    /* We initialize the target length here, so that if the user
      * passes no explicit buffering metrics the default is similar to
      * what older PA versions provided. */
 
     s->buffer_attr.maxlength = (uint32_t) -1;
-    s->buffer_attr.tlength = (uint32_t) pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */
+    if (ss)
+        s->buffer_attr.tlength = (uint32_t) pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */
+    else {
+        /* FIXME: We assume a worst-case compressed format corresponding to
+         * 48000 Hz, 2 ch, S16 PCM, but this can very well be incorrect */
+        pa_sample_spec tmp_ss = {
+            .format   = PA_SAMPLE_S16NE,
+            .rate     = 48000,
+            .channels = 2,
+        };
+        s->buffer_attr.tlength = (uint32_t) pa_usec_to_bytes(250*PA_USEC_PER_MSEC, &tmp_ss); /* 250ms of buffering */
+    }
     s->buffer_attr.minreq = (uint32_t) -1;
     s->buffer_attr.prebuf = (uint32_t) -1;
     s->buffer_attr.fragsize = (uint32_t) -1;
@@ -155,6 +182,7 @@ pa_stream *pa_stream_new_with_proplist(
     s->timing_info_valid = FALSE;
 
     s->previous_time = 0;
+    s->latest_underrun_at_index = -1;
 
     s->read_index_not_before = 0;
     s->write_index_not_before = 0;
@@ -177,6 +205,39 @@ pa_stream *pa_stream_new_with_proplist(
     return s;
 }
 
+pa_stream *pa_stream_new_with_proplist(
+        pa_context *c,
+        const char *name,
+        const pa_sample_spec *ss,
+        const pa_channel_map *map,
+        pa_proplist *p) {
+
+    pa_channel_map tmap;
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, ss && pa_sample_spec_valid(ss), PA_ERR_INVALID);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 12 || (ss->format != PA_SAMPLE_S32LE && ss->format != PA_SAMPLE_S32BE), PA_ERR_NOTSUPPORTED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15 || (ss->format != PA_SAMPLE_S24LE && ss->format != PA_SAMPLE_S24BE), PA_ERR_NOTSUPPORTED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15 || (ss->format != PA_SAMPLE_S24_32LE && ss->format != PA_SAMPLE_S24_32BE), PA_ERR_NOTSUPPORTED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !map || (pa_channel_map_valid(map) && map->channels == ss->channels), PA_ERR_INVALID);
+
+    if (!map)
+        PA_CHECK_VALIDITY_RETURN_NULL(c, map = pa_channel_map_init_auto(&tmap, ss->channels, PA_CHANNEL_MAP_DEFAULT), PA_ERR_INVALID);
+
+    return pa_stream_new_with_proplist_internal(c, name, ss, map, NULL, 0, p);
+}
+
+pa_stream *pa_stream_new_extended(
+        pa_context *c,
+        const char *name,
+        pa_format_info * const *formats,
+        unsigned int n_formats,
+        pa_proplist *p) {
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 21, PA_ERR_NOTSUPPORTED);
+
+    return pa_stream_new_with_proplist_internal(c, name, NULL, NULL, formats, n_formats, p);
+}
+
 static void stream_unlink(pa_stream *s) {
     pa_operation *o, *n;
     pa_assert(s);
@@ -186,7 +247,7 @@ static void stream_unlink(pa_stream *s) {
 
     /* Detach from context */
 
-    /* Unref all operatio object that point to us */
+    /* Unref all operation objects that point to us */
     for (o = s->context->operations; o; o = n) {
         n = o->next;
 
@@ -199,7 +260,7 @@ static void stream_unlink(pa_stream *s) {
         pa_pdispatch_unregister_reply(s->context->pdispatch, s);
 
     if (s->channel_valid) {
-        pa_dynarray_put((s->direction == PA_STREAM_PLAYBACK) ? s->context->playback_streams : s->context->record_streams, s->channel, NULL);
+        pa_hashmap_remove((s->direction == PA_STREAM_RECORD) ? s->context->record_streams : s->context->playback_streams, PA_UINT32_TO_PTR(s->channel));
         s->channel = 0;
         s->channel_valid = FALSE;
     }
@@ -218,13 +279,16 @@ static void stream_unlink(pa_stream *s) {
 }
 
 static void stream_free(pa_stream *s) {
+    unsigned int i;
+
     pa_assert(s);
 
     stream_unlink(s);
 
     if (s->write_memblock) {
-        pa_memblock_release(s->write_memblock);
-        pa_memblock_unref(s->write_data);
+        if (s->write_data)
+            pa_memblock_release(s->write_memblock);
+        pa_memblock_unref(s->write_memblock);
     }
 
     if (s->peek_memchunk.memblock) {
@@ -242,6 +306,12 @@ static void stream_free(pa_stream *s) {
     if (s->smoother)
         pa_smoother_free(s->smoother);
 
+    for (i = 0; i < s->n_formats; i++)
+        pa_format_info_free(s->req_formats[i]);
+
+    if (s->format)
+        pa_format_info_free(s->format);
+
     pa_xfree(s->device_name);
     pa_xfree(s);
 }
@@ -317,7 +387,9 @@ static void request_auto_timing_update(pa_stream *s, pa_bool_t force) {
         (force || !s->auto_timing_update_requested)) {
         pa_operation *o;
 
-/*         pa_log("Automatically requesting new timing data"); */
+#ifdef STREAM_DEBUG
+        pa_log_debug("Automatically requesting new timing data");
+#endif
 
         if ((o = pa_stream_update_timing_info(s, NULL, NULL))) {
             pa_operation_unref(o);
@@ -326,12 +398,18 @@ static void request_auto_timing_update(pa_stream *s, pa_bool_t force) {
     }
 
     if (s->auto_timing_update_event) {
-        if (force)
-            s->auto_timing_interval_usec = AUTO_TIMING_INTERVAL_START_USEC;
+        if (s->suspended && !force) {
+            pa_assert(s->mainloop);
+            s->mainloop->time_free(s->auto_timing_update_event);
+            s->auto_timing_update_event = NULL;
+        } else {
+            if (force)
+                s->auto_timing_interval_usec = AUTO_TIMING_INTERVAL_START_USEC;
 
-        pa_context_rttime_restart(s->context, s->auto_timing_update_event, pa_rtclock_now() + s->auto_timing_interval_usec);
+            pa_context_rttime_restart(s->context, s->auto_timing_update_event, pa_rtclock_now() + s->auto_timing_interval_usec);
 
-        s->auto_timing_interval_usec = PA_MIN(AUTO_TIMING_INTERVAL_END_USEC, s->auto_timing_interval_usec*2);
+            s->auto_timing_interval_usec = PA_MIN(AUTO_TIMING_INTERVAL_END_USEC, s->auto_timing_interval_usec*2);
+        }
     }
 }
 
@@ -354,7 +432,7 @@ void pa_command_stream_killed(pa_pdispatch *pd, uint32_t command, uint32_t tag,
         goto finish;
     }
 
-    if (!(s = pa_dynarray_get(command == PA_COMMAND_PLAYBACK_STREAM_KILLED ? c->playback_streams : c->record_streams, channel)))
+    if (!(s = pa_hashmap_get(command == PA_COMMAND_PLAYBACK_STREAM_KILLED ? c->playback_streams : c->record_streams, PA_UINT32_TO_PTR(channel))))
         goto finish;
 
     if (s->state != PA_STREAM_READY)
@@ -399,7 +477,7 @@ static void check_smoother_status(pa_stream *s, pa_bool_t aposteriori, pa_bool_t
              * indications when audio really starts/stops playing, if
              * we don't have any timing info yet -- instead of trying
              * to be smart and guessing the server time. Otherwise the
-             * unknown transport delay add too much noise to our time
+             * unknown transport delay adds too much noise to our time
              * calculations. */
 
             return;
@@ -412,6 +490,8 @@ static void check_smoother_status(pa_stream *s, pa_bool_t aposteriori, pa_bool_t
      * if prebuf is non-zero! */
 }
 
+static void auto_timing_update_callback(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata);
+
 void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
     pa_context *c = userdata;
     pa_stream *s;
@@ -474,7 +554,7 @@ void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, uint32_t tag, p
         goto finish;
     }
 
-    if (!(s = pa_dynarray_get(command == PA_COMMAND_PLAYBACK_STREAM_MOVED ? c->playback_streams : c->record_streams, channel)))
+    if (!(s = pa_hashmap_get(command == PA_COMMAND_PLAYBACK_STREAM_MOVED ? c->playback_streams : c->record_streams, PA_UINT32_TO_PTR(channel))))
         goto finish;
 
     if (s->state != PA_STREAM_READY)
@@ -499,6 +579,12 @@ void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, uint32_t tag, p
 
     s->suspended = suspended;
 
+    if ((s->flags & PA_STREAM_AUTO_TIMING_UPDATE) && !suspended && !s->auto_timing_update_event) {
+        s->auto_timing_interval_usec = AUTO_TIMING_INTERVAL_START_USEC;
+        s->auto_timing_update_event = pa_context_rttime_new(s->context, pa_rtclock_now() + s->auto_timing_interval_usec, &auto_timing_update_callback, s);
+        request_auto_timing_update(s, TRUE);
+    }
+
     check_smoother_status(s, TRUE, FALSE, FALSE);
     request_auto_timing_update(s, TRUE);
 
@@ -557,7 +643,7 @@ void pa_command_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, uint32_t
         goto finish;
     }
 
-    if (!(s = pa_dynarray_get(command == PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED ? c->playback_streams : c->record_streams, channel)))
+    if (!(s = pa_hashmap_get(command == PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED ? c->playback_streams : c->record_streams, PA_UINT32_TO_PTR(channel))))
         goto finish;
 
     if (s->state != PA_STREAM_READY)
@@ -609,7 +695,7 @@ void pa_command_stream_suspended(pa_pdispatch *pd, uint32_t command, uint32_t ta
         goto finish;
     }
 
-    if (!(s = pa_dynarray_get(command == PA_COMMAND_PLAYBACK_STREAM_SUSPENDED ? c->playback_streams : c->record_streams, channel)))
+    if (!(s = pa_hashmap_get(command == PA_COMMAND_PLAYBACK_STREAM_SUSPENDED ? c->playback_streams : c->record_streams, PA_UINT32_TO_PTR(channel))))
         goto finish;
 
     if (s->state != PA_STREAM_READY)
@@ -617,6 +703,12 @@ void pa_command_stream_suspended(pa_pdispatch *pd, uint32_t command, uint32_t ta
 
     s->suspended = suspended;
 
+    if ((s->flags & PA_STREAM_AUTO_TIMING_UPDATE) && !suspended && !s->auto_timing_update_event) {
+        s->auto_timing_interval_usec = AUTO_TIMING_INTERVAL_START_USEC;
+        s->auto_timing_update_event = pa_context_rttime_new(s->context, pa_rtclock_now() + s->auto_timing_interval_usec, &auto_timing_update_callback, s);
+        request_auto_timing_update(s, TRUE);
+    }
+
     check_smoother_status(s, TRUE, FALSE, FALSE);
     request_auto_timing_update(s, TRUE);
 
@@ -651,7 +743,7 @@ void pa_command_stream_started(pa_pdispatch *pd, uint32_t command, uint32_t tag,
         goto finish;
     }
 
-    if (!(s = pa_dynarray_get(c->playback_streams, channel)))
+    if (!(s = pa_hashmap_get(c->playback_streams, PA_UINT32_TO_PTR(channel))))
         goto finish;
 
     if (s->state != PA_STREAM_READY)
@@ -697,12 +789,19 @@ void pa_command_stream_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, p
         goto finish;
     }
 
-    if (!(s = pa_dynarray_get(command == PA_COMMAND_PLAYBACK_STREAM_EVENT ? c->playback_streams : c->record_streams, channel)))
+    if (!(s = pa_hashmap_get(command == PA_COMMAND_PLAYBACK_STREAM_EVENT ? c->playback_streams : c->record_streams, PA_UINT32_TO_PTR(channel))))
         goto finish;
 
     if (s->state != PA_STREAM_READY)
         goto finish;
 
+    if (pa_streq(event, PA_STREAM_EVENT_FORMAT_LOST)) {
+        /* Let client know what the running time was when the stream had to be killed  */
+        pa_usec_t stream_time;
+        if (pa_stream_get_time(s, &stream_time) == 0)
+            pa_proplist_setf(pl, "stream-time", "%llu", (unsigned long long) stream_time);
+    }
+
     if (s->event_callback)
         s->event_callback(s, event, pl, s->event_userdata);
 
@@ -733,7 +832,7 @@ void pa_command_request(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tag
         goto finish;
     }
 
-    if (!(s = pa_dynarray_get(c->playback_streams, channel)))
+    if (!(s = pa_hashmap_get(c->playback_streams, PA_UINT32_TO_PTR(channel))))
         goto finish;
 
     if (s->state != PA_STREAM_READY)
@@ -741,6 +840,10 @@ void pa_command_request(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tag
 
     s->requested_bytes += bytes;
 
+#ifdef STREAM_DEBUG
+    pa_log_debug("got request for %lli, now at %lli", (long long) bytes, (long long) s->requested_bytes);
+#endif
+
     if (s->requested_bytes > 0 && s->write_callback)
         s->write_callback(s, (size_t) s->requested_bytes, s->write_userdata);
 
@@ -748,10 +851,17 @@ finish:
     pa_context_unref(c);
 }
 
+int64_t pa_stream_get_underflow_index(pa_stream *p)
+{
+    pa_assert(p);
+    return p->latest_underrun_at_index;
+}
+
 void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
     pa_stream *s;
     pa_context *c = userdata;
     uint32_t channel;
+    int64_t offset = -1;
 
     pa_assert(pd);
     pa_assert(command == PA_COMMAND_OVERFLOW || command == PA_COMMAND_UNDERFLOW);
@@ -761,18 +871,32 @@ void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, uint32
 
     pa_context_ref(c);
 
-    if (pa_tagstruct_getu32(t, &channel) < 0 ||
-        !pa_tagstruct_eof(t)) {
+    if (pa_tagstruct_getu32(t, &channel) < 0) {
+        pa_context_fail(c, PA_ERR_PROTOCOL);
+        goto finish;
+    }
+
+    if (c->version >= 23 && command == PA_COMMAND_UNDERFLOW) {
+        if (pa_tagstruct_gets64(t, &offset) < 0) {
+            pa_context_fail(c, PA_ERR_PROTOCOL);
+            goto finish;
+        }
+    }
+
+    if (!pa_tagstruct_eof(t)) {
         pa_context_fail(c, PA_ERR_PROTOCOL);
         goto finish;
     }
 
-    if (!(s = pa_dynarray_get(c->playback_streams, channel)))
+    if (!(s = pa_hashmap_get(c->playback_streams, PA_UINT32_TO_PTR(channel))))
         goto finish;
 
     if (s->state != PA_STREAM_READY)
         goto finish;
 
+    if (offset != -1)
+        s->latest_underrun_at_index = offset;
+
     if (s->buffer_attr.prebuf > 0)
         check_smoother_status(s, TRUE, FALSE, TRUE);
 
@@ -786,7 +910,7 @@ void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, uint32
             s->underflow_callback(s, s->underflow_userdata);
     }
 
- finish:
+finish:
     pa_context_unref(c);
 }
 
@@ -794,7 +918,9 @@ static void invalidate_indexes(pa_stream *s, pa_bool_t r, pa_bool_t w) {
     pa_assert(s);
     pa_assert(PA_REFCNT_VALUE(s) >= 1);
 
-/*     pa_log("invalidate r:%u w:%u tag:%u", r, w, s->context->ctag); */
+#ifdef STREAM_DEBUG
+    pa_log_debug("invalidate r:%u w:%u tag:%u", r, w, s->context->ctag);
+#endif
 
     if (s->state != PA_STREAM_READY)
         return;
@@ -805,7 +931,9 @@ static void invalidate_indexes(pa_stream *s, pa_bool_t r, pa_bool_t w) {
         if (s->timing_info_valid)
             s->timing_info.write_index_corrupt = TRUE;
 
-/*         pa_log("write_index invalidated"); */
+#ifdef STREAM_DEBUG
+        pa_log_debug("write_index invalidated");
+#endif
     }
 
     if (r) {
@@ -814,7 +942,9 @@ static void invalidate_indexes(pa_stream *s, pa_bool_t r, pa_bool_t w) {
         if (s->timing_info_valid)
             s->timing_info.read_index_corrupt = TRUE;
 
-/*         pa_log("read_index invalidated"); */
+#ifdef STREAM_DEBUG
+        pa_log_debug("read_index invalidated");
+#endif
     }
 
     request_auto_timing_update(s, TRUE);
@@ -852,10 +982,28 @@ static void create_stream_complete(pa_stream *s) {
     check_smoother_status(s, TRUE, FALSE, FALSE);
 }
 
-static void automatic_buffer_attr(pa_stream *s, pa_buffer_attr *attr, const pa_sample_spec *ss) {
+static void patch_buffer_attr(pa_stream *s, pa_buffer_attr *attr, pa_stream_flags_t *flags) {
+    const char *e;
+
     pa_assert(s);
     pa_assert(attr);
-    pa_assert(ss);
+
+    if ((e = getenv("PULSE_LATENCY_MSEC"))) {
+        uint32_t ms;
+
+        if (pa_atou(e, &ms) < 0 || ms <= 0)
+            pa_log_debug("Failed to parse $PULSE_LATENCY_MSEC: %s", e);
+        else {
+            attr->maxlength = (uint32_t) -1;
+            attr->tlength = pa_usec_to_bytes(ms * PA_USEC_PER_MSEC, &s->sample_spec);
+            attr->minreq = (uint32_t) -1;
+            attr->prebuf = (uint32_t) -1;
+            attr->fragsize = attr->tlength;
+        }
+
+        if (flags)
+            *flags |= PA_STREAM_ADJUST_LATENCY;
+    }
 
     if (s->context->version >= 13)
         return;
@@ -870,7 +1018,7 @@ static void automatic_buffer_attr(pa_stream *s, pa_buffer_attr *attr, const pa_s
         attr->maxlength = 4*1024*1024; /* 4MB is the maximum queue length PulseAudio <= 0.9.9 supported. */
 
     if (attr->tlength == (uint32_t) -1)
-        attr->tlength = (uint32_t) pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */
+        attr->tlength = (uint32_t) pa_usec_to_bytes(250*PA_USEC_PER_MSEC, &s->sample_spec); /* 250ms of buffering */
 
     if (attr->minreq == (uint32_t) -1)
         attr->minreq = (attr->tlength)/5; /* Ask for more data when there are only 200ms left in the playback buffer */
@@ -903,7 +1051,7 @@ void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag,
 
     if (pa_tagstruct_getu32(t, &s->channel) < 0 ||
         s->channel == PA_INVALID_INDEX ||
-        ((s->direction != PA_STREAM_UPLOAD) && (pa_tagstruct_getu32(t, &s->stream_index) < 0 ||  s->stream_index == PA_INVALID_INDEX)) ||
+        ((s->direction != PA_STREAM_UPLOAD) && (pa_tagstruct_getu32(t, &s->stream_index) < 0 || s->stream_index == PA_INVALID_INDEX)) ||
         ((s->direction != PA_STREAM_RECORD) && pa_tagstruct_getu32(t, &requested_bytes) < 0)) {
         pa_context_fail(s->context, PA_ERR_PROTOCOL);
         goto finish;
@@ -948,9 +1096,10 @@ void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag,
             ss.channels != cm.channels ||
             !pa_channel_map_valid(&cm) ||
             !pa_sample_spec_valid(&ss) ||
-            (!(s->flags & PA_STREAM_FIX_FORMAT) && ss.format != s->sample_spec.format) ||
-            (!(s->flags & PA_STREAM_FIX_RATE) && ss.rate != s->sample_spec.rate) ||
-            (!(s->flags & PA_STREAM_FIX_CHANNELS) && !pa_channel_map_equal(&cm, &s->channel_map))) {
+            (s->n_formats == 0 && (
+                (!(s->flags & PA_STREAM_FIX_FORMAT) && ss.format != s->sample_spec.format) ||
+                (!(s->flags & PA_STREAM_FIX_RATE) && ss.rate != s->sample_spec.rate) ||
+                (!(s->flags & PA_STREAM_FIX_CHANNELS) && !pa_channel_map_equal(&cm, &s->channel_map))))) {
             pa_context_fail(s->context, PA_ERR_PROTOCOL);
             goto finish;
         }
@@ -977,6 +1126,24 @@ void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag,
             s->timing_info.configured_sink_usec = usec;
     }
 
+    if ((s->context->version >= 21 && s->direction == PA_STREAM_PLAYBACK)
+        || s->context->version >= 22) {
+
+        pa_format_info *f = pa_format_info_new();
+        pa_tagstruct_get_format_info(t, f);
+
+        if (pa_format_info_valid(f))
+            s->format = f;
+        else {
+            pa_format_info_free(f);
+            if (s->n_formats > 0) {
+                /* We used the extended API, so we should have got back a proper format */
+                pa_context_fail(s->context, PA_ERR_PROTOCOL);
+                goto finish;
+            }
+        }
+    }
+
     if (!pa_tagstruct_eof(t)) {
         pa_context_fail(s->context, PA_ERR_PROTOCOL);
         goto finish;
@@ -986,10 +1153,11 @@ void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag,
         pa_assert(!s->record_memblockq);
 
         s->record_memblockq = pa_memblockq_new(
+                "client side record memblockq",
                 0,
                 s->buffer_attr.maxlength,
                 0,
-                pa_frame_size(&s->sample_spec),
+                &s->sample_spec,
                 1,
                 0,
                 0,
@@ -997,7 +1165,7 @@ void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag,
     }
 
     s->channel_valid = TRUE;
-    pa_dynarray_put((s->direction == PA_STREAM_RECORD) ? s->context->record_streams : s->context->playback_streams, s->channel, s);
+    pa_hashmap_put((s->direction == PA_STREAM_RECORD) ? s->context->record_streams : s->context->playback_streams, PA_UINT32_TO_PTR(s->channel), s);
 
     create_stream_complete(s);
 
@@ -1016,7 +1184,9 @@ static int create_stream(
 
     pa_tagstruct *t;
     uint32_t tag;
-    pa_bool_t volume_set = FALSE;
+    pa_bool_t volume_set = !!volume;
+    pa_cvolume cv;
+    uint32_t i;
 
     pa_assert(s);
     pa_assert(PA_REFCNT_VALUE(s) >= 1);
@@ -1042,34 +1212,37 @@ static int create_stream(
                                               PA_STREAM_EARLY_REQUESTS|
                                               PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND|
                                               PA_STREAM_START_UNMUTED|
-                                              PA_STREAM_FAIL_ON_SUSPEND)), PA_ERR_INVALID);
+                                              PA_STREAM_FAIL_ON_SUSPEND|
+                                              PA_STREAM_RELATIVE_VOLUME|
+                                              PA_STREAM_PASSTHROUGH)), PA_ERR_INVALID);
+
 
     PA_CHECK_VALIDITY(s->context, s->context->version >= 12 || !(flags & PA_STREAM_VARIABLE_RATE), PA_ERR_NOTSUPPORTED);
     PA_CHECK_VALIDITY(s->context, s->context->version >= 13 || !(flags & PA_STREAM_PEAK_DETECT), PA_ERR_NOTSUPPORTED);
     PA_CHECK_VALIDITY(s->context, s->context->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
-    /* Althought some of the other flags are not supported on older
+    /* Although some of the other flags are not supported on older
      * version, we don't check for them here, because it doesn't hurt
      * when they are passed but actually not supported. This makes
      * client development easier */
 
-    PA_CHECK_VALIDITY(s->context, direction == PA_STREAM_PLAYBACK || !(flags & (PA_STREAM_START_MUTED)), PA_ERR_INVALID);
     PA_CHECK_VALIDITY(s->context, direction == PA_STREAM_RECORD || !(flags & (PA_STREAM_PEAK_DETECT)), PA_ERR_INVALID);
-    PA_CHECK_VALIDITY(s->context, !volume || volume->channels == s->sample_spec.channels, PA_ERR_INVALID);
+    PA_CHECK_VALIDITY(s->context, !volume || s->n_formats || (pa_sample_spec_valid(&s->sample_spec) && volume->channels == s->sample_spec.channels), PA_ERR_INVALID);
     PA_CHECK_VALIDITY(s->context, !sync_stream || (direction == PA_STREAM_PLAYBACK && sync_stream->direction == PA_STREAM_PLAYBACK), PA_ERR_INVALID);
     PA_CHECK_VALIDITY(s->context, (flags & (PA_STREAM_ADJUST_LATENCY|PA_STREAM_EARLY_REQUESTS)) != (PA_STREAM_ADJUST_LATENCY|PA_STREAM_EARLY_REQUESTS), PA_ERR_INVALID);
 
     pa_stream_ref(s);
 
     s->direction = direction;
-    s->flags = flags;
-    s->corked = !!(flags & PA_STREAM_START_CORKED);
 
     if (sync_stream)
         s->syncid = sync_stream->syncid;
 
     if (attr)
         s->buffer_attr = *attr;
-    automatic_buffer_attr(s, &s->buffer_attr, &s->sample_spec);
+    patch_buffer_attr(s, &s->buffer_attr, &flags);
+
+    s->flags = flags;
+    s->corked = !!(flags & PA_STREAM_START_CORKED);
 
     if (flags & PA_STREAM_INTERPOLATE_TIMING) {
         pa_usec_t x;
@@ -1108,9 +1281,18 @@ static int create_stream(
             PA_TAG_BOOLEAN, s->corked,
             PA_TAG_INVALID);
 
-    if (s->direction == PA_STREAM_PLAYBACK) {
-        pa_cvolume cv;
+    if (!volume) {
+        if (pa_sample_spec_valid(&s->sample_spec))
+            volume = pa_cvolume_reset(&cv, s->sample_spec.channels);
+        else {
+            /* This is not really relevant, since no volume was set, and
+             * the real number of channels is embedded in the format_info
+             * structure */
+            volume = pa_cvolume_reset(&cv, PA_CHANNELS_MAX);
+        }
+    }
 
+    if (s->direction == PA_STREAM_PLAYBACK) {
         pa_tagstruct_put(
                 t,
                 PA_TAG_U32, s->buffer_attr.tlength,
@@ -1119,11 +1301,6 @@ static int create_stream(
                 PA_TAG_U32, s->syncid,
                 PA_TAG_INVALID);
 
-        volume_set = !!volume;
-
-        if (!volume)
-            volume = pa_cvolume_reset(&cv, s->sample_spec.channels);
-
         pa_tagstruct_put_cvolume(t, volume);
     } else
         pa_tagstruct_putu32(t, s->buffer_attr.fragsize);
@@ -1175,6 +1352,29 @@ static int create_stream(
         pa_tagstruct_put_boolean(t, flags & PA_STREAM_FAIL_ON_SUSPEND);
     }
 
+    if (s->context->version >= 17 && s->direction == PA_STREAM_PLAYBACK)
+        pa_tagstruct_put_boolean(t, flags & PA_STREAM_RELATIVE_VOLUME);
+
+    if (s->context->version >= 18 && s->direction == PA_STREAM_PLAYBACK)
+        pa_tagstruct_put_boolean(t, flags & (PA_STREAM_PASSTHROUGH));
+
+    if ((s->context->version >= 21 && s->direction == PA_STREAM_PLAYBACK)
+        || s->context->version >= 22) {
+
+        pa_tagstruct_putu8(t, s->n_formats);
+        for (i = 0; i < s->n_formats; i++)
+            pa_tagstruct_put_format_info(t, s->req_formats[i]);
+    }
+
+    if (s->context->version >= 22 && s->direction == PA_STREAM_RECORD) {
+        pa_tagstruct_put_cvolume(t, volume);
+        pa_tagstruct_put_boolean(t, flags & PA_STREAM_START_MUTED);
+        pa_tagstruct_put_boolean(t, volume_set);
+        pa_tagstruct_put_boolean(t, flags & (PA_STREAM_START_MUTED|PA_STREAM_START_UNMUTED));
+        pa_tagstruct_put_boolean(t, flags & PA_STREAM_RELATIVE_VOLUME);
+        pa_tagstruct_put_boolean(t, flags & (PA_STREAM_PASSTHROUGH));
+    }
+
     pa_pstream_send_tagstruct(s->context->pstream, t);
     pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_create_stream_callback, s, NULL);
 
@@ -1354,6 +1554,10 @@ int pa_stream_write(
      * that's OK, the server side applies the same error */
     s->requested_bytes -= (seek == PA_SEEK_RELATIVE ? offset : 0) + (int64_t) length;
 
+#ifdef STREAM_DEBUG
+    pa_log_debug("wrote %lli, now at %lli", (long long) length, (long long) s->requested_bytes);
+#endif
+
     if (s->direction == PA_STREAM_PLAYBACK) {
 
         /* Update latency request correction */
@@ -1403,9 +1607,17 @@ int pa_stream_peek(pa_stream *s, const void **data, size_t *length) {
     if (!s->peek_memchunk.memblock) {
 
         if (pa_memblockq_peek(s->record_memblockq, &s->peek_memchunk) < 0) {
+            /* record_memblockq is empty. */
             *data = NULL;
             *length = 0;
             return 0;
+
+        } else if (!s->peek_memchunk.memblock) {
+            /* record_memblockq isn't empty, but it doesn't have any data at
+             * the current read index. */
+            *data = NULL;
+            *length = s->peek_memchunk.length;
+            return 0;
         }
 
         s->peek_data = pa_memblock_acquire(s->peek_memchunk.memblock);
@@ -1424,7 +1636,7 @@ int pa_stream_drop(pa_stream *s) {
     PA_CHECK_VALIDITY(s->context, !pa_detect_fork(), PA_ERR_FORKED);
     PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE);
     PA_CHECK_VALIDITY(s->context, s->direction == PA_STREAM_RECORD, PA_ERR_BADSTATE);
-    PA_CHECK_VALIDITY(s->context, s->peek_memchunk.memblock, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY(s->context, s->peek_memchunk.length > 0, PA_ERR_BADSTATE);
 
     pa_memblockq_drop(s->record_memblockq, s->peek_memchunk.length);
 
@@ -1432,9 +1644,13 @@ int pa_stream_drop(pa_stream *s) {
     if (s->timing_info_valid && !s->timing_info.read_index_corrupt)
         s->timing_info.read_index += (int64_t) s->peek_memchunk.length;
 
-    pa_assert(s->peek_data);
-    pa_memblock_release(s->peek_memchunk.memblock);
-    pa_memblock_unref(s->peek_memchunk.memblock);
+    if (s->peek_memchunk.memblock) {
+        pa_assert(s->peek_data);
+        s->peek_data = NULL;
+        pa_memblock_release(s->peek_memchunk.memblock);
+        pa_memblock_unref(s->peek_memchunk.memblock);
+    }
+
     pa_memchunk_reset(&s->peek_memchunk);
 
     return 0;
@@ -1486,7 +1702,7 @@ pa_operation * pa_stream_drain(pa_stream *s, pa_stream_success_cb_t cb, void *us
     pa_pstream_send_tagstruct(s->context->pstream, t);
     pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_stream_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
 
-    /* This might cause the read index to conitnue again, hence
+    /* This might cause the read index to continue again, hence
      * let's request a timing update */
     request_auto_timing_update(s, TRUE);
 
@@ -1615,7 +1831,7 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
 
         pa_gettimeofday(&now);
 
-        /* Calculcate timestamps */
+        /* Calculate timestamps */
         if (pa_timeval_cmp(&local, &remote) <= 0 && pa_timeval_cmp(&remote, &now) <= 0) {
             /* local and remote seem to have synchronized clocks */
 
@@ -1692,8 +1908,8 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
                 i->read_index -= (int64_t) pa_memblockq_get_length(o->stream->record_memblockq);
         }
 
-        /* Update smoother */
-        if (o->stream->smoother) {
+        /* Update smoother if we're not corked */
+        if (o->stream->smoother && !o->stream->corked) {
             pa_usec_t u, x;
 
             u = x = pa_rtclock_now() - i->transport_usec;
@@ -2121,6 +2337,11 @@ pa_operation* pa_stream_flush(pa_stream *s, pa_stream_success_cb_t cb, void *use
          * index, but the read index might jump. */
         invalidate_indexes(s, TRUE, FALSE);
 
+    /* Note that we do not update requested_bytes here. This is
+     * because we cannot really know how data actually was dropped
+     * from the write index due to this. This 'error' will be applied
+     * by both client and server and hence we should be fine. */
+
     return o;
 }
 
@@ -2328,6 +2549,16 @@ const pa_channel_map* pa_stream_get_channel_map(pa_stream *s) {
     return &s->channel_map;
 }
 
+const pa_format_info* pa_stream_get_format_info(pa_stream *s) {
+    pa_assert(s);
+    pa_assert(PA_REFCNT_VALUE(s) >= 1);
+
+    /* We don't have the format till routing is done */
+    PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(s->context, !pa_detect_fork(), PA_ERR_FORKED);
+
+    return s->format;
+}
 const pa_buffer_attr* pa_stream_get_buffer_attr(pa_stream *s) {
     pa_assert(s);
     pa_assert(PA_REFCNT_VALUE(s) >= 1);
@@ -2407,6 +2638,7 @@ pa_operation* pa_stream_set_buffer_attr(pa_stream *s, const pa_buffer_attr *attr
     pa_operation *o;
     pa_tagstruct *t;
     uint32_t tag;
+    pa_buffer_attr copy;
 
     pa_assert(s);
     pa_assert(PA_REFCNT_VALUE(s) >= 1);
@@ -2430,6 +2662,10 @@ pa_operation* pa_stream_set_buffer_attr(pa_stream *s, const pa_buffer_attr *attr
             &tag);
     pa_tagstruct_putu32(t, s->channel);
 
+    copy = *attr;
+    patch_buffer_attr(s, &copy, NULL);
+    attr = &copy;
+
     pa_tagstruct_putu32(t, attr->maxlength);
 
     if (s->direction == PA_STREAM_PLAYBACK)
@@ -2451,7 +2687,7 @@ pa_operation* pa_stream_set_buffer_attr(pa_stream *s, const pa_buffer_attr *attr
     pa_pstream_send_tagstruct(s->context->pstream, t);
     pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, stream_set_buffer_attr_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
 
-    /* This might cause changes in the read/write indexex, hence let's
+    /* This might cause changes in the read/write index, hence let's
      * request a timing update */
     request_auto_timing_update(s, TRUE);
 
index bc54a11..a6785ec 100644 (file)
@@ -26,6 +26,7 @@
 #include <sys/types.h>
 
 #include <pulse/sample.h>
+#include <pulse/format.h>
 #include <pulse/channelmap.h>
 #include <pulse/volume.h>
 #include <pulse/def.h>
  * index. The application writes to the write index and the sound
  * device reads from the read index. The read index is increased
  * monotonically, while the write index may be freely controlled by
- * the application. Substracting the read index from the write index
+ * the application. Subtracting the read index from the write index
  * will give you the current fill level of the buffer. The read/write
  * indexes are 64bit values and measured in bytes, they will never
  * wrap. The current read/write index may be queried using
  * The transfer buffers can be controlled through a number of operations:
  *
  * \li pa_stream_cork() - Start or stop the playback or recording.
- * \li pa_stream_trigger() - Start playback immediatly and do not wait for
+ * \li pa_stream_trigger() - Start playback immediately and do not wait for
  *                           the buffer to fill up to the set trigger level.
  * \li pa_stream_prebuf() - Reenable the playback trigger level.
  * \li pa_stream_drain() - Wait for the playback buffer to go empty. Will
  * by pa_stream_get_timing_info(). Hence the same rules for keeping
  * the timing data up-to-date apply here. In case the write or read
  * index is corrupted, these two functions will fail with
- * PA_ERR_NODATA set.
+ * -PA_ERR_NODATA set.
  *
  * Since updating the timing info structure usually requires a full
  * network round trip and some applications monitor the timing very
  * pa_stream_get_time() and pa_stream_get_latency() will try to
  * interpolate the current playback time/latency by estimating the
  * number of samples that have been played back by the hardware since
- * the last regular timing update. It is espcially useful to combine
+ * the last regular timing update. It is especially useful to combine
  * this option with PA_STREAM_AUTO_TIMING_UPDATE, which will enable
  * you to monitor the current playback time/latency very precisely and
  * very frequently without requiring a network round trip every time.
  * pa_stream_set_overflow_callback() and
  * pa_stream_set_underflow_callback().
  *
- * \section sync_streams Sychronizing Multiple Playback Streams
+ * \section sync_streams Synchronizing Multiple Playback Streams
  *
  * PulseAudio allows applications to fully synchronize multiple
  * playback streams that are connected to the same output device. That
  * issued on the others.
  *
  * To synchronize a stream to another, just pass the "master" stream
- * as last argument to pa_stream_connect_playack(). To make sure that
+ * as last argument to pa_stream_connect_playback(). To make sure that
  * the freshly created stream doesn't start playback right-away, make
- * sure to pass PA_STREAM_START_CORKED and - after all streams have
- * been created - uncork them all with a single call to
+ * sure to pass PA_STREAM_START_CORKED and -- after all streams have
+ * been created -- uncork them all with a single call to
  * pa_stream_cork() for the master stream.
  *
  * To make sure that a particular stream doesn't stop to play when a
  * server side buffer underrun happens on it while the other
- * synchronized streams continue playing and hence deviate you need to
+ * synchronized streams continue playing and hence deviate, you need to
  * pass a "prebuf" pa_buffer_attr of 0 when connecting it.
  *
  * \section disc_sec Disconnecting
  */
 
 /** \file
- * Audio streams for input, output and sample upload */
+ * Audio streams for input, output and sample upload
+ *
+ * See also \subpage streams
+ */
 
 PA_C_DECL_BEGIN
 
@@ -344,7 +348,7 @@ pa_stream* pa_stream_new(
         const pa_channel_map *map         /**< The desired channel map, or NULL for default */);
 
 /** Create a new, unconnected stream with the specified name and
- * sample type, and specify the the initial stream property
+ * sample type, and specify the initial stream property
  * list. \since 0.9.11 */
 pa_stream* pa_stream_new_with_proplist(
         pa_context *c                     /**< The context to create this stream in */,
@@ -353,67 +357,82 @@ pa_stream* pa_stream_new_with_proplist(
         const pa_channel_map *map         /**< The desired channel map, or NULL for default */,
         pa_proplist *p                    /**< The initial property list */);
 
-/** Decrease the reference counter by one */
+/** Create a new, unconnected stream with the specified name, the set of formats
+ * this client can provide, and an initial list of properties. While
+ * connecting, the server will select the most appropriate format which the
+ * client must then provide. \since 1.0 */
+pa_stream *pa_stream_new_extended(
+        pa_context *c                     /**< The context to create this stream in */,
+        const char *name                  /**< A name for this stream */,
+        pa_format_info * const * formats  /**< The list of formats that can be provided */,
+        unsigned int n_formats            /**< The number of formats being passed in */,
+        pa_proplist *p                    /**< The initial property list */);
+
+/** Decrease the reference counter by one. */
 void pa_stream_unref(pa_stream *s);
 
-/** Increase the reference counter by one */
+/** Increase the reference counter by one. */
 pa_stream *pa_stream_ref(pa_stream *s);
 
-/** Return the current state of the stream */
+/** Return the current state of the stream. */
 pa_stream_state_t pa_stream_get_state(pa_stream *p);
 
-/** Return the context this stream is attached to */
+/** Return the context this stream is attached to. */
 pa_context* pa_stream_get_context(pa_stream *p);
 
-/** Return the sink input resp. source output index this stream is
- * identified in the server with. This is useful for usage with the
- * introspection functions, such as pa_context_get_sink_input_info()
- * resp. pa_context_get_source_output_info(). */
+/** Return the sink input resp.\ source output index this stream is
+ * identified in the server with. This is useful with the
+ * introspection functions such as pa_context_get_sink_input_info()
+ * or pa_context_get_source_output_info(). */
 uint32_t pa_stream_get_index(pa_stream *s);
 
 /** Return the index of the sink or source this stream is connected to
- * in the server. This is useful for usage with the introspection
- * functions, such as pa_context_get_sink_info_by_index()
- * resp. pa_context_get_source_info_by_index(). Please note that
- * streams may be moved between sinks/sources and thus it is
- * recommended to use pa_stream_set_moved_callback() to be notified
- * about this. This function will return with PA_ERR_NOTSUPPORTED when the
+ * in the server. This is useful with the introspection
+ * functions such as pa_context_get_sink_info_by_index() or
+ * pa_context_get_source_info_by_index().
+ *
+ * Please note that streams may be moved between sinks/sources and thus
+ * it is recommended to use pa_stream_set_moved_callback() to be notified
+ * about this. This function will return with -PA_ERR_NOTSUPPORTED when the
  * server is older than 0.9.8. \since 0.9.8 */
 uint32_t pa_stream_get_device_index(pa_stream *s);
 
 /** Return the name of the sink or source this stream is connected to
- * in the server. This is useful for usage with the introspection
- * functions, such as pa_context_get_sink_info_by_name()
- * resp. pa_context_get_source_info_by_name(). Please note that
- * streams may be moved between sinks/sources and thus it is
- * recommended to use pa_stream_set_moved_callback() to be notified
- * about this. This function will return with PA_ERR_NOTSUPPORTED when the
+ * in the server. This is useful with the introspection
+ * functions such as pa_context_get_sink_info_by_name()
+ * or pa_context_get_source_info_by_name().
+ *
+ * Please note that streams may be moved between sinks/sources and thus
+ * it is recommended to use pa_stream_set_moved_callback() to be notified
+ * about this. This function will return with -PA_ERR_NOTSUPPORTED when the
  * server is older than 0.9.8. \since 0.9.8 */
 const char *pa_stream_get_device_name(pa_stream *s);
 
 /** Return 1 if the sink or source this stream is connected to has
- * been suspended. This will return 0 if not, and negative on
- * error. This function will return with PA_ERR_NOTSUPPORTED when the
+ * been suspended. This will return 0 if not, and a negative value on
+ * error. This function will return with -PA_ERR_NOTSUPPORTED when the
  * server is older than 0.9.8. \since 0.9.8 */
 int pa_stream_is_suspended(pa_stream *s);
 
 /** Return 1 if the this stream has been corked. This will return 0 if
- * not, and negative on error. \since 0.9.11 */
+ * not, and a negative value on error. \since 0.9.11 */
 int pa_stream_is_corked(pa_stream *s);
 
 /** Connect the stream to a sink. It is strongly recommended to pass
- * NULL in both dev and volume and not to set either
+ * NULL in both \a dev and \a volume and not to set either
  * PA_STREAM_START_MUTED nor PA_STREAM_START_UNMUTED -- unless these
- * options are directly dependant on user input or configuration. If
- * you follow this rule then the sound server will have the full
+ * options are directly dependent on user input or configuration.
+ *
+ * If you follow this rule then the sound server will have the full
  * flexibility to choose the device, volume and mute status
  * automatically, based on server-side policies, heuristics and stored
  * information from previous uses. Also the server may choose to
  * reconfigure audio devices to make other sinks/sources or
- * capabilities available to be able to accept the stream. Before
- * 0.9.20 it was not defined whether the 'volume' parameter was
+ * capabilities available to be able to accept the stream.
+ *
+ * Before 0.9.20 it was not defined whether the \a volume parameter was
  * interpreted relative to the sink's current volume or treated as
- * absolute device volume. Since 0.9.20 it is an absolute volume when
+ * an absolute device volume. Since 0.9.20 it is an absolute volume when
  * the sink is in flat volume mode, and relative otherwise, thus
  * making sure the volume passed here has always the same semantics as
  * the volume passed to pa_context_set_sink_input_volume(). */
@@ -423,38 +442,42 @@ int pa_stream_connect_playback(
         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 */,
-        pa_stream *sync_stream        /**< Synchronize this stream with the specified one, or NULL for a standalone stream*/);
+        pa_stream *sync_stream        /**< Synchronize this stream with the specified one, or NULL for a standalone stream */);
 
-/** Connect the stream to a source */
+/** Connect the stream to a source. */
 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 pa_buffer_attr *attr    /**< Buffer attributes, or NULL for default */,
         pa_stream_flags_t flags       /**< Additional flags, or 0 for default */);
 
-/** Disconnect a stream from a source/sink */
+/** Disconnect a stream from a source/sink. */
 int pa_stream_disconnect(pa_stream *s);
 
 /** Prepare writing data to the server (for playback streams). This
  * function may be used to optimize the number of memory copies when
  * doing playback ("zero-copy"). It is recommended to call this
- * function before each call to pa_stream_write(). Pass in the address
- * to a pointer and an address of the number of bytes you want to
- * write. On return the two values will contain a pointer where you
- * can place the data to write and the maximum number of bytes you can
- * write. On return *nbytes can be smaller or have the same value as
- * you passed in. You need to be able to handle both cases. Accessing
- * memory beyond the returned *nbytes value is invalid. Acessing the
- * memory returned after the following pa_stream_write() or
- * pa_stream_cancel_write() is invalid. On invocation only *nbytes
- * needs to be initialized, on return both *data and *nbytes will be
- * valid. If you place (size_t) -1 in *nbytes on invocation the memory
- * size will be chosen automatically (which is recommended to
- * do). After placing your data in the memory area returned call
- * pa_stream_write() with data set to an address within this memory
- * area and an nbytes value that is smaller or equal to what was
- * returned by this function to actually execute the write. An
- * invocation of pa_stream_write() should follow "quickly" on
+ * function before each call to pa_stream_write().
+ *
+ * Pass in the address to a pointer and an address of the number of
+ * bytes you want to write. On return the two values will contain a
+ * pointer where you can place the data to write and the maximum number
+ * of bytes you can write. \a *nbytes can be smaller or have the same
+ * value as you passed in. You need to be able to handle both cases.
+ * Accessing memory beyond the returned \a *nbytes value is invalid.
+ * Accessing the memory returned after the following pa_stream_write()
+ * or pa_stream_cancel_write() is invalid.
+ *
+ * On invocation only \a *nbytes needs to be initialized, on return both
+ * *data and *nbytes will be valid. If you place (size_t) -1 in *nbytes
+ * on invocation the memory size will be chosen automatically (which is
+ * recommended to do). After placing your data in the memory area
+ * returned, call pa_stream_write() with \a data set to an address
+ * within this memory area and an \a nbytes value that is smaller or
+ * equal to what was returned by this function to actually execute the
+ * write.
+ *
+ * An invocation of pa_stream_write() should follow "quickly" on
  * pa_stream_begin_write(). It is not recommended letting an unbounded
  * amount of time pass after calling pa_stream_begin_write() and
  * before calling pa_stream_write(). If you want to cancel a
@@ -462,7 +485,7 @@ int pa_stream_disconnect(pa_stream *s);
  * pa_stream_write() use pa_stream_cancel_write(). Calling
  * pa_stream_begin_write() twice without calling pa_stream_write() or
  * pa_stream_cancel_write() in between will return exactly the same
- * pointer/nbytes values.\since 0.9.16 */
+ * \a data pointer and \a nbytes values. \since 0.9.16 */
 int pa_stream_begin_write(
         pa_stream *p,
         void **data,
@@ -480,15 +503,17 @@ int pa_stream_begin_write(
 int pa_stream_cancel_write(
         pa_stream *p);
 
-/** Write some data to the server (for playback streams), if free_cb
- * is non-NULL this routine is called when all data has been written
- * out and an internal reference to the specified data is kept, the
- * data is not copied. If NULL, the data is copied into an internal
- * buffer. The client may freely seek around in the output buffer. For
- * most applications passing 0 and PA_SEEK_RELATIVE as arguments for
- * offset and seek should be useful. Afte ther write call succeeded
- * the write index will be a the position after where this chunk of
- * data has been written to.
+/** Write some data to the server (for playback streams).
+ * If \a free_cb is non-NULL this routine is called when all data has
+ * been written out. An internal reference to the specified data is
+ * kept, the data is not copied. If NULL, the data is copied into an
+ * internal buffer.
+ *
+ * The client may freely seek around in the output buffer. For
+ * most applications it is typical to pass 0 and PA_SEEK_RELATIVE
+ * as values for the arguments \a offset and \a seek. After the write
+ * call succeeded the write index will be at the position after where
+ * this chunk of data has been written to.
  *
  * As an optimization for avoiding needless memory copies you may call
  * pa_stream_begin_write() before this call and then place your audio
@@ -503,17 +528,27 @@ int pa_stream_cancel_write(
 int pa_stream_write(
         pa_stream *p             /**< The stream to use */,
         const void *data         /**< The data to write */,
-        size_t nbytes            /**< The length of the data to write in bytes*/,
+        size_t nbytes            /**< The length of the data to write in bytes */,
         pa_free_cb_t free_cb     /**< A cleanup routine for the data or NULL to request an internal copy */,
         int64_t offset,          /**< Offset for seeking, must be 0 for upload streams */
         pa_seek_mode_t seek      /**< Seek mode, must be PA_SEEK_RELATIVE for upload streams */);
 
 /** Read the next fragment from the buffer (for recording streams).
- * data will point to the actual data and nbytes will contain the size
- * of the data in bytes (which can be less or more than a complete
- * fragment).  Use pa_stream_drop() to actually remove the data from
- * the buffer. If no data is available this will return a NULL
- * pointer */
+ * If there is data at the current read index, \a data will point to
+ * the actual data and \a nbytes will contain the size of the data in
+ * bytes (which can be less or more than a complete fragment).
+ *
+ * If there is no data at the current read index, it means that either
+ * the buffer is empty or it contains a hole (that is, the write index
+ * is ahead of the read index but there's no data where the read index
+ * points at). If the buffer is empty, \a data will be NULL and
+ * \a nbytes will be 0. If there is a hole, \a data will be NULL and
+ * \a nbytes will contain the length of the hole.
+ *
+ * Use pa_stream_drop() to actually remove the data from the buffer
+ * and move the read index forward. pa_stream_drop() should not be
+ * called if the buffer is empty, but it should be called if there is
+ * a hole. */
 int pa_stream_peek(
         pa_stream *p                 /**< The stream to use */,
         const void **data            /**< Pointer to pointer that will point to data */,
@@ -523,15 +558,16 @@ int pa_stream_peek(
  * calling pa_stream_peek(). */
 int pa_stream_drop(pa_stream *p);
 
-/** Return the number of bytes that may be written using pa_stream_write() */
+/** Return the number of bytes that may be written using pa_stream_write(). */
 size_t pa_stream_writable_size(pa_stream *p);
 
-/** Return the number of bytes that may be read using pa_stream_peek()*/
+/** Return the number of bytes that may be read using pa_stream_peek()*/
 size_t pa_stream_readable_size(pa_stream *p);
 
-/** Drain a playback stream. Use this for notification when the buffer
- * is empty. Please note that only one drain operation per stream may
- * be issued at a time. */
+/** Drain a playback stream.  Use this for notification when the
+ * playback buffer is empty after playing all the audio in the buffer.
+ * Please note that only one drain operation per stream may be issued
+ * at a time. */
 pa_operation* pa_stream_drain(pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
 
 /** Request a timing info structure update for a stream. Use
@@ -540,27 +576,32 @@ pa_operation* pa_stream_drain(pa_stream *s, pa_stream_success_cb_t cb, void *use
  * up values. */
 pa_operation* pa_stream_update_timing_info(pa_stream *p, pa_stream_success_cb_t cb, void *userdata);
 
-/** Set the callback function that is called whenever the state of the stream changes */
+/** Set the callback function that is called whenever the state of the stream changes. */
 void pa_stream_set_state_callback(pa_stream *s, pa_stream_notify_cb_t cb, void *userdata);
 
 /** Set the callback function that is called when new data may be
  * written to the stream. */
 void pa_stream_set_write_callback(pa_stream *p, pa_stream_request_cb_t cb, void *userdata);
 
-/** Set the callback function that is called when new data is available from the stream.
- * Return the number of bytes read.*/
+/** Set the callback function that is called when new data is available from the stream. */
 void pa_stream_set_read_callback(pa_stream *p, pa_stream_request_cb_t cb, void *userdata);
 
 /** Set the callback function that is called when a buffer overflow happens. (Only for playback streams) */
 void pa_stream_set_overflow_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
 
+/** Return at what position the latest underflow occurred, or -1 if this information is not
+ * known (e.g.\ if no underflow has occurred, or server is older than 1.0).
+ * Can be used inside the underflow callback to get information about the current underflow.
+ * (Only for playback streams) \since 1.0 */
+int64_t pa_stream_get_underflow_index(pa_stream *p);
+
 /** Set the callback function that is called when a buffer underflow happens. (Only for playback streams) */
 void pa_stream_set_underflow_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
 
 /** Set the callback function that is called when a the server starts
  * playback after an underrun or on initial startup. This only informs
  * that audio is flowing again, it is no indication that audio started
- * to reach the speakers already. (Only for playback streams). \since
+ * to reach the speakers already. (Only for playback streams) \since
  * 0.9.11 */
 void pa_stream_set_started_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
 
@@ -570,7 +611,7 @@ void pa_stream_set_started_callback(pa_stream *p, pa_stream_notify_cb_t cb, void
 void pa_stream_set_latency_update_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
 
 /** Set the callback function that is called whenever the stream is
- * moved to a different sink/source. Use pa_stream_get_device_name()or
+ * moved to a different sink/source. Use pa_stream_get_device_name() or
  * pa_stream_get_device_index() to query the new sink/source. This
  * notification is only generated when the server is at least
  * 0.9.8. \since 0.9.8 */
@@ -581,16 +622,16 @@ void pa_stream_set_moved_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *
  * pa_stream_is_suspended() to query the new suspend status. Please
  * note that the suspend status might also change when the stream is
  * moved between devices. Thus if you call this function you very
- * likely want to call pa_stream_set_moved_callback, too. This
+ * likely want to call pa_stream_set_moved_callback() too. This
  * notification is only generated when the server is at least
  * 0.9.8. \since 0.9.8 */
 void pa_stream_set_suspended_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
 
-/** Set the callback function that is called whenver a meta/policy
- * control event is received.\since 0.9.15 */
+/** Set the callback function that is called whenever a meta/policy
+ * control event is received. \since 0.9.15 */
 void pa_stream_set_event_callback(pa_stream *p, pa_stream_event_cb_t cb, void *userdata);
 
-/** Set the callback function that is called whenver the buffer
+/** Set the callback function that is called whenever the buffer
  * attributes on the server side change. Please note that the buffer
  * attributes can change when moving a stream to a different
  * sink/source too, hence if you use this callback you should use
@@ -598,30 +639,30 @@ void pa_stream_set_event_callback(pa_stream *p, pa_stream_event_cb_t cb, void *u
 void pa_stream_set_buffer_attr_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
 
 /** Pause (or resume) playback of this stream temporarily. Available
- * on both playback and recording streams. If b is 1 the stream is
- * paused. If b is 0 the stream is resumed. The pause/resume operation
+ * on both playback and recording streams. If \a b is 1 the stream is
+ * paused. If \a b is 0 the stream is resumed. The pause/resume operation
  * is executed as quickly as possible. If a cork is very quickly
- * followed by an uncork or the other way round this might not
+ * followed by an uncork or the other way round, this might not
  * actually have any effect on the stream that is output. You can use
  * pa_stream_is_corked() to find out whether the stream is currently
  * paused or not. Normally a stream will be created in uncorked
- * state. If you pass PA_STREAM_START_CORKED as flag during connection
- * of the stream it will be created in corked state. */
+ * state. If you pass PA_STREAM_START_CORKED as a flag when connecting
+ * the stream, it will be created in corked state. */
 pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, void *userdata);
 
-/** Flush the playback buffer of this stream. Most of the time you're
- * better off using the parameter delta of pa_stream_write() instead
- * of this function. Available on both playback and recording
- * streams. */
+/** Flush the playback buffer of this stream. This discards any audio data
+ * in the buffer.  Most of the time you're better off using the parameter
+ * delta of pa_stream_write() instead of this function. Available on both
+ * playback and recording streams. */
 pa_operation* pa_stream_flush(pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
 
-/** Reenable prebuffering as specified in the pa_buffer_attr
+/** Reenable prebuffering if specified in the pa_buffer_attr
  * structure. Available for playback streams only. */
 pa_operation* pa_stream_prebuf(pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
 
 /** Request immediate start of playback on this stream. This disables
- * prebuffering as specified in the pa_buffer_attr structure,
- * temporarily. Available for playback streams only. */
+ * prebuffering temporarily if specified in the pa_buffer_attr structure.
+ * Available for playback streams only. */
 pa_operation* pa_stream_trigger(pa_stream *s, pa_stream_success_cb_t cb, void *userdata);
 
 /** Rename the stream. */
@@ -632,48 +673,50 @@ pa_operation* pa_stream_set_name(pa_stream *s, const char *name, pa_stream_succe
  * pa_stream_get_timing_info().
  *
  * This function will usually only return new data if a timing info
- * update has been recieved. Only if timing interpolation has been
+ * update has been received. Only if timing interpolation has been
  * requested (PA_STREAM_INTERPOLATE_TIMING) the data from the last
  * timing update is used for an estimation of the current
  * playback/recording time based on the local time that passed since
  * the timing info structure has been acquired.
  *
  * The time value returned by this function is guaranteed to increase
- * monotonically.  (that means: the returned value is always greater
- * or equal to the value returned on the last call). This behaviour
+ * monotonically (the returned value is always greater
+ * or equal to the value returned by the last call). This behaviour
  * can be disabled by using PA_STREAM_NOT_MONOTONIC. This may be
- * desirable to deal better with bad estimations of transport
+ * desirable to better deal with bad estimations of transport
  * latencies, but may have strange effects if the application is not
  * able to deal with time going 'backwards'.
  *
  * The time interpolator activated by PA_STREAM_INTERPOLATE_TIMING
  * favours 'smooth' time graphs over accurate ones to improve the
  * smoothness of UI operations that are tied to the audio clock. If
- * accuracy is more important to you you might need to estimate your
+ * accuracy is more important to you, you might need to estimate your
  * timing based on the data from pa_stream_get_timing_info() yourself
  * or not work with interpolated timing at all and instead always
- * query on the server side for the most up to date timing with
+ * query the server side for the most up to date timing with
  * pa_stream_update_timing_info().
  *
  * If no timing information has been
- * recieved yet this call will return PA_ERR_NODATA. For more details
+ * received yet this call will return -PA_ERR_NODATA. For more details
  * see pa_stream_get_timing_info(). */
 int pa_stream_get_time(pa_stream *s, pa_usec_t *r_usec);
 
-/** Return the total stream latency. This function is based on
+/** Determine the total stream latency. This function is based on
  * pa_stream_get_time().
  *
- * In case the stream is a monitoring stream the result can be
- * negative, i.e. the captured samples are not yet played. In this
- * case *negative is set to 1.
+ * The latency is stored in \a *r_usec. In case the stream is a
+ * monitoring stream the result can be negative, i.e. the captured
+ * samples are not yet played. In this case \a *negative is set to 1.
+ *
+ * If no timing information has been received yet, this call will
+ * return -PA_ERR_NODATA. On success, it will return 0.
  *
- * If no timing information has been recieved yet this call will
- * return PA_ERR_NODATA. For more details see
- * pa_stream_get_timing_info() and pa_stream_get_time(). */
+ * For more details see pa_stream_get_timing_info() and
+ * pa_stream_get_time(). */
 int pa_stream_get_latency(pa_stream *s, pa_usec_t *r_usec, int *negative);
 
 /** Return the latest raw timing data structure. The returned pointer
- * points to an internal read-only instance of the timing
+ * refers to an internal read-only instance of the timing
  * structure. The user should make a copy of this structure if he
  * wants to modify it. An in-place update to this data structure may
  * be requested using pa_stream_update_timing_info().
@@ -681,11 +724,11 @@ int pa_stream_get_latency(pa_stream *s, pa_usec_t *r_usec, int *negative);
  * If no timing information has been received before (i.e. by
  * requesting pa_stream_update_timing_info() or by using
  * PA_STREAM_AUTO_TIMING_UPDATE), this function will fail with
- * PA_ERR_NODATA.
+ * -PA_ERR_NODATA.
  *
  * Please note that the write_index member field (and only this field)
  * is updated on each pa_stream_write() call, not just when a timing
- * update has been recieved. */
+ * update has been received. */
 const pa_timing_info* pa_stream_get_timing_info(pa_stream *s);
 
 /** Return a pointer to the stream's sample specification. */
@@ -694,13 +737,16 @@ const pa_sample_spec* pa_stream_get_sample_spec(pa_stream *s);
 /** Return a pointer to the stream's channel map. */
 const pa_channel_map* pa_stream_get_channel_map(pa_stream *s);
 
+/** Return a pointer to the stream's format. \since 1.0 */
+const pa_format_info* pa_stream_get_format_info(pa_stream *s);
+
 /** Return the per-stream server-side buffer metrics of the
- * stream. Only valid after the stream has been connected successfuly
+ * stream. Only valid after the stream has been connected successfully
  * and if the server is at least PulseAudio 0.9. This will return the
  * actual configured buffering metrics, which may differ from what was
  * requested during pa_stream_connect_record() or
  * pa_stream_connect_playback(). This call will always return the
- * actually per-stream server-side buffer metrics, regardless whether
+ * actual per-stream server-side buffer metrics, regardless whether
  * PA_STREAM_ADJUST_LATENCY is set or not. \since 0.9.0 */
 const pa_buffer_attr* pa_stream_get_buffer_attr(pa_stream *s);
 
@@ -716,16 +762,16 @@ pa_operation *pa_stream_set_buffer_attr(pa_stream *s, const pa_buffer_attr *attr
 
 /** Change the stream sampling rate during playback. You need to pass
  * PA_STREAM_VARIABLE_RATE in the flags parameter of
- * pa_stream_connect() if you plan to use this function. Only valid
+ * pa_stream_connect_playback() if you plan to use this function. Only valid
  * after the stream has been connected successfully and if the server
  * is at least PulseAudio 0.9.8. \since 0.9.8 */
 pa_operation *pa_stream_update_sample_rate(pa_stream *s, uint32_t rate, pa_stream_success_cb_t cb, void *userdata);
 
 /** Update the property list of the sink input/source output of this
  * stream, adding new entries. Please note that it is highly
- * recommended to set as much properties initially via
+ * recommended to set as many properties initially via
  * pa_stream_new_with_proplist() as possible instead a posteriori with
- * this function, since that information may then be used to route
+ * this function, since that information may be used to route
  * this stream to the right device. \since 0.9.11 */
 pa_operation *pa_stream_proplist_update(pa_stream *s, pa_update_mode_t mode, pa_proplist *p, pa_stream_success_cb_t cb, void *userdata);
 
@@ -734,13 +780,14 @@ pa_operation *pa_stream_proplist_update(pa_stream *s, pa_update_mode_t mode, pa_
 pa_operation *pa_stream_proplist_remove(pa_stream *s, const char *const keys[], pa_stream_success_cb_t cb, void *userdata);
 
 /** For record streams connected to a monitor source: monitor only a
- * very specific sink input of the sink. Thus function needs to be
+ * very specific sink input of the sink. This function needs to be
  * called before pa_stream_connect_record() is called. \since
  * 0.9.11 */
 int pa_stream_set_monitor_stream(pa_stream *s, uint32_t sink_input_idx);
 
-/** Return what has been set with pa_stream_set_monitor_stream()
- * ebfore. \since 0.9.11 */
+/** Return the sink input index previously set with
+ * pa_stream_set_monitor_stream().
+ * \since 0.9.11 */
 uint32_t pa_stream_get_monitor_stream(pa_stream *s);
 
 PA_C_DECL_END
index 203bc92..a6ad238 100644 (file)
 
 #include <stdio.h>
 
-#include <pulse/gccmacro.h>
-
 #include <pulsecore/macro.h>
 #include <pulsecore/pstream-util.h>
 
 #include "internal.h"
-
 #include "subscribe.h"
 
 void pa_command_subscribe_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
index 44ed24a..667a887 100644 (file)
  * The application sets the notification mask using pa_context_subscribe()
  * and the function that will be called whenever a notification occurs using
  * pa_context_set_subscribe_callback().
+ *
+ * The callback will be called with a \ref pa_subscription_event_type_t
+ * representing the event that caused the callback. Clients can examine what
+ * object changed using \ref PA_SUBSCRIPTION_EVENT_FACILITY_MASK. The actual
+ * event type can then be extracted with \ref PA_SUBSCRIPTION_EVENT_TYPE_MASK.
+ * Please note that the masked values are integers, not flags (so you will
+ * check the object/event type using a comparison not a binary AND). For
+ * example, the callback might look something like:
+ *
+@verbatim
+void my_subscription_callback(pa_context *c, pa_subscription_event_type_t t,
+                              uint32_t idx, void *userdata)
+{
+    if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE) {
+        if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
+            ... a source was added, let's do stuff! ...
+        }
+    }
+}
+@endverbatim
  */
 
 /** \file
- * Daemon introspection event subscription subsystem. */
+ * Daemon introspection event subscription subsystem.
+ *
+ * See also \subpage subscribe
+ */
 
 PA_C_DECL_BEGIN
 
index a2b98ce..aa56a92 100644 (file)
 #include <signal.h>
 #include <stdio.h>
 
-#ifdef HAVE_POLL_H
-#include <poll.h>
-#else
-#include <pulsecore/poll.h>
-#endif
-
 #include <pulse/xmalloc.h>
 #include <pulse/mainloop.h>
-#include <pulse/i18n.h>
 
+#include <pulsecore/i18n.h>
 #include <pulsecore/log.h>
-#include <pulsecore/hashmap.h>
 #include <pulsecore/thread.h>
 #include <pulsecore/mutex.h>
 #include <pulsecore/macro.h>
+#include <pulsecore/poll.h>
 
 #include "thread-mainloop.h"
 
 struct pa_threaded_mainloop {
     pa_mainloop *real_mainloop;
-    int n_waiting, n_waiting_for_accept;
+    volatile int n_waiting, n_waiting_for_accept;
 
     pa_thread* thread;
     pa_mutex* mutex;
@@ -72,7 +66,7 @@ static int poll_func(struct pollfd *ufds, unsigned long nfds, int timeout, void
      * avahi_simple_poll_quit() can succeed from another thread. */
 
     pa_mutex_unlock(mutex);
-    r = poll(ufds, nfds, timeout);
+    r = pa_poll(ufds, nfds, timeout);
     pa_mutex_lock(mutex);
 
     return r;
@@ -116,6 +110,7 @@ pa_threaded_mainloop *pa_threaded_mainloop_new(void) {
     pa_mainloop_set_poll_func(m->real_mainloop, poll_func, m->mutex);
 
     m->n_waiting = 0;
+    m->n_waiting_for_accept = 0;
 
     return m;
 }
@@ -145,7 +140,7 @@ int pa_threaded_mainloop_start(pa_threaded_mainloop *m) {
 
     pa_assert(!m->thread || !pa_thread_is_running(m->thread));
 
-    if (!(m->thread = pa_thread_new(thread, m)))
+    if (!(m->thread = pa_thread_new("threaded-ml", thread, m)))
         return -1;
 
     return 0;
@@ -185,6 +180,7 @@ void pa_threaded_mainloop_unlock(pa_threaded_mainloop *m) {
     pa_mutex_unlock(m->mutex);
 }
 
+/* Called with the lock taken */
 void pa_threaded_mainloop_signal(pa_threaded_mainloop *m, int wait_for_accept) {
     pa_assert(m);
 
@@ -198,6 +194,7 @@ void pa_threaded_mainloop_signal(pa_threaded_mainloop *m, int wait_for_accept) {
     }
 }
 
+/* Called with the lock taken */
 void pa_threaded_mainloop_wait(pa_threaded_mainloop *m) {
     pa_assert(m);
 
@@ -212,6 +209,7 @@ void pa_threaded_mainloop_wait(pa_threaded_mainloop *m) {
     m->n_waiting --;
 }
 
+/* Called with the lock taken */
 void pa_threaded_mainloop_accept(pa_threaded_mainloop *m) {
     pa_assert(m);
 
index 2cf496e..ff166f8 100644 (file)
@@ -155,7 +155,7 @@ PA_C_DECL_BEGIN
  * deal with that.
  *
  * The functions will not dead lock because the wait function will release
- * the lock before waiting and then regrab it once it has been signaled.
+ * the lock before waiting and then regrab it once it has been signalled.
  * For those of you familiar with threads, the behaviour is that of a
  * condition variable.
  *
@@ -207,10 +207,10 @@ PA_C_DECL_BEGIN
  * copy the contents of success, but for larger data structures this can be
  * wasteful.
  *
- * The difference here compared to the basic callback is the 1 sent to
- * pa_threaded_mainloop_signal() and the call to
+ * The difference here compared to the basic callback is the value 1 passed
+ * to pa_threaded_mainloop_signal() and the call to
  * pa_threaded_mainloop_accept(). What will happen is that
- * pa_threaded_mainloop_signal() will signal the main function and then stop.
+ * pa_threaded_mainloop_signal() will signal the main function and then wait.
  * The main function is then free to use the data in the callback until
  * pa_threaded_mainloop_accept() is called, which will allow the callback
  * to continue.
@@ -223,10 +223,10 @@ PA_C_DECL_BEGIN
  * \subsection async_subsec Asynchronous callbacks
  *
  * PulseAudio also has callbacks that are completely asynchronous, meaning
- * that they can be called at any time. The threading main loop API provides
+ * that they can be called at any time. The threaded main loop API provides
  * the locking mechanism to handle concurrent accesses, but nothing else.
  * Applications will have to handle communication from the callback to the
- * main program through some own system.
+ * main program through its own mechanisms.
  *
  * The callbacks that are completely asynchronous are:
  *
@@ -239,7 +239,10 @@ PA_C_DECL_BEGIN
  * A thread based event loop implementation based on pa_mainloop. The
  * event loop is run in a helper thread in the background. A few
  * synchronization primitives are available to access the objects
- * attached to the event loop safely. */
+ * attached to the event loop safely.
+ *
+ * See also \subpage threaded_mainloop
+ */
 
 /** An opaque threaded main loop object */
 typedef struct pa_threaded_mainloop pa_threaded_mainloop;
@@ -250,7 +253,7 @@ typedef struct pa_threaded_mainloop pa_threaded_mainloop;
 pa_threaded_mainloop *pa_threaded_mainloop_new(void);
 
 /** Free a threaded main loop object. If the event loop thread is
- * still running, it is terminated using pa_threaded_mainloop_stop()
+ * still running, terminate it with pa_threaded_mainloop_stop()
  * first. */
 void pa_threaded_mainloop_free(pa_threaded_mainloop* m);
 
@@ -274,13 +277,13 @@ void pa_threaded_mainloop_unlock(pa_threaded_mainloop *m);
 
 /** Wait for an event to be signalled by the event loop thread. You
  * can use this to pass data from the event loop thread to the main
- * thread in synchronized fashion. This function may not be called
+ * thread in synchronized fashion. This function may not be called
  * inside the event loop thread. Prior to this call the event loop
  * object needs to be locked using pa_threaded_mainloop_lock(). While
- * waiting the lock will be released, immediately before returning it
+ * waiting the lock will be released. Immediately before returning it
  * will be acquired again. This function may spuriously wake up even
- * without _signal() being called. You need to make sure to handle
- * that! */
+ * without pa_threaded_mainloop_signal() being called. You need to
+ * make sure to handle that! */
 void pa_threaded_mainloop_wait(pa_threaded_mainloop *m);
 
 /** Signal all threads waiting for a signalling event in
@@ -296,15 +299,16 @@ void pa_threaded_mainloop_signal(pa_threaded_mainloop *m, int wait_for_accept);
  * wait_for_accept value.  */
 void pa_threaded_mainloop_accept(pa_threaded_mainloop *m);
 
-/** Return the return value as specified with the main loop's quit() routine. */
+/** Return the return value as specified with the main loop's
+ * pa_mainloop_quit() routine. */
 int pa_threaded_mainloop_get_retval(pa_threaded_mainloop *m);
 
-/** Return the abstract main loop abstraction layer vtable for this
   main loop. No need of freeing the API as it is owned by the loop
   and it is destroyed when this dies */
+/** Return the main loop abstraction layer vtable for this main loop.
* There is no need to free this object as it is owned by the loop
* and is destroyed when the loop is freed. */
 pa_mainloop_api* pa_threaded_mainloop_get_api(pa_threaded_mainloop*m);
 
-/** Returns non-zero when called from withing the event loop thread. \since 0.9.7 */
+/** Returns non-zero when called from within the event loop thread. \since 0.9.7 */
 int pa_threaded_mainloop_in_thread(pa_threaded_mainloop *m);
 
 PA_C_DECL_END
index cde4417..a394dbe 100644 (file)
 #include <windows.h>
 #endif
 
-#include <pulsecore/winsock.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
 
 #include "timeval.h"
 
 struct timeval *pa_gettimeofday(struct timeval *tv) {
-#ifdef HAVE_GETTIMEOFDAY
     pa_assert(tv);
 
-    pa_assert_se(gettimeofday(tv, NULL) == 0);
-    return tv;
-#elif defined(OS_IS_WIN32)
+#if defined(OS_IS_WIN32)
     /*
      * Copied from implementation by Steven Edwards (LGPL).
      * Found on wine mailing list.
      */
-
 #if defined(_MSC_VER) || defined(__BORLANDC__)
 #define EPOCHFILETIME (116444736000000000i64)
 #else
 #define EPOCHFILETIME (116444736000000000LL)
 #endif
-
+{
     FILETIME ft;
     LARGE_INTEGER li;
     int64_t t;
 
-    pa_assert(tv);
-
     GetSystemTimeAsFileTime(&ft);
     li.LowPart  = ft.dwLowDateTime;
     li.HighPart = ft.dwHighDateTime;
@@ -69,11 +62,14 @@ struct timeval *pa_gettimeofday(struct timeval *tv) {
     t /= 10;                /* In microseconds */
     tv->tv_sec  = (time_t) (t / PA_USEC_PER_SEC);
     tv->tv_usec = (suseconds_t) (t % PA_USEC_PER_SEC);
-
-    return tv;
+}
+#elif defined(HAVE_GETTIMEOFDAY)
+    pa_assert_se(gettimeofday(tv, NULL) == 0);
 #else
 #error "Platform lacks gettimeofday() or equivalent function."
 #endif
+
+    return tv;
 }
 
 pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) {
@@ -82,7 +78,7 @@ pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) {
     pa_assert(a);
     pa_assert(b);
 
-    /* Check which whan is the earlier time and swap the two arguments if required. */
+    /* Check which is the earlier time and swap the two arguments if required. */
     if (PA_UNLIKELY(pa_timeval_cmp(a, b) < 0)) {
         const struct timeval *c;
         c = a;
index 3cea5d3..8f255f9 100644 (file)
@@ -72,13 +72,13 @@ int pa_timeval_cmp(const struct timeval *a, const struct timeval *b) PA_GCC_PURE
 /** Return the time difference between now and the specified timestamp */
 pa_usec_t pa_timeval_age(const struct timeval *tv);
 
-/** Add the specified time inmicroseconds to the specified timeval structure */
+/** Add the specified time in microseconds to the specified timeval structure */
 struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v);
 
-/** Subtract the specified time inmicroseconds to the specified timeval structure. \since 0.9.11 */
+/** Subtract the specified time in microseconds to the specified timeval structure. \since 0.9.11 */
 struct timeval* pa_timeval_sub(struct timeval *tv, pa_usec_t v);
 
-/** Store the specified uec value in the timeval struct. \since 0.9.7 */
+/** Store the specified usec value in the timeval struct. \since 0.9.7 */
 struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v);
 
 /** Load the specified tv value and return it in usec. \since 0.9.7 */
index fe7bcd2..773a1f8 100644 (file)
@@ -249,11 +249,16 @@ char* pa_locale_to_utf8 (const char *str) {
 
 char* pa_utf8_to_locale (const char *str) {
     pa_assert(str);
-    return NULL;
+
+    return pa_ascii_filter(str);
 }
 
 char* pa_locale_to_utf8 (const char *str) {
     pa_assert(str);
+
+    if (pa_utf8_valid(str))
+        return pa_xstrdup(str);
+
     return NULL;
 }
 
index b9f7495..2b5bd28 100644 (file)
@@ -28,7 +28,7 @@
 #include <pulse/version.h>
 
 /** \file
- * UTF8 Validation functions
+ * UTF-8 validation functions
  */
 
 PA_C_DECL_BEGIN
index 9440f5d..6656bc3 100644 (file)
 #include <pwd.h>
 #endif
 
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
 #ifdef HAVE_NETDB_H
 #include <netdb.h>
 #endif
 #include <sys/prctl.h>
 #endif
 
+#ifdef OS_IS_DARWIN
+#include <libgen.h>
+#include <sys/sysctl.h>
+#endif
+
 #include <pulse/xmalloc.h>
 #include <pulse/timeval.h>
 
-#include <pulsecore/winsock.h>
-#include <pulsecore/core-error.h>
-#include <pulsecore/log.h>
+#include <pulsecore/socket.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/usergroup.h>
@@ -79,11 +78,15 @@ char *pa_get_user_name(char *s, size_t l) {
     pa_assert(s);
     pa_assert(l > 0);
 
-    if ((p = (getuid() == 0 ? "root" : NULL)) ||
-        (p = getenv("USER")) ||
-        (p = getenv("LOGNAME")) ||
-        (p = getenv("USERNAME")))
-    {
+    p = NULL;
+#ifdef HAVE_GETUID
+    p = getuid() == 0 ? "root" : NULL;
+#endif
+    if (!p) p = getenv("USER");
+    if (!p) p = getenv("LOGNAME");
+    if (!p) p = getenv("USERNAME");
+
+    if (p) {
         name = pa_strlcpy(s, p, l);
     } else {
 #ifdef HAVE_PWD_H
@@ -128,9 +131,9 @@ char *pa_get_host_name(char *s, size_t l) {
 }
 
 char *pa_get_home_dir(char *s, size_t l) {
-    char *e, *dir;
-
+    char *e;
 #ifdef HAVE_PWD_H
+    char *dir;
     struct passwd *r;
 #endif
 
@@ -189,7 +192,18 @@ char *pa_get_binary_name(char *s, size_t l) {
             return s;
         }
     }
+#endif
+
+#ifdef __FreeBSD__
+    {
+        char *rp;
 
+        if ((rp = pa_readlink("/proc/curproc/file"))) {
+            pa_strlcpy(s, pa_path_get_filename(rp), l);
+            pa_xfree(rp);
+            return s;
+        }
+    }
 #endif
 
 #if defined(HAVE_SYS_PRCTL_H) && defined(PR_GET_NAME)
@@ -210,6 +224,27 @@ char *pa_get_binary_name(char *s, size_t l) {
     }
 #endif
 
+#ifdef OS_IS_DARWIN
+    {
+        int mib[] = { CTL_KERN, KERN_PROCARGS, getpid(), 0 };
+        size_t len, nmib = (sizeof(mib) / sizeof(mib[0])) - 1;
+        char *buf;
+
+        sysctl(mib, nmib, NULL, &len, NULL, 0);
+        buf = (char *) pa_xmalloc(len);
+
+        if (sysctl(mib, nmib, buf, &len, NULL, 0) == 0) {
+            pa_strlcpy(s, basename(buf), l);
+            pa_xfree(buf);
+            return s;
+        }
+
+        pa_xfree(buf);
+
+        /* fall thru */
+    }
+#endif /* OS_IS_DARWIN */
+
     errno = ENOENT;
     return NULL;
 }
index ad85653..e490d56 100644 (file)
@@ -26,7 +26,6 @@
 #include <stddef.h>
 
 #include <pulse/cdecl.h>
-#include <pulse/gccmacro.h>
 #include <pulse/version.h>
 
 /** \file
index c2c1f20..1be4c75 100644 (file)
@@ -35,7 +35,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() ("@PACKAGE_VERSION@")
+#define pa_get_headers_version() ("@PA_MAJOR@.@PA_MINOR@.0")
 
 /** Return the version of the library the current application is
  * linked to. */
@@ -57,8 +57,8 @@ const char* pa_get_library_version(void);
 /** The minor version of PA. \since 0.9.15 */
 #define PA_MINOR @PA_MINOR@
 
-/** The micro version of PA. \since 0.9.15 */
-#define PA_MICRO @PA_MICRO@
+/** The micro version of PA (will always be 0 from v1.0 onwards). \since 0.9.15 */
+#define PA_MICRO 0
 
 /** Evaluates to TRUE if the PulseAudio library version is equal or
  * newer than the specified. \since 0.9.16 */
index 2d2bba2..12db06b 100644 (file)
 
 #include <stdio.h>
 #include <string.h>
-
-#include <pulse/i18n.h>
+#include <math.h>
 
 #include <pulsecore/core-util.h>
+#include <pulsecore/i18n.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/sample-util.h>
 
@@ -79,7 +79,9 @@ pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v) {
     a->channels = (uint8_t) channels;
 
     for (i = 0; i < a->channels; i++)
-        a->values[i] = v;
+        /* Clamp in case there is stale data that exceeds the current
+         * PA_VOLUME_MAX */
+        a->values[i] = PA_CLAMP_VOLUME(v);
 
     return a;
 }
@@ -201,18 +203,18 @@ pa_volume_t pa_cvolume_min_mask(const pa_cvolume *a, const pa_channel_map *cm, p
 
 pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) {
 
-    pa_return_val_if_fail(a != PA_VOLUME_INVALID, PA_VOLUME_INVALID);
-    pa_return_val_if_fail(b != PA_VOLUME_INVALID, PA_VOLUME_INVALID);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(a), PA_VOLUME_INVALID);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(b), PA_VOLUME_INVALID);
 
     /* cbrt((a/PA_VOLUME_NORM)^3*(b/PA_VOLUME_NORM)^3)*PA_VOLUME_NORM = a*b/PA_VOLUME_NORM */
 
-    return (pa_volume_t) (((uint64_t) a * (uint64_t) b + (uint64_t) PA_VOLUME_NORM / 2ULL) / (uint64_t) PA_VOLUME_NORM);
+    return (pa_volume_t) PA_CLAMP_VOLUME((((uint64_t) a * (uint64_t) b + (uint64_t) PA_VOLUME_NORM / 2ULL) / (uint64_t) PA_VOLUME_NORM));
 }
 
 pa_volume_t pa_sw_volume_divide(pa_volume_t a, pa_volume_t b) {
 
-    pa_return_val_if_fail(a != PA_VOLUME_INVALID, PA_VOLUME_INVALID);
-    pa_return_val_if_fail(b != PA_VOLUME_INVALID, PA_VOLUME_INVALID);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(a), PA_VOLUME_INVALID);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(b), PA_VOLUME_INVALID);
 
     if (b <= PA_VOLUME_MUTED)
         return 0;
@@ -238,7 +240,7 @@ pa_volume_t pa_sw_volume_from_dB(double dB) {
 
 double pa_sw_volume_to_dB(pa_volume_t v) {
 
-    pa_return_val_if_fail(v != PA_VOLUME_INVALID, PA_DECIBEL_MININFTY);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(v), PA_DECIBEL_MININFTY);
 
     if (v <= PA_VOLUME_MUTED)
         return PA_DECIBEL_MININFTY;
@@ -261,13 +263,13 @@ pa_volume_t pa_sw_volume_from_linear(double v) {
      * same volume value! That's why we need the lround() below!
      */
 
-    return (pa_volume_t) lround(cbrt(v) * PA_VOLUME_NORM);
+    return (pa_volume_t) PA_CLAMP_VOLUME((uint64_t) lround(cbrt(v) * PA_VOLUME_NORM));
 }
 
 double pa_sw_volume_to_linear(pa_volume_t v) {
     double f;
 
-    pa_return_val_if_fail(v != PA_VOLUME_INVALID, 0.0);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(v), 0.0);
 
     if (v <= PA_VOLUME_MUTED)
         return 0.0;
@@ -317,7 +319,7 @@ char *pa_volume_snprint(char *s, size_t l, pa_volume_t v) {
 
     pa_init_i18n();
 
-    if (v == PA_VOLUME_INVALID) {
+    if (!PA_VOLUME_IS_VALID(v)) {
         pa_snprintf(s, l, _("(invalid)"));
         return s;
     }
@@ -367,14 +369,13 @@ char *pa_sw_volume_snprint_dB(char *s, size_t l, pa_volume_t v) {
 
     pa_init_i18n();
 
-    if (v == PA_VOLUME_INVALID) {
+    if (!PA_VOLUME_IS_VALID(v)) {
         pa_snprintf(s, l, _("(invalid)"));
         return s;
     }
 
     f = pa_sw_volume_to_dB(v);
-    pa_snprintf(s, l, "%0.2f dB",
-                isinf(f) < 0 || f <= PA_DECIBEL_MININFTY ?  -INFINITY : f);
+    pa_snprintf(s, l, "%0.2f dB", isinf(f) < 0 || f <= PA_DECIBEL_MININFTY ? -INFINITY : f);
 
     return s;
 }
@@ -384,7 +385,7 @@ int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v) {
     pa_assert(a);
 
     pa_return_val_if_fail(pa_cvolume_valid(a), 0);
-    pa_return_val_if_fail(v != PA_VOLUME_INVALID, 0);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(v), 0);
 
     for (c = 0; c < a->channels; c++)
         if (a->values[c] != v)
@@ -408,7 +409,7 @@ pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const
 
     dest->channels = (uint8_t) i;
 
-    return dest;
+   return dest;
 }
 
 pa_cvolume *pa_sw_cvolume_multiply_scalar(pa_cvolume *dest, const pa_cvolume *a, pa_volume_t b) {
@@ -418,7 +419,7 @@ pa_cvolume *pa_sw_cvolume_multiply_scalar(pa_cvolume *dest, const pa_cvolume *a,
     pa_assert(a);
 
     pa_return_val_if_fail(pa_cvolume_valid(a), NULL);
-    pa_return_val_if_fail(b != PA_VOLUME_INVALID, NULL);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(b), NULL);
 
     for (i = 0; i < a->channels; i++)
         dest->values[i] = pa_sw_volume_multiply(a->values[i], b);
@@ -453,7 +454,7 @@ pa_cvolume *pa_sw_cvolume_divide_scalar(pa_cvolume *dest, const pa_cvolume *a, p
     pa_assert(a);
 
     pa_return_val_if_fail(pa_cvolume_valid(a), NULL);
-    pa_return_val_if_fail(b != PA_VOLUME_INVALID, NULL);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(b), NULL);
 
     for (i = 0; i < a->channels; i++)
         dest->values[i] = pa_sw_volume_divide(a->values[i], b);
@@ -472,7 +473,7 @@ int pa_cvolume_valid(const pa_cvolume *v) {
         return 0;
 
     for (c = 0; c < v->channels; c++)
-        if (v->values[c] == PA_VOLUME_INVALID)
+        if (!PA_VOLUME_IS_VALID(v->values[c]))
             return 0;
 
     return 1;
@@ -655,9 +656,9 @@ pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, flo
     m = PA_MAX(left, right);
 
     if (new_balance <= 0) {
-        nright  = (new_balance + 1.0f) * m;
+        nright = (new_balance + 1.0f) * m;
         nleft = m;
-    } else  {
+    } else {
         nleft = (1.0f - new_balance) * m;
         nright = m;
     }
@@ -667,12 +668,12 @@ pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, flo
             if (left == 0)
                 v->values[c] = nleft;
             else
-                v->values[c] = (pa_volume_t) (((uint64_t) v->values[c] * (uint64_t) nleft) / (uint64_t) left);
+                v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) nleft) / (uint64_t) left);
         } else if (on_right(map->map[c])) {
             if (right == 0)
                 v->values[c] = nright;
             else
-                v->values[c] = (pa_volume_t) (((uint64_t) v->values[c] * (uint64_t) nright) / (uint64_t) right);
+                v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) nright) / (uint64_t) right);
         }
     }
 
@@ -686,7 +687,7 @@ pa_cvolume* pa_cvolume_scale(pa_cvolume *v, pa_volume_t max) {
     pa_assert(v);
 
     pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
-    pa_return_val_if_fail(max != PA_VOLUME_INVALID, NULL);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(max), NULL);
 
     t = pa_cvolume_max(v);
 
@@ -694,7 +695,7 @@ pa_cvolume* pa_cvolume_scale(pa_cvolume *v, pa_volume_t max) {
         return pa_cvolume_set(v, v->channels, max);
 
     for (c = 0; c < v->channels; c++)
-        v->values[c] = (pa_volume_t) (((uint64_t)  v->values[c] * (uint64_t) max) / (uint64_t) t);
+        v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) max) / (uint64_t) t);
 
     return v;
 }
@@ -705,7 +706,7 @@ pa_cvolume* pa_cvolume_scale_mask(pa_cvolume *v, pa_volume_t max, pa_channel_map
 
     pa_assert(v);
 
-    pa_return_val_if_fail(max != PA_VOLUME_INVALID, NULL);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(max), NULL);
 
     if (!cm)
         return pa_cvolume_scale(v, max);
@@ -718,7 +719,7 @@ pa_cvolume* pa_cvolume_scale_mask(pa_cvolume *v, pa_volume_t max, pa_channel_map
         return pa_cvolume_set(v, v->channels, max);
 
     for (c = 0; c < v->channels; c++)
-        v->values[c] = (pa_volume_t) (((uint64_t)  v->values[c] * (uint64_t) max) / (uint64_t) t);
+        v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) max) / (uint64_t) t);
 
     return v;
 }
@@ -796,9 +797,9 @@ pa_cvolume* pa_cvolume_set_fade(pa_cvolume *v, const pa_channel_map *map, float
     m = PA_MAX(front, rear);
 
     if (new_fade <= 0) {
-        nfront  = (new_fade + 1.0f) * m;
+        nfront = (new_fade + 1.0f) * m;
         nrear = m;
-    } else  {
+    } else {
         nrear = (1.0f - new_fade) * m;
         nfront = m;
     }
@@ -808,12 +809,12 @@ pa_cvolume* pa_cvolume_set_fade(pa_cvolume *v, const pa_channel_map *map, float
             if (front == 0)
                 v->values[c] = nfront;
             else
-                v->values[c] = (pa_volume_t) (((uint64_t) v->values[c] * (uint64_t) nfront) / (uint64_t) front);
+                v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) nfront) / (uint64_t) front);
         } else if (on_rear(map->map[c])) {
             if (rear == 0)
                 v->values[c] = nrear;
             else
-                v->values[c] = (pa_volume_t) (((uint64_t) v->values[c] * (uint64_t) nrear) / (uint64_t) rear);
+                v->values[c] = (pa_volume_t) PA_CLAMP_VOLUME(((uint64_t) v->values[c] * (uint64_t) nrear) / (uint64_t) rear);
         }
     }
 
@@ -834,7 +835,7 @@ pa_cvolume* pa_cvolume_set_position(
 
     pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(cv, map), NULL);
     pa_return_val_if_fail(t < PA_CHANNEL_POSITION_MAX, NULL);
-    pa_return_val_if_fail(v != PA_VOLUME_INVALID, NULL);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(v), NULL);
 
     for (c = 0; c < map->channels; c++)
         if (map->map[c] == t) {
@@ -885,31 +886,35 @@ pa_cvolume* pa_cvolume_merge(pa_cvolume *dest, const pa_cvolume *a, const pa_cvo
     return dest;
 }
 
-pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc) {
+pa_cvolume* pa_cvolume_inc_clamp(pa_cvolume *v, pa_volume_t inc, pa_volume_t limit) {
     pa_volume_t m;
 
     pa_assert(v);
 
     pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
-    pa_return_val_if_fail(inc != PA_VOLUME_INVALID, NULL);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(inc), NULL);
 
     m = pa_cvolume_max(v);
 
-    if (m >= PA_VOLUME_MAX - inc)
-        m = PA_VOLUME_MAX;
+    if (m >= limit - inc)
+        m = limit;
     else
         m += inc;
 
     return pa_cvolume_scale(v, m);
 }
 
+pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc){
+    return pa_cvolume_inc_clamp(v, inc, PA_VOLUME_MAX);
+}
+
 pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec) {
     pa_volume_t m;
 
     pa_assert(v);
 
     pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
-    pa_return_val_if_fail(dec != PA_VOLUME_INVALID, NULL);
+    pa_return_val_if_fail(PA_VOLUME_IS_VALID(dec), NULL);
 
     m = pa_cvolume_max(v);
 
@@ -920,3 +925,66 @@ pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec) {
 
     return pa_cvolume_scale(v, m);
 }
+
+#ifdef PA_EXT_USE_VOLUME_FADING
+void pa_cvolume_fading_set(pa_cvolume *v, pa_cvolume_fading_info *f) {
+    pa_assert(v);
+    pa_assert(f);
+
+    strncpy(v->fading_token, PA_VOLUME_FADING_TOKEN_STR, PA_VOLUME_FADING_TOKEN_LEN);
+    v->fading_info = f;
+}
+
+void pa_cvolume_fading_unset(pa_cvolume *v) {
+    pa_assert(v);
+
+    memset(v->fading_token, 0x00, PA_VOLUME_FADING_TOKEN_LEN);
+    v->fading_info = NULL;
+}
+
+int pa_cvolume_fading_valid(const pa_cvolume *v) {
+    pa_assert(v);
+
+    if (strncmp(v->fading_token, PA_VOLUME_FADING_TOKEN_STR, PA_VOLUME_FADING_TOKEN_LEN) != 0)
+        return 0;
+
+    if (!v->fading_info)
+        return 0;
+
+    return 1;
+}
+
+void pa_cvolume_fading_update(pa_cvolume *dest, pa_cvolume *a)
+{
+    pa_assert(dest);
+    pa_assert(a);
+
+    if (pa_cvolume_fading_valid(a))
+        pa_cvolume_fading_set(dest, a->fading_info);
+    else
+        pa_cvolume_fading_unset(dest);
+}
+
+int pa_cvolume_fading_multiply(pa_cvolume *v, pa_cvolume *f)
+{
+    unsigned i;
+
+    pa_assert(v);
+    pa_assert(f);
+
+    if (!pa_cvolume_fading_valid(f))
+        return 0;
+
+    if (f->fading_info->multiply)
+        return 0;
+
+    for (i = 0; i < v->channels && i < f->channels; i++) {
+        f->fading_info->cur_values[i] = pa_sw_volume_multiply(v->values[i], f->fading_info->cur_values[i]);
+        f->fading_info->dst_values[i] = pa_sw_volume_multiply(v->values[i], f->fading_info->dst_values[i]);
+    }
+
+    f->fading_info->multiply = 1;
+
+    return 1;
+}
+#endif
index c964020..74aa8f4 100644 (file)
@@ -37,7 +37,7 @@
  * \section overv_sec Overview
  *
  * Sinks, sources, sink inputs and samples can all have their own volumes.
- * To deal with these, The PulseAudio libray contains a number of functions
+ * To deal with these, The PulseAudio library contains a number of functions
  * that ease handling.
  *
  * The basic volume type in PulseAudio is the \ref pa_volume_t type. Most of
@@ -71,7 +71,7 @@
  * \section conv_sec Convenience Functions
  *
  * To handle the pa_cvolume structure, the PulseAudio library provides a
- * number of convenienc functions:
+ * number of convenience functions:
  *
  * \li pa_cvolume_valid() - Tests if a pa_cvolume structure is valid.
  * \li pa_cvolume_equal() - Tests if two pa_cvolume structures are identical.
  *                             structure are muted.
  * \li pa_cvolume_is_norm() - Tests if all channels of a pa_cvolume structure
  *                            are at a normal volume.
- * \li pa_cvolume_set() - Set all channels of a pa_cvolume structure to a
- *                        certain volume.
- * \li pa_cvolume_reset() - Set all channels of a pa_cvolume structure to a
- *                          normal volume.
- * \li pa_cvolume_mute() - Set all channels of a pa_cvolume structure to a
- *                         muted volume.
+ * \li pa_cvolume_set() - Set the first n channels of a pa_cvolume structure to
+ *                        certain volume.
+ * \li pa_cvolume_reset() - Set the first n channels of a pa_cvolume structure
+ *                          to a normal volume.
+ * \li pa_cvolume_mute() - Set the first n channels of a pa_cvolume structure
+ *                         to a muted volume.
  * \li pa_cvolume_avg() - Return the average volume of all channels.
  * \li pa_cvolume_snprint() - Pretty print a pa_cvolume structure.
  */
 
 /** \file
- * Constants and routines for volume handling */
+ * Constants and routines for volume handling
+ *
+ * See also \subpage volume
+ */
 
 PA_C_DECL_BEGIN
 
@@ -110,15 +113,44 @@ typedef uint32_t pa_volume_t;
 #define PA_VOLUME_MUTED ((pa_volume_t) 0U)
 
 /** Maximum valid volume we can store. \since 0.9.15 */
-#define PA_VOLUME_MAX ((pa_volume_t) UINT32_MAX-1)
+#define PA_VOLUME_MAX ((pa_volume_t) UINT32_MAX/2)
+
+/** Recommended maximum volume to show in user facing UIs.
+ * Note: UIs should deal gracefully with volumes greater than this value
+ * and not cause feedback loops etc. - i.e. if the volume is more than
+ * this, the UI should not limit it and push the limited value back to
+ * the server. \since 0.9.23 */
+#define PA_VOLUME_UI_MAX (pa_sw_volume_from_dB(+11.0))
 
 /** Special 'invalid' volume. \since 0.9.16 */
 #define PA_VOLUME_INVALID ((pa_volume_t) UINT32_MAX)
 
+#ifdef PA_EXT_USE_VOLUME_FADING
+#define PA_VOLUME_FADING_TOKEN_STR "fadi"
+#define PA_VOLUME_FADING_TOKEN_LEN 4
+#define PA_VOLUME_FADING_OPERATION_FRAMES 5
+typedef struct pa_cvolume_fading_info {
+    unsigned multiply;
+    size_t remain_frames;
+    pa_volume_t cur_values[PA_CHANNELS_MAX];
+    pa_volume_t dst_values[PA_CHANNELS_MAX];
+} pa_cvolume_fading_info;
+#endif
+
+/** Check if volume is valid. \since 1.0 */
+#define PA_VOLUME_IS_VALID(v) ((v) <= PA_VOLUME_MAX)
+
+/** Clamp volume to the permitted range. \since 1.0 */
+#define PA_CLAMP_VOLUME(v) (PA_CLAMP_UNLIKELY((v), PA_VOLUME_MUTED, PA_VOLUME_MAX))
+
 /** A structure encapsulating a per-channel volume */
 typedef struct pa_cvolume {
     uint8_t channels;                     /**< Number of channels */
-    pa_volume_t values[PA_CHANNELS_MAX];  /**< Per-channel volume  */
+    pa_volume_t values[PA_CHANNELS_MAX];  /**< Per-channel volume */
+#ifdef PA_EXT_USE_VOLUME_FADING
+    char fading_token[PA_VOLUME_FADING_TOKEN_LEN];
+    pa_cvolume_fading_info *fading_info;
+#endif
 } pa_cvolume;
 
 /** Return non-zero when *a == *b */
@@ -129,13 +161,13 @@ int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b) PA_GCC_PURE;
  * pa_cvolume_valid() will fail for it. \since 0.9.13 */
 pa_cvolume* pa_cvolume_init(pa_cvolume *a);
 
-/** Set the volume of all channels to PA_VOLUME_NORM */
+/** Set the volume of the first n channels to PA_VOLUME_NORM */
 #define pa_cvolume_reset(a, n) pa_cvolume_set((a), (n), PA_VOLUME_NORM)
 
-/** Set the volume of all channels to PA_VOLUME_MUTED */
+/** Set the volume of the first n channels to PA_VOLUME_MUTED */
 #define pa_cvolume_mute(a, n) pa_cvolume_set((a), (n), PA_VOLUME_MUTED)
 
-/** Set the volume of all channels to the specified parameter */
+/** Set the volume of the specified number of channels to the volume v */
 pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v);
 
 /** Maximum length of the strings returned by
@@ -149,7 +181,7 @@ pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v);
 char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c);
 
 /** Maximum length of the strings returned by
- * pa_cvolume_snprint_dB(). Please note that this value can change with
+ * pa_sw_cvolume_snprint_dB(). Please note that this value can change with
  * any release without warning and without being considered API or ABI
  * breakage. You should not use this definition anywhere where it
  * might become part of an ABI. \since 0.9.13 */
@@ -169,7 +201,7 @@ char *pa_sw_cvolume_snprint_dB(char *s, size_t l, const pa_cvolume *c);
 char *pa_volume_snprint(char *s, size_t l, pa_volume_t v);
 
 /** Maximum length of the strings returned by
- * pa_volume_snprint_dB(). Please note that this value can change with
+ * pa_sw_volume_snprint_dB(). Please note that this value can change with
  * any release without warning and without being considered API or ABI
  * breakage. You should not use this definition anywhere where it
  * might become part of an ABI. \since 0.9.15 */
@@ -259,7 +291,8 @@ pa_volume_t pa_sw_volume_from_dB(double f) PA_GCC_CONST;
 /** Convert a volume to a decibel value (amplitude, not power). This is only valid for software volumes! */
 double pa_sw_volume_to_dB(pa_volume_t v) PA_GCC_CONST;
 
-/** Convert a linear factor to a volume. This is only valid for software volumes! */
+/** Convert a linear factor to a volume.  0.0 and less is muted while
+ * 1.0 is PA_VOLUME_NORM.  This is only valid for software volumes! */
 pa_volume_t pa_sw_volume_from_linear(double v) PA_GCC_CONST;
 
 /** Convert a volume to a linear factor. This is only valid for software volumes! */
@@ -268,7 +301,7 @@ double pa_sw_volume_to_linear(pa_volume_t v) PA_GCC_CONST;
 #ifdef INFINITY
 #define PA_DECIBEL_MININFTY ((double) -INFINITY)
 #else
-/** This floor value is used as minus infinity when using pa_volume_{to,from}_dB(). */
+/** This floor value is used as minus infinity when using pa_sw_volume_to_dB() / pa_sw_volume_from_dB(). */
 #define PA_DECIBEL_MININFTY ((double) -200.0)
 #endif
 
@@ -301,14 +334,14 @@ float pa_cvolume_get_balance(const pa_cvolume *v, const pa_channel_map *map) PA_
  * pa_channel_map_can_balance(). \since 0.9.15 */
 pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, float new_balance);
 
-/** Calculate a 'fade' value (i.e. 'balance' between front and rear)
+/** Calculate a 'fade' value (i.e.\ 'balance' between front and rear)
  * for the specified volume with the specified channel map. The return
  * value will range from -1.0f (rear) to +1.0f (left). If no fade
  * value is applicable to this channel map the return value will
  * always be 0.0f. See pa_channel_map_can_fade(). \since 0.9.15 */
 float pa_cvolume_get_fade(const pa_cvolume *v, const pa_channel_map *map) PA_GCC_PURE;
 
-/** Adjust the 'fade' value (i.e. 'balance' between front and rear)
+/** Adjust the 'fade' value (i.e.\ 'balance' between front and rear)
  * for the specified volume with the specified channel map. v will be
  * modified in place and returned. The balance is a value between
  * -1.0f and +1.0f. This operation might not be reversible! Also,
@@ -348,14 +381,26 @@ pa_volume_t pa_cvolume_get_position(pa_cvolume *cv, const pa_channel_map *map, p
  * and dest may point to the same structure. \since 0.9.16 */
 pa_cvolume* pa_cvolume_merge(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b);
 
+/** Increase the volume passed in by 'inc', but not exceeding 'limit'.
+ * The proportions between the channels are kept. \since 0.9.19 */
+pa_cvolume* pa_cvolume_inc_clamp(pa_cvolume *v, pa_volume_t inc, pa_volume_t limit);
+
 /** Increase the volume passed in by 'inc'. The proportions between
  * the channels are kept. \since 0.9.16 */
 pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc);
 
-/** Increase the volume passed in by 'inc'. The proportions between
+/** Decrease the volume passed in by 'dec'. The proportions between
  * the channels are kept. \since 0.9.16 */
 pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec);
 
+#ifdef PA_EXT_USE_VOLUME_FADING
+void pa_cvolume_fading_set(pa_cvolume *v, pa_cvolume_fading_info *f);
+void pa_cvolume_fading_unset(pa_cvolume *v);
+int pa_cvolume_fading_valid(const pa_cvolume *v);
+void pa_cvolume_fading_update(pa_cvolume *dest, pa_cvolume *a);
+int pa_cvolume_fading_multiply(pa_cvolume *v, pa_cvolume *f);
+#endif
+
 PA_C_DECL_END
 
 #endif
similarity index 75%
rename from src/pulsecore/inet_ntop.c
rename to src/pulsecore/arpa-inet.c
index 012a1a0..09570bb 100644 (file)
 #include <config.h>
 #endif
 
-#include <stdio.h>
-#include <errno.h>
-
-#ifndef HAVE_INET_NTOP
+#if !defined(HAVE_ARPA_INET_H) && defined(OS_IS_WIN32)
 
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
+#include <errno.h>
 
-#include "winsock.h"
+#include <pulsecore/macro.h>
+#include <pulsecore/socket.h>
+#include <pulsecore/core-util.h>
 
-#include "inet_ntop.h"
+#include "arpa-inet.h"
 
 const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) {
     struct in_addr *in = (struct in_addr*)src;
@@ -42,7 +39,8 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) {
     struct in6_addr *in6 = (struct in6_addr*)src;
 #endif
 
-    assert(src && dst);
+    pa_assert(src);
+    pa_assert(dst);
 
     switch (af) {
     case AF_INET:
@@ -80,4 +78,31 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) {
     return dst;
 }
 
-#endif /* INET_NTOP */
+int inet_pton(int af, const char *src, void *dst) {
+    struct in_addr *in = (struct in_addr*)dst;
+#ifdef HAVE_IPV6
+    struct in6_addr *in6 = (struct in6_addr*)dst;
+#endif
+
+    pa_assert(src);
+    pa_assert(dst);
+
+    switch (af) {
+    case AF_INET:
+        in->s_addr = inet_addr(src);
+        if (in->s_addr == INADDR_NONE)
+            return 0;
+        break;
+#ifdef HAVE_IPV6
+    case AF_INET6:
+        /* FIXME */
+#endif
+    default:
+        errno = EAFNOSUPPORT;
+        return -1;
+    }
+
+    return 1;
+}
+
+#endif
diff --git a/src/pulsecore/arpa-inet.h b/src/pulsecore/arpa-inet.h
new file mode 100644 (file)
index 0000000..303c905
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef fooarpa_inethfoo
+#define fooarpa_inethfoo
+
+
+#if defined(HAVE_ARPA_INET_H)
+
+#include <arpa/inet.h>
+
+#elif defined(OS_IS_WIN32)
+
+/* On Windows winsock2.h (here included via pulsecore/socket.h) provides most of the functionality of arpa/inet.h, except for
+ * the inet_ntop and inet_pton functions, which are implemented here. */
+
+#include <pulsecore/socket.h>
+
+const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
+
+int inet_pton(int af, const char *src, void *dst);
+
+#endif
+
+
+#endif
index b0804f7..408416c 100644 (file)
 
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/atomic.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/log.h>
-#include <pulsecore/thread.h>
 #include <pulsecore/semaphore.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/core-util.h>
+#include <pulsecore/mutex.h>
 #include <pulsecore/flist.h>
 
 #include "asyncmsgq.h"
@@ -321,7 +319,7 @@ void pa_asyncmsgq_write_after_poll(pa_asyncmsgq *a) {
 int pa_asyncmsgq_dispatch(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *memchunk) {
 
     if (object)
-        return object->process_msg(object, code, userdata, offset, memchunk);
+        return object->process_msg(object, code, userdata, offset, pa_memchunk_isset(memchunk) ? memchunk : NULL);
 
     return 0;
 }
index 072ef02..8c2d58a 100644 (file)
@@ -26,6 +26,8 @@
 #include <unistd.h>
 #include <errno.h>
 
+#include <pulse/xmalloc.h>
+
 #include <pulsecore/atomic.h>
 #include <pulsecore/log.h>
 #include <pulsecore/thread.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/llist.h>
 #include <pulsecore/flist.h>
-#include <pulse/xmalloc.h>
+#include <pulsecore/fdsem.h>
 
 #include "asyncq.h"
-#include "fdsem.h"
 
 #define ASYNCQ_SIZE 256
 
@@ -206,7 +207,7 @@ void pa_asyncq_post(pa_asyncq*l, void *p) {
     /* OK, we couldn't push anything in the queue. So let's queue it
      * locally and push it later */
 
-    if (pa_log_ratelimit())
+    if (pa_log_ratelimit(PA_LOG_WARN))
         pa_log_warn("q overrun, queuing locally");
 
     if (!(q = pa_flist_pop(PA_STATIC_FLIST_GET(localq))))
index e6847ab..47ccbf0 100644 (file)
@@ -48,8 +48,9 @@ void pa_asyncq_free(pa_asyncq* q, pa_free_cb_t free_cb);
 void* pa_asyncq_pop(pa_asyncq *q, pa_bool_t wait);
 int pa_asyncq_push(pa_asyncq *q, void *p, pa_bool_t wait);
 
-/* Similar to pa_asyncq_push(), but if the queue is full, postpone it
- * locally and delay until pa_asyncq_before_poll_post() */
+/* Similar to pa_asyncq_push(), but if the queue is full, postpone the
+ * appending of the item locally and delay until
+ * pa_asyncq_before_poll_post() is called. */
 void pa_asyncq_post(pa_asyncq*l, void *p);
 
 /* For the reading side */
index 119c445..bca9576 100644 (file)
@@ -180,11 +180,115 @@ static inline pa_bool_t pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, v
     return r == old_p;
 }
 
+#elif defined(__FreeBSD__)
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <machine/atomic.h>
+
+#if __FreeBSD_version < 600000
+#if defined(__i386__) || defined(__amd64__)
+#if defined(__amd64__)
+#define atomic_load_acq_64      atomic_load_acq_long
+#endif
+static inline u_int atomic_fetchadd_int(volatile u_int *p, u_int v) {
+    __asm __volatile(
+            "   " __XSTRING(MPLOCKED) "         "
+            "   xaddl   %0, %1 ;        "
+            "# atomic_fetchadd_int"
+            : "+r" (v),
+            "=m" (*p)
+            : "m" (*p));
+
+    return (v);
+}
+#elif defined(__sparc64__)
+#define atomic_load_acq_64      atomic_load_acq_long
+#define atomic_fetchadd_int     atomic_add_int
+#elif defined(__ia64__)
+#define atomic_load_acq_64      atomic_load_acq_long
+static inline uint32_t
+atomic_fetchadd_int(volatile uint32_t *p, uint32_t v) {
+    uint32_t value;
+
+    do {
+        value = *p;
+    } while (!atomic_cmpset_32(p, value, value + v));
+    return (value);
+}
+#endif
+#endif
+
+typedef struct pa_atomic {
+    volatile unsigned long value;
+} pa_atomic_t;
+
+#define PA_ATOMIC_INIT(v) { .value = (v) }
+
+static inline int pa_atomic_load(const pa_atomic_t *a) {
+    return (int) atomic_load_acq_int((unsigned int *) &a->value);
+}
+
+static inline void pa_atomic_store(pa_atomic_t *a, int i) {
+    atomic_store_rel_int((unsigned int *) &a->value, i);
+}
+
+static inline int pa_atomic_add(pa_atomic_t *a, int i) {
+    return atomic_fetchadd_int((unsigned int *) &a->value, i);
+}
+
+static inline int pa_atomic_sub(pa_atomic_t *a, int i) {
+    return atomic_fetchadd_int((unsigned int *) &a->value, -(i));
+}
+
+static inline int pa_atomic_inc(pa_atomic_t *a) {
+    return atomic_fetchadd_int((unsigned int *) &a->value, 1);
+}
+
+static inline int pa_atomic_dec(pa_atomic_t *a) {
+    return atomic_fetchadd_int((unsigned int *) &a->value, -1);
+}
+
+static inline int pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) {
+    return atomic_cmpset_int((unsigned int *) &a->value, old_i, new_i);
+}
+
+typedef struct pa_atomic_ptr {
+    volatile unsigned long value;
+} pa_atomic_ptr_t;
+
+#define PA_ATOMIC_PTR_INIT(v) { .value = (unsigned long) (v) }
+
+static inline void* pa_atomic_ptr_load(const pa_atomic_ptr_t *a) {
+#ifdef atomic_load_acq_64
+    return (void*) atomic_load_acq_ptr((unsigned long *) &a->value);
+#else
+    return (void*) atomic_load_acq_ptr((unsigned int *) &a->value);
+#endif
+}
+
+static inline void pa_atomic_ptr_store(pa_atomic_ptr_t *a, void *p) {
+#ifdef atomic_load_acq_64
+    atomic_store_rel_ptr(&a->value, (unsigned long) p);
+#else
+    atomic_store_rel_ptr((unsigned int *) &a->value, (unsigned int) p);
+#endif
+}
+
+static inline int pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* new_p) {
+#ifdef atomic_load_acq_64
+    return atomic_cmpset_ptr(&a->value, (unsigned long) old_p, (unsigned long) new_p);
+#else
+    return atomic_cmpset_ptr((unsigned int *) &a->value, (unsigned int) old_p, (unsigned int) new_p);
+#endif
+}
+
 #elif defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__))
 
 #warn "The native atomic operations implementation for AMD64 has not been tested thoroughly. libatomic_ops is known to not work properly on AMD64 and your gcc version is too old for the gcc-builtin atomic ops support. You have three options now: test the native atomic operations implementation for AMD64, fix libatomic_ops, or upgrade your GCC."
 
-/* Addapted from glibc */
+/* Adapted from glibc */
 
 typedef struct pa_atomic {
     volatile int value;
@@ -387,7 +491,7 @@ static inline pa_bool_t pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, v
 /* See file arch/arm/kernel/entry-armv.S in your kernel sources for more
    information about these functions. The arm kernel helper functions first
    appeared in 2.6.16.
-   Apply --disable-atomic-arm-linux-helpers flag to confugure if you prefere
+   Apply --disable-atomic-arm-linux-helpers flag to configure if you prefer
    inline asm implementation or you have an obsolete Linux kernel.
 */
 /* Memory barrier */
index fb38ffa..4f543ab 100644 (file)
@@ -39,7 +39,7 @@ void pa_aupdate_write_end(pa_aupdate *a);
 
 /* Will return 0, or 1, depending which copy of the data the caller
  * should modify. Each time called this will return the opposite of
- * the previous pa_aupdate_write_begin()/pa_aupdate_write_swap()
+ * the previous pa_aupdate_write_begin() / pa_aupdate_write_swap()
  * call. Should only be called between pa_aupdate_write_begin() and
  * pa_aupdate_write_end() */
 unsigned pa_aupdate_write_swap(pa_aupdate *a);
@@ -47,10 +47,10 @@ unsigned pa_aupdate_write_swap(pa_aupdate *a);
 /*
  * This infrastructure allows lock-free updates of arbitrary data
  * structures in an rcu'ish way: two copies of the data structure
- * should be exisiting. One side ('the reader') has read access to one
+ * should be existing. One side ('the reader') has read access to one
  * of the two data structure at a time. It does not have to lock it,
  * however it needs to signal that it is using it/stopped using
- * it. The other side ('the writer') modifes the second data structure,
+ * it. The other side ('the writer') modifies the second data structure,
  * and then atomically swaps the two data structures, followed by a
  * modification of the other one.
  *
index 2f45eca..97ea351 100644 (file)
@@ -26,7 +26,6 @@
 #include <sys/types.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/util.h>
 
 #include <pulsecore/refcnt.h>
 #include <pulsecore/macro.h>
@@ -43,7 +42,7 @@ struct pa_auth_cookie {
     size_t size;
 };
 
-pa_auth_cookie* pa_auth_cookie_get(pa_core *core, const char *cn, size_t size) {
+pa_auth_cookie* pa_auth_cookie_get(pa_core *core, const char *cn, pa_bool_t create, size_t size) {
     pa_auth_cookie *c;
     char *t;
 
@@ -70,7 +69,7 @@ pa_auth_cookie* pa_auth_cookie_get(pa_core *core, const char *cn, size_t size) {
 
     pa_assert_se(pa_shared_set(core, t, c) >= 0);
 
-    if (pa_authkey_load_auto(cn, (uint8_t*) c + PA_ALIGN(sizeof(pa_auth_cookie)), size) < 0) {
+    if (pa_authkey_load_auto(cn, create, (uint8_t*) c + PA_ALIGN(sizeof(pa_auth_cookie)), size) < 0) {
         pa_auth_cookie_unref(c);
         return NULL;
     }
index 3db40bc..5f871b1 100644 (file)
@@ -26,7 +26,7 @@
 
 typedef struct pa_auth_cookie pa_auth_cookie;
 
-pa_auth_cookie* pa_auth_cookie_get(pa_core *c, const char *cn, size_t size);
+pa_auth_cookie* pa_auth_cookie_get(pa_core *c, const char *cn, pa_bool_t create, size_t size);
 pa_auth_cookie* pa_auth_cookie_ref(pa_auth_cookie *c);
 void pa_auth_cookie_unref(pa_auth_cookie *c);
 
index 15613e2..fdf49de 100644 (file)
 #include <string.h>
 #include <errno.h>
 #include <stdio.h>
-#include <inttypes.h>
 #include <stdlib.h>
-#include <time.h>
-#include <limits.h>
 #include <sys/stat.h>
 
 #include <pulse/util.h>
@@ -56,7 +53,10 @@ static int generate(int fd, void *ret_data, size_t length) {
     pa_random(ret_data, length);
 
     lseek(fd, (off_t) 0, SEEK_SET);
-    (void) ftruncate(fd, (off_t) 0);
+    if (ftruncate(fd, (off_t) 0) < 0) {
+        pa_log("Failed to truncate cookie file: %s", pa_cstrerror(errno));
+        return -1;
+    }
 
     if ((r = pa_loop_write(fd, ret_data, length, NULL)) < 0 || (size_t) r != length) {
         pa_log("Failed to write cookie file: %s", pa_cstrerror(errno));
@@ -70,13 +70,9 @@ static int generate(int fd, void *ret_data, size_t length) {
 #define O_BINARY 0
 #endif
 
-#ifndef O_NOCTTY
-#define O_NOCTTY 0
-#endif
-
-/* Load an euthorization cookie from file fn and store it in data. If
+/* Load an authorization cookie from file fn and store it in data. If
  * the cookie file doesn't exist, create it */
-static int load(const char *fn, void *data, size_t length) {
+static int load(const char *fn, pa_bool_t create, void *data, size_t length) {
     int fd = -1;
     int writable = 1;
     int unlock = 0, ret = -1;
@@ -86,9 +82,12 @@ static int load(const char *fn, void *data, size_t length) {
     pa_assert(data);
     pa_assert(length > 0);
 
-    if ((fd = open(fn, O_RDWR|O_CREAT|O_BINARY|O_NOCTTY, S_IRUSR|S_IWUSR)) < 0) {
+    if (create)
+        pa_make_secure_parent_dir(fn, pa_in_system_mode() ? 0755U : 0700U, -1, -1, FALSE);
+
+    if ((fd = pa_open_cloexec(fn, (create ? O_RDWR|O_CREAT : O_RDONLY)|O_BINARY, S_IRUSR|S_IWUSR)) < 0) {
 
-        if (errno != EACCES || (fd = open(fn, O_RDONLY|O_BINARY|O_NOCTTY)) < 0) {
+        if (!create || errno != EACCES || (fd = open(fn, O_RDONLY|O_BINARY)) < 0) {
             pa_log_warn("Failed to open cookie file '%s': %s", fn, pa_cstrerror(errno));
             goto finish;
         } else
@@ -133,14 +132,14 @@ finish:
 }
 
 /* Load a cookie from a cookie file. If the file doesn't exist, create it. */
-int pa_authkey_load(const char *path, void *data, size_t length) {
+int pa_authkey_load(const char *path, pa_bool_t create, void *data, size_t length) {
     int ret;
 
     pa_assert(path);
     pa_assert(data);
     pa_assert(length > 0);
 
-    if ((ret = load(path, data, length)) < 0)
+    if ((ret = load(path, create, data, length)) < 0)
         pa_log_warn("Failed to load authorization key '%s': %s", path, (ret < 0) ? pa_cstrerror(errno) : "File corrupt");
 
     return ret;
@@ -155,7 +154,7 @@ static char *normalize_path(const char *fn) {
 #ifndef OS_IS_WIN32
     if (fn[0] != '/') {
 #else
-    if (strlen(fn) < 3 || !isalpha(fn[0]) || fn[1] != ':' || fn[2] != '\\') {
+    if (strlen(fn) < 3 || !IsCharAlpha(fn[0]) || fn[1] != ':' || fn[2] != '\\') {
 #endif
         char *homedir, *s;
 
@@ -173,7 +172,7 @@ static char *normalize_path(const char *fn) {
 
 /* Load a cookie from a file in the home directory. If the specified
  * path starts with /, use it as absolute path instead. */
-int pa_authkey_load_auto(const char *fn, void *data, size_t length) {
+int pa_authkey_load_auto(const char *fn, pa_bool_t create, void *data, size_t length) {
     char *p;
     int ret;
 
@@ -184,7 +183,7 @@ int pa_authkey_load_auto(const char *fn, void *data, size_t length) {
     if (!(p = normalize_path(fn)))
         return -2;
 
-    ret = pa_authkey_load(p, data, length);
+    ret = pa_authkey_load(p, create, data, length);
     pa_xfree(p);
 
     return ret;
@@ -204,7 +203,7 @@ int pa_authkey_save(const char *fn, const void *data, size_t length) {
     if (!(p = normalize_path(fn)))
         return -2;
 
-    if ((fd = open(p, O_RDWR|O_CREAT|O_NOCTTY, S_IRUSR|S_IWUSR)) < 0) {
+    if ((fd = pa_open_cloexec(p, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) < 0) {
         pa_log_warn("Failed to open cookie file '%s': %s", fn, pa_cstrerror(errno));
         goto finish;
     }
index 8301db1..22ec990 100644 (file)
@@ -24,8 +24,8 @@
 
 #include <sys/types.h>
 
-int pa_authkey_load(const char *path, void *data, size_t len);
-int pa_authkey_load_auto(const char *fn, void *data, size_t length);
+int pa_authkey_load(const char *path, pa_bool_t create, void *data, size_t len);
+int pa_authkey_load_auto(const char *fn, pa_bool_t create, void *data, size_t length);
 
 int pa_authkey_save(const char *path, const void *data, size_t length);
 
index f1f08bc..997d81f 100644 (file)
@@ -26,7 +26,6 @@
 #include <pulse/timeval.h>
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 
 #include "avahi-wrap.h"
index 2f0a3af..7cf45df 100644 (file)
@@ -34,6 +34,7 @@
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/namereg.h>
+#include <pulsecore/device-port.h>
 
 #include "card.h"
 
@@ -43,12 +44,14 @@ pa_card_profile *pa_card_profile_new(const char *name, const char *description,
     pa_assert(name);
 
     c = pa_xmalloc(PA_ALIGN(sizeof(pa_card_profile)) + extra);
+    c->card = NULL;
     c->name = pa_xstrdup(name);
     c->description = pa_xstrdup(description);
 
     c->priority = 0;
     c->n_sinks = c->n_sources = 0;
     c->max_sink_channels = c->max_source_channels = 0;
+    c->available = PA_AVAILABLE_UNKNOWN;
 
     return c;
 }
@@ -61,12 +64,33 @@ void pa_card_profile_free(pa_card_profile *c) {
     pa_xfree(c);
 }
 
+void pa_card_profile_set_available(pa_card_profile *c, pa_available_t available) {
+    pa_core *core;
+
+    pa_assert(c);
+    pa_assert(c->card); /* Modify member variable directly during creation instead of using this function */
+
+    if (c->available == available)
+        return;
+
+    c->available = available;
+    pa_log_debug("Setting card %s profile %s to availability status %s", c->card->name, c->name,
+                 available == PA_AVAILABLE_YES ? "yes" : available == PA_AVAILABLE_NO ? "no" : "unknown");
+
+    /* Post subscriptions to the card which owns us */
+    pa_assert_se(core = c->card->core);
+    pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, c->card->index);
+
+    pa_hook_fire(&core->hooks[PA_CORE_HOOK_CARD_PROFILE_AVAILABLE_CHANGED], c);
+}
+
 pa_card_new_data* pa_card_new_data_init(pa_card_new_data *data) {
     pa_assert(data);
 
     memset(data, 0, sizeof(*data));
     data->proplist = pa_proplist_new();
-
+    data->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    data->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
     return data;
 }
 
@@ -77,6 +101,19 @@ void pa_card_new_data_set_name(pa_card_new_data *data, const char *name) {
     data->name = pa_xstrdup(name);
 }
 
+void pa_card_add_profile(pa_card *c, pa_card_profile *profile) {
+    pa_assert(c);
+    pa_assert(profile);
+
+    /* take ownership of the profile */
+    pa_assert_se(pa_hashmap_put(c->profiles, profile->name, profile) >= 0);
+    profile->card = c;
+
+    pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, c->index);
+
+    pa_hook_fire(&c->core->hooks[PA_CORE_HOOK_CARD_PROFILE_ADDED], profile);
+}
+
 void pa_card_new_data_set_profile(pa_card_new_data *data, const char *profile) {
     pa_assert(data);
 
@@ -90,14 +127,11 @@ void pa_card_new_data_done(pa_card_new_data *data) {
 
     pa_proplist_free(data->proplist);
 
-    if (data->profiles) {
-        pa_card_profile *c;
+    if (data->profiles)
+        pa_hashmap_free(data->profiles, (pa_free_cb_t) pa_card_profile_free);
 
-        while ((c = pa_hashmap_steal_first(data->profiles)))
-            pa_card_profile_free(c);
-
-        pa_hashmap_free(data->profiles, NULL, NULL);
-    }
+    if (data->ports)
+        pa_hashmap_free(data->ports, (pa_free_cb_t) pa_device_port_unref);
 
     pa_xfree(data->name);
     pa_xfree(data->active_profile);
@@ -106,10 +140,15 @@ void pa_card_new_data_done(pa_card_new_data *data) {
 pa_card *pa_card_new(pa_core *core, pa_card_new_data *data) {
     pa_card *c;
     const char *name;
+    void *state;
+    pa_card_profile *profile;
+    pa_device_port *port;
 
     pa_core_assert_ref(core);
     pa_assert(data);
     pa_assert(data->name);
+    pa_assert(data->profiles);
+    pa_assert(!pa_hashmap_isempty(data->profiles));
 
     c = pa_xnew(pa_card, 1);
 
@@ -137,23 +176,28 @@ pa_card *pa_card_new(pa_core *core, pa_card_new_data *data) {
 
     /* As a minor optimization we just steal the list instead of
      * copying it here */
-    c->profiles = data->profiles;
+    pa_assert_se(c->profiles = data->profiles);
     data->profiles = NULL;
+    pa_assert_se(c->ports = data->ports);
+    data->ports = NULL;
+
+    PA_HASHMAP_FOREACH(profile, c->profiles, state)
+        profile->card = c;
+
+    PA_HASHMAP_FOREACH(port, c->ports, state)
+        port->card = c;
 
     c->active_profile = NULL;
     c->save_profile = FALSE;
 
-    if (data->active_profile && c->profiles)
+    if (data->active_profile)
         if ((c->active_profile = pa_hashmap_get(c->profiles, data->active_profile)))
             c->save_profile = data->save_profile;
 
-    if (!c->active_profile && c->profiles) {
-        void *state;
-        pa_card_profile *p;
-
-        PA_HASHMAP_FOREACH(p, c->profiles, state)
-            if (!c->active_profile || p->priority > c->active_profile->priority)
-                c->active_profile = p;
+    if (!c->active_profile) {
+        PA_HASHMAP_FOREACH(profile, c->profiles, state)
+            if (!c->active_profile || profile->priority > c->active_profile->priority)
+                c->active_profile = profile;
     }
 
     c->userdata = NULL;
@@ -191,18 +235,14 @@ void pa_card_free(pa_card *c) {
     pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_REMOVE, c->index);
 
     pa_assert(pa_idxset_isempty(c->sinks));
-    pa_idxset_free(c->sinks, NULL, NULL);
+    pa_idxset_free(c->sinks, NULL);
     pa_assert(pa_idxset_isempty(c->sources));
-    pa_idxset_free(c->sources, NULL, NULL);
-
-    if (c->profiles) {
-        pa_card_profile *p;
+    pa_idxset_free(c->sources, NULL);
 
-        while ((p = pa_hashmap_steal_first(c->profiles)))
-            pa_card_profile_free(p);
+    pa_hashmap_free(c->ports, (pa_free_cb_t) pa_device_port_unref);
 
-        pa_hashmap_free(c->profiles, NULL, NULL);
-    }
+    if (c->profiles)
+        pa_hashmap_free(c->profiles, (pa_free_cb_t) pa_card_profile_free);
 
     pa_proplist_free(c->proplist);
     pa_xfree(c->driver);
@@ -213,6 +253,7 @@ void pa_card_free(pa_card *c) {
 int pa_card_set_profile(pa_card *c, const char *name, pa_bool_t save) {
     pa_card_profile *profile;
     int r;
+
     pa_assert(c);
 
     if (!c->set_profile) {
@@ -220,7 +261,7 @@ int pa_card_set_profile(pa_card *c, const char *name, pa_bool_t save) {
         return -PA_ERR_NOTIMPLEMENTED;
     }
 
-    if (!c->profiles)
+    if (!name)
         return -PA_ERR_NOENTITY;
 
     if (!(profile = pa_hashmap_get(c->profiles, name)))
@@ -241,6 +282,8 @@ int pa_card_set_profile(pa_card *c, const char *name, pa_bool_t save) {
     c->active_profile = profile;
     c->save_profile = save;
 
+    pa_hook_fire(&c->core->hooks[PA_CORE_HOOK_CARD_PROFILE_CHANGED], c);
+
     return 0;
 }
 
@@ -253,14 +296,14 @@ int pa_card_suspend(pa_card *c, pa_bool_t suspend, pa_suspend_cause_t cause) {
     pa_assert(c);
     pa_assert(cause != 0);
 
-    for (sink = pa_idxset_first(c->sinks, &idx); sink; sink = pa_idxset_next(c->sinks, &idx)) {
+    PA_IDXSET_FOREACH(sink, c->sinks, idx) {
         int r;
 
         if ((r = pa_sink_suspend(sink, suspend, cause)) < 0)
             ret = r;
     }
 
-    for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) {
+    PA_IDXSET_FOREACH(source, c->sources, idx) {
         int r;
 
         if ((r = pa_source_suspend(source, suspend, cause)) < 0)
index 2d691b6..32deb7b 100644 (file)
@@ -29,11 +29,21 @@ typedef struct pa_card pa_card;
 #include <pulsecore/module.h>
 #include <pulsecore/idxset.h>
 
+/* This enum replaces pa_port_available_t (defined in pulse/def.h) for
+ * internal use, so make sure both enum types stay in sync. */
+typedef enum pa_available {
+    PA_AVAILABLE_UNKNOWN = 0,
+    PA_AVAILABLE_NO = 1,
+    PA_AVAILABLE_YES = 2,
+} pa_available_t;
+
 typedef struct pa_card_profile {
+    pa_card *card;
     char *name;
     char *description;
 
     unsigned priority;
+    pa_available_t available; /* PA_AVAILABLE_UNKNOWN, PA_AVAILABLE_NO or PA_AVAILABLE_YES */
 
     /* We probably want to have different properties later on here */
     unsigned n_sinks;
@@ -63,6 +73,8 @@ struct pa_card {
     pa_hashmap *profiles;
     pa_card_profile *active_profile;
 
+    pa_hashmap *ports;
+
     pa_bool_t save_profile:1;
 
     void *userdata;
@@ -80,6 +92,8 @@ typedef struct pa_card_new_data {
     pa_hashmap *profiles;
     char *active_profile;
 
+    pa_hashmap *ports;
+
     pa_bool_t namereg_fail:1;
 
     pa_bool_t save_profile:1;
@@ -88,6 +102,9 @@ typedef struct pa_card_new_data {
 pa_card_profile *pa_card_profile_new(const char *name, const char *description, size_t extra);
 void pa_card_profile_free(pa_card_profile *c);
 
+/* The profile's available status has changed */
+void pa_card_profile_set_available(pa_card_profile *c, pa_available_t available);
+
 pa_card_new_data *pa_card_new_data_init(pa_card_new_data *data);
 void pa_card_new_data_set_name(pa_card_new_data *data, const char *name);
 void pa_card_new_data_set_profile(pa_card_new_data *data, const char *profile);
@@ -96,6 +113,8 @@ void pa_card_new_data_done(pa_card_new_data *data);
 pa_card *pa_card_new(pa_core *c, pa_card_new_data *data);
 void pa_card_free(pa_card *c);
 
+void pa_card_add_profile(pa_card *c, pa_card_profile *profile);
+
 int pa_card_set_profile(pa_card *c, const char *name, pa_bool_t save);
 
 int pa_card_suspend(pa_card *c, pa_bool_t suspend, pa_suspend_cause_t cause);
index b57919a..f5489d6 100644 (file)
 #include <errno.h>
 #include <unistd.h>
 #include <ltdl.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <time.h>
+#include <fcntl.h>
+#include <ctype.h>
 
 #include <pulse/xmalloc.h>
 #include <pulse/error.h>
@@ -45,7 +50,6 @@
 #include <pulsecore/namereg.h>
 #include <pulsecore/cli-text.h>
 #include <pulsecore/core-scache.h>
-#include <pulsecore/sample-util.h>
 #include <pulsecore/sound-file.h>
 #include <pulsecore/play-memchunk.h>
 #include <pulsecore/sound-file-stream.h>
@@ -53,6 +57,7 @@
 #include <pulsecore/core-util.h>
 #include <pulsecore/core-error.h>
 #include <pulsecore/modinfo.h>
+#include <pulsecore/dynarray.h>
 
 #include "cli-command.h"
 
@@ -93,10 +98,12 @@ static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa
 static int pa_cli_command_describe(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_sink_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
+static int pa_cli_command_source_output_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_sink_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_source_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_sink_input_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
+static int pa_cli_command_source_output_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_sink_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
@@ -116,6 +123,7 @@ static int pa_cli_command_vacuum(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa
 static int pa_cli_command_suspend_sink(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
+static int pa_cli_command_log_target(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_log_level(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_log_meta(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_log_time(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
@@ -127,63 +135,70 @@ static int pa_cli_command_update_source_output_proplist(pa_core *c, pa_tokenizer
 static int pa_cli_command_card_profile(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_sink_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_source_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
+static int pa_cli_command_port_offset(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
+static int pa_cli_command_dump_volumes(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 
 /* A method table for all available commands */
 
 static const struct command commands[] = {
-    { "exit",                    pa_cli_command_exit,               "Terminate the daemon",         1 },
     { "help",                    pa_cli_command_help,               "Show this help",               1 },
     { "list-modules",            pa_cli_command_modules,            "List loaded modules",          1 },
+    { "list-cards",              pa_cli_command_cards,              "List cards",                   1 },
     { "list-sinks",              pa_cli_command_sinks,              "List loaded sinks",            1 },
     { "list-sources",            pa_cli_command_sources,            "List loaded sources",          1 },
     { "list-clients",            pa_cli_command_clients,            "List loaded clients",          1 },
     { "list-sink-inputs",        pa_cli_command_sink_inputs,        "List sink inputs",             1 },
     { "list-source-outputs",     pa_cli_command_source_outputs,     "List source outputs",          1 },
-    { "list-cards",              pa_cli_command_cards,              "List cards",                   1 },
     { "stat",                    pa_cli_command_stat,               "Show memory block statistics", 1 },
     { "info",                    pa_cli_command_info,               "Show comprehensive status",    1 },
     { "ls",                      pa_cli_command_info,               NULL,                           1 },
     { "list",                    pa_cli_command_info,               NULL,                           1 },
     { "load-module",             pa_cli_command_load,               "Load a module (args: name, arguments)", 3},
-    { "unload-module",           pa_cli_command_unload,             "Unload a module (args: index)", 2},
+    { "unload-module",           pa_cli_command_unload,             "Unload a module (args: index|name)", 2},
     { "describe-module",         pa_cli_command_describe,           "Describe a module (arg: name)", 2},
     { "set-sink-volume",         pa_cli_command_sink_volume,        "Set the volume of a sink (args: index|name, volume)", 3},
-    { "set-sink-input-volume",   pa_cli_command_sink_input_volume,  "Set the volume of a sink input (args: index, volume)", 3},
     { "set-source-volume",       pa_cli_command_source_volume,      "Set the volume of a source (args: index|name, volume)", 3},
     { "set-sink-mute",           pa_cli_command_sink_mute,          "Set the mute switch of a sink (args: index|name, bool)", 3},
-    { "set-sink-input-mute",     pa_cli_command_sink_input_mute,    "Set the mute switch of a sink input (args: index, bool)", 3},
     { "set-source-mute",         pa_cli_command_source_mute,        "Set the mute switch of a source (args: index|name, bool)", 3},
+    { "set-sink-input-volume",   pa_cli_command_sink_input_volume,  "Set the volume of a sink input (args: index, volume)", 3},
+    { "set-source-output-volume",pa_cli_command_source_output_volume,"Set the volume of a source output (args: index, volume)", 3},
+    { "set-sink-input-mute",     pa_cli_command_sink_input_mute,    "Set the mute switch of a sink input (args: index, bool)", 3},
+    { "set-source-output-mute",  pa_cli_command_source_output_mute, "Set the mute switch of a source output (args: index, bool)", 3},
+    { "set-default-sink",        pa_cli_command_sink_default,       "Set the default sink (args: index|name)", 2},
+    { "set-default-source",      pa_cli_command_source_default,     "Set the default source (args: index|name)", 2},
+    { "set-card-profile",        pa_cli_command_card_profile,       "Change the profile of a card (args: index|name, profile-name)", 3},
+    { "set-sink-port",           pa_cli_command_sink_port,          "Change the port of a sink (args: index|name, port-name)", 3},
+    { "set-source-port",         pa_cli_command_source_port,        "Change the port of a source (args: index|name, port-name)", 3},
+    { "set-port-latency-offset", pa_cli_command_port_offset,        "Change the latency of a port (args: card-index|card-name, port-name, latency-offset)", 4},
+    { "suspend-sink",            pa_cli_command_suspend_sink,       "Suspend sink (args: index|name, bool)", 3},
+    { "suspend-source",          pa_cli_command_suspend_source,     "Suspend source (args: index|name, bool)", 3},
+    { "suspend",                 pa_cli_command_suspend,            "Suspend all sinks and all sources (args: bool)", 2},
+    { "move-sink-input",         pa_cli_command_move_sink_input,    "Move sink input to another sink (args: index, sink)", 3},
+    { "move-source-output",      pa_cli_command_move_source_output, "Move source output to another source (args: index, source)", 3},
     { "update-sink-proplist",    pa_cli_command_update_sink_proplist, "Update the properties of a sink (args: index|name, properties)", 3},
     { "update-source-proplist",  pa_cli_command_update_source_proplist, "Update the properties of a source (args: index|name, properties)", 3},
     { "update-sink-input-proplist", pa_cli_command_update_sink_input_proplist, "Update the properties of a sink input (args: index, properties)", 3},
-    { "update-source-output-proplist", pa_cli_command_update_source_output_proplist, "Update the properties of a source_output (args: index, properties)", 3},
-    { "set-default-sink",        pa_cli_command_sink_default,       "Set the default sink (args: index|name)", 2},
-    { "set-default-source",      pa_cli_command_source_default,     "Set the default source (args: index|name)", 2},
-    { "kill-client",             pa_cli_command_kill_client,        "Kill a client (args: index)", 2},
-    { "kill-sink-input",         pa_cli_command_kill_sink_input,    "Kill a sink input (args: index)", 2},
-    { "kill-source-output",      pa_cli_command_kill_source_output, "Kill a source output (args: index)", 2},
+    { "update-source-output-proplist", pa_cli_command_update_source_output_proplist, "Update the properties of a source output (args: index, properties)", 3},
     { "list-samples",            pa_cli_command_scache_list,        "List all entries in the sample cache", 1},
     { "play-sample",             pa_cli_command_scache_play,        "Play a sample from the sample cache (args: name, sink|index)", 3},
     { "remove-sample",           pa_cli_command_scache_remove,      "Remove a sample from the sample cache (args: name)", 2},
     { "load-sample",             pa_cli_command_scache_load,        "Load a sound file into the sample cache (args: name, filename)", 3},
     { "load-sample-lazy",        pa_cli_command_scache_load,        "Lazily load a sound file into the sample cache (args: name, filename)", 3},
     { "load-sample-dir-lazy",    pa_cli_command_scache_load_dir,    "Lazily load all files in a directory into the sample cache (args: pathname)", 2},
-    { "play-file",               pa_cli_command_play_file,          "Play a sound file (args: filename, sink|index)", 3},
-    { "dump",                    pa_cli_command_dump,               "Dump daemon configuration", 1},
-    { "shared",                  pa_cli_command_list_shared_props,  NULL, 1},
-    { "move-sink-input",         pa_cli_command_move_sink_input,    "Move sink input to another sink (args: index, sink)", 3},
-    { "move-source-output",      pa_cli_command_move_source_output, "Move source output to another source (args: index, source)", 3},
-    { "vacuum",                  pa_cli_command_vacuum,             NULL, 1},
-    { "suspend-sink",            pa_cli_command_suspend_sink,       "Suspend sink (args: index|name, bool)", 3},
-    { "suspend-source",          pa_cli_command_suspend_source,     "Suspend source (args: index|name, bool)", 3},
-    { "suspend",                 pa_cli_command_suspend,            "Suspend all sinks and all sources (args: bool)", 2},
-    { "set-card-profile",        pa_cli_command_card_profile,       "Change the profile of a card (args: index, name)", 3},
-    { "set-sink-port",           pa_cli_command_sink_port,          "Change the port of a sink (args: index, name)", 3},
-    { "set-source-port",         pa_cli_command_source_port,        "Change the port of a source (args: index, name)", 3},
+    { "kill-client",             pa_cli_command_kill_client,        "Kill a client (args: index)", 2},
+    { "kill-sink-input",         pa_cli_command_kill_sink_input,    "Kill a sink input (args: index)", 2},
+    { "kill-source-output",      pa_cli_command_kill_source_output, "Kill a source output (args: index)", 2},
+    { "set-log-target",          pa_cli_command_log_target,         "Change the log target (args: null,auto,syslog,stderr,file:PATH)", 2},
     { "set-log-level",           pa_cli_command_log_level,          "Change the log level (args: numeric level)", 2},
     { "set-log-meta",            pa_cli_command_log_meta,           "Show source code location in log messages (args: bool)", 2},
     { "set-log-time",            pa_cli_command_log_time,           "Show timestamps in log messages (args: bool)", 2},
     { "set-log-backtrace",       pa_cli_command_log_backtrace,      "Show backtrace in log messages (args: frames)", 2},
+    { "play-file",               pa_cli_command_play_file,          "Play a sound file (args: filename, sink|index)", 3},
+    { "dump",                    pa_cli_command_dump,               "Dump daemon configuration", 1},
+    { "dump-volumes",            pa_cli_command_dump_volumes,       "Debug: Show the state of all volumes", 1 },
+    { "shared",                  pa_cli_command_list_shared_props,  "Debug: Show shared properties", 1},
+    { "exit",                    pa_cli_command_exit,               "Terminate the daemon",         1 },
+    { "vacuum",                  pa_cli_command_vacuum,             NULL, 1},
     { NULL, NULL, NULL, 0 }
 };
 
@@ -329,7 +344,7 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
     char ss[PA_SAMPLE_SPEC_SNPRINT_MAX];
     char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
     char bytes[PA_BYTES_SNPRINT_MAX];
-    const pa_mempool_stat *stat;
+    const pa_mempool_stat *mstat;
     unsigned k;
     pa_sink *def_sink;
     pa_source *def_source;
@@ -348,23 +363,23 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
     pa_assert(buf);
     pa_assert(fail);
 
-    stat = pa_mempool_get_stat(c->mempool);
+    mstat = pa_mempool_get_stat(c->mempool);
 
     pa_strbuf_printf(buf, "Memory blocks currently allocated: %u, size: %s.\n",
-                     (unsigned) pa_atomic_load(&stat->n_allocated),
-                     pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&stat->allocated_size)));
+                     (unsigned) pa_atomic_load(&mstat->n_allocated),
+                     pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&mstat->allocated_size)));
 
     pa_strbuf_printf(buf, "Memory blocks allocated during the whole lifetime: %u, size: %s.\n",
-                     (unsigned) pa_atomic_load(&stat->n_accumulated),
-                     pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&stat->accumulated_size)));
+                     (unsigned) pa_atomic_load(&mstat->n_accumulated),
+                     pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&mstat->accumulated_size)));
 
     pa_strbuf_printf(buf, "Memory blocks imported from other processes: %u, size: %s.\n",
-                     (unsigned) pa_atomic_load(&stat->n_imported),
-                     pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&stat->imported_size)));
+                     (unsigned) pa_atomic_load(&mstat->n_imported),
+                     pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&mstat->imported_size)));
 
     pa_strbuf_printf(buf, "Memory blocks exported to other processes: %u, size: %s.\n",
-                     (unsigned) pa_atomic_load(&stat->n_exported),
-                     pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&stat->exported_size)));
+                     (unsigned) pa_atomic_load(&mstat->n_exported),
+                     pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_atomic_load(&mstat->exported_size)));
 
     pa_strbuf_printf(buf, "Total sample cache size: %s.\n",
                      pa_bytes_snprint(bytes, sizeof(bytes), (unsigned) pa_scache_total_size(c)));
@@ -386,8 +401,8 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
         pa_strbuf_printf(buf,
                          "Memory blocks of type %s: %u allocated/%u accumulated.\n",
                          type_table[k],
-                         (unsigned) pa_atomic_load(&stat->n_allocated_by_type[k]),
-                         (unsigned) pa_atomic_load(&stat->n_accumulated_by_type[k]));
+                         (unsigned) pa_atomic_load(&mstat->n_allocated_by_type[k]),
+                         (unsigned) pa_atomic_load(&mstat->n_accumulated_by_type[k]));
 
     return 0;
 }
@@ -435,7 +450,7 @@ static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa
     pa_module *m;
     uint32_t idx;
     const char *i;
-    char *e;
+    pa_bool_t unloaded = FALSE;
 
     pa_core_assert_ref(c);
     pa_assert(t);
@@ -443,17 +458,31 @@ static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa
     pa_assert(fail);
 
     if (!(i = pa_tokenizer_get(t, 1))) {
-        pa_strbuf_puts(buf, "You need to specify the module index.\n");
+        pa_strbuf_puts(buf, "You need to specify the module index or name.\n");
         return -1;
     }
 
-    idx = (uint32_t) strtoul(i, &e, 10);
-    if (*e || !(m = pa_idxset_get_by_index(c->modules, idx))) {
-        pa_strbuf_puts(buf, "Invalid module index.\n");
-        return -1;
+    if (pa_atou(i, &idx) >= 0) {
+        if (!(m = pa_idxset_get_by_index(c->modules, idx))) {
+            pa_strbuf_puts(buf, "Invalid module index.\n");
+            return -1;
+        }
+
+        pa_module_unload_request(m, FALSE);
+
+    } else {
+        PA_IDXSET_FOREACH(m, c->modules, idx)
+            if (pa_streq(i, m->name)) {
+                unloaded = TRUE;
+                pa_module_unload_request(m, FALSE);
+            }
+
+        if (unloaded == FALSE) {
+            pa_strbuf_printf(buf, "Module %s not loaded.\n", i);
+            return -1;
+        }
     }
 
-    pa_module_unload_request(m, FALSE);
     return 0;
 }
 
@@ -524,6 +553,11 @@ static int pa_cli_command_sink_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *bu
         return -1;
     }
 
+    if (!PA_VOLUME_IS_VALID(volume)) {
+        pa_strbuf_puts(buf, "Volume outside permissible range.\n");
+        return -1;
+    }
+
     if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK))) {
         pa_strbuf_puts(buf, "No sink found by this name or index.\n");
         return -1;
@@ -566,11 +600,21 @@ static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strb
         return -1;
     }
 
-    if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) {
+    if (!PA_VOLUME_IS_VALID(volume)) {
+        pa_strbuf_puts(buf, "Volume outside permissible range.\n");
+        return -1;
+    }
+
+    if (!(si = pa_idxset_get_by_index(c->sink_inputs, idx))) {
         pa_strbuf_puts(buf, "No sink input found with this index.\n");
         return -1;
     }
 
+    if (!si->volume_writable) {
+        pa_strbuf_puts(buf, "This sink input's volume can't be changed.\n");
+        return -1;
+    }
+
     pa_cvolume_set(&cvolume, 1, volume);
     pa_sink_input_set_volume(si, &cvolume, TRUE, TRUE);
     return 0;
@@ -602,13 +646,70 @@ static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *
         return -1;
     }
 
+    if (!PA_VOLUME_IS_VALID(volume)) {
+        pa_strbuf_puts(buf, "Volume outside permissible range.\n");
+        return -1;
+    }
+
     if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE))) {
         pa_strbuf_puts(buf, "No source found by this name or index.\n");
         return -1;
     }
 
     pa_cvolume_set(&cvolume, 1, volume);
-    pa_source_set_volume(source, &cvolume, TRUE);
+    pa_source_set_volume(source, &cvolume, TRUE, TRUE);
+    return 0;
+}
+
+static int pa_cli_command_source_output_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
+    const char *n, *v;
+    pa_source_output *so;
+    pa_volume_t volume;
+    pa_cvolume cvolume;
+    uint32_t idx;
+
+    pa_core_assert_ref(c);
+    pa_assert(t);
+    pa_assert(buf);
+    pa_assert(fail);
+
+    if (!(n = pa_tokenizer_get(t, 1))) {
+        pa_strbuf_puts(buf, "You need to specify a source output by its index.\n");
+        return -1;
+    }
+
+    if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
+        pa_strbuf_puts(buf, "Failed to parse index.\n");
+        return -1;
+    }
+
+    if (!(v = pa_tokenizer_get(t, 2))) {
+        pa_strbuf_puts(buf, "You need to specify a volume >= 0. (0 is muted, 0x10000 is normal volume)\n");
+        return -1;
+    }
+
+    if (pa_atou(v, &volume) < 0) {
+        pa_strbuf_puts(buf, "Failed to parse volume.\n");
+        return -1;
+    }
+
+    if (!PA_VOLUME_IS_VALID(volume)) {
+        pa_strbuf_puts(buf, "Volume outside permissible range.\n");
+        return -1;
+    }
+
+    if (!(so = pa_idxset_get_by_index(c->source_outputs, idx))) {
+        pa_strbuf_puts(buf, "No source output found with this index.\n");
+        return -1;
+    }
+
+    if (!so->volume_writable) {
+        pa_strbuf_puts(buf, "This source output's volume can't be changed.\n");
+        return -1;
+    }
+
+    pa_cvolume_set(&cvolume, 1, volume);
+    pa_source_output_set_volume(so, &cvolume, TRUE, TRUE);
     return 0;
 }
 
@@ -880,6 +981,46 @@ static int pa_cli_command_sink_input_mute(pa_core *c, pa_tokenizer *t, pa_strbuf
     return 0;
 }
 
+static int pa_cli_command_source_output_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
+    const char *n, *v;
+    pa_source_output *so;
+    uint32_t idx;
+    int mute;
+
+    pa_core_assert_ref(c);
+    pa_assert(t);
+    pa_assert(buf);
+    pa_assert(fail);
+
+    if (!(n = pa_tokenizer_get(t, 1))) {
+        pa_strbuf_puts(buf, "You need to specify a source output by its index.\n");
+        return -1;
+    }
+
+    if ((idx = parse_index(n)) == PA_IDXSET_INVALID) {
+        pa_strbuf_puts(buf, "Failed to parse index.\n");
+        return -1;
+    }
+
+    if (!(v = pa_tokenizer_get(t, 2))) {
+        pa_strbuf_puts(buf, "You need to specify a mute switch setting (0/1).\n");
+        return -1;
+    }
+
+    if ((mute = pa_parse_boolean(v)) < 0) {
+        pa_strbuf_puts(buf, "Failed to parse mute switch.\n");
+        return -1;
+    }
+
+    if (!(so = pa_idxset_get_by_index(c->source_outputs, (uint32_t) idx))) {
+        pa_strbuf_puts(buf, "No source output found with this index.\n");
+        return -1;
+    }
+
+    pa_source_output_set_mute(so, mute, TRUE);
+    return 0;
+}
+
 static int pa_cli_command_sink_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     const char *n;
     pa_sink *s;
@@ -1282,6 +1423,8 @@ static int pa_cli_command_suspend_sink(pa_core *c, pa_tokenizer *t, pa_strbuf *b
         return -1;
     }
 
+    pa_log_debug("%s of sink %s requested via CLI.", suspend ? "Suspending" : "Resuming", sink->name);
+
     if ((r = pa_sink_suspend(sink, suspend, PA_SUSPEND_USER)) < 0)
         pa_strbuf_printf(buf, "Failed to resume/suspend sink: %s\n", pa_strerror(r));
 
@@ -1318,6 +1461,8 @@ static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf
         return -1;
     }
 
+    pa_log_debug("%s of source %s requested via CLI.", suspend ? "Suspending" : "Resuming", source->name);
+
     if ((r = pa_source_suspend(source, suspend, PA_SUSPEND_USER)) < 0)
         pa_strbuf_printf(buf, "Failed to resume/suspend source: %s\n", pa_strerror(r));
 
@@ -1343,6 +1488,8 @@ static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, p
         return -1;
     }
 
+    pa_log_debug("%s of all sinks and sources requested via CLI.", suspend ? "Suspending" : "Resuming");
+
     if ((r = pa_sink_suspend_all(c, suspend, PA_SUSPEND_USER)) < 0)
         pa_strbuf_printf(buf, "Failed to resume/suspend all sinks: %s\n", pa_strerror(r));
 
@@ -1352,6 +1499,46 @@ static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, p
     return 0;
 }
 
+static int pa_cli_command_log_target(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
+    const char *m;
+
+    pa_core_assert_ref(c);
+    pa_assert(t);
+    pa_assert(buf);
+    pa_assert(fail);
+
+    if (!(m = pa_tokenizer_get(t, 1))) {
+        pa_strbuf_puts(buf, "You need to specify a log target (null,auto,syslog,stderr,file:PATH).\n");
+        return -1;
+    }
+
+    if (pa_streq(m, "null"))
+        pa_log_set_target(PA_LOG_NULL);
+    else if (pa_streq(m, "syslog"))
+        pa_log_set_target(PA_LOG_SYSLOG);
+    else if (pa_streq(m, "stderr") || pa_streq(m, "auto")) {
+        /* 'auto' is actually the effect with 'stderr' */
+        pa_log_set_target(PA_LOG_STDERR);
+    } else if (pa_startswith(m, "file:")) {
+        const char *file_path = m + 5;
+        int log_fd;
+
+        /* Open target file with user rights */
+        if ((log_fd = open(file_path, O_RDWR|O_TRUNC|O_CREAT, S_IRUSR | S_IWUSR)) >= 0) {
+            pa_log_set_target(PA_LOG_FD);
+            pa_log_set_fd(log_fd);
+        } else {
+            pa_strbuf_printf(buf, "Failed to open target file %s, error : %s\n", file_path, pa_cstrerror(errno));
+            return -1;
+        }
+    } else {
+        pa_strbuf_puts(buf, "You need to specify a log target (null,auto,syslog,stderr,file:PATH).\n");
+        return -1;
+    }
+
+    return 0;
+}
+
 static int pa_cli_command_log_level(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     const char *m;
     uint32_t level;
@@ -1378,7 +1565,7 @@ static int pa_cli_command_log_level(pa_core *c, pa_tokenizer *t, pa_strbuf *buf,
 
 static int pa_cli_command_log_meta(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     const char *m;
-    pa_bool_t b;
+    int b;
 
     pa_core_assert_ref(c);
     pa_assert(t);
@@ -1402,7 +1589,7 @@ static int pa_cli_command_log_meta(pa_core *c, pa_tokenizer *t, pa_strbuf *buf,
 
 static int pa_cli_command_log_time(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     const char *m;
-    pa_bool_t b;
+    int b;
 
     pa_core_assert_ref(c);
     pa_assert(t);
@@ -1544,6 +1731,52 @@ static int pa_cli_command_source_port(pa_core *c, pa_tokenizer *t, pa_strbuf *bu
     return 0;
 }
 
+static int pa_cli_command_port_offset(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
+    const char *n, *p, *l;
+    pa_device_port *port;
+    pa_card *card;
+    int32_t offset;
+
+    pa_core_assert_ref(c);
+    pa_assert(t);
+    pa_assert(buf);
+    pa_assert(fail);
+
+    if (!(n = pa_tokenizer_get(t, 1))) {
+        pa_strbuf_puts(buf, "You need to specify a card either by its name or its index.\n");
+        return -1;
+    }
+
+    if (!(p = pa_tokenizer_get(t, 2))) {
+        pa_strbuf_puts(buf, "You need to specify a port by its name.\n");
+        return -1;
+    }
+
+    if (!(l = pa_tokenizer_get(t, 3))) {
+        pa_strbuf_puts(buf, "You need to specify a latency offset.\n");
+        return -1;
+    }
+
+    if (pa_atoi(l, &offset) < 0) {
+        pa_strbuf_puts(buf, "Failed to parse the latency offset.\n");
+        return -1;
+    }
+
+    if (!(card = pa_namereg_get(c, n, PA_NAMEREG_CARD))) {
+        pa_strbuf_puts(buf, "No card found by this name or index.\n");
+        return -1;
+    }
+
+    if (!(port = pa_hashmap_get(card->ports, p))) {
+        pa_strbuf_puts(buf, "No port found by this name.\n");
+        return -1;
+    }
+
+    pa_device_port_set_latency_offset(port, offset);
+
+    return 0;
+}
+
 static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     pa_module *m;
     pa_sink *sink;
@@ -1551,8 +1784,10 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
     pa_card *card;
     pa_bool_t nl;
     uint32_t idx;
-    char txt[256];
     time_t now;
+#ifdef HAVE_CTIME_R
+    char txt[256];
+#endif
 
     pa_core_assert_ref(c);
     pa_assert(t);
@@ -1611,8 +1846,7 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
             nl = TRUE;
         }
 
-        if (card->active_profile)
-            pa_strbuf_printf(buf, "set-card-profile %s %s\n", card->name, card->active_profile->name);
+        pa_strbuf_printf(buf, "set-card-profile %s %s\n", card->name, card->active_profile->name);
     }
 
     nl = FALSE;
@@ -1637,6 +1871,62 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
     return 0;
 }
 
+static int pa_cli_command_dump_volumes(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
+    pa_sink *s;
+    pa_source *so;
+    pa_sink_input *i;
+    pa_source_output *o;
+    uint32_t s_idx, i_idx;
+    char v_str[PA_CVOLUME_SNPRINT_MAX];
+
+    pa_core_assert_ref(c);
+    pa_assert(t);
+    pa_assert(buf);
+    pa_assert(fail);
+
+    PA_IDXSET_FOREACH(s, c->sinks, s_idx) {
+        pa_strbuf_printf(buf, "Sink %d: ", s_idx);
+        pa_strbuf_printf(buf, "reference = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &s->reference_volume));
+        pa_strbuf_printf(buf, "real = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &s->real_volume));
+        pa_strbuf_printf(buf, "soft = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &s->soft_volume));
+        pa_strbuf_printf(buf, "current_hw = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &s->thread_info.current_hw_volume));
+        pa_strbuf_printf(buf, "save = %s\n", pa_yes_no(s->save_volume));
+
+        PA_IDXSET_FOREACH(i, s->inputs, i_idx) {
+            pa_strbuf_printf(buf, "\tInput %d: ", i_idx);
+            pa_strbuf_printf(buf, "volume = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &i->volume));
+            pa_strbuf_printf(buf, "reference_ratio = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &i->reference_ratio));
+            pa_strbuf_printf(buf, "real_ratio = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &i->real_ratio));
+            pa_strbuf_printf(buf, "soft = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &i->soft_volume));
+            pa_strbuf_printf(buf, "volume_factor = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &i->volume_factor));
+            pa_strbuf_printf(buf, "volume_factor_sink = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &i->volume_factor_sink));
+            pa_strbuf_printf(buf, "save = %s\n", pa_yes_no(i->save_volume));
+        }
+    }
+
+    PA_IDXSET_FOREACH(so, c->sources, s_idx) {
+        pa_strbuf_printf(buf, "Source %d: ", s_idx);
+        pa_strbuf_printf(buf, "reference = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &so->reference_volume));
+        pa_strbuf_printf(buf, "real = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &so->real_volume));
+        pa_strbuf_printf(buf, "soft = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &so->soft_volume));
+        pa_strbuf_printf(buf, "current_hw = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &so->thread_info.current_hw_volume));
+        pa_strbuf_printf(buf, "save = %s\n", pa_yes_no(so->save_volume));
+
+        PA_IDXSET_FOREACH(o, so->outputs, i_idx) {
+            pa_strbuf_printf(buf, "\tOutput %d: ", i_idx);
+            pa_strbuf_printf(buf, "volume = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &o->volume));
+            pa_strbuf_printf(buf, "reference_ratio = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &o->reference_ratio));
+            pa_strbuf_printf(buf, "real_ratio = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &o->real_ratio));
+            pa_strbuf_printf(buf, "soft = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &o->soft_volume));
+            pa_strbuf_printf(buf, "volume_factor = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &o->volume_factor));
+            pa_strbuf_printf(buf, "volume_factor_source = %s, ", pa_cvolume_snprint(v_str, sizeof(v_str), &o->volume_factor_source));
+            pa_strbuf_printf(buf, "save = %s\n", pa_yes_no(o->save_volume));
+        }
+    }
+
+    return 0;
+}
+
 int pa_cli_command_execute_line_stateful(pa_core *c, const char *s, pa_strbuf *buf, pa_bool_t *fail, int *ifstate) {
     const char *cs;
 
@@ -1677,10 +1967,74 @@ int pa_cli_command_execute_line_stateful(pa_core *c, const char *s, pa_strbuf *b
             l = strcspn(cs, whitespace);
 
             if (l == sizeof(META_INCLUDE)-1 && !strncmp(cs, META_INCLUDE, l)) {
+                struct stat st;
                 const char *filename = cs+l+strspn(cs+l, whitespace);
-                if (pa_cli_command_execute_file(c, filename, buf, fail) < 0)
+
+                if (stat(filename, &st) < 0) {
+                    pa_log_warn("stat('%s'): %s", filename, pa_cstrerror(errno));
                     if (*fail)
                         return -1;
+                } else {
+                    if (S_ISDIR(st.st_mode)) {
+                        DIR *d;
+
+                        if (!(d = opendir(filename))) {
+                            pa_log_warn("Failed to read '%s': %s", filename, pa_cstrerror(errno));
+                            if (*fail)
+                                return -1;
+                        } else {
+                            unsigned i, count;
+                            char **sorted_files;
+                            struct dirent *de;
+                            pa_bool_t failed = FALSE;
+                            pa_dynarray *files = pa_dynarray_new();
+
+                            while ((de = readdir(d))) {
+                                char *extn;
+                                size_t flen = strlen(de->d_name);
+
+                                if (flen < 4)
+                                    continue;
+
+                                extn = &de->d_name[flen-3];
+                                if (strncmp(extn, ".pa", 3) == 0)
+                                    pa_dynarray_append(files, pa_sprintf_malloc("%s" PA_PATH_SEP "%s", filename, de->d_name));
+                            }
+
+                            closedir(d);
+
+                            count = pa_dynarray_size(files);
+                            sorted_files = pa_xnew(char*, count);
+                            for (i = 0; i < count; ++i)
+                                sorted_files[i] = pa_dynarray_get(files, i);
+                            pa_dynarray_free(files, NULL);
+
+                            for (i = 0; i < count; ++i) {
+                                for (unsigned j = 0; j < count; ++j) {
+                                    if (strcmp(sorted_files[i], sorted_files[j]) < 0) {
+                                        char *tmp = sorted_files[i];
+                                        sorted_files[i] = sorted_files[j];
+                                        sorted_files[j] = tmp;
+                                    }
+                                }
+                            }
+
+                            for (i = 0; i < count; ++i) {
+                                if (!failed) {
+                                    if (pa_cli_command_execute_file(c, sorted_files[i], buf, fail) < 0 && *fail)
+                                        failed = TRUE;
+                                }
+
+                                pa_xfree(sorted_files[i]);
+                            }
+                            pa_xfree(sorted_files);
+                            if (failed)
+                                return -1;
+                        }
+                    } else if (pa_cli_command_execute_file(c, filename, buf, fail) < 0 && *fail) {
+                        return -1;
+                    }
+                }
             } else if (l == sizeof(META_IFEXISTS)-1 && !strncmp(cs, META_IFEXISTS, l)) {
                 if (!ifstate) {
                     pa_strbuf_printf(buf, "Meta command %s is not valid in this context\n", cs);
@@ -1695,7 +2049,7 @@ int pa_cli_command_execute_line_stateful(pa_core *c, const char *s, pa_strbuf *b
                     if (filename[0] == PA_PATH_SEP_CHAR) {
 
                         *ifstate = access(filename, F_OK) == 0 ? IFSTATE_TRUE : IFSTATE_FALSE;
-                        pa_log_debug("Checking for existance of '%s': %s", filename, *ifstate == IFSTATE_TRUE ? "success" : "failure");
+                        pa_log_debug("Checking for existence of '%s': %s", filename, *ifstate == IFSTATE_TRUE ? "success" : "failure");
 
                     } else {
                         const char *paths, *state = NULL;
@@ -1708,11 +2062,21 @@ int pa_cli_command_execute_line_stateful(pa_core *c, const char *s, pa_strbuf *b
                             char *pathname;
 
                             pathname = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", p, filename);
-                            pa_xfree(p);
 
                             *ifstate = access(pathname, F_OK) == 0 ? IFSTATE_TRUE : IFSTATE_FALSE;
-                            pa_log_debug("Checking for existance of '%s': %s", pathname, *ifstate == IFSTATE_TRUE ? "success" : "failure");
+                            pa_log_debug("Checking for existence of '%s': %s", pathname, *ifstate == IFSTATE_TRUE ? "success" : "failure");
+
+                            if (PA_UNLIKELY(pa_run_from_build_tree())) {
+                                /* If run from the build tree, search in <path>/.libs as well */
+                                char *ltpathname = pa_sprintf_malloc("%s" PA_PATH_SEP ".libs" PA_PATH_SEP "%s", p, filename);
 
+                                *ifstate = access(ltpathname, F_OK) == 0 ? IFSTATE_TRUE : IFSTATE_FALSE;
+                                pa_log_debug("Checking for existence of '%s': %s", ltpathname, *ifstate == IFSTATE_TRUE ? "success" : "failure");
+
+                                pa_xfree(ltpathname);
+                            }
+
+                            pa_xfree(p);
                             pa_xfree(pathname);
 
                             if (*ifstate == IFSTATE_TRUE)
@@ -1766,7 +2130,7 @@ int pa_cli_command_execute_line(pa_core *c, const char *s, pa_strbuf *buf, pa_bo
 }
 
 int pa_cli_command_execute_file_stream(pa_core *c, FILE *f, pa_strbuf *buf, pa_bool_t *fail) {
-    char line[1024];
+    char line[2048];
     int ifstate = IFSTATE_NONE;
     int ret = -1;
     pa_bool_t _fail = TRUE;
@@ -1804,13 +2168,14 @@ int pa_cli_command_execute_file(pa_core *c, const char *fn, pa_strbuf *buf, pa_b
     if (!fail)
         fail = &_fail;
 
-    if (!(f = fopen(fn, "r"))) {
+    if (!(f = pa_fopen_cloexec(fn, "r"))) {
         pa_strbuf_printf(buf, "open('%s') failed: %s\n", fn, pa_cstrerror(errno));
         if (!*fail)
             ret = 0;
         goto fail;
     }
 
+    pa_log_debug("Parsing script '%s'", fn);
     ret = pa_cli_command_execute_file_stream(c, f, buf, fail);
 
 fail:
index 23a57d3..963f130 100644 (file)
@@ -23,8 +23,6 @@
 #include <config.h>
 #endif
 
-#include <string.h>
-
 #include <pulse/volume.h>
 #include <pulse/xmalloc.h>
 #include <pulse/timeval.h>
 #include <pulsecore/sink-input.h>
 #include <pulsecore/source-output.h>
 #include <pulsecore/strbuf.h>
-#include <pulsecore/sample-util.h>
 #include <pulsecore/core-scache.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
+#include <pulsecore/namereg.h>
 
 #include "cli-text.h"
 
@@ -53,7 +51,7 @@ char *pa_module_list_to_string(pa_core *c) {
 
     pa_strbuf_printf(s, "%u module(s) loaded.\n", pa_idxset_size(c->modules));
 
-    for (m = pa_idxset_first(c->modules, &idx); m; m = pa_idxset_next(c->modules, &idx)) {
+    PA_IDXSET_FOREACH(m, c->modules, idx) {
         char *t;
 
         pa_strbuf_printf(s, "    index: %u\n"
@@ -85,7 +83,7 @@ char *pa_client_list_to_string(pa_core *c) {
 
     pa_strbuf_printf(s, "%u client(s) logged in.\n", pa_idxset_size(c->clients));
 
-    for (client = pa_idxset_first(c->clients, &idx); client; client = pa_idxset_next(c->clients, &idx)) {
+    PA_IDXSET_FOREACH(client, c->clients, idx) {
         char *t;
         pa_strbuf_printf(
                 s,
@@ -105,6 +103,40 @@ char *pa_client_list_to_string(pa_core *c) {
     return pa_strbuf_tostring_free(s);
 }
 
+static const char *available_to_string(pa_available_t a) {
+    switch (a) {
+        case PA_AVAILABLE_UNKNOWN:
+            return "unknown";
+        case PA_AVAILABLE_NO:
+            return "no";
+        case PA_AVAILABLE_YES:
+            return "yes";
+        default:
+            return "invalid"; /* Should never happen! */
+    }
+}
+
+static void append_port_list(pa_strbuf *s, pa_hashmap *ports)
+{
+    pa_device_port *p;
+    void *state;
+
+    pa_assert(ports);
+
+    if (pa_hashmap_isempty(ports))
+        return;
+
+    pa_strbuf_puts(s, "\tports:\n");
+    PA_HASHMAP_FOREACH(p, ports, state) {
+        char *t = pa_proplist_to_string_sep(p->proplist, "\n\t\t\t\t");
+        pa_strbuf_printf(s, "\t\t%s: %s (priority %u, latency offset %" PRId64 " usec, available: %s)\n",
+            p->name, p->description, p->priority, p->latency_offset,
+            available_to_string(p->available));
+        pa_strbuf_printf(s, "\t\t\tproperties:\n\t\t\t\t%s\n", t);
+        pa_xfree(t);
+    }
+}
+
 char *pa_card_list_to_string(pa_core *c) {
     pa_strbuf *s;
     pa_card *card;
@@ -115,11 +147,13 @@ char *pa_card_list_to_string(pa_core *c) {
 
     pa_strbuf_printf(s, "%u card(s) available.\n", pa_idxset_size(c->cards));
 
-    for (card = pa_idxset_first(c->cards, &idx); card; card = pa_idxset_next(c->cards, &idx)) {
+    PA_IDXSET_FOREACH(card, c->cards, idx) {
         char *t;
         pa_sink *sink;
         pa_source *source;
         uint32_t sidx;
+        pa_card_profile *profile;
+        void *state;
 
         pa_strbuf_printf(
                 s,
@@ -137,32 +171,29 @@ char *pa_card_list_to_string(pa_core *c) {
         pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t);
         pa_xfree(t);
 
-        if (card->profiles) {
-            pa_card_profile *p;
-            void *state;
+        pa_strbuf_puts(s, "\tprofiles:\n");
+        PA_HASHMAP_FOREACH(profile, card->profiles, state)
+            pa_strbuf_printf(s, "\t\t%s: %s (priority %u, available: %s)\n", profile->name, profile->description,
+                             profile->priority, available_to_string(profile->available));
 
-            pa_strbuf_puts(s, "\tprofiles:\n");
-            PA_HASHMAP_FOREACH(p, card->profiles, state)
-                pa_strbuf_printf(s, "\t\t%s: %s (priority %u)\n", p->name, p->description, p->priority);
-        }
-
-        if (card->active_profile)
-            pa_strbuf_printf(
-                    s,
-                    "\tactive profile: <%s>\n",
-                    card->active_profile->name);
+        pa_strbuf_printf(
+                s,
+                "\tactive profile: <%s>\n",
+                card->active_profile->name);
 
         if (!pa_idxset_isempty(card->sinks)) {
             pa_strbuf_puts(s, "\tsinks:\n");
-            for (sink = pa_idxset_first(card->sinks, &sidx); sink; sink = pa_idxset_next(card->sinks, &sidx))
+            PA_IDXSET_FOREACH(sink, card->sinks, sidx)
                 pa_strbuf_printf(s, "\t\t%s/#%u: %s\n", sink->name, sink->index, pa_strna(pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_DESCRIPTION)));
         }
 
         if (!pa_idxset_isempty(card->sources)) {
             pa_strbuf_puts(s, "\tsources:\n");
-            for (source = pa_idxset_first(card->sources, &sidx); source; source = pa_idxset_next(card->sources, &sidx))
+            PA_IDXSET_FOREACH(source, card->sources, sidx)
                 pa_strbuf_printf(s, "\t\t%s/#%u: %s\n", source->name, source->index, pa_strna(pa_proplist_gets(source->proplist, PA_PROP_DEVICE_DESCRIPTION)));
         }
+
+        append_port_list(s, card->ports);
     }
 
     return pa_strbuf_tostring_free(s);
@@ -204,7 +235,7 @@ static const char *source_state_to_string(pa_source_state_t state) {
 
 char *pa_sink_list_to_string(pa_core *c) {
     pa_strbuf *s;
-    pa_sink *sink;
+    pa_sink *sink, *default_sink;
     uint32_t idx = PA_IDXSET_INVALID;
     pa_assert(c);
 
@@ -212,7 +243,9 @@ char *pa_sink_list_to_string(pa_core *c) {
 
     pa_strbuf_printf(s, "%u sink(s) available.\n", pa_idxset_size(c->sinks));
 
-    for (sink = pa_idxset_first(c->sinks, &idx); sink; sink = pa_idxset_next(c->sinks, &idx)) {
+    default_sink = pa_namereg_get_default_sink(c);
+
+    PA_IDXSET_FOREACH(sink, c->sinks, idx) {
         char ss[PA_SAMPLE_SPEC_SNPRINT_MAX],
             cv[PA_CVOLUME_SNPRINT_MAX],
             cvdb[PA_SW_CVOLUME_SNPRINT_DB_MAX],
@@ -246,7 +279,7 @@ char *pa_sink_list_to_string(pa_core *c) {
             "\tchannel map: %s%s%s\n"
             "\tused by: %u\n"
             "\tlinked by: %u\n",
-            sink == c->default_sink ? '*' : ' ',
+            sink == default_sink ? '*' : ' ',
             sink->index,
             sink->name,
             sink->driver,
@@ -309,15 +342,7 @@ char *pa_sink_list_to_string(pa_core *c) {
         pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t);
         pa_xfree(t);
 
-        if (sink->ports) {
-            pa_device_port *p;
-            void *state;
-
-            pa_strbuf_puts(s, "\tports:\n");
-            PA_HASHMAP_FOREACH(p, sink->ports, state)
-                pa_strbuf_printf(s, "\t\t%s: %s (priority %u)\n", p->name, p->description, p->priority);
-        }
-
+        append_port_list(s, sink->ports);
 
         if (sink->active_port)
             pa_strbuf_printf(
@@ -331,7 +356,7 @@ char *pa_sink_list_to_string(pa_core *c) {
 
 char *pa_source_list_to_string(pa_core *c) {
     pa_strbuf *s;
-    pa_source *source;
+    pa_source *source, *default_source;
     uint32_t idx = PA_IDXSET_INVALID;
     pa_assert(c);
 
@@ -339,7 +364,9 @@ char *pa_source_list_to_string(pa_core *c) {
 
     pa_strbuf_printf(s, "%u source(s) available.\n", pa_idxset_size(c->sources));
 
-    for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) {
+    default_source = pa_namereg_get_default_source(c);
+
+    PA_IDXSET_FOREACH(source, c->sources, idx) {
         char ss[PA_SAMPLE_SPEC_SNPRINT_MAX],
             cv[PA_CVOLUME_SNPRINT_MAX],
             cvdb[PA_SW_CVOLUME_SNPRINT_DB_MAX],
@@ -370,7 +397,7 @@ char *pa_source_list_to_string(pa_core *c) {
             "\tchannel map: %s%s%s\n"
             "\tused by: %u\n"
             "\tlinked by: %u\n",
-            c->default_source == source ? '*' : ' ',
+            source == default_source ? '*' : ' ',
             source->index,
             source->name,
             source->driver,
@@ -432,14 +459,7 @@ char *pa_source_list_to_string(pa_core *c) {
         pa_strbuf_printf(s, "\tproperties:\n\t\t%s\n", t);
         pa_xfree(t);
 
-        if (source->ports) {
-            pa_device_port *p;
-            void *state;
-
-            pa_strbuf_puts(s, "\tports:\n");
-            PA_HASHMAP_FOREACH(p, source->ports, state)
-                pa_strbuf_printf(s, "\t\t%s: %s (priority %u)\n", p->name, p->description, p->priority);
-        }
+        append_port_list(s, source->ports);
 
         if (source->active_port)
             pa_strbuf_printf(
@@ -468,10 +488,12 @@ char *pa_source_output_list_to_string(pa_core *c) {
 
     pa_strbuf_printf(s, "%u source outputs(s) available.\n", pa_idxset_size(c->source_outputs));
 
-    for (o = pa_idxset_first(c->source_outputs, &idx); o; o = pa_idxset_next(c->source_outputs, &idx)) {
-        char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX], *t, clt[28];
+    PA_IDXSET_FOREACH(o, c->source_outputs, idx) {
+        char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cvdb[PA_SW_CVOLUME_SNPRINT_DB_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX], *t, clt[28];
         pa_usec_t cl;
         const char *cmn;
+        pa_cvolume v;
+        char *volume_str = NULL;
 
         cmn = pa_channel_map_to_pretty_name(&o->channel_map);
 
@@ -482,13 +504,25 @@ char *pa_source_output_list_to_string(pa_core *c) {
 
         pa_assert(o->source);
 
+        if (pa_source_output_is_volume_readable(o)) {
+            pa_source_output_get_volume(o, &v, TRUE);
+            volume_str = pa_sprintf_malloc("%s\n\t        %s\n\t        balance %0.2f",
+                                           pa_cvolume_snprint(cv, sizeof(cv), &v),
+                                           pa_sw_cvolume_snprint_dB(cvdb, sizeof(cvdb), &v),
+                                           pa_cvolume_get_balance(&v, &o->channel_map));
+        } else
+            volume_str = pa_xstrdup("n/a");
+
+
         pa_strbuf_printf(
             s,
             "    index: %u\n"
             "\tdriver: <%s>\n"
-            "\tflags: %s%s%s%s%s%s%s%s%s%s%s\n"
+            "\tflags: %s%s%s%s%s%s%s%s%s%s%s%s\n"
             "\tstate: %s\n"
             "\tsource: %u <%s>\n"
+            "\tvolume: %s\n"
+            "\tmuted: %s\n"
             "\tcurrent latency: %0.2f ms\n"
             "\trequested latency: %s\n"
             "\tsample spec: %s\n"
@@ -507,8 +541,11 @@ char *pa_source_output_list_to_string(pa_core *c) {
             o->flags & PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND ? "DONT_INHIBIT_AUTO_SUSPEND " : "",
             o->flags & PA_SOURCE_OUTPUT_NO_CREATE_ON_SUSPEND ? "NO_CREATE_ON_SUSPEND " : "",
             o->flags & PA_SOURCE_OUTPUT_KILL_ON_SUSPEND ? "KILL_ON_SUSPEND " : "",
+            o->flags & PA_SOURCE_OUTPUT_PASSTHROUGH ? "PASSTHROUGH " : "",
             state_table[pa_source_output_get_state(o)],
             o->source->index, o->source->name,
+            volume_str,
+            pa_yes_no(pa_source_output_get_mute(o)),
             (double) pa_source_output_get_latency(o, NULL) / PA_USEC_PER_MSEC,
             clt,
             pa_sample_spec_snprint(ss, sizeof(ss), &o->sample_spec),
@@ -516,6 +553,9 @@ char *pa_source_output_list_to_string(pa_core *c) {
             cmn ? "\n\t             " : "",
             cmn ? cmn : "",
             pa_resample_method_to_string(pa_source_output_get_resample_method(o)));
+
+        pa_xfree(volume_str);
+
         if (o->module)
             pa_strbuf_printf(s, "\towner module: %u\n", o->module->index);
         if (o->client)
@@ -548,13 +588,12 @@ char *pa_sink_input_list_to_string(pa_core *c) {
 
     pa_strbuf_printf(s, "%u sink input(s) available.\n", pa_idxset_size(c->sink_inputs));
 
-    for (i = pa_idxset_first(c->sink_inputs, &idx); i; i = pa_idxset_next(c->sink_inputs, &idx)) {
+    PA_IDXSET_FOREACH(i, c->sink_inputs, idx) {
         char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cvdb[PA_SW_CVOLUME_SNPRINT_DB_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX], *t, clt[28];
         pa_usec_t cl;
         const char *cmn;
         pa_cvolume v;
-
-        pa_sink_input_get_volume(i, &v, TRUE);
+        char *volume_str = NULL;
 
         cmn = pa_channel_map_to_pretty_name(&i->channel_map);
 
@@ -565,16 +604,23 @@ char *pa_sink_input_list_to_string(pa_core *c) {
 
         pa_assert(i->sink);
 
+        if (pa_sink_input_is_volume_readable(i)) {
+            pa_sink_input_get_volume(i, &v, TRUE);
+            volume_str = pa_sprintf_malloc("%s\n\t        %s\n\t        balance %0.2f",
+                                           pa_cvolume_snprint(cv, sizeof(cv), &v),
+                                           pa_sw_cvolume_snprint_dB(cvdb, sizeof(cvdb), &v),
+                                           pa_cvolume_get_balance(&v, &i->channel_map));
+        } else
+            volume_str = pa_xstrdup("n/a");
+
         pa_strbuf_printf(
             s,
             "    index: %u\n"
             "\tdriver: <%s>\n"
-            "\tflags: %s%s%s%s%s%s%s%s%s%s%s\n"
+            "\tflags: %s%s%s%s%s%s%s%s%s%s%s%s\n"
             "\tstate: %s\n"
             "\tsink: %u <%s>\n"
             "\tvolume: %s\n"
-            "\t        %s\n"
-            "\t        balance %0.2f\n"
             "\tmuted: %s\n"
             "\tcurrent latency: %0.2f ms\n"
             "\trequested latency: %s\n"
@@ -594,11 +640,10 @@ char *pa_sink_input_list_to_string(pa_core *c) {
             i->flags & PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND ? "DONT_INHIBIT_AUTO_SUSPEND " : "",
             i->flags & PA_SINK_INPUT_NO_CREATE_ON_SUSPEND ? "NO_CREATE_SUSPEND " : "",
             i->flags & PA_SINK_INPUT_KILL_ON_SUSPEND ? "KILL_ON_SUSPEND " : "",
+            i->flags & PA_SINK_INPUT_PASSTHROUGH ? "PASSTHROUGH " : "",
             state_table[pa_sink_input_get_state(i)],
             i->sink->index, i->sink->name,
-            pa_cvolume_snprint(cv, sizeof(cv), &v),
-            pa_sw_cvolume_snprint_dB(cvdb, sizeof(cvdb), &v),
-            pa_cvolume_get_balance(&v, &i->channel_map),
+            volume_str,
             pa_yes_no(pa_sink_input_get_mute(i)),
             (double) pa_sink_input_get_latency(i, NULL) / PA_USEC_PER_MSEC,
             clt,
@@ -608,6 +653,8 @@ char *pa_sink_input_list_to_string(pa_core *c) {
             cmn ? cmn : "",
             pa_resample_method_to_string(pa_sink_input_get_resample_method(i)));
 
+        pa_xfree(volume_str);
+
         if (i->module)
             pa_strbuf_printf(s, "\tmodule: %u\n", i->module->index);
         if (i->client)
@@ -633,7 +680,7 @@ char *pa_scache_list_to_string(pa_core *c) {
         pa_scache_entry *e;
         uint32_t idx = PA_IDXSET_INVALID;
 
-        for (e = pa_idxset_first(c->scache, &idx); e; e = pa_idxset_next(c->scache, &idx)) {
+        PA_IDXSET_FOREACH(e, c->scache, idx) {
             double l = 0;
             char ss[PA_SAMPLE_SPEC_SNPRINT_MAX] = "n/a", cv[PA_CVOLUME_SNPRINT_MAX], cvdb[PA_SW_CVOLUME_SNPRINT_DB_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX] = "n/a", *t;
             const char *cmn;
index 54514e7..53aa651 100644 (file)
 #endif
 
 #include <stdio.h>
-#include <string.h>
 #include <stdlib.h>
 
 #include <pulse/xmalloc.h>
 
+#include <pulsecore/core-util.h>
 #include <pulsecore/ioline.h>
 #include <pulsecore/module.h>
-#include <pulsecore/sink.h>
-#include <pulsecore/source.h>
 #include <pulsecore/client.h>
-#include <pulsecore/sink-input.h>
-#include <pulsecore/source-output.h>
 #include <pulsecore/tokenizer.h>
 #include <pulsecore/strbuf.h>
-#include <pulsecore/namereg.h>
 #include <pulsecore/cli-text.h>
 #include <pulsecore/cli-command.h>
 #include <pulsecore/log.h>
index c956b10..b2af4c1 100644 (file)
@@ -76,8 +76,9 @@ pa_client *pa_client_new(pa_core *core, pa_client_new_data *data) {
     c->send_event = NULL;
 
     pa_assert_se(pa_idxset_put(core->clients, c, &c->index) >= 0);
-
+#ifdef _DEBUG_
     pa_log_info("Created %u \"%s\"", c->index, pa_strnull(pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME)));
+#endif
     pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_NEW, c->index);
 
     pa_hook_fire(&core->hooks[PA_CORE_HOOK_CLIENT_PUT], c);
@@ -99,13 +100,13 @@ void pa_client_free(pa_client *c) {
 
     pa_idxset_remove_by_data(c->core->clients, c, NULL);
 
-    pa_log_info("Freed %u \"%s\"", c->index, pa_strnull(pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME)));
+    pa_log_info_verbose("Freed %u \"%s\"", c->index, pa_strnull(pa_proplist_gets(c->proplist, PA_PROP_APPLICATION_NAME)));
     pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_REMOVE, c->index);
 
     pa_assert(pa_idxset_isempty(c->sink_inputs));
-    pa_idxset_free(c->sink_inputs, NULL, NULL);
+    pa_idxset_free(c->sink_inputs, NULL);
     pa_assert(pa_idxset_isempty(c->source_outputs));
-    pa_idxset_free(c->source_outputs, NULL, NULL);
+    pa_idxset_free(c->source_outputs, NULL);
 
     pa_proplist_free(c->proplist);
     pa_xfree(c->driver);
index dd4a99e..062fa8e 100644 (file)
 #define COMMENTS "#;\n"
 
 /* Run the user supplied parser for an assignment */
-static int next_assignment(
-        const char *filename,
-        unsigned line,
-        const char *section,
-        const pa_config_item *t,
-        const char *lvalue,
-        const char *rvalue,
-        void *userdata) {
+static int normal_assignment(pa_config_parser_state *state) {
+    const pa_config_item *item;
 
-    pa_assert(filename);
-    pa_assert(t);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
+    pa_assert(state);
 
-    for (; t->parse; t++) {
+    for (item = state->item_table; item->parse; item++) {
 
-        if (t->lvalue && !pa_streq(lvalue, t->lvalue))
+        if (item->lvalue && !pa_streq(state->lvalue, item->lvalue))
             continue;
 
-        if (t->section && !section)
+        if (item->section && !state->section)
             continue;
 
-        if (t->section && !pa_streq(section, t->section))
+        if (item->section && !pa_streq(state->section, item->section))
             continue;
 
-        return t->parse(filename, line, section, lvalue, rvalue, t->data, userdata);
+        state->data = item->data;
+
+        return item->parse(state);
     }
 
-    pa_log("[%s:%u] Unknown lvalue '%s' in section '%s'.", filename, line, lvalue, pa_strna(section));
+    pa_log("[%s:%u] Unknown lvalue '%s' in section '%s'.", state->filename, state->lineno, state->lvalue, pa_strna(state->section));
 
     return -1;
 }
 
-/* Returns non-zero when c is contained in s */
-static int in_string(char c, const char *s) {
-    pa_assert(s);
+/* Parse a proplist entry. */
+static int proplist_assignment(pa_config_parser_state *state) {
+    pa_assert(state);
+    pa_assert(state->proplist);
 
-    for (; *s; s++)
-        if (*s == c)
-            return 1;
+    if (pa_proplist_sets(state->proplist, state->lvalue, state->rvalue) < 0) {
+        pa_log("[%s:%u] Failed to parse a proplist entry: %s = %s", state->filename, state->lineno, state->lvalue, state->rvalue);
+        return -1;
+    }
 
     return 0;
 }
 
-/* Remove all whitepsapce from the beginning and the end of *s. *s may
- * be modified. */
-static char *strip(char *s) {
-    char *b = s+strspn(s, WHITESPACE);
-    char *e, *l = NULL;
-
-    for (e = b; *e; e++)
-        if (!in_string(*e, WHITESPACE))
-            l = e;
-
-    if (l)
-        *(l+1) = 0;
-
-    return b;
-}
-
 /* Parse a variable assignment line */
-static int parse_line(const char *filename, unsigned line, char **section, const pa_config_item *t, char *l, void *userdata) {
-    char *e, *c, *b;
+static int parse_line(pa_config_parser_state *state) {
+    char *c;
 
-    b = l+strspn(l, WHITESPACE);
+    state->lvalue = state->buf + strspn(state->buf, WHITESPACE);
 
-    if ((c = strpbrk(b, COMMENTS)))
+    if ((c = strpbrk(state->lvalue, COMMENTS)))
         *c = 0;
 
-    if (!*b)
+    if (!*state->lvalue)
         return 0;
 
-    if (pa_startswith(b, ".include ")) {
+    if (pa_startswith(state->lvalue, ".include ")) {
         char *path = NULL, *fn;
         int r;
 
-        fn = strip(b+9);
+        fn = pa_strip(state->lvalue + 9);
         if (!pa_is_path_absolute(fn)) {
             const char *k;
-            if ((k = strrchr(filename, '/'))) {
-                char *dir = pa_xstrndup(filename, k-filename);
+            if ((k = strrchr(state->filename, '/'))) {
+                char *dir = pa_xstrndup(state->filename, k - state->filename);
                 fn = path = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", dir, fn);
                 pa_xfree(dir);
             }
         }
 
-        r = pa_config_parse(fn, NULL, t, userdata);
+        r = pa_config_parse(fn, NULL, state->item_table, state->proplist, state->userdata);
         pa_xfree(path);
         return r;
     }
 
-    if (*b == '[') {
+    if (*state->lvalue == '[') {
         size_t k;
 
-        k = strlen(b);
+        k = strlen(state->lvalue);
         pa_assert(k > 0);
 
-        if (b[k-1] != ']') {
-            pa_log("[%s:%u] Invalid section header.", filename, line);
+        if (state->lvalue[k-1] != ']') {
+            pa_log("[%s:%u] Invalid section header.", state->filename, state->lineno);
             return -1;
         }
 
-        pa_xfree(*section);
-        *section = pa_xstrndup(b+1, k-2);
+        pa_xfree(state->section);
+        state->section = pa_xstrndup(state->lvalue + 1, k-2);
+
+        if (pa_streq(state->section, "Properties")) {
+            if (!state->proplist) {
+                pa_log("[%s:%u] \"Properties\" section is not allowed in this file.", state->filename, state->lineno);
+                return -1;
+            }
+
+            state->in_proplist = TRUE;
+        } else
+            state->in_proplist = FALSE;
+
         return 0;
     }
 
-    if (!(e = strchr(b, '='))) {
-        pa_log("[%s:%u] Missing '='.", filename, line);
+    if (!(state->rvalue = strchr(state->lvalue, '='))) {
+        pa_log("[%s:%u] Missing '='.", state->filename, state->lineno);
         return -1;
     }
 
-    *e = 0;
-    e++;
+    *state->rvalue = 0;
+    state->rvalue++;
 
-    return next_assignment(filename, line, *section, t, strip(b), strip(e), userdata);
+    state->lvalue = pa_strip(state->lvalue);
+    state->rvalue = pa_strip(state->rvalue);
+
+    if (state->in_proplist)
+        return proplist_assignment(state);
+    else
+        return normal_assignment(state);
 }
 
 /* Go through the file and parse each line */
-int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void *userdata) {
+int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, pa_proplist *proplist, void *userdata) {
     int r = -1;
-    unsigned line = 0;
     pa_bool_t do_close = !f;
-    char *section = NULL;
+    pa_config_parser_state state;
 
     pa_assert(filename);
     pa_assert(t);
 
-    if (!f && !(f = fopen(filename, "r"))) {
+    pa_zero(state);
+
+    if (!f && !(f = pa_fopen_cloexec(filename, "r"))) {
         if (errno == ENOENT) {
             pa_log_debug("Failed to open configuration file '%s': %s", filename, pa_cstrerror(errno));
             r = 0;
@@ -179,10 +176,15 @@ int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void
         goto finish;
     }
 
-    while (!feof(f)) {
-        char l[4096];
+    state.filename = filename;
+    state.item_table = t;
+    state.userdata = userdata;
+
+    if (proplist)
+        state.proplist = pa_proplist_new();
 
-        if (!fgets(l, sizeof(l), f)) {
+    while (!feof(f)) {
+        if (!fgets(state.buf, sizeof(state.buf), f)) {
             if (feof(f))
                 break;
 
@@ -190,14 +192,22 @@ int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void
             goto finish;
         }
 
-        if (parse_line(filename, ++line, &section, t, l, userdata) < 0)
+        state.lineno++;
+
+        if (parse_line(&state) < 0)
             goto finish;
     }
 
+    if (proplist)
+        pa_proplist_update(proplist, PA_UPDATE_REPLACE, state.proplist);
+
     r = 0;
 
 finish:
-    pa_xfree(section);
+    if (state.proplist)
+        pa_proplist_free(state.proplist);
+
+    pa_xfree(state.section);
 
     if (do_close && f)
         fclose(f);
@@ -205,17 +215,16 @@ finish:
     return r;
 }
 
-int pa_config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    int *i = data;
+int pa_config_parse_int(pa_config_parser_state *state) {
+    int *i;
     int32_t k;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
 
-    if (pa_atoi(rvalue, &k) < 0) {
-        pa_log("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
+    i = state->data;
+
+    if (pa_atoi(state->rvalue, &k) < 0) {
+        pa_log("[%s:%u] Failed to parse numeric value: %s", state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -223,17 +232,16 @@ int pa_config_parse_int(const char *filename, unsigned line, const char *section
     return 0;
 }
 
-int pa_config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    unsigned *u = data;
+int pa_config_parse_unsigned(pa_config_parser_state *state) {
+    unsigned *u;
     uint32_t k;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
 
-    if (pa_atou(rvalue, &k) < 0) {
-        pa_log("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
+    u = state->data;
+
+    if (pa_atou(state->rvalue, &k) < 0) {
+        pa_log("[%s:%u] Failed to parse numeric value: %s", state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -241,17 +249,16 @@ int pa_config_parse_unsigned(const char *filename, unsigned line, const char *se
     return 0;
 }
 
-int pa_config_parse_size(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    size_t *i = data;
+int pa_config_parse_size(pa_config_parser_state *state) {
+    size_t *i;
     uint32_t k;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
 
-    if (pa_atou(rvalue, &k) < 0) {
-        pa_log("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
+    i = state->data;
+
+    if (pa_atou(state->rvalue, &k) < 0) {
+        pa_log("[%s:%u] Failed to parse numeric value: %s", state->filename, state->lineno, state->rvalue);
         return -1;
     }
 
@@ -259,17 +266,16 @@ int pa_config_parse_size(const char *filename, unsigned line, const char *sectio
     return 0;
 }
 
-int pa_config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+int pa_config_parse_bool(pa_config_parser_state *state) {
     int k;
-    pa_bool_t *b = data;
+    pa_bool_t *b;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
 
-    if ((k = pa_parse_boolean(rvalue)) < 0) {
-        pa_log("[%s:%u] Failed to parse boolean value: %s", filename, line, rvalue);
+    b = 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;
     }
 
@@ -278,22 +284,16 @@ int pa_config_parse_bool(const char *filename, unsigned line, const char *sectio
     return 0;
 }
 
-int pa_config_parse_not_bool(
-        const char *filename, unsigned line,
-        const char *section,
-        const char *lvalue, const char *rvalue,
-        void *data, void *userdata) {
-
+int pa_config_parse_not_bool(pa_config_parser_state *state) {
     int k;
-    pa_bool_t *b = data;
+    pa_bool_t *b;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
+
+    b = state->data;
 
-    if ((k = pa_parse_boolean(rvalue)) < 0) {
-        pa_log("[%s:%u] Failed to parse boolean value: %s", filename, line, rvalue);
+    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;
     }
 
@@ -302,15 +302,14 @@ int pa_config_parse_not_bool(
     return 0;
 }
 
-int pa_config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
-    char **s = data;
+int pa_config_parse_string(pa_config_parser_state *state) {
+    char **s;
 
-    pa_assert(filename);
-    pa_assert(lvalue);
-    pa_assert(rvalue);
-    pa_assert(data);
+    pa_assert(state);
+
+    s = state->data;
 
     pa_xfree(*s);
-    *s = *rvalue ? pa_xstrdup(rvalue) : NULL;
+    *s = *state->rvalue ? pa_xstrdup(state->rvalue) : NULL;
     return 0;
 }
index c6c8a14..7892a07 100644 (file)
 
 #include <stdio.h>
 
+#include <pulse/proplist.h>
+
 /* An abstract parser for simple, line based, shallow configuration
  * files consisting of variable assignments only. */
 
-typedef int (*pa_config_parser_cb_t)(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
+typedef struct pa_config_parser_state pa_config_parser_state;
+
+typedef int (*pa_config_parser_cb_t)(pa_config_parser_state *state);
 
 /* Wraps info for parsing a specific configuration variable */
 typedef struct pa_config_item {
@@ -37,17 +41,43 @@ typedef struct pa_config_item {
     const char *section;
 } pa_config_item;
 
+struct pa_config_parser_state {
+    const char *filename;
+    unsigned lineno;
+    char *section;
+    char *lvalue;
+    char *rvalue;
+    void *data; /* The data pointer of the current pa_config_item. */
+    void *userdata; /* The pointer that was given to pa_config_parse(). */
+
+    /* Private data to be used only by conf-parser.c. */
+    const pa_config_item *item_table;
+    char buf[4096];
+    pa_proplist *proplist;
+    pa_bool_t in_proplist;
+};
+
 /* The configuration file parsing routine. Expects a table of
  * pa_config_items in *t that is terminated by an item where lvalue is
- * NULL */
-int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void *userdata);
+ * NULL.
+ *
+ * Some configuration files may contain a Properties section, which
+ * is a bit special. Normally all accepted lvalues must be predefined
+ * in the pa_config_item table, but in the Properties section the
+ * pa_config_item table is ignored, and all lvalues are accepted (as
+ * long as they are valid proplist keys). If the proplist pointer is
+ * non-NULL, the parser will parse any section named "Properties" as
+ * properties, and those properties will be merged into the given
+ * proplist. If proplist is NULL, then sections named "Properties"
+ * are not allowed at all in the configuration file. */
+int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, pa_proplist *proplist, void *userdata);
 
 /* Generic parsers for integers, size_t, booleans and strings */
-int pa_config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
-int pa_config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
-int pa_config_parse_size(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
-int pa_config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
-int pa_config_parse_not_bool(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
-int pa_config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
+int pa_config_parse_int(pa_config_parser_state *state);
+int pa_config_parse_unsigned(pa_config_parser_state *state);
+int pa_config_parse_size(pa_config_parser_state *state);
+int pa_config_parse_bool(pa_config_parser_state *state);
+int pa_config_parse_not_bool(pa_config_parser_state *state);
+int pa_config_parse_string(pa_config_parser_state *state);
 
 #endif
index c440806..a1aee0e 100644 (file)
@@ -32,8 +32,6 @@
 #include <pulse/utf8.h>
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/core-util.h>
-#include <pulsecore/native-common.h>
 #include <pulsecore/thread.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/log.h>
@@ -65,8 +63,9 @@ const char* pa_cstrerror(int errnum) {
     original = strerror(errnum);
 #endif
 
-    if (!original) {
-        pa_snprintf(errbuf, sizeof(errbuf), "Unknown error %i", errnum);
+    /* The second condition is a Windows-ism */
+    if (!original || !strcasecmp(original, "Unknown error")) {
+        pa_snprintf(errbuf, sizeof(errbuf), "Unknown error %d", errnum);
         original = errbuf;
     }
 
index e7bc4fc..e295091 100644 (file)
@@ -23,7 +23,6 @@
   USA.
 ***/
 
-#include <inttypes.h>
 #include <pulse/cdecl.h>
 
 /** \file
index 1420470..6632cc6 100644 (file)
 #include <config.h>
 #endif
 
+#ifdef OS_IS_DARWIN
+#define _POSIX_C_SOURCE 1
+#endif
+
 #include <stddef.h>
 #include <time.h>
 #include <sys/time.h>
 #include <sys/prctl.h>
 #endif
 
+#ifdef OS_IS_DARWIN
+#include <CoreServices/CoreServices.h>
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
 #include <pulse/timeval.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-error.h>
 
 #include "core-rtclock.h"
 
+#ifdef OS_IS_WIN32
+static int64_t counter_freq = 0;
+#endif
+
 pa_usec_t pa_rtclock_age(const struct timeval *tv) {
     struct timeval now;
     pa_assert(tv);
@@ -47,7 +66,20 @@ pa_usec_t pa_rtclock_age(const struct timeval *tv) {
 }
 
 struct timeval *pa_rtclock_get(struct timeval *tv) {
-#ifdef HAVE_CLOCK_GETTIME
+
+#if defined(OS_IS_DARWIN)
+    uint64_t val, abs_time = mach_absolute_time();
+    Nanoseconds nanos;
+
+    nanos = AbsoluteToNanoseconds(*(AbsoluteTime *) &abs_time);
+    val = *(uint64_t *) &nanos;
+
+    tv->tv_sec = val / PA_NSEC_PER_SEC;
+    tv->tv_usec = (val % PA_NSEC_PER_SEC) / PA_NSEC_PER_USEC;
+
+    return tv;
+
+#elif defined(HAVE_CLOCK_GETTIME)
     struct timespec ts;
 
 #ifdef CLOCK_MONOTONIC
@@ -59,7 +91,7 @@ struct timeval *pa_rtclock_get(struct timeval *tv) {
             no_monotonic = TRUE;
 
     if (no_monotonic)
-#endif
+#endif /* CLOCK_MONOTONIC */
         pa_assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
 
     pa_assert(tv);
@@ -68,36 +100,61 @@ struct timeval *pa_rtclock_get(struct timeval *tv) {
     tv->tv_usec = ts.tv_nsec / PA_NSEC_PER_USEC;
 
     return tv;
+#elif defined(OS_IS_WIN32)
+    if (counter_freq > 0) {
+        LARGE_INTEGER count;
 
-#else /* HAVE_CLOCK_GETTIME */
+        pa_assert_se(QueryPerformanceCounter(&count));
 
-    return pa_gettimeofday(tv);
+        tv->tv_sec = count.QuadPart / counter_freq;
+        tv->tv_usec = (count.QuadPart % counter_freq) * PA_USEC_PER_SEC / counter_freq;
 
-#endif
+        return tv;
+    }
+#endif /* HAVE_CLOCK_GETTIME */
+
+    return pa_gettimeofday(tv);
 }
 
 pa_bool_t pa_rtclock_hrtimer(void) {
-#ifdef HAVE_CLOCK_GETTIME
+
+#if defined (OS_IS_DARWIN)
+    mach_timebase_info_data_t tbi;
+    uint64_t time_nsec;
+
+    mach_timebase_info(&tbi);
+
+    /* nsec = nticks * (N/D) - we want 1 tick == resolution !? */
+    time_nsec = tbi.numer / tbi.denom;
+    return time_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC);
+
+#elif defined(HAVE_CLOCK_GETTIME)
     struct timespec ts;
 
 #ifdef CLOCK_MONOTONIC
+
     if (clock_getres(CLOCK_MONOTONIC, &ts) >= 0)
         return ts.tv_sec == 0 && ts.tv_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC);
-#endif
+
+#endif /* CLOCK_MONOTONIC */
 
     pa_assert_se(clock_getres(CLOCK_REALTIME, &ts) == 0);
     return ts.tv_sec == 0 && ts.tv_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC);
 
-#else /* HAVE_CLOCK_GETTIME */
+#elif defined(OS_IS_WIN32)
 
-    return FALSE;
+    if (counter_freq > 0)
+        return counter_freq >= (int64_t) (PA_USEC_PER_SEC/PA_HRTIMER_THRESHOLD_USEC);
 
-#endif
+#endif /* HAVE_CLOCK_GETTIME */
+
+    return FALSE;
 }
 
 #define TIMER_SLACK_NS (int) ((500 * PA_NSEC_PER_USEC))
 
 void pa_rtclock_hrtimer_enable(void) {
+
 #ifdef PR_SET_TIMERSLACK
     int slack_ns;
 
@@ -119,19 +176,23 @@ void pa_rtclock_hrtimer_enable(void) {
         }
     }
 
+#elif defined(OS_IS_WIN32)
+    LARGE_INTEGER freq;
+
+    pa_assert_se(QueryPerformanceFrequency(&freq));
+    counter_freq = freq.QuadPart;
+
 #endif
 }
 
 struct timeval* pa_rtclock_from_wallclock(struct timeval *tv) {
-
-#ifdef HAVE_CLOCK_GETTIME
     struct timeval wc_now, rt_now;
 
+    pa_assert(tv);
+
     pa_gettimeofday(&wc_now);
     pa_rtclock_get(&rt_now);
 
-    pa_assert(tv);
-
     /* pa_timeval_sub() saturates on underflow! */
 
     if (pa_timeval_cmp(&wc_now, tv) < 0)
@@ -140,11 +201,11 @@ struct timeval* pa_rtclock_from_wallclock(struct timeval *tv) {
         pa_timeval_sub(&rt_now, pa_timeval_diff(&wc_now, tv));
 
     *tv = rt_now;
-#endif
 
     return tv;
 }
 
+#ifdef HAVE_CLOCK_GETTIME
 pa_usec_t pa_timespec_load(const struct timespec *ts) {
 
     if (PA_UNLIKELY(!ts))
@@ -169,17 +230,16 @@ struct timespec* pa_timespec_store(struct timespec *ts, pa_usec_t v) {
 
     return ts;
 }
+#endif
 
 static struct timeval* wallclock_from_rtclock(struct timeval *tv) {
-
-#ifdef HAVE_CLOCK_GETTIME
     struct timeval wc_now, rt_now;
 
+    pa_assert(tv);
+
     pa_gettimeofday(&wc_now);
     pa_rtclock_get(&rt_now);
 
-    pa_assert(tv);
-
     /* pa_timeval_sub() saturates on underflow! */
 
     if (pa_timeval_cmp(&rt_now, tv) < 0)
@@ -188,7 +248,6 @@ static struct timeval* wallclock_from_rtclock(struct timeval *tv) {
         pa_timeval_sub(&wc_now, pa_timeval_diff(&rt_now, tv));
 
     *tv = wc_now;
-#endif
 
     return tv;
 }
index 3b393ed..6253536 100644 (file)
@@ -43,8 +43,10 @@ void pa_rtclock_hrtimer_enable(void);
 
 struct timeval* pa_rtclock_from_wallclock(struct timeval *tv);
 
+#ifdef HAVE_CLOCK_GETTIME
 pa_usec_t pa_timespec_load(const struct timespec *ts);
 struct timespec* pa_timespec_store(struct timespec *ts, pa_usec_t v);
+#endif
 
 struct timeval* pa_timeval_rtstore(struct timeval *tv, pa_usec_t v, pa_bool_t rtclock);
 
index 1fb81d0..c3cb8eb 100644 (file)
 #endif
 
 #include <stdlib.h>
-#include <string.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <dirent.h>
 #include <sys/stat.h>
 #include <errno.h>
 #include <limits.h>
+#include <time.h>
 
 #ifdef HAVE_GLOB_H
 #include <glob.h>
@@ -50,7 +50,6 @@
 #include <pulse/rtclock.h>
 
 #include <pulsecore/sink-input.h>
-#include <pulsecore/sample-util.h>
 #include <pulsecore/play-memchunk.h>
 #include <pulsecore/core-subscribe.h>
 #include <pulsecore/namereg.h>
@@ -193,7 +192,7 @@ int pa_scache_add_item(
     if (idx)
         *idx = e->index;
 
-    pa_log_debug("Created sample \"%s\" (#%d), %lu bytes with sample spec %s",
+    pa_log_debug_verbose("Created sample \"%s\" (#%d), %lu bytes with sample spec %s",
                  name, e->index, (unsigned long) e->memchunk.length,
                  pa_sample_spec_snprint(st, sizeof(st), &e->sample_spec));
 
@@ -275,7 +274,7 @@ int pa_scache_remove_item(pa_core *c, const char *name) {
 
     pa_assert_se(pa_idxset_remove_by_data(c->scache, e, NULL) == e);
 
-    pa_log_debug("Removed sample \"%s\"", name);
+    pa_log_debug_verbose("Removed sample \"%s\"", name);
 
     free_entry(e);
 
@@ -283,12 +282,9 @@ int pa_scache_remove_item(pa_core *c, const char *name) {
 }
 
 void pa_scache_free_all(pa_core *c) {
-    pa_scache_entry *e;
-
     pa_assert(c);
 
-    while ((e = pa_idxset_steal_first(c->scache, NULL)))
-        free_entry(e);
+    pa_idxset_remove_all(c->scache, (pa_free_cb_t) free_entry);
 
     if (c->scache_auto_unload_event) {
         c->mainloop->time_free(c->scache_auto_unload_event);
@@ -310,7 +306,8 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t
         return -1;
 
     merged = pa_proplist_new();
-    pa_proplist_setf(merged, PA_PROP_MEDIA_NAME, "Sample %s", name);
+    pa_proplist_sets(merged, PA_PROP_MEDIA_NAME, name);
+    pa_proplist_sets(merged, PA_PROP_EVENT_ID, name);
 
     if (e->lazy && !e->memchunk.memblock) {
         pa_channel_map old_channel_map = e->channel_map;
@@ -331,16 +328,16 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t
     if (!e->memchunk.memblock)
         goto fail;
 
-    pa_log_debug("Playing sample \"%s\" on \"%s\"", name, sink->name);
+    pa_log_debug_verbose("Playing sample \"%s\" on \"%s\"", name, sink->name);
 
     pass_volume = TRUE;
 
-    if (e->volume_is_set && volume != PA_VOLUME_INVALID) {
+    if (e->volume_is_set && PA_VOLUME_IS_VALID(volume)) {
         pa_cvolume_set(&r, e->sample_spec.channels, volume);
         pa_sw_cvolume_multiply(&r, &r, &e->volume);
     } else if (e->volume_is_set)
         r = e->volume;
-    else if (volume != PA_VOLUME_INVALID)
+    else if (PA_VOLUME_IS_VALID(volume))
         pa_cvolume_set(&r, e->sample_spec.channels, volume);
     else
         pass_volume = FALSE;
@@ -350,7 +347,12 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t
     if (p)
         pa_proplist_update(merged, PA_UPDATE_REPLACE, p);
 
-    if (pa_play_memchunk(sink, &e->sample_spec, &e->channel_map, &e->memchunk, pass_volume ? &r : NULL, merged, sink_input_idx) < 0)
+    if (pa_play_memchunk(sink,
+                         &e->sample_spec, &e->channel_map,
+                         &e->memchunk,
+                         pass_volume ? &r : NULL,
+                         merged,
+                         PA_SINK_INPUT_NO_CREATE_ON_SUSPEND|PA_SINK_INPUT_KILL_ON_SUSPEND, sink_input_idx) < 0)
         goto fail;
 
     pa_proplist_free(merged);
@@ -411,7 +413,7 @@ size_t pa_scache_total_size(pa_core *c) {
     if (!c->scache || !pa_idxset_size(c->scache))
         return 0;
 
-    for (e = pa_idxset_first(c->scache, &idx); e; e = pa_idxset_next(c->scache, &idx))
+    PA_IDXSET_FOREACH(e, c->scache, idx)
         if (e->memchunk.memblock)
             sum += e->memchunk.length;
 
@@ -430,7 +432,7 @@ void pa_scache_unload_unused(pa_core *c) {
 
     time(&now);
 
-    for (e = pa_idxset_first(c->scache, &idx); e; e = pa_idxset_next(c->scache, &idx)) {
+    PA_IDXSET_FOREACH(e, c->scache, idx) {
 
         if (!e->lazy || !e->memchunk.memblock)
             continue;
index 54fb7ec..58cb4e8 100644 (file)
@@ -27,7 +27,6 @@
 
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/queue.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 
@@ -153,7 +152,7 @@ static void dump_event(const char * prefix, pa_subscription_event*e) {
 }
 #endif
 
-/* Deferred callback for dispatching subscirption events */
+/* Deferred callback for dispatching subscription events */
 static void defer_cb(pa_mainloop_api *m, pa_defer_event *de, void *userdata) {
     pa_core *c = userdata;
     pa_subscription *s;
@@ -209,7 +208,7 @@ void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t i
     pa_subscription_event *e;
     pa_assert(c);
 
-    /* No need for queuing subscriptions of noone is listening */
+    /* No need for queuing subscriptions of no one is listening */
     if (!c->subscriptions)
         return;
 
@@ -234,7 +233,7 @@ void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t i
                  * entry in the queue. */
 
                 free_event(i);
-                pa_log_debug("Dropped redundant event due to remove event.");
+                pa_log_debug_verbose("Dropped redundant event due to remove event.");
                 continue;
             }
 
@@ -242,7 +241,7 @@ void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t i
                 /* This object has changed. If a "new" or "change" event for
                  * this object is still in the queue we can exit. */
 
-                pa_log_debug("Dropped redundant event due to change event.");
+                pa_log_debug_verbose("Dropped redundant event due to change event.");
                 return;
             }
         }
index 258e8ee..9d1b484 100644 (file)
 #include <fcntl.h>
 #include <unistd.h>
 #include <limits.h>
-#include <time.h>
 #include <ctype.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/time.h>
 #include <dirent.h>
-#include <regex.h>
+
+#ifdef HAVE_LANGINFO_H
 #include <langinfo.h>
+#endif
+
+#ifdef HAVE_UNAME
 #include <sys/utsname.h>
-#include <sys/socket.h>
+#endif
+
+#if defined(HAVE_REGEX_H)
+#include <regex.h>
+#elif defined(HAVE_PCREPOSIX_H)
+#include <pcreposix.h>
+#endif
 
 #ifdef HAVE_STRTOF_L
 #include <locale.h>
 #include <windows.h>
 #endif
 
+#ifndef ENOTSUP
+#define ENOTSUP   135
+#endif
+
 #ifdef HAVE_PWD_H
 #include <pwd.h>
 #endif
 
 #ifdef __APPLE__
 #include <xlocale.h>
+#include <mach/mach_init.h>
+#include <mach/thread_act.h>
+#include <mach/thread_policy.h>
+#include <sys/sysctl.h>
 #endif
 
 #ifdef HAVE_DBUS
 #include <pulse/utf8.h>
 
 #include <pulsecore/core-error.h>
-#include <pulsecore/winsock.h>
+#include <pulsecore/socket.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/thread.h>
 #include <pulsecore/usergroup.h>
 #include <pulsecore/strlist.h>
 #include <pulsecore/cpu-x86.h>
+#include <pulsecore/pipe.h>
 
 #include "core-util.h"
 
 #define MSG_NOSIGNAL 0
 #endif
 
+#define NEWLINE "\r\n"
+#define WHITESPACE "\n\r \t"
+
 static pa_strlist *recorded_env = NULL;
 
 #ifdef OS_IS_WIN32
 
-#define PULSE_ROOTENV "PULSE_ROOT"
+#include "poll.h"
 
-int pa_set_root(HANDLE handle) {
-    char library_path[MAX_PATH + sizeof(PULSE_ROOTENV) + 1], *sep;
+/* Returns the directory of the current DLL, with '/bin/' removed if it is the last component */
+char *pa_win32_get_toplevel(HANDLE handle) {
+    static char *toplevel = NULL;
 
-    strcpy(library_path, PULSE_ROOTENV "=");
+    if (!toplevel) {
+        char library_path[MAX_PATH];
+        char *p;
 
-    /* FIXME: Needs to set errno */
+        if (!GetModuleFileName(handle, library_path, MAX_PATH))
+            return NULL;
 
-    if (!GetModuleFileName(handle, library_path + sizeof(PULSE_ROOTENV), MAX_PATH))
-        return 0;
+        toplevel = pa_xstrdup(library_path);
 
-    sep = strrchr(library_path, PA_PATH_SEP_CHAR);
-    if (sep)
-        *sep = '\0';
+        p = strrchr(toplevel, PA_PATH_SEP_CHAR);
+        if (p)
+            *p = '\0';
 
-    if (_putenv(library_path) < 0)
-        return 0;
+        p = strrchr(toplevel, PA_PATH_SEP_CHAR);
+        if (p && pa_streq(p + 1, "bin"))
+            *p = '\0';
+    }
 
-    return 1;
+    return toplevel;
 }
 
 #endif
@@ -193,37 +218,84 @@ void pa_make_fd_cloexec(int fd) {
 
 }
 
-/** Creates a directory securely */
-int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) {
+/** Creates a directory securely. Will create parent directories recursively if
+ * required. This will not update permissions on parent directories if they
+ * already exist, however. */
+int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid, pa_bool_t update_perms) {
     struct stat st;
     int r, saved_errno;
+    pa_bool_t retry = TRUE;
 
     pa_assert(dir);
 
+again:
 #ifdef OS_IS_WIN32
     r = mkdir(dir);
 #else
-    {
+{
     mode_t u;
     u = umask((~m) & 0777);
     r = mkdir(dir, m);
     umask(u);
-    }
+}
 #endif
 
+    if (r < 0 && errno == ENOENT && retry) {
+        /* If a parent directory in the path doesn't exist, try to create that
+         * first, then try again. */
+        pa_make_secure_parent_dir(dir, m, uid, gid, FALSE);
+        retry = FALSE;
+        goto again;
+    }
+
     if (r < 0 && errno != EEXIST)
         return -1;
 
-#ifdef HAVE_CHOWN
-    if (uid == (uid_t)-1)
+#if defined(HAVE_FSTAT) && !defined(OS_IS_WIN32)
+{
+    int fd;
+    if ((fd = open(dir,
+#ifdef O_CLOEXEC
+                   O_CLOEXEC|
+#endif
+#ifdef O_NOCTTY
+                   O_NOCTTY|
+#endif
+#ifdef O_NOFOLLOW
+                   O_NOFOLLOW|
+#endif
+                   O_RDONLY)) < 0)
+        goto fail;
+
+    if (fstat(fd, &st) < 0) {
+        pa_assert_se(pa_close(fd) >= 0);
+        goto fail;
+    }
+
+    if (!S_ISDIR(st.st_mode)) {
+        pa_assert_se(pa_close(fd) >= 0);
+        errno = EEXIST;
+        goto fail;
+    }
+
+    if (!update_perms)
+        return 0;
+
+#ifdef HAVE_FCHOWN
+    if (uid == (uid_t) -1)
         uid = getuid();
-    if (gid == (gid_t)-1)
+    if (gid == (gid_t) -1)
         gid = getgid();
-    (void) chown(dir, uid, gid);
+    if (fchown(fd, uid, gid) < 0)
+        goto fail;
 #endif
 
-#ifdef HAVE_CHMOD
-    chmod(dir, m);
+#ifdef HAVE_FCHMOD
+    (void) fchmod(fd, m);
+#endif
+
+    pa_assert_se(pa_close(fd) >= 0);
+}
 #endif
 
 #ifdef HAVE_LSTAT
@@ -270,14 +342,14 @@ char *pa_parent_dir(const char *fn) {
 }
 
 /* Creates a the parent directory of the specified path securely */
-int pa_make_secure_parent_dir(const char *fn, mode_t m, uid_t uid, gid_t gid) {
+int pa_make_secure_parent_dir(const char *fn, mode_t m, uid_t uid, gid_t gid, pa_bool_t update_perms) {
     int ret = -1;
     char *dir;
 
     if (!(dir = pa_parent_dir(fn)))
         goto finish;
 
-    if (pa_make_secure_dir(dir, m, uid, gid) < 0)
+    if (pa_make_secure_dir(dir, m, uid, gid, update_perms) < 0)
         goto finish;
 
     ret = 0;
@@ -298,13 +370,26 @@ ssize_t pa_read(int fd, void *buf, size_t count, int *type) {
 #ifdef OS_IS_WIN32
 
     if (!type || *type == 0) {
+        int err;
         ssize_t r;
 
+retry:
         if ((r = recv(fd, buf, count, 0)) >= 0)
             return r;
 
-        if (WSAGetLastError() != WSAENOTSOCK) {
-            errno = WSAGetLastError();
+        err = WSAGetLastError();
+        if (err != WSAENOTSOCK) {
+            /* transparently handle non-blocking sockets, by waiting
+             * for readiness */
+            if (err == WSAEWOULDBLOCK) {
+                struct pollfd pfd;
+                pfd.fd = fd;
+                pfd.events = POLLIN;
+                if (pa_poll(&pfd, 1, -1) >= 0) {
+                    goto retry;
+                }
+            }
+            errno = err;
             return r;
         }
 
@@ -330,7 +415,11 @@ ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {
 
     if (!type || *type == 0) {
         ssize_t r;
+#ifdef OS_IS_WIN32
+        int err;
 
+retry:
+#endif
         for (;;) {
             if ((r = send(fd, buf, count, MSG_NOSIGNAL)) < 0) {
 
@@ -344,8 +433,19 @@ ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {
         }
 
 #ifdef OS_IS_WIN32
-        if (WSAGetLastError() != WSAENOTSOCK) {
-            errno = WSAGetLastError();
+        err = WSAGetLastError();
+        if (err != WSAENOTSOCK) {
+            /* transparently handle non-blocking sockets, by waiting
+             * for readiness */
+            if (err == WSAEWOULDBLOCK) {
+                struct pollfd pfd;
+                pfd.fd = fd;
+                pfd.events = POLLOUT;
+                if (pa_poll(&pfd, 1, -1) >= 0) {
+                    goto retry;
+                }
+            }
+            errno = err;
             return r;
         }
 #else
@@ -502,7 +602,7 @@ void pa_check_signal_is_blocked(int sig) {
 /* The following function is based on an example from the GNU libc
  * documentation. This function is similar to GNU's asprintf(). */
 char *pa_sprintf_malloc(const char *format, ...) {
-    size_t  size = 100;
+    size_t size = 100;
     char *c = NULL;
 
     pa_assert(format);
@@ -532,7 +632,7 @@ char *pa_sprintf_malloc(const char *format, ...) {
 /* Same as the previous function, but use a va_list instead of an
  * ellipsis */
 char *pa_vsprintf_malloc(const char *format, va_list ap) {
-    size_t  size = 100;
+    size_t size = 100;
     char *c = NULL;
 
     pa_assert(format);
@@ -578,10 +678,12 @@ char *pa_strlcpy(char *b, const char *s, size_t l) {
     return b;
 }
 
+#ifdef _POSIX_PRIORITY_SCHEDULING
 static int set_scheduler(int rtprio) {
+#ifdef HAVE_SCHED_H
     struct sched_param sp;
-    int r;
 #ifdef HAVE_DBUS
+    int r;
     DBusError error;
     DBusConnection *bus;
 
@@ -602,11 +704,12 @@ static int set_scheduler(int rtprio) {
         pa_log_debug("SCHED_RR worked.");
         return 0;
     }
+#endif  /* HAVE_SCHED_H */
 
 #ifdef HAVE_DBUS
     /* Try to talk to RealtimeKit */
 
-    if (!(bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
+    if (!(bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error))) {
         pa_log("Failed to connect to system bus: %s\n", error.message);
         dbus_error_free(&error);
         errno = -EIO;
@@ -619,6 +722,7 @@ static int set_scheduler(int rtprio) {
     dbus_connection_set_exit_on_disconnect(bus, FALSE);
 
     r = rtkit_make_realtime(bus, 0, rtprio);
+    dbus_connection_close(bus);
     dbus_connection_unref(bus);
 
     if (r >= 0) {
@@ -628,18 +732,51 @@ static int set_scheduler(int rtprio) {
 
     errno = -r;
 #else
-    errno = r;
+    errno = 0;
 #endif
 
     return -1;
 }
+#endif
 
 /* Make the current thread a realtime thread, and acquire the highest
  * rtprio we can get that is less or equal the specified parameter. If
  * the thread is already realtime, don't do anything. */
 int pa_make_realtime(int rtprio) {
 
-#ifdef _POSIX_PRIORITY_SCHEDULING
+#if defined(OS_IS_DARWIN)
+    struct thread_time_constraint_policy ttcpolicy;
+    uint64_t freq = 0;
+    size_t size = sizeof(freq);
+    int ret;
+
+    ret = sysctlbyname("hw.cpufrequency", &freq, &size, NULL, 0);
+    if (ret < 0) {
+        pa_log_info("Unable to read CPU frequency, acquisition of real-time scheduling failed.");
+        return -1;
+    }
+
+    pa_log_debug("sysctl for hw.cpufrequency: %llu", freq);
+
+    /* See http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html */
+    ttcpolicy.period = freq / 160;
+    ttcpolicy.computation = freq / 3300;
+    ttcpolicy.constraint = freq / 2200;
+    ttcpolicy.preemptible = 1;
+
+    ret = thread_policy_set(mach_thread_self(),
+                            THREAD_TIME_CONSTRAINT_POLICY,
+                            (thread_policy_t) &ttcpolicy,
+                            THREAD_TIME_CONSTRAINT_POLICY_COUNT);
+    if (ret) {
+        pa_log_info("Unable to set real-time thread priority (%08x).", ret);
+        return -1;
+    }
+
+    pa_log_info("Successfully acquired real-time thread priority.");
+    return 0;
+
+#elif defined(_POSIX_PRIORITY_SCHEDULING)
     int p;
 
     if (set_scheduler(rtprio) >= 0) {
@@ -648,20 +785,28 @@ int pa_make_realtime(int rtprio) {
     }
 
     for (p = rtprio-1; p >= 1; p--)
-        if (set_scheduler(p)) {
+        if (set_scheduler(p) >= 0) {
             pa_log_info("Successfully enabled SCHED_RR scheduling for thread, with priority %i, which is lower than the requested %i.", p, rtprio);
             return 0;
         }
+#elif defined(OS_IS_WIN32)
+    /* Windows only allows realtime scheduling to be set on a per process basis.
+     * Therefore, instead of making the thread realtime, just give it the highest non-realtime priority. */
+    if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL)) {
+        pa_log_info("Successfully enabled THREAD_PRIORITY_TIME_CRITICAL scheduling for thread.");
+        return 0;
+    }
 
-    pa_log_info("Failed to acquire real-time scheduling: %s", pa_cstrerror(errno));
-    return -1;
+    pa_log_warn("SetThreadPriority() failed: 0x%08X", GetLastError());
+    errno = EPERM;
 #else
-
     errno = ENOTSUP;
-    return -1;
 #endif
+    pa_log_info("Failed to acquire real-time scheduling: %s", pa_cstrerror(errno));
+    return -1;
 }
 
+#ifdef HAVE_SYS_RESOURCE_H
 static int set_nice(int nice_level) {
 #ifdef HAVE_DBUS
     DBusError error;
@@ -671,10 +816,12 @@ static int set_nice(int nice_level) {
     dbus_error_init(&error);
 #endif
 
+#ifdef HAVE_SYS_RESOURCE_H
     if (setpriority(PRIO_PROCESS, 0, nice_level) >= 0) {
         pa_log_debug("setpriority() worked.");
         return 0;
     }
+#endif
 
 #ifdef HAVE_DBUS
     /* Try to talk to RealtimeKit */
@@ -704,6 +851,7 @@ static int set_nice(int nice_level) {
 
     return -1;
 }
+#endif
 
 /* Raise the priority of the current process as much as possible that
  * is <= the specified nice level..*/
@@ -718,7 +866,7 @@ int pa_raise_priority(int nice_level) {
     }
 
     for (n = nice_level+1; n < 0; n++)
-        if (set_nice(n) > 0) {
+        if (set_nice(n) >= 0) {
             pa_log_info("Successfully acquired nice level %i, which is lower than the requested %i.", n, nice_level);
             return 0;
         }
@@ -786,16 +934,18 @@ int pa_match(const char *expr, const char *v) {
 
 /* Try to parse a boolean string value.*/
 int pa_parse_boolean(const char *v) {
-    const char *expr;
     pa_assert(v);
 
-    /* First we check language independant */
-    if (!strcmp(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
+    /* First we check language independent */
+    if (pa_streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
         return 1;
-    else if (!strcmp(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
+    else if (pa_streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
         return 0;
 
-    /* And then we check language dependant */
+#ifdef HAVE_LANGINFO_H
+{
+    const char *expr;
+    /* And then we check language dependent */
     if ((expr = nl_langinfo(YESEXPR)))
         if (expr[0])
             if (pa_match(expr, v) > 0)
@@ -805,15 +955,59 @@ int pa_parse_boolean(const char *v) {
         if (expr[0])
             if (pa_match(expr, v) > 0)
                 return 0;
+}
+#endif
 
     errno = EINVAL;
     return -1;
 }
 
+/* Try to parse a volume string to pa_volume_t. The allowed formats are:
+ * db, % and unsigned integer */
+int pa_parse_volume(const char *v, pa_volume_t *volume) {
+    int len, ret = -1;
+    uint32_t i;
+    double d;
+    char str[64];
+
+    pa_assert(v);
+    pa_assert(volume);
+
+    len = strlen(v);
+
+    if (len >= 64)
+        return -1;
+
+    memcpy(str, v, len + 1);
+
+    if (str[len - 1] == '%') {
+        str[len - 1] = '\0';
+        if (pa_atou(str, &i) == 0) {
+            *volume = PA_CLAMP_VOLUME((uint64_t) PA_VOLUME_NORM * i / 100);
+            ret = 0;
+        }
+    } else if (len > 2 && (str[len - 1] == 'b' || str[len - 1] == 'B') &&
+               (str[len - 2] == 'd' || str[len - 2] == 'D')) {
+        str[len - 2] = '\0';
+        if (pa_atod(str, &d) == 0) {
+            *volume = pa_sw_volume_from_dB(d);
+            ret = 0;
+        }
+    } else {
+        if (pa_atou(v, &i) == 0) {
+            *volume= PA_CLAMP_VOLUME(i);
+            ret = 0;
+        }
+
+    }
+
+    return ret;
+}
+
 /* Split the specified string wherever one of the strings in delimiter
  * occurs. Each time it is called returns a newly allocated string
  * with pa_xmalloc(). The variable state points to, should be
- * initiallized to NULL before the first call. */
+ * initialized to NULL before the first call. */
 char *pa_split(const char *c, const char *delimiter, const char**state) {
     const char *current = *state ? *state : c;
     size_t l;
@@ -830,8 +1024,28 @@ char *pa_split(const char *c, const char *delimiter, const char**state) {
     return pa_xstrndup(current, l);
 }
 
-/* What is interpreted as whitespace? */
-#define WHITESPACE " \t\n"
+/* Split the specified string wherever one of the strings in delimiter
+ * occurs. Each time it is called returns a pointer to the substring within the
+ * string and the length in 'n'. Note that the resultant string cannot be used
+ * as-is without the length parameter, since it is merely pointing to a point
+ * within the original string. The variable state points to, should be
+ * initialized to NULL before the first call. */
+const char *pa_split_in_place(const char *c, const char *delimiter, int *n, const char**state) {
+    const char *current = *state ? *state : c;
+    size_t l;
+
+    if (!*current)
+        return NULL;
+
+    l = strcspn(current, delimiter);
+    *state = current+l;
+
+    if (**state)
+        (*state)++;
+
+    *n = l;
+    return current;
+}
 
 /* Split a string into words. Otherwise similar to pa_split(). */
 char *pa_split_spaces(const char *c, const char **state) {
@@ -876,7 +1090,7 @@ const char *pa_sig2str(int sig) {
     }
 #else
 
-    switch(sig) {
+    switch (sig) {
 #ifdef SIGHUP
         case SIGHUP:    return "SIGHUP";
 #endif
@@ -987,8 +1201,7 @@ static int is_group(gid_t gid, const char *name) {
     int r = -1;
 
     errno = 0;
-    if (!(group = pa_getgrgid_malloc(gid)))
-    {
+    if (!(group = pa_getgrgid_malloc(gid))) {
         if (!errno)
             errno = ENOENT;
 
@@ -997,7 +1210,7 @@ static int is_group(gid_t gid, const char *name) {
         goto finish;
     }
 
-    r = strcmp(name, group->gr_name) == 0;
+    r = pa_streq(name, group->gr_name);
 
 finish:
     pa_getgrgid_free(group);
@@ -1047,15 +1260,14 @@ finish:
     return r;
 }
 
-/* Check whether the specifc user id is a member of the specified group */
+/* Check whether the specific user id is a member of the specified group */
 int pa_uid_in_group(uid_t uid, const char *name) {
     struct group *group = NULL;
     char **i;
     int r = -1;
 
     errno = 0;
-    if (!(group = pa_getgrnam_malloc(name)))
-    {
+    if (!(group = pa_getgrnam_malloc(name))) {
         if (!errno)
             errno = ENOENT;
         goto finish;
@@ -1084,14 +1296,13 @@ finish:
     return r;
 }
 
-/* Get the GID of a gfiven group, return (gid_t) -1 on failure. */
+/* Get the GID of a given group, return (gid_t) -1 on failure. */
 gid_t pa_get_gid_of_group(const char *name) {
     gid_t ret = (gid_t) -1;
     struct group *gr = NULL;
 
     errno = 0;
-    if (!(gr = pa_getgrnam_malloc(name)))
-    {
+    if (!(gr = pa_getgrnam_malloc(name))) {
         if (!errno)
             errno = ENOENT;
         goto finish;
@@ -1121,23 +1332,23 @@ int pa_check_in_group(gid_t g) {
 #else /* HAVE_GRP_H */
 
 int pa_own_uid_in_group(const char *name, gid_t *gid) {
-    errno = ENOSUP;
+    errno = ENOTSUP;
     return -1;
 
 }
 
 int pa_uid_in_group(uid_t uid, const char *name) {
-    errno = ENOSUP;
+    errno = ENOTSUP;
     return -1;
 }
 
 gid_t pa_get_gid_of_group(const char *name) {
-    errno = ENOSUP;
+    errno = ENOTSUP;
     return (gid_t) -1;
 }
 
 int pa_check_in_group(gid_t g) {
-    errno = ENOSUP;
+    errno = ENOTSUP;
     return -1;
 }
 
@@ -1159,18 +1370,18 @@ int pa_lock_fd(int fd, int b) {
     if (fcntl(fd, F_SETLKW, &f_lock) >= 0)
         return 0;
 
-    /* Perhaps the file descriptor qas opened for read only, than try again with a read lock. */
+    /* Perhaps the file descriptor was opened for read only, than try again with a read lock. */
     if (b && errno == EBADF) {
         f_lock.l_type = F_RDLCK;
         if (fcntl(fd, F_SETLKW, &f_lock) >= 0)
             return 0;
     }
 
-    pa_log("%slock: %s", !b? "un" : "", pa_cstrerror(errno));
+    pa_log("%slock: %s", !b ? "un" : "", pa_cstrerror(errno));
 #endif
 
 #ifdef OS_IS_WIN32
-    HANDLE h = (HANDLE)_get_osfhandle(fd);
+    HANDLE h = (HANDLE) _get_osfhandle(fd);
 
     if (b && LockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF))
         return 0;
@@ -1189,7 +1400,27 @@ int pa_lock_fd(int fd, int b) {
 char* pa_strip_nl(char *s) {
     pa_assert(s);
 
-    s[strcspn(s, "\r\n")] = 0;
+    s[strcspn(s, NEWLINE)] = 0;
+    return s;
+}
+
+char *pa_strip(char *s) {
+    char *e, *l = NULL;
+
+    /* Drops trailing whitespace. Modifies the string in
+     * place. Returns pointer to first non-space character */
+
+    s += strspn(s, WHITESPACE);
+
+    for (e = s; *e; e++)
+        if (!strchr(WHITESPACE, *e))
+            l = e;
+
+    if (l)
+        *(l+1) = 0;
+    else
+        *s = 0;
+
     return s;
 }
 
@@ -1201,10 +1432,7 @@ int pa_lock_lockfile(const char *fn) {
     for (;;) {
         struct stat st;
 
-        if ((fd = open(fn, O_CREAT|O_RDWR
-#ifdef O_NOCTTY
-                       |O_NOCTTY
-#endif
+        if ((fd = pa_open_cloexec(fn, O_CREAT|O_RDWR
 #ifdef O_NOFOLLOW
                        |O_NOFOLLOW
 #endif
@@ -1253,7 +1481,7 @@ fail:
     return -1;
 }
 
-/* Unlock a temporary lcok file */
+/* Unlock a temporary lock file */
 int pa_unlock_lockfile(const char *fn, int fd) {
     int r = 0;
     pa_assert(fd >= 0);
@@ -1278,31 +1506,62 @@ int pa_unlock_lockfile(const char *fn, int fd) {
     return r;
 }
 
-static char *get_pulse_home(void) {
-    char *h;
+static char *get_config_home(char *home) {
+    char *t;
+
+    t = getenv("XDG_CONFIG_HOME");
+    if (t)
+        return pa_xstrdup(t);
+
+    return pa_sprintf_malloc("%s" PA_PATH_SEP ".config", home);
+}
+
+static int check_ours(const char *p) {
     struct stat st;
-    char *ret = NULL;
 
-    if (!(h = pa_get_home_dir_malloc())) {
+    pa_assert(p);
+
+    if (stat(p, &st) < 0)
+        return -errno;
+
+#ifdef HAVE_GETUID
+    if (st.st_uid != getuid())
+        return -EACCES;
+#endif
+
+    return 0;
+}
+
+static char *get_pulse_home(void) {
+    char *h, *ret, *config_home;
+    int t;
+
+    h = pa_get_home_dir_malloc();
+    if (!h) {
         pa_log_error("Failed to get home directory.");
         return NULL;
     }
 
-    if (stat(h, &st) < 0) {
-        pa_log_error("Failed to stat home directory %s: %s", h, pa_cstrerror(errno));
-        goto finish;
-    }
-
-    if (st.st_uid != getuid()) {
-        pa_log_error("Home directory %s not ours.", h);
-        errno = EACCES;
-        goto finish;
+    t = check_ours(h);
+    if (t < 0 && t != -ENOENT) {
+        pa_log_error("Home directory not accessible: %s", pa_cstrerror(-t));
+        pa_xfree(h);
+        return NULL;
     }
 
+    /* If the old directory exists, use it. */
     ret = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse", h);
+    if (access(ret, F_OK) >= 0) {
+        free(h);
+        return ret;
+    }
+    free(ret);
 
-finish:
-    pa_xfree(h);
+    /* Otherwise go for the XDG compliant directory. */
+    config_home = get_config_home(h);
+    free(h);
+    ret = pa_sprintf_malloc("%s" PA_PATH_SEP "pulse", config_home);
+    free(config_home);
 
     return ret;
 }
@@ -1320,8 +1579,8 @@ char *pa_get_state_dir(void) {
     /* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
      * dir then this will break. */
 
-    if (pa_make_secure_dir(d, 0700U, (uid_t) -1, (gid_t) -1) < 0)  {
-        pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
+    if (pa_make_secure_dir(d, 0700U, (uid_t) -1, (gid_t) -1, TRUE) < 0) {
+        pa_log_error("Failed to create secure directory (%s): %s", d, pa_cstrerror(errno));
         pa_xfree(d);
         return NULL;
     }
@@ -1395,7 +1654,11 @@ static char* make_random_dir(mode_t m) {
             fn[i] = table[rand() % (sizeof(table)-1)];
 
         u = umask((~m) & 0777);
+#ifndef OS_IS_WIN32
         r = mkdir(fn, m);
+#else
+        r = mkdir(fn);
+#endif
 
         saved_errno = errno;
         umask(u);
@@ -1418,6 +1681,7 @@ static int make_random_dir_and_link(mode_t m, const char *k) {
     if (!(p = make_random_dir(m)))
         return -1;
 
+#ifdef HAVE_SYMLINK
     if (symlink(p, k) < 0) {
         int saved_errno = errno;
 
@@ -1430,6 +1694,10 @@ static int make_random_dir_and_link(mode_t m, const char *k) {
         errno = saved_errno;
         return -1;
     }
+#else
+    pa_xfree(p);
+    return -1;
+#endif
 
     pa_xfree(p);
     return 0;
@@ -1437,38 +1705,56 @@ static int make_random_dir_and_link(mode_t m, const char *k) {
 
 char *pa_get_runtime_dir(void) {
     char *d, *k = NULL, *p = NULL, *t = NULL, *mid;
-    struct stat st;
     mode_t m;
 
     /* The runtime directory shall contain dynamic data that needs NOT
-     * to be kept accross reboots and is usuallly private to the user,
+     * to be kept across reboots and is usually private to the user,
      * except in system mode, where it might be accessible by other
      * users, too. Since we need POSIX locking and UNIX sockets in
-     * this directory, we link it to a random subdir in /tmp, if it
-     * was not explicitly configured. */
+     * this directory, we try XDG_RUNTIME_DIR first, and if that isn't
+     * set create a directory in $HOME and link it to a random subdir
+     * in /tmp, if it was not explicitly configured. */
 
     m = pa_in_system_mode() ? 0755U : 0700U;
 
-    if ((d = getenv("PULSE_RUNTIME_PATH"))) {
+    /* Use the explicitly configured value if it is set */
+    d = getenv("PULSE_RUNTIME_PATH");
+    if (d) {
 
-        if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0)  {
-            pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
+        if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1, TRUE) < 0) {
+            pa_log_error("Failed to create secure directory (%s): %s", d, pa_cstrerror(errno));
             goto fail;
         }
 
         return pa_xstrdup(d);
     }
 
-    if (!(d = get_pulse_home()))
+    /* Use the XDG standard for the runtime directory. */
+    d = getenv("XDG_RUNTIME_DIR");
+    if (d) {
+        k = pa_sprintf_malloc("%s" PA_PATH_SEP "pulse", d);
+
+        if (pa_make_secure_dir(k, m, (uid_t) -1, (gid_t) -1, TRUE) < 0) {
+            pa_log_error("Failed to create secure directory (%s): %s", k, pa_cstrerror(errno));
+            goto fail;
+        }
+
+        return k;
+    }
+
+    /* XDG_RUNTIME_DIR wasn't set, use the old legacy fallback */
+    d = get_pulse_home();
+    if (!d)
         goto fail;
 
-    if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0)  {
-        pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
+    if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1, TRUE) < 0) {
+        pa_log_error("Failed to create secure directory (%s): %s", d, pa_cstrerror(errno));
         pa_xfree(d);
         goto fail;
     }
 
-    if (!(mid = pa_machine_id())) {
+    mid = pa_machine_id();
+    if (!mid) {
         pa_xfree(d);
         goto fail;
     }
@@ -1478,16 +1764,17 @@ char *pa_get_runtime_dir(void) {
     pa_xfree(mid);
 
     for (;;) {
-        /* OK, first let's check if the "runtime" symlink is already
-         * existant */
+        /* OK, first let's check if the "runtime" symlink already exists */
 
-        if (!(p = pa_readlink(k))) {
+        p = pa_readlink(k);
+        if (!p) {
 
             if (errno != ENOENT) {
                 pa_log_error("Failed to stat runtime directory %s: %s", k, pa_cstrerror(errno));
                 goto fail;
             }
 
+#ifdef HAVE_SYMLINK
             /* Hmm, so the runtime directory didn't exist yet, so let's
              * create one in /tmp and symlink that to it */
 
@@ -1500,6 +1787,12 @@ char *pa_get_runtime_dir(void) {
 
                 goto fail;
             }
+#else
+            /* No symlink possible, so let's just create the runtime directly
+             * Do not check again if it exists since it cannot be a symlink */
+            if (mkdir(k) < 0 && errno != EEXIST)
+                goto fail;
+#endif
 
             return k;
         }
@@ -1511,9 +1804,10 @@ char *pa_get_runtime_dir(void) {
             goto fail;
         }
 
-        /* Hmm, so this symlink is still around, make sure nobody fools
-         * us */
-
+        /* Hmm, so this symlink is still around, make sure nobody fools us */
+#ifdef HAVE_LSTAT
+{
+        struct stat st;
         if (lstat(p, &st) < 0) {
 
             if (errno != ENOENT) {
@@ -1533,6 +1827,8 @@ char *pa_get_runtime_dir(void) {
 
             pa_log_info("Hmm, runtime path exists, but points to an invalid directory. Changing runtime directory.");
         }
+}
+#endif
 
         pa_xfree(p);
         p = NULL;
@@ -1554,7 +1850,7 @@ char *pa_get_runtime_dir(void) {
             pa_xfree(t);
             t = NULL;
 
-            /* Hmm, someone lese was quicker then us. Let's give
+            /* Hmm, someone else was quicker then us. Let's give
              * him some time to finish, and retry. */
             pa_msleep(10);
             continue;
@@ -1587,24 +1883,10 @@ fail:
  * stored there.*/
 FILE *pa_open_config_file(const char *global, const char *local, const char *env, char **result) {
     const char *fn;
-#ifdef OS_IS_WIN32
-    char buf[PATH_MAX];
-
-    if (!getenv(PULSE_ROOTENV))
-        pa_set_root(NULL);
-#endif
+    FILE *f;
 
     if (env && (fn = getenv(env))) {
-        FILE *f;
-
-#ifdef OS_IS_WIN32
-        if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX))
-            /* FIXME: Needs to set errno! */
-            return NULL;
-        fn = buf;
-#endif
-
-        if ((f = fopen(fn, "r"))) {
+        if ((f = pa_fopen_cloexec(fn, "r"))) {
             if (result)
                 *result = pa_xstrdup(fn);
 
@@ -1619,26 +1901,23 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env
         const char *e;
         char *lfn;
         char *h;
-        FILE *f;
 
-        if ((e = getenv("PULSE_CONFIG_PATH")))
+        if ((e = getenv("PULSE_CONFIG_PATH"))) {
             fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", e, local);
-        else if ((h = pa_get_home_dir_malloc())) {
+            f = pa_fopen_cloexec(fn, "r");
+        } else if ((h = pa_get_home_dir_malloc())) {
             fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".pulse" PA_PATH_SEP "%s", h, local);
+            f = pa_fopen_cloexec(fn, "r");
+            if (!f) {
+                free(lfn);
+                fn = lfn = pa_sprintf_malloc("%s" PA_PATH_SEP ".config/pulse" PA_PATH_SEP "%s", h, local);
+                f = pa_fopen_cloexec(fn, "r");
+            }
             pa_xfree(h);
         } else
             return NULL;
 
-#ifdef OS_IS_WIN32
-        if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX)) {
-            /* FIXME: Needs to set errno! */
-            pa_xfree(lfn);
-            return NULL;
-        }
-        fn = buf;
-#endif
-
-        if ((f = fopen(fn, "r"))) {
+        if (f) {
             if (result)
                 *result = pa_xstrdup(fn);
 
@@ -1656,22 +1935,26 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env
     }
 
     if (global) {
-        FILE *f;
+        char *gfn;
 
 #ifdef OS_IS_WIN32
-        if (!ExpandEnvironmentStrings(global, buf, PATH_MAX))
-            /* FIXME: Needs to set errno! */
-            return NULL;
-        global = buf;
+        if (strncmp(global, PA_DEFAULT_CONFIG_DIR, strlen(PA_DEFAULT_CONFIG_DIR)) == 0)
+            gfn = pa_sprintf_malloc("%s" PA_PATH_SEP "etc" PA_PATH_SEP "pulse%s",
+                                    pa_win32_get_toplevel(NULL),
+                                    global + strlen(PA_DEFAULT_CONFIG_DIR));
+        else
 #endif
+        gfn = pa_xstrdup(global);
 
-        if ((f = fopen(global, "r"))) {
-
+        if ((f = pa_fopen_cloexec(gfn, "r"))) {
             if (result)
-                *result = pa_xstrdup(global);
+                *result = gfn;
+            else
+                pa_xfree(gfn);
 
             return f;
         }
+        pa_xfree(gfn);
     }
 
     errno = ENOENT;
@@ -1680,22 +1963,8 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env
 
 char *pa_find_config_file(const char *global, const char *local, const char *env) {
     const char *fn;
-#ifdef OS_IS_WIN32
-    char buf[PATH_MAX];
-
-    if (!getenv(PULSE_ROOTENV))
-        pa_set_root(NULL);
-#endif
 
     if (env && (fn = getenv(env))) {
-
-#ifdef OS_IS_WIN32
-        if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX))
-            /* FIXME: Needs to set errno! */
-            return NULL;
-        fn = buf;
-#endif
-
         if (access(fn, R_OK) == 0)
             return pa_xstrdup(fn);
 
@@ -1716,15 +1985,6 @@ char *pa_find_config_file(const char *global, const char *local, const char *env
         } else
             return NULL;
 
-#ifdef OS_IS_WIN32
-        if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX)) {
-            /* FIXME: Needs to set errno! */
-            pa_xfree(lfn);
-            return NULL;
-        }
-        fn = buf;
-#endif
-
         if (access(fn, R_OK) == 0) {
             char *r = pa_xstrdup(fn);
             pa_xfree(lfn);
@@ -1741,15 +2001,20 @@ char *pa_find_config_file(const char *global, const char *local, const char *env
     }
 
     if (global) {
+        char *gfn;
+
 #ifdef OS_IS_WIN32
-        if (!ExpandEnvironmentStrings(global, buf, PATH_MAX))
-            /* FIXME: Needs to set errno! */
-            return NULL;
-        global = buf;
+        if (strncmp(global, PA_DEFAULT_CONFIG_DIR, strlen(PA_DEFAULT_CONFIG_DIR)) == 0)
+            gfn = pa_sprintf_malloc("%s" PA_PATH_SEP "etc" PA_PATH_SEP "pulse%s",
+                                    pa_win32_get_toplevel(NULL),
+                                    global + strlen(PA_DEFAULT_CONFIG_DIR));
+        else
 #endif
+        gfn = pa_xstrdup(global);
 
-        if (access(global, R_OK) == 0)
-            return pa_xstrdup(global);
+        if (access(gfn, R_OK) == 0)
+            return gfn;
+        pa_xfree(gfn);
     }
 
     errno = ENOENT;
@@ -1766,7 +2031,7 @@ char *pa_hexstr(const uint8_t* d, size_t dlength, char *s, size_t slength) {
     pa_assert(s);
     pa_assert(slength > 0);
 
-    while (i < dlength && j+3 <= slength) {
+    while (j+2 < slength && i < dlength) {
         s[j++] = hex[*d >> 4];
         s[j++] = hex[*d & 0xF];
 
@@ -1843,7 +2108,7 @@ pa_bool_t pa_endswith(const char *s, const char *sfx) {
     l1 = strlen(s);
     l2 = strlen(sfx);
 
-    return l1 >= l2 && strcmp(s+l1-l2, sfx) == 0;
+    return l1 >= l2 && pa_streq(s + l1 - l2, sfx);
 }
 
 pa_bool_t pa_is_path_absolute(const char *fn) {
@@ -1873,37 +2138,50 @@ char *pa_make_path_absolute(const char *p) {
     return r;
 }
 
-/* if fn is null return the PulseAudio run time path in s (~/.pulse)
- * if fn is non-null and starts with / return fn
- * otherwise append fn to the run time path and return it */
+/* If fn is NULL, return the PulseAudio runtime or state dir (depending on the
+ * rt parameter). If fn is non-NULL and starts with /, return fn. Otherwise,
+ * append fn to the runtime/state dir and return it. */
 static char *get_path(const char *fn, pa_bool_t prependmid, pa_bool_t rt) {
     char *rtp;
 
     rtp = rt ? pa_get_runtime_dir() : pa_get_state_dir();
 
     if (fn) {
-        char *r;
+        char *r, *canonical_rtp;
 
-        if (pa_is_path_absolute(fn))
+        if (pa_is_path_absolute(fn)) {
+            pa_xfree(rtp);
             return pa_xstrdup(fn);
+        }
 
         if (!rtp)
             return NULL;
 
+        /* Hopefully make the path smaller to avoid 108 char limit (fdo#44680) */
+        if ((canonical_rtp = pa_realpath(rtp))) {
+            if (strlen(rtp) >= strlen(canonical_rtp))
+                pa_xfree(rtp);
+            else {
+                pa_xfree(canonical_rtp);
+                canonical_rtp = rtp;
+            }
+        } else
+            canonical_rtp = rtp;
+
         if (prependmid) {
             char *mid;
 
             if (!(mid = pa_machine_id())) {
-                pa_xfree(rtp);
+                pa_xfree(canonical_rtp);
                 return NULL;
             }
 
-            r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s-%s", rtp, mid, fn);
+            r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s-%s", canonical_rtp, mid, fn);
             pa_xfree(mid);
         } else
-            r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", rtp, fn);
+            r = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", canonical_rtp, fn);
 
-        pa_xfree(rtp);
+        pa_xfree(canonical_rtp);
         return r;
     } else
         return rtp;
@@ -1919,20 +2197,13 @@ char *pa_state_path(const char *fn, pa_bool_t appendmid) {
 
 /* Convert the string s to a signed integer in *ret_i */
 int pa_atoi(const char *s, int32_t *ret_i) {
-    char *x = NULL;
     long l;
 
     pa_assert(s);
     pa_assert(ret_i);
 
-    errno = 0;
-    l = strtol(s, &x, 0);
-
-    if (!x || *x || errno) {
-        if (!errno)
-            errno = EINVAL;
+    if (pa_atol(s, &l) < 0)
         return -1;
-    }
 
     if ((int32_t) l != l) {
         errno = ERANGE;
@@ -1971,6 +2242,28 @@ int pa_atou(const char *s, uint32_t *ret_u) {
     return 0;
 }
 
+/* Convert the string s to a signed long integer in *ret_l. */
+int pa_atol(const char *s, long *ret_l) {
+    char *x = NULL;
+    long l;
+
+    pa_assert(s);
+    pa_assert(ret_l);
+
+    errno = 0;
+    l = strtol(s, &x, 0);
+
+    if (!x || *x || errno) {
+        if (!errno)
+            errno = EINVAL;
+        return -1;
+    }
+
+    *ret_l = l;
+
+    return 0;
+}
+
 #ifdef HAVE_STRTOF_L
 static locale_t c_locale = NULL;
 
@@ -2094,7 +2387,7 @@ void *pa_will_need(const void *p, size_t l) {
 #endif
     const void *a;
     size_t size;
-    int r;
+    int r = ENOTSUP;
     size_t bs;
 
     pa_assert(p);
@@ -2105,7 +2398,7 @@ void *pa_will_need(const void *p, size_t l) {
 
 #ifdef HAVE_POSIX_MADVISE
     if ((r = posix_madvise((void*) a, size, POSIX_MADV_WILLNEED)) == 0) {
-        pa_log_debug("posix_madvise() worked fine!");
+        pa_log_debug_verbose("posix_madvise() worked fine!");
         return (void*) p;
     }
 #endif
@@ -2172,6 +2465,7 @@ void pa_close_pipe(int fds[2]) {
 }
 
 char *pa_readlink(const char *p) {
+#ifdef HAVE_READLINK
     size_t l = 100;
 
     for (;;) {
@@ -2193,6 +2487,9 @@ char *pa_readlink(const char *p) {
         pa_xfree(c);
         l *= 2;
     }
+#else
+    return NULL;
+#endif
 }
 
 int pa_close_all(int except_fd, ...) {
@@ -2231,6 +2528,7 @@ int pa_close_all(int except_fd, ...) {
 }
 
 int pa_close_allv(const int except_fds[]) {
+#ifndef OS_IS_WIN32
     struct rlimit rl;
     int maxfd, fd;
 
@@ -2320,6 +2618,7 @@ int pa_close_allv(const int except_fds[]) {
         if (pa_close(fd) < 0 && errno != EBADF)
             return -1;
     }
+#endif  /* !OS_IS_WIN32 */
 
     return 0;
 }
@@ -2360,6 +2659,7 @@ int pa_unblock_sigs(int except, ...) {
 }
 
 int pa_unblock_sigsv(const int except[]) {
+#ifndef OS_IS_WIN32
     int i;
     sigset_t ss;
 
@@ -2371,6 +2671,9 @@ int pa_unblock_sigsv(const int except[]) {
             return -1;
 
     return sigprocmask(SIG_SETMASK, &ss, NULL);
+#else
+    return 0;
+#endif
 }
 
 int pa_reset_sigs(int except, ...) {
@@ -2409,6 +2712,7 @@ int pa_reset_sigs(int except, ...) {
 }
 
 int pa_reset_sigsv(const int except[]) {
+#ifndef OS_IS_WIN32
     int sig;
 
     for (sig = 1; sig < NSIG; sig++) {
@@ -2417,6 +2721,14 @@ int pa_reset_sigsv(const int except[]) {
         switch (sig) {
             case SIGKILL:
             case SIGSTOP:
+#ifdef __TIZEN__
+            /*for crash-walker*/
+            case SIGILL:
+            case SIGABRT:
+            case SIGBUS:
+            case SIGFPE:
+            case SIGSEGV:
+#endif
                 reset = FALSE;
                 break;
 
@@ -2445,6 +2757,7 @@ int pa_reset_sigsv(const int except[]) {
                     return -1;
         }
     }
+#endif
 
     return 0;
 }
@@ -2455,7 +2768,11 @@ void pa_set_env(const char *key, const char *value) {
 
     /* This is not thread-safe */
 
-    putenv(pa_sprintf_malloc("%s=%s", key, value));
+#ifdef OS_IS_WIN32
+    SetEnvironmentVariable(key, value);
+#else
+    setenv(key, value, 1);
+#endif
 }
 
 void pa_set_env_and_record(const char *key, const char *value) {
@@ -2480,7 +2797,11 @@ void pa_unset_env_recorded(void) {
         if (!s)
             break;
 
+#ifdef OS_IS_WIN32
+        SetEnvironmentVariable(s, NULL);
+#else
         unsetenv(s);
+#endif
         pa_xfree(s);
     }
 }
@@ -2494,6 +2815,26 @@ pa_bool_t pa_in_system_mode(void) {
     return !!atoi(e);
 }
 
+/* Checks a whitespace-separated list of words in haystack for needle */
+pa_bool_t pa_str_in_list_spaces(const char *haystack, const char *needle) {
+    char *s;
+    const char *state = NULL;
+
+    if (!haystack || !needle)
+        return FALSE;
+
+    while ((s = pa_split_spaces(haystack, &state))) {
+        if (pa_streq(needle, s)) {
+            pa_xfree(s);
+            return TRUE;
+        }
+
+        pa_xfree(s);
+    }
+
+    return FALSE;
+}
+
 char *pa_get_user_name_malloc(void) {
     ssize_t k;
     char *u;
@@ -2560,11 +2901,12 @@ char *pa_machine_id(void) {
     /* The returned value is supposed be some kind of ascii identifier
      * that is unique and stable across reboots. */
 
-    /* First we try the D-Bus UUID, which is the best option we have,
-     * since it fits perfectly our needs and is not as volatile as the
-     * hostname which might be set from dhcp. */
+    /* First we try the /etc/machine-id, which is the best option we
+     * have, since it fits perfectly our needs and is not as volatile
+     * as the hostname which might be set from dhcp. */
 
-    if ((f = fopen(PA_MACHINE_ID, "r"))) {
+    if ((f = pa_fopen_cloexec(PA_MACHINE_ID, "r")) ||
+        (f = pa_fopen_cloexec(PA_MACHINE_ID_FALLBACK, "r"))) {
         char ln[34] = "", *r;
 
         r = fgets(ln, sizeof(ln)-1, f);
@@ -2579,26 +2921,42 @@ char *pa_machine_id(void) {
     if ((h = pa_get_host_name_malloc()))
         return h;
 
+#ifndef OS_IS_WIN32
     /* If no hostname was set we use the POSIX hostid. It's usually
      * the IPv4 address.  Might not be that stable. */
-    return pa_sprintf_malloc("%08lx", (unsigned long) gethostid);
+    return pa_sprintf_malloc("%08lx", (unsigned long) gethostid());
+#else
+    return NULL;
+#endif
 }
 
 char *pa_session_id(void) {
     const char *e;
 
-    if (!(e = getenv("XDG_SESSION_COOKIE")))
+    e = getenv("XDG_SESSION_ID");
+    if (!e)
         return NULL;
 
     return pa_utf8_filter(e);
 }
 
 char *pa_uname_string(void) {
+#ifdef HAVE_UNAME
     struct utsname u;
 
     pa_assert_se(uname(&u) >= 0);
 
     return pa_sprintf_malloc("%s %s %s %s", u.sysname, u.machine, u.release, u.version);
+#endif
+#ifdef OS_IS_WIN32
+    OSVERSIONINFO i;
+
+    pa_zero(i);
+    i.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    pa_assert_se(GetVersionEx(&i));
+
+    return pa_sprintf_malloc("Windows %d.%d (%d) %s", i.dwMajorVersion, i.dwMinorVersion, i.dwBuildNumber, i.szCSDVersion);
+#endif
 }
 
 #ifdef HAVE_VALGRIND_MEMCHECK_H
@@ -2679,6 +3037,28 @@ char *pa_replace(const char*s, const char*a, const char *b) {
     return pa_strbuf_tostring_free(sb);
 }
 
+char *pa_escape(const char *p, const char *chars) {
+    const char *s;
+    const char *c;
+    pa_strbuf *buf = pa_strbuf_new();
+
+    for (s = p; *s; ++s) {
+        if (*s == '\\')
+            pa_strbuf_putc(buf, '\\');
+        else if (chars) {
+            for (c = chars; *c; ++c) {
+                if (*s == *c) {
+                    pa_strbuf_putc(buf, '\\');
+                    break;
+                }
+            }
+        }
+        pa_strbuf_putc(buf, *s);
+    }
+
+    return pa_strbuf_tostring_free(buf);
+}
+
 char *pa_unescape(char *p) {
     char *s, *d;
     pa_bool_t escaped = FALSE;
@@ -2702,13 +3082,13 @@ char *pa_realpath(const char *path) {
     char *t;
     pa_assert(path);
 
-    /* We want only abolsute paths */
+    /* We want only absolute paths */
     if (path[0] != '/') {
         errno = EINVAL;
         return NULL;
     }
 
-#if defined(__GLIBC__) || defined(__APPLE__)
+#if defined(__GLIBC__)
     {
         char *r;
 
@@ -2725,10 +3105,17 @@ char *pa_realpath(const char *path) {
         char *path_buf;
         path_buf = pa_xmalloc(PATH_MAX);
 
+#if defined(OS_IS_WIN32)
+        if (!(t = _fullpath(path_buf, path, _MAX_PATH))) {
+            pa_xfree(path_buf);
+            return NULL;
+        }
+#else
         if (!(t = realpath(path, path_buf))) {
             pa_xfree(path_buf);
             return NULL;
         }
+#endif
     }
 #else
 #error "It's not clear whether this system supports realpath(..., NULL) like GNU libc does. If it doesn't we need a private version of realpath() here."
@@ -2828,25 +3215,20 @@ void pa_reset_personality(void) {
 
 }
 
-#if defined(__linux__) && !defined(__OPTIMIZE__)
-
 pa_bool_t pa_run_from_build_tree(void) {
     char *rp;
-    pa_bool_t b = FALSE;
+    static pa_bool_t b = FALSE;
 
-    /* We abuse __OPTIMIZE__ as a check whether we are a debug build
-     * or not. */
-
-    if ((rp = pa_readlink("/proc/self/exe"))) {
-        b = pa_startswith(rp, PA_BUILDDIR);
-        pa_xfree(rp);
-    }
+    PA_ONCE_BEGIN {
+        if ((rp = pa_readlink("/proc/self/exe"))) {
+            b = pa_startswith(rp, PA_BUILDDIR);
+            pa_xfree(rp);
+        }
+    } PA_ONCE_END;
 
     return b;
 }
 
-#endif
-
 const char *pa_get_temp_dir(void) {
     const char *t;
 
@@ -2866,14 +3248,145 @@ const char *pa_get_temp_dir(void) {
         pa_is_path_absolute(t))
         return t;
 
-    return "/tmp";
+    return "/tmp/pulseaudio";
+}
+
+int pa_open_cloexec(const char *fn, int flags, mode_t mode) {
+    int fd;
+
+#ifdef O_NOCTTY
+    flags |= O_NOCTTY;
+#endif
+
+#ifdef O_CLOEXEC
+    if ((fd = open(fn, flags|O_CLOEXEC, mode)) >= 0)
+        goto finish;
+
+    if (errno != EINVAL)
+        return fd;
+#endif
+
+    if ((fd = open(fn, flags, mode)) < 0)
+        return fd;
+
+finish:
+    /* Some implementations might simply ignore O_CLOEXEC if it is not
+     * understood, make sure FD_CLOEXEC is enabled anyway */
+
+    pa_make_fd_cloexec(fd);
+    return fd;
+}
+
+int pa_socket_cloexec(int domain, int type, int protocol) {
+    int fd;
+
+#ifdef SOCK_CLOEXEC
+    if ((fd = socket(domain, type | SOCK_CLOEXEC, protocol)) >= 0)
+        goto finish;
+
+    if (errno != EINVAL)
+        return fd;
+#endif
+
+    if ((fd = socket(domain, type, protocol)) < 0)
+        return fd;
+
+finish:
+    /* Some implementations might simply ignore SOCK_CLOEXEC if it is
+     * not understood, make sure FD_CLOEXEC is enabled anyway */
+
+    pa_make_fd_cloexec(fd);
+    return fd;
+}
+
+int pa_pipe_cloexec(int pipefd[2]) {
+    int r;
+
+#ifdef HAVE_PIPE2
+    if ((r = pipe2(pipefd, O_CLOEXEC)) >= 0)
+        goto finish;
+
+    if (errno != EINVAL && errno != ENOSYS)
+        return r;
+
+#endif
+
+    if ((r = pipe(pipefd)) < 0)
+        return r;
+
+finish:
+    pa_make_fd_cloexec(pipefd[0]);
+    pa_make_fd_cloexec(pipefd[1]);
+
+    return 0;
+}
+
+int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
+    int fd;
+
+#ifdef HAVE_ACCEPT4
+    if ((fd = accept4(sockfd, addr, addrlen, SOCK_CLOEXEC)) >= 0)
+        goto finish;
+
+    if (errno != EINVAL && errno != ENOSYS)
+        return fd;
+
+#endif
+
+    if ((fd = accept(sockfd, addr, addrlen)) < 0)
+        return fd;
+
+finish:
+    pa_make_fd_cloexec(fd);
+    return fd;
+}
+
+FILE* pa_fopen_cloexec(const char *path, const char *mode) {
+    FILE *f;
+    char *m;
+
+    m = pa_sprintf_malloc("%se", mode);
+
+    errno = 0;
+    if ((f = fopen(path, m))) {
+        pa_xfree(m);
+        goto finish;
+    }
+
+    pa_xfree(m);
+
+    if (errno != EINVAL)
+        return NULL;
+
+    if (!(f = fopen(path, mode)))
+        return NULL;
+
+finish:
+    pa_make_fd_cloexec(fileno(f));
+    return f;
+}
+
+void pa_nullify_stdfds(void) {
+
+#ifndef OS_IS_WIN32
+        pa_close(STDIN_FILENO);
+        pa_close(STDOUT_FILENO);
+        pa_close(STDERR_FILENO);
+
+        pa_assert_se(open("/dev/null", O_RDONLY) == STDIN_FILENO);
+        pa_assert_se(open("/dev/null", O_WRONLY) == STDOUT_FILENO);
+        pa_assert_se(open("/dev/null", O_WRONLY) == STDERR_FILENO);
+#else
+        FreeConsole();
+#endif
+
 }
 
 char *pa_read_line_from_file(const char *fn) {
     FILE *f;
     char ln[256] = "", *r;
 
-    if (!(f = fopen(fn, "r")))
+    if (!(f = pa_fopen_cloexec(fn, "r")))
         return NULL;
 
     r = fgets(ln, sizeof(ln)-1, f);
index eba1b40..7b59fbc 100644 (file)
@@ -34,7 +34,9 @@
 #endif
 
 #include <pulse/gccmacro.h>
+#include <pulse/volume.h>
 #include <pulsecore/macro.h>
+#include <pulsecore/socket.h>
 
 #ifndef PACKAGE
 #error "Please include config.h before including this file!"
@@ -57,8 +59,8 @@ struct timeval;
 void pa_make_fd_nonblock(int fd);
 void pa_make_fd_cloexec(int fd);
 
-int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid);
-int pa_make_secure_parent_dir(const char *fn, mode_t, uid_t uid, gid_t gid);
+int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid, pa_bool_t update_perms);
+int pa_make_secure_parent_dir(const char *fn, mode_t, uid_t uid, gid_t gid, pa_bool_t update_perms);
 
 ssize_t pa_read(int fd, void *buf, size_t count, int *type);
 ssize_t pa_write(int fd, const void *buf, size_t count, int *type);
@@ -82,6 +84,8 @@ void pa_reset_priority(void);
 
 int pa_parse_boolean(const char *s) PA_GCC_PURE;
 
+int pa_parse_volume(const char *s, pa_volume_t *volume);
+
 static inline const char *pa_yes_no(pa_bool_t b) {
     return b ? "yes" : "no";
 }
@@ -99,9 +103,11 @@ static inline const char *pa_strna(const char *x) {
 }
 
 char *pa_split(const char *c, const char*delimiters, const char **state);
+const char *pa_split_in_place(const char *c, const char*delimiters, int *n, const char **state);
 char *pa_split_spaces(const char *c, const char **state);
 
 char *pa_strip_nl(char *s);
+char *pa_strip(char *s);
 
 const char *pa_sig2str(int sig) PA_GCC_PURE;
 
@@ -133,6 +139,7 @@ char *pa_state_path(const char *fn, pa_bool_t prepend_machine_id);
 
 int pa_atoi(const char *s, int32_t *ret_i);
 int pa_atou(const char *s, uint32_t *ret_u);
+int pa_atol(const char *s, long *ret_l);
 int pa_atod(const char *s, double *ret_d);
 
 size_t pa_snprintf(char *str, size_t size, const char *format, ...);
@@ -202,6 +209,16 @@ pa_bool_t pa_in_system_mode(void);
 
 #define pa_streq(a,b) (!strcmp((a),(b)))
 
+/* Like pa_streq, but does not blow up on NULL pointers. */
+static inline bool pa_safe_streq(const char *a, const char *b)
+{
+    if (a == NULL || b == NULL)
+        return a == b;
+    return pa_streq(a, b);
+}
+
+pa_bool_t pa_str_in_list_spaces(const char *needle, const char *haystack);
+
 char *pa_get_host_name_malloc(void);
 char *pa_get_user_name_malloc(void);
 
@@ -224,6 +241,13 @@ unsigned pa_ncpus(void);
 
 char *pa_replace(const char*s, const char*a, const char *b);
 
+/* Escapes p by inserting backslashes in front of backslashes. chars is a
+ * regular (i.e. NULL-terminated) string containing additional characters that
+ * should be escaped. chars can be NULL. The caller has to free the returned
+ * string. */
+char *pa_escape(const char *p, const char *chars);
+
+/* Does regular backslash unescaping. Returns the argument p. */
 char *pa_unescape(char *p);
 
 char *pa_realpath(const char *path);
@@ -245,13 +269,23 @@ size_t pa_pipe_buf(int fd);
 
 void pa_reset_personality(void);
 
-#if defined(__linux__) && !defined(__OPTIMIZE__)
-pa_bool_t pa_run_from_build_tree(void);
-#endif
+pa_bool_t pa_run_from_build_tree(void) PA_GCC_CONST;
 
 const char *pa_get_temp_dir(void);
 
+int pa_open_cloexec(const char *fn, int flags, mode_t mode);
+int pa_socket_cloexec(int domain, int type, int protocol);
+int pa_pipe_cloexec(int pipefd[2]);
+int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+FILE* pa_fopen_cloexec(const char *path, const char *mode);
+
+void pa_nullify_stdfds(void);
+
 char *pa_read_line_from_file(const char *fn);
 pa_bool_t pa_running_in_vm(void);
 
+#ifdef OS_IS_WIN32
+char *pa_win32_get_toplevel(HANDLE handle);
+#endif
+
 #endif
index f072645..9ff2979 100644 (file)
 #include <pulse/xmalloc.h>
 
 #include <pulsecore/module.h>
-#include <pulsecore/sink.h>
-#include <pulsecore/source.h>
-#include <pulsecore/namereg.h>
 #include <pulsecore/core-rtclock.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/core-scache.h>
 #include <pulsecore/core-subscribe.h>
-#include <pulsecore/shared.h>
 #include <pulsecore/random.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
@@ -117,6 +113,9 @@ pa_core* pa_core_new(pa_mainloop_api *m, pa_bool_t shared, size_t shm_size) {
     c->default_n_fragments = 4;
     c->default_fragment_size_msec = 25;
 
+    c->deferred_volume_safety_margin_usec = 8000;
+    c->deferred_volume_extra_delay_usec = 0;
+
     c->module_defer_unload_event = NULL;
     c->scache_auto_unload_event = NULL;
 
@@ -141,7 +140,8 @@ pa_core* pa_core_new(pa_mainloop_api *m, pa_bool_t shared, size_t shm_size) {
     c->realtime_priority = 5;
     c->disable_remixing = FALSE;
     c->disable_lfe_remixing = FALSE;
-    c->resample_method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 3;
+    c->deferred_volume = TRUE;
+    c->resample_method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 1;
 
     for (j = 0; j < PA_CORE_HOOK_MAX; j++)
         pa_hook_init(&c->hooks[j], c);
@@ -154,6 +154,13 @@ pa_core* pa_core_new(pa_mainloop_api *m, pa_bool_t shared, size_t shm_size) {
 
     pa_core_check_idle(c);
 
+#ifdef __TIZEN__
+    c->dump_sink = FALSE;
+    c->dump_sink_input = FALSE;
+    c->dump_source = FALSE;
+    c->dump_source_output = FALSE;
+#endif
+
     c->state = PA_CORE_RUNNING;
 
     return c;
@@ -166,38 +173,38 @@ static void core_free(pa_object *o) {
 
     c->state = PA_CORE_SHUTDOWN;
 
-    pa_module_unload_all(c);
-    pa_scache_free_all(c);
+    /* Note: All modules and samples in the cache should be unloaded before
+     * we get here */
 
     pa_assert(pa_idxset_isempty(c->scache));
-    pa_idxset_free(c->scache, NULL, NULL);
+    pa_idxset_free(c->scache, NULL);
 
     pa_assert(pa_idxset_isempty(c->modules));
-    pa_idxset_free(c->modules, NULL, NULL);
+    pa_idxset_free(c->modules, NULL);
 
     pa_assert(pa_idxset_isempty(c->clients));
-    pa_idxset_free(c->clients, NULL, NULL);
+    pa_idxset_free(c->clients, NULL);
 
     pa_assert(pa_idxset_isempty(c->cards));
-    pa_idxset_free(c->cards, NULL, NULL);
+    pa_idxset_free(c->cards, NULL);
 
     pa_assert(pa_idxset_isempty(c->sinks));
-    pa_idxset_free(c->sinks, NULL, NULL);
+    pa_idxset_free(c->sinks, NULL);
 
     pa_assert(pa_idxset_isempty(c->sources));
-    pa_idxset_free(c->sources, NULL, NULL);
+    pa_idxset_free(c->sources, NULL);
 
     pa_assert(pa_idxset_isempty(c->source_outputs));
-    pa_idxset_free(c->source_outputs, NULL, NULL);
+    pa_idxset_free(c->source_outputs, NULL);
 
     pa_assert(pa_idxset_isempty(c->sink_inputs));
-    pa_idxset_free(c->sink_inputs, NULL, NULL);
+    pa_idxset_free(c->sink_inputs, NULL);
 
     pa_assert(pa_hashmap_isempty(c->namereg));
-    pa_hashmap_free(c->namereg, NULL, NULL);
+    pa_hashmap_free(c->namereg, NULL);
 
     pa_assert(pa_hashmap_isempty(c->shared));
-    pa_hashmap_free(c->shared, NULL, NULL);
+    pa_hashmap_free(c->shared, NULL);
 
     pa_subscription_free_all(c);
 
@@ -252,12 +259,27 @@ int pa_core_exit(pa_core *c, pa_bool_t force, int retval) {
 void pa_core_maybe_vacuum(pa_core *c) {
     pa_assert(c);
 
-    if (!pa_idxset_isempty(c->sink_inputs) ||
-        !pa_idxset_isempty(c->source_outputs))
-        return;
-
-    pa_log_debug("Hmm, no streams around, trying to vacuum.");
-    pa_mempool_vacuum(c->mempool);
+    if (pa_idxset_isempty(c->sink_inputs) && pa_idxset_isempty(c->source_outputs)) {
+        pa_log_debug_verbose("Hmm, no streams around, trying to vacuum.");
+        pa_mempool_vacuum(c->mempool);
+    } else {
+        pa_sink *si;
+        pa_source *so;
+        uint32_t idx;
+
+        idx = 0;
+        PA_IDXSET_FOREACH(si, c->sinks, idx)
+            if (pa_sink_get_state(si) != PA_SINK_SUSPENDED)
+                return;
+
+        idx = 0;
+        PA_IDXSET_FOREACH(so, c->sources, idx)
+            if (pa_source_get_state(so) != PA_SOURCE_SUSPENDED)
+                return;
+
+        pa_log_info("All sinks and sources are suspended, vacuuming memory");
+        pa_mempool_vacuum(c->mempool);
+    }
 }
 
 pa_time_event* pa_core_rttime_new(pa_core *c, pa_usec_t usec, pa_time_event_cb_t cb, void *userdata) {
index c1002f9..3348598 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <pulse/mainloop-api.h>
 #include <pulse/sample.h>
+#include <pulsecore/cpu.h>
 
 typedef struct pa_core pa_core;
 
@@ -34,6 +35,10 @@ typedef enum pa_suspend_cause {
     PA_SUSPEND_APPLICATION = 2,  /* Used by the device reservation logic */
     PA_SUSPEND_IDLE = 4,         /* Used by module-suspend-on-idle */
     PA_SUSPEND_SESSION = 8,      /* Used by module-hal for mark inactive sessions */
+    PA_SUSPEND_PASSTHROUGH = 16, /* Used to suspend monitor sources when the sink is in passthrough mode */
+#ifdef __TIZEN__
+    PA_SUSPEND_SWITCH = 32, /* Used to suspend for switching device */
+#endif /* __TIZEN__ */
     PA_SUSPEND_ALL = 0xFFFF      /* Magic cause that can be used to resume forcibly */
 } pa_suspend_cause_t;
 
@@ -41,7 +46,6 @@ typedef enum pa_suspend_cause {
 #include <pulsecore/hashmap.h>
 #include <pulsecore/memblock.h>
 #include <pulsecore/resampler.h>
-#include <pulsecore/queue.h>
 #include <pulsecore/llist.h>
 #include <pulsecore/hook-list.h>
 #include <pulsecore/asyncmsgq.h>
@@ -49,9 +53,15 @@ typedef enum pa_suspend_cause {
 #include <pulsecore/sink.h>
 #include <pulsecore/source.h>
 #include <pulsecore/core-subscribe.h>
-#include <pulsecore/sink-input.h>
 #include <pulsecore/msgobject.h>
 
+typedef enum pa_server_type {
+    PA_SERVER_TYPE_UNSET,
+    PA_SERVER_TYPE_USER,
+    PA_SERVER_TYPE_SYSTEM,
+    PA_SERVER_TYPE_NONE
+} pa_server_type_t;
+
 typedef enum pa_core_state {
     PA_CORE_STARTUP,
     PA_CORE_RUNNING,
@@ -66,6 +76,8 @@ typedef enum pa_core_hook {
     PA_CORE_HOOK_SINK_UNLINK_POST,
     PA_CORE_HOOK_SINK_STATE_CHANGED,
     PA_CORE_HOOK_SINK_PROPLIST_CHANGED,
+    PA_CORE_HOOK_SINK_PORT_CHANGED,
+    PA_CORE_HOOK_SINK_FLAGS_CHANGED,
     PA_CORE_HOOK_SOURCE_NEW,
     PA_CORE_HOOK_SOURCE_FIXATE,
     PA_CORE_HOOK_SOURCE_PUT,
@@ -73,6 +85,8 @@ typedef enum pa_core_hook {
     PA_CORE_HOOK_SOURCE_UNLINK_POST,
     PA_CORE_HOOK_SOURCE_STATE_CHANGED,
     PA_CORE_HOOK_SOURCE_PROPLIST_CHANGED,
+    PA_CORE_HOOK_SOURCE_PORT_CHANGED,
+    PA_CORE_HOOK_SOURCE_FLAGS_CHANGED,
     PA_CORE_HOOK_SINK_INPUT_NEW,
     PA_CORE_HOOK_SINK_INPUT_FIXATE,
     PA_CORE_HOOK_SINK_INPUT_PUT,
@@ -103,6 +117,11 @@ typedef enum pa_core_hook {
     PA_CORE_HOOK_CARD_NEW,
     PA_CORE_HOOK_CARD_PUT,
     PA_CORE_HOOK_CARD_UNLINK,
+    PA_CORE_HOOK_CARD_PROFILE_CHANGED,
+    PA_CORE_HOOK_CARD_PROFILE_ADDED,
+    PA_CORE_HOOK_CARD_PROFILE_AVAILABLE_CHANGED,
+    PA_CORE_HOOK_PORT_AVAILABLE_CHANGED,
+    PA_CORE_HOOK_PORT_LATENCY_OFFSET_CHANGED,
     PA_CORE_HOOK_MAX
 } pa_core_hook_t;
 
@@ -133,7 +152,10 @@ struct pa_core {
 
     pa_channel_map default_channel_map;
     pa_sample_spec default_sample_spec;
+    uint32_t alternate_sample_rate;
     unsigned default_n_fragments, default_fragment_size_msec;
+    unsigned deferred_volume_safety_margin_usec;
+    int deferred_volume_extra_delay_usec;
 
     pa_defer_event *module_defer_unload_event;
 
@@ -157,12 +179,23 @@ struct pa_core {
     pa_bool_t realtime_scheduling:1;
     pa_bool_t disable_remixing:1;
     pa_bool_t disable_lfe_remixing:1;
+    pa_bool_t deferred_volume:1;
 
     pa_resample_method_t resample_method;
     int realtime_priority;
 
+    pa_server_type_t server_type;
+    pa_cpu_info cpu_info;
+
     /* hooks */
     pa_hook hooks[PA_CORE_HOOK_MAX];
+
+#ifdef __TIZEN__
+    pa_bool_t dump_sink;
+    pa_bool_t dump_sink_input;
+    pa_bool_t dump_source;
+    pa_bool_t dump_source_output;
+#endif
 };
 
 PA_DECLARE_PUBLIC_CLASS(pa_core);
@@ -175,7 +208,7 @@ enum {
 
 pa_core* pa_core_new(pa_mainloop_api *m, pa_bool_t shared, size_t shm_size);
 
-/* Check whether noone is connected to this core */
+/* Check whether no one is connected to this core */
 void pa_core_check_idle(pa_core *c);
 
 int pa_core_exit(pa_core *c, pa_bool_t force, int retval);
index 453b784..1378124 100644 (file)
 
 #include <stdint.h>
 #include <sys/types.h>
-#include <sys/stat.h>
 #include <fcntl.h>
 
 #include <pulse/xmalloc.h>
+#include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 
 #include "cpu-arm.h"
 
 #if defined (__arm__) && defined (__linux__)
 
-#define MAX_BUFFER  4096
+#define MAX_BUFFER 4096
 static char *
-get_cpuinfo_line (char *cpuinfo, const char *tag) {
+get_cpuinfo_line(char *cpuinfo, const char *tag) {
     char *line, *end, *colon;
 
-    if (!(line = strstr (cpuinfo, tag)))
+    if (!(line = strstr(cpuinfo, tag)))
         return NULL;
 
-    if (!(end = strchr (line, '\n')))
+    if (!(end = strchr(line, '\n')))
         return NULL;
 
-    if (!(colon = strchr (line, ':')))
+    if (!(colon = strchr(line, ':')))
         return NULL;
 
     if (++colon >= end)
         return NULL;
 
-    return pa_xstrndup (colon, end - colon);
+    return pa_xstrndup(colon, end - colon);
 }
 
 static char *get_cpuinfo(void) {
@@ -62,12 +62,12 @@ static char *get_cpuinfo(void) {
 
     cpuinfo = pa_xmalloc(MAX_BUFFER);
 
-    if ((fd = open("/proc/cpuinfo", O_RDONLY)) < 0) {
+    if ((fd = pa_open_cloexec("/proc/cpuinfo", O_RDONLY, 0)) < 0) {
         pa_xfree(cpuinfo);
         return NULL;
     }
 
-    if ((n = pa_read(fd, cpuinfo, MAX_BUFFER-1)) < 0) {
+    if ((n = pa_read(fd, cpuinfo, MAX_BUFFER-1, NULL)) < 0) {
         pa_xfree(cpuinfo);
         pa_close(fd);
         return NULL;
@@ -79,61 +79,83 @@ static char *get_cpuinfo(void) {
 }
 #endif /* defined (__arm__) && defined (__linux__) */
 
-void pa_cpu_init_arm (void) {
+void pa_cpu_get_arm_flags(pa_cpu_arm_flag_t *flags) {
 #if defined (__arm__)
 #if defined (__linux__)
     char *cpuinfo, *line;
     int arch;
-    pa_cpu_arm_flag_t flags = 0;
 
     /* We need to read the CPU flags from /proc/cpuinfo because there is no user
      * space support to get the CPU features. This only works on linux AFAIK. */
-    if (!(cpuinfo = get_cpuinfo ())) {
-        pa_log ("Can't read cpuinfo");
+    if (!(cpuinfo = get_cpuinfo())) {
+        pa_log("Can't read cpuinfo");
         return;
     }
 
+    *flags = 0;
+
     /* get the CPU architecture */
-    if ((line = get_cpuinfo_line (cpuinfo, "CPU architecture"))) {
-        arch = strtoul (line, NULL, 0);
+    if ((line = get_cpuinfo_line(cpuinfo, "CPU architecture"))) {
+        arch = strtoul(line, NULL, 0);
         if (arch >= 6)
-            flags |= PA_CPU_ARM_V6;
+            *flags |= PA_CPU_ARM_V6;
         if (arch >= 7)
-            flags |= PA_CPU_ARM_V7;
+            *flags |= PA_CPU_ARM_V7;
 
         pa_xfree(line);
     }
     /* get the CPU features */
-    if ((line = get_cpuinfo_line (cpuinfo, "Features"))) {
-        char *state = NULL, *current;
-
-        while ((current = pa_split_spaces (line, &state))) {
-            if (!strcmp (current, "vfp"))
-                flags |= PA_CPU_ARM_VFP;
-            else if (!strcmp (current, "edsp"))
-                flags |= PA_CPU_ARM_EDSP;
-            else if (!strcmp (current, "neon"))
-                flags |= PA_CPU_ARM_NEON;
-            else if (!strcmp (current, "vfpv3"))
-                flags |= PA_CPU_ARM_VFPV3;
+    if ((line = get_cpuinfo_line(cpuinfo, "Features"))) {
+        const char *state = NULL;
+        char *current;
+
+        while ((current = pa_split_spaces(line, &state))) {
+            if (pa_streq(current, "vfp"))
+                *flags |= PA_CPU_ARM_VFP;
+            else if (pa_streq(current, "edsp"))
+                *flags |= PA_CPU_ARM_EDSP;
+            else if (pa_streq(current, "neon"))
+                *flags |= PA_CPU_ARM_NEON;
+            else if (pa_streq(current, "vfpv3"))
+                *flags |= PA_CPU_ARM_VFPV3;
 
             pa_xfree(current);
         }
     }
     pa_xfree(cpuinfo);
 
-    pa_log_info ("CPU flags: %s%s%s%s%s%s",
-          (flags & PA_CPU_ARM_V6) ? "V6 " : "",
-          (flags & PA_CPU_ARM_V7) ? "V7 " : "",
-          (flags & PA_CPU_ARM_VFP) ? "VFP " : "",
-          (flags & PA_CPU_ARM_EDSP) ? "EDSP " : "",
-          (flags & PA_CPU_ARM_NEON) ? "NEON " : "",
-          (flags & PA_CPU_ARM_VFPV3) ? "VFPV3 " : "");
+    pa_log_info("CPU flags: %s%s%s%s%s%s",
+          (*flags & PA_CPU_ARM_V6) ? "V6 " : "",
+          (*flags & PA_CPU_ARM_V7) ? "V7 " : "",
+          (*flags & PA_CPU_ARM_VFP) ? "VFP " : "",
+          (*flags & PA_CPU_ARM_EDSP) ? "EDSP " : "",
+          (*flags & PA_CPU_ARM_NEON) ? "NEON " : "",
+          (*flags & PA_CPU_ARM_VFPV3) ? "VFPV3 " : "");
+#endif
+#endif
+}
+
+pa_bool_t pa_cpu_init_arm(pa_cpu_arm_flag_t *flags) {
+#if defined (__arm__)
+#if defined (__linux__)
+    pa_cpu_get_arm_flags(flags);
+
+    if (*flags & PA_CPU_ARM_V6)
+        pa_volume_func_init_arm(*flags);
+#ifdef HAVE_NEON
+    if (*flags & PA_CPU_ARM_NEON) {
+        pa_convert_func_init_neon(*flags);
+        pa_mix_func_init_neon(*flags);
+    }
+#endif
+
+    return TRUE;
+
 #else /* defined (__linux__) */
-    pa_log ("ARM cpu features not yet supported on this OS");
+    pa_log("Reading ARM CPU features not yet supported on this OS");
 #endif /* defined (__linux__) */
 
-    if (flags & PA_CPU_ARM_V6)
-        pa_volume_func_init_arm (flags);
+#else /* defined (__arm__) */
+    return FALSE;
 #endif /* defined (__arm__) */
 }
index 3ccd070..d9dc3d5 100644 (file)
@@ -5,7 +5,7 @@
   This file is part of PulseAudio.
 
   Copyright 2004-2006 Lennart Poettering
-  Copyright 2009 Wim Taymans <wim.taymans@collabora.co.uk> 
+  Copyright 2009 Wim Taymans <wim.taymans@collabora.co.uk>
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
 ***/
 
 #include <stdint.h>
+#include <pulsecore/macro.h>
+
+#ifndef PACKAGE
+#error "Please include config.h before including this file!"
+#endif
 
 typedef enum pa_cpu_arm_flag {
     PA_CPU_ARM_V6       = (1 << 0),
@@ -34,9 +39,15 @@ typedef enum pa_cpu_arm_flag {
     PA_CPU_ARM_VFPV3    = (1 << 5)
 } pa_cpu_arm_flag_t;
 
-void pa_cpu_init_arm (void);
+void pa_cpu_get_arm_flags(pa_cpu_arm_flag_t *flags);
+pa_bool_t pa_cpu_init_arm(pa_cpu_arm_flag_t *flags);
 
 /* some optimized functions */
 void pa_volume_func_init_arm(pa_cpu_arm_flag_t flags);
 
+#ifdef HAVE_NEON
+void pa_convert_func_init_neon(pa_cpu_arm_flag_t flags);
+void pa_mix_func_init_neon(pa_cpu_arm_flag_t flags);
+#endif
+
 #endif /* foocpuarmhfoo */
diff --git a/src/pulsecore/cpu-orc.c b/src/pulsecore/cpu-orc.c
new file mode 100644 (file)
index 0000000..d40c224
--- /dev/null
@@ -0,0 +1,42 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2010 Arun Raghavan <arun.raghavan@collabora.co.uk>
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "cpu-orc.h"
+
+pa_bool_t pa_cpu_init_orc(pa_cpu_info cpu_info)
+{
+#ifndef DISABLE_ORC
+    /* Update these as we test on more architectures */
+    pa_cpu_x86_flag_t x86_want_flags = PA_CPU_X86_MMX | PA_CPU_X86_SSE | PA_CPU_X86_SSE2 | PA_CPU_X86_SSE3 | PA_CPU_X86_SSSE3 | PA_CPU_X86_SSE4_1 | PA_CPU_X86_SSE4_2;
+
+    /* Enable Orc svolume optimizations */
+    if ((cpu_info.cpu_type == PA_CPU_X86) && (cpu_info.flags.x86 & x86_want_flags)) {
+        pa_volume_func_init_orc();
+        return TRUE;
+    }
+#endif
+
+    return FALSE;
+}
diff --git a/src/pulsecore/cpu-orc.h b/src/pulsecore/cpu-orc.h
new file mode 100644 (file)
index 0000000..0bf81cb
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef foocpuorchfoo
+#define foocpuorchfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2010 Arun Raghavan <arun.raghavan@collabora.co.uk>
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <pulsecore/cpu.h>
+
+/* Orc-optimised bits */
+
+pa_bool_t pa_cpu_init_orc(pa_cpu_info cpu_info);
+
+void pa_volume_func_init_orc(void);
+
+#endif /* foocpuorchfoo */
index f194a60..b2a558a 100644 (file)
@@ -31,9 +31,7 @@
 #include "cpu-x86.h"
 
 #if defined (__i386__) || defined (__amd64__)
-static void
-get_cpuid (uint32_t op, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)
-{
+static void get_cpuid(uint32_t op, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d) {
     __asm__ __volatile__ (
         "  push %%"PA_REG_b"   \n\t"
         "  cpuid               \n\t"
@@ -46,80 +44,94 @@ get_cpuid (uint32_t op, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)
 }
 #endif
 
-void pa_cpu_init_x86 (void) {
+void pa_cpu_get_x86_flags(pa_cpu_x86_flag_t *flags) {
 #if defined (__i386__) || defined (__amd64__)
     uint32_t eax, ebx, ecx, edx;
     uint32_t level;
-    pa_cpu_x86_flag_t flags = 0;
+
+    *flags = 0;
 
     /* get standard level */
-    get_cpuid (0x00000000, &level, &ebx, &ecx, &edx);
+    get_cpuid(0x00000000, &level, &ebx, &ecx, &edx);
     if (level >= 1) {
-        get_cpuid (0x00000001, &eax, &ebx, &ecx, &edx);
+        get_cpuid(0x00000001, &eax, &ebx, &ecx, &edx);
+
+        if (edx & (1<<15))
+          *flags |= PA_CPU_X86_CMOV;
 
         if (edx & (1<<23))
-          flags |= PA_CPU_X86_MMX;
+          *flags |= PA_CPU_X86_MMX;
 
         if (edx & (1<<25))
-          flags |= PA_CPU_X86_SSE;
+          *flags |= PA_CPU_X86_SSE;
 
         if (edx & (1<<26))
-          flags |= PA_CPU_X86_SSE2;
+          *flags |= PA_CPU_X86_SSE2;
 
         if (ecx & (1<<0))
-          flags |= PA_CPU_X86_SSE3;
+          *flags |= PA_CPU_X86_SSE3;
 
         if (ecx & (1<<9))
-          flags |= PA_CPU_X86_SSSE3;
+          *flags |= PA_CPU_X86_SSSE3;
 
         if (ecx & (1<<19))
-          flags |= PA_CPU_X86_SSE4_1;
+          *flags |= PA_CPU_X86_SSE4_1;
 
         if (ecx & (1<<20))
-          flags |= PA_CPU_X86_SSE4_2;
+          *flags |= PA_CPU_X86_SSE4_2;
     }
 
     /* get extended level */
-    get_cpuid (0x80000000, &level, &ebx, &ecx, &edx);
+    get_cpuid(0x80000000, &level, &ebx, &ecx, &edx);
     if (level >= 0x80000001) {
-        get_cpuid (0x80000001, &eax, &ebx, &ecx, &edx);
+        get_cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
 
         if (edx & (1<<22))
-          flags |= PA_CPU_X86_MMXEXT;
+          *flags |= PA_CPU_X86_MMXEXT;
 
         if (edx & (1<<23))
-          flags |= PA_CPU_X86_MMX;
+          *flags |= PA_CPU_X86_MMX;
 
         if (edx & (1<<30))
-          flags |= PA_CPU_X86_3DNOWEXT;
+          *flags |= PA_CPU_X86_3DNOWEXT;
 
         if (edx & (1<<31))
-          flags |= PA_CPU_X86_3DNOW;
+          *flags |= PA_CPU_X86_3DNOW;
     }
 
-    pa_log_info ("CPU flags: %s%s%s%s%s%s%s%s%s%s",
-    (flags & PA_CPU_X86_MMX) ? "MMX " : "",
-    (flags & PA_CPU_X86_SSE) ? "SSE " : "",
-    (flags & PA_CPU_X86_SSE2) ? "SSE2 " : "",
-    (flags & PA_CPU_X86_SSE3) ? "SSE3 " : "",
-    (flags & PA_CPU_X86_SSSE3) ? "SSSE3 " : "",
-    (flags & PA_CPU_X86_SSE4_1) ? "SSE4_1 " : "",
-    (flags & PA_CPU_X86_SSE4_2) ? "SSE4_2 " : "",
-    (flags & PA_CPU_X86_MMXEXT) ? "MMXEXT " : "",
-    (flags & PA_CPU_X86_3DNOW) ? "3DNOW " : "",
-    (flags & PA_CPU_X86_3DNOWEXT) ? "3DNOWEXT " : "");
+    pa_log_info("CPU flags: %s%s%s%s%s%s%s%s%s%s%s",
+    (*flags & PA_CPU_X86_CMOV) ? "CMOV " : "",
+    (*flags & PA_CPU_X86_MMX) ? "MMX " : "",
+    (*flags & PA_CPU_X86_SSE) ? "SSE " : "",
+    (*flags & PA_CPU_X86_SSE2) ? "SSE2 " : "",
+    (*flags & PA_CPU_X86_SSE3) ? "SSE3 " : "",
+    (*flags & PA_CPU_X86_SSSE3) ? "SSSE3 " : "",
+    (*flags & PA_CPU_X86_SSE4_1) ? "SSE4_1 " : "",
+    (*flags & PA_CPU_X86_SSE4_2) ? "SSE4_2 " : "",
+    (*flags & PA_CPU_X86_MMXEXT) ? "MMXEXT " : "",
+    (*flags & PA_CPU_X86_3DNOW) ? "3DNOW " : "",
+    (*flags & PA_CPU_X86_3DNOWEXT) ? "3DNOWEXT " : "");
+#endif /* defined (__i386__) || defined (__amd64__) */
+}
+
+pa_bool_t pa_cpu_init_x86(pa_cpu_x86_flag_t *flags) {
+#if defined (__i386__) || defined (__amd64__)
+    pa_cpu_get_x86_flags(flags);
 
     /* activate various optimisations */
-    if (flags & PA_CPU_X86_MMX) {
-        pa_volume_func_init_mmx (flags);
-        pa_remap_func_init_mmx (flags);
+    if (*flags & PA_CPU_X86_MMX) {
+        pa_volume_func_init_mmx(*flags);
+        pa_remap_func_init_mmx(*flags);
     }
 
-    if (flags & (PA_CPU_X86_SSE | PA_CPU_X86_SSE2)) {
-        pa_volume_func_init_sse (flags);
-        pa_remap_func_init_sse (flags);
-        pa_convert_func_init_sse (flags);
+    if (*flags & (PA_CPU_X86_SSE | PA_CPU_X86_SSE2)) {
+        pa_volume_func_init_sse(*flags);
+        pa_remap_func_init_sse(*flags);
+        pa_convert_func_init_sse(*flags);
     }
 
+    return TRUE;
+#else /* defined (__i386__) || defined (__amd64__) */
+    return FALSE;
 #endif /* defined (__i386__) || defined (__amd64__) */
 }
index b40eb5c..9a9f3a1 100644 (file)
@@ -5,7 +5,7 @@
   This file is part of PulseAudio.
 
   Copyright 2004-2006 Lennart Poettering
-  Copyright 2009 Wim Taymans <wim.taymans@collabora.co.uk> 
+  Copyright 2009 Wim Taymans <wim.taymans@collabora.co.uk>
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
@@ -24,6 +24,7 @@
 ***/
 
 #include <stdint.h>
+#include <pulsecore/macro.h>
 
 typedef enum pa_cpu_x86_flag {
     PA_CPU_X86_MMX       = (1 << 0),
@@ -35,11 +36,12 @@ typedef enum pa_cpu_x86_flag {
     PA_CPU_X86_SSE4_1    = (1 << 6),
     PA_CPU_X86_SSE4_2    = (1 << 7),
     PA_CPU_X86_3DNOW     = (1 << 8),
-    PA_CPU_X86_3DNOWEXT  = (1 << 9)
+    PA_CPU_X86_3DNOWEXT  = (1 << 9),
+    PA_CPU_X86_CMOV      = (1 << 10)
 } pa_cpu_x86_flag_t;
 
-void pa_cpu_init_x86 (void);
-
+void pa_cpu_get_x86_flags(pa_cpu_x86_flag_t *flags);
+pa_bool_t pa_cpu_init_x86 (pa_cpu_x86_flag_t *flags);
 
 #if defined (__i386__)
 typedef int32_t pa_reg_x86;
diff --git a/src/pulsecore/cpu.h b/src/pulsecore/cpu.h
new file mode 100644 (file)
index 0000000..7fe6f0b
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef foocpuhfoo
+#define foocpuhfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2010 Arun Raghavan
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <pulsecore/cpu-x86.h>
+#include <pulsecore/cpu-arm.h>
+
+typedef enum {
+    PA_CPU_UNDEFINED = 0,
+    PA_CPU_X86,
+    PA_CPU_ARM,
+} pa_cpu_type_t;
+
+typedef struct pa_cpu_info pa_cpu_info;
+
+struct pa_cpu_info {
+    pa_cpu_type_t cpu_type;
+
+    union {
+        pa_cpu_x86_flag_t x86;
+        pa_cpu_arm_flag_t arm;
+    } flags;
+};
+
+#endif /* foocpuhfoo */
index c15c469..aa1d560 100644 (file)
 #error "Please include config.h before including this file!"
 #endif
 
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#ifdef HAVE_SYS_UN_H
-#include <sys/un.h>
-#endif
+#include <pulsecore/socket.h>
 
 typedef struct pa_creds pa_creds;
 
index e65125d..c4a7ccb 100644 (file)
@@ -69,7 +69,7 @@ pa_database* pa_database_open(const char *fn, pa_bool_t for_write) {
     pa_assert(fn);
 
     /* We include the host identifier in the file name because gdbm
-     * files are CPU dependant, and we don't want things to go wrong
+     * files are CPU dependent, and we don't want things to go wrong
      * if we are on a multiarch system. */
     path = pa_sprintf_malloc("%s."CANONICAL_HOST".gdbm", fn);
     errno = 0;
index 1f4caf7..91c1b45 100644 (file)
@@ -25,9 +25,7 @@
 #endif
 
 #include <errno.h>
-#include <sys/stat.h>
 #include <sys/types.h>
-#include <fcntl.h>
 #include <unistd.h>
 #include <stdio.h>
 
@@ -237,7 +235,7 @@ pa_database* pa_database_open(const char *fn, pa_bool_t for_write) {
     path = pa_sprintf_malloc("%s."CANONICAL_HOST".simple", fn);
     errno = 0;
 
-    f = fopen(path, "r");
+    f = pa_fopen_cloexec(path, "r");
 
     if (f || errno == ENOENT) { /* file not found is ok */
         db = pa_xnew0(simple_data, 1);
@@ -266,10 +264,9 @@ void pa_database_close(pa_database *database) {
     pa_assert(db);
 
     pa_database_sync(database);
-    pa_database_clear(database);
     pa_xfree(db->filename);
     pa_xfree(db->tmp_filename);
-    pa_hashmap_free(db->map, NULL, NULL);
+    pa_hashmap_free(db->map, (pa_free_cb_t) free_entry);
     pa_xfree(db);
 }
 
@@ -313,7 +310,7 @@ int pa_database_set(pa_database *database, const pa_datum *key, const pa_datum*
             r = pa_hashmap_remove(db->map, key);
             pa_hashmap_put(db->map, &e->key, e);
         } else {
-            /* wont't overwrite, so clean new entry */
+            /* won't overwrite, so clean new entry */
             r = e;
             ret = -1;
         }
@@ -342,12 +339,10 @@ int pa_database_unset(pa_database *database, const pa_datum *key) {
 
 int pa_database_clear(pa_database *database) {
     simple_data *db = (simple_data*)database;
-    entry *e;
 
     pa_assert(db);
 
-    while ((e = pa_hashmap_steal_first(db->map)))
-        free_entry(e);
+    pa_hashmap_remove_all(db->map, (pa_free_cb_t) free_entry);
 
     return 0;
 }
@@ -429,7 +424,7 @@ static int write_uint(FILE *f, const uint32_t num) {
     errno = 0;
 
     for (i = 0; i < 4; i++)
-         values[i] = (num >> (i*8)) & 0xFF;
+        values[i] = (num >> (i*8)) & 0xFF;
 
     items = fwrite(&values, sizeof(values), sizeof(uint8_t), f);
 
@@ -480,7 +475,7 @@ int pa_database_sync(pa_database *database) {
 
     errno = 0;
 
-    f = fopen(db->tmp_filename, "w");
+    f = pa_fopen_cloexec(db->tmp_filename, "w");
 
     if (!f)
         goto fail;
index b79d283..4e782d6 100644 (file)
@@ -66,6 +66,39 @@ void pa_datum_free(pa_datum *d) {
     pa_zero(d);
 }
 
+static struct tdb_context *tdb_open_cloexec(
+        const char *name,
+        int hash_size,
+        int tdb_flags,
+        int open_flags,
+        mode_t mode) {
+
+    /* Mimics pa_open_cloexec() */
+
+    struct tdb_context *c;
+
+#ifdef O_NOCTTY
+    open_flags |= O_NOCTTY;
+#endif
+
+#ifdef O_CLOEXEC
+    errno = 0;
+    if ((c = tdb_open(name, hash_size, tdb_flags, open_flags | O_CLOEXEC, mode)))
+        goto finish;
+
+    if (errno != EINVAL)
+        return NULL;
+#endif
+
+    errno = 0;
+    if (!(c = tdb_open(name, hash_size, tdb_flags, open_flags, mode)))
+        return NULL;
+
+finish:
+    pa_make_fd_cloexec(tdb_fd(c));
+    return c;
+}
+
 pa_database* pa_database_open(const char *fn, pa_bool_t for_write) {
     struct tdb_context *c;
     char *path;
@@ -73,15 +106,7 @@ pa_database* pa_database_open(const char *fn, pa_bool_t for_write) {
     pa_assert(fn);
 
     path = pa_sprintf_malloc("%s.tdb", fn);
-    errno = 0;
-    c = tdb_open(path, 0, TDB_NOSYNC|TDB_NOLOCK,
-                 (for_write ? O_RDWR|O_CREAT : O_RDONLY)|O_NOCTTY
-#ifdef O_CLOEXEC
-                 |O_CLOEXEC
-#endif
-                 , 0644);
-
-    if (c)
+    if ((c = tdb_open_cloexec(path, 0, TDB_NOSYNC|TDB_NOLOCK, (for_write ? O_RDWR|O_CREAT : O_RDONLY), 0644)))
         pa_log_debug("Opened TDB database '%s'", path);
 
     pa_xfree(path);
index 17455d4..f1a85b6 100644 (file)
@@ -29,7 +29,7 @@
 /* A little abstraction over simple databases, such as gdbm, tdb, and
  * so on. We only make minimal assumptions about the supported
  * backend: it does not need to support locking, it does not have to
- * be arch independant. */
+ * be arch independent. */
 
 typedef struct pa_database pa_database;
 
index 20ef9b1..3477407 100644 (file)
 #include <config.h>
 #endif
 
-#include <stdarg.h>
-
 #include <pulse/xmalloc.h>
-#include <pulse/timeval.h>
-#include <pulsecore/log.h>
+
 #include <pulsecore/shared.h>
 
 #include "dbus-shared.h"
index 3ebfd49..adffa88 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <pulse/rtclock.h>
 #include <pulse/timeval.h>
+#include <pulse/utf8.h>
 #include <pulse/xmalloc.h>
 
 #include <pulsecore/core-rtclock.h>
@@ -44,17 +45,16 @@ struct pa_dbus_wrap_connection {
 };
 
 struct timeout_data {
-    pa_dbus_wrap_connection *c;
+    pa_dbus_wrap_connection *connection;
     DBusTimeout *timeout;
 };
 
 static void dispatch_cb(pa_mainloop_api *ea, pa_defer_event *ev, void *userdata) {
     DBusConnection *conn = userdata;
 
-    if (dbus_connection_dispatch(conn) == DBUS_DISPATCH_COMPLETE) {
+    if (dbus_connection_dispatch(conn) == DBUS_DISPATCH_COMPLETE)
         /* no more data to process, disable the deferred */
         ea->defer_enable(ev, 0);
-    }
 }
 
 /* DBusDispatchStatusFunction callback for the pa mainloop */
@@ -131,13 +131,17 @@ static void handle_time_event(pa_mainloop_api *ea, pa_time_event* e, const struc
     struct timeout_data *d = userdata;
 
     pa_assert(d);
-    pa_assert(d->c);
+    pa_assert(d->connection);
 
     if (dbus_timeout_get_enabled(d->timeout)) {
-        dbus_timeout_handle(d->timeout);
+        /* Restart it for the next scheduled time. We do this before
+         * calling dbus_timeout_handle() to make sure that the time
+         * event is still around. */
+        ea->time_restart(e, pa_timeval_rtstore(&tv,
+                                               pa_timeval_load(t) + dbus_timeout_get_interval(d->timeout) * PA_USEC_PER_MSEC,
+                                               d->connection->use_rtclock));
 
-        /* restart it for the next scheduled time */
-        ea->time_restart(e, pa_timeval_rtstore(&tv, pa_timeval_load(t) + dbus_timeout_get_interval(d->timeout) * PA_USEC_PER_MSEC, d->c->use_rtclock));
+        dbus_timeout_handle(d->timeout);
     }
 }
 
@@ -207,7 +211,7 @@ static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) {
         return FALSE;
 
     d = pa_xnew(struct timeout_data, 1);
-    d->c = c;
+    d->connection = c;
     d->timeout = timeout;
     ev = c->mainloop->time_new(c->mainloop, pa_timeval_rtstore(&tv, pa_rtclock_now() + dbus_timeout_get_interval(timeout) * PA_USEC_PER_MSEC, c->use_rtclock), handle_time_event, d);
     c->mainloop->time_set_destroy(ev, time_event_destroy_cb);
@@ -236,15 +240,15 @@ static void toggle_timeout(DBusTimeout *timeout, void *data) {
     struct timeval tv;
 
     pa_assert(d);
-    pa_assert(d->c);
+    pa_assert(d->connection);
     pa_assert(timeout);
 
     pa_assert_se(ev = dbus_timeout_get_data(timeout));
 
-    if (dbus_timeout_get_enabled(timeout)) {
-        d->c->mainloop->time_restart(ev, pa_timeval_rtstore(&tv, pa_rtclock_now() + dbus_timeout_get_interval(timeout) * PA_USEC_PER_MSEC, d->c->use_rtclock));
-    else
-        d->c->mainloop->time_restart(ev, pa_timeval_rtstore(&tv, PA_USEC_INVALID, d->c->use_rtclock));
+    if (dbus_timeout_get_enabled(timeout))
+        d->connection->mainloop->time_restart(ev, pa_timeval_rtstore(&tv, pa_rtclock_now() + dbus_timeout_get_interval(timeout) * PA_USEC_PER_MSEC, d->connection->use_rtclock));
+    else
+        d->connection->mainloop->time_restart(ev, pa_timeval_rtstore(&tv, PA_USEC_INVALID, d->connection->use_rtclock));
 }
 
 static void wakeup_main(void *userdata) {
@@ -290,6 +294,31 @@ pa_dbus_wrap_connection* pa_dbus_wrap_connection_new(pa_mainloop_api *m, pa_bool
     return pconn;
 }
 
+pa_dbus_wrap_connection* pa_dbus_wrap_connection_new_from_existing(
+        pa_mainloop_api *m,
+        pa_bool_t use_rtclock,
+        DBusConnection *conn) {
+    pa_dbus_wrap_connection *pconn;
+
+    pa_assert(m);
+    pa_assert(conn);
+
+    pconn = pa_xnew(pa_dbus_wrap_connection, 1);
+    pconn->mainloop = m;
+    pconn->connection = dbus_connection_ref(conn);
+    pconn->use_rtclock = use_rtclock;
+
+    dbus_connection_set_exit_on_disconnect(conn, FALSE);
+    dbus_connection_set_dispatch_status_function(conn, dispatch_status, pconn, NULL);
+    dbus_connection_set_watch_functions(conn, add_watch, remove_watch, toggle_watch, pconn, NULL);
+    dbus_connection_set_timeout_functions(conn, add_timeout, remove_timeout, toggle_timeout, pconn, NULL);
+    dbus_connection_set_wakeup_main_function(conn, wakeup_main, pconn, NULL);
+
+    pconn->dispatch_event = pconn->mainloop->defer_new(pconn->mainloop, dispatch_cb, conn);
+
+    return pconn;
+}
+
 void pa_dbus_wrap_connection_free(pa_dbus_wrap_connection* c) {
     pa_assert(c);
 
@@ -338,13 +367,8 @@ fail:
     va_end(ap);
     va_start(ap, error);
     for (; k > 0; k--) {
-        DBusError e;
-
         pa_assert_se(t = va_arg(ap, const char*));
-
-        dbus_error_init(&e);
-        dbus_bus_remove_match(c, t, &e);
-        dbus_error_free(&e);
+        dbus_bus_remove_match(c, t, NULL);
     }
     va_end(ap);
 
@@ -354,17 +378,12 @@ fail:
 void pa_dbus_remove_matches(DBusConnection *c, ...) {
     const char *t;
     va_list ap;
-    DBusError error;
 
     pa_assert(c);
 
-    dbus_error_init(&error);
-
     va_start(ap, c);
-    while ((t = va_arg(ap, const char*))) {
-        dbus_bus_remove_match(c, t, &error);
-        dbus_error_free(&error);
-    }
+    while ((t = va_arg(ap, const char*)))
+        dbus_bus_remove_match(c, t, NULL);
     va_end(ap);
 }
 
@@ -437,23 +456,50 @@ const char *pa_dbus_get_error_message(DBusMessage *m) {
     return message;
 }
 
-/* Note: returns sizeof(char*) for strings, object paths and signatures. */
-static unsigned basic_type_size(int type) {
-    switch (type) {
-        case DBUS_TYPE_BOOLEAN: return sizeof(dbus_bool_t);
-        case DBUS_TYPE_BYTE: return 1;
-        case DBUS_TYPE_INT16: return sizeof(dbus_int16_t);
-        case DBUS_TYPE_UINT16: return sizeof(dbus_uint16_t);
-        case DBUS_TYPE_INT32: return sizeof(dbus_int32_t);
-        case DBUS_TYPE_UINT32: return sizeof(dbus_uint32_t);
-        case DBUS_TYPE_INT64: return sizeof(dbus_int64_t);
-        case DBUS_TYPE_UINT64: return sizeof(dbus_uint64_t);
-        case DBUS_TYPE_DOUBLE: return sizeof(double);
-        case DBUS_TYPE_STRING:
-        case DBUS_TYPE_OBJECT_PATH:
-        case DBUS_TYPE_SIGNATURE: return sizeof(char*);
-        default: pa_assert_not_reached();
-    }
+void pa_dbus_send_error(DBusConnection *c, DBusMessage *in_reply_to, const char *name, const char *format, ...) {
+    va_list ap;
+    char *message;
+    DBusMessage *reply = NULL;
+
+    pa_assert(c);
+    pa_assert(in_reply_to);
+    pa_assert(name);
+    pa_assert(format);
+
+    va_start(ap, format);
+    message = pa_vsprintf_malloc(format, ap);
+    va_end(ap);
+    pa_assert_se((reply = dbus_message_new_error(in_reply_to, name, message)));
+    pa_assert_se(dbus_connection_send(c, reply, NULL));
+
+    dbus_message_unref(reply);
+
+    pa_xfree(message);
+}
+
+void pa_dbus_send_empty_reply(DBusConnection *c, DBusMessage *in_reply_to) {
+    DBusMessage *reply = NULL;
+
+    pa_assert(c);
+    pa_assert(in_reply_to);
+
+    pa_assert_se((reply = dbus_message_new_method_return(in_reply_to)));
+    pa_assert_se(dbus_connection_send(c, reply, NULL));
+    dbus_message_unref(reply);
+}
+
+void pa_dbus_send_basic_value_reply(DBusConnection *c, DBusMessage *in_reply_to, int type, void *data) {
+    DBusMessage *reply = NULL;
+
+    pa_assert(c);
+    pa_assert(in_reply_to);
+    pa_assert(dbus_type_is_basic(type));
+    pa_assert(data);
+
+    pa_assert_se((reply = dbus_message_new_method_return(in_reply_to)));
+    pa_assert_se(dbus_message_append_args(reply, type, data, DBUS_TYPE_INVALID));
+    pa_assert_se(dbus_connection_send(c, reply, NULL));
+    dbus_message_unref(reply);
 }
 
 static const char *signature_from_basic_type(int type) {
@@ -474,16 +520,81 @@ static const char *signature_from_basic_type(int type) {
     }
 }
 
-void pa_dbus_append_basic_variant(DBusMessageIter *iter, int type, void *data) {
+void pa_dbus_send_basic_variant_reply(DBusConnection *c, DBusMessage *in_reply_to, int type, void *data) {
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
     DBusMessageIter variant_iter;
 
-    pa_assert(iter);
+    pa_assert(c);
+    pa_assert(in_reply_to);
     pa_assert(dbus_type_is_basic(type));
     pa_assert(data);
 
-    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, signature_from_basic_type(type), &variant_iter));
+    pa_assert_se((reply = dbus_message_new_method_return(in_reply_to)));
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter,
+                                                  DBUS_TYPE_VARIANT,
+                                                  signature_from_basic_type(type),
+                                                  &variant_iter));
     pa_assert_se(dbus_message_iter_append_basic(&variant_iter, type, data));
-    pa_assert_se(dbus_message_iter_close_container(iter, &variant_iter));
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &variant_iter));
+    pa_assert_se(dbus_connection_send(c, reply, NULL));
+    dbus_message_unref(reply);
+}
+
+/* Note: returns sizeof(char*) for strings, object paths and signatures. */
+static unsigned basic_type_size(int type) {
+    switch (type) {
+        case DBUS_TYPE_BOOLEAN: return sizeof(dbus_bool_t);
+        case DBUS_TYPE_BYTE: return 1;
+        case DBUS_TYPE_INT16: return sizeof(dbus_int16_t);
+        case DBUS_TYPE_UINT16: return sizeof(dbus_uint16_t);
+        case DBUS_TYPE_INT32: return sizeof(dbus_int32_t);
+        case DBUS_TYPE_UINT32: return sizeof(dbus_uint32_t);
+        case DBUS_TYPE_INT64: return sizeof(dbus_int64_t);
+        case DBUS_TYPE_UINT64: return sizeof(dbus_uint64_t);
+        case DBUS_TYPE_DOUBLE: return sizeof(double);
+        case DBUS_TYPE_STRING:
+        case DBUS_TYPE_OBJECT_PATH:
+        case DBUS_TYPE_SIGNATURE: return sizeof(char*);
+        default: pa_assert_not_reached();
+    }
+}
+
+void pa_dbus_send_basic_array_variant_reply(
+        DBusConnection *c,
+        DBusMessage *in_reply_to,
+        int item_type,
+        void *array,
+        unsigned n) {
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+
+    pa_assert(c);
+    pa_assert(in_reply_to);
+    pa_assert(dbus_type_is_basic(item_type));
+    pa_assert(array || n == 0);
+
+    pa_assert_se((reply = dbus_message_new_method_return(in_reply_to)));
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_dbus_append_basic_array_variant(&msg_iter, item_type, array, n);
+    pa_assert_se(dbus_connection_send(c, reply, NULL));
+    dbus_message_unref(reply);
+}
+
+void pa_dbus_send_proplist_variant_reply(DBusConnection *c, DBusMessage *in_reply_to, pa_proplist *proplist) {
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter;
+
+    pa_assert(c);
+    pa_assert(in_reply_to);
+    pa_assert(proplist);
+
+    pa_assert_se((reply = dbus_message_new_method_return(in_reply_to)));
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_dbus_append_proplist_variant(&msg_iter, proplist);
+    pa_assert_se(dbus_connection_send(c, reply, NULL));
+    dbus_message_unref(reply);
 }
 
 void pa_dbus_append_basic_array(DBusMessageIter *iter, int item_type, const void *array, unsigned n) {
@@ -505,18 +616,16 @@ void pa_dbus_append_basic_array(DBusMessageIter *iter, int item_type, const void
     pa_assert_se(dbus_message_iter_close_container(iter, &array_iter));
 }
 
-void pa_dbus_append_basic_variant_dict_entry(DBusMessageIter *dict_iter, const char *key, int type, void *data) {
-    DBusMessageIter dict_entry_iter;
+void pa_dbus_append_basic_variant(DBusMessageIter *iter, int type, void *data) {
+    DBusMessageIter variant_iter;
 
-    pa_assert(dict_iter);
-    pa_assert(key);
+    pa_assert(iter);
     pa_assert(dbus_type_is_basic(type));
     pa_assert(data);
 
-    pa_assert_se(dbus_message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter));
-    pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &key));
-    pa_dbus_append_basic_variant(&dict_entry_iter, type, data);
-    pa_assert_se(dbus_message_iter_close_container(dict_iter, &dict_entry_iter));
+    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, signature_from_basic_type(type), &variant_iter));
+    pa_assert_se(dbus_message_iter_append_basic(&variant_iter, type, data));
+    pa_assert_se(dbus_message_iter_close_container(iter, &variant_iter));
 }
 
 void pa_dbus_append_basic_array_variant(DBusMessageIter *iter, int item_type, const void *array, unsigned n) {
@@ -536,6 +645,20 @@ void pa_dbus_append_basic_array_variant(DBusMessageIter *iter, int item_type, co
     pa_xfree(array_signature);
 }
 
+void pa_dbus_append_basic_variant_dict_entry(DBusMessageIter *dict_iter, const char *key, int type, void *data) {
+    DBusMessageIter dict_entry_iter;
+
+    pa_assert(dict_iter);
+    pa_assert(key);
+    pa_assert(dbus_type_is_basic(type));
+    pa_assert(data);
+
+    pa_assert_se(dbus_message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter));
+    pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &key));
+    pa_dbus_append_basic_variant(&dict_entry_iter, type, data);
+    pa_assert_se(dbus_message_iter_close_container(dict_iter, &dict_entry_iter));
+}
+
 void pa_dbus_append_basic_array_variant_dict_entry(
         DBusMessageIter *dict_iter,
         const char *key,
@@ -554,3 +677,107 @@ void pa_dbus_append_basic_array_variant_dict_entry(
     pa_dbus_append_basic_array_variant(&dict_entry_iter, item_type, array, n);
     pa_assert_se(dbus_message_iter_close_container(dict_iter, &dict_entry_iter));
 }
+
+void pa_dbus_append_proplist(DBusMessageIter *iter, pa_proplist *proplist) {
+    DBusMessageIter dict_iter;
+    DBusMessageIter dict_entry_iter;
+    DBusMessageIter array_iter;
+    void *state = NULL;
+    const char *key;
+
+    pa_assert(iter);
+    pa_assert(proplist);
+
+    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{say}", &dict_iter));
+
+    while ((key = pa_proplist_iterate(proplist, &state))) {
+        const void *value = NULL;
+        size_t nbytes;
+
+        pa_assert_se(pa_proplist_get(proplist, key, &value, &nbytes) >= 0);
+
+        pa_assert_se(dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter));
+
+        pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &key));
+
+        pa_assert_se(dbus_message_iter_open_container(&dict_entry_iter, DBUS_TYPE_ARRAY, "y", &array_iter));
+        pa_assert_se(dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE, &value, nbytes));
+        pa_assert_se(dbus_message_iter_close_container(&dict_entry_iter, &array_iter));
+
+        pa_assert_se(dbus_message_iter_close_container(&dict_iter, &dict_entry_iter));
+    }
+
+    pa_assert_se(dbus_message_iter_close_container(iter, &dict_iter));
+}
+
+void pa_dbus_append_proplist_variant(DBusMessageIter *iter, pa_proplist *proplist) {
+    DBusMessageIter variant_iter;
+
+    pa_assert(iter);
+    pa_assert(proplist);
+
+    pa_assert_se(dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a{say}", &variant_iter));
+    pa_dbus_append_proplist(&variant_iter, proplist);
+    pa_assert_se(dbus_message_iter_close_container(iter, &variant_iter));
+}
+
+void pa_dbus_append_proplist_variant_dict_entry(DBusMessageIter *dict_iter, const char *key, pa_proplist *proplist) {
+    DBusMessageIter dict_entry_iter;
+
+    pa_assert(dict_iter);
+    pa_assert(key);
+    pa_assert(proplist);
+
+    pa_assert_se(dbus_message_iter_open_container(dict_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_iter));
+    pa_assert_se(dbus_message_iter_append_basic(&dict_entry_iter, DBUS_TYPE_STRING, &key));
+    pa_dbus_append_proplist_variant(&dict_entry_iter, proplist);
+    pa_assert_se(dbus_message_iter_close_container(dict_iter, &dict_entry_iter));
+}
+
+pa_proplist *pa_dbus_get_proplist_arg(DBusConnection *c, DBusMessage *msg, DBusMessageIter *iter) {
+    DBusMessageIter dict_iter;
+    DBusMessageIter dict_entry_iter;
+    pa_proplist *proplist = NULL;
+    const char *key = NULL;
+    const uint8_t *value = NULL;
+    int value_length = 0;
+
+    pa_assert(c);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(pa_streq(dbus_message_iter_get_signature(iter), "a{say}"));
+
+    proplist = pa_proplist_new();
+
+    dbus_message_iter_recurse(iter, &dict_iter);
+
+    while (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_INVALID) {
+        dbus_message_iter_recurse(&dict_iter, &dict_entry_iter);
+
+        dbus_message_iter_get_basic(&dict_entry_iter, &key);
+        dbus_message_iter_next(&dict_entry_iter);
+
+        if (strlen(key) <= 0 || !pa_ascii_valid(key)) {
+            pa_dbus_send_error(c, msg, DBUS_ERROR_INVALID_ARGS, "Invalid property list key: '%s'.", key);
+            goto fail;
+        }
+
+        dbus_message_iter_get_fixed_array(&dict_entry_iter, &value, &value_length);
+
+        pa_assert(value_length >= 0);
+
+        pa_assert_se(pa_proplist_set(proplist, key, value, value_length) >= 0);
+
+        dbus_message_iter_next(&dict_iter);
+    }
+
+    dbus_message_iter_next(iter);
+
+    return proplist;
+
+fail:
+    if (proplist)
+        pa_proplist_free(proplist);
+
+    return NULL;
+}
index 51327fc..e3d6e4f 100644 (file)
 
 #include <dbus/dbus.h>
 
-#include <pulsecore/llist.h>
+#include <pulse/gccmacro.h>
 #include <pulse/mainloop-api.h>
+#include <pulse/proplist.h>
+
+#include <pulsecore/llist.h>
 
 /* A wrap connection is not shared or refcounted, it is available in client side */
 typedef struct pa_dbus_wrap_connection pa_dbus_wrap_connection;
 
 pa_dbus_wrap_connection* pa_dbus_wrap_connection_new(pa_mainloop_api *mainloop, pa_bool_t use_rtclock, DBusBusType type, DBusError *error);
+pa_dbus_wrap_connection* pa_dbus_wrap_connection_new_from_existing(
+        pa_mainloop_api *mainloop,
+        pa_bool_t use_rtclock,
+        DBusConnection *conn);
 void pa_dbus_wrap_connection_free(pa_dbus_wrap_connection* conn);
 
 DBusConnection* pa_dbus_wrap_connection_get(pa_dbus_wrap_connection *conn);
@@ -68,19 +75,42 @@ void pa_dbus_free_pending_list(pa_dbus_pending **p);
  * "<no explanation>" is returned. */
 const char *pa_dbus_get_error_message(DBusMessage *m);
 
-void pa_dbus_append_basic_variant(DBusMessageIter *iter, int type, void *data) ;
+/* Sends an error message as the reply to the given message. */
+void pa_dbus_send_error(
+        DBusConnection *c,
+        DBusMessage *in_reply_to,
+        const char *name,
+        const char *format, ...) PA_GCC_PRINTF_ATTR(4, 5);
+
+void pa_dbus_send_empty_reply(DBusConnection *c, DBusMessage *in_reply_to);
+void pa_dbus_send_basic_value_reply(DBusConnection *c, DBusMessage *in_reply_to, int type, void *data);
+void pa_dbus_send_basic_variant_reply(DBusConnection *c, DBusMessage *in_reply_to, int type, void *data);
+void pa_dbus_send_basic_array_variant_reply(
+        DBusConnection *c,
+        DBusMessage *in_reply_to,
+        int item_type,
+        void *array,
+        unsigned n);
+void pa_dbus_send_proplist_variant_reply(DBusConnection *c, DBusMessage *in_reply_to, pa_proplist *proplist);
 
 void pa_dbus_append_basic_array(DBusMessageIter *iter, int item_type, const void *array, unsigned n);
-
-void pa_dbus_append_basic_array_variant_dict_entry(
-                                                               DBusMessageIter *dict_iter,
-                                                               const char *key,
-                                                               int item_type,
-                                                               const void *array,
-                                                               unsigned n);
-
-void pa_dbus_append_basic_variant_dict_entry(DBusMessageIter *dict_iter, const char *key, int type, void *data) ;
-
 void pa_dbus_append_basic_array_variant(DBusMessageIter *iter, int item_type, const void *array, unsigned n);
+void pa_dbus_append_basic_variant(DBusMessageIter *iter, int type, void *data);
+void pa_dbus_append_basic_variant_dict_entry(DBusMessageIter *dict_iter, const char *key, int type, void *data);
+void pa_dbus_append_basic_array_variant_dict_entry(
+        DBusMessageIter *dict_iter,
+        const char *key,
+        int item_type,
+        const void *array,
+        unsigned n);
+void pa_dbus_append_proplist(DBusMessageIter *iter, pa_proplist *proplist);
+void pa_dbus_append_proplist_variant(DBusMessageIter *iter, pa_proplist *proplist);
+void pa_dbus_append_proplist_variant_dict_entry(DBusMessageIter *dict_iter, const char *key, pa_proplist *proplist);
+
+/* Returns a new proplist that the caller has to free. If the proplist contains
+ * invalid keys, an error reply is sent and NULL is returned. The iterator must
+ * point to "a{say}" element. This function calls dbus_message_iter_next(iter)
+ * before returning. */
+pa_proplist *pa_dbus_get_proplist_arg(DBusConnection *c, DBusMessage *msg, DBusMessageIter *iter);
 
 #endif
diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c
new file mode 100644 (file)
index 0000000..f16de3a
--- /dev/null
@@ -0,0 +1,125 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+  Copyright 2011 David Henningsson, Canonical Ltd.
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include "device-port.h"
+#include <pulsecore/card.h>
+
+PA_DEFINE_PUBLIC_CLASS(pa_device_port, pa_object);
+
+void pa_device_port_set_available(pa_device_port *p, pa_available_t status)
+{
+    pa_core *core;
+
+    pa_assert(p);
+
+    if (p->available == status)
+        return;
+
+/*    pa_assert(status != PA_AVAILABLE_UNKNOWN); */
+
+    p->available = status;
+    pa_log_debug("Setting port %s to status %s", p->name, status == PA_AVAILABLE_YES ? "yes" :
+       status == PA_AVAILABLE_NO ? "no" : "unknown");
+
+    /* Post subscriptions to the card which owns us */
+    pa_assert_se(core = p->core);
+    pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, p->card->index);
+
+    pa_hook_fire(&core->hooks[PA_CORE_HOOK_PORT_AVAILABLE_CHANGED], p);
+}
+
+static void device_port_free(pa_object *o) {
+    pa_device_port *p = PA_DEVICE_PORT(o);
+
+    pa_assert(p);
+    pa_assert(pa_device_port_refcnt(p) == 0);
+
+    if (p->proplist)
+        pa_proplist_free(p->proplist);
+
+    if (p->profiles)
+        pa_hashmap_free(p->profiles, NULL);
+
+    pa_xfree(p->name);
+    pa_xfree(p->description);
+    pa_xfree(p);
+}
+
+
+pa_device_port *pa_device_port_new(pa_core *c, const char *name, const char *description, size_t extra) {
+    pa_device_port *p;
+
+    pa_assert(name);
+
+    p = PA_DEVICE_PORT(pa_object_new_internal(PA_ALIGN(sizeof(pa_device_port)) + extra, pa_device_port_type_id, pa_device_port_check_type));
+    p->parent.free = device_port_free;
+
+    p->name = pa_xstrdup(name);
+    p->description = pa_xstrdup(description);
+    p->core = c;
+    p->card = NULL;
+    p->priority = 0;
+    p->available = PA_AVAILABLE_UNKNOWN;
+    p->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    p->is_input = FALSE;
+    p->is_output = FALSE;
+    p->latency_offset = 0;
+    p->proplist = pa_proplist_new();
+
+    return p;
+}
+
+void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset) {
+    uint32_t state;
+    pa_core *core;
+
+    pa_assert(p);
+
+    if (offset == p->latency_offset)
+        return;
+
+    p->latency_offset = offset;
+
+    if (p->is_output) {
+        pa_sink *sink;
+
+        PA_IDXSET_FOREACH(sink, p->core->sinks, state)
+            if (sink->active_port == p) {
+                pa_sink_set_latency_offset(sink, p->latency_offset);
+                break;
+            }
+
+    } else {
+        pa_source *source;
+
+        PA_IDXSET_FOREACH(source, p->core->sources, state)
+            if (source->active_port == p) {
+                pa_source_set_latency_offset(source, p->latency_offset);
+                break;
+            }
+    }
+
+    pa_assert_se(core = p->core);
+    pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, p->card->index);
+    pa_hook_fire(&core->hooks[PA_CORE_HOOK_PORT_LATENCY_OFFSET_CHANGED], p);
+}
diff --git a/src/pulsecore/device-port.h b/src/pulsecore/device-port.h
new file mode 100644 (file)
index 0000000..c0c00cf
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef foopulsedeviceporthfoo
+#define foopulsedeviceporthfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+  Copyright 2011 David Henningsson, Canonical Ltd.
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+typedef struct pa_device_port pa_device_port;
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <inttypes.h>
+
+#include <pulse/def.h>
+#include <pulsecore/object.h>
+#include <pulsecore/hashmap.h>
+#include <pulsecore/core.h>
+#include <pulsecore/card.h>
+
+struct pa_device_port {
+    pa_object parent; /* Needed for reference counting */
+    pa_core *core;
+    pa_card *card;
+
+    char *name;
+    char *description;
+
+    unsigned priority;
+    pa_available_t available;         /* PA_AVAILABLE_UNKNOWN, PA_AVAILABLE_NO or PA_AVAILABLE_YES */
+
+    pa_proplist *proplist;
+    pa_hashmap *profiles; /* Does not own the profiles */
+    pa_bool_t is_input:1;
+    pa_bool_t is_output:1;
+    int64_t latency_offset;
+
+    /* .. followed by some implementation specific data */
+};
+
+PA_DECLARE_PUBLIC_CLASS(pa_device_port);
+#define PA_DEVICE_PORT(s) (pa_device_port_cast(s))
+
+#define PA_DEVICE_PORT_DATA(d) ((void*) ((uint8_t*) d + PA_ALIGN(sizeof(pa_device_port))))
+
+pa_device_port *pa_device_port_new(pa_core *c, const char *name, const char *description, size_t extra);
+
+/* The port's available status has changed */
+void pa_device_port_set_available(pa_device_port *p, pa_available_t available);
+
+void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset);
+
+#endif
index 491ec75..d2de73d 100644 (file)
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <string.h>
 
 #include <windows.h>
+#include <winsock2.h>
 
-extern pa_set_root(HANDLE handle);
+extern char *pa_win32_get_toplevel(HANDLE handle);
 
 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
     WSADATA data;
@@ -39,7 +39,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
     switch (fdwReason) {
 
     case DLL_PROCESS_ATTACH:
-        if (!pa_set_root(hinstDLL))
+        if (!pa_win32_get_toplevel(hinstDLL))
             return FALSE;
         WSAStartup(MAKEWORD(2, 0), &data);
         break;
index 69d835a..78b2eb9 100644 (file)
@@ -50,14 +50,14 @@ pa_dynarray* pa_dynarray_new(void) {
     return a;
 }
 
-void pa_dynarray_free(pa_dynarray* a, pa_free2_cb_t free_func, void *userdata) {
+void pa_dynarray_free(pa_dynarray *a, pa_free_cb_t free_func) {
     unsigned i;
     pa_assert(a);
 
     if (free_func)
         for (i = 0; i < a->n_entries; i++)
             if (a->data[i])
-                free_func(a->data[i], userdata);
+                free_func(a->data[i]);
 
     pa_xfree(a->data);
     pa_xfree(a);
index 9a8e64e..70deebb 100644 (file)
@@ -22,7 +22,7 @@
   USA.
 ***/
 
-#include <pulsecore/idxset.h>
+#include <pulse/def.h>
 
 typedef struct pa_dynarray pa_dynarray;
 
@@ -34,7 +34,7 @@ pa_dynarray* pa_dynarray_new(void);
 
 /* Free the array calling the specified function for every entry in
  * the array. The function may be NULL. */
-void pa_dynarray_free(pa_dynarray* a, pa_free2_cb_t free_func, void *userdata);
+void pa_dynarray_free(pa_dynarray *a, pa_free_cb_t free_func);
 
 /* Store p at position i in the array */
 void pa_dynarray_put(pa_dynarray*a, unsigned i, void *p);
diff --git a/src/pulsecore/envelope.c b/src/pulsecore/envelope.c
deleted file mode 100644 (file)
index fd6a948..0000000
+++ /dev/null
@@ -1,786 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2007 Lennart Poettering
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as
-  published by the Free Software Foundation; either version 2.1 of the
-  License, or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-
-#include <pulse/sample.h>
-#include <pulse/xmalloc.h>
-
-#include <pulsecore/endianmacros.h>
-#include <pulsecore/memchunk.h>
-#include <pulsecore/macro.h>
-#include <pulsecore/flist.h>
-#include <pulsecore/semaphore.h>
-#include <pulsecore/g711.h>
-
-#include "envelope.h"
-
-/*
-    Envelope subsystem for applying linear interpolated volume
-    envelopes on audio data. If multiple enevelopes shall be applied
-    at the same time, the "minimum" envelope is determined and
-    applied.
-
-    Envelopes are defined in a statically allocated constant structure
-    pa_envelope_def. It may be activated using pa_envelope_add(). And
-    already active envelope may be replaced with pa_envelope_replace()
-    and removed with pa_envelope_remove().The combined "minimum"
-    envelope can be applied to audio data with pa_envelope_apply().
-
-    _apply() on one hand and _add()/_replace()/_remove() on the other
-    can be executed in seperate threads, in which case no locking is
-    used.
-*/
-
-PA_STATIC_FLIST_DECLARE(items, 0, pa_xfree);
-
-struct pa_envelope_item {
-    PA_LLIST_FIELDS(pa_envelope_item);
-    const pa_envelope_def *def;
-    pa_usec_t start_x;
-    union {
-        int32_t i;
-        float f;
-    } start_y;
-    unsigned j;
-};
-
-enum envelope_state {
-    STATE_VALID0,
-    STATE_VALID1,
-    STATE_READ0,
-    STATE_READ1,
-    STATE_WAIT0,
-    STATE_WAIT1,
-    STATE_WRITE0,
-    STATE_WRITE1
-};
-
-struct pa_envelope {
-    pa_sample_spec sample_spec;
-
-    PA_LLIST_HEAD(pa_envelope_item, items);
-
-    pa_atomic_t state;
-
-    size_t x;
-
-    struct {
-        unsigned n_points, n_allocated, n_current;
-
-        size_t *x;
-        union {
-            int32_t *i;
-            float *f;
-        } y;
-
-        size_t cached_dx;
-        int32_t cached_dy_i;
-        float cached_dy_dx;
-        pa_bool_t cached_valid;
-    } points[2];
-
-    pa_bool_t is_float;
-
-    pa_semaphore *semaphore;
-};
-
-pa_envelope *pa_envelope_new(const pa_sample_spec *ss) {
-    pa_envelope *e;
-    pa_assert(ss);
-
-    e = pa_xnew(pa_envelope, 1);
-
-    e->sample_spec = *ss;
-    PA_LLIST_HEAD_INIT(pa_envelope_item, e->items);
-
-    e->x = 0;
-
-    e->points[0].n_points = e->points[1].n_points = 0;
-    e->points[0].n_allocated = e->points[1].n_allocated = 0;
-    e->points[0].n_current = e->points[1].n_current = 0;
-    e->points[0].x = e->points[1].x = NULL;
-    e->points[0].y.i = e->points[1].y.i = NULL;
-    e->points[0].cached_valid = e->points[1].cached_valid = FALSE;
-
-    pa_atomic_store(&e->state, STATE_VALID0);
-
-    e->is_float =
-        ss->format == PA_SAMPLE_FLOAT32LE ||
-        ss->format == PA_SAMPLE_FLOAT32BE;
-
-    e->semaphore = pa_semaphore_new(0);
-
-    return e;
-}
-
-void pa_envelope_free(pa_envelope *e) {
-    pa_assert(e);
-
-    while (e->items)
-        pa_envelope_remove(e, e->items);
-
-    pa_xfree(e->points[0].x);
-    pa_xfree(e->points[1].x);
-    pa_xfree(e->points[0].y.i);
-    pa_xfree(e->points[1].y.i);
-
-    pa_semaphore_free(e->semaphore);
-
-    pa_xfree(e);
-}
-
-static int32_t linear_interpolate_int(pa_usec_t x1, int32_t _y1, pa_usec_t x2, int32_t y2, pa_usec_t x3) {
-    return (int32_t) ((double) _y1 + (double) (x3 - x1) * (double) (y2 - _y1) / (double) (x2 - x1));
-}
-
-static float linear_interpolate_float(pa_usec_t x1, float _y1, pa_usec_t x2, float y2, pa_usec_t x3) {
-    return _y1 + ((float) x3 - (float) x1) * (y2 - _y1) / ((float) x2 - (float) x1);
-}
-
-static int32_t item_get_int(pa_envelope_item *i, pa_usec_t x) {
-    pa_assert(i);
-
-    if (x <= i->start_x)
-        return i->start_y.i;
-
-    x -= i->start_x;
-
-    if (x <= i->def->points_x[0])
-        return linear_interpolate_int(0, i->start_y.i,
-                                      i->def->points_x[0], i->def->points_y.i[0], x);
-
-    if (x >= i->def->points_x[i->def->n_points-1])
-        return i->def->points_y.i[i->def->n_points-1];
-
-    pa_assert(i->j > 0);
-    pa_assert(i->def->points_x[i->j-1] <= x);
-    pa_assert(x < i->def->points_x[i->j]);
-
-    return linear_interpolate_int(i->def->points_x[i->j-1], i->def->points_y.i[i->j-1],
-                                  i->def->points_x[i->j], i->def->points_y.i[i->j], x);
-}
-
-static float item_get_float(pa_envelope_item *i, pa_usec_t x) {
-    pa_assert(i);
-
-    if (x <= i->start_x)
-        return i->start_y.f;
-
-    x -= i->start_x;
-
-    if (x <= i->def->points_x[0])
-        return linear_interpolate_float(0, i->start_y.f,
-                                        i->def->points_x[0], i->def->points_y.f[0], x);
-
-    if (x >= i->def->points_x[i->def->n_points-1])
-        return i->def->points_y.f[i->def->n_points-1];
-
-    pa_assert(i->j > 0);
-    pa_assert(i->def->points_x[i->j-1] <= x);
-    pa_assert(x < i->def->points_x[i->j]);
-
-    return linear_interpolate_float(i->def->points_x[i->j-1], i->def->points_y.f[i->j-1],
-                                    i->def->points_x[i->j], i->def->points_y.f[i->j], x);
-}
-
-static void envelope_begin_write(pa_envelope *e, int *v) {
-    enum envelope_state new_state, old_state;
-    pa_bool_t wait_sem;
-
-    pa_assert(e);
-    pa_assert(v);
-
-    for (;;) {
-        do {
-            wait_sem = FALSE;
-            old_state = pa_atomic_load(&e->state);
-
-            switch (old_state) {
-                case STATE_VALID0:
-                    *v = 1;
-                    new_state = STATE_WRITE0;
-                    break;
-                case STATE_VALID1:
-                    *v = 0;
-                    new_state = STATE_WRITE1;
-                    break;
-                case STATE_READ0:
-                    new_state = STATE_WAIT0;
-                    wait_sem = TRUE;
-                    break;
-                case STATE_READ1:
-                    new_state = STATE_WAIT1;
-                    wait_sem = TRUE;
-                    break;
-                default:
-                    pa_assert_not_reached();
-            }
-        } while (!pa_atomic_cmpxchg(&e->state, old_state, new_state));
-
-        if (!wait_sem)
-            break;
-
-        pa_semaphore_wait(e->semaphore);
-    }
-}
-
-static pa_bool_t envelope_commit_write(pa_envelope *e, int v) {
-    enum envelope_state new_state, old_state;
-
-    pa_assert(e);
-
-    do {
-        old_state = pa_atomic_load(&e->state);
-
-        switch (old_state) {
-            case STATE_WRITE0:
-                pa_assert(v == 1);
-                new_state = STATE_VALID1;
-                break;
-            case STATE_WRITE1:
-                pa_assert(v == 0);
-                new_state = STATE_VALID0;
-                break;
-            case STATE_VALID0:
-            case STATE_VALID1:
-            case STATE_READ0:
-            case STATE_READ1:
-                return FALSE;
-            default:
-                pa_assert_not_reached();
-        }
-    } while (!pa_atomic_cmpxchg(&e->state, old_state, new_state));
-
-    return TRUE;
-}
-
-static void envelope_begin_read(pa_envelope *e, int *v) {
-    enum envelope_state new_state, old_state;
-    pa_assert(e);
-    pa_assert(v);
-
-    do {
-        old_state = pa_atomic_load(&e->state);
-
-        switch (old_state) {
-            case STATE_VALID0:
-            case STATE_WRITE0:
-                *v = 0;
-                new_state = STATE_READ0;
-                break;
-            case STATE_VALID1:
-            case STATE_WRITE1:
-                *v = 1;
-                new_state = STATE_READ1;
-                break;
-            default:
-                pa_assert_not_reached();
-        }
-    } while (!pa_atomic_cmpxchg(&e->state, old_state, new_state));
-}
-
-static void envelope_commit_read(pa_envelope *e, int v) {
-    enum envelope_state new_state, old_state;
-    pa_bool_t post_sem;
-
-    pa_assert(e);
-
-    do {
-        post_sem = FALSE;
-        old_state = pa_atomic_load(&e->state);
-
-        switch (old_state) {
-            case STATE_READ0:
-                pa_assert(v == 0);
-                new_state = STATE_VALID0;
-                break;
-            case STATE_READ1:
-                pa_assert(v == 1);
-                new_state = STATE_VALID1;
-                break;
-            case STATE_WAIT0:
-                pa_assert(v == 0);
-                new_state = STATE_VALID0;
-                post_sem = TRUE;
-                break;
-            case STATE_WAIT1:
-                pa_assert(v == 1);
-                new_state = STATE_VALID1;
-                post_sem = TRUE;
-                break;
-            default:
-                pa_assert_not_reached();
-        }
-    } while (!pa_atomic_cmpxchg(&e->state, old_state, new_state));
-
-    if (post_sem)
-        pa_semaphore_post(e->semaphore);
-}
-
-static void envelope_merge(pa_envelope *e, int v) {
-
-    e->points[v].n_points = 0;
-
-    if (e->items) {
-        pa_envelope_item *i;
-        pa_usec_t x = (pa_usec_t) -1;
-
-        for (i = e->items; i; i = i->next)
-            i->j = 0;
-
-        for (;;) {
-            pa_bool_t min_is_set;
-            pa_envelope_item *s = NULL;
-
-            /* Let's find the next spot on the X axis to analyze */
-            for (i = e->items; i; i = i->next) {
-
-                for (;;) {
-
-                    if (i->j >= i->def->n_points)
-                        break;
-
-                    if ((x != (pa_usec_t) -1) && i->start_x + i->def->points_x[i->j] <= x) {
-                        i->j++;
-                        continue;
-                    }
-
-                    if (!s || (i->start_x + i->def->points_x[i->j] < s->start_x + s->def->points_x[s->j]))
-                        s = i;
-
-                    break;
-                }
-            }
-
-            if (!s)
-                break;
-
-            if (e->points[v].n_points >= e->points[v].n_allocated) {
-                e->points[v].n_allocated = PA_MAX(e->points[v].n_points*2, PA_ENVELOPE_POINTS_MAX);
-
-                e->points[v].x = pa_xrealloc(e->points[v].x, sizeof(size_t) * e->points[v].n_allocated);
-                e->points[v].y.i = pa_xrealloc(e->points[v].y.i, sizeof(int32_t) * e->points[v].n_allocated);
-            }
-
-            x = s->start_x + s->def->points_x[s->j];
-            e->points[v].x[e->points[v].n_points] = pa_usec_to_bytes(x, &e->sample_spec);
-
-            min_is_set = FALSE;
-
-            /* Now let's find the lowest value */
-            if (e->is_float) {
-                float min_f;
-
-                for (i = e->items; i; i = i->next) {
-                    float f = item_get_float(i, x);
-                    if (!min_is_set || f < min_f) {
-                        min_f = f;
-                        min_is_set = TRUE;
-                    }
-                }
-
-                e->points[v].y.f[e->points[v].n_points] = min_f;
-            } else {
-                int32_t min_k;
-
-                for (i = e->items; i; i = i->next) {
-                    int32_t k = item_get_int(i, x);
-                    if (!min_is_set || k < min_k) {
-                        min_k = k;
-                        min_is_set = TRUE;
-                    }
-                }
-
-                e->points[v].y.i[e->points[v].n_points] = min_k;
-            }
-
-            pa_assert_se(min_is_set);
-            e->points[v].n_points++;
-        }
-    }
-
-    e->points[v].n_current = 0;
-    e->points[v].cached_valid = FALSE;
-}
-
-pa_envelope_item *pa_envelope_add(pa_envelope *e, const pa_envelope_def *def) {
-    pa_envelope_item *i;
-    int v;
-
-    pa_assert(e);
-    pa_assert(def);
-    pa_assert(def->n_points > 0);
-
-    if (!(i = pa_flist_pop(PA_STATIC_FLIST_GET(items))))
-        i = pa_xnew(pa_envelope_item, 1);
-
-    i->def = def;
-
-    if (e->is_float)
-        i->start_y.f = def->points_y.f[0];
-    else
-        i->start_y.i = def->points_y.i[0];
-
-    PA_LLIST_PREPEND(pa_envelope_item, e->items, i);
-
-    envelope_begin_write(e, &v);
-
-    do {
-
-        i->start_x = pa_bytes_to_usec(e->x, &e->sample_spec);
-        envelope_merge(e, v);
-
-    } while (!envelope_commit_write(e, v));
-
-    return i;
-}
-
-pa_envelope_item *pa_envelope_replace(pa_envelope *e, pa_envelope_item *i, const pa_envelope_def *def) {
-    pa_usec_t x;
-    int v;
-
-    pa_assert(e);
-    pa_assert(i);
-    pa_assert(def->n_points > 0);
-
-    envelope_begin_write(e, &v);
-
-    for (;;) {
-        float saved_f;
-        int32_t saved_i;
-        uint64_t saved_start_x;
-        const pa_envelope_def *saved_def;
-
-        x = pa_bytes_to_usec(e->x, &e->sample_spec);
-
-        if (e->is_float) {
-            saved_f = i->start_y.f;
-            i->start_y.f = item_get_float(i, x);
-        } else {
-            saved_i = i->start_y.i;
-            i->start_y.i = item_get_int(i, x);
-        }
-
-        saved_start_x = i->start_x;
-        saved_def = i->def;
-
-        i->start_x = x;
-        i->def = def;
-
-        envelope_merge(e, v);
-
-        if (envelope_commit_write(e, v))
-            break;
-
-        i->start_x = saved_start_x;
-        i->def = saved_def;
-
-        if (e->is_float)
-            i->start_y.f = saved_f;
-        else
-            i->start_y.i = saved_i;
-    }
-
-    return i;
-}
-
-void pa_envelope_remove(pa_envelope *e, pa_envelope_item *i) {
-    int v;
-
-    pa_assert(e);
-    pa_assert(i);
-
-    PA_LLIST_REMOVE(pa_envelope_item, e->items, i);
-
-    if (pa_flist_push(PA_STATIC_FLIST_GET(items), i) < 0)
-        pa_xfree(i);
-
-    envelope_begin_write(e, &v);
-    do {
-        envelope_merge(e, v);
-    } while (!envelope_commit_write(e, v));
-}
-
-static int32_t linear_get_int(pa_envelope *e, int v) {
-    pa_assert(e);
-
-    /* The repeated division could be replaced by Bresenham, as an
-     * optimization */
-
-    if (e->x < e->points[v].x[0])
-        return e->points[v].y.i[0];
-
-    for (;;) {
-        if (e->points[v].n_current+1 >= e->points[v].n_points)
-            return e->points[v].y.i[e->points[v].n_points-1];
-
-        if (e->x < e->points[v].x[e->points[v].n_current+1])
-            break;
-
-        e->points[v].n_current++;
-        e->points[v].cached_valid = FALSE;
-    }
-
-    if (!e->points[v].cached_valid) {
-        e->points[v].cached_dx = e->points[v].x[e->points[v].n_current+1] - e->points[v].x[e->points[v].n_current];
-        e->points[v].cached_dy_i = e->points[v].y.i[e->points[v].n_current+1] - e->points[v].y.i[e->points[v].n_current];
-        e->points[v].cached_valid = TRUE;
-    }
-
-    return e->points[v].y.i[e->points[v].n_current] + (e->points[v].cached_dy_i * (int32_t) (e->x - e->points[v].x[e->points[v].n_current])) / (int32_t) e->points[v].cached_dx;
-}
-
-static float linear_get_float(pa_envelope *e, int v) {
-    pa_assert(e);
-
-    if (e->x < e->points[v].x[0])
-        return e->points[v].y.f[0];
-
-    for (;;) {
-        if (e->points[v].n_current+1 >= e->points[v].n_points)
-            return e->points[v].y.f[e->points[v].n_points-1];
-
-        if (e->x < e->points[v].x[e->points[v].n_current+1])
-            break;
-
-        e->points[v].n_current++;
-        e->points[v].cached_valid = FALSE;
-    }
-
-    if (!e->points[v].cached_valid) {
-        e->points[v].cached_dy_dx =
-            (e->points[v].y.f[e->points[v].n_current+1] - e->points[v].y.f[e->points[v].n_current]) /
-            ((float) e->points[v].x[e->points[v].n_current+1] - (float) e->points[v].x[e->points[v].n_current]);
-        e->points[v].cached_valid = TRUE;
-    }
-
-    return e->points[v].y.f[e->points[v].n_current] + (float) (e->x - e->points[v].x[e->points[v].n_current]) * e->points[v].cached_dy_dx;
-}
-
-void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) {
-    int v;
-
-    pa_assert(e);
-    pa_assert(chunk);
-
-    envelope_begin_read(e, &v);
-
-    if (e->points[v].n_points > 0) {
-        void *p;
-        size_t fs, n;
-
-        pa_memchunk_make_writable(chunk, 0);
-        p = (uint8_t*) pa_memblock_acquire(chunk->memblock) + chunk->index;
-        fs = pa_frame_size(&e->sample_spec);
-        n = chunk->length;
-
-        switch (e->sample_spec.format) {
-
-            case PA_SAMPLE_U8: {
-                uint8_t *t;
-
-                for (t = p; n > 0; n -= fs) {
-                    int32_t factor = linear_get_int(e, v);
-                    unsigned c;
-                    e->x += fs;
-
-                    for (c = 0; c < e->sample_spec.channels; c++, t++)
-                        *t = (uint8_t) (((factor * ((int16_t) *t - 0x80)) / 0x10000) + 0x80);
-                }
-
-                break;
-            }
-
-            case PA_SAMPLE_ULAW: {
-                uint8_t *t;
-
-                for (t = p; n > 0; n -= fs) {
-                    int32_t factor = linear_get_int(e, v);
-                    unsigned c;
-                    e->x += fs;
-
-                    for (c = 0; c < e->sample_spec.channels; c++, t++) {
-                        int16_t k = st_ulaw2linear16(*t);
-                        *t = (uint8_t) st_14linear2ulaw((int16_t) (((factor * k) / 0x10000) >> 2));
-                    }
-                }
-
-                break;
-            }
-
-            case PA_SAMPLE_ALAW: {
-                uint8_t *t;
-
-                for (t = p; n > 0; n -= fs) {
-                    int32_t factor = linear_get_int(e, v);
-                    unsigned c;
-                    e->x += fs;
-
-                    for (c = 0; c < e->sample_spec.channels; c++, t++) {
-                        int16_t k = st_alaw2linear16(*t);
-                        *t = (uint8_t) st_13linear2alaw((int16_t) (((factor * k) / 0x10000) >> 3));
-                    }
-                }
-
-                break;
-            }
-
-            case PA_SAMPLE_S16NE: {
-                int16_t *t;
-
-                for (t = p; n > 0; n -= fs) {
-                    int32_t factor = linear_get_int(e, v);
-                    unsigned c;
-                    e->x += fs;
-
-                    for (c = 0; c < e->sample_spec.channels; c++, t++)
-                        *t = (int16_t) ((factor * *t) / 0x10000);
-                }
-
-                break;
-            }
-
-            case PA_SAMPLE_S16RE: {
-                int16_t *t;
-
-                for (t = p; n > 0; n -= fs) {
-                    int32_t factor = linear_get_int(e, v);
-                    unsigned c;
-                    e->x += fs;
-
-                    for (c = 0; c < e->sample_spec.channels; c++, t++) {
-                        int16_t r = (int16_t) ((factor * PA_INT16_SWAP(*t)) / 0x10000);
-                        *t = PA_INT16_SWAP(r);
-                    }
-                }
-
-                break;
-            }
-
-            case PA_SAMPLE_S32NE: {
-                int32_t *t;
-
-                for (t = p; n > 0; n -= fs) {
-                    int32_t factor = linear_get_int(e, v);
-                    unsigned c;
-                    e->x += fs;
-
-                    for (c = 0; c < e->sample_spec.channels; c++, t++)
-                        *t = (int32_t) (((int64_t) factor * (int64_t) *t) / 0x10000);
-                }
-
-                break;
-            }
-
-            case PA_SAMPLE_S32RE: {
-                int32_t *t;
-
-                for (t = p; n > 0; n -= fs) {
-                    int32_t factor = linear_get_int(e, v);
-                    unsigned c;
-                    e->x += fs;
-
-                    for (c = 0; c < e->sample_spec.channels; c++, t++) {
-                        int32_t r = (int32_t) (((int64_t) factor * (int64_t) PA_INT32_SWAP(*t)) / 0x10000);
-                        *t = PA_INT32_SWAP(r);
-                    }
-                }
-
-                break;
-            }
-
-            case PA_SAMPLE_FLOAT32NE: {
-                float *t;
-
-                for (t = p; n > 0; n -= fs) {
-                    float factor = linear_get_float(e, v);
-                    unsigned c;
-                    e->x += fs;
-
-                    for (c = 0; c < e->sample_spec.channels; c++, t++)
-                        *t = *t * factor;
-                }
-
-                break;
-            }
-
-            case PA_SAMPLE_FLOAT32RE: {
-                float *t;
-
-                for (t = p; n > 0; n -= fs) {
-                    float factor = linear_get_float(e, v);
-                    unsigned c;
-                    e->x += fs;
-
-                    for (c = 0; c < e->sample_spec.channels; c++, t++) {
-                        float r = PA_FLOAT32_SWAP(*t) * factor;
-                        *t = PA_FLOAT32_SWAP(r);
-                    }
-                }
-
-                break;
-            }
-
-            case PA_SAMPLE_S24LE:
-            case PA_SAMPLE_S24BE:
-            case PA_SAMPLE_S24_32LE:
-            case PA_SAMPLE_S24_32BE:
-                /* FIXME */
-                pa_assert_not_reached();
-
-            case PA_SAMPLE_MAX:
-            case PA_SAMPLE_INVALID:
-                pa_assert_not_reached();
-        }
-
-        pa_memblock_release(chunk->memblock);
-
-        e->x += chunk->length;
-    } else {
-        /* When we have no envelope to apply we reset our origin */
-        e->x = 0;
-    }
-
-    envelope_commit_read(e, v);
-}
-
-void pa_envelope_rewind(pa_envelope *e, size_t n_bytes) {
-    int v;
-
-    pa_assert(e);
-
-    envelope_begin_read(e, &v);
-
-    if (n_bytes < e->x)
-        e->x -= n_bytes;
-    else
-        e->x = 0;
-
-    e->points[v].n_current = 0;
-    e->points[v].cached_valid = FALSE;
-
-    envelope_commit_read(e, v);
-}
diff --git a/src/pulsecore/envelope.h b/src/pulsecore/envelope.h
deleted file mode 100644 (file)
index 5296415..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef foopulseenvelopehfoo
-#define foopulseenvelopehfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2007 Lennart Poettering
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as
-  published by the Free Software Foundation; either version 2.1 of the
-  License, or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <pulsecore/macro.h>
-#include <pulsecore/memchunk.h>
-
-#include <pulse/sample.h>
-
-#define PA_ENVELOPE_POINTS_MAX 4U
-
-typedef struct pa_envelope pa_envelope;
-typedef struct pa_envelope_item pa_envelope_item;
-
-typedef struct pa_envelope_def {
-    unsigned n_points;
-
-    pa_usec_t points_x[PA_ENVELOPE_POINTS_MAX];
-    struct {
-        int32_t i[PA_ENVELOPE_POINTS_MAX];
-        float f[PA_ENVELOPE_POINTS_MAX];
-    } points_y;
-} pa_envelope_def;
-
-pa_envelope *pa_envelope_new(const pa_sample_spec *ss);
-void pa_envelope_free(pa_envelope *e);
-pa_envelope_item *pa_envelope_add(pa_envelope *e, const pa_envelope_def *def);
-pa_envelope_item *pa_envelope_replace(pa_envelope *e, pa_envelope_item *i, const pa_envelope_def *def);
-void pa_envelope_remove(pa_envelope *e, pa_envelope_item *i);
-void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk);
-void pa_envelope_rewind(pa_envelope *e, size_t n_bytes);
-
-#endif
index abc2355..965f4db 100644 (file)
@@ -55,7 +55,7 @@
 /*************************************/
 /* what can we do to/with the EsounD */
 enum esd_proto {
-    ESD_PROTO_CONNECT,      /* implied on inital client connection */
+    ESD_PROTO_CONNECT,      /* implied on initial client connection */
 
     /* pseudo "security" functionality */
     ESD_PROTO_LOCK,         /* disable "foreign" client connections */
@@ -72,7 +72,7 @@ enum esd_proto {
     ESD_PROTO_SAMPLE_PLAY,  /* play a cached sample */
     ESD_PROTO_SAMPLE_LOOP,  /* loop a cached sample, til eoloop */
     ESD_PROTO_SAMPLE_STOP,  /* stop a looping sample when done */
-    ESD_PROTO_SAMPLE_KILL,  /* stop the looping sample immed. */
+    ESD_PROTO_SAMPLE_KILL,  /* stop the looping sample immediately */
 
     /* free and reclaim /dev/dsp functionality */
     ESD_PROTO_STANDBY,      /* release /dev/dsp and ignore all data */
@@ -194,7 +194,7 @@ typedef int esd_standby_mode_t;
 enum esd_client_state {
     ESD_STREAMING_DATA,         /* data from here on is streamed data */
     ESD_CACHING_SAMPLE,         /* midway through caching a sample */
-    ESD_NEEDS_REQDATA,          /* more data needed to complere request */
+    ESD_NEEDS_REQDATA,          /* more data needed to complete request */
     ESD_NEXT_REQUEST,           /* proceed to next request */
     ESD_CLIENT_STATE_MAX        /* place holder */
 };
index 380f34f..14fcbd6 100644 (file)
@@ -32,9 +32,9 @@
 
 #include <pulsecore/atomic.h>
 #include <pulsecore/log.h>
-#include <pulsecore/thread.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
+#include <pulsecore/core-error.h>
 #include <pulse/xmalloc.h>
 
 #ifndef HAVE_PIPE
@@ -62,19 +62,15 @@ pa_fdsem *pa_fdsem_new(void) {
     f = pa_xmalloc(PA_ALIGN(sizeof(pa_fdsem)) + PA_ALIGN(sizeof(pa_fdsem_data)));
 
 #ifdef HAVE_SYS_EVENTFD_H
-    if ((f->efd = eventfd(0, 0)) >= 0) {
-        pa_make_fd_cloexec(f->efd);
+    if ((f->efd = eventfd(0, EFD_CLOEXEC)) >= 0)
         f->fds[0] = f->fds[1] = -1;
-    else
+    else
 #endif
     {
-        if (pipe(f->fds) < 0) {
+        if (pa_pipe_cloexec(f->fds) < 0) {
             pa_xfree(f);
             return NULL;
         }
-
-        pa_make_fd_cloexec(f->fds[0]);
-        pa_make_fd_cloexec(f->fds[1]);
     }
 
     f->data = (pa_fdsem_data*) ((uint8_t*) f + PA_ALIGN(sizeof(pa_fdsem)));
@@ -114,12 +110,11 @@ pa_fdsem *pa_fdsem_new_shm(pa_fdsem_data *data, int* event_fd) {
 
     f = pa_xnew(pa_fdsem, 1);
 
-    if ((f->efd = eventfd(0, 0)) < 0) {
+    if ((f->efd = eventfd(0, EFD_CLOEXEC)) < 0) {
         pa_xfree(f);
         return NULL;
     }
 
-    pa_make_fd_cloexec(f->efd);
     f->fds[0] = f->fds[1] = -1;
     f->data = data;
 
@@ -158,16 +153,26 @@ static void flush(pa_fdsem *f) {
         if (f->efd >= 0) {
             uint64_t u;
 
-            if ((r = read(f->efd, &u, sizeof(u))) != sizeof(u)) {
-                pa_assert(r < 0 && errno == EINTR);
+            if ((r = pa_read(f->efd, &u, sizeof(u), NULL)) != sizeof(u)) {
+
+                if (r >= 0 || errno != EINTR) {
+                    pa_log_error("Invalid read from eventfd: %s", r < 0 ? pa_cstrerror(errno) : "EOF");
+                    pa_assert_not_reached();
+                }
+
                 continue;
             }
             r = (ssize_t) u;
         } else
 #endif
 
-        if ((r = read(f->fds[0], &x, sizeof(x))) <= 0) {
-            pa_assert(r < 0 && errno == EINTR);
+        if ((r = pa_read(f->fds[0], &x, sizeof(x), NULL)) <= 0) {
+
+            if (r >= 0 || errno != EINTR) {
+                pa_log_error("Invalid read from pipe: %s", r < 0 ? pa_cstrerror(errno) : "EOF");
+                pa_assert_not_reached();
+            }
+
             continue;
         }
 
@@ -191,15 +196,23 @@ void pa_fdsem_post(pa_fdsem *f) {
                 if (f->efd >= 0) {
                     uint64_t u = 1;
 
-                    if ((r = write(f->efd, &u, sizeof(u))) != sizeof(u)) {
-                        pa_assert(r < 0 && errno == EINTR);
+                    if ((r = pa_write(f->efd, &u, sizeof(u), NULL)) != sizeof(u)) {
+                        if (r >= 0 || errno != EINTR) {
+                            pa_log_error("Invalid write to eventfd: %s", r < 0 ? pa_cstrerror(errno) : "EOF");
+                            pa_assert_not_reached();
+                        }
+
                         continue;
                     }
                 } else
 #endif
 
-                if ((r = write(f->fds[1], &x, 1)) != 1) {
-                    pa_assert(r < 0 && errno == EINTR);
+                if ((r = pa_write(f->fds[1], &x, 1, NULL)) != 1) {
+                    if (r >= 0 || errno != EINTR) {
+                        pa_log_error("Invalid write to pipe: %s", r < 0 ? pa_cstrerror(errno) : "EOF");
+                        pa_assert_not_reached();
+                    }
+
                     continue;
                 }
 
@@ -227,8 +240,13 @@ void pa_fdsem_wait(pa_fdsem *f) {
         if (f->efd >= 0) {
             uint64_t u;
 
-            if ((r = read(f->efd, &u, sizeof(u))) != sizeof(u)) {
-                pa_assert(r < 0 && errno == EINTR);
+            if ((r = pa_read(f->efd, &u, sizeof(u), NULL)) != sizeof(u)) {
+
+                if (r >= 0 || errno != EINTR) {
+                    pa_log_error("Invalid read from eventfd: %s", r < 0 ? pa_cstrerror(errno) : "EOF");
+                    pa_assert_not_reached();
+                }
+
                 continue;
             }
 
@@ -236,8 +254,13 @@ void pa_fdsem_wait(pa_fdsem *f) {
         } else
 #endif
 
-        if ((r = read(f->fds[0], &x, sizeof(x))) <= 0) {
-            pa_assert(r < 0 && errno == EINTR);
+        if ((r = pa_read(f->fds[0], &x, sizeof(x), NULL)) <= 0) {
+
+            if (r >= 0 || errno != EINTR) {
+                pa_log_error("Invalid read from pipe: %s", r < 0 ? pa_cstrerror(errno) : "EOF");
+                pa_assert_not_reached();
+            }
+
             continue;
         }
 
index 48a77c4..90e8599 100644 (file)
@@ -23,7 +23,6 @@
 ***/
 
 #include <sys/types.h>
-#include <pulse/def.h>
 
 /* A simple, asynchronous semaphore which uses fds for sleeping. In
  * the best case all functions are lock-free unless sleeping is
index c65cd68..87675f6 100644 (file)
@@ -187,16 +187,14 @@ int64_t __gettime(void)
 
 #define PRELOAD_FILTER
 
-AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff)
-{
+AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff){
 #ifdef DEBUG_MODE
        int64_t start = __gettime ();
-       printf("[%s][%d] out=%d, in=%d, filter_size=%d, phase_shift=%d, linear=%d, cutoff=%f\n", __func__, __LINE__,
+       printf("out=%d, in=%d, filter_size=%d, phase_shift=%d, linear=%d, cutoff=%f\n",
                        out_rate, in_rate, filter_size, phase_shift, linear, cutoff);
 #endif
     AVResampleContext *c= av_mallocz(sizeof(AVResampleContext));
     double factor= FFMIN(out_rate * cutoff / in_rate, 1.0);
-
     int phase_count= 1<<phase_shift;
 
     c->phase_shift= phase_shift;
@@ -260,7 +258,7 @@ AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_size,
     c->index= -phase_count*((c->filter_length-1)/2);
 
 #ifdef DEBUG_MODE
-    printf("[%s][%d] elapsed = %lld\n", __func__, __LINE__, __gettime() - start);
+    printf("elapsed = %lld\n", __gettime() - start);
 #endif
 
     return c;
index 7e5ee24..b110e1e 100644 (file)
@@ -2,6 +2,10 @@
   This file is part of PulseAudio.
 
   Copyright 2006-2008 Lennart Poettering
+  Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+  Copyright (C) 2012 Canonical Ltd.
+
+  Contact: Jyri Sarha <Jyri.Sarha@nokia.com>
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as
 
 #include <pulsecore/atomic.h>
 #include <pulsecore/log.h>
-#include <pulsecore/thread.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/macro.h>
 
 #include "flist.h"
 
-/* Algorithm is not perfect, in a few corner cases it will fail to pop
- * from the flist although it isn't empty, and fail to push into the
- * flist, although it isn't full.
- *
- * We keep a fixed size array of entries, each item is an atomic
- * pointer.
- *
- * To accelerate finding of used/unused cells we maintain a read and a
- * write index which is used like a ring buffer. After each push we
- * increase the write index and after each pop we increase the read
- * index.
- *
- * The indexes are incremented atomically and are never truncated to
- * the buffer size. Instead we assume that the buffer size is a power
- * of two and that the truncation can thus be done by applying a
- * simple AND on read.
- *
- * To make sure that we do not look for empty cells indefinitely we
- * maintain a length value which stores the number of used cells. From
- * this value the number of unused cells is easily calculated. Please
- * note that the length value is not updated atomically with the read
- * and write index and might thus be a few cells off the real
- * value. To deal with this we always look for N_EXTRA_SCAN extra
- * cells when pushing/popping entries.
- *
- * It might make sense to replace this implementation with a link list
- * stack or queue, which however requires DCAS to be simple. Patches
- * welcome.
- *
- * Please note that this algorithm is home grown.*/
-
-#define FLIST_SIZE 128
-#define N_EXTRA_SCAN 3
-
-/* For debugging purposes we can define _Y to put and extra thread
- * yield between each operation. */
-
-#ifdef PROFILE
-#define _Y pa_thread_yield()
-#else
-#define _Y do { } while(0)
-#endif
+#define FLIST_SIZE 256
+
+/* Atomic table indices contain
+   sign bit = if set, indicates empty/NULL value
+   tag bits (to avoid the ABA problem)
+   actual index bits
+*/
+
+/* Lock free single linked list element. */
+struct pa_flist_elem {
+    pa_atomic_t next;
+    pa_atomic_ptr_t ptr;
+};
+
+typedef struct pa_flist_elem pa_flist_elem;
 
 struct pa_flist {
+    char *name;
     unsigned size;
-    pa_atomic_t length;
-    pa_atomic_t read_idx;
-    pa_atomic_t write_idx;
+
+    pa_atomic_t current_tag;
+    int index_mask;
+    int tag_shift;
+    int tag_mask;
+
+    /* Stack that contains pointers stored into free list */
+    pa_atomic_t stored;
+    /* Stack that contains empty list elements */
+    pa_atomic_t empty;
+    pa_flist_elem table[];
 };
 
-#define PA_FLIST_CELLS(x) ((pa_atomic_ptr_t*) ((uint8_t*) (x) + PA_ALIGN(sizeof(struct pa_flist))))
+/* Lock free pop from linked list stack */
+static pa_flist_elem *stack_pop(pa_flist *flist, pa_atomic_t *list) {
+    pa_flist_elem *popped;
+    int idx;
+    pa_assert(list);
 
-pa_flist *pa_flist_new(unsigned size) {
+    do {
+        idx = pa_atomic_load(list);
+        if (idx < 0)
+            return NULL;
+        popped = &flist->table[idx & flist->index_mask];
+    } while (!pa_atomic_cmpxchg(list, idx, pa_atomic_load(&popped->next)));
+
+    return popped;
+}
+
+/* Lock free push to linked list stack */
+static void stack_push(pa_flist *flist, pa_atomic_t *list, pa_flist_elem *new_elem) {
+    int tag, newindex, next;
+    pa_assert(list);
+
+    tag = pa_atomic_inc(&flist->current_tag);
+    newindex = new_elem - flist->table;
+    pa_assert(newindex >= 0 && newindex < (int) flist->size);
+    newindex |= (tag << flist->tag_shift) & flist->tag_mask;
+
+    do {
+        next = pa_atomic_load(list);
+        pa_atomic_store(&new_elem->next, next);
+    } while (!pa_atomic_cmpxchg(list, next, newindex));
+}
+
+pa_flist *pa_flist_new_with_name(unsigned size, const char *name) {
     pa_flist *l;
+    unsigned i;
+    pa_assert(name);
 
     if (!size)
         size = FLIST_SIZE;
 
-    pa_assert(pa_is_power_of_two(size));
-
-    l = pa_xmalloc0(PA_ALIGN(sizeof(pa_flist)) + (sizeof(pa_atomic_ptr_t) * size));
+    l = pa_xmalloc0(sizeof(pa_flist) + sizeof(pa_flist_elem) * size);
 
+    l->name = pa_xstrdup(name);
     l->size = size;
 
-    pa_atomic_store(&l->read_idx, 0);
-    pa_atomic_store(&l->write_idx, 0);
-    pa_atomic_store(&l->length, 0);
+    while (1 << l->tag_shift < (int) size)
+        l->tag_shift++;
+    l->index_mask = (1 << l->tag_shift) - 1;
+    l->tag_mask = INT_MAX - l->index_mask;
 
+    pa_atomic_store(&l->stored, -1);
+    pa_atomic_store(&l->empty, -1);
+    for (i=0; i < size; i++) {
+        stack_push(l, &l->empty, &l->table[i]);
+    }
     return l;
 }
 
-static unsigned reduce(pa_flist *l, unsigned value) {
-    return value & (l->size - 1);
+pa_flist *pa_flist_new(unsigned size) {
+    return pa_flist_new_with_name(size, "unknown");
 }
 
 void pa_flist_free(pa_flist *l, pa_free_cb_t free_cb) {
     pa_assert(l);
+    pa_assert(l->name);
 
     if (free_cb) {
-        pa_atomic_ptr_t*cells;
-        unsigned idx;
-
-        cells = PA_FLIST_CELLS(l);
-
-        for (idx = 0; idx < l->size; idx ++) {
-            void *p;
-
-            if ((p = pa_atomic_ptr_load(&cells[idx])))
-                free_cb(p);
-        }
+        pa_flist_elem *elem;
+        while((elem = stack_pop(l, &l->stored)))
+            free_cb(pa_atomic_ptr_load(&elem->ptr));
     }
 
+    pa_xfree(l->name);
     pa_xfree(l);
 }
 
-int pa_flist_push(pa_flist*l, void *p) {
-    unsigned idx, n;
-    pa_atomic_ptr_t*cells;
-#ifdef PROFILE
-    unsigned len;
-#endif
-
+int pa_flist_push(pa_flist *l, void *p) {
+    pa_flist_elem *elem;
     pa_assert(l);
     pa_assert(p);
 
-    cells = PA_FLIST_CELLS(l);
-
-    n = l->size + N_EXTRA_SCAN - (unsigned) pa_atomic_load(&l->length);
-
-#ifdef PROFILE
-    len = n;
-#endif
-
-    _Y;
-    idx = reduce(l, (unsigned) pa_atomic_load(&l->write_idx));
-
-    for (; n > 0 ; n--) {
-
-        _Y;
-
-        if (pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p)) {
-
-            _Y;
-            pa_atomic_inc(&l->write_idx);
-
-            _Y;
-            pa_atomic_inc(&l->length);
-
-            return 0;
-        }
-
-        _Y;
-        idx = reduce(l, idx + 1);
+    elem = stack_pop(l, &l->empty);
+    if (elem == NULL) {
+        if (pa_log_ratelimit(PA_LOG_DEBUG))
+            pa_log_debug("%s flist is full (don't worry)", l->name);
+        return -1;
     }
+    pa_atomic_ptr_store(&elem->ptr, p);
+    stack_push(l, &l->stored, elem);
 
-#ifdef PROFILE
-    if (len > N_EXTRA_SCAN)
-        pa_log_warn("Didn't  find free cell after %u iterations.", len);
-#endif
-
-    return -1;
+    return 0;
 }
 
-void* pa_flist_pop(pa_flist*l) {
-    unsigned idx, n;
-    pa_atomic_ptr_t *cells;
-#ifdef PROFILE
-    unsigned len;
-#endif
-
+void* pa_flist_pop(pa_flist *l) {
+    pa_flist_elem *elem;
+    void *ptr;
     pa_assert(l);
 
-    cells = PA_FLIST_CELLS(l);
+    elem = stack_pop(l, &l->stored);
+    if (elem == NULL)
+        return NULL;
 
-    n = (unsigned) pa_atomic_load(&l->length) + N_EXTRA_SCAN;
+    ptr = pa_atomic_ptr_load(&elem->ptr);
 
-#ifdef PROFILE
-    len = n;
-#endif
-
-    _Y;
-    idx = reduce(l, (unsigned) pa_atomic_load(&l->read_idx));
-
-    for (; n > 0 ; n--) {
-        void *p;
-
-        _Y;
-        p = pa_atomic_ptr_load(&cells[idx]);
-
-        if (p) {
-
-            _Y;
-            if (!pa_atomic_ptr_cmpxchg(&cells[idx], p, NULL))
-                continue;
-
-            _Y;
-            pa_atomic_inc(&l->read_idx);
-
-            _Y;
-            pa_atomic_dec(&l->length);
-
-            return p;
-        }
-
-        _Y;
-        idx = reduce(l, idx+1);
-    }
-
-#ifdef PROFILE
-    if (len > N_EXTRA_SCAN)
-        pa_log_warn("Didn't find used cell after %u iterations.", len);
-#endif
+    stack_push(l, &l->empty, elem);
 
-    return NULL;
+    return ptr;
 }
index e147486..2ce88cc 100644 (file)
 
 typedef struct pa_flist pa_flist;
 
-/* Size is required to be a power of two, or 0 for the default size */
 pa_flist * pa_flist_new(unsigned size);
+/* Name string is copied and added to flist structure. The original is
+ * responsibility of the caller. The name is only used for debug printing. */
+pa_flist * pa_flist_new_with_name(unsigned size, const char *name);
 void pa_flist_free(pa_flist *l, pa_free_cb_t free_cb);
 
 /* Please note that this routine might fail! */
 int pa_flist_push(pa_flist*l, void *p);
 void* pa_flist_pop(pa_flist*l);
 
-/* Please not that the destructor stuff is not really necesary, we do
+/* Please note that the destructor stuff is not really necessary, we do
  * this just to make valgrind output more useful. */
 
 #define PA_STATIC_FLIST_DECLARE(name, size, free_cb)                    \
     static struct {                                                     \
-        pa_flist *flist;                                                \
+        pa_flist *volatile flist;                                       \
         pa_once once;                                                   \
     } name##_flist = { NULL, PA_ONCE_INIT };                            \
     static void name##_flist_init(void) {                               \
-        name##_flist.flist = pa_flist_new(size);                        \
+        name##_flist.flist =                                            \
+            pa_flist_new_with_name(size, __FILE__ ": " #name);          \
     }                                                                   \
     static inline pa_flist* name##_flist_get(void) {                    \
         pa_run_once(&name##_flist.once, name##_flist_init);             \
index 1fac97e..3e1d9f1 100644 (file)
 #endif
 
 #include <stdlib.h>
-#include <string.h>
 
 #include <pulse/xmalloc.h>
 #include <pulsecore/idxset.h>
-#include <pulsecore/log.h>
 #include <pulsecore/flist.h>
 #include <pulsecore/macro.h>
 
@@ -103,18 +101,10 @@ static void remove_entry(pa_hashmap *h, struct hashmap_entry *e) {
     h->n_entries--;
 }
 
-void pa_hashmap_free(pa_hashmap*h, pa_free2_cb_t free_cb, void *userdata) {
+void pa_hashmap_free(pa_hashmap *h, pa_free_cb_t free_cb) {
     pa_assert(h);
 
-    while (h->iterate_list_head) {
-        void *data;
-        data = h->iterate_list_head->value;
-        remove_entry(h, h->iterate_list_head);
-
-        if (free_cb)
-            free_cb(data, userdata);
-    }
-
+    pa_hashmap_remove_all(h, free_cb);
     pa_xfree(h);
 }
 
@@ -204,6 +194,19 @@ void* pa_hashmap_remove(pa_hashmap *h, const void *key) {
     return data;
 }
 
+void pa_hashmap_remove_all(pa_hashmap *h, pa_free_cb_t free_cb) {
+    pa_assert(h);
+
+    while (h->iterate_list_head) {
+        void *data;
+        data = h->iterate_list_head->value;
+        remove_entry(h, h->iterate_list_head);
+
+        if (free_cb)
+            free_cb(data);
+    }
+}
+
 void *pa_hashmap_iterate(pa_hashmap *h, void **state, const void **key) {
     struct hashmap_entry *e;
 
index ac2092a..59ff12e 100644 (file)
@@ -22,6 +22,8 @@
   USA.
 ***/
 
+#include <pulse/def.h>
+
 #include <pulsecore/idxset.h>
 
 /* Simple Implementation of a hash table. Memory management is the
@@ -35,7 +37,7 @@ typedef struct pa_hashmap pa_hashmap;
 pa_hashmap *pa_hashmap_new(pa_hash_func_t hash_func, pa_compare_func_t compare_func);
 
 /* Free the hash table. Calls the specified function for every value in the table. The function may be NULL */
-void pa_hashmap_free(pa_hashmap*, pa_free2_cb_t free_cb, void *userdata);
+void pa_hashmap_free(pa_hashmap*, pa_free_cb_t free_cb);
 
 /* Add an entry to the hashmap. Returns non-zero when the entry already exists */
 int pa_hashmap_put(pa_hashmap *h, const void *key, void *value);
@@ -46,6 +48,9 @@ void* pa_hashmap_get(pa_hashmap *h, const void *key);
 /* Returns the data of the entry while removing */
 void* pa_hashmap_remove(pa_hashmap *h, const void *key);
 
+/* If free_cb is not NULL, it's called for each entry. */
+void pa_hashmap_remove_all(pa_hashmap *h, pa_free_cb_t free_cb);
+
 /* Return the current number of entries of the hashmap */
 unsigned pa_hashmap_size(pa_hashmap *h);
 
index d9b9917..00981be 100644 (file)
@@ -23,6 +23,8 @@
 #include <config.h>
 #endif
 
+#include <pulse/xmalloc.h>
+
 #include <pulsecore/macro.h>
 
 #include "hook-list.h"
index 86ce9d2..e4b70d3 100644 (file)
@@ -22,9 +22,6 @@
   USA.
 ***/
 
-#include <pulse/xmalloc.h>
-#include <pulse/gccmacro.h>
-
 #include <pulsecore/llist.h>
 
 typedef struct pa_hook_slot pa_hook_slot;
similarity index 97%
rename from src/pulse/i18n.c
rename to src/pulsecore/i18n.c
index 7f25b20..b4f0a66 100644 (file)
 #include "i18n.h"
 
 void pa_init_i18n(void) {
-
+#ifdef ENABLE_NLS
     PA_ONCE_BEGIN {
 
         bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);
         bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
 
     } PA_ONCE_END;
+#endif
 }
similarity index 96%
rename from src/pulse/i18n.h
rename to src/pulsecore/i18n.h
index f91c0bf..b206867 100644 (file)
 ***/
 
 #include <pulse/cdecl.h>
-#include <pulse/gccmacro.h>
-#include <pulse/version.h>
 
 PA_C_DECL_BEGIN
 
+#ifdef ENABLE_NLS
+
 #if !defined(GETTEXT_PACKAGE)
 #error "Something is very wrong here, config.h needs to be included first"
 #endif
 
-#ifdef ENABLE_NLS
-
 #include <libintl.h>
 
 #define _(String) dgettext(GETTEXT_PACKAGE, String)
index 408011f..27e4980 100644 (file)
@@ -29,7 +29,6 @@
 #include <string.h>
 
 #include <pulse/xmalloc.h>
-#include <pulsecore/log.h>
 #include <pulsecore/flist.h>
 #include <pulsecore/macro.h>
 
@@ -140,18 +139,10 @@ static void remove_entry(pa_idxset *s, struct idxset_entry *e) {
     s->n_entries--;
 }
 
-void pa_idxset_free(pa_idxset *s, pa_free2_cb_t free_cb, void *userdata) {
+void pa_idxset_free(pa_idxset *s, pa_free_cb_t free_cb) {
     pa_assert(s);
 
-    while (s->iterate_list_head) {
-        void *data = s->iterate_list_head->data;
-
-        remove_entry(s, s->iterate_list_head);
-
-        if (free_cb)
-            free_cb(data, userdata);
-    }
-
+    pa_idxset_remove_all(s, free_cb);
     pa_xfree(s);
 }
 
@@ -309,6 +300,19 @@ void* pa_idxset_remove_by_data(pa_idxset*s, const void *data, uint32_t *idx) {
     return r;
 }
 
+void pa_idxset_remove_all(pa_idxset *s, pa_free_cb_t free_cb) {
+    pa_assert(s);
+
+    while (s->iterate_list_head) {
+        void *data = s->iterate_list_head->data;
+
+        remove_entry(s, s->iterate_list_head);
+
+        if (free_cb)
+            free_cb(data);
+    }
+}
+
 void* pa_idxset_rrobin(pa_idxset *s, uint32_t *idx) {
     unsigned hash;
     struct idxset_entry *e;
index d1e68c5..039e4be 100644 (file)
@@ -25,6 +25,8 @@
 
 #include <inttypes.h>
 
+#include <pulse/def.h>
+
 #include <pulsecore/macro.h>
 
 /* A combination of a set and a dynamic array. Entries are indexable
@@ -35,9 +37,6 @@
 /* A special index value denoting the invalid index. */
 #define PA_IDXSET_INVALID ((uint32_t) -1)
 
-/* Similar to pa_free_cb_t, but takes a userdata argument */
-typedef void (*pa_free2_cb_t)(void *p, void *userdata);
-
 /* Generic implementations for hash and comparison functions. Just
  * compares the pointer or calculates the hash value directly from the
  * pointer value. */
@@ -57,7 +56,7 @@ typedef struct pa_idxset pa_idxset;
 pa_idxset* pa_idxset_new(pa_hash_func_t hash_func, pa_compare_func_t compare_func);
 
 /* Free the idxset. When the idxset is not empty the specified function is called for every entry contained */
-void pa_idxset_free(pa_idxset *s, pa_free2_cb_t free_cb, void *userdata);
+void pa_idxset_free(pa_idxset *s, pa_free_cb_t free_cb);
 
 /* Store a new item in the idxset. The index of the item is returned in *idx */
 int pa_idxset_put(pa_idxset*s, void *p, uint32_t *idx);
@@ -65,7 +64,7 @@ int pa_idxset_put(pa_idxset*s, void *p, uint32_t *idx);
 /* Get the entry by its idx */
 void* pa_idxset_get_by_index(pa_idxset*s, uint32_t idx);
 
-/* Get the entry by its data. The idx is returned in *index */
+/* Get the entry by its data. The index is returned in *idx */
 void* pa_idxset_get_by_data(pa_idxset*s, const void *p, uint32_t *idx);
 
 /* Similar to pa_idxset_get_by_index(), but removes the entry from the idxset. */
@@ -74,6 +73,9 @@ void* pa_idxset_remove_by_index(pa_idxset*s, uint32_t idx);
 /* Similar to pa_idxset_get_by_data(), but removes the entry from the idxset */
 void* pa_idxset_remove_by_data(pa_idxset*s, const void *p, uint32_t *idx);
 
+/* If free_cb is not NULL, it's called for each entry. */
+void pa_idxset_remove_all(pa_idxset *s, pa_free_cb_t free_cb);
+
 /* This may be used to iterate through all entries. When called with
    an invalid index value it returns the first entry, otherwise the
    next following. The function is best called with *idx =
diff --git a/src/pulsecore/inet_ntop.h b/src/pulsecore/inet_ntop.h
deleted file mode 100644 (file)
index 7fb67b4..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef fooinet_ntophfoo
-#define fooinet_ntophfoo
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#include "winsock.h"
-
-const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
-
-#endif
diff --git a/src/pulsecore/inet_pton.c b/src/pulsecore/inet_pton.c
deleted file mode 100644 (file)
index abdfa46..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as
-  published by the Free Software Foundation; either version 2.1 of the
-  License, or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-
-#ifndef HAVE_INET_PTON
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#include "winsock.h"
-
-#include "inet_pton.h"
-
-int inet_pton(int af, const char *src, void *dst) {
-    struct in_addr *in = (struct in_addr*)dst;
-#ifdef HAVE_IPV6
-    struct in6_addr *in6 = (struct in6_addr*)dst;
-#endif
-
-    assert(src && dst);
-
-    switch (af) {
-    case AF_INET:
-        in->s_addr = inet_addr(src);
-        if (in->s_addr == INADDR_NONE)
-            return 0;
-        break;
-#ifdef HAVE_IPV6
-    case AF_INET6:
-        /* FIXME */
-#endif
-    default:
-        errno = EAFNOSUPPORT;
-        return -1;
-    }
-
-    return 1;
-}
-
-#endif /* INET_PTON */
diff --git a/src/pulsecore/inet_pton.h b/src/pulsecore/inet_pton.h
deleted file mode 100644 (file)
index 111b4a0..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef fooinet_ptonhfoo
-#define fooinet_ptonhfoo
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#include "winsock.h"
-
-int inet_pton(int af, const char *src, void *dst);
-
-#endif
index b40c981..fa3d767 100644 (file)
 #endif
 
 #include <stdlib.h>
-#include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
 
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
 #ifdef HAVE_SYS_UN_H
 #include <sys/un.h>
 #endif
 
-#include "winsock.h"
-
 #include <pulse/xmalloc.h>
 
 #include <pulsecore/core-error.h>
 #include <pulsecore/core-util.h>
+#include <pulsecore/socket.h>
 #include <pulsecore/socket-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
@@ -56,33 +51,79 @@ struct pa_iochannel {
     pa_iochannel_cb_t callback;
     void*userdata;
 
-    pa_bool_t readable;
-    pa_bool_t writable;
-    pa_bool_t hungup;
-
-    pa_bool_t no_close;
+    pa_bool_t readable:1;
+    pa_bool_t writable:1;
+    pa_bool_t hungup:1;
+    pa_bool_t no_close:1;
 
     pa_io_event* input_event, *output_event;
 };
 
-static void enable_mainloop_sources(pa_iochannel *io) {
+static void callback(pa_mainloop_api* m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata);
+
+static void delete_events(pa_iochannel *io) {
     pa_assert(io);
 
-    if (io->input_event == io->output_event && io->input_event) {
+    if (io->input_event)
+        io->mainloop->io_free(io->input_event);
+
+    if (io->output_event && io->output_event != io->input_event)
+        io->mainloop->io_free(io->output_event);
+
+    io->input_event = io->output_event = NULL;
+}
+
+static void enable_events(pa_iochannel *io) {
+    pa_assert(io);
+
+    if (io->hungup) {
+        delete_events(io);
+        return;
+    }
+
+    if (io->ifd == io->ofd && io->ifd >= 0) {
         pa_io_event_flags_t f = PA_IO_EVENT_NULL;
-        pa_assert(io->input_event);
 
         if (!io->readable)
             f |= PA_IO_EVENT_INPUT;
         if (!io->writable)
             f |= PA_IO_EVENT_OUTPUT;
 
-        io->mainloop->io_enable(io->input_event, f);
+        pa_assert(io->input_event == io->output_event);
+
+        if (f != PA_IO_EVENT_NULL) {
+            if (io->input_event)
+                io->mainloop->io_enable(io->input_event, f);
+            else
+                io->input_event = io->output_event = io->mainloop->io_new(io->mainloop, io->ifd, f, callback, io);
+        } else
+            delete_events(io);
+
     } else {
-        if (io->input_event)
-            io->mainloop->io_enable(io->input_event, io->readable ? PA_IO_EVENT_NULL : PA_IO_EVENT_INPUT);
-        if (io->output_event)
-            io->mainloop->io_enable(io->output_event, io->writable ? PA_IO_EVENT_NULL : PA_IO_EVENT_OUTPUT);
+
+        if (io->ifd >= 0) {
+            if (!io->readable) {
+                if (io->input_event)
+                    io->mainloop->io_enable(io->input_event, PA_IO_EVENT_INPUT);
+                else
+                    io->input_event = io->mainloop->io_new(io->mainloop, io->ifd, PA_IO_EVENT_INPUT, callback, io);
+            } else if (io->input_event) {
+                io->mainloop->io_free(io->input_event);
+                io->input_event = NULL;
+            }
+        }
+
+        if (io->ofd >= 0) {
+            if (!io->writable) {
+                if (io->output_event)
+                    io->mainloop->io_enable(io->output_event, PA_IO_EVENT_OUTPUT);
+                else
+                    io->output_event = io->mainloop->io_new(io->mainloop, io->ofd, PA_IO_EVENT_OUTPUT, callback, io);
+            } else if (io->input_event) {
+                io->mainloop->io_free(io->output_event);
+                io->output_event = NULL;
+            }
+        }
     }
 }
 
@@ -113,7 +154,7 @@ static void callback(pa_mainloop_api* m, pa_io_event *e, int fd, pa_io_event_fla
     }
 
     if (changed) {
-        enable_mainloop_sources(io);
+        enable_events(io);
 
         if (io->callback)
             io->callback(io, io->userdata);
@@ -126,49 +167,25 @@ pa_iochannel* pa_iochannel_new(pa_mainloop_api*m, int ifd, int ofd) {
     pa_assert(m);
     pa_assert(ifd >= 0 || ofd >= 0);
 
-    io = pa_xnew(pa_iochannel, 1);
+    io = pa_xnew0(pa_iochannel, 1);
     io->ifd = ifd;
     io->ofd = ofd;
-    io->ifd_type = io->ofd_type = 0;
     io->mainloop = m;
 
-    io->userdata = NULL;
-    io->callback = NULL;
-    io->readable = FALSE;
-    io->writable = FALSE;
-    io->hungup = FALSE;
-    io->no_close = FALSE;
-
-    io->input_event = io->output_event = NULL;
-
-    if (ifd == ofd) {
-        pa_assert(ifd >= 0);
+    if (io->ifd >= 0)
         pa_make_fd_nonblock(io->ifd);
-        io->input_event = io->output_event = m->io_new(m, ifd, PA_IO_EVENT_INPUT|PA_IO_EVENT_OUTPUT, callback, io);
-    } else {
-
-        if (ifd >= 0) {
-            pa_make_fd_nonblock(io->ifd);
-            io->input_event = m->io_new(m, ifd, PA_IO_EVENT_INPUT, callback, io);
-        }
 
-        if (ofd >= 0) {
-            pa_make_fd_nonblock(io->ofd);
-            io->output_event = m->io_new(m, ofd, PA_IO_EVENT_OUTPUT, callback, io);
-        }
-    }
+    if (io->ofd >= 0 && io->ofd != io->ifd)
+        pa_make_fd_nonblock(io->ofd);
 
+    enable_events(io);
     return io;
 }
 
 void pa_iochannel_free(pa_iochannel*io) {
     pa_assert(io);
 
-    if (io->input_event)
-        io->mainloop->io_free(io->input_event);
-
-    if (io->output_event && (io->output_event != io->input_event))
-        io->mainloop->io_free(io->output_event);
+    delete_events(io);
 
     if (!io->no_close) {
         if (io->ifd >= 0)
@@ -207,8 +224,8 @@ ssize_t pa_iochannel_write(pa_iochannel*io, const void*data, size_t l) {
     pa_assert(io->ofd >= 0);
 
     if ((r = pa_write(io->ofd, data, l, &io->ofd_type)) >= 0) {
-        io->writable = FALSE;
-        enable_mainloop_sources(io);
+        io->writable = io->hungup = FALSE;
+        enable_events(io);
     }
 
     return r;
@@ -222,8 +239,12 @@ ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l) {
     pa_assert(io->ifd >= 0);
 
     if ((r = pa_read(io->ifd, data, l, &io->ifd_type)) >= 0) {
-        io->readable = FALSE;
-        enable_mainloop_sources(io);
+
+        /* We also reset the hangup flag here to ensure that another
+         * IO callback is triggered so that we will again call into
+         * user code */
+        io->readable = io->hungup = FALSE;
+        enable_events(io);
     }
 
     return r;
@@ -232,7 +253,14 @@ ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l) {
 #ifdef HAVE_CREDS
 
 pa_bool_t pa_iochannel_creds_supported(pa_iochannel *io) {
-    struct sockaddr_un sa;
+    struct {
+        struct sockaddr sa;
+#ifdef HAVE_SYS_UN_H
+        struct sockaddr_un un;
+#endif
+        struct sockaddr_storage storage;
+    } sa;
+
     socklen_t l;
 
     pa_assert(io);
@@ -240,11 +268,10 @@ pa_bool_t pa_iochannel_creds_supported(pa_iochannel *io) {
     pa_assert(io->ofd == io->ifd);
 
     l = sizeof(sa);
+    if (getsockname(io->ifd, &sa.sa, &l) < 0)
+        return FALSE;
 
-    if (getsockname(io->ifd, (struct sockaddr*) &sa, &l) < 0)
-        return 0;
-
-    return sa.sun_family == AF_UNIX;
+    return sa.sa.sa_family == AF_UNIX;
 }
 
 int pa_iochannel_creds_enable(pa_iochannel *io) {
@@ -276,11 +303,11 @@ ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l
     pa_assert(l);
     pa_assert(io->ofd >= 0);
 
-    memset(&iov, 0, sizeof(iov));
+    pa_zero(iov);
     iov.iov_base = (void*) data;
     iov.iov_len = l;
 
-    memset(&cmsg, 0, sizeof(cmsg));
+    pa_zero(cmsg);
     cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(struct ucred));
     cmsg.hdr.cmsg_level = SOL_SOCKET;
     cmsg.hdr.cmsg_type = SCM_CREDENTIALS;
@@ -296,18 +323,15 @@ ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l
         u->gid = getgid();
     }
 
-    memset(&mh, 0, sizeof(mh));
-    mh.msg_name = NULL;
-    mh.msg_namelen = 0;
+    pa_zero(mh);
     mh.msg_iov = &iov;
     mh.msg_iovlen = 1;
     mh.msg_control = &cmsg;
     mh.msg_controllen = sizeof(cmsg);
-    mh.msg_flags = 0;
 
     if ((r = sendmsg(io->ofd, &mh, MSG_NOSIGNAL)) >= 0) {
-        io->writable = FALSE;
-        enable_mainloop_sources(io);
+        io->writable = io->hungup = FALSE;
+        enable_events(io);
     }
 
     return r;
@@ -329,25 +353,21 @@ ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, pa_cr
     pa_assert(creds);
     pa_assert(creds_valid);
 
-    memset(&iov, 0, sizeof(iov));
+    pa_zero(iov);
     iov.iov_base = data;
     iov.iov_len = l;
 
-    memset(&cmsg, 0, sizeof(cmsg));
-
-    memset(&mh, 0, sizeof(mh));
-    mh.msg_name = NULL;
-    mh.msg_namelen = 0;
+    pa_zero(cmsg);
+    pa_zero(mh);
     mh.msg_iov = &iov;
     mh.msg_iovlen = 1;
     mh.msg_control = &cmsg;
     mh.msg_controllen = sizeof(cmsg);
-    mh.msg_flags = 0;
 
     if ((r = recvmsg(io->ifd, &mh, 0)) >= 0) {
         struct cmsghdr *cmh;
 
-        *creds_valid = 0;
+        *creds_valid = FALSE;
 
         for (cmh = CMSG_FIRSTHDR(&mh); cmh; cmh = CMSG_NXTHDR(&mh, cmh)) {
 
@@ -363,8 +383,8 @@ ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, pa_cr
             }
         }
 
-        io->readable = FALSE;
-        enable_mainloop_sources(io);
+        io->readable = io->hungup = FALSE;
+        enable_events(io);
     }
 
     return r;
index 9050df9..f809f47 100644 (file)
 #include <pulsecore/macro.h>
 
 /* A wrapper around UNIX file descriptors for attaching them to the a
-   main event loop. Everytime new data may be read or be written to
+   main event loop. Every time new data may be read or be written to
    the channel a callback function is called. It is safe to destroy
    the calling iochannel object from the callback */
 
-/* When pa_iochannel_is_readable() returns non-zero, the user has to
- * call this function in a loop until it is no longer set or EOF
- * reached. Otherwise strange things may happen when an EOF is
- * reached. */
-
 typedef struct pa_iochannel pa_iochannel;
 
 /* Create a new IO channel for the specified file descriptors for
@@ -68,7 +63,7 @@ pa_bool_t pa_iochannel_is_readable(pa_iochannel*io);
 pa_bool_t pa_iochannel_is_writable(pa_iochannel*io);
 pa_bool_t pa_iochannel_is_hungup(pa_iochannel*io);
 
-/* Don't close the file descirptors when the io channel is freed. By
+/* Don't close the file descriptors when the io channel is freed. By
  * default the file descriptors are closed. */
 void pa_iochannel_set_noclose(pa_iochannel*io, pa_bool_t b);
 
@@ -79,7 +74,7 @@ void pa_iochannel_set_callback(pa_iochannel*io, pa_iochannel_cb_t callback, void
 /* In case the file descriptor is a socket, return a pretty-printed string in *s which describes the peer connected */
 void pa_iochannel_socket_peer_to_string(pa_iochannel*io, char*s, size_t l);
 
-/* Use setsockopt() to tune the recieve and send buffers of TCP sockets */
+/* Use setsockopt() to tune the receive and send buffers of TCP sockets */
 int pa_iochannel_socket_set_rcvbuf(pa_iochannel*io, size_t l);
 int pa_iochannel_socket_set_sndbuf(pa_iochannel*io, size_t l);
 
index 7afdb08..a18188d 100644 (file)
@@ -30,8 +30,9 @@
 
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/winsock.h>
+#include <pulsecore/socket.h>
 #include <pulsecore/core-error.h>
+#include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/refcnt.h>
index d973a3c..120984e 100644 (file)
   USA.
 ***/
 
+#include <pulse/gccmacro.h>
+
 #include <pulsecore/iochannel.h>
-#include <pulsecore/core-util.h>
 
 /* An ioline wraps an iochannel for line based communication. A
- * callback function is called whenever a new line has been recieved
+ * callback function is called whenever a new line has been received
  * from the client */
 
 typedef struct pa_ioline pa_ioline;
@@ -45,7 +46,7 @@ void pa_ioline_puts(pa_ioline *s, const char *c);
 /* Write a string to the channel */
 void pa_ioline_printf(pa_ioline *s, const char *format, ...) PA_GCC_PRINTF_ATTR(2,3);
 
-/* Set the callback function that is called for every recieved line */
+/* Set the callback function that is called for every received line */
 void pa_ioline_set_callback(pa_ioline*io, pa_ioline_cb_t callback, void *userdata);
 
 /* Set the callback function that is called when everything has been written */
index 312e040..5455d0e 100644 (file)
@@ -28,9 +28,6 @@
 #include <sys/types.h>
 #include <string.h>
 
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
@@ -40,9 +37,6 @@
 #ifdef HAVE_NETINET_IP_H
 #include <netinet/ip.h>
 #endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
 
 #include <pulse/xmalloc.h>
 
 #include <pulsecore/llist.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/winsock.h>
-
-#ifndef HAVE_INET_PTON
-#include "inet_pton.h"
-#endif
+#include <pulsecore/socket.h>
+#include <pulsecore/arpa-inet.h>
 
 #include "ipacl.h"
 
@@ -178,7 +169,7 @@ void pa_ip_acl_free(pa_ip_acl *acl) {
 int pa_ip_acl_check(pa_ip_acl *acl, int fd) {
     struct sockaddr_storage sa;
     struct acl_entry *e;
-    socklen_t  salen;
+    socklen_t salen;
 
     pa_assert(acl);
     pa_assert(fd >= 0);
@@ -215,7 +206,7 @@ int pa_ip_acl_check(pa_ip_acl *acl, int fd) {
                 return 1;
 #ifdef HAVE_IPV6
         } else if (e->family == AF_INET6) {
-            int i, bits ;
+            int i, bits;
             struct sockaddr_in6 *sai = (struct sockaddr_in6*) &sa;
 
             if (e->bits == 128)
index c0df793..b1d414b 100644 (file)
 #include <config.h>
 #endif
 
-#include <fcntl.h>
 #include <errno.h>
 #include <string.h>
-#include <sys/poll.h>
 #include <signal.h>
+
+#ifdef HAVE_PTHREAD
 #include <pthread.h>
+#endif
 
-#include <pulse/i18n.h>
+#include <pulse/gccmacro.h>
 #include <pulse/xmalloc.h>
 
+#include <pulsecore/i18n.h>
+#include <pulsecore/poll.h>
 #include <pulsecore/mutex.h>
 #include <pulsecore/thread.h>
 #include <pulsecore/core-util.h>
@@ -87,12 +90,9 @@ static int ref(void) {
     pa_assert(pipe_fd[0] < 0);
     pa_assert(pipe_fd[1] < 0);
 
-    if (pipe(pipe_fd) < 0)
+    if (pa_pipe_cloexec(pipe_fd) < 0)
         return -1;
 
-    pa_make_fd_cloexec(pipe_fd[0]);
-    pa_make_fd_cloexec(pipe_fd[1]);
-
     pa_make_fd_nonblock(pipe_fd[1]);
     pa_make_fd_nonblock(pipe_fd[0]);
 
@@ -161,7 +161,7 @@ static void ping(void) {
     for (;;) {
         char x = 'x';
 
-        if ((s = write(pipe_fd[1], &x, 1)) == 1)
+        if ((s = pa_write(pipe_fd[1], &x, 1, NULL)) == 1)
             break;
 
         pa_assert(s < 0);
@@ -185,10 +185,10 @@ static void wait_for_ping(void) {
     pfd.fd = pipe_fd[0];
     pfd.events = POLLIN;
 
-    if ((k = poll(&pfd, 1, -1)) != 1) {
+    if ((k = pa_poll(&pfd, 1, -1)) != 1) {
         pa_assert(k < 0);
         pa_assert(errno == EINTR);
-    } else if ((s = read(pipe_fd[0], &x, 1)) != 1) {
+    } else if ((s = pa_read(pipe_fd[0], &x, 1, NULL)) != 1) {
         pa_assert(s < 0);
         pa_assert(errno == EAGAIN);
     }
@@ -200,7 +200,7 @@ static void empty_pipe(void) {
 
     pa_assert(pipe_fd[0] >= 0);
 
-    if ((s = read(pipe_fd[0], &x, sizeof(x))) < 1) {
+    if ((s = pa_read(pipe_fd[0], &x, sizeof(x), NULL)) < 1) {
         pa_assert(s < 0);
         pa_assert(errno == EAGAIN);
     }
@@ -209,11 +209,14 @@ static void empty_pipe(void) {
 static void thread_func(void *u) {
     int fd;
     char *lf;
+
+#ifdef HAVE_PTHREAD
     sigset_t fullset;
 
     /* No signals in this thread please */
     sigfillset(&fullset);
     pthread_sigmask(SIG_BLOCK, &fullset, NULL);
+#endif
 
     if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK))) {
         pa_log_warn(_("Cannot access autospawn lock."));
@@ -246,7 +249,7 @@ finish:
 static int start_thread(void) {
 
     if (!thread)
-        if (!(thread = pa_thread_new(thread_func, NULL)))
+        if (!(thread = pa_thread_new("autospawn", thread_func, NULL)))
             return -1;
 
     return 0;
index 75b46d9..74f888d 100644 (file)
@@ -38,6 +38,7 @@
 #include <syslog.h>
 #endif
 
+#include <pulse/gccmacro.h>
 #include <pulse/rtclock.h>
 #include <pulse/utf8.h>
 #include <pulse/xmalloc.h>
 
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
-#include <pulsecore/core-rtclock.h>
 #include <pulsecore/once.h>
 #include <pulsecore/ratelimit.h>
+#include <pulsecore/thread.h>
 
 #include "log.h"
 
-#ifdef USE_DLOG
-#include <dlog.h>
-#define        DLOG_TAG        "PULSEAUDIO"
-
-#define COLOR_BLACK            30
-#define COLOR_RED              31
-#define COLOR_GREEN            32
-#define COLOR_BLUE             34
-#define COLOR_MAGENTA          35
-#define COLOR_CYAN             36
-#define COLOR_WHITE            97
-#define COLOR_B_GRAY           100
-#define COLOR_B_RED            101
-#define COLOR_B_GREEN          102
-#define COLOR_B_YELLOW         103
-#define COLOR_B_BLUE           104
-#define COLOR_B_MAGENTA        105
-#define COLOR_B_CYAN           106
-#define COLOR_REVERSE          7
-
-#endif
-
 #define ENV_LOG_SYSLOG "PULSE_LOG_SYSLOG"
 #define ENV_LOG_LEVEL "PULSE_LOG"
 #define ENV_LOG_COLORS "PULSE_LOG_COLORS"
 #define ENV_LOG_PRINT_LEVEL "PULSE_LOG_LEVEL"
 #define ENV_LOG_BACKTRACE "PULSE_LOG_BACKTRACE"
 #define ENV_LOG_BACKTRACE_SKIP "PULSE_LOG_BACKTRACE_SKIP"
+#define ENV_LOG_NO_RATELIMIT "PULSE_LOG_NO_RATE_LIMIT"
+
+#ifdef __TIZEN__
+#define ENV_LOG_DLOG_CLIENT "PULSE_LOG_DLOG_CLIENT"
+#endif
 
 static char *ident = NULL; /* in local charset format */
 static pa_log_target_t target = PA_LOG_STDERR, target_override;
@@ -90,9 +74,14 @@ static pa_bool_t target_override_set = FALSE;
 static pa_log_level_t maximum_level = PA_LOG_ERROR, maximum_level_override = PA_LOG_ERROR;
 static unsigned show_backtrace = 0, show_backtrace_override = 0, skip_backtrace = 0;
 static pa_log_flags_t flags = 0, flags_override = 0;
+static pa_bool_t no_rate_limit = FALSE;
+static int log_fd = -1;
 
 #ifdef HAVE_SYSLOG_H
 static const int level_to_syslog[] = {
+#ifdef __TIZEN_LOG__
+    [PA_LOG_VERBOSE] = LOG_DEBUG,
+#endif
     [PA_LOG_ERROR] = LOG_ERR,
     [PA_LOG_WARN] = LOG_WARNING,
     [PA_LOG_NOTICE] = LOG_NOTICE,
@@ -102,6 +91,9 @@ static const int level_to_syslog[] = {
 #endif
 
 static const char level_to_char[] = {
+#ifdef __TIZEN_LOG__
+    [PA_LOG_VERBOSE] = 'D',
+#endif
     [PA_LOG_ERROR] = 'E',
     [PA_LOG_WARN] = 'W',
     [PA_LOG_NOTICE] = 'N',
@@ -148,6 +140,15 @@ void pa_log_set_flags(pa_log_flags_t _flags, pa_log_merge_t merge) {
         flags = _flags;
 }
 
+void pa_log_set_fd(int fd) {
+    if (fd >= 0)
+        log_fd = fd;
+    else if (log_fd >= 0) {
+        pa_close(log_fd);
+        log_fd = -1;
+    }
+}
+
 void pa_log_set_show_backtrace(unsigned nlevels) {
     show_backtrace = nlevels;
 }
@@ -217,54 +218,71 @@ static char* get_backtrace(unsigned show_nframes) {
 #endif
 
 static void init_defaults(void) {
-    const char *e;
+    PA_ONCE_BEGIN {
 
-    if (!ident) {
-        char binary[256];
-        if (pa_get_binary_name(binary, sizeof(binary)))
-            pa_log_set_ident(binary);
-    }
+        const char *e;
 
-    if (getenv(ENV_LOG_SYSLOG)) {
-        target_override = PA_LOG_SYSLOG;
-        target_override_set = TRUE;
-    }
+        if (!ident) {
+            char binary[256];
+            if (pa_get_binary_name(binary, sizeof(binary)))
+                pa_log_set_ident(binary);
+        }
 
-    if ((e = getenv(ENV_LOG_LEVEL))) {
-        maximum_level_override = (pa_log_level_t) atoi(e);
+        if (getenv(ENV_LOG_SYSLOG)) {
+            target_override = PA_LOG_SYSLOG;
+            target_override_set = TRUE;
+        }
 
-        if (maximum_level_override >= PA_LOG_LEVEL_MAX)
-            maximum_level_override = PA_LOG_LEVEL_MAX-1;
-    }
+        if ((e = getenv(ENV_LOG_LEVEL))) {
+            maximum_level_override = (pa_log_level_t) atoi(e);
+
+            if (maximum_level_override >= PA_LOG_LEVEL_MAX)
+                maximum_level_override = PA_LOG_LEVEL_MAX-1;
+        }
 
-    if (getenv(ENV_LOG_COLORS))
-        flags_override |= PA_LOG_COLORS;
+#ifdef __TIZEN__
+        // usage : mmf.sh - export PULSE_LOG_DLOG_CLIENT=5
+        if(e = getenv(ENV_LOG_DLOG_CLIENT)) {
+            target_override = PA_LOG_DLOG;
+            target_override_set = TRUE;
+            maximum_level_override = atoi(e);
+            flags_override |= PA_LOG_PRINT_META;
+        }
+#endif
 
-    if (getenv(ENV_LOG_PRINT_TIME))
-        flags_override |= PA_LOG_PRINT_TIME;
+        if (getenv(ENV_LOG_COLORS))
+            flags_override |= PA_LOG_COLORS;
 
-    if (getenv(ENV_LOG_PRINT_FILE))
-        flags_override |= PA_LOG_PRINT_FILE;
+        if (getenv(ENV_LOG_PRINT_TIME))
+            flags_override |= PA_LOG_PRINT_TIME;
 
-    if (getenv(ENV_LOG_PRINT_META))
-        flags_override |= PA_LOG_PRINT_META;
+        if (getenv(ENV_LOG_PRINT_FILE))
+            flags_override |= PA_LOG_PRINT_FILE;
 
-    if (getenv(ENV_LOG_PRINT_LEVEL))
-        flags_override |= PA_LOG_PRINT_LEVEL;
+        if (getenv(ENV_LOG_PRINT_META))
+            flags_override |= PA_LOG_PRINT_META;
 
-    if ((e = getenv(ENV_LOG_BACKTRACE))) {
-        show_backtrace_override = (unsigned) atoi(e);
+        if (getenv(ENV_LOG_PRINT_LEVEL))
+            flags_override |= PA_LOG_PRINT_LEVEL;
 
-        if (show_backtrace_override <= 0)
-            show_backtrace_override = 0;
-    }
+        if ((e = getenv(ENV_LOG_BACKTRACE))) {
+            show_backtrace_override = (unsigned) atoi(e);
 
-    if ((e = getenv(ENV_LOG_BACKTRACE_SKIP))) {
-        skip_backtrace = (unsigned) atoi(e);
+            if (show_backtrace_override <= 0)
+                show_backtrace_override = 0;
+        }
 
-        if (skip_backtrace <= 0)
-            skip_backtrace = 0;
-    }
+        if ((e = getenv(ENV_LOG_BACKTRACE_SKIP))) {
+            skip_backtrace = (unsigned) atoi(e);
+
+            if (skip_backtrace <= 0)
+                skip_backtrace = 0;
+        }
+
+        if (getenv(ENV_LOG_NO_RATELIMIT))
+            no_rate_limit = TRUE;
+
+    } PA_ONCE_END;
 }
 
 void pa_log_levelv_meta(
@@ -290,9 +308,7 @@ void pa_log_levelv_meta(
     pa_assert(level < PA_LOG_LEVEL_MAX);
     pa_assert(format);
 
-    PA_ONCE_BEGIN {
-        init_defaults();
-    } PA_ONCE_END;
+    init_defaults();
 
     _target = target_override_set ? target_override : target;
     _maximum_level = PA_MAX(maximum_level, maximum_level_override);
@@ -307,9 +323,14 @@ void pa_log_levelv_meta(
     pa_vsnprintf(text, sizeof(text), format, ap);
 
     if ((_flags & PA_LOG_PRINT_META) && file && line > 0 && func)
-        pa_snprintf(location, sizeof(location), "[%s:%i %s()] ", file, line, func);
+#ifdef USE_DLOG
+        if (_target == PA_LOG_DLOG)
+            pa_snprintf(location, sizeof(location), "%s: %s(%i) > [%s] ", pa_path_get_filename(file), func, line, pa_thread_get_name(pa_thread_self()));
+        else
+#endif
+            pa_snprintf(location, sizeof(location), "[%s][%s:%i %s()] ", pa_thread_get_name(pa_thread_self()), file, line, func);
     else if ((_flags & (PA_LOG_PRINT_META|PA_LOG_PRINT_FILE)) && file)
-        pa_snprintf(location, sizeof(location), "%s: ", pa_path_get_filename(file));
+        pa_snprintf(location, sizeof(location), "[%s] %s: ", pa_thread_get_name(pa_thread_self()), pa_path_get_filename(file));
     else
         location[0] = 0;
 
@@ -389,6 +410,9 @@ void pa_log_levelv_meta(
                     fprintf(stderr, "%s%c: %s%s%s%s%s%s\n", timestamp, level_to_char[level], location, prefix, t, grey, pa_strempty(bt), suffix);
                 else
                     fprintf(stderr, "%s%s%s%s%s%s%s\n", timestamp, location, prefix, t, grey, pa_strempty(bt), suffix);
+#ifdef OS_IS_WIN32
+                fflush(stderr);
+#endif
 
                 pa_xfree(local_t);
 
@@ -422,22 +446,25 @@ void pa_log_levelv_meta(
 
                 switch (level)
                 {
-                                       case PA_LOG_DEBUG:
-                                               SLOG (LOG_DEBUG, DLOG_TAG, "%s%s%s%s",  timestamp, location, t, pa_strempty(bt));
-                                               break;
-                                       case PA_LOG_INFO:
-                                       case PA_LOG_NOTICE:     // no notice category in dlog, use info instead.
-                                               SLOG (LOG_INFO, DLOG_TAG, "%s%s%s%s", timestamp, location, t, pa_strempty(bt));
-                                               break;
-                                       case PA_LOG_WARN:
-                                               SLOG (LOG_WARN, DLOG_TAG, "%s%s%s%s", timestamp, location, t, pa_strempty(bt));
-                                               break;
-                                       case PA_LOG_ERROR:
-                                               SLOG (LOG_ERROR, DLOG_TAG, "%s%s%s%s", timestamp, location, t, pa_strempty(bt));
-                                               break;
-                                       default:
-                                               SLOG (LOG_DEBUG, DLOG_TAG, "%s%s%s%s", timestamp, location, t, pa_strempty(bt));
-                                               break;
+#ifdef __TIZEN_LOG__
+                    case PA_LOG_VERBOSE:
+#endif
+                    case PA_LOG_DEBUG:
+                        print_system_log(DLOG_DEBUG, DLOG_TAG, "%s%s%s%s", location, timestamp, t, pa_strempty(bt));
+                        break;
+                    case PA_LOG_INFO:
+                    case PA_LOG_NOTICE:        // no notice category in dlog, use info instead.
+                        print_system_log(DLOG_INFO, DLOG_TAG, "%s%s%s%s", location, timestamp, t, pa_strempty(bt));
+                        break;
+                    case PA_LOG_WARN:
+                        print_system_log(DLOG_WARN, DLOG_TAG, "%s%s%s%s", location, timestamp, t, pa_strempty(bt));
+                        break;
+                    case PA_LOG_ERROR:
+                        print_system_log(DLOG_ERROR, DLOG_TAG, "%s%s%s%s", location, timestamp, t, pa_strempty(bt));
+                        break;
+                    default:
+                        print_system_log(DLOG_DEBUG, DLOG_TAG, "%s%s%s%s", location, timestamp, t, pa_strempty(bt));
+                        break;
                 }
 
                 pa_xfree(local_t);
@@ -445,44 +472,66 @@ void pa_log_levelv_meta(
                 break;
             }
             case PA_LOG_DLOG_COLOR: {
-                               char *local_t;
-
-                               openlog(ident, LOG_PID, LOG_USER);
-
-                               if ((local_t = pa_utf8_to_locale(t)))
-                                       t = local_t;
-
-                               switch (level)
-                               {
-                                       case PA_LOG_DEBUG:
-                                               SLOG (LOG_DEBUG, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_GREEN, timestamp, location, t, pa_strempty(bt));
-                                               break;
-                                       case PA_LOG_INFO:
-                                       case PA_LOG_NOTICE:     // no notice category in dlog, use info instead.
-                                               SLOG (LOG_INFO, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_BLUE, timestamp, location, t, pa_strempty(bt));
-                                               break;
-                                       case PA_LOG_WARN:
-                                               SLOG (LOG_WARN, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_MAGENTA, timestamp, location, t, pa_strempty(bt));
-                                               break;
-                                       case PA_LOG_ERROR:
-                                               SLOG (LOG_ERROR, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_RED, timestamp, location, t, pa_strempty(bt));
-                                               break;
-                                       default:
-                                               SLOG (LOG_DEBUG, DLOG_TAG, "%s%s%s%s", timestamp, location, t, pa_strempty(bt));
-                                               break;
-                               }
-
-                               pa_xfree(local_t);
-
-                               break;
-                       }
+                char *local_t;
+
+                openlog(ident, LOG_PID, LOG_USER);
+
+                if ((local_t = pa_utf8_to_locale(t)))
+                    t = local_t;
+
+                switch (level)
+                {
+#ifdef __TIZEN_LOG__
+                    case PA_LOG_VERBOSE:
+#endif
+                    case PA_LOG_DEBUG:
+                        print_system_log(DLOG_DEBUG, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_GREEN, location, timestamp, t, pa_strempty(bt));
+                        break;
+                    case PA_LOG_INFO:
+                    case PA_LOG_NOTICE:        // no notice category in dlog, use info instead.
+                        print_system_log(DLOG_INFO, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_BLUE, location, timestamp, t, pa_strempty(bt));
+                        break;
+                    case PA_LOG_WARN:
+                        print_system_log(DLOG_WARN, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_MAGENTA, location, timestamp, t, pa_strempty(bt));
+                        break;
+                    case PA_LOG_ERROR:
+                        print_system_log(DLOG_ERROR, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_RED, location, timestamp, t, pa_strempty(bt));
+                        break;
+                    default:
+                        print_system_log(DLOG_DEBUG, DLOG_TAG, "\033[%dm%s%s%s%s\033[0m", COLOR_GREEN, location, timestamp, t, pa_strempty(bt));
+                        break;
+                }
+
+                pa_xfree(local_t);
+
+                break;
+            }
 
 #endif
-          case PA_LOG_NULL:
+
+            case PA_LOG_FD: {
+                if (log_fd >= 0) {
+                    char metadata[256];
+
+                    pa_snprintf(metadata, sizeof(metadata), "\n%c %s %s", level_to_char[level], timestamp, location);
+
+                    if ((write(log_fd, metadata, strlen(metadata)) < 0) || (write(log_fd, t, strlen(t)) < 0)) {
+                        saved_errno = errno;
+                        pa_log_set_fd(-1);
+                        fprintf(stderr, "%s\n", "Error writing logs to a file descriptor. Redirect log messages to console.");
+                        fprintf(stderr, "%s %s\n", metadata, t);
+                        pa_log_set_target(PA_LOG_STDERR);
+                    }
+                }
+
+                break;
+            }
+            case PA_LOG_NULL:
             default:
                 break;
         }
     }
+
     pa_xfree(bt);
     errno = saved_errno;
 }
@@ -512,9 +561,14 @@ void pa_log_level(pa_log_level_t level, const char *format, ...) {
     va_end(ap);
 }
 
-pa_bool_t pa_log_ratelimit(void) {
+pa_bool_t pa_log_ratelimit(pa_log_level_t level) {
     /* Not more than 10 messages every 5s */
     static PA_DEFINE_RATELIMIT(ratelimit, 5 * PA_USEC_PER_SEC, 10);
 
-    return pa_ratelimit_test(&ratelimit);
+    init_defaults();
+
+    if (no_rate_limit)
+        return TRUE;
+
+    return pa_ratelimit_test(&ratelimit, level);
 }
index 4393dde..22e7b21 100644 (file)
 #include <pulsecore/macro.h>
 #include <pulse/gccmacro.h>
 
+#ifdef USE_DLOG
+
+#include <dlog.h>
+#ifndef DLOG_TAG
+#define DLOG_TAG    "PULSEAUDIO"
+#endif
+#define USE_DLOG_DIRECT
+
+#define COLOR_BLACK     30
+#define COLOR_RED       31
+#define COLOR_GREEN     32
+#define COLOR_BLUE      34
+#define COLOR_MAGENTA   35
+#define COLOR_CYAN      36
+#define COLOR_WHITE     97
+#define COLOR_B_GRAY    100
+#define COLOR_B_RED     101
+#define COLOR_B_GREEN   102
+#define COLOR_B_YELLOW  103
+#define COLOR_B_BLUE    104
+#define COLOR_B_MAGENTA 105
+#define COLOR_B_CYAN    106
+#define COLOR_REVERSE   7
+
+#endif /* USE_DLOG */
+
 /* A simple logging subsystem */
 
 /* Where to log to */
@@ -40,6 +66,7 @@ typedef enum pa_log_target {
     PA_LOG_DLOG_COLOR,
 #endif
     PA_LOG_NULL,    /* to /dev/null */
+    PA_LOG_FD,      /* to a file descriptor, e.g. a char device */
     PA_LOG_TARGET_MAX
 } pa_log_target_t;
 
@@ -49,6 +76,9 @@ typedef enum pa_log_level {
     PA_LOG_NOTICE = 2,    /* Notice messages */
     PA_LOG_INFO   = 3,    /* Info messages */
     PA_LOG_DEBUG  = 4,    /* debug message */
+#ifdef __TIZEN_LOG__
+    PA_LOG_VERBOSE = 5,
+#endif
     PA_LOG_LEVEL_MAX
 } pa_log_level_t;
 
@@ -56,7 +86,7 @@ typedef enum pa_log_flags {
     PA_LOG_COLORS      = 0x01, /* Show colorful output */
     PA_LOG_PRINT_TIME  = 0x02, /* Show time */
     PA_LOG_PRINT_FILE  = 0x04, /* Show source file */
-    PA_LOG_PRINT_META  = 0x08, /* Show extended locaton information */
+    PA_LOG_PRINT_META  = 0x08, /* Show extended location information */
     PA_LOG_PRINT_LEVEL = 0x10, /* Show log level prefix */
 } pa_log_flags_t;
 
@@ -78,6 +108,10 @@ void pa_log_set_level(pa_log_level_t l);
 /* Set flags */
 void pa_log_set_flags(pa_log_flags_t flags, pa_log_merge_t merge);
 
+/* Set the file descriptor of the logging device.
+   Daemon conf is in charge of opening this device */
+void pa_log_set_fd(int fd);
+
 /* Enable backtrace */
 void pa_log_set_show_backtrace(unsigned nlevels);
 
@@ -112,6 +146,15 @@ void pa_log_levelv(
 
 /* ISO varargs available */
 
+#ifdef __TIZEN_LOG__
+#define pa_log_debug_verbose(...)   pa_log_level_meta(PA_LOG_VERBOSE,  __FILE__, __LINE__, __func__, __VA_ARGS__)
+#define pa_log_info_verbose(...)    pa_log_level_meta(PA_LOG_VERBOSE,  __FILE__, __LINE__, __func__, __VA_ARGS__)
+#define pa_log_info_debug(...)      pa_log_level_meta(PA_LOG_DEBUG,  __FILE__, __LINE__, __func__, __VA_ARGS__)
+#else
+#define pa_log_debug_verbose(...)   pa_log_level_meta(PA_LOG_DEBUG,  __FILE__, __LINE__, __func__, __VA_ARGS__)
+#define pa_log_info_verbose(...)    pa_log_level_meta(PA_LOG_INFO,  __FILE__, __LINE__, __func__, __VA_ARGS__)
+#define pa_log_info_debug(...)      pa_log_level_meta(PA_LOG_INFO,  __FILE__, __LINE__, __func__, __VA_ARGS__)
+#endif
 #define pa_log_debug(...)  pa_log_level_meta(PA_LOG_DEBUG,  __FILE__, __LINE__, __func__, __VA_ARGS__)
 #define pa_log_info(...)   pa_log_level_meta(PA_LOG_INFO,   __FILE__, __LINE__, __func__, __VA_ARGS__)
 #define pa_log_notice(...) pa_log_level_meta(PA_LOG_NOTICE, __FILE__, __LINE__, __func__, __VA_ARGS__)
@@ -129,6 +172,15 @@ PA_GCC_UNUSED static void pa_log_##suffix(const char *format, ...) { \
     va_end(ap); \
 }
 
+#ifdef __TIZEN_LOG__
+LOG_FUNC(debug_verbose, PA_LOG_VERBOSE)
+LOG_FUNC(info_verbose, PA_LOG_VERBOSE)
+LOG_FUNC(info_debug, PA_LOG_DEBUG)
+#else
+LOG_FUNC(debug_verbose, PA_LOG_DEBUG)
+LOG_FUNC(info_verbose, PA_LOG_INFO)
+LOG_FUNC(info_debug, PA_LOG_INFO)
+#endif
 LOG_FUNC(debug, PA_LOG_DEBUG)
 LOG_FUNC(info, PA_LOG_INFO)
 LOG_FUNC(notice, PA_LOG_NOTICE)
@@ -139,6 +191,6 @@ LOG_FUNC(error, PA_LOG_ERROR)
 
 #define pa_log pa_log_error
 
-pa_bool_t pa_log_ratelimit(void);
+pa_bool_t pa_log_ratelimit(pa_log_level_t level);
 
 #endif
index be200ca..bdb5a5d 100644 (file)
@@ -28,7 +28,6 @@
 #include <ctype.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/util.h>
 
 #include <pulsecore/core-util.h>
 #include <pulsecore/macro.h>
@@ -42,7 +41,7 @@ pa_void_func_t pa_load_sym(lt_dlhandle handle, const char *module, const char *s
     pa_assert(handle);
     pa_assert(symbol);
 
-    *(void**) &f = lt_dlsym(handle, symbol);
+    f = (pa_void_func_t) lt_dlsym(handle, symbol);
 
     if (f)
         return f;
@@ -59,7 +58,7 @@ pa_void_func_t pa_load_sym(lt_dlhandle handle, const char *module, const char *s
         if (!isalnum(*c))
             *c = '_';
 
-    *(void**) &f = lt_dlsym(handle, sn);
+    f = (pa_void_func_t) lt_dlsym(handle, sn);
     pa_xfree(sn);
 
     return f;
index 9a5a267..c6d7d56 100644 (file)
@@ -30,8 +30,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-
-#include <pulse/gccmacro.h>
+#include <stdbool.h>
 
 #ifndef PACKAGE
 #error "Please include config.h before including this file!"
@@ -86,6 +85,10 @@ static inline size_t PA_PAGE_ALIGN(size_t l) {
     #define PA_DECLARE_ALIGNED(n,t,v)      t v
 #endif
 
+#ifdef __GNUC__
+#define typeof __typeof__
+#endif
+
 /* The users of PA_MIN and PA_MAX, PA_CLAMP, PA_ROUND_UP should be
  * aware that these macros on non-GCC executed code with side effects
  * twice. It is thus considered misuse to use code with side effects
@@ -176,7 +179,7 @@ static inline size_t PA_PAGE_ALIGN(size_t l) {
 
 /* This type is not intended to be used in exported APIs! Use classic "int" there! */
 #ifdef HAVE_STD_BOOL
-typedef _Bool pa_bool_t;
+typedef bool pa_bool_t;
 #else
 typedef int pa_bool_t;
 #endif
index a03d5ae..f5363eb 100644 (file)
@@ -182,7 +182,7 @@ int pa_mcalign_pop(pa_mcalign *m, pa_memchunk *c) {
         if (m->current.length == 0)
             pa_memblock_unref(m->current.memblock);
         else {
-            /* Move the raimainder to leftover */
+            /* Move the remainder to leftover */
             pa_assert(m->current.length < m->base && !m->leftover.memblock);
 
             m->leftover = m->current;
index e82eb00..e897643 100644 (file)
@@ -70,7 +70,7 @@ void pa_mcalign_free(pa_mcalign *m);
  * has to free the memchunk by himself. */
 void pa_mcalign_push(pa_mcalign *m, const pa_memchunk *c);
 
-/* Pop a new memchunk from the aligner. Returns 0 when sucessful,
+/* Pop a new memchunk from the aligner. Returns 0 when successful,
  * nonzero otherwise. */
 int pa_mcalign_pop(pa_mcalign *m, pa_memchunk *c);
 
index f38b17c..5b77df3 100644 (file)
 #include <pulsecore/log.h>
 #include <pulsecore/hashmap.h>
 #include <pulsecore/semaphore.h>
+#include <pulsecore/mutex.h>
 #include <pulsecore/macro.h>
+#include <pulsecore/refcnt.h>
+#include <pulsecore/llist.h>
 #include <pulsecore/flist.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/memtrap.h>
@@ -82,7 +85,7 @@ struct pa_memblock {
             pa_free_cb_t free_cb;
         } user;
 
-        struct  {
+        struct {
             uint32_t id;
             pa_memimport_segment *segment;
         } imported;
@@ -226,7 +229,7 @@ static pa_memblock *memblock_new_appended(pa_mempool *p, size_t length) {
     /* If -1 is passed as length we choose the size for the caller. */
 
     if (length == (size_t) -1)
-        length = p->block_size - PA_ALIGN(sizeof(pa_memblock));
+        length = pa_mempool_block_size_max(p);
 
     b = pa_xmalloc(PA_ALIGN(sizeof(pa_memblock)) + length);
     PA_REFCNT_INIT(b);
@@ -258,7 +261,7 @@ static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) {
             slot = (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (p->block_size * (size_t) idx));
 
         if (!slot) {
-            if (pa_log_ratelimit())
+            if (pa_log_ratelimit(PA_LOG_DEBUG))
                 pa_log_debug("Pool full");
             pa_atomic_inc(&p->stat.n_pool_full);
             return NULL;
@@ -456,6 +459,13 @@ void* pa_memblock_acquire(pa_memblock *b) {
     return pa_atomic_ptr_load(&b->data);
 }
 
+/* No lock necessary */
+void *pa_memblock_acquire_chunk(const pa_memchunk *c) {
+    pa_assert(c);
+
+    return (uint8_t *) pa_memblock_acquire(c->memblock) + c->index;
+}
+
 /* No lock necessary, in corner cases locks by its own */
 void pa_memblock_release(pa_memblock *b) {
     int r;
@@ -515,8 +525,8 @@ static void memblock_free(pa_memblock *b) {
 
         case PA_MEMBLOCK_APPENDED:
 
-            /* We could attached it unused_memblocks, but that would
-             * probably waste some considerable memory */
+            /* We could attach it to unused_memblocks, but that would
+             * probably waste some considerable amount of memory */
             pa_xfree(b);
             break;
 
@@ -531,9 +541,7 @@ static void memblock_free(pa_memblock *b) {
 
             pa_mutex_lock(import->mutex);
 
-            pa_assert_se(pa_hashmap_remove(
-                                 import->blocks,
-                                 PA_UINT32_TO_PTR(b->per_type.imported.id)));
+            pa_assert_se(pa_hashmap_remove(import->blocks, PA_UINT32_TO_PTR(b->per_type.imported.id)));
 
             pa_assert(segment->n_blocks >= 1);
             if (-- segment->n_blocks <= 0)
@@ -693,9 +701,7 @@ static void memblock_replace_import(pa_memblock *b) {
 
     pa_mutex_lock(import->mutex);
 
-    pa_assert_se(pa_hashmap_remove(
-                         import->blocks,
-                         PA_UINT32_TO_PTR(b->per_type.imported.id)));
+    pa_assert_se(pa_hashmap_remove(import->blocks, PA_UINT32_TO_PTR(b->per_type.imported.id)));
 
     memblock_make_local(b);
 
@@ -712,9 +718,6 @@ pa_mempool* pa_mempool_new(pa_bool_t shared, size_t size) {
 
     p = pa_xnew(pa_mempool, 1);
 
-    p->mutex = pa_mutex_new(TRUE, TRUE);
-    p->semaphore = pa_semaphore_new(0);
-
     p->block_size = PA_PAGE_ALIGN(PA_MEMPOOL_SLOT_SIZE);
     if (p->block_size < PA_PAGE_SIZE)
         p->block_size = PA_PAGE_SIZE;
@@ -746,6 +749,9 @@ pa_mempool* pa_mempool_new(pa_bool_t shared, size_t size) {
     PA_LLIST_HEAD_INIT(pa_memimport, p->imports);
     PA_LLIST_HEAD_INIT(pa_memexport, p->exports);
 
+    p->mutex = pa_mutex_new(TRUE, TRUE);
+    p->semaphore = pa_semaphore_new(0);
+
     p->free_slots = pa_flist_new(p->n_blocks);
 
     return p;
@@ -874,7 +880,7 @@ pa_bool_t pa_mempool_is_shared(pa_mempool *p) {
     return !!p->memory.shared;
 }
 
-/* For recieving blocks from other nodes */
+/* For receiving blocks from other nodes */
 pa_memimport* pa_memimport_new(pa_mempool *p, pa_memimport_release_cb_t cb, void *userdata) {
     pa_memimport *i;
 
@@ -958,8 +964,8 @@ void pa_memimport_free(pa_memimport *i) {
 
     pa_mutex_unlock(i->pool->mutex);
 
-    pa_hashmap_free(i->blocks, NULL, NULL);
-    pa_hashmap_free(i->segments, NULL, NULL);
+    pa_hashmap_free(i->blocks, NULL);
+    pa_hashmap_free(i->segments, NULL);
 
     pa_mutex_free(i->mutex);
 
index b1eab2a..84c5d05 100644 (file)
   USA.
 ***/
 
+typedef struct pa_memblock pa_memblock;
+
 #include <sys/types.h>
 #include <inttypes.h>
 
 #include <pulse/def.h>
-#include <pulsecore/llist.h>
-#include <pulsecore/refcnt.h>
 #include <pulsecore/atomic.h>
+#include <pulsecore/memchunk.h>
 
 /* A pa_memblock is a reference counted memory block. PulseAudio
- * passed references to pa_memblocks around instead of copying
+ * passes references to pa_memblocks around instead of copying
  * data. See pa_memchunk for a structure that describes parts of
  * memory blocks. */
 
 /* The type of memory this block points to */
 typedef enum pa_memblock_type {
     PA_MEMBLOCK_POOL,             /* Memory is part of the memory pool */
-    PA_MEMBLOCK_POOL_EXTERNAL,    /* Data memory is part of the memory pool but the pa_memblock structure itself not */
-    PA_MEMBLOCK_APPENDED,         /* the data is appended to the memory block */
+    PA_MEMBLOCK_POOL_EXTERNAL,    /* Data memory is part of the memory pool but the pa_memblock structure itself is not */
+    PA_MEMBLOCK_APPENDED,         /* The data is appended to the memory block */
     PA_MEMBLOCK_USER,             /* User supplied memory, to be freed with free_cb */
-    PA_MEMBLOCK_FIXED,            /* data is a pointer to fixed memory that needs not to be freed */
+    PA_MEMBLOCK_FIXED,            /* Data is a pointer to fixed memory that needs not to be freed */
     PA_MEMBLOCK_IMPORTED,         /* Memory is imported from another process via shm */
     PA_MEMBLOCK_TYPE_MAX
 } pa_memblock_type_t;
 
-typedef struct pa_memblock pa_memblock;
 typedef struct pa_mempool pa_mempool;
 typedef struct pa_mempool_stat pa_mempool_stat;
 typedef struct pa_memimport_segment pa_memimport_segment;
@@ -110,7 +110,9 @@ pa_bool_t pa_memblock_ref_is_one(pa_memblock *b);
 void pa_memblock_set_is_silence(pa_memblock *b, pa_bool_t v);
 
 void* pa_memblock_acquire(pa_memblock *b);
+void *pa_memblock_acquire_chunk(const pa_memchunk *c);
 void pa_memblock_release(pa_memblock *b);
+
 size_t pa_memblock_get_length(pa_memblock *b);
 pa_mempool * pa_memblock_get_pool(pa_memblock *b);
 
@@ -125,7 +127,7 @@ int pa_mempool_get_shm_id(pa_mempool *p, uint32_t *id);
 pa_bool_t pa_mempool_is_shared(pa_mempool *p);
 size_t pa_mempool_block_size_max(pa_mempool *p);
 
-/* For recieving blocks from other nodes */
+/* For receiving blocks from other nodes */
 pa_memimport* pa_memimport_new(pa_mempool *p, pa_memimport_release_cb_t cb, void *userdata);
 void pa_memimport_free(pa_memimport *i);
 pa_memblock* pa_memimport_get(pa_memimport *i, uint32_t block_id, uint32_t shm_id, size_t offset, size_t size);
index c784048..ac87d7b 100644 (file)
@@ -23,8 +23,6 @@
 #include <config.h>
 #endif
 
-#include <sys/time.h>
-#include <time.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -38,6 +36,8 @@
 
 #include "memblockq.h"
 
+/* #define MEMBLOCKQ_DEBUG */
+
 struct list_item {
     struct list_item *next, *prev;
     int64_t index;
@@ -56,13 +56,16 @@ struct pa_memblockq {
     pa_memchunk silence;
     pa_mcalign *mcalign;
     int64_t missing, requested;
+    char *name;
+    pa_sample_spec sample_spec;
 };
 
 pa_memblockq* pa_memblockq_new(
+        const char *name,
         int64_t idx,
         size_t maxlength,
         size_t tlength,
-        size_t base,
+        const pa_sample_spec *sample_spec,
         size_t prebuf,
         size_t minreq,
         size_t maxrewind,
@@ -70,21 +73,19 @@ pa_memblockq* pa_memblockq_new(
 
     pa_memblockq* bq;
 
-    pa_assert(base > 0);
+    pa_assert(sample_spec);
+    pa_assert(name);
 
-    bq = pa_xnew(pa_memblockq, 1);
-    bq->blocks = bq->blocks_tail = NULL;
-    bq->current_read = bq->current_write = NULL;
-    bq->n_blocks = 0;
+    bq = pa_xnew0(pa_memblockq, 1);
+    bq->name = pa_xstrdup(name);
 
-    bq->base = base;
+    bq->sample_spec = *sample_spec;
+    bq->base = pa_frame_size(sample_spec);
     bq->read_index = bq->write_index = idx;
 
-    pa_log_debug("memblockq requested: maxlength=%lu, tlength=%lu, base=%lu, prebuf=%lu, minreq=%lu maxrewind=%lu",
-                 (unsigned long) maxlength, (unsigned long) tlength, (unsigned long) base, (unsigned long) prebuf, (unsigned long) minreq, (unsigned long) maxrewind);
+    pa_log_debug_verbose("memblockq requested: maxlength=%lu, tlength=%lu, base=%lu, prebuf=%lu, minreq=%lu maxrewind=%lu",
+                 (unsigned long) maxlength, (unsigned long) tlength, (unsigned long) bq->base, (unsigned long) prebuf, (unsigned long) minreq, (unsigned long) maxrewind);
 
-    bq->missing = bq->requested = 0;
-    bq->maxlength = bq->tlength = bq->prebuf = bq->minreq = bq->maxrewind = 0;
     bq->in_prebuf = TRUE;
 
     pa_memblockq_set_maxlength(bq, maxlength);
@@ -93,14 +94,13 @@ pa_memblockq* pa_memblockq_new(
     pa_memblockq_set_prebuf(bq, prebuf);
     pa_memblockq_set_maxrewind(bq, maxrewind);
 
-    pa_log_debug("memblockq sanitized: maxlength=%lu, tlength=%lu, base=%lu, prebuf=%lu, minreq=%lu maxrewind=%lu",
+    pa_log_debug_verbose("memblockq sanitized: maxlength=%lu, tlength=%lu, base=%lu, prebuf=%lu, minreq=%lu maxrewind=%lu",
                  (unsigned long) bq->maxlength, (unsigned long) bq->tlength, (unsigned long) bq->base, (unsigned long) bq->prebuf, (unsigned long) bq->minreq, (unsigned long) bq->maxrewind);
 
     if (silence) {
         bq->silence = *silence;
         pa_memblock_ref(bq->silence.memblock);
-    } else
-        pa_memchunk_reset(&bq->silence);
+    }
 
     bq->mcalign = pa_mcalign_new(bq->base);
 
@@ -118,6 +118,7 @@ void pa_memblockq_free(pa_memblockq* bq) {
     if (bq->mcalign)
         pa_mcalign_free(bq->mcalign);
 
+    pa_xfree(bq->name);
     pa_xfree(bq);
 }
 
@@ -257,7 +258,9 @@ static void write_index_changed(pa_memblockq *bq, int64_t old_write_index, pa_bo
     else
         bq->missing -= delta;
 
-    /* pa_log("pushed/seeked %lli: requested counter at %lli, account=%i", (long long) delta, (long long) bq->requested, account); */
+#ifdef MEMBLOCKQ_DEBUG
+     pa_log_debug("[%s] pushed/seeked %lli: requested counter at %lli, account=%i", bq->name, (long long) delta, (long long) bq->requested, account);
+#endif
 }
 
 static void read_index_changed(pa_memblockq *bq, int64_t old_read_index) {
@@ -268,7 +271,9 @@ static void read_index_changed(pa_memblockq *bq, int64_t old_read_index) {
     delta = bq->read_index - old_read_index;
     bq->missing += delta;
 
-    /* pa_log("popped %lli: missing counter at %lli", (long long) delta, (long long) bq->missing); */
+#ifdef MEMBLOCKQ_DEBUG
+    pa_log_debug("[%s] popped %lli: missing counter at %lli", bq->name, (long long) delta, (long long) bq->missing);
+#endif
 }
 
 int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {
@@ -282,8 +287,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {
     pa_assert(uchunk->length > 0);
     pa_assert(uchunk->index + uchunk->length <= pa_memblock_get_length(uchunk->memblock));
 
-    if (uchunk->length % bq->base)
-        return -1;
+    pa_assert_se(uchunk->length % bq->base == 0);
 
     if (!can_push(bq, uchunk->length))
         return -1;
@@ -338,7 +342,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {
                 struct list_item *p;
                 size_t d;
 
-                /* Create a new list entry for the end of thie memchunk */
+                /* Create a new list entry for the end of the memchunk */
                 if (!(p = pa_flist_pop(PA_STATIC_FLIST_GET(list_items))))
                     p = pa_xnew(struct list_item, 1);
 
@@ -378,8 +382,8 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {
             size_t d;
 
             pa_assert(bq->write_index + (int64_t)chunk.length > q->index &&
-                   bq->write_index + (int64_t)chunk.length < q->index + (int64_t)q->chunk.length &&
-                   bq->write_index < q->index);
+                      bq->write_index + (int64_t)chunk.length < q->index + (int64_t)q->chunk.length &&
+                      bq->write_index < q->index);
 
             /* The job overwrites the current entry at the end, so let's drop the beginning of this entry */
 
@@ -827,7 +831,9 @@ size_t pa_memblockq_pop_missing(pa_memblockq *bq) {
 
     pa_assert(bq);
 
-/*     pa_log("pop: %lli", bq->missing); */
+#ifdef MEMBLOCKQ_DEBUG
+    pa_log_debug("[%s] pop: %lli", bq->name, (long long) bq->missing);
+#endif
 
     if (bq->missing <= 0)
         return 0;
@@ -837,7 +843,9 @@ size_t pa_memblockq_pop_missing(pa_memblockq *bq) {
     bq->requested += bq->missing;
     bq->missing = 0;
 
-    /* pa_log("sent %lli: request counter is at %lli", (long long) l, (long long) bq->requested); */
+#ifdef MEMBLOCKQ_DEBUG
+    pa_log_debug("[%s] sent %lli: request counter is at %lli", bq->name, (long long) l, (long long) bq->requested);
+#endif
 
     return l;
 }
@@ -921,8 +929,8 @@ void pa_memblockq_apply_attr(pa_memblockq *bq, const pa_buffer_attr *a) {
 
     pa_memblockq_set_maxlength(bq, a->maxlength);
     pa_memblockq_set_tlength(bq, a->tlength);
-    pa_memblockq_set_prebuf(bq, a->prebuf);
     pa_memblockq_set_minreq(bq, a->minreq);
+    pa_memblockq_set_prebuf(bq, a->prebuf);
 }
 
 void pa_memblockq_get_attr(pa_memblockq *bq, pa_buffer_attr *a) {
index 3775c3f..88906ba 100644 (file)
@@ -40,6 +40,8 @@ typedef struct pa_memblockq pa_memblockq;
 
 /* Parameters:
 
+   - name:      name for debugging purposes
+
    - idx:       start value for both read and write index
 
    - maxlength: maximum length of queue. If more data is pushed into
@@ -47,9 +49,9 @@ typedef struct pa_memblockq pa_memblockq;
 
    - tlength:   the target length of the queue. Pass 0 for the default.
 
-   - base:      a base value for all metrics. Only multiples of this value
-                are popped from the queue or should be pushed into
-                it. Must not be 0.
+   - ss:        Sample spec describing the queue contents. Only multiples
+                of the frame size as implied by the sample spec are
+                allowed into the queue or can be popped from it.
 
    - prebuf:    If the queue runs empty wait until this many bytes are in
                 queue again before passing the first byte out. If set
@@ -62,13 +64,14 @@ typedef struct pa_memblockq pa_memblockq;
 
    - maxrewind: how many bytes of history to keep in the queue
 
-   - silence:   return this memchunk when reading unitialized data
+   - silence:   return this memchunk when reading uninitialized data
 */
 pa_memblockq* pa_memblockq_new(
+        const char *name,
         int64_t idx,
         size_t maxlength,
         size_t tlength,
-        size_t base,
+        const pa_sample_spec *sample_spec,
         size_t prebuf,
         size_t minreq,
         size_t maxrewind,
@@ -161,8 +164,8 @@ int64_t pa_memblockq_get_write_index(pa_memblockq *bq);
 /* Change metrics. Always call in order. */
 void pa_memblockq_set_maxlength(pa_memblockq *memblockq, size_t maxlength); /* might modify tlength, prebuf, minreq too */
 void pa_memblockq_set_tlength(pa_memblockq *memblockq, size_t tlength); /* might modify minreq, too */
-void pa_memblockq_set_prebuf(pa_memblockq *memblockq, size_t prebuf); /* might modify minreq, too */
-void pa_memblockq_set_minreq(pa_memblockq *memblockq, size_t minreq);
+void pa_memblockq_set_minreq(pa_memblockq *memblockq, size_t minreq); /* might modify prebuf, too */
+void pa_memblockq_set_prebuf(pa_memblockq *memblockq, size_t prebuf);
 void pa_memblockq_set_maxrewind(pa_memblockq *memblockq, size_t maxrewind); /* Set the maximum history size */
 void pa_memblockq_set_silence(pa_memblockq *memblockq, pa_memchunk *silence);
 
@@ -170,7 +173,7 @@ void pa_memblockq_set_silence(pa_memblockq *memblockq, pa_memchunk *silence);
 void pa_memblockq_apply_attr(pa_memblockq *memblockq, const pa_buffer_attr *a);
 void pa_memblockq_get_attr(pa_memblockq *bq, pa_buffer_attr *a);
 
-/* Call pa_memchunk_willneed() for every chunk in the queue from the current read pointer to the end */
+/* Call pa_memchunk_will_need() for every chunk in the queue from the current read pointer to the end */
 void pa_memblockq_willneed(pa_memblockq *bq);
 
 /* Check whether the memblockq is completely empty, i.e. no data
index 0bbf859..5f03597 100644 (file)
@@ -28,7 +28,6 @@
 #include <string.h>
 #include <errno.h>
 
-#include <pulse/xmalloc.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
 
@@ -84,7 +83,7 @@ pa_memchunk *pa_memchunk_will_need(const pa_memchunk *c) {
     /* A version of pa_memblock_will_need() that works on memchunks
      * instead of memblocks */
 
-    p = (uint8_t*) pa_memblock_acquire(c->memblock) + c->index;
+    p = pa_memblock_acquire_chunk(c);
     pa_will_need(p, c->length);
     pa_memblock_release(c->memblock);
 
@@ -110,3 +109,12 @@ pa_memchunk* pa_memchunk_memcpy(pa_memchunk *dst, pa_memchunk *src) {
 
     return dst;
 }
+
+pa_bool_t pa_memchunk_isset(pa_memchunk *chunk) {
+    assert(chunk);
+
+    return
+        chunk->memblock ||
+        chunk->index > 0 ||
+        chunk->length > 0;
+}
index 9458f4f..922ffaa 100644 (file)
   USA.
 ***/
 
+typedef struct pa_memchunk pa_memchunk;
+
 #include <pulsecore/memblock.h>
 
 /* A memchunk describes a part of a memblock. In contrast to the memblock, a
  * memchunk is not allocated dynamically or reference counted, instead
  * it is usually stored on the stack and copied around */
 
-typedef struct pa_memchunk {
+struct pa_memchunk {
     pa_memblock *memblock;
     size_t index, length;
-} pa_memchunk;
+};
 
 /* Make a memchunk writable, i.e. make sure that the caller may have
- * exclusive access to the memblock and it is not read_only. If needed
+ * exclusive access to the memblock and it is not read-only. If needed
  * the memblock in the structure is replaced by a copy. If min is not
  * 0 it is made sure that the returned memblock is at least of the
  * specified size, i.e. is enlarged if necessary. */
 pa_memchunk* pa_memchunk_make_writable(pa_memchunk *c, size_t min);
 
-/* Invalidate a memchunk. This does not free the cotaining memblock,
+/* Invalidate a memchunk. This does not free the containing memblock,
  * but sets all members to zero. */
 pa_memchunk* pa_memchunk_reset(pa_memchunk *c);
 
@@ -50,4 +52,7 @@ pa_memchunk *pa_memchunk_will_need(const pa_memchunk *c);
 /* Copy the data in the src memchunk to the dst memchunk */
 pa_memchunk* pa_memchunk_memcpy(pa_memchunk *dst, pa_memchunk *src);
 
+/* Return TRUE if any field is set != 0 */
+pa_bool_t pa_memchunk_isset(pa_memchunk *c);
+
 #endif
index 4fc1821..4236934 100644 (file)
 #endif
 
 #include <signal.h>
+
+#ifdef HAVE_SYS_MMAN_H
 #include <sys/mman.h>
+#endif
 
 /* This is deprecated on glibc but is still used by FreeBSD */
 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
@@ -64,8 +67,10 @@ pa_bool_t pa_memtrap_is_good(pa_memtrap *m) {
     return !pa_atomic_load(&m->bad);
 }
 
+#ifdef HAVE_SIGACTION
 static void sigsafe_error(const char *s) {
-    (void) write(STDERR_FILENO, s, strlen(s));
+    size_t ret PA_GCC_UNUSED;
+    ret = write(STDERR_FILENO, s, strlen(s));
 }
 
 static void signal_handler(int sig, siginfo_t* si, void *data) {
@@ -102,6 +107,7 @@ fail:
     sigsafe_error("Failed to handle SIGBUS.\n");
     abort();
 }
+#endif
 
 static void memtrap_link(pa_memtrap *m, unsigned j) {
     pa_assert(m);
@@ -221,6 +227,7 @@ unlock:
 }
 
 void pa_memtrap_install(void) {
+#ifdef HAVE_SIGACTION
     struct sigaction sa;
 
     allocate_aupdate();
@@ -230,4 +237,5 @@ void pa_memtrap_install(void) {
     sa.sa_flags = SA_RESTART|SA_SIGINFO;
 
     pa_assert_se(sigaction(SIGBUS, &sa, NULL) == 0);
+#endif
 }
index b9fe944..09ce00b 100644 (file)
@@ -145,6 +145,7 @@ void pa_sample_spec_mimefy(pa_sample_spec *ss, pa_channel_map *cm) {
 
 char *pa_sample_spec_to_mime_type(const pa_sample_spec *ss, const pa_channel_map *cm) {
     pa_assert(pa_channel_map_compatible(cm, ss));
+    pa_assert(pa_sample_spec_valid(ss));
 
     if (!pa_sample_spec_is_mime(ss, cm))
         return NULL;
@@ -168,8 +169,6 @@ char *pa_sample_spec_to_mime_type(const pa_sample_spec *ss, const pa_channel_map
         default:
             pa_assert_not_reached();
     }
-
-    pa_assert(pa_sample_spec_valid(ss));
 }
 
 char *pa_sample_spec_to_mime_type_mimefy(const pa_sample_spec *_ss, const pa_channel_map *_cm) {
index db77379..0a1d892 100644 (file)
   USA.
 ***/
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #include <pulsecore/macro.h>
 #include <pulse/sample.h>
 #include <pulse/channelmap.h>
diff --git a/src/pulsecore/mix.c b/src/pulsecore/mix.c
new file mode 100644 (file)
index 0000000..aacf4e1
--- /dev/null
@@ -0,0 +1,852 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+  Copyright 2013 Peter Meerwald <pmeerw@pmeerw.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+
+#include <pulsecore/sample-util.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/g711.h>
+#include <pulsecore/endianmacros.h>
+
+#include "mix.h"
+
+#define VOLUME_PADDING 32
+
+static void calc_linear_integer_volume(int32_t linear[], const pa_cvolume *volume) {
+    unsigned channel, nchannels, padding;
+
+    pa_assert(linear);
+    pa_assert(volume);
+
+    nchannels = volume->channels;
+
+    for (channel = 0; channel < nchannels; channel++)
+        linear[channel] = (int32_t) lrint(pa_sw_volume_to_linear(volume->values[channel]) * 0x10000);
+
+    for (padding = 0; padding < VOLUME_PADDING; padding++, channel++)
+        linear[channel] = linear[padding];
+}
+
+static void calc_linear_float_volume(float linear[], const pa_cvolume *volume) {
+    unsigned channel, nchannels, padding;
+
+    pa_assert(linear);
+    pa_assert(volume);
+
+    nchannels = volume->channels;
+
+    for (channel = 0; channel < nchannels; channel++)
+        linear[channel] = (float) pa_sw_volume_to_linear(volume->values[channel]);
+
+    for (padding = 0; padding < VOLUME_PADDING; padding++, channel++)
+        linear[channel] = linear[padding];
+}
+
+static void calc_linear_integer_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec) {
+    unsigned k, channel;
+    float linear[PA_CHANNELS_MAX + VOLUME_PADDING];
+
+    pa_assert(streams);
+    pa_assert(spec);
+    pa_assert(volume);
+
+    calc_linear_float_volume(linear, volume);
+
+    for (k = 0; k < nstreams; k++) {
+
+        for (channel = 0; channel < spec->channels; channel++) {
+            pa_mix_info *m = streams + k;
+            m->linear[channel].i = (int32_t) lrint(pa_sw_volume_to_linear(m->volume.values[channel]) * linear[channel] * 0x10000);
+        }
+    }
+}
+
+static void calc_linear_float_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec) {
+    unsigned k, channel;
+    float linear[PA_CHANNELS_MAX + VOLUME_PADDING];
+
+    pa_assert(streams);
+    pa_assert(spec);
+    pa_assert(volume);
+
+    calc_linear_float_volume(linear, volume);
+
+    for (k = 0; k < nstreams; k++) {
+
+        for (channel = 0; channel < spec->channels; channel++) {
+            pa_mix_info *m = streams + k;
+            m->linear[channel].f = (float) (pa_sw_volume_to_linear(m->volume.values[channel]) * linear[channel]);
+        }
+    }
+}
+
+typedef void (*pa_calc_stream_volumes_func_t) (pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec);
+
+static const pa_calc_stream_volumes_func_t calc_stream_volumes_table[] = {
+  [PA_SAMPLE_U8]        = (pa_calc_stream_volumes_func_t) calc_linear_integer_stream_volumes,
+  [PA_SAMPLE_ALAW]      = (pa_calc_stream_volumes_func_t) calc_linear_integer_stream_volumes,
+  [PA_SAMPLE_ULAW]      = (pa_calc_stream_volumes_func_t) calc_linear_integer_stream_volumes,
+  [PA_SAMPLE_S16LE]     = (pa_calc_stream_volumes_func_t) calc_linear_integer_stream_volumes,
+  [PA_SAMPLE_S16BE]     = (pa_calc_stream_volumes_func_t) calc_linear_integer_stream_volumes,
+  [PA_SAMPLE_FLOAT32LE] = (pa_calc_stream_volumes_func_t) calc_linear_float_stream_volumes,
+  [PA_SAMPLE_FLOAT32BE] = (pa_calc_stream_volumes_func_t) calc_linear_float_stream_volumes,
+  [PA_SAMPLE_S32LE]     = (pa_calc_stream_volumes_func_t) calc_linear_integer_stream_volumes,
+  [PA_SAMPLE_S32BE]     = (pa_calc_stream_volumes_func_t) calc_linear_integer_stream_volumes,
+  [PA_SAMPLE_S24LE]     = (pa_calc_stream_volumes_func_t) calc_linear_integer_stream_volumes,
+  [PA_SAMPLE_S24BE]     = (pa_calc_stream_volumes_func_t) calc_linear_integer_stream_volumes,
+  [PA_SAMPLE_S24_32LE]  = (pa_calc_stream_volumes_func_t) calc_linear_integer_stream_volumes,
+  [PA_SAMPLE_S24_32BE]  = (pa_calc_stream_volumes_func_t) calc_linear_integer_stream_volumes
+};
+
+/* special case: mix 2 s16ne streams, 1 channel each */
+static void pa_mix2_ch1_s16ne(pa_mix_info streams[], int16_t *data, unsigned length) {
+    const int16_t *ptr0 = streams[0].ptr;
+    const int16_t *ptr1 = streams[1].ptr;
+
+    const int32_t cv0 = streams[0].linear[0].i;
+    const int32_t cv1 = streams[1].linear[0].i;
+
+    length /= sizeof(int16_t);
+
+    for (; length > 0; length--) {
+        int32_t sum;
+
+        sum = pa_mult_s16_volume(*ptr0++, cv0);
+        sum += pa_mult_s16_volume(*ptr1++, cv1);
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
+        *data++ = sum;
+    }
+}
+
+/* special case: mix 2 s16ne streams, 2 channels each */
+static void pa_mix2_ch2_s16ne(pa_mix_info streams[], int16_t *data, unsigned length) {
+    const int16_t *ptr0 = streams[0].ptr;
+    const int16_t *ptr1 = streams[1].ptr;
+
+    length /= sizeof(int16_t) * 2;
+
+    for (; length > 0; length--) {
+        int32_t sum;
+
+        sum = pa_mult_s16_volume(*ptr0++, streams[0].linear[0].i);
+        sum += pa_mult_s16_volume(*ptr1++, streams[1].linear[0].i);
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
+        *data++ = sum;
+
+        sum = pa_mult_s16_volume(*ptr0++, streams[0].linear[1].i);
+        sum += pa_mult_s16_volume(*ptr1++, streams[1].linear[1].i);
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
+        *data++ = sum;
+    }
+}
+
+/* special case: mix 2 s16ne streams */
+static void pa_mix2_s16ne(pa_mix_info streams[], unsigned channels, int16_t *data, unsigned length) {
+    const int16_t *ptr0 = streams[0].ptr;
+    const int16_t *ptr1 = streams[1].ptr;
+    unsigned channel = 0;
+
+    length /= sizeof(int16_t);
+
+    for (; length > 0; length--) {
+        int32_t sum;
+
+        sum = pa_mult_s16_volume(*ptr0++, streams[0].linear[channel].i);
+        sum += pa_mult_s16_volume(*ptr1++, streams[1].linear[channel].i);
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
+        *data++ = sum;
+
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
+}
+
+/* special case: mix s16ne streams, 2 channels each */
+static void pa_mix_ch2_s16ne(pa_mix_info streams[], unsigned nstreams, int16_t *data, unsigned length) {
+
+    length /= sizeof(int16_t) * 2;
+
+    for (; length > 0; length--) {
+        int32_t sum0 = 0, sum1 = 0;
+        unsigned i;
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            int32_t cv0 = m->linear[0].i;
+            int32_t cv1 = m->linear[1].i;
+
+            sum0 += pa_mult_s16_volume(*((int16_t*) m->ptr), cv0);
+            m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
+
+            sum1 += pa_mult_s16_volume(*((int16_t*) m->ptr), cv1);
+            m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
+        }
+
+        *data++ = PA_CLAMP_UNLIKELY(sum0, -0x8000, 0x7FFF);
+        *data++ = PA_CLAMP_UNLIKELY(sum1, -0x8000, 0x7FFF);
+    }
+}
+
+static void pa_mix_generic_s16ne(pa_mix_info streams[], unsigned nstreams, unsigned channels, int16_t *data, unsigned length) {
+    unsigned channel = 0;
+
+    length /= sizeof(int16_t);
+
+    for (; length > 0; length--) {
+        int32_t sum = 0;
+        unsigned i;
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            int32_t cv = m->linear[channel].i;
+
+            if (PA_LIKELY(cv > 0))
+                sum += pa_mult_s16_volume(*((int16_t*) m->ptr), cv);
+            m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
+        }
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
+        *data++ = sum;
+
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
+}
+
+static void pa_mix_s16ne_c(pa_mix_info streams[], unsigned nstreams, unsigned channels, int16_t *data, unsigned length) {
+    if (nstreams == 2 && channels == 1)
+        pa_mix2_ch1_s16ne(streams, data, length);
+    else if (nstreams == 2 && channels == 2)
+        pa_mix2_ch2_s16ne(streams, data, length);
+    else if (nstreams == 2)
+        pa_mix2_s16ne(streams, channels, data, length);
+    else if (channels == 2)
+        pa_mix_ch2_s16ne(streams, nstreams, data, length);
+    else
+        pa_mix_generic_s16ne(streams, nstreams, channels, data, length);
+}
+
+static void pa_mix_s16re_c(pa_mix_info streams[], unsigned nstreams, unsigned channels, int16_t *data, unsigned length) {
+    unsigned channel = 0;
+
+    length /= sizeof(int16_t);
+
+    for (; length > 0; length--, data++) {
+        int32_t sum = 0;
+        unsigned i;
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            int32_t cv = m->linear[channel].i;
+
+            if (PA_LIKELY(cv > 0))
+                sum += pa_mult_s16_volume(PA_INT16_SWAP(*((int16_t*) m->ptr)), cv);
+            m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
+        }
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
+        *data = PA_INT16_SWAP((int16_t) sum);
+
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
+}
+
+static void pa_mix_s32ne_c(pa_mix_info streams[], unsigned nstreams, unsigned channels, int32_t *data, unsigned length) {
+    unsigned channel = 0;
+
+    length /= sizeof(int32_t);
+
+    for (; length > 0; length--, data++) {
+        int64_t sum = 0;
+        unsigned i;
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            int32_t cv = m->linear[channel].i;
+            int64_t v;
+
+            if (PA_LIKELY(cv > 0)) {
+                v = *((int32_t*) m->ptr);
+                v = (v * cv) >> 16;
+                sum += v;
+            }
+            m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
+        }
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
+        *data = (int32_t) sum;
+
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
+}
+
+static void pa_mix_s32re_c(pa_mix_info streams[], unsigned nstreams, unsigned channels, int32_t *data, unsigned length) {
+    unsigned channel = 0;
+
+    length /= sizeof(int32_t);
+
+    for (; length > 0; length--, data++) {
+        int64_t sum = 0;
+        unsigned i;
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            int32_t cv = m->linear[channel].i;
+            int64_t v;
+
+            if (PA_LIKELY(cv > 0)) {
+                v = PA_INT32_SWAP(*((int32_t*) m->ptr));
+                v = (v * cv) >> 16;
+                sum += v;
+            }
+            m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
+        }
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
+        *data = PA_INT32_SWAP((int32_t) sum);
+
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
+}
+
+static void pa_mix_s24ne_c(pa_mix_info streams[], unsigned nstreams, unsigned channels, uint8_t *data, unsigned length) {
+    unsigned channel = 0;
+
+    for (; length > 0; length -= 3, data += 3) {
+        int64_t sum = 0;
+        unsigned i;
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            int32_t cv = m->linear[channel].i;
+            int64_t v;
+
+            if (PA_LIKELY(cv > 0)) {
+                v = (int32_t) (PA_READ24NE(m->ptr) << 8);
+                v = (v * cv) >> 16;
+                sum += v;
+            }
+            m->ptr = (uint8_t*) m->ptr + 3;
+        }
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
+        PA_WRITE24NE(data, ((uint32_t) sum) >> 8);
+
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
+}
+
+static void pa_mix_s24re_c(pa_mix_info streams[], unsigned nstreams, unsigned channels, uint8_t *data, unsigned length) {
+    unsigned channel = 0;
+
+    for (; length > 0; length -= 3, data += 3) {
+        int64_t sum = 0;
+        unsigned i;
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            int32_t cv = m->linear[channel].i;
+            int64_t v;
+
+            if (PA_LIKELY(cv > 0)) {
+                v = (int32_t) (PA_READ24RE(m->ptr) << 8);
+                v = (v * cv) >> 16;
+                sum += v;
+            }
+            m->ptr = (uint8_t*) m->ptr + 3;
+        }
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
+        PA_WRITE24RE(data, ((uint32_t) sum) >> 8);
+
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
+}
+
+static void pa_mix_s24_32ne_c(pa_mix_info streams[], unsigned nstreams, unsigned channels, uint32_t *data, unsigned length) {
+    unsigned channel = 0;
+
+    length /= sizeof(uint32_t);
+
+    for (; length > 0; length--, data++) {
+        int64_t sum = 0;
+        unsigned i;
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            int32_t cv = m->linear[channel].i;
+            int64_t v;
+
+            if (PA_LIKELY(cv > 0)) {
+                v = (int32_t) (*((uint32_t*)m->ptr) << 8);
+                v = (v * cv) >> 16;
+                sum += v;
+            }
+            m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
+        }
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
+        *data = ((uint32_t) (int32_t) sum) >> 8;
+
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
+}
+
+static void pa_mix_s24_32re_c(pa_mix_info streams[], unsigned nstreams, unsigned channels, uint32_t *data, unsigned length) {
+    unsigned channel = 0;
+
+    length /= sizeof(uint32_t);
+
+    for (; length > 0; length--, data++) {
+        int64_t sum = 0;
+        unsigned i;
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            int32_t cv = m->linear[channel].i;
+            int64_t v;
+
+            if (PA_LIKELY(cv > 0)) {
+                v = (int32_t) (PA_UINT32_SWAP(*((uint32_t*) m->ptr)) << 8);
+                v = (v * cv) >> 16;
+                sum += v;
+            }
+            m->ptr = (uint8_t*) m->ptr + 3;
+        }
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
+        *data = PA_INT32_SWAP(((uint32_t) (int32_t) sum) >> 8);
+
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
+}
+
+static void pa_mix_u8_c(pa_mix_info streams[], unsigned nstreams, unsigned channels, uint8_t *data, unsigned length) {
+    unsigned channel = 0;
+
+    length /= sizeof(uint8_t);
+
+    for (; length > 0; length--, data++) {
+        int32_t sum = 0;
+        unsigned i;
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            int32_t v, cv = m->linear[channel].i;
+
+            if (PA_LIKELY(cv > 0)) {
+                v = (int32_t) *((uint8_t*) m->ptr) - 0x80;
+                v = (v * cv) >> 16;
+                sum += v;
+            }
+            m->ptr = (uint8_t*) m->ptr + 1;
+        }
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x80, 0x7F);
+        *data = (uint8_t) (sum + 0x80);
+
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
+}
+
+static void pa_mix_ulaw_c(pa_mix_info streams[], unsigned nstreams, unsigned channels, uint8_t *data, unsigned length) {
+    unsigned channel = 0;
+
+    length /= sizeof(uint8_t);
+
+    for (; length > 0; length--, data++) {
+        int32_t sum = 0;
+        unsigned i;
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            int32_t cv = m->linear[channel].i;
+
+            if (PA_LIKELY(cv > 0))
+                sum += pa_mult_s16_volume(st_ulaw2linear16(*((uint8_t*) m->ptr)), cv);
+            m->ptr = (uint8_t*) m->ptr + 1;
+        }
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
+        *data = (uint8_t) st_14linear2ulaw((int16_t) sum >> 2);
+
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
+}
+
+static void pa_mix_alaw_c(pa_mix_info streams[], unsigned nstreams, unsigned channels, uint8_t *data, unsigned length) {
+    unsigned channel = 0;
+
+    length /= sizeof(uint8_t);
+
+    for (; length > 0; length--, data++) {
+        int32_t sum = 0;
+        unsigned i;
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            int32_t cv = m->linear[channel].i;
+
+            if (PA_LIKELY(cv > 0))
+                sum += pa_mult_s16_volume(st_alaw2linear16(*((uint8_t*) m->ptr)), cv);
+            m->ptr = (uint8_t*) m->ptr + 1;
+        }
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
+        *data = (uint8_t) st_13linear2alaw((int16_t) sum >> 3);
+
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
+}
+
+static void pa_mix_float32ne_c(pa_mix_info streams[], unsigned nstreams, unsigned channels, float *data, unsigned length) {
+    unsigned channel = 0;
+
+    length /= sizeof(float);
+
+    for (; length > 0; length--, data++) {
+        float sum = 0;
+        unsigned i;
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            float v, cv = m->linear[channel].f;
+
+            if (PA_LIKELY(cv > 0)) {
+                v = *((float*) m->ptr);
+                v *= cv;
+                sum += v;
+            }
+            m->ptr = (uint8_t*) m->ptr + sizeof(float);
+        }
+
+        *data = sum;
+
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
+}
+
+static void pa_mix_float32re_c(pa_mix_info streams[], unsigned nstreams, unsigned channels, float *data, unsigned length) {
+    unsigned channel = 0;
+
+    length /= sizeof(float);
+
+    for (; length > 0; length--, data++) {
+        float sum = 0;
+        unsigned i;
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            float v, cv = m->linear[channel].f;
+
+            if (PA_LIKELY(cv > 0)) {
+                v = PA_FLOAT32_SWAP(*(float*) m->ptr);
+                v *= cv;
+                sum += v;
+            }
+            m->ptr = (uint8_t*) m->ptr + sizeof(float);
+        }
+
+        *data = PA_FLOAT32_SWAP(sum);
+
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
+}
+
+static pa_do_mix_func_t do_mix_table[] = {
+    [PA_SAMPLE_U8]        = (pa_do_mix_func_t) pa_mix_u8_c,
+    [PA_SAMPLE_ALAW]      = (pa_do_mix_func_t) pa_mix_alaw_c,
+    [PA_SAMPLE_ULAW]      = (pa_do_mix_func_t) pa_mix_ulaw_c,
+    [PA_SAMPLE_S16NE]     = (pa_do_mix_func_t) pa_mix_s16ne_c,
+    [PA_SAMPLE_S16RE]     = (pa_do_mix_func_t) pa_mix_s16re_c,
+    [PA_SAMPLE_FLOAT32NE] = (pa_do_mix_func_t) pa_mix_float32ne_c,
+    [PA_SAMPLE_FLOAT32RE] = (pa_do_mix_func_t) pa_mix_float32re_c,
+    [PA_SAMPLE_S32NE]     = (pa_do_mix_func_t) pa_mix_s32ne_c,
+    [PA_SAMPLE_S32RE]     = (pa_do_mix_func_t) pa_mix_s32re_c,
+    [PA_SAMPLE_S24NE]     = (pa_do_mix_func_t) pa_mix_s24ne_c,
+    [PA_SAMPLE_S24RE]     = (pa_do_mix_func_t) pa_mix_s24re_c,
+    [PA_SAMPLE_S24_32NE]  = (pa_do_mix_func_t) pa_mix_s24_32ne_c,
+    [PA_SAMPLE_S24_32RE]  = (pa_do_mix_func_t) pa_mix_s24_32re_c
+};
+
+size_t pa_mix(
+        pa_mix_info streams[],
+        unsigned nstreams,
+        void *data,
+        size_t length,
+        const pa_sample_spec *spec,
+        const pa_cvolume *volume,
+        pa_bool_t mute) {
+
+    pa_cvolume full_volume;
+    unsigned k;
+
+    pa_assert(streams);
+    pa_assert(data);
+    pa_assert(length);
+    pa_assert(spec);
+
+    if (!volume)
+        volume = pa_cvolume_reset(&full_volume, spec->channels);
+
+    if (mute || pa_cvolume_is_muted(volume) || nstreams <= 0) {
+        pa_silence_memory(data, length, spec);
+        return length;
+    }
+
+    for (k = 0; k < nstreams; k++) {
+        streams[k].ptr = pa_memblock_acquire_chunk(&streams[k].chunk);
+        if (length > streams[k].chunk.length)
+            length = streams[k].chunk.length;
+    }
+
+    calc_stream_volumes_table[spec->format](streams, nstreams, volume, spec);
+    do_mix_table[spec->format](streams, nstreams, spec->channels, data, length);
+
+    for (k = 0; k < nstreams; k++)
+        pa_memblock_release(streams[k].chunk.memblock);
+
+    return length;
+}
+
+pa_do_mix_func_t pa_get_mix_func(pa_sample_format_t f) {
+    pa_assert(f >= 0);
+    pa_assert(f < PA_SAMPLE_MAX);
+
+    return do_mix_table[f];
+}
+
+void pa_set_mix_func(pa_sample_format_t f, pa_do_mix_func_t func) {
+    pa_assert(f >= 0);
+    pa_assert(f < PA_SAMPLE_MAX);
+
+    do_mix_table[f] = func;
+}
+
+typedef union {
+  float f;
+  uint32_t i;
+} volume_val;
+
+typedef void (*pa_calc_volume_func_t) (void *volumes, const pa_cvolume *volume);
+
+static const pa_calc_volume_func_t calc_volume_table[] = {
+  [PA_SAMPLE_U8]        = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_ALAW]      = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_ULAW]      = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_S16LE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_S16BE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_FLOAT32LE] = (pa_calc_volume_func_t) calc_linear_float_volume,
+  [PA_SAMPLE_FLOAT32BE] = (pa_calc_volume_func_t) calc_linear_float_volume,
+  [PA_SAMPLE_S32LE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_S32BE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_S24LE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_S24BE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_S24_32LE]  = (pa_calc_volume_func_t) calc_linear_integer_volume,
+  [PA_SAMPLE_S24_32BE]  = (pa_calc_volume_func_t) calc_linear_integer_volume
+};
+
+void pa_volume_memchunk(
+        pa_memchunk*c,
+        const pa_sample_spec *spec,
+        const pa_cvolume *volume) {
+
+    void *ptr;
+    volume_val linear[PA_CHANNELS_MAX + VOLUME_PADDING];
+    pa_do_volume_func_t do_volume;
+#ifdef PA_EXT_USE_VOLUME_FADING
+    pa_bool_t is_fading = FALSE;
+    pa_cvolume_fading_info *f = volume->fading_info;
+#endif
+
+    pa_assert(c);
+    pa_assert(spec);
+    pa_assert(pa_sample_spec_valid(spec));
+    pa_assert(pa_frame_aligned(c->length, spec));
+    pa_assert(volume);
+#ifdef PA_EXT_USE_VOLUME_FADING
+    is_fading = pa_cvolume_fading_valid(volume) && (volume->fading_info->remain_frames > 0);
+#endif
+
+    if (pa_memblock_is_silence(c->memblock))
+        return;
+
+    if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_NORM))
+        return;
+
+    if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_MUTED)
+#ifdef PA_EXT_USE_VOLUME_FADING
+        && (!is_fading)
+#endif
+    ) {
+        pa_silence_memchunk(c, spec);
+        return;
+    }
+
+    do_volume = pa_get_volume_func(spec->format);
+    pa_assert(do_volume);
+
+#ifdef PA_EXT_USE_VOLUME_FADING
+    ptr = (uint8_t*) pa_memblock_acquire(c->memblock) + c->index;
+
+    if (is_fading) {
+        size_t length = c->length;
+        unsigned channel;
+        pa_cvolume cur_volume;
+        pa_volume_t fading_step[PA_CHANNELS_MAX];
+        size_t operation_count, operation_size = PA_VOLUME_FADING_OPERATION_FRAMES * pa_frame_size(spec);
+        size_t remain_size, fading_pre_size, fading_size, fading_post_size;
+        pa_bool_t increase[PA_CHANNELS_MAX];
+#ifdef PA_EXT_CHECK_VOLUME_FADING_TIME
+        struct timeval start, finish;
+
+        pa_gettimeofday(&start);
+#endif
+
+        remain_size = f->remain_frames * pa_frame_size(spec);
+        cur_volume.channels = volume->channels;
+        for (channel = 0; channel < volume->channels; channel++) {
+            cur_volume.values[channel] = f->cur_values[channel];
+            if (f->dst_values[channel] > f->cur_values[channel])
+                increase[channel] = TRUE;
+            else
+                increase[channel] = FALSE;
+        }
+
+        pa_log_debug_verbose("fading length:%ld remain:%ld cur:%d dst:%d", c->length, f->remain_frames, f->cur_values[0], f->dst_values[0]);
+
+        /* pre fading */
+        fading_pre_size = PA_MIN(length, remain_size % operation_size);
+        if (fading_pre_size > 0) {
+            calc_volume_table[spec->format] ((void *)linear, &cur_volume);
+            do_volume (ptr, (void *)linear, spec->channels, fading_pre_size);
+
+            ptr = (uint8_t*) ptr + fading_pre_size;
+            length -= fading_pre_size;
+            remain_size -= fading_pre_size;
+        }
+
+        if (remain_size > 0 && length > 0) {
+            void *ptr_end;
+
+            fading_size = PA_MIN(length, remain_size);
+            operation_count = fading_size / operation_size;
+            fading_post_size = fading_size % operation_size;
+            ptr_end = (uint8_t*) ptr + operation_count * operation_size;
+
+            for (channel = 0; channel < volume->channels; channel++) {
+                if (increase[channel])
+                    fading_step[channel] = (f->dst_values[channel] - cur_volume.values[channel]) / (remain_size / operation_size);
+                else
+                    fading_step[channel] = (cur_volume.values[channel] - f->dst_values[channel]) / (remain_size / operation_size);
+            }
+
+            for (; ptr < ptr_end; ptr = (uint8_t*) ptr + operation_size) {
+                for (channel = 0; channel < volume->channels; channel++) {
+                    if (increase[channel])
+                        cur_volume.values[channel] += fading_step[channel];
+                    else
+                        cur_volume.values[channel] -= fading_step[channel];
+                }
+                calc_volume_table[spec->format] ((void *)linear, &cur_volume);
+                do_volume (ptr, (void *)linear, spec->channels, operation_size);
+            }
+
+            length -= operation_count * operation_size;
+            remain_size -= operation_count * operation_size;
+
+            /* post fading */
+            if (fading_post_size > 0) {
+                for (channel = 0; channel < volume->channels; channel++) {
+                    if (increase[channel])
+                        cur_volume.values[channel] += fading_step[channel];
+                    else
+                        cur_volume.values[channel] -= fading_step[channel];
+                }
+
+                calc_volume_table[spec->format] ((void *)linear, &cur_volume);
+                do_volume (ptr, (void *)linear, spec->channels, fading_post_size);
+
+                length -= fading_post_size;
+                remain_size -= fading_post_size;
+            }
+
+        }
+
+        if (remain_size > 0) {
+            for (channel = 0; channel < volume->channels; channel++)
+                f->cur_values[channel] = cur_volume.values[channel];
+            f->remain_frames = remain_size / pa_frame_size(spec);
+        } else {
+            for (channel = 0; channel < volume->channels; channel++)
+                cur_volume.values[channel] = f->dst_values[channel];
+            f->remain_frames = 0;
+        }
+
+        /* fading is finished */
+        if (length > 0) {
+            if (pa_cvolume_channels_equal_to(&cur_volume, PA_VOLUME_MUTED)) {
+                pa_silence_memory(ptr, length, spec);
+            } else {
+                calc_volume_table[spec->format] ((void *)linear, &cur_volume);
+                do_volume (ptr, (void *)linear, spec->channels, length);
+            }
+        }
+#ifdef PA_EXT_CHECK_VOLUME_FADING_TIME
+        pa_gettimeofday(&finish);
+
+        pa_log_info("fading %ld bytes in %ld usec", (c->length - length), pa_timeval_diff(&finish, &start));
+#endif
+    } else {
+        calc_volume_table[spec->format] ((void *)linear, volume);
+        do_volume (ptr, (void *)linear, spec->channels, c->length);
+    }
+#else
+    calc_volume_table[spec->format] ((void *)linear, volume);
+
+    ptr = pa_memblock_acquire_chunk(c);
+
+    do_volume(ptr, (void *)linear, spec->channels, c->length);
+#endif
+    pa_memblock_release(c->memblock);
+}
diff --git a/src/pulsecore/mix.h b/src/pulsecore/mix.h
new file mode 100644 (file)
index 0000000..e90652a
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef foomixhfoo
+#define foomixhfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
+  Copyright 2013 Peter Meerwald <pmeerw@pmeerw.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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <pulse/sample.h>
+#include <pulse/volume.h>
+#include <pulsecore/memchunk.h>
+
+typedef struct pa_mix_info {
+    pa_memchunk chunk;
+    pa_cvolume volume;
+    void *userdata;
+
+    /* The following fields are used internally by pa_mix(), should
+     * not be initialised by the caller of pa_mix(). */
+    void *ptr;
+    union {
+        int32_t i;
+        float f;
+    } linear[PA_CHANNELS_MAX];
+} pa_mix_info;
+
+size_t pa_mix(
+    pa_mix_info channels[],
+    unsigned nchannels,
+    void *data,
+    size_t length,
+    const pa_sample_spec *spec,
+    const pa_cvolume *volume,
+    pa_bool_t mute);
+
+typedef void (*pa_do_mix_func_t) (pa_mix_info streams[], unsigned nstreams, unsigned channels, void *data, unsigned length);
+
+pa_do_mix_func_t pa_get_mix_func(pa_sample_format_t f);
+void pa_set_mix_func(pa_sample_format_t f, pa_do_mix_func_t func);
+
+void pa_volume_memchunk(
+    pa_memchunk*c,
+    const pa_sample_spec *spec,
+    const pa_cvolume *volume);
+
+#endif
diff --git a/src/pulsecore/mix_neon.c b/src/pulsecore/mix_neon.c
new file mode 100644 (file)
index 0000000..ff05ccf
--- /dev/null
@@ -0,0 +1,94 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2013 Peter Meerwald <pmeerw@pmeerw.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.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulsecore/macro.h>
+#include <pulsecore/endianmacros.h>
+
+#include "cpu-arm.h"
+#include "mix.h"
+
+#include <arm_neon.h>
+
+static pa_do_mix_func_t fallback;
+
+/* special case: mix s16ne streams, 2 channels each */
+static void pa_mix_ch2_s16ne_neon(pa_mix_info streams[], unsigned nstreams, uint8_t *data, unsigned length) {
+    const unsigned mask = sizeof(int16_t) * 8 - 1;
+    const uint8_t *end = data + (length & ~mask);
+
+    while (data < end) {
+        int32x4_t sum0, sum1;
+        unsigned i;
+
+        __asm__ __volatile__ (
+            "veor.s32 %q[sum0], %q[sum0]     \n\t"
+            "veor.s32 %q[sum1], %q[sum1]     \n\t"
+            : [sum0] "=w" (sum0), [sum1] "=w" (sum1)
+            :
+            : "cc" /* clobber list */
+        );
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            int32_t cv0 = m->linear[0].i;
+            int32_t cv1 = m->linear[1].i;
+
+            __asm__ __volatile__ (
+                "vld2.s16    {d0,d2}, [%[ptr]]!      \n\t"
+                "vmov.s32    d4[0], %[cv0]           \n\t"
+                "vmov.s32    d4[1], %[cv1]           \n\t"
+                "vshll.s16   q0, d0, #15             \n\t"
+                "vshll.s16   q1, d2, #15             \n\t"
+                "vqdmulh.s32 q0, q0, d4[0]           \n\t"
+                "vqdmulh.s32 q1, q1, d4[1]           \n\t"
+                "vqadd.s32   %q[sum0], %q[sum0], q0  \n\t"
+                "vqadd.s32   %q[sum1], %q[sum1], q1  \n\t"
+                : [ptr] "+r" (m->ptr), [sum0] "+w" (sum0), [sum1] "+w" (sum1)
+                : [cv0] "r" (cv0), [cv1] "r" (cv1)
+                : "memory", "cc", "q0", "q1", "d4" /* clobber list */
+            );
+        }
+
+        __asm__ __volatile__ (
+            "vqmovn.s32 d0, %q[sum0]         \n\t"
+            "vqmovn.s32 d1, %q[sum1]         \n\t"
+            "vst2.s16   {d0,d1}, [%[data]]!  \n\t"
+            : [data] "+r" (data)
+            : [sum0] "w" (sum0), [sum1] "w" (sum1)
+            : "memory", "cc", "q0" /* clobber list */
+        );
+    }
+
+    fallback(streams, nstreams, 2, data, length & mask);
+}
+
+static void pa_mix_s16ne_neon(pa_mix_info streams[], unsigned nstreams, unsigned nchannels, void *data, unsigned length) {
+    if (nchannels == 2)
+        pa_mix_ch2_s16ne_neon(streams, nstreams, data, length);
+    else
+        fallback(streams, nstreams, nchannels, data, length);
+}
+
+void pa_mix_func_init_neon(pa_cpu_arm_flag_t flags) {
+    pa_log_info("Initialising ARM NEON optimized mixing functions.");
+
+    fallback = pa_get_mix_func(PA_SAMPLE_S16NE);
+    pa_set_mix_func(PA_SAMPLE_S16NE, (pa_do_mix_func_t) pa_mix_s16ne_neon);
+}
index c7d734d..d48a2c8 100644 (file)
 
 #include <pulsecore/hashmap.h>
 #include <pulsecore/idxset.h>
-#include <pulsecore/sample-util.h>
-#include <pulsecore/namereg.h>
-#include <pulsecore/sink.h>
-#include <pulsecore/source.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/macro.h>
 
 #include "modargs.h"
 
+struct pa_modargs {
+    pa_hashmap *raw;
+    pa_hashmap *unescaped;
+};
+
 struct entry {
     char *key, *value;
 };
 
-static int add_key_value(pa_hashmap *map, char *key, char *value, const char* const valid_keys[]) {
+static int add_key_value(pa_modargs *ma, char *key, char *value, const char* const valid_keys[]) {
     struct entry *e;
+    char *raw;
 
-    pa_assert(map);
+    pa_assert(ma);
+    pa_assert(ma->raw);
+    pa_assert(ma->unescaped);
     pa_assert(key);
     pa_assert(value);
 
-    if (pa_hashmap_get(map, key)) {
+    if (pa_hashmap_get(ma->unescaped, key)) {
         pa_xfree(key);
         pa_xfree(value);
         return -1;
@@ -60,7 +64,7 @@ static int add_key_value(pa_hashmap *map, char *key, char *value, const char* co
     if (valid_keys) {
         const char*const* v;
         for (v = valid_keys; *v; v++)
-            if (strcmp(*v, key) == 0)
+            if (pa_streq(*v, key))
                 break;
 
         if (!*v) {
@@ -70,10 +74,21 @@ static int add_key_value(pa_hashmap *map, char *key, char *value, const char* co
         }
     }
 
+    raw = pa_xstrdup(value);
+
     e = pa_xnew(struct entry, 1);
     e->key = key;
-    e->value = value;
-    pa_hashmap_put(map, key, e);
+    e->value = pa_unescape(value);
+    pa_hashmap_put(ma->unescaped, key, e);
+
+    if (pa_streq(raw, value))
+        pa_xfree(raw);
+    else {
+        e = pa_xnew(struct entry, 1);
+        e->key = pa_xstrdup(key);
+        e->value = raw;
+        pa_hashmap_put(ma->raw, key, e);
+    }
 
     return 0;
 }
@@ -93,12 +108,13 @@ pa_modargs *pa_modargs_new(const char *args, const char* const* valid_keys) {
 
     const char *p, *key = NULL, *value = NULL;
     size_t key_len = 0, value_len = 0;
-    pa_hashmap *map;
+    pa_modargs *ma = pa_xnew(pa_modargs, 1);
 
-    map = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    ma->raw = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    ma->unescaped = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
 
     if (!args)
-        return (pa_modargs*) map;
+        return ma;
 
     state = WHITESPACE;
 
@@ -124,7 +140,7 @@ pa_modargs *pa_modargs_new(const char *args, const char* const* valid_keys) {
                     key_len++;
                 break;
 
-            case  VALUE_START:
+            case VALUE_START:
                 if (*p == '\'') {
                     state = VALUE_TICKS;
                     value = p+1;
@@ -134,7 +150,7 @@ pa_modargs *pa_modargs_new(const char *args, const char* const* valid_keys) {
                     value = p+1;
                     value_len = 0;
                 } else if (isspace(*p)) {
-                    if (add_key_value(map,
+                    if (add_key_value(ma,
                                       pa_xstrndup(key, key_len),
                                       pa_xstrdup(""),
                                       valid_keys) < 0)
@@ -153,9 +169,9 @@ pa_modargs *pa_modargs_new(const char *args, const char* const* valid_keys) {
 
             case VALUE_SIMPLE:
                 if (isspace(*p)) {
-                    if (add_key_value(map,
+                    if (add_key_value(ma,
                                       pa_xstrndup(key, key_len),
-                                      pa_unescape(pa_xstrndup(value, value_len)),
+                                      pa_xstrndup(value, value_len),
                                       valid_keys) < 0)
                         goto fail;
                     state = WHITESPACE;
@@ -173,9 +189,9 @@ pa_modargs *pa_modargs_new(const char *args, const char* const* valid_keys) {
 
             case VALUE_DOUBLE_QUOTES:
                 if (*p == '"') {
-                    if (add_key_value(map,
+                    if (add_key_value(ma,
                                       pa_xstrndup(key, key_len),
-                                      pa_unescape(pa_xstrndup(value, value_len)),
+                                      pa_xstrndup(value, value_len),
                                       valid_keys) < 0)
                         goto fail;
                     state = WHITESPACE;
@@ -193,9 +209,9 @@ pa_modargs *pa_modargs_new(const char *args, const char* const* valid_keys) {
 
             case VALUE_TICKS:
                 if (*p == '\'') {
-                    if (add_key_value(map,
+                    if (add_key_value(ma,
                                       pa_xstrndup(key, key_len),
-                                      pa_unescape(pa_xstrndup(value, value_len)),
+                                      pa_xstrndup(value, value_len),
                                       valid_keys) < 0)
                         goto fail;
                     state = WHITESPACE;
@@ -214,24 +230,24 @@ pa_modargs *pa_modargs_new(const char *args, const char* const* valid_keys) {
     }
 
     if (state == VALUE_START) {
-        if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0)
+        if (add_key_value(ma, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0)
             goto fail;
     } else if (state == VALUE_SIMPLE) {
-        if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(value), valid_keys) < 0)
+        if (add_key_value(ma, pa_xstrndup(key, key_len), pa_xstrdup(value), valid_keys) < 0)
             goto fail;
     } else if (state != WHITESPACE)
         goto fail;
 
-    return (pa_modargs*) map;
+    return ma;
 
 fail:
 
-    pa_modargs_free((pa_modargs*) map);
+    pa_modargs_free(ma);
 
     return NULL;
 }
 
-static void free_func(void *p, void*userdata) {
+static void free_func(void *p) {
     struct entry *e = p;
     pa_assert(e);
 
@@ -241,25 +257,41 @@ static void free_func(void *p, void*userdata) {
 }
 
 void pa_modargs_free(pa_modargs*ma) {
-    pa_hashmap *map = (pa_hashmap*) ma;
-    pa_hashmap_free(map, free_func, NULL);
+    pa_assert(ma);
+
+    pa_hashmap_free(ma->raw, free_func);
+    pa_hashmap_free(ma->unescaped, free_func);
+    pa_xfree(ma);
 }
 
 const char *pa_modargs_get_value(pa_modargs *ma, const char *key, const char *def) {
-    pa_hashmap *map = (pa_hashmap*) ma;
     struct entry*e;
 
-    if (!(e = pa_hashmap_get(map, key)))
+    pa_assert(ma);
+    pa_assert(key);
+
+    if (!(e = pa_hashmap_get(ma->unescaped, key)))
         return def;
 
     return e->value;
 }
 
-int pa_modargs_get_value_u32(pa_modargs *ma, const char *key, uint32_t *value) {
-    const char *v;
+static const char *modargs_get_value_raw(pa_modargs *ma, const char *key, const char *def) {
+    struct entry*e;
 
     pa_assert(ma);
     pa_assert(key);
+
+    if (!(e = pa_hashmap_get(ma->raw, key)))
+        if (!(e = pa_hashmap_get(ma->unescaped, key)))
+            return def;
+
+    return e->value;
+}
+
+int pa_modargs_get_value_u32(pa_modargs *ma, const char *key, uint32_t *value) {
+    const char *v;
+
     pa_assert(value);
 
     if (!(v = pa_modargs_get_value(ma, key, NULL)))
@@ -274,8 +306,6 @@ int pa_modargs_get_value_u32(pa_modargs *ma, const char *key, uint32_t *value) {
 int pa_modargs_get_value_s32(pa_modargs *ma, const char *key, int32_t *value) {
     const char *v;
 
-    pa_assert(ma);
-    pa_assert(key);
     pa_assert(value);
 
     if (!(v = pa_modargs_get_value(ma, key, NULL)))
@@ -291,8 +321,6 @@ int pa_modargs_get_value_boolean(pa_modargs *ma, const char *key, pa_bool_t *val
     const char *v;
     int r;
 
-    pa_assert(ma);
-    pa_assert(key);
     pa_assert(value);
 
     if (!(v = pa_modargs_get_value(ma, key, NULL)))
@@ -308,12 +336,39 @@ int pa_modargs_get_value_boolean(pa_modargs *ma, const char *key, pa_bool_t *val
     return 0;
 }
 
+int pa_modargs_get_value_double(pa_modargs *ma, const char *key, double *value) {
+    const char *v;
+
+    pa_assert(value);
+
+    if (!(v = pa_modargs_get_value(ma, key, NULL)))
+        return 0;
+
+    if (pa_atod(v, value) < 0)
+        return -1;
+
+    return 0;
+}
+
+int pa_modargs_get_value_volume(pa_modargs *ma, const char *key, pa_volume_t *value) {
+    const char *v;
+
+    pa_assert(value);
+
+    if (!(v = pa_modargs_get_value(ma, key, NULL)))
+        return 0;
+
+    if (pa_parse_volume(v, value) < 0)
+        return -1;
+
+    return 0;
+}
+
 int pa_modargs_get_sample_spec(pa_modargs *ma, pa_sample_spec *rss) {
     const char *format;
     uint32_t channels;
     pa_sample_spec ss;
 
-    pa_assert(ma);
     pa_assert(rss);
 
     ss = *rss;
@@ -341,11 +396,23 @@ int pa_modargs_get_sample_spec(pa_modargs *ma, pa_sample_spec *rss) {
     return 0;
 }
 
+int pa_modargs_get_alternate_sample_rate(pa_modargs *ma, uint32_t *alternate_rate) {
+    pa_assert(ma);
+    pa_assert(alternate_rate);
+
+    if ((pa_modargs_get_value_u32(ma, "alternate_rate", alternate_rate)) < 0 ||
+        *alternate_rate <= 0 ||
+        *alternate_rate > PA_RATE_MAX ||
+        !((*alternate_rate % 4000 == 0) || (*alternate_rate % 11025 == 0)))
+        return -1;
+
+    return 0;
+}
+
 int pa_modargs_get_channel_map(pa_modargs *ma, const char *name, pa_channel_map *rmap) {
     pa_channel_map map;
     const char *cm;
 
-    pa_assert(ma);
     pa_assert(rmap);
 
     map = *rmap;
@@ -370,7 +437,6 @@ int pa_modargs_get_sample_spec_and_channel_map(
     pa_sample_spec ss;
     pa_channel_map map;
 
-    pa_assert(ma);
     pa_assert(rss);
     pa_assert(rmap);
 
@@ -387,8 +453,12 @@ int pa_modargs_get_sample_spec_and_channel_map(
     if (pa_modargs_get_channel_map(ma, NULL, &map) < 0)
         return -1;
 
-    if (map.channels != ss.channels)
-        return -1;
+    if (map.channels != ss.channels) {
+        if (!pa_modargs_get_value(ma, "channels", NULL))
+            ss.channels = map.channels;
+        else
+            return -1;
+    }
 
     *rmap = map;
     *rss = ss;
@@ -404,7 +474,7 @@ int pa_modargs_get_proplist(pa_modargs *ma, const char *name, pa_proplist *p, pa
     pa_assert(name);
     pa_assert(p);
 
-    if (!(v = pa_modargs_get_value(ma, name, NULL)))
+    if (!(v = modargs_get_value_raw(ma, name, NULL)))
         return 0;
 
     if (!(n = pa_proplist_from_string(v)))
@@ -415,3 +485,14 @@ int pa_modargs_get_proplist(pa_modargs *ma, const char *name, pa_proplist *p, pa
 
     return 0;
 }
+
+const char *pa_modargs_iterate(pa_modargs *ma, void **state) {
+    struct entry *e;
+
+    pa_assert(ma);
+
+    if (!(e = pa_hashmap_iterate(ma->unescaped, state, NULL)))
+        return NULL;
+
+    return e->key;
+}
index b3125b1..c1345ea 100644 (file)
@@ -25,7 +25,8 @@
 #include <inttypes.h>
 #include <pulse/sample.h>
 #include <pulse/channelmap.h>
-#include <pulsecore/core.h>
+#include <pulse/proplist.h>
+#include <pulse/volume.h>
 #include <pulsecore/macro.h>
 
 typedef struct pa_modargs pa_modargs;
@@ -45,6 +46,12 @@ int pa_modargs_get_value_u32(pa_modargs *ma, const char *key, uint32_t *value);
 int pa_modargs_get_value_s32(pa_modargs *ma, const char *key, int32_t *value);
 int pa_modargs_get_value_boolean(pa_modargs *ma, const char *key, pa_bool_t *value);
 
+/* Return a module argument as double value in *value */
+int pa_modargs_get_value_double(pa_modargs *ma, const char *key, double *value);
+
+/* Return a module argument as pa_volume_t value in *value */
+int pa_modargs_get_value_volume(pa_modargs *ma, const char *key, pa_volume_t *value);
+
 /* Return sample spec data from the three arguments "rate", "format" and "channels" */
 int pa_modargs_get_sample_spec(pa_modargs *ma, pa_sample_spec *ss);
 
@@ -58,6 +65,18 @@ structure if no channel_map is found, using pa_channel_map_init_auto() */
 
 int pa_modargs_get_sample_spec_and_channel_map(pa_modargs *ma, pa_sample_spec *ss, pa_channel_map *map, pa_channel_map_def_t def);
 
+/* Return alternate sample rate from "alternate_sample_rate" parameter */
+int pa_modargs_get_alternate_sample_rate(pa_modargs *ma, uint32_t *alternate_rate);
+
 int pa_modargs_get_proplist(pa_modargs *ma, const char *name, pa_proplist *p, pa_update_mode_t m);
 
+/* Iterate through the module argument list. The user should allocate a
+ * state variable of type void* and initialize it with NULL. A pointer
+ * to this variable should then be passed to pa_modargs_iterate()
+ * which should be called in a loop until it returns NULL which
+ * signifies EOL. On each invocation this function will return the
+ * key string for the next entry. The keys in the argument list do not
+ * have any particular order. */
+const char *pa_modargs_iterate(pa_modargs *ma, void **state);
+
 #endif
index b5ee9f5..860b806 100644 (file)
@@ -27,7 +27,6 @@
 
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/ltdl-helper.h>
index 5bcdd89..268d85d 100644 (file)
 #include <config.h>
 #endif
 
-#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <ctype.h>
 
-#include <pulse/timeval.h>
 #include <pulse/xmalloc.h>
 #include <pulse/proplist.h>
 
@@ -69,7 +66,13 @@ pa_module* pa_module_load(pa_core *c, const char *name, const char *argument) {
     m->proplist = pa_proplist_new();
 
     if (!(m->dl = lt_dlopenext(name))) {
-        pa_log("Failed to open module \"%s\": %s", name, lt_dlerror());
+        /* We used to print the error that is returned by lt_dlerror(), but
+         * lt_dlerror() is useless. It returns pretty much always "file not
+         * found". That's because if there are any problems with loading the
+         * module with normal loaders, libltdl falls back to the "preload"
+         * loader, which never finds anything, and therefore says "file not
+         * found". */
+        pa_log("Failed to open module \"%s\".", name);
         goto fail;
     }
 
@@ -82,8 +85,8 @@ pa_module* pa_module_load(pa_core *c, const char *name, const char *argument) {
             uint32_t idx;
             /* OK, the module only wants to be loaded once, let's make sure it is */
 
-            for (i = pa_idxset_first(c->modules, &idx); i; i = pa_idxset_next(c->modules, &idx)) {
-                if (strcmp(name, i->name) == 0) {
+            PA_IDXSET_FOREACH(i, c->modules, idx) {
+                if (pa_streq(name, i->name)) {
                     pa_log("Module \"%s\" should be loaded once at most. Refusing to load.", name);
                     goto fail;
                 }
@@ -110,7 +113,7 @@ pa_module* pa_module_load(pa_core *c, const char *name, const char *argument) {
     m->unload_requested = FALSE;
 
     if (m->init(m) < 0) {
-        pa_log_error("Failed to load  module \"%s\" (argument: \"%s\"): initialization failed.", name, argument ? argument : "");
+        pa_log_error("Failed to load module \"%s\" (argument: \"%s\"): initialization failed.", name, argument ? argument : "");
         goto fail;
     }
 
@@ -207,10 +210,29 @@ void pa_module_unload_by_index(pa_core *c, uint32_t idx, pa_bool_t force) {
 
 void pa_module_unload_all(pa_core *c) {
     pa_module *m;
+    uint32_t *indices;
+    uint32_t state;
+    int i;
+
     pa_assert(c);
+    pa_assert(c->modules);
+
+    /* Unload modules in reverse order by default */
+    indices = pa_xnew(uint32_t, pa_idxset_size(c->modules));
+    i = 0;
+    PA_IDXSET_FOREACH(m, c->modules, state)
+        indices[i++] = state;
+    pa_assert(i == (int) pa_idxset_size(c->modules));
+    i--;
+    for (; i >= 0; i--) {
+        m = pa_idxset_remove_by_index(c->modules, indices[i]);
+        if (m)
+            pa_module_free(m);
+    }
+    pa_xfree(indices);
 
-    while ((m = pa_idxset_steal_first(c->modules, NULL)))
-        pa_module_free(m);
+    /* Just in case module unloading caused more modules to load */
+    pa_idxset_remove_all(c->modules, (pa_free_cb_t) pa_module_free);
 
     if (c->module_defer_unload_event) {
         c->mainloop->defer_free(c->module_defer_unload_event);
@@ -263,3 +285,12 @@ int pa_module_get_n_used(pa_module*m) {
 
     return m->get_n_used(m);
 }
+
+void pa_module_update_proplist(pa_module *m, pa_update_mode_t mode, pa_proplist *p) {
+    pa_assert(m);
+
+    if (p)
+        pa_proplist_update(m->proplist, mode, p);
+
+    pa_subscription_post(m->core, PA_SUBSCRIPTION_EVENT_MODULE|PA_SUBSCRIPTION_EVENT_CHANGE, m->index);
+}
index af89d79..0b6cb7c 100644 (file)
@@ -62,6 +62,8 @@ void pa_module_unload_all(pa_core *c);
 
 int pa_module_get_n_used(pa_module*m);
 
+void pa_module_update_proplist(pa_module *m, pa_update_mode_t mode, pa_proplist *p);
+
 #define PA_MODULE_AUTHOR(s)                                     \
     const char *pa__get_author(void) { return s; }              \
     struct __stupid_useless_struct_to_allow_trailing_semicolon
index ee0ec1e..9b5712b 100644 (file)
@@ -25,8 +25,6 @@
 
 #include <sys/types.h>
 
-#include <pulse/xmalloc.h>
-#include <pulsecore/refcnt.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/object.h>
 #include <pulsecore/memchunk.h>
index 0ff4bee..d90525b 100644 (file)
@@ -28,8 +28,6 @@
 
 #include <pulse/xmalloc.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/log.h>
-#include <pulsecore/core-error.h>
 
 #include "mutex.h"
 
@@ -52,8 +50,10 @@ pa_mutex* pa_mutex_new(pa_bool_t recursive, pa_bool_t inherit_priority) {
         pa_assert_se(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == 0);
 
 #ifdef HAVE_PTHREAD_PRIO_INHERIT
-    if (inherit_priority)
-        pa_assert_se(pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT) == 0);
+    if (inherit_priority) {
+        r = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
+        pa_assert(r == 0 || r == ENOTSUP);
+    }
 #endif
 
     m = pa_xnew(pa_mutex, 1);
index 3a910b0..e70f230 100644 (file)
@@ -80,7 +80,7 @@ pa_cond *pa_cond_new(void) {
 void pa_cond_free(pa_cond *c) {
     assert(c);
 
-    pa_hashmap_free(c->wait_events, NULL, NULL);
+    pa_hashmap_free(c->wait_events, NULL);
     pa_xfree(c);
 }
 
@@ -91,7 +91,7 @@ void pa_cond_signal(pa_cond *c, int broadcast) {
         return;
 
     if (broadcast)
-        SetEvent(pa_hashmap_get_first(c->wait_events));
+        SetEvent(pa_hashmap_first(c->wait_events));
     else {
         void *iter;
         const void *key;
@@ -131,3 +131,26 @@ int pa_cond_wait(pa_cond *c, pa_mutex *m) {
 
     return 0;
 }
+
+/* This is a copy of the function in mutex-posix.c */
+pa_mutex* pa_static_mutex_get(pa_static_mutex *s, pa_bool_t recursive, pa_bool_t inherit_priority) {
+    pa_mutex *m;
+
+    pa_assert(s);
+
+    /* First, check if already initialized and short cut */
+    if ((m = pa_atomic_ptr_load(&s->ptr)))
+        return m;
+
+    /* OK, not initialized, so let's allocate, and fill in */
+    m = pa_mutex_new(recursive, inherit_priority);
+    if ((pa_atomic_ptr_cmpxchg(&s->ptr, NULL, m)))
+        return m;
+
+    pa_mutex_free(m);
+
+    /* Him, filling in failed, so someone else must have filled in
+     * already */
+    pa_assert_se(m = pa_atomic_ptr_load(&s->ptr));
+    return m;
+}
index b1edc13..fd6939f 100644 (file)
@@ -28,7 +28,7 @@
 typedef struct pa_mutex pa_mutex;
 
 /* Please think twice before enabling priority inheritance. This is no
- * magic wand! Use it only when the potentially priorized threads are
+ * magic wand! Use it only when the potentially prioritized threads are
  * good candidates for it. Don't use this blindly! Also, note that
  * only very few operating systems actually implement this, hence this
  * is merely a hint. */
old mode 100644 (file)
new mode 100755 (executable)
index d982187..4e56335
@@ -259,7 +259,12 @@ pa_sink* pa_namereg_set_default_sink(pa_core*c, pa_sink *s) {
 
     if (c->default_sink != s) {
         c->default_sink = s;
+#ifdef __TIZEN__
+        // we need sink index for module-poliyc:subscribe_cb
+        pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, s != NULL ? s->index : PA_INVALID_INDEX);
+#else
         pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
+#endif
     }
 
     return s;
@@ -280,23 +285,26 @@ pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s) {
 }
 
 pa_sink *pa_namereg_get_default_sink(pa_core *c) {
+#ifndef __TIZEN__
     pa_sink *s, *best = NULL;
     uint32_t idx;
+#endif
 
     pa_assert(c);
 
     if (c->default_sink && PA_SINK_IS_LINKED(pa_sink_get_state(c->default_sink)))
         return c->default_sink;
 
+#ifdef __TIZEN__
+    return pa_namereg_get(c, "null", PA_NAMEREG_SINK);
+#else
     PA_IDXSET_FOREACH(s, c->sinks, idx)
         if (PA_SINK_IS_LINKED(pa_sink_get_state(s)))
             if (!best || s->priority > best->priority)
                 best = s;
 
-    if (best)
-        return pa_namereg_set_default_sink(c, best);
-
-    return NULL;
+    return best;
+#endif /* __TIZEN__ */
 }
 
 pa_source *pa_namereg_get_default_source(pa_core *c) {
@@ -316,7 +324,7 @@ pa_source *pa_namereg_get_default_source(pa_core *c) {
                 best = s;
 
     if (best)
-        return pa_namereg_set_default_source(c, best);
+        return best;
 
     /* Then, fallback to a monitor */
     PA_IDXSET_FOREACH(s, c->sources, idx)
@@ -329,8 +337,5 @@ pa_source *pa_namereg_get_default_source(pa_core *c) {
                  s->monitor_of->priority > best->monitor_of->priority))
                 best = s;
 
-    if (best)
-        return pa_namereg_set_default_source(c, best);
-
-    return NULL;
+    return best;
 }
index f49abb0..2564432 100644 (file)
@@ -78,10 +78,18 @@ enum {
     PA_COMMAND_SET_SOURCE_MUTE,
 
     PA_COMMAND_CORK_PLAYBACK_STREAM,
+#ifdef __TIZEN__
+    PA_COMMAND_CORK_PLAYBACK_STREAM_ALL,
+#endif
     PA_COMMAND_FLUSH_PLAYBACK_STREAM,
     PA_COMMAND_TRIGGER_PLAYBACK_STREAM,
 
     PA_COMMAND_SET_DEFAULT_SINK,
+#ifdef __TIZEN__
+    PA_COMMAND_SET_DEFAULT_SINK_BY_API_BUS,
+    PA_COMMAND_SET_DEFAULT_SINK_FOR_USB,
+    PA_COMMAND_UNLOAD_HDMI,
+#endif
     PA_COMMAND_SET_DEFAULT_SOURCE,
 
     PA_COMMAND_SET_PLAYBACK_STREAM_NAME,
@@ -169,11 +177,19 @@ enum {
     PA_COMMAND_SET_SINK_PORT,
     PA_COMMAND_SET_SOURCE_PORT,
 
+    /* Supported since protocol v22 (1.0) */
+    PA_COMMAND_SET_SOURCE_OUTPUT_VOLUME,
+    PA_COMMAND_SET_SOURCE_OUTPUT_MUTE,
+
+    /* Supported since protocol v27 (3.0) */
+    PA_COMMAND_SET_PORT_LATENCY_OFFSET,
+
     PA_COMMAND_MAX
 };
 
 #define PA_NATIVE_COOKIE_LENGTH 256
-#define PA_NATIVE_COOKIE_FILE ".pulse-cookie"
+#define PA_NATIVE_COOKIE_FILE ".config/pulse/cookie"
+#define PA_NATIVE_COOKIE_FILE_FALLBACK ".pulse-cookie"
 
 #define PA_NATIVE_DEFAULT_PORT 4713
 
index 099d50d..0dc8198 100644 (file)
@@ -24,8 +24,6 @@
 #include <config.h>
 #endif
 
-#include <pulsecore/core-util.h>
-
 #include "object.h"
 
 const char pa_object_type_id[] = "pa_object";
index 4c120cd..8be429e 100644 (file)
@@ -23,7 +23,6 @@
   USA.
 ***/
 
-#include <string.h>
 #include <sys/types.h>
 
 #include <pulse/xmalloc.h>
@@ -80,7 +79,7 @@ static inline pa_object* pa_object_cast(void *o) {
         return (c*) o;                                                  \
     }                                                                   \
     static inline c* c##_ref(c *o) {                                    \
-        return (c*) pa_object_ref(PA_OBJECT(o));                        \
+        return (c *) ((void *) pa_object_ref(PA_OBJECT(o)));            \
     }                                                                   \
     static inline void c##_unref(c* o) {                                \
         pa_object_unref(PA_OBJECT(o));                                  \
index 05a3ad2..30b35a6 100644 (file)
 #endif
 
 #include <pulsecore/macro.h>
-#include <pulsecore/mutex.h>
 
 #include "once.h"
 
+/* See http://www.hpl.hp.com/research/linux/atomic_ops/example.php4 for the
+ * reference algorithm used here. */
+
 pa_bool_t pa_once_begin(pa_once *control) {
     pa_mutex *m;
 
@@ -36,35 +38,19 @@ pa_bool_t pa_once_begin(pa_once *control) {
     if (pa_atomic_load(&control->done))
         return FALSE;
 
-    pa_atomic_inc(&control->ref);
-
     /* Caveat: We have to make sure that the once func has completed
      * before returning, even if the once func is not actually
      * executed by us. Hence the awkward locking. */
 
-    for (;;) {
-
-        if ((m = pa_atomic_ptr_load(&control->mutex))) {
-
-            /* The mutex is stored in locked state, hence let's just
-             * wait until it is unlocked */
-            pa_mutex_lock(m);
-
-            pa_assert(pa_atomic_load(&control->done));
-
-            pa_once_end(control);
-            return FALSE;
-        }
-
-        pa_assert_se(m = pa_mutex_new(FALSE, FALSE));
-        pa_mutex_lock(m);
-
-        if (pa_atomic_ptr_cmpxchg(&control->mutex, NULL, m))
-            return TRUE;
+    m = pa_static_mutex_get(&control->mutex, FALSE, FALSE);
+    pa_mutex_lock(m);
 
+    if (pa_atomic_load(&control->done)) {
         pa_mutex_unlock(m);
-        pa_mutex_free(m);
+        return FALSE;
     }
+
+    return TRUE;
 }
 
 void pa_once_end(pa_once *control) {
@@ -72,15 +58,11 @@ void pa_once_end(pa_once *control) {
 
     pa_assert(control);
 
+    pa_assert(!pa_atomic_load(&control->done));
     pa_atomic_store(&control->done, 1);
 
-    pa_assert_se(m = pa_atomic_ptr_load(&control->mutex));
+    m = pa_static_mutex_get(&control->mutex, FALSE, FALSE);
     pa_mutex_unlock(m);
-
-    if (pa_atomic_dec(&control->ref) <= 1) {
-        pa_assert_se(pa_atomic_ptr_cmpxchg(&control->mutex, m, NULL));
-        pa_mutex_free(m);
-    }
 }
 
 /* Not reentrant -- how could it be? */
index 50ac18c..a478d1f 100644 (file)
   USA.
 ***/
 
-#include <pulsecore/mutex.h>
 #include <pulsecore/atomic.h>
+#include <pulsecore/mutex.h>
 
 typedef struct pa_once {
-    pa_atomic_ptr_t mutex;
-    pa_atomic_t ref, done;
+    pa_static_mutex mutex;
+    pa_atomic_t done;
 } pa_once;
 
 #define PA_ONCE_INIT                                                    \
     {                                                                   \
-        .mutex = PA_ATOMIC_PTR_INIT(NULL),                              \
-        .ref = PA_ATOMIC_INIT(0),                                       \
+        .mutex = PA_STATIC_MUTEX_INIT,                                  \
         .done = PA_ATOMIC_INIT(0)                                       \
     }
 
index 44cd9a0..7ec068a 100644 (file)
 
 #include <string.h>
 #include <stdlib.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/util.h>
 
 #include <pulsecore/core-util.h>
 #include <pulsecore/macro.h>
+#include <pulsecore/arpa-inet.h>
 
 #include "parseaddr.h"
 
index f15466c..d607781 100644 (file)
@@ -90,7 +90,7 @@ static const char *command_names[PA_COMMAND_MAX] = {
 
     [PA_COMMAND_SET_SINK_VOLUME] = "SET_SINK_VOLUME",
     [PA_COMMAND_SET_SINK_INPUT_VOLUME] = "SET_SINK_INPUT_VOLUME",
-    [PA_COMMAND_SET_SOURCE_VOLUME] = "SET_SOURCE_VOLME",
+    [PA_COMMAND_SET_SOURCE_VOLUME] = "SET_SOURCE_VOLUME",
 
     [PA_COMMAND_SET_SINK_MUTE] = "SET_SINK_MUTE",
     [PA_COMMAND_SET_SOURCE_MUTE] = "SET_SOURCE_MUTE",
@@ -100,6 +100,7 @@ static const char *command_names[PA_COMMAND_MAX] = {
     [PA_COMMAND_CORK_PLAYBACK_STREAM] = "CORK_PLAYBACK_STREAM",
 
     [PA_COMMAND_SET_DEFAULT_SINK] = "SET_DEFAULT_SINK",
+    [PA_COMMAND_SET_DEFAULT_SINK_BY_API_BUS] = "SET_DEFAULT_SINK_BY_API_BUS",
     [PA_COMMAND_SET_DEFAULT_SOURCE] = "SET_DEFAULT_SOURCE",
 
     [PA_COMMAND_SET_PLAYBACK_STREAM_NAME] = "SET_PLAYBACK_STREAM_NAME",
@@ -184,7 +185,12 @@ static const char *command_names[PA_COMMAND_MAX] = {
 
     /* Supported since protocol v16 (0.9.16) */
     [PA_COMMAND_SET_SINK_PORT] = "SET_SINK_PORT",
-    [PA_COMMAND_SET_SOURCE_PORT] = "SET_SOURCE_PORT"
+    [PA_COMMAND_SET_SOURCE_PORT] = "SET_SOURCE_PORT",
+
+    /* Supported since protocol v22 (1.0) */
+    [PA_COMMAND_SET_SOURCE_OUTPUT_VOLUME] = "SET_SOURCE_OUTPUT_VOLUME",
+    [PA_COMMAND_SET_SOURCE_OUTPUT_MUTE] = "SET_SOURCE_OUTPUT_MUTE",
+
 };
 
 #endif
index 996946c..588349b 100644 (file)
@@ -40,7 +40,6 @@
 #endif
 
 #include <pulse/xmalloc.h>
-#include <pulse/util.h>
 
 #include <pulsecore/core-error.h>
 #include <pulsecore/core-util.h>
@@ -88,10 +87,7 @@ static int open_pid_file(const char *fn, int mode) {
     for (;;) {
         struct stat st;
 
-        if ((fd = open(fn, mode
-#ifdef O_NOCTTY
-                       |O_NOCTTY
-#endif
+        if ((fd = pa_open_cloexec(fn, mode
 #ifdef O_NOFOLLOW
                        |O_NOFOLLOW
 #endif
@@ -146,7 +142,7 @@ static int proc_name_ours(pid_t pid, const char *procname) {
 
     pa_snprintf(bn, sizeof(bn), "/proc/%lu/stat", (unsigned long) pid);
 
-    if (!(f = fopen(bn, "r"))) {
+    if (!(f = pa_fopen_cloexec(bn, "r"))) {
         pa_log_info("Failed to open %s: %s", bn, pa_cstrerror(errno));
         return -1;
     } else {
@@ -221,7 +217,7 @@ int pa_pid_file_create(const char *procname) {
             if (procname)
                 if ((ours = proc_name_ours(pid, procname)) < 0) {
                     pa_log_warn("Could not check to see if pid %lu is a pulseaudio process. "
-                                "Asssuming it is and the daemon is already running.", (unsigned long) pid);
+                                "Assuming it is and the daemon is already running.", (unsigned long) pid);
                     goto fail;
                 }
 
@@ -324,7 +320,7 @@ fail:
 }
 
 /* Check whether the daemon is currently running, i.e. if a PID file
- * exists and the PID therein too. Returns 0 on succcess, -1
+ * exists and the PID therein too. Returns 0 on success, -1
  * otherwise. If pid is non-NULL and a running daemon was found,
  * return its PID therein */
 int pa_pid_file_check_running(pid_t *pid, const char *procname) {
index c21e4b1..f873ef6 100644 (file)
 
 #include <sys/types.h>
 
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#include "winsock.h"
+#include <pulsecore/socket.h>
+#include <pulsecore/core-util.h>
 
 #include "pipe.h"
 
index f528c49..2ce92e5 100644 (file)
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <string.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/gccmacro.h>
 
 #include <pulsecore/sink-input.h>
 #include <pulsecore/thread-mq.h>
-#include <pulsecore/sample-util.h>
 
 #include "play-memblockq.h"
 
@@ -135,6 +132,15 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
         return -1;
     }
 
+    /* If there's no memblock, there's going to be data in the memblockq after
+     * a gap with length chunk->length. Drop the gap and peek the actual
+     * data. There should always be some data coming - hence the assert. The
+     * gap will occur if the memblockq is rewound beyond index 0.*/
+    if (!chunk->memblock) {
+        pa_memblockq_drop(u->memblockq, chunk->length);
+        pa_assert_se(pa_memblockq_peek(u->memblockq, chunk) >= 0);
+    }
+
     chunk->length = PA_MIN(chunk->length, nbytes);
     pa_memblockq_drop(u->memblockq, chunk->length);
 
@@ -173,7 +179,8 @@ pa_sink_input* pa_memblockq_sink_input_new(
         const pa_channel_map *map,
         pa_memblockq *q,
         pa_cvolume *volume,
-        pa_proplist *p) {
+        pa_proplist *p,
+        pa_sink_input_flags_t flags) {
 
     memblockq_stream *u = NULL;
     pa_sink_input_new_data data;
@@ -192,12 +199,13 @@ pa_sink_input* pa_memblockq_sink_input_new(
     u->memblockq = NULL;
 
     pa_sink_input_new_data_init(&data);
-    data.sink = sink;
+    pa_sink_input_new_data_set_sink(&data, sink, FALSE);
     data.driver = __FILE__;
     pa_sink_input_new_data_set_sample_spec(&data, ss);
     pa_sink_input_new_data_set_channel_map(&data, map);
     pa_sink_input_new_data_set_volume(&data, volume);
     pa_proplist_update(data.proplist, PA_UPDATE_REPLACE, p);
+    data.flags |= flags;
 
     pa_sink_input_new(&u->sink_input, sink->core, &data);
     pa_sink_input_new_data_done(&data);
@@ -237,6 +245,7 @@ int pa_play_memblockq(
         pa_memblockq *q,
         pa_cvolume *volume,
         pa_proplist *p,
+        pa_sink_input_flags_t flags,
         uint32_t *sink_input_index) {
 
     pa_sink_input *i;
@@ -245,7 +254,7 @@ int pa_play_memblockq(
     pa_assert(ss);
     pa_assert(q);
 
-    if (!(i = pa_memblockq_sink_input_new(sink, ss, map, q, volume, p)))
+    if (!(i = pa_memblockq_sink_input_new(sink, ss, map, q, volume, p, flags)))
         return -1;
 
     pa_sink_input_put(i);
index 9d5f40f..a55fed0 100644 (file)
@@ -31,17 +31,19 @@ pa_sink_input* pa_memblockq_sink_input_new(
         const pa_channel_map *map,
         pa_memblockq *q,
         pa_cvolume *volume,
-        pa_proplist *p);
+        pa_proplist *p,
+        pa_sink_input_flags_t flags);
 
 void pa_memblockq_sink_input_set_queue(pa_sink_input *i, pa_memblockq *q);
 
 int pa_play_memblockq(
-    pa_sink *sink,
-    const pa_sample_spec *ss,
-    const pa_channel_map *map,
-    pa_memblockq *q,
-    pa_cvolume *cvolume,
-    pa_proplist *p,
-    uint32_t *sink_input_index);
+        pa_sink *sink,
+        const pa_sample_spec *ss,
+        const pa_channel_map *map,
+        pa_memblockq *q,
+        pa_cvolume *cvolume,
+        pa_proplist *p,
+        pa_sink_input_flags_t flags,
+        uint32_t *sink_input_index);
 
 #endif
index f127d7a..26a2bcc 100644 (file)
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <string.h>
-
-#include <pulse/xmalloc.h>
-#include <pulse/gccmacro.h>
 
 #include <pulsecore/sink-input.h>
-#include <pulsecore/thread-mq.h>
 #include <pulsecore/play-memblockq.h>
 
 #include "play-memchunk.h"
@@ -43,19 +38,24 @@ int pa_play_memchunk(
         const pa_memchunk *chunk,
         pa_cvolume *volume,
         pa_proplist *p,
+        pa_sink_input_flags_t flags,
         uint32_t *sink_input_index) {
 
     pa_memblockq *q;
     int r;
+    pa_memchunk silence;
 
     pa_assert(sink);
     pa_assert(ss);
     pa_assert(chunk);
 
-    q = pa_memblockq_new(0, chunk->length, 0, pa_frame_size(ss), 1, 1, 0, NULL);
+    pa_silence_memchunk_get(&sink->core->silence_cache, sink->core->mempool, &silence, ss, 0);
+    q = pa_memblockq_new("pa_play_memchunk() q", 0, chunk->length, 0, ss, 1, 1, 0, &silence);
+    pa_memblock_unref(silence.memblock);
+
     pa_assert_se(pa_memblockq_push(q, chunk) >= 0);
 
-    if ((r = pa_play_memblockq(sink, ss, map, q, volume, p, sink_input_index)) < 0) {
+    if ((r = pa_play_memblockq(sink, ss, map, q, volume, p, flags, sink_input_index)) < 0) {
         pa_memblockq_free(q);
         return r;
     }
index c813611..068add1 100644 (file)
 #include <pulsecore/memchunk.h>
 
 int pa_play_memchunk(
-    pa_sink *sink,
-    const pa_sample_spec *ss,
-    const pa_channel_map *map,
-    const pa_memchunk *chunk,
-    pa_cvolume *cvolume,
-    pa_proplist *p,
-    uint32_t *sink_input_index);
+        pa_sink *sink,
+        const pa_sample_spec *ss,
+        const pa_channel_map *map,
+        const pa_memchunk *chunk,
+        pa_cvolume *cvolume,
+        pa_proplist *p,
+        pa_sink_input_flags_t flags,
+        uint32_t *sink_input_index);
 
 #endif
similarity index 71%
rename from src/pulsecore/poll.c
rename to src/pulsecore/poll-posix.c
index 46a69c5..cd888b5 100644 (file)
 #include <config.h>
 #endif
 
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
 #include <errno.h>
+#include <fcntl.h>
 
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
 #endif
 
-#include "winsock.h"
-
-#ifndef HAVE_POLL_H
-
+#include <pulsecore/socket.h>
 #include <pulsecore/core-util.h>
+#include <pulse/util.h>
 
 #include "poll.h"
 
-int poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
+/* Mac OSX fails to implement poll() in a working way since 10.4. IOW, for
+ * several years. We need to enable a dirty workaround and emulate that call
+ * with select(), just like for Windows. sic! */
+
+#if !defined(HAVE_POLL_H) || defined(OS_IS_DARWIN)
+
+int pa_poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
     struct timeval tv;
     fd_set rset, wset, xset;
     struct pollfd *f;
     int ready;
     int maxfd = 0;
+#ifdef OS_IS_WIN32
     char data[64];
+#endif
 
     FD_ZERO (&rset);
     FD_ZERO (&wset);
@@ -95,18 +106,22 @@ int poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
     tv.tv_sec = timeout / 1000;
     tv.tv_usec = (timeout % 1000) * 1000;
 
-    ready = select ((SELECT_TYPE_ARG1) maxfd + 1, SELECT_TYPE_ARG234 &rset,
-                    SELECT_TYPE_ARG234 &wset, SELECT_TYPE_ARG234 &xset,
-                    SELECT_TYPE_ARG5 (timeout == -1 ? NULL : &tv));
+    ready = select(maxfd + 1, &rset, &wset, &xset, (timeout == -1 ? NULL : &tv));
+
     if ((ready == -1) && (errno == EBADF)) {
         ready = 0;
+        maxfd = -1;
+
+#ifdef OS_IS_WIN32
+        /*
+         * Windows has no fcntl(), so we have to trick around with more
+         * select() calls to find out what went wrong
+         */
 
         FD_ZERO (&rset);
         FD_ZERO (&wset);
         FD_ZERO (&xset);
 
-        maxfd = -1;
-
         for (f = fds; f < &fds[nfds]; ++f) {
             if (f->fd != -1) {
                 fd_set sngl_rset, sngl_wset, sngl_xset;
@@ -127,9 +142,7 @@ int poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
                     singl_tv.tv_sec = 0;
                     singl_tv.tv_usec = 0;
 
-                    if (select((SELECT_TYPE_ARG1) f->fd, SELECT_TYPE_ARG234 &rset,
-                               SELECT_TYPE_ARG234 &wset, SELECT_TYPE_ARG234 &xset,
-                               SELECT_TYPE_ARG5 &singl_tv) != -1) {
+                    if (select(f->fd, &rset, &wset, &xset, &singl_tv) != -1) {
                         if (f->events & POLLIN)
                             FD_SET (f->fd, &rset);
                         if (f->events & POLLOUT)
@@ -145,13 +158,30 @@ int poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
             }
         }
 
+#else /* !OS_IS_WIN32 */
+
+        for (f = fds; f < &fds[nfds]; f++)
+            if (f->fd != -1) {
+                /* use fcntl() to find out whether the descriptor is valid */
+                if (fcntl(f->fd, F_GETFL) != -1) {
+                    if (f->fd > maxfd && (f->events & (POLLIN|POLLOUT|POLLPRI))) {
+                        maxfd = f->fd;
+                        ready++;
+                    }
+                } else {
+                    FD_CLR(f->fd, &rset);
+                    FD_CLR(f->fd, &wset);
+                    FD_CLR(f->fd, &xset);
+                }
+            }
+
+#endif
+
         if (ready) {
         /* Linux alters the tv struct... but it shouldn't matter here ...
          * as we're going to be a little bit out anyway as we've just eaten
          * more than a couple of cpu cycles above */
-            ready = select ((SELECT_TYPE_ARG1) maxfd + 1, SELECT_TYPE_ARG234 &rset,
-                            SELECT_TYPE_ARG234 &wset, SELECT_TYPE_ARG234 &xset,
-                            SELECT_TYPE_ARG5 (timeout == -1 ? NULL : &tv));
+            ready = select(maxfd + 1, &rset, &wset, &xset, (timeout == -1 ? NULL : &tv));
         }
     }
 
@@ -167,6 +197,18 @@ int poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
                 if (FD_ISSET (f->fd, &rset)) {
                     /* support for POLLHUP.  An hung up descriptor does not
                        increase the return value! */
+#ifdef OS_IS_DARWIN
+                    /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
+                     * for some kinds of descriptors.  Detect if this descriptor is a
+                     * connected socket, a server socket, or something else using a
+                     * 0-byte recv, and use ioctl(2) to detect POLLHUP.  */
+                    int r = recv(f->fd, NULL, 0, MSG_PEEK);
+                    if (r == 0 || (r < 0 && errno == ENOTSOCK))
+                        ioctl(f->fd, FIONREAD, &r);
+
+                    if (r == 0)
+                        f->revents |= POLLHUP;
+#else /* !OS_IS_DARWIN */
                     if (recv (f->fd, data, 64, MSG_PEEK) == -1) {
                         if (errno == ESHUTDOWN || errno == ECONNRESET ||
                             errno == ECONNABORTED || errno == ENETRESET) {
@@ -174,6 +216,7 @@ int poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
                             f->revents |= POLLHUP;
                         }
                     }
+#endif
 
                     if (f->revents == 0)
                         f->revents |= POLLIN;
diff --git a/src/pulsecore/poll-win32.c b/src/pulsecore/poll-win32.c
new file mode 100644 (file)
index 0000000..4256ed7
--- /dev/null
@@ -0,0 +1,639 @@
+
+/* Emulation for poll(2)
+   Contributed by Paolo Bonzini.
+
+   Copyright 2001-2003, 2006-2012 Free Software Foundation, Inc.
+
+   This file is part of gnulib.
+
+   This program 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, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License along
+   with this program; if not, see <http://www.gnu.org/licenses/>.  */
+
+/* Tell gcc not to warn about the (nfd < 0) tests, below.  */
+#if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__
+# pragma GCC diagnostic ignored "-Wtype-limits"
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <malloc.h>
+
+#include <sys/types.h>
+
+/* Specification.  */
+#include "poll.h"
+typedef unsigned long nfds_t;
+
+#include <errno.h>
+#include <limits.h>
+#include <assert.h>
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+# define WINDOWS_NATIVE
+# include <winsock2.h>
+# include <windows.h>
+# include <io.h>
+# include <stdio.h>
+# include <conio.h>
+# if 0
+# include "msvc-nothrow.h"
+# endif
+#else
+# include <sys/time.h>
+# include <sys/socket.h>
+# include <sys/select.h>
+# include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include <sys/filio.h>
+#endif
+
+#include <time.h>
+
+#ifndef INFTIM
+# define INFTIM (-1)
+#endif
+
+/* BeOS does not have MSG_PEEK.  */
+#ifndef MSG_PEEK
+# define MSG_PEEK 0
+#endif
+
+#ifndef POLLRDNORM
+# define POLLRDNORM  0
+# define POLLRDBAND  0
+# define POLLWRNORM  0
+# define POLLWRBAND  0
+#endif
+
+#ifdef WINDOWS_NATIVE
+
+/* Optimized test whether a HANDLE refers to a console.
+   See <http://lists.gnu.org/archive/html/bug-gnulib/2009-08/msg00065.html>.  */
+#define IsConsoleHandle(h) (((intptr_t) (h) & 3) == 3)
+
+static BOOL
+IsSocketHandle (HANDLE h)
+{
+  WSANETWORKEVENTS ev;
+
+  if (IsConsoleHandle (h))
+    return FALSE;
+
+  /* Under Wine, it seems that getsockopt returns 0 for pipes too.
+     WSAEnumNetworkEvents instead distinguishes the two correctly.  */
+  ev.lNetworkEvents = 0xDEADBEEFl;
+  WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
+  return ev.lNetworkEvents != 0xDEADBEEFl;
+}
+
+static HANDLE
+HandleFromFd (int fd)
+{
+  /* since socket() returns a HANDLE already, try that first */
+  if (IsSocketHandle((HANDLE) fd))
+    return ((HANDLE) fd);
+
+  return ((HANDLE) _get_osfhandle(fd));
+}
+
+/* Declare data structures for ntdll functions.  */
+typedef struct _FILE_PIPE_LOCAL_INFORMATION {
+  ULONG NamedPipeType;
+  ULONG NamedPipeConfiguration;
+  ULONG MaximumInstances;
+  ULONG CurrentInstances;
+  ULONG InboundQuota;
+  ULONG ReadDataAvailable;
+  ULONG OutboundQuota;
+  ULONG WriteQuotaAvailable;
+  ULONG NamedPipeState;
+  ULONG NamedPipeEnd;
+} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
+
+typedef struct _IO_STATUS_BLOCK
+{
+  union {
+    DWORD Status;
+    PVOID Pointer;
+  } u;
+  ULONG_PTR Information;
+} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
+
+typedef enum _FILE_INFORMATION_CLASS {
+  FilePipeLocalInformation = 24
+} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
+
+typedef DWORD (WINAPI *PNtQueryInformationFile)
+         (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
+
+# ifndef PIPE_BUF
+#  define PIPE_BUF      512
+# endif
+
+/* Compute revents values for file handle H.  If some events cannot happen
+   for the handle, eliminate them from *P_SOUGHT.  */
+
+static int
+windows_compute_revents (HANDLE h, int *p_sought)
+{
+  int i, ret, happened;
+  INPUT_RECORD *irbuffer;
+  DWORD avail, nbuffer;
+  BOOL bRet;
+  IO_STATUS_BLOCK iosb;
+  FILE_PIPE_LOCAL_INFORMATION fpli;
+  static PNtQueryInformationFile NtQueryInformationFile;
+  static BOOL once_only;
+
+  switch (GetFileType (h))
+    {
+    case FILE_TYPE_PIPE:
+      if (!once_only)
+        {
+          NtQueryInformationFile = (PNtQueryInformationFile)
+            GetProcAddress (GetModuleHandle ("ntdll.dll"),
+                            "NtQueryInformationFile");
+          once_only = TRUE;
+        }
+
+      happened = 0;
+      if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
+        {
+          if (avail)
+            happened |= *p_sought & (POLLIN | POLLRDNORM);
+        }
+      else if (GetLastError () == ERROR_BROKEN_PIPE)
+        happened |= POLLHUP;
+
+      else
+        {
+          /* It was the write-end of the pipe.  Check if it is writable.
+             If NtQueryInformationFile fails, optimistically assume the pipe is
+             writable.  This could happen on Windows 9x, where
+             NtQueryInformationFile is not available, or if we inherit a pipe
+             that doesn't permit FILE_READ_ATTRIBUTES access on the write end
+             (I think this should not happen since Windows XP SP2; WINE seems
+             fine too).  Otherwise, ensure that enough space is available for
+             atomic writes.  */
+          memset (&iosb, 0, sizeof (iosb));
+          memset (&fpli, 0, sizeof (fpli));
+
+          if (!NtQueryInformationFile
+              || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
+                                         FilePipeLocalInformation)
+              || fpli.WriteQuotaAvailable >= PIPE_BUF
+              || (fpli.OutboundQuota < PIPE_BUF &&
+                  fpli.WriteQuotaAvailable == fpli.OutboundQuota))
+            happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
+        }
+      return happened;
+
+    case FILE_TYPE_CHAR:
+      ret = WaitForSingleObject (h, 0);
+      if (!IsConsoleHandle (h))
+        return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
+
+      nbuffer = avail = 0;
+      bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
+      if (bRet)
+        {
+          /* Input buffer.  */
+          *p_sought &= POLLIN | POLLRDNORM;
+          if (nbuffer == 0)
+            return POLLHUP;
+          if (!*p_sought)
+            return 0;
+
+          irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
+          bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
+          if (!bRet || avail == 0)
+            return POLLHUP;
+
+          for (i = 0; i < avail; i++)
+            if (irbuffer[i].EventType == KEY_EVENT)
+              return *p_sought;
+          return 0;
+        }
+      else
+        {
+          /* Screen buffer.  */
+          *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
+          return *p_sought;
+        }
+
+    default:
+      ret = WaitForSingleObject (h, 0);
+      if (ret == WAIT_OBJECT_0)
+        return *p_sought & ~(POLLPRI | POLLRDBAND);
+
+      return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
+    }
+}
+
+/* Convert fd_sets returned by select into revents values.  */
+
+static int
+windows_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
+{
+  int happened = 0;
+
+  if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)
+    happened |= (POLLIN | POLLRDNORM) & sought;
+
+  else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
+    {
+      int r, error;
+
+      char data[64];
+      WSASetLastError (0);
+      r = recv (h, data, sizeof (data), MSG_PEEK);
+      error = WSAGetLastError ();
+      WSASetLastError (0);
+
+      if (r > 0 || error == WSAENOTCONN)
+        happened |= (POLLIN | POLLRDNORM) & sought;
+
+      /* Distinguish hung-up sockets from other errors.  */
+      else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
+               || error == WSAECONNABORTED || error == WSAENETRESET)
+        happened |= POLLHUP;
+
+      else
+        happened |= POLLERR;
+    }
+
+  if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
+    happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
+
+  if (lNetworkEvents & FD_OOB)
+    happened |= (POLLPRI | POLLRDBAND) & sought;
+
+  return happened;
+}
+
+#else /* !MinGW */
+
+/* Convert select(2) returned fd_sets into poll(2) revents values.  */
+static int
+compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
+{
+  int happened = 0;
+  if (FD_ISSET (fd, rfds))
+    {
+      int r;
+      int socket_errno;
+
+# if defined __MACH__ && defined __APPLE__
+      /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
+         for some kinds of descriptors.  Detect if this descriptor is a
+         connected socket, a server socket, or something else using a
+         0-byte recv, and use ioctl(2) to detect POLLHUP.  */
+      r = recv (fd, NULL, 0, MSG_PEEK);
+      socket_errno = (r < 0) ? errno : 0;
+      if (r == 0 || socket_errno == ENOTSOCK)
+        ioctl (fd, FIONREAD, &r);
+# else
+      char data[64];
+      r = recv (fd, data, sizeof (data), MSG_PEEK);
+      socket_errno = (r < 0) ? errno : 0;
+# endif
+      if (r == 0)
+        happened |= POLLHUP;
+
+      /* If the event happened on an unconnected server socket,
+         that's fine. */
+      else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
+        happened |= (POLLIN | POLLRDNORM) & sought;
+
+      /* Distinguish hung-up sockets from other errors.  */
+      else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
+               || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
+        happened |= POLLHUP;
+
+      /* some systems can't use recv() on non-socket, including HP NonStop */
+      else if (socket_errno == ENOTSOCK)
+        happened |= (POLLIN | POLLRDNORM) & sought;
+
+      else
+        happened |= POLLERR;
+    }
+
+  if (FD_ISSET (fd, wfds))
+    happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
+
+  if (FD_ISSET (fd, efds))
+    happened |= (POLLPRI | POLLRDBAND) & sought;
+
+  return happened;
+}
+#endif /* !MinGW */
+
+int
+pa_poll (struct pollfd *pfd, nfds_t nfd, int timeout)
+{
+  struct timeval tv;
+  struct timeval *ptv;
+#ifndef WINDOWS_NATIVE
+  fd_set rfds, wfds, efds;
+  int maxfd, rc;
+  nfds_t i;
+
+# ifdef _SC_OPEN_MAX
+  static int sc_open_max = -1;
+
+  if (nfd < 0
+      || (nfd > sc_open_max
+          && (sc_open_max != -1
+              || nfd > (sc_open_max = sysconf (_SC_OPEN_MAX)))))
+    {
+      errno = EINVAL;
+      return -1;
+    }
+# else /* !_SC_OPEN_MAX */
+#  ifdef OPEN_MAX
+  if (nfd < 0 || nfd > OPEN_MAX)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+#  endif /* OPEN_MAX -- else, no check is needed */
+# endif /* !_SC_OPEN_MAX */
+#else /* WINDOWS_NATIVE*/
+  static HANDLE hEvent;
+  WSANETWORKEVENTS ev;
+  HANDLE h, handle_array[FD_SETSIZE + 2];
+  DWORD ret, wait_timeout, nhandles;
+  fd_set rfds, wfds, xfds;
+  BOOL poll_again;
+  MSG msg;
+  int rc = 0;
+  nfds_t i;
+#endif
+
+  /* EFAULT is not necessary to implement, but let's do it in the
+     simplest case. */
+  if (!pfd && nfd)
+    {
+      errno = EFAULT;
+      return -1;
+    }
+
+  /* convert timeout number into a timeval structure */
+  if (timeout == 0)
+    {
+      ptv = &tv;
+      ptv->tv_sec = 0;
+      ptv->tv_usec = 0;
+    }
+  else if (timeout > 0)
+    {
+      ptv = &tv;
+      ptv->tv_sec = timeout / 1000;
+      ptv->tv_usec = (timeout % 1000) * 1000;
+    }
+  else if (timeout == INFTIM)
+    /* wait forever */
+    ptv = NULL;
+  else
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+#ifndef WINDOWS_NATIVE
+  /* create fd sets and determine max fd */
+  maxfd = -1;
+  FD_ZERO (&rfds);
+  FD_ZERO (&wfds);
+  FD_ZERO (&efds);
+  for (i = 0; i < nfd; i++)
+    {
+      if (pfd[i].fd < 0)
+        continue;
+
+      if (pfd[i].events & (POLLIN | POLLRDNORM))
+        FD_SET (pfd[i].fd, &rfds);
+
+      /* see select(2): "the only exceptional condition detectable
+         is out-of-band data received on a socket", hence we push
+         POLLWRBAND events onto wfds instead of efds. */
+      if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND))
+        FD_SET (pfd[i].fd, &wfds);
+      if (pfd[i].events & (POLLPRI | POLLRDBAND))
+        FD_SET (pfd[i].fd, &efds);
+      if (pfd[i].fd >= maxfd
+          && (pfd[i].events & (POLLIN | POLLOUT | POLLPRI
+                               | POLLRDNORM | POLLRDBAND
+                               | POLLWRNORM | POLLWRBAND)))
+        {
+          maxfd = pfd[i].fd;
+          if (maxfd > FD_SETSIZE)
+            {
+              errno = EOVERFLOW;
+              return -1;
+            }
+        }
+    }
+
+  /* examine fd sets */
+  rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv);
+  if (rc < 0)
+    return rc;
+
+  /* establish results */
+  rc = 0;
+  for (i = 0; i < nfd; i++)
+    if (pfd[i].fd < 0)
+      pfd[i].revents = 0;
+    else
+      {
+        int happened = compute_revents (pfd[i].fd, pfd[i].events,
+                                        &rfds, &wfds, &efds);
+        if (happened)
+          {
+            pfd[i].revents = happened;
+            rc++;
+          }
+      }
+
+  return rc;
+#else
+
+  if (!hEvent)
+    hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
+
+restart:
+  handle_array[0] = hEvent;
+  nhandles = 1;
+  FD_ZERO (&rfds);
+  FD_ZERO (&wfds);
+  FD_ZERO (&xfds);
+
+  /* Classify socket handles and create fd sets. */
+  for (i = 0; i < nfd; i++)
+    {
+      int sought = pfd[i].events;
+      pfd[i].revents = 0;
+      if (pfd[i].fd < 0)
+        continue;
+      if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
+                      | POLLPRI | POLLRDBAND)))
+        continue;
+
+      h = HandleFromFd (pfd[i].fd);
+      assert (h != NULL && h != INVALID_HANDLE_VALUE);
+      if (IsSocketHandle (h))
+        {
+          int requested = FD_CLOSE;
+
+          /* see above; socket handles are mapped onto select.  */
+          if (sought & (POLLIN | POLLRDNORM))
+            {
+              requested |= FD_READ | FD_ACCEPT;
+              FD_SET ((SOCKET) h, &rfds);
+            }
+          if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
+            {
+              requested |= FD_WRITE | FD_CONNECT;
+              FD_SET ((SOCKET) h, &wfds);
+            }
+          if (sought & (POLLPRI | POLLRDBAND))
+            {
+              requested |= FD_OOB;
+              FD_SET ((SOCKET) h, &xfds);
+            }
+
+          if (requested)
+            WSAEventSelect ((SOCKET) h, hEvent, requested);
+        }
+      else
+        {
+          /* Poll now.  If we get an event, do not poll again.  Also,
+             screen buffer handles are waitable, and they'll block until
+             a character is available.  windows_compute_revents eliminates
+             bits for the "wrong" direction. */
+          pfd[i].revents = windows_compute_revents (h, &sought);
+          if (sought)
+            handle_array[nhandles++] = h;
+          if (pfd[i].revents)
+            timeout = 0;
+          else
+            {
+              if (!ptv)
+                ptv = &tv;
+              /* tune down to 0.25s. But don't touch smaller timeouts */
+              if (ptv->tv_usec > 250*1000 || ptv->tv_sec > 0)
+                ptv->tv_usec = 250*1000;
+              ptv->tv_sec = 0;
+            }
+        }
+    }
+
+  if (select (0, &rfds, &wfds, &xfds, ptv) > 0)
+    {
+      /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
+         no need to call select again.  */
+      poll_again = FALSE;
+      wait_timeout = 0;
+    }
+  else
+    {
+      poll_again = TRUE;
+      if (timeout == INFTIM)
+        wait_timeout = INFINITE;
+      else
+        wait_timeout = timeout;
+    }
+
+  for (;;)
+    {
+      ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
+                                       wait_timeout, QS_ALLINPUT);
+
+      if (ret == WAIT_OBJECT_0 + nhandles)
+        {
+          /* new input of some other kind */
+          BOOL bRet;
+          while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
+            {
+              TranslateMessage (&msg);
+              DispatchMessage (&msg);
+            }
+        }
+      else
+        break;
+    }
+
+  if (poll_again)
+    select (0, &rfds, &wfds, &xfds, ptv);
+
+  /* Place a sentinel at the end of the array.  */
+  handle_array[nhandles] = NULL;
+  nhandles = 1;
+  for (i = 0; i < nfd; i++)
+    {
+      int happened;
+
+      if (pfd[i].fd < 0)
+        continue;
+      if (!(pfd[i].events & (POLLIN | POLLRDNORM |
+                             POLLOUT | POLLWRNORM | POLLWRBAND)))
+        continue;
+
+      h = (HANDLE) HandleFromFd (pfd[i].fd);
+      if (h != handle_array[nhandles])
+        {
+          /* It's a socket.  */
+          WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
+          WSAEventSelect ((SOCKET) h, 0, 0);
+
+          /* If we're lucky, WSAEnumNetworkEvents already provided a way
+             to distinguish FD_READ and FD_ACCEPT; this saves a recv later.  */
+          if (FD_ISSET ((SOCKET) h, &rfds)
+              && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
+            ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
+          if (FD_ISSET ((SOCKET) h, &wfds))
+            ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
+          if (FD_ISSET ((SOCKET) h, &xfds))
+            ev.lNetworkEvents |= FD_OOB;
+
+          happened = windows_compute_revents_socket ((SOCKET) h, pfd[i].events,
+                                                     ev.lNetworkEvents);
+        }
+      else
+        {
+          /* Not a socket.  */
+          int sought = pfd[i].events;
+          happened = windows_compute_revents (h, &sought);
+          nhandles++;
+        }
+
+       if ((pfd[i].revents |= happened) != 0)
+        rc++;
+    }
+
+  if (!rc && timeout == INFTIM)
+    {
+      SleepEx (1, TRUE);
+      goto restart;
+    }
+
+  return rc;
+#endif
+}
index fe0c6af..dc741e5 100644 (file)
    Copyright (C) 1994,96,97,98,99,2000,2001,2004 Free Software Foundation, Inc.
 ***/
 
+#if defined(HAVE_POLL_H)
+#include <poll.h>
+#else
+
 /* Event types that can be polled for.  These bits may be set in `events'
    to indicate the interesting event types; they will appear in `revents'
    to indicate the status of the file descriptor.  */
 #define POLLHUP         0x010           /* Hung up.  */
 #define POLLNVAL        0x020           /* Invalid polling request.  */
 
-
-/* Type used for the number of file descriptors.  */
-typedef unsigned long int nfds_t;
-
 /* Data structure describing a polling request.  */
-struct pollfd
-  {
+struct pollfd {
     int fd;                     /* File descriptor to poll.  */
     short int events;           /* Types of events poller cares about.  */
     short int revents;          /* Types of events that actually occurred.  */
-  };
+};
+
 
 /* Poll the file descriptors described by the NFDS structures starting at
    FDS.  If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for
    an event to occur; if TIMEOUT is -1, block until an event occurs.
    Returns the number of file descriptors with events, zero if timed out,
    or -1 for errors.  */
-extern int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout);
+
+#endif /* HAVE_POLL_H */
+
+#if defined(HAVE_POLL_H) && !defined(OS_IS_DARWIN)
+#define pa_poll(fds,nfds,timeout) poll((fds),(nfds),(timeout))
+#else
+int pa_poll(struct pollfd *fds, unsigned long nfds, int timeout);
+#endif
diff --git a/src/pulsecore/prioq.c b/src/pulsecore/prioq.c
deleted file mode 100644 (file)
index 983db0f..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2008 Lennart Poettering
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2.1 of the License,
-  or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <pulse/xmalloc.h>
-
-#include <pulsecore/flist.h>
-
-#include "prioq.h"
-
-struct pa_prioq_item {
-    void *value;
-    unsigned idx;
-};
-
-struct pa_prioq {
-    pa_prioq_item **items;
-    unsigned n_items;
-    unsigned n_allocated;
-    pa_compare_func_t compare_func;
-};
-
-PA_STATIC_FLIST_DECLARE(items, 0, pa_xfree);
-
-pa_prioq *pa_prioq_new(pa_compare_func_t compare_func) {
-
-    pa_prioq *q;
-
-    q = pa_xnew(pa_prioq, 1);
-    q->compare_func = compare_func;
-    q->n_items = 0;
-    q->n_allocated = 64;
-    q->items = pa_xnew(pa_prioq_item*, q->n_allocated);
-
-    return q;
-}
-
-void pa_prioq_free(pa_prioq *q, pa_free2_cb_t free_cb, void *userdata) {
-    pa_prioq_item **i, **e;
-
-    pa_assert(q);
-
-    for (i = q->items, e = q->items + q->n_items; i < e; i++) {
-
-        if (!*i)
-            continue;
-
-        if (free_cb)
-            free_cb((*i)->value, userdata);
-
-        pa_xfree(*i);
-    }
-
-    pa_xfree(q->items);
-    pa_xfree(q);
-}
-
-static void shuffle_up(pa_prioq *q, pa_prioq_item *i) {
-    unsigned j;
-
-    pa_assert(q);
-    pa_assert(i);
-
-    j = i->idx;
-
-    while (j > 0) {
-        unsigned k;
-
-        k = (j-1)/2;
-
-        if (q->compare_func(q->items[k]->value, i->value) < 0)
-            break;
-
-        q->items[k]->idx = j;
-        q->items[j] = q->items[k];
-
-        j = k;
-    }
-
-    i->idx = j;
-    q->items[j] = i;
-
-}
-
-pa_prioq_item* pa_prioq_put(pa_prioq *q, void *p) {
-    pa_prioq_item *i;
-
-    pa_assert(q);
-
-    if (q->n_items >= q->n_allocated) {
-        q->n_allocated = PA_MAX(q->n_items+1, q->n_allocated)*2;
-        q->items = pa_xrealloc(q->items, sizeof(pa_prioq_item*) * q->n_allocated);
-    }
-
-    if (!(i = pa_flist_pop(PA_STATIC_FLIST_GET(items))))
-        i = pa_xnew(pa_prioq_item, 1);
-
-    i->value = p;
-    i->idx = q->n_items++;
-
-    shuffle_up(q, i);
-
-    return i;
-}
-
-void* pa_prioq_peek(pa_prioq *q) {
-    pa_assert(q);
-
-    if (q->n_items <= 0)
-        return NULL;
-
-    return q->items[0]->value;
-}
-
-void* pa_prioq_pop(pa_prioq *q){
-    pa_assert(q);
-
-    if (q->n_items <= 0)
-        return NULL;
-
-    return pa_prioq_remove(q, q->items[0]);
-}
-
-static void swap(pa_prioq *q, unsigned j, unsigned k) {
-    pa_prioq_item *t;
-
-    pa_assert(q);
-    pa_assert(j < q->n_items);
-    pa_assert(k < q->n_items);
-
-    pa_assert(q->items[j]->idx == j);
-    pa_assert(q->items[k]->idx == k);
-
-    t = q->items[j];
-
-    q->items[j]->idx = k;
-    q->items[j] = q->items[k];
-
-    q->items[k]->idx = j;
-    q->items[k] = t;
-}
-
-static void shuffle_down(pa_prioq *q, unsigned idx) {
-
-    pa_assert(q);
-    pa_assert(idx < q->n_items);
-
-    for (;;) {
-        unsigned j, k, s;
-
-        k = (idx+1)*2; /* right child */
-        j = k-1;       /* left child */
-
-        if (j >= q->n_items)
-            break;
-
-        if (q->compare_func(q->items[j]->value, q->items[idx]->value) < 0)
-
-            /* So our left child is smaller than we are, let's
-             * remember this fact */
-            s = j;
-        else
-            s = idx;
-
-        if (k < q->n_items &&
-            q->compare_func(q->items[k]->value, q->items[s]->value) < 0)
-
-            /* So our right child is smaller than we are, let's
-             * remember this fact */
-            s = k;
-
-        /* s now points to the smallest of the three items */
-
-        if (s == idx)
-            /* No swap necessary, we're done */
-            break;
-
-        swap(q, idx, s);
-        idx = s;
-    }
-}
-
-void* pa_prioq_remove(pa_prioq *q, pa_prioq_item *i) {
-    void *p;
-
-    pa_assert(q);
-    pa_assert(i);
-    pa_assert(q->n_items >= 1);
-
-    p = i->value;
-
-    if (q->n_items-1 == i->idx) {
-        /* We are the last entry, so let's just remove us and good */
-        q->n_items--;
-
-    } else {
-
-        /* We are not the last entry, we need to replace ourselves
-         * with the last node and reshuffle */
-
-        q->items[i->idx] = q->items[q->n_items-1];
-        q->items[i->idx]->idx = i->idx;
-        q->n_items--;
-
-        shuffle_down(q, i->idx);
-    }
-
-    if (pa_flist_push(PA_STATIC_FLIST_GET(items), i) < 0)
-        pa_xfree(i);
-
-    return p;
-}
-
-unsigned pa_prioq_size(pa_prioq *q) {
-    pa_assert(q);
-
-    return q->n_items;
-}
-
-pa_bool_t pa_prioq_isempty(pa_prioq *q) {
-    pa_assert(q);
-
-    return q->n_items == 0;
-}
-
-void pa_prioq_reshuffle(pa_prioq *q, pa_prioq_item *i) {
-    pa_assert(q);
-    pa_assert(i);
-
-    /* This will move the entry down as far as necessary */
-    shuffle_down(q, i->idx);
-
-    /* And this will move the entry up as far as necessary */
-    shuffle_up(q, i);
-}
diff --git a/src/pulsecore/prioq.h b/src/pulsecore/prioq.h
deleted file mode 100644 (file)
index fd3550b..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef foopulsecoreprioqhfoo
-#define foopulsecoreprioqhfoo
-
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2008 Lennart Poettering
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as
-  published by the Free Software Foundation; either version 2.1 of the
-  License, or (at your option) any later version.
-
-  PulseAudio is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with PulseAudio; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <inttypes.h>
-
-#include <pulsecore/macro.h>
-#include <pulsecore/idxset.h>
-
-/* A heap-based priority queue. Removal and insertion is O(log
- * n). Removal can happen a the top or at any position referenced by a
- * pa_prioq_item.  */
-
-typedef struct pa_prioq pa_prioq;
-typedef struct pa_prioq_item pa_prioq_item;
-
-/* Instantiate a new prioq with the specified comparison functions */
-pa_prioq* pa_prioq_new(pa_compare_func_t compare_func);
-
-/* Free the prioq. When the prioq is not empty the specified function is called for every entry contained */
-void pa_prioq_free(pa_prioq *q, pa_free2_cb_t free_cb, void *userdata);
-
-/* Store a new item in the prioq. */
-pa_prioq_item* pa_prioq_put(pa_prioq *q, void* data);
-
-/* Get the item on the top of the queue, but don't remove it from the queue*/
-void* pa_prioq_peek(pa_prioq*q);
-
-/* Get the item on the top of the queue, and remove it from thq queue */
-void* pa_prioq_pop(pa_prioq*q);
-
-/* Remove an arbitrary from theq prioq, returning it's data */
-void* pa_prioq_remove(pa_prioq*q, pa_prioq_item *i);
-
-/* The priority of an item was modified. Adjustthe queue to that */
-void pa_prioq_reshuffle(pa_prioq *q, pa_prioq_item *i);
-
-/* Return the current number of items in the prioq */
-unsigned pa_prioq_size(pa_prioq*s);
-
-/* Return TRUE of the prioq is empty */
-pa_bool_t pa_prioq_isempty(pa_prioq *s);
-
-#endif
index 23864bc..f447431 100644 (file)
 
 #include <string.h>
 #include <locale.h>
-#include <dlfcn.h>
+
+#ifdef ENABLE_NLS
+#include <libintl.h>
+#endif
 
 #ifdef __APPLE__
 #include <crt_externs.h>
@@ -241,3 +244,33 @@ void pa_init_proplist(pa_proplist *p) {
         }
     }
 }
+
+char *pa_proplist_get_stream_group(pa_proplist *p, const char *prefix, const char *cache) {
+    const char *r;
+    char *t;
+
+    if (!p)
+        return NULL;
+
+    if (cache && (r = pa_proplist_gets(p, cache)))
+        return pa_xstrdup(r);
+
+    if (!prefix)
+        prefix = "stream";
+
+    if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_ROLE)))
+        t = pa_sprintf_malloc("%s-by-media-role:%s", prefix, r);
+    else if ((r = pa_proplist_gets(p, PA_PROP_APPLICATION_ID)))
+        t = pa_sprintf_malloc("%s-by-application-id:%s", prefix, r);
+    else if ((r = pa_proplist_gets(p, PA_PROP_APPLICATION_NAME)))
+        t = pa_sprintf_malloc("%s-by-application-name:%s", prefix, r);
+    else if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_NAME)))
+        t = pa_sprintf_malloc("%s-by-media-name:%s", prefix, r);
+    else
+        t = pa_sprintf_malloc("%s-fallback:%s", prefix, r);
+
+    if (cache)
+        pa_proplist_sets(p, cache, t);
+
+    return t;
+}
index c6bdc10..3d08776 100644 (file)
@@ -25,5 +25,6 @@
 #include <pulse/proplist.h>
 
 void pa_init_proplist(pa_proplist *p);
+char *pa_proplist_get_stream_group(pa_proplist *pl, const char *prefix, const char *cache);
 
 #endif
index da64874..cc6eeee 100644 (file)
@@ -134,7 +134,7 @@ void pa_cli_protocol_unref(pa_cli_protocol *p) {
     while ((c = pa_idxset_first(p->connections, NULL)))
         cli_unlink(p, c);
 
-    pa_idxset_free(p->connections, NULL, NULL);
+    pa_idxset_free(p->connections, NULL);
 
     pa_assert_se(pa_shared_remove(p->core, "cli-protocol") >= 0);
 
diff --git a/src/pulsecore/protocol-dbus.c b/src/pulsecore/protocol-dbus.c
new file mode 100644 (file)
index 0000000..df2e483
--- /dev/null
@@ -0,0 +1,1140 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dbus/dbus.h>
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-util.h>
+#include <pulsecore/hashmap.h>
+#include <pulsecore/idxset.h>
+#include <pulsecore/shared.h>
+#include <pulsecore/strbuf.h>
+
+#include "protocol-dbus.h"
+
+struct pa_dbus_protocol {
+    PA_REFCNT_DECLARE;
+
+    pa_core *core;
+    pa_hashmap *objects; /* Object path -> struct object_entry */
+    pa_hashmap *connections; /* DBusConnection -> struct connection_entry */
+    pa_idxset *extensions; /* Strings */
+
+    pa_hook hooks[PA_DBUS_PROTOCOL_HOOK_MAX];
+};
+
+struct object_entry {
+    char *path;
+    pa_hashmap *interfaces; /* Interface name -> struct interface_entry */
+    char *introspection;
+};
+
+struct connection_entry {
+    DBusConnection *connection;
+    pa_client *client;
+
+    pa_bool_t listening_for_all_signals;
+
+    /* Contains object paths. If this is empty, then signals from all objects
+     * are accepted. Only used when listening_for_all_signals == TRUE. */
+    pa_idxset *all_signals_objects;
+
+    /* Signal name -> signal paths entry. The entries contain object paths. If
+     * a path set is empty, then that signal is accepted from all objects. This
+     * variable is only used when listening_for_all_signals == FALSE. */
+    pa_hashmap *listening_signals;
+};
+
+/* Only used in connection entries' listening_signals hashmap. */
+struct signal_paths_entry {
+    char *signal;
+    pa_idxset *paths;
+};
+
+struct interface_entry {
+    char *name;
+    pa_hashmap *method_handlers;
+    pa_hashmap *method_signatures; /* Derived from method_handlers. Contains only "in" arguments. */
+    pa_hashmap *property_handlers;
+    pa_dbus_receive_cb_t get_all_properties_cb;
+    pa_dbus_signal_info *signals;
+    unsigned n_signals;
+    void *userdata;
+};
+
+char *pa_get_dbus_address_from_server_type(pa_server_type_t server_type) {
+    char *address = NULL;
+    char *runtime_path = NULL;
+    char *escaped_path = NULL;
+
+    switch (server_type) {
+        case PA_SERVER_TYPE_USER:
+            pa_assert_se((runtime_path = pa_runtime_path(PA_DBUS_SOCKET_NAME)));
+            pa_assert_se((escaped_path = dbus_address_escape_value(runtime_path)));
+            address = pa_sprintf_malloc("unix:path=%s", escaped_path);
+            break;
+
+        case PA_SERVER_TYPE_SYSTEM:
+            pa_assert_se((escaped_path = dbus_address_escape_value(PA_DBUS_SYSTEM_SOCKET_PATH)));
+            address = pa_sprintf_malloc("unix:path=%s", escaped_path);
+            break;
+
+        case PA_SERVER_TYPE_NONE:
+            address = pa_xnew0(char, 1);
+            break;
+
+        default:
+            pa_assert_not_reached();
+    }
+
+    pa_xfree(runtime_path);
+    dbus_free(escaped_path);
+
+    return address;
+}
+
+static pa_dbus_protocol *dbus_protocol_new(pa_core *c) {
+    pa_dbus_protocol *p;
+    unsigned i;
+
+    pa_assert(c);
+
+    p = pa_xnew(pa_dbus_protocol, 1);
+    PA_REFCNT_INIT(p);
+    p->core = c;
+    p->objects = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    p->connections = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+    p->extensions = pa_idxset_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+
+    for (i = 0; i < PA_DBUS_PROTOCOL_HOOK_MAX; ++i)
+        pa_hook_init(&p->hooks[i], p);
+
+    pa_assert_se(pa_shared_set(c, "dbus-protocol", p) >= 0);
+
+    return p;
+}
+
+pa_dbus_protocol* pa_dbus_protocol_get(pa_core *c) {
+    pa_dbus_protocol *p;
+
+    if ((p = pa_shared_get(c, "dbus-protocol")))
+        return pa_dbus_protocol_ref(p);
+
+    return dbus_protocol_new(c);
+}
+
+pa_dbus_protocol* pa_dbus_protocol_ref(pa_dbus_protocol *p) {
+    pa_assert(p);
+    pa_assert(PA_REFCNT_VALUE(p) >= 1);
+
+    PA_REFCNT_INC(p);
+
+    return p;
+}
+
+void pa_dbus_protocol_unref(pa_dbus_protocol *p) {
+    unsigned i;
+
+    pa_assert(p);
+    pa_assert(PA_REFCNT_VALUE(p) >= 1);
+
+    if (PA_REFCNT_DEC(p) > 0)
+        return;
+
+    pa_assert(pa_hashmap_isempty(p->objects));
+    pa_assert(pa_hashmap_isempty(p->connections));
+    pa_assert(pa_idxset_isempty(p->extensions));
+
+    pa_hashmap_free(p->objects, NULL);
+    pa_hashmap_free(p->connections, NULL);
+    pa_idxset_free(p->extensions, NULL);
+
+    for (i = 0; i < PA_DBUS_PROTOCOL_HOOK_MAX; ++i)
+        pa_hook_done(&p->hooks[i]);
+
+    pa_assert_se(pa_shared_remove(p->core, "dbus-protocol") >= 0);
+
+    pa_xfree(p);
+}
+
+static void update_introspection(struct object_entry *oe) {
+    pa_strbuf *buf;
+    void *interfaces_state = NULL;
+    struct interface_entry *iface_entry = NULL;
+
+    pa_assert(oe);
+
+    buf = pa_strbuf_new();
+    pa_strbuf_puts(buf, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE);
+    pa_strbuf_puts(buf, "<node>\n");
+
+    PA_HASHMAP_FOREACH(iface_entry, oe->interfaces, interfaces_state) {
+        pa_dbus_method_handler *method_handler;
+        pa_dbus_property_handler *property_handler;
+        void *handlers_state = NULL;
+        unsigned i;
+        unsigned j;
+
+        pa_strbuf_printf(buf, " <interface name=\"%s\">\n", iface_entry->name);
+
+        PA_HASHMAP_FOREACH(method_handler, iface_entry->method_handlers, handlers_state) {
+            pa_strbuf_printf(buf, "  <method name=\"%s\">\n", method_handler->method_name);
+
+            for (i = 0; i < method_handler->n_arguments; ++i)
+                pa_strbuf_printf(buf, "   <arg name=\"%s\" type=\"%s\" direction=\"%s\"/>\n",
+                                 method_handler->arguments[i].name,
+                                 method_handler->arguments[i].type,
+                                 method_handler->arguments[i].direction);
+
+            pa_strbuf_puts(buf, "  </method>\n");
+        }
+
+        handlers_state = NULL;
+
+        PA_HASHMAP_FOREACH(property_handler, iface_entry->property_handlers, handlers_state)
+            pa_strbuf_printf(buf, "  <property name=\"%s\" type=\"%s\" access=\"%s\"/>\n",
+                             property_handler->property_name,
+                             property_handler->type,
+                             property_handler->get_cb ? (property_handler->set_cb ? "readwrite" : "read") : "write");
+
+        for (i = 0; i < iface_entry->n_signals; ++i) {
+            pa_strbuf_printf(buf, "  <signal name=\"%s\">\n", iface_entry->signals[i].name);
+
+            for (j = 0; j < iface_entry->signals[i].n_arguments; ++j)
+                pa_strbuf_printf(buf, "   <arg name=\"%s\" type=\"%s\"/>\n", iface_entry->signals[i].arguments[j].name,
+                                                                             iface_entry->signals[i].arguments[j].type);
+
+            pa_strbuf_puts(buf, "  </signal>\n");
+        }
+
+        pa_strbuf_puts(buf, " </interface>\n");
+    }
+
+    pa_strbuf_puts(buf, " <interface name=\"" DBUS_INTERFACE_INTROSPECTABLE "\">\n"
+                        "  <method name=\"Introspect\">\n"
+                        "   <arg name=\"data\" type=\"s\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        " </interface>\n"
+                        " <interface name=\"" DBUS_INTERFACE_PROPERTIES "\">\n"
+                        "  <method name=\"Get\">\n"
+                        "   <arg name=\"interface_name\" type=\"s\" direction=\"in\"/>\n"
+                        "   <arg name=\"property_name\" type=\"s\" direction=\"in\"/>\n"
+                        "   <arg name=\"value\" type=\"v\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"Set\">\n"
+                        "   <arg name=\"interface_name\" type=\"s\" direction=\"in\"/>\n"
+                        "   <arg name=\"property_name\" type=\"s\" direction=\"in\"/>\n"
+                        "   <arg name=\"value\" type=\"v\" direction=\"in\"/>\n"
+                        "  </method>\n"
+                        "  <method name=\"GetAll\">\n"
+                        "   <arg name=\"interface_name\" type=\"s\" direction=\"in\"/>\n"
+                        "   <arg name=\"props\" type=\"a{sv}\" direction=\"out\"/>\n"
+                        "  </method>\n"
+                        " </interface>\n");
+
+    pa_strbuf_puts(buf, "</node>\n");
+
+    pa_xfree(oe->introspection);
+    oe->introspection = pa_strbuf_tostring_free(buf);
+}
+
+/* Return value of find_handler() and its subfunctions. */
+enum find_result_t {
+    /* The received message is a valid .Get call. */
+    FOUND_GET_PROPERTY,
+
+    /* The received message is a valid .Set call. */
+    FOUND_SET_PROPERTY,
+
+    /* The received message is a valid .GetAll call. */
+    FOUND_GET_ALL,
+
+    /* The received message is a valid method call. */
+    FOUND_METHOD,
+
+    /* The interface of the received message hasn't been registered for the
+     * destination object. */
+    NO_SUCH_INTERFACE,
+
+    /* No property handler was found for the received .Get or .Set call. */
+    NO_SUCH_PROPERTY,
+
+    /* The interface argument of a property call didn't match any registered
+     * interface. */
+    NO_SUCH_PROPERTY_INTERFACE,
+
+    /* The received message called .Get or .Set for a property whose access
+     * mode doesn't match the call. */
+    PROPERTY_ACCESS_DENIED,
+
+    /* The new value signature of a .Set call didn't match the expected
+     * signature. */
+    INVALID_PROPERTY_SIG,
+
+    /* No method handler was found for the received message. */
+    NO_SUCH_METHOD,
+
+    /* The signature of the received message didn't match the expected
+     * signature. Despite the name, this can also be returned for a property
+     * call if its message signature is invalid. */
+    INVALID_METHOD_SIG
+};
+
+/* Data for resolving the correct reaction to a received message. */
+struct call_info {
+    DBusMessage *message; /* The received message. */
+    struct object_entry *obj_entry;
+    const char *interface; /* Destination interface name (extracted from the message). */
+    struct interface_entry *iface_entry;
+
+    const char *property; /* Property name (extracted from the message). */
+    const char *property_interface; /* The interface argument of a property call is stored here. */
+    pa_dbus_property_handler *property_handler;
+    const char *expected_property_sig; /* Property signature from the introspection data. */
+    const char *property_sig; /* The signature of the new value in the received .Set message. */
+    DBusMessageIter variant_iter; /* Iterator pointing to the beginning of the new value variant of a .Set call. */
+
+    const char *method; /* Method name (extracted from the message). */
+    pa_dbus_method_handler *method_handler;
+    const char *expected_method_sig; /* Method signature from the introspection data. */
+    const char *method_sig; /* The signature of the received message. */
+};
+
+/* Called when call_info->property has been set and the property interface has
+ * not been given. In case of a Set call, call_info->property_sig is also set,
+ * which is checked against the expected value in this function. */
+static enum find_result_t find_handler_by_property(struct call_info *call_info) {
+    void *state = NULL;
+
+    pa_assert(call_info);
+
+    PA_HASHMAP_FOREACH(call_info->iface_entry, call_info->obj_entry->interfaces, state) {
+        if ((call_info->property_handler = pa_hashmap_get(call_info->iface_entry->property_handlers, call_info->property))) {
+            if (pa_streq(call_info->method, "Get"))
+                return call_info->property_handler->get_cb ? FOUND_GET_PROPERTY : PROPERTY_ACCESS_DENIED;
+
+            else if (pa_streq(call_info->method, "Set")) {
+                call_info->expected_property_sig = call_info->property_handler->type;
+
+                if (pa_streq(call_info->property_sig, call_info->expected_property_sig))
+                    return call_info->property_handler->set_cb ? FOUND_SET_PROPERTY : PROPERTY_ACCESS_DENIED;
+                else
+                    return INVALID_PROPERTY_SIG;
+
+            } else
+                pa_assert_not_reached();
+        }
+    }
+
+    return NO_SUCH_PROPERTY;
+}
+
+static enum find_result_t find_handler_by_method(struct call_info *call_info) {
+    void *state = NULL;
+
+    pa_assert(call_info);
+
+    PA_HASHMAP_FOREACH(call_info->iface_entry, call_info->obj_entry->interfaces, state) {
+        if ((call_info->method_handler = pa_hashmap_get(call_info->iface_entry->method_handlers, call_info->method))) {
+            pa_assert_se(call_info->expected_method_sig = pa_hashmap_get(call_info->iface_entry->method_signatures, call_info->method));
+
+            if (pa_streq(call_info->method_sig, call_info->expected_method_sig))
+                return FOUND_METHOD;
+            else
+                return INVALID_METHOD_SIG;
+        }
+    }
+
+    return NO_SUCH_METHOD;
+}
+
+static enum find_result_t find_handler_from_properties_call(struct call_info *call_info) {
+    pa_assert(call_info);
+
+    if (pa_streq(call_info->method, "GetAll")) {
+        call_info->expected_method_sig = "s";
+        if (!pa_streq(call_info->method_sig, call_info->expected_method_sig))
+            return INVALID_METHOD_SIG;
+
+        pa_assert_se(dbus_message_get_args(call_info->message, NULL,
+                                           DBUS_TYPE_STRING, &call_info->property_interface,
+                                           DBUS_TYPE_INVALID));
+
+        if (*call_info->property_interface) {
+            if ((call_info->iface_entry = pa_hashmap_get(call_info->obj_entry->interfaces, call_info->property_interface)))
+                return FOUND_GET_ALL;
+            else
+                return NO_SUCH_PROPERTY_INTERFACE;
+
+        } else {
+            pa_assert_se(call_info->iface_entry = pa_hashmap_first(call_info->obj_entry->interfaces));
+            return FOUND_GET_ALL;
+        }
+
+    } else if (pa_streq(call_info->method, "Get")) {
+        call_info->expected_method_sig = "ss";
+        if (!pa_streq(call_info->method_sig, call_info->expected_method_sig))
+            return INVALID_METHOD_SIG;
+
+        pa_assert_se(dbus_message_get_args(call_info->message, NULL,
+                                           DBUS_TYPE_STRING, &call_info->property_interface,
+                                           DBUS_TYPE_STRING, &call_info->property,
+                                           DBUS_TYPE_INVALID));
+
+        if (*call_info->property_interface) {
+            if (!(call_info->iface_entry = pa_hashmap_get(call_info->obj_entry->interfaces, call_info->property_interface)))
+                return NO_SUCH_PROPERTY_INTERFACE;
+            else if ((call_info->property_handler =
+                        pa_hashmap_get(call_info->iface_entry->property_handlers, call_info->property)))
+                return call_info->property_handler->get_cb ? FOUND_GET_PROPERTY : PROPERTY_ACCESS_DENIED;
+            else
+                return NO_SUCH_PROPERTY;
+
+        } else
+            return find_handler_by_property(call_info);
+
+    } else if (pa_streq(call_info->method, "Set")) {
+        DBusMessageIter msg_iter;
+
+        call_info->expected_method_sig = "ssv";
+        if (!pa_streq(call_info->method_sig, call_info->expected_method_sig))
+            return INVALID_METHOD_SIG;
+
+        pa_assert_se(dbus_message_iter_init(call_info->message, &msg_iter));
+
+        dbus_message_iter_get_basic(&msg_iter, &call_info->property_interface);
+        pa_assert_se(dbus_message_iter_next(&msg_iter));
+        dbus_message_iter_get_basic(&msg_iter, &call_info->property);
+        pa_assert_se(dbus_message_iter_next(&msg_iter));
+
+        dbus_message_iter_recurse(&msg_iter, &call_info->variant_iter);
+
+        call_info->property_sig = dbus_message_iter_get_signature(&call_info->variant_iter);
+
+        if (*call_info->property_interface) {
+            if (!(call_info->iface_entry = pa_hashmap_get(call_info->obj_entry->interfaces, call_info->property_interface)))
+                return NO_SUCH_PROPERTY_INTERFACE;
+
+            else if ((call_info->property_handler =
+                        pa_hashmap_get(call_info->iface_entry->property_handlers, call_info->property))) {
+                call_info->expected_property_sig = call_info->property_handler->type;
+
+                if (pa_streq(call_info->property_sig, call_info->expected_property_sig))
+                    return call_info->property_handler->set_cb ? FOUND_SET_PROPERTY : PROPERTY_ACCESS_DENIED;
+                else
+                    return INVALID_PROPERTY_SIG;
+
+            } else
+                return NO_SUCH_PROPERTY;
+
+        } else
+            return find_handler_by_property(call_info);
+
+    } else
+        pa_assert_not_reached();
+}
+
+static enum find_result_t find_handler(struct call_info *call_info) {
+    pa_assert(call_info);
+
+    if (call_info->interface) {
+        if (pa_streq(call_info->interface, DBUS_INTERFACE_PROPERTIES))
+            return find_handler_from_properties_call(call_info);
+
+        else if (!(call_info->iface_entry = pa_hashmap_get(call_info->obj_entry->interfaces, call_info->interface)))
+            return NO_SUCH_INTERFACE;
+
+        else if ((call_info->method_handler = pa_hashmap_get(call_info->iface_entry->method_handlers, call_info->method))) {
+            pa_assert_se(call_info->expected_method_sig = pa_hashmap_get(call_info->iface_entry->method_signatures, call_info->method));
+
+            if (!pa_streq(call_info->method_sig, call_info->expected_method_sig))
+                return INVALID_METHOD_SIG;
+
+            return FOUND_METHOD;
+
+        } else
+            return NO_SUCH_METHOD;
+
+    } else { /* The method call doesn't contain an interface. */
+        if (pa_streq(call_info->method, "Get") || pa_streq(call_info->method, "Set") || pa_streq(call_info->method, "GetAll")) {
+            if (find_handler_by_method(call_info) == FOUND_METHOD)
+                /* The object has a method named Get, Set or GetAll in some other interface than .Properties. */
+                return FOUND_METHOD;
+            else
+                /* Assume this is a .Properties call. */
+                return find_handler_from_properties_call(call_info);
+
+        } else /* This is not a .Properties call. */
+            return find_handler_by_method(call_info);
+    }
+}
+
+static DBusHandlerResult handle_message_cb(DBusConnection *connection, DBusMessage *message, void *user_data) {
+    pa_dbus_protocol *p = user_data;
+    struct call_info call_info;
+
+    pa_assert(connection);
+    pa_assert(message);
+    pa_assert(p);
+    pa_assert(p->objects);
+
+    if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    pa_log_debug("Received message: destination = %s, interface = %s, member = %s",
+                 dbus_message_get_path(message),
+                 dbus_message_get_interface(message),
+                 dbus_message_get_member(message));
+
+    call_info.message = message;
+    pa_assert_se(call_info.obj_entry = pa_hashmap_get(p->objects, dbus_message_get_path(message)));
+    call_info.interface = dbus_message_get_interface(message);
+    pa_assert_se(call_info.method = dbus_message_get_member(message));
+    pa_assert_se(call_info.method_sig = dbus_message_get_signature(message));
+
+    if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect") ||
+        (!dbus_message_get_interface(message) && dbus_message_has_member(message, "Introspect"))) {
+        pa_dbus_send_basic_value_reply(connection, message, DBUS_TYPE_STRING, &call_info.obj_entry->introspection);
+        goto finish;
+    }
+
+    switch (find_handler(&call_info)) {
+        case FOUND_GET_PROPERTY:
+            call_info.property_handler->get_cb(connection, message, call_info.iface_entry->userdata);
+            break;
+
+        case FOUND_SET_PROPERTY:
+            call_info.property_handler->set_cb(connection, message, &call_info.variant_iter, call_info.iface_entry->userdata);
+            break;
+
+        case FOUND_METHOD:
+            call_info.method_handler->receive_cb(connection, message, call_info.iface_entry->userdata);
+            break;
+
+        case FOUND_GET_ALL:
+            if (call_info.iface_entry->get_all_properties_cb)
+                call_info.iface_entry->get_all_properties_cb(connection, message, call_info.iface_entry->userdata);
+            else {
+                DBusMessage *dummy_reply = NULL;
+                DBusMessageIter msg_iter;
+                DBusMessageIter dict_iter;
+
+                pa_assert_se(dummy_reply = dbus_message_new_method_return(message));
+                dbus_message_iter_init_append(dummy_reply, &msg_iter);
+                pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter));
+                pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter));
+                pa_assert_se(dbus_connection_send(connection, dummy_reply, NULL));
+                dbus_message_unref(dummy_reply);
+            }
+            break;
+
+        case PROPERTY_ACCESS_DENIED:
+            pa_dbus_send_error(connection, message, DBUS_ERROR_ACCESS_DENIED,
+                               "%s access denied for property %s", call_info.method, call_info.property);
+            break;
+
+        case NO_SUCH_METHOD:
+            pa_dbus_send_error(connection, message, DBUS_ERROR_UNKNOWN_METHOD, "No such method: %s", call_info.method);
+            break;
+
+        case NO_SUCH_INTERFACE:
+            pa_dbus_send_error(connection, message, PA_DBUS_ERROR_NO_SUCH_INTERFACE, "No such interface: %s", call_info.interface);
+            break;
+
+        case NO_SUCH_PROPERTY:
+            pa_dbus_send_error(connection, message, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "No such property: %s", call_info.property);
+            break;
+
+        case NO_SUCH_PROPERTY_INTERFACE:
+            pa_dbus_send_error(connection, message, PA_DBUS_ERROR_NO_SUCH_INTERFACE, "No such property interface: %s", call_info.property_interface);
+            break;
+
+        case INVALID_METHOD_SIG:
+            pa_dbus_send_error(connection, message, DBUS_ERROR_INVALID_ARGS,
+                               "Invalid signature for method %s: '%s'. Expected '%s'.",
+                               call_info.method, call_info.method_sig, call_info.expected_method_sig);
+            break;
+
+        case INVALID_PROPERTY_SIG:
+            pa_dbus_send_error(connection, message, DBUS_ERROR_INVALID_ARGS,
+                               "Invalid signature for property %s: '%s'. Expected '%s'.",
+                               call_info.property, call_info.property_sig, call_info.expected_property_sig);
+            break;
+
+        default:
+            pa_assert_not_reached();
+    }
+
+finish:
+    return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusObjectPathVTable vtable = {
+    .unregister_function = NULL,
+    .message_function = handle_message_cb,
+    .dbus_internal_pad1 = NULL,
+    .dbus_internal_pad2 = NULL,
+    .dbus_internal_pad3 = NULL,
+    .dbus_internal_pad4 = NULL
+};
+
+static void register_object(pa_dbus_protocol *p, struct object_entry *obj_entry) {
+    struct connection_entry *conn_entry;
+    void *state = NULL;
+
+    pa_assert(p);
+    pa_assert(obj_entry);
+
+    PA_HASHMAP_FOREACH(conn_entry, p->connections, state)
+        pa_assert_se(dbus_connection_register_object_path(conn_entry->connection, obj_entry->path, &vtable, p));
+}
+
+static pa_dbus_arg_info *copy_args(const pa_dbus_arg_info *src, unsigned n) {
+    pa_dbus_arg_info *dst;
+    unsigned i;
+
+    if (n == 0)
+        return NULL;
+
+    pa_assert(src);
+
+    dst = pa_xnew0(pa_dbus_arg_info, n);
+
+    for (i = 0; i < n; ++i) {
+        dst[i].name = pa_xstrdup(src[i].name);
+        dst[i].type = pa_xstrdup(src[i].type);
+        dst[i].direction = pa_xstrdup(src[i].direction);
+    }
+
+    return dst;
+}
+
+static pa_hashmap *create_method_handlers(const pa_dbus_interface_info *info) {
+    pa_hashmap *handlers;
+    unsigned i;
+
+    pa_assert(info);
+    pa_assert(info->method_handlers || info->n_method_handlers == 0);
+
+    handlers = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+
+    for (i = 0; i < info->n_method_handlers; ++i) {
+        pa_dbus_method_handler *h = pa_xnew(pa_dbus_method_handler, 1);
+        h->method_name = pa_xstrdup(info->method_handlers[i].method_name);
+        h->arguments = copy_args(info->method_handlers[i].arguments, info->method_handlers[i].n_arguments);
+        h->n_arguments = info->method_handlers[i].n_arguments;
+        h->receive_cb = info->method_handlers[i].receive_cb;
+
+        pa_hashmap_put(handlers, h->method_name, h);
+    }
+
+    return handlers;
+}
+
+static pa_hashmap *extract_method_signatures(pa_hashmap *method_handlers) {
+    pa_hashmap *signatures = NULL;
+    pa_dbus_method_handler *handler = NULL;
+    void *state = NULL;
+    pa_strbuf *sig_buf = NULL;
+    unsigned i = 0;
+
+    pa_assert(method_handlers);
+
+    signatures = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+
+    PA_HASHMAP_FOREACH(handler, method_handlers, state) {
+        sig_buf = pa_strbuf_new();
+
+        for (i = 0; i < handler->n_arguments; ++i) {
+            if (pa_streq(handler->arguments[i].direction, "in"))
+                pa_strbuf_puts(sig_buf, handler->arguments[i].type);
+        }
+
+        pa_hashmap_put(signatures, handler->method_name, pa_strbuf_tostring_free(sig_buf));
+    }
+
+    return signatures;
+}
+
+static pa_hashmap *create_property_handlers(const pa_dbus_interface_info *info) {
+    pa_hashmap *handlers;
+    unsigned i = 0;
+
+    pa_assert(info);
+    pa_assert(info->property_handlers || info->n_property_handlers == 0);
+
+    handlers = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+
+    for (i = 0; i < info->n_property_handlers; ++i) {
+        pa_dbus_property_handler *h = pa_xnew(pa_dbus_property_handler, 1);
+        h->property_name = pa_xstrdup(info->property_handlers[i].property_name);
+        h->type = pa_xstrdup(info->property_handlers[i].type);
+        h->get_cb = info->property_handlers[i].get_cb;
+        h->set_cb = info->property_handlers[i].set_cb;
+
+        pa_hashmap_put(handlers, h->property_name, h);
+    }
+
+    return handlers;
+}
+
+static pa_dbus_signal_info *copy_signals(const pa_dbus_interface_info *info) {
+    pa_dbus_signal_info *dst;
+    unsigned i;
+
+    pa_assert(info);
+
+    if (info->n_signals == 0)
+        return NULL;
+
+    pa_assert(info->signals);
+
+    dst = pa_xnew(pa_dbus_signal_info, info->n_signals);
+
+    for (i = 0; i < info->n_signals; ++i) {
+        dst[i].name = pa_xstrdup(info->signals[i].name);
+        dst[i].arguments = copy_args(info->signals[i].arguments, info->signals[i].n_arguments);
+        dst[i].n_arguments = info->signals[i].n_arguments;
+    }
+
+    return dst;
+}
+
+int pa_dbus_protocol_add_interface(pa_dbus_protocol *p,
+                                   const char *path,
+                                   const pa_dbus_interface_info *info,
+                                   void *userdata) {
+    struct object_entry *obj_entry;
+    struct interface_entry *iface_entry;
+    pa_bool_t obj_entry_created = FALSE;
+
+    pa_assert(p);
+    pa_assert(path);
+    pa_assert(info);
+    pa_assert(info->name);
+    pa_assert(info->method_handlers || info->n_method_handlers == 0);
+    pa_assert(info->property_handlers || info->n_property_handlers == 0);
+    pa_assert(info->get_all_properties_cb || info->n_property_handlers == 0);
+    pa_assert(info->signals || info->n_signals == 0);
+
+    if (!(obj_entry = pa_hashmap_get(p->objects, path))) {
+        obj_entry = pa_xnew(struct object_entry, 1);
+        obj_entry->path = pa_xstrdup(path);
+        obj_entry->interfaces = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+        obj_entry->introspection = NULL;
+
+        pa_hashmap_put(p->objects, obj_entry->path, obj_entry);
+        obj_entry_created = TRUE;
+    }
+
+    if (pa_hashmap_get(obj_entry->interfaces, info->name) != NULL)
+        goto fail; /* The interface was already registered. */
+
+    iface_entry = pa_xnew(struct interface_entry, 1);
+    iface_entry->name = pa_xstrdup(info->name);
+    iface_entry->method_handlers = create_method_handlers(info);
+    iface_entry->method_signatures = extract_method_signatures(iface_entry->method_handlers);
+    iface_entry->property_handlers = create_property_handlers(info);
+    iface_entry->get_all_properties_cb = info->get_all_properties_cb;
+    iface_entry->signals = copy_signals(info);
+    iface_entry->n_signals = info->n_signals;
+    iface_entry->userdata = userdata;
+    pa_hashmap_put(obj_entry->interfaces, iface_entry->name, iface_entry);
+
+    update_introspection(obj_entry);
+
+    if (obj_entry_created)
+        register_object(p, obj_entry);
+#ifdef _DEBUG_
+    pa_log_debug("Interface %s added for object %s", iface_entry->name, obj_entry->path);
+#endif
+
+    return 0;
+
+fail:
+    return -1;
+}
+
+static void unregister_object(pa_dbus_protocol *p, struct object_entry *obj_entry) {
+    struct connection_entry *conn_entry;
+    void *state = NULL;
+
+    pa_assert(p);
+    pa_assert(obj_entry);
+
+    PA_HASHMAP_FOREACH(conn_entry, p->connections, state)
+        pa_assert_se(dbus_connection_unregister_object_path(conn_entry->connection, obj_entry->path));
+}
+
+static void method_handler_free(pa_dbus_method_handler *h) {
+    unsigned i;
+
+    pa_assert(h);
+
+    pa_xfree((char *) h->method_name);
+
+    for (i = 0; i < h->n_arguments; ++i) {
+        pa_xfree((char *) h->arguments[i].name);
+        pa_xfree((char *) h->arguments[i].type);
+        pa_xfree((char *) h->arguments[i].direction);
+    }
+
+    pa_xfree((pa_dbus_arg_info *) h->arguments);
+    pa_xfree(h);
+}
+
+static void property_handler_free(pa_dbus_property_handler *h) {
+    pa_assert(h);
+
+    pa_xfree((char *) h->property_name);
+    pa_xfree((char *) h->type);
+
+    pa_xfree(h);
+}
+
+int pa_dbus_protocol_remove_interface(pa_dbus_protocol *p, const char* path, const char* interface) {
+    struct object_entry *obj_entry;
+    struct interface_entry *iface_entry;
+    unsigned i;
+
+    pa_assert(p);
+    pa_assert(path);
+    pa_assert(interface);
+
+    if (!(obj_entry = pa_hashmap_get(p->objects, path)))
+        return -1;
+
+    if (!(iface_entry = pa_hashmap_remove(obj_entry->interfaces, interface)))
+        return -1;
+
+    update_introspection(obj_entry);
+#ifdef _DEBUG_
+    pa_log_debug("Interface %s removed from object %s", iface_entry->name, obj_entry->path);
+#endif
+
+    pa_xfree(iface_entry->name);
+    pa_hashmap_free(iface_entry->method_signatures, pa_xfree);
+    pa_hashmap_free(iface_entry->method_handlers, (pa_free_cb_t) method_handler_free);
+    pa_hashmap_free(iface_entry->property_handlers, (pa_free_cb_t) property_handler_free);
+
+    for (i = 0; i < iface_entry->n_signals; ++i) {
+        unsigned j;
+
+        pa_xfree((char *) iface_entry->signals[i].name);
+
+        for (j = 0; j < iface_entry->signals[i].n_arguments; ++j) {
+            pa_xfree((char *) iface_entry->signals[i].arguments[j].name);
+            pa_xfree((char *) iface_entry->signals[i].arguments[j].type);
+            pa_assert(iface_entry->signals[i].arguments[j].direction == NULL);
+        }
+
+        pa_xfree((pa_dbus_arg_info *) iface_entry->signals[i].arguments);
+    }
+
+    pa_xfree(iface_entry->signals);
+    pa_xfree(iface_entry);
+
+    if (pa_hashmap_isempty(obj_entry->interfaces)) {
+        unregister_object(p, obj_entry);
+
+        pa_hashmap_remove(p->objects, path);
+        pa_xfree(obj_entry->path);
+        pa_hashmap_free(obj_entry->interfaces, NULL);
+        pa_xfree(obj_entry->introspection);
+        pa_xfree(obj_entry);
+    }
+
+    return 0;
+}
+
+static void register_all_objects(pa_dbus_protocol *p, DBusConnection *conn) {
+    struct object_entry *obj_entry;
+    void *state = NULL;
+
+    pa_assert(p);
+    pa_assert(conn);
+
+    PA_HASHMAP_FOREACH(obj_entry, p->objects, state)
+        pa_assert_se(dbus_connection_register_object_path(conn, obj_entry->path, &vtable, p));
+}
+
+int pa_dbus_protocol_register_connection(pa_dbus_protocol *p, DBusConnection *conn, pa_client *client) {
+    struct connection_entry *conn_entry;
+
+    pa_assert(p);
+    pa_assert(conn);
+    pa_assert(client);
+
+    if (pa_hashmap_get(p->connections, conn))
+        return -1; /* The connection was already registered. */
+
+    register_all_objects(p, conn);
+
+    conn_entry = pa_xnew(struct connection_entry, 1);
+    conn_entry->connection = dbus_connection_ref(conn);
+    conn_entry->client = client;
+    conn_entry->listening_for_all_signals = FALSE;
+    conn_entry->all_signals_objects = pa_idxset_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    conn_entry->listening_signals = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+
+    pa_hashmap_put(p->connections, conn, conn_entry);
+
+    return 0;
+}
+
+static void unregister_all_objects(pa_dbus_protocol *p, DBusConnection *conn) {
+    struct object_entry *obj_entry;
+    void *state = NULL;
+
+    pa_assert(p);
+    pa_assert(conn);
+
+    PA_HASHMAP_FOREACH(obj_entry, p->objects, state)
+        pa_assert_se(dbus_connection_unregister_object_path(conn, obj_entry->path));
+}
+
+static struct signal_paths_entry *signal_paths_entry_new(const char *signal_name) {
+    struct signal_paths_entry *e = NULL;
+
+    pa_assert(signal_name);
+
+    e = pa_xnew0(struct signal_paths_entry, 1);
+    e->signal = pa_xstrdup(signal_name);
+    e->paths = pa_idxset_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+
+    return e;
+}
+
+static void signal_paths_entry_free(struct signal_paths_entry *e) {
+    pa_assert(e);
+
+    pa_xfree(e->signal);
+    pa_idxset_free(e->paths, pa_xfree);
+    pa_xfree(e);
+}
+
+int pa_dbus_protocol_unregister_connection(pa_dbus_protocol *p, DBusConnection *conn) {
+    struct connection_entry *conn_entry = NULL;
+
+    pa_assert(p);
+    pa_assert(conn);
+
+    if (!(conn_entry = pa_hashmap_remove(p->connections, conn)))
+        return -1;
+
+    unregister_all_objects(p, conn);
+
+    dbus_connection_unref(conn_entry->connection);
+    pa_idxset_free(conn_entry->all_signals_objects, pa_xfree);
+    pa_hashmap_free(conn_entry->listening_signals, (pa_free_cb_t) signal_paths_entry_free);
+    pa_xfree(conn_entry);
+
+    return 0;
+}
+
+pa_client *pa_dbus_protocol_get_client(pa_dbus_protocol *p, DBusConnection *conn) {
+    struct connection_entry *conn_entry;
+
+    pa_assert(p);
+    pa_assert(conn);
+
+    if (!(conn_entry = pa_hashmap_get(p->connections, conn)))
+        return NULL;
+
+    return conn_entry->client;
+}
+
+void pa_dbus_protocol_add_signal_listener(
+        pa_dbus_protocol *p,
+        DBusConnection *conn,
+        const char *signal_name,
+        char **objects,
+        unsigned n_objects) {
+    struct connection_entry *conn_entry = NULL;
+    struct signal_paths_entry *signal_paths_entry = NULL;
+    unsigned i = 0;
+
+    pa_assert(p);
+    pa_assert(conn);
+    pa_assert(objects || n_objects == 0);
+
+    pa_assert_se((conn_entry = pa_hashmap_get(p->connections, conn)));
+
+    /* all_signals_objects will either be emptied or replaced with new objects,
+     * so we empty it here unconditionally. If listening_for_all_signals is
+     * currently FALSE, the idxset is empty already so this does nothing. */
+    pa_idxset_remove_all(conn_entry->all_signals_objects, pa_xfree);
+
+    if (signal_name) {
+        conn_entry->listening_for_all_signals = FALSE;
+
+        /* Replace the old signal paths entry for this signal with a new
+         * one. */
+        if ((signal_paths_entry = pa_hashmap_remove(conn_entry->listening_signals, signal_name)))
+            signal_paths_entry_free(signal_paths_entry);
+        signal_paths_entry = signal_paths_entry_new(signal_name);
+
+        for (i = 0; i < n_objects; ++i)
+            pa_idxset_put(signal_paths_entry->paths, pa_xstrdup(objects[i]), NULL);
+
+        pa_hashmap_put(conn_entry->listening_signals, signal_paths_entry->signal, signal_paths_entry);
+
+    } else {
+        conn_entry->listening_for_all_signals = TRUE;
+
+        /* We're not interested in individual signals anymore, so let's empty
+         * listening_signals. */
+        pa_hashmap_remove_all(conn_entry->listening_signals, (pa_free_cb_t) signal_paths_entry_free);
+
+        for (i = 0; i < n_objects; ++i)
+            pa_idxset_put(conn_entry->all_signals_objects, pa_xstrdup(objects[i]), NULL);
+    }
+}
+
+void pa_dbus_protocol_remove_signal_listener(pa_dbus_protocol *p, DBusConnection *conn, const char *signal_name) {
+    struct connection_entry *conn_entry = NULL;
+    struct signal_paths_entry *signal_paths_entry = NULL;
+
+    pa_assert(p);
+    pa_assert(conn);
+
+    pa_assert_se((conn_entry = pa_hashmap_get(p->connections, conn)));
+
+    if (signal_name) {
+        if ((signal_paths_entry = pa_hashmap_remove(conn_entry->listening_signals, signal_name)))
+            signal_paths_entry_free(signal_paths_entry);
+
+    } else {
+        conn_entry->listening_for_all_signals = FALSE;
+        pa_idxset_remove_all(conn_entry->all_signals_objects, pa_xfree);
+        pa_hashmap_remove_all(conn_entry->listening_signals, (pa_free_cb_t) signal_paths_entry_free);
+    }
+}
+
+void pa_dbus_protocol_send_signal(pa_dbus_protocol *p, DBusMessage *signal_msg) {
+    struct connection_entry *conn_entry;
+    struct signal_paths_entry *signal_paths_entry;
+    void *state = NULL;
+    DBusMessage *signal_copy;
+    char *signal_string;
+
+    pa_assert(p);
+    pa_assert(signal_msg);
+    pa_assert(dbus_message_get_type(signal_msg) == DBUS_MESSAGE_TYPE_SIGNAL);
+    pa_assert(dbus_message_get_path(signal_msg));
+    pa_assert(dbus_message_get_interface(signal_msg));
+    pa_assert(dbus_message_get_member(signal_msg));
+
+    signal_string = pa_sprintf_malloc("%s.%s", dbus_message_get_interface(signal_msg), dbus_message_get_member(signal_msg));
+
+    PA_HASHMAP_FOREACH(conn_entry, p->connections, state) {
+        if ((conn_entry->listening_for_all_signals /* Case 1: listening for all signals */
+             && (pa_idxset_get_by_data(conn_entry->all_signals_objects, dbus_message_get_path(signal_msg), NULL)
+                 || pa_idxset_isempty(conn_entry->all_signals_objects)))
+
+            || (!conn_entry->listening_for_all_signals /* Case 2: not listening for all signals */
+                && (signal_paths_entry = pa_hashmap_get(conn_entry->listening_signals, signal_string))
+                && (pa_idxset_get_by_data(signal_paths_entry->paths, dbus_message_get_path(signal_msg), NULL)
+                    || pa_idxset_isempty(signal_paths_entry->paths)))) {
+
+            pa_assert_se(signal_copy = dbus_message_copy(signal_msg));
+            pa_assert_se(dbus_connection_send(conn_entry->connection, signal_copy, NULL));
+            dbus_message_unref(signal_copy);
+        }
+    }
+
+    pa_xfree(signal_string);
+}
+
+const char **pa_dbus_protocol_get_extensions(pa_dbus_protocol *p, unsigned *n) {
+    const char **extensions;
+    const char *ext_name;
+    void *state = NULL;
+    unsigned i = 0;
+
+    pa_assert(p);
+    pa_assert(n);
+
+    *n = pa_idxset_size(p->extensions);
+
+    if (*n <= 0)
+        return NULL;
+
+    extensions = pa_xnew(const char *, *n);
+
+    while ((ext_name = pa_idxset_iterate(p->extensions, &state, NULL)))
+        extensions[i++] = ext_name;
+
+    return extensions;
+}
+
+int pa_dbus_protocol_register_extension(pa_dbus_protocol *p, const char *name) {
+    char *internal_name;
+
+    pa_assert(p);
+    pa_assert(name);
+
+    internal_name = pa_xstrdup(name);
+
+    if (pa_idxset_put(p->extensions, internal_name, NULL) < 0) {
+        pa_xfree(internal_name);
+        return -1;
+    }
+
+    pa_hook_fire(&p->hooks[PA_DBUS_PROTOCOL_HOOK_EXTENSION_REGISTERED], internal_name);
+
+    return 0;
+}
+
+int pa_dbus_protocol_unregister_extension(pa_dbus_protocol *p, const char *name) {
+    char *internal_name;
+
+    pa_assert(p);
+    pa_assert(name);
+
+    if (!(internal_name = pa_idxset_remove_by_data(p->extensions, name, NULL)))
+        return -1;
+
+    pa_hook_fire(&p->hooks[PA_DBUS_PROTOCOL_HOOK_EXTENSION_UNREGISTERED], internal_name);
+
+    pa_xfree(internal_name);
+
+    return 0;
+}
+
+pa_hook_slot *pa_dbus_protocol_hook_connect(
+        pa_dbus_protocol *p,
+        pa_dbus_protocol_hook_t hook,
+        pa_hook_priority_t prio,
+        pa_hook_cb_t cb,
+        void *data) {
+    pa_assert(p);
+    pa_assert(hook < PA_DBUS_PROTOCOL_HOOK_MAX);
+    pa_assert(cb);
+
+    return pa_hook_connect(&p->hooks[hook], prio, cb, data);
+}
diff --git a/src/pulsecore/protocol-dbus.h b/src/pulsecore/protocol-dbus.h
new file mode 100644 (file)
index 0000000..8999933
--- /dev/null
@@ -0,0 +1,218 @@
+#ifndef fooprotocoldbushfoo
+#define fooprotocoldbushfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Tanu Kaskinen
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#include <dbus/dbus.h>
+
+#include <pulsecore/core.h>
+#include <pulsecore/macro.h>
+
+#define PA_DBUS_DEFAULT_PORT 24883
+#define PA_DBUS_SOCKET_NAME "dbus-socket"
+
+#define PA_DBUS_SYSTEM_SOCKET_PATH PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_DBUS_SOCKET_NAME
+
+#define PA_DBUS_CORE_INTERFACE "org.PulseAudio.Core1"
+#define PA_DBUS_CORE_OBJECT_PATH "/org/pulseaudio/core1"
+
+#define PA_DBUS_ERROR_NO_SUCH_INTERFACE PA_DBUS_CORE_INTERFACE ".NoSuchInterfaceError"
+#define PA_DBUS_ERROR_NO_SUCH_PROPERTY PA_DBUS_CORE_INTERFACE ".NoSuchPropertyError"
+#define PA_DBUS_ERROR_NOT_FOUND PA_DBUS_CORE_INTERFACE ".NotFoundError"
+
+/* Returns the default address of the server type in the escaped form. For
+ * PA_SERVER_TYPE_NONE an empty string is returned. The caller frees the
+ * string. */
+char *pa_get_dbus_address_from_server_type(pa_server_type_t server_type);
+
+typedef struct pa_dbus_protocol pa_dbus_protocol;
+
+/* This function either creates a new pa_dbus_protocol object, or if one
+ * already exists, increases the reference count. */
+pa_dbus_protocol* pa_dbus_protocol_get(pa_core *c);
+
+pa_dbus_protocol* pa_dbus_protocol_ref(pa_dbus_protocol *p);
+void pa_dbus_protocol_unref(pa_dbus_protocol *p);
+
+/* Called when a received message needs handling. Completely ignoring the
+ * message isn't a good idea; if you can't handle the message, reply with an
+ * error.
+ *
+ * The message signature is already checked against the introspection data, so
+ * you don't have to do that yourself.
+ *
+ * All messages are method calls. */
+typedef void (*pa_dbus_receive_cb_t)(DBusConnection *conn, DBusMessage *msg, void *userdata);
+
+/* A specialized version of pa_dbus_receive_cb_t: the additional iterator
+ * argument points to the element inside the new value variant.
+ *
+ * The new value signature is checked against the introspection data, so you
+ * don't have to do that yourself. */
+typedef void (*pa_dbus_set_property_cb_t)(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+
+typedef struct pa_dbus_arg_info {
+    const char *name;
+    const char *type;
+    const char *direction; /* NULL for signal arguments. */
+} pa_dbus_arg_info;
+
+typedef struct pa_dbus_signal_info {
+    const char *name;
+    const pa_dbus_arg_info *arguments; /* NULL, if the signal has no args. */
+    unsigned n_arguments;
+} pa_dbus_signal_info;
+
+typedef struct pa_dbus_method_handler {
+    const char *method_name;
+    const pa_dbus_arg_info *arguments; /* NULL, if the method has no args. */
+    unsigned n_arguments;
+    pa_dbus_receive_cb_t receive_cb;
+} pa_dbus_method_handler;
+
+typedef struct pa_dbus_property_handler {
+    const char *property_name;
+    const char *type;
+
+    /* The access mode for the property is determined by checking whether
+     * get_cb or set_cb is NULL. */
+    pa_dbus_receive_cb_t get_cb;
+    pa_dbus_set_property_cb_t set_cb;
+} pa_dbus_property_handler;
+
+typedef struct pa_dbus_interface_info {
+    const char* name;
+    const pa_dbus_method_handler *method_handlers; /* NULL, if the interface has no methods. */
+    unsigned n_method_handlers;
+    const pa_dbus_property_handler *property_handlers; /* NULL, if the interface has no properties. */
+    unsigned n_property_handlers;
+    const pa_dbus_receive_cb_t get_all_properties_cb; /* May be NULL, in which case GetAll returns an error. */
+    const pa_dbus_signal_info *signals; /* NULL, if the interface has no signals. */
+    unsigned n_signals;
+} pa_dbus_interface_info;
+
+
+/* The following functions may only be called from the main thread. */
+
+/* Registers the given interface to the given object path. It doesn't matter
+ * whether or not the object has already been registered; if it is, then its
+ * interface set is extended.
+ *
+ * Introspection requests are handled automatically.
+ *
+ * Userdata is passed to all the callbacks.
+ *
+ * Fails and returns a negative number if the object already has the interface
+ * registered. */
+int pa_dbus_protocol_add_interface(pa_dbus_protocol *p, const char *path, const pa_dbus_interface_info *info, void *userdata);
+
+/* Returns a negative number if the given object doesn't have the given
+ * interface registered. */
+int pa_dbus_protocol_remove_interface(pa_dbus_protocol *p, const char* path, const char* interface);
+
+/* Fails and returns a negative number if the connection is already
+ * registered. */
+int pa_dbus_protocol_register_connection(pa_dbus_protocol *p, DBusConnection *conn, pa_client *client);
+
+/* Returns a negative number if the connection isn't registered. */
+int pa_dbus_protocol_unregister_connection(pa_dbus_protocol *p, DBusConnection *conn);
+
+/* Returns NULL if the connection isn't registered. */
+pa_client *pa_dbus_protocol_get_client(pa_dbus_protocol *p, DBusConnection *conn);
+
+/* Enables signal receiving for the given connection. The connection must have
+ * been registered earlier. The signal string must contain both the signal
+ * interface and the signal name, concatenated using a period as the separator.
+ *
+ * If the signal argument is NULL, all signals will be sent to the connection,
+ * otherwise calling this function only adds the given signal to the list of
+ * signals that will be delivered to the connection.
+ *
+ * The objects argument is a list of object paths. If the list is not empty,
+ * only signals from the given objects are delivered. If this function is
+ * called multiple time for the same connection and signal, the latest call
+ * always replaces the previous object list. */
+void pa_dbus_protocol_add_signal_listener(
+        pa_dbus_protocol *p,
+        DBusConnection *conn,
+        const char *signal,
+        char **objects,
+        unsigned n_objects);
+
+/* Disables the delivery of the signal for the given connection. The connection
+ * must have been registered. If signal is NULL, all signals are disabled. If
+ * signal is non-NULL and _add_signal_listener() was previously called with
+ * NULL signal (causing all signals to be enabled), this function doesn't do
+ * anything. Also, if the signal wasn't enabled before, this function doesn't
+ * do anything in that case either. */
+void pa_dbus_protocol_remove_signal_listener(pa_dbus_protocol *p, DBusConnection *conn, const char *signal);
+
+/* Sends the given signal to all interested clients. By default no signals are
+ * sent - clients have to explicitly to request signals by calling
+ * .Core1.ListenForSignal. That method's handler then calls
+ * pa_dbus_protocol_add_signal_listener(). */
+void pa_dbus_protocol_send_signal(pa_dbus_protocol *p, DBusMessage *signal);
+
+/* Returns an array of extension identifier strings. The strings pointers point
+ * to the internal copies, so don't free the strings. The caller must free the
+ * array, however. Also, do not save the returned pointer or any of the string
+ * pointers, because the contained strings may be freed at any time. If you
+ * need to save the array, copy it. */
+const char **pa_dbus_protocol_get_extensions(pa_dbus_protocol *p, unsigned *n);
+
+/* Modules that want to provide a D-Bus interface for clients should register
+ * an identifier that the clients can use to check whether the additional
+ * functionality is available.
+ *
+ * This function registers the extension with the given name. It is recommended
+ * that the name follows the D-Bus interface naming convention, so that the
+ * names remain unique in case there will be at some point in the future
+ * extensions that aren't included with the main PulseAudio source tree. For
+ * in-tree extensions the convention is to use the org.PulseAudio.Ext
+ * namespace.
+ *
+ * It is suggested that the name contains a version number, and whenever the
+ * extension interface is modified in non-backwards compatible way, the version
+ * number is incremented.
+ *
+ * Fails and returns a negative number if the extension is already registered.
+ */
+int pa_dbus_protocol_register_extension(pa_dbus_protocol *p, const char *name);
+
+/* Returns a negative number if the extension isn't registered. */
+int pa_dbus_protocol_unregister_extension(pa_dbus_protocol *p, const char *name);
+
+/* All hooks have the pa_dbus_protocol object as hook data. */
+typedef enum pa_dbus_protocol_hook {
+    PA_DBUS_PROTOCOL_HOOK_EXTENSION_REGISTERED, /* Extension name as call data. */
+    PA_DBUS_PROTOCOL_HOOK_EXTENSION_UNREGISTERED, /* Extension name as call data. */
+    PA_DBUS_PROTOCOL_HOOK_MAX
+} pa_dbus_protocol_hook_t;
+
+pa_hook_slot *pa_dbus_protocol_hook_connect(
+        pa_dbus_protocol *p,
+        pa_dbus_protocol_hook_t hook,
+        pa_hook_priority_t prio,
+        pa_hook_cb_t cb,
+        void *data);
+
+#endif
index 2326eb3..52aa2c5 100644 (file)
@@ -28,7 +28,6 @@
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <limits.h>
 
 #include <pulse/rtclock.h>
 #include <pulse/sample.h>
@@ -46,7 +45,6 @@
 #include <pulsecore/source.h>
 #include <pulsecore/core-scache.h>
 #include <pulsecore/sample-util.h>
-#include <pulsecore/authkey.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/log.h>
 #include <pulsecore/core-util.h>
@@ -55,8 +53,7 @@
 #include <pulsecore/macro.h>
 #include <pulsecore/thread-mq.h>
 #include <pulsecore/shared.h>
-
-#include "endianmacros.h"
+#include <pulsecore/endianmacros.h>
 
 #include "protocol-esound.h"
 
@@ -328,12 +325,12 @@ static int format_native2esd(pa_sample_spec *ss) {
     return format;
 }
 
-#define CHECK_VALIDITY(expression, ...) do { \
-    if (!(expression)) { \
-        pa_log_warn(__FILE__ ": " __VA_ARGS__); \
-        return -1; \
-    } \
-} while(0);
+#define CHECK_VALIDITY(expression, ...) do {            \
+        if (PA_UNLIKELY(!(expression))) {               \
+            pa_log_warn(__FILE__ ": " __VA_ARGS__);     \
+            return -1;                                  \
+        }                                               \
+    } while(0);
 
 /*** esound commands ***/
 
@@ -389,6 +386,7 @@ static int esd_proto_stream_play(connection *c, esd_proto_t request, const void
     size_t l;
     pa_sink *sink = NULL;
     pa_sink_input_new_data sdata;
+    pa_memchunk silence;
 
     connection_assert_ref(c);
     pa_assert(data);
@@ -426,7 +424,8 @@ static int esd_proto_stream_play(connection *c, esd_proto_t request, const void
     sdata.driver = __FILE__;
     sdata.module = c->options->module;
     sdata.client = c->client;
-    sdata.sink = sink;
+    if (sink)
+        pa_sink_input_new_data_set_sink(&sdata, sink, FALSE);
     pa_sink_input_new_data_set_sample_spec(&sdata, &ss);
 
     pa_sink_input_new(&c->sink_input, c->protocol->core, &sdata);
@@ -435,15 +434,18 @@ static int esd_proto_stream_play(connection *c, esd_proto_t request, const void
     CHECK_VALIDITY(c->sink_input, "Failed to create sink input.");
 
     l = (size_t) ((double) pa_bytes_per_second(&ss)*PLAYBACK_BUFFER_SECONDS);
+    pa_sink_input_get_silence(c->sink_input, &silence);
     c->input_memblockq = pa_memblockq_new(
+            "esound protocol connection input_memblockq",
             0,
             l,
             l,
-            pa_frame_size(&ss),
+            &ss,
             (size_t) -1,
             l/PLAYBACK_BUFFER_FRAGMENTS,
             0,
-            NULL);
+            &silence);
+    pa_memblock_unref(silence.memblock);
     pa_iochannel_socket_set_rcvbuf(c->io, l);
 
     c->sink_input->parent.process_msg = sink_input_process_msg;
@@ -459,7 +461,7 @@ static int esd_proto_stream_play(connection *c, esd_proto_t request, const void
 
     c->protocol->n_player++;
 
-    pa_atomic_store(&c->playback.missing, (int) pa_memblockq_missing(c->input_memblockq));
+    pa_atomic_store(&c->playback.missing, (int) pa_memblockq_pop_missing(c->input_memblockq));
 
     pa_sink_input_put(c->sink_input);
 
@@ -522,7 +524,8 @@ static int esd_proto_stream_record(connection *c, esd_proto_t request, const voi
     sdata.driver = __FILE__;
     sdata.module = c->options->module;
     sdata.client = c->client;
-    sdata.source = source;
+    if (source)
+        pa_source_output_new_data_set_source(&sdata, source, FALSE);
     pa_source_output_new_data_set_sample_spec(&sdata, &ss);
 
     pa_source_output_new(&c->source_output, c->protocol->core, &sdata);
@@ -532,10 +535,11 @@ static int esd_proto_stream_record(connection *c, esd_proto_t request, const voi
 
     l = (size_t) (pa_bytes_per_second(&ss)*RECORD_BUFFER_SECONDS);
     c->output_memblockq = pa_memblockq_new(
+            "esound protocol connection output_memblockq",
             0,
             l,
             l,
-            pa_frame_size(&ss),
+            &ss,
             1,
             0,
             0,
@@ -628,7 +632,7 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da
 
     memset(terminator, 0, sizeof(terminator));
 
-    for (conn = pa_idxset_first(c->protocol->connections, &idx); conn; conn = pa_idxset_next(c->protocol->connections, &idx)) {
+    PA_IDXSET_FOREACH(conn, c->protocol->connections, idx) {
         int32_t id, format = ESD_BITS16 | ESD_STEREO, rate = 44100, lvolume = ESD_VOLUME_BASE, rvolume = ESD_VOLUME_BASE;
         char name[ESD_NAME_MAX];
 
@@ -686,7 +690,8 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da
         pa_scache_entry *ce;
 
         idx = PA_IDXSET_INVALID;
-        for (ce = pa_idxset_first(c->protocol->core->scache, &idx); ce; ce = pa_idxset_next(c->protocol->core->scache, &idx)) {
+
+        PA_IDXSET_FOREACH(ce, c->protocol->core->scache, idx) {
             int32_t id, rate, lvolume, rvolume, format, len;
             char name[ESD_NAME_MAX];
             pa_channel_map stereo = { .channels = 2, .map = { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } };
@@ -944,11 +949,16 @@ static int esd_proto_standby_or_resume(connection *c, esd_proto_t request, const
     connection_write_prepare(c, sizeof(int32_t) * 2);
     connection_write(c, &ok, sizeof(int32_t));
 
-    if (request == ESD_PROTO_STANDBY)
-        ok = pa_sink_suspend_all(c->protocol->core, TRUE, PA_SUSPEND_USER) >= 0;
-    else {
+    pa_log_debug("%s of all sinks and sources requested by client %" PRIu32 ".",
+                 request == ESD_PROTO_STANDBY ? "Suspending" : "Resuming", c->client->index);
+
+    if (request == ESD_PROTO_STANDBY) {
+        ok = pa_sink_suspend_all(c->protocol->core, true, PA_SUSPEND_USER) >= 0;
+        ok &= pa_source_suspend_all(c->protocol->core, true, PA_SUSPEND_USER) >= 0;
+    } else {
         pa_assert(request == ESD_PROTO_RESUME);
-        ok = pa_sink_suspend_all(c->protocol->core, FALSE, PA_SUSPEND_USER) >= 0;
+        ok = pa_sink_suspend_all(c->protocol->core, false, PA_SUSPEND_USER) >= 0;
+        ok &= pa_source_suspend_all(c->protocol->core, false, PA_SUSPEND_USER) >= 0;
     }
 
     connection_write(c, &ok, sizeof(int32_t));
@@ -1016,7 +1026,7 @@ static int do_read(connection *c) {
             c->request = PA_MAYBE_INT32_SWAP(c->swap_byte_order, c->request);
 
             if (c->request < ESD_PROTO_CONNECT || c->request >= ESD_PROTO_MAX) {
-                pa_log("recieved invalid request.");
+                pa_log("received invalid request.");
                 return -1;
             }
 
@@ -1025,7 +1035,7 @@ static int do_read(connection *c) {
 /*             pa_log("executing request #%u", c->request); */
 
             if (!handler->proc) {
-                pa_log("recieved unimplemented request #%u.", c->request);
+                pa_log("received unimplemented request #%u.", c->request);
                 return -1;
             }
 
@@ -1127,7 +1137,7 @@ static int do_read(connection *c) {
 
 /*         pa_log("STREAMING_DATA"); */
 
-        if (!(l = (size_t) pa_atomic_load(&c->playback.missing)))
+        if ((l = (size_t) pa_atomic_load(&c->playback.missing)) <= 0)
             return 0;
 
         if (c->playback.current_memblock) {
@@ -1169,8 +1179,8 @@ static int do_read(connection *c) {
 
         c->playback.memblock_index += (size_t) r;
 
-        pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, &chunk, NULL);
         pa_atomic_sub(&c->playback.missing, (int) r);
+        pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, &chunk, NULL);
     }
 
     return 0;
@@ -1378,10 +1388,9 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk
     } else {
         size_t m;
 
-        chunk->length = PA_MIN(length, chunk->length);
-
         c->playback.underrun = FALSE;
 
+        chunk->length = PA_MIN(length, chunk->length);
         pa_memblockq_drop(c->input_memblockq, chunk->length);
         m = pa_memblockq_pop_missing(c->input_memblockq);
 
@@ -1618,7 +1627,7 @@ void pa_esound_protocol_unref(pa_esound_protocol *p) {
     while ((c = pa_idxset_first(p->connections, NULL)))
         connection_unlink(c);
 
-    pa_idxset_free(p->connections, NULL, NULL);
+    pa_idxset_free(p->connections, NULL);
 
     pa_assert_se(pa_shared_remove(p->core, "esound-protocol") >= 0);
 
@@ -1707,7 +1716,7 @@ int pa_esound_options_parse(pa_esound_options *o, pa_core *c, pa_modargs *ma) {
             if (!(cn = pa_modargs_get_value(ma, "cookie", NULL)))
                 cn = DEFAULT_COOKIE_FILE;
 
-        if (!(o->auth_cookie = pa_auth_cookie_get(c, cn, ESD_KEY_LEN)))
+        if (!(o->auth_cookie = pa_auth_cookie_get(c, cn, TRUE, ESD_KEY_LEN)))
             return -1;
 
     } else
index c09e534..400150f 100644 (file)
@@ -32,6 +32,7 @@
 #include <pulse/xmalloc.h>
 #include <pulse/timeval.h>
 
+#include <pulsecore/core-util.h>
 #include <pulsecore/ioline.h>
 #include <pulsecore/thread-mq.h>
 #include <pulsecore/macro.h>
@@ -80,6 +81,11 @@ enum state {
     STATE_DATA
 };
 
+enum method {
+    METHOD_GET,
+    METHOD_HEAD
+};
+
 struct connection {
     pa_http_protocol *protocol;
     pa_iochannel *io;
@@ -89,6 +95,7 @@ struct connection {
     pa_client *client;
     enum state state;
     char *url;
+    enum method method;
     pa_module *module;
 };
 
@@ -327,6 +334,11 @@ static void html_response(
 
     http_response(c, code, msg, MIME_HTML);
 
+    if (c->method == METHOD_HEAD) {
+        pa_ioline_defer_close(c->line);
+        return;
+    }
+
     if (!text)
         text = msg;
 
@@ -363,6 +375,11 @@ static void handle_root(struct connection *c) {
 
     http_response(c, 200, "OK", MIME_HTML);
 
+    if (c->method == METHOD_HEAD) {
+        pa_ioline_defer_close(c->line);
+        return;
+    }
+
     pa_ioline_puts(c->line,
                    HTML_HEADER(PACKAGE_NAME" "PACKAGE_VERSION)
                    "<h1>"PACKAGE_NAME" "PACKAGE_VERSION"</h1>\n"
@@ -402,6 +419,11 @@ static void handle_css(struct connection *c) {
 
     http_response(c, 200, "OK", MIME_CSS);
 
+    if (c->method == METHOD_HEAD) {
+        pa_ioline_defer_close(c->line);
+        return;
+    }
+
     pa_ioline_puts(c->line,
                    "body { color: black; background-color: white; }\n"
                    "a:link, a:visited { color: #900000; }\n"
@@ -420,6 +442,12 @@ static void handle_status(struct connection *c) {
     pa_assert(c);
 
     http_response(c, 200, "OK", MIME_TEXT);
+
+    if (c->method == METHOD_HEAD) {
+        pa_ioline_defer_close(c->line);
+        return;
+    }
+
     r = pa_full_status_string(c->protocol->core);
     pa_ioline_puts(c->line, r);
     pa_xfree(r);
@@ -439,6 +467,11 @@ static void handle_listen(struct connection *c) {
                    "<h2>Sinks</h2>\n"
                    "<p>\n");
 
+    if (c->method == METHOD_HEAD) {
+        pa_ioline_defer_close(c->line);
+        return;
+    }
+
     PA_IDXSET_FOREACH(sink, c->protocol->core->sinks, idx) {
         char *t, *m;
 
@@ -528,7 +561,7 @@ static void handle_listen_prefix(struct connection *c, const char *source_name)
     data.driver = __FILE__;
     data.module = c->module;
     data.client = c->client;
-    data.source = source;
+    pa_source_output_new_data_set_source(&data, source, FALSE);
     pa_proplist_update(data.proplist, PA_UPDATE_MERGE, c->client->proplist);
     pa_source_output_new_data_set_sample_spec(&data, &ss);
     pa_source_output_new_data_set_channel_map(&data, &cm);
@@ -551,10 +584,11 @@ static void handle_listen_prefix(struct connection *c, const char *source_name)
 
     l = (size_t) (pa_bytes_per_second(&ss)*RECORD_BUFFER_SECONDS);
     c->output_memblockq = pa_memblockq_new(
+            "http protocol connection output_memblockq",
             0,
             l,
             0,
-            pa_frame_size(&ss),
+            &ss,
             1,
             0,
             0,
@@ -566,6 +600,10 @@ static void handle_listen_prefix(struct connection *c, const char *source_name)
     http_response(c, 200, "OK", t);
     pa_xfree(t);
 
+    if(c->method == METHOD_HEAD) {
+        connection_unlink(c);
+        return;
+    }
     pa_ioline_set_callback(c->line, NULL, NULL);
 
     if (pa_ioline_is_drained(c->line))
@@ -606,10 +644,15 @@ static void line_callback(pa_ioline *line, const char *s, void *userdata) {
 
     switch (c->state) {
         case STATE_REQUEST_LINE: {
-            if (!pa_startswith(s, "GET "))
+            if (pa_startswith(s, "GET ")) {
+                c->method = METHOD_GET;
+                s +=4;
+            } else if (pa_startswith(s, "HEAD ")) {
+                c->method = METHOD_HEAD;
+                s +=5;
+            } else {
                 goto fail;
-
-            s +=4;
+            }
 
             c->url = pa_xstrndup(s, strcspn(s, " \r\n\t?"));
             c->state = STATE_MIME_HEADER;
@@ -743,7 +786,7 @@ void pa_http_protocol_unref(pa_http_protocol *p) {
     while ((c = pa_idxset_first(p->connections, NULL)))
         connection_unlink(c);
 
-    pa_idxset_free(p->connections, NULL, NULL);
+    pa_idxset_free(p->connections, NULL);
 
     pa_strlist_free(p->servers);
 
old mode 100644 (file)
new mode 100755 (executable)
index 2be9146..a7094dc
@@ -35,6 +35,7 @@
 #include <pulse/utf8.h>
 #include <pulse/util.h>
 #include <pulse/xmalloc.h>
+#include <pulse/internal.h>
 
 #include <pulsecore/native-common.h>
 #include <pulsecore/packet.h>
@@ -45,7 +46,6 @@
 #include <pulsecore/tagstruct.h>
 #include <pulsecore/pdispatch.h>
 #include <pulsecore/pstream-util.h>
-#include <pulsecore/authkey.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/core-scache.h>
 #include <pulsecore/core-subscribe.h>
@@ -53,7 +53,6 @@
 #include <pulsecore/strlist.h>
 #include <pulsecore/shared.h>
 #include <pulsecore/sample-util.h>
-#include <pulsecore/llist.h>
 #include <pulsecore/creds.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/ipacl.h>
@@ -61,6 +60,8 @@
 
 #include "protocol-native.h"
 
+/* #define PROTOCOL_NATIVE_DEBUG */
+
 /* Kick a client if it doesn't authenticate within this time */
 #define AUTH_TIMEOUT (60 * PA_USEC_PER_SEC)
 
 #define DEFAULT_PROCESS_MSEC 20   /* 20ms */
 #define DEFAULT_FRAGSIZE_MSEC DEFAULT_TLENGTH_MSEC
 
+#define DEVICE_BUS_BUILTIN "builtin"
+
+#ifdef __TIZEN__
+#define MEDIA_POLICY_VOIP "voip"
+#endif
+
 struct pa_native_protocol;
 
 typedef struct record_stream {
@@ -86,6 +93,9 @@ typedef struct record_stream {
     pa_bool_t adjust_latency:1;
     pa_bool_t early_requests:1;
 
+    /* Requested buffer attributes */
+    pa_buffer_attr buffer_attr_req;
+    /* Fixed-up and adjusted buffer attributes */
     pa_buffer_attr buffer_attr;
 
     pa_atomic_t on_the_fly;
@@ -125,8 +135,15 @@ typedef struct playback_stream {
     uint32_t drain_tag;
     uint32_t syncid;
 
+    /* Optimization to avoid too many rewinds with a lot of small blocks */
+    pa_atomic_t seek_or_post_in_queue;
+    int64_t seek_windex;
+
     pa_atomic_t missing;
     pa_usec_t configured_sink_latency;
+    /* Requested buffer attributes */
+    pa_buffer_attr buffer_attr_req;
+    /* Fixed-up and adjusted buffer attributes */
     pa_buffer_attr buffer_attr;
 
     /* Only updated after SINK_INPUT_MESSAGE_UPDATE_LATENCY */
@@ -220,6 +237,7 @@ enum {
     CONNECTION_MESSAGE_REVOKE
 };
 
+static bool sink_input_process_underrun_cb(pa_sink_input *i);
 static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk);
 static void sink_input_kill_cb(pa_sink_input *i);
 static void sink_input_suspend_cb(pa_sink_input *i, pa_bool_t suspend);
@@ -264,8 +282,15 @@ static void command_subscribe(pa_pdispatch *pd, uint32_t command, uint32_t tag,
 static void command_set_volume(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
 static void command_set_mute(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
 static void command_cork_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
+#ifdef __TIZEN__
+static void command_cork_playback_stream_all(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
+#endif
 static void command_trigger_or_flush_or_prebuf_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
 static void command_set_default_sink_or_source(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
+#ifdef __TIZEN__
+static void command_set_default_sink_by_api_bus(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
+static void command_set_default_sink_for_usb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
+#endif
 static void command_set_stream_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
 static void command_kill(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
 static void command_load_module(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
@@ -281,6 +306,7 @@ static void command_remove_proplist(pa_pdispatch *pd, uint32_t command, uint32_t
 static void command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
 static void command_set_card_profile(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
 static void command_set_sink_or_source_port(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
+static void command_set_port_latency_offset(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
 
 static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
     [PA_COMMAND_ERROR] = NULL,
@@ -327,15 +353,20 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
     [PA_COMMAND_SET_SINK_VOLUME] = command_set_volume,
     [PA_COMMAND_SET_SINK_INPUT_VOLUME] = command_set_volume,
     [PA_COMMAND_SET_SOURCE_VOLUME] = command_set_volume,
+    [PA_COMMAND_SET_SOURCE_OUTPUT_VOLUME] = command_set_volume,
 
     [PA_COMMAND_SET_SINK_MUTE] = command_set_mute,
     [PA_COMMAND_SET_SINK_INPUT_MUTE] = command_set_mute,
     [PA_COMMAND_SET_SOURCE_MUTE] = command_set_mute,
+    [PA_COMMAND_SET_SOURCE_OUTPUT_MUTE] = command_set_mute,
 
     [PA_COMMAND_SUSPEND_SINK] = command_suspend,
     [PA_COMMAND_SUSPEND_SOURCE] = command_suspend,
 
     [PA_COMMAND_CORK_PLAYBACK_STREAM] = command_cork_playback_stream,
+#ifdef __TIZEN__
+    [PA_COMMAND_CORK_PLAYBACK_STREAM_ALL] = command_cork_playback_stream_all,
+#endif
     [PA_COMMAND_FLUSH_PLAYBACK_STREAM] = command_trigger_or_flush_or_prebuf_playback_stream,
     [PA_COMMAND_TRIGGER_PLAYBACK_STREAM] = command_trigger_or_flush_or_prebuf_playback_stream,
     [PA_COMMAND_PREBUF_PLAYBACK_STREAM] = command_trigger_or_flush_or_prebuf_playback_stream,
@@ -344,6 +375,10 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
     [PA_COMMAND_FLUSH_RECORD_STREAM] = command_flush_record_stream,
 
     [PA_COMMAND_SET_DEFAULT_SINK] = command_set_default_sink_or_source,
+#ifdef __TIZEN__
+    [PA_COMMAND_SET_DEFAULT_SINK_BY_API_BUS] = command_set_default_sink_by_api_bus,
+    [PA_COMMAND_SET_DEFAULT_SINK_FOR_USB] = command_set_default_sink_for_usb,
+#endif
     [PA_COMMAND_SET_DEFAULT_SOURCE] = command_set_default_sink_or_source,
     [PA_COMMAND_SET_PLAYBACK_STREAM_NAME] = command_set_stream_name,
     [PA_COMMAND_SET_RECORD_STREAM_NAME] = command_set_stream_name,
@@ -380,6 +415,8 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
     [PA_COMMAND_SET_SINK_PORT] = command_set_sink_or_source_port,
     [PA_COMMAND_SET_SOURCE_PORT] = command_set_sink_or_source_port,
 
+    [PA_COMMAND_SET_PORT_LATENCY_OFFSET] = command_set_port_latency_offset,
+
     [PA_COMMAND_EXTENSION] = command_extension
 };
 
@@ -521,6 +558,7 @@ static void fix_record_buffer_attr_pre(record_stream *s) {
      * ->thread_info data! */
 
     frame_size = pa_frame_size(&s->source_output->sample_spec);
+    s->buffer_attr = s->buffer_attr_req;
 
     if (s->buffer_attr.maxlength == (uint32_t) -1 || s->buffer_attr.maxlength > MAX_MEMBLOCKQ_LENGTH)
         s->buffer_attr.maxlength = MAX_MEMBLOCKQ_LENGTH;
@@ -617,18 +655,24 @@ static record_stream* record_stream_new(
         pa_source *source,
         pa_sample_spec *ss,
         pa_channel_map *map,
-        pa_bool_t peak_detect,
+        pa_idxset *formats,
         pa_buffer_attr *attr,
+        pa_cvolume *volume,
+        pa_bool_t muted,
+        pa_bool_t muted_set,
         pa_source_output_flags_t flags,
         pa_proplist *p,
         pa_bool_t adjust_latency,
-        pa_sink_input *direct_on_input,
         pa_bool_t early_requests,
+        pa_bool_t relative_volume,
+        pa_bool_t peak_detect,
+        pa_sink_input *direct_on_input,
         int *ret) {
 
     record_stream *s;
     pa_source_output *source_output = NULL;
     pa_source_output_new_data data;
+    char *memblockq_name;
 
     pa_assert(c);
     pa_assert(ss);
@@ -641,10 +685,24 @@ static record_stream* record_stream_new(
     data.driver = __FILE__;
     data.module = c->options->module;
     data.client = c->client;
-    data.source = source;
+    if (source)
+        pa_source_output_new_data_set_source(&data, source, FALSE);
+    if (pa_sample_spec_valid(ss))
+        pa_source_output_new_data_set_sample_spec(&data, ss);
+    if (pa_channel_map_valid(map))
+        pa_source_output_new_data_set_channel_map(&data, map);
+    if (formats)
+        pa_source_output_new_data_set_formats(&data, formats);
     data.direct_on_input = direct_on_input;
-    pa_source_output_new_data_set_sample_spec(&data, ss);
-    pa_source_output_new_data_set_channel_map(&data, map);
+    if (volume) {
+        pa_source_output_new_data_set_volume(&data, volume);
+        data.volume_is_absolute = !relative_volume;
+        data.save_volume = FALSE;
+    }
+    if (muted_set) {
+        pa_source_output_new_data_set_muted(&data, muted);
+        data.save_muted = FALSE;
+    }
     if (peak_detect)
         data.resample_method = PA_RESAMPLER_PEAKS;
     data.flags = flags;
@@ -661,7 +719,7 @@ static record_stream* record_stream_new(
     s->parent.process_msg = record_stream_process_msg;
     s->connection = c;
     s->source_output = source_output;
-    s->buffer_attr = *attr;
+    s->buffer_attr_req = *attr;
     s->adjust_latency = adjust_latency;
     s->early_requests = early_requests;
     pa_atomic_store(&s->on_the_fly, 0);
@@ -677,15 +735,18 @@ static record_stream* record_stream_new(
 
     fix_record_buffer_attr_pre(s);
 
+    memblockq_name = pa_sprintf_malloc("native protocol record stream memblockq [%u]", s->source_output->index);
     s->memblockq = pa_memblockq_new(
+            memblockq_name,
             0,
             s->buffer_attr.maxlength,
             0,
-            pa_frame_size(&source_output->sample_spec),
+            &source_output->sample_spec,
             1,
             0,
             0,
             NULL);
+    pa_xfree(memblockq_name);
 
     pa_memblockq_get_attr(s->memblockq, &s->buffer_attr);
     fix_record_buffer_attr_post(s);
@@ -777,20 +838,26 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata,
             pa_tagstruct_putu32(t, (uint32_t) l);
             pa_pstream_send_tagstruct(s->connection->pstream, t);
 
-/*             pa_log("Requesting %lu bytes", (unsigned long) l); */
+#ifdef PROTOCOL_NATIVE_DEBUG
+            pa_log("Requesting %lu bytes", (unsigned long) l);
+#endif
             break;
         }
 
         case PLAYBACK_STREAM_MESSAGE_UNDERFLOW: {
             pa_tagstruct *t;
 
-/*             pa_log("signalling underflow"); */
+#ifdef PROTOCOL_NATIVE_DEBUG
+            pa_log("signalling underflow");
+#endif
 
             /* Report that we're empty */
             t = pa_tagstruct_new(NULL, 0);
             pa_tagstruct_putu32(t, PA_COMMAND_UNDERFLOW);
             pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
             pa_tagstruct_putu32(t, s->index);
+            if (s->connection->version >= 23)
+                pa_tagstruct_puts64(t, offset);
             pa_pstream_send_tagstruct(s->connection->pstream, t);
             break;
         }
@@ -858,12 +925,27 @@ static void fix_playback_buffer_attr(playback_stream *s) {
 
     pa_assert(s);
 
+#ifdef PROTOCOL_NATIVE_DEBUG
+    pa_log("Client requested: maxlength=%li bytes tlength=%li bytes minreq=%li bytes prebuf=%li bytes",
+           (long) s->buffer_attr_req.maxlength,
+           (long) s->buffer_attr_req.tlength,
+           (long) s->buffer_attr_req.minreq,
+           (long) s->buffer_attr_req.prebuf);
+
+    pa_log("Client requested: maxlength=%lu ms tlength=%lu ms minreq=%lu ms prebuf=%lu ms",
+           (unsigned long) (pa_bytes_to_usec(s->buffer_attr_req.maxlength, &s->sink_input->sample_spec) / PA_USEC_PER_MSEC),
+           (unsigned long) (pa_bytes_to_usec(s->buffer_attr_req.tlength, &s->sink_input->sample_spec) / PA_USEC_PER_MSEC),
+           (unsigned long) (pa_bytes_to_usec(s->buffer_attr_req.minreq, &s->sink_input->sample_spec) / PA_USEC_PER_MSEC),
+           (unsigned long) (pa_bytes_to_usec(s->buffer_attr_req.prebuf, &s->sink_input->sample_spec) / PA_USEC_PER_MSEC));
+#endif
+
     /* This function will be called from the main thread, before as
      * well as after the sink input has been activated using
      * pa_sink_input_put()! That means it may not touch any
      * ->thread_info data, such as the memblockq! */
 
     frame_size = pa_frame_size(&s->sink_input->sample_spec);
+    s->buffer_attr = s->buffer_attr_req;
 
     if (s->buffer_attr.maxlength == (uint32_t) -1 || s->buffer_attr.maxlength > MAX_MEMBLOCKQ_LENGTH)
         s->buffer_attr.maxlength = MAX_MEMBLOCKQ_LENGTH;
@@ -874,9 +956,17 @@ static void fix_playback_buffer_attr(playback_stream *s) {
         s->buffer_attr.tlength = (uint32_t) pa_usec_to_bytes_round_up(DEFAULT_TLENGTH_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec);
     if (s->buffer_attr.tlength <= 0)
         s->buffer_attr.tlength = (uint32_t) frame_size;
+    if (s->buffer_attr.tlength > s->buffer_attr.maxlength)
+        s->buffer_attr.tlength = s->buffer_attr.maxlength;
 
-    if (s->buffer_attr.minreq == (uint32_t) -1)
-        s->buffer_attr.minreq = (uint32_t) pa_usec_to_bytes_round_up(DEFAULT_PROCESS_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec);
+    if (s->buffer_attr.minreq == (uint32_t) -1) {
+        uint32_t process = (uint32_t) pa_usec_to_bytes_round_up(DEFAULT_PROCESS_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec);
+        /* With low-latency, tlength/4 gives a decent default in all of traditional, adjust latency and early request modes. */
+        uint32_t m = s->buffer_attr.tlength / 4;
+        if (frame_size)
+            m -= m % frame_size;
+        s->buffer_attr.minreq = PA_MIN(process, m);
+    }
     if (s->buffer_attr.minreq <= 0)
         s->buffer_attr.minreq = (uint32_t) frame_size;
 
@@ -886,7 +976,7 @@ static void fix_playback_buffer_attr(playback_stream *s) {
     orig_tlength_usec = tlength_usec = pa_bytes_to_usec(s->buffer_attr.tlength, &s->sink_input->sample_spec);
     orig_minreq_usec = minreq_usec = pa_bytes_to_usec(s->buffer_attr.minreq, &s->sink_input->sample_spec);
 
-    pa_log_info("Requested tlength=%0.2f ms, minreq=%0.2f ms",
+    pa_log_debug_verbose("Requested tlength=%0.2f ms, minreq=%0.2f ms",
                 (double) tlength_usec / PA_USEC_PER_MSEC,
                 (double) minreq_usec / PA_USEC_PER_MSEC);
 
@@ -897,7 +987,7 @@ static void fix_playback_buffer_attr(playback_stream *s) {
          * latency to the fragment size. */
 
         sink_usec = minreq_usec;
-        pa_log_debug("Early requests mode enabled, configuring sink latency to minreq.");
+        pa_log_debug_verbose("Early requests mode enabled, configuring sink latency to minreq.");
 
     } else if (s->adjust_latency) {
 
@@ -907,9 +997,9 @@ static void fix_playback_buffer_attr(playback_stream *s) {
          * half the latency will be spent on the hw buffer, the other
          * half of it in the async buffer queue we maintain for each
          * client. In between we'll have a safety space of size
-         * 2*minreq. Why the 2*minreq? When the hw buffer is completey
+         * 2*minreq. Why the 2*minreq? When the hw buffer is completely
          * empty and needs to be filled, then our buffer must have
-         * enough data to fulfill this request immediatly and thus
+         * enough data to fulfill this request immediately and thus
          * have at least the same tlength as the size of the hw
          * buffer. It additionally needs space for 2 times minreq
          * because if the buffer ran empty and a partial fillup
@@ -923,7 +1013,7 @@ static void fix_playback_buffer_attr(playback_stream *s) {
         else
             sink_usec = 0;
 
-        pa_log_debug("Adjust latency mode enabled, configuring sink latency to half of overall latency.");
+        pa_log_debug_verbose("Adjust latency mode enabled, configuring sink latency to half of overall latency.");
 
     } else {
 
@@ -936,7 +1026,7 @@ static void fix_playback_buffer_attr(playback_stream *s) {
         else
             sink_usec = 0;
 
-        pa_log_debug("Traditional mode enabled, modifying sink usec only for compat with minreq.");
+        pa_log_debug_verbose("Traditional mode enabled, modifying sink usec only for compat with minreq.");
     }
 
     s->configured_sink_latency = pa_sink_input_set_requested_latency(s->sink_input, sink_usec);
@@ -958,6 +1048,10 @@ static void fix_playback_buffer_attr(playback_stream *s) {
             tlength_usec -= s->configured_sink_latency;
     }
 
+    pa_log_debug_verbose("Requested latency=%0.2f ms, Received latency=%0.2f ms",
+                 (double) sink_usec / PA_USEC_PER_MSEC,
+                 (double) s->configured_sink_latency / PA_USEC_PER_MSEC);
+
     /* FIXME: This is actually larger than necessary, since not all of
      * the sink latency is actually rewritable. */
     if (tlength_usec < s->configured_sink_latency + 2*minreq_usec)
@@ -984,6 +1078,14 @@ static void fix_playback_buffer_attr(playback_stream *s) {
     if (s->buffer_attr.prebuf == (uint32_t) -1 ||
         s->buffer_attr.prebuf > max_prebuf)
         s->buffer_attr.prebuf = max_prebuf;
+
+#ifdef PROTOCOL_NATIVE_DEBUG
+    pa_log("Client accepted: maxlength=%lu ms tlength=%lu ms minreq=%lu ms prebuf=%lu ms",
+           (unsigned long) (pa_bytes_to_usec(s->buffer_attr.maxlength, &s->sink_input->sample_spec) / PA_USEC_PER_MSEC),
+           (unsigned long) (pa_bytes_to_usec(s->buffer_attr.tlength, &s->sink_input->sample_spec) / PA_USEC_PER_MSEC),
+           (unsigned long) (pa_bytes_to_usec(s->buffer_attr.minreq, &s->sink_input->sample_spec) / PA_USEC_PER_MSEC),
+           (unsigned long) (pa_bytes_to_usec(s->buffer_attr.prebuf, &s->sink_input->sample_spec) / PA_USEC_PER_MSEC));
+#endif
 }
 
 /* Called from main context */
@@ -992,24 +1094,31 @@ static playback_stream* playback_stream_new(
         pa_sink *sink,
         pa_sample_spec *ss,
         pa_channel_map *map,
+        pa_idxset *formats,
         pa_buffer_attr *a,
         pa_cvolume *volume,
         pa_bool_t muted,
         pa_bool_t muted_set,
-        uint32_t syncid,
-        uint32_t *missing,
         pa_sink_input_flags_t flags,
         pa_proplist *p,
         pa_bool_t adjust_latency,
         pa_bool_t early_requests,
+        pa_bool_t relative_volume,
+        uint32_t syncid,
+        uint32_t *missing,
         int *ret) {
 
-    playback_stream *s, *ssync;
+    /* Note: This function takes ownership of the 'formats' param, so we need
+     * to take extra care to not leak it */
+
+    playback_stream *ssync;
+    playback_stream *s = NULL;
     pa_sink_input *sink_input = NULL;
     pa_memchunk silence;
     uint32_t idx;
     int64_t start_index;
     pa_sink_input_new_data data;
+    char *memblockq_name;
 
     pa_assert(c);
     pa_assert(ss);
@@ -1018,7 +1127,7 @@ static playback_stream* playback_stream_new(
     pa_assert(ret);
 
     /* Find syncid group */
-    for (ssync = pa_idxset_first(c->output_streams, &idx); ssync; ssync = pa_idxset_next(c->output_streams, &idx)) {
+    PA_IDXSET_FOREACH(ssync, c->output_streams, idx) {
 
         if (!playback_stream_isinstance(ssync))
             continue;
@@ -1034,7 +1143,7 @@ static playback_stream* playback_stream_new(
             sink = ssync->sink_input->sink;
         else if (sink != ssync->sink_input->sink) {
             *ret = PA_ERR_INVALID;
-            return NULL;
+            goto out;
         }
     }
 
@@ -1044,20 +1153,25 @@ static playback_stream* playback_stream_new(
     data.driver = __FILE__;
     data.module = c->options->module;
     data.client = c->client;
-    if (sink) {
-        data.sink = sink;
-        data.save_sink = TRUE;
+    if (sink)
+        pa_sink_input_new_data_set_sink(&data, sink, FALSE);
+    if (pa_sample_spec_valid(ss))
+        pa_sink_input_new_data_set_sample_spec(&data, ss);
+    if (pa_channel_map_valid(map))
+        pa_sink_input_new_data_set_channel_map(&data, map);
+    if (formats) {
+        pa_sink_input_new_data_set_formats(&data, formats);
+        /* Ownership transferred to new_data, so we don't free it ourselves */
+        formats = NULL;
     }
-    pa_sink_input_new_data_set_sample_spec(&data, ss);
-    pa_sink_input_new_data_set_channel_map(&data, map);
     if (volume) {
         pa_sink_input_new_data_set_volume(&data, volume);
-        data.volume_is_absolute = TRUE;
-        data.save_volume = TRUE;
+        data.volume_is_absolute = !relative_volume;
+        data.save_volume = FALSE;
     }
     if (muted_set) {
         pa_sink_input_new_data_set_muted(&data, muted);
-        data.save_muted = TRUE;
+        data.save_muted = FALSE;
     }
     data.sync_base = ssync ? ssync->sink_input : NULL;
     data.flags = flags;
@@ -1067,7 +1181,7 @@ static playback_stream* playback_stream_new(
     pa_sink_input_new_data_done(&data);
 
     if (!sink_input)
-        return NULL;
+        goto out;
 
     s = pa_msgobject_new(playback_stream);
     s->parent.parent.parent.free = playback_stream_free;
@@ -1078,12 +1192,15 @@ static playback_stream* playback_stream_new(
     s->is_underrun = TRUE;
     s->drain_request = FALSE;
     pa_atomic_store(&s->missing, 0);
-    s->buffer_attr = *a;
+    s->buffer_attr_req = *a;
     s->adjust_latency = adjust_latency;
     s->early_requests = early_requests;
+    pa_atomic_store(&s->seek_or_post_in_queue, 0);
+    s->seek_windex = -1;
 
     s->sink_input->parent.process_msg = sink_input_process_msg;
     s->sink_input->pop = sink_input_pop_cb;
+    s->sink_input->process_underrun = sink_input_process_underrun_cb;
     s->sink_input->process_rewind = sink_input_process_rewind_cb;
     s->sink_input->update_max_rewind = sink_input_update_max_rewind_cb;
     s->sink_input->update_max_request = sink_input_update_max_request_cb;
@@ -1098,33 +1215,45 @@ static playback_stream* playback_stream_new(
     fix_playback_buffer_attr(s);
 
     pa_sink_input_get_silence(sink_input, &silence);
+    memblockq_name = pa_sprintf_malloc("native protocol playback stream memblockq [%u]", s->sink_input->index);
     s->memblockq = pa_memblockq_new(
+            memblockq_name,
             start_index,
             s->buffer_attr.maxlength,
             s->buffer_attr.tlength,
-            pa_frame_size(&sink_input->sample_spec),
+            &sink_input->sample_spec,
             s->buffer_attr.prebuf,
             s->buffer_attr.minreq,
             0,
             &silence);
+    pa_xfree(memblockq_name);
     pa_memblock_unref(silence.memblock);
 
     pa_memblockq_get_attr(s->memblockq, &s->buffer_attr);
 
     *missing = (uint32_t) pa_memblockq_pop_missing(s->memblockq);
 
+#ifdef PROTOCOL_NATIVE_DEBUG
+    pa_log("missing original: %li", (long int) *missing);
+#endif
+
     *ss = s->sink_input->sample_spec;
     *map = s->sink_input->channel_map;
 
     pa_idxset_put(c->output_streams, s, &s->index);
 
-    pa_log_info("Final latency %0.2f ms = %0.2f ms + 2*%0.2f ms + %0.2f ms",
+    pa_log_info_debug("Final latency %0.2f ms = %0.2f ms + 2*%0.2f ms + %0.2f ms",
                 ((double) pa_bytes_to_usec(s->buffer_attr.tlength, &sink_input->sample_spec) + (double) s->configured_sink_latency) / PA_USEC_PER_MSEC,
                 (double) pa_bytes_to_usec(s->buffer_attr.tlength-s->buffer_attr.minreq*2, &sink_input->sample_spec) / PA_USEC_PER_MSEC,
                 (double) pa_bytes_to_usec(s->buffer_attr.minreq, &sink_input->sample_spec) / PA_USEC_PER_MSEC,
                 (double) s->configured_sink_latency / PA_USEC_PER_MSEC);
 
     pa_sink_input_put(s->sink_input);
+
+out:
+    if (formats)
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
+
     return s;
 }
 
@@ -1137,16 +1266,19 @@ static void playback_stream_request_bytes(playback_stream *s) {
 
     m = pa_memblockq_pop_missing(s->memblockq);
 
-    /* pa_log("request_bytes(%lu) (tlength=%lu minreq=%lu length=%lu)", */
+    /* pa_log("request_bytes(%lu) (tlength=%lu minreq=%lu length=%lu really missing=%lli)", */
     /*        (unsigned long) m, */
     /*        pa_memblockq_get_tlength(s->memblockq), */
     /*        pa_memblockq_get_minreq(s->memblockq), */
-    /*        pa_memblockq_get_length(s->memblockq)); */
+    /*        pa_memblockq_get_length(s->memblockq), */
+    /*        (long long) pa_memblockq_get_tlength(s->memblockq) - (long long) pa_memblockq_get_length(s->memblockq)); */
 
     if (m <= 0)
         return;
 
-/*     pa_log("request_bytes(%lu)", (unsigned long) m); */
+#ifdef PROTOCOL_NATIVE_DEBUG
+    pa_log("request_bytes(%lu)", (unsigned long) m);
+#endif
 
     previous_missing = pa_atomic_add(&s->missing, (int) m);
     minreq = pa_memblockq_get_minreq(s->memblockq);
@@ -1238,8 +1370,8 @@ static void native_connection_free(pa_object *o) {
 
     native_connection_unlink(c);
 
-    pa_idxset_free(c->record_streams, NULL, NULL);
-    pa_idxset_free(c->output_streams, NULL, NULL);
+    pa_idxset_free(c->record_streams, NULL);
+    pa_idxset_free(c->output_streams, NULL);
 
     pa_pdispatch_unref(c->pdispatch);
     pa_pstream_unref(c->pstream);
@@ -1265,7 +1397,7 @@ static void native_connection_send_memblock(pa_native_connection *c) {
         else if (start == c->rrobin_index)
             return;
 
-        if (pa_memblockq_peek(r->memblockq,  &chunk) >= 0) {
+        if (pa_memblockq_peek(r->memblockq, &chunk) >= 0) {
             pa_memchunk schunk = chunk;
 
             if (schunk.length > r->buffer_attr.fragsize)
@@ -1298,7 +1430,7 @@ static void handle_seek(playback_stream *s, int64_t indexw) {
             /* We just ended an underrun, let's ask the sink
              * for a complete rewind rewrite */
 
-            pa_log_debug("Requesting rewind due to end of underrun.");
+            pa_log_debug_verbose("Requesting rewind due to end of underrun.");
             pa_sink_input_request_rewind(s->sink_input,
                                          (size_t) (s->sink_input->thread_info.underrun_for == (uint64_t) -1 ? 0 :
                                                    s->sink_input->thread_info.underrun_for),
@@ -1311,23 +1443,11 @@ static void handle_seek(playback_stream *s, int64_t indexw) {
         indexr = pa_memblockq_get_read_index(s->memblockq);
 
         if (indexw < indexr) {
-
-       #if 1
-
-            pa_log_debug("Requesting rewind due to rewrite. indexw:%lld, indexr:%lld", indexw, indexr);
-
-           pa_memblockq_flush_read(s->memblockq);
-    
-       #else
-
             /* OK, the sink already asked for this data, so
-             * let's have it usk us again */
+             * let's have it ask us again */
 
             pa_log_debug("Requesting rewind due to rewrite.");
             pa_sink_input_request_rewind(s->sink_input, (size_t) (indexr - indexw), TRUE, FALSE, FALSE);
-
-       #endif
-
         }
     }
 
@@ -1349,42 +1469,45 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int
 
     switch (code) {
 
-        case SINK_INPUT_MESSAGE_SEEK: {
-            int64_t windex;
-
-            windex = pa_memblockq_get_write_index(s->memblockq);
-
-            /* The client side is incapable of accounting correctly
-             * for seeks of a type != PA_SEEK_RELATIVE. We need to be
-             * able to deal with that. */
-
-            pa_memblockq_seek(s->memblockq, offset, PA_PTR_TO_UINT(userdata), PA_PTR_TO_UINT(userdata) == PA_SEEK_RELATIVE);
-
-            handle_seek(s, windex);
-            return 0;
-        }
-
+        case SINK_INPUT_MESSAGE_SEEK:
         case SINK_INPUT_MESSAGE_POST_DATA: {
-            int64_t windex;
-
-            pa_assert(chunk);
+            int64_t windex = pa_memblockq_get_write_index(s->memblockq);
 
-            windex = pa_memblockq_get_write_index(s->memblockq);
-
-/*             pa_log("sink input post: %lu %lli", (unsigned long) chunk->length, (long long) windex); */
+            if (code == SINK_INPUT_MESSAGE_SEEK) {
+                /* The client side is incapable of accounting correctly
+                 * for seeks of a type != PA_SEEK_RELATIVE. We need to be
+                 * able to deal with that. */
 
-            if (pa_memblockq_push_align(s->memblockq, chunk) < 0) {
+                pa_memblockq_seek(s->memblockq, offset, PA_PTR_TO_UINT(userdata), PA_PTR_TO_UINT(userdata) == PA_SEEK_RELATIVE);
+                windex = PA_MIN(windex, pa_memblockq_get_write_index(s->memblockq));
+            }
 
-                if (pa_log_ratelimit())
+            if (chunk && pa_memblockq_push_align(s->memblockq, chunk) < 0) {
+                if (pa_log_ratelimit(PA_LOG_WARN))
                     pa_log_warn("Failed to push data into queue");
                 pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_OVERFLOW, NULL, 0, NULL, NULL);
                 pa_memblockq_seek(s->memblockq, (int64_t) chunk->length, PA_SEEK_RELATIVE, TRUE);
             }
 
-            handle_seek(s, windex);
-
-/*             pa_log("sink input post2: %lu", (unsigned long) pa_memblockq_get_length(s->memblockq)); */
+            /* If more data is in queue, we rewind later instead. */
+            if (s->seek_windex != -1)
+                windex = PA_MIN(windex, s->seek_windex);
+            if (pa_atomic_dec(&s->seek_or_post_in_queue) > 1)
+                s->seek_windex = windex;
+            else {
+#ifdef __TIZEN__
+                const char *name = NULL;
+#endif
+                s->seek_windex = -1;
 
+#ifdef __TIZEN__
+                name = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_POLICY);
+                if (!name || (name && !pa_streq(name, MEDIA_POLICY_VOIP)))
+                    handle_seek(s, windex);
+#else
+                    handle_seek(s, windex);
+#endif
+            }
             return 0;
         }
 
@@ -1397,9 +1520,9 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int
             pa_sink_input *isync;
             void (*func)(pa_memblockq *bq);
 
-            switch  (code) {
+            switch (code) {
                 case SINK_INPUT_MESSAGE_FLUSH:
-                    func = flush_write_no_account;//pa_memblockq_flush_write;
+                    func = flush_write_no_account;
                     break;
 
                 case SINK_INPUT_MESSAGE_PREBUF_FORCE:
@@ -1434,6 +1557,13 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int
                 handle_seek(ssync, windex);
             }
 
+#ifdef __TIZEN__
+            if (code == SINK_INPUT_MESSAGE_FLUSH) {
+                pa_log_debug("Requesting rewind due to rewrite. Flush old data in sink");
+                pa_sink_input_request_rewind(s->sink_input, 0, FALSE, TRUE, FALSE);
+            }
+#endif
+
             if (code == SINK_INPUT_MESSAGE_DRAIN) {
                 if (!pa_memblockq_is_readable(s->memblockq))
                     pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_DRAIN_ACK, userdata, 0, NULL, NULL);
@@ -1490,36 +1620,62 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int
     return pa_sink_input_process_msg(o, code, userdata, offset, chunk);
 }
 
+
+static bool handle_input_underrun(playback_stream *s, bool force)
+{
+    bool send_drain;
+
+    if (pa_memblockq_is_readable(s->memblockq))
+        return false;
+
+    if (!s->is_underrun)
+        pa_log_debug_verbose("%s %s of '%s'", force ? "Actual" : "Implicit",
+            s->drain_request ? "drain" : "underrun", pa_strnull(pa_proplist_gets(s->sink_input->proplist, PA_PROP_MEDIA_NAME)));
+
+    send_drain = s->drain_request && (force || pa_sink_input_safe_to_remove(s->sink_input));
+
+    if (send_drain) {
+         s->drain_request = false;
+         pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_DRAIN_ACK, PA_UINT_TO_PTR(s->drain_tag), 0, NULL, NULL);
+         pa_log_debug("Drain acknowledged of '%s'", pa_strnull(pa_proplist_gets(s->sink_input->proplist, PA_PROP_MEDIA_NAME)));
+    } else if (!s->is_underrun) {
+         pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_UNDERFLOW, NULL, pa_memblockq_get_read_index(s->memblockq), NULL, NULL);
+    }
+    s->is_underrun = true;
+    playback_stream_request_bytes(s);
+    return true;
+}
+
 /* Called from thread context */
-static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
+static bool sink_input_process_underrun_cb(pa_sink_input *i) {
     playback_stream *s;
 
     pa_sink_input_assert_ref(i);
     s = PLAYBACK_STREAM(i->userdata);
     playback_stream_assert_ref(s);
-    pa_assert(chunk);
 
-/*     pa_log("%s, pop(): %lu", pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME), (unsigned long) pa_memblockq_get_length(s->memblockq)); */
+    return handle_input_underrun(s, true);
+}
 
-    if (pa_memblockq_is_readable(s->memblockq))
-        s->is_underrun = FALSE;
-    else {
-        if (!s->is_underrun)
-            pa_log_debug("Underrun on '%s', %lu bytes in queue.", pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)), (unsigned long) pa_memblockq_get_length(s->memblockq));
 
-        if (s->drain_request && pa_sink_input_safe_to_remove(i)) {
-            s->drain_request = FALSE;
-            pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_DRAIN_ACK, PA_UINT_TO_PTR(s->drain_tag), 0, NULL, NULL);
-        } else if (!s->is_underrun)
-            pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_UNDERFLOW, NULL, 0, NULL, NULL);
+/* Called from thread context */
+static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {
+    playback_stream *s;
 
-        s->is_underrun = TRUE;
+    pa_sink_input_assert_ref(i);
+    s = PLAYBACK_STREAM(i->userdata);
+    playback_stream_assert_ref(s);
+    pa_assert(chunk);
 
-        playback_stream_request_bytes(s);
-    }
+#ifdef PROTOCOL_NATIVE_DEBUG
+    pa_log("%s, pop(): %lu", pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME), (unsigned long) pa_memblockq_get_length(s->memblockq));
+#endif
+
+    if (!handle_input_underrun(s, false))
+        s->is_underrun = false;
 
     /* This call will not fail with prebuf=0, hence we check for
-       underrun explicitly above */
+       underrun explicitly in handle_input_underrun */
     if (pa_memblockq_peek(s->memblockq, chunk) < 0)
         return -1;
 
@@ -1580,7 +1736,7 @@ static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) {
         if (new_tlength == old_tlength)
             pa_log_debug("Failed to increase tlength");
         else {
-            pa_log_debug("Notifying client about increased tlength");
+            pa_log_debug_verbose("Notifying client about increased tlength");
             pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_UPDATE_TLENGTH, NULL, pa_memblockq_get_tlength(s->memblockq), NULL, NULL);
         }
     }
@@ -1828,6 +1984,13 @@ if (!(expression)) { \
 } \
 } while(0);
 
+#define CHECK_VALIDITY_GOTO(pstream, expression, tag, error, label) do { \
+if (!(expression)) { \
+    pa_pstream_send_error((pstream), (tag), (error)); \
+    goto label; \
+} \
+} while(0);
+
 static pa_tagstruct *reply_new(uint32_t tag) {
     pa_tagstruct *reply;
 
@@ -1840,7 +2003,7 @@ static pa_tagstruct *reply_new(uint32_t tag) {
 static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
     pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
     playback_stream *s;
-    uint32_t sink_index, syncid, missing;
+    uint32_t sink_index, syncid, missing = 0;
     pa_buffer_attr attr;
     const char *name = NULL, *sink_name;
     pa_sample_spec ss;
@@ -1861,12 +2024,19 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
         adjust_latency = FALSE,
         early_requests = FALSE,
         dont_inhibit_auto_suspend = FALSE,
+        volume_set = TRUE,
         muted_set = FALSE,
-        fail_on_suspend = FALSE;
+        fail_on_suspend = FALSE,
+        relative_volume = FALSE,
+        passthrough = FALSE;
+
     pa_sink_input_flags_t flags = 0;
-    pa_proplist *p;
-    pa_bool_t volume_set = TRUE;
+    pa_proplist *p = NULL;
     int ret = PA_ERR_INVALID;
+    uint8_t n_formats = 0;
+    pa_format_info *format;
+    pa_idxset *formats = NULL;
+    uint32_t i;
 
     pa_native_connection_assert_ref(c);
     pa_assert(t);
@@ -1889,24 +2059,21 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
                 PA_TAG_INVALID) < 0) {
 
         protocol_error(c);
-        return;
+        goto finish;
     }
 
-    CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
-    CHECK_VALIDITY(c->pstream, !sink_name || pa_namereg_is_valid_name_or_wildcard(sink_name, PA_NAMEREG_SINK), tag, PA_ERR_INVALID);
-    CHECK_VALIDITY(c->pstream, sink_index == PA_INVALID_INDEX || !sink_name, tag, PA_ERR_INVALID);
-    CHECK_VALIDITY(c->pstream, !sink_name || sink_index == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
-    CHECK_VALIDITY(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID);
-    CHECK_VALIDITY(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID);
-    CHECK_VALIDITY(c->pstream, pa_cvolume_valid(&volume), tag, PA_ERR_INVALID);
-    CHECK_VALIDITY(c->pstream, map.channels == ss.channels && volume.channels == ss.channels, tag, PA_ERR_INVALID);
+    CHECK_VALIDITY_GOTO(c->pstream, c->authorized, tag, PA_ERR_ACCESS, finish);
+    CHECK_VALIDITY_GOTO(c->pstream, !sink_name || pa_namereg_is_valid_name_or_wildcard(sink_name, PA_NAMEREG_SINK), tag, PA_ERR_INVALID, finish);
+    CHECK_VALIDITY_GOTO(c->pstream, sink_index == PA_INVALID_INDEX || !sink_name, tag, PA_ERR_INVALID, finish);
+    CHECK_VALIDITY_GOTO(c->pstream, !sink_name || sink_index == PA_INVALID_INDEX, tag, PA_ERR_INVALID, finish);
+    CHECK_VALIDITY_GOTO(c->pstream, pa_cvolume_valid(&volume), tag, PA_ERR_INVALID, finish);
 
     p = pa_proplist_new();
 
     if (name)
         pa_proplist_sets(p, PA_PROP_MEDIA_NAME, name);
 
-    if (c->version >= 12)  {
+    if (c->version >= 12) {
         /* Since 0.9.8 the user can ask for a couple of additional flags */
 
         if (pa_tagstruct_get_boolean(t, &no_remap) < 0 ||
@@ -1918,8 +2085,7 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
             pa_tagstruct_get_boolean(t, &variable_rate) < 0) {
 
             protocol_error(c);
-            pa_proplist_free(p);
-            return;
+            goto finish;
         }
     }
 
@@ -1928,9 +2094,9 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
         if (pa_tagstruct_get_boolean(t, &muted) < 0 ||
             pa_tagstruct_get_boolean(t, &adjust_latency) < 0 ||
             pa_tagstruct_get_proplist(t, p) < 0) {
+
             protocol_error(c);
-            pa_proplist_free(p);
-            return;
+            goto finish;
         }
     }
 
@@ -1938,9 +2104,9 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
 
         if (pa_tagstruct_get_boolean(t, &volume_set) < 0 ||
             pa_tagstruct_get_boolean(t, &early_requests) < 0) {
+
             protocol_error(c);
-            pa_proplist_free(p);
-            return;
+            goto finish;
         }
     }
 
@@ -1949,55 +2115,101 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
         if (pa_tagstruct_get_boolean(t, &muted_set) < 0 ||
             pa_tagstruct_get_boolean(t, &dont_inhibit_auto_suspend) < 0 ||
             pa_tagstruct_get_boolean(t, &fail_on_suspend) < 0) {
+
             protocol_error(c);
-            pa_proplist_free(p);
-            return;
+            goto finish;
+        }
+    }
+
+    if (c->version >= 17) {
+
+        if (pa_tagstruct_get_boolean(t, &relative_volume) < 0) {
+
+            protocol_error(c);
+            goto finish;
+        }
+    }
+
+    if (c->version >= 18) {
+
+        if (pa_tagstruct_get_boolean(t, &passthrough) < 0 ) {
+            protocol_error(c);
+            goto finish;
+        }
+    }
+
+    if (c->version >= 21) {
+
+        if (pa_tagstruct_getu8(t, &n_formats) < 0) {
+            protocol_error(c);
+            goto finish;
+        }
+
+        if (n_formats)
+            formats = pa_idxset_new(NULL, NULL);
+
+        for (i = 0; i < n_formats; i++) {
+            format = pa_format_info_new();
+            if (pa_tagstruct_get_format_info(t, format) < 0) {
+                protocol_error(c);
+                goto finish;
+            }
+            pa_idxset_put(formats, format, NULL);
+        }
+    }
+
+    if (n_formats == 0) {
+        CHECK_VALIDITY_GOTO(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID, finish);
+        CHECK_VALIDITY_GOTO(c->pstream, map.channels == ss.channels && volume.channels == ss.channels, tag, PA_ERR_INVALID, finish);
+        CHECK_VALIDITY_GOTO(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID, finish);
+    } else {
+        PA_IDXSET_FOREACH(format, formats, i) {
+            CHECK_VALIDITY_GOTO(c->pstream, pa_format_info_valid(format), tag, PA_ERR_INVALID, finish);
         }
     }
 
     if (!pa_tagstruct_eof(t)) {
         protocol_error(c);
-        pa_proplist_free(p);
-        return;
+        goto finish;
     }
 
     if (sink_index != PA_INVALID_INDEX) {
 
         if (!(sink = pa_idxset_get_by_index(c->protocol->core->sinks, sink_index))) {
             pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
-            pa_proplist_free(p);
-            return;
+            goto finish;
         }
 
     } else if (sink_name) {
 
         if (!(sink = pa_namereg_get(c->protocol->core, sink_name, PA_NAMEREG_SINK))) {
             pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
-            pa_proplist_free(p);
-            return;
+            goto finish;
         }
     }
 
     flags =
-        (corked ?  PA_SINK_INPUT_START_CORKED : 0) |
-        (no_remap ?  PA_SINK_INPUT_NO_REMAP : 0) |
-        (no_remix ?  PA_SINK_INPUT_NO_REMIX : 0) |
-        (fix_format ?  PA_SINK_INPUT_FIX_FORMAT : 0) |
-        (fix_rate ?  PA_SINK_INPUT_FIX_RATE : 0) |
-        (fix_channels ?  PA_SINK_INPUT_FIX_CHANNELS : 0) |
-        (no_move ?  PA_SINK_INPUT_DONT_MOVE : 0) |
-        (variable_rate ?  PA_SINK_INPUT_VARIABLE_RATE : 0) |
+        (corked ? PA_SINK_INPUT_START_CORKED : 0) |
+        (no_remap ? PA_SINK_INPUT_NO_REMAP : 0) |
+        (no_remix ? PA_SINK_INPUT_NO_REMIX : 0) |
+        (fix_format ? PA_SINK_INPUT_FIX_FORMAT : 0) |
+        (fix_rate ? PA_SINK_INPUT_FIX_RATE : 0) |
+        (fix_channels ? PA_SINK_INPUT_FIX_CHANNELS : 0) |
+        (no_move ? PA_SINK_INPUT_DONT_MOVE : 0) |
+        (variable_rate ? PA_SINK_INPUT_VARIABLE_RATE : 0) |
         (dont_inhibit_auto_suspend ? PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND : 0) |
-        (fail_on_suspend ? PA_SINK_INPUT_NO_CREATE_ON_SUSPEND|PA_SINK_INPUT_KILL_ON_SUSPEND : 0);
+        (fail_on_suspend ? PA_SINK_INPUT_NO_CREATE_ON_SUSPEND|PA_SINK_INPUT_KILL_ON_SUSPEND : 0) |
+        (passthrough ? PA_SINK_INPUT_PASSTHROUGH : 0);
 
-    /* Only since protocol version 15 there's a seperate muted_set
+    /* Only since protocol version 15 there's a separate muted_set
      * flag. For older versions we synthesize it here */
     muted_set = muted_set || muted;
 
-    s = playback_stream_new(c, sink, &ss, &map, &attr, volume_set ? &volume : NULL, muted, muted_set, syncid, &missing, flags, p, adjust_latency, early_requests, &ret);
-    pa_proplist_free(p);
+    s = playback_stream_new(c, sink, &ss, &map, formats, &attr, volume_set ? &volume : NULL, muted, muted_set, flags, p, adjust_latency, early_requests, relative_volume, syncid, &missing, &ret);
+    /* We no longer own the formats idxset */
+    formats = NULL;
 
-    CHECK_VALIDITY(c->pstream, s, tag, ret);
+    CHECK_VALIDITY_GOTO(c->pstream, s, tag, ret, finish);
 
     reply = reply_new(tag);
     pa_tagstruct_putu32(reply, s->index);
@@ -2005,7 +2217,9 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
     pa_tagstruct_putu32(reply, s->sink_input->index);
     pa_tagstruct_putu32(reply, missing);
 
-/*     pa_log("initial request is %u", missing); */
+#ifdef PROTOCOL_NATIVE_DEBUG
+    pa_log("initial request is %u", missing);
+#endif
 
     if (c->version >= 9) {
         /* Since 0.9.0 we support sending the buffer metrics back to the client */
@@ -2033,7 +2247,24 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
     if (c->version >= 13)
         pa_tagstruct_put_usec(reply, s->configured_sink_latency);
 
+    if (c->version >= 21) {
+        /* Send back the format we negotiated */
+        if (s->sink_input->format)
+            pa_tagstruct_put_format_info(reply, s->sink_input->format);
+        else {
+            pa_format_info *f = pa_format_info_new();
+            pa_tagstruct_put_format_info(reply, f);
+            pa_format_info_free(f);
+        }
+    }
+
     pa_pstream_send_tagstruct(c->pstream, reply);
+
+finish:
+    if (p)
+        pa_proplist_free(p);
+    if (formats)
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
 }
 
 static void command_delete_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
@@ -2104,6 +2335,7 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
     pa_channel_map map;
     pa_tagstruct *reply;
     pa_source *source = NULL;
+    pa_cvolume volume;
     pa_bool_t
         corked = FALSE,
         no_remap = FALSE,
@@ -2113,16 +2345,26 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
         fix_channels = FALSE,
         no_move = FALSE,
         variable_rate = FALSE,
+        muted = FALSE,
         adjust_latency = FALSE,
         peak_detect = FALSE,
         early_requests = FALSE,
         dont_inhibit_auto_suspend = FALSE,
-        fail_on_suspend = FALSE;
+        volume_set = FALSE,
+        muted_set = FALSE,
+        fail_on_suspend = FALSE,
+        relative_volume = FALSE,
+        passthrough = FALSE;
+
     pa_source_output_flags_t flags = 0;
-    pa_proplist *p;
+    pa_proplist *p = NULL;
     uint32_t direct_on_input_idx = PA_INVALID_INDEX;
     pa_sink_input *direct_on_input = NULL;
     int ret = PA_ERR_INVALID;
+    uint8_t n_formats = 0;
+    pa_format_info *format;
+    pa_idxset *formats = NULL;
+    uint32_t i;
 
     pa_native_connection_assert_ref(c);
     pa_assert(t);
@@ -2137,24 +2379,25 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
         pa_tagstruct_getu32(t, &attr.maxlength) < 0 ||
         pa_tagstruct_get_boolean(t, &corked) < 0 ||
         pa_tagstruct_getu32(t, &attr.fragsize) < 0) {
+
         protocol_error(c);
-        return;
+        goto finish;
     }
 
-    CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
-    CHECK_VALIDITY(c->pstream, !source_name || pa_namereg_is_valid_name_or_wildcard(source_name, PA_NAMEREG_SOURCE), tag, PA_ERR_INVALID);
-    CHECK_VALIDITY(c->pstream, source_index == PA_INVALID_INDEX || !source_name, tag, PA_ERR_INVALID);
-    CHECK_VALIDITY(c->pstream, !source_name || source_index == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
-    CHECK_VALIDITY(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID);
-    CHECK_VALIDITY(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID);
-    CHECK_VALIDITY(c->pstream, map.channels == ss.channels, tag, PA_ERR_INVALID);
+    CHECK_VALIDITY_GOTO(c->pstream, c->authorized, tag, PA_ERR_ACCESS, finish);
+    CHECK_VALIDITY_GOTO(c->pstream, !source_name || pa_namereg_is_valid_name_or_wildcard(source_name, PA_NAMEREG_SOURCE), tag, PA_ERR_INVALID, finish);
+    CHECK_VALIDITY_GOTO(c->pstream, source_index == PA_INVALID_INDEX || !source_name, tag, PA_ERR_INVALID, finish);
+    CHECK_VALIDITY_GOTO(c->pstream, !source_name || source_index == PA_INVALID_INDEX, tag, PA_ERR_INVALID, finish);
 
+#ifdef USE_SECURITY
+    CHECK_VALIDITY(c->pstream, pa_pstream_check_security(c->pstream), tag, PA_ERR_ACCESS_BY_SECURITY);
+#endif /* USE_SECURITY */
     p = pa_proplist_new();
 
     if (name)
         pa_proplist_sets(p, PA_PROP_MEDIA_NAME, name);
 
-    if (c->version >= 12)  {
+    if (c->version >= 12) {
         /* Since 0.9.8 the user can ask for a couple of additional flags */
 
         if (pa_tagstruct_get_boolean(t, &no_remap) < 0 ||
@@ -2166,8 +2409,7 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
             pa_tagstruct_get_boolean(t, &variable_rate) < 0) {
 
             protocol_error(c);
-            pa_proplist_free(p);
-            return;
+            goto finish;
         }
     }
 
@@ -2177,9 +2419,9 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
             pa_tagstruct_get_boolean(t, &adjust_latency) < 0 ||
             pa_tagstruct_get_proplist(t, p) < 0 ||
             pa_tagstruct_getu32(t, &direct_on_input_idx) < 0) {
+
             protocol_error(c);
-            pa_proplist_free(p);
-            return;
+            goto finish;
         }
     }
 
@@ -2187,8 +2429,7 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
 
         if (pa_tagstruct_get_boolean(t, &early_requests) < 0) {
             protocol_error(c);
-            pa_proplist_free(p);
-            return;
+            goto finish;
         }
     }
 
@@ -2196,32 +2437,77 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
 
         if (pa_tagstruct_get_boolean(t, &dont_inhibit_auto_suspend) < 0 ||
             pa_tagstruct_get_boolean(t, &fail_on_suspend) < 0) {
+
             protocol_error(c);
-            pa_proplist_free(p);
-            return;
+            goto finish;
         }
     }
 
+    if (c->version >= 22) {
+        /* For newer client versions (with per-source-output volumes), we try
+         * to make the behaviour for playback and record streams the same. */
+        volume_set = TRUE;
+
+        if (pa_tagstruct_getu8(t, &n_formats) < 0) {
+            protocol_error(c);
+            goto finish;
+        }
+
+        if (n_formats)
+            formats = pa_idxset_new(NULL, NULL);
+
+        for (i = 0; i < n_formats; i++) {
+            format = pa_format_info_new();
+            if (pa_tagstruct_get_format_info(t, format) < 0) {
+                protocol_error(c);
+                goto finish;
+            }
+            pa_idxset_put(formats, format, NULL);
+        }
+
+        if (pa_tagstruct_get_cvolume(t, &volume) < 0 ||
+            pa_tagstruct_get_boolean(t, &muted) < 0 ||
+            pa_tagstruct_get_boolean(t, &volume_set) < 0 ||
+            pa_tagstruct_get_boolean(t, &muted_set) < 0 ||
+            pa_tagstruct_get_boolean(t, &relative_volume) < 0 ||
+            pa_tagstruct_get_boolean(t, &passthrough) < 0) {
+
+            protocol_error(c);
+            goto finish;
+        }
+
+        CHECK_VALIDITY_GOTO(c->pstream, pa_cvolume_valid(&volume), tag, PA_ERR_INVALID, finish);
+    }
+
+    if (n_formats == 0) {
+        CHECK_VALIDITY_GOTO(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID, finish);
+        CHECK_VALIDITY_GOTO(c->pstream, map.channels == ss.channels, tag, PA_ERR_INVALID, finish);
+        CHECK_VALIDITY_GOTO(c->pstream, c->version < 22 || (volume.channels == ss.channels), tag, PA_ERR_INVALID, finish);
+        CHECK_VALIDITY_GOTO(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID, finish);
+    } else {
+        PA_IDXSET_FOREACH(format, formats, i) {
+            CHECK_VALIDITY_GOTO(c->pstream, pa_format_info_valid(format), tag, PA_ERR_INVALID, finish);
+        }
+    }
+
+
     if (!pa_tagstruct_eof(t)) {
         protocol_error(c);
-        pa_proplist_free(p);
-        return;
+        goto finish;
     }
 
     if (source_index != PA_INVALID_INDEX) {
 
         if (!(source = pa_idxset_get_by_index(c->protocol->core->sources, source_index))) {
             pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
-            pa_proplist_free(p);
-            return;
+            goto finish;
         }
 
     } else if (source_name) {
 
         if (!(source = pa_namereg_get(c->protocol->core, source_name, PA_NAMEREG_SOURCE))) {
             pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
-            pa_proplist_free(p);
-            return;
+            goto finish;
         }
     }
 
@@ -2229,27 +2515,26 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
 
         if (!(direct_on_input = pa_idxset_get_by_index(c->protocol->core->sink_inputs, direct_on_input_idx))) {
             pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
-            pa_proplist_free(p);
-            return;
+            goto finish;
         }
     }
 
     flags =
-        (corked ?  PA_SOURCE_OUTPUT_START_CORKED : 0) |
-        (no_remap ?  PA_SOURCE_OUTPUT_NO_REMAP : 0) |
-        (no_remix ?  PA_SOURCE_OUTPUT_NO_REMIX : 0) |
-        (fix_format ?  PA_SOURCE_OUTPUT_FIX_FORMAT : 0) |
-        (fix_rate ?  PA_SOURCE_OUTPUT_FIX_RATE : 0) |
-        (fix_channels ?  PA_SOURCE_OUTPUT_FIX_CHANNELS : 0) |
-        (no_move ?  PA_SOURCE_OUTPUT_DONT_MOVE : 0) |
-        (variable_rate ?  PA_SOURCE_OUTPUT_VARIABLE_RATE : 0) |
+        (corked ? PA_SOURCE_OUTPUT_START_CORKED : 0) |
+        (no_remap ? PA_SOURCE_OUTPUT_NO_REMAP : 0) |
+        (no_remix ? PA_SOURCE_OUTPUT_NO_REMIX : 0) |
+        (fix_format ? PA_SOURCE_OUTPUT_FIX_FORMAT : 0) |
+        (fix_rate ? PA_SOURCE_OUTPUT_FIX_RATE : 0) |
+        (fix_channels ? PA_SOURCE_OUTPUT_FIX_CHANNELS : 0) |
+        (no_move ? PA_SOURCE_OUTPUT_DONT_MOVE : 0) |
+        (variable_rate ? PA_SOURCE_OUTPUT_VARIABLE_RATE : 0) |
         (dont_inhibit_auto_suspend ? PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND : 0) |
-        (fail_on_suspend ? PA_SOURCE_OUTPUT_NO_CREATE_ON_SUSPEND|PA_SOURCE_OUTPUT_KILL_ON_SUSPEND : 0);
+        (fail_on_suspend ? PA_SOURCE_OUTPUT_NO_CREATE_ON_SUSPEND|PA_SOURCE_OUTPUT_KILL_ON_SUSPEND : 0) |
+        (passthrough ? PA_SOURCE_OUTPUT_PASSTHROUGH : 0);
 
-    s = record_stream_new(c, source, &ss, &map, peak_detect, &attr, flags, p, adjust_latency, direct_on_input, early_requests, &ret);
-    pa_proplist_free(p);
+    s = record_stream_new(c, source, &ss, &map, formats, &attr, volume_set ? &volume : NULL, muted, muted_set, flags, p, adjust_latency, early_requests, relative_volume, peak_detect, direct_on_input, &ret);
 
-    CHECK_VALIDITY(c->pstream, s, tag, ret);
+    CHECK_VALIDITY_GOTO(c->pstream, s, tag, ret, finish);
 
     reply = reply_new(tag);
     pa_tagstruct_putu32(reply, s->index);
@@ -2280,7 +2565,24 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
     if (c->version >= 13)
         pa_tagstruct_put_usec(reply, s->configured_source_latency);
 
+    if (c->version >= 22) {
+        /* Send back the format we negotiated */
+        if (s->source_output->format)
+            pa_tagstruct_put_format_info(reply, s->source_output->format);
+        else {
+            pa_format_info *f = pa_format_info_new();
+            pa_tagstruct_put_format_info(reply, f);
+            pa_format_info_free(f);
+        }
+    }
+
     pa_pstream_send_tagstruct(c->pstream, reply);
+
+finish:
+    if (p)
+        pa_proplist_free(p);
+    if (formats)
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
 }
 
 static void command_exit(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
@@ -2334,7 +2636,7 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
         c->version &= 0x7FFFFFFFU;
     }
 
-    pa_log_debug("Protocol version: remote %u, local %u", c->version, PA_PROTOCOL_VERSION);
+    pa_log_debug_verbose("Protocol version: remote %u, local %u", c->version, PA_PROTOCOL_VERSION);
 
     pa_proplist_setf(c->client->proplist, "native-protocol.version", "%u", c->version);
 
@@ -2364,7 +2666,7 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
                 }
             }
 
-            pa_log_info("Got credentials: uid=%lu gid=%lu success=%i",
+            pa_log_debug_verbose("Got credentials: uid=%lu gid=%lu success=%i",
                         (unsigned long) creds->uid,
                         (unsigned long) creds->gid,
                         (int) success);
@@ -2397,7 +2699,7 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
         pa_mempool_is_shared(c->protocol->core->mempool) &&
         c->is_local;
 
-    pa_log_debug("SHM possible: %s", pa_yes_no(do_shm));
+    pa_log_debug_verbose("SHM possible: %s", pa_yes_no(do_shm));
 
     if (do_shm)
         if (c->version < 10 || (c->version >= 13 && !shm_on_remote))
@@ -2415,7 +2717,7 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
     }
 #endif
 
-    pa_log_debug("Negotiated SHM: %s", pa_yes_no(do_shm));
+    pa_log_debug_verbose("Negotiated SHM: %s", pa_yes_no(do_shm));
     pa_pstream_enable_shm(c->pstream, do_shm);
 
     reply = reply_new(tag);
@@ -2871,7 +3173,7 @@ static void sink_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_sin
         PA_TAG_STRING, sink->monitor_source ? sink->monitor_source->name : NULL,
         PA_TAG_USEC, pa_sink_get_latency(sink),
         PA_TAG_STRING, sink->driver,
-        PA_TAG_U32, sink->flags,
+        PA_TAG_U32, sink->flags & PA_SINK_CLIENT_FLAGS_MASK,
         PA_TAG_INVALID);
 
     if (c->version >= 13) {
@@ -2889,21 +3191,34 @@ static void sink_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_sin
     }
 
     if (c->version >= 16) {
-        pa_tagstruct_putu32(t, sink->ports ? pa_hashmap_size(sink->ports) : 0);
+        void *state;
+        pa_device_port *p;
 
-        if (sink->ports) {
-            void *state;
-            pa_device_port *p;
+        pa_tagstruct_putu32(t, pa_hashmap_size(sink->ports));
 
-            PA_HASHMAP_FOREACH(p, sink->ports, state) {
-                pa_tagstruct_puts(t, p->name);
-                pa_tagstruct_puts(t, p->description);
-                pa_tagstruct_putu32(t, p->priority);
-            }
+        PA_HASHMAP_FOREACH(p, sink->ports, state) {
+            pa_tagstruct_puts(t, p->name);
+            pa_tagstruct_puts(t, p->description);
+            pa_tagstruct_putu32(t, p->priority);
+            if (c->version >= 24)
+                pa_tagstruct_putu32(t, p->available);
         }
 
         pa_tagstruct_puts(t, sink->active_port ? sink->active_port->name : NULL);
     }
+
+    if (c->version >= 21) {
+        uint32_t i;
+        pa_format_info *f;
+        pa_idxset *formats = pa_sink_get_formats(sink);
+
+        pa_tagstruct_putu8(t, (uint8_t) pa_idxset_size(formats));
+        PA_IDXSET_FOREACH(f, formats, i) {
+            pa_tagstruct_put_format_info(t, f);
+        }
+
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
+    }
 }
 
 static void source_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_source *source) {
@@ -2928,7 +3243,7 @@ static void source_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_s
         PA_TAG_STRING, source->monitor_of ? source->monitor_of->name : NULL,
         PA_TAG_USEC, pa_source_get_latency(source),
         PA_TAG_STRING, source->driver,
-        PA_TAG_U32, source->flags,
+        PA_TAG_U32, source->flags & PA_SOURCE_CLIENT_FLAGS_MASK,
         PA_TAG_INVALID);
 
     if (c->version >= 13) {
@@ -2946,22 +3261,34 @@ static void source_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_s
     }
 
     if (c->version >= 16) {
+        void *state;
+        pa_device_port *p;
 
-        pa_tagstruct_putu32(t, source->ports ? pa_hashmap_size(source->ports) : 0);
+        pa_tagstruct_putu32(t, pa_hashmap_size(source->ports));
 
-        if (source->ports) {
-            void *state;
-            pa_device_port *p;
-
-            PA_HASHMAP_FOREACH(p, source->ports, state) {
-                pa_tagstruct_puts(t, p->name);
-                pa_tagstruct_puts(t, p->description);
-                pa_tagstruct_putu32(t, p->priority);
-            }
+        PA_HASHMAP_FOREACH(p, source->ports, state) {
+            pa_tagstruct_puts(t, p->name);
+            pa_tagstruct_puts(t, p->description);
+            pa_tagstruct_putu32(t, p->priority);
+            if (c->version >= 24)
+                pa_tagstruct_putu32(t, p->available);
         }
 
         pa_tagstruct_puts(t, source->active_port ? source->active_port->name : NULL);
     }
+
+    if (c->version >= 22) {
+        uint32_t i;
+        pa_format_info *f;
+        pa_idxset *formats = pa_source_get_formats(source);
+
+        pa_tagstruct_putu8(t, (uint8_t) pa_idxset_size(formats));
+        PA_IDXSET_FOREACH(f, formats, i) {
+            pa_tagstruct_put_format_info(t, f);
+        }
+
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
+    }
 }
 
 static void client_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_client *client) {
@@ -2980,6 +3307,7 @@ static void client_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_c
 static void card_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_card *card) {
     void *state = NULL;
     pa_card_profile *p;
+    pa_device_port *port;
 
     pa_assert(t);
     pa_assert(card);
@@ -2989,20 +3317,42 @@ static void card_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_car
     pa_tagstruct_putu32(t, card->module ? card->module->index : PA_INVALID_INDEX);
     pa_tagstruct_puts(t, card->driver);
 
-    pa_tagstruct_putu32(t, card->profiles ? pa_hashmap_size(card->profiles) : 0);
+    pa_tagstruct_putu32(t, pa_hashmap_size(card->profiles));
 
-    if (card->profiles) {
-        while ((p = pa_hashmap_iterate(card->profiles, &state, NULL))) {
-            pa_tagstruct_puts(t, p->name);
-            pa_tagstruct_puts(t, p->description);
-            pa_tagstruct_putu32(t, p->n_sinks);
-            pa_tagstruct_putu32(t, p->n_sources);
-            pa_tagstruct_putu32(t, p->priority);
-        }
+    PA_HASHMAP_FOREACH(p, card->profiles, state) {
+        pa_tagstruct_puts(t, p->name);
+        pa_tagstruct_puts(t, p->description);
+        pa_tagstruct_putu32(t, p->n_sinks);
+        pa_tagstruct_putu32(t, p->n_sources);
+        pa_tagstruct_putu32(t, p->priority);
     }
 
-    pa_tagstruct_puts(t, card->active_profile ? card->active_profile->name : NULL);
+    pa_tagstruct_puts(t, card->active_profile->name);
     pa_tagstruct_put_proplist(t, card->proplist);
+
+    if (c->version < 26)
+        return;
+
+    pa_tagstruct_putu32(t, pa_hashmap_size(card->ports));
+
+    PA_HASHMAP_FOREACH(port, card->ports, state) {
+        void *state2;
+
+        pa_tagstruct_puts(t, port->name);
+        pa_tagstruct_puts(t, port->description);
+        pa_tagstruct_putu32(t, port->priority);
+        pa_tagstruct_putu32(t, port->available);
+        pa_tagstruct_putu8(t, /* FIXME: port->direction */ (port->is_input ? PA_DIRECTION_INPUT : 0) | (port->is_output ? PA_DIRECTION_OUTPUT : 0));
+        pa_tagstruct_put_proplist(t, port->proplist);
+
+        pa_tagstruct_putu32(t, pa_hashmap_size(port->profiles));
+
+        PA_HASHMAP_FOREACH(p, port->profiles, state2)
+            pa_tagstruct_puts(t, p->name);
+
+        if (c->version >= 27)
+            pa_tagstruct_puts64(t, port->latency_offset);
+    }
 }
 
 static void module_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_module *module) {
@@ -3025,12 +3375,19 @@ static void sink_input_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t,
     pa_sample_spec fixed_ss;
     pa_usec_t sink_latency;
     pa_cvolume v;
+    pa_bool_t has_volume = FALSE;
 
     pa_assert(t);
     pa_sink_input_assert_ref(s);
 
     fixup_sample_spec(c, &fixed_ss, &s->sample_spec);
 
+    has_volume = pa_sink_input_is_volume_readable(s);
+    if (has_volume)
+        pa_sink_input_get_volume(s, &v, TRUE);
+    else
+        pa_cvolume_reset(&v, fixed_ss.channels);
+
     pa_tagstruct_putu32(t, s->index);
     pa_tagstruct_puts(t, pa_strnull(pa_proplist_gets(s->proplist, PA_PROP_MEDIA_NAME)));
     pa_tagstruct_putu32(t, s->module ? s->module->index : PA_INVALID_INDEX);
@@ -3038,7 +3395,7 @@ static void sink_input_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t,
     pa_tagstruct_putu32(t, s->sink->index);
     pa_tagstruct_put_sample_spec(t, &fixed_ss);
     pa_tagstruct_put_channel_map(t, &s->channel_map);
-    pa_tagstruct_put_cvolume(t, pa_sink_input_get_volume(s, &v, TRUE));
+    pa_tagstruct_put_cvolume(t, &v);
     pa_tagstruct_put_usec(t, pa_sink_input_get_latency(s, &sink_latency));
     pa_tagstruct_put_usec(t, sink_latency);
     pa_tagstruct_puts(t, pa_resample_method_to_string(pa_sink_input_get_resample_method(s)));
@@ -3047,17 +3404,33 @@ static void sink_input_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t,
         pa_tagstruct_put_boolean(t, pa_sink_input_get_mute(s));
     if (c->version >= 13)
         pa_tagstruct_put_proplist(t, s->proplist);
+    if (c->version >= 19)
+        pa_tagstruct_put_boolean(t, (pa_sink_input_get_state(s) == PA_SINK_INPUT_CORKED));
+    if (c->version >= 20) {
+        pa_tagstruct_put_boolean(t, has_volume);
+        pa_tagstruct_put_boolean(t, s->volume_writable);
+    }
+    if (c->version >= 21)
+        pa_tagstruct_put_format_info(t, s->format);
 }
 
 static void source_output_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_source_output *s) {
     pa_sample_spec fixed_ss;
     pa_usec_t source_latency;
+    pa_cvolume v;
+    pa_bool_t has_volume = FALSE;
 
     pa_assert(t);
     pa_source_output_assert_ref(s);
 
     fixup_sample_spec(c, &fixed_ss, &s->sample_spec);
 
+    has_volume = pa_source_output_is_volume_readable(s);
+    if (has_volume)
+        pa_source_output_get_volume(s, &v, TRUE);
+    else
+        pa_cvolume_reset(&v, fixed_ss.channels);
+
     pa_tagstruct_putu32(t, s->index);
     pa_tagstruct_puts(t, pa_strnull(pa_proplist_gets(s->proplist, PA_PROP_MEDIA_NAME)));
     pa_tagstruct_putu32(t, s->module ? s->module->index : PA_INVALID_INDEX);
@@ -3069,9 +3442,17 @@ static void source_output_fill_tagstruct(pa_native_connection *c, pa_tagstruct *
     pa_tagstruct_put_usec(t, source_latency);
     pa_tagstruct_puts(t, pa_resample_method_to_string(pa_source_output_get_resample_method(s)));
     pa_tagstruct_puts(t, s->driver);
-
     if (c->version >= 13)
         pa_tagstruct_put_proplist(t, s->proplist);
+    if (c->version >= 19)
+        pa_tagstruct_put_boolean(t, (pa_source_output_get_state(s) == PA_SOURCE_OUTPUT_CORKED));
+    if (c->version >= 22) {
+        pa_tagstruct_put_cvolume(t, &v);
+        pa_tagstruct_put_boolean(t, pa_source_output_get_mute(s));
+        pa_tagstruct_put_boolean(t, has_volume);
+        pa_tagstruct_put_boolean(t, s->volume_writable);
+        pa_tagstruct_put_format_info(t, s->format);
+    }
 }
 
 static void scache_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_scache_entry *e) {
@@ -3141,7 +3522,9 @@ static void command_get_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, p
                    (command == PA_COMMAND_GET_SOURCE_INFO &&
                     pa_namereg_is_valid_name_or_wildcard(name, PA_NAMEREG_SOURCE)) ||
                    pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
-    CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID);
+    CHECK_VALIDITY(c->pstream, command == PA_COMMAND_GET_SINK_INFO ||
+                   command == PA_COMMAND_GET_SOURCE_INFO ||
+                   (idx != PA_INVALID_INDEX || name), tag, PA_ERR_INVALID);
     CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID);
     CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
 
@@ -3240,7 +3623,7 @@ static void command_get_info_list(pa_pdispatch *pd, uint32_t command, uint32_t t
     }
 
     if (i) {
-        for (p = pa_idxset_first(i, &idx); p; p = pa_idxset_next(i, &idx)) {
+        PA_IDXSET_FOREACH(p, i, idx) {
             if (command == PA_COMMAND_GET_SINK_INFO_LIST)
                 sink_fill_tagstruct(c, reply, p);
             else if (command == PA_COMMAND_GET_SOURCE_INFO_LIST)
@@ -3366,6 +3749,7 @@ static void command_set_volume(
     pa_sink *sink = NULL;
     pa_source *source = NULL;
     pa_sink_input *si = NULL;
+    pa_source_output *so = NULL;
     const char *name = NULL;
     const char *client_name;
 
@@ -3408,11 +3792,15 @@ static void command_set_volume(
             si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx);
             break;
 
+        case PA_COMMAND_SET_SOURCE_OUTPUT_VOLUME:
+            so = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx);
+            break;
+
         default:
             pa_assert_not_reached();
     }
 
-    CHECK_VALIDITY(c->pstream, si || sink || source, tag, PA_ERR_NOENTITY);
+    CHECK_VALIDITY(c->pstream, si || so || sink || source, tag, PA_ERR_NOENTITY);
 
     client_name = pa_strnull(pa_proplist_gets(c->client->proplist, PA_PROP_APPLICATION_PROCESS_BINARY));
 
@@ -3425,14 +3813,22 @@ static void command_set_volume(
         CHECK_VALIDITY(c->pstream, volume.channels == 1 || pa_cvolume_compatible(&volume, &source->sample_spec), tag, PA_ERR_INVALID);
 
         pa_log_debug("Client %s changes volume of source %s.", client_name, source->name);
-        pa_source_set_volume(source, &volume, TRUE);
+        pa_source_set_volume(source, &volume, TRUE, TRUE);
     } else if (si) {
+        CHECK_VALIDITY(c->pstream, si->volume_writable, tag, PA_ERR_BADSTATE);
         CHECK_VALIDITY(c->pstream, volume.channels == 1 || pa_cvolume_compatible(&volume, &si->sample_spec), tag, PA_ERR_INVALID);
 
         pa_log_debug("Client %s changes volume of sink input %s.",
                      client_name,
                      pa_strnull(pa_proplist_gets(si->proplist, PA_PROP_MEDIA_NAME)));
         pa_sink_input_set_volume(si, &volume, TRUE, TRUE);
+    } else if (so) {
+        CHECK_VALIDITY(c->pstream, volume.channels == 1 || pa_cvolume_compatible(&volume, &so->sample_spec), tag, PA_ERR_INVALID);
+
+        pa_log_debug("Client %s changes volume of source output %s.",
+                     client_name,
+                     pa_strnull(pa_proplist_gets(so->proplist, PA_PROP_MEDIA_NAME)));
+        pa_source_output_set_volume(so, &volume, TRUE, TRUE);
     }
 
     pa_pstream_send_simple_ack(c->pstream, tag);
@@ -3451,6 +3847,7 @@ static void command_set_mute(
     pa_sink *sink = NULL;
     pa_source *source = NULL;
     pa_sink_input *si = NULL;
+    pa_source_output *so = NULL;
     const char *name = NULL, *client_name;
 
     pa_native_connection_assert_ref(c);
@@ -3493,11 +3890,15 @@ static void command_set_mute(
             si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx);
             break;
 
+        case PA_COMMAND_SET_SOURCE_OUTPUT_MUTE:
+            so = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx);
+            break;
+
         default:
             pa_assert_not_reached();
     }
 
-    CHECK_VALIDITY(c->pstream, si || sink || source, tag, PA_ERR_NOENTITY);
+    CHECK_VALIDITY(c->pstream, si || so || sink || source, tag, PA_ERR_NOENTITY);
 
     client_name = pa_strnull(pa_proplist_gets(c->client->proplist, PA_PROP_APPLICATION_PROCESS_BINARY));
 
@@ -3512,6 +3913,11 @@ static void command_set_mute(
                      client_name,
                      pa_strnull(pa_proplist_gets(si->proplist, PA_PROP_MEDIA_NAME)));
         pa_sink_input_set_mute(si, mute, TRUE);
+    } else if (so) {
+        pa_log_debug("Client %s changes mute of source output %s.",
+                     client_name,
+                     pa_strnull(pa_proplist_gets(so->proplist, PA_PROP_MEDIA_NAME)));
+        pa_source_output_set_mute(so, mute, TRUE);
     }
 
     pa_pstream_send_simple_ack(c->pstream, tag);
@@ -3547,6 +3953,110 @@ static void command_cork_playback_stream(pa_pdispatch *pd, uint32_t command, uin
     pa_pstream_send_simple_ack(c->pstream, tag);
 }
 
+#ifdef __TIZEN__
+#define SINK_ALSA_NORMAL "alsa_output.0.analog-stereo"
+#define SINK_ALSA_HDMI   "alsa_output.1.analog-stereo"
+#define SINK_ALSA_VOIP   "alsa_output.3.analog-stereo"
+#define SINK_ALSA_LPA    "alsa_output.4.analog-stereo"
+
+#define PROP_MANUAL_CORK "manual_cork_by_device_switch"
+
+static void command_cork_playback_stream_all(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
+    uint32_t idx;
+    uint32_t sink_idx;
+    pa_bool_t b;
+    playback_stream *s;
+    pa_sink_input* si;
+    pa_sink* sink;
+    char* role = NULL;
+    int ret;
+    char* is_manual_corked_str = NULL;
+    int is_manual_corked;
+    pa_sink_input_state_t si_state;
+
+    void *state = NULL;
+
+    pa_native_connection_assert_ref(c);
+    pa_assert(t);
+
+    if (pa_tagstruct_get_boolean(t, &b) < 0 ||
+        !pa_tagstruct_eof(t)) {
+        protocol_error(c);
+        return;
+    }
+
+    CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
+
+    pa_log_debug_verbose("========================= %s start =========================", b > 0 ? "cork" : "uncork");
+
+    PA_IDXSET_FOREACH(si, c->protocol->core->sink_inputs, idx) {
+        /* Skip this if it is already in the process of being moved
+         * anyway */
+        if (!si->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(pa_sink_input_get_state(si)))
+            continue;
+
+        if ((role = pa_proplist_gets(si->proplist, PA_PROP_MEDIA_ROLE))) {
+            if (pa_streq(role, "filter")) {
+                pa_log_debug("This sink-input [%d] linked to [%s] is FILTER...skip", si->index, (si->sink)? si->sink->name : NULL);
+                continue;
+            }
+        }
+
+        if (pa_streq (si->sink->name, SINK_ALSA_VOIP)) {
+            pa_log_info("Skip sink-input for VOIP sink");
+            continue;
+        }
+
+        if (b) {
+            si_state = pa_sink_input_get_state(si);
+            /* Cork only if sink-input was Running / Drained */
+            if (si_state == PA_SINK_INPUT_RUNNING || si_state == PA_SINK_INPUT_DRAINED) {
+                pa_proplist_sets(si->proplist, PROP_MANUAL_CORK, "1");
+                pa_sink_input_cork(si, TRUE);
+                pa_log_info(" <Cork %d> for sink-input[%d]:sink[%s]", b, si->index, si->sink->name);
+            }
+        } else {
+            /* UnCork if corked by manually */
+            if ((is_manual_corked_str = pa_proplist_gets(si->proplist, PROP_MANUAL_CORK))) {
+                pa_atou(is_manual_corked_str, &is_manual_corked);
+                if (is_manual_corked) {
+                    pa_proplist_sets(si->proplist, PROP_MANUAL_CORK, "0");
+                    pa_sink_input_cork(si, FALSE);
+                    pa_log_info(" <UnCork %d> for sink-input[%d]:sink[%s]", b, si->index, si->sink->name);
+                }
+            }
+        }
+    }
+
+    /* If CORK case, Do manual suspend for ALSA devices */
+    if (b) {
+        PA_IDXSET_FOREACH(sink,  c->protocol->core->sinks, sink_idx) {
+            if (pa_streq (sink->name, SINK_ALSA_NORMAL) ||
+                pa_streq (sink->name, SINK_ALSA_LPA) ||
+                pa_streq (sink->name, SINK_ALSA_HDMI)) {
+                pa_log_info("sink[%d][%s] state=[%d], used_by[%d], check_suspend[%d], suspend-cause[0x%x]",
+                    sink->index, sink->name, pa_sink_get_state(sink), pa_sink_used_by(sink), pa_sink_check_suspend(sink), sink->suspend_cause);
+
+                /* If sink is Not Suspended and can be suspended, do suspend */
+                if (pa_sink_get_state(sink) != PA_SINK_SUSPENDED && pa_sink_check_suspend(sink) == 0) {
+                    ret = pa_sink_suspend (sink, TRUE, PA_SUSPEND_SWITCH);
+                    pa_log_info("suspend result [%d], after suspend-cause[0x%x]", ret, sink->suspend_cause);
+                }
+            }
+        }
+    }
+    pa_log_debug_verbose("========================= %s end =========================", b > 0 ? "cork" : "uncork");
+    pa_pstream_send_simple_ack(c->pstream, tag);
+}
+#endif /* __TIZEN__ */
+
 static void command_trigger_or_flush_or_prebuf_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
     pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
     uint32_t idx;
@@ -3676,7 +4186,7 @@ static void command_set_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, u
 
         s->adjust_latency = adjust_latency;
         s->early_requests = early_requests;
-        s->buffer_attr = a;
+        s->buffer_attr_req = a;
 
         fix_playback_buffer_attr(s);
         pa_assert_se(pa_asyncmsgq_send(s->sink_input->sink->asyncmsgq, PA_MSGOBJECT(s->sink_input), SINK_INPUT_MESSAGE_UPDATE_BUFFER_ATTR, NULL, 0, NULL) == 0);
@@ -3712,7 +4222,7 @@ static void command_set_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, u
 
         s->adjust_latency = adjust_latency;
         s->early_requests = early_requests;
-        s->buffer_attr = a;
+        s->buffer_attr_req = a;
 
         fix_record_buffer_attr_pre(s);
         pa_memblockq_set_maxlength(s->memblockq, s->buffer_attr.maxlength);
@@ -3972,6 +4482,134 @@ static void command_set_default_sink_or_source(pa_pdispatch *pd, uint32_t comman
     pa_pstream_send_simple_ack(c->pstream, tag);
 }
 
+#ifdef __TIZEN__
+static void command_set_default_sink_by_api_bus(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+       pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
+       pa_sink *sink;
+       pa_bool_t found = FALSE;
+       const char *api, *bus;
+       const char *api_string, *bus_string, *form_factor;
+       uint32_t idx;
+
+       pa_native_connection_assert_ref(c);
+       pa_assert(t);
+
+       if (pa_tagstruct_gets(t, &api) < 0 ||
+                       pa_tagstruct_gets(t, &bus) < 0 ||
+                       !pa_tagstruct_eof(t)) {
+               protocol_error(c);
+               return;
+       }
+
+       CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
+       CHECK_VALIDITY(c->pstream, !api || pa_utf8_valid(api), tag, PA_ERR_INVALID);
+       CHECK_VALIDITY(c->pstream, !bus || pa_utf8_valid(bus), tag, PA_ERR_INVALID);
+
+       pa_assert(command == PA_COMMAND_SET_DEFAULT_SINK_BY_API_BUS);
+
+       PA_IDXSET_FOREACH(sink, c->protocol->core->sinks, idx) {
+               if (sink && sink->proplist) {
+                       api_string = pa_proplist_gets(sink->proplist, "device.api");
+                       if (api_string) {
+                               pa_log_debug("Found api = [%s]\n", api_string);
+                               if (!strcmp(api, api_string)) {
+                                       bus_string = pa_proplist_gets(sink->proplist, "device.bus");
+                                       if (bus_string) {
+                                               pa_log_debug("Found bus = [%s]\n", bus_string);
+                                               if(!strcmp(bus, bus_string)) {
+                                                       pa_log_debug("  ** FOUND!!! set default sink to [%s]\n", sink->name);
+                                                       found = TRUE;
+                                                       break;
+                                               } else {
+                                                       pa_log_debug("No string [%s] match, match with form_factor = internal\n", bus);
+                            form_factor = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_FORM_FACTOR );
+                            if (form_factor) {
+                                if(!strcmp(form_factor, "internal")) {
+                                    pa_log_debug("Found internal device(sink) , set (%s) as default sink", sink->name);
+                                    found = TRUE;
+                                    break;
+                                }
+                            }
+                            else {
+                                pa_log_debug("This device doesn't have form factor property");
+                            }
+                        }
+                                       } else {
+                                               pa_log_debug(" Found no bus ");
+                                               if (!strcmp(DEVICE_BUS_BUILTIN, bus)) {
+                                                       pa_log_debug(" searching bus was builtin, then select this");
+                                                       found = TRUE;
+                                                       break;
+                                               }
+                                       }
+                               } else {
+                                       pa_log_debug("No string [%s] match!!!!\n", api);
+                               }
+                       }
+
+               }
+       }
+
+       if (!found)
+               sink = NULL;
+
+       CHECK_VALIDITY(c->pstream, sink, tag, PA_ERR_NOENTITY);
+
+       pa_namereg_set_default_sink(c->protocol->core, sink);
+
+       pa_pstream_send_simple_ack(c->pstream, tag);
+}
+
+static void command_set_default_sink_for_usb(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
+    pa_sink *sink;
+    pa_bool_t found = FALSE;
+    const char *serial;
+    const char *s;
+    uint32_t idx;
+
+    pa_native_connection_assert_ref(c);
+    pa_assert(t);
+
+    if (pa_tagstruct_gets(t, &s) < 0 ||
+        !pa_tagstruct_eof(t)) {
+        protocol_error(c);
+        return;
+    }
+
+    CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
+    CHECK_VALIDITY(c->pstream, !s || pa_namereg_is_valid_name(s), tag, PA_ERR_INVALID);
+
+    pa_assert(command == PA_COMMAND_SET_DEFAULT_SINK_FOR_USB);
+
+    PA_IDXSET_FOREACH(sink, c->protocol->core->sinks, idx) {
+        if (sink && sink->card && sink->card->proplist) {
+            if ((serial = pa_proplist_gets(sink->card->proplist, PA_PROP_DEVICE_SERIAL)) == NULL) {
+                pa_log_warn("  ** No serial for this sink [%s]", sink->name);
+                continue;
+            }
+
+            if ((found = pa_streq(serial, s))) {
+                pa_log_info("  ** serial [%s] for sink [%s] is matched, set as default sink\n", serial, sink->name);
+                break;
+            } else {
+                pa_log_debug("  ** serial [%s] for sink [%s] is not matched...", serial, sink->name);
+            }
+        }
+    }
+
+    if (!found)
+        sink = NULL;
+
+    CHECK_VALIDITY(c->pstream, sink, tag, PA_ERR_NOENTITY);
+
+    pa_namereg_set_default_sink(c->protocol->core, sink);
+
+    pa_pstream_send_simple_ack(c->pstream, tag);
+}
+
+#endif /* __TIZEN__ */
+
 static void command_set_stream_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
     pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
     uint32_t idx;
@@ -4220,6 +4858,9 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa
 
             CHECK_VALIDITY(c->pstream, sink, tag, PA_ERR_NOENTITY);
 
+            pa_log_debug("%s of sink %s requested by client %" PRIu32 ".",
+                         b ? "Suspending" : "Resuming", sink->name, c->client->index);
+
             if (pa_sink_suspend(sink, b, PA_SUSPEND_USER) < 0) {
                 pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID);
                 return;
@@ -4248,6 +4889,9 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa
 
             CHECK_VALIDITY(c->pstream, source, tag, PA_ERR_NOENTITY);
 
+            pa_log_debug("%s of source %s requested by client %" PRIu32 ".",
+                         b ? "Suspending" : "Resuming", source->name, c->client->index);
+
             if (pa_source_suspend(source, b, PA_SUSPEND_USER) < 0) {
                 pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID);
                 return;
@@ -4282,11 +4926,10 @@ static void command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag,
 
     if (idx != PA_INVALID_INDEX)
         m = pa_idxset_get_by_index(c->protocol->core->modules, idx);
-    else {
-        for (m = pa_idxset_first(c->protocol->core->modules, &idx); m; m = pa_idxset_next(c->protocol->core->modules, &idx))
-            if (strcmp(name, m->name) == 0)
+    else
+        PA_IDXSET_FOREACH(m, c->protocol->core->modules, idx)
+            if (pa_streq(name, m->name))
                 break;
-    }
 
     CHECK_VALIDITY(c->pstream, m, tag, PA_ERR_NOEXTENSION);
     CHECK_VALIDITY(c->pstream, m->load_once || idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID);
@@ -4356,9 +4999,8 @@ static void command_set_sink_or_source_port(pa_pdispatch *pd, uint32_t command,
 
     CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
     CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name_or_wildcard(name, command == PA_COMMAND_SET_SINK_PORT ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE), tag, PA_ERR_INVALID);
-    CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID);
-    CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID);
-    CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
+    CHECK_VALIDITY(c->pstream, (idx != PA_INVALID_INDEX) ^ (name != NULL), tag, PA_ERR_INVALID);
+    CHECK_VALIDITY(c->pstream, port, tag, PA_ERR_INVALID);
 
     if (command == PA_COMMAND_SET_SINK_PORT) {
         pa_sink *sink;
@@ -4395,6 +5037,46 @@ static void command_set_sink_or_source_port(pa_pdispatch *pd, uint32_t command,
     pa_pstream_send_simple_ack(c->pstream, tag);
 }
 
+static void command_set_port_latency_offset(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
+    const char *port_name, *card_name;
+    uint32_t idx = PA_INVALID_INDEX;
+    int64_t offset;
+    pa_card *card = NULL;
+    pa_device_port *port = NULL;
+
+    pa_native_connection_assert_ref(c);
+    pa_assert(t);
+
+    if (pa_tagstruct_getu32(t, &idx) < 0 ||
+        pa_tagstruct_gets(t, &card_name) < 0 ||
+        pa_tagstruct_gets(t, &port_name) < 0 ||
+        pa_tagstruct_gets64(t, &offset) < 0 ||
+        !pa_tagstruct_eof(t)) {
+        protocol_error(c);
+    }
+
+    CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
+    CHECK_VALIDITY(c->pstream, !card_name || pa_namereg_is_valid_name(card_name), tag, PA_ERR_INVALID);
+    CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || card_name, tag, PA_ERR_INVALID);
+    CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !card_name, tag, PA_ERR_INVALID);
+    CHECK_VALIDITY(c->pstream, port_name, tag, PA_ERR_INVALID);
+
+    if (idx != PA_INVALID_INDEX)
+        card = pa_idxset_get_by_index(c->protocol->core->cards, idx);
+    else
+        card = pa_namereg_get(c->protocol->core, card_name, PA_NAMEREG_CARD);
+
+    CHECK_VALIDITY(c->pstream, card, tag, PA_ERR_NOENTITY);
+
+    port = pa_hashmap_get(card->ports, port_name);
+    CHECK_VALIDITY(c->pstream, port, tag, PA_ERR_NOENTITY);
+
+    pa_device_port_set_latency_offset(port, offset);
+
+    pa_pstream_send_simple_ack(c->pstream, tag);
+}
+
 /*** pstream callbacks ***/
 
 static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) {
@@ -4424,16 +5106,19 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o
         return;
     }
 
-/*     pa_log("got %lu bytes", (unsigned long) chunk->length); */
+#ifdef PROTOCOL_NATIVE_DEBUG
+    pa_log("got %lu bytes from client", (unsigned long) chunk->length);
+#endif
 
     if (playback_stream_isinstance(stream)) {
         playback_stream *ps = PLAYBACK_STREAM(stream);
 
+        pa_atomic_inc(&ps->seek_or_post_in_queue);
         if (chunk->memblock) {
             if (seek != PA_SEEK_RELATIVE || offset != 0)
-                pa_asyncmsgq_post(ps->sink_input->sink->asyncmsgq, PA_MSGOBJECT(ps->sink_input), SINK_INPUT_MESSAGE_SEEK, PA_UINT_TO_PTR(seek), offset, NULL, NULL);
-
-            pa_asyncmsgq_post(ps->sink_input->sink->asyncmsgq, PA_MSGOBJECT(ps->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, chunk, NULL);
+                pa_asyncmsgq_post(ps->sink_input->sink->asyncmsgq, PA_MSGOBJECT(ps->sink_input), SINK_INPUT_MESSAGE_SEEK, PA_UINT_TO_PTR(seek), offset, chunk, NULL);
+            else
+                pa_asyncmsgq_post(ps->sink_input->sink->asyncmsgq, PA_MSGOBJECT(ps->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, chunk, NULL);
         } else
             pa_asyncmsgq_post(ps->sink_input->sink->asyncmsgq, PA_MSGOBJECT(ps->sink_input), SINK_INPUT_MESSAGE_SEEK, PA_UINT_TO_PTR(seek), offset+chunk->length, NULL, NULL);
 
@@ -4488,7 +5173,7 @@ static void pstream_die_callback(pa_pstream *p, void *userdata) {
     pa_native_connection_assert_ref(c);
 
     native_connection_unlink(c);
-    pa_log_info("Connection died.");
+    pa_log_debug_verbose("Connection died.");
 }
 
 static void pstream_drain_callback(pa_pstream *p, void *userdata) {
@@ -4623,8 +5308,8 @@ void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_nati
     c->client->userdata = c;
 
     c->pstream = pa_pstream_new(p->core->mainloop, io, p->core->mempool);
-    pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c);
-    pa_pstream_set_recieve_memblock_callback(c->pstream, pstream_memblock_callback, c);
+    pa_pstream_set_receive_packet_callback(c->pstream, pstream_packet_callback, c);
+    pa_pstream_set_receive_memblock_callback(c->pstream, pstream_memblock_callback, c);
     pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c);
     pa_pstream_set_drain_callback(c->pstream, pstream_drain_callback, c);
     pa_pstream_set_revoke_callback(c->pstream, pstream_revoke_callback, c);
@@ -4714,14 +5399,14 @@ void pa_native_protocol_unref(pa_native_protocol *p) {
     while ((c = pa_idxset_first(p->connections, NULL)))
         native_connection_unlink(c);
 
-    pa_idxset_free(p->connections, NULL, NULL);
+    pa_idxset_free(p->connections, NULL);
 
     pa_strlist_free(p->servers);
 
     for (h = 0; h < PA_NATIVE_HOOK_MAX; h++)
         pa_hook_done(&p->hooks[h]);
 
-    pa_hashmap_free(p->extensions, NULL, NULL);
+    pa_hashmap_free(p->extensions, NULL);
 
     pa_assert_se(pa_shared_remove(p->core, "native-protocol") >= 0);
 
@@ -4831,8 +5516,8 @@ int pa_native_options_parse(pa_native_options *o, pa_core *c, pa_modargs *ma) {
     }
 
     enabled = TRUE;
-    if (pa_modargs_get_value_boolean(ma, "auth-group-enabled", &enabled) < 0) {
-        pa_log("auth-group-enabled= expects a boolean argument.");
+    if (pa_modargs_get_value_boolean(ma, "auth-group-enable", &enabled) < 0) {
+        pa_log("auth-group-enable= expects a boolean argument.");
         return -1;
     }
 
@@ -4872,11 +5557,23 @@ int pa_native_options_parse(pa_native_options *o, pa_core *c, pa_modargs *ma) {
 
         /* The new name for this is 'auth-cookie', for compat reasons
          * we check the old name too */
-        if (!(cn = pa_modargs_get_value(ma, "auth-cookie", NULL)))
-            if (!(cn = pa_modargs_get_value(ma, "cookie", NULL)))
-                cn = PA_NATIVE_COOKIE_FILE;
+        cn = pa_modargs_get_value(ma, "auth-cookie", NULL);
+        if (!cn)
+            cn = pa_modargs_get_value(ma, "cookie", NULL);
 
-        if (!(o->auth_cookie = pa_auth_cookie_get(c, cn, PA_NATIVE_COOKIE_LENGTH)))
+        if (cn)
+            o->auth_cookie = pa_auth_cookie_get(c, cn, TRUE, PA_NATIVE_COOKIE_LENGTH);
+        else {
+            o->auth_cookie = pa_auth_cookie_get(c, PA_NATIVE_COOKIE_FILE, FALSE, PA_NATIVE_COOKIE_LENGTH);
+            if (!o->auth_cookie) {
+                o->auth_cookie = pa_auth_cookie_get(c, PA_NATIVE_COOKIE_FILE_FALLBACK, FALSE, PA_NATIVE_COOKIE_LENGTH);
+
+                if (!o->auth_cookie)
+                    o->auth_cookie = pa_auth_cookie_get(c, PA_NATIVE_COOKIE_FILE, TRUE, PA_NATIVE_COOKIE_LENGTH);
+            }
+        }
+
+        if (!o->auth_cookie)
             return -1;
 
     } else
@@ -4892,7 +5589,7 @@ pa_pstream* pa_native_connection_get_pstream(pa_native_connection *c) {
 }
 
 pa_client* pa_native_connection_get_client(pa_native_connection *c) {
-   pa_native_connection_assert_ref(c);
+    pa_native_connection_assert_ref(c);
 
-   return c->client;
+    return c->client;
 }
index a9f7389..9242e68 100644 (file)
 #endif
 
 #include <stdlib.h>
-#include <limits.h>
 #include <stdio.h>
 #include <errno.h>
-#include <string.h>
 
 #include <pulse/xmalloc.h>
 #include <pulse/timeval.h>
@@ -87,7 +85,7 @@ enum {
 enum {
     CONNECTION_MESSAGE_REQUEST_DATA,      /* data requested from sink input from the main loop */
     CONNECTION_MESSAGE_POST_DATA,         /* data from source output to main loop */
-    CONNECTION_MESSAGE_UNLINK_CONNECTION    /* Please drop a aconnection now */
+    CONNECTION_MESSAGE_UNLINK_CONNECTION  /* Please drop the connection now */
 };
 
 #define PLAYBACK_BUFFER_SECONDS (.5)
@@ -525,6 +523,7 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
 
     if (o->playback) {
         pa_sink_input_new_data data;
+        pa_memchunk silence;
         size_t l;
         pa_sink *sink;
 
@@ -537,7 +536,7 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
         data.driver = __FILE__;
         data.module = o->module;
         data.client = c->client;
-        data.sink = sink;
+        pa_sink_input_new_data_set_sink(&data, sink, FALSE);
         pa_proplist_update(data.proplist, PA_UPDATE_MERGE, c->client->proplist);
         pa_sink_input_new_data_set_sample_spec(&data, &o->sample_spec);
 
@@ -559,18 +558,22 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
         pa_sink_input_set_requested_latency(c->sink_input, DEFAULT_SINK_LATENCY);
 
         l = (size_t) ((double) pa_bytes_per_second(&o->sample_spec)*PLAYBACK_BUFFER_SECONDS);
+        pa_sink_input_get_silence(c->sink_input, &silence);
         c->input_memblockq = pa_memblockq_new(
+                "simple protocol connection input_memblockq",
                 0,
                 l,
                 l,
-                pa_frame_size(&o->sample_spec),
+                &o->sample_spec,
                 (size_t) -1,
                 l/PLAYBACK_BUFFER_FRAGMENTS,
                 0,
-                NULL);
+                &silence);
+        pa_memblock_unref(silence.memblock);
+
         pa_iochannel_socket_set_rcvbuf(io, l);
 
-        pa_atomic_store(&c->playback.missing, (int) pa_memblockq_missing(c->input_memblockq));
+        pa_atomic_store(&c->playback.missing, (int) pa_memblockq_pop_missing(c->input_memblockq));
 
         pa_sink_input_put(c->sink_input);
     }
@@ -589,7 +592,7 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
         data.driver = __FILE__;
         data.module = o->module;
         data.client = c->client;
-        data.source = source;
+        pa_source_output_new_data_set_source(&data, source, FALSE);
         pa_proplist_update(data.proplist, PA_UPDATE_MERGE, c->client->proplist);
         pa_source_output_new_data_set_sample_spec(&data, &o->sample_spec);
 
@@ -609,10 +612,11 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
 
         l = (size_t) (pa_bytes_per_second(&o->sample_spec)*RECORD_BUFFER_SECONDS);
         c->output_memblockq = pa_memblockq_new(
+                "simple protocol connection output_memblockq",
                 0,
                 l,
                 0,
-                pa_frame_size(&o->sample_spec),
+                &o->sample_spec,
                 1,
                 0,
                 0,
@@ -686,7 +690,7 @@ void pa_simple_protocol_unref(pa_simple_protocol *p) {
     while ((c = pa_idxset_first(p->connections, NULL)))
         connection_unlink(c);
 
-    pa_idxset_free(p->connections, NULL, NULL);
+    pa_idxset_free(p->connections, NULL);
 
     pa_assert_se(pa_shared_remove(p->core, "simple-protocol") >= 0);
 
index 1d4ac17..6c4984e 100644 (file)
 #include <stdlib.h>
 #include <unistd.h>
 
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_SYS_UN_H
-#include <sys/un.h>
-#endif
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
 
-
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/winsock.h>
+#include <pulsecore/socket.h>
 #include <pulsecore/queue.h>
 #include <pulsecore/log.h>
-#include <pulsecore/core-scache.h>
 #include <pulsecore/creds.h>
 #include <pulsecore/refcnt.h>
 #include <pulsecore/flist.h>
 
 #include "pstream.h"
 
+#ifdef USE_SECURITY
+#include <security-server.h>
+#endif /* USE_SECURITY */
+
 /* We piggyback information if audio data blocks are stored in SHM on the seek mode */
 #define PA_FLAG_SHMDATA    0x80000000LU
 #define PA_FLAG_SHMRELEASE 0x40000000LU
@@ -81,7 +77,13 @@ enum {
 typedef uint32_t pa_pstream_descriptor[PA_PSTREAM_DESCRIPTOR_MAX];
 
 #define PA_PSTREAM_DESCRIPTOR_SIZE (PA_PSTREAM_DESCRIPTOR_MAX*sizeof(uint32_t))
-#define FRAME_SIZE_MAX_ALLOW PA_SCACHE_ENTRY_SIZE_MAX /* allow uploading a single sample in one frame at max */
+
+#define MINIBUF_SIZE (256)
+
+/* To allow uploading a single sample in one frame, this value should be the
+ * same size (16 MB) as PA_SCACHE_ENTRY_SIZE_MAX from pulsecore/core-scache.h.
+ */
+#define FRAME_SIZE_MAX_ALLOW (1024*1024*16)
 
 PA_STATIC_FLIST_DECLARE(items, 0, pa_xfree);
 
@@ -122,11 +124,14 @@ struct pa_pstream {
     pa_bool_t dead;
 
     struct {
-        pa_pstream_descriptor descriptor;
+        union {
+            uint8_t minibuf[MINIBUF_SIZE];
+            pa_pstream_descriptor descriptor;
+        };
         struct item_info* current;
-        uint32_t shm_info[PA_PSTREAM_SHM_MAX];
         void *data;
         size_t index;
+        int minibuf_validsize;
         pa_memchunk memchunk;
     } write;
 
@@ -143,11 +148,11 @@ struct pa_pstream {
     pa_memimport *import;
     pa_memexport *export;
 
-    pa_pstream_packet_cb_t recieve_packet_callback;
-    void *recieve_packet_callback_userdata;
+    pa_pstream_packet_cb_t receive_packet_callback;
+    void *receive_packet_callback_userdata;
 
-    pa_pstream_memblock_cb_t recieve_memblock_callback;
-    void *recieve_memblock_callback_userdata;
+    pa_pstream_memblock_cb_t receive_memblock_callback;
+    void *receive_memblock_callback_userdata;
 
     pa_pstream_notify_cb_t drain_callback;
     void *drain_callback_userdata;
@@ -172,7 +177,7 @@ struct pa_pstream {
 static int do_write(pa_pstream *p);
 static int do_read(pa_pstream *p);
 
-static void do_something(pa_pstream *p) {
+static void do_pstream_read_write(pa_pstream *p) {
     pa_assert(p);
     pa_assert(PA_REFCNT_VALUE(p) > 0);
 
@@ -210,7 +215,7 @@ static void io_callback(pa_iochannel*io, void *userdata) {
     pa_assert(PA_REFCNT_VALUE(p) > 0);
     pa_assert(p->io == io);
 
-    do_something(p);
+    do_pstream_read_write(p);
 }
 
 static void defer_callback(pa_mainloop_api *m, pa_defer_event *e, void*userdata) {
@@ -221,7 +226,7 @@ static void defer_callback(pa_mainloop_api *m, pa_defer_event *e, void*userdata)
     pa_assert(p->defer_event == e);
     pa_assert(p->mainloop == m);
 
-    do_something(p);
+    do_pstream_read_write(p);
 }
 
 static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userdata);
@@ -252,10 +257,10 @@ pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *poo
     p->read.packet = NULL;
     p->read.index = 0;
 
-    p->recieve_packet_callback = NULL;
-    p->recieve_packet_callback_userdata = NULL;
-    p->recieve_memblock_callback = NULL;
-    p->recieve_memblock_callback_userdata = NULL;
+    p->receive_packet_callback = NULL;
+    p->receive_packet_callback_userdata = NULL;
+    p->receive_memblock_callback = NULL;
+    p->receive_memblock_callback_userdata = NULL;
     p->drain_callback = NULL;
     p->drain_callback_userdata = NULL;
     p->die_callback = NULL;
@@ -283,7 +288,7 @@ pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *poo
     return p;
 }
 
-static void item_free(void *item, void *q) {
+static void item_free(void *item) {
     struct item_info *i = item;
     pa_assert(i);
 
@@ -304,10 +309,10 @@ static void pstream_free(pa_pstream *p) {
 
     pa_pstream_unlink(p);
 
-    pa_queue_free(p->send_queue, item_free, NULL);
+    pa_queue_free(p->send_queue, item_free);
 
     if (p->write.current)
-        item_free(p->write.current, NULL);
+        item_free(p->write.current);
 
     if (p->write.memchunk.memblock)
         pa_memblock_unref(p->write.memchunk.memblock);
@@ -473,9 +478,9 @@ static void prepare_next_write_item(pa_pstream *p) {
 
     if (!p->write.current)
         return;
-
     p->write.index = 0;
     p->write.data = NULL;
+    p->write.minibuf_validsize = 0;
     pa_memchunk_reset(&p->write.memchunk);
 
     p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = 0;
@@ -490,6 +495,11 @@ static void prepare_next_write_item(pa_pstream *p) {
         p->write.data = p->write.current->packet->data;
         p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl((uint32_t) p->write.current->packet->length);
 
+        if (p->write.current->packet->length <= MINIBUF_SIZE - PA_PSTREAM_DESCRIPTOR_SIZE) {
+            memcpy(&p->write.minibuf[PA_PSTREAM_DESCRIPTOR_SIZE], p->write.data, p->write.current->packet->length);
+            p->write.minibuf_validsize = PA_PSTREAM_DESCRIPTOR_SIZE + p->write.current->packet->length;
+        }
+
     } else if (p->write.current->type == PA_PSTREAM_ITEM_SHMRELEASE) {
 
         p->write.descriptor[PA_PSTREAM_DESCRIPTOR_FLAGS] = htonl(PA_FLAG_SHMRELEASE);
@@ -516,6 +526,8 @@ static void prepare_next_write_item(pa_pstream *p) {
         if (p->use_shm) {
             uint32_t block_id, shm_id;
             size_t offset, length;
+            uint32_t *shm_info = (uint32_t *) &p->write.minibuf[PA_PSTREAM_DESCRIPTOR_SIZE];
+            size_t shm_size = sizeof(uint32_t) * PA_PSTREAM_SHM_MAX;
 
             pa_assert(p->export);
 
@@ -529,13 +541,13 @@ static void prepare_next_write_item(pa_pstream *p) {
                 flags |= PA_FLAG_SHMDATA;
                 send_payload = FALSE;
 
-                p->write.shm_info[PA_PSTREAM_SHM_BLOCKID] = htonl(block_id);
-                p->write.shm_info[PA_PSTREAM_SHM_SHMID] = htonl(shm_id);
-                p->write.shm_info[PA_PSTREAM_SHM_INDEX] = htonl((uint32_t) (offset + p->write.current->chunk.index));
-                p->write.shm_info[PA_PSTREAM_SHM_LENGTH] = htonl((uint32_t) p->write.current->chunk.length);
+                shm_info[PA_PSTREAM_SHM_BLOCKID] = htonl(block_id);
+                shm_info[PA_PSTREAM_SHM_SHMID] = htonl(shm_id);
+                shm_info[PA_PSTREAM_SHM_INDEX] = htonl((uint32_t) (offset + p->write.current->chunk.index));
+                shm_info[PA_PSTREAM_SHM_LENGTH] = htonl((uint32_t) p->write.current->chunk.length);
 
-                p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl(sizeof(p->write.shm_info));
-                p->write.data = p->write.shm_info;
+                p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl(shm_size);
+                p->write.minibuf_validsize = PA_PSTREAM_DESCRIPTOR_SIZE + shm_size;
             }
 /*             else */
 /*                 pa_log_warn("Failed to export memory block."); */
@@ -572,7 +584,10 @@ static int do_write(pa_pstream *p) {
     if (!p->write.current)
         return 0;
 
-    if (p->write.index < PA_PSTREAM_DESCRIPTOR_SIZE) {
+    if (p->write.minibuf_validsize > 0) {
+        d = p->write.minibuf + p->write.index;
+        l = p->write.minibuf_validsize - p->write.index;
+    } else if (p->write.index < PA_PSTREAM_DESCRIPTOR_SIZE) {
         d = (uint8_t*) p->write.descriptor + p->write.index;
         l = PA_PSTREAM_DESCRIPTOR_SIZE - p->write.index;
     } else {
@@ -581,7 +596,7 @@ static int do_write(pa_pstream *p) {
         if (p->write.data)
             d = p->write.data;
         else {
-            d = (uint8_t*) pa_memblock_acquire(p->write.memchunk.memblock) + p->write.memchunk.index;
+            d = pa_memblock_acquire_chunk(&p->write.memchunk);
             release_memblock = p->write.memchunk.memblock;
         }
 
@@ -611,7 +626,7 @@ static int do_write(pa_pstream *p) {
 
     if (p->write.index >= PA_PSTREAM_DESCRIPTOR_SIZE + ntohl(p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH])) {
         pa_assert(p->write.current);
-        item_free(p->write.current, NULL);
+        item_free(p->write.current);
         p->write.current = NULL;
 
         if (p->write.memchunk.memblock)
@@ -743,7 +758,7 @@ static int do_read(pa_pstream *p) {
             if ((flags & PA_FLAG_SHMMASK) == PA_FLAG_SHMDATA) {
 
                 if (length != sizeof(p->read.shm_info)) {
-                    pa_log_warn("Received SHM memblock frame with Invalid frame length.");
+                    pa_log_warn("Received SHM memblock frame with invalid frame length.");
                     return -1;
                 }
 
@@ -766,7 +781,7 @@ static int do_read(pa_pstream *p) {
     } else if (p->read.index > PA_PSTREAM_DESCRIPTOR_SIZE) {
         /* Frame payload available */
 
-        if (p->read.memblock && p->recieve_memblock_callback) {
+        if (p->read.memblock && p->receive_memblock_callback) {
 
             /* Is this memblock data? Than pass it to the user */
             l = (p->read.index - (size_t) r) < PA_PSTREAM_DESCRIPTOR_SIZE ? (size_t) (p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE) : (size_t) r;
@@ -778,20 +793,20 @@ static int do_read(pa_pstream *p) {
                 chunk.index = p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE - l;
                 chunk.length = l;
 
-                if (p->recieve_memblock_callback) {
+                if (p->receive_memblock_callback) {
                     int64_t offset;
 
                     offset = (int64_t) (
                             (((uint64_t) ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI])) << 32) |
                             (((uint64_t) ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_LO]))));
 
-                    p->recieve_memblock_callback(
+                    p->receive_memblock_callback(
                         p,
                         ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_CHANNEL]),
                         offset,
                         ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_FLAGS]) & PA_FLAG_SEEKMASK,
                         &chunk,
-                        p->recieve_memblock_callback_userdata);
+                        p->receive_memblock_callback_userdata);
                 }
 
                 /* Drop seek info for following callbacks */
@@ -811,11 +826,11 @@ static int do_read(pa_pstream *p) {
 
             } else if (p->read.packet) {
 
-                if (p->recieve_packet_callback)
+                if (p->receive_packet_callback)
 #ifdef HAVE_CREDS
-                    p->recieve_packet_callback(p, p->read.packet, p->read_creds_valid ? &p->read_creds : NULL, p->recieve_packet_callback_userdata);
+                    p->receive_packet_callback(p, p->read.packet, p->read_creds_valid ? &p->read_creds : NULL, p->receive_packet_callback_userdata);
 #else
-                    p->recieve_packet_callback(p, p->read.packet, NULL, p->recieve_packet_callback_userdata);
+                    p->receive_packet_callback(p, p->read.packet, NULL, p->receive_packet_callback_userdata);
 #endif
 
                 pa_packet_unref(p->read.packet);
@@ -832,11 +847,11 @@ static int do_read(pa_pstream *p) {
                                           ntohl(p->read.shm_info[PA_PSTREAM_SHM_INDEX]),
                                           ntohl(p->read.shm_info[PA_PSTREAM_SHM_LENGTH])))) {
 
-                    if (pa_log_ratelimit())
+                    if (pa_log_ratelimit(PA_LOG_DEBUG))
                         pa_log_debug("Failed to import memory block.");
                 }
 
-                if (p->recieve_memblock_callback) {
+                if (p->receive_memblock_callback) {
                     int64_t offset;
                     pa_memchunk chunk;
 
@@ -848,13 +863,13 @@ static int do_read(pa_pstream *p) {
                             (((uint64_t) ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI])) << 32) |
                             (((uint64_t) ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_LO]))));
 
-                    p->recieve_memblock_callback(
+                    p->receive_memblock_callback(
                             p,
                             ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_CHANNEL]),
                             offset,
                             ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_FLAGS]) & PA_FLAG_SEEKMASK,
                             &chunk,
-                            p->recieve_memblock_callback_userdata);
+                            p->receive_memblock_callback_userdata);
                 }
 
                 if (b)
@@ -902,20 +917,20 @@ void pa_pstream_set_drain_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, voi
     p->drain_callback_userdata = userdata;
 }
 
-void pa_pstream_set_recieve_packet_callback(pa_pstream *p, pa_pstream_packet_cb_t cb, void *userdata) {
+void pa_pstream_set_receive_packet_callback(pa_pstream *p, pa_pstream_packet_cb_t cb, void *userdata) {
     pa_assert(p);
     pa_assert(PA_REFCNT_VALUE(p) > 0);
 
-    p->recieve_packet_callback = cb;
-    p->recieve_packet_callback_userdata = userdata;
+    p->receive_packet_callback = cb;
+    p->receive_packet_callback_userdata = userdata;
 }
 
-void pa_pstream_set_recieve_memblock_callback(pa_pstream *p, pa_pstream_memblock_cb_t cb, void *userdata) {
+void pa_pstream_set_receive_memblock_callback(pa_pstream *p, pa_pstream_memblock_cb_t cb, void *userdata) {
     pa_assert(p);
     pa_assert(PA_REFCNT_VALUE(p) > 0);
 
-    p->recieve_memblock_callback = cb;
-    p->recieve_memblock_callback_userdata = userdata;
+    p->receive_memblock_callback = cb;
+    p->receive_memblock_callback_userdata = userdata;
 }
 
 void pa_pstream_set_release_callback(pa_pstream *p, pa_pstream_block_id_cb_t cb, void *userdata) {
@@ -948,6 +963,35 @@ pa_bool_t pa_pstream_is_pending(pa_pstream *p) {
     return b;
 }
 
+#ifdef USE_SECURITY
+pa_bool_t pa_pstream_check_security(pa_pstream *p) {
+    int ifd, ofd;
+    int secu_ret = 0;
+    pa_bool_t ret = FALSE;
+
+    pa_assert(p);
+    pa_assert(PA_REFCNT_VALUE(p) > 0);
+
+    if (p->dead) {
+        pa_log_warn("current pstream is dead");
+    } else {
+        /* Get socket fd from channel io */
+        ifd = pa_iochannel_get_recv_fd(p->io);
+        ofd = pa_iochannel_get_send_fd(p->io);
+
+        /* Check security by socket fd */
+        /* Note: assume that ifd and ofd is same, check with ifd here */
+        secu_ret = security_server_check_privilege_by_sockfd(ifd, "pulseaudio::record", "r");
+        pa_log_warn("ifd(%d), ofd(%d), security check ret(%d)", ifd, ofd, secu_ret);
+        if (secu_ret == SECURITY_SERVER_API_SUCCESS) {
+            ret = TRUE;
+        }
+    }
+
+    return ret;
+}
+#endif /* USE_SECURITY */
+
 void pa_pstream_unref(pa_pstream*p) {
     pa_assert(p);
     pa_assert(PA_REFCNT_VALUE(p) > 0);
@@ -994,8 +1038,8 @@ void pa_pstream_unlink(pa_pstream *p) {
 
     p->die_callback = NULL;
     p->drain_callback = NULL;
-    p->recieve_packet_callback = NULL;
-    p->recieve_memblock_callback = NULL;
+    p->receive_packet_callback = NULL;
+    p->receive_memblock_callback = NULL;
 }
 
 void pa_pstream_enable_shm(pa_pstream *p, pa_bool_t enable) {
index a528b25..f74ef15 100644 (file)
@@ -54,8 +54,8 @@ void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa
 void pa_pstream_send_release(pa_pstream *p, uint32_t block_id);
 void pa_pstream_send_revoke(pa_pstream *p, uint32_t block_id);
 
-void pa_pstream_set_recieve_packet_callback(pa_pstream *p, pa_pstream_packet_cb_t cb, void *userdata);
-void pa_pstream_set_recieve_memblock_callback(pa_pstream *p, pa_pstream_memblock_cb_t cb, void *userdata);
+void pa_pstream_set_receive_packet_callback(pa_pstream *p, pa_pstream_packet_cb_t cb, void *userdata);
+void pa_pstream_set_receive_memblock_callback(pa_pstream *p, pa_pstream_memblock_cb_t cb, void *userdata);
 void pa_pstream_set_drain_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata);
 void pa_pstream_set_die_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata);
 void pa_pstream_set_release_callback(pa_pstream *p, pa_pstream_block_id_cb_t cb, void *userdata);
@@ -63,6 +63,10 @@ void pa_pstream_set_revoke_callback(pa_pstream *p, pa_pstream_block_id_cb_t cb,
 
 pa_bool_t pa_pstream_is_pending(pa_pstream *p);
 
+#ifdef USE_SECURITY
+pa_bool_t pa_pstream_check_security(pa_pstream *p);
+#endif /* USE_SECURITY */
+
 void pa_pstream_enable_shm(pa_pstream *p, pa_bool_t enable);
 pa_bool_t pa_pstream_get_shm(pa_pstream *p);
 
index 2c73a3d..f4216ee 100644 (file)
@@ -52,13 +52,13 @@ pa_queue* pa_queue_new(void) {
     return q;
 }
 
-void pa_queue_free(pa_queue* q, pa_free2_cb_t free_func, void *userdata) {
+void pa_queue_free(pa_queue *q, pa_free_cb_t free_func) {
     void *data;
     pa_assert(q);
 
     while ((data = pa_queue_pop(q)))
         if (free_func)
-            free_func(data, userdata);
+            free_func(data);
 
     pa_assert(!q->front);
     pa_assert(!q->back);
index f3cec9b..1b95ec8 100644 (file)
@@ -22,7 +22,7 @@
   USA.
 ***/
 
-#include <pulsecore/idxset.h>
+#include <pulse/def.h>
 
 typedef struct pa_queue pa_queue;
 
@@ -33,7 +33,7 @@ pa_queue* pa_queue_new(void);
 
 /* Free the queue and run the specified callback function for every
  * remaining entry. The callback function may be NULL. */
-void pa_queue_free(pa_queue* q, pa_free2_cb_t free_func, void *userdata);
+void pa_queue_free(pa_queue *q, pa_free_cb_t free_func);
 
 void pa_queue_push(pa_queue *q, void *p);
 void* pa_queue_pop(pa_queue *q);
index 58a5302..b2ec19f 100644 (file)
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
-#include <string.h>
 #include <stdlib.h>
 #include <time.h>
 
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#include <wincrypt.h>
+#endif
+
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
@@ -43,10 +47,20 @@ static const char * const devices[] = { "/dev/urandom", "/dev/random", NULL };
 
 static int random_proper(void *ret_data, size_t length) {
 #ifdef OS_IS_WIN32
+    int ret = -1;
+
+    HCRYPTPROV hCryptProv = 0;
+
     pa_assert(ret_data);
     pa_assert(length > 0);
 
-    return -1;
+    if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+        if(CryptGenRandom(hCryptProv, length, ret_data))
+            ret = 0;
+        CryptReleaseContext(hCryptProv, 0);
+    }
+
+    return ret;
 
 #else /* OS_IS_WIN32 */
 
@@ -62,11 +76,7 @@ static int random_proper(void *ret_data, size_t length) {
     while (*device) {
         ret = 0;
 
-        if ((fd = open(*device, O_RDONLY
-#ifdef O_NOCTTY
-                       | O_NOCTTY
-#endif
-             )) >= 0) {
+        if ((fd = pa_open_cloexec(*device, O_RDONLY, 0)) >= 0) {
 
             if ((r = pa_loop_read(fd, ret_data, length, NULL)) < 0 || (size_t) r != length)
                 ret = -1;
index 844dd77..a274d2c 100644 (file)
@@ -35,7 +35,7 @@ static pa_static_mutex mutex = PA_STATIC_MUTEX_INIT;
 /* Modelled after Linux' lib/ratelimit.c by Dave Young
  * <hidave.darkstar@gmail.com>, which is licensed GPLv2. */
 
-pa_bool_t pa_ratelimit_test(pa_ratelimit *r) {
+pa_bool_t pa_ratelimit_test(pa_ratelimit *r, pa_log_level_t t) {
     pa_usec_t now;
     pa_mutex *m;
 
@@ -52,7 +52,7 @@ pa_bool_t pa_ratelimit_test(pa_ratelimit *r) {
         r->begin + r->interval < now) {
 
         if (r->n_missed > 0)
-            pa_log_warn("%u events suppressed", r->n_missed);
+            pa_logl(t, "%u events suppressed", r->n_missed);
 
         r->begin = now;
 
index 9857a29..9a36195 100644 (file)
@@ -23,6 +23,7 @@
 ***/
 
 #include <pulse/sample.h>
+#include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 
 typedef struct pa_ratelimit {
@@ -51,6 +52,6 @@ typedef struct pa_ratelimit {
         r->begin = 0;                                   \
     } while (FALSE);
 
-pa_bool_t pa_ratelimit_test(pa_ratelimit *r);
+pa_bool_t pa_ratelimit_test(pa_ratelimit *r, pa_log_level_t t);
 
 #endif
index a0fc85b..b31f00c 100644 (file)
 #include <string.h>
 
 #include <pulse/sample.h>
+#include <pulse/volume.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 
 #include "remap.h"
 
-static void remap_mono_to_stereo_c (pa_remap_t *m, void *dst, const void *src, unsigned n) {
+static void remap_mono_to_stereo_c(pa_remap_t *m, void *dst, const void *src, unsigned n) {
     unsigned i;
 
     switch (*m->format) {
@@ -80,12 +81,36 @@ static void remap_mono_to_stereo_c (pa_remap_t *m, void *dst, const void *src, u
             }
             break;
         }
+        /* Add signed 32bit support */
+        case PA_SAMPLE_S24_32NE:
+        case PA_SAMPLE_S32NE:
+        {
+            int32_t *d, *s;
+
+            d = (int32_t *) dst;
+            s = (int32_t *) src;
+
+            for (i = n >> 2; i; i--) {
+                d[0] = d[1] = s[0];
+                d[2] = d[3] = s[1];
+                d[4] = d[5] = s[2];
+                d[6] = d[7] = s[3];
+                s += 4;
+                d += 8;
+            }
+            for (i = n & 3; i; i--) {
+                d[0] = d[1] = s[0];
+                s++;
+                d += 2;
+            }
+            break;
+        }
         default:
             pa_assert_not_reached();
     }
 }
 
-static void remap_channels_matrix_c (pa_remap_t *m, void *dst, const void *src, unsigned n) {
+static void remap_channels_matrix_c(pa_remap_t *m, void *dst, const void *src, unsigned n) {
     unsigned oc, ic, i;
     unsigned n_ic, n_oc;
 
@@ -97,7 +122,7 @@ static void remap_channels_matrix_c (pa_remap_t *m, void *dst, const void *src,
         {
             float *d, *s;
 
-            memset(dst, 0, n * sizeof (float) * n_oc);
+            memset(dst, 0, n * sizeof(float) * n_oc);
 
             for (oc = 0; oc < n_oc; oc++) {
 
@@ -128,7 +153,7 @@ static void remap_channels_matrix_c (pa_remap_t *m, void *dst, const void *src,
         {
             int16_t *d, *s;
 
-            memset(dst, 0, n * sizeof (int16_t) * n_oc);
+            memset(dst, 0, n * sizeof(int16_t) * n_oc);
 
             for (oc = 0; oc < n_oc; oc++) {
 
@@ -154,13 +179,52 @@ static void remap_channels_matrix_c (pa_remap_t *m, void *dst, const void *src,
             }
             break;
         }
+#ifdef __TIZEN__
+        /* Add signed 32bit support */
+        case PA_SAMPLE_S24_32NE:
+        case PA_SAMPLE_S32NE:
+        {
+            int32_t *d, *s;
+
+            memset(dst, 0, n * sizeof(int32_t) * n_oc);
+
+            for (oc = 0; oc < n_oc; oc++) {
+
+                for (ic = 0; ic < n_ic; ic++) {
+                    int32_t vol;
+
+                    vol = m->map_table_i[oc][ic];
+
+                    if (vol <= 0)
+                        continue;
+
+                    d = (int32_t *)dst + oc;
+                    s = (int32_t *)src + ic;
+
+                    if (vol >= 0x10000) {
+                        for (i = n; i > 0; i--, s += n_ic, d += n_oc)
+                            *d += (*s<<8)>>8;
+                    } else {
+                        for (i = n; i > 0; i--, s += n_ic, d += n_oc){
+                            /**
+                              * Sample is left shifted by 8-bits so that sign value is retained.
+                              * vol is converted from float to intiger so after multipication it is right shifted by 16-bits.
+                              */
+                            *d += (int32_t) (((int64_t)((*s<<8)>>8)* vol) >> 16);
+                        }
+                    }
+                }
+            }
+            break;
+        }
+#endif
         default:
             pa_assert_not_reached();
     }
 }
 
 /* set the function that will execute the remapping based on the matrices */
-static void init_remap_c (pa_remap_t *m) {
+static void init_remap_c(pa_remap_t *m) {
     unsigned n_oc, n_ic;
 
     n_oc = m->o_ss->channels;
@@ -168,12 +232,12 @@ static void init_remap_c (pa_remap_t *m) {
 
     /* find some common channel remappings, fall back to full matrix operation. */
     if (n_ic == 1 && n_oc == 2 &&
-            m->map_table_f[0][0] >= 1.0 && m->map_table_f[1][0] >= 1.0) {
+            m->map_table_i[0][0] == PA_VOLUME_NORM && m->map_table_i[1][0] == PA_VOLUME_NORM) {
         m->do_remap = (pa_do_remap_func_t) remap_mono_to_stereo_c;
-        pa_log_info("Using mono to stereo remapping");
+        pa_log_info_verbose("Using mono to stereo remapping");
     } else {
         m->do_remap = (pa_do_remap_func_t) remap_channels_matrix_c;
-        pa_log_info("Using generic matrix remapping");
+        pa_log_info_verbose("Using generic matrix remapping");
     }
 }
 
@@ -181,17 +245,17 @@ static void init_remap_c (pa_remap_t *m) {
 /* default C implementation */
 static pa_init_remap_func_t remap_func = init_remap_c;
 
-void pa_init_remap (pa_remap_t *m) {
-    pa_assert (remap_func);
+void pa_init_remap(pa_remap_t *m) {
+    pa_assert(remap_func);
 
     m->do_remap = NULL;
 
     /* call the installed remap init function */
-    remap_func (m);
+    remap_func(m);
 
     if (m->do_remap == NULL) {
         /* nothing was installed, fallback to C version */
-        init_remap_c (m);
+        init_remap_c(m);
     }
 }
 
index d358a58..5b3f0f9 100644 (file)
@@ -24,9 +24,8 @@
 #include <config.h>
 #endif
 
-#include <string.h>
-
 #include <pulse/sample.h>
+#include <pulse/volume.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 
                 " emms                          \n\t"
 
 #if defined (__i386__) || defined (__amd64__)
-static void remap_mono_to_stereo_mmx (pa_remap_t *m, void *dst, const void *src, unsigned n) {
+static void remap_mono_to_stereo_mmx(pa_remap_t *m, void *dst, const void *src, unsigned n) {
     pa_reg_x86 temp, temp2;
 
     switch (*m->format) {
@@ -133,7 +132,7 @@ static void remap_mono_to_stereo_mmx (pa_remap_t *m, void *dst, const void *src,
 }
 
 /* set the function that will execute the remapping based on the matrices */
-static void init_remap_mmx (pa_remap_t *m) {
+static void init_remap_mmx(pa_remap_t *m) {
     unsigned n_oc, n_ic;
 
     n_oc = m->o_ss->channels;
@@ -141,20 +140,20 @@ static void init_remap_mmx (pa_remap_t *m) {
 
     /* find some common channel remappings, fall back to full matrix operation. */
     if (n_ic == 1 && n_oc == 2 &&
-            m->map_table_f[0][0] >= 1.0 && m->map_table_f[1][0] >= 1.0) {
+            m->map_table_i[0][0] == PA_VOLUME_NORM && m->map_table_i[1][0] == PA_VOLUME_NORM) {
         m->do_remap = (pa_do_remap_func_t) remap_mono_to_stereo_mmx;
         pa_log_info("Using MMX mono to stereo remapping");
     }
 }
 #endif /* defined (__i386__) || defined (__amd64__) */
 
-void pa_remap_func_init_mmx (pa_cpu_x86_flag_t flags) {
+void pa_remap_func_init_mmx(pa_cpu_x86_flag_t flags) {
 #if defined (__i386__) || defined (__amd64__)
 
     if (flags & PA_CPU_X86_MMX) {
         pa_log_info("Initialising MMX optimized remappers.");
 
-        pa_set_init_remap_func ((pa_init_remap_func_t) init_remap_mmx);
+        pa_set_init_remap_func((pa_init_remap_func_t) init_remap_mmx);
     }
 
 #endif /* defined (__i386__) || defined (__amd64__) */
index 0ccf316..8831723 100644 (file)
@@ -24,9 +24,8 @@
 #include <config.h>
 #endif
 
-#include <string.h>
-
 #include <pulse/sample.h>
+#include <pulse/volume.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 
                 "4:                             \n\t"
 
 #if defined (__i386__) || defined (__amd64__)
-static void remap_mono_to_stereo_sse2 (pa_remap_t *m, void *dst, const void *src, unsigned n) {
+static void remap_mono_to_stereo_sse2(pa_remap_t *m, void *dst, const void *src, unsigned n) {
     pa_reg_x86 temp, temp2;
 
     switch (*m->format) {
@@ -132,7 +131,7 @@ static void remap_mono_to_stereo_sse2 (pa_remap_t *m, void *dst, const void *src
 }
 
 /* set the function that will execute the remapping based on the matrices */
-static void init_remap_sse2 (pa_remap_t *m) {
+static void init_remap_sse2(pa_remap_t *m) {
     unsigned n_oc, n_ic;
 
     n_oc = m->o_ss->channels;
@@ -140,14 +139,14 @@ static void init_remap_sse2 (pa_remap_t *m) {
 
     /* find some common channel remappings, fall back to full matrix operation. */
     if (n_ic == 1 && n_oc == 2 &&
-            m->map_table_f[0][0] >= 1.0 && m->map_table_f[1][0] >= 1.0) {
+            m->map_table_i[0][0] == PA_VOLUME_NORM && m->map_table_i[1][0] == PA_VOLUME_NORM) {
         m->do_remap = (pa_do_remap_func_t) remap_mono_to_stereo_sse2;
-        pa_log_info("Using SSE mono to stereo remapping");
+        pa_log_info("Using SSE2 mono to stereo remapping");
     }
 }
 #endif /* defined (__i386__) || defined (__amd64__) */
 
-void pa_remap_func_init_sse (pa_cpu_x86_flag_t flags) {
+void pa_remap_func_init_sse(pa_cpu_x86_flag_t flags) {
 #if defined (__i386__) || defined (__amd64__)
 
     if (flags & PA_CPU_X86_SSE2) {
index f543ad1..18854c6 100644 (file)
 #include <samplerate.h>
 #endif
 
+#ifdef HAVE_SPEEX
 #include <speex/speex_resampler.h>
+#endif
 
 #include <pulse/xmalloc.h>
 #include <pulsecore/sconv.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/strbuf.h>
-
+#include <pulsecore/remap.h>
+#include <pulsecore/core-util.h>
 #include "ffmpeg/avcodec.h"
 
 #include "resampler.h"
-#include "remap.h"
 
 /* Number of samples of extra space we allow the resamplers to return */
 #define EXTRA_FRAMES 128
@@ -54,16 +56,24 @@ struct pa_resampler {
     size_t i_fz, o_fz, w_sz;
     pa_mempool *mempool;
 
-    pa_memchunk buf1, buf2, buf3, buf4;
-    unsigned buf1_samples, buf2_samples, buf3_samples, buf4_samples;
+    pa_memchunk to_work_format_buf;
+    pa_memchunk remap_buf;
+    pa_memchunk resample_buf;
+    pa_memchunk from_work_format_buf;
+    unsigned to_work_format_buf_samples;
+    size_t remap_buf_size;
+    unsigned resample_buf_samples;
+    unsigned from_work_format_buf_samples;
+    bool remap_buf_contains_leftover_data;
 
     pa_sample_format_t work_format;
+    uint8_t work_channels;
 
     pa_convert_func_t to_work_format_func;
     pa_convert_func_t from_work_format_func;
 
     pa_remap_t remap;
-    pa_bool_t map_required;
+    bool map_required;
 
     void (*impl_free)(pa_resampler *r);
     void (*impl_update_rates)(pa_resampler *r);
@@ -90,9 +100,11 @@ struct pa_resampler {
     } src;
 #endif
 
+#ifdef HAVE_SPEEX
     struct { /* data specific to speex */
         SpeexResamplerState* state;
     } speex;
+#endif
 
     struct { /* data specific to ffmpeg */
         struct AVResampleContext *state;
@@ -102,7 +114,9 @@ struct pa_resampler {
 
 static int copy_init(pa_resampler *r);
 static int trivial_init(pa_resampler*r);
+#ifdef HAVE_SPEEX
 static int speex_init(pa_resampler*r);
+#endif
 static int ffmpeg_init(pa_resampler*r);
 static int peaks_init(pa_resampler*r);
 #ifdef HAVE_LIBSAMPLERATE
@@ -126,6 +140,7 @@ static int (* const init_table[])(pa_resampler*r) = {
     [PA_RESAMPLER_SRC_LINEAR]              = NULL,
 #endif
     [PA_RESAMPLER_TRIVIAL]                 = trivial_init,
+#ifdef HAVE_SPEEX
     [PA_RESAMPLER_SPEEX_FLOAT_BASE+0]      = speex_init,
     [PA_RESAMPLER_SPEEX_FLOAT_BASE+1]      = speex_init,
     [PA_RESAMPLER_SPEEX_FLOAT_BASE+2]      = speex_init,
@@ -148,6 +163,30 @@ static int (* const init_table[])(pa_resampler*r) = {
     [PA_RESAMPLER_SPEEX_FIXED_BASE+8]      = speex_init,
     [PA_RESAMPLER_SPEEX_FIXED_BASE+9]      = speex_init,
     [PA_RESAMPLER_SPEEX_FIXED_BASE+10]     = speex_init,
+#else
+    [PA_RESAMPLER_SPEEX_FLOAT_BASE+0]      = NULL,
+    [PA_RESAMPLER_SPEEX_FLOAT_BASE+1]      = NULL,
+    [PA_RESAMPLER_SPEEX_FLOAT_BASE+2]      = NULL,
+    [PA_RESAMPLER_SPEEX_FLOAT_BASE+3]      = NULL,
+    [PA_RESAMPLER_SPEEX_FLOAT_BASE+4]      = NULL,
+    [PA_RESAMPLER_SPEEX_FLOAT_BASE+5]      = NULL,
+    [PA_RESAMPLER_SPEEX_FLOAT_BASE+6]      = NULL,
+    [PA_RESAMPLER_SPEEX_FLOAT_BASE+7]      = NULL,
+    [PA_RESAMPLER_SPEEX_FLOAT_BASE+8]      = NULL,
+    [PA_RESAMPLER_SPEEX_FLOAT_BASE+9]      = NULL,
+    [PA_RESAMPLER_SPEEX_FLOAT_BASE+10]     = NULL,
+    [PA_RESAMPLER_SPEEX_FIXED_BASE+0]      = NULL,
+    [PA_RESAMPLER_SPEEX_FIXED_BASE+1]      = NULL,
+    [PA_RESAMPLER_SPEEX_FIXED_BASE+2]      = NULL,
+    [PA_RESAMPLER_SPEEX_FIXED_BASE+3]      = NULL,
+    [PA_RESAMPLER_SPEEX_FIXED_BASE+4]      = NULL,
+    [PA_RESAMPLER_SPEEX_FIXED_BASE+5]      = NULL,
+    [PA_RESAMPLER_SPEEX_FIXED_BASE+6]      = NULL,
+    [PA_RESAMPLER_SPEEX_FIXED_BASE+7]      = NULL,
+    [PA_RESAMPLER_SPEEX_FIXED_BASE+8]      = NULL,
+    [PA_RESAMPLER_SPEEX_FIXED_BASE+9]      = NULL,
+    [PA_RESAMPLER_SPEEX_FIXED_BASE+10]     = NULL,
+#endif
     [PA_RESAMPLER_FFMPEG]                  = ffmpeg_init,
     [PA_RESAMPLER_AUTO]                    = NULL,
     [PA_RESAMPLER_COPY]                    = copy_init,
@@ -176,7 +215,7 @@ pa_resampler* pa_resampler_new(
     /* Fix method */
 
     if (!(flags & PA_RESAMPLER_VARIABLE_RATE) && a->rate == b->rate) {
-        pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
+        pa_log_debug_verbose("Forcing resampler 'copy', because of fixed, identical sample rates.");
         method = PA_RESAMPLER_COPY;
     }
 
@@ -195,22 +234,22 @@ pa_resampler* pa_resampler_new(
         method = PA_RESAMPLER_AUTO;
     }
 
-    if (method == PA_RESAMPLER_AUTO)
-    {
-       //method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 3;
-       method = PA_RESAMPLER_SPEEX_FIXED_BASE + 3;//use fixed base
+    if (method == PA_RESAMPLER_AUTO) {
+#ifdef HAVE_SPEEX
+        method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 1;
+#else
+        if (flags & PA_RESAMPLER_VARIABLE_RATE)
+            method = PA_RESAMPLER_TRIVIAL;
+        else
+            method = PA_RESAMPLER_FFMPEG;
+#endif
     }
 
-    r = pa_xnew(pa_resampler, 1);
+    r = pa_xnew0(pa_resampler, 1);
     r->mempool = pool;
     r->method = method;
     r->flags = flags;
 
-    r->impl_free = NULL;
-    r->impl_update_rates = NULL;
-    r->impl_resample = NULL;
-    r->impl_reset = NULL;
-
     /* Fill sample specs */
     r->i_ss = *a;
     r->o_ss = *b;
@@ -233,25 +272,18 @@ pa_resampler* pa_resampler_new(
     r->i_fz = pa_frame_size(a);
     r->o_fz = pa_frame_size(b);
 
-    pa_memchunk_reset(&r->buf1);
-    pa_memchunk_reset(&r->buf2);
-    pa_memchunk_reset(&r->buf3);
-    pa_memchunk_reset(&r->buf4);
-
-    r->buf1_samples = r->buf2_samples = r->buf3_samples = r->buf4_samples = 0;
-
     calc_map_table(r);
 
-    pa_log_info("Using resampler '%s'", pa_resample_method_to_string(method));
-
     if ((method >= PA_RESAMPLER_SPEEX_FIXED_BASE && method <= PA_RESAMPLER_SPEEX_FIXED_MAX) ||
-        (method == PA_RESAMPLER_FFMPEG))
-        r->work_format = PA_SAMPLE_S16NE;
-    else if (method == PA_RESAMPLER_TRIVIAL || method == PA_RESAMPLER_COPY || method == PA_RESAMPLER_PEAKS) {
+        (method == PA_RESAMPLER_FFMPEG)
+    ){
+        r->work_format =  PA_SAMPLE_S16NE;
+    }else if (method == PA_RESAMPLER_TRIVIAL || method == PA_RESAMPLER_COPY || method == PA_RESAMPLER_PEAKS) {
 
         if (r->map_required || a->format != b->format || method == PA_RESAMPLER_PEAKS) {
-
-            if (a->format == PA_SAMPLE_S32NE || a->format == PA_SAMPLE_S32RE ||
+            if (a->format == PA_SAMPLE_S16NE || b->format == PA_SAMPLE_S16NE)
+                r->work_format = PA_SAMPLE_S16NE;
+            else if (a->format == PA_SAMPLE_S32NE || a->format == PA_SAMPLE_S32RE ||
                 a->format == PA_SAMPLE_FLOAT32NE || a->format == PA_SAMPLE_FLOAT32RE ||
                 a->format == PA_SAMPLE_S24NE || a->format == PA_SAMPLE_S24RE ||
                 a->format == PA_SAMPLE_S24_32NE || a->format == PA_SAMPLE_S24_32RE ||
@@ -269,32 +301,53 @@ pa_resampler* pa_resampler_new(
     } else
         r->work_format = PA_SAMPLE_FLOAT32NE;
 
-    pa_log_info("Using %s as working format.", pa_sample_format_to_string(r->work_format));
+    pa_log_info_verbose("Using resampler '%s', %s as working format.",
+                pa_resample_method_to_string(method), pa_sample_format_to_string(r->work_format));
 
     r->w_sz = pa_sample_size_of_format(r->work_format);
 
-    if (r->i_ss.format == r->work_format)
-        r->to_work_format_func = NULL;
-    else if (r->work_format == PA_SAMPLE_FLOAT32NE) {
-        if (!(r->to_work_format_func = pa_get_convert_to_float32ne_function(r->i_ss.format)))
-            goto fail;
-    } else {
-        pa_assert(r->work_format == PA_SAMPLE_S16NE);
-        if (!(r->to_work_format_func = pa_get_convert_to_s16ne_function(r->i_ss.format)))
-            goto fail;
+    if (r->i_ss.format != r->work_format) {
+        if (r->work_format == PA_SAMPLE_FLOAT32NE) {
+            if (!(r->to_work_format_func = pa_get_convert_to_float32ne_function(r->i_ss.format)))
+                goto fail;
+        } else {
+            pa_assert(r->work_format == PA_SAMPLE_S16NE);
+            if (!(r->to_work_format_func = pa_get_convert_to_s16ne_function(r->i_ss.format)))
+                goto fail;
+        }
     }
-
-    if (r->o_ss.format == r->work_format)
-        r->from_work_format_func = NULL;
-    else if (r->work_format == PA_SAMPLE_FLOAT32NE) {
-        if (!(r->from_work_format_func = pa_get_convert_from_float32ne_function(r->o_ss.format)))
-            goto fail;
-    } else {
-        pa_assert(r->work_format == PA_SAMPLE_S16NE);
-        if (!(r->from_work_format_func = pa_get_convert_from_s16ne_function(r->o_ss.format)))
-            goto fail;
+    /*Todo:SECSRC is capable of converting of format conversion,
+           Currently,format conversion is happening through resampler wrapper,need to optimize it
+          input & output of resampler will be in same format[S24_32NE or S16NE]
+      Todo:24 to 16 bit is having issue,need to fix it*/
+    if (r->o_ss.format != r->work_format) {
+        if (r->work_format == PA_SAMPLE_FLOAT32NE) {
+            if (!(r->from_work_format_func = pa_get_convert_from_float32ne_function(r->o_ss.format)))
+                goto fail;
+        } else {
+            pa_assert(r->work_format == PA_SAMPLE_S16NE);
+            if (!(r->from_work_format_func = pa_get_convert_from_s16ne_function(r->o_ss.format)))
+                goto fail;
+        }
     }
 
+    if (r->o_ss.channels <= r->i_ss.channels)
+        r->work_channels = r->o_ss.channels;
+    else
+        r->work_channels = r->i_ss.channels;
+
+#ifdef __TIZEN_LOG__
+    pa_log_debug("Resampler rate:%d->%d(%s) format:%s->%s(%s) channels:%d->%d(resampling %d)",
+        a->rate, b->rate, pa_resample_method_to_string(r->method),
+        pa_sample_format_to_string(a->format), pa_sample_format_to_string(b->format), pa_sample_format_to_string(r->work_format),
+        a->channels, b->channels, r->work_channels);
+#else
+    pa_log_debug("Resampler:\n  rate %d -> %d (method %s),\n  format %s -> %s (intermediate %s),\n  channels %d -> %d (resampling %d)",
+        a->rate, b->rate, pa_resample_method_to_string(r->method),
+        pa_sample_format_to_string(a->format), pa_sample_format_to_string(b->format), pa_sample_format_to_string(r->work_format),
+        a->channels, b->channels, r->work_channels);
+#endif
+
     /* initialize implementation */
     if (init_table[method](r) < 0)
         goto fail;
@@ -313,14 +366,14 @@ void pa_resampler_free(pa_resampler *r) {
     if (r->impl_free)
         r->impl_free(r);
 
-    if (r->buf1.memblock)
-        pa_memblock_unref(r->buf1.memblock);
-    if (r->buf2.memblock)
-        pa_memblock_unref(r->buf2.memblock);
-    if (r->buf3.memblock)
-        pa_memblock_unref(r->buf3.memblock);
-    if (r->buf4.memblock)
-        pa_memblock_unref(r->buf4.memblock);
+    if (r->to_work_format_buf.memblock)
+        pa_memblock_unref(r->to_work_format_buf.memblock);
+    if (r->remap_buf.memblock)
+        pa_memblock_unref(r->remap_buf.memblock);
+    if (r->resample_buf.memblock)
+        pa_memblock_unref(r->resample_buf.memblock);
+    if (r->from_work_format_buf.memblock)
+        pa_memblock_unref(r->from_work_format_buf.memblock);
 
     pa_xfree(r);
 }
@@ -352,23 +405,39 @@ void pa_resampler_set_output_rate(pa_resampler *r, uint32_t rate) {
 size_t pa_resampler_request(pa_resampler *r, size_t out_length) {
     pa_assert(r);
 
-    /* Let's round up here */
-
-    return (((((out_length + r->o_fz-1) / r->o_fz) * r->i_ss.rate) + r->o_ss.rate-1) / r->o_ss.rate) * r->i_fz;
+    /* Let's round up here to make it more likely that the caller will get at
+     * least out_length amount of data from pa_resampler_run().
+     *
+     * We don't take the leftover into account here. If we did, then it might
+     * be in theory possible that this function would return 0 and
+     * pa_resampler_run() would also return 0. That could lead to infinite
+     * loops. When the leftover is ignored here, such loops would eventually
+     * terminate, because the leftover would grow each round, finally
+     * surpassing the minimum input threshold of the resampler. */
+    return ((((uint64_t) ((out_length + r->o_fz-1) / r->o_fz) * r->i_ss.rate) + r->o_ss.rate-1) / r->o_ss.rate) * r->i_fz;
 }
 
 size_t pa_resampler_result(pa_resampler *r, size_t in_length) {
+    size_t frames;
+
     pa_assert(r);
 
-    /* Let's round up here */
+    /* Let's round up here to ensure that the caller will always allocate big
+     * enough output buffer. */
+
+    frames = (in_length + r->i_fz - 1) / r->i_fz;
 
-    return (((((in_length + r->i_fz-1) / r->i_fz) * r->o_ss.rate) + r->i_ss.rate-1) / r->i_ss.rate) * r->o_fz;
+    if (r->remap_buf_contains_leftover_data)
+        frames += r->remap_buf.length / (r->w_sz * r->o_ss.channels);
+
+    return (((uint64_t) frames * r->o_ss.rate + r->i_ss.rate - 1) / r->i_ss.rate) * r->o_fz;
 }
 
 size_t pa_resampler_max_block_size(pa_resampler *r) {
     size_t block_size_max;
-    pa_sample_spec ss;
-    size_t fs;
+    pa_sample_spec max_ss;
+    size_t max_fs;
+    size_t frames;
 
     pa_assert(r);
 
@@ -376,17 +445,21 @@ size_t pa_resampler_max_block_size(pa_resampler *r) {
 
     /* We deduce the "largest" sample spec we're using during the
      * conversion */
-    ss.channels = (uint8_t) (PA_MAX(r->i_ss.channels, r->o_ss.channels));
+    max_ss.channels = (uint8_t) (PA_MAX(r->i_ss.channels, r->o_ss.channels));
 
     /* We silently assume that the format enum is ordered by size */
-    ss.format = PA_MAX(r->i_ss.format, r->o_ss.format);
-    ss.format = PA_MAX(ss.format, r->work_format);
+    max_ss.format = PA_MAX(r->i_ss.format, r->o_ss.format);
+    max_ss.format = PA_MAX(max_ss.format, r->work_format);
+
+    max_ss.rate = PA_MAX(r->i_ss.rate, r->o_ss.rate);
 
-    ss.rate = PA_MAX(r->i_ss.rate, r->o_ss.rate);
+    max_fs = pa_frame_size(&max_ss);
+    frames = block_size_max / max_fs - EXTRA_FRAMES;
 
-    fs = pa_frame_size(&ss);
+    if (r->remap_buf_contains_leftover_data)
+        frames -= r->remap_buf.length / (r->w_sz * r->o_ss.channels);
 
-    return (((block_size_max/fs - EXTRA_FRAMES)*r->i_ss.rate)/ss.rate)*r->i_fz;
+    return ((uint64_t) frames * r->i_ss.rate / max_ss.rate) * r->i_fz;
 }
 
 void pa_resampler_reset(pa_resampler *r) {
@@ -394,6 +467,8 @@ void pa_resampler_reset(pa_resampler *r) {
 
     if (r->impl_reset)
         r->impl_reset(r);
+
+    r->remap_buf_contains_leftover_data = false;
 }
 
 pa_resample_method_t pa_resampler_get_method(pa_resampler *r) {
@@ -479,6 +554,13 @@ int pa_resample_method_supported(pa_resample_method_t m) {
         return 0;
 #endif
 
+#ifndef HAVE_SPEEX
+    if (m >= PA_RESAMPLER_SPEEX_FLOAT_BASE && m <= PA_RESAMPLER_SPEEX_FLOAT_MAX)
+        return 0;
+    if (m >= PA_RESAMPLER_SPEEX_FIXED_BASE && m <= PA_RESAMPLER_SPEEX_FIXED_MAX)
+        return 0;
+#endif
+
     return 1;
 }
 
@@ -488,19 +570,19 @@ pa_resample_method_t pa_parse_resample_method(const char *string) {
     pa_assert(string);
 
     for (m = 0; m < PA_RESAMPLER_MAX; m++)
-        if (!strcmp(string, resample_methods[m]))
+        if (pa_streq(string, resample_methods[m]))
             return m;
 
-    if (!strcmp(string, "speex-fixed"))
-        return PA_RESAMPLER_SPEEX_FIXED_BASE + 3;
+    if (pa_streq(string, "speex-fixed"))
+        return PA_RESAMPLER_SPEEX_FIXED_BASE + 1;
 
-    if (!strcmp(string, "speex-float"))
-        return PA_RESAMPLER_SPEEX_FLOAT_BASE + 3;
+    if (pa_streq(string, "speex-float"))
+        return PA_RESAMPLER_SPEEX_FLOAT_BASE + 1;
 
     return PA_RESAMPLER_INVALID;
 }
 
-static pa_bool_t on_left(pa_channel_position_t p) {
+static bool on_left(pa_channel_position_t p) {
 
     return
         p == PA_CHANNEL_POSITION_FRONT_LEFT ||
@@ -511,7 +593,7 @@ static pa_bool_t on_left(pa_channel_position_t p) {
         p == PA_CHANNEL_POSITION_TOP_REAR_LEFT;
 }
 
-static pa_bool_t on_right(pa_channel_position_t p) {
+static bool on_right(pa_channel_position_t p) {
 
     return
         p == PA_CHANNEL_POSITION_FRONT_RIGHT ||
@@ -522,7 +604,7 @@ static pa_bool_t on_right(pa_channel_position_t p) {
         p == PA_CHANNEL_POSITION_TOP_REAR_RIGHT;
 }
 
-static pa_bool_t on_center(pa_channel_position_t p) {
+static bool on_center(pa_channel_position_t p) {
 
     return
         p == PA_CHANNEL_POSITION_FRONT_CENTER ||
@@ -532,12 +614,12 @@ static pa_bool_t on_center(pa_channel_position_t p) {
         p == PA_CHANNEL_POSITION_TOP_REAR_CENTER;
 }
 
-static pa_bool_t on_lfe(pa_channel_position_t p) {
+static bool on_lfe(pa_channel_position_t p) {
     return
         p == PA_CHANNEL_POSITION_LFE;
 }
 
-static pa_bool_t on_front(pa_channel_position_t p) {
+static bool on_front(pa_channel_position_t p) {
     return
         p == PA_CHANNEL_POSITION_FRONT_LEFT ||
         p == PA_CHANNEL_POSITION_FRONT_RIGHT ||
@@ -549,7 +631,7 @@ static pa_bool_t on_front(pa_channel_position_t p) {
         p == PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER;
 }
 
-static pa_bool_t on_rear(pa_channel_position_t p) {
+static bool on_rear(pa_channel_position_t p) {
     return
         p == PA_CHANNEL_POSITION_REAR_LEFT ||
         p == PA_CHANNEL_POSITION_REAR_RIGHT ||
@@ -559,7 +641,7 @@ static pa_bool_t on_rear(pa_channel_position_t p) {
         p == PA_CHANNEL_POSITION_TOP_REAR_CENTER;
 }
 
-static pa_bool_t on_side(pa_channel_position_t p) {
+static bool on_side(pa_channel_position_t p) {
     return
         p == PA_CHANNEL_POSITION_SIDE_LEFT ||
         p == PA_CHANNEL_POSITION_SIDE_RIGHT ||
@@ -586,8 +668,8 @@ static int front_rear_side(pa_channel_position_t p) {
 static void calc_map_table(pa_resampler *r) {
     unsigned oc, ic;
     unsigned n_oc, n_ic;
-    pa_bool_t ic_connected[PA_CHANNELS_MAX];
-    pa_bool_t remix;
+    bool ic_connected[PA_CHANNELS_MAX];
+    bool remix;
     pa_strbuf *s;
     char *t;
     pa_remap_t *m;
@@ -606,228 +688,208 @@ static void calc_map_table(pa_resampler *r) {
     memset(m->map_table_i, 0, sizeof(m->map_table_i));
 
     memset(ic_connected, 0, sizeof(ic_connected));
-    remix = (r->flags & (PA_RESAMPLER_NO_REMAP|PA_RESAMPLER_NO_REMIX)) == 0;
+    remix = (r->flags & (PA_RESAMPLER_NO_REMAP | PA_RESAMPLER_NO_REMIX)) == 0;
 
-    for (oc = 0; oc < n_oc; oc++) {
-        pa_bool_t oc_connected = FALSE;
-        pa_channel_position_t b = r->o_cm.map[oc];
+    if (r->flags & PA_RESAMPLER_NO_REMAP) {
+        pa_assert(!remix);
 
-        for (ic = 0; ic < n_ic; ic++) {
-            pa_channel_position_t a = r->i_cm.map[ic];
+        for (oc = 0; oc < PA_MIN(n_ic, n_oc); oc++)
+            m->map_table_f[oc][oc] = 1.0f;
 
-            if (r->flags & PA_RESAMPLER_NO_REMAP) {
-                /* We shall not do any remapping. Hence, just check by index */
+    } else if (r->flags & PA_RESAMPLER_NO_REMIX) {
+        pa_assert(!remix);
+        for (oc = 0; oc < n_oc; oc++) {
+            pa_channel_position_t b = r->o_cm.map[oc];
 
-                if (ic == oc)
-                    m->map_table_f[oc][ic] = 1.0;
+            for (ic = 0; ic < n_ic; ic++) {
+                pa_channel_position_t a = r->i_cm.map[ic];
 
-                continue;
+                /* We shall not do any remixing. Hence, just check by name */
+                if (a == b)
+                    m->map_table_f[oc][ic] = 1.0f;
             }
+        }
+    } else {
 
-            if (r->flags & PA_RESAMPLER_NO_REMIX) {
-                /* We shall not do any remixing. Hence, just check by name */
+        /* OK, we shall do the full monty: upmixing and downmixing. Our
+         * algorithm is relatively simple, does not do spacialization, delay
+         * elements or apply lowpass filters for LFE. Patches are always
+         * welcome, though. Oh, and it doesn't do any matrix decoding. (Which
+         * probably wouldn't make any sense anyway.)
+         *
+         * This code is not idempotent: downmixing an upmixed stereo stream is
+         * not identical to the original. The volume will not match, and the
+         * two channels will be a linear combination of both.
+         *
+         * This is loosely based on random suggestions found on the Internet,
+         * such as this:
+         * http://www.halfgaar.net/surround-sound-in-linux and the alsa upmix
+         * plugin.
+         *
+         * The algorithm works basically like this:
+         *
+         * 1) Connect all channels with matching names.
+         *
+         * 2) Mono Handling:
+         *    S:Mono: Copy into all D:channels
+         *    D:Mono: Avg all S:channels
+         *
+         * 3) Mix D:Left, D:Right:
+         *    D:Left: If not connected, avg all S:Left
+         *    D:Right: If not connected, avg all S:Right
+         *
+         * 4) Mix D:Center
+         *    If not connected, avg all S:Center
+         *    If still not connected, avg all S:Left, S:Right
+         *
+         * 5) Mix D:LFE
+         *    If not connected, avg all S:*
+         *
+         * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If not
+         *    connected, mix into all D:left and all D:right channels. Gain is
+         *    1/9.
+         *
+         * 7) Make sure S:Center, S:LFE is used:
+         *
+         *    S:Center, S:LFE: If not connected, mix into all D:left, all
+         *    D:right, all D:center channels. Gain is 0.5 for center and 0.375
+         *    for LFE. C-front is only mixed into L-front/R-front if available,
+         *    otherwise into all L/R channels. Similarly for C-rear.
+         *
+         * 8) Normalize each row in the matrix such that the sum for each row is
+         *    not larger than 1.0 in order to avoid clipping.
+         *
+         * S: and D: shall relate to the source resp. destination channels.
+         *
+         * Rationale: 1, 2 are probably obvious. For 3: this copies front to
+         * rear if needed. For 4: we try to find some suitable C source for C,
+         * if we don't find any, we avg L and R. For 5: LFE is mixed from all
+         * channels. For 6: the rear channels should not be dropped entirely,
+         * however have only minimal impact. For 7: movies usually encode
+         * speech on the center channel. Thus we have to make sure this channel
+         * is distributed to L and R if not available in the output. Also, LFE
+         * is used to achieve a greater dynamic range, and thus we should try
+         * to do our best to pass it to L+R.
+         */
 
-                if (a == b)
-                    m->map_table_f[oc][ic] = 1.0;
+        unsigned
+            ic_left = 0,
+            ic_right = 0,
+            ic_center = 0,
+            ic_unconnected_left = 0,
+            ic_unconnected_right = 0,
+            ic_unconnected_center = 0,
+            ic_unconnected_lfe = 0;
+        bool ic_unconnected_center_mixed_in = 0;
 
-                continue;
-            }
+        pa_assert(remix);
 
-            pa_assert(remix);
-
-            /* OK, we shall do the full monty: upmixing and
-             * downmixing. Our algorithm is relatively simple, does
-             * not do spacialization, delay elements or apply lowpass
-             * filters for LFE. Patches are always welcome,
-             * though. Oh, and it doesn't do any matrix
-             * decoding. (Which probably wouldn't make any sense
-             * anyway.)
-             *
-             * This code is not idempotent: downmixing an upmixed
-             * stereo stream is not identical to the original. The
-             * volume will not match, and the two channels will be a
-             * linear combination of both.
-             *
-             * This is losely based on random suggestions found on the
-             * Internet, such as this:
-             * http://www.halfgaar.net/surround-sound-in-linux and the
-             * alsa upmix plugin.
-             *
-             * The algorithm works basically like this:
-             *
-             * 1) Connect all channels with matching names.
-             *
-             * 2) Mono Handling:
-             *    S:Mono: Copy into all D:channels
-             *    D:Mono: Copy in all S:channels
-             *
-             * 3) Mix D:Left, D:Right:
-             *    D:Left: If not connected, avg all S:Left
-             *    D:Right: If not connected, avg all S:Right
-             *
-             * 4) Mix D:Center
-             *       If not connected, avg all S:Center
-             *       If still not connected, avg all S:Left, S:Right
-             *
-             * 5) Mix D:LFE
-             *       If not connected, avg all S:*
-             *
-             * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
-             *    not connected, mix into all D:left and all D:right
-             *    channels. Gain is 0.1, the current left and right
-             *    should be multiplied by 0.9.
-             *
-             * 7) Make sure S:Center, S:LFE is used:
-             *
-             *    S:Center, S:LFE: If not connected, mix into all
-             *    D:left, all D:right, all D:center channels, gain is
-             *    0.375. The current (as result of 1..6) factors
-             *    should be multiplied by 0.75. (Alt. suggestion: 0.25
-             *    vs. 0.5) If C-front is only mixed into
-             *    L-front/R-front if available, otherwise into all L/R
-             *    channels. Similarly for C-rear.
-             *
-             * S: and D: shall relate to the source resp. destination channels.
-             *
-             * Rationale: 1, 2 are probably obvious. For 3: this
-             * copies front to rear if needed. For 4: we try to find
-             * some suitable C source for C, if we don't find any, we
-             * avg L and R. For 5: LFE is mixed from all channels. For
-             * 6: the rear channels should not be dropped entirely,
-             * however have only minimal impact. For 7: movies usually
-             * encode speech on the center channel. Thus we have to
-             * make sure this channel is distributed to L and R if not
-             * available in the output. Also, LFE is used to achieve a
-             * greater dynamic range, and thus we should try to do our
-             * best to pass it to L+R.
-             */
-
-            if (a == b || a == PA_CHANNEL_POSITION_MONO) {
-                /* if input=output or if input=mono */
-                m->map_table_f[oc][ic] = 1.0;
-
-                oc_connected = TRUE;
-                ic_connected[ic] = TRUE;
-            } else if (b == PA_CHANNEL_POSITION_MONO) {
-                /* if output=mono and input=stereo */
-                m->map_table_f[oc][ic] = 1.0 / n_ic;
-
-                oc_connected = TRUE;
-                ic_connected[ic] = TRUE;
-            }
+        for (ic = 0; ic < n_ic; ic++) {
+            if (on_left(r->i_cm.map[ic]))
+                ic_left++;
+            if (on_right(r->i_cm.map[ic]))
+                ic_right++;
+            if (on_center(r->i_cm.map[ic]))
+                ic_center++;
         }
 
-        if (!oc_connected && remix) {
-            /* OK, we shall remix */
+        for (oc = 0; oc < n_oc; oc++) {
+            bool oc_connected = false;
+            pa_channel_position_t b = r->o_cm.map[oc];
 
-            /* Try to find matching input ports for this output port */
+            for (ic = 0; ic < n_ic; ic++) {
+                pa_channel_position_t a = r->i_cm.map[ic];
 
-            if (on_left(b)) {
-                unsigned n = 0;
+                if (a == b || a == PA_CHANNEL_POSITION_MONO) {
+                    m->map_table_f[oc][ic] = 1.0f;
 
-                /* We are not connected and on the left side, let's
-                 * average all left side input channels. */
+                    oc_connected = true;
+                    ic_connected[ic] = true;
+                }
+                else if (b == PA_CHANNEL_POSITION_MONO) {
+                    m->map_table_f[oc][ic] = 1.0f / (float) n_ic;
 
-                for (ic = 0; ic < n_ic; ic++)
-                    if (on_left(r->i_cm.map[ic]))
-                        n++;
+                    oc_connected = true;
+                    ic_connected[ic] = true;
+                }
+            }
 
-                if (n > 0)
-                    for (ic = 0; ic < n_ic; ic++)
-                        if (on_left(r->i_cm.map[ic])) {
-                            m->map_table_f[oc][ic] = 1.0f / (float) n;
-                            ic_connected[ic] = TRUE;
-                        }
+            if (!oc_connected) {
+                /* Try to find matching input ports for this output port */
 
-                /* We ignore the case where there is no left input
-                 * channel. Something is really wrong in this case
-                 * anyway. */
+                if (on_left(b)) {
 
-            } else if (on_right(b)) {
-                unsigned n = 0;
+                    /* We are not connected and on the left side, let's
+                     * average all left side input channels. */
 
-                /* We are not connected and on the right side, let's
-                 * average all right side input channels. */
+                    if (ic_left > 0)
+                        for (ic = 0; ic < n_ic; ic++)
+                            if (on_left(r->i_cm.map[ic])) {
+                                m->map_table_f[oc][ic] = 1.0f / (float) ic_left;
+                                ic_connected[ic] = true;
+                            }
 
-                for (ic = 0; ic < n_ic; ic++)
-                    if (on_right(r->i_cm.map[ic]))
-                        n++;
+                    /* We ignore the case where there is no left input channel.
+                     * Something is really wrong in this case anyway. */
 
-                if (n > 0)
-                    for (ic = 0; ic < n_ic; ic++)
-                        if (on_right(r->i_cm.map[ic])) {
-                            m->map_table_f[oc][ic] = 1.0f / (float) n;
-                            ic_connected[ic] = TRUE;
-                        }
+                } else if (on_right(b)) {
 
-                /* We ignore the case where there is no right input
-                 * channel. Something is really wrong in this case
-                 * anyway. */
+                    /* We are not connected and on the right side, let's
+                     * average all right side input channels. */
 
-            } else if (on_center(b)) {
-                unsigned n = 0;
+                    if (ic_right > 0)
+                        for (ic = 0; ic < n_ic; ic++)
+                            if (on_right(r->i_cm.map[ic])) {
+                                m->map_table_f[oc][ic] = 1.0f / (float) ic_right;
+                                ic_connected[ic] = true;
+                            }
 
-                /* We are not connected and at the center. Let's
-                 * average all center input channels. */
+                    /* We ignore the case where there is no right input
+                     * channel. Something is really wrong in this case anyway.
+                     * */
 
-                for (ic = 0; ic < n_ic; ic++)
-                    if (on_center(r->i_cm.map[ic]))
-                        n++;
+                } else if (on_center(b)) {
 
-                if (n > 0) {
-                    for (ic = 0; ic < n_ic; ic++)
-                        if (on_center(r->i_cm.map[ic])) {
-                            m->map_table_f[oc][ic] = 1.0f / (float) n;
-                            ic_connected[ic] = TRUE;
-                        }
-                } else {
+                    if (ic_center > 0) {
+
+                        /* We are not connected and at the center. Let's average
+                         * all center input channels. */
 
-                    /* Hmm, no center channel around, let's synthesize
-                     * it by mixing L and R.*/
+                        for (ic = 0; ic < n_ic; ic++)
+                            if (on_center(r->i_cm.map[ic])) {
+                                m->map_table_f[oc][ic] = 1.0f / (float) ic_center;
+                                ic_connected[ic] = true;
+                            }
 
-                    n = 0;
+                    } else if (ic_left + ic_right > 0) {
 
-                    for (ic = 0; ic < n_ic; ic++)
-                        if (on_left(r->i_cm.map[ic]) || on_right(r->i_cm.map[ic]))
-                            n++;
+                        /* Hmm, no center channel around, let's synthesize it
+                         * by mixing L and R.*/
 
-                    if (n > 0)
                         for (ic = 0; ic < n_ic; ic++)
                             if (on_left(r->i_cm.map[ic]) || on_right(r->i_cm.map[ic])) {
-                                m->map_table_f[oc][ic] = 1.0f / (float) n;
-                                ic_connected[ic] = TRUE;
+                                m->map_table_f[oc][ic] = 1.0f / (float) (ic_left + ic_right);
+                                ic_connected[ic] = true;
                             }
+                    }
 
-                    /* We ignore the case where there is not even a
-                     * left or right input channel. Something is
-                     * really wrong in this case anyway. */
-                }
-
-            } else if (on_lfe(b)) {
+                    /* We ignore the case where there is not even a left or
+                     * right input channel. Something is really wrong in this
+                     * case anyway. */
 
-                /* We are not connected and an LFE. Let's average all
-                 * channels for LFE. */
+                } else if (on_lfe(b) && !(r->flags & PA_RESAMPLER_NO_LFE)) {
 
-                for (ic = 0; ic < n_ic; ic++) {
+                    /* We are not connected and an LFE. Let's average all
+                     * channels for LFE. */
 
-                    if (!(r->flags & PA_RESAMPLER_NO_LFE))
+                    for (ic = 0; ic < n_ic; ic++)
                         m->map_table_f[oc][ic] = 1.0f / (float) n_ic;
-                    else
-                        m->map_table_f[oc][ic] = 0;
 
-                    /* Please note that a channel connected to LFE
-                     * doesn't really count as connected. */
+                    /* Please note that a channel connected to LFE doesn't
+                     * really count as connected. */
                 }
             }
         }
-    }
-
-    if (remix) {
-        unsigned
-            ic_unconnected_left = 0,
-            ic_unconnected_right = 0,
-            ic_unconnected_center = 0,
-            ic_unconnected_lfe = 0;
 
         for (ic = 0; ic < n_ic; ic++) {
             pa_channel_position_t a = r->i_cm.map[ic];
@@ -845,164 +907,100 @@ static void calc_map_table(pa_resampler *r) {
                 ic_unconnected_lfe++;
         }
 
-        if (ic_unconnected_left > 0) {
+        for (ic = 0; ic < n_ic; ic++) {
+            pa_channel_position_t a = r->i_cm.map[ic];
 
-            /* OK, so there are unconnected input channels on the
-             * left. Let's multiply all already connected channels on
-             * the left side by .9 and add in our averaged unconnected
-             * channels multplied by .1 */
+            if (ic_connected[ic])
+                continue;
 
             for (oc = 0; oc < n_oc; oc++) {
+                pa_channel_position_t b = r->o_cm.map[oc];
 
-                if (!on_left(r->o_cm.map[oc]))
-                    continue;
+                if (on_left(a) && on_left(b))
+                    m->map_table_f[oc][ic] = (1.f/9.f) / (float) ic_unconnected_left;
 
-                for (ic = 0; ic < n_ic; ic++) {
+                else if (on_right(a) && on_right(b))
+                    m->map_table_f[oc][ic] = (1.f/9.f) / (float) ic_unconnected_right;
 
-                    if (ic_connected[ic]) {
-                        m->map_table_f[oc][ic] *= .9f;
-                        continue;
-                    }
+                else if (on_center(a) && on_center(b)) {
+                    m->map_table_f[oc][ic] = (1.f/9.f) / (float) ic_unconnected_center;
+                    ic_unconnected_center_mixed_in = true;
 
-                    if (on_left(r->i_cm.map[ic]))
-                        m->map_table_f[oc][ic] = .1f / (float) ic_unconnected_left;
-                }
+                } else if (on_lfe(a) && !(r->flags & PA_RESAMPLER_NO_LFE))
+                    m->map_table_f[oc][ic] = .375f / (float) ic_unconnected_lfe;
             }
         }
 
-        if (ic_unconnected_right > 0) {
+        if (ic_unconnected_center > 0 && !ic_unconnected_center_mixed_in) {
+            unsigned ncenter[PA_CHANNELS_MAX];
+            bool found_frs[PA_CHANNELS_MAX];
 
-            /* OK, so there are unconnected input channels on the
-             * right. Let's multiply all already connected channels on
-             * the right side by .9 and add in our averaged unconnected
-             * channels multplied by .1 */
+            memset(ncenter, 0, sizeof(ncenter));
+            memset(found_frs, 0, sizeof(found_frs));
 
-            for (oc = 0; oc < n_oc; oc++) {
+            /* Hmm, as it appears there was no center channel we
+               could mix our center channel in. In this case, mix it into
+               left and right. Using .5 as the factor. */
 
-                if (!on_right(r->o_cm.map[oc]))
+            for (ic = 0; ic < n_ic; ic++) {
+
+                if (ic_connected[ic])
                     continue;
 
-                for (ic = 0; ic < n_ic; ic++) {
+                if (!on_center(r->i_cm.map[ic]))
+                    continue;
 
-                    if (ic_connected[ic]) {
-                        m->map_table_f[oc][ic] *= .9f;
+                for (oc = 0; oc < n_oc; oc++) {
+
+                    if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
                         continue;
-                    }
 
-                    if (on_right(r->i_cm.map[ic]))
-                        m->map_table_f[oc][ic] = .1f / (float) ic_unconnected_right;
+                    if (front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc])) {
+                        found_frs[ic] = true;
+                        break;
+                    }
                 }
-            }
-        }
-
-        if (ic_unconnected_center > 0) {
-            pa_bool_t mixed_in = FALSE;
-
-            /* OK, so there are unconnected input channels on the
-             * center. Let's multiply all already connected channels on
-             * the center side by .9 and add in our averaged unconnected
-             * channels multplied by .1 */
-
-            for (oc = 0; oc < n_oc; oc++) {
-
-                if (!on_center(r->o_cm.map[oc]))
-                    continue;
 
-                for (ic = 0; ic < n_ic; ic++)  {
+                for (oc = 0; oc < n_oc; oc++) {
 
-                    if (ic_connected[ic]) {
-                        m->map_table_f[oc][ic] *= .9f;
+                    if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
                         continue;
-                    }
 
-                    if (on_center(r->i_cm.map[ic])) {
-                        m->map_table_f[oc][ic] = .1f / (float) ic_unconnected_center;
-                        mixed_in = TRUE;
-                    }
+                    if (!found_frs[ic] || front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc]))
+                        ncenter[oc]++;
                 }
             }
 
-            if (!mixed_in) {
-                unsigned ncenter[PA_CHANNELS_MAX];
-                pa_bool_t found_frs[PA_CHANNELS_MAX];
+            for (oc = 0; oc < n_oc; oc++) {
 
-                memset(ncenter, 0, sizeof(ncenter));
-                memset(found_frs, 0, sizeof(found_frs));
+                if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
+                    continue;
 
-                /* Hmm, as it appears there was no center channel we
-                   could mix our center channel in. In this case, mix
-                   it into left and right. Using .375 and 0.75 as
-                   factors. */
+                if (ncenter[oc] <= 0)
+                    continue;
 
                 for (ic = 0; ic < n_ic; ic++) {
 
-                    if (ic_connected[ic])
-                        continue;
-
                     if (!on_center(r->i_cm.map[ic]))
                         continue;
 
-                    for (oc = 0; oc < n_oc; oc++) {
-
-                        if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
-                            continue;
-
-                        if (front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc])) {
-                            found_frs[ic] = TRUE;
-                            break;
-                        }
-                    }
-
-                    for (oc = 0; oc < n_oc; oc++) {
-
-                        if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
-                            continue;
-
-                        if (!found_frs[ic] || front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc]))
-                            ncenter[oc]++;
-                    }
-                }
-
-                for (oc = 0; oc < n_oc; oc++) {
-
-                    if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
-                        continue;
-
-                    if (ncenter[oc] <= 0)
-                        continue;
-
-                    for (ic = 0; ic < n_ic; ic++)  {
-
-                        if (ic_connected[ic]) {
-                            m->map_table_f[oc][ic] *= .75f;
-                            continue;
-                        }
-
-                        if (!on_center(r->i_cm.map[ic]))
-                            continue;
-
-                        if (!found_frs[ic] || front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc]))
-                            m->map_table_f[oc][ic] = .375f / (float) ncenter[oc];
-                    }
+                    if (!found_frs[ic] || front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc]))
+                        m->map_table_f[oc][ic] = .5f / (float) ncenter[oc];
                 }
             }
         }
+    }
 
-        if (ic_unconnected_lfe > 0 && !(r->flags & PA_RESAMPLER_NO_LFE)) {
-
-            /* OK, so there is an unconnected LFE channel. Let's mix
-             * it into all channels, with factor 0.375 */
-
-            for (ic = 0; ic < n_ic; ic++)  {
-
-                if (!on_lfe(r->i_cm.map[ic]))
-                    continue;
+    for (oc = 0; oc < n_oc; oc++) {
+        float sum = 0.0f;
+        for (ic = 0; ic < n_ic; ic++)
+            sum += m->map_table_f[oc][ic];
 
-                for (oc = 0; oc < n_oc; oc++)
-                    m->map_table_f[oc][ic] = 0.375f / (float) ic_unconnected_lfe;
-            }
-        }
+        if (sum > 1.0f)
+            for (ic = 0; ic < n_ic; ic++)
+                m->map_table_f[oc][ic] /= sum;
     }
+
     /* make an 16:16 int version of the matrix */
     for (oc = 0; oc < n_oc; oc++)
         for (ic = 0; ic < n_ic; ic++)
@@ -1028,11 +1026,11 @@ static void calc_map_table(pa_resampler *r) {
         pa_strbuf_puts(s, "\n");
     }
 
-    pa_log_debug("Channel matrix:\n%s", t = pa_strbuf_tostring_free(s));
+    pa_log_debug_verbose("Channel matrix:\n%s", t = pa_strbuf_tostring_free(s));
     pa_xfree(t);
 
     /* initialize the remapping function */
-    pa_init_remap (m);
+    pa_init_remap(m);
 }
 
 static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input) {
@@ -1043,76 +1041,110 @@ static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input)
     pa_assert(input);
     pa_assert(input->memblock);
 
-    /* Convert the incoming sample into the work sample format and place them in buf1 */
+    /* Convert the incoming sample into the work sample format and place them
+     * in to_work_format_buf. */
 
     if (!r->to_work_format_func || !input->length)
         return input;
 
     n_samples = (unsigned) ((input->length / r->i_fz) * r->i_ss.channels);
 
-    r->buf1.index = 0;
-    r->buf1.length = r->w_sz * n_samples;
+    r->to_work_format_buf.index = 0;
+    r->to_work_format_buf.length = r->w_sz * n_samples;
 
-    if (!r->buf1.memblock || r->buf1_samples < n_samples) {
-        if (r->buf1.memblock)
-            pa_memblock_unref(r->buf1.memblock);
+    if (!r->to_work_format_buf.memblock || r->to_work_format_buf_samples < n_samples) {
+        if (r->to_work_format_buf.memblock)
+            pa_memblock_unref(r->to_work_format_buf.memblock);
 
-        r->buf1_samples = n_samples;
-        r->buf1.memblock = pa_memblock_new(r->mempool, r->buf1.length);
+        r->to_work_format_buf_samples = n_samples;
+        r->to_work_format_buf.memblock = pa_memblock_new(r->mempool, r->to_work_format_buf.length);
     }
 
-    src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
-    dst = (uint8_t*) pa_memblock_acquire(r->buf1.memblock);
+    src = pa_memblock_acquire_chunk(input);
+    dst = pa_memblock_acquire(r->to_work_format_buf.memblock);
 
     r->to_work_format_func(n_samples, src, dst);
 
     pa_memblock_release(input->memblock);
-    pa_memblock_release(r->buf1.memblock);
+    pa_memblock_release(r->to_work_format_buf.memblock);
 
-    return &r->buf1;
+    return &r->to_work_format_buf;
 }
 
 static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
-    unsigned in_n_samples, out_n_samples, n_frames;
+    unsigned in_n_samples, out_n_samples, in_n_frames, out_n_frames;
     void *src, *dst;
-    pa_remap_t *remap;
+    size_t leftover_length = 0;
+    bool have_leftover;
 
     pa_assert(r);
     pa_assert(input);
     pa_assert(input->memblock);
 
-    /* Remap channels and place the result int buf2 */
+    /* Remap channels and place the result in remap_buf. There may be leftover
+     * data in the beginning of remap_buf. The leftover data is already
+     * remapped, so it's not part of the input, it's part of the output. */
+
+    have_leftover = r->remap_buf_contains_leftover_data;
+    r->remap_buf_contains_leftover_data = false;
 
-    if (!r->map_required || !input->length)
+    if (!have_leftover && (!r->map_required || input->length <= 0))
         return input;
+    else if (input->length <= 0)
+        return &r->remap_buf;
 
     in_n_samples = (unsigned) (input->length / r->w_sz);
-    n_frames = in_n_samples / r->i_ss.channels;
-    out_n_samples = n_frames * r->o_ss.channels;
+    in_n_frames = out_n_frames = in_n_samples / r->i_ss.channels;
 
-    r->buf2.index = 0;
-    r->buf2.length = r->w_sz * out_n_samples;
+    if (have_leftover) {
+        leftover_length = r->remap_buf.length;
+        out_n_frames += leftover_length / (r->w_sz * r->o_ss.channels);
+    }
+
+    out_n_samples = out_n_frames * r->o_ss.channels;
+    r->remap_buf.length = out_n_samples * r->w_sz;
 
-    if (!r->buf2.memblock || r->buf2_samples < out_n_samples) {
-        if (r->buf2.memblock)
-            pa_memblock_unref(r->buf2.memblock);
+    if (have_leftover) {
+        if (r->remap_buf_size < r->remap_buf.length) {
+            pa_memblock *new_block = pa_memblock_new(r->mempool, r->remap_buf.length);
 
-        r->buf2_samples = out_n_samples;
-        r->buf2.memblock = pa_memblock_new(r->mempool, r->buf2.length);
+            src = pa_memblock_acquire(r->remap_buf.memblock);
+            dst = pa_memblock_acquire(new_block);
+            memcpy(dst, src, leftover_length);
+            pa_memblock_release(r->remap_buf.memblock);
+            pa_memblock_release(new_block);
+
+            pa_memblock_unref(r->remap_buf.memblock);
+            r->remap_buf.memblock = new_block;
+            r->remap_buf_size = r->remap_buf.length;
+        }
+
+    } else {
+        if (!r->remap_buf.memblock || r->remap_buf_size < r->remap_buf.length) {
+            if (r->remap_buf.memblock)
+                pa_memblock_unref(r->remap_buf.memblock);
+
+            r->remap_buf_size = r->remap_buf.length;
+            r->remap_buf.memblock = pa_memblock_new(r->mempool, r->remap_buf.length);
+        }
     }
 
-    src = ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
-    dst = pa_memblock_acquire(r->buf2.memblock);
+    src = pa_memblock_acquire_chunk(input);
+    dst = (uint8_t *) pa_memblock_acquire(r->remap_buf.memblock) + leftover_length;
 
-    remap = &r->remap;
+    if (r->map_required) {
+        pa_remap_t *remap = &r->remap;
 
-    pa_assert (remap->do_remap);
-    remap->do_remap (remap, dst, src, n_frames);
+        pa_assert(remap->do_remap);
+        remap->do_remap(remap, dst, src, in_n_frames);
+
+    } else
+        memcpy(dst, src, input->length);
 
     pa_memblock_release(input->memblock);
-    pa_memblock_release(r->buf2.memblock);
+    pa_memblock_release(r->remap_buf.memblock);
 
-    return &r->buf2;
+    return &r->remap_buf;
 }
 
 static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) {
@@ -1122,32 +1154,32 @@ static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) {
     pa_assert(r);
     pa_assert(input);
 
-    /* Resample the data and place the result in buf3 */
+    /* Resample the data and place the result in resample_buf. */
 
     if (!r->impl_resample || !input->length)
         return input;
 
     in_n_samples = (unsigned) (input->length / r->w_sz);
-    in_n_frames = (unsigned) (in_n_samples / r->o_ss.channels);
+    in_n_frames = (unsigned) (in_n_samples / r->work_channels);
 
     out_n_frames = ((in_n_frames*r->o_ss.rate)/r->i_ss.rate)+EXTRA_FRAMES;
-    out_n_samples = out_n_frames * r->o_ss.channels;
+    out_n_samples = out_n_frames * r->work_channels;
 
-    r->buf3.index = 0;
-    r->buf3.length = r->w_sz * out_n_samples;
+    r->resample_buf.index = 0;
+    r->resample_buf.length = r->w_sz * out_n_samples;
 
-    if (!r->buf3.memblock || r->buf3_samples < out_n_samples) {
-        if (r->buf3.memblock)
-            pa_memblock_unref(r->buf3.memblock);
+    if (!r->resample_buf.memblock || r->resample_buf_samples < out_n_samples) {
+        if (r->resample_buf.memblock)
+            pa_memblock_unref(r->resample_buf.memblock);
 
-        r->buf3_samples = out_n_samples;
-        r->buf3.memblock = pa_memblock_new(r->mempool, r->buf3.length);
+        r->resample_buf_samples = out_n_samples;
+        r->resample_buf.memblock = pa_memblock_new(r->mempool, r->resample_buf.length);
     }
 
-    r->impl_resample(r, input, in_n_frames, &r->buf3, &out_n_frames);
-    r->buf3.length = out_n_frames * r->w_sz * r->o_ss.channels;
+    r->impl_resample(r, input, in_n_frames, &r->resample_buf, &out_n_frames);
+    r->resample_buf.length = out_n_frames * r->w_sz * r->work_channels;
 
-    return &r->buf3;
+    return &r->resample_buf;
 }
 
 static pa_memchunk *convert_from_work_format(pa_resampler *r, pa_memchunk *input) {
@@ -1157,7 +1189,8 @@ static pa_memchunk *convert_from_work_format(pa_resampler *r, pa_memchunk *input
     pa_assert(r);
     pa_assert(input);
 
-    /* Convert the data into the correct sample type and place the result in buf4 */
+    /* Convert the data into the correct sample type and place the result in
+     * from_work_format_buf. */
 
     if (!r->from_work_format_func || !input->length)
         return input;
@@ -1165,26 +1198,24 @@ static pa_memchunk *convert_from_work_format(pa_resampler *r, pa_memchunk *input
     n_samples = (unsigned) (input->length / r->w_sz);
     n_frames = n_samples / r->o_ss.channels;
 
-    r->buf4.index = 0;
-    r->buf4.length = r->o_fz * n_frames;
+    r->from_work_format_buf.index = 0;
+    r->from_work_format_buf.length = r->o_fz * n_frames;
 
-    if (!r->buf4.memblock || r->buf4_samples < n_samples) {
-        if (r->buf4.memblock)
-            pa_memblock_unref(r->buf4.memblock);
+    if (!r->from_work_format_buf.memblock || r->from_work_format_buf_samples < n_samples) {
+        if (r->from_work_format_buf.memblock)
+            pa_memblock_unref(r->from_work_format_buf.memblock);
 
-        r->buf4_samples = n_samples;
-        r->buf4.memblock = pa_memblock_new(r->mempool, r->buf4.length);
+        r->from_work_format_buf_samples = n_samples;
+        r->from_work_format_buf.memblock = pa_memblock_new(r->mempool, r->from_work_format_buf.length);
     }
 
-    src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
-    dst = pa_memblock_acquire(r->buf4.memblock);
+    src = pa_memblock_acquire_chunk(input);
+    dst = pa_memblock_acquire(r->from_work_format_buf.memblock);
     r->from_work_format_func(n_samples, src, dst);
     pa_memblock_release(input->memblock);
-    pa_memblock_release(r->buf4.memblock);
-
-    r->buf4.length = r->o_fz * n_frames;
+    pa_memblock_release(r->from_work_format_buf.memblock);
 
-    return &r->buf4;
+    return &r->from_work_format_buf;
 }
 
 void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) {
@@ -1199,8 +1230,15 @@ void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out)
 
     buf = (pa_memchunk*) in;
     buf = convert_to_work_format(r, buf);
-    buf = remap_channels(r, buf);
-    buf = resample(r, buf);
+    /* Try to save resampling effort: if we have more output channels than
+     * input channels, do resampling first, then remapping. */
+    if (r->o_ss.channels <= r->i_ss.channels) {
+        buf = remap_channels(r, buf);
+        buf = resample(r, buf);
+    } else {
+        buf = resample(r, buf);
+        buf = remap_channels(r, buf);
+    }
 
     if (buf->length) {
         buf = convert_from_work_format(r, buf);
@@ -1214,6 +1252,32 @@ void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out)
         pa_memchunk_reset(out);
 }
 
+static void save_leftover(pa_resampler *r, void *buf, size_t len) {
+    void *dst;
+
+    pa_assert(r);
+    pa_assert(buf);
+    pa_assert(len > 0);
+
+    /* Store the leftover to remap_buf. */
+
+    r->remap_buf.length = len;
+
+    if (!r->remap_buf.memblock || r->remap_buf_size < r->remap_buf.length) {
+        if (r->remap_buf.memblock)
+            pa_memblock_unref(r->remap_buf.memblock);
+
+        r->remap_buf_size = r->remap_buf.length;
+        r->remap_buf.memblock = pa_memblock_new(r->mempool, r->remap_buf.length);
+    }
+
+    dst = pa_memblock_acquire(r->remap_buf.memblock);
+    memcpy(dst, buf, r->remap_buf.length);
+    pa_memblock_release(r->remap_buf.memblock);
+
+    r->remap_buf_contains_leftover_data = true;
+}
+
 /*** libsamplerate based implementation ***/
 
 #ifdef HAVE_LIBSAMPLERATE
@@ -1227,17 +1291,23 @@ static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, un
 
     memset(&data, 0, sizeof(data));
 
-    data.data_in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
+    data.data_in = pa_memblock_acquire_chunk(input);
     data.input_frames = (long int) in_n_frames;
 
-    data.data_out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
+    data.data_out = pa_memblock_acquire_chunk(output);
     data.output_frames = (long int) *out_n_frames;
 
     data.src_ratio = (double) r->o_ss.rate / r->i_ss.rate;
     data.end_of_input = 0;
 
     pa_assert_se(src_process(r->src.state, &data) == 0);
-    pa_assert((unsigned) data.input_frames_used == in_n_frames);
+
+    if (data.input_frames_used < in_n_frames) {
+        void *leftover_data = data.data_in + data.input_frames_used * r->work_channels;
+        size_t leftover_length = (in_n_frames - data.input_frames_used) * sizeof(float) * r->work_channels;
+
+        save_leftover(r, leftover_data, leftover_length);
+    }
 
     pa_memblock_release(input->memblock);
     pa_memblock_release(output->memblock);
@@ -1281,6 +1351,7 @@ static int libsamplerate_init(pa_resampler *r) {
 }
 #endif
 
+#ifdef HAVE_SPEEX
 /*** speex based implementation ***/
 
 static void speex_resample_float(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
@@ -1292,8 +1363,8 @@ static void speex_resample_float(pa_resampler *r, const pa_memchunk *input, unsi
     pa_assert(output);
     pa_assert(out_n_frames);
 
-    in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
-    out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
+    in = pa_memblock_acquire_chunk(input);
+    out = pa_memblock_acquire_chunk(output);
 
     pa_assert_se(speex_resampler_process_interleaved_float(r->speex.state, in, &inf, out, &outf) == 0);
 
@@ -1313,8 +1384,8 @@ static void speex_resample_int(pa_resampler *r, const pa_memchunk *input, unsign
     pa_assert(output);
     pa_assert(out_n_frames);
 
-    in = (int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
-    out = (int16_t*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
+    in = pa_memblock_acquire_chunk(input);
+    out = pa_memblock_acquire_chunk(output);
 
     pa_assert_se(speex_resampler_process_interleaved_int(r->speex.state, in, &inf, out, &outf) == 0);
 
@@ -1369,17 +1440,18 @@ static int speex_init(pa_resampler *r) {
 
     pa_log_info("Choosing speex quality setting %i.", q);
 
-    if (!(r->speex.state = speex_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err)))
+    if (!(r->speex.state = speex_resampler_init(r->work_channels, r->i_ss.rate, r->o_ss.rate, q, &err)))
         return -1;
 
     return 0;
 }
+#endif
 
 /* Trivial implementation */
 
 static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
     size_t fz;
-    unsigned o_index;
+    unsigned i_index, o_index;
     void *src, *dst;
 
     pa_assert(r);
@@ -1387,24 +1459,21 @@ static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned
     pa_assert(output);
     pa_assert(out_n_frames);
 
-    fz = r->w_sz * r->o_ss.channels;
+    fz = r->w_sz * r->work_channels;
 
-    src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
-    dst = (uint8_t*) pa_memblock_acquire(output->memblock) + output->index;
+    src = pa_memblock_acquire_chunk(input);
+    dst = pa_memblock_acquire_chunk(output);
 
     for (o_index = 0;; o_index++, r->trivial.o_counter++) {
-        unsigned j;
-
-        j = ((r->trivial.o_counter * r->i_ss.rate) / r->o_ss.rate);
-        j = j > r->trivial.i_counter ? j - r->trivial.i_counter : 0;
+        i_index = ((uint64_t) r->trivial.o_counter * r->i_ss.rate) / r->o_ss.rate;
+        i_index = i_index > r->trivial.i_counter ? i_index - r->trivial.i_counter : 0;
 
-        if (j >= in_n_frames)
+        if (i_index >= in_n_frames)
             break;
 
-        pa_assert(o_index * fz < pa_memblock_get_length(output->memblock));
+        pa_assert_fp(o_index * fz < pa_memblock_get_length(output->memblock));
 
-        memcpy((uint8_t*) dst + fz * o_index,
-                   (uint8_t*) src + fz * j, (int) fz);
+        memcpy((uint8_t*) dst + fz * o_index, (uint8_t*) src + fz * i_index, (int) fz);
     }
 
     pa_memblock_release(input->memblock);
@@ -1445,82 +1514,83 @@ static int trivial_init(pa_resampler*r) {
 /* Peak finder implementation */
 
 static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
-    size_t fz;
-    unsigned o_index;
+    unsigned c, o_index = 0;
+    unsigned i, i_end = 0;
     void *src, *dst;
-    unsigned start = 0;
 
     pa_assert(r);
     pa_assert(input);
     pa_assert(output);
     pa_assert(out_n_frames);
 
-    fz = r->w_sz * r->o_ss.channels;
-
-    src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
-    dst = (uint8_t*) pa_memblock_acquire(output->memblock) + output->index;
+    src = pa_memblock_acquire_chunk(input);
+    dst = pa_memblock_acquire_chunk(output);
 
-    for (o_index = 0;; o_index++, r->peaks.o_counter++) {
-        unsigned j;
+    i = ((uint64_t) r->peaks.o_counter * r->i_ss.rate) / r->o_ss.rate;
+    i = i > r->peaks.i_counter ? i - r->peaks.i_counter : 0;
 
-        j = ((r->peaks.o_counter * r->i_ss.rate) / r->o_ss.rate);
+    while (i_end < in_n_frames) {
+        i_end = ((uint64_t) (r->peaks.o_counter + 1) * r->i_ss.rate) / r->o_ss.rate;
+        i_end = i_end > r->peaks.i_counter ? i_end - r->peaks.i_counter : 0;
 
-        if (j > r->peaks.i_counter)
-            j -= r->peaks.i_counter;
-        else
-            j = 0;
+        pa_assert_fp(o_index * r->w_sz * r->o_ss.channels < pa_memblock_get_length(output->memblock));
 
-        pa_assert(o_index * fz < pa_memblock_get_length(output->memblock));
+        /* 1ch float is treated separately, because that is the common case */
+        if (r->o_ss.channels == 1 && r->work_format == PA_SAMPLE_FLOAT32NE) {
+            float *s = (float*) src + i;
+            float *d = (float*) dst + o_index;
 
-        if (r->work_format == PA_SAMPLE_S16NE) {
-            unsigned i, c;
-            int16_t *s = (int16_t*) ((uint8_t*) src + fz * start);
-            int16_t *d = (int16_t*) ((uint8_t*) dst + fz * o_index);
+            for (; i < i_end && i < in_n_frames; i++) {
+                float n = fabsf(*s++);
 
-            for (i = start; i <= j && i < in_n_frames; i++)
+                if (n > r->peaks.max_f[0])
+                    r->peaks.max_f[0] = n;
+            }
 
-                for (c = 0; c < r->o_ss.channels; c++, s++) {
-                    int16_t n;
+            if (i == i_end) {
+                *d = r->peaks.max_f[0];
+                r->peaks.max_f[0] = 0;
+                o_index++, r->peaks.o_counter++;
+            }
+        } else if (r->work_format == PA_SAMPLE_S16NE) {
+            int16_t *s = (int16_t*) src + r->i_ss.channels * i;
+            int16_t *d = (int16_t*) dst + r->o_ss.channels * o_index;
 
-                    n = (int16_t) (*s < 0 ? -*s : *s);
+            for (; i < i_end && i < in_n_frames; i++)
+                for (c = 0; c < r->o_ss.channels; c++) {
+                    int16_t n = abs(*s++);
 
-                    if (PA_UNLIKELY(n > r->peaks.max_i[c]))
+                    if (n > r->peaks.max_i[c])
                         r->peaks.max_i[c] = n;
                 }
 
-            if (i >= in_n_frames)
-                break;
-
-            for (c = 0; c < r->o_ss.channels; c++, d++) {
-                *d = r->peaks.max_i[c];
-                r->peaks.max_i[c] = 0;
+            if (i == i_end) {
+                for (c = 0; c < r->o_ss.channels; c++, d++) {
+                    *d = r->peaks.max_i[c];
+                    r->peaks.max_i[c] = 0;
+                }
+                o_index++, r->peaks.o_counter++;
             }
-
         } else {
-            unsigned i, c;
-            float *s = (float*) ((uint8_t*) src + fz * start);
-            float *d = (float*) ((uint8_t*) dst + fz * o_index);
-
-            pa_assert(r->work_format == PA_SAMPLE_FLOAT32NE);
+            float *s = (float*) src + r->i_ss.channels * i;
+            float *d = (float*) dst + r->o_ss.channels * o_index;
 
-            for (i = start; i <= j && i < in_n_frames; i++)
-                for (c = 0; c < r->o_ss.channels; c++, s++) {
-                    float n = fabsf(*s);
+            for (; i < i_end && i < in_n_frames; i++)
+                for (c = 0; c < r->o_ss.channels; c++) {
+                    float n = fabsf(*s++);
 
                     if (n > r->peaks.max_f[c])
                         r->peaks.max_f[c] = n;
                 }
 
-            if (i >= in_n_frames)
-                break;
-
-            for (c = 0; c < r->o_ss.channels; c++, d++) {
-                *d = r->peaks.max_f[c];
-                r->peaks.max_f[c] = 0;
+            if (i == i_end) {
+                for (c = 0; c < r->o_ss.channels; c++, d++) {
+                    *d = r->peaks.max_f[c];
+                    r->peaks.max_f[c] = 0;
+                }
+                o_index++, r->peaks.o_counter++;
             }
         }
-
-        start = j;
     }
 
     pa_memblock_release(input->memblock);
@@ -1548,6 +1618,8 @@ static void peaks_update_rates_or_reset(pa_resampler *r) {
 
 static int peaks_init(pa_resampler*r) {
     pa_assert(r);
+    pa_assert(r->i_ss.rate >= r->o_ss.rate);
+    pa_assert(r->work_format == PA_SAMPLE_S16NE || r->work_format == PA_SAMPLE_FLOAT32NE);
 
     r->peaks.o_counter = r->peaks.i_counter = 0;
     memset(r->peaks.max_i, 0, sizeof(r->peaks.max_i));
@@ -1564,46 +1636,33 @@ static int peaks_init(pa_resampler*r) {
 
 static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
     unsigned used_frames = 0, c;
+    int previous_consumed_frames = -1;
 
     pa_assert(r);
     pa_assert(input);
     pa_assert(output);
     pa_assert(out_n_frames);
 
-    for (c = 0; c < r->o_ss.channels; c++) {
+    for (c = 0; c < r->work_channels; c++) {
         unsigned u;
         pa_memblock *b, *w;
         int16_t *p, *t, *k, *q, *s;
         int consumed_frames;
-        unsigned in, l;
 
         /* Allocate a new block */
         b = pa_memblock_new(r->mempool, r->ffmpeg.buf[c].length + in_n_frames * sizeof(int16_t));
         p = pa_memblock_acquire(b);
 
-        /* Copy the remaining data into it */
-        l = (unsigned) r->ffmpeg.buf[c].length;
-        if (r->ffmpeg.buf[c].memblock) {
-            t = (int16_t*) ((uint8_t*) pa_memblock_acquire(r->ffmpeg.buf[c].memblock) + r->ffmpeg.buf[c].index);
-            memcpy(p, t, l);
-            pa_memblock_release(r->ffmpeg.buf[c].memblock);
-            pa_memblock_unref(r->ffmpeg.buf[c].memblock);
-            pa_memchunk_reset(&r->ffmpeg.buf[c]);
-        }
-
-        /* Now append the new data, splitting up channels */
-        t = ((int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index)) + c;
-        k = (int16_t*) ((uint8_t*) p + l);
+        /* Now copy the input data, splitting up channels */
+        t = (int16_t*) pa_memblock_acquire_chunk(input) + c;
+        k = p;
         for (u = 0; u < in_n_frames; u++) {
             *k = *t;
-            t += r->o_ss.channels;
+            t += r->work_channels;
             k ++;
         }
         pa_memblock_release(input->memblock);
 
-        /* Calculate the resulting number of frames */
-        in = (unsigned) in_n_frames + l / (unsigned) sizeof(int16_t);
-
         /* Allocate buffer for the result */
         w = pa_memblock_new(r->mempool, *out_n_frames * sizeof(int16_t));
         q = pa_memblock_acquire(w);
@@ -1612,32 +1671,36 @@ static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned
         used_frames = (unsigned) av_resample(r->ffmpeg.state,
                                              q, p,
                                              &consumed_frames,
-                                             (int) in, (int) *out_n_frames,
-                                             c >= (unsigned) (r->o_ss.channels-1));
+                                             (int) in_n_frames, (int) *out_n_frames,
+                                             c >= (unsigned) (r->work_channels-1));
 
         pa_memblock_release(b);
+        pa_memblock_unref(b);
 
-        /* Now store the remaining samples away */
-        pa_assert(consumed_frames <= (int) in);
-        if (consumed_frames < (int) in) {
-            r->ffmpeg.buf[c].memblock = b;
-            r->ffmpeg.buf[c].index = (size_t) consumed_frames * sizeof(int16_t);
-            r->ffmpeg.buf[c].length = (size_t) (in - (unsigned) consumed_frames) * sizeof(int16_t);
-        } else
-            pa_memblock_unref(b);
+        pa_assert(consumed_frames <= (int) in_n_frames);
+        pa_assert(previous_consumed_frames == -1 || consumed_frames == previous_consumed_frames);
+        previous_consumed_frames = consumed_frames;
 
         /* And place the results in the output buffer */
-        s = (short*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index) + c;
+        s = (int16_t *) pa_memblock_acquire_chunk(output) + c;
         for (u = 0; u < used_frames; u++) {
             *s = *q;
             q++;
-            s += r->o_ss.channels;
+            s += r->work_channels;
         }
         pa_memblock_release(output->memblock);
         pa_memblock_release(w);
         pa_memblock_unref(w);
     }
 
+    if (previous_consumed_frames < (int) in_n_frames) {
+        void *leftover_data = (int16_t *) pa_memblock_acquire_chunk(input) + previous_consumed_frames * r->o_ss.channels;
+        size_t leftover_length = (in_n_frames - previous_consumed_frames) * r->o_ss.channels * sizeof(int16_t);
+
+        save_leftover(r, leftover_data, leftover_length);
+        pa_memblock_release(input->memblock);
+    }
+
     *out_n_frames = used_frames;
 }
 
index 742de6a..40b1207 100644 (file)
@@ -42,6 +42,9 @@ typedef enum pa_resample_method {
     PA_RESAMPLER_SPEEX_FIXED_BASE,
     PA_RESAMPLER_SPEEX_FIXED_MAX = PA_RESAMPLER_SPEEX_FIXED_BASE + 10,
     PA_RESAMPLER_FFMPEG,
+#ifdef HAVE_SEC_SRC
+    PA_RESAMPLER_SECSRC,
+#endif
     PA_RESAMPLER_AUTO, /* automatic select based on sample format */
     PA_RESAMPLER_COPY,
     PA_RESAMPLER_PEAKS,
index aecc4e3..d47610f 100644 (file)
@@ -2,6 +2,7 @@
 
 /***
   Copyright 2009 Lennart Poettering
+  Copyright 2010 David Henningsson <diwic@ubuntu.com>
 
   Permission is hereby granted, free of charge, to any person
   obtaining a copy of this software and associated documentation files
 #define _GNU_SOURCE
 #endif
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <string.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/syscall.h>
+#include <pulsecore/core-util.h>
 
 static pid_t _gettid(void) {
         return (pid_t) syscall(SYS_gettid);
 }
 
 static int translate_error(const char *name) {
-        if (strcmp(name, DBUS_ERROR_NO_MEMORY) == 0)
+        if (pa_streq(name, DBUS_ERROR_NO_MEMORY))
                 return -ENOMEM;
-        if (strcmp(name, DBUS_ERROR_SERVICE_UNKNOWN) == 0 ||
-            strcmp(name, DBUS_ERROR_NAME_HAS_NO_OWNER) == 0)
+        if (pa_streq(name, DBUS_ERROR_SERVICE_UNKNOWN) ||
+            pa_streq(name, DBUS_ERROR_NAME_HAS_NO_OWNER))
                 return -ENOENT;
-        if (strcmp(name, DBUS_ERROR_ACCESS_DENIED) == 0 ||
-            strcmp(name, DBUS_ERROR_AUTH_FAILED) == 0)
+        if (pa_streq(name, DBUS_ERROR_ACCESS_DENIED) ||
+            pa_streq(name, DBUS_ERROR_AUTH_FAILED))
                 return -EACCES;
 
         return -EIO;
 }
 
+static long long rtkit_get_int_property(DBusConnection *connection, const char* propname, long long* propval) {
+        DBusMessage *m = NULL, *r = NULL;
+        DBusMessageIter iter, subiter;
+        dbus_int64_t i64;
+        dbus_int32_t i32;
+        DBusError error;
+        int current_type;
+        long long ret;
+        const char * interfacestr = "org.freedesktop.RealtimeKit1";
+
+        dbus_error_init(&error);
+
+        if (!(m = dbus_message_new_method_call(
+                              RTKIT_SERVICE_NAME,
+                              RTKIT_OBJECT_PATH,
+                              "org.freedesktop.DBus.Properties",
+                              "Get"))) {
+                ret = -ENOMEM;
+                goto finish;
+        }
+
+        if (!dbus_message_append_args(
+                            m,
+                            DBUS_TYPE_STRING, &interfacestr,
+                            DBUS_TYPE_STRING, &propname,
+                            DBUS_TYPE_INVALID)) {
+                ret = -ENOMEM;
+                goto finish;
+        }
+
+        if (!(r = dbus_connection_send_with_reply_and_block(connection, m, -1, &error))) {
+                ret = translate_error(error.name);
+                goto finish;
+        }
+
+        if (dbus_set_error_from_message(&error, r)) {
+                ret = translate_error(error.name);
+                goto finish;
+        }
+
+        ret = -EBADMSG;
+        dbus_message_iter_init(r, &iter);
+        while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID) {
+
+                if (current_type == DBUS_TYPE_VARIANT) {
+                        dbus_message_iter_recurse(&iter, &subiter);
+
+                        while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) {
+
+                                if (current_type == DBUS_TYPE_INT32) {
+                                        dbus_message_iter_get_basic(&subiter, &i32);
+                                        *propval = i32;
+                                        ret = 0;
+                                }
+
+                                if (current_type == DBUS_TYPE_INT64) {
+                                        dbus_message_iter_get_basic(&subiter, &i64);
+                                        *propval = i64;
+                                        ret = 0;
+                                }
+
+                                dbus_message_iter_next (&subiter);
+                         }
+                }
+                dbus_message_iter_next (&iter);
+        }
+
+finish:
+
+        if (m)
+                dbus_message_unref(m);
+
+        if (r)
+                dbus_message_unref(r);
+
+        dbus_error_free(&error);
+
+        return ret;
+}
+
+int rtkit_get_max_realtime_priority(DBusConnection *connection) {
+        long long retval;
+        int err;
+
+        err = rtkit_get_int_property(connection, "MaxRealtimePriority", &retval);
+        return err < 0 ? err : retval;
+}
+
+int rtkit_get_min_nice_level(DBusConnection *connection, int* min_nice_level) {
+        long long retval;
+        int err;
+
+        err = rtkit_get_int_property(connection, "MinNiceLevel", &retval);
+        if (err >= 0)
+                *min_nice_level = retval;
+        return err;
+}
+
+long long rtkit_get_rttime_usec_max(DBusConnection *connection) {
+        long long retval;
+        int err;
+
+        err = rtkit_get_int_property(connection, "RTTimeUSecMax", &retval);
+        return err < 0 ? err : retval;
+}
+
 int rtkit_make_realtime(DBusConnection *connection, pid_t thread, int priority) {
         DBusMessage *m = NULL, *r = NULL;
         dbus_uint64_t u64;
@@ -186,4 +298,16 @@ int rtkit_make_high_priority(DBusConnection *connection, pid_t thread, int nice_
         return -ENOTSUP;
 }
 
+int rtkit_get_max_realtime_priority(DBusConnection *connection) {
+        return -ENOTSUP;
+}
+
+int rtkit_get_min_nice_level(DBusConnection *connection, int* min_nice_level) {
+        return -ENOTSUP;
+}
+
+long long rtkit_get_rttime_usec_max(DBusConnection *connection) {
+        return -ENOTSUP;
+}
+
 #endif
index 2081b4e..ac4d599 100644 (file)
@@ -5,6 +5,7 @@
 
 /***
   Copyright 2009 Lennart Poettering
+  Copyright 2010 David Henningsson <diwic@ubuntu.com>
 
   Permission is hereby granted, free of charge, to any person
   obtaining a copy of this software and associated documentation files
@@ -55,6 +56,22 @@ int rtkit_make_realtime(DBusConnection *system_bus, pid_t thread, int priority);
  * on success.*/
 int rtkit_make_high_priority(DBusConnection *system_bus, pid_t thread, int nice_level);
 
+/* Return the maximum value of realtime priority available. Realtime requests
+ * above this value will fail. A negative value is an errno style error code.
+ */
+int rtkit_get_max_realtime_priority(DBusConnection *system_bus);
+
+/* Retreive the minimum value of nice level available. High prio requests
+ * below this value will fail. The returned value is a negative errno
+ * style error code, or 0 on success.*/
+int rtkit_get_min_nice_level(DBusConnection *system_bus, int* min_nice_level);
+
+/* Return the maximum value of RLIMIT_RTTIME to set before attempting a
+ * realtime request. A negative value is an errno style error code.
+ */
+long long rtkit_get_rttime_usec_max(DBusConnection *system_bus);
+
+
 #ifdef __cplusplus
 }
 #endif
index 666cbc9..d90c996 100644 (file)
 
 #include <sys/types.h>
 #include <stdio.h>
-#include <signal.h>
 #include <string.h>
 #include <errno.h>
 
-#ifdef HAVE_POLL_H
-#include <poll.h>
-#else
-#include <pulsecore/poll.h>
-#endif
-
 #include <pulse/xmalloc.h>
 #include <pulse/timeval.h>
 
+#include <pulsecore/poll.h>
 #include <pulsecore/core-error.h>
 #include <pulsecore/core-rtclock.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/llist.h>
 #include <pulsecore/flist.h>
 #include <pulsecore/core-util.h>
-#include <pulsecore/winsock.h>
 #include <pulsecore/ratelimit.h>
+#include <pulse/rtclock.h>
 
 #include "rtpoll.h"
 
@@ -129,7 +123,7 @@ static void rtpoll_rebuild(pa_rtpoll *p) {
 
     for (i = p->items; i; i = i->next) {
 
-        if (i->n_pollfd > 0)  {
+        if (i->n_pollfd > 0) {
             size_t l = i->n_pollfd * sizeof(struct pollfd);
 
             if (i->pollfd)
@@ -217,6 +211,10 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait_op) {
     pa_assert(p);
     pa_assert(!p->running);
 
+#ifdef DEBUG_TIMING
+    pa_log("rtpoll_run");
+#endif
+
     p->running = TRUE;
     p->timer_elapsed = FALSE;
 
@@ -230,13 +228,19 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait_op) {
         if (!i->work_cb)
             continue;
 
-        if (p->quit)
+        if (p->quit) {
+#ifdef DEBUG_TIMING
+            pa_log("rtpoll finish");
+#endif
             goto finish;
+        }
 
         if ((k = i->work_cb(i)) != 0) {
             if (k < 0)
                 r = k;
-
+#ifdef DEBUG_TIMING
+            pa_log("rtpoll finish");
+#endif
             goto finish;
         }
     }
@@ -268,7 +272,9 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait_op) {
 
             if (k < 0)
                 r = k;
-
+#ifdef DEBUG_TIMING
+            pa_log("rtpoll finish");
+#endif
             goto finish;
         }
     }
@@ -292,6 +298,10 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait_op) {
         pa_usec_t now = pa_rtclock_now();
         p->awake = now - p->timestamp;
         p->timestamp = now;
+        if (!wait_op || p->quit || p->timer_enabled)
+            pa_log("poll timeout: %d ms ",(int) ((timeout.tv_sec*1000) + (timeout.tv_usec / 1000)));
+        else
+            pa_log("poll timeout is ZERO");
     }
 #endif
 
@@ -304,7 +314,7 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait_op) {
         r = ppoll(p->pollfd, p->n_pollfd_used, (!wait_op || p->quit || p->timer_enabled) ? &ts : NULL, NULL);
     }
 #else
-    r = poll(p->pollfd, p->n_pollfd_used, (!wait_op || p->quit || p->timer_enabled) ? (int) ((timeout.tv_sec*1000) + (timeout.tv_usec / 1000)) : -1);
+    r = pa_poll(p->pollfd, p->n_pollfd_used, (!wait_op || p->quit || p->timer_enabled) ? (int) ((timeout.tv_sec*1000) + (timeout.tv_usec / 1000)) : -1);
 #endif
 
     p->timer_elapsed = r == 0;
index b2a87fc..1c8f8b0 100644 (file)
  * yet another wrapper around poll(). However it has certain
  * advantages over pa_mainloop and suchlike:
  *
- * 1) It uses timer_create() and POSIX real time signals to guarantee
- * optimal high-resolution timing. Starting with Linux 2.6.21 hrtimers
- * are available, and since right now only nanosleep() and the POSIX
- * clock and timer interfaces have been ported to hrtimers (and not
- * ppoll/pselect!) we have to combine ppoll() with timer_create(). The
- * fact that POSIX timers and POSIX rt signals are used internally is
- * completely hidden.
+ * 1) High resolution timers are used
  *
  * 2) It allows raw access to the pollfd data to users
  *
@@ -53,7 +47,7 @@ typedef struct pa_rtpoll pa_rtpoll;
 typedef struct pa_rtpoll_item pa_rtpoll_item;
 
 typedef enum pa_rtpoll_priority {
-    PA_RTPOLL_EARLY  = -100,          /* For veeery important stuff, like handling control messages */
+    PA_RTPOLL_EARLY  = -100,          /* For very important stuff, like handling control messages */
     PA_RTPOLL_NORMAL = 0,             /* For normal stuff */
     PA_RTPOLL_LATE   = +100,          /* For housekeeping */
     PA_RTPOLL_NEVER  = INT_MAX,       /* For stuff that doesn't register any callbacks, but only fds to listen on */
@@ -88,13 +82,12 @@ 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
- * iteraton of the loop will start immediately. */
+ * 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));
 
 /* 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 iteraton of the loop will start
- * immediately.. */
+ * 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));
 
 /* Set the callback that shall be called immediately after having
index a26dc87..bda5a5e 100644 (file)
 #include <config.h>
 #endif
 
-#include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <errno.h>
+#include <math.h>
 
 #include <pulse/timeval.h>
 
@@ -37,9 +37,9 @@
 #include <pulsecore/macro.h>
 #include <pulsecore/g711.h>
 #include <pulsecore/core-util.h>
+#include <pulsecore/endianmacros.h>
 
 #include "sample-util.h"
-#include "endianmacros.h"
 
 #define PA_SILENCE_MAX (PA_PAGE_SIZE*16)
 
@@ -103,667 +103,6 @@ void* pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) {
     return p;
 }
 
-#define VOLUME_PADDING 32
-
-static void calc_linear_integer_volume(int32_t linear[], const pa_cvolume *volume) {
-    unsigned channel, nchannels, padding;
-
-    pa_assert(linear);
-    pa_assert(volume);
-
-    nchannels = volume->channels;
-
-    for (channel = 0; channel < nchannels; channel++)
-        linear[channel] = (int32_t) lrint(pa_sw_volume_to_linear(volume->values[channel]) * 0x10000);
-
-    for (padding = 0; padding < VOLUME_PADDING; padding++, channel++)
-        linear[channel] = linear[padding];
-}
-
-static void calc_linear_float_volume(float linear[], const pa_cvolume *volume) {
-    unsigned channel, nchannels, padding;
-
-    pa_assert(linear);
-    pa_assert(volume);
-
-    nchannels = volume->channels;
-
-    for (channel = 0; channel < nchannels; channel++)
-        linear[channel] = (float) pa_sw_volume_to_linear(volume->values[channel]);
-
-    for (padding = 0; padding < VOLUME_PADDING; padding++, channel++)
-        linear[channel] = linear[padding];
-}
-
-static void calc_linear_integer_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec) {
-    unsigned k, channel;
-    float linear[PA_CHANNELS_MAX + VOLUME_PADDING];
-
-    pa_assert(streams);
-    pa_assert(spec);
-    pa_assert(volume);
-
-    calc_linear_float_volume(linear, volume);
-
-    for (k = 0; k < nstreams; k++) {
-
-        for (channel = 0; channel < spec->channels; channel++) {
-            pa_mix_info *m = streams + k;
-            m->linear[channel].i = (int32_t) lrint(pa_sw_volume_to_linear(m->volume.values[channel]) * linear[channel] * 0x10000);
-        }
-    }
-}
-
-static void calc_linear_float_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec) {
-    unsigned k, channel;
-    float linear[PA_CHANNELS_MAX + VOLUME_PADDING];
-
-    pa_assert(streams);
-    pa_assert(spec);
-    pa_assert(volume);
-
-    calc_linear_float_volume(linear, volume);
-
-    for (k = 0; k < nstreams; k++) {
-
-        for (channel = 0; channel < spec->channels; channel++) {
-            pa_mix_info *m = streams + k;
-            m->linear[channel].f = (float) (pa_sw_volume_to_linear(m->volume.values[channel]) * linear[channel]);
-        }
-    }
-}
-
-size_t pa_mix(
-        pa_mix_info streams[],
-        unsigned nstreams,
-        void *data,
-        size_t length,
-        const pa_sample_spec *spec,
-        const pa_cvolume *volume,
-        pa_bool_t mute) {
-
-    pa_cvolume full_volume;
-    unsigned k;
-    unsigned z;
-    void *end;
-
-    pa_assert(streams);
-    pa_assert(data);
-    pa_assert(length);
-    pa_assert(spec);
-
-    if (!volume)
-        volume = pa_cvolume_reset(&full_volume, spec->channels);
-
-    if (mute || pa_cvolume_is_muted(volume) || nstreams <= 0) {
-        pa_silence_memory(data, length, spec);
-        return length;
-    }
-
-    for (k = 0; k < nstreams; k++)
-        streams[k].ptr = (uint8_t*) pa_memblock_acquire(streams[k].chunk.memblock) + streams[k].chunk.index;
-
-    for (z = 0; z < nstreams; z++)
-        if (length > streams[z].chunk.length)
-            length = streams[z].chunk.length;
-
-    end = (uint8_t*) data + length;
-
-    switch (spec->format) {
-
-        case PA_SAMPLE_S16NE:{
-            unsigned channel = 0;
-
-            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
-
-            while (data < end) {
-                int32_t sum = 0;
-                unsigned i;
-
-                for (i = 0; i < nstreams; i++) {
-                    pa_mix_info *m = streams + i;
-                    int32_t v, lo, hi, cv = m->linear[channel].i;
-
-                    if (PA_UNLIKELY(cv <= 0))
-                        continue;
-
-                    /* Multiplying the 32bit volume factor with the
-                     * 16bit sample might result in an 48bit value. We
-                     * want to do without 64 bit integers and hence do
-                     * the multiplication independantly for the HI and
-                     * LO part of the volume. */
-
-                    hi = cv >> 16;
-                    lo = cv & 0xFFFF;
-
-                    v = *((int16_t*) m->ptr);
-                    v = ((v * lo) >> 16) + (v * hi);
-                    sum += v;
-
-                    m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
-                }
-
-                sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
-                *((int16_t*) data) = (int16_t) sum;
-
-                data = (uint8_t*) data + sizeof(int16_t);
-
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-
-            break;
-        }
-
-        case PA_SAMPLE_S16RE:{
-            unsigned channel = 0;
-
-            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
-
-            while (data < end) {
-                int32_t sum = 0;
-                unsigned i;
-
-                for (i = 0; i < nstreams; i++) {
-                    pa_mix_info *m = streams + i;
-                    int32_t v, lo, hi, cv = m->linear[channel].i;
-
-                    if (PA_UNLIKELY(cv <= 0))
-                        continue;
-
-                    hi = cv >> 16;
-                    lo = cv & 0xFFFF;
-
-                    v = PA_INT16_SWAP(*((int16_t*) m->ptr));
-                    v = ((v * lo) >> 16) + (v * hi);
-                    sum += v;
-
-                    m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
-                }
-
-                sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
-                *((int16_t*) data) = PA_INT16_SWAP((int16_t) sum);
-
-                data = (uint8_t*) data + sizeof(int16_t);
-
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-
-            break;
-        }
-
-        case PA_SAMPLE_S32NE:{
-            unsigned channel = 0;
-
-            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
-
-            while (data < end) {
-                int64_t sum = 0;
-                unsigned i;
-
-                for (i = 0; i < nstreams; i++) {
-                    pa_mix_info *m = streams + i;
-                    int32_t cv = m->linear[channel].i;
-                    int64_t v;
-
-                    if (PA_UNLIKELY(cv <= 0))
-                        continue;
-
-                    v = *((int32_t*) m->ptr);
-                    v = (v * cv) >> 16;
-                    sum += v;
-
-                    m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
-                }
-
-                sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
-                *((int32_t*) data) = (int32_t) sum;
-
-                data = (uint8_t*) data + sizeof(int32_t);
-
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-
-            break;
-        }
-
-        case PA_SAMPLE_S32RE:{
-            unsigned channel = 0;
-
-            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
-
-            while (data < end) {
-                int64_t sum = 0;
-                unsigned i;
-
-                for (i = 0; i < nstreams; i++) {
-                    pa_mix_info *m = streams + i;
-                    int32_t cv = m->linear[channel].i;
-                    int64_t v;
-
-                    if (PA_UNLIKELY(cv <= 0))
-                        continue;
-
-                    v = PA_INT32_SWAP(*((int32_t*) m->ptr));
-                    v = (v * cv) >> 16;
-                    sum += v;
-
-                    m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
-                }
-
-                sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
-                *((int32_t*) data) = PA_INT32_SWAP((int32_t) sum);
-
-                data = (uint8_t*) data + sizeof(int32_t);
-
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-
-            break;
-        }
-
-        case PA_SAMPLE_S24NE: {
-            unsigned channel = 0;
-
-            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
-
-            while (data < end) {
-                int64_t sum = 0;
-                unsigned i;
-
-                for (i = 0; i < nstreams; i++) {
-                    pa_mix_info *m = streams + i;
-                    int32_t cv = m->linear[channel].i;
-                    int64_t v;
-
-                    if (PA_UNLIKELY(cv <= 0))
-                        continue;
-
-                    v = (int32_t) (PA_READ24NE(m->ptr) << 8);
-                    v = (v * cv) >> 16;
-                    sum += v;
-
-                    m->ptr = (uint8_t*) m->ptr + 3;
-                }
-
-                sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
-                PA_WRITE24NE(data, ((uint32_t) sum) >> 8);
-
-                data = (uint8_t*) data + 3;
-
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-
-            break;
-        }
-
-        case PA_SAMPLE_S24RE: {
-            unsigned channel = 0;
-
-            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
-
-            while (data < end) {
-                int64_t sum = 0;
-                unsigned i;
-
-                for (i = 0; i < nstreams; i++) {
-                    pa_mix_info *m = streams + i;
-                    int32_t cv = m->linear[channel].i;
-                    int64_t v;
-
-                    if (PA_UNLIKELY(cv <= 0))
-                        continue;
-
-                    v = (int32_t) (PA_READ24RE(m->ptr) << 8);
-                    v = (v * cv) >> 16;
-                    sum += v;
-
-                    m->ptr = (uint8_t*) m->ptr + 3;
-                }
-
-                sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
-                PA_WRITE24RE(data, ((uint32_t) sum) >> 8);
-
-                data = (uint8_t*) data + 3;
-
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-
-            break;
-        }
-
-        case PA_SAMPLE_S24_32NE: {
-            unsigned channel = 0;
-
-            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
-
-            while (data < end) {
-                int64_t sum = 0;
-                unsigned i;
-
-                for (i = 0; i < nstreams; i++) {
-                    pa_mix_info *m = streams + i;
-                    int32_t cv = m->linear[channel].i;
-                    int64_t v;
-
-                    if (PA_UNLIKELY(cv <= 0))
-                        continue;
-
-                    v = (int32_t) (*((uint32_t*)m->ptr) << 8);
-                    v = (v * cv) >> 16;
-                    sum += v;
-
-                    m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
-                }
-
-                sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
-                *((uint32_t*) data) = ((uint32_t) (int32_t) sum) >> 8;
-
-                data = (uint8_t*) data + sizeof(uint32_t);
-
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-
-            break;
-        }
-
-        case PA_SAMPLE_S24_32RE: {
-            unsigned channel = 0;
-
-            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
-
-            while (data < end) {
-                int64_t sum = 0;
-                unsigned i;
-
-                for (i = 0; i < nstreams; i++) {
-                    pa_mix_info *m = streams + i;
-                    int32_t cv = m->linear[channel].i;
-                    int64_t v;
-
-                    if (PA_UNLIKELY(cv <= 0))
-                        continue;
-
-                    v = (int32_t) (PA_UINT32_SWAP(*((uint32_t*) m->ptr)) << 8);
-                    v = (v * cv) >> 16;
-                    sum += v;
-
-                    m->ptr = (uint8_t*) m->ptr + 3;
-                }
-
-                sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
-                *((uint32_t*) data) = PA_INT32_SWAP(((uint32_t) (int32_t) sum) >> 8);
-
-                data = (uint8_t*) data + sizeof(uint32_t);
-
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-
-            break;
-        }
-
-        case PA_SAMPLE_U8: {
-            unsigned channel = 0;
-
-            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
-
-            while (data < end) {
-                int32_t sum = 0;
-                unsigned i;
-
-                for (i = 0; i < nstreams; i++) {
-                    pa_mix_info *m = streams + i;
-                    int32_t v, cv = m->linear[channel].i;
-
-                    if (PA_UNLIKELY(cv <= 0))
-                        continue;
-
-                    v = (int32_t) *((uint8_t*) m->ptr) - 0x80;
-                    v = (v * cv) >> 16;
-                    sum += v;
-
-                    m->ptr = (uint8_t*) m->ptr + 1;
-                }
-
-                sum = PA_CLAMP_UNLIKELY(sum, -0x80, 0x7F);
-                *((uint8_t*) data) = (uint8_t) (sum + 0x80);
-
-                data = (uint8_t*) data + 1;
-
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-
-            break;
-        }
-
-        case PA_SAMPLE_ULAW: {
-            unsigned channel = 0;
-
-            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
-
-            while (data < end) {
-                int32_t sum = 0;
-                unsigned i;
-
-                for (i = 0; i < nstreams; i++) {
-                    pa_mix_info *m = streams + i;
-                    int32_t v, hi, lo, cv = m->linear[channel].i;
-
-                    if (PA_UNLIKELY(cv <= 0))
-                        continue;
-
-                    hi = cv >> 16;
-                    lo = cv & 0xFFFF;
-
-                    v = (int32_t) st_ulaw2linear16(*((uint8_t*) m->ptr));
-                    v = ((v * lo) >> 16) + (v * hi);
-                    sum += v;
-
-                    m->ptr = (uint8_t*) m->ptr + 1;
-                }
-
-                sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
-                *((uint8_t*) data) = (uint8_t) st_14linear2ulaw((int16_t) sum >> 2);
-
-                data = (uint8_t*) data + 1;
-
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-
-            break;
-        }
-
-        case PA_SAMPLE_ALAW: {
-            unsigned channel = 0;
-
-            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
-
-            while (data < end) {
-                int32_t sum = 0;
-                unsigned i;
-
-                for (i = 0; i < nstreams; i++) {
-                    pa_mix_info *m = streams + i;
-                    int32_t v, hi, lo, cv = m->linear[channel].i;
-
-                    if (PA_UNLIKELY(cv <= 0))
-                        continue;
-
-                    hi = cv >> 16;
-                    lo = cv & 0xFFFF;
-
-                    v = (int32_t) st_alaw2linear16(*((uint8_t*) m->ptr));
-                    v = ((v * lo) >> 16) + (v * hi);
-                    sum += v;
-
-                    m->ptr = (uint8_t*) m->ptr + 1;
-                }
-
-                sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
-                *((uint8_t*) data) = (uint8_t) st_13linear2alaw((int16_t) sum >> 3);
-
-                data = (uint8_t*) data + 1;
-
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-
-            break;
-        }
-
-        case PA_SAMPLE_FLOAT32NE: {
-            unsigned channel = 0;
-
-            calc_linear_float_stream_volumes(streams, nstreams, volume, spec);
-
-            while (data < end) {
-                float sum = 0;
-                unsigned i;
-
-                for (i = 0; i < nstreams; i++) {
-                    pa_mix_info *m = streams + i;
-                    float v, cv = m->linear[channel].f;
-
-                    if (PA_UNLIKELY(cv <= 0))
-                        continue;
-
-                    v = *((float*) m->ptr);
-                    v *= cv;
-                    sum += v;
-
-                    m->ptr = (uint8_t*) m->ptr + sizeof(float);
-                }
-
-                *((float*) data) = sum;
-
-                data = (uint8_t*) data + sizeof(float);
-
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-
-            break;
-        }
-
-        case PA_SAMPLE_FLOAT32RE: {
-            unsigned channel = 0;
-
-            calc_linear_float_stream_volumes(streams, nstreams, volume, spec);
-
-            while (data < end) {
-                float sum = 0;
-                unsigned i;
-
-                for (i = 0; i < nstreams; i++) {
-                    pa_mix_info *m = streams + i;
-                    float v, cv = m->linear[channel].f;
-
-                    if (PA_UNLIKELY(cv <= 0))
-                        continue;
-
-                    v = PA_FLOAT32_SWAP(*(float*) m->ptr);
-                    v *= cv;
-                    sum += v;
-
-                    m->ptr = (uint8_t*) m->ptr + sizeof(float);
-                }
-
-                *((float*) data) = PA_FLOAT32_SWAP(sum);
-
-                data = (uint8_t*) data + sizeof(float);
-
-                if (PA_UNLIKELY(++channel >= spec->channels))
-                    channel = 0;
-            }
-
-            break;
-        }
-
-        default:
-            pa_log_error("Unable to mix audio data of format %s.", pa_sample_format_to_string(spec->format));
-            pa_assert_not_reached();
-    }
-
-    for (k = 0; k < nstreams; k++)
-        pa_memblock_release(streams[k].chunk.memblock);
-
-    return length;
-}
-
-typedef union {
-  float f;
-  uint32_t i;
-} volume_val;
-
-typedef void (*pa_calc_volume_func_t) (void *volumes, const pa_cvolume *volume);
-
-static const pa_calc_volume_func_t calc_volume_table[] = {
-  [PA_SAMPLE_U8]        = (pa_calc_volume_func_t) calc_linear_integer_volume,
-  [PA_SAMPLE_ALAW]      = (pa_calc_volume_func_t) calc_linear_integer_volume,
-  [PA_SAMPLE_ULAW]      = (pa_calc_volume_func_t) calc_linear_integer_volume,
-  [PA_SAMPLE_S16LE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
-  [PA_SAMPLE_S16BE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
-  [PA_SAMPLE_FLOAT32LE] = (pa_calc_volume_func_t) calc_linear_float_volume,
-  [PA_SAMPLE_FLOAT32BE] = (pa_calc_volume_func_t) calc_linear_float_volume,
-  [PA_SAMPLE_S32LE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
-  [PA_SAMPLE_S32BE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
-  [PA_SAMPLE_S24LE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
-  [PA_SAMPLE_S24BE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
-  [PA_SAMPLE_S24_32LE]  = (pa_calc_volume_func_t) calc_linear_integer_volume,
-  [PA_SAMPLE_S24_32BE]  = (pa_calc_volume_func_t) calc_linear_integer_volume
-};
-
-void pa_volume_memchunk(
-        pa_memchunk*c,
-        const pa_sample_spec *spec,
-        const pa_cvolume *volume) {
-
-    void *ptr;
-    volume_val linear[PA_CHANNELS_MAX + VOLUME_PADDING];
-    pa_do_volume_func_t do_volume;
-
-    pa_assert(c);
-    pa_assert(spec);
-    pa_assert(c->length % pa_frame_size(spec) == 0);
-    pa_assert(volume);
-
-    if (pa_memblock_is_silence(c->memblock))
-        return;
-
-    if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_NORM))
-        return;
-
-    if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_MUTED)) {
-        pa_silence_memchunk(c, spec);
-        return;
-    }
-
-    if (spec->format < 0 || spec->format > PA_SAMPLE_MAX) {
-      pa_log_warn(" Unable to change volume of format %s.", pa_sample_format_to_string(spec->format));
-      return;
-    }
-
-    do_volume = pa_get_volume_func (spec->format);
-    pa_assert(do_volume);
-
-    calc_volume_table[spec->format] ((void *)linear, volume);
-
-    ptr = (uint8_t*) pa_memblock_acquire(c->memblock) + c->index;
-
-    do_volume (ptr, (void *)linear, spec->channels, c->length);
-
-    pa_memblock_release(c->memblock);
-}
-
 size_t pa_frame_align(size_t l, const pa_sample_spec *ss) {
     size_t fs;
 
@@ -1007,7 +346,7 @@ void pa_memchunk_dump_to_file(pa_memchunk *c, const char *fn) {
 
     /* Only for debugging purposes */
 
-    f = fopen(fn, "a");
+    f = pa_fopen_cloexec(fn, "a");
 
     if (!f) {
         pa_log_warn("Failed to open '%s': %s", fn, pa_cstrerror(errno));
index d0235d6..dda1be5 100644 (file)
   USA.
 ***/
 
+#include <inttypes.h>
+#include <limits.h>
+
+#include <pulse/gccmacro.h>
 #include <pulse/sample.h>
 #include <pulse/volume.h>
 #include <pulse/channelmap.h>
+
 #include <pulsecore/memblock.h>
 #include <pulsecore/memchunk.h>
 
@@ -42,34 +47,6 @@ pa_memblock* pa_silence_memblock(pa_memblock *b, const pa_sample_spec *spec);
 
 pa_memchunk* pa_silence_memchunk_get(pa_silence_cache *cache, pa_mempool *pool, pa_memchunk* ret, const pa_sample_spec *spec, size_t length);
 
-typedef struct pa_mix_info {
-    pa_memchunk chunk;
-    pa_cvolume volume;
-    void *userdata;
-
-    /* The following fields are used internally by pa_mix(), should
-     * not be initialised by the caller of pa_mix(). */
-    void *ptr;
-    union {
-        int32_t i;
-        float f;
-    } linear[PA_CHANNELS_MAX];
-} pa_mix_info;
-
-size_t pa_mix(
-    pa_mix_info channels[],
-    unsigned nchannels,
-    void *data,
-    size_t length,
-    const pa_sample_spec *spec,
-    const pa_cvolume *volume,
-    pa_bool_t mute);
-
-void pa_volume_memchunk(
-    pa_memchunk*c,
-    const pa_sample_spec *spec,
-    const pa_cvolume *volume);
-
 size_t pa_frame_align(size_t l, const pa_sample_spec *ss) PA_GCC_PURE;
 
 pa_bool_t pa_frame_aligned(size_t l, const pa_sample_spec *ss) PA_GCC_PURE;
@@ -79,6 +56,23 @@ void pa_deinterleave(const void *src, void *dst[], unsigned channels, size_t ss,
 
 void pa_sample_clamp(pa_sample_format_t format, void *dst, size_t dstr, const void *src, size_t sstr, unsigned n);
 
+static inline int32_t pa_mult_s16_volume(int16_t v, int32_t cv) {
+#if __WORDSIZE == 64 || ((ULONG_MAX) > (UINT_MAX))
+    /* Multiply with 64 bit integers on 64 bit platforms */
+    return (v * (int64_t) cv) >> 16;
+#else
+    /* Multiplying the 32 bit volume factor with the
+     * 16 bit sample might result in an 48 bit value. We
+     * want to do without 64 bit integers and hence do
+     * the multiplication independently for the HI and
+     * LO part of the volume. */
+
+    int32_t hi = cv >> 16;
+    int32_t lo = cv & 0xFFFF;
+    return ((v * lo) >> 16) + (v * hi);
+#endif
+}
+
 pa_usec_t pa_bytes_to_usec_round_up(uint64_t length, const pa_sample_spec *spec);
 size_t pa_usec_to_bytes_round_up(pa_usec_t t, const pa_sample_spec *spec);
 
@@ -86,7 +80,7 @@ void pa_memchunk_dump_to_file(pa_memchunk *c, const char *fn);
 
 void pa_memchunk_sine(pa_memchunk *c, pa_mempool *pool, unsigned rate, unsigned freq);
 
-typedef void (*pa_do_volume_func_t) (void *samples, void *volumes, unsigned channels, unsigned length);
+typedef void (*pa_do_volume_func_t) (void *samples, const void *volumes, unsigned channels, unsigned length);
 
 pa_do_volume_func_t pa_get_volume_func(pa_sample_format_t f);
 void pa_set_volume_func(pa_sample_format_t f, pa_do_volume_func_t func);
index 0fefdf1..45cf972 100644 (file)
 
 #include <inttypes.h>
 #include <stdio.h>
+#include <math.h>
 
 #include <pulsecore/sconv.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/log.h>
-
-#include "endianmacros.h"
+#include <pulsecore/endianmacros.h>
 
 #include "sconv-s16le.h"
 
@@ -86,11 +85,11 @@ void pa_sconv_s16le_to_float32ne(unsigned n, const int16_t *a, float *b) {
 #if SWAP_WORDS == 1
     for (; n > 0; n--) {
         int16_t s = *(a++);
-        *(b++) = ((float) INT16_FROM(s))/(float) 0x7FFF;
+        *(b++) = INT16_FROM(s) * (1.0f / (1 << 15));
     }
 #else
     for (; n > 0; n--)
-        *(b++) = ((float) (*(a++)))/(float) 0x7FFF;
+        *(b++) = *(a++) * (1.0f / (1 << 15));
 #endif
 }
 
@@ -101,11 +100,11 @@ void pa_sconv_s32le_to_float32ne(unsigned n, const int32_t *a, float *b) {
 #if SWAP_WORDS == 1
     for (; n > 0; n--) {
         int32_t s = *(a++);
-        *(b++) = (float) (((double) INT32_FROM(s))/0x7FFFFFFF);
+        *(b++) = INT32_FROM(s) * (1.0f / (1U << 31));
     }
 #else
     for (; n > 0; n--)
-        *(b++) = (float) (((double) (*(a++)))/0x7FFFFFFF);
+        *(b++) = *(a++) * (1.0f / (1U << 31));
 #endif
 }
 
@@ -116,18 +115,16 @@ void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) {
 #if SWAP_WORDS == 1
     for (; n > 0; n--) {
         int16_t s;
-        float v = *(a++);
+        float v = *(a++) * (1 << 15);
 
-        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.f);
-        s = (int16_t) lrintf(v * 0x7FFF);
+        s = (int16_t) PA_CLAMP_UNLIKELY(lrintf(v), -0x8000, 0x7FFF);
         *(b++) = INT16_TO(s);
     }
 #else
     for (; n > 0; n--) {
-        float v = *(a++);
+        float v = *(a++) * (1 << 15);
 
-        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.f);
-        *(b++) = (int16_t) lrintf(v * 0x7FFF);
+        *(b++) = (int16_t) PA_CLAMP_UNLIKELY(lrintf(v), -0x8000, 0x7FFF);
     }
 #endif
 }
@@ -139,18 +136,16 @@ void pa_sconv_s32le_from_float32ne(unsigned n, const float *a, int32_t *b) {
 #if SWAP_WORDS == 1
     for (; n > 0; n--) {
         int32_t s;
-        float v = *(a++);
+        float v = *(a++) * (1U << 31);
 
-        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
-        s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
+        s = (int32_t) PA_CLAMP_UNLIKELY(llrintf(v), -0x80000000LL, 0x7FFFFFFFLL);
         *(b++) = INT32_TO(s);
     }
 #else
     for (; n > 0; n--) {
-        float v = *(a++);
+        float v = *(a++) * (1U << 31);
 
-        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
-        *(b++) = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
+        *(b++) = (int32_t) PA_CLAMP_UNLIKELY(llrintf(v), -0x80000000LL, 0x7FFFFFFFLL);
     }
 #endif
 }
@@ -161,7 +156,7 @@ void pa_sconv_s16le_to_float32re(unsigned n, const int16_t *a, float *b) {
 
     for (; n > 0; n--) {
         int16_t s = *(a++);
-        float k = ((float) INT16_FROM(s))/0x7FFF;
+        float k = INT16_FROM(s) * (1.0f / (1 << 15));
         k = PA_FLOAT32_SWAP(k);
         *(b++) = k;
     }
@@ -173,7 +168,7 @@ void pa_sconv_s32le_to_float32re(unsigned n, const int32_t *a, float *b) {
 
     for (; n > 0; n--) {
         int32_t s = *(a++);
-        float k = (float) (((double) INT32_FROM(s))/0x7FFFFFFF);
+        float k = INT32_FROM(s) * (1.0f / (1U << 31));
         k = PA_FLOAT32_SWAP(k);
         *(b++) = k;
     }
@@ -186,9 +181,8 @@ void pa_sconv_s16le_from_float32re(unsigned n, const float *a, int16_t *b) {
     for (; n > 0; n--) {
         int16_t s;
         float v = *(a++);
-        v = PA_FLOAT32_SWAP(v);
-        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
-        s = (int16_t) lrintf(v * 0x7FFF);
+        v = PA_FLOAT32_SWAP(v) * (1 << 15);
+        s = (int16_t) PA_CLAMP_UNLIKELY(lrintf(v), -0x8000, 0x7FFF);
         *(b++) = INT16_TO(s);
     }
 }
@@ -200,9 +194,8 @@ void pa_sconv_s32le_from_float32re(unsigned n, const float *a, int32_t *b) {
     for (; n > 0; n--) {
         int32_t s;
         float v = *(a++);
-        v = PA_FLOAT32_SWAP(v);
-        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
-        s = (int32_t) lrint((double) v * 0x7FFFFFFF);
+        v = PA_FLOAT32_SWAP(v) * (1U << 31);
+        s = (int32_t) PA_CLAMP_UNLIKELY(llrintf(v), -0x80000000LL, 0x7FFFFFFFLL);
         *(b++) = INT32_TO(s);
     }
 }
@@ -305,9 +298,9 @@ void pa_sconv_s24le_to_float32ne(unsigned n, const uint8_t *a, float *b) {
 
     for (; n > 0; n--) {
         int32_t s = READ24(a) << 8;
-        *b = ((float) s) / 0x7FFFFFFF;
+        *b = s * (1.0f / (1U << 31));
         a += 3;
-        b ++;
+        b++;
     }
 }
 
@@ -317,12 +310,11 @@ void pa_sconv_s24le_from_float32ne(unsigned n, const float *a, uint8_t *b) {
 
     for (; n > 0; n--) {
         int32_t s;
-        float v = *a;
-        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
-        s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
+        float v = *a * (1U << 31);
+        s = (int32_t) PA_CLAMP_UNLIKELY(llrint(v), -0x80000000LL, 0x7FFFFFFFLL);
         WRITE24(b, ((uint32_t) s) >> 8);
         a++;
-        b+=3;
+        b += 3;
     }
 }
 
@@ -332,10 +324,10 @@ void pa_sconv_s24le_to_float32re(unsigned n, const uint8_t *a, float *b) {
 
     for (; n > 0; n--) {
         int32_t s = READ24(a) << 8;
-        float k = ((float) s) / 0x7FFFFFFF;
+        float k = s * (1.0f / (1U << 31));
         *b = PA_FLOAT32_SWAP(k);
         a += 3;
-        b ++;
+        b++;
     }
 }
 
@@ -346,9 +338,8 @@ void pa_sconv_s24le_from_float32re(unsigned n, const float *a, uint8_t *b) {
     for (; n > 0; n--) {
         int32_t s;
         float v = *a;
-        v = PA_FLOAT32_SWAP(v);
-        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
-        s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
+        v = PA_FLOAT32_SWAP(v) * (1U << 31);
+        s = (int32_t) PA_CLAMP_UNLIKELY(llrint(v), -0x80000000LL, 0x7FFFFFFFLL);
         WRITE24(b, ((uint32_t) s) >> 8);
         a++;
         b+=3;
@@ -407,9 +398,9 @@ void pa_sconv_s24_32le_to_float32ne(unsigned n, const uint32_t *a, float *b) {
 
     for (; n > 0; n--) {
         int32_t s = (int32_t) (UINT32_FROM(*a) << 8);
-        *b = (float) s / (float) 0x7FFFFFFF;
-        a ++;
-        b ++;
+        *b = s * (1.0f / (1U << 31));
+        a++;
+        b++;
     }
 }
 
@@ -419,10 +410,10 @@ void pa_sconv_s24_32le_to_float32re(unsigned n, const uint32_t *a, float *b) {
 
     for (; n > 0; n--) {
         int32_t s = (int32_t) (UINT32_FROM(*a) << 8);
-        float k = (float) s / (float) 0x7FFFFFFF;
+        float k = s * (1.0f / (1U << 31));
         *b = PA_FLOAT32_SWAP(k);
-        a ++;
-        b ++;
+        a++;
+        b++;
     }
 }
 
@@ -432,9 +423,8 @@ void pa_sconv_s24_32le_from_float32ne(unsigned n, const float *a, uint32_t *b) {
 
     for (; n > 0; n--) {
         int32_t s;
-        float v = *a;
-        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
-        s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
+        float v = *a * (1U << 31);
+        s = (int32_t) PA_CLAMP_UNLIKELY(llrint(v), -0x80000000LL, 0x7FFFFFFFLL);
         *b = UINT32_TO(((uint32_t) s) >> 8);
         a++;
         b++;
@@ -448,9 +438,8 @@ void pa_sconv_s24_32le_from_float32re(unsigned n, const float *a, uint32_t *b) {
     for (; n > 0; n--) {
         int32_t s;
         float v = *a;
-        v = PA_FLOAT32_SWAP(v);
-        v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
-        s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
+        v = PA_FLOAT32_SWAP(v) * (1U << 31);
+        s = (int32_t) PA_CLAMP_UNLIKELY(llrint(v), -0x80000000LL, 0x7FFFFFFFLL);
         *b = UINT32_TO(((uint32_t) s) >> 8);
         a++;
         b++;
index 301f08b..fbefc97 100644 (file)
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <math.h>
 
 #include <pulsecore/g711.h>
 #include <pulsecore/macro.h>
+#include <pulsecore/endianmacros.h>
 
-#include "endianmacros.h"
-#include "sconv-s16le.h"
-#include "sconv-s16be.h"
+#include <pulsecore/sconv-s16le.h>
+#include <pulsecore/sconv-s16be.h>
 
 #include "sconv.h"
 
@@ -83,6 +84,16 @@ static void float32ne_to_float32ne(unsigned n, const float *a, float *b) {
     memcpy(b, a, (int) (sizeof(float) * n));
 }
 
+#ifdef __TIZEN__
+static void u8_to_s24_32le(unsigned n, const uint8_t *a, int32_t *b) {
+    pa_assert(a);
+    pa_assert(b);
+
+    for (; n > 0; n--, a++, b++)
+        *b = (((int32_t)*a) - 128) << 8;
+}
+#endif
+
 static void float32re_to_float32ne(unsigned n, const float *a, float *b) {
     pa_assert(a);
     pa_assert(b);
@@ -311,3 +322,38 @@ void pa_set_convert_from_s16ne_function(pa_sample_format_t f, pa_convert_func_t
 
     from_s16ne_table[f] = func;
 }
+
+#ifdef __TIZEN__
+static pa_convert_func_t to_s24_32le_table[] = {
+    [PA_SAMPLE_U8]        = (pa_convert_func_t) u8_to_s24_32le,
+    [PA_SAMPLE_S16NE]     = (pa_convert_func_t) pa_sconv_s24_32le_from_s16ne,
+    [PA_SAMPLE_S16RE]     = (pa_convert_func_t) pa_sconv_s24_32le_from_s16re,
+     /** TODO: In future conversion function will be added based on requirement*/
+    [PA_SAMPLE_FLOAT32BE] = (pa_convert_func_t) NULL, //pa_sconv_float32be_to_s24_32le,
+    [PA_SAMPLE_FLOAT32LE] = (pa_convert_func_t) NULL, //pa_sconv_float32le_to_s24_32le,
+    [PA_SAMPLE_S32BE]     = (pa_convert_func_t) NULL, //pa_sconv_s32be_to_s24_32le,
+    [PA_SAMPLE_S32LE]     = (pa_convert_func_t) NULL, //pa_sconv_s32le_to_s24_32le,
+    [PA_SAMPLE_S24BE]     = (pa_convert_func_t) NULL, //pa_sconv_s24be_to_s24_32le,
+    [PA_SAMPLE_S24LE]     = (pa_convert_func_t) NULL, //pa_sconv_s24le_to_s24_32le,
+    [PA_SAMPLE_S24_32BE]  = (pa_convert_func_t) NULL, //pa_sconv_s24_32be_to_s24_32le,
+    [PA_SAMPLE_S24_32LE]  = (pa_convert_func_t) NULL, //pa_sconv_s24_32le_to_s24_32le,
+    [PA_SAMPLE_ALAW]      = (pa_convert_func_t) NULL, //alaw_to_s24_32le,
+    [PA_SAMPLE_ULAW]      = (pa_convert_func_t) NULL, //ulaw_to_s24_32le
+};
+
+pa_convert_func_t pa_get_convert_to_s24_32le_function(pa_sample_format_t f) {
+
+    pa_assert(f >= 0);
+    pa_assert(f < PA_SAMPLE_MAX);
+
+    return to_s24_32le_table[f];
+}
+
+void pa_set_convert_to_s24_32le_function(pa_sample_format_t f, pa_convert_func_t func) {
+
+    pa_assert(f >= 0);
+    pa_assert(f < PA_SAMPLE_MAX);
+
+    to_s24_32le_table[f] = func;
+}
+#endif
index cd93755..c41f7b6 100644 (file)
@@ -23,6 +23,7 @@
   USA.
 ***/
 
+#include <pulse/gccmacro.h>
 #include <pulse/sample.h>
 
 typedef void (*pa_convert_func_t)(unsigned n, const void *a, void *b);
@@ -33,6 +34,12 @@ pa_convert_func_t pa_get_convert_from_float32ne_function(pa_sample_format_t f) P
 pa_convert_func_t pa_get_convert_to_s16ne_function(pa_sample_format_t f) PA_GCC_PURE;
 pa_convert_func_t pa_get_convert_from_s16ne_function(pa_sample_format_t f) PA_GCC_PURE;
 
+#ifdef __TIZEN__
+pa_convert_func_t pa_get_convert_to_s24_32le_function(pa_sample_format_t f) PA_GCC_PURE;
+
+void pa_set_convert_to_s24_32le_function(pa_sample_format_t f, pa_convert_func_t func);
+#endif
+
 void pa_set_convert_to_float32ne_function(pa_sample_format_t f, pa_convert_func_t func);
 void pa_set_convert_from_float32ne_function(pa_sample_format_t f, pa_convert_func_t func);
 
diff --git a/src/pulsecore/sconv_neon.c b/src/pulsecore/sconv_neon.c
new file mode 100644 (file)
index 0000000..ddcdcc2
--- /dev/null
@@ -0,0 +1,101 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2012 Peter Meerwald <p.meerwald@bct-electronic.com>
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.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.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/rtclock.h>
+
+#include <pulsecore/macro.h>
+#include <pulsecore/endianmacros.h>
+
+#include "cpu-arm.h"
+#include "sconv.h"
+
+#include <math.h>
+#include <arm_neon.h>
+
+static void pa_sconv_s16le_from_f32ne_neon(unsigned n, const float *src, int16_t *dst) {
+    unsigned i = n & 3;
+
+    __asm__ __volatile__ (
+        "movs       %[n], %[n], lsr #2      \n\t"
+        "beq        2f                      \n\t"
+
+        "vdup.f32   q1, %[scale]            \n\t"
+
+        "1:                                 \n\t"
+        "vld1.32    {q0}, [%[src]]!         \n\t"
+        "vmul.f32   q0, q0, q1              \n\t" /* scale */
+        "vcvt.s32.f32 q0, q0, #16           \n\t" /* s32<-f32 as 16:16 fixed-point */
+        "vqrshrn.s32 d0, q0, #16            \n\t" /* shift, round, narrow */
+        "subs       %[n], %[n], #1          \n\t"
+        "vst1.16    {d0}, [%[dst]]!         \n\t"
+        "bgt        1b                      \n\t"
+
+        "2:                                 \n\t"
+
+        : [dst] "+r" (dst), [src] "+r" (src), [n] "+r" (n) /* output operands (or input operands that get modified) */
+        : [scale] "r" (32768.0f) /* input operands */
+        : "memory", "cc", "q0", "q1" /* clobber list */
+    );
+
+    /* leftovers */
+    while (i--) {
+        *dst++ = (int16_t) PA_CLAMP_UNLIKELY(lrintf(*src * (1 << 15)), -0x8000, 0x7FFF);
+        src++;
+    }
+}
+
+static void pa_sconv_s16le_to_f32ne_neon(unsigned n, const int16_t *src, float *dst) {
+    unsigned i = n & 3;
+
+    const float invscale = 1.0f / (1 << 15);
+
+    __asm__ __volatile__ (
+        "movs        %[n], %[n], lsr #2     \n\t"
+        "beq        2f                      \n\t"
+
+        "vdup.f32   q1, %[invscale]         \n\t"
+
+        "1:                                 \n\t"
+        "vld1.16    {d0}, [%[src]]!         \n\t"
+        "vmovl.s16  q0, d0                  \n\t" /* widen */
+        "vcvt.f32.s32 q0, q0                \n\t" /* f32<-s32 */
+        "vmul.f32   q0, q0, q1              \n\t"
+        "subs       %[n], %[n], #1          \n\t"
+        "vst1.32    {q0}, [%[dst]]!         \n\t"
+        "bgt        1b                      \n\t"
+
+        "2:                                 \n\t"
+
+        : [dst] "+r" (dst), [src] "+r" (src), [n] "+r" (n) /* output operands (or input operands that get modified) */
+        : [invscale] "r" (invscale) /* input operands */
+        : "memory", "cc", "q0", "q1" /* clobber list */
+    );
+
+    /* leftovers */
+    while (i--) {
+        *dst++ = *src++ * invscale;
+    }
+}
+
+void pa_convert_func_init_neon(pa_cpu_arm_flag_t flags) {
+    pa_log_info("Initialising ARM NEON optimized conversions.");
+    pa_set_convert_from_float32ne_function(PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_neon);
+    pa_set_convert_to_float32ne_function(PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_to_f32ne_neon);
+}
index 3737af2..2f84f5a 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 
-#include <pulsecore/g711.h>
 #include <pulsecore/macro.h>
-
-#include "endianmacros.h"
+#include <pulsecore/endianmacros.h>
 
 #include "cpu-x86.h"
 #include "sconv.h"
 
-#if defined (__i386__) || defined (__amd64__)
+#if !defined(__APPLE__) && defined (__i386__) || defined (__amd64__)
 
-static const PA_DECLARE_ALIGNED (16, float, one[4]) = { 1.0, 1.0, 1.0, 1.0 };
-static const PA_DECLARE_ALIGNED (16, float, mone[4]) = { -1.0, -1.0, -1.0, -1.0 };
-static const PA_DECLARE_ALIGNED (16, float, scale[4]) = { 0x7fff, 0x7fff, 0x7fff, 0x7fff };
+static const PA_DECLARE_ALIGNED (16, float, scale[4]) = { 0x8000, 0x8000, 0x8000, 0x8000 };
 
 static void pa_sconv_s16le_from_f32ne_sse(unsigned n, const float *a, int16_t *b) {
     pa_reg_x86 temp, i;
 
     __asm__ __volatile__ (
         " movaps %5, %%xmm5             \n\t"
-        " movaps %6, %%xmm6             \n\t"
-        " movaps %7, %%xmm7             \n\t"
         " xor %0, %0                    \n\t"
 
         " mov %4, %1                    \n\t"
@@ -56,14 +50,10 @@ static void pa_sconv_s16le_from_f32ne_sse(unsigned n, const float *a, int16_t *b
         " je 2f                         \n\t"
 
         "1:                             \n\t"
-        " movups (%2, %0, 2), %%xmm0    \n\t" /* read 8 floats */
-        " movups 16(%2, %0, 2), %%xmm2  \n\t"
-        " minps  %%xmm5, %%xmm0         \n\t" /* clamp to 1.0 */
-        " minps  %%xmm5, %%xmm2         \n\t"
-        " maxps  %%xmm6, %%xmm0         \n\t" /* clamp to -1.0 */
-        " maxps  %%xmm6, %%xmm2         \n\t"
-        " mulps  %%xmm7, %%xmm0         \n\t" /* *= 0x7fff */
-        " mulps  %%xmm7, %%xmm2         \n\t"
+        " movups (%q2, %0, 2), %%xmm0   \n\t" /* read 8 floats */
+        " movups 16(%q2, %0, 2), %%xmm2 \n\t"
+        " mulps  %%xmm5, %%xmm0         \n\t" /* *= 0x8000 */
+        " mulps  %%xmm5, %%xmm2         \n\t"
 
         " cvtps2pi %%xmm0, %%mm0        \n\t" /* low part to int */
         " cvtps2pi %%xmm2, %%mm2        \n\t"
@@ -74,8 +64,8 @@ static void pa_sconv_s16le_from_f32ne_sse(unsigned n, const float *a, int16_t *b
 
         " packssdw %%mm1, %%mm0         \n\t" /* pack parts */
         " packssdw %%mm3, %%mm2         \n\t"
-        " movq     %%mm0, (%3, %0)      \n\t"
-        " movq    %%mm2, 8(%3, %0)     \n\t"
+        " movq     %%mm0, (%q3, %0)     \n\t"
+        " movq     %%mm2, 8(%q3, %0)    \n\t"
 
         " add $16, %0                   \n\t"
         " dec %1                        \n\t"
@@ -84,24 +74,30 @@ static void pa_sconv_s16le_from_f32ne_sse(unsigned n, const float *a, int16_t *b
         "2:                             \n\t"
         " mov %4, %1                    \n\t" /* prepare for leftovers */
         " and $7, %1                    \n\t"
-        " je 4f                         \n\t"
+        " je 5f                         \n\t"
 
         "3:                             \n\t"
-        " movss (%2, %0, 2), %%xmm0     \n\t"
-        " minss  %%xmm5, %%xmm0         \n\t"
-        " maxss  %%xmm6, %%xmm0         \n\t"
-        " mulss  %%xmm7, %%xmm0         \n\t"
+        " movss (%q2, %0, 2), %%xmm0    \n\t"
+        " mulss  %%xmm5, %%xmm0         \n\t"
         " cvtss2si %%xmm0, %4           \n\t"
-        " movw  %w4, (%3, %0)           \n\t"
+        " add $0x8000, %4               \n\t" /* check for saturation */
+        " and $~0xffff, %4              \n\t"
+        " cvtss2si %%xmm0, %4           \n\t"
+        " je 4f                         \n\t"
+        " sar $31, %4                   \n\t"
+        " xor $0x7fff, %4               \n\t"
+
+        "4:                             \n\t"
+        " movw  %w4, (%q3, %0)          \n\t" /* store leftover */
         " add $2, %0                    \n\t"
         " dec %1                        \n\t"
         " jne 3b                        \n\t"
 
-        "4:                             \n\t"
+        "5:                             \n\t"
         " emms                          \n\t"
 
         : "=&r" (i), "=&r" (temp)
-        : "r" (a), "r" (b), "r" ((pa_reg_x86)n), "m" (*one), "m" (*mone), "m" (*scale)
+        : "r" (a), "r" (b), "r" ((pa_reg_x86)n), "m" (*scale)
         : "cc", "memory"
     );
 }
@@ -111,8 +107,6 @@ static void pa_sconv_s16le_from_f32ne_sse2(unsigned n, const float *a, int16_t *
 
     __asm__ __volatile__ (
         " movaps %5, %%xmm5             \n\t"
-        " movaps %6, %%xmm6             \n\t"
-        " movaps %7, %%xmm7             \n\t"
         " xor %0, %0                    \n\t"
 
         " mov %4, %1                    \n\t"
@@ -121,20 +115,16 @@ static void pa_sconv_s16le_from_f32ne_sse2(unsigned n, const float *a, int16_t *
         " je 2f                         \n\t"
 
         "1:                             \n\t"
-        " movups (%2, %0, 2), %%xmm0    \n\t" /* read 8 floats */
-        " movups 16(%2, %0, 2), %%xmm2  \n\t"
-        " minps  %%xmm5, %%xmm0         \n\t" /* clamp to 1.0 */
-        " minps  %%xmm5, %%xmm2         \n\t"
-        " maxps  %%xmm6, %%xmm0         \n\t" /* clamp to -1.0 */
-        " maxps  %%xmm6, %%xmm2         \n\t"
-        " mulps  %%xmm7, %%xmm0         \n\t" /* *= 0x7fff */
-        " mulps  %%xmm7, %%xmm2         \n\t"
+        " movups (%q2, %0, 2), %%xmm0   \n\t" /* read 8 floats */
+        " movups 16(%q2, %0, 2), %%xmm2 \n\t"
+        " mulps  %%xmm5, %%xmm0         \n\t" /* *= 0x8000 */
+        " mulps  %%xmm5, %%xmm2         \n\t"
 
         " cvtps2dq %%xmm0, %%xmm0       \n\t"
         " cvtps2dq %%xmm2, %%xmm2       \n\t"
 
         " packssdw %%xmm2, %%xmm0       \n\t"
-        " movdqu   %%xmm0, (%3, %0)     \n\t"
+        " movdqu   %%xmm0, (%q3, %0)    \n\t"
 
         " add $16, %0                   \n\t"
         " dec %1                        \n\t"
@@ -143,92 +133,45 @@ static void pa_sconv_s16le_from_f32ne_sse2(unsigned n, const float *a, int16_t *
         "2:                             \n\t"
         " mov %4, %1                    \n\t" /* prepare for leftovers */
         " and $7, %1                    \n\t"
-        " je 4f                         \n\t"
+        " je 5f                         \n\t"
 
         "3:                             \n\t"
-        " movss (%2, %0, 2), %%xmm0     \n\t"
-        " minss  %%xmm5, %%xmm0         \n\t"
-        " maxss  %%xmm6, %%xmm0         \n\t"
-        " mulss  %%xmm7, %%xmm0         \n\t"
+        " movss (%q2, %0, 2), %%xmm0    \n\t"
+        " mulss  %%xmm5, %%xmm0         \n\t"
         " cvtss2si %%xmm0, %4           \n\t"
-        " movw  %w4, (%3, %0)           \n\t"
+        " add $0x8000, %4               \n\t"
+        " and $~0xffff, %4              \n\t" /* check for saturation */
+        " cvtss2si %%xmm0, %4           \n\t"
+        " je 4f                         \n\t"
+        " sar $31, %4                   \n\t"
+        " xor $0x7fff, %4               \n\t"
+
+        "4:                             \n\t"
+        " movw  %w4, (%q3, %0)          \n\t" /* store leftover */
         " add $2, %0                    \n\t"
         " dec %1                        \n\t"
         " jne 3b                        \n\t"
 
-        "4:                             \n\t"
+        "5:                             \n\t"
 
         : "=&r" (i), "=&r" (temp)
-        : "r" (a), "r" (b), "r" ((pa_reg_x86)n), "m" (*one), "m" (*mone), "m" (*scale)
+        : "r" (a), "r" (b), "r" ((pa_reg_x86)n), "m" (*scale)
         : "cc", "memory"
     );
 }
 
-#undef RUN_TEST
-
-#ifdef RUN_TEST
-#define SAMPLES 1019
-#define TIMES 1000
-
-static void run_test (void) {
-    int16_t samples[SAMPLES];
-    int16_t samples_ref[SAMPLES];
-    float floats[SAMPLES];
-    int i;
-    pa_usec_t start, stop;
-    pa_convert_func_t func;
-
-    printf ("checking SSE %zd\n", sizeof (samples));
-
-    memset (samples_ref, 0, sizeof (samples_ref));
-    memset (samples, 0, sizeof (samples));
-
-    for (i = 0; i < SAMPLES; i++) {
-        floats[i] = (rand()/(RAND_MAX+2.2)) - 1.1;
-    }
-
-    func = pa_get_convert_from_float32ne_function (PA_SAMPLE_S16LE);
-    func (SAMPLES, floats, samples_ref);
-    pa_sconv_s16le_from_f32ne_sse2 (SAMPLES, floats, samples);
-
-    for (i = 0; i < SAMPLES; i++) {
-        if (samples[i] != samples_ref[i]) {
-            printf ("%d: %04x != %04x (%f)\n", i, samples[i], samples_ref[i],
-                      floats[i]);
-        }
-    }
-
-    start = pa_rtclock_now();
-    for (i = 0; i < TIMES; i++) {
-        pa_sconv_s16le_from_f32ne_sse2 (SAMPLES, floats, samples);
-    }
-    stop = pa_rtclock_now();
-    pa_log_info("SSE: %llu usec.", (long long unsigned int)(stop - start));
-
-    start = pa_rtclock_now();
-    for (i = 0; i < TIMES; i++) {
-        func (SAMPLES, floats, samples_ref);
-    }
-    stop = pa_rtclock_now();
-    pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start));
-}
-#endif
 #endif /* defined (__i386__) || defined (__amd64__) */
 
-
-void pa_convert_func_init_sse (pa_cpu_x86_flag_t flags) {
-#if defined (__i386__) || defined (__amd64__)
-
-#ifdef RUN_TEST
-    run_test ();
-#endif
+void pa_convert_func_init_sse(pa_cpu_x86_flag_t flags) {
+#if !defined(__APPLE__) && defined (__i386__) || defined (__amd64__)
 
     if (flags & PA_CPU_X86_SSE2) {
         pa_log_info("Initialising SSE2 optimized conversions.");
-        pa_set_convert_from_float32ne_function (PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_sse2);
-    } else {
+        pa_set_convert_from_float32ne_function(PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_sse2);
+
+    } else if (flags & PA_CPU_X86_SSE) {
         pa_log_info("Initialising SSE optimized conversions.");
-        pa_set_convert_from_float32ne_function (PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_sse);
+        pa_set_convert_from_float32ne_function(PA_SAMPLE_S16LE, (pa_convert_func_t) pa_sconv_s16le_from_f32ne_sse);
     }
 
 #endif /* defined (__i386__) || defined (__amd64__) */
diff --git a/src/pulsecore/semaphore-osx.c b/src/pulsecore/semaphore-osx.c
new file mode 100644 (file)
index 0000000..835c4cf
--- /dev/null
@@ -0,0 +1,94 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2006 Lennart Poettering
+  Copyright 2013 Albert Zeyer
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <pulse/xmalloc.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/atomic.h>
+#include <pulsecore/core-util.h>
+
+#include "semaphore.h"
+
+/* OSX doesn't support unnamed semaphores (via sem_init).
+ * Thus, we use a counter to give them enumerated names. */
+static pa_atomic_t id_counter = PA_ATOMIC_INIT(0);
+
+struct pa_semaphore {
+    sem_t *sem;
+    int id;
+};
+
+static char *sem_name(char *fn, size_t l, int id) {
+    pa_snprintf(fn, l, "/pulse-sem-%u-%u", getpid(), id);
+    return fn;
+}
+
+pa_semaphore *pa_semaphore_new(unsigned value) {
+    pa_semaphore *s;
+    char fn[32];
+
+    s = pa_xnew(pa_semaphore, 1);
+    s->id = pa_atomic_inc(&id_counter);
+    sem_name(fn, sizeof(fn), s->id);
+    sem_unlink(fn); /* in case an old stale semaphore is left around */
+    pa_assert_se(s->sem = sem_open(fn, O_CREAT|O_EXCL, 0700, value));
+    pa_assert(s->sem != SEM_FAILED);
+    return s;
+}
+
+void pa_semaphore_free(pa_semaphore *s) {
+    char fn[32];
+
+    pa_assert(s);
+
+    pa_assert_se(sem_close(s->sem) == 0);
+    sem_name(fn, sizeof(fn), s->id);
+    pa_assert_se(sem_unlink(fn) == 0);
+    pa_xfree(s);
+}
+
+void pa_semaphore_post(pa_semaphore *s) {
+    pa_assert(s);
+    pa_assert_se(sem_post(s->sem) == 0);
+}
+
+void pa_semaphore_wait(pa_semaphore *s) {
+    int ret;
+
+    pa_assert(s);
+
+    do {
+        ret = sem_wait(s->sem);
+    } while (ret < 0 && errno == EINTR);
+
+    pa_assert(ret == 0);
+}
index 9ffbde6..c2e00c6 100644 (file)
@@ -30,8 +30,7 @@
 
 #include "semaphore.h"
 
-struct pa_semaphore
-{
+struct pa_semaphore {
     HANDLE sema;
 };
 
index edd7b7f..368a6c3 100644 (file)
@@ -24,7 +24,6 @@
 #endif
 
 #include <pulse/xmalloc.h>
-#include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 
 #include "shared.h"
index fbf777a..8aa34fa 100644 (file)
  * /dev/shm. We can use that information to list all blocks and
  * cleanup unused ones */
 #define SHM_PATH "/dev/shm/"
+#define SHM_ID_LEN 10
+#elif defined(__sun)
+#define SHM_PATH "/tmp"
+#define SHM_ID_LEN 15
 #else
 #undef SHM_PATH
+#undef SHM_ID_LEN
 #endif
 
 #define SHM_MARKER ((int) 0xbeefcafe)
@@ -77,7 +82,7 @@
 /* We now put this SHM marker at the end of each segment. It's
  * optional, to not require a reboot when upgrading, though. Note that
  * on multiarch systems 32bit and 64bit processes might access this
- * region simultaneously. The header fields need to be independant
+ * region simultaneously. The header fields need to be independent
  * from the process' word with */
 struct shm_marker {
     pa_atomic_t marker; /* 0xbeefcafe */
@@ -90,18 +95,23 @@ struct shm_marker {
 
 #define SHM_MARKER_SIZE PA_ALIGN(sizeof(struct shm_marker))
 
+#ifdef HAVE_SHM_OPEN
 static char *segment_name(char *fn, size_t l, unsigned id) {
     pa_snprintf(fn, l, "/pulse-shm-%u", id);
     return fn;
 }
+#endif
 
 int pa_shm_create_rw(pa_shm *m, size_t size, pa_bool_t shared, mode_t mode) {
+#ifdef HAVE_SHM_OPEN
     char fn[32];
     int fd = -1;
+#endif
 
     pa_assert(m);
     pa_assert(size > 0);
     pa_assert(size <= MAX_SHM_SIZE);
+    pa_assert(!(mode & ~0777));
     pa_assert(mode >= 0600);
 
     /* Each time we create a new SHM area, let's first drop all stale
@@ -142,7 +152,7 @@ int pa_shm_create_rw(pa_shm *m, size_t size, pa_bool_t shared, mode_t mode) {
         pa_random(&m->id, sizeof(m->id));
         segment_name(fn, sizeof(fn), m->id);
 
-        if ((fd = shm_open(fn, O_RDWR|O_CREAT|O_EXCL, mode & 0444)) < 0) {
+        if ((fd = shm_open(fn, O_RDWR|O_CREAT|O_EXCL, mode)) < 0) {
             pa_log("shm_open() failed: %s", pa_cstrerror(errno));
             goto fail;
         }
@@ -154,7 +164,11 @@ int pa_shm_create_rw(pa_shm *m, size_t size, pa_bool_t shared, mode_t mode) {
             goto fail;
         }
 
-        if ((m->ptr = mmap(NULL, PA_PAGE_ALIGN(m->size), PROT_READ|PROT_WRITE, MAP_SHARED, fd, (off_t) 0)) == MAP_FAILED) {
+#ifndef MAP_NORESERVE
+#define MAP_NORESERVE 0
+#endif
+
+        if ((m->ptr = mmap(NULL, PA_PAGE_ALIGN(m->size), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_NORESERVE, fd, (off_t) 0)) == MAP_FAILED) {
             pa_log("mmap() failed: %s", pa_cstrerror(errno));
             goto fail;
         }
@@ -168,7 +182,7 @@ int pa_shm_create_rw(pa_shm *m, size_t size, pa_bool_t shared, mode_t mode) {
         pa_assert_se(pa_close(fd) == 0);
         m->do_unlink = TRUE;
 #else
-        return -1;
+        goto fail;
 #endif
     }
 
@@ -286,7 +300,7 @@ int pa_shm_attach_ro(pa_shm *m, unsigned id) {
     segment_name(fn, sizeof(fn), m->id = id);
 
     if ((fd = shm_open(fn, O_RDONLY, 0)) < 0) {
-        if (errno != EACCES)
+        if (errno != EACCES && errno != ENOENT)
             pa_log("shm_open() failed: %s", pa_cstrerror(errno));
         goto fail;
     }
@@ -351,10 +365,14 @@ int pa_shm_cleanup(void) {
         char fn[128];
         struct shm_marker *m;
 
-        if (strncmp(de->d_name, "pulse-shm-", 10))
+#if defined(__sun)
+        if (strncmp(de->d_name, ".SHMDpulse-shm-", SHM_ID_LEN))
+#else
+        if (strncmp(de->d_name, "pulse-shm-", SHM_ID_LEN))
+#endif
             continue;
 
-        if (pa_atou(de->d_name + 10, &id) < 0)
+        if (pa_atou(de->d_name + SHM_ID_LEN, &id) < 0)
             continue;
 
         if (pa_shm_attach_ro(&seg, id) < 0)
old mode 100644 (file)
new mode 100755 (executable)
index 7acb25f..68810d5
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
+#ifdef __TIZEN__
+#include <time.h>
+#include "tizen-audio.h"
+#endif
 
 #include <pulse/utf8.h>
 #include <pulse/xmalloc.h>
 #include <pulse/util.h>
+#include <pulse/internal.h>
 
-#include <pulsecore/sample-util.h>
+#include <pulsecore/mix.h>
 #include <pulsecore/core-subscribe.h>
 #include <pulsecore/log.h>
 #include <pulsecore/play-memblockq.h>
 
 #include "sink-input.h"
 
+/* #define SINK_INPUT_DEBUG */
+#define PA_EXT_FADE_INTERVAL_MSEC 20
+
 #define MEMBLOCKQ_MAXLENGTH (32*1024*1024)
 #define CONVERT_BUFFER_LENGTH (PA_PAGE_SIZE)
 
 PA_DEFINE_PUBLIC_CLASS(pa_sink_input, pa_msgobject);
 
+struct volume_factor_entry {
+    char *key;
+    pa_cvolume volume;
+};
+
+#ifdef __TIZEN__
+#define PA_SINK_INPUT_DUMP_PATH_PREFIX      "/tmp/dump_ap_out_stream"
+#endif
+
+static struct volume_factor_entry *volume_factor_entry_new(const char *key, const pa_cvolume *volume) {
+    struct volume_factor_entry *entry;
+
+    pa_assert(key);
+    pa_assert(volume);
+
+    entry = pa_xnew(struct volume_factor_entry, 1);
+    entry->key = pa_xstrdup(key);
+
+    entry->volume = *volume;
+
+    return entry;
+}
+
+static void volume_factor_entry_free(struct volume_factor_entry *volume_entry) {
+    pa_assert(volume_entry);
+
+    pa_xfree(volume_entry->key);
+    pa_xfree(volume_entry);
+}
+
+static void volume_factor_from_hashmap(pa_cvolume *v, pa_hashmap *items, uint8_t channels) {
+    struct volume_factor_entry *entry;
+    void *state = NULL;
+
+    pa_cvolume_reset(v, channels);
+    PA_HASHMAP_FOREACH(entry, items, state)
+        pa_sw_cvolume_multiply(v, v, &entry->volume);
+}
+
 static void sink_input_free(pa_object *o);
 static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v);
 
+static int check_passthrough_connection(pa_bool_t passthrough, pa_sink *dest) {
+    if (pa_sink_is_passthrough(dest)) {
+        pa_log_warn("Sink is already connected to PASSTHROUGH input");
+        return -PA_ERR_BUSY;
+    }
+
+    /* If current input(s) exist, check new input is not PASSTHROUGH */
+    if (pa_idxset_size(dest->inputs) > 0 && passthrough) {
+        pa_log_warn("Sink is already connected, cannot accept new PASSTHROUGH INPUT");
+        return -PA_ERR_BUSY;
+    }
+
+    return PA_OK;
+}
+
 pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data) {
     pa_assert(data);
 
     pa_zero(*data);
     data->resample_method = PA_RESAMPLER_INVALID;
     data->proplist = pa_proplist_new();
+    data->volume_writable = TRUE;
+
+    data->volume_factor_items = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
+    data->volume_factor_sink_items = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
 
     return data;
 }
@@ -73,35 +138,46 @@ void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const
         data->channel_map = *map;
 }
 
+pa_bool_t pa_sink_input_new_data_is_passthrough(pa_sink_input_new_data *data) {
+    pa_assert(data);
+
+    if (PA_LIKELY(data->format) && PA_UNLIKELY(!pa_format_info_is_pcm(data->format)))
+        return TRUE;
+
+    if (PA_UNLIKELY(data->flags & PA_SINK_INPUT_PASSTHROUGH))
+        return TRUE;
+
+    return FALSE;
+}
+
 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) {
     pa_assert(data);
+    pa_assert(data->volume_writable);
 
     if ((data->volume_is_set = !!volume))
         data->volume = *volume;
 }
 
-void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {
+void pa_sink_input_new_data_add_volume_factor(pa_sink_input_new_data *data, const char *key, const pa_cvolume *volume_factor) {
+    struct volume_factor_entry *v;
+
     pa_assert(data);
+    pa_assert(key);
     pa_assert(volume_factor);
 
-    if (data->volume_factor_is_set)
-        pa_sw_cvolume_multiply(&data->volume_factor, &data->volume_factor, volume_factor);
-    else {
-        data->volume_factor_is_set = TRUE;
-        data->volume_factor = *volume_factor;
-    }
+    v = volume_factor_entry_new(key, volume_factor);
+    pa_assert_se(pa_hashmap_put(data->volume_factor_items, v->key, v) >= 0);
 }
 
-void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {
+void pa_sink_input_new_data_add_volume_factor_sink(pa_sink_input_new_data *data, const char *key, const pa_cvolume *volume_factor) {
+    struct volume_factor_entry *v;
+
     pa_assert(data);
+    pa_assert(key);
     pa_assert(volume_factor);
 
-    if (data->volume_factor_sink_is_set)
-        pa_sw_cvolume_multiply(&data->volume_factor_sink, &data->volume_factor_sink, volume_factor);
-    else {
-        data->volume_factor_sink_is_set = TRUE;
-        data->volume_factor_sink = *volume_factor;
-    }
+    v = volume_factor_entry_new(key, volume_factor);
+    pa_assert_se(pa_hashmap_put(data->volume_factor_sink_items, v->key, v) >= 0);
 }
 
 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute) {
@@ -111,9 +187,74 @@ void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mu
     data->muted = !!mute;
 }
 
+pa_bool_t pa_sink_input_new_data_set_sink(pa_sink_input_new_data *data, pa_sink *s, pa_bool_t save) {
+    pa_bool_t ret = TRUE;
+    pa_idxset *formats = NULL;
+
+    pa_assert(data);
+    pa_assert(s);
+
+    if (!data->req_formats) {
+        /* We're not working with the extended API */
+        data->sink = s;
+        data->save_sink = save;
+    } else {
+        /* Extended API: let's see if this sink supports the formats the client can provide */
+        formats = pa_sink_check_formats(s, data->req_formats);
+
+        if (formats && !pa_idxset_isempty(formats)) {
+            /* Sink supports at least one of the requested formats */
+            data->sink = s;
+            data->save_sink = save;
+            if (data->nego_formats)
+                pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free);
+            data->nego_formats = formats;
+        } else {
+            /* Sink doesn't support any of the formats requested by the client */
+            if (formats)
+                pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
+            ret = FALSE;
+        }
+    }
+
+    return ret;
+}
+
+pa_bool_t pa_sink_input_new_data_set_formats(pa_sink_input_new_data *data, pa_idxset *formats) {
+    pa_assert(data);
+    pa_assert(formats);
+
+    if (data->req_formats)
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
+
+    data->req_formats = formats;
+
+    if (data->sink) {
+        /* Trigger format negotiation */
+        return pa_sink_input_new_data_set_sink(data, data->sink, data->save_sink);
+    }
+
+    return TRUE;
+}
+
 void pa_sink_input_new_data_done(pa_sink_input_new_data *data) {
     pa_assert(data);
 
+    if (data->req_formats)
+        pa_idxset_free(data->req_formats, (pa_free_cb_t) pa_format_info_free);
+
+    if (data->nego_formats)
+        pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free);
+
+    if (data->format)
+        pa_format_info_free(data->format);
+
+    if (data->volume_factor_items)
+        pa_hashmap_free(data->volume_factor_items, (pa_free_cb_t) volume_factor_entry_free);
+
+    if (data->volume_factor_sink_items)
+        pa_hashmap_free(data->volume_factor_sink_items, (pa_free_cb_t) volume_factor_entry_free);
+
     pa_proplist_free(data->proplist);
 }
 
@@ -122,6 +263,7 @@ static void reset_callbacks(pa_sink_input *i) {
     pa_assert(i);
 
     i->pop = NULL;
+    i->process_underrun = NULL;
     i->process_rewind = NULL;
     i->update_max_rewind = NULL;
     i->update_max_request = NULL;
@@ -154,6 +296,9 @@ int pa_sink_input_new(
     pa_channel_map original_cm;
     int r;
     char *pt;
+    char *memblockq_name;
+    pa_sample_spec ss;
+    pa_channel_map map;
 
     pa_assert(_i);
     pa_assert(core);
@@ -163,20 +308,59 @@ int pa_sink_input_new(
     if (data->client)
         pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist);
 
+    if (data->origin_sink && (data->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
+        data->volume_writable = FALSE;
+
+    if (!data->req_formats) {
+        /* From this point on, we want to work only with formats, and get back
+         * to using the sample spec and channel map after all decisions w.r.t.
+         * routing are complete. */
+        pa_idxset *tmp = pa_idxset_new(NULL, NULL);
+        pa_format_info *f = pa_format_info_from_sample_spec(&data->sample_spec,
+                data->channel_map_is_set ? &data->channel_map : NULL);
+        pa_idxset_put(tmp, f, NULL);
+        pa_sink_input_new_data_set_formats(data, tmp);
+    }
+
     if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], data)) < 0)
         return r;
 
     pa_return_val_if_fail(!data->driver || pa_utf8_valid(data->driver), -PA_ERR_INVALID);
 
     if (!data->sink) {
-        data->sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK);
-        data->save_sink = FALSE;
+        pa_sink *sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK);
+        pa_return_val_if_fail(sink, -PA_ERR_NOENTITY);
+        pa_sink_input_new_data_set_sink(data, sink, FALSE);
+    }
+    else
+    {
+        pa_sink_input_new_data_set_sink(data, data->sink, FALSE);
     }
 
-    pa_return_val_if_fail(data->sink, -PA_ERR_NOENTITY);
+    /* Routing's done, we have a sink. Now let's fix the format and set up the
+     * sample spec */
+
+    /* If something didn't pick a format for us, pick the top-most format since
+     * we assume this is sorted in priority order */
+    if (!data->format && data->nego_formats && !pa_idxset_isempty(data->nego_formats))
+        data->format = pa_format_info_copy(pa_idxset_first(data->nego_formats, NULL));
+
+    pa_return_val_if_fail(data->format, -PA_ERR_NOTSUPPORTED);
+
+    /* Now populate the sample spec and format according to the final
+     * format that we've negotiated */
+    pa_return_val_if_fail(pa_format_info_to_sample_spec(data->format, &ss, &map) == 0, -PA_ERR_INVALID);
+    pa_sink_input_new_data_set_sample_spec(data, &ss);
+    if (pa_format_info_is_pcm(data->format) && pa_channel_map_valid(&map))
+        pa_sink_input_new_data_set_channel_map(data, &map);
+
     pa_return_val_if_fail(PA_SINK_IS_LINKED(pa_sink_get_state(data->sink)), -PA_ERR_BADSTATE);
     pa_return_val_if_fail(!data->sync_base || (data->sync_base->sink == data->sink && pa_sink_input_get_state(data->sync_base) == PA_SINK_INPUT_CORKED), -PA_ERR_INVALID);
 
+    r = check_passthrough_connection(pa_sink_input_new_data_is_passthrough(data), data->sink);
+    if (r != PA_OK)
+        return r;
+
     if (!data->sample_spec_is_set)
         data->sample_spec = data->sink->sample_spec;
 
@@ -191,43 +375,72 @@ int pa_sink_input_new(
 
     pa_return_val_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec), -PA_ERR_INVALID);
 
+    /* Don't restore (or save) stream volume for passthrough streams and
+     * prevent attenuation/gain */
+    if (pa_sink_input_new_data_is_passthrough(data)) {
+        data->volume_is_set = TRUE;
+        pa_cvolume_reset(&data->volume, data->sample_spec.channels);
+        data->volume_is_absolute = TRUE;
+        data->save_volume = FALSE;
+    }
+
     if (!data->volume_is_set) {
         pa_cvolume_reset(&data->volume, data->sample_spec.channels);
         data->volume_is_absolute = FALSE;
         data->save_volume = FALSE;
     }
 
-    pa_return_val_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec), -PA_ERR_INVALID);
-
-    if (!data->volume_factor_is_set)
-        pa_cvolume_reset(&data->volume_factor, data->sample_spec.channels);
-
-    pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor, &data->sample_spec), -PA_ERR_INVALID);
+    if (!data->volume_writable)
+        data->save_volume = false;
 
-    if (!data->volume_factor_sink_is_set)
-        pa_cvolume_reset(&data->volume_factor_sink, data->sink->sample_spec.channels);
-
-    pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor_sink, &data->sink->sample_spec), -PA_ERR_INVALID);
+    pa_return_val_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec), -PA_ERR_INVALID);
 
     if (!data->muted_is_set)
         data->muted = FALSE;
 
-    if (data->flags & PA_SINK_INPUT_FIX_FORMAT)
+    if (data->flags & PA_SINK_INPUT_FIX_FORMAT) {
+        pa_return_val_if_fail(pa_format_info_is_pcm(data->format), -PA_ERR_INVALID);
         data->sample_spec.format = data->sink->sample_spec.format;
+        pa_format_info_set_sample_format(data->format, data->sample_spec.format);
+    }
 
-    if (data->flags & PA_SINK_INPUT_FIX_RATE)
+    if (data->flags & PA_SINK_INPUT_FIX_RATE) {
+        pa_return_val_if_fail(pa_format_info_is_pcm(data->format), -PA_ERR_INVALID);
         data->sample_spec.rate = data->sink->sample_spec.rate;
+        pa_format_info_set_rate(data->format, data->sample_spec.rate);
+    }
 
     original_cm = data->channel_map;
 
     if (data->flags & PA_SINK_INPUT_FIX_CHANNELS) {
+        pa_return_val_if_fail(pa_format_info_is_pcm(data->format), -PA_ERR_INVALID);
         data->sample_spec.channels = data->sink->sample_spec.channels;
         data->channel_map = data->sink->channel_map;
+        pa_format_info_set_channels(data->format, data->sample_spec.channels);
+        pa_format_info_set_channel_map(data->format, &data->channel_map);
     }
 
     pa_assert(pa_sample_spec_valid(&data->sample_spec));
     pa_assert(pa_channel_map_valid(&data->channel_map));
 
+    if (!(data->flags & PA_SINK_INPUT_VARIABLE_RATE) &&
+        !pa_sample_spec_equal(&data->sample_spec, &data->sink->sample_spec)) {
+        /* try to change sink rate. This is done before the FIXATE hook since
+           module-suspend-on-idle can resume a sink */
+
+        pa_log_debug_verbose("Trying to change sample rate");
+        if (pa_sink_update_rate(data->sink, data->sample_spec.rate, pa_sink_input_new_data_is_passthrough(data)) == TRUE)
+            pa_log_info("Rate changed to %u Hz", data->sink->sample_spec.rate);
+    }
+
+    if (pa_sink_input_new_data_is_passthrough(data) &&
+        !pa_sample_spec_equal(&data->sample_spec, &data->sink->sample_spec)) {
+        /* rate update failed, or other parts of sample spec didn't match */
+
+        pa_log_debug("Could not update sink sample spec to match passthrough stream");
+        return -PA_ERR_NOTSUPPORTED;
+    }
+
     /* Due to the fixing of the sample spec the volume might not match anymore */
     pa_cvolume_remap(&data->volume, &original_cm, &data->channel_map);
 
@@ -254,18 +467,20 @@ int pa_sink_input_new(
         !pa_sample_spec_equal(&data->sample_spec, &data->sink->sample_spec) ||
         !pa_channel_map_equal(&data->channel_map, &data->sink->channel_map)) {
 
-        if (!(resampler = pa_resampler_new(
-                      core->mempool,
-                      &data->sample_spec, &data->channel_map,
-                      &data->sink->sample_spec, &data->sink->channel_map,
-                      data->resample_method,
-                      ((data->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
-                      ((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->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
-            pa_log_warn("Unsupported resampling operation.");
-            return -PA_ERR_NOTSUPPORTED;
-        }
+        /* Note: for passthrough content we need to adjust the output rate to that of the current sink-input */
+        if (!pa_sink_input_new_data_is_passthrough(data)) /* no resampler for passthrough content */
+            if (!(resampler = pa_resampler_new(
+                          core->mempool,
+                          &data->sample_spec, &data->channel_map,
+                          &data->sink->sample_spec, &data->sink->channel_map,
+                          data->resample_method,
+                          ((data->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
+                          ((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->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
+                pa_log_warn("Unsupported resampling operation.");
+                return -PA_ERR_NOTSUPPORTED;
+            }
     }
 
     i = pa_msgobject_new(pa_sink_input);
@@ -279,14 +494,16 @@ int pa_sink_input_new(
     i->driver = pa_xstrdup(pa_path_get_filename(data->driver));
     i->module = data->module;
     i->sink = data->sink;
+    i->origin_sink = data->origin_sink;
     i->client = data->client;
 
     i->requested_resample_method = data->resample_method;
     i->actual_resample_method = resampler ? pa_resampler_get_method(resampler) : PA_RESAMPLER_INVALID;
     i->sample_spec = data->sample_spec;
     i->channel_map = data->channel_map;
+    i->format = pa_format_info_copy(data->format);
 
-    if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !data->volume_is_absolute) {
+    if (!data->volume_is_absolute && pa_sink_flat_volume_enabled(i->sink)) {
         pa_cvolume remapped;
 
         /* When the 'absolute' bool is not set then we'll treat the volume
@@ -297,17 +514,28 @@ int pa_sink_input_new(
     } else
         i->volume = data->volume;
 
-    i->volume_factor = data->volume_factor;
-    i->volume_factor_sink = data->volume_factor_sink;
+    i->volume_factor_items = data->volume_factor_items;
+    data->volume_factor_items = NULL;
+    volume_factor_from_hashmap(&i->volume_factor, i->volume_factor_items, i->sample_spec.channels);
+
+    i->volume_factor_sink_items = data->volume_factor_sink_items;
+    data->volume_factor_sink_items = NULL;
+    volume_factor_from_hashmap(&i->volume_factor_sink, i->volume_factor_sink_items, i->sample_spec.channels);
+
     i->real_ratio = i->reference_ratio = data->volume;
     pa_cvolume_reset(&i->soft_volume, i->sample_spec.channels);
     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->save_muted = data->save_muted;
 
     i->muted = data->muted;
 
+#ifdef PA_EXT_USE_VOLUME_FADING
+    i->fading_queue = pa_queue_new();
+#endif
+
     if (data->sync_base) {
         i->sync_next = data->sync_base->sync_next;
         i->sync_prev = data->sync_base;
@@ -322,6 +550,9 @@ int pa_sink_input_new(
 
     reset_callbacks(i);
     i->userdata = NULL;
+#ifdef __TIZEN__
+    i->dump_fp = NULL;
+#endif
 
     i->thread_info.state = i->state;
     i->thread_info.attached = FALSE;
@@ -335,33 +566,38 @@ int pa_sink_input_new(
     i->thread_info.rewrite_flush = FALSE;
     i->thread_info.dont_rewind_render = FALSE;
     i->thread_info.underrun_for = (uint64_t) -1;
+    i->thread_info.underrun_for_sink = 0;
     i->thread_info.playing_for = 0;
     i->thread_info.direct_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
 
+    pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0);
+    pa_assert_se(pa_idxset_put(i->sink->inputs, pa_sink_input_ref(i), NULL) == 0);
+
+    if (i->client)
+        pa_assert_se(pa_idxset_put(i->client->sink_inputs, i, NULL) >= 0);
+
+    memblockq_name = pa_sprintf_malloc("sink input render_memblockq [%u]", i->index);
     i->thread_info.render_memblockq = pa_memblockq_new(
+            memblockq_name,
             0,
             MEMBLOCKQ_MAXLENGTH,
             0,
-            pa_frame_size(&i->sink->sample_spec),
+            &i->sink->sample_spec,
             0,
             1,
             0,
             &i->sink->silence);
-
-    pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0);
-    pa_assert_se(pa_idxset_put(i->sink->inputs, pa_sink_input_ref(i), NULL) == 0);
-
-    if (i->client)
-        pa_assert_se(pa_idxset_put(i->client->sink_inputs, i, NULL) >= 0);
+    pa_xfree(memblockq_name);
 
     pt = pa_proplist_to_string_sep(i->proplist, "\n    ");
-    pa_log_info("Created input %u \"%s\" on %s with sample spec %s and channel map %s\n    %s",
+    pa_log_info("Created input %u \"%s\" (%s) on %s with sample spec %s and channel map %s\n",
                 i->index,
                 pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_MEDIA_NAME)),
+                pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_PROCESS_ID)),
                 i->sink->name,
                 pa_sample_spec_snprint(st, sizeof(st), &i->sample_spec),
-                pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
-                pt);
+                pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map));
+    pa_log_debug_verbose("    %s", pt);
     pa_xfree(pt);
 
     /* Don't forget to call pa_sink_input_put! */
@@ -380,8 +616,13 @@ static void update_n_corked(pa_sink_input *i, pa_sink_input_state_t state) {
 
     if (i->state == PA_SINK_INPUT_CORKED && state != PA_SINK_INPUT_CORKED)
         pa_assert_se(i->sink->n_corked -- >= 1);
-    else if (i->state != PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_CORKED)
+    else if (i->state != PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_CORKED) {
+#ifdef __TIZEN__
+        if (i->thread_info.resampler)
+            pa_resampler_reset(i->thread_info.resampler);
+#endif
         i->sink->n_corked++;
+    }
 }
 
 /* Called from main context */
@@ -396,6 +637,13 @@ static void sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state)
     if (i->state == state)
         return;
 
+    if (i->state == PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_RUNNING && pa_sink_used_by(i->sink) == 0 &&
+        !pa_sample_spec_equal(&i->sample_spec, &i->sink->sample_spec)) {
+        /* We were uncorked and the sink was not playing anything -- let's try
+         * to update the sample rate to avoid resampling */
+        pa_sink_update_rate(i->sink, i->sample_spec.rate, pa_sink_input_is_passthrough(i));
+    }
+
     pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) == 0);
 
     update_n_corked(i, state);
@@ -418,6 +666,9 @@ static void sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state)
 
         for (ssync = i->sync_next; ssync; ssync = ssync->sync_next)
             pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], ssync);
+
+        if (PA_SINK_INPUT_IS_LINKED(state))
+            pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
     }
 
     pa_sink_update_status(i->sink);
@@ -426,7 +677,7 @@ static void sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state)
 /* Called from main context */
 void pa_sink_input_unlink(pa_sink_input *i) {
     pa_bool_t linked;
-    pa_source_output *o, *p =  NULL;
+    pa_source_output *o, *p = NULL;
 
     pa_assert(i);
     pa_assert_ctl_context();
@@ -467,8 +718,11 @@ void pa_sink_input_unlink(pa_sink_input *i) {
     i->state = PA_SINK_INPUT_UNLINKED;
 
     if (linked && i->sink) {
+        if (pa_sink_input_is_passthrough(i))
+            pa_sink_leave_passthrough(i->sink);
+
         /* We might need to update the sink's volume if we are in flat volume mode. */
-        if (i->sink->flags & PA_SINK_FLAT_VOLUME)
+        if (pa_sink_flat_volume_enabled(i->sink))
             pa_sink_set_volume(i->sink, NULL, FALSE, FALSE);
 
         if (i->sink->asyncmsgq)
@@ -483,7 +737,9 @@ void pa_sink_input_unlink(pa_sink_input *i) {
     }
 
     if (i->sink) {
-        pa_sink_update_status(i->sink);
+        if (PA_SINK_IS_LINKED(pa_sink_get_state(i->sink)))
+            pa_sink_update_status(i->sink);
+
         i->sink = NULL;
     }
 
@@ -516,14 +772,38 @@ static void sink_input_free(pa_object *o) {
     if (i->thread_info.resampler)
         pa_resampler_free(i->thread_info.resampler);
 
+#ifdef PA_EXT_USE_VOLUME_FADING
+    if (pa_cvolume_fading_valid(&i->thread_info.soft_volume)) {
+        pa_xfree(i->thread_info.soft_volume.fading_info);
+        pa_cvolume_fading_unset(&i->thread_info.soft_volume);
+    }
+    pa_queue_free(i->fading_queue, pa_xfree);
+#endif
+#ifdef __TIZEN__
+    /* close file for dump pcm */
+    if (i->dump_fp) {
+        fclose(i->dump_fp);
+        i->dump_fp = NULL;
+    }
+#endif
+
+    if (i->format)
+        pa_format_info_free(i->format);
+
     if (i->proplist)
         pa_proplist_free(i->proplist);
 
     if (i->direct_outputs)
-        pa_idxset_free(i->direct_outputs, NULL, NULL);
+        pa_idxset_free(i->direct_outputs, NULL);
 
     if (i->thread_info.direct_outputs)
-        pa_hashmap_free(i->thread_info.direct_outputs, NULL, NULL);
+        pa_hashmap_free(i->thread_info.direct_outputs, NULL);
+
+    if (i->volume_factor_items)
+        pa_hashmap_free(i->volume_factor_items, (pa_free_cb_t) volume_factor_entry_free);
+
+    if (i->volume_factor_sink_items)
+        pa_hashmap_free(i->volume_factor_sink_items, (pa_free_cb_t) volume_factor_entry_free);
 
     pa_xfree(i->driver);
     pa_xfree(i);
@@ -549,10 +829,19 @@ void pa_sink_input_put(pa_sink_input *i) {
     i->state = state;
 
     /* We might need to update the sink's volume if we are in flat volume mode. */
-    if (i->sink->flags & PA_SINK_FLAT_VOLUME)
+    if (pa_sink_flat_volume_enabled(i->sink))
         pa_sink_set_volume(i->sink, NULL, FALSE, i->save_volume);
-    else
+    else {
+        if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
+            pa_assert(pa_cvolume_is_norm(&i->volume));
+            pa_assert(pa_cvolume_is_norm(&i->reference_ratio));
+        }
+
         set_real_ratio(i, &i->volume);
+    }
+
+    if (pa_sink_input_is_passthrough(i))
+        pa_sink_enter_passthrough(i->sink);
 
     i->thread_info.soft_volume = i->soft_volume;
     i->thread_info.muted = i->muted;
@@ -594,11 +883,12 @@ pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency) {
 }
 
 /* Called from thread context */
-void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa_memchunk *chunk, pa_cvolume *volume) {
+void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink bytes */, pa_memchunk *chunk, pa_cvolume *volume) {
     pa_bool_t do_volume_adj_here, need_volume_factor_sink;
     pa_bool_t volume_is_norm;
     size_t block_size_max_sink, block_size_max_sink_input;
     size_t ilength;
+    size_t ilength_full;
 
     pa_sink_input_assert_ref(i);
     pa_sink_input_assert_io_context(i);
@@ -607,11 +897,9 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
     pa_assert(chunk);
     pa_assert(volume);
 
-/*     pa_log_debug("peek"); */
-
-    pa_assert(i->thread_info.state == PA_SINK_INPUT_RUNNING ||
-              i->thread_info.state == PA_SINK_INPUT_CORKED ||
-              i->thread_info.state == PA_SINK_INPUT_DRAINED);
+#ifdef SINK_INPUT_DEBUG
+    pa_log_debug("peek");
+#endif
 
     block_size_max_sink_input = i->thread_info.resampler ?
         pa_resampler_max_block_size(i->thread_info.resampler) :
@@ -634,6 +922,10 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
     } else
         ilength = slength;
 
+    /* Length corresponding to slength (without limiting to
+     * block_size_max_sink_input). */
+    ilength_full = ilength;
+
     if (ilength > block_size_max_sink_input)
         ilength = block_size_max_sink_input;
 
@@ -660,8 +952,10 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
 
             pa_memblockq_seek(i->thread_info.render_memblockq, (int64_t) slength, PA_SEEK_RELATIVE, TRUE);
             i->thread_info.playing_for = 0;
-            if (i->thread_info.underrun_for != (uint64_t) -1)
-                i->thread_info.underrun_for += ilength;
+            if (i->thread_info.underrun_for != (uint64_t) -1) {
+                i->thread_info.underrun_for += ilength_full;
+                i->thread_info.underrun_for_sink += slength;
+            }
             break;
         }
 
@@ -671,6 +965,7 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
         pa_assert(tchunk.memblock);
 
         i->thread_info.underrun_for = 0;
+        i->thread_info.underrun_for_sink = 0;
         i->thread_info.playing_for += tchunk.length;
 
         while (tchunk.length > 0) {
@@ -687,7 +982,12 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
             if (do_volume_adj_here && !volume_is_norm) {
                 pa_memchunk_make_writable(&wchunk, 0);
 
-                if (i->thread_info.muted) {
+                if (i->thread_info.muted
+#ifdef PA_EXT_USE_VOLUME_FADING
+                    && !(pa_cvolume_fading_valid(&i->thread_info.soft_volume)
+                        && (i->thread_info.soft_volume.fading_info->remain_frames > 0))
+#endif
+                ) {
                     pa_silence_memchunk(&wchunk, &i->thread_info.sample_spec);
                     nvfs = FALSE;
 
@@ -698,6 +998,9 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
                      * post and the pre volume adjustment into one */
 
                     pa_sw_cvolume_multiply(&v, &i->thread_info.soft_volume, &i->volume_factor_sink);
+#ifdef PA_EXT_USE_VOLUME_FADING
+                    pa_cvolume_fading_update(&v, &i->thread_info.soft_volume);
+#endif
                     pa_volume_memchunk(&wchunk, &i->thread_info.sample_spec, &v);
                     nvfs = FALSE;
 
@@ -709,6 +1012,9 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
 
                 if (nvfs) {
                     pa_memchunk_make_writable(&wchunk, 0);
+#ifdef PA_EXT_USE_VOLUME_FADING
+                    pa_cvolume_fading_update(&i->volume_factor_sink, &i->thread_info.soft_volume);
+#endif
                     pa_volume_memchunk(&wchunk, &i->sink->sample_spec, &i->volume_factor_sink);
                 }
 
@@ -717,12 +1023,17 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
                 pa_memchunk rchunk;
                 pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk);
 
-/*                 pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
+#ifdef SINK_INPUT_DEBUG
+                pa_log_debug("pushing %lu", (unsigned long) rchunk.length);
+#endif
 
                 if (rchunk.memblock) {
 
                     if (nvfs) {
                         pa_memchunk_make_writable(&rchunk, 0);
+#ifdef PA_EXT_USE_VOLUME_FADING
+                        pa_cvolume_fading_update(&i->volume_factor_sink, &i->thread_info.soft_volume);
+#endif
                         pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
                     }
 
@@ -745,7 +1056,9 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
     pa_assert(chunk->length > 0);
     pa_assert(chunk->memblock);
 
-/*     pa_log_debug("peeking %lu", (unsigned long) chunk->length); */
+#ifdef SINK_INPUT_DEBUG
+    pa_log_debug("peeking %lu", (unsigned long) chunk->length);
+#endif
 
     if (chunk->length > block_size_max_sink)
         chunk->length = block_size_max_sink;
@@ -753,14 +1066,55 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
     /* Let's see if we had to apply the volume adjustment ourselves,
      * or if this can be done by the sink for us */
 
-    if (do_volume_adj_here)
+    if (do_volume_adj_here) {
         /* We had different channel maps, so we already did the adjustment */
         pa_cvolume_reset(volume, i->sink->sample_spec.channels);
-    else if (i->thread_info.muted)
+#ifdef PA_EXT_USE_VOLUME_FADING
+        volume->fading_info = NULL;
+#endif
+    } else if (i->thread_info.muted)
         /* We've both the same channel map, so let's have the sink do the adjustment for us*/
         pa_cvolume_mute(volume, i->sink->sample_spec.channels);
     else
         *volume = i->thread_info.soft_volume;
+#ifdef PA_EXT_USE_VOLUME_FADING
+    if (!do_volume_adj_here)
+        pa_cvolume_fading_update(volume, &i->thread_info.soft_volume);
+#endif
+
+#ifdef __TIZEN__
+    /* open file for dump pcm */
+    if (i->core->dump_sink_input && !i->dump_fp) {
+        time_t t;
+        char datetime[12];
+        char *dump_path = NULL;
+
+        time(&t);
+        memset(&datetime[0], 0x00, sizeof(datetime));
+        strftime(&datetime[0], sizeof(datetime), "%m%d_%H%M%S", localtime(&t));
+        dump_path = pa_sprintf_malloc("%s_%s_%d_sink%d.pcm", PA_SINK_INPUT_DUMP_PATH_PREFIX, &datetime[0], i->index, i->sink->index);
+
+        if (dump_path) {
+            i->dump_fp = fopen(dump_path, "w");
+            pa_xfree(dump_path);
+        }
+    /* close file for dump pcm when config is changed */
+    } else if (!i->core->dump_sink && i->dump_fp) {
+        fclose(i->dump_fp);
+        i->dump_fp = NULL;
+    }
+
+    /* dump pcm */
+    if (i->dump_fp) {
+        void *ptr;
+
+        ptr = pa_memblock_acquire(chunk->memblock);
+
+        fwrite((uint8_t*) ptr + chunk->index, 1, chunk->length, i->dump_fp);
+
+        pa_memblock_release(chunk->memblock);
+    }
+#endif
 }
 
 /* Called from thread context */
@@ -772,12 +1126,31 @@ void pa_sink_input_drop(pa_sink_input *i, size_t nbytes /* in sink sample spec *
     pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
     pa_assert(nbytes > 0);
 
-/*     pa_log_debug("dropping %lu", (unsigned long) nbytes); */
+#ifdef SINK_INPUT_DEBUG
+    pa_log_debug("dropping %lu", (unsigned long) nbytes);
+#endif
 
     pa_memblockq_drop(i->thread_info.render_memblockq, nbytes);
 }
 
 /* Called from thread context */
+bool pa_sink_input_process_underrun(pa_sink_input *i) {
+    pa_sink_input_assert_ref(i);
+    pa_sink_input_assert_io_context(i);
+
+    if (pa_memblockq_is_readable(i->thread_info.render_memblockq))
+        return false;
+
+    if (i->process_underrun && i->process_underrun(i)) {
+        /* All valid data has been played back, so we can empty this queue. */
+        pa_memblockq_silence(i->thread_info.render_memblockq);
+        return true;
+    }
+    return false;
+}
+
+
+/* Called from thread context */
 void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sample spec */) {
     size_t lbq;
     pa_bool_t called = FALSE;
@@ -787,19 +1160,28 @@ void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sam
     pa_assert(PA_SINK_INPUT_IS_LINKED(i->thread_info.state));
     pa_assert(pa_frame_aligned(nbytes, &i->sink->sample_spec));
 
-/*     pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes); */
+#ifdef SINK_INPUT_DEBUG
+    pa_log_debug("rewind(%lu, %lu)", (unsigned long) nbytes, (unsigned long) i->thread_info.rewrite_nbytes);
+#endif
 
     lbq = pa_memblockq_get_length(i->thread_info.render_memblockq);
 
     if (nbytes > 0 && !i->thread_info.dont_rewind_render) {
-        pa_log_debug("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes);
+        pa_log_debug_verbose("Have to rewind %lu bytes on render memblockq.", (unsigned long) nbytes);
         pa_memblockq_rewind(i->thread_info.render_memblockq, nbytes);
     }
 
     if (i->thread_info.rewrite_nbytes == (size_t) -1) {
 
+#ifdef __TIZEN__
+        /* rewind pcm */
+        if (i->dump_fp) {
+            fseeko(i->dump_fp, (off_t)pa_memblockq_get_length(i->thread_info.render_memblockq) * (-1), SEEK_CUR);
+        }
+#endif
+
         /* We were asked to drop all buffered data, and rerequest new
-         * data from implementor the next time push() is called */
+         * data from implementor the next time peek() is called */
 
         pa_memblockq_flush_write(i->thread_info.render_memblockq, TRUE);
 
@@ -819,6 +1201,13 @@ void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes /* in sink sam
         if (amount > 0) {
             pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) amount);
 
+#ifdef __TIZEN__
+            /* rewind pcm */
+            if (i->dump_fp) {
+                fseeko(i->dump_fp, (off_t)amount * (-1), SEEK_CUR);
+            }
+#endif
+
             /* Tell the implementor */
             if (i->process_rewind)
                 i->process_rewind(i, amount);
@@ -930,7 +1319,7 @@ pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec)
         if (usec != (pa_usec_t) -1) {
             pa_usec_t min_latency, max_latency;
             pa_sink_get_latency_range(i->sink, &min_latency, &max_latency);
-            usec =  PA_CLAMP(usec, min_latency, max_latency);
+            usec = PA_CLAMP(usec, min_latency, max_latency);
         }
     }
 
@@ -957,29 +1346,12 @@ pa_usec_t pa_sink_input_get_requested_latency(pa_sink_input *i) {
 }
 
 /* Called from main context */
-static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {
-    pa_sink_input_assert_ref(i);
-    pa_assert_ctl_context();
-    pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
-    pa_assert(!v || pa_cvolume_compatible(v, &i->sample_spec));
-
-    /* This basically calculates:
-     *
-     * i->real_ratio := v
-     * i->soft_volume := i->real_ratio * i->volume_factor */
-
-    if (v)
-        i->real_ratio = *v;
-    else
-        pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
-
-    pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
-    /* We don't copy the data to the thread_info data. That's left for someone else to do */
-}
-
-/* Called from main context */
 void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute) {
     pa_cvolume v;
+#ifdef PA_EXT_USE_VOLUME_FADING
+    pa_cvolume_fading_info *f;
+    unsigned channel;
+#endif
 
     pa_sink_input_assert_ref(i);
     pa_assert_ctl_context();
@@ -987,8 +1359,9 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_boo
     pa_assert(volume);
     pa_assert(pa_cvolume_valid(volume));
     pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &i->sample_spec));
+    pa_assert(i->volume_writable);
 
-    if ((i->sink->flags & PA_SINK_FLAT_VOLUME) && !absolute) {
+    if (!absolute && pa_sink_flat_volume_enabled(i->sink)) {
         v = i->sink->reference_volume;
         pa_cvolume_remap(&v, &i->sink->channel_map, &i->channel_map);
 
@@ -997,7 +1370,6 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_boo
         else
             volume = pa_sw_cvolume_multiply_scalar(&v, &v, pa_cvolume_max(volume));
     } else {
-
         if (!pa_cvolume_compatible(volume, &i->sample_spec)) {
             v = i->volume;
             volume = pa_cvolume_scale(&v, pa_cvolume_max(volume));
@@ -1012,16 +1384,29 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_boo
     i->volume = *volume;
     i->save_volume = save;
 
-    if (i->sink->flags & PA_SINK_FLAT_VOLUME)
+    if (pa_sink_flat_volume_enabled(i->sink)) {
         /* We are in flat volume mode, so let's update all sink input
          * volumes and update the flat volume of the sink */
 
         pa_sink_set_volume(i->sink, NULL, TRUE, save);
 
-    else {
+    else {
         /* OK, we are in normal volume mode. The volume only affects
          * ourselves */
+#ifdef PA_EXT_USE_VOLUME_FADING
+        f = pa_xnew(pa_cvolume_fading_info, 1);
+        f->multiply = 0;
+        f->remain_frames = i->sample_spec.rate * PA_EXT_FADE_INTERVAL_MSEC / 1000;
+        for (channel = 0; channel < volume->channels; channel++)
+            f->cur_values[channel] = i->soft_volume.values[channel];
+#endif
         set_real_ratio(i, volume);
+        i->reference_ratio = i->volume;
+#ifdef PA_EXT_USE_VOLUME_FADING
+        for (channel = 0; channel < volume->channels; channel++)
+            f->dst_values[channel] = i->soft_volume.values[channel];
+        pa_queue_push(i->fading_queue, (void *)f);
+#endif
 
         /* Copy the new soft_volume to the thread_info struct */
         pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0);
@@ -1031,16 +1416,141 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_boo
     if (i->volume_changed)
         i->volume_changed(i);
 
+    /* The virtual volume changed, let's tell people so */
     pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
 }
 
+#ifdef PA_EXT_USE_VOLUME_FADING
+/* Called from main context */
+void pa_sink_input_update_sink_fade(pa_sink_input *i, const pa_cvolume *old_volume, const pa_cvolume *new_volume) {
+    pa_cvolume_fading_info *f;
+    unsigned channel;
+
+    if (!pa_channel_map_equal(&i->sink->channel_map, &i->channel_map))
+        return;
+
+    f = pa_xnew(pa_cvolume_fading_info, 1);
+    f->remain_frames = i->sample_spec.rate * PA_EXT_FADE_INTERVAL_MSEC / 1000;
+
+    for (channel = 0; channel < i->soft_volume.channels; channel++) {
+        f->cur_values[channel] = pa_sw_volume_multiply(old_volume->values[channel], i->soft_volume.values[channel]);
+        f->dst_values[channel] = pa_sw_volume_multiply(new_volume->values[channel], i->soft_volume.values[channel]);
+    }
+    f->multiply = 1;
+
+    pa_queue_push(i->fading_queue, (void *)f);
+
+    /* Copy the new fade to the thread_info struct */
+    pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_FADE, NULL, 0, NULL) == 0);
+}
+#endif
+
+void pa_sink_input_add_volume_factor(pa_sink_input *i, const char *key, const pa_cvolume *volume_factor) {
+    struct volume_factor_entry *v;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_ctl_context();
+    pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
+    pa_assert(volume_factor);
+    pa_assert(key);
+    pa_assert(pa_cvolume_valid(volume_factor));
+    pa_assert(volume_factor->channels == 1 || pa_cvolume_compatible(volume_factor, &i->sample_spec));
+
+    v = volume_factor_entry_new(key, volume_factor);
+    if (!pa_cvolume_compatible(volume_factor, &i->sample_spec))
+        pa_cvolume_set(&v->volume, i->sample_spec.channels, volume_factor->values[0]);
+
+    pa_assert_se(pa_hashmap_put(i->volume_factor_items, v->key, v) >= 0);
+    if (pa_hashmap_size(i->volume_factor_items) == 1)
+        i->volume_factor = v->volume;
+    else
+        pa_sw_cvolume_multiply(&i->volume_factor, &i->volume_factor, &v->volume);
+
+    pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
+
+    /* Copy the new soft_volume to the thread_info struct */
+    pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0);
+}
+
+void pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key) {
+    struct volume_factor_entry *v;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert(key);
+    pa_assert_ctl_context();
+    pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
+
+    pa_assert_se(v = pa_hashmap_remove(i->volume_factor_items, key));
+    volume_factor_entry_free(v);
+
+    switch (pa_hashmap_size(i->volume_factor_items)) {
+        case 0:
+            pa_cvolume_reset(&i->volume_factor, i->sample_spec.channels);
+            break;
+        case 1:
+            v = pa_hashmap_first(i->volume_factor_items);
+            i->volume_factor = v->volume;
+            break;
+        default:
+            volume_factor_from_hashmap(&i->volume_factor, i->volume_factor_items, i->volume_factor.channels);
+    }
+
+    pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
+
+    /* Copy the new soft_volume to the thread_info struct */
+    pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0);
+}
+
+/* Called from main context */
+static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {
+    pa_sink_input_assert_ref(i);
+    pa_assert_ctl_context();
+    pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
+    pa_assert(!v || pa_cvolume_compatible(v, &i->sample_spec));
+
+    /* This basically calculates:
+     *
+     * i->real_ratio := v
+     * i->soft_volume := i->real_ratio * i->volume_factor */
+
+    if (v)
+        i->real_ratio = *v;
+    else
+        pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
+
+    pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
+    /* We don't copy the data to the thread_info data. That's left for someone else to do */
+}
+
+/* Called from main or I/O context */
+pa_bool_t pa_sink_input_is_passthrough(pa_sink_input *i) {
+    pa_sink_input_assert_ref(i);
+
+    if (PA_UNLIKELY(!pa_format_info_is_pcm(i->format)))
+        return TRUE;
+
+    if (PA_UNLIKELY(i->flags & PA_SINK_INPUT_PASSTHROUGH))
+        return TRUE;
+
+    return FALSE;
+}
+
+/* Called from main context */
+pa_bool_t pa_sink_input_is_volume_readable(pa_sink_input *i) {
+    pa_sink_input_assert_ref(i);
+    pa_assert_ctl_context();
+
+    return !pa_sink_input_is_passthrough(i);
+}
+
 /* Called from main context */
 pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, pa_bool_t absolute) {
     pa_sink_input_assert_ref(i);
     pa_assert_ctl_context();
     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
+    pa_assert(pa_sink_input_is_volume_readable(i));
 
-    if (absolute || !(i->sink->flags & PA_SINK_FLAT_VOLUME))
+    if (absolute || !pa_sink_flat_volume_enabled(i->sink))
         *volume = i->volume;
     else
         *volume = i->reference_ratio;
@@ -1050,16 +1560,41 @@ pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, pa_bo
 
 /* Called from main context */
 void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save) {
+#ifdef PA_EXT_USE_VOLUME_FADING_FOR_MUTE
+    pa_cvolume_fading_info *f;
+    unsigned channel;
+#endif
+
     pa_sink_input_assert_ref(i);
     pa_assert_ctl_context();
     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
 
-    if (!i->muted == !mute)
+    if (!i->muted == !mute) {
+        i->save_muted = i->save_muted || mute;
         return;
+    }
 
     i->muted = mute;
     i->save_muted = save;
 
+#ifdef PA_EXT_USE_VOLUME_FADING_FOR_MUTE
+    f = pa_xnew(pa_cvolume_fading_info, 1);
+    f->multiply = 0;
+    f->remain_frames = i->sample_spec.rate * PA_EXT_FADE_INTERVAL_MSEC / 1000;
+    if (i->muted) {
+        for (channel = 0; channel < i->soft_volume.channels; channel++) {
+            f->cur_values[channel] = i->soft_volume.values[channel];
+            f->dst_values[channel] = PA_VOLUME_MUTED;
+        }
+    } else {
+        for (channel = 0; channel < i->soft_volume.channels; channel++) {
+            f->cur_values[channel] = PA_VOLUME_MUTED;
+            f->dst_values[channel] = i->soft_volume.values[channel];
+        }
+    }
+    pa_queue_push(i->fading_queue, (void *)f);
+#endif
+
     pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE, NULL, 0, NULL) == 0);
 
     /* The mute status changed, let's tell people so */
@@ -1086,7 +1621,7 @@ void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_p
     if (p)
         pa_proplist_update(i->proplist, mode, p);
 
-    if (PA_SINK_IS_LINKED(i->state)) {
+    if (PA_SINK_INPUT_IS_LINKED(i->state)) {
         pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED], i);
         pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
     }
@@ -1162,13 +1697,24 @@ pa_bool_t pa_sink_input_may_move(pa_sink_input *i) {
         return FALSE;
 
     if (i->sync_next || i->sync_prev) {
-        pa_log_warn("Moving synchronised streams not supported.");
+        pa_log_warn("Moving synchronized streams not supported.");
         return FALSE;
     }
 
     return TRUE;
 }
 
+static pa_bool_t find_filter_sink_input(pa_sink_input *target, pa_sink *s) {
+    int i = 0;
+    while (s && s->input_to_master) {
+        if (s->input_to_master == target)
+            return TRUE;
+        s = s->input_to_master->sink;
+        pa_assert(i++ < 100);
+    }
+    return FALSE;
+}
+
 /* Called from main context */
 pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
     pa_sink_input_assert_ref(i);
@@ -1182,11 +1728,20 @@ pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
     if (!pa_sink_input_may_move(i))
         return FALSE;
 
+    /* Make sure we're not creating a filter sink cycle */
+    if (find_filter_sink_input(i, dest)) {
+        pa_log_debug("Can't connect input to %s, as that would create a cycle.", dest->name);
+        return FALSE;
+    }
+
     if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) {
         pa_log_warn("Failed to move sink input: too many inputs per sink.");
         return FALSE;
     }
 
+    if (check_passthrough_connection(pa_sink_input_is_passthrough(i), dest) < 0)
+        return FALSE;
+
     if (i->may_move_to)
         if (!i->may_move_to(i, dest))
             return FALSE;
@@ -1197,6 +1752,8 @@ pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
 /* Called from main context */
 int pa_sink_input_start_move(pa_sink_input *i) {
     pa_source_output *o, *p = NULL;
+    struct volume_factor_entry *v;
+    void *state = NULL;
     int r;
 
     pa_sink_input_assert_ref(i);
@@ -1223,7 +1780,10 @@ int pa_sink_input_start_move(pa_sink_input *i) {
     if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
         pa_assert_se(i->sink->n_corked-- >= 1);
 
-    if (i->sink->flags & PA_SINK_FLAT_VOLUME)
+    if (pa_sink_input_is_passthrough(i))
+        pa_sink_leave_passthrough(i->sink);
+
+    if (pa_sink_flat_volume_enabled(i->sink))
         /* We might need to update the sink's volume if we are in flat
          * volume mode. */
         pa_sink_set_volume(i->sink, NULL, FALSE, FALSE);
@@ -1231,7 +1791,12 @@ int pa_sink_input_start_move(pa_sink_input *i) {
     pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
 
     pa_sink_update_status(i->sink);
+
+    PA_HASHMAP_FOREACH(v, i->volume_factor_sink_items, state)
+        pa_cvolume_remap(&v->volume, &i->sink->channel_map, &i->channel_map);
+
     pa_cvolume_remap(&i->volume_factor_sink, &i->sink->channel_map, &i->channel_map);
+
     i->sink = NULL;
 
     pa_sink_input_unref(i);
@@ -1239,9 +1804,160 @@ int pa_sink_input_start_move(pa_sink_input *i) {
     return 0;
 }
 
+/* Called from main context. If i has an origin sink that uses volume sharing,
+ * then also the origin sink and all streams connected to it need to update
+ * their volume - this function does all that by using recursion. */
+static void update_volume_due_to_moving(pa_sink_input *i, pa_sink *dest) {
+    pa_cvolume old_volume;
+
+    pa_assert(i);
+    pa_assert(dest);
+    pa_assert(i->sink); /* The destination sink should already be set. */
+
+    if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
+        pa_sink *root_sink = pa_sink_get_master(i->sink);
+        pa_sink_input *origin_sink_input;
+        uint32_t idx;
+
+        if (PA_UNLIKELY(!root_sink))
+            return;
+
+        if (pa_sink_flat_volume_enabled(i->sink)) {
+            /* Ok, so the origin sink uses volume sharing, and flat volume is
+             * enabled. The volume will have to be updated as follows:
+             *
+             *     i->volume := i->sink->real_volume
+             *         (handled later by pa_sink_set_volume)
+             *     i->reference_ratio := i->volume / i->sink->reference_volume
+             *         (handled later by pa_sink_set_volume)
+             *     i->real_ratio stays unchanged
+             *         (streams whose origin sink uses volume sharing should
+             *          always have real_ratio of 0 dB)
+             *     i->soft_volume stays unchanged
+             *         (streams whose origin sink uses volume sharing should
+             *          always have volume_factor as soft_volume, so no change
+             *          should be needed) */
+
+            pa_assert(pa_cvolume_is_norm(&i->real_ratio));
+            pa_assert(pa_cvolume_equal(&i->soft_volume, &i->volume_factor));
+
+            /* Notifications will be sent by pa_sink_set_volume(). */
+
+        } else {
+            /* Ok, so the origin sink uses volume sharing, and flat volume is
+             * disabled. The volume will have to be updated as follows:
+             *
+             *     i->volume := 0 dB
+             *     i->reference_ratio := 0 dB
+             *     i->real_ratio stays unchanged
+             *         (streams whose origin sink uses volume sharing should
+             *          always have real_ratio of 0 dB)
+             *     i->soft_volume stays unchanged
+             *         (streams whose origin sink uses volume sharing should
+             *          always have volume_factor as soft_volume, so no change
+             *          should be needed) */
+
+            old_volume = i->volume;
+            pa_cvolume_reset(&i->volume, i->volume.channels);
+            pa_cvolume_reset(&i->reference_ratio, i->reference_ratio.channels);
+            pa_assert(pa_cvolume_is_norm(&i->real_ratio));
+            pa_assert(pa_cvolume_equal(&i->soft_volume, &i->volume_factor));
+
+            /* Notify others about the changed sink input volume. */
+            if (!pa_cvolume_equal(&i->volume, &old_volume)) {
+                if (i->volume_changed)
+                    i->volume_changed(i);
+
+                pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
+            }
+        }
+
+        /* Additionally, the origin sink volume needs updating:
+         *
+         *     i->origin_sink->reference_volume := root_sink->reference_volume
+         *     i->origin_sink->real_volume := root_sink->real_volume
+         *     i->origin_sink->soft_volume stays unchanged
+         *         (sinks that use volume sharing should always have
+         *          soft_volume of 0 dB) */
+
+        old_volume = i->origin_sink->reference_volume;
+
+        i->origin_sink->reference_volume = root_sink->reference_volume;
+        pa_cvolume_remap(&i->origin_sink->reference_volume, &root_sink->channel_map, &i->origin_sink->channel_map);
+
+        i->origin_sink->real_volume = root_sink->real_volume;
+        pa_cvolume_remap(&i->origin_sink->real_volume, &root_sink->channel_map, &i->origin_sink->channel_map);
+
+        pa_assert(pa_cvolume_is_norm(&i->origin_sink->soft_volume));
+
+        /* Notify others about the changed sink volume. If you wonder whether
+         * i->origin_sink->set_volume() should be called somewhere, that's not
+         * the case, because sinks that use volume sharing shouldn't have any
+         * internal volume that set_volume() would update. If you wonder
+         * whether the thread_info variables should be synced, yes, they
+         * should, and it's done by the PA_SINK_MESSAGE_FINISH_MOVE message
+         * handler. */
+        if (!pa_cvolume_equal(&i->origin_sink->reference_volume, &old_volume))
+            pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, i->origin_sink->index);
+
+        /* Recursively update origin sink inputs. */
+        PA_IDXSET_FOREACH(origin_sink_input, i->origin_sink->inputs, idx)
+            update_volume_due_to_moving(origin_sink_input, dest);
+
+    } else {
+        old_volume = i->volume;
+
+        if (pa_sink_flat_volume_enabled(i->sink)) {
+            /* Ok, so this is a regular stream, and flat volume is enabled. The
+             * volume will have to be updated as follows:
+             *
+             *     i->volume := i->reference_ratio * i->sink->reference_volume
+             *     i->reference_ratio stays unchanged
+             *     i->real_ratio := i->volume / i->sink->real_volume
+             *         (handled later by pa_sink_set_volume)
+             *     i->soft_volume := i->real_ratio * i->volume_factor
+             *         (handled later by pa_sink_set_volume) */
+
+            i->volume = i->sink->reference_volume;
+            pa_cvolume_remap(&i->volume, &i->sink->channel_map, &i->channel_map);
+            pa_sw_cvolume_multiply(&i->volume, &i->volume, &i->reference_ratio);
+
+        } else {
+            /* Ok, so this is a regular stream, and flat volume is disabled.
+             * The volume will have to be updated as follows:
+             *
+             *     i->volume := i->reference_ratio
+             *     i->reference_ratio stays unchanged
+             *     i->real_ratio := i->reference_ratio
+             *     i->soft_volume := i->real_ratio * i->volume_factor */
+
+            i->volume = i->reference_ratio;
+            i->real_ratio = i->reference_ratio;
+            pa_sw_cvolume_multiply(&i->soft_volume, &i->real_ratio, &i->volume_factor);
+        }
+
+        /* Notify others about the changed sink input volume. */
+        if (!pa_cvolume_equal(&i->volume, &old_volume)) {
+            /* XXX: In case i->sink has flat volume enabled, then real_ratio
+             * and soft_volume are not updated yet. Let's hope that the
+             * callback implementation doesn't care about those variables... */
+            if (i->volume_changed)
+                i->volume_changed(i);
+
+            pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
+        }
+    }
+
+    /* If i->sink == dest, then recursion has finished, and we can finally call
+     * pa_sink_set_volume(), which will do the rest of the updates. */
+    if ((i->sink == dest) && pa_sink_flat_volume_enabled(i->sink))
+        pa_sink_set_volume(i->sink, NULL, FALSE, i->save_volume);
+}
+
 /* Called from main context */
 int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
-    pa_resampler *new_resampler;
+    struct volume_factor_entry *v;
+    void *state = NULL;
 
     pa_sink_input_assert_ref(i);
     pa_assert_ctl_context();
@@ -1252,32 +1968,27 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
     if (!pa_sink_input_may_move_to(i, dest))
         return -PA_ERR_NOTSUPPORTED;
 
-    if (i->thread_info.resampler &&
-        pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &dest->sample_spec) &&
-        pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &dest->channel_map))
-
-        /* Try to reuse the old resampler if possible */
-        new_resampler = i->thread_info.resampler;
-
-    else if ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
-             !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec) ||
-             !pa_channel_map_equal(&i->channel_map, &dest->channel_map)) {
+    if (pa_sink_input_is_passthrough(i) && !pa_sink_check_format(dest, i->format)) {
+        pa_proplist *p = pa_proplist_new();
+        pa_log_debug("New sink doesn't support stream format, sending format-changed and killing");
+        /* Tell the client what device we want to be on if it is going to
+         * reconnect */
+        pa_proplist_sets(p, "device", dest->name);
+        pa_sink_input_send_event(i, PA_STREAM_EVENT_FORMAT_LOST, p);
+        pa_proplist_free(p);
+        return -PA_ERR_NOTSUPPORTED;
+    }
 
-        /* Okey, we need a new resampler for the new sink */
+    if (!(i->flags & PA_SINK_INPUT_VARIABLE_RATE) &&
+        !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec)) {
+        /* try to change dest sink rate if possible without glitches.
+           module-suspend-on-idle resumes destination sink with
+           SINK_INPUT_MOVE_FINISH hook */
 
-        if (!(new_resampler = pa_resampler_new(
-                      i->core->mempool,
-                      &i->sample_spec, &i->channel_map,
-                      &dest->sample_spec, &dest->channel_map,
-                      i->requested_resample_method,
-                      ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
-                      ((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)))) {
-            pa_log_warn("Unsupported resampling operation.");
-            return -PA_ERR_NOTSUPPORTED;
-        }
-    } else
-        new_resampler = NULL;
+        pa_log_debug("Trying to change sample rate");
+        if (pa_sink_update_rate(dest, i->sample_spec.rate, pa_sink_input_is_passthrough(i)) == TRUE)
+            pa_log_info("Rate changed to %u Hz", dest->sample_spec.rate);
+    }
 
     if (i->moving)
         i->moving(i, dest);
@@ -1286,43 +1997,22 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
     i->save_sink = save;
     pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL);
 
+    PA_HASHMAP_FOREACH(v, i->volume_factor_sink_items, state)
+        pa_cvolume_remap(&v->volume, &i->channel_map, &i->sink->channel_map);
+
     pa_cvolume_remap(&i->volume_factor_sink, &i->channel_map, &i->sink->channel_map);
 
     if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED)
         i->sink->n_corked++;
 
-    /* Replace resampler and render queue */
-    if (new_resampler != i->thread_info.resampler) {
+    pa_sink_input_update_rate(i);
 
-        if (i->thread_info.resampler)
-            pa_resampler_free(i->thread_info.resampler);
-        i->thread_info.resampler = new_resampler;
-
-        pa_memblockq_free(i->thread_info.render_memblockq);
-
-        i->thread_info.render_memblockq = pa_memblockq_new(
-                0,
-                MEMBLOCKQ_MAXLENGTH,
-                0,
-                pa_frame_size(&i->sink->sample_spec),
-                0,
-                1,
-                0,
-                &i->sink->silence);
-    }
     pa_sink_update_status(dest);
 
-    if (i->sink->flags & PA_SINK_FLAT_VOLUME) {
-        pa_cvolume remapped;
+    update_volume_due_to_moving(i, dest);
 
-        /* Make relative volumes absolute */
-        remapped = dest->reference_volume;
-        pa_cvolume_remap(&remapped, &dest->channel_map, &i->channel_map);
-        pa_sw_cvolume_multiply(&i->volume, &i->reference_ratio, &remapped);
-
-        /* We might need to update the sink's volume if we are in flat volume mode. */
-        pa_sink_set_volume(i->sink, NULL, FALSE, i->save_volume);
-    }
+    if (pa_sink_input_is_passthrough(i))
+        pa_sink_enter_passthrough(i->sink);
 
     pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_FINISH_MOVE, i, 0, NULL) == 0);
 
@@ -1330,10 +2020,6 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
 
     /* Notify everyone */
     pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], i);
-
-    if (i->volume_changed)
-        i->volume_changed(i);
-
     pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
 
     return 0;
@@ -1411,8 +2097,6 @@ void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state
     if (i->state_change)
         i->state_change(i, state);
 
-    i->thread_info.state = state;
-
     if (corking) {
 
         pa_log_debug("Requesting rewind due to corking");
@@ -1421,38 +2105,88 @@ void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state
          * so that the unplayed already mixed data is not lost */
         pa_sink_input_request_rewind(i, 0, TRUE, TRUE, FALSE);
 
+        /* Set the corked state *after* requesting rewind */
+        i->thread_info.state = state;
+
     } else if (uncorking) {
 
+        pa_log_debug("Requesting rewind due to uncorking");
+
         i->thread_info.underrun_for = (uint64_t) -1;
+        i->thread_info.underrun_for_sink = 0;
         i->thread_info.playing_for = 0;
 
-        pa_log_debug("Requesting rewind due to uncorking");
+        /* Set the uncorked state *before* requesting rewind */
+        i->thread_info.state = state;
 
         /* OK, we're being uncorked. Make sure we're not rewound when
          * the hw buffer is remixed and request a remix. */
         pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE);
-    }
+    } else
+        /* We may not be corking or uncorking, but we still need to set the state. */
+        i->thread_info.state = state;
 }
 
 /* Called from thread context, except when it is not. */
 int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
     pa_sink_input *i = PA_SINK_INPUT(o);
+#ifdef PA_EXT_USE_VOLUME_FADING
+    pa_cvolume_fading_info *f = NULL;
+#endif
     pa_sink_input_assert_ref(i);
 
     switch (code) {
 
         case PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME:
+#ifdef PA_EXT_USE_VOLUME_FADING
+            f = (pa_cvolume_fading_info *)pa_queue_pop(i->fading_queue);
+#endif
             if (!pa_cvolume_equal(&i->thread_info.soft_volume, &i->soft_volume)) {
                 i->thread_info.soft_volume = i->soft_volume;
+#ifdef PA_EXT_USE_VOLUME_FADING
+                if (!i->muted && f != NULL) {
+                    if (pa_cvolume_fading_valid(&i->thread_info.soft_volume))
+                        pa_xfree(i->thread_info.soft_volume.fading_info);
+                    pa_cvolume_fading_set(&i->thread_info.soft_volume, f);
+                } else if (f) {
+                    pa_xfree(f);
+                }
+#endif
                 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
             }
             return 0;
 
+#ifdef PA_EXT_USE_VOLUME_FADING
+        case PA_SINK_INPUT_MESSAGE_SET_FADE:
+            f = (pa_cvolume_fading_info *)pa_queue_pop(i->fading_queue);
+
+            if (pa_cvolume_fading_valid(&i->thread_info.soft_volume))
+                pa_xfree(i->thread_info.soft_volume.fading_info);
+            pa_cvolume_fading_set(&i->thread_info.soft_volume, f);
+
+            pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
+
+            return 0;
+#endif
+
         case PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE:
+#ifdef PA_EXT_USE_VOLUME_FADING_FOR_MUTE
+            f = (pa_cvolume_fading_info *)pa_queue_pop(i->fading_queue);
+#endif
             if (i->thread_info.muted != i->muted) {
                 i->thread_info.muted = i->muted;
+#ifdef PA_EXT_USE_VOLUME_FADING_FOR_MUTE
+                if (pa_cvolume_fading_valid(&i->thread_info.soft_volume))
+                    pa_xfree(i->thread_info.soft_volume.fading_info);
+                pa_cvolume_fading_set(&i->thread_info.soft_volume, f);
+#endif
                 pa_sink_input_request_rewind(i, 0, TRUE, FALSE, FALSE);
             }
+#ifdef PA_EXT_USE_VOLUME_FADING_FOR_MUTE
+            else if (f) {
+                pa_xfree(f);
+            }
+#endif
             return 0;
 
         case PA_SINK_INPUT_MESSAGE_GET_LATENCY: {
@@ -1524,7 +2258,9 @@ pa_bool_t pa_sink_input_safe_to_remove(pa_sink_input *i) {
 
     return TRUE;
 }
-
+#ifdef __TIZEN__
+#define SINK_VOIP           "alsa_output.3.analog-stereo"
+#endif
 /* Called from IO context */
 void pa_sink_input_request_rewind(
         pa_sink_input *i,
@@ -1553,14 +2289,52 @@ void pa_sink_input_request_rewind(
     pa_sink_input_assert_io_context(i);
     pa_assert(rewrite || flush);
     pa_assert(!dont_rewind_render || !rewrite);
-
+#ifdef __TIZEN__
+    /*FixMe:Since voip driver dosen't support rewind ,So avoiding rewind for the streams connected
+            to voip Sink Module*/
+    if (i->sink->name && pa_streq(i->sink->name,SINK_VOIP))
+    {
+        pa_log_info("Avoiding rewind for sink-input %d connected to sink %s",i->index,i->sink->name);
+        return;
+    }
+#endif
     /* We don't take rewind requests while we are corked */
     if (i->thread_info.state == PA_SINK_INPUT_CORKED)
         return;
 
+#ifdef __TIZEN__
+    /* FIXME: due to current observation, rewinding with resampler generates noise,
+     * following code will avoid just conflict but we need to investigate more about this */
+    if (i->sink) {
+        pa_log_debug_verbose("sample rate : sink-input [%d], sink [%d], if not same, skip rewind",
+            i->sample_spec.rate, i->sink->sample_spec.rate);
+        if (i->sample_spec.rate != i->sink->sample_spec.rate) {
+            return;
+        }
+    } else {
+        pa_log_warn("sink is not available for sink-input [%d]", i->index);
+    }
+
+    /* FIXME: remove tick noise during playing keysound */
+    {
+        uint32_t gain_type = 0;
+        const char *si_gain_type_str = NULL;
+        if ((si_gain_type_str = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_TIZEN_GAIN_TYPE))) {
+            pa_atou(si_gain_type_str, &gain_type);
+            if(gain_type == AUDIO_GAIN_TYPE_TOUCH) {
+                pa_log_debug_verbose("skip rewind");
+                return; // skip rewind.
+            }
+        }
+    }
+#endif
+
+
     nbytes = PA_MAX(i->thread_info.rewrite_nbytes, nbytes);
 
-    /* pa_log_debug("request rewrite %zu", nbytes); */
+#ifdef SINK_INPUT_DEBUG
+    pa_log_debug("request rewrite %zu", nbytes);
+#endif
 
     /* Calculate how much we can rewind locally without having to
      * touch the sink */
@@ -1593,13 +2367,13 @@ void pa_sink_input_request_rewind(
     }
 
     i->thread_info.rewrite_flush =
-        i->thread_info.rewrite_flush ||
-        (flush && i->thread_info.rewrite_nbytes != 0);
+        i->thread_info.rewrite_flush || flush;
 
     i->thread_info.dont_rewind_render =
         i->thread_info.dont_rewind_render ||
         dont_rewind_render;
 
+    /* nbytes is -1 if some earlier rewind request had rewrite == false. */
     if (nbytes != (size_t) -1) {
 
         /* Transform to sink domain */
@@ -1660,3 +2434,69 @@ finish:
     if (pl)
         pa_proplist_free(pl);
 }
+
+/* Called from main context */
+/* Updates the sink input's resampler with whatever the current sink requires
+ * -- useful when the underlying sink's rate might have changed */
+int pa_sink_input_update_rate(pa_sink_input *i) {
+    pa_resampler *new_resampler;
+    char *memblockq_name;
+
+    pa_sink_input_assert_ref(i);
+    pa_assert_ctl_context();
+
+    if (i->thread_info.resampler &&
+        pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &i->sink->sample_spec) &&
+        pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &i->sink->channel_map))
+
+        new_resampler = i->thread_info.resampler;
+
+    else if (!pa_sink_input_is_passthrough(i) &&
+        ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ||
+         !pa_sample_spec_equal(&i->sample_spec, &i->sink->sample_spec) ||
+         !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map))) {
+
+        new_resampler = pa_resampler_new(i->core->mempool,
+                                     &i->sample_spec, &i->channel_map,
+                                     &i->sink->sample_spec, &i->sink->channel_map,
+                                     i->requested_resample_method,
+                                     ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
+                                     ((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));
+
+        if (!new_resampler) {
+            pa_log_warn("Unsupported resampling operation.");
+            return -PA_ERR_NOTSUPPORTED;
+        }
+    } else
+        new_resampler = NULL;
+
+    if (new_resampler == i->thread_info.resampler)
+        return 0;
+
+    if (i->thread_info.resampler)
+        pa_resampler_free(i->thread_info.resampler);
+
+    i->thread_info.resampler = new_resampler;
+
+    pa_memblockq_free(i->thread_info.render_memblockq);
+
+    memblockq_name = pa_sprintf_malloc("sink input render_memblockq [%u]", i->index);
+    i->thread_info.render_memblockq = pa_memblockq_new(
+            memblockq_name,
+            0,
+            MEMBLOCKQ_MAXLENGTH,
+            0,
+            &i->sink->sample_spec,
+            0,
+            1,
+            0,
+            &i->sink->silence);
+    pa_xfree(memblockq_name);
+
+    i->actual_resample_method = new_resampler ? pa_resampler_get_method(new_resampler) : PA_RESAMPLER_INVALID;
+
+    pa_log_debug("Updated resampler for sink input %d", i->index);
+
+    return 0;
+}
index 415a801..760fd8c 100644 (file)
@@ -28,7 +28,7 @@
 typedef struct pa_sink_input pa_sink_input;
 
 #include <pulse/sample.h>
-#include <pulsecore/hook-list.h>
+#include <pulse/format.h>
 #include <pulsecore/memblockq.h>
 #include <pulsecore/resampler.h>
 #include <pulsecore/module.h>
@@ -37,7 +37,7 @@ typedef struct pa_sink_input pa_sink_input;
 #include <pulsecore/core.h>
 
 typedef enum pa_sink_input_state {
-    PA_SINK_INPUT_INIT,         /*< The stream is not active yet, because pa_sink_put() has not been called yet */
+    PA_SINK_INPUT_INIT,         /*< The stream is not active yet, because pa_sink_input_put() has not been called yet */
     PA_SINK_INPUT_DRAINED,      /*< The stream stopped playing because there was no data to play */
     PA_SINK_INPUT_RUNNING,      /*< The stream is alive and kicking */
     PA_SINK_INPUT_CORKED,       /*< The stream was corked on user request */
@@ -60,7 +60,8 @@ typedef enum pa_sink_input_flags {
     PA_SINK_INPUT_FIX_CHANNELS = 128,
     PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND = 256,
     PA_SINK_INPUT_NO_CREATE_ON_SUSPEND = 512,
-    PA_SINK_INPUT_KILL_ON_SUSPEND = 1024
+    PA_SINK_INPUT_KILL_ON_SUSPEND = 1024,
+    PA_SINK_INPUT_PASSTHROUGH = 2048
 } pa_sink_input_flags_t;
 
 struct pa_sink_input {
@@ -81,7 +82,8 @@ struct pa_sink_input {
     pa_module *module;                  /* may be NULL */
     pa_client *client;                  /* may be NULL */
 
-    pa_sink *sink; /* NULL while we are being moved */
+    pa_sink *sink;                      /* NULL while we are being moved */
+    pa_sink *origin_sink;               /* only set by filter sinks */
 
     /* A sink input may be connected to multiple source outputs
      * directly, so that they don't get mixed data of the entire
@@ -90,6 +92,7 @@ struct pa_sink_input {
 
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
+    pa_format_info *format;
 
     pa_sink_input *sync_prev, *sync_next;
 
@@ -97,14 +100,29 @@ struct pa_sink_input {
     pa_cvolume volume;             /* The volume clients are informed about */
     pa_cvolume reference_ratio;    /* The ratio of the stream's volume to the sink's reference volume */
     pa_cvolume real_ratio;         /* The ratio of the stream's volume to the sink's real volume */
-    pa_cvolume volume_factor;      /* An internally used volume factor that can be used by modules to apply effects and suchlike without having that visible to the outside */
-    pa_cvolume soft_volume;        /* The internal software volume we apply to all PCM data while it passes through. Usually calculated as real_ratio * volume_factor */
-
-    pa_cvolume volume_factor_sink; /* A second volume factor in format of the sink this stream is connected to */
+    /* volume_factor is an internally used "additional volume" that can be used
+     * by modules without having the volume visible to clients. volume_factor
+     * calculated by merging all the individual items in volume_factor_items.
+     * Modules must not modify these variables directly, instead
+     * pa_sink_input_add/remove_volume_factor() have to be used to add and
+     * remove items, or pa_sink_input_new_data_add_volume_factor() during input
+     * creation time. */
+    pa_cvolume volume_factor;
+    pa_hashmap *volume_factor_items;
+    pa_cvolume soft_volume;          /* The internal software volume we apply to all PCM data while it passes through. Usually calculated as real_ratio * volume_factor */
+
+    pa_cvolume volume_factor_sink; /* A second volume factor in format of the sink this stream is connected to. */
+    pa_hashmap *volume_factor_sink_items;
+
+    pa_bool_t volume_writable:1;
 
     pa_bool_t muted:1;
 
-    /* if TRUE then the source we are connected to and/or the volume
+#ifdef PA_EXT_USE_VOLUME_FADING
+    pa_queue *fading_queue;
+#endif
+
+    /* 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
      * this.*/
@@ -121,6 +139,11 @@ struct pa_sink_input {
      * the full block. */
     int (*pop) (pa_sink_input *i, size_t request_nbytes, pa_memchunk *chunk); /* may NOT be NULL */
 
+    /* This is called when the playback buffer has actually played back
+       all available data. Return true unless there is more data to play back.
+       Called from IO context. */
+    bool (*process_underrun) (pa_sink_input *i);
+
     /* Rewind the queue by the specified number of bytes. Called just
      * before peek() if it is called at all. Only called if the sink
      * input driver ever plans to call
@@ -139,11 +162,11 @@ struct pa_sink_input {
      * changes. Called from IO context. */
     void (*update_sink_requested_latency) (pa_sink_input *i); /* may be NULL */
 
-    /* Called whenver the latency range of the sink changes. Called
+    /* Called whenever the latency range of the sink changes. Called
      * from IO context. */
     void (*update_sink_latency_range) (pa_sink_input *i); /* may be NULL */
 
-    /* Called whenver the fixed latency of the sink changes, if there
+    /* Called whenever the fixed latency of the sink changes, if there
      * is one. Called from IO context. */
     void (*update_sink_fixed_latency) (pa_sink_input *i); /* may be NULL */
 
@@ -178,7 +201,7 @@ struct pa_sink_input {
      * context. */
     void (*kill) (pa_sink_input *i);             /* may NOT be NULL */
 
-    /* Return the current latency (i.e. length of bufferd audio) of
+    /* Return the current latency (i.e. length of buffered audio) of
     this stream. Called from main context. This is added to what the
     PA_SINK_INPUT_MESSAGE_GET_LATENCY message sent to the IO thread
     returns */
@@ -218,6 +241,7 @@ struct pa_sink_input {
         pa_bool_t rewrite_flush:1, dont_rewind_render:1;
         size_t rewrite_nbytes;
         uint64_t underrun_for, playing_for;
+        uint64_t underrun_for_sink; /* Like underrun_for, but in sink sample spec */
 
         pa_sample_spec sample_spec;
 
@@ -234,6 +258,10 @@ struct pa_sink_input {
         pa_hashmap *direct_outputs;
     } thread_info;
 
+#ifdef __TIZEN__
+    FILE *dump_fp;
+#endif
+
     void *userdata;
 };
 
@@ -248,6 +276,9 @@ enum {
     PA_SINK_INPUT_MESSAGE_SET_STATE,
     PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY,
     PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY,
+#ifdef PA_EXT_USE_VOLUME_FADING
+    PA_SINK_INPUT_MESSAGE_SET_FADE,
+#endif
     PA_SINK_INPUT_MESSAGE_MAX
 };
 
@@ -267,6 +298,7 @@ typedef struct pa_sink_input_new_data {
     pa_client *client;
 
     pa_sink *sink;
+    pa_sink *origin_sink;
 
     pa_resample_method_t resample_method;
 
@@ -274,28 +306,37 @@ typedef struct pa_sink_input_new_data {
 
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
+    pa_format_info *format;
+    pa_idxset *req_formats;
+    pa_idxset *nego_formats;
 
-    pa_cvolume volume, volume_factor, volume_factor_sink;
+    pa_cvolume volume;
     pa_bool_t muted:1;
+    pa_hashmap *volume_factor_items, *volume_factor_sink_items;
 
     pa_bool_t sample_spec_is_set:1;
     pa_bool_t channel_map_is_set:1;
 
-    pa_bool_t volume_is_set:1, volume_factor_is_set:1, volume_factor_sink_is_set:1;
+    pa_bool_t volume_is_set:1;
     pa_bool_t muted_is_set:1;
 
     pa_bool_t volume_is_absolute:1;
 
+    pa_bool_t volume_writable:1;
+
     pa_bool_t save_sink:1, save_volume:1, save_muted:1;
 } pa_sink_input_new_data;
 
 pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data);
 void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec);
 void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map);
+pa_bool_t pa_sink_input_new_data_is_passthrough(pa_sink_input_new_data *data);
 void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume);
-void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, const pa_cvolume *volume_factor);
-void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data *data, const pa_cvolume *volume_factor);
+void pa_sink_input_new_data_add_volume_factor(pa_sink_input_new_data *data, const char *key, const pa_cvolume *volume_factor);
+void pa_sink_input_new_data_add_volume_factor_sink(pa_sink_input_new_data *data, const char *key, const pa_cvolume *volume_factor);
 void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute);
+pa_bool_t pa_sink_input_new_data_set_sink(pa_sink_input_new_data *data, pa_sink *s, pa_bool_t save);
+pa_bool_t pa_sink_input_new_data_set_formats(pa_sink_input_new_data *data, pa_idxset *formats);
 void pa_sink_input_new_data_done(pa_sink_input_new_data *data);
 
 /* To be called by the implementing module only */
@@ -324,6 +365,7 @@ void pa_sink_input_request_rewind(pa_sink_input *i, size_t nbytes, pa_bool_t rew
 void pa_sink_input_cork(pa_sink_input *i, pa_bool_t b);
 
 int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate);
+int pa_sink_input_update_rate(pa_sink_input *i);
 
 /* This returns the sink's fields converted into out sample type */
 size_t pa_sink_input_get_max_rewind(pa_sink_input *i);
@@ -336,7 +378,14 @@ void pa_sink_input_kill(pa_sink_input*i);
 
 pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency);
 
+pa_bool_t pa_sink_input_is_passthrough(pa_sink_input *i);
+pa_bool_t pa_sink_input_is_volume_readable(pa_sink_input *i);
 void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute);
+#ifdef PA_EXT_USE_VOLUME_FADING
+void pa_sink_input_update_sink_fade(pa_sink_input *i, const pa_cvolume *old_volume, const pa_cvolume *new_volume);
+#endif
+void pa_sink_input_add_volume_factor(pa_sink_input *i, const char *key, const pa_cvolume *volume_factor);
+void pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key);
 pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, pa_bool_t absolute);
 
 void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save);
@@ -352,7 +401,7 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, pa_bool_t save);
 pa_bool_t pa_sink_input_may_move(pa_sink_input *i); /* may this sink input move at all? */
 pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest); /* may this sink input move to this sink? */
 
-/* The same as pa_sink_input_move_to() but in two seperate steps,
+/* The same as pa_sink_input_move_to() but in two separate steps,
  * first the detaching from the old sink, then the attaching to the
  * new sink */
 int pa_sink_input_start_move(pa_sink_input *i);
@@ -378,6 +427,8 @@ int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t
 pa_usec_t pa_sink_input_set_requested_latency_within_thread(pa_sink_input *i, pa_usec_t usec);
 
 pa_bool_t pa_sink_input_safe_to_remove(pa_sink_input *i);
+bool pa_sink_input_process_underrun(pa_sink_input *i);
+
 
 pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret);
 
index e6d718f..40e19d7 100644 (file)
 #include <config.h>
 #endif
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stdio.h>
+#ifdef __TIZEN__
+#include <time.h>
+#endif
 
 #include <pulse/introspect.h>
+#include <pulse/format.h>
 #include <pulse/utf8.h>
 #include <pulse/xmalloc.h>
 #include <pulse/timeval.h>
 #include <pulse/util.h>
-#include <pulse/i18n.h>
+#include <pulse/rtclock.h>
+#include <pulse/internal.h>
 
+#include <pulsecore/i18n.h>
 #include <pulsecore/sink-input.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/sample-util.h>
+#include <pulsecore/mix.h>
 #include <pulsecore/core-subscribe.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/play-memblockq.h>
+#include <pulsecore/flist.h>
 
 #include "sink.h"
 
 
 PA_DEFINE_PUBLIC_CLASS(pa_sink, pa_msgobject);
 
+struct pa_sink_volume_change {
+    pa_usec_t at;
+    pa_cvolume hw_volume;
+
+    PA_LLIST_FIELDS(pa_sink_volume_change);
+};
+
+struct sink_message_set_port {
+    pa_device_port *port;
+    int ret;
+};
+
+#ifdef __TIZEN__
+//#define PA_DUMP_SINK_FOR_EACH_SUSPEND
+#define PA_DUMP_SINK_PATH_PREFIX            "/tmp/dump_pa_sink"
+#endif
+
 static void sink_free(pa_object *s);
 
+static void pa_sink_volume_change_push(pa_sink *s);
+static void pa_sink_volume_change_flush(pa_sink *s);
+static void pa_sink_volume_change_rewind(pa_sink *s, size_t nbytes);
+
+#ifdef __TIZEN__
+static void __toggle_open_close_n_write_dump(pa_sink *s, pa_memchunk *target)
+{
+    /* open file for dump pcm */
+    if (s->core->dump_sink && !s->dump_fp) {
+        char *dump_path = NULL, *dump_path_surfix = NULL;
+        const char *s_device_api_str;
+#ifdef PA_DUMP_SINK_FOR_EACH_SUSPEND
+        time_t t;
+        char datetime[12];
+
+        time(&t);
+        memset(&datetime[0], 0x00, sizeof(datetime));
+        strftime(&datetime[0], sizeof(datetime), "%m%d_%H%M%S", localtime(&t));
+#endif
+
+        if ((s_device_api_str = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_API))) {
+            if (pa_streq(s_device_api_str, "alsa")) {
+                const char *card_idx_str, *device_idx_str;
+                uint32_t card_idx = 0, device_idx = 0;
+
+                if ((card_idx_str = pa_proplist_gets(s->proplist, "alsa.card")))
+                    pa_atou(card_idx_str, &card_idx);
+                if ((device_idx_str = pa_proplist_gets(s->proplist, "alsa.device")))
+                    pa_atou(device_idx_str, &device_idx);
+                dump_path_surfix = pa_sprintf_malloc("alsa_%d_%d.pcm", card_idx, device_idx);
+            } else if (pa_streq(s_device_api_str, "bluez")) {
+                dump_path_surfix = pa_sprintf_malloc("bluez.pcm");
+            }
+        }
+        if (!dump_path_surfix) {
+            dump_path_surfix = pa_sprintf_malloc("idx_%d.pcm", s->index);
+        }
+
+#ifdef PA_DUMP_SINK_FOR_EACH_SUSPEND
+        dump_path = pa_sprintf_malloc("%s_%s_%s", PA_DUMP_SINK_PATH_PREFIX, &datetime[0], dump_path_surfix);
+#else
+        dump_path = pa_sprintf_malloc("%s_%s", PA_DUMP_SINK_PATH_PREFIX, dump_path_surfix);
+#endif
+
+        if (dump_path) {
+            s->dump_fp = fopen(dump_path, "w");
+            pa_log_info("pa_sink dump started:%s", dump_path);
+            pa_xfree(dump_path);
+        }
+        if (dump_path_surfix)
+            pa_xfree(dump_path_surfix);
+    /* close file for dump pcm when config is changed */
+    } else if (!s->core->dump_sink && s->dump_fp) {
+        fclose(s->dump_fp);
+        s->dump_fp = NULL;
+    }
+
+    /* dump pcm */
+    if (s->dump_fp) {
+        void *ptr;
+
+        ptr = pa_memblock_acquire(target->memblock);
+
+        fwrite((uint8_t*) ptr + target->index, 1, target->length, s->dump_fp);
+
+        pa_memblock_release(target->memblock);
+    }
+}
+#endif
+
 pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data) {
     pa_assert(data);
 
     pa_zero(*data);
     data->proplist = pa_proplist_new();
+    data->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
 
     return data;
 }
@@ -86,6 +182,13 @@ void pa_sink_new_data_set_channel_map(pa_sink_new_data *data, const pa_channel_m
         data->channel_map = *map;
 }
 
+void pa_sink_new_data_set_alternate_sample_rate(pa_sink_new_data *data, const uint32_t alternate_sample_rate) {
+    pa_assert(data);
+
+    data->alternate_sample_rate_is_set = TRUE;
+    data->alternate_sample_rate = alternate_sample_rate;
+}
+
 void pa_sink_new_data_set_volume(pa_sink_new_data *data, const pa_cvolume *volume) {
     pa_assert(data);
 
@@ -112,40 +215,13 @@ void pa_sink_new_data_done(pa_sink_new_data *data) {
 
     pa_proplist_free(data->proplist);
 
-    if (data->ports) {
-        pa_device_port *p;
-
-        while ((p = pa_hashmap_steal_first(data->ports)))
-            pa_device_port_free(p);
-
-        pa_hashmap_free(data->ports, NULL, NULL);
-    }
+    if (data->ports)
+        pa_hashmap_free(data->ports, (pa_free_cb_t) pa_device_port_unref);
 
     pa_xfree(data->name);
     pa_xfree(data->active_port);
 }
 
-pa_device_port *pa_device_port_new(const char *name, const char *description, size_t extra) {
-    pa_device_port *p;
-
-    pa_assert(name);
-
-    p = pa_xmalloc(PA_ALIGN(sizeof(pa_device_port)) + extra);
-    p->name = pa_xstrdup(name);
-    p->description = pa_xstrdup(description);
-
-    p->priority = 0;
-
-    return p;
-}
-
-void pa_device_port_free(pa_device_port *p) {
-    pa_assert(p);
-
-    pa_xfree(p->name);
-    pa_xfree(p->description);
-    pa_xfree(p);
-}
 
 /* Called from main context */
 static void reset_callbacks(pa_sink *s) {
@@ -154,11 +230,15 @@ static void reset_callbacks(pa_sink *s) {
     s->set_state = NULL;
     s->get_volume = NULL;
     s->set_volume = NULL;
+    s->write_volume = NULL;
     s->get_mute = NULL;
     s->set_mute = NULL;
     s->request_rewind = NULL;
     s->update_requested_latency = NULL;
     s->set_port = NULL;
+    s->get_formats = NULL;
+    s->set_formats = NULL;
+    s->update_rate = NULL;
 }
 
 /* Called from main context */
@@ -208,8 +288,14 @@ pa_sink* pa_sink_new(
     pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
     pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels);
 
-    if (!data->volume_is_set)
+    /* FIXME: There should probably be a general function for checking whether
+     * the sink volume is allowed to be set, like there is for sink inputs. */
+    pa_assert(!data->volume_is_set || !(flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
+
+    if (!data->volume_is_set) {
         pa_cvolume_reset(&data->volume, data->sample_spec.channels);
+        data->save_volume = FALSE;
+    }
 
     pa_return_null_if_fail(pa_cvolume_valid(&data->volume));
     pa_return_null_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec));
@@ -237,7 +323,8 @@ pa_sink* pa_sink_new(
     s->state = PA_SINK_INIT;
     s->flags = flags;
     s->priority = 0;
-    s->suspend_cause = 0;
+    s->suspend_cause = data->suspend_cause;
+    pa_sink_set_mixer_dirty(s, FALSE);
     s->name = pa_xstrdup(name);
     s->proplist = pa_proplist_copy(data->proplist);
     s->driver = pa_xstrdup(pa_path_get_filename(data->driver));
@@ -248,9 +335,21 @@ pa_sink* pa_sink_new(
 
     s->sample_spec = data->sample_spec;
     s->channel_map = data->channel_map;
+    s->default_sample_rate = s->sample_spec.rate;
+
+    if (data->alternate_sample_rate_is_set)
+        s->alternate_sample_rate = data->alternate_sample_rate;
+    else
+        s->alternate_sample_rate = s->core->alternate_sample_rate;
+
+    if (s->sample_spec.rate == s->alternate_sample_rate) {
+        pa_log_warn("Default and alternate sample rates are the same.");
+        s->alternate_sample_rate = 0;
+    }
 
     s->inputs = pa_idxset_new(NULL, NULL);
     s->n_corked = 0;
+    s->input_to_master = NULL;
 
     s->reference_volume = s->real_volume = data->volume;
     pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
@@ -272,11 +371,11 @@ pa_sink* pa_sink_new(
     s->active_port = NULL;
     s->save_port = FALSE;
 
-    if (data->active_port && s->ports)
+    if (data->active_port)
         if ((s->active_port = pa_hashmap_get(s->ports, data->active_port)))
             s->save_port = data->save_port;
 
-    if (!s->active_port && s->ports) {
+    if (!s->active_port) {
         void *state;
         pa_device_port *p;
 
@@ -285,8 +384,16 @@ pa_sink* pa_sink_new(
                 s->active_port = p;
     }
 
+    if (s->active_port)
+        s->latency_offset = s->active_port->latency_offset;
+    else
+        s->latency_offset = 0;
+
     s->save_volume = data->save_volume;
     s->save_muted = data->save_muted;
+#ifdef __TIZEN__
+    s->dump_fp = NULL;
+#endif
 
     pa_silence_memchunk_get(
             &core->silence_cache,
@@ -310,6 +417,13 @@ pa_sink* pa_sink_new(
     s->thread_info.max_latency = ABSOLUTE_MAX_LATENCY;
     s->thread_info.fixed_latency = flags & PA_SINK_DYNAMIC_LATENCY ? 0 : DEFAULT_FIXED_LATENCY;
 
+    PA_LLIST_HEAD_INIT(pa_sink_volume_change, s->thread_info.volume_changes);
+    s->thread_info.volume_changes_tail = NULL;
+    pa_sw_cvolume_multiply(&s->thread_info.current_hw_volume, &s->soft_volume, &s->real_volume);
+    s->thread_info.volume_change_safety_margin = core->deferred_volume_safety_margin_usec;
+    s->thread_info.volume_change_extra_delay = core->deferred_volume_extra_delay_usec;
+    s->thread_info.latency_offset = s->latency_offset;
+
     /* FIXME: This should probably be moved to pa_sink_put() */
     pa_assert_se(pa_idxset_put(core->sinks, s, &s->index) >= 0);
 
@@ -328,6 +442,7 @@ pa_sink* pa_sink_new(
     pa_source_new_data_init(&source_data);
     pa_source_new_data_set_sample_spec(&source_data, &s->sample_spec);
     pa_source_new_data_set_channel_map(&source_data, &s->channel_map);
+    pa_source_new_data_set_alternate_sample_rate(&source_data, s->alternate_sample_rate);
     source_data.name = pa_sprintf_malloc("%s.monitor", name);
     source_data.driver = data->driver;
     source_data.module = data->module;
@@ -358,6 +473,25 @@ pa_sink* pa_sink_new(
     return s;
 }
 
+#ifdef __TIZEN__
+static const char* sink_get_state_string(pa_sink *s, pa_sink_state_t state) {
+    switch(state) {
+        case PA_SINK_INVALID_STATE:
+            return "PA_SINK_INVALID_STATE";
+        case PA_SINK_RUNNING:
+            return "PA_SINK_RUNNING";
+        case PA_SINK_IDLE:
+            return "PA_SINK_IDLE";
+        case PA_SINK_SUSPENDED:
+            return "PA_SINK_SUSPENDED";
+        case PA_SINK_INIT:
+            return "PA_SINK_INIT";
+        case PA_SINK_UNLINKED:
+            return "PA_SINK_UNLINKED";
+    }
+}
+#endif
+
 /* Called from main context */
 static int sink_set_state(pa_sink *s, pa_sink_state_t state) {
     int ret;
@@ -390,8 +524,11 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) {
         }
 
     s->state = state;
-
-    if (state != PA_SINK_UNLINKED) { /* if we enter UNLINKED state pa_sink_unlink() will fire the apropriate events */
+#ifdef __TIZEN__
+    pa_log_info("SINK[%s] state changed (%s) => (%s)", s->name != NULL ? s->name : "noname",
+        sink_get_state_string(s, original_state), sink_get_state_string(s, s->state));
+#endif
+    if (state != PA_SINK_UNLINKED) { /* if we enter UNLINKED state pa_sink_unlink() will fire the appropriate events */
         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], s);
         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
     }
@@ -416,36 +553,194 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) {
     return 0;
 }
 
+void pa_sink_set_get_volume_callback(pa_sink *s, pa_sink_cb_t cb) {
+    pa_assert(s);
+
+    s->get_volume = cb;
+}
+
+void pa_sink_set_set_volume_callback(pa_sink *s, pa_sink_cb_t cb) {
+    pa_sink_flags_t flags;
+
+    pa_assert(s);
+    pa_assert(!s->write_volume || cb);
+
+    s->set_volume = cb;
+
+    /* Save the current flags so we can tell if they've changed */
+    flags = s->flags;
+
+    if (cb) {
+        /* The sink implementor is responsible for setting decibel volume support */
+        s->flags |= PA_SINK_HW_VOLUME_CTRL;
+    } else {
+        s->flags &= ~PA_SINK_HW_VOLUME_CTRL;
+        /* See note below in pa_sink_put() about volume sharing and decibel volumes */
+        pa_sink_enable_decibel_volume(s, !(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
+    }
+
+    /* If the flags have changed after init, let any clients know via a change event */
+    if (s->state != PA_SINK_INIT && flags != s->flags)
+        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+}
+
+void pa_sink_set_write_volume_callback(pa_sink *s, pa_sink_cb_t cb) {
+    pa_sink_flags_t flags;
+
+    pa_assert(s);
+    pa_assert(!cb || s->set_volume);
+
+    s->write_volume = cb;
+
+    /* Save the current flags so we can tell if they've changed */
+    flags = s->flags;
+
+    if (cb)
+        s->flags |= PA_SINK_DEFERRED_VOLUME;
+    else
+        s->flags &= ~PA_SINK_DEFERRED_VOLUME;
+
+    /* If the flags have changed after init, let any clients know via a change event */
+    if (s->state != PA_SINK_INIT && flags != s->flags)
+        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+}
+
+void pa_sink_set_get_mute_callback(pa_sink *s, pa_sink_cb_t cb) {
+    pa_assert(s);
+
+    s->get_mute = cb;
+}
+
+void pa_sink_set_set_mute_callback(pa_sink *s, pa_sink_cb_t cb) {
+    pa_sink_flags_t flags;
+
+    pa_assert(s);
+
+    s->set_mute = cb;
+
+    /* Save the current flags so we can tell if they've changed */
+    flags = s->flags;
+
+    if (cb)
+        s->flags |= PA_SINK_HW_MUTE_CTRL;
+    else
+        s->flags &= ~PA_SINK_HW_MUTE_CTRL;
+
+    /* If the flags have changed after init, let any clients know via a change event */
+    if (s->state != PA_SINK_INIT && flags != s->flags)
+        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+}
+
+static void enable_flat_volume(pa_sink *s, pa_bool_t enable) {
+    pa_sink_flags_t flags;
+
+    pa_assert(s);
+
+    /* Always follow the overall user preference here */
+    enable = enable && s->core->flat_volumes;
+
+    /* Save the current flags so we can tell if they've changed */
+    flags = s->flags;
+
+    if (enable)
+        s->flags |= PA_SINK_FLAT_VOLUME;
+    else
+        s->flags &= ~PA_SINK_FLAT_VOLUME;
+
+    /* If the flags have changed after init, let any clients know via a change event */
+    if (s->state != PA_SINK_INIT && flags != s->flags)
+        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+}
+
+void pa_sink_enable_decibel_volume(pa_sink *s, pa_bool_t enable) {
+    pa_sink_flags_t flags;
+
+    pa_assert(s);
+
+    /* Save the current flags so we can tell if they've changed */
+    flags = s->flags;
+
+    if (enable) {
+        s->flags |= PA_SINK_DECIBEL_VOLUME;
+        enable_flat_volume(s, TRUE);
+    } else {
+        s->flags &= ~PA_SINK_DECIBEL_VOLUME;
+        enable_flat_volume(s, FALSE);
+    }
+
+    /* If the flags have changed after init, let any clients know via a change event */
+    if (s->state != PA_SINK_INIT && flags != s->flags)
+        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+}
+
 /* Called from main context */
 void pa_sink_put(pa_sink* s) {
     pa_sink_assert_ref(s);
     pa_assert_ctl_context();
 
     pa_assert(s->state == PA_SINK_INIT);
+    pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER) || s->input_to_master);
 
     /* The following fields must be initialized properly when calling _put() */
     pa_assert(s->asyncmsgq);
     pa_assert(s->thread_info.min_latency <= s->thread_info.max_latency);
 
     /* Generally, flags should be initialized via pa_sink_new(). As a
-     * special exception we allow volume related flags to be set
-     * between _new() and _put(). */
+     * special exception we allow some volume related flags to be set
+     * between _new() and _put() by the callback setter functions above.
+     *
+     * Thus we implement a couple safeguards here which ensure the above
+     * setters were used (or at least the implementor made manual changes
+     * in a compatible way).
+     *
+     * Note: All of these flags set here can change over the life time
+     * of the sink. */
+    pa_assert(!(s->flags & PA_SINK_HW_VOLUME_CTRL) || s->set_volume);
+    pa_assert(!(s->flags & PA_SINK_DEFERRED_VOLUME) || s->write_volume);
+    pa_assert(!(s->flags & PA_SINK_HW_MUTE_CTRL) || s->set_mute);
+
+    /* XXX: Currently decibel volume is disabled for all sinks that use volume
+     * sharing. When the master sink supports decibel volume, it would be good
+     * to have the flag also in the filter sink, but currently we don't do that
+     * so that the flags of the filter sink never change when it's moved from
+     * a master sink to another. One solution for this problem would be to
+     * remove user-visible volume altogether from filter sinks when volume
+     * sharing is used, but the current approach was easier to implement... */
+    /* We always support decibel volumes in software, otherwise we leave it to
+     * the sink implementor to set this flag as needed.
+     *
+     * Note: This flag can also change over the life time of the sink. */
+    if (!(s->flags & PA_SINK_HW_VOLUME_CTRL) && !(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
+        pa_sink_enable_decibel_volume(s, TRUE);
 
-    if (!(s->flags & PA_SINK_HW_VOLUME_CTRL))
-        s->flags |= PA_SINK_DECIBEL_VOLUME;
+    /* If the sink implementor support DB volumes by itself, we should always
+     * try and enable flat volumes too */
+    if ((s->flags & PA_SINK_DECIBEL_VOLUME))
+        enable_flat_volume(s, TRUE);
 
-    if ((s->flags & PA_SINK_DECIBEL_VOLUME) && s->core->flat_volumes)
-        s->flags |= PA_SINK_FLAT_VOLUME;
+    if (s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER) {
+        pa_sink *root_sink = pa_sink_get_master(s);
+
+        pa_assert(root_sink);
+
+        s->reference_volume = root_sink->reference_volume;
+        pa_cvolume_remap(&s->reference_volume, &root_sink->channel_map, &s->channel_map);
 
-    /* We assume that if the sink implementor changed the default
-     * volume he did so in real_volume, because that is the usual
-     * place where he is supposed to place his changes.  */
-    s->reference_volume = s->real_volume;
+        s->real_volume = root_sink->real_volume;
+        pa_cvolume_remap(&s->real_volume, &root_sink->channel_map, &s->channel_map);
+    } else
+        /* We assume that if the sink implementor changed the default
+         * volume he did so in real_volume, because that is the usual
+         * place where he is supposed to place his changes.  */
+        s->reference_volume = s->real_volume;
 
     s->thread_info.soft_volume = s->soft_volume;
     s->thread_info.soft_muted = s->muted;
+    pa_sw_cvolume_multiply(&s->thread_info.current_hw_volume, &s->soft_volume, &s->real_volume);
 
-    pa_assert((s->flags & PA_SINK_HW_VOLUME_CTRL) || (s->base_volume == PA_VOLUME_NORM && s->flags & PA_SINK_DECIBEL_VOLUME));
+    pa_assert((s->flags & PA_SINK_HW_VOLUME_CTRL)
+              || (s->base_volume == PA_VOLUME_NORM
+                  && ((s->flags & PA_SINK_DECIBEL_VOLUME || (s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)))));
     pa_assert(!(s->flags & PA_SINK_DECIBEL_VOLUME) || s->n_volume_steps == PA_VOLUME_NORM+1);
     pa_assert(!(s->flags & PA_SINK_DYNAMIC_LATENCY) == (s->thread_info.fixed_latency != 0));
     pa_assert(!(s->flags & PA_SINK_LATENCY) == !(s->monitor_source->flags & PA_SOURCE_LATENCY));
@@ -455,7 +750,10 @@ void pa_sink_put(pa_sink* s) {
     pa_assert(s->monitor_source->thread_info.min_latency == s->thread_info.min_latency);
     pa_assert(s->monitor_source->thread_info.max_latency == s->thread_info.max_latency);
 
-    pa_assert_se(sink_set_state(s, PA_SINK_IDLE) == 0);
+    if (s->suspend_cause)
+        pa_assert_se(sink_set_state(s, PA_SINK_SUSPENDED) == 0);
+    else
+        pa_assert_se(sink_set_state(s, PA_SINK_IDLE) == 0);
 
     pa_source_put(s->monitor_source);
 
@@ -516,7 +814,6 @@ void pa_sink_unlink(pa_sink* s) {
 /* Called from main context */
 static void sink_free(pa_object *o) {
     pa_sink *s = PA_SINK(o);
-    pa_sink_input *i;
 
     pa_assert(s);
     pa_assert_ctl_context();
@@ -532,12 +829,8 @@ static void sink_free(pa_object *o) {
         s->monitor_source = NULL;
     }
 
-    pa_idxset_free(s->inputs, NULL, NULL);
-
-    while ((i = pa_hashmap_steal_first(s->thread_info.inputs)))
-        pa_sink_input_unref(i);
-
-    pa_hashmap_free(s->thread_info.inputs, NULL, NULL);
+    pa_idxset_free(s->inputs, NULL);
+    pa_hashmap_free(s->thread_info.inputs, (pa_free_cb_t) pa_sink_input_unref);
 
     if (s->silence.memblock)
         pa_memblock_unref(s->silence.memblock);
@@ -548,14 +841,16 @@ static void sink_free(pa_object *o) {
     if (s->proplist)
         pa_proplist_free(s->proplist);
 
-    if (s->ports) {
-        pa_device_port *p;
+    if (s->ports)
+        pa_hashmap_free(s->ports, (pa_free_cb_t) pa_device_port_unref);
 
-        while ((p = pa_hashmap_steal_first(s->ports)))
-            pa_device_port_free(p);
-
-        pa_hashmap_free(s->ports, NULL, NULL);
+#ifdef __TIZEN__
+    /* close file for dump pcm */
+    if (s->dump_fp) {
+        fclose(s->dump_fp);
+        s->dump_fp = NULL;
     }
+#endif
 
     pa_xfree(s);
 }
@@ -573,22 +868,43 @@ void pa_sink_set_asyncmsgq(pa_sink *s, pa_asyncmsgq *q) {
 
 /* Called from main context, and not while the IO thread is active, please */
 void pa_sink_update_flags(pa_sink *s, pa_sink_flags_t mask, pa_sink_flags_t value) {
+    pa_sink_flags_t old_flags;
+    pa_sink_input *input;
+    uint32_t idx;
+
     pa_sink_assert_ref(s);
     pa_assert_ctl_context();
 
-    if (mask == 0)
-        return;
-
     /* For now, allow only a minimal set of flags to be changed. */
     pa_assert((mask & ~(PA_SINK_DYNAMIC_LATENCY|PA_SINK_LATENCY)) == 0);
 
+    old_flags = s->flags;
     s->flags = (s->flags & ~mask) | (value & mask);
 
-    pa_source_update_flags(s->monitor_source,
-                           ((mask & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
-                           ((mask & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0),
-                           ((value & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
-                           ((value & PA_SINK_DYNAMIC_LATENCY) ? PA_SINK_DYNAMIC_LATENCY : 0));
+    if (s->flags == old_flags)
+        return;
+
+    if ((s->flags & PA_SINK_LATENCY) != (old_flags & PA_SINK_LATENCY))
+        pa_log_debug("Sink %s: LATENCY flag %s.", s->name, (s->flags & PA_SINK_LATENCY) ? "enabled" : "disabled");
+
+    if ((s->flags & PA_SINK_DYNAMIC_LATENCY) != (old_flags & PA_SINK_DYNAMIC_LATENCY))
+        pa_log_debug("Sink %s: DYNAMIC_LATENCY flag %s.",
+                     s->name, (s->flags & PA_SINK_DYNAMIC_LATENCY) ? "enabled" : "disabled");
+
+    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_FLAGS_CHANGED], s);
+
+    if (s->monitor_source)
+        pa_source_update_flags(s->monitor_source,
+                               ((mask & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
+                               ((mask & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0),
+                               ((value & PA_SINK_LATENCY) ? PA_SOURCE_LATENCY : 0) |
+                               ((value & PA_SINK_DYNAMIC_LATENCY) ? PA_SOURCE_DYNAMIC_LATENCY : 0));
+
+    PA_IDXSET_FOREACH(input, s->inputs, idx) {
+        if (input->origin_sink)
+            pa_sink_update_flags(input->origin_sink, mask, value);
+    }
 }
 
 /* Called from IO context, or before _put() from main context */
@@ -614,8 +930,17 @@ int pa_sink_update_status(pa_sink*s) {
     return sink_set_state(s, pa_sink_used_by(s) ? PA_SINK_RUNNING : PA_SINK_IDLE);
 }
 
+/* Called from any context - must be threadsafe */
+void pa_sink_set_mixer_dirty(pa_sink *s, pa_bool_t is_dirty)
+{
+    pa_atomic_store(&s->mixer_dirty, is_dirty ? 1 : 0);
+}
+
 /* Called from main context */
 int pa_sink_suspend(pa_sink *s, pa_bool_t suspend, pa_suspend_cause_t cause) {
+#ifdef __TIZEN__
+    int ret = 0;
+#endif
     pa_sink_assert_ref(s);
     pa_assert_ctl_context();
     pa_assert(PA_SINK_IS_LINKED(s->state));
@@ -629,14 +954,65 @@ int pa_sink_suspend(pa_sink *s, pa_bool_t suspend, pa_suspend_cause_t cause) {
         s->monitor_source->suspend_cause &= ~cause;
     }
 
-    if ((pa_sink_get_state(s) == PA_SINK_SUSPENDED) == !!s->suspend_cause)
+    if (!(s->suspend_cause & PA_SUSPEND_SESSION) && (pa_atomic_load(&s->mixer_dirty) != 0)) {
+        /* This might look racy but isn't: If somebody sets mixer_dirty exactly here,
+           it'll be handled just fine. */
+        pa_sink_set_mixer_dirty(s, FALSE);
+        pa_log_debug("Mixer is now accessible. Updating alsa mixer settings.");
+        if (s->active_port && s->set_port) {
+            if (s->flags & PA_SINK_DEFERRED_VOLUME) {
+                struct sink_message_set_port msg = { .port = s->active_port, .ret = 0 };
+                pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
+            }
+            else
+                s->set_port(s, s->active_port);
+        }
+        else {
+            if (s->set_mute)
+                s->set_mute(s);
+            if (s->set_volume)
+                s->set_volume(s);
+        }
+    }
+
+    if ((pa_sink_get_state(s) == PA_SINK_SUSPENDED) == !!s->suspend_cause) {
+#ifdef __TIZEN__
+        if (cause == PA_SUSPEND_SWITCH) {
+            /* Clear suspend by switch after manual suspend */
+            s->suspend_cause &= ~cause;
+        }
+#endif
         return 0;
+    }
 
-    pa_log_debug("Suspend cause of sink %s is 0x%04x, %s", s->name, s->suspend_cause, s->suspend_cause ? "suspending" : "resuming");
+    pa_log_debug_verbose("Suspend cause of sink %s is 0x%04x, %s", s->name, s->suspend_cause, s->suspend_cause ? "suspending" : "resuming");
+
+#ifdef __TIZEN__
+#ifdef PA_DUMP_SINK_FOR_EACH_SUSPEND
+    /* close file for dump pcm */
+    if (suspend && s->dump_in_fp) {
+        fclose(s->dump_in_fp);
+        s->dump_in_fp = NULL;
+    }
+    if (suspend && s->dump_out_fp) {
+        fclose(s->dump_out_fp);
+        s->dump_out_fp = NULL;
+    }
+#endif
 
+    if (s->suspend_cause) {
+        ret = sink_set_state(s, PA_SINK_SUSPENDED);
+        if (ret == 0 && cause == PA_SUSPEND_SWITCH) {
+            /* Clear suspend by switch after manual suspend */
+            s->suspend_cause &= ~cause;
+        }
+        return ret;
+    } else
+#else
     if (s->suspend_cause)
         return sink_set_state(s, PA_SINK_SUSPENDED);
     else
+#endif /* __TIZEN__ */
         return sink_set_state(s, pa_sink_used_by(s) ? PA_SINK_RUNNING : PA_SINK_IDLE);
 }
 
@@ -682,7 +1058,7 @@ void pa_sink_move_all_finish(pa_sink *s, pa_queue *q, pa_bool_t save) {
         pa_sink_input_unref(i);
     }
 
-    pa_queue_free(q, NULL, NULL);
+    pa_queue_free(q, NULL);
 }
 
 /* Called from main context */
@@ -697,7 +1073,33 @@ void pa_sink_move_all_fail(pa_queue *q) {
         pa_sink_input_unref(i);
     }
 
-    pa_queue_free(q, NULL, NULL);
+    pa_queue_free(q, NULL);
+}
+
+ /* Called from IO thread context */
+size_t pa_sink_process_input_underruns(pa_sink *s, size_t left_to_play) {
+    pa_sink_input *i;
+    void *state = NULL;
+    size_t result = 0;
+
+    pa_sink_assert_ref(s);
+    pa_sink_assert_io_context(s);
+
+    PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
+        size_t uf = i->thread_info.underrun_for_sink;
+        if (uf == 0)
+            continue;
+        if (uf >= left_to_play) {
+            if (pa_sink_input_process_underrun(i))
+                continue;
+        }
+        else if (uf > result)
+            result = uf;
+    }
+
+    if (result > 0)
+        pa_log_debug_verbose("Found underrun %ld bytes ago (%ld bytes ahead in playback buffer)", (long) result, (long) left_to_play - result);
+    return left_to_play - result;
 }
 
 /* Called from IO thread context */
@@ -719,20 +1121,27 @@ void pa_sink_process_rewind(pa_sink *s, size_t nbytes) {
     s->thread_info.rewind_nbytes = 0;
     s->thread_info.rewind_requested = FALSE;
 
-    if (s->thread_info.state == PA_SINK_SUSPENDED)
-        return;
-
-    if (nbytes > 0)
-        pa_log_debug("Processing rewind...");
+    if (nbytes > 0) {
+        pa_log_debug_verbose("Processing rewind...");
+        if (s->flags & PA_SINK_DEFERRED_VOLUME)
+            pa_sink_volume_change_rewind(s, nbytes);
+#ifdef __TIZEN__
+        /* rewind pcm */
+        if (s->dump_fp) {
+            fseeko(s->dump_fp, (off_t)nbytes * (-1), SEEK_CUR);
+        }
+#endif
+    }
 
     PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
         pa_sink_input_assert_ref(i);
         pa_sink_input_process_rewind(i, nbytes);
     }
 
-    if (nbytes > 0)
+    if (nbytes > 0) {
         if (s->monitor_source && PA_SOURCE_IS_LINKED(s->monitor_source->thread_info.state))
             pa_source_process_rewind(s->monitor_source, nbytes);
+    }
 }
 
 /* Called from IO thread context */
@@ -826,6 +1235,9 @@ static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned n, pa_memchunk *
                     c.length = result->length;
 
                     pa_memchunk_make_writable(&c, 0);
+#ifdef PA_EXT_USE_VOLUME_FADING
+                    pa_cvolume_fading_update(&m->volume, &i->thread_info.soft_volume);
+#endif
                     pa_volume_memchunk(&c, &s->sample_spec, &m->volume);
                 } else {
                     c = s->silence;
@@ -925,8 +1337,17 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
             result->length = length;
 
         pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume);
+#ifdef PA_EXT_USE_VOLUME_FADING
+        pa_cvolume_fading_update(&volume, &info[0].volume);
+        pa_cvolume_fading_multiply(&s->thread_info.soft_volume, &volume);
+#endif
 
-        if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume)) {
+        if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume)
+#ifdef PA_EXT_USE_VOLUME_FADING
+            && !(pa_cvolume_fading_valid(&volume)
+                && (volume.fading_info->remain_frames > 0))
+#endif
+        ) {
             pa_memblock_unref(result->memblock);
             pa_silence_memchunk_get(&s->core->silence_cache,
                                     s->core->mempool,
@@ -954,6 +1375,10 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
 
     inputs_drop(s, info, n, result);
 
+#ifdef __TIZEN__
+    __toggle_open_close_n_write_dump(s, result);
+#endif
+
     pa_sink_unref(s);
 }
 
@@ -1002,8 +1427,17 @@ void pa_sink_render_into(pa_sink*s, pa_memchunk *target) {
             target->length = length;
 
         pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume);
+#ifdef PA_EXT_USE_VOLUME_FADING
+        pa_cvolume_fading_update(&volume, &info[0].volume);
+        pa_cvolume_fading_multiply(&s->thread_info.soft_volume, &volume);
+#endif
 
-        if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume))
+        if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume)
+#ifdef PA_EXT_USE_VOLUME_FADING
+            && !(pa_cvolume_fading_valid(&volume)
+                && (volume.fading_info->remain_frames > 0))
+#endif
+        )
             pa_silence_memchunk(target, &s->sample_spec);
         else {
             pa_memchunk vchunk;
@@ -1037,8 +1471,32 @@ void pa_sink_render_into(pa_sink*s, pa_memchunk *target) {
         pa_memblock_release(target->memblock);
     }
 
+#ifdef __TIZEN__
+    {
+        /**
+          * This section is added to pack 24bits of data in upper 3bytes of s24-32le format.
+          * This is required because ALSA expect the 24bits of data to be filled in upper three byte of 32bitf of S24_LE format.
+          * But pulseaudio expects the 24bits of data in lower 3bytes of s24-32le format.
+          */
+        int *siptr = (int *) ( pa_memblock_acquire(target->memblock) + target->index);
+        if( PA_SAMPLE_S24_32LE == s->sample_spec.format){
+
+            int max_iteration = target->length/4;
+            for(int tmp = 0; tmp<max_iteration; tmp++){
+                *siptr = (*siptr)<<8;
+                siptr++;
+            }
+        }
+        pa_memblock_release(target->memblock);
+    }
+#endif
+
     inputs_drop(s, info, n, target);
 
+#ifdef __TIZEN__
+    __toggle_open_close_n_write_dump(s, target);
+#endif
+
     pa_sink_unref(s);
 }
 
@@ -1115,6 +1573,87 @@ void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) {
 }
 
 /* Called from main thread */
+pa_bool_t pa_sink_update_rate(pa_sink *s, uint32_t rate, pa_bool_t passthrough)
+{
+    if (s->update_rate) {
+        uint32_t desired_rate = rate;
+        uint32_t default_rate = s->default_sample_rate;
+        uint32_t alternate_rate = s->alternate_sample_rate;
+        uint32_t idx;
+        pa_sink_input *i;
+        pa_bool_t use_alternate = FALSE;
+
+        if (PA_UNLIKELY(default_rate == alternate_rate)) {
+            pa_log_warn("Default and alternate sample rates are the same.");
+            return FALSE;
+        }
+
+        if (PA_SINK_IS_RUNNING(s->state)) {
+            pa_log_info("Cannot update rate, SINK_IS_RUNNING, will keep using %u Hz",
+                        s->sample_spec.rate);
+            return FALSE;
+        }
+
+        if (s->monitor_source) {
+            if (PA_SOURCE_IS_RUNNING(s->monitor_source->state) == TRUE) {
+                pa_log_info("Cannot update rate, monitor source is RUNNING");
+                return FALSE;
+            }
+        }
+
+        if (PA_UNLIKELY (desired_rate < 8000 ||
+                         desired_rate > PA_RATE_MAX))
+            return FALSE;
+
+        if (!passthrough) {
+            pa_assert(default_rate % 4000 || default_rate % 11025);
+            pa_assert(alternate_rate % 4000 || alternate_rate % 11025);
+
+            if (default_rate % 4000) {
+                /* default is a 11025 multiple */
+                if ((alternate_rate % 4000 == 0) && (desired_rate % 4000 == 0))
+                    use_alternate=TRUE;
+            } else {
+                /* default is 4000 multiple */
+                if ((alternate_rate % 11025 == 0) && (desired_rate % 11025 == 0))
+                    use_alternate=TRUE;
+            }
+
+            if (use_alternate)
+                desired_rate = alternate_rate;
+            else
+                desired_rate = default_rate;
+        } else {
+            desired_rate = rate; /* use stream sampling rate, discard default/alternate settings */
+        }
+
+        if (desired_rate == s->sample_spec.rate)
+            return FALSE;
+
+        if (!passthrough && pa_sink_used_by(s) > 0)
+            return FALSE;
+
+        pa_log_debug("Suspending sink %s due to changing the sample rate.", s->name);
+        pa_sink_suspend(s, TRUE, PA_SUSPEND_IDLE); /* needed before rate update, will be resumed automatically */
+
+        if (s->update_rate(s, desired_rate) == TRUE) {
+            /* update monitor source as well */
+            if (s->monitor_source && !passthrough)
+                pa_source_update_rate(s->monitor_source, desired_rate, FALSE);
+            pa_log_info("Changed sampling rate successfully");
+
+            PA_IDXSET_FOREACH(i, s->inputs, idx) {
+                if (i->state == PA_SINK_INPUT_CORKED)
+                    pa_sink_input_update_rate(i);
+            }
+
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+/* Called from main thread */
 pa_usec_t pa_sink_get_latency(pa_sink *s) {
     pa_usec_t usec = 0;
 
@@ -1132,6 +1671,13 @@ pa_usec_t pa_sink_get_latency(pa_sink *s) {
 
     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) == 0);
 
+    /* usec is unsigned, so check that the offset can be added to usec without
+     * underflowing. */
+    if (-s->latency_offset <= (int64_t) usec)
+        usec += s->latency_offset;
+    else
+        usec = 0;
+
     return usec;
 }
 
@@ -1159,55 +1705,158 @@ pa_usec_t pa_sink_get_latency_within_thread(pa_sink *s) {
     if (o->process_msg(o, PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0)
         return -1;
 
+    /* usec is unsigned, so check that the offset can be added to usec without
+     * underflowing. */
+    if (-s->thread_info.latency_offset <= (int64_t) usec)
+        usec += s->thread_info.latency_offset;
+    else
+        usec = 0;
+
     return usec;
 }
 
+/* Called from the main thread (and also from the IO thread while the main
+ * thread is waiting).
+ *
+ * When a sink uses volume sharing, it never has the PA_SINK_FLAT_VOLUME flag
+ * set. Instead, flat volume mode is detected by checking whether the root sink
+ * has the flag set. */
+pa_bool_t pa_sink_flat_volume_enabled(pa_sink *s) {
+    pa_sink_assert_ref(s);
+
+    s = pa_sink_get_master(s);
+
+    if (PA_LIKELY(s))
+        return (s->flags & PA_SINK_FLAT_VOLUME);
+    else
+        return FALSE;
+}
+
+/* Called from the main thread (and also from the IO thread while the main
+ * thread is waiting). */
+pa_sink *pa_sink_get_master(pa_sink *s) {
+    pa_sink_assert_ref(s);
+
+    while (s && (s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
+        if (PA_UNLIKELY(!s->input_to_master))
+            return NULL;
+
+        s = s->input_to_master->sink;
+    }
+
+    return s;
+}
+
 /* Called from main context */
-static void compute_reference_ratios(pa_sink *s) {
+pa_bool_t pa_sink_is_passthrough(pa_sink *s) {
+    pa_sink_input *alt_i;
     uint32_t idx;
-    pa_sink_input *i;
 
     pa_sink_assert_ref(s);
-    pa_assert_ctl_context();
-    pa_assert(PA_SINK_IS_LINKED(s->state));
-    pa_assert(s->flags & PA_SINK_FLAT_VOLUME);
 
-    PA_IDXSET_FOREACH(i, s->inputs, idx) {
-        unsigned c;
-        pa_cvolume remapped;
+    /* one and only one PASSTHROUGH input can possibly be connected */
+    if (pa_idxset_size(s->inputs) == 1) {
+        alt_i = pa_idxset_first(s->inputs, &idx);
 
-        /*
-         * Calculates the reference volume from the sink's reference
-         * volume. This basically calculates:
-         *
-         * i->reference_ratio = i->volume / s->reference_volume
-         */
+        if (pa_sink_input_is_passthrough(alt_i))
+            return TRUE;
+    }
 
-        remapped = s->reference_volume;
-        pa_cvolume_remap(&remapped, &s->channel_map, &i->channel_map);
+    return FALSE;
+}
 
-        i->reference_ratio.channels = i->sample_spec.channels;
+/* Called from main context */
+void pa_sink_enter_passthrough(pa_sink *s) {
+    pa_cvolume volume;
 
-        for (c = 0; c < i->sample_spec.channels; c++) {
+    /* disable the monitor in passthrough mode */
+    if (s->monitor_source) {
+        pa_log_debug("Suspending monitor source %s, because the sink is entering the passthrough mode.", s->monitor_source->name);
+        pa_source_suspend(s->monitor_source, TRUE, PA_SUSPEND_PASSTHROUGH);
+    }
 
-            /* We don't update when the sink volume is 0 anyway */
-            if (remapped.values[c] <= PA_VOLUME_MUTED)
-                continue;
+    /* set the volume to NORM */
+    s->saved_volume = *pa_sink_get_volume(s, TRUE);
+    s->saved_save_volume = s->save_volume;
 
-            /* Don't update the reference ratio unless necessary */
-            if (pa_sw_volume_multiply(
-                        i->reference_ratio.values[c],
-                        remapped.values[c]) == i->volume.values[c])
-                continue;
+    pa_cvolume_set(&volume, s->sample_spec.channels, PA_MIN(s->base_volume, PA_VOLUME_NORM));
+    pa_sink_set_volume(s, &volume, TRUE, FALSE);
+}
 
-            i->reference_ratio.values[c] = pa_sw_volume_divide(
-                    i->volume.values[c],
-                    remapped.values[c]);
-        }
+/* Called from main context */
+void pa_sink_leave_passthrough(pa_sink *s) {
+    /* Unsuspend monitor */
+    if (s->monitor_source) {
+        pa_log_debug("Resuming monitor source %s, because the sink is leaving the passthrough mode.", s->monitor_source->name);
+        pa_source_suspend(s->monitor_source, FALSE, PA_SUSPEND_PASSTHROUGH);
     }
+
+    /* Restore sink volume to what it was before we entered passthrough mode */
+    pa_sink_set_volume(s, &s->saved_volume, TRUE, s->saved_save_volume);
+
+    pa_cvolume_init(&s->saved_volume);
+    s->saved_save_volume = FALSE;
 }
 
-/* Called from main context */
+/* Called from main context. */
+static void compute_reference_ratio(pa_sink_input *i) {
+    unsigned c = 0;
+    pa_cvolume remapped;
+
+    pa_assert(i);
+    pa_assert(pa_sink_flat_volume_enabled(i->sink));
+
+    /*
+     * Calculates the reference ratio from the sink's reference
+     * volume. This basically calculates:
+     *
+     * i->reference_ratio = i->volume / i->sink->reference_volume
+     */
+
+    remapped = i->sink->reference_volume;
+    pa_cvolume_remap(&remapped, &i->sink->channel_map, &i->channel_map);
+
+    i->reference_ratio.channels = i->sample_spec.channels;
+
+    for (c = 0; c < i->sample_spec.channels; c++) {
+
+        /* We don't update when the sink volume is 0 anyway */
+        if (remapped.values[c] <= PA_VOLUME_MUTED)
+            continue;
+
+        /* Don't update the reference ratio unless necessary */
+        if (pa_sw_volume_multiply(
+                    i->reference_ratio.values[c],
+                    remapped.values[c]) == i->volume.values[c])
+            continue;
+
+        i->reference_ratio.values[c] = pa_sw_volume_divide(
+                i->volume.values[c],
+                remapped.values[c]);
+    }
+}
+
+/* Called from main context. Only called for the root sink in volume sharing
+ * cases, except for internal recursive calls. */
+static void compute_reference_ratios(pa_sink *s) {
+    uint32_t idx;
+    pa_sink_input *i;
+
+    pa_sink_assert_ref(s);
+    pa_assert_ctl_context();
+    pa_assert(PA_SINK_IS_LINKED(s->state));
+    pa_assert(pa_sink_flat_volume_enabled(s));
+
+    PA_IDXSET_FOREACH(i, s->inputs, idx) {
+        compute_reference_ratio(i);
+
+        if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
+            compute_reference_ratios(i->origin_sink);
+    }
+}
+
+/* Called from main context. Only called for the root sink in volume sharing
+ * cases, except for internal recursive calls. */
 static void compute_real_ratios(pa_sink *s) {
     pa_sink_input *i;
     uint32_t idx;
@@ -1215,12 +1864,24 @@ static void compute_real_ratios(pa_sink *s) {
     pa_sink_assert_ref(s);
     pa_assert_ctl_context();
     pa_assert(PA_SINK_IS_LINKED(s->state));
-    pa_assert(s->flags & PA_SINK_FLAT_VOLUME);
+    pa_assert(pa_sink_flat_volume_enabled(s));
 
     PA_IDXSET_FOREACH(i, s->inputs, idx) {
         unsigned c;
         pa_cvolume remapped;
 
+        if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
+            /* The origin sink uses volume sharing, so this input's real ratio
+             * is handled as a special case - the real ratio must be 0 dB, and
+             * as a result i->soft_volume must equal i->volume_factor. */
+            pa_cvolume_reset(&i->real_ratio, i->real_ratio.channels);
+            i->soft_volume = i->volume_factor;
+
+            compute_real_ratios(i->origin_sink);
+
+            continue;
+        }
+
         /*
          * This basically calculates:
          *
@@ -1261,23 +1922,153 @@ static void compute_real_ratios(pa_sink *s) {
     }
 }
 
-/* Called from main thread */
-static void compute_real_volume(pa_sink *s) {
+static pa_cvolume *cvolume_remap_minimal_impact(
+        pa_cvolume *v,
+        const pa_cvolume *template,
+        const pa_channel_map *from,
+        const pa_channel_map *to) {
+
+    pa_cvolume t;
+
+    pa_assert(v);
+    pa_assert(template);
+    pa_assert(from);
+    pa_assert(to);
+    pa_assert(pa_cvolume_compatible_with_channel_map(v, from));
+    pa_assert(pa_cvolume_compatible_with_channel_map(template, to));
+
+    /* Much like pa_cvolume_remap(), but tries to minimize impact when
+     * mapping from sink input to sink volumes:
+     *
+     * If template is a possible remapping from v it is used instead
+     * of remapping anew.
+     *
+     * If the channel maps don't match we set an all-channel volume on
+     * the sink to ensure that changing a volume on one stream has no
+     * effect that cannot be compensated for in another stream that
+     * does not have the same channel map as the sink. */
+
+    if (pa_channel_map_equal(from, to))
+        return v;
+
+    t = *template;
+    if (pa_cvolume_equal(pa_cvolume_remap(&t, to, from), v)) {
+        *v = *template;
+        return v;
+    }
+
+    pa_cvolume_set(v, to->channels, pa_cvolume_max(v));
+    return v;
+}
+
+/* Called from main thread. Only called for the root sink in volume sharing
+ * cases, except for internal recursive calls. */
+static void get_maximum_input_volume(pa_sink *s, pa_cvolume *max_volume, const pa_channel_map *channel_map) {
     pa_sink_input *i;
     uint32_t idx;
 
     pa_sink_assert_ref(s);
+    pa_assert(max_volume);
+    pa_assert(channel_map);
+    pa_assert(pa_sink_flat_volume_enabled(s));
+
+    PA_IDXSET_FOREACH(i, s->inputs, idx) {
+        pa_cvolume remapped;
+
+        if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
+            get_maximum_input_volume(i->origin_sink, max_volume, channel_map);
+
+            /* Ignore this input. The origin sink uses volume sharing, so this
+             * input's volume will be set to be equal to the root sink's real
+             * volume. Obviously this input's current volume must not then
+             * affect what the root sink's real volume will be. */
+            continue;
+        }
+
+        remapped = i->volume;
+        cvolume_remap_minimal_impact(&remapped, max_volume, &i->channel_map, channel_map);
+        pa_cvolume_merge(max_volume, max_volume, &remapped);
+    }
+}
+
+/* Called from main thread. Only called for the root sink in volume sharing
+ * cases, except for internal recursive calls. */
+static pa_bool_t has_inputs(pa_sink *s) {
+    pa_sink_input *i;
+    uint32_t idx;
+
+    pa_sink_assert_ref(s);
+
+    PA_IDXSET_FOREACH(i, s->inputs, idx) {
+        if (!i->origin_sink || !(i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER) || has_inputs(i->origin_sink))
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+/* Called from main thread. Only called for the root sink in volume sharing
+ * cases, except for internal recursive calls. */
+static void update_real_volume(pa_sink *s, const pa_cvolume *new_volume, pa_channel_map *channel_map) {
+    pa_sink_input *i;
+    pa_cvolume ori_volume;
+    uint32_t idx;
+
+    pa_sink_assert_ref(s);
+    pa_assert(new_volume);
+    pa_assert(channel_map);
+
+#ifdef PA_EXT_USE_VOLUME_FADING
+    ori_volume = s->real_volume;
+#endif
+    s->real_volume = *new_volume;
+    pa_cvolume_remap(&s->real_volume, channel_map, &s->channel_map);
+
+    PA_IDXSET_FOREACH(i, s->inputs, idx) {
+        if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
+            if (pa_sink_flat_volume_enabled(s)) {
+                pa_cvolume old_volume = i->volume;
+
+                /* Follow the root sink's real volume. */
+                i->volume = *new_volume;
+                pa_cvolume_remap(&i->volume, channel_map, &i->channel_map);
+                compute_reference_ratio(i);
+
+                /* The volume changed, let's tell people so */
+                if (!pa_cvolume_equal(&old_volume, &i->volume)) {
+                    if (i->volume_changed)
+                        i->volume_changed(i);
+
+                    pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
+                }
+            }
+
+            update_real_volume(i->origin_sink, new_volume, channel_map);
+        }
+#ifdef PA_EXT_USE_VOLUME_FADING
+        if(!pa_streq(i->module->name,"module-remap-sink")) {
+            pa_sink_input_update_sink_fade(i, &ori_volume, new_volume);
+        }
+#endif
+    }
+}
+
+/* Called from main thread. Only called for the root sink in shared volume
+ * cases. */
+static void compute_real_volume(pa_sink *s) {
+    pa_sink_assert_ref(s);
     pa_assert_ctl_context();
     pa_assert(PA_SINK_IS_LINKED(s->state));
-    pa_assert(s->flags & PA_SINK_FLAT_VOLUME);
+    pa_assert(pa_sink_flat_volume_enabled(s));
+    pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
 
     /* This determines the maximum volume of all streams and sets
      * s->real_volume accordingly. */
 
-    if (pa_idxset_isempty(s->inputs)) {
-        /* In the special case that we have no sink input we leave the
+    if (!has_inputs(s)) {
+        /* In the special case that we have no sink inputs we leave the
          * volume unmodified. */
-        s->real_volume = s->reference_volume;
+        update_real_volume(s, &s->reference_volume, &s->channel_map);
         return;
     }
 
@@ -1285,20 +2076,16 @@ static void compute_real_volume(pa_sink *s) {
 
     /* First let's determine the new maximum volume of all inputs
      * connected to this sink */
-    PA_IDXSET_FOREACH(i, s->inputs, idx) {
-        pa_cvolume remapped;
-
-        remapped = i->volume;
-        pa_cvolume_remap(&remapped, &i->channel_map, &s->channel_map);
-        pa_cvolume_merge(&s->real_volume, &s->real_volume, &remapped);
-    }
+    get_maximum_input_volume(s, &s->real_volume, &s->channel_map);
+    update_real_volume(s, &s->real_volume, &s->channel_map);
 
     /* Then, let's update the real ratios/soft volumes of all inputs
      * connected to this sink */
     compute_real_ratios(s);
 }
 
-/* Called from main thread */
+/* Called from main thread. Only called for the root sink in shared volume
+ * cases, except for internal recursive calls. */
 static void propagate_reference_volume(pa_sink *s) {
     pa_sink_input *i;
     uint32_t idx;
@@ -1306,14 +2093,23 @@ static void propagate_reference_volume(pa_sink *s) {
     pa_sink_assert_ref(s);
     pa_assert_ctl_context();
     pa_assert(PA_SINK_IS_LINKED(s->state));
-    pa_assert(s->flags & PA_SINK_FLAT_VOLUME);
+    pa_assert(pa_sink_flat_volume_enabled(s));
 
     /* This is called whenever the sink volume changes that is not
      * caused by a sink input volume change. We need to fix up the
      * sink input volumes accordingly */
 
     PA_IDXSET_FOREACH(i, s->inputs, idx) {
-        pa_cvolume old_volume, remapped;
+        pa_cvolume old_volume;
+
+        if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
+            propagate_reference_volume(i->origin_sink);
+
+            /* Since the origin sink uses volume sharing, this input's volume
+             * needs to be updated to match the root sink's real volume, but
+             * that will be done later in update_shared_real_volume(). */
+            continue;
+        }
 
         old_volume = i->volume;
 
@@ -1321,9 +2117,9 @@ static void propagate_reference_volume(pa_sink *s) {
          *
          * i->volume := s->reference_volume * i->reference_ratio  */
 
-        remapped = s->reference_volume;
-        pa_cvolume_remap(&remapped, &s->channel_map, &i->channel_map);
-        pa_sw_cvolume_multiply(&i->volume, &remapped, &i->reference_ratio);
+        i->volume = s->reference_volume;
+        pa_cvolume_remap(&i->volume, &s->channel_map, &i->channel_map);
+        pa_sw_cvolume_multiply(&i->volume, &i->volume, &i->reference_ratio);
 
         /* The volume changed, let's tell people so */
         if (!pa_cvolume_equal(&old_volume, &i->volume)) {
@@ -1336,108 +2132,180 @@ static void propagate_reference_volume(pa_sink *s) {
     }
 }
 
+/* Called from main thread. Only called for the root sink in volume sharing
+ * cases, except for internal recursive calls. The return value indicates
+ * whether any reference volume actually changed. */
+static pa_bool_t update_reference_volume(pa_sink *s, const pa_cvolume *v, const pa_channel_map *channel_map, pa_bool_t save) {
+    pa_cvolume volume;
+    pa_bool_t reference_volume_changed;
+    pa_sink_input *i;
+    uint32_t idx;
+
+    pa_sink_assert_ref(s);
+    pa_assert(PA_SINK_IS_LINKED(s->state));
+    pa_assert(v);
+    pa_assert(channel_map);
+    pa_assert(pa_cvolume_valid(v));
+
+    volume = *v;
+    pa_cvolume_remap(&volume, channel_map, &s->channel_map);
+
+    reference_volume_changed = !pa_cvolume_equal(&volume, &s->reference_volume);
+    s->reference_volume = volume;
+
+    s->save_volume = (!reference_volume_changed && s->save_volume) || save;
+
+    if (reference_volume_changed)
+        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+    else if (!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
+        /* If the root sink's volume doesn't change, then there can't be any
+         * changes in the other sinks in the sink tree either.
+         *
+         * It's probably theoretically possible that even if the root sink's
+         * volume changes slightly, some filter sink doesn't change its volume
+         * due to rounding errors. If that happens, we still want to propagate
+         * the changed root sink volume to the sinks connected to the
+         * intermediate sink that didn't change its volume. This theoretical
+         * possibility is the reason why we have that !(s->flags &
+         * PA_SINK_SHARE_VOLUME_WITH_MASTER) condition. Probably nobody would
+         * notice even if we returned here FALSE always if
+         * reference_volume_changed is FALSE. */
+        return FALSE;
+
+    PA_IDXSET_FOREACH(i, s->inputs, idx) {
+        if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
+            update_reference_volume(i->origin_sink, v, channel_map, FALSE);
+    }
+
+    return TRUE;
+}
+
 /* Called from main thread */
 void pa_sink_set_volume(
         pa_sink *s,
         const pa_cvolume *volume,
-        pa_bool_t sendmsg,
+        pa_bool_t send_msg,
         pa_bool_t save) {
 
-    pa_cvolume old_reference_volume;
-    pa_bool_t reference_changed;
+    pa_cvolume new_reference_volume;
+    pa_sink *root_sink;
 
     pa_sink_assert_ref(s);
     pa_assert_ctl_context();
     pa_assert(PA_SINK_IS_LINKED(s->state));
     pa_assert(!volume || pa_cvolume_valid(volume));
-    pa_assert(volume || (s->flags & PA_SINK_FLAT_VOLUME));
+    pa_assert(volume || pa_sink_flat_volume_enabled(s));
     pa_assert(!volume || volume->channels == 1 || pa_cvolume_compatible(volume, &s->sample_spec));
 
-    /* As a special exception we accept mono volumes on all sinks --
-     * even on those with more complex channel maps */
+    /* make sure we don't change the volume when a PASSTHROUGH input is connected ...
+     * ... *except* if we're being invoked to reset the volume to ensure 0 dB gain */
+    if (pa_sink_is_passthrough(s) && (!volume || !pa_cvolume_is_norm(volume))) {
+        pa_log_warn("Cannot change volume, Sink is connected to PASSTHROUGH input");
+        return;
+    }
 
-    /* If volume is NULL we synchronize the sink's real and reference
-     * volumes with the stream volumes. If it is not NULL we update
-     * the reference_volume with it. */
+    /* In case of volume sharing, the volume is set for the root sink first,
+     * from which it's then propagated to the sharing sinks. */
+    root_sink = pa_sink_get_master(s);
 
-    old_reference_volume = s->reference_volume;
+    if (PA_UNLIKELY(!root_sink))
+        return;
 
-    if (volume) {
+    /* As a special exception we accept mono volumes on all sinks --
+     * even on those with more complex channel maps */
 
+    if (volume) {
         if (pa_cvolume_compatible(volume, &s->sample_spec))
-            s->reference_volume = *volume;
-        else
-            pa_cvolume_scale(&s->reference_volume, pa_cvolume_max(volume));
+            new_reference_volume = *volume;
+        else {
+            new_reference_volume = s->reference_volume;
+            pa_cvolume_scale(&new_reference_volume, pa_cvolume_max(volume));
+        }
 
-        if (s->flags & PA_SINK_FLAT_VOLUME) {
-            /* OK, propagate this volume change back to the inputs */
-            propagate_reference_volume(s);
+        pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_sink->channel_map);
 
-            /* And now recalculate the real volume */
-            compute_real_volume(s);
-        } else
-            s->real_volume = s->reference_volume;
+        if (update_reference_volume(root_sink, &new_reference_volume, &root_sink->channel_map, save)) {
+            if (pa_sink_flat_volume_enabled(root_sink)) {
+                /* OK, propagate this volume change back to the inputs */
+                propagate_reference_volume(root_sink);
+
+                /* And now recalculate the real volume */
+                compute_real_volume(root_sink);
+            } else
+                update_real_volume(root_sink, &root_sink->reference_volume, &root_sink->channel_map);
+        }
 
     } else {
-        pa_assert(s->flags & PA_SINK_FLAT_VOLUME);
+        /* If volume is NULL we synchronize the sink's real and
+         * reference volumes with the stream volumes. */
+
+        pa_assert(pa_sink_flat_volume_enabled(root_sink));
 
         /* Ok, let's determine the new real volume */
-        compute_real_volume(s);
+        compute_real_volume(root_sink);
 
         /* Let's 'push' the reference volume if necessary */
-        pa_cvolume_merge(&s->reference_volume, &s->reference_volume, &s->real_volume);
-
-        /* We need to fix the reference ratios of all streams now that
-         * we changed the reference volume */
-        compute_reference_ratios(s);
+        pa_cvolume_merge(&new_reference_volume, &s->reference_volume, &root_sink->real_volume);
+        /* If the sink and it's root don't have the same number of channels, we need to remap */
+        if (s != root_sink && !pa_channel_map_equal(&s->channel_map, &root_sink->channel_map))
+            pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_sink->channel_map);
+        update_reference_volume(root_sink, &new_reference_volume, &root_sink->channel_map, save);
+
+        /* Now that the reference volume is updated, we can update the streams'
+         * reference ratios. */
+        compute_reference_ratios(root_sink);
     }
 
-    reference_changed = !pa_cvolume_equal(&old_reference_volume, &s->reference_volume);
-    s->save_volume = (!reference_changed && s->save_volume) || save;
-
-    if (s->set_volume) {
+    if (root_sink->set_volume) {
         /* If we have a function set_volume(), then we do not apply a
          * soft volume by default. However, set_volume() is free to
-         * apply one to s->soft_volume */
+         * apply one to root_sink->soft_volume */
 
-        pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
-        s->set_volume(s);
+        pa_cvolume_reset(&root_sink->soft_volume, root_sink->sample_spec.channels);
+        if (!(root_sink->flags & PA_SINK_DEFERRED_VOLUME))
+            root_sink->set_volume(root_sink);
 
     } else
         /* If we have no function set_volume(), then the soft volume
-         * becomes the virtual volume */
-        s->soft_volume = s->real_volume;
+         * becomes the real volume */
+        root_sink->soft_volume = root_sink->real_volume;
 
-    /* This tells the sink that soft and/or virtual volume changed */
-    if (sendmsg)
-        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
-
-    if (reference_changed)
-        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+    /* This tells the sink that soft volume and/or real volume changed */
+    if (send_msg)
+        pa_assert_se(pa_asyncmsgq_send(root_sink->asyncmsgq, PA_MSGOBJECT(root_sink), PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL) == 0);
 }
 
-/* Called from main thread. Only to be called by sink implementor */
+/* Called from the io thread if sync volume is used, otherwise from the main thread.
+ * Only to be called by sink implementor */
 void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume) {
+
     pa_sink_assert_ref(s);
-    pa_assert_ctl_context();
+    pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
+
+    if (s->flags & PA_SINK_DEFERRED_VOLUME)
+        pa_sink_assert_io_context(s);
+    else
+        pa_assert_ctl_context();
 
     if (!volume)
         pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
     else
         s->soft_volume = *volume;
 
-    if (PA_SINK_IS_LINKED(s->state))
+    if (PA_SINK_IS_LINKED(s->state) && !(s->flags & PA_SINK_DEFERRED_VOLUME))
         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
     else
         s->thread_info.soft_volume = s->soft_volume;
 }
 
+/* Called from the main thread. Only called for the root sink in volume sharing
+ * cases, except for internal recursive calls. */
 static void propagate_real_volume(pa_sink *s, const pa_cvolume *old_real_volume) {
     pa_sink_input *i;
     uint32_t idx;
-    pa_cvolume old_reference_volume;
 
     pa_sink_assert_ref(s);
+    pa_assert(old_real_volume);
     pa_assert_ctl_context();
     pa_assert(PA_SINK_IS_LINKED(s->state));
 
@@ -1446,20 +2314,18 @@ static void propagate_real_volume(pa_sink *s, const pa_cvolume *old_real_volume)
      * reference volume and then rebuild the stream volumes based on
      * i->real_ratio which should stay fixed. */
 
-    if (pa_cvolume_equal(old_real_volume, &s->real_volume))
-        return;
-
-    old_reference_volume = s->reference_volume;
+    if (!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER)) {
+        if (pa_cvolume_equal(old_real_volume, &s->real_volume))
+            return;
 
-    /* 1. Make the real volume the reference volume */
-    s->reference_volume = s->real_volume;
+        /* 1. Make the real volume the reference volume */
+        update_reference_volume(s, &s->real_volume, &s->channel_map, TRUE);
+    }
 
-    if (s->flags & PA_SINK_FLAT_VOLUME) {
+    if (pa_sink_flat_volume_enabled(s)) {
 
         PA_IDXSET_FOREACH(i, s->inputs, idx) {
-            pa_cvolume old_volume, remapped;
-
-            old_volume = i->volume;
+            pa_cvolume old_volume = i->volume;
 
             /* 2. Since the sink's reference and real volumes are equal
              * now our ratios should be too. */
@@ -1473,9 +2339,9 @@ static void propagate_real_volume(pa_sink *s, const pa_cvolume *old_real_volume)
              * i->volume = s->reference_volume * i->reference_ratio
              *
              * This is identical to propagate_reference_volume() */
-            remapped = s->reference_volume;
-            pa_cvolume_remap(&remapped, &s->channel_map, &i->channel_map);
-            pa_sw_cvolume_multiply(&i->volume, &remapped, &i->reference_ratio);
+            i->volume = s->reference_volume;
+            pa_cvolume_remap(&i->volume, &s->channel_map, &i->channel_map);
+            pa_sw_cvolume_multiply(&i->volume, &i->volume, &i->reference_ratio);
 
             /* Notify if something changed */
             if (!pa_cvolume_equal(&old_volume, &i->volume)) {
@@ -1485,16 +2351,25 @@ static void propagate_real_volume(pa_sink *s, const pa_cvolume *old_real_volume)
 
                 pa_subscription_post(i->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
             }
+
+            if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
+                propagate_real_volume(i->origin_sink, old_real_volume);
         }
     }
 
     /* Something got changed in the hardware. It probably makes sense
      * to save changed hw settings given that hw volume changes not
      * triggered by PA are almost certainly done by the user. */
-    s->save_volume = TRUE;
+    if (!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
+        s->save_volume = TRUE;
+}
 
-    if (!pa_cvolume_equal(&old_reference_volume, &s->reference_volume))
-        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+/* Called from io thread */
+void pa_sink_update_volume_and_mute(pa_sink *s) {
+    pa_assert(s);
+    pa_sink_assert_io_context(s);
+
+    pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_UPDATE_VOLUME_AND_MUTE, NULL, 0, NULL, NULL);
 }
 
 /* Called from main thread */
@@ -1506,32 +2381,36 @@ const pa_cvolume *pa_sink_get_volume(pa_sink *s, pa_bool_t force_refresh) {
     if (s->refresh_volume || force_refresh) {
         struct pa_cvolume old_real_volume;
 
+        pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
+
         old_real_volume = s->real_volume;
 
-        if (s->get_volume)
+        if (!(s->flags & PA_SINK_DEFERRED_VOLUME) && s->get_volume)
             s->get_volume(s);
 
         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_VOLUME, NULL, 0, NULL) == 0);
 
+        update_real_volume(s, &s->real_volume, &s->channel_map);
         propagate_real_volume(s, &old_real_volume);
     }
 
     return &s->reference_volume;
 }
 
-/* Called from main thread */
+/* Called from main thread. In volume sharing cases, only the root sink may
+ * call this. */
 void pa_sink_volume_changed(pa_sink *s, const pa_cvolume *new_real_volume) {
     pa_cvolume old_real_volume;
 
     pa_sink_assert_ref(s);
     pa_assert_ctl_context();
     pa_assert(PA_SINK_IS_LINKED(s->state));
+    pa_assert(!(s->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER));
 
     /* The sink implementor may call this if the volume changed to make sure everyone is notified */
 
     old_real_volume = s->real_volume;
-    s->real_volume = *new_real_volume;
-
+    update_real_volume(s, new_real_volume, &s->channel_map);
     propagate_real_volume(s, &old_real_volume);
 }
 
@@ -1547,7 +2426,7 @@ void pa_sink_set_mute(pa_sink *s, pa_bool_t mute, pa_bool_t save) {
     s->muted = mute;
     s->save_muted = (old_muted == s->muted && s->save_muted) || save;
 
-    if (s->set_mute)
+    if (!(s->flags & PA_SINK_DEFERRED_VOLUME) && s->set_mute)
         s->set_mute(s);
 
     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
@@ -1566,7 +2445,7 @@ pa_bool_t pa_sink_get_mute(pa_sink *s, pa_bool_t force_refresh) {
     if (s->refresh_muted || force_refresh) {
         pa_bool_t old_muted = s->muted;
 
-        if (s->get_mute)
+        if (!(s->flags & PA_SINK_DEFERRED_VOLUME) && s->get_mute)
             s->get_mute(s);
 
         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MUTE, NULL, 0, NULL) == 0);
@@ -1662,7 +2541,7 @@ unsigned pa_sink_linked_by(pa_sink *s) {
     ret = pa_idxset_size(s->inputs);
 
     /* We add in the number of streams connected to us here. Please
-     * note the asymmmetry to pa_sink_used_by()! */
+     * note the asymmetry to pa_sink_used_by()! */
 
     if (s->monitor_source)
         ret += pa_source_linked_by(s->monitor_source);
@@ -1705,7 +2584,14 @@ unsigned pa_sink_check_suspend(pa_sink *s) {
         pa_sink_input_state_t st;
 
         st = pa_sink_input_get_state(i);
-        pa_assert(PA_SINK_INPUT_IS_LINKED(st));
+
+        /* We do not assert here. It is perfectly valid for a sink input to
+         * be in the INIT state (i.e. created, marked done but not yet put)
+         * and we should not care if it's unlinked as it won't contribute
+         * towards our busy status.
+         */
+        if (!PA_SINK_INPUT_IS_LINKED(st))
+            continue;
 
         if (st == PA_SINK_INPUT_CORKED)
             continue;
@@ -1739,6 +2625,22 @@ static void sync_input_volumes_within_thread(pa_sink *s) {
     }
 }
 
+/* Called from the IO thread. Only called for the root sink in volume sharing
+ * cases, except for internal recursive calls. */
+static void set_shared_volume_within_thread(pa_sink *s) {
+    pa_sink_input *i = NULL;
+    void *state = NULL;
+
+    pa_sink_assert_ref(s);
+
+    PA_MSGOBJECT(s)->process_msg(PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME_SYNCED, NULL, 0, NULL);
+
+    PA_HASHMAP_FOREACH(i, s->thread_info.inputs, state) {
+        if (i->origin_sink && (i->origin_sink->flags & PA_SINK_SHARE_VOLUME_WITH_MASTER))
+            set_shared_volume_within_thread(i->origin_sink);
+    }
+}
+
 /* Called from IO thread, except when it is not */
 int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
     pa_sink *s = PA_SINK(o);
@@ -1779,8 +2681,16 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
 
             pa_sink_input_set_state_within_thread(i, i->state);
 
-            /* The requested latency of the sink input needs to be
-             * fixed up and then configured on the sink */
+            /* The requested latency of the sink input needs to be fixed up and
+             * then configured on the sink. If this causes the sink latency to
+             * go down, the sink implementor is responsible for doing a rewind
+             * in the update_requested_latency() callback to ensure that the
+             * sink buffer doesn't contain more data than what the new latency
+             * allows.
+             *
+             * XXX: Does it really make sense to push this responsibility to
+             * the sink implementors? Wouldn't it be better to do it once in
+             * the core than many times in the modules? */
 
             if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
                 pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
@@ -1791,11 +2701,15 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
             /* We don't rewind here automatically. This is left to the
              * sink input implementor because some sink inputs need a
              * slow start, i.e. need some time to buffer client
-             * samples before beginning streaming. */
+             * samples before beginning streaming.
+             *
+             * XXX: Does it really make sense to push this functionality to
+             * the sink implementors? Wouldn't it be better to do it once in
+             * the core than many times in the modules? */
 
             /* In flat volume mode we need to update the volume as
              * well */
-            return o->process_msg(o, PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL);
+            return o->process_msg(o, PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
         }
 
         case PA_SINK_MESSAGE_REMOVE_INPUT: {
@@ -1803,7 +2717,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
 
             /* If you change anything here, make sure to change the
              * sink input handling a few lines down at
-             * PA_SINK_MESSAGE_PREPAPRE_MOVE, too. */
+             * PA_SINK_MESSAGE_START_MOVE, too. */
 
             if (i->detach)
                 i->detach(i);
@@ -1838,7 +2752,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
 
             /* In flat volume mode we need to update the volume as
              * well */
-            return o->process_msg(o, PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL);
+            return o->process_msg(o, PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
         }
 
         case PA_SINK_MESSAGE_START_MOVE: {
@@ -1854,6 +2768,46 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
                 pa_usec_t usec = 0;
                 size_t sink_nbytes, total_nbytes;
 
+                /* The old sink probably has some audio from this
+                 * stream in its buffer. We want to "take it back" as
+                 * much as possible and play it to the new sink. We
+                 * don't know at this point how much the old sink can
+                 * rewind. We have to pick something, and that
+                 * something is the full latency of the old sink here.
+                 * So we rewind the stream buffer by the sink latency
+                 * amount, which may be more than what we should
+                 * rewind. This can result in a chunk of audio being
+                 * played both to the old sink and the new sink.
+                 *
+                 * FIXME: Fix this code so that we don't have to make
+                 * guesses about how much the sink will actually be
+                 * able to rewind. If someone comes up with a solution
+                 * for this, something to note is that the part of the
+                 * latency that the old sink couldn't rewind should
+                 * ideally be compensated after the stream has moved
+                 * to the new sink by adding silence. The new sink
+                 * most likely can't start playing the moved stream
+                 * immediately, and that gap should be removed from
+                 * the "compensation silence" (at least at the time of
+                 * writing this, the move finish code will actually
+                 * already take care of dropping the new sink's
+                 * unrewindable latency, so taking into account the
+                 * unrewindable latency of the old sink is the only
+                 * problem).
+                 *
+                 * The render_memblockq contents are discarded,
+                 * because when the sink changes, the format of the
+                 * audio stored in the render_memblockq may change
+                 * too, making the stored audio invalid. FIXME:
+                 * However, the read and write indices are moved back
+                 * the same amount, so if they are not the same now,
+                 * they won't be the same after the rewind either. If
+                 * the write index of the render_memblockq is ahead of
+                 * the read index, then the render_memblockq will feed
+                 * the new sink some silence first, which it shouldn't
+                 * do. The write index should be flushed to be the
+                 * same as the read index. */
+
                 /* Get the latency of the sink */
                 usec = pa_sink_get_latency_within_thread(s);
                 sink_nbytes = pa_usec_to_bytes(usec, &s->sample_spec);
@@ -1883,7 +2837,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
 
             /* In flat volume mode we need to update the volume as
              * well */
-            return o->process_msg(o, PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL);
+            return o->process_msg(o, PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
         }
 
         case PA_SINK_MESSAGE_FINISH_MOVE: {
@@ -1903,16 +2857,28 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
             if (i->attach)
                 i->attach(i);
 
-            if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
-                pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
-
-            pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
-            pa_sink_input_update_max_request(i, s->thread_info.max_request);
-
             if (i->thread_info.state != PA_SINK_INPUT_CORKED) {
                 pa_usec_t usec = 0;
                 size_t nbytes;
 
+                /* In the ideal case the new sink would start playing
+                 * the stream immediately. That requires the sink to
+                 * be able to rewind all of its latency, which usually
+                 * isn't possible, so there will probably be some gap
+                 * before the moved stream becomes audible. We then
+                 * have two possibilities: 1) start playing the stream
+                 * from where it is now, or 2) drop the unrewindable
+                 * latency of the sink from the stream. With option 1
+                 * we won't lose any audio but the stream will have a
+                 * pause. With option 2 we may lose some audio but the
+                 * stream time will be somewhat in sync with the wall
+                 * clock. Lennart seems to have chosen option 2 (one
+                 * of the reasons might have been that option 1 is
+                 * actually much harder to implement), so we drop the
+                 * latency of the new sink from the moved stream and
+                 * hope that the sink will undo most of that in the
+                 * rewind. */
+
                 /* Get the latency of the sink */
                 usec = pa_sink_get_latency_within_thread(s);
                 nbytes = pa_usec_to_bytes(usec, &s->sample_spec);
@@ -1924,11 +2890,37 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
                 pa_sink_request_rewind(s, nbytes);
             }
 
-            /* In flat volume mode we need to update the volume as
-             * well */
-            return o->process_msg(o, PA_SINK_MESSAGE_SET_VOLUME, NULL, 0, NULL);
+            /* Updating the requested sink latency has to be done
+             * after the sink rewind request, not before, because
+             * otherwise the sink may limit the rewind amount
+             * needlessly. */
+
+            if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
+                pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
+
+            pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
+            pa_sink_input_update_max_request(i, s->thread_info.max_request);
+
+            return o->process_msg(o, PA_SINK_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
+        }
+
+        case PA_SINK_MESSAGE_SET_SHARED_VOLUME: {
+            pa_sink *root_sink = pa_sink_get_master(s);
+
+            if (PA_LIKELY(root_sink))
+                set_shared_volume_within_thread(root_sink);
+
+            return 0;
         }
 
+        case PA_SINK_MESSAGE_SET_VOLUME_SYNCED:
+
+            if (s->flags & PA_SINK_DEFERRED_VOLUME) {
+                s->set_volume(s);
+                pa_sink_volume_change_push(s);
+            }
+            /* Fall through ... */
+
         case PA_SINK_MESSAGE_SET_VOLUME:
 
             if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
@@ -1936,9 +2928,6 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
                 pa_sink_request_rewind(s, (size_t) -1);
             }
 
-            if (!(s->flags & PA_SINK_FLAT_VOLUME))
-                return 0;
-
             /* Fall through ... */
 
         case PA_SINK_MESSAGE_SYNC_VOLUMES:
@@ -1946,6 +2935,19 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
             return 0;
 
         case PA_SINK_MESSAGE_GET_VOLUME:
+
+            if ((s->flags & PA_SINK_DEFERRED_VOLUME) && s->get_volume) {
+                s->get_volume(s);
+                pa_sink_volume_change_flush(s);
+                pa_sw_cvolume_divide(&s->thread_info.current_hw_volume, &s->real_volume, &s->soft_volume);
+            }
+
+            /* In case sink implementor reset SW volume. */
+            if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
+                s->thread_info.soft_volume = s->soft_volume;
+                pa_sink_request_rewind(s, (size_t) -1);
+            }
+
             return 0;
 
         case PA_SINK_MESSAGE_SET_MUTE:
@@ -1955,9 +2957,16 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
                 pa_sink_request_rewind(s, (size_t) -1);
             }
 
+            if (s->flags & PA_SINK_DEFERRED_VOLUME && s->set_mute)
+                s->set_mute(s);
+
             return 0;
 
         case PA_SINK_MESSAGE_GET_MUTE:
+
+            if (s->flags & PA_SINK_DEFERRED_VOLUME && s->get_mute)
+                s->get_mute(s);
+
             return 0;
 
         case PA_SINK_MESSAGE_SET_STATE: {
@@ -2058,6 +3067,31 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
             pa_sink_set_max_request_within_thread(s, (size_t) offset);
             return 0;
 
+        case PA_SINK_MESSAGE_SET_PORT:
+
+            pa_assert(userdata);
+            if (s->set_port) {
+                struct sink_message_set_port *msg_data = userdata;
+                msg_data->ret = s->set_port(s, msg_data->port);
+            }
+            return 0;
+
+        case PA_SINK_MESSAGE_UPDATE_VOLUME_AND_MUTE:
+            /* This message is sent from IO-thread and handled in main thread. */
+            pa_assert_ctl_context();
+
+            /* Make sure we're not messing with main thread when no longer linked */
+            if (!PA_SINK_IS_LINKED(s->state))
+                return 0;
+
+            pa_sink_get_volume(s, TRUE);
+            pa_sink_get_mute(s, TRUE);
+            return 0;
+
+        case PA_SINK_MESSAGE_SET_LATENCY_OFFSET:
+            s->thread_info.latency_offset = offset;
+            return 0;
+
         case PA_SINK_MESSAGE_GET_LATENCY:
         case PA_SINK_MESSAGE_MAX:
             ;
@@ -2144,9 +3178,6 @@ void pa_sink_request_rewind(pa_sink*s, size_t nbytes) {
     pa_sink_assert_io_context(s);
     pa_assert(PA_SINK_IS_LINKED(s->thread_info.state));
 
-    if (s->thread_info.state == PA_SINK_SUSPENDED)
-        return;
-
     if (nbytes == (size_t) -1)
         nbytes = s->thread_info.max_rewind;
 
@@ -2214,6 +3245,7 @@ pa_usec_t pa_sink_get_requested_latency(pa_sink *s) {
         return 0;
 
     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
+
     return usec;
 }
 
@@ -2341,22 +3373,22 @@ void pa_sink_set_latency_range(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_
 
 /* Called from main thread */
 void pa_sink_get_latency_range(pa_sink *s, pa_usec_t *min_latency, pa_usec_t *max_latency) {
-   pa_sink_assert_ref(s);
-   pa_assert_ctl_context();
-   pa_assert(min_latency);
-   pa_assert(max_latency);
+    pa_sink_assert_ref(s);
+    pa_assert_ctl_context();
+    pa_assert(min_latency);
+    pa_assert(max_latency);
 
-   if (PA_SINK_IS_LINKED(s->state)) {
-       pa_usec_t r[2] = { 0, 0 };
+    if (PA_SINK_IS_LINKED(s->state)) {
+        pa_usec_t r[2] = { 0, 0 };
 
-       pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY_RANGE, r, 0, NULL) == 0);
+        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY_RANGE, r, 0, NULL) == 0);
 
-       *min_latency = r[0];
-       *max_latency = r[1];
-   } else {
-       *min_latency = s->thread_info.min_latency;
-       *max_latency = s->thread_info.max_latency;
-   }
+        *min_latency = r[0];
+        *max_latency = r[1];
+    } else {
+        *min_latency = s->thread_info.min_latency;
+        *max_latency = s->thread_info.max_latency;
+    }
 }
 
 /* Called from IO thread */
@@ -2443,6 +3475,11 @@ void pa_sink_set_fixed_latency_within_thread(pa_sink *s, pa_usec_t latency) {
 
     if (s->flags & PA_SINK_DYNAMIC_LATENCY) {
         pa_assert(latency == 0);
+        s->thread_info.fixed_latency = 0;
+
+        if (s->monitor_source)
+            pa_source_set_fixed_latency_within_thread(s->monitor_source, 0);
+
         return;
     }
 
@@ -2469,10 +3506,22 @@ void pa_sink_set_fixed_latency_within_thread(pa_sink *s, pa_usec_t latency) {
 }
 
 /* Called from main context */
+void pa_sink_set_latency_offset(pa_sink *s, int64_t offset) {
+    pa_sink_assert_ref(s);
+
+    s->latency_offset = offset;
+
+    if (PA_SINK_IS_LINKED(s->state))
+        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_LATENCY_OFFSET, NULL, offset, NULL) == 0);
+    else
+        s->thread_info.latency_offset = offset;
+}
+
+/* Called from main context */
 size_t pa_sink_get_max_rewind(pa_sink *s) {
     size_t r;
-    pa_sink_assert_ref(s);
     pa_assert_ctl_context();
+    pa_sink_assert_ref(s);
 
     if (!PA_SINK_IS_LINKED(s->state))
         return s->thread_info.max_rewind;
@@ -2499,6 +3548,7 @@ size_t pa_sink_get_max_request(pa_sink *s) {
 /* Called from main context */
 int pa_sink_set_port(pa_sink *s, const char *name, pa_bool_t save) {
     pa_device_port *port;
+    int ret;
 
     pa_sink_assert_ref(s);
     pa_assert_ctl_context();
@@ -2508,7 +3558,7 @@ int pa_sink_set_port(pa_sink *s, const char *name, pa_bool_t save) {
         return -PA_ERR_NOTIMPLEMENTED;
     }
 
-    if (!s->ports)
+    if (!name)
         return -PA_ERR_NOENTITY;
 
     if (!(port = pa_hashmap_get(s->ports, name)))
@@ -2519,7 +3569,15 @@ int pa_sink_set_port(pa_sink *s, const char *name, pa_bool_t save) {
         return 0;
     }
 
-    if ((s->set_port(s, port)) < 0)
+    if (s->flags & PA_SINK_DEFERRED_VOLUME) {
+        struct sink_message_set_port msg = { .port = port, .ret = 0 };
+        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
+        ret = msg.ret;
+    }
+    else
+        ret = s->set_port(s, port);
+
+    if (ret < 0)
         return -PA_ERR_NOENTITY;
 
     pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
@@ -2529,6 +3587,10 @@ int pa_sink_set_port(pa_sink *s, const char *name, pa_bool_t save) {
     s->active_port = port;
     s->save_port = save;
 
+    pa_sink_set_latency_offset(s, s->active_port->latency_offset);
+
+    pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PORT_CHANGED], s);
+
     return 0;
 }
 
@@ -2608,7 +3670,7 @@ pa_bool_t pa_device_init_description(pa_proplist *p) {
 
     if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR)))
         if (pa_streq(s, "internal"))
-            d = _("Internal Audio");
+            d = _("Built-in Audio");
 
     if (!d)
         if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_CLASS)))
@@ -2624,7 +3686,7 @@ pa_bool_t pa_device_init_description(pa_proplist *p) {
     k = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_DESCRIPTION);
 
     if (d && k)
-        pa_proplist_setf(p, PA_PROP_DEVICE_DESCRIPTION, _("%s %s"), d, k);
+        pa_proplist_setf(p, PA_PROP_DEVICE_DESCRIPTION, "%s %s", d, k);
     else if (d)
         pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, d);
 
@@ -2639,7 +3701,8 @@ pa_bool_t pa_device_init_intended_roles(pa_proplist *p) {
         return TRUE;
 
     if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR)))
-        if (pa_streq(s, "handset") || pa_streq(s, "hands-free")) {
+        if (pa_streq(s, "handset") || pa_streq(s, "hands-free")
+            || pa_streq(s, "headset")) {
             pa_proplist_sets(p, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
             return TRUE;
         }
@@ -2691,3 +3754,273 @@ unsigned pa_device_init_priority(pa_proplist *p) {
 
     return priority;
 }
+
+PA_STATIC_FLIST_DECLARE(pa_sink_volume_change, 0, pa_xfree);
+
+/* Called from the IO thread. */
+static pa_sink_volume_change *pa_sink_volume_change_new(pa_sink *s) {
+    pa_sink_volume_change *c;
+    if (!(c = pa_flist_pop(PA_STATIC_FLIST_GET(pa_sink_volume_change))))
+        c = pa_xnew(pa_sink_volume_change, 1);
+
+    PA_LLIST_INIT(pa_sink_volume_change, c);
+    c->at = 0;
+    pa_cvolume_reset(&c->hw_volume, s->sample_spec.channels);
+    return c;
+}
+
+/* Called from the IO thread. */
+static void pa_sink_volume_change_free(pa_sink_volume_change *c) {
+    pa_assert(c);
+    if (pa_flist_push(PA_STATIC_FLIST_GET(pa_sink_volume_change), c) < 0)
+        pa_xfree(c);
+}
+
+/* Called from the IO thread. */
+void pa_sink_volume_change_push(pa_sink *s) {
+    pa_sink_volume_change *c = NULL;
+    pa_sink_volume_change *nc = NULL;
+    uint32_t safety_margin = s->thread_info.volume_change_safety_margin;
+
+    const char *direction = NULL;
+
+    pa_assert(s);
+    nc = pa_sink_volume_change_new(s);
+
+    /* NOTE: There is already more different volumes in pa_sink that I can remember.
+     *       Adding one more volume for HW would get us rid of this, but I am trying
+     *       to survive with the ones we already have. */
+    pa_sw_cvolume_divide(&nc->hw_volume, &s->real_volume, &s->soft_volume);
+
+    if (!s->thread_info.volume_changes && pa_cvolume_equal(&nc->hw_volume, &s->thread_info.current_hw_volume)) {
+        pa_log_debug("Volume not changing");
+        pa_sink_volume_change_free(nc);
+        return;
+    }
+
+    nc->at = pa_sink_get_latency_within_thread(s);
+    nc->at += pa_rtclock_now() + s->thread_info.volume_change_extra_delay;
+
+    if (s->thread_info.volume_changes_tail) {
+        for (c = s->thread_info.volume_changes_tail; c; c = c->prev) {
+            /* If volume is going up let's do it a bit late. If it is going
+             * down let's do it a bit early. */
+            if (pa_cvolume_avg(&nc->hw_volume) > pa_cvolume_avg(&c->hw_volume)) {
+                if (nc->at + safety_margin > c->at) {
+                    nc->at += safety_margin;
+                    direction = "up";
+                    break;
+                }
+            }
+            else if (nc->at - safety_margin > c->at) {
+                    nc->at -= safety_margin;
+                    direction = "down";
+                    break;
+            }
+        }
+    }
+
+    if (c == NULL) {
+        if (pa_cvolume_avg(&nc->hw_volume) > pa_cvolume_avg(&s->thread_info.current_hw_volume)) {
+            nc->at += safety_margin;
+            direction = "up";
+        } else {
+            nc->at -= safety_margin;
+            direction = "down";
+        }
+        PA_LLIST_PREPEND(pa_sink_volume_change, s->thread_info.volume_changes, nc);
+    }
+    else {
+        PA_LLIST_INSERT_AFTER(pa_sink_volume_change, s->thread_info.volume_changes, c, nc);
+    }
+
+    pa_log_debug("Volume going %s to %d at %llu", direction, pa_cvolume_avg(&nc->hw_volume), (long long unsigned) nc->at);
+
+    /* We can ignore volume events that came earlier but should happen later than this. */
+    PA_LLIST_FOREACH(c, nc->next) {
+        pa_log_debug("Volume change to %d at %llu was dropped", pa_cvolume_avg(&c->hw_volume), (long long unsigned) c->at);
+        pa_sink_volume_change_free(c);
+    }
+    nc->next = NULL;
+    s->thread_info.volume_changes_tail = nc;
+}
+
+/* Called from the IO thread. */
+static void pa_sink_volume_change_flush(pa_sink *s) {
+    pa_sink_volume_change *c = s->thread_info.volume_changes;
+    pa_assert(s);
+    s->thread_info.volume_changes = NULL;
+    s->thread_info.volume_changes_tail = NULL;
+    while (c) {
+        pa_sink_volume_change *next = c->next;
+        pa_sink_volume_change_free(c);
+        c = next;
+    }
+}
+
+/* Called from the IO thread. */
+pa_bool_t pa_sink_volume_change_apply(pa_sink *s, pa_usec_t *usec_to_next) {
+    pa_usec_t now;
+    pa_bool_t ret = FALSE;
+
+    pa_assert(s);
+
+    if (!s->thread_info.volume_changes || !PA_SINK_IS_LINKED(s->state)) {
+        if (usec_to_next)
+            *usec_to_next = 0;
+        return ret;
+    }
+
+    pa_assert(s->write_volume);
+
+    now = pa_rtclock_now();
+
+    while (s->thread_info.volume_changes && now >= s->thread_info.volume_changes->at) {
+        pa_sink_volume_change *c = s->thread_info.volume_changes;
+        PA_LLIST_REMOVE(pa_sink_volume_change, s->thread_info.volume_changes, c);
+        pa_log_debug("Volume change to %d at %llu was written %llu usec late",
+                     pa_cvolume_avg(&c->hw_volume), (long long unsigned) c->at, (long long unsigned) (now - c->at));
+        ret = TRUE;
+        s->thread_info.current_hw_volume = c->hw_volume;
+        pa_sink_volume_change_free(c);
+    }
+
+    if (ret)
+        s->write_volume(s);
+
+    if (s->thread_info.volume_changes) {
+        if (usec_to_next)
+            *usec_to_next = s->thread_info.volume_changes->at - now;
+        if (pa_log_ratelimit(PA_LOG_DEBUG))
+            pa_log_debug("Next volume change in %lld usec", (long long) (s->thread_info.volume_changes->at - now));
+    }
+    else {
+        if (usec_to_next)
+            *usec_to_next = 0;
+        s->thread_info.volume_changes_tail = NULL;
+    }
+    return ret;
+}
+
+/* Called from the IO thread. */
+static void pa_sink_volume_change_rewind(pa_sink *s, size_t nbytes) {
+    /* All the queued volume events later than current latency are shifted to happen earlier. */
+    pa_sink_volume_change *c;
+    pa_volume_t prev_vol = pa_cvolume_avg(&s->thread_info.current_hw_volume);
+    pa_usec_t rewound = pa_bytes_to_usec(nbytes, &s->sample_spec);
+    pa_usec_t limit = pa_sink_get_latency_within_thread(s);
+
+    pa_log_debug("latency = %lld", (long long) limit);
+    limit += pa_rtclock_now() + s->thread_info.volume_change_extra_delay;
+
+    PA_LLIST_FOREACH(c, s->thread_info.volume_changes) {
+        pa_usec_t modified_limit = limit;
+        if (prev_vol > pa_cvolume_avg(&c->hw_volume))
+            modified_limit -= s->thread_info.volume_change_safety_margin;
+        else
+            modified_limit += s->thread_info.volume_change_safety_margin;
+        if (c->at > modified_limit) {
+            c->at -= rewound;
+            if (c->at < modified_limit)
+                c->at = modified_limit;
+        }
+        prev_vol = pa_cvolume_avg(&c->hw_volume);
+    }
+    pa_sink_volume_change_apply(s, NULL);
+}
+
+/* Called from the main thread */
+/* Gets the list of formats supported by the sink. The members and idxset must
+ * be freed by the caller. */
+pa_idxset* pa_sink_get_formats(pa_sink *s) {
+    pa_idxset *ret;
+
+    pa_assert(s);
+
+    if (s->get_formats) {
+        /* Sink supports format query, all is good */
+        ret = s->get_formats(s);
+    } else {
+        /* Sink doesn't support format query, so assume it does PCM */
+        pa_format_info *f = pa_format_info_new();
+        f->encoding = PA_ENCODING_PCM;
+
+        ret = pa_idxset_new(NULL, NULL);
+        pa_idxset_put(ret, f, NULL);
+    }
+
+    return ret;
+}
+
+/* Called from the main thread */
+/* Allows an external source to set what formats a sink supports if the sink
+ * permits this. The function makes a copy of the formats on success. */
+pa_bool_t pa_sink_set_formats(pa_sink *s, pa_idxset *formats) {
+    pa_assert(s);
+    pa_assert(formats);
+
+    if (s->set_formats)
+        /* Sink supports setting formats -- let's give it a shot */
+        return s->set_formats(s, formats);
+    else
+        /* Sink doesn't support setting this -- bail out */
+        return FALSE;
+}
+
+/* Called from the main thread */
+/* Checks if the sink can accept this format */
+pa_bool_t pa_sink_check_format(pa_sink *s, pa_format_info *f)
+{
+    pa_idxset *formats = NULL;
+    pa_bool_t ret = FALSE;
+
+    pa_assert(s);
+    pa_assert(f);
+
+    formats = pa_sink_get_formats(s);
+
+    if (formats) {
+        pa_format_info *finfo_device;
+        uint32_t i;
+
+        PA_IDXSET_FOREACH(finfo_device, formats, i) {
+            if (pa_format_info_is_compatible(finfo_device, f)) {
+                ret = TRUE;
+                break;
+            }
+        }
+
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
+    }
+
+    return ret;
+}
+
+/* Called from the main thread */
+/* Calculates the intersection between formats supported by the sink and
+ * in_formats, and returns these, in the order of the sink's formats. */
+pa_idxset* pa_sink_check_formats(pa_sink *s, pa_idxset *in_formats) {
+    pa_idxset *out_formats = pa_idxset_new(NULL, NULL), *sink_formats = NULL;
+    pa_format_info *f_sink, *f_in;
+    uint32_t i, j;
+
+    pa_assert(s);
+
+    if (!in_formats || pa_idxset_isempty(in_formats))
+        goto done;
+
+    sink_formats = pa_sink_get_formats(s);
+
+    PA_IDXSET_FOREACH(f_sink, sink_formats, i) {
+        PA_IDXSET_FOREACH(f_in, in_formats, j) {
+            if (pa_format_info_is_compatible(f_sink, f_in))
+                pa_idxset_put(out_formats, pa_format_info_copy(f_in), NULL);
+        }
+    }
+
+done:
+    if (sink_formats)
+        pa_idxset_free(sink_formats, (pa_free_cb_t) pa_format_info_free);
+
+    return out_formats;
+}
index ba547fc..896aa8a 100644 (file)
 ***/
 
 typedef struct pa_sink pa_sink;
-typedef struct pa_device_port pa_device_port;
+typedef struct pa_sink_volume_change pa_sink_volume_change;
 
 #include <inttypes.h>
 
 #include <pulse/def.h>
+#include <pulse/format.h>
 #include <pulse/sample.h>
 #include <pulse/channelmap.h>
 #include <pulse/volume.h>
 
 #include <pulsecore/core.h>
 #include <pulsecore/idxset.h>
+#include <pulsecore/memchunk.h>
 #include <pulsecore/source.h>
 #include <pulsecore/module.h>
-#include <pulsecore/refcnt.h>
+#include <pulsecore/asyncmsgq.h>
 #include <pulsecore/msgobject.h>
 #include <pulsecore/rtpoll.h>
+#include <pulsecore/device-port.h>
 #include <pulsecore/card.h>
 #include <pulsecore/queue.h>
 #include <pulsecore/thread-mq.h>
+#include <pulsecore/sink-input.h>
 
 #define PA_MAX_INPUTS_PER_SINK 32
 
@@ -51,16 +55,8 @@ static inline pa_bool_t PA_SINK_IS_LINKED(pa_sink_state_t x) {
     return x == PA_SINK_RUNNING || x == PA_SINK_IDLE || x == PA_SINK_SUSPENDED;
 }
 
-struct pa_device_port {
-    char *name;
-    char *description;
-
-    unsigned priority;
-
-    /* .. followed by some implementation specific data */
-};
-
-#define PA_DEVICE_PORT_DATA(d) ((void*) ((uint8_t*) d + PA_ALIGN(sizeof(pa_device_port))))
+/* A generic definition for void callback functions */
+typedef void(*pa_sink_cb_t)(pa_sink *s);
 
 struct pa_sink {
     pa_msgobject parent;
@@ -81,10 +77,13 @@ struct pa_sink {
 
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
+    uint32_t default_sample_rate;
+    uint32_t alternate_sample_rate;
 
     pa_idxset *inputs;
     unsigned n_corked;
     pa_source *monitor_source;
+    pa_sink_input *input_to_master;         /* non-NULL only for filter sinks */
 
     pa_volume_t base_volume; /* shall be constant */
     unsigned n_volume_steps; /* shall be constant */
@@ -102,12 +101,20 @@ struct pa_sink {
     pa_bool_t save_volume:1;
     pa_bool_t save_muted:1;
 
+    /* Saved volume state while we're in passthrough mode */
+    pa_cvolume saved_volume;
+    pa_bool_t saved_save_volume:1;
+
     pa_asyncmsgq *asyncmsgq;
 
     pa_memchunk silence;
 
     pa_hashmap *ports;
     pa_device_port *active_port;
+    pa_atomic_t mixer_dirty;
+
+    /* The latency offset is inherited from the currently active port */
+    int64_t latency_offset;
 
     unsigned priority;
 
@@ -116,39 +123,114 @@ struct pa_sink {
      * inhibited */
     int (*set_state)(pa_sink *s, pa_sink_state_t state); /* may be NULL */
 
-    /* Callled when the volume is queried. Called from main loop
-     * context. If this is NULL a PA_SINK_MESSAGE_GET_VOLUME message
-     * will be sent to the IO thread instead. If refresh_volume is
-     * FALSE neither this function is called nor a message is sent. */
-    void (*get_volume)(pa_sink *s);             /* may be NULL */
-
-    /* Called when the volume shall be changed. Called from main loop
-     * context. If this is NULL a PA_SINK_MESSAGE_SET_VOLUME message
-     * will be sent to the IO thread instead. */
-    void (*set_volume)(pa_sink *s);             /* dito */
-
-    /* Called when the mute setting is queried. Called from main loop
-     * context. If this is NULL a PA_SINK_MESSAGE_GET_MUTE message
-     * will be sent to the IO thread instead. If refresh_mute is
-     * FALSE neither this function is called nor a message is sent.*/
-    void (*get_mute)(pa_sink *s);               /* dito */
-
-    /* Called when the mute setting shall be changed. Called from main
-     * loop context. If this is NULL a PA_SINK_MESSAGE_SET_MUTE
-     * message will be sent to the IO thread instead. */
-    void (*set_mute)(pa_sink *s);               /* dito */
+    /* Sink drivers that support hardware volume may set this
+     * callback. This is called when the current volume needs to be
+     * re-read from the hardware.
+     *
+     * There are two ways for drivers to implement hardware volume
+     * query: either set this callback or handle
+     * PA_SINK_MESSAGE_GET_VOLUME. The callback implementation or the
+     * message handler must update s->real_volume and s->soft_volume
+     * (using pa_sink_set_soft_volume()) to match the current hardware
+     * volume.
+     *
+     * If PA_SINK_DEFERRED_VOLUME is not set, then this is called from the
+     * main thread before sending PA_SINK_MESSAGE_GET_VOLUME, so in
+     * this case the driver can choose whether to read the volume from
+     * the hardware in the main thread or in the IO thread.
+     *
+     * If PA_SINK_DEFERRED_VOLUME is set, then this is called from the IO
+     * thread within the default handler for
+     * PA_SINK_MESSAGE_GET_VOLUME (the main thread is waiting while
+     * the message is being processed), so there's no choice of where
+     * to do the volume reading - it has to be done in the IO thread
+     * always.
+     *
+     * You must use the function pa_sink_set_get_volume_callback() to
+     * set this callback. */
+    pa_sink_cb_t get_volume; /* may be NULL */
+
+    /* Sink drivers that support hardware volume must set this
+     * callback. This is called when the hardware volume needs to be
+     * updated.
+     *
+     * If PA_SINK_DEFERRED_VOLUME is not set, then this is called from the
+     * main thread. The callback implementation must set the hardware
+     * volume according to s->real_volume. If the driver can't set the
+     * hardware volume to the exact requested value, it has to update
+     * s->real_volume and/or s->soft_volume so that they together
+     * match the actual hardware volume that was set.
+     *
+     * If PA_SINK_DEFERRED_VOLUME is set, then this is called from the IO
+     * thread. The callback implementation must not actually set the
+     * hardware volume yet, but it must check how close to the
+     * requested volume the hardware volume can be set, and update
+     * s->real_volume and/or s->soft_volume so that they together
+     * match the actual hardware volume that will be set later in the
+     * write_volume callback.
+     *
+     * You must use the function pa_sink_set_set_volume_callback() to
+     * set this callback. */
+    pa_sink_cb_t set_volume; /* may be NULL */
+
+    /* Sink drivers that set PA_SINK_DEFERRED_VOLUME must provide this
+     * callback. This callback is not used with sinks that do not set
+     * PA_SINK_DEFERRED_VOLUME. This is called from the IO thread when a
+     * pending hardware volume change has to be written to the
+     * hardware. The requested volume is passed to the callback
+     * implementation in s->thread_info.current_hw_volume.
+     *
+     * The call is done inside pa_sink_volume_change_apply(), which is
+     * not called automatically - it is the driver's responsibility to
+     * schedule that function to be called at the right times in the
+     * IO thread.
+     *
+     * You must use the function pa_sink_set_write_volume_callback() to
+     * set this callback. */
+    pa_sink_cb_t write_volume; /* may be NULL */
+
+    /* Called when the mute setting is queried. A PA_SINK_MESSAGE_GET_MUTE
+     * message will also be sent. Called from IO thread if PA_SINK_DEFERRED_VOLUME
+     * flag is set otherwise from main loop context. If refresh_mute is FALSE
+     * neither this function is called nor a message is sent.
+     *
+     * You must use the function pa_sink_set_get_mute_callback() to
+     * set this callback. */
+    pa_sink_cb_t get_mute; /* may be NULL */
+
+    /* Called when the mute setting shall be changed. A PA_SINK_MESSAGE_SET_MUTE
+     * message will also be sent. Called from IO thread if PA_SINK_DEFERRED_VOLUME
+     * flag is set otherwise from main loop context.
+     *
+     * You must use the function pa_sink_set_set_mute_callback() to
+     * set this callback. */
+    pa_sink_cb_t set_mute; /* may be NULL */
 
     /* Called when a rewind request is issued. Called from IO thread
      * context. */
-    void (*request_rewind)(pa_sink *s);        /* dito */
+    pa_sink_cb_t request_rewind; /* may be NULL */
 
     /* Called when a the requested latency is changed. Called from IO
      * thread context. */
-    void (*update_requested_latency)(pa_sink *s); /* dito */
+    pa_sink_cb_t update_requested_latency; /* may be NULL */
+
+    /* Called whenever the port shall be changed. Called from IO
+     * thread if deferred volumes are enabled, and main thread otherwise. */
+    int (*set_port)(pa_sink *s, pa_device_port *port); /* may be NULL */
 
-    /* Called whenever the port shall be changed. Called from main
-     * thread. */
-    int (*set_port)(pa_sink *s, pa_device_port *port); /* dito */
+    /* Called to get the list of formats supported by the sink, sorted
+     * in descending order of preference. */
+    pa_idxset* (*get_formats)(pa_sink *s); /* may be NULL */
+
+    /* Called to set the list of formats supported by the sink. Can be
+     * NULL if the sink does not support this. Returns TRUE on success,
+     * FALSE otherwise (for example when an unsupportable format is
+     * set). Makes a copy of the formats passed in. */
+    pa_bool_t (*set_formats)(pa_sink *s, pa_idxset *formats); /* may be NULL */
+
+    /* Called whenever the sampling frequency shall be changed. Called from
+     * main thread. */
+    pa_bool_t (*update_rate)(pa_sink *s, uint32_t rate);
 
     /* Contains copies of the above data so that the real-time worker
      * thread can work without access locking */
@@ -188,8 +270,30 @@ struct pa_sink {
          * decided on by the sink, and the clients have no influence
          * in changing it */
         pa_usec_t fixed_latency; /* for sinks with PA_SINK_DYNAMIC_LATENCY this is 0 */
+
+        /* This latency offset is a direct copy from s->latency_offset */
+        int64_t latency_offset;
+
+        /* Delayed volume change events are queued here. The events
+         * are stored in expiration order. The one expiring next is in
+         * the head of the list. */
+        PA_LLIST_HEAD(pa_sink_volume_change, volume_changes);
+        pa_sink_volume_change *volume_changes_tail;
+        /* This value is updated in pa_sink_volume_change_apply() and
+         * used only by sinks with PA_SINK_DEFERRED_VOLUME. */
+        pa_cvolume current_hw_volume;
+
+        /* The amount of usec volume up events are delayed and volume
+         * down events are made earlier. */
+        uint32_t volume_change_safety_margin;
+        /* Usec delay added to all volume change events, may be negative. */
+        int32_t volume_change_extra_delay;
     } thread_info;
 
+#ifdef __TIZEN__
+    FILE *dump_fp;
+#endif
+
     void *userdata;
 };
 
@@ -200,6 +304,8 @@ typedef enum pa_sink_message {
     PA_SINK_MESSAGE_ADD_INPUT,
     PA_SINK_MESSAGE_REMOVE_INPUT,
     PA_SINK_MESSAGE_GET_VOLUME,
+    PA_SINK_MESSAGE_SET_SHARED_VOLUME,
+    PA_SINK_MESSAGE_SET_VOLUME_SYNCED,
     PA_SINK_MESSAGE_SET_VOLUME,
     PA_SINK_MESSAGE_SYNC_VOLUMES,
     PA_SINK_MESSAGE_GET_MUTE,
@@ -219,10 +325,15 @@ typedef enum pa_sink_message {
     PA_SINK_MESSAGE_GET_MAX_REQUEST,
     PA_SINK_MESSAGE_SET_MAX_REWIND,
     PA_SINK_MESSAGE_SET_MAX_REQUEST,
+    PA_SINK_MESSAGE_SET_PORT,
+    PA_SINK_MESSAGE_UPDATE_VOLUME_AND_MUTE,
+    PA_SINK_MESSAGE_SET_LATENCY_OFFSET,
     PA_SINK_MESSAGE_MAX
 } pa_sink_message_t;
 
 typedef struct pa_sink_new_data {
+    pa_suspend_cause_t suspend_cause;
+
     char *name;
     pa_proplist *proplist;
 
@@ -235,11 +346,13 @@ typedef struct pa_sink_new_data {
 
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
+    uint32_t alternate_sample_rate;
     pa_cvolume volume;
     pa_bool_t muted :1;
 
     pa_bool_t sample_spec_is_set:1;
     pa_bool_t channel_map_is_set:1;
+    pa_bool_t alternate_sample_rate_is_set:1;
     pa_bool_t volume_is_set:1;
     pa_bool_t muted_is_set:1;
 
@@ -254,6 +367,7 @@ pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data);
 void pa_sink_new_data_set_name(pa_sink_new_data *data, const char *name);
 void pa_sink_new_data_set_sample_spec(pa_sink_new_data *data, const pa_sample_spec *spec);
 void pa_sink_new_data_set_channel_map(pa_sink_new_data *data, const pa_channel_map *map);
+void pa_sink_new_data_set_alternate_sample_rate(pa_sink_new_data *data, const uint32_t alternate_sample_rate);
 void pa_sink_new_data_set_volume(pa_sink_new_data *data, const pa_cvolume *volume);
 void pa_sink_new_data_set_muted(pa_sink_new_data *data, pa_bool_t mute);
 void pa_sink_new_data_set_port(pa_sink_new_data *data, const char *port);
@@ -266,6 +380,13 @@ pa_sink* pa_sink_new(
         pa_sink_new_data *data,
         pa_sink_flags_t flags);
 
+void pa_sink_set_get_volume_callback(pa_sink *s, pa_sink_cb_t cb);
+void pa_sink_set_set_volume_callback(pa_sink *s, pa_sink_cb_t cb);
+void pa_sink_set_write_volume_callback(pa_sink *s, pa_sink_cb_t cb);
+void pa_sink_set_get_mute_callback(pa_sink *s, pa_sink_cb_t cb);
+void pa_sink_set_set_mute_callback(pa_sink *s, pa_sink_cb_t cb);
+void pa_sink_enable_decibel_volume(pa_sink *s, pa_bool_t enable);
+
 void pa_sink_put(pa_sink *s);
 void pa_sink_unlink(pa_sink* s);
 
@@ -294,6 +415,9 @@ unsigned pa_device_init_priority(pa_proplist *p);
 
 /**** May be called by everyone, from main context */
 
+pa_bool_t pa_sink_update_rate(pa_sink *s, uint32_t rate, pa_bool_t passthrough);
+void pa_sink_set_latency_offset(pa_sink *s, int64_t offset);
+
 /* The returned value is supposed to be in the time domain of the sound card! */
 pa_usec_t pa_sink_get_latency(pa_sink *s);
 pa_usec_t pa_sink_get_requested_latency(pa_sink *s);
@@ -307,6 +431,19 @@ int pa_sink_update_status(pa_sink*s);
 int pa_sink_suspend(pa_sink *s, pa_bool_t suspend, pa_suspend_cause_t cause);
 int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause);
 
+/* Use this instead of checking s->flags & PA_SINK_FLAT_VOLUME directly. */
+pa_bool_t pa_sink_flat_volume_enabled(pa_sink *s);
+
+/* Get the master sink when sharing volumes */
+pa_sink *pa_sink_get_master(pa_sink *s);
+
+/* Is the sink in passthrough mode? (that is, is there a passthrough sink input
+ * connected to this sink? */
+pa_bool_t pa_sink_is_passthrough(pa_sink *s);
+/* These should be called when a sink enters/leaves passthrough mode */
+void pa_sink_enter_passthrough(pa_sink *s);
+void pa_sink_leave_passthrough(pa_sink *s);
+
 void pa_sink_set_volume(pa_sink *sink, const pa_cvolume *volume, pa_bool_t sendmsg, pa_bool_t save);
 const pa_cvolume *pa_sink_get_volume(pa_sink *sink, pa_bool_t force_refresh);
 
@@ -316,6 +453,7 @@ pa_bool_t pa_sink_get_mute(pa_sink *sink, pa_bool_t force_refresh);
 pa_bool_t pa_sink_update_proplist(pa_sink *s, pa_update_mode_t mode, pa_proplist *p);
 
 int pa_sink_set_port(pa_sink *s, const char *name, pa_bool_t save);
+void pa_sink_set_mixer_dirty(pa_sink *s, pa_bool_t is_dirty);
 
 unsigned pa_sink_linked_by(pa_sink *s); /* Number of connected streams */
 unsigned pa_sink_used_by(pa_sink *s); /* Number of connected streams which are not corked */
@@ -327,6 +465,11 @@ pa_queue *pa_sink_move_all_start(pa_sink *s, pa_queue *q);
 void pa_sink_move_all_finish(pa_sink *s, pa_queue *q, pa_bool_t save);
 void pa_sink_move_all_fail(pa_queue *q);
 
+pa_idxset* pa_sink_get_formats(pa_sink *s);
+pa_bool_t pa_sink_set_formats(pa_sink *s, pa_idxset *formats);
+pa_bool_t pa_sink_check_format(pa_sink *s, pa_format_info *f);
+pa_idxset* pa_sink_check_formats(pa_sink *s, pa_idxset *in_formats);
+
 /*** To be called exclusively by the sink driver, from IO context */
 
 void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result);
@@ -349,6 +492,12 @@ void pa_sink_set_max_request_within_thread(pa_sink *s, size_t max_request);
 void pa_sink_set_latency_range_within_thread(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency);
 void pa_sink_set_fixed_latency_within_thread(pa_sink *s, pa_usec_t latency);
 
+void pa_sink_update_volume_and_mute(pa_sink *s);
+
+pa_bool_t pa_sink_volume_change_apply(pa_sink *s, pa_usec_t *usec_to_next);
+
+size_t pa_sink_process_input_underruns(pa_sink *s, size_t left_to_play);
+
 /*** To be called exclusively by sink input drivers, from IO context */
 
 void pa_sink_request_rewind(pa_sink*s, size_t nbytes);
@@ -357,9 +506,6 @@ void pa_sink_invalidate_requested_latency(pa_sink *s, pa_bool_t dynamic);
 
 pa_usec_t pa_sink_get_latency_within_thread(pa_sink *s);
 
-pa_device_port *pa_device_port_new(const char *name, const char *description, size_t extra);
-void pa_device_port_free(pa_device_port *p);
-
 /* 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. */
index 4f7f8bd..d8cc244 100644 (file)
 #include <pulse/utf8.h>
 
 #include <pulsecore/macro.h>
-#include <pulsecore/core-util.h>
 
 #include "sndfile-util.h"
 
 int pa_sndfile_read_sample_spec(SNDFILE *sf, pa_sample_spec *ss) {
     SF_INFO sfi;
+    int sf_errno;
 
     pa_assert(sf);
     pa_assert(ss);
 
     pa_zero(sfi);
-    pa_assert_se(sf_command(sf, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)) == 0);
+    if ((sf_errno = sf_command(sf, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)))) {
+        pa_log_error("sndfile: %s", sf_error_number(sf_errno));
+        return -1;
+    }
 
     switch (sfi.format & SF_FORMAT_SUBMASK) {
 
@@ -51,6 +54,9 @@ int pa_sndfile_read_sample_spec(SNDFILE *sf, pa_sample_spec *ss) {
             break;
 
         case SF_FORMAT_PCM_24:
+            ss->format = PA_SAMPLE_S24NE;
+            break;
+
         case SF_FORMAT_PCM_32:
             ss->format = PA_SAMPLE_S32NE;
             break;
@@ -106,10 +112,14 @@ int pa_sndfile_write_sample_spec(SF_INFO *sfi, pa_sample_spec *ss) {
 
         case PA_SAMPLE_S24LE:
         case PA_SAMPLE_S24BE:
+            ss->format = PA_SAMPLE_S24NE;
+            sfi->format |= SF_FORMAT_PCM_24;
+            break;
+
         case PA_SAMPLE_S24_32LE:
         case PA_SAMPLE_S24_32BE:
-            ss->format = PA_SAMPLE_S32NE;
-            sfi->format |= SF_FORMAT_PCM_24;
+            ss->format = PA_SAMPLE_S24_32NE;
+            sfi->format |= SF_FORMAT_PCM_32;
             break;
 
         case PA_SAMPLE_S32LE:
@@ -145,7 +155,7 @@ int pa_sndfile_read_channel_map(SNDFILE *sf, pa_channel_map *cm) {
 
     static const pa_channel_position_t table[] = {
         [SF_CHANNEL_MAP_MONO] =                  PA_CHANNEL_POSITION_MONO,
-        [SF_CHANNEL_MAP_LEFT] =                  PA_CHANNEL_POSITION_FRONT_LEFT, /* libsndfile distuingishes left und front-left, which we don't */
+        [SF_CHANNEL_MAP_LEFT] =                  PA_CHANNEL_POSITION_FRONT_LEFT, /* libsndfile distinguishes left and front-left, which we don't */
         [SF_CHANNEL_MAP_RIGHT] =                 PA_CHANNEL_POSITION_FRONT_RIGHT,
         [SF_CHANNEL_MAP_CENTER] =                PA_CHANNEL_POSITION_FRONT_CENTER,
         [SF_CHANNEL_MAP_FRONT_LEFT] =            PA_CHANNEL_POSITION_FRONT_LEFT,
@@ -169,6 +179,7 @@ int pa_sndfile_read_channel_map(SNDFILE *sf, pa_channel_map *cm) {
     };
 
     SF_INFO sfi;
+    int sf_errno;
     int *channels;
     unsigned c;
 
@@ -176,12 +187,13 @@ int pa_sndfile_read_channel_map(SNDFILE *sf, pa_channel_map *cm) {
     pa_assert(cm);
 
     pa_zero(sfi);
-    pa_assert_se(sf_command(sf, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)) == 0);
+    if ((sf_errno = sf_command(sf, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)))) {
+        pa_log_error("sndfile: %s", sf_error_number(sf_errno));
+        return -1;
+    }
 
     channels = pa_xnew(int, sfi.channels);
-    if (!sf_command(sf, SFC_GET_CHANNEL_MAP_INFO,
-                    channels, sizeof(channels[0]) * sfi.channels)) {
-
+    if (!sf_command(sf, SFC_GET_CHANNEL_MAP_INFO, channels, sizeof(channels[0]) * sfi.channels)) {
         pa_xfree(channels);
         return -1;
     }
@@ -297,8 +309,7 @@ int pa_sndfile_write_channel_map(SNDFILE *sf, pa_channel_map *cm) {
         channels[c] = table[cm->map[c]];
     }
 
-    if (!sf_command(sf, SFC_SET_CHANNEL_MAP_INFO,
-                    channels, sizeof(channels[0]) * cm->channels)) {
+    if (!sf_command(sf, SFC_SET_CHANNEL_MAP_INFO, channels, sizeof(channels[0]) * cm->channels)) {
         pa_xfree(channels);
         return -1;
     }
@@ -320,6 +331,7 @@ void pa_sndfile_init_proplist(SNDFILE *sf, pa_proplist *p) {
 
     SF_INFO sfi;
     SF_FORMAT_INFO fi;
+    int sf_errno;
     unsigned c;
 
     pa_assert(sf);
@@ -341,7 +353,10 @@ void pa_sndfile_init_proplist(SNDFILE *sf, pa_proplist *p) {
     }
 
     pa_zero(sfi);
-    pa_assert_se(sf_command(sf, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)) == 0);
+    if ((sf_errno = sf_command(sf, SFC_GET_CURRENT_SF_INFO, &sfi, sizeof(sfi)))) {
+        pa_log_error("sndfile: %s", sf_error_number(sf_errno));
+        return;
+    }
 
     pa_zero(fi);
     fi.format = sfi.format;
@@ -362,6 +377,7 @@ pa_sndfile_readf_t pa_sndfile_readf_function(const pa_sample_spec *ss) {
             return (pa_sndfile_readf_t) sf_readf_short;
 
         case PA_SAMPLE_S32NE:
+        case PA_SAMPLE_S24_32NE:
             return (pa_sndfile_readf_t) sf_readf_int;
 
         case PA_SAMPLE_FLOAT32NE:
@@ -384,6 +400,7 @@ pa_sndfile_writef_t pa_sndfile_writef_function(const pa_sample_spec *ss) {
             return (pa_sndfile_writef_t) sf_writef_short;
 
         case PA_SAMPLE_S32NE:
+        case PA_SAMPLE_S24_32NE:
             return (pa_sndfile_writef_t) sf_writef_int;
 
         case PA_SAMPLE_FLOAT32NE:
@@ -407,7 +424,6 @@ int pa_sndfile_format_from_string(const char *name) {
 
     pa_assert_se(sf_command(NULL, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof(int)) == 0);
 
-    /* First try to match via full type string */
     for (i = 0; i < count; i++) {
         SF_FORMAT_INFO fi;
         pa_zero(fi);
@@ -415,32 +431,17 @@ int pa_sndfile_format_from_string(const char *name) {
 
         pa_assert_se(sf_command(NULL, SFC_GET_FORMAT_MAJOR, &fi, sizeof(fi)) == 0);
 
+       /* First try to match via full type string */
         if (strcasecmp(name, fi.name) == 0)
-            return i;
-    }
-
-    /* Then, try to match via the full extension */
-    for (i = 0; i < count; i++) {
-        SF_FORMAT_INFO fi;
-        pa_zero(fi);
-        fi.format = i;
-
-        pa_assert_se(sf_command(NULL, SFC_GET_FORMAT_MAJOR, &fi, sizeof(fi)) == 0);
+            return fi.format;
 
+       /* Then, try to match via the full extension */
         if (strcasecmp(name, fi.extension) == 0)
-            return i;
-    }
-
-    /* Then, try to match via the start of the type string */
-    for (i = 0; i < count; i++) {
-        SF_FORMAT_INFO fi;
-        pa_zero(fi);
-        fi.format = i;
-
-        pa_assert_se(sf_command(NULL, SFC_GET_FORMAT_MAJOR, &fi, sizeof(fi)) == 0);
+            return fi.format;
 
-        if (strncasecmp(name, fi.extension, strlen(name)) == 0)
-            return i;
+       /* Then, try to match via the start of the type string */
+        if (strncasecmp(name, fi.name, strlen(name)) == 0)
+            return fi.format;
     }
 
     return -1;
index b9d6950..23d5d88 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
 #ifdef HAVE_SYS_UN_H
 #include <sys/un.h>
 #endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
@@ -56,9 +50,9 @@
 #include <pulse/timeval.h>
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/winsock.h>
-#include <pulsecore/core-error.h>
+#include <pulsecore/socket.h>
 #include <pulsecore/socket-util.h>
+#include <pulsecore/core-error.h>
 #include <pulsecore/core-rtclock.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/socket-util.h>
@@ -66,6 +60,7 @@
 #include <pulsecore/parseaddr.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/refcnt.h>
+#include <pulsecore/arpa-inet.h>
 
 #include "socket-client.h"
 
@@ -257,13 +252,11 @@ static int sockaddr_prepare(pa_socket_client *c, const struct sockaddr *sa, size
 
     c->local = pa_socket_address_is_local(sa);
 
-    if ((c->fd = socket(sa->sa_family, SOCK_STREAM, 0)) < 0) {
+    if ((c->fd = pa_socket_cloexec(sa->sa_family, SOCK_STREAM, 0)) < 0) {
         pa_log("socket(): %s", pa_cstrerror(errno));
         return -1;
     }
 
-    pa_make_fd_cloexec(c->fd);
-
 #ifdef HAVE_IPV6
     if (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)
 #else
@@ -389,7 +382,8 @@ static void asyncns_cb(pa_mainloop_api*m, pa_io_event *e, int fd, pa_io_event_fl
         goto fail;
 
     if (res->ai_addr)
-        sockaddr_prepare(c, res->ai_addr, res->ai_addrlen);
+        if (sockaddr_prepare(c, res->ai_addr, res->ai_addrlen) < 0)
+            goto fail;
 
     asyncns_freeaddrinfo(res);
 
@@ -526,7 +520,7 @@ pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, pa_bool_t use_
                 if (!host)
                     goto finish;
 
-                pa_zero(sa);
+                pa_zero(s);
                 s.sin_family = AF_INET;
                 memcpy(&s.sin_addr, host->h_addr, sizeof(struct in_addr));
                 s.sin_port = htons(a.port);
index e660700..74db9e3 100644 (file)
@@ -32,9 +32,6 @@
 #include <unistd.h>
 #include <sys/stat.h>
 
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
 #ifdef HAVE_SYS_UN_H
 #include <sys/un.h>
 #ifndef SUN_LEN
     ((size_t)(((struct sockaddr_un *) 0)->sun_path) + strlen((ptr)->sun_path))
 #endif
 #endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
 
 #ifdef HAVE_LIBWRAP
 #include <tcpd.h>
-#endif
 
-#ifndef HAVE_INET_NTOP
-#include "inet_ntop.h"
+/* Solaris requires that the allow_severity and deny_severity variables be
+ * defined in the client program. */
+#ifdef __sun
+#include <syslog.h>
+int allow_severity = LOG_INFO;
+int deny_severity = LOG_WARNING;
 #endif
 
-#ifndef HAVE_INET_PTON
-#include "inet_pton.h"
-#endif
-
-#include "winsock.h"
+#endif /* HAVE_LIBWRAP */
 
 #include <pulse/xmalloc.h>
 #include <pulse/util.h>
 
+#include <pulsecore/socket.h>
 #include <pulsecore/socket-util.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-error.h>
 #include <pulsecore/refcnt.h>
+#include <pulsecore/arpa-inet.h>
 
 #include "socket-server.h"
 
@@ -86,7 +81,12 @@ struct pa_socket_server {
 
     pa_io_event *io_event;
     pa_mainloop_api *mainloop;
-    enum { SOCKET_SERVER_GENERIC, SOCKET_SERVER_IPV4, SOCKET_SERVER_UNIX, SOCKET_SERVER_IPV6 } type;
+    enum {
+        SOCKET_SERVER_GENERIC,
+        SOCKET_SERVER_IPV4,
+        SOCKET_SERVER_UNIX,
+        SOCKET_SERVER_IPV6
+    } type;
 };
 
 static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
@@ -104,13 +104,11 @@ static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, pa_io_ev
 
     pa_socket_server_ref(s);
 
-    if ((nfd = accept(fd, NULL, NULL)) < 0) {
+    if ((nfd = pa_accept_cloexec(fd, NULL, NULL)) < 0) {
         pa_log("accept(): %s", pa_cstrerror(errno));
         goto finish;
     }
 
-    pa_make_fd_cloexec(nfd);
-
     if (!s->on_connection) {
         pa_close(nfd);
         goto finish;
@@ -135,9 +133,9 @@ static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, pa_io_ev
 
     /* There should be a check for socket type here */
     if (s->type == SOCKET_SERVER_IPV4)
-        pa_make_tcp_socket_low_delay(fd);
+        pa_make_tcp_socket_low_delay(nfd);
     else
-        pa_make_socket_low_delay(fd);
+        pa_make_socket_low_delay(nfd);
 
     pa_assert_se(io = pa_iochannel_new(s->mainloop, nfd, nfd));
     s->on_connection(s, io, s->userdata);
@@ -152,15 +150,11 @@ pa_socket_server* pa_socket_server_new(pa_mainloop_api *m, int fd) {
     pa_assert(m);
     pa_assert(fd >= 0);
 
-    s = pa_xnew(pa_socket_server, 1);
+    s = pa_xnew0(pa_socket_server, 1);
     PA_REFCNT_INIT(s);
     s->fd = fd;
-    s->filename = NULL;
-    s->on_connection = NULL;
-    s->userdata = NULL;
-    s->tcpwrap_service = NULL;
-
     s->mainloop = m;
+
     pa_assert_se(s->io_event = m->io_new(m, fd, PA_IO_EVENT_INPUT, callback, s));
 
     s->type = SOCKET_SERVER_GENERIC;
@@ -186,13 +180,11 @@ pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *file
     pa_assert(m);
     pa_assert(filename);
 
-    if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
+    if ((fd = pa_socket_cloexec(PF_UNIX, SOCK_STREAM, 0)) < 0) {
         pa_log("socket(): %s", pa_cstrerror(errno));
         goto fail;
     }
 
-    pa_make_fd_cloexec(fd);
-
     memset(&sa, 0, sizeof(sa));
     sa.sun_family = AF_UNIX;
     pa_strlcpy(sa.sun_path, filename, sizeof(sa.sun_path));
@@ -237,7 +229,7 @@ pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *file
 
 #endif /* HAVE_SYS_UN_H */
 
-pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port, const char *tcpwrap_service) {
+pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port, pa_bool_t fallback, const char *tcpwrap_service) {
     pa_socket_server *ss;
     int fd = -1;
     struct sockaddr_in sa;
@@ -246,15 +238,13 @@ pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address
     pa_assert(m);
     pa_assert(port);
 
-    if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
+    if ((fd = pa_socket_cloexec(PF_INET, SOCK_STREAM, 0)) < 0) {
         pa_log("socket(PF_INET): %s", pa_cstrerror(errno));
         goto fail;
     }
 
-    pa_make_fd_cloexec(fd);
-
 #ifdef SO_REUSEADDR
-    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &on, sizeof(on)) < 0)
         pa_log("setsockopt(): %s", pa_cstrerror(errno));
 #endif
 
@@ -266,8 +256,19 @@ pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address
     sa.sin_addr.s_addr = htonl(address);
 
     if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
+
+        if (errno == EADDRINUSE && fallback) {
+            sa.sin_port = 0;
+
+            if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) >= 0)
+                goto good;
+        }
+
         pa_log("bind(): %s", pa_cstrerror(errno));
         goto fail;
+
+    good:
+        ;
     }
 
     if (listen(fd, 5) < 0) {
@@ -290,7 +291,7 @@ fail:
 }
 
 #ifdef HAVE_IPV6
-pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t address[16], uint16_t port, const char *tcpwrap_service) {
+pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t address[16], uint16_t port, pa_bool_t fallback, const char *tcpwrap_service) {
     pa_socket_server *ss;
     int fd = -1;
     struct sockaddr_in6 sa;
@@ -299,22 +300,20 @@ pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t ad
     pa_assert(m);
     pa_assert(port > 0);
 
-    if ((fd = socket(PF_INET6, SOCK_STREAM, 0)) < 0) {
+    if ((fd = pa_socket_cloexec(PF_INET6, SOCK_STREAM, 0)) < 0) {
         pa_log("socket(PF_INET6): %s", pa_cstrerror(errno));
         goto fail;
     }
 
-    pa_make_fd_cloexec(fd);
-
 #ifdef IPV6_V6ONLY
     on = 1;
-    if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0)
+    if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const void *) &on, sizeof(on)) < 0)
         pa_log("setsockopt(IPPROTO_IPV6, IPV6_V6ONLY): %s", pa_cstrerror(errno));
 #endif
 
 #ifdef SO_REUSEADDR
     on = 1;
-    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &on, sizeof(on)) < 0)
         pa_log("setsockopt(SOL_SOCKET, SO_REUSEADDR, 1): %s", pa_cstrerror(errno));
 #endif
 
@@ -326,8 +325,19 @@ pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t ad
     memcpy(sa.sin6_addr.s6_addr, address, 16);
 
     if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
+
+        if (errno == EADDRINUSE && fallback) {
+            sa.sin6_port = 0;
+
+            if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) >= 0)
+                goto good;
+        }
+
         pa_log("bind(): %s", pa_cstrerror(errno));
         goto fail;
+
+    good:
+        ;
     }
 
     if (listen(fd, 5) < 0) {
@@ -350,39 +360,39 @@ fail:
 }
 #endif
 
-pa_socket_server* pa_socket_server_new_ipv4_loopback(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) {
+pa_socket_server* pa_socket_server_new_ipv4_loopback(pa_mainloop_api *m, uint16_t port, pa_bool_t fallback, const char *tcpwrap_service) {
     pa_assert(m);
     pa_assert(port > 0);
 
-    return pa_socket_server_new_ipv4(m, INADDR_LOOPBACK, port, tcpwrap_service);
+    return pa_socket_server_new_ipv4(m, INADDR_LOOPBACK, port, fallback, tcpwrap_service);
 }
 
 #ifdef HAVE_IPV6
-pa_socket_server* pa_socket_server_new_ipv6_loopback(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) {
+pa_socket_server* pa_socket_server_new_ipv6_loopback(pa_mainloop_api *m, uint16_t port, pa_bool_t fallback, const char *tcpwrap_service) {
     pa_assert(m);
     pa_assert(port > 0);
 
-    return pa_socket_server_new_ipv6(m, in6addr_loopback.s6_addr, port, tcpwrap_service);
+    return pa_socket_server_new_ipv6(m, in6addr_loopback.s6_addr, port, fallback, tcpwrap_service);
 }
 #endif
 
-pa_socket_server* pa_socket_server_new_ipv4_any(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) {
+pa_socket_server* pa_socket_server_new_ipv4_any(pa_mainloop_api *m, uint16_t port, pa_bool_t fallback, const char *tcpwrap_service) {
     pa_assert(m);
     pa_assert(port > 0);
 
-    return pa_socket_server_new_ipv4(m, INADDR_ANY, port, tcpwrap_service);
+    return pa_socket_server_new_ipv4(m, INADDR_ANY, port, fallback, tcpwrap_service);
 }
 
 #ifdef HAVE_IPV6
-pa_socket_server* pa_socket_server_new_ipv6_any(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) {
+pa_socket_server* pa_socket_server_new_ipv6_any(pa_mainloop_api *m, uint16_t port, pa_bool_t fallback, const char *tcpwrap_service) {
     pa_assert(m);
     pa_assert(port > 0);
 
-    return pa_socket_server_new_ipv6(m, in6addr_any.s6_addr, port, tcpwrap_service);
+    return pa_socket_server_new_ipv6(m, in6addr_any.s6_addr, port, fallback, tcpwrap_service);
 }
 #endif
 
-pa_socket_server* pa_socket_server_new_ipv4_string(pa_mainloop_api *m, const char *name, uint16_t port, const char *tcpwrap_service) {
+pa_socket_server* pa_socket_server_new_ipv4_string(pa_mainloop_api *m, const char *name, uint16_t port, pa_bool_t fallback, const char *tcpwrap_service) {
     struct in_addr ipv4;
 
     pa_assert(m);
@@ -390,13 +400,13 @@ pa_socket_server* pa_socket_server_new_ipv4_string(pa_mainloop_api *m, const cha
     pa_assert(port > 0);
 
     if (inet_pton(AF_INET, name, &ipv4) > 0)
-        return pa_socket_server_new_ipv4(m, ntohl(ipv4.s_addr), port, tcpwrap_service);
+        return pa_socket_server_new_ipv4(m, ntohl(ipv4.s_addr), port, fallback, tcpwrap_service);
 
     return NULL;
 }
 
 #ifdef HAVE_IPV6
-pa_socket_server* pa_socket_server_new_ipv6_string(pa_mainloop_api *m, const char *name, uint16_t port, const char *tcpwrap_service) {
+pa_socket_server* pa_socket_server_new_ipv6_string(pa_mainloop_api *m, const char *name, uint16_t port, pa_bool_t fallback, const char *tcpwrap_service) {
     struct in6_addr ipv6;
 
     pa_assert(m);
@@ -404,7 +414,7 @@ pa_socket_server* pa_socket_server_new_ipv6_string(pa_mainloop_api *m, const cha
     pa_assert(port > 0);
 
     if (inet_pton(AF_INET6, name, &ipv6) > 0)
-        return pa_socket_server_new_ipv6(m, ipv6.s6_addr, port, tcpwrap_service);
+        return pa_socket_server_new_ipv6(m, ipv6.s6_addr, port, fallback, tcpwrap_service);
 
     return NULL;
 }
index 72b6eda..16da07b 100644 (file)
@@ -33,15 +33,15 @@ typedef struct pa_socket_server pa_socket_server;
 
 pa_socket_server* pa_socket_server_new(pa_mainloop_api *m, int fd);
 pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *filename);
-pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port, const char *tcpwrap_service);
-pa_socket_server* pa_socket_server_new_ipv4_loopback(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service);
-pa_socket_server* pa_socket_server_new_ipv4_any(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service);
-pa_socket_server* pa_socket_server_new_ipv4_string(pa_mainloop_api *m, const char *name, uint16_t port, const char *tcpwrap_service);
+pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port, pa_bool_t fallback, const char *tcpwrap_service);
+pa_socket_server* pa_socket_server_new_ipv4_loopback(pa_mainloop_api *m, uint16_t port, pa_bool_t fallback, const char *tcpwrap_service);
+pa_socket_server* pa_socket_server_new_ipv4_any(pa_mainloop_api *m, uint16_t port, pa_bool_t fallback, const char *tcpwrap_service);
+pa_socket_server* pa_socket_server_new_ipv4_string(pa_mainloop_api *m, const char *name, uint16_t port, pa_bool_t fallback, const char *tcpwrap_service);
 #ifdef HAVE_IPV6
-pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t address[16], uint16_t port, const char *tcpwrap_service);
-pa_socket_server* pa_socket_server_new_ipv6_loopback(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service);
-pa_socket_server* pa_socket_server_new_ipv6_any(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service);
-pa_socket_server* pa_socket_server_new_ipv6_string(pa_mainloop_api *m, const char *name, uint16_t port, const char *tcpwrap_service);
+pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t address[16], uint16_t port, pa_bool_t fallback, const char *tcpwrap_service);
+pa_socket_server* pa_socket_server_new_ipv6_loopback(pa_mainloop_api *m, uint16_t port, pa_bool_t fallback, const char *tcpwrap_service);
+pa_socket_server* pa_socket_server_new_ipv6_any(pa_mainloop_api *m, uint16_t port, pa_bool_t fallback, const char *tcpwrap_service);
+pa_socket_server* pa_socket_server_new_ipv6_string(pa_mainloop_api *m, const char *name, uint16_t port, pa_bool_t fallback, const char *tcpwrap_service);
 #endif
 
 void pa_socket_server_unref(pa_socket_server*s);
index 5fd5dd6..2b8d463 100644 (file)
 #include <config.h>
 #endif
 
-#include <stdarg.h>
 #include <stdlib.h>
 #include <signal.h>
 #include <errno.h>
 #include <string.h>
 #include <stdio.h>
 #include <sys/types.h>
-#include <fcntl.h>
 #include <unistd.h>
 #include <sys/stat.h>
 
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
 #ifdef HAVE_SYS_UN_H
 #include <sys/un.h>
 #endif
 #ifdef HAVE_NETDB_H
 #include <netdb.h>
 #endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-#ifndef HAVE_INET_NTOP
-#include "inet_ntop.h"
-#endif
-
-#include "winsock.h"
-
-#include <pulse/xmalloc.h>
 
 #include <pulsecore/core-error.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
+#include <pulsecore/socket.h>
+#include <pulsecore/arpa-inet.h>
 
 #include "socket-util.h"
 
 void pa_socket_peer_to_string(int fd, char *c, size_t l) {
+#ifndef OS_IS_WIN32
     struct stat st;
+#endif
 
     pa_assert(fd >= 0);
     pa_assert(c);
@@ -85,12 +73,12 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) {
 
 #ifndef OS_IS_WIN32
     pa_assert_se(fstat(fd, &st) == 0);
-#endif
 
-#ifndef OS_IS_WIN32
-    if (S_ISSOCK(st.st_mode)) {
+    if (S_ISSOCK(st.st_mode))
 #endif
+    {
         union {
+            struct sockaddr_storage storage;
             struct sockaddr sa;
             struct sockaddr_in in;
 #ifdef HAVE_IPV6
@@ -133,10 +121,11 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) {
             }
         }
 
-#ifndef OS_IS_WIN32
         pa_snprintf(c, l, "Unknown network client");
         return;
-    } else if (S_ISCHR(st.st_mode) && (fd == 0 || fd == 1)) {
+    }
+#ifndef OS_IS_WIN32
+    else if (S_ISCHR(st.st_mode) && (fd == 0 || fd == 1)) {
         pa_snprintf(c, l, "STDIN/STDOUT client");
         return;
     }
@@ -152,7 +141,7 @@ void pa_make_socket_low_delay(int fd) {
     pa_assert(fd >= 0);
 
     priority = 6;
-    if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (void*)&priority, sizeof(priority)) < 0)
+    if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (const void *) &priority, sizeof(priority)) < 0)
         pa_log_warn("SO_PRIORITY failed: %s", pa_cstrerror(errno));
 #endif
 }
@@ -166,9 +155,9 @@ void pa_make_tcp_socket_low_delay(int fd) {
     {
         int on = 1;
 #if defined(SOL_TCP)
-        if (setsockopt(fd, SOL_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0)
+        if (setsockopt(fd, SOL_TCP, TCP_NODELAY, (const void *) &on, sizeof(on)) < 0)
 #else
-        if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0)
+        if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const void *) &on, sizeof(on)) < 0)
 #endif
             pa_log_warn("TCP_NODELAY failed: %s", pa_cstrerror(errno));
     }
@@ -178,9 +167,9 @@ void pa_make_tcp_socket_low_delay(int fd) {
     {
         int tos = IPTOS_LOWDELAY;
 #ifdef SOL_IP
-        if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0)
+        if (setsockopt(fd, SOL_IP, IP_TOS, (const void *) &tos, sizeof(tos)) < 0)
 #else
-        if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0)
+        if (setsockopt(fd, IPPROTO_IP, IP_TOS, (const void *) &tos, sizeof(tos)) < 0)
 #endif
             pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno));
     }
@@ -196,9 +185,9 @@ void pa_make_udp_socket_low_delay(int fd) {
     {
         int tos = IPTOS_LOWDELAY;
 #ifdef SOL_IP
-        if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0)
+        if (setsockopt(fd, SOL_IP, IP_TOS, (const void *) &tos, sizeof(tos)) < 0)
 #else
-        if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0)
+        if (setsockopt(fd, IPPROTO_IP, IP_TOS, (const void *) &tos, sizeof(tos)) < 0)
 #endif
             pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno));
     }
@@ -206,11 +195,11 @@ void pa_make_udp_socket_low_delay(int fd) {
 }
 
 int pa_socket_set_rcvbuf(int fd, size_t l) {
-    int bufsz = (int)l;
+    int bufsz = (int) l;
 
     pa_assert(fd >= 0);
 
-    if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void*)&bufsz, sizeof(bufsz)) < 0) {
+    if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const void *) &bufsz, sizeof(bufsz)) < 0) {
         pa_log_warn("SO_RCVBUF: %s", pa_cstrerror(errno));
         return -1;
     }
@@ -219,12 +208,12 @@ int pa_socket_set_rcvbuf(int fd, size_t l) {
 }
 
 int pa_socket_set_sndbuf(int fd, size_t l) {
-    int bufsz = (int)l;
+    int bufsz = (int) l;
 
     pa_assert(fd >= 0);
 
-    if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void*)&bufsz, sizeof(bufsz)) < 0) {
-        pa_log("SO_SNDBUF: %s", pa_cstrerror(errno));
+    if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &bufsz, sizeof(bufsz)) < 0) {
+        pa_log_warn("SO_SNDBUF: %s", pa_cstrerror(errno));
         return -1;
     }
 
@@ -239,7 +228,7 @@ int pa_unix_socket_is_stale(const char *fn) {
 
     pa_assert(fn);
 
-    if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
+    if ((fd = pa_socket_cloexec(PF_UNIX, SOCK_STREAM, 0)) < 0) {
         pa_log("socket(): %s", pa_cstrerror(errno));
         goto finish;
     }
@@ -315,6 +304,7 @@ pa_bool_t pa_socket_address_is_local(const struct sockaddr *sa) {
 pa_bool_t pa_socket_is_local(int fd) {
 
     union {
+        struct sockaddr_storage storage;
         struct sockaddr sa;
         struct sockaddr_in in;
 #ifdef HAVE_IPV6
index f6d1637..154afd4 100644 (file)
@@ -24,8 +24,8 @@
 ***/
 
 #include <sys/types.h>
-#include <sys/socket.h>
 
+#include <pulsecore/socket.h>
 #include <pulsecore/macro.h>
 
 void pa_socket_peer_to_string(int fd, char *c, size_t l);
similarity index 77%
rename from src/pulsecore/winsock.h
rename to src/pulsecore/socket.h
index 0352bf4..0d38bee 100644 (file)
@@ -1,5 +1,9 @@
-#ifndef foowinsockhfoo
-#define foowinsockhfoo
+#ifndef foopulsecoresockethfoo
+#define foopulsecoresockethfoo
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
 
 #ifdef HAVE_WINSOCK2_H
 #include <winsock2.h>
@@ -14,6 +18,7 @@
 #define ECONNREFUSED    WSAECONNREFUSED
 #define EHOSTUNREACH    WSAEHOSTUNREACH
 #define EWOULDBLOCK     WSAEWOULDBLOCK
+#define EADDRINUSE      WSAEADDRINUSE
 
 typedef long suseconds_t;
 
index 16de492..4101dea 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
@@ -40,7 +39,7 @@
 #include <pulsecore/log.h>
 #include <pulsecore/thread-mq.h>
 #include <pulsecore/core-util.h>
-#include <pulsecore/sample-util.h>
+#include <pulsecore/mix.h>
 #include <pulsecore/sndfile-util.h>
 
 #include "sound-file-stream.h"
@@ -200,7 +199,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk
     }
 
     return -1;
- }
+}
 
 static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {
     file_stream *u;
@@ -239,6 +238,7 @@ int pa_play_file(
     pa_sink_input_new_data data;
     int fd;
     SF_INFO sfi;
+    pa_memchunk silence;
 
     pa_assert(sink);
     pa_assert(fname);
@@ -252,11 +252,7 @@ int pa_play_file(
     u->readf_function = NULL;
     u->memblockq = NULL;
 
-    if ((fd = open(fname, O_RDONLY
-#ifdef O_NOCTTY
-                   |O_NOCTTY
-#endif
-                   )) < 0) {
+    if ((fd = pa_open_cloexec(fname, O_RDONLY, 0)) < 0) {
         pa_log("Failed to open file %s: %s", fname, pa_cstrerror(errno));
         goto fail;
     }
@@ -302,7 +298,7 @@ int pa_play_file(
     u->readf_function = pa_sndfile_readf_function(&ss);
 
     pa_sink_input_new_data_init(&data);
-    data.sink = sink;
+    pa_sink_input_new_data_set_sink(&data, sink, FALSE);
     data.driver = __FILE__;
     pa_sink_input_new_data_set_sample_spec(&data, &ss);
     pa_sink_input_new_data_set_channel_map(&data, &cm);
@@ -324,7 +320,9 @@ int pa_play_file(
     u->sink_input->state_change = sink_input_state_change_cb;
     u->sink_input->userdata = u;
 
-    u->memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, NULL);
+    pa_sink_input_get_silence(u->sink_input, &silence);
+    u->memblockq = pa_memblockq_new("sound-file-stream memblockq", 0, MEMBLOCKQ_MAXLENGTH, 0, &ss, 1, 1, 0, &silence);
+    pa_memblock_unref(silence.memblock);
 
     pa_sink_input_put(u->sink_input);
 
index 2d9b76a..a20286f 100644 (file)
@@ -23,7 +23,6 @@
 #include <config.h>
 #endif
 
-#include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
@@ -62,11 +61,7 @@ int pa_sound_file_load(
 
     pa_memchunk_reset(chunk);
 
-    if ((fd = open(fname, O_RDONLY
-#ifdef O_NOCTTY
-                   |O_NOCTTY
-#endif
-                   )) < 0) {
+    if ((fd = pa_open_cloexec(fname, O_RDONLY, 0)) < 0) {
         pa_log("Failed to open file %s: %s", fname, pa_cstrerror(errno));
         goto finish;
     }
@@ -76,7 +71,7 @@ int pa_sound_file_load(
         pa_log_warn("POSIX_FADV_SEQUENTIAL failed: %s", pa_cstrerror(errno));
         goto finish;
     } else
-        pa_log_debug("POSIX_FADV_SEQUENTIAL succeeded.");
+        pa_log_debug_verbose("POSIX_FADV_SEQUENTIAL succeeded.");
 #endif
 
     pa_zero(sfi);
index 57ccc06..1264638 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifdef __TIZEN__
+#include <time.h>
+#endif
 
 #include <pulse/utf8.h>
 #include <pulse/xmalloc.h>
 #include <pulse/util.h>
+#include <pulse/internal.h>
 
-#include <pulsecore/sample-util.h>
+#include <pulsecore/mix.h>
 #include <pulsecore/core-subscribe.h>
 #include <pulsecore/log.h>
 #include <pulsecore/namereg.h>
 PA_DEFINE_PUBLIC_CLASS(pa_source_output, pa_msgobject);
 
 static void source_output_free(pa_object* mo);
+static void set_real_ratio(pa_source_output *o, const pa_cvolume *v);
+
+#ifdef __TIZEN__
+#define PA_SOURCE_OUTPUT_DUMP_PATH_PREFIX      "/tmp/dump_pa_source_output"
+#endif
 
 pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data) {
     pa_assert(data);
@@ -51,6 +60,7 @@ pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_d
     pa_zero(*data);
     data->resample_method = PA_RESAMPLER_INVALID;
     data->proplist = pa_proplist_new();
+    data->volume_writable = TRUE;
 
     return data;
 }
@@ -69,9 +79,119 @@ void pa_source_output_new_data_set_channel_map(pa_source_output_new_data *data,
         data->channel_map = *map;
 }
 
+pa_bool_t pa_source_output_new_data_is_passthrough(pa_source_output_new_data *data) {
+    pa_assert(data);
+
+    if (PA_LIKELY(data->format) && PA_UNLIKELY(!pa_format_info_is_pcm(data->format)))
+        return TRUE;
+
+    if (PA_UNLIKELY(data->flags & PA_SOURCE_OUTPUT_PASSTHROUGH))
+        return TRUE;
+
+    return FALSE;
+}
+
+void pa_source_output_new_data_set_volume(pa_source_output_new_data *data, const pa_cvolume *volume) {
+    pa_assert(data);
+    pa_assert(data->volume_writable);
+
+    if ((data->volume_is_set = !!volume))
+        data->volume = *volume;
+}
+
+void pa_source_output_new_data_apply_volume_factor(pa_source_output_new_data *data, const pa_cvolume *volume_factor) {
+    pa_assert(data);
+    pa_assert(volume_factor);
+
+    if (data->volume_factor_is_set)
+        pa_sw_cvolume_multiply(&data->volume_factor, &data->volume_factor, volume_factor);
+    else {
+        data->volume_factor_is_set = TRUE;
+        data->volume_factor = *volume_factor;
+    }
+}
+
+void pa_source_output_new_data_apply_volume_factor_source(pa_source_output_new_data *data, const pa_cvolume *volume_factor) {
+    pa_assert(data);
+    pa_assert(volume_factor);
+
+    if (data->volume_factor_source_is_set)
+        pa_sw_cvolume_multiply(&data->volume_factor_source, &data->volume_factor_source, volume_factor);
+    else {
+        data->volume_factor_source_is_set = TRUE;
+        data->volume_factor_source = *volume_factor;
+    }
+}
+
+void pa_source_output_new_data_set_muted(pa_source_output_new_data *data, pa_bool_t mute) {
+    pa_assert(data);
+
+    data->muted_is_set = TRUE;
+    data->muted = !!mute;
+}
+
+pa_bool_t pa_source_output_new_data_set_source(pa_source_output_new_data *data, pa_source *s, pa_bool_t save) {
+    pa_bool_t ret = TRUE;
+    pa_idxset *formats = NULL;
+
+    pa_assert(data);
+    pa_assert(s);
+
+    if (!data->req_formats) {
+        /* We're not working with the extended API */
+        data->source = s;
+        data->save_source = save;
+    } else {
+        /* Extended API: let's see if this source supports the formats the client would like */
+        formats = pa_source_check_formats(s, data->req_formats);
+
+        if (formats && !pa_idxset_isempty(formats)) {
+            /* Source supports at least one of the requested formats */
+            data->source = s;
+            data->save_source = save;
+            if (data->nego_formats)
+                pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free);
+            data->nego_formats = formats;
+        } else {
+            /* Source doesn't support any of the formats requested by the client */
+            if (formats)
+                pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
+            ret = FALSE;
+        }
+    }
+
+    return ret;
+}
+
+pa_bool_t pa_source_output_new_data_set_formats(pa_source_output_new_data *data, pa_idxset *formats) {
+    pa_assert(data);
+    pa_assert(formats);
+
+    if (data->req_formats)
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
+
+    data->req_formats = formats;
+
+    if (data->source) {
+        /* Trigger format negotiation */
+        return pa_source_output_new_data_set_source(data, data->source, data->save_source);
+    }
+
+    return TRUE;
+}
+
 void pa_source_output_new_data_done(pa_source_output_new_data *data) {
     pa_assert(data);
 
+    if (data->req_formats)
+        pa_idxset_free(data->req_formats, (pa_free_cb_t) pa_format_info_free);
+
+    if (data->nego_formats)
+        pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free);
+
+    if (data->format)
+        pa_format_info_free(data->format);
+
     pa_proplist_free(data->proplist);
 }
 
@@ -95,6 +215,8 @@ static void reset_callbacks(pa_source_output *o) {
     o->state_change = NULL;
     o->may_move_to = NULL;
     o->send_event = NULL;
+    o->volume_changed = NULL;
+    o->mute_changed = NULL;
 }
 
 /* Called from main context */
@@ -106,8 +228,11 @@ int pa_source_output_new(
     pa_source_output *o;
     pa_resampler *resampler = NULL;
     char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
+    pa_channel_map original_cm;
     int r;
     char *pt;
+    pa_sample_spec ss;
+    pa_channel_map map;
 
     pa_assert(_o);
     pa_assert(core);
@@ -117,17 +242,52 @@ int pa_source_output_new(
     if (data->client)
         pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->client->proplist);
 
+    if (data->destination_source && (data->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
+        data->volume_writable = FALSE;
+
+    if (!data->req_formats) {
+        /* From this point on, we want to work only with formats, and get back
+         * to using the sample spec and channel map after all decisions w.r.t.
+         * routing are complete. */
+        pa_idxset *tmp = pa_idxset_new(NULL, NULL);
+        pa_format_info *f = pa_format_info_from_sample_spec(&data->sample_spec,
+                data->channel_map_is_set ? &data->channel_map : NULL);
+        pa_idxset_put(tmp, f, NULL);
+        pa_source_output_new_data_set_formats(data, tmp);
+    }
+
     if ((r = pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NEW], data)) < 0)
         return r;
 
     pa_return_val_if_fail(!data->driver || pa_utf8_valid(data->driver), -PA_ERR_INVALID);
 
     if (!data->source) {
-        data->source = pa_namereg_get(core, NULL, PA_NAMEREG_SOURCE);
-        data->save_source = FALSE;
+        pa_source *source = pa_namereg_get(core, NULL, PA_NAMEREG_SOURCE);
+        pa_return_val_if_fail(source, -PA_ERR_NOENTITY);
+        pa_source_output_new_data_set_source(data, source, FALSE);
     }
+    else
+    {
+       pa_source_output_new_data_set_source(data, data->source, FALSE);
+    }
+
+    /* Routing's done, we have a source. Now let's fix the format and set up the
+     * sample spec */
+
+    /* If something didn't pick a format for us, pick the top-most format since
+     * we assume this is sorted in priority order */
+    if (!data->format && data->nego_formats && !pa_idxset_isempty(data->nego_formats))
+        data->format = pa_format_info_copy(pa_idxset_first(data->nego_formats, NULL));
+
+    pa_return_val_if_fail(data->format, -PA_ERR_NOTSUPPORTED);
+
+    /* Now populate the sample spec and format according to the final
+     * format that we've negotiated */
+    pa_return_val_if_fail(pa_format_info_to_sample_spec(data->format, &ss, &map) == 0, -PA_ERR_INVALID);
+    pa_source_output_new_data_set_sample_spec(data, &ss);
+    if (pa_format_info_is_pcm(data->format) && pa_channel_map_valid(&map))
+        pa_source_output_new_data_set_channel_map(data, &map);
 
-    pa_return_val_if_fail(data->source, -PA_ERR_NOENTITY);
     pa_return_val_if_fail(PA_SOURCE_IS_LINKED(pa_source_get_state(data->source)), -PA_ERR_BADSTATE);
     pa_return_val_if_fail(!data->direct_on_input || data->direct_on_input->sink == data->source->monitor_of, -PA_ERR_INVALID);
 
@@ -143,23 +303,87 @@ int pa_source_output_new(
             pa_channel_map_init_extend(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
     }
 
-    pa_return_val_if_fail(pa_channel_map_valid(&data->channel_map), -PA_ERR_INVALID);
     pa_return_val_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec), -PA_ERR_INVALID);
 
-    if (data->flags & PA_SOURCE_OUTPUT_FIX_FORMAT)
+    /* Don't restore (or save) stream volume for passthrough streams and
+     * prevent attenuation/gain */
+    if (pa_source_output_new_data_is_passthrough(data)) {
+        data->volume_is_set = TRUE;
+        pa_cvolume_reset(&data->volume, data->sample_spec.channels);
+        data->volume_is_absolute = TRUE;
+        data->save_volume = FALSE;
+    }
+
+    if (!data->volume_is_set) {
+        pa_cvolume_reset(&data->volume, data->sample_spec.channels);
+        data->volume_is_absolute = FALSE;
+        data->save_volume = FALSE;
+    }
+
+    if (!data->volume_writable)
+        data->save_volume = false;
+
+    pa_return_val_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec), -PA_ERR_INVALID);
+
+    if (!data->volume_factor_is_set)
+        pa_cvolume_reset(&data->volume_factor, data->sample_spec.channels);
+
+    pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor, &data->sample_spec), -PA_ERR_INVALID);
+
+    if (!data->volume_factor_source_is_set)
+        pa_cvolume_reset(&data->volume_factor_source, data->source->sample_spec.channels);
+
+    pa_return_val_if_fail(pa_cvolume_compatible(&data->volume_factor_source, &data->source->sample_spec), -PA_ERR_INVALID);
+
+    if (!data->muted_is_set)
+        data->muted = FALSE;
+
+    if (data->flags & PA_SOURCE_OUTPUT_FIX_FORMAT) {
+        pa_return_val_if_fail(pa_format_info_is_pcm(data->format), -PA_ERR_INVALID);
         data->sample_spec.format = data->source->sample_spec.format;
+        pa_format_info_set_sample_format(data->format, data->sample_spec.format);
+    }
 
-    if (data->flags & PA_SOURCE_OUTPUT_FIX_RATE)
+    if (data->flags & PA_SOURCE_OUTPUT_FIX_RATE) {
+        pa_return_val_if_fail(pa_format_info_is_pcm(data->format), -PA_ERR_INVALID);
+        pa_format_info_set_rate(data->format, data->sample_spec.rate);
         data->sample_spec.rate = data->source->sample_spec.rate;
+    }
+
+    original_cm = data->channel_map;
 
     if (data->flags & PA_SOURCE_OUTPUT_FIX_CHANNELS) {
+        pa_return_val_if_fail(pa_format_info_is_pcm(data->format), -PA_ERR_INVALID);
         data->sample_spec.channels = data->source->sample_spec.channels;
         data->channel_map = data->source->channel_map;
+        pa_format_info_set_channels(data->format, data->sample_spec.channels);
+        pa_format_info_set_channel_map(data->format, &data->channel_map);
     }
 
     pa_assert(pa_sample_spec_valid(&data->sample_spec));
     pa_assert(pa_channel_map_valid(&data->channel_map));
 
+    if (!(data->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) &&
+        !pa_sample_spec_equal(&data->sample_spec, &data->source->sample_spec)){
+        /* try to change source rate. This is done before the FIXATE hook since
+           module-suspend-on-idle can resume a source */
+
+        pa_log_info("Trying to change sample rate");
+        if (pa_source_update_rate(data->source, data->sample_spec.rate, pa_source_output_new_data_is_passthrough(data)) == TRUE)
+            pa_log_info("Rate changed to %u Hz", data->source->sample_spec.rate);
+    }
+
+    if (pa_source_output_new_data_is_passthrough(data) &&
+        !pa_sample_spec_equal(&data->sample_spec, &data->source->sample_spec)) {
+        /* rate update failed, or other parts of sample spec didn't match */
+
+        pa_log_debug("Could not update source sample spec to match passthrough stream");
+        return -PA_ERR_NOTSUPPORTED;
+    }
+
+    /* Due to the fixing of the sample spec the volume might not match anymore */
+    pa_cvolume_remap(&data->volume, &original_cm, &data->channel_map);
+
     if (data->resample_method == PA_RESAMPLER_INVALID)
         data->resample_method = core->resample_method;
 
@@ -183,18 +407,19 @@ int pa_source_output_new(
         !pa_sample_spec_equal(&data->sample_spec, &data->source->sample_spec) ||
         !pa_channel_map_equal(&data->channel_map, &data->source->channel_map)) {
 
-        if (!(resampler = pa_resampler_new(
-                      core->mempool,
-                      &data->source->sample_spec, &data->source->channel_map,
-                      &data->sample_spec, &data->channel_map,
-                      data->resample_method,
-                      ((data->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
-                      ((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->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
-            pa_log_warn("Unsupported resampling operation.");
-            return -PA_ERR_NOTSUPPORTED;
-        }
+        if (!pa_source_output_new_data_is_passthrough(data)) /* no resampler for passthrough content */
+            if (!(resampler = pa_resampler_new(
+                        core->mempool,
+                        &data->source->sample_spec, &data->source->channel_map,
+                        &data->sample_spec, &data->channel_map,
+                        data->resample_method,
+                        ((data->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
+                        ((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->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
+                pa_log_warn("Unsupported resampling operation.");
+                return -PA_ERR_NOTSUPPORTED;
+            }
     }
 
     o = pa_msgobject_new(pa_source_output);
@@ -208,32 +433,61 @@ int pa_source_output_new(
     o->driver = pa_xstrdup(pa_path_get_filename(data->driver));
     o->module = data->module;
     o->source = data->source;
+    o->destination_source = data->destination_source;
     o->client = data->client;
 
-    o->actual_resample_method = resampler ? pa_resampler_get_method(resampler) : PA_RESAMPLER_INVALID;
     o->requested_resample_method = data->resample_method;
+    o->actual_resample_method = resampler ? pa_resampler_get_method(resampler) : PA_RESAMPLER_INVALID;
     o->sample_spec = data->sample_spec;
     o->channel_map = data->channel_map;
+    o->format = pa_format_info_copy(data->format);
 
-    o->direct_on_input = data->direct_on_input;
+    if (!data->volume_is_absolute && pa_source_flat_volume_enabled(o->source)) {
+        pa_cvolume remapped;
 
+        /* When the 'absolute' bool is not set then we'll treat the volume
+         * as relative to the source volume even in flat volume mode */
+        remapped = data->source->reference_volume;
+        pa_cvolume_remap(&remapped, &data->source->channel_map, &data->channel_map);
+        pa_sw_cvolume_multiply(&o->volume, &data->volume, &remapped);
+    } else
+        o->volume = data->volume;
+
+    o->volume_factor = data->volume_factor;
+    o->volume_factor_source = data->volume_factor_source;
+    o->real_ratio = o->reference_ratio = data->volume;
+    pa_cvolume_reset(&o->soft_volume, o->sample_spec.channels);
+    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->save_muted = data->save_muted;
+
+    o->muted = data->muted;
+
+    o->direct_on_input = data->direct_on_input;
 
     reset_callbacks(o);
     o->userdata = NULL;
+#ifdef __TIZEN__
+    o->dump_fp = NULL;
+#endif
 
     o->thread_info.state = o->state;
     o->thread_info.attached = FALSE;
     o->thread_info.sample_spec = o->sample_spec;
     o->thread_info.resampler = resampler;
+    o->thread_info.soft_volume = o->soft_volume;
+    o->thread_info.muted = o->muted;
     o->thread_info.requested_source_latency = (pa_usec_t) -1;
     o->thread_info.direct_on_input = o->direct_on_input;
 
     o->thread_info.delay_memblockq = pa_memblockq_new(
+            "source output delay_memblockq",
             0,
             MEMBLOCKQ_MAXLENGTH,
             0,
-            pa_frame_size(&o->source->sample_spec),
+            &o->source->sample_spec,
             0,
             1,
             0,
@@ -249,13 +503,14 @@ int pa_source_output_new(
         pa_assert_se(pa_idxset_put(o->direct_on_input->direct_outputs, o, NULL) == 0);
 
     pt = pa_proplist_to_string_sep(o->proplist, "\n    ");
-    pa_log_info("Created output %u \"%s\" on %s with sample spec %s and channel map %s\n    %s",
+    pa_log_info("Created output %u \"%s\" (%s) on %s with sample spec %s and channel map %s\n",
                 o->index,
                 pa_strnull(pa_proplist_gets(o->proplist, PA_PROP_MEDIA_NAME)),
+                pa_strnull(pa_proplist_gets(o->proplist, PA_PROP_APPLICATION_PROCESS_ID)),
                 o->source->name,
                 pa_sample_spec_snprint(st, sizeof(st), &o->sample_spec),
-                pa_channel_map_snprint(cm, sizeof(cm), &o->channel_map),
-                pt);
+                pa_channel_map_snprint(cm, sizeof(cm), &o->channel_map));
+    pa_log_debug("    %s", pt);
     pa_xfree(pt);
 
     /* Don't forget to call pa_source_output_put! */
@@ -280,20 +535,32 @@ static void update_n_corked(pa_source_output *o, pa_source_output_state_t state)
 
 /* Called from main context */
 static void source_output_set_state(pa_source_output *o, pa_source_output_state_t state) {
+
     pa_assert(o);
     pa_assert_ctl_context();
 
     if (o->state == state)
         return;
 
+    if (o->state == PA_SOURCE_OUTPUT_CORKED && state == PA_SOURCE_OUTPUT_RUNNING && pa_source_used_by(o->source) == 0 &&
+        !pa_sample_spec_equal(&o->sample_spec, &o->source->sample_spec)) {
+        /* We were uncorked and the source was not playing anything -- let's try
+         * to update the sample rate to avoid resampling */
+        pa_source_update_rate(o->source, o->sample_spec.rate, pa_source_output_is_passthrough(o));
+    }
+
     pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) == 0);
 
     update_n_corked(o, state);
     o->state = state;
 
-    if (state != PA_SOURCE_OUTPUT_UNLINKED)
+    if (state != PA_SOURCE_OUTPUT_UNLINKED) {
         pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_STATE_CHANGED], o);
 
+        if (PA_SOURCE_OUTPUT_IS_LINKED(state))
+            pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
+    }
+
     pa_source_update_status(o->source);
 }
 
@@ -328,9 +595,17 @@ void pa_source_output_unlink(pa_source_output*o) {
     update_n_corked(o, PA_SOURCE_OUTPUT_UNLINKED);
     o->state = PA_SOURCE_OUTPUT_UNLINKED;
 
-    if (linked && o->source)
+    if (linked && o->source) {
+        if (pa_source_output_is_passthrough(o))
+            pa_source_leave_passthrough(o->source);
+
+        /* We might need to update the source's volume if we are in flat volume mode. */
+        if (pa_source_flat_volume_enabled(o->source))
+            pa_source_set_volume(o->source, NULL, FALSE, FALSE);
+
         if (o->source->asyncmsgq)
             pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, 0, NULL) == 0);
+    }
 
     reset_callbacks(o);
 
@@ -340,7 +615,9 @@ void pa_source_output_unlink(pa_source_output*o) {
     }
 
     if (o->source) {
-        pa_source_update_status(o->source);
+        if (PA_SOURCE_IS_LINKED(pa_source_get_state(o->source)))
+            pa_source_update_status(o->source);
+
         o->source = NULL;
     }
 
@@ -368,6 +645,17 @@ static void source_output_free(pa_object* mo) {
     if (o->thread_info.resampler)
         pa_resampler_free(o->thread_info.resampler);
 
+#ifdef __TIZEN__
+    /* close file for dump pcm */
+    if (o->dump_fp) {
+        fclose(o->dump_fp);
+        o->dump_fp = NULL;
+    }
+#endif
+
+    if (o->format)
+        pa_format_info_free(o->format);
+
     if (o->proplist)
         pa_proplist_free(o->proplist);
 
@@ -393,6 +681,24 @@ void pa_source_output_put(pa_source_output *o) {
     update_n_corked(o, state);
     o->state = state;
 
+    /* We might need to update the source's volume if we are in flat volume mode. */
+    if (pa_source_flat_volume_enabled(o->source))
+        pa_source_set_volume(o->source, NULL, FALSE, o->save_volume);
+    else {
+        if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
+            pa_assert(pa_cvolume_is_norm(&o->volume));
+            pa_assert(pa_cvolume_is_norm(&o->reference_ratio));
+        }
+
+        set_real_ratio(o, &o->volume);
+    }
+
+    if (pa_source_output_is_passthrough(o))
+        pa_source_enter_passthrough(o->source);
+
+    o->thread_info.soft_volume = o->soft_volume;
+    o->thread_info.muted = o->muted;
+
     pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_ADD_OUTPUT, o, 0, NULL) == 0);
 
     pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW, o->index);
@@ -431,6 +737,8 @@ pa_usec_t pa_source_output_get_latency(pa_source_output *o, pa_usec_t *source_la
 
 /* Called from thread context */
 void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) {
+    pa_bool_t need_volume_factor_source;
+    pa_bool_t volume_is_norm;
     size_t length;
     size_t limit, mbs = 0;
 
@@ -452,6 +760,9 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) {
 
     limit = o->process_rewind ? 0 : o->source->thread_info.max_rewind;
 
+    volume_is_norm = pa_cvolume_is_norm(&o->thread_info.soft_volume) && !o->thread_info.muted;
+    need_volume_factor_source = !pa_cvolume_is_norm(&o->volume_factor_source);
+
     if (limit > 0 && o->source->monitor_of) {
         pa_usec_t latency;
         size_t n;
@@ -474,6 +785,7 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) {
     /* Implement the delay queue */
     while ((length = pa_memblockq_get_length(o->thread_info.delay_memblockq)) > limit) {
         pa_memchunk qchunk;
+        pa_bool_t nvfs = need_volume_factor_source;
 
         length -= limit;
 
@@ -484,9 +796,36 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) {
 
         pa_assert(qchunk.length > 0);
 
-        if (!o->thread_info.resampler)
+        /* It might be necessary to adjust the volume here */
+        if (!volume_is_norm) {
+            pa_memchunk_make_writable(&qchunk, 0);
+
+            if (o->thread_info.muted) {
+                pa_silence_memchunk(&qchunk, &o->source->sample_spec);
+                nvfs = FALSE;
+
+            } else if (!o->thread_info.resampler && nvfs) {
+                pa_cvolume v;
+
+                /* If we don't need a resampler we can merge the
+                 * post and the pre volume adjustment into one */
+
+                pa_sw_cvolume_multiply(&v, &o->thread_info.soft_volume, &o->volume_factor_source);
+                pa_volume_memchunk(&qchunk, &o->source->sample_spec, &v);
+                nvfs = FALSE;
+
+            } else
+                pa_volume_memchunk(&qchunk, &o->source->sample_spec, &o->thread_info.soft_volume);
+        }
+
+        if (!o->thread_info.resampler) {
+            if (nvfs) {
+                pa_memchunk_make_writable(&qchunk, 0);
+                pa_volume_memchunk(&qchunk, &o->thread_info.sample_spec, &o->volume_factor_source);
+            }
+
             o->push(o, &qchunk);
-        else {
+        else {
             pa_memchunk rchunk;
 
             if (mbs == 0)
@@ -497,8 +836,14 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) {
 
             pa_resampler_run(o->thread_info.resampler, &qchunk, &rchunk);
 
-            if (rchunk.length > 0)
+            if (rchunk.length > 0) {
+                if (nvfs) {
+                    pa_memchunk_make_writable(&rchunk, 0);
+                    pa_volume_memchunk(&rchunk, &o->thread_info.sample_spec, &o->volume_factor_source);
+                }
+
                 o->push(o, &rchunk);
+            }
 
             if (rchunk.memblock)
                 pa_memblock_unref(rchunk.memblock);
@@ -507,6 +852,38 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) {
         pa_memblock_unref(qchunk.memblock);
         pa_memblockq_drop(o->thread_info.delay_memblockq, qchunk.length);
     }
+
+#ifdef __TIZEN__
+    /* open file for dump pcm */
+    if (o->core->dump_source_output && !o->dump_fp) {
+        time_t t;
+        char datetime[12];
+        char *dump_path = NULL;
+
+        time(&t);
+        memset(&datetime[0], 0x00, sizeof(datetime));
+        strftime(&datetime[0], sizeof(datetime), "%m%d_%H%M%S", localtime(&t));
+        dump_path = pa_sprintf_malloc("%s_%s_%d_source%d.pcm", PA_SOURCE_OUTPUT_DUMP_PATH_PREFIX, &datetime[0], o->index, o->source->index);
+
+        if (dump_path) {
+            o->dump_fp = fopen(dump_path, "w");
+            pa_xfree(dump_path);
+        }
+    /* close file for dump pcm when config is changed */
+    } else if (!o->core->dump_source_output && o->dump_fp) {
+        fclose(o->dump_fp);
+        o->dump_fp = NULL;
+    }
+
+    /* dump pcm */
+    if (o->dump_fp) {
+        void *ptr;
+
+        ptr = pa_memblock_acquire(chunk->memblock);
+        fwrite((uint8_t*) ptr + chunk->index, 1, chunk->length, o->dump_fp);
+        pa_memblock_release(chunk->memblock);
+    }
+#endif
 }
 
 /* Called from thread context */
@@ -527,6 +904,12 @@ void pa_source_output_process_rewind(pa_source_output *o, size_t nbytes /* in so
             nbytes = pa_resampler_result(o->thread_info.resampler, nbytes);
 
         pa_log_debug("Have to rewind %lu bytes on implementor.", (unsigned long) nbytes);
+#ifdef __TIZEN__
+        /* rewind pcm */
+        if (o->dump_fp) {
+            fseeko(o->dump_fp, (off_t)nbytes * (-1), SEEK_CUR);
+        }
+#endif
 
         if (nbytes > 0)
             o->process_rewind(o, nbytes);
@@ -621,6 +1004,167 @@ pa_usec_t pa_source_output_get_requested_latency(pa_source_output *o) {
 }
 
 /* Called from main context */
+void pa_source_output_set_volume(pa_source_output *o, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute) {
+    pa_cvolume v;
+
+    pa_source_output_assert_ref(o);
+    pa_assert_ctl_context();
+    pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state));
+    pa_assert(volume);
+    pa_assert(pa_cvolume_valid(volume));
+    pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &o->sample_spec));
+    pa_assert(o->volume_writable);
+
+    if (!absolute && pa_source_flat_volume_enabled(o->source)) {
+        v = o->source->reference_volume;
+        pa_cvolume_remap(&v, &o->source->channel_map, &o->channel_map);
+
+        if (pa_cvolume_compatible(volume, &o->sample_spec))
+            volume = pa_sw_cvolume_multiply(&v, &v, volume);
+        else
+            volume = pa_sw_cvolume_multiply_scalar(&v, &v, pa_cvolume_max(volume));
+    } else {
+        if (!pa_cvolume_compatible(volume, &o->sample_spec)) {
+            v = o->volume;
+            volume = pa_cvolume_scale(&v, pa_cvolume_max(volume));
+        }
+    }
+
+    if (pa_cvolume_equal(volume, &o->volume)) {
+        o->save_volume = o->save_volume || save;
+        return;
+    }
+
+    o->volume = *volume;
+    o->save_volume = save;
+
+    if (pa_source_flat_volume_enabled(o->source)) {
+        /* We are in flat volume mode, so let's update all source input
+         * volumes and update the flat volume of the source */
+
+        pa_source_set_volume(o->source, NULL, TRUE, save);
+
+    } else {
+        /* OK, we are in normal volume mode. The volume only affects
+         * ourselves */
+        set_real_ratio(o, volume);
+
+        /* Copy the new soft_volume to the thread_info struct */
+        pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_SOFT_VOLUME, NULL, 0, NULL) == 0);
+    }
+
+    /* The volume changed, let's tell people so */
+    if (o->volume_changed)
+        o->volume_changed(o);
+
+    /* The virtual volume changed, let's tell people so */
+    pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
+}
+
+/* Called from main context */
+static void set_real_ratio(pa_source_output *o, const pa_cvolume *v) {
+    pa_source_output_assert_ref(o);
+    pa_assert_ctl_context();
+    pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state));
+    pa_assert(!v || pa_cvolume_compatible(v, &o->sample_spec));
+
+    /* This basically calculates:
+     *
+     * o->real_ratio := v
+     * o->soft_volume := o->real_ratio * o->volume_factor */
+
+    if (v)
+        o->real_ratio = *v;
+    else
+        pa_cvolume_reset(&o->real_ratio, o->sample_spec.channels);
+
+    pa_sw_cvolume_multiply(&o->soft_volume, &o->real_ratio, &o->volume_factor);
+    /* We don't copy the data to the thread_info data. That's left for someone else to do */
+}
+
+/* Called from main or I/O context */
+pa_bool_t pa_source_output_is_passthrough(pa_source_output *o) {
+    pa_source_output_assert_ref(o);
+
+    if (PA_UNLIKELY(!pa_format_info_is_pcm(o->format)))
+        return TRUE;
+
+    if (PA_UNLIKELY(o->flags & PA_SOURCE_OUTPUT_PASSTHROUGH))
+        return TRUE;
+
+    return FALSE;
+}
+
+/* Called from main context */
+pa_bool_t pa_source_output_is_volume_readable(pa_source_output *o) {
+    pa_source_output_assert_ref(o);
+    pa_assert_ctl_context();
+
+    return !pa_source_output_is_passthrough(o);
+}
+
+/* Called from main context */
+pa_cvolume *pa_source_output_get_volume(pa_source_output *o, pa_cvolume *volume, pa_bool_t absolute) {
+    pa_source_output_assert_ref(o);
+    pa_assert_ctl_context();
+    pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state));
+    pa_assert(pa_source_output_is_volume_readable(o));
+
+    if (absolute || !pa_source_flat_volume_enabled(o->source))
+        *volume = o->volume;
+    else
+        *volume = o->reference_ratio;
+
+    return volume;
+}
+
+/* Called from main context */
+void pa_source_output_set_mute(pa_source_output *o, pa_bool_t mute, pa_bool_t save) {
+    pa_source_output_assert_ref(o);
+    pa_assert_ctl_context();
+    pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state));
+
+    if (!o->muted == !mute) {
+        o->save_muted = o->save_muted || mute;
+        return;
+    }
+
+    o->muted = mute;
+    o->save_muted = save;
+
+    pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_SOFT_MUTE, NULL, 0, NULL) == 0);
+
+    /* The mute status changed, let's tell people so */
+    if (o->mute_changed)
+        o->mute_changed(o);
+
+    pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
+}
+
+/* Called from main context */
+pa_bool_t pa_source_output_get_mute(pa_source_output *o) {
+    pa_source_output_assert_ref(o);
+    pa_assert_ctl_context();
+    pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state));
+
+    return o->muted;
+}
+
+/* Called from main thread */
+void pa_source_output_update_proplist(pa_source_output *o, pa_update_mode_t mode, pa_proplist *p) {
+    pa_source_output_assert_ref(o);
+    pa_assert_ctl_context();
+
+    if (p)
+        pa_proplist_update(o->proplist, mode, p);
+
+    if (PA_SOURCE_OUTPUT_IS_LINKED(o->state)) {
+        pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PROPLIST_CHANGED], o);
+        pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
+    }
+}
+
+/* Called from main context */
 void pa_source_output_cork(pa_source_output *o, pa_bool_t b) {
     pa_source_output_assert_ref(o);
     pa_assert_ctl_context();
@@ -658,7 +1202,7 @@ void pa_source_output_set_name(pa_source_output *o, const char *name) {
 
     old = pa_proplist_gets(o->proplist, PA_PROP_MEDIA_NAME);
 
-    if (old && name && !strcmp(old, name))
+    if (old && name && pa_streq(old, name))
         return;
 
     if (name)
@@ -672,20 +1216,6 @@ void pa_source_output_set_name(pa_source_output *o, const char *name) {
     }
 }
 
-/* Called from main thread */
-void pa_source_output_update_proplist(pa_source_output *o, pa_update_mode_t mode, pa_proplist *p) {
-    pa_source_output_assert_ref(o);
-    pa_assert_ctl_context();
-
-    if (p)
-        pa_proplist_update(o->proplist, mode, p);
-
-    if (PA_SOURCE_OUTPUT_IS_LINKED(o->state)) {
-        pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PROPLIST_CHANGED], o);
-        pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
-    }
-}
-
 /* Called from main context */
 pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o) {
     pa_source_output_assert_ref(o);
@@ -709,6 +1239,17 @@ pa_bool_t pa_source_output_may_move(pa_source_output *o) {
     return TRUE;
 }
 
+static pa_bool_t find_filter_source_output(pa_source_output *target, pa_source *s) {
+    int i = 0;
+    while (s && s->output_from_master) {
+        if (s->output_from_master == target)
+            return TRUE;
+        s = s->output_from_master->source;
+        pa_assert(i++ < 100);
+    }
+    return FALSE;
+}
+
 /* Called from main context */
 pa_bool_t pa_source_output_may_move_to(pa_source_output *o, pa_source *dest) {
     pa_source_output_assert_ref(o);
@@ -721,6 +1262,12 @@ pa_bool_t pa_source_output_may_move_to(pa_source_output *o, pa_source *dest) {
     if (!pa_source_output_may_move(o))
         return FALSE;
 
+    /* Make sure we're not creating a filter source cycle */
+    if (find_filter_source_output(o, dest)) {
+        pa_log_debug("Can't connect output to %s, as that would create a cycle.", dest->name);
+        return FALSE;
+    }
+
     if (pa_idxset_size(dest->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) {
         pa_log_warn("Failed to move source output: too many outputs per source.");
         return FALSE;
@@ -756,6 +1303,14 @@ int pa_source_output_start_move(pa_source_output *o) {
     if (pa_source_output_get_state(o) == PA_SOURCE_OUTPUT_CORKED)
         pa_assert_se(origin->n_corked-- >= 1);
 
+    if (pa_source_output_is_passthrough(o))
+        pa_source_leave_passthrough(o->source);
+
+    if (pa_source_flat_volume_enabled(o->source))
+        /* We might need to update the source's volume if we are in flat
+         * volume mode. */
+        pa_source_set_volume(o->source, NULL, FALSE, FALSE);
+
     pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, 0, NULL) == 0);
 
     pa_source_update_status(o->source);
@@ -766,10 +1321,160 @@ int pa_source_output_start_move(pa_source_output *o) {
     return 0;
 }
 
+/* Called from main context. If it has an origin source that uses volume sharing,
+ * then also the origin source and all streams connected to it need to update
+ * their volume - this function does all that by using recursion. */
+static void update_volume_due_to_moving(pa_source_output *o, pa_source *dest) {
+    pa_cvolume old_volume;
+
+    pa_assert(o);
+    pa_assert(dest);
+    pa_assert(o->source); /* The destination source should already be set. */
+
+    if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
+        pa_source *root_source;
+        pa_source_output *destination_source_output;
+        uint32_t idx;
+
+        root_source = pa_source_get_master(o->source);
+
+        if (PA_UNLIKELY(!root_source))
+            return;
+
+        if (pa_source_flat_volume_enabled(o->source)) {
+            /* Ok, so the origin source uses volume sharing, and flat volume is
+             * enabled. The volume will have to be updated as follows:
+             *
+             *     o->volume := o->source->real_volume
+             *         (handled later by pa_source_set_volume)
+             *     o->reference_ratio := o->volume / o->source->reference_volume
+             *         (handled later by pa_source_set_volume)
+             *     o->real_ratio stays unchanged
+             *         (streams whose origin source uses volume sharing should
+             *          always have real_ratio of 0 dB)
+             *     o->soft_volume stays unchanged
+             *         (streams whose origin source uses volume sharing should
+             *          always have volume_factor as soft_volume, so no change
+             *          should be needed) */
+
+            pa_assert(pa_cvolume_is_norm(&o->real_ratio));
+            pa_assert(pa_cvolume_equal(&o->soft_volume, &o->volume_factor));
+
+            /* Notifications will be sent by pa_source_set_volume(). */
+
+        } else {
+            /* Ok, so the origin source uses volume sharing, and flat volume is
+             * disabled. The volume will have to be updated as follows:
+             *
+             *     o->volume := 0 dB
+             *     o->reference_ratio := 0 dB
+             *     o->real_ratio stays unchanged
+             *         (streams whose origin source uses volume sharing should
+             *          always have real_ratio of 0 dB)
+             *     o->soft_volume stays unchanged
+             *         (streams whose origin source uses volume sharing should
+             *          always have volume_factor as soft_volume, so no change
+             *          should be needed) */
+
+            old_volume = o->volume;
+            pa_cvolume_reset(&o->volume, o->volume.channels);
+            pa_cvolume_reset(&o->reference_ratio, o->reference_ratio.channels);
+            pa_assert(pa_cvolume_is_norm(&o->real_ratio));
+            pa_assert(pa_cvolume_equal(&o->soft_volume, &o->volume_factor));
+
+            /* Notify others about the changed source output volume. */
+            if (!pa_cvolume_equal(&o->volume, &old_volume)) {
+                if (o->volume_changed)
+                    o->volume_changed(o);
+
+                pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
+            }
+        }
+
+        /* Additionally, the origin source volume needs updating:
+         *
+         *     o->destination_source->reference_volume := root_source->reference_volume
+         *     o->destination_source->real_volume := root_source->real_volume
+         *     o->destination_source->soft_volume stays unchanged
+         *         (sources that use volume sharing should always have
+         *          soft_volume of 0 dB) */
+
+        old_volume = o->destination_source->reference_volume;
+
+        o->destination_source->reference_volume = root_source->reference_volume;
+        pa_cvolume_remap(&o->destination_source->reference_volume, &root_source->channel_map, &o->destination_source->channel_map);
+
+        o->destination_source->real_volume = root_source->real_volume;
+        pa_cvolume_remap(&o->destination_source->real_volume, &root_source->channel_map, &o->destination_source->channel_map);
+
+        pa_assert(pa_cvolume_is_norm(&o->destination_source->soft_volume));
+
+        /* Notify others about the changed source volume. If you wonder whether
+         * o->destination_source->set_volume() should be called somewhere, that's not
+         * the case, because sources that use volume sharing shouldn't have any
+         * internal volume that set_volume() would update. If you wonder
+         * whether the thread_info variables should be synced, yes, they
+         * should, and it's done by the PA_SOURCE_MESSAGE_FINISH_MOVE message
+         * handler. */
+        if (!pa_cvolume_equal(&o->destination_source->reference_volume, &old_volume))
+            pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, o->destination_source->index);
+
+        /* Recursively update origin source outputs. */
+        PA_IDXSET_FOREACH(destination_source_output, o->destination_source->outputs, idx)
+            update_volume_due_to_moving(destination_source_output, dest);
+
+    } else {
+        old_volume = o->volume;
+
+        if (pa_source_flat_volume_enabled(o->source)) {
+            /* Ok, so this is a regular stream, and flat volume is enabled. The
+             * volume will have to be updated as follows:
+             *
+             *     o->volume := o->reference_ratio * o->source->reference_volume
+             *     o->reference_ratio stays unchanged
+             *     o->real_ratio := o->volume / o->source->real_volume
+             *         (handled later by pa_source_set_volume)
+             *     o->soft_volume := o->real_ratio * o->volume_factor
+             *         (handled later by pa_source_set_volume) */
+
+            o->volume = o->source->reference_volume;
+            pa_cvolume_remap(&o->volume, &o->source->channel_map, &o->channel_map);
+            pa_sw_cvolume_multiply(&o->volume, &o->volume, &o->reference_ratio);
+
+        } else {
+            /* Ok, so this is a regular stream, and flat volume is disabled.
+             * The volume will have to be updated as follows:
+             *
+             *     o->volume := o->reference_ratio
+             *     o->reference_ratio stays unchanged
+             *     o->real_ratio := o->reference_ratio
+             *     o->soft_volume := o->real_ratio * o->volume_factor */
+
+            o->volume = o->reference_ratio;
+            o->real_ratio = o->reference_ratio;
+            pa_sw_cvolume_multiply(&o->soft_volume, &o->real_ratio, &o->volume_factor);
+        }
+
+        /* Notify others about the changed source output volume. */
+        if (!pa_cvolume_equal(&o->volume, &old_volume)) {
+            /* XXX: In case o->source has flat volume enabled, then real_ratio
+             * and soft_volume are not updated yet. Let's hope that the
+             * callback implementation doesn't care about those variables... */
+            if (o->volume_changed)
+                o->volume_changed(o);
+
+            pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
+        }
+    }
+
+    /* If o->source == dest, then recursion has finished, and we can finally call
+     * pa_source_set_volume(), which will do the rest of the updates. */
+    if ((o->source == dest) && pa_source_flat_volume_enabled(o->source))
+        pa_source_set_volume(o->source, NULL, FALSE, o->save_volume);
+}
+
 /* Called from main context */
 int pa_source_output_finish_move(pa_source_output *o, pa_source *dest, pa_bool_t save) {
-    pa_resampler *new_resampler;
-
     pa_source_output_assert_ref(o);
     pa_assert_ctl_context();
     pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state));
@@ -777,34 +1482,29 @@ int pa_source_output_finish_move(pa_source_output *o, pa_source *dest, pa_bool_t
     pa_source_assert_ref(dest);
 
     if (!pa_source_output_may_move_to(o, dest))
-        return -1;
-
-    if (o->thread_info.resampler &&
-        pa_sample_spec_equal(pa_resampler_input_sample_spec(o->thread_info.resampler), &dest->sample_spec) &&
-        pa_channel_map_equal(pa_resampler_input_channel_map(o->thread_info.resampler), &dest->channel_map))
-
-        /* Try to reuse the old resampler if possible */
-        new_resampler = o->thread_info.resampler;
+        return -PA_ERR_NOTSUPPORTED;
 
-    else if ((o->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ||
-             !pa_sample_spec_equal(&o->sample_spec, &dest->sample_spec) ||
-             !pa_channel_map_equal(&o->channel_map, &dest->channel_map)) {
+    if (pa_source_output_is_passthrough(o) && !pa_source_check_format(dest, o->format)) {
+        pa_proplist *p = pa_proplist_new();
+        pa_log_debug("New source doesn't support stream format, sending format-changed and killing");
+        /* Tell the client what device we want to be on if it is going to
+         * reconnect */
+        pa_proplist_sets(p, "device", dest->name);
+        pa_source_output_send_event(o, PA_STREAM_EVENT_FORMAT_LOST, p);
+        pa_proplist_free(p);
+        return -PA_ERR_NOTSUPPORTED;
+    }
 
-        /* Okey, we need a new resampler for the new source */
+    if (!(o->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) &&
+        !pa_sample_spec_equal(&o->sample_spec, &dest->sample_spec)){
+        /* try to change dest sink rate if possible without glitches.
+           module-suspend-on-idle resumes destination source with
+           SOURCE_OUTPUT_MOVE_FINISH hook */
 
-        if (!(new_resampler = pa_resampler_new(
-                      o->core->mempool,
-                      &dest->sample_spec, &dest->channel_map,
-                      &o->sample_spec, &o->channel_map,
-                      o->requested_resample_method,
-                      ((o->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
-                      ((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)))) {
-            pa_log_warn("Unsupported resampling operation.");
-            return -PA_ERR_NOTSUPPORTED;
-        }
-    } else
-        new_resampler = NULL;
+        pa_log_info("Trying to change sample rate");
+        if (pa_source_update_rate(dest, o->sample_spec.rate, pa_source_output_is_passthrough(o)) == TRUE)
+            pa_log_info("Rate changed to %u Hz", dest->sample_spec.rate);
+    }
 
     if (o->moving)
         o->moving(o, dest);
@@ -813,29 +1513,19 @@ int pa_source_output_finish_move(pa_source_output *o, pa_source *dest, pa_bool_t
     o->save_source = save;
     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);
+
     if (pa_source_output_get_state(o) == PA_SOURCE_OUTPUT_CORKED)
         o->source->n_corked++;
 
-    /* Replace resampler */
-    if (new_resampler != o->thread_info.resampler) {
-        if (o->thread_info.resampler)
-            pa_resampler_free(o->thread_info.resampler);
-        o->thread_info.resampler = new_resampler;
+    pa_source_output_update_rate(o);
 
-        pa_memblockq_free(o->thread_info.delay_memblockq);
+    pa_source_update_status(dest);
 
-        o->thread_info.delay_memblockq = pa_memblockq_new(
-                0,
-                MEMBLOCKQ_MAXLENGTH,
-                0,
-                pa_frame_size(&o->source->sample_spec),
-                0,
-                1,
-                0,
-                &o->source->silence);
-    }
+    update_volume_due_to_moving(o, dest);
 
-    pa_source_update_status(dest);
+    if (pa_source_output_is_passthrough(o))
+        pa_source_enter_passthrough(o->source);
 
     pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_ADD_OUTPUT, o, 0, NULL) == 0);
 
@@ -939,6 +1629,7 @@ int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int
         case PA_SOURCE_OUTPUT_MESSAGE_SET_STATE:
 
             pa_source_output_set_state_within_thread(o, PA_PTR_TO_UINT(userdata));
+
             return 0;
 
         case PA_SOURCE_OUTPUT_MESSAGE_SET_REQUESTED_LATENCY: {
@@ -955,6 +1646,18 @@ int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int
             *r = o->thread_info.requested_source_latency;
             return 0;
         }
+
+        case PA_SOURCE_OUTPUT_MESSAGE_SET_SOFT_VOLUME:
+            if (!pa_cvolume_equal(&o->thread_info.soft_volume, &o->soft_volume)) {
+                o->thread_info.soft_volume = o->soft_volume;
+            }
+            return 0;
+
+        case PA_SOURCE_OUTPUT_MESSAGE_SET_SOFT_MUTE:
+            if (o->thread_info.muted != o->muted) {
+                o->thread_info.muted = o->muted;
+            }
+            return 0;
     }
 
     return -PA_ERR_NOTIMPLEMENTED;
@@ -988,3 +1691,69 @@ finish:
     if (pl)
         pa_proplist_free(pl);
 }
+
+/* Called from main context */
+/* Updates the source output's resampler with whatever the current source
+ * requires -- useful when the underlying source's rate might have changed */
+int pa_source_output_update_rate(pa_source_output *o) {
+    pa_resampler *new_resampler;
+    char *memblockq_name;
+
+    pa_source_output_assert_ref(o);
+    pa_assert_ctl_context();
+
+    if (o->thread_info.resampler &&
+        pa_sample_spec_equal(pa_resampler_input_sample_spec(o->thread_info.resampler), &o->source->sample_spec) &&
+        pa_channel_map_equal(pa_resampler_input_channel_map(o->thread_info.resampler), &o->source->channel_map))
+
+        new_resampler = o->thread_info.resampler;
+
+    else if (!pa_source_output_is_passthrough(o) &&
+        ((o->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ||
+         !pa_sample_spec_equal(&o->sample_spec, &o->source->sample_spec) ||
+         !pa_channel_map_equal(&o->channel_map, &o->source->channel_map))) {
+
+        new_resampler = pa_resampler_new(o->core->mempool,
+                                     &o->source->sample_spec, &o->source->channel_map,
+                                     &o->sample_spec, &o->channel_map,
+                                     o->requested_resample_method,
+                                     ((o->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
+                                     ((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));
+
+        if (!new_resampler) {
+            pa_log_warn("Unsupported resampling operation.");
+            return -PA_ERR_NOTSUPPORTED;
+        }
+    } else
+        new_resampler = NULL;
+
+    if (new_resampler == o->thread_info.resampler)
+        return 0;
+
+    if (o->thread_info.resampler)
+        pa_resampler_free(o->thread_info.resampler);
+
+    o->thread_info.resampler = new_resampler;
+
+    pa_memblockq_free(o->thread_info.delay_memblockq);
+
+    memblockq_name = pa_sprintf_malloc("source output delay_memblockq [%u]", o->index);
+    o->thread_info.delay_memblockq = pa_memblockq_new(
+            memblockq_name,
+            0,
+            MEMBLOCKQ_MAXLENGTH,
+            0,
+            &o->source->sample_spec,
+            0,
+            1,
+            0,
+            &o->source->silence);
+    pa_xfree(memblockq_name);
+
+    o->actual_resample_method = new_resampler ? pa_resampler_get_method(new_resampler) : PA_RESAMPLER_INVALID;
+
+    pa_log_debug("Updated resampler for source output %d", o->index);
+
+    return 0;
+}
index 273b78f..d5fedd5 100644 (file)
 typedef struct pa_source_output pa_source_output;
 
 #include <pulse/sample.h>
-#include <pulsecore/source.h>
+#include <pulse/format.h>
 #include <pulsecore/memblockq.h>
 #include <pulsecore/resampler.h>
 #include <pulsecore/module.h>
 #include <pulsecore/client.h>
+#include <pulsecore/source.h>
+#include <pulsecore/core.h>
 #include <pulsecore/sink-input.h>
 
 typedef enum pa_source_output_state {
@@ -56,7 +58,8 @@ typedef enum pa_source_output_flags {
     PA_SOURCE_OUTPUT_FIX_CHANNELS = 128,
     PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND = 256,
     PA_SOURCE_OUTPUT_NO_CREATE_ON_SUSPEND = 512,
-    PA_SOURCE_OUTPUT_KILL_ON_SUSPEND = 1024
+    PA_SOURCE_OUTPUT_KILL_ON_SUSPEND = 1024,
+    PA_SOURCE_OUTPUT_PASSTHROUGH = 2048
 } pa_source_output_flags_t;
 
 struct pa_source_output {
@@ -74,18 +77,34 @@ struct pa_source_output {
     pa_module *module;                    /* may be NULL */
     pa_client *client;                    /* may be NULL */
 
-    pa_source *source; /* NULL while being moved */
+    pa_source *source;                    /* NULL while being moved */
+    pa_source *destination_source;        /* only set by filter sources */
 
     /* A source output can monitor just a single input of a sink, in which case we find it here */
     pa_sink_input *direct_on_input;       /* may be NULL */
 
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
+    pa_format_info *format;
+
+    /* Also see http://pulseaudio.org/wiki/InternalVolumes */
+    pa_cvolume volume;             /* The volume clients are informed about */
+    pa_cvolume reference_ratio;    /* The ratio of the stream's volume to the source's reference volume */
+    pa_cvolume real_ratio;         /* The ratio of the stream's volume to the source's real volume */
+    pa_cvolume volume_factor;      /* An internally used volume factor that can be used by modules to apply effects and suchlike without having that visible to the outside */
+    pa_cvolume soft_volume;        /* The internal software volume we apply to all PCM data while it passes through. Usually calculated as real_ratio * volume_factor */
+
+    pa_cvolume volume_factor_source; /* A second volume factor in format of the source this stream is connected to */
 
-    /* if TRUE then the source we are connected to is worth
-     * remembering, i.e. was explicitly chosen by the user and not
-     * automatically. module-stream-restore looks for this.*/
-    pa_bool_t save_source:1;
+    pa_bool_t volume_writable:1;
+
+    pa_bool_t 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.*/
+    pa_bool_t save_source:1, save_volume:1, save_muted:1;
 
     pa_resample_method_t requested_resample_method, actual_resample_method;
 
@@ -105,16 +124,19 @@ struct pa_source_output {
      * changes. Called from IO context. */
     void (*update_source_requested_latency) (pa_source_output *o); /* may be NULL */
 
-    /* Called whenver the latency range of the source changes. Called
+    /* Called whenever the latency range of the source changes. Called
      * from IO context. */
     void (*update_source_latency_range) (pa_source_output *o); /* may be NULL */
 
-    /* Called whenver the fixed latency of the source changes, if there
+    /* Called whenever the fixed latency of the source changes, if there
      * is one. Called from IO context. */
     void (*update_source_fixed_latency) (pa_source_output *i); /* may be NULL */
 
     /* If non-NULL this function is called when the output is first
-     * connected to a source. Called from IO thread context */
+     * connected to a source or when the rtpoll/asyncmsgq fields
+     * change. You usually don't need to implement this function
+     * unless you rewrite a source that is piggy-backed onto
+     * another. Called from IO thread context */
     void (*attach) (pa_source_output *o);           /* may be NULL */
 
     /* If non-NULL this function is called when the output is
@@ -130,9 +152,9 @@ struct pa_source_output {
     void (*suspend_within_thread) (pa_source_output *o, pa_bool_t b);   /* may be NULL */
 
     /* If non-NULL called whenever the source output is moved to a new
-     * source. Called from main context after the stream was detached
-     * from the old source and before it is attached to the new
-     * source. If dest is NULL the move was executed in two
+     * source. Called from main context after the source output has been
+     * detached from the old source and before it has been attached to
+     * the new source. If dest is NULL the move was executed in two
      * phases and the second one failed; the stream will be destroyed
      * after this call. */
     void (*moving) (pa_source_output *o, pa_source *dest);   /* may be NULL */
@@ -141,7 +163,7 @@ struct pa_source_output {
      * context. */
     void (*kill)(pa_source_output* o);              /* may NOT be NULL */
 
-    /* Return the current latency (i.e. length of bufferd audio) of
+    /* Return the current latency (i.e. length of buffered audio) of
     this stream. Called from main context. This is added to what the
     PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY message sent to the IO thread
     returns */
@@ -160,9 +182,20 @@ struct pa_source_output {
      * control events. */
     void (*send_event)(pa_source_output *o, const char *event, pa_proplist* data);
 
+    /* If non-NULL this function is called whenever the source output
+     * volume changes. Called from main context */
+    void (*volume_changed)(pa_source_output *o); /* may be NULL */
+
+    /* If non-NULL this function is called whenever the source output
+     * mute status changes. Called from main context */
+    void (*mute_changed)(pa_source_output *o); /* may be NULL */
+
     struct {
         pa_source_output_state_t state;
 
+        pa_cvolume soft_volume;
+        pa_bool_t muted:1;
+
         pa_bool_t attached:1; /* True only between ->attach() and ->detach() calls */
 
         pa_sample_spec sample_spec;
@@ -178,6 +211,9 @@ struct pa_source_output {
 
         pa_sink_input *direct_on_input;       /* may be NULL */
     } thread_info;
+#ifdef __TIZEN__
+    FILE *dump_fp;
+#endif
 
     void *userdata;
 };
@@ -191,6 +227,8 @@ enum {
     PA_SOURCE_OUTPUT_MESSAGE_SET_STATE,
     PA_SOURCE_OUTPUT_MESSAGE_SET_REQUESTED_LATENCY,
     PA_SOURCE_OUTPUT_MESSAGE_GET_REQUESTED_LATENCY,
+    PA_SOURCE_OUTPUT_MESSAGE_SET_SOFT_VOLUME,
+    PA_SOURCE_OUTPUT_MESSAGE_SET_SOFT_MUTE,
     PA_SOURCE_OUTPUT_MESSAGE_MAX
 };
 
@@ -211,21 +249,42 @@ typedef struct pa_source_output_new_data {
     pa_client *client;
 
     pa_source *source;
+    pa_source *destination_source;
 
     pa_resample_method_t resample_method;
 
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
+    pa_format_info *format;
+    pa_idxset *req_formats;
+    pa_idxset *nego_formats;
+
+    pa_cvolume volume, volume_factor, volume_factor_source;
+    pa_bool_t muted:1;
 
     pa_bool_t sample_spec_is_set:1;
     pa_bool_t channel_map_is_set:1;
 
-    pa_bool_t save_source:1;
+    pa_bool_t volume_is_set:1, volume_factor_is_set:1, volume_factor_source_is_set:1;
+    pa_bool_t muted_is_set:1;
+
+    pa_bool_t volume_is_absolute:1;
+
+    pa_bool_t volume_writable:1;
+
+    pa_bool_t save_source:1, save_volume:1, save_muted:1;
 } pa_source_output_new_data;
 
 pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data);
 void pa_source_output_new_data_set_sample_spec(pa_source_output_new_data *data, const pa_sample_spec *spec);
 void pa_source_output_new_data_set_channel_map(pa_source_output_new_data *data, const pa_channel_map *map);
+pa_bool_t pa_source_output_new_data_is_passthrough(pa_source_output_new_data *data);
+void pa_source_output_new_data_set_volume(pa_source_output_new_data *data, const pa_cvolume *volume);
+void pa_source_output_new_data_apply_volume_factor(pa_source_output_new_data *data, const pa_cvolume *volume_factor);
+void pa_source_output_new_data_apply_volume_factor_source(pa_source_output_new_data *data, const pa_cvolume *volume_factor);
+void pa_source_output_new_data_set_muted(pa_source_output_new_data *data, pa_bool_t mute);
+pa_bool_t pa_source_output_new_data_set_source(pa_source_output_new_data *data, pa_source *s, pa_bool_t save);
+pa_bool_t pa_source_output_new_data_set_formats(pa_source_output_new_data *data, pa_idxset *formats);
 void pa_source_output_new_data_done(pa_source_output_new_data *data);
 
 /* To be called by the implementing module only */
@@ -245,16 +304,25 @@ pa_usec_t pa_source_output_set_requested_latency(pa_source_output *o, pa_usec_t
 void pa_source_output_cork(pa_source_output *o, pa_bool_t b);
 
 int pa_source_output_set_rate(pa_source_output *o, uint32_t rate);
+int pa_source_output_update_rate(pa_source_output *o);
 
 size_t pa_source_output_get_max_rewind(pa_source_output *o);
 
 /* Callable by everyone */
 
-/* External code may request disconnection with this funcion */
+/* External code may request disconnection with this function */
 void pa_source_output_kill(pa_source_output*o);
 
 pa_usec_t pa_source_output_get_latency(pa_source_output *o, pa_usec_t *source_latency);
 
+pa_bool_t pa_source_output_is_volume_readable(pa_source_output *o);
+pa_bool_t pa_source_output_is_passthrough(pa_source_output *o);
+void pa_source_output_set_volume(pa_source_output *o, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute);
+pa_cvolume *pa_source_output_get_volume(pa_source_output *o, pa_cvolume *volume, pa_bool_t absolute);
+
+void pa_source_output_set_mute(pa_source_output *o, pa_bool_t mute, pa_bool_t save);
+pa_bool_t pa_source_output_get_mute(pa_source_output *o);
+
 void pa_source_output_update_proplist(pa_source_output *o, pa_update_mode_t mode, pa_proplist *p);
 
 pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o);
@@ -265,7 +333,7 @@ pa_bool_t pa_source_output_may_move(pa_source_output *o);
 pa_bool_t pa_source_output_may_move_to(pa_source_output *o, pa_source *dest);
 int pa_source_output_move_to(pa_source_output *o, pa_source *dest, pa_bool_t save);
 
-/* The same as pa_source_output_move_to() but in two seperate steps,
+/* The same as pa_source_output_move_to() but in two separate steps,
  * first the detaching from the old source, then the attaching to the
  * new source */
 int pa_source_output_start_move(pa_source_output *o);
index 415c54b..31b60af 100644 (file)
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
+#ifdef __TIZEN__
+#include <time.h>
+#endif
 
+#include <pulse/format.h>
 #include <pulse/utf8.h>
 #include <pulse/xmalloc.h>
 #include <pulse/timeval.h>
 #include <pulse/util.h>
+#include <pulse/rtclock.h>
+#include <pulse/internal.h>
 
 #include <pulsecore/core-util.h>
 #include <pulsecore/source-output.h>
 #include <pulsecore/namereg.h>
 #include <pulsecore/core-subscribe.h>
 #include <pulsecore/log.h>
-#include <pulsecore/sample-util.h>
+#include <pulsecore/mix.h>
+#include <pulsecore/flist.h>
 
 #include "source.h"
 
 
 PA_DEFINE_PUBLIC_CLASS(pa_source, pa_msgobject);
 
+struct pa_source_volume_change {
+    pa_usec_t at;
+    pa_cvolume hw_volume;
+
+    PA_LLIST_FIELDS(pa_source_volume_change);
+};
+
+struct source_message_set_port {
+    pa_device_port *port;
+    int ret;
+};
+
+#ifdef __TIZEN__
+//#define PA_DUMP_SOURCE_FOR_EACH_SUSPEND
+#define PA_DUMP_SOURCE_PATH_PREFIX            "/tmp/dump_pa_source"
+#endif
+
 static void source_free(pa_object *o);
 
+static void pa_source_volume_change_push(pa_source *s);
+static void pa_source_volume_change_flush(pa_source *s);
+
+#ifdef __TIZEN__
+static void __toggle_open_close_n_write_dump_source(pa_source *s, pa_memchunk *target)
+{
+
+    /* open file for dump pcm */
+    if (s->core->dump_source && !s->dump_fp) {
+        char *dump_path = NULL, *dump_path_surfix = NULL;
+        const char *s_device_api_str;
+#ifdef PA_DUMP_SOURCE_FOR_EACH_SUSPEND
+        time_t t;
+        char datetime[12];
+
+        time(&t);
+        memset(&datetime[0], 0x00, sizeof(datetime));
+        strftime(&datetime[0], sizeof(datetime), "%m%d_%H%M%S", localtime(&t));
+#endif
+
+        if ((s_device_api_str = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_API))) {
+            if (pa_streq(s_device_api_str, "alsa")) {
+                const char *card_idx_str, *device_idx_str;
+                uint32_t card_idx = 0, device_idx = 0;
+
+                if ((card_idx_str = pa_proplist_gets(s->proplist, "alsa.card")))
+                    pa_atou(card_idx_str, &card_idx);
+                if ((device_idx_str = pa_proplist_gets(s->proplist, "alsa.device")))
+                    pa_atou(device_idx_str, &device_idx);
+                dump_path_surfix = pa_sprintf_malloc("alsa_%d_%d.pcm", card_idx, device_idx);
+            } else if (pa_streq(s_device_api_str, "bluez")) {
+                dump_path_surfix = pa_sprintf_malloc("bluez.pcm");
+            }
+        }
+        if (!dump_path_surfix) {
+            dump_path_surfix = pa_sprintf_malloc("idx_%d.pcm", s->index);
+        }
+
+#ifdef PA_DUMP_SOURCE_FOR_EACH_SUSPEND
+        dump_path = pa_sprintf_malloc("%s_%s_%s", PA_DUMP_SOURCE_PATH_PREFIX, &datetime[0], dump_path_surfix);
+#else
+        dump_path = pa_sprintf_malloc("%s_%s", PA_DUMP_SOURCE_PATH_PREFIX, dump_path_surfix);
+#endif
+
+        if (dump_path) {
+            s->dump_fp = fopen(dump_path, "w");
+            pa_log_info("pa_source dump started:%s", dump_path);
+            pa_xfree(dump_path);
+        }
+        if (dump_path_surfix)
+            pa_xfree(dump_path_surfix);
+    /* close file for dump pcm when config is changed */
+    } else if (!s->core->dump_source && s->dump_fp) {
+        fclose(s->dump_fp);
+        s->dump_fp = NULL;
+    }
+
+    /* dump pcm */
+    if (s->dump_fp) {
+        void *ptr;
+
+        ptr = pa_memblock_acquire(target->memblock);
+
+        fwrite((uint8_t*) ptr + target->index, 1, target->length, s->dump_fp);
+
+        pa_memblock_release(target->memblock);
+    }
+}
+#endif
+
 pa_source_new_data* pa_source_new_data_init(pa_source_new_data *data) {
     pa_assert(data);
 
     pa_zero(*data);
     data->proplist = pa_proplist_new();
+    data->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
 
     return data;
 }
@@ -80,6 +174,13 @@ void pa_source_new_data_set_channel_map(pa_source_new_data *data, const pa_chann
         data->channel_map = *map;
 }
 
+void pa_source_new_data_set_alternate_sample_rate(pa_source_new_data *data, const uint32_t alternate_sample_rate) {
+    pa_assert(data);
+
+    data->alternate_sample_rate_is_set = TRUE;
+    data->alternate_sample_rate = alternate_sample_rate;
+}
+
 void pa_source_new_data_set_volume(pa_source_new_data *data, const pa_cvolume *volume) {
     pa_assert(data);
 
@@ -106,14 +207,8 @@ void pa_source_new_data_done(pa_source_new_data *data) {
 
     pa_proplist_free(data->proplist);
 
-    if (data->ports) {
-        pa_device_port *p;
-
-        while ((p = pa_hashmap_steal_first(data->ports)))
-            pa_device_port_free(p);
-
-        pa_hashmap_free(data->ports, NULL, NULL);
-    }
+    if (data->ports)
+        pa_hashmap_free(data->ports, (pa_free_cb_t) pa_device_port_unref);
 
     pa_xfree(data->name);
     pa_xfree(data->active_port);
@@ -126,10 +221,13 @@ static void reset_callbacks(pa_source *s) {
     s->set_state = NULL;
     s->get_volume = NULL;
     s->set_volume = NULL;
+    s->write_volume = NULL;
     s->get_mute = NULL;
     s->set_mute = NULL;
     s->update_requested_latency = NULL;
     s->set_port = NULL;
+    s->get_formats = NULL;
+    s->update_rate = NULL;
 }
 
 /* Called from main context */
@@ -177,8 +275,14 @@ pa_source* pa_source_new(
     pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
     pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels);
 
-    if (!data->volume_is_set)
+    /* FIXME: There should probably be a general function for checking whether
+     * the source volume is allowed to be set, like there is for source outputs. */
+    pa_assert(!data->volume_is_set || !(flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER));
+
+    if (!data->volume_is_set) {
         pa_cvolume_reset(&data->volume, data->sample_spec.channels);
+        data->save_volume = FALSE;
+    }
 
     pa_return_null_if_fail(pa_cvolume_valid(&data->volume));
     pa_return_null_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec));
@@ -206,7 +310,8 @@ pa_source* pa_source_new(
     s->state = PA_SOURCE_INIT;
     s->flags = flags;
     s->priority = 0;
-    s->suspend_cause = 0;
+    s->suspend_cause = data->suspend_cause;
+    pa_source_set_mixer_dirty(s, FALSE);
     s->name = pa_xstrdup(name);
     s->proplist = pa_proplist_copy(data->proplist);
     s->driver = pa_xstrdup(pa_path_get_filename(data->driver));
@@ -217,12 +322,24 @@ pa_source* pa_source_new(
 
     s->sample_spec = data->sample_spec;
     s->channel_map = data->channel_map;
+    s->default_sample_rate = s->sample_spec.rate;
+
+    if (data->alternate_sample_rate_is_set)
+        s->alternate_sample_rate = data->alternate_sample_rate;
+    else
+        s->alternate_sample_rate = s->core->alternate_sample_rate;
+
+    if (s->sample_spec.rate == s->alternate_sample_rate) {
+        pa_log_warn("Default and alternate sample rates are the same.");
+        s->alternate_sample_rate = 0;
+    }
 
     s->outputs = pa_idxset_new(NULL, NULL);
     s->n_corked = 0;
     s->monitor_of = NULL;
+    s->output_from_master = NULL;
 
-    s->volume = data->volume;
+    s->reference_volume = s->real_volume = data->volume;
     pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
     s->base_volume = PA_VOLUME_NORM;
     s->n_volume_steps = PA_VOLUME_NORM+1;
@@ -242,11 +359,11 @@ pa_source* pa_source_new(
     s->active_port = NULL;
     s->save_port = FALSE;
 
-    if (data->active_port && s->ports)
+    if (data->active_port)
         if ((s->active_port = pa_hashmap_get(s->ports, data->active_port)))
             s->save_port = data->save_port;
 
-    if (!s->active_port && s->ports) {
+    if (!s->active_port) {
         void *state;
         pa_device_port *p;
 
@@ -255,8 +372,16 @@ pa_source* pa_source_new(
                 s->active_port = p;
     }
 
+    if (s->active_port)
+        s->latency_offset = s->active_port->latency_offset;
+    else
+        s->latency_offset = 0;
+
     s->save_volume = data->save_volume;
     s->save_muted = data->save_muted;
+#ifdef __TIZEN__
+    s->dump_fp = NULL;
+#endif
 
     pa_silence_memchunk_get(
             &core->silence_cache,
@@ -277,6 +402,14 @@ pa_source* pa_source_new(
     s->thread_info.max_latency = ABSOLUTE_MAX_LATENCY;
     s->thread_info.fixed_latency = flags & PA_SOURCE_DYNAMIC_LATENCY ? 0 : DEFAULT_FIXED_LATENCY;
 
+    PA_LLIST_HEAD_INIT(pa_source_volume_change, s->thread_info.volume_changes);
+    s->thread_info.volume_changes_tail = NULL;
+    pa_sw_cvolume_multiply(&s->thread_info.current_hw_volume, &s->soft_volume, &s->real_volume);
+    s->thread_info.volume_change_safety_margin = core->deferred_volume_safety_margin_usec;
+    s->thread_info.volume_change_extra_delay = core->deferred_volume_extra_delay_usec;
+    s->thread_info.latency_offset = s->latency_offset;
+
+    /* FIXME: This should probably be moved to pa_source_put() */
     pa_assert_se(pa_idxset_put(core->sources, s, &s->index) >= 0);
 
     if (s->card)
@@ -294,6 +427,25 @@ pa_source* pa_source_new(
     return s;
 }
 
+#ifdef __TIZEN__
+static const char* source_get_state_string(pa_source *s, pa_source_state_t state) {
+    switch(state) {
+        case PA_SOURCE_INVALID_STATE:
+            return "PA_SOURCE_INVALID_STATE";
+        case PA_SOURCE_RUNNING:
+            return "PA_SOURCE_RUNNING";
+        case PA_SOURCE_IDLE:
+            return "PA_SOURCE_IDLE";
+        case PA_SOURCE_SUSPENDED:
+            return "PA_SOURCE_SUSPENDED";
+        case PA_SOURCE_INIT:
+            return "PA_SOURCE_INIT";
+        case PA_SOURCE_UNLINKED:
+            return "PA_SOURCE_UNLINKED";
+    }
+}
+#endif
+
 /* Called from main context */
 static int source_set_state(pa_source *s, pa_source_state_t state) {
     int ret;
@@ -326,8 +478,12 @@ static int source_set_state(pa_source *s, pa_source_state_t state) {
         }
 
     s->state = state;
+#ifdef __TIZEN__
+    pa_log_info_verbose("SOURCE[%s] state changed (%s) => (%s)", s->name != NULL ? s->name : "noname",
+        source_get_state_string(s, original_state), source_get_state_string(s, s->state));
+#endif
 
-    if (state != PA_SOURCE_UNLINKED) { /* if we enter UNLINKED state pa_source_unlink() will fire the apropriate events */
+    if (state != PA_SOURCE_UNLINKED) { /* if we enter UNLINKED state pa_source_unlink() will fire the appropriate events */
         pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], s);
         pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
     }
@@ -349,32 +505,201 @@ static int source_set_state(pa_source *s, pa_source_state_t state) {
     return 0;
 }
 
+void pa_source_set_get_volume_callback(pa_source *s, pa_source_cb_t cb) {
+    pa_assert(s);
+
+    s->get_volume = cb;
+}
+
+void pa_source_set_set_volume_callback(pa_source *s, pa_source_cb_t cb) {
+    pa_source_flags_t flags;
+
+    pa_assert(s);
+    pa_assert(!s->write_volume || cb);
+
+    s->set_volume = cb;
+
+    /* Save the current flags so we can tell if they've changed */
+    flags = s->flags;
+
+    if (cb) {
+        /* The source implementor is responsible for setting decibel volume support */
+        s->flags |= PA_SOURCE_HW_VOLUME_CTRL;
+    } else {
+        s->flags &= ~PA_SOURCE_HW_VOLUME_CTRL;
+        /* See note below in pa_source_put() about volume sharing and decibel volumes */
+        pa_source_enable_decibel_volume(s, !(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER));
+    }
+
+    /* If the flags have changed after init, let any clients know via a change event */
+    if (s->state != PA_SOURCE_INIT && flags != s->flags)
+        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+}
+
+void pa_source_set_write_volume_callback(pa_source *s, pa_source_cb_t cb) {
+    pa_source_flags_t flags;
+
+    pa_assert(s);
+    pa_assert(!cb || s->set_volume);
+
+    s->write_volume = cb;
+
+    /* Save the current flags so we can tell if they've changed */
+    flags = s->flags;
+
+    if (cb)
+        s->flags |= PA_SOURCE_DEFERRED_VOLUME;
+    else
+        s->flags &= ~PA_SOURCE_DEFERRED_VOLUME;
+
+    /* If the flags have changed after init, let any clients know via a change event */
+    if (s->state != PA_SOURCE_INIT && flags != s->flags)
+        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+}
+
+void pa_source_set_get_mute_callback(pa_source *s, pa_source_cb_t cb) {
+    pa_assert(s);
+
+    s->get_mute = cb;
+}
+
+void pa_source_set_set_mute_callback(pa_source *s, pa_source_cb_t cb) {
+    pa_source_flags_t flags;
+
+    pa_assert(s);
+
+    s->set_mute = cb;
+
+    /* Save the current flags so we can tell if they've changed */
+    flags = s->flags;
+
+    if (cb)
+        s->flags |= PA_SOURCE_HW_MUTE_CTRL;
+    else
+        s->flags &= ~PA_SOURCE_HW_MUTE_CTRL;
+
+    /* If the flags have changed after init, let any clients know via a change event */
+    if (s->state != PA_SOURCE_INIT && flags != s->flags)
+        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+}
+
+static void enable_flat_volume(pa_source *s, pa_bool_t enable) {
+    pa_source_flags_t flags;
+
+    pa_assert(s);
+
+    /* Always follow the overall user preference here */
+    enable = enable && s->core->flat_volumes;
+
+    /* Save the current flags so we can tell if they've changed */
+    flags = s->flags;
+
+    if (enable)
+        s->flags |= PA_SOURCE_FLAT_VOLUME;
+    else
+        s->flags &= ~PA_SOURCE_FLAT_VOLUME;
+
+    /* If the flags have changed after init, let any clients know via a change event */
+    if (s->state != PA_SOURCE_INIT && flags != s->flags)
+        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+}
+
+void pa_source_enable_decibel_volume(pa_source *s, pa_bool_t enable) {
+    pa_source_flags_t flags;
+
+    pa_assert(s);
+
+    /* Save the current flags so we can tell if they've changed */
+    flags = s->flags;
+
+    if (enable) {
+        s->flags |= PA_SOURCE_DECIBEL_VOLUME;
+        enable_flat_volume(s, TRUE);
+    } else {
+        s->flags &= ~PA_SOURCE_DECIBEL_VOLUME;
+        enable_flat_volume(s, FALSE);
+    }
+
+    /* If the flags have changed after init, let any clients know via a change event */
+    if (s->state != PA_SOURCE_INIT && flags != s->flags)
+        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+}
+
 /* Called from main context */
 void pa_source_put(pa_source *s) {
     pa_source_assert_ref(s);
     pa_assert_ctl_context();
 
     pa_assert(s->state == PA_SOURCE_INIT);
+    pa_assert(!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER) || s->output_from_master);
 
     /* The following fields must be initialized properly when calling _put() */
     pa_assert(s->asyncmsgq);
     pa_assert(s->thread_info.min_latency <= s->thread_info.max_latency);
 
-    /* Generally, flags should be initialized via pa_source_new(). As
-     * a special exception we allow volume related flags to be set
-     * between _new() and _put(). */
+    /* Generally, flags should be initialized via pa_source_new(). As a
+     * special exception we allow some volume related flags to be set
+     * between _new() and _put() by the callback setter functions above.
+     *
+     * Thus we implement a couple safeguards here which ensure the above
+     * setters were used (or at least the implementor made manual changes
+     * in a compatible way).
+     *
+     * Note: All of these flags set here can change over the life time
+     * of the source. */
+    pa_assert(!(s->flags & PA_SOURCE_HW_VOLUME_CTRL) || s->set_volume);
+    pa_assert(!(s->flags & PA_SOURCE_DEFERRED_VOLUME) || s->write_volume);
+    pa_assert(!(s->flags & PA_SOURCE_HW_MUTE_CTRL) || s->set_mute);
+
+    /* XXX: Currently decibel volume is disabled for all sources that use volume
+     * sharing. When the master source supports decibel volume, it would be good
+     * to have the flag also in the filter source, but currently we don't do that
+     * so that the flags of the filter source never change when it's moved from
+     * a master source to another. One solution for this problem would be to
+     * remove user-visible volume altogether from filter sources when volume
+     * sharing is used, but the current approach was easier to implement... */
+    /* We always support decibel volumes in software, otherwise we leave it to
+     * the source implementor to set this flag as needed.
+     *
+     * Note: This flag can also change over the life time of the source. */
+    if (!(s->flags & PA_SOURCE_HW_VOLUME_CTRL) && !(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
+        pa_source_enable_decibel_volume(s, TRUE);
 
-    if (!(s->flags & PA_SOURCE_HW_VOLUME_CTRL))
-        s->flags |= PA_SOURCE_DECIBEL_VOLUME;
+    /* If the source implementor support DB volumes by itself, we should always
+     * try and enable flat volumes too */
+    if ((s->flags & PA_SOURCE_DECIBEL_VOLUME))
+        enable_flat_volume(s, TRUE);
+
+    if (s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER) {
+        pa_source *root_source = pa_source_get_master(s);
+
+        pa_assert(PA_LIKELY(root_source));
+
+        s->reference_volume = root_source->reference_volume;
+        pa_cvolume_remap(&s->reference_volume, &root_source->channel_map, &s->channel_map);
+
+        s->real_volume = root_source->real_volume;
+        pa_cvolume_remap(&s->real_volume, &root_source->channel_map, &s->channel_map);
+    } else
+        /* We assume that if the sink implementor changed the default
+         * volume he did so in real_volume, because that is the usual
+         * place where he is supposed to place his changes.  */
+        s->reference_volume = s->real_volume;
 
     s->thread_info.soft_volume = s->soft_volume;
     s->thread_info.soft_muted = s->muted;
+    pa_sw_cvolume_multiply(&s->thread_info.current_hw_volume, &s->soft_volume, &s->real_volume);
 
-    pa_assert((s->flags & PA_SOURCE_HW_VOLUME_CTRL) || (s->base_volume == PA_VOLUME_NORM && s->flags & PA_SOURCE_DECIBEL_VOLUME));
+    pa_assert((s->flags & PA_SOURCE_HW_VOLUME_CTRL)
+              || (s->base_volume == PA_VOLUME_NORM
+                  && ((s->flags & PA_SOURCE_DECIBEL_VOLUME || (s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)))));
     pa_assert(!(s->flags & PA_SOURCE_DECIBEL_VOLUME) || s->n_volume_steps == PA_VOLUME_NORM+1);
     pa_assert(!(s->flags & PA_SOURCE_DYNAMIC_LATENCY) == (s->thread_info.fixed_latency != 0));
 
-    pa_assert_se(source_set_state(s, PA_SOURCE_IDLE) == 0);
+    if (s->suspend_cause)
+        pa_assert_se(source_set_state(s, PA_SOURCE_SUSPENDED) == 0);
+    else
+        pa_assert_se(source_set_state(s, PA_SOURCE_IDLE) == 0);
 
     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);
@@ -424,7 +749,6 @@ void pa_source_unlink(pa_source *s) {
 
 /* Called from main context */
 static void source_free(pa_object *o) {
-    pa_source_output *so;
     pa_source *s = PA_SOURCE(o);
 
     pa_assert(s);
@@ -436,12 +760,8 @@ static void source_free(pa_object *o) {
 
     pa_log_info("Freeing source %u \"%s\"", s->index, s->name);
 
-    pa_idxset_free(s->outputs, NULL, NULL);
-
-    while ((so = pa_hashmap_steal_first(s->thread_info.outputs)))
-        pa_source_output_unref(so);
-
-    pa_hashmap_free(s->thread_info.outputs, NULL, NULL);
+    pa_idxset_free(s->outputs, NULL);
+    pa_hashmap_free(s->thread_info.outputs, (pa_free_cb_t) pa_source_output_unref);
 
     if (s->silence.memblock)
         pa_memblock_unref(s->silence.memblock);
@@ -452,14 +772,16 @@ static void source_free(pa_object *o) {
     if (s->proplist)
         pa_proplist_free(s->proplist);
 
-    if (s->ports) {
-        pa_device_port *p;
-
-        while ((p = pa_hashmap_steal_first(s->ports)))
-            pa_device_port_free(p);
+    if (s->ports)
+        pa_hashmap_free(s->ports, (pa_free_cb_t) pa_device_port_unref);
 
-        pa_hashmap_free(s->ports, NULL, NULL);
+#ifdef __TIZEN__
+    /* close file for dump pcm */
+    if (s->dump_fp) {
+        fclose(s->dump_fp);
+        s->dump_fp = NULL;
     }
+#endif
 
     pa_xfree(s);
 }
@@ -474,16 +796,36 @@ void pa_source_set_asyncmsgq(pa_source *s, pa_asyncmsgq *q) {
 
 /* Called from main context, and not while the IO thread is active, please */
 void pa_source_update_flags(pa_source *s, pa_source_flags_t mask, pa_source_flags_t value) {
+    pa_source_flags_t old_flags;
+    pa_source_output *output;
+    uint32_t idx;
+
     pa_source_assert_ref(s);
     pa_assert_ctl_context();
 
-    if (mask == 0)
-        return;
-
     /* For now, allow only a minimal set of flags to be changed. */
     pa_assert((mask & ~(PA_SOURCE_DYNAMIC_LATENCY|PA_SOURCE_LATENCY)) == 0);
 
+    old_flags = s->flags;
     s->flags = (s->flags & ~mask) | (value & mask);
+
+    if (s->flags == old_flags)
+        return;
+
+    if ((s->flags & PA_SOURCE_LATENCY) != (old_flags & PA_SOURCE_LATENCY))
+        pa_log_debug("Source %s: LATENCY flag %s.", s->name, (s->flags & PA_SOURCE_LATENCY) ? "enabled" : "disabled");
+
+    if ((s->flags & PA_SOURCE_DYNAMIC_LATENCY) != (old_flags & PA_SOURCE_DYNAMIC_LATENCY))
+        pa_log_debug("Source %s: DYNAMIC_LATENCY flag %s.",
+                     s->name, (s->flags & PA_SOURCE_DYNAMIC_LATENCY) ? "enabled" : "disabled");
+
+    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_FLAGS_CHANGED], s);
+
+    PA_IDXSET_FOREACH(output, s->outputs, idx) {
+        if (output->destination_source)
+            pa_source_update_flags(output->destination_source, mask, value);
+    }
 }
 
 /* Called from IO context, or before _put() from main context */
@@ -506,14 +848,24 @@ int pa_source_update_status(pa_source*s) {
     return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE);
 }
 
+/* Called from any context - must be threadsafe */
+void pa_source_set_mixer_dirty(pa_source *s, pa_bool_t is_dirty)
+{
+    pa_atomic_store(&s->mixer_dirty, is_dirty ? 1 : 0);
+}
+
 /* Called from main context */
 int pa_source_suspend(pa_source *s, pa_bool_t suspend, pa_suspend_cause_t cause) {
+#ifdef __TIZEN__
+    int ret = 0;
+#endif
+
     pa_source_assert_ref(s);
     pa_assert_ctl_context();
     pa_assert(PA_SOURCE_IS_LINKED(s->state));
     pa_assert(cause != 0);
 
-    if (s->monitor_of)
+    if (s->monitor_of && cause != PA_SUSPEND_PASSTHROUGH)
         return -PA_ERR_NOTSUPPORTED;
 
     if (suspend)
@@ -521,14 +873,65 @@ int pa_source_suspend(pa_source *s, pa_bool_t suspend, pa_suspend_cause_t cause)
     else
         s->suspend_cause &= ~cause;
 
-    if ((pa_source_get_state(s) == PA_SOURCE_SUSPENDED) == !!s->suspend_cause)
+    if (!(s->suspend_cause & PA_SUSPEND_SESSION) && (pa_atomic_load(&s->mixer_dirty) != 0)) {
+        /* This might look racy but isn't: If somebody sets mixer_dirty exactly here,
+           it'll be handled just fine. */
+        pa_source_set_mixer_dirty(s, FALSE);
+        pa_log_debug("Mixer is now accessible. Updating alsa mixer settings.");
+        if (s->active_port && s->set_port) {
+            if (s->flags & PA_SOURCE_DEFERRED_VOLUME) {
+                struct source_message_set_port msg = { .port = s->active_port, .ret = 0 };
+                pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
+            }
+            else
+                s->set_port(s, s->active_port);
+        }
+        else {
+            if (s->set_mute)
+                s->set_mute(s);
+            if (s->set_volume)
+                s->set_volume(s);
+        }
+    }
+
+    if ((pa_source_get_state(s) == PA_SOURCE_SUSPENDED) == !!s->suspend_cause) {
+#ifdef __TIZEN__
+        if (cause == PA_SUSPEND_SWITCH) {
+            /* Clear suspend by switch after manual suspend */
+            s->suspend_cause &= ~cause;
+        }
+#endif
         return 0;
+    }
 
     pa_log_debug("Suspend cause of source %s is 0x%04x, %s", s->name, s->suspend_cause, s->suspend_cause ? "suspending" : "resuming");
 
-    if (suspend)
+#ifdef __TIZEN__
+#ifdef PA_DUMP_SOURCE_FOR_EACH_SUSPEND
+    /* close file for dump pcm */
+    if (suspend && s->dump_in_fp) {
+        fclose(s->dump_in_fp);
+        s->dump_in_fp = NULL;
+    }
+    if (suspend && s->dump_out_fp) {
+        fclose(s->dump_out_fp);
+        s->dump_out_fp = NULL;
+    }
+#endif
+    if (s->suspend_cause) {
+        ret = source_set_state(s, PA_SOURCE_SUSPENDED);
+        if (ret == 0 && cause == PA_SUSPEND_SWITCH) {
+            /* Clear suspend by switch after manual suspend */
+            s->suspend_cause &= ~cause;
+        }
+        return ret;
+    } else
+#else
+
+    if (s->suspend_cause)
         return source_set_state(s, PA_SOURCE_SUSPENDED);
     else
+#endif /* __TIZEN__ */
         return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE);
 }
 
@@ -593,7 +996,7 @@ void pa_source_move_all_finish(pa_source *s, pa_queue *q, pa_bool_t save) {
         pa_source_output_unref(o);
     }
 
-    pa_queue_free(q, NULL, NULL);
+    pa_queue_free(q, NULL);
 }
 
 /* Called from main context */
@@ -608,7 +1011,7 @@ void pa_source_move_all_fail(pa_queue *q) {
         pa_source_output_unref(o);
     }
 
-    pa_queue_free(q, NULL, NULL);
+    pa_queue_free(q, NULL);
 }
 
 /* Called from IO thread context */
@@ -626,7 +1029,14 @@ void pa_source_process_rewind(pa_source *s, size_t nbytes) {
     if (s->thread_info.state == PA_SOURCE_SUSPENDED)
         return;
 
-    pa_log_debug("Processing rewind...");
+    pa_log_debug_verbose("Processing rewind...");
+
+#ifdef __TIZEN__
+    /* rewind pcm */
+    if (s->dump_fp) {
+        fseeko(s->dump_fp, (off_t)nbytes * (-1), SEEK_CUR);
+    }
+#endif
 
     PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state) {
         pa_source_output_assert_ref(o);
@@ -647,6 +1057,10 @@ void pa_source_post(pa_source*s, const pa_memchunk *chunk) {
     if (s->thread_info.state == PA_SOURCE_SUSPENDED)
         return;
 
+#ifdef __TIZEN__
+    __toggle_open_close_n_write_dump_source(s, chunk);
+#endif
+
     if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&s->thread_info.soft_volume)) {
         pa_memchunk vchunk = *chunk;
 
@@ -689,6 +1103,10 @@ void pa_source_post_direct(pa_source*s, pa_source_output *o, const pa_memchunk *
     if (s->thread_info.state == PA_SOURCE_SUSPENDED)
         return;
 
+#ifdef __TIZEN__
+    __toggle_open_close_n_write_dump_source(s, chunk);
+#endif
+
     if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&s->thread_info.soft_volume)) {
         pa_memchunk vchunk = *chunk;
 
@@ -708,6 +1126,76 @@ void pa_source_post_direct(pa_source*s, pa_source_output *o, const pa_memchunk *
 }
 
 /* Called from main thread */
+pa_bool_t pa_source_update_rate(pa_source *s, uint32_t rate, pa_bool_t passthrough)
+{
+    if (s->update_rate) {
+        uint32_t desired_rate = rate;
+        uint32_t default_rate = s->default_sample_rate;
+        uint32_t alternate_rate = s->alternate_sample_rate;
+        uint32_t idx;
+        pa_source_output *o;
+        pa_bool_t use_alternate = FALSE;
+
+        if (PA_UNLIKELY(default_rate == alternate_rate)) {
+            pa_log_warn("Default and alternate sample rates are the same.");
+            return FALSE;
+        }
+
+        if (PA_SOURCE_IS_RUNNING(s->state)) {
+            pa_log_info("Cannot update rate, SOURCE_IS_RUNNING, will keep using %u Hz",
+                        s->sample_spec.rate);
+            return FALSE;
+        }
+
+        if (PA_UNLIKELY (desired_rate < 8000 ||
+                         desired_rate > PA_RATE_MAX))
+            return FALSE;
+
+        if (!passthrough) {
+            pa_assert(default_rate % 4000 || default_rate % 11025);
+            pa_assert(alternate_rate % 4000 || alternate_rate % 11025);
+
+            if (default_rate % 4000) {
+                /* default is a 11025 multiple */
+                if ((alternate_rate % 4000 == 0) && (desired_rate % 4000 == 0))
+                    use_alternate=TRUE;
+            } else {
+                /* default is 4000 multiple */
+                if ((alternate_rate % 11025 == 0) && (desired_rate % 11025 == 0))
+                    use_alternate=TRUE;
+            }
+
+            if (use_alternate)
+                desired_rate = alternate_rate;
+            else
+                desired_rate = default_rate;
+        } else {
+            desired_rate = rate; /* use stream sampling rate, discard default/alternate settings */
+        }
+
+        if (desired_rate == s->sample_spec.rate)
+            return FALSE;
+
+        if (!passthrough && pa_source_used_by(s) > 0)
+            return FALSE;
+
+        pa_log_debug("Suspending source %s due to changing the sample rate.", s->name);
+        pa_source_suspend(s, TRUE, PA_SUSPEND_IDLE); /* needed before rate update, will be resumed automatically */
+
+        if (s->update_rate(s, desired_rate) == TRUE) {
+            pa_log_info("Changed sampling rate successfully ");
+
+            PA_IDXSET_FOREACH(o, s->outputs, idx) {
+                if (o->state == PA_SOURCE_OUTPUT_CORKED)
+                    pa_source_output_update_rate(o);
+            }
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+/* Called from main thread */
 pa_usec_t pa_source_get_latency(pa_source *s) {
     pa_usec_t usec;
 
@@ -723,6 +1211,13 @@ pa_usec_t pa_source_get_latency(pa_source *s) {
 
     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_LATENCY, &usec, 0, NULL) == 0);
 
+    /* usec is unsigned, so check that the offset can be added to usec without
+     * underflowing. */
+    if (-s->latency_offset <= (int64_t) usec)
+        usec += s->latency_offset;
+    else
+        usec = 0;
+
     return usec;
 }
 
@@ -731,81 +1226,662 @@ pa_usec_t pa_source_get_latency_within_thread(pa_source *s) {
     pa_usec_t usec = 0;
     pa_msgobject *o;
 
-    pa_source_assert_ref(s);
-    pa_source_assert_io_context(s);
-    pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
+    pa_source_assert_ref(s);
+    pa_source_assert_io_context(s);
+    pa_assert(PA_SOURCE_IS_LINKED(s->thread_info.state));
+
+    /* The returned value is supposed to be in the time domain of the sound card! */
+
+    if (s->thread_info.state == PA_SOURCE_SUSPENDED)
+        return 0;
+
+    if (!(s->flags & PA_SOURCE_LATENCY))
+        return 0;
+
+    o = PA_MSGOBJECT(s);
+
+    /* FIXME: We probably should make this a proper vtable callback instead of going through process_msg() */
+
+    if (o->process_msg(o, PA_SOURCE_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0)
+        return -1;
+
+    /* usec is unsigned, so check that the offset can be added to usec without
+     * underflowing. */
+    if (-s->thread_info.latency_offset <= (int64_t) usec)
+        usec += s->thread_info.latency_offset;
+    else
+        usec = 0;
+
+    return usec;
+}
+
+/* Called from the main thread (and also from the IO thread while the main
+ * thread is waiting).
+ *
+ * When a source uses volume sharing, it never has the PA_SOURCE_FLAT_VOLUME flag
+ * set. Instead, flat volume mode is detected by checking whether the root source
+ * has the flag set. */
+pa_bool_t pa_source_flat_volume_enabled(pa_source *s) {
+    pa_source_assert_ref(s);
+
+    s = pa_source_get_master(s);
+
+    if (PA_LIKELY(s))
+        return (s->flags & PA_SOURCE_FLAT_VOLUME);
+    else
+        return FALSE;
+}
+
+/* Called from the main thread (and also from the IO thread while the main
+ * thread is waiting). */
+pa_source *pa_source_get_master(pa_source *s) {
+    pa_source_assert_ref(s);
+
+    while (s && (s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
+        if (PA_UNLIKELY(!s->output_from_master))
+            return NULL;
+
+        s = s->output_from_master->source;
+    }
+
+    return s;
+}
+
+/* Called from main context */
+pa_bool_t pa_source_is_passthrough(pa_source *s) {
+
+    pa_source_assert_ref(s);
+
+    /* NB Currently only monitor sources support passthrough mode */
+    return (s->monitor_of && pa_sink_is_passthrough(s->monitor_of));
+}
+
+/* Called from main context */
+void pa_source_enter_passthrough(pa_source *s) {
+    pa_cvolume volume;
+
+    /* set the volume to NORM */
+    s->saved_volume = *pa_source_get_volume(s, TRUE);
+    s->saved_save_volume = s->save_volume;
+
+    pa_cvolume_set(&volume, s->sample_spec.channels, PA_MIN(s->base_volume, PA_VOLUME_NORM));
+    pa_source_set_volume(s, &volume, TRUE, FALSE);
+}
+
+/* Called from main context */
+void pa_source_leave_passthrough(pa_source *s) {
+    /* Restore source volume to what it was before we entered passthrough mode */
+    pa_source_set_volume(s, &s->saved_volume, TRUE, s->saved_save_volume);
+
+    pa_cvolume_init(&s->saved_volume);
+    s->saved_save_volume = FALSE;
+}
+
+/* Called from main context. */
+static void compute_reference_ratio(pa_source_output *o) {
+    unsigned c = 0;
+    pa_cvolume remapped;
+
+    pa_assert(o);
+    pa_assert(pa_source_flat_volume_enabled(o->source));
+
+    /*
+     * Calculates the reference ratio from the source's reference
+     * volume. This basically calculates:
+     *
+     * o->reference_ratio = o->volume / o->source->reference_volume
+     */
+
+    remapped = o->source->reference_volume;
+    pa_cvolume_remap(&remapped, &o->source->channel_map, &o->channel_map);
+
+    o->reference_ratio.channels = o->sample_spec.channels;
+
+    for (c = 0; c < o->sample_spec.channels; c++) {
+
+        /* We don't update when the source volume is 0 anyway */
+        if (remapped.values[c] <= PA_VOLUME_MUTED)
+            continue;
+
+        /* Don't update the reference ratio unless necessary */
+        if (pa_sw_volume_multiply(
+                    o->reference_ratio.values[c],
+                    remapped.values[c]) == o->volume.values[c])
+            continue;
+
+        o->reference_ratio.values[c] = pa_sw_volume_divide(
+                o->volume.values[c],
+                remapped.values[c]);
+    }
+}
+
+/* Called from main context. Only called for the root source in volume sharing
+ * cases, except for internal recursive calls. */
+static void compute_reference_ratios(pa_source *s) {
+    uint32_t idx;
+    pa_source_output *o;
+
+    pa_source_assert_ref(s);
+    pa_assert_ctl_context();
+    pa_assert(PA_SOURCE_IS_LINKED(s->state));
+    pa_assert(pa_source_flat_volume_enabled(s));
+
+    PA_IDXSET_FOREACH(o, s->outputs, idx) {
+        compute_reference_ratio(o);
+
+        if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
+            compute_reference_ratios(o->destination_source);
+    }
+}
+
+/* Called from main context. Only called for the root source in volume sharing
+ * cases, except for internal recursive calls. */
+static void compute_real_ratios(pa_source *s) {
+    pa_source_output *o;
+    uint32_t idx;
+
+    pa_source_assert_ref(s);
+    pa_assert_ctl_context();
+    pa_assert(PA_SOURCE_IS_LINKED(s->state));
+    pa_assert(pa_source_flat_volume_enabled(s));
+
+    PA_IDXSET_FOREACH(o, s->outputs, idx) {
+        unsigned c;
+        pa_cvolume remapped;
+
+        if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
+            /* The origin source uses volume sharing, so this input's real ratio
+             * is handled as a special case - the real ratio must be 0 dB, and
+             * as a result i->soft_volume must equal i->volume_factor. */
+            pa_cvolume_reset(&o->real_ratio, o->real_ratio.channels);
+            o->soft_volume = o->volume_factor;
+
+            compute_real_ratios(o->destination_source);
+
+            continue;
+        }
+
+        /*
+         * This basically calculates:
+         *
+         * i->real_ratio := i->volume / s->real_volume
+         * i->soft_volume := i->real_ratio * i->volume_factor
+         */
+
+        remapped = s->real_volume;
+        pa_cvolume_remap(&remapped, &s->channel_map, &o->channel_map);
+
+        o->real_ratio.channels = o->sample_spec.channels;
+        o->soft_volume.channels = o->sample_spec.channels;
+
+        for (c = 0; c < o->sample_spec.channels; c++) {
+
+            if (remapped.values[c] <= PA_VOLUME_MUTED) {
+                /* We leave o->real_ratio untouched */
+                o->soft_volume.values[c] = PA_VOLUME_MUTED;
+                continue;
+            }
+
+            /* Don't lose accuracy unless necessary */
+            if (pa_sw_volume_multiply(
+                        o->real_ratio.values[c],
+                        remapped.values[c]) != o->volume.values[c])
+
+                o->real_ratio.values[c] = pa_sw_volume_divide(
+                        o->volume.values[c],
+                        remapped.values[c]);
+
+            o->soft_volume.values[c] = pa_sw_volume_multiply(
+                    o->real_ratio.values[c],
+                    o->volume_factor.values[c]);
+        }
+
+        /* We don't copy the soft_volume to the thread_info data
+         * here. That must be done by the caller */
+    }
+}
+
+static pa_cvolume *cvolume_remap_minimal_impact(
+        pa_cvolume *v,
+        const pa_cvolume *template,
+        const pa_channel_map *from,
+        const pa_channel_map *to) {
+
+    pa_cvolume t;
+
+    pa_assert(v);
+    pa_assert(template);
+    pa_assert(from);
+    pa_assert(to);
+    pa_assert(pa_cvolume_compatible_with_channel_map(v, from));
+    pa_assert(pa_cvolume_compatible_with_channel_map(template, to));
+
+    /* Much like pa_cvolume_remap(), but tries to minimize impact when
+     * mapping from source output to source volumes:
+     *
+     * If template is a possible remapping from v it is used instead
+     * of remapping anew.
+     *
+     * If the channel maps don't match we set an all-channel volume on
+     * the source to ensure that changing a volume on one stream has no
+     * effect that cannot be compensated for in another stream that
+     * does not have the same channel map as the source. */
+
+    if (pa_channel_map_equal(from, to))
+        return v;
+
+    t = *template;
+    if (pa_cvolume_equal(pa_cvolume_remap(&t, to, from), v)) {
+        *v = *template;
+        return v;
+    }
+
+    pa_cvolume_set(v, to->channels, pa_cvolume_max(v));
+    return v;
+}
+
+/* Called from main thread. Only called for the root source in volume sharing
+ * cases, except for internal recursive calls. */
+static void get_maximum_output_volume(pa_source *s, pa_cvolume *max_volume, const pa_channel_map *channel_map) {
+    pa_source_output *o;
+    uint32_t idx;
+
+    pa_source_assert_ref(s);
+    pa_assert(max_volume);
+    pa_assert(channel_map);
+    pa_assert(pa_source_flat_volume_enabled(s));
+
+    PA_IDXSET_FOREACH(o, s->outputs, idx) {
+        pa_cvolume remapped;
+
+        if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
+            get_maximum_output_volume(o->destination_source, max_volume, channel_map);
+
+            /* Ignore this output. The origin source uses volume sharing, so this
+             * output's volume will be set to be equal to the root source's real
+             * volume. Obviously this output's current volume must not then
+             * affect what the root source's real volume will be. */
+            continue;
+        }
+
+        remapped = o->volume;
+        cvolume_remap_minimal_impact(&remapped, max_volume, &o->channel_map, channel_map);
+        pa_cvolume_merge(max_volume, max_volume, &remapped);
+    }
+}
+
+/* Called from main thread. Only called for the root source in volume sharing
+ * cases, except for internal recursive calls. */
+static pa_bool_t has_outputs(pa_source *s) {
+    pa_source_output *o;
+    uint32_t idx;
+
+    pa_source_assert_ref(s);
+
+    PA_IDXSET_FOREACH(o, s->outputs, idx) {
+        if (!o->destination_source || !(o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER) || has_outputs(o->destination_source))
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+/* Called from main thread. Only called for the root source in volume sharing
+ * cases, except for internal recursive calls. */
+static void update_real_volume(pa_source *s, const pa_cvolume *new_volume, pa_channel_map *channel_map) {
+    pa_source_output *o;
+    uint32_t idx;
+
+    pa_source_assert_ref(s);
+    pa_assert(new_volume);
+    pa_assert(channel_map);
+
+    s->real_volume = *new_volume;
+    pa_cvolume_remap(&s->real_volume, channel_map, &s->channel_map);
+
+    PA_IDXSET_FOREACH(o, s->outputs, idx) {
+        if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
+            if (pa_source_flat_volume_enabled(s)) {
+                pa_cvolume old_volume = o->volume;
+
+                /* Follow the root source's real volume. */
+                o->volume = *new_volume;
+                pa_cvolume_remap(&o->volume, channel_map, &o->channel_map);
+                compute_reference_ratio(o);
+
+                /* The volume changed, let's tell people so */
+                if (!pa_cvolume_equal(&old_volume, &o->volume)) {
+                    if (o->volume_changed)
+                        o->volume_changed(o);
+
+                    pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
+                }
+            }
+
+            update_real_volume(o->destination_source, new_volume, channel_map);
+        }
+    }
+}
+
+/* Called from main thread. Only called for the root source in shared volume
+ * cases. */
+static void compute_real_volume(pa_source *s) {
+    pa_source_assert_ref(s);
+    pa_assert_ctl_context();
+    pa_assert(PA_SOURCE_IS_LINKED(s->state));
+    pa_assert(pa_source_flat_volume_enabled(s));
+    pa_assert(!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER));
+
+    /* This determines the maximum volume of all streams and sets
+     * s->real_volume accordingly. */
+
+    if (!has_outputs(s)) {
+        /* In the special case that we have no source outputs we leave the
+         * volume unmodified. */
+        update_real_volume(s, &s->reference_volume, &s->channel_map);
+        return;
+    }
+
+    pa_cvolume_mute(&s->real_volume, s->channel_map.channels);
+
+    /* First let's determine the new maximum volume of all outputs
+     * connected to this source */
+    get_maximum_output_volume(s, &s->real_volume, &s->channel_map);
+    update_real_volume(s, &s->real_volume, &s->channel_map);
+
+    /* Then, let's update the real ratios/soft volumes of all outputs
+     * connected to this source */
+    compute_real_ratios(s);
+}
+
+/* Called from main thread. Only called for the root source in shared volume
+ * cases, except for internal recursive calls. */
+static void propagate_reference_volume(pa_source *s) {
+    pa_source_output *o;
+    uint32_t idx;
+
+    pa_source_assert_ref(s);
+    pa_assert_ctl_context();
+    pa_assert(PA_SOURCE_IS_LINKED(s->state));
+    pa_assert(pa_source_flat_volume_enabled(s));
+
+    /* This is called whenever the source volume changes that is not
+     * caused by a source output volume change. We need to fix up the
+     * source output volumes accordingly */
+
+    PA_IDXSET_FOREACH(o, s->outputs, idx) {
+        pa_cvolume old_volume;
+
+        if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
+            propagate_reference_volume(o->destination_source);
+
+            /* Since the origin source uses volume sharing, this output's volume
+             * needs to be updated to match the root source's real volume, but
+             * that will be done later in update_shared_real_volume(). */
+            continue;
+        }
+
+        old_volume = o->volume;
+
+        /* This basically calculates:
+         *
+         * o->volume := o->reference_volume * o->reference_ratio  */
+
+        o->volume = s->reference_volume;
+        pa_cvolume_remap(&o->volume, &s->channel_map, &o->channel_map);
+        pa_sw_cvolume_multiply(&o->volume, &o->volume, &o->reference_ratio);
+
+        /* The volume changed, let's tell people so */
+        if (!pa_cvolume_equal(&old_volume, &o->volume)) {
+
+            if (o->volume_changed)
+                o->volume_changed(o);
+
+            pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
+        }
+    }
+}
+
+/* Called from main thread. Only called for the root source in volume sharing
+ * cases, except for internal recursive calls. The return value indicates
+ * whether any reference volume actually changed. */
+static pa_bool_t update_reference_volume(pa_source *s, const pa_cvolume *v, const pa_channel_map *channel_map, pa_bool_t save) {
+    pa_cvolume volume;
+    pa_bool_t reference_volume_changed;
+    pa_source_output *o;
+    uint32_t idx;
 
-    /* The returned value is supposed to be in the time domain of the sound card! */
+    pa_source_assert_ref(s);
+    pa_assert(PA_SOURCE_IS_LINKED(s->state));
+    pa_assert(v);
+    pa_assert(channel_map);
+    pa_assert(pa_cvolume_valid(v));
 
-    if (s->thread_info.state == PA_SOURCE_SUSPENDED)
-        return 0;
+    volume = *v;
+    pa_cvolume_remap(&volume, channel_map, &s->channel_map);
 
-    if (!(s->flags & PA_SOURCE_LATENCY))
-        return 0;
+    reference_volume_changed = !pa_cvolume_equal(&volume, &s->reference_volume);
+    s->reference_volume = volume;
 
-    o = PA_MSGOBJECT(s);
+    s->save_volume = (!reference_volume_changed && s->save_volume) || save;
 
-    /* We probably should make this a proper vtable callback instead of going through process_msg() */
+    if (reference_volume_changed)
+        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+    else if (!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
+        /* If the root source's volume doesn't change, then there can't be any
+         * changes in the other source in the source tree either.
+         *
+         * It's probably theoretically possible that even if the root source's
+         * volume changes slightly, some filter source doesn't change its volume
+         * due to rounding errors. If that happens, we still want to propagate
+         * the changed root source volume to the sources connected to the
+         * intermediate source that didn't change its volume. This theoretical
+         * possibility is the reason why we have that !(s->flags &
+         * PA_SOURCE_SHARE_VOLUME_WITH_MASTER) condition. Probably nobody would
+         * notice even if we returned here FALSE always if
+         * reference_volume_changed is FALSE. */
+        return FALSE;
 
-    if (o->process_msg(o, PA_SOURCE_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0)
-        return -1;
+    PA_IDXSET_FOREACH(o, s->outputs, idx) {
+        if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
+            update_reference_volume(o->destination_source, v, channel_map, FALSE);
+    }
 
-    return usec;
+    return TRUE;
 }
 
 /* Called from main thread */
 void pa_source_set_volume(
         pa_source *s,
         const pa_cvolume *volume,
+        pa_bool_t send_msg,
         pa_bool_t save) {
 
-    pa_bool_t real_changed;
-    pa_cvolume old_volume;
+    pa_cvolume new_reference_volume;
+    pa_source *root_source;
 
     pa_source_assert_ref(s);
     pa_assert_ctl_context();
     pa_assert(PA_SOURCE_IS_LINKED(s->state));
-    pa_assert(pa_cvolume_valid(volume));
-    pa_assert(volume->channels == 1 || pa_cvolume_compatible(volume, &s->sample_spec));
+    pa_assert(!volume || pa_cvolume_valid(volume));
+    pa_assert(volume || pa_source_flat_volume_enabled(s));
+    pa_assert(!volume || volume->channels == 1 || pa_cvolume_compatible(volume, &s->sample_spec));
+
+    /* make sure we don't change the volume in PASSTHROUGH mode ...
+     * ... *except* if we're being invoked to reset the volume to ensure 0 dB gain */
+    if (pa_source_is_passthrough(s) && (!volume || !pa_cvolume_is_norm(volume))) {
+        pa_log_warn("Cannot change volume, source is monitor of a PASSTHROUGH sink");
+        return;
+    }
 
-    old_volume = s->volume;
+    /* In case of volume sharing, the volume is set for the root source first,
+     * from which it's then propagated to the sharing sources. */
+    root_source = pa_source_get_master(s);
 
-    if (pa_cvolume_compatible(volume, &s->sample_spec))
-        s->volume = *volume;
-    else
-        pa_cvolume_scale(&s->volume, pa_cvolume_max(volume));
+    if (PA_UNLIKELY(!root_source))
+        return;
 
-    real_changed = !pa_cvolume_equal(&old_volume, &s->volume);
-    s->save_volume = (!real_changed && s->save_volume) || save;
+    /* As a special exception we accept mono volumes on all sources --
+     * even on those with more complex channel maps */
 
-    if (s->set_volume) {
-        pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
-        s->set_volume(s);
-    } else
-        s->soft_volume = s->volume;
+    if (volume) {
+        if (pa_cvolume_compatible(volume, &s->sample_spec))
+            new_reference_volume = *volume;
+        else {
+            new_reference_volume = s->reference_volume;
+            pa_cvolume_scale(&new_reference_volume, pa_cvolume_max(volume));
+        }
 
-    pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
+        pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_source->channel_map);
 
-    if (real_changed)
-        pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+        if (update_reference_volume(root_source, &new_reference_volume, &root_source->channel_map, save)) {
+            if (pa_source_flat_volume_enabled(root_source)) {
+                /* OK, propagate this volume change back to the outputs */
+                propagate_reference_volume(root_source);
+
+                /* And now recalculate the real volume */
+                compute_real_volume(root_source);
+            } else
+                update_real_volume(root_source, &root_source->reference_volume, &root_source->channel_map);
+        }
+
+    } else {
+        /* If volume is NULL we synchronize the source's real and
+         * reference volumes with the stream volumes. */
+
+        pa_assert(pa_source_flat_volume_enabled(root_source));
+
+        /* Ok, let's determine the new real volume */
+        compute_real_volume(root_source);
+
+        /* Let's 'push' the reference volume if necessary */
+        pa_cvolume_merge(&new_reference_volume, &s->reference_volume, &root_source->real_volume);
+        /* If the source and it's root don't have the same number of channels, we need to remap */
+        if (s != root_source && !pa_channel_map_equal(&s->channel_map, &root_source->channel_map))
+            pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_source->channel_map);
+        update_reference_volume(root_source, &new_reference_volume, &root_source->channel_map, save);
+
+        /* Now that the reference volume is updated, we can update the streams'
+         * reference ratios. */
+        compute_reference_ratios(root_source);
+    }
+
+    if (root_source->set_volume) {
+        /* If we have a function set_volume(), then we do not apply a
+         * soft volume by default. However, set_volume() is free to
+         * apply one to root_source->soft_volume */
+
+        pa_cvolume_reset(&root_source->soft_volume, root_source->sample_spec.channels);
+        if (!(root_source->flags & PA_SOURCE_DEFERRED_VOLUME))
+            root_source->set_volume(root_source);
+
+    } else
+        /* If we have no function set_volume(), then the soft volume
+         * becomes the real volume */
+        root_source->soft_volume = root_source->real_volume;
+
+    /* This tells the source that soft volume and/or real volume changed */
+    if (send_msg)
+        pa_assert_se(pa_asyncmsgq_send(root_source->asyncmsgq, PA_MSGOBJECT(root_source), PA_SOURCE_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL) == 0);
 }
 
-/* Called from main thread. Only to be called by source implementor */
+/* Called from the io thread if sync volume is used, otherwise from the main thread.
+ * Only to be called by source implementor */
 void pa_source_set_soft_volume(pa_source *s, const pa_cvolume *volume) {
+
     pa_source_assert_ref(s);
-    pa_assert_ctl_context();
+    pa_assert(!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER));
+
+    if (s->flags & PA_SOURCE_DEFERRED_VOLUME)
+        pa_source_assert_io_context(s);
+    else
+        pa_assert_ctl_context();
 
     if (!volume)
         pa_cvolume_reset(&s->soft_volume, s->sample_spec.channels);
     else
         s->soft_volume = *volume;
 
-    if (PA_SOURCE_IS_LINKED(s->state))
+    if (PA_SOURCE_IS_LINKED(s->state) && !(s->flags & PA_SOURCE_DEFERRED_VOLUME))
         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, NULL, 0, NULL) == 0);
     else
         s->thread_info.soft_volume = s->soft_volume;
 }
 
+/* Called from the main thread. Only called for the root source in volume sharing
+ * cases, except for internal recursive calls. */
+static void propagate_real_volume(pa_source *s, const pa_cvolume *old_real_volume) {
+    pa_source_output *o;
+    uint32_t idx;
+
+    pa_source_assert_ref(s);
+    pa_assert(old_real_volume);
+    pa_assert_ctl_context();
+    pa_assert(PA_SOURCE_IS_LINKED(s->state));
+
+    /* This is called when the hardware's real volume changes due to
+     * some external event. We copy the real volume into our
+     * reference volume and then rebuild the stream volumes based on
+     * i->real_ratio which should stay fixed. */
+
+    if (!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER)) {
+        if (pa_cvolume_equal(old_real_volume, &s->real_volume))
+            return;
+
+        /* 1. Make the real volume the reference volume */
+        update_reference_volume(s, &s->real_volume, &s->channel_map, TRUE);
+    }
+
+    if (pa_source_flat_volume_enabled(s)) {
+
+        PA_IDXSET_FOREACH(o, s->outputs, idx) {
+            pa_cvolume old_volume = o->volume;
+
+            /* 2. Since the source's reference and real volumes are equal
+             * now our ratios should be too. */
+            o->reference_ratio = o->real_ratio;
+
+            /* 3. Recalculate the new stream reference volume based on the
+             * reference ratio and the sink's reference volume.
+             *
+             * This basically calculates:
+             *
+             * o->volume = s->reference_volume * o->reference_ratio
+             *
+             * This is identical to propagate_reference_volume() */
+            o->volume = s->reference_volume;
+            pa_cvolume_remap(&o->volume, &s->channel_map, &o->channel_map);
+            pa_sw_cvolume_multiply(&o->volume, &o->volume, &o->reference_ratio);
+
+            /* Notify if something changed */
+            if (!pa_cvolume_equal(&old_volume, &o->volume)) {
+
+                if (o->volume_changed)
+                    o->volume_changed(o);
+
+                pa_subscription_post(o->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index);
+            }
+
+            if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
+                propagate_real_volume(o->destination_source, old_real_volume);
+        }
+    }
+
+    /* Something got changed in the hardware. It probably makes sense
+     * to save changed hw settings given that hw volume changes not
+     * triggered by PA are almost certainly done by the user. */
+    if (!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
+        s->save_volume = TRUE;
+}
+
+/* Called from io thread */
+void pa_source_update_volume_and_mute(pa_source *s) {
+    pa_assert(s);
+    pa_source_assert_io_context(s);
+
+    pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_UPDATE_VOLUME_AND_MUTE, NULL, 0, NULL, NULL);
+}
+
 /* Called from main thread */
 const pa_cvolume *pa_source_get_volume(pa_source *s, pa_bool_t force_refresh) {
     pa_source_assert_ref(s);
@@ -813,39 +1889,39 @@ const pa_cvolume *pa_source_get_volume(pa_source *s, pa_bool_t force_refresh) {
     pa_assert(PA_SOURCE_IS_LINKED(s->state));
 
     if (s->refresh_volume || force_refresh) {
-        pa_cvolume old_volume;
+        struct pa_cvolume old_real_volume;
+
+        pa_assert(!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER));
 
-        old_volume = s->volume;
+        old_real_volume = s->real_volume;
 
-        if (s->get_volume)
+        if (!(s->flags & PA_SOURCE_DEFERRED_VOLUME) && s->get_volume)
             s->get_volume(s);
 
         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_VOLUME, NULL, 0, NULL) == 0);
 
-        if (!pa_cvolume_equal(&old_volume, &s->volume)) {
-            s->save_volume = TRUE;
-            pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
-        }
+        update_real_volume(s, &s->real_volume, &s->channel_map);
+        propagate_real_volume(s, &old_real_volume);
     }
 
-    return &s->volume;
+    return &s->reference_volume;
 }
 
-/* Called from main thread */
-void pa_source_volume_changed(pa_source *s, const pa_cvolume *new_volume) {
+/* Called from main thread. In volume sharing cases, only the root source may
+ * call this. */
+void pa_source_volume_changed(pa_source *s, const pa_cvolume *new_real_volume) {
+    pa_cvolume old_real_volume;
+
     pa_source_assert_ref(s);
     pa_assert_ctl_context();
     pa_assert(PA_SOURCE_IS_LINKED(s->state));
+    pa_assert(!(s->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER));
 
     /* The source implementor may call this if the volume changed to make sure everyone is notified */
 
-    if (pa_cvolume_equal(&s->volume, new_volume))
-        return;
-
-    s->volume = *new_volume;
-    s->save_volume = TRUE;
-
-    pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
+    old_real_volume = s->real_volume;
+    update_real_volume(s, new_real_volume, &s->channel_map);
+    propagate_real_volume(s, &old_real_volume);
 }
 
 /* Called from main thread */
@@ -860,7 +1936,7 @@ void pa_source_set_mute(pa_source *s, pa_bool_t mute, pa_bool_t save) {
     s->muted = mute;
     s->save_muted = (old_muted == s->muted && s->save_muted) || save;
 
-    if (s->set_mute)
+    if (!(s->flags & PA_SOURCE_DEFERRED_VOLUME) && s->set_mute)
         s->set_mute(s);
 
     pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0);
@@ -871,6 +1947,7 @@ void pa_source_set_mute(pa_source *s, pa_bool_t mute, pa_bool_t save) {
 
 /* Called from main thread */
 pa_bool_t pa_source_get_mute(pa_source *s, pa_bool_t force_refresh) {
+
     pa_source_assert_ref(s);
     pa_assert_ctl_context();
     pa_assert(PA_SOURCE_IS_LINKED(s->state));
@@ -878,7 +1955,7 @@ pa_bool_t pa_source_get_mute(pa_source *s, pa_bool_t force_refresh) {
     if (s->refresh_muted || force_refresh) {
         pa_bool_t old_muted = s->muted;
 
-        if (s->get_mute)
+        if (!(s->flags & PA_SOURCE_DEFERRED_VOLUME) && s->get_mute)
             s->get_mute(s);
 
         pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_MUTE, NULL, 0, NULL) == 0);
@@ -958,8 +2035,8 @@ void pa_source_set_description(pa_source *s, const char *description) {
 /* Called from main thread */
 unsigned pa_source_linked_by(pa_source *s) {
     pa_source_assert_ref(s);
-    pa_assert(PA_SOURCE_IS_LINKED(s->state));
     pa_assert_ctl_context();
+    pa_assert(PA_SOURCE_IS_LINKED(s->state));
 
     return pa_idxset_size(s->outputs);
 }
@@ -969,8 +2046,8 @@ unsigned pa_source_used_by(pa_source *s) {
     unsigned ret;
 
     pa_source_assert_ref(s);
-    pa_assert(PA_SOURCE_IS_LINKED(s->state));
     pa_assert_ctl_context();
+    pa_assert(PA_SOURCE_IS_LINKED(s->state));
 
     ret = pa_idxset_size(s->outputs);
     pa_assert(ret >= s->n_corked);
@@ -996,7 +2073,14 @@ unsigned pa_source_check_suspend(pa_source *s) {
         pa_source_output_state_t st;
 
         st = pa_source_output_get_state(o);
-        pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(st));
+
+        /* We do not assert here. It is perfectly valid for a source output to
+         * be in the INIT state (i.e. created, marked done but not yet put)
+         * and we should not care if it's unlinked as it won't contribute
+         * towards our busy status.
+         */
+        if (!PA_SOURCE_OUTPUT_IS_LINKED(st))
+            continue;
 
         if (st == PA_SOURCE_OUTPUT_CORKED)
             continue;
@@ -1010,6 +2094,39 @@ unsigned pa_source_check_suspend(pa_source *s) {
     return ret;
 }
 
+/* Called from the IO thread */
+static void sync_output_volumes_within_thread(pa_source *s) {
+    pa_source_output *o;
+    void *state = NULL;
+
+    pa_source_assert_ref(s);
+    pa_source_assert_io_context(s);
+
+    PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state) {
+        if (pa_cvolume_equal(&o->thread_info.soft_volume, &o->soft_volume))
+            continue;
+
+        o->thread_info.soft_volume = o->soft_volume;
+        //pa_source_output_request_rewind(o, 0, TRUE, FALSE, FALSE);
+    }
+}
+
+/* Called from the IO thread. Only called for the root source in volume sharing
+ * cases, except for internal recursive calls. */
+static void set_shared_volume_within_thread(pa_source *s) {
+    pa_source_output *o;
+    void *state = NULL;
+
+    pa_source_assert_ref(s);
+
+    PA_MSGOBJECT(s)->process_msg(PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME_SYNCED, NULL, 0, NULL);
+
+    PA_HASHMAP_FOREACH(o, s->thread_info.outputs, state) {
+        if (o->destination_source && (o->destination_source->flags & PA_SOURCE_SHARE_VOLUME_WITH_MASTER))
+            set_shared_volume_within_thread(o->destination_source);
+    }
+}
+
 /* Called from IO thread, except when it is not */
 int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
     pa_source *s = PA_SOURCE(object);
@@ -1045,7 +2162,9 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_
              * requested latency. */
             pa_source_output_set_requested_latency_within_thread(o, o->thread_info.requested_source_latency);
 
-            return 0;
+            /* In flat volume mode we need to update the volume as
+             * well */
+            return object->process_msg(object, PA_SOURCE_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
         }
 
         case PA_SOURCE_MESSAGE_REMOVE_OUTPUT: {
@@ -1069,21 +2188,71 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_
 
             pa_source_invalidate_requested_latency(s, TRUE);
 
+            /* In flat volume mode we need to update the volume as
+             * well */
+            return object->process_msg(object, PA_SOURCE_MESSAGE_SET_SHARED_VOLUME, NULL, 0, NULL);
+        }
+
+        case PA_SOURCE_MESSAGE_SET_SHARED_VOLUME: {
+            pa_source *root_source = pa_source_get_master(s);
+
+            if (PA_LIKELY(root_source))
+                set_shared_volume_within_thread(root_source);
+
             return 0;
         }
 
+        case PA_SOURCE_MESSAGE_SET_VOLUME_SYNCED:
+
+            if (s->flags & PA_SOURCE_DEFERRED_VOLUME) {
+                s->set_volume(s);
+                pa_source_volume_change_push(s);
+            }
+            /* Fall through ... */
+
         case PA_SOURCE_MESSAGE_SET_VOLUME:
-            s->thread_info.soft_volume = s->soft_volume;
+
+            if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
+                s->thread_info.soft_volume = s->soft_volume;
+            }
+
+            /* Fall through ... */
+
+        case PA_SOURCE_MESSAGE_SYNC_VOLUMES:
+            sync_output_volumes_within_thread(s);
             return 0;
 
         case PA_SOURCE_MESSAGE_GET_VOLUME:
+
+            if ((s->flags & PA_SOURCE_DEFERRED_VOLUME) && s->get_volume) {
+                s->get_volume(s);
+                pa_source_volume_change_flush(s);
+                pa_sw_cvolume_divide(&s->thread_info.current_hw_volume, &s->real_volume, &s->soft_volume);
+            }
+
+            /* In case source implementor reset SW volume. */
+            if (!pa_cvolume_equal(&s->thread_info.soft_volume, &s->soft_volume)) {
+                s->thread_info.soft_volume = s->soft_volume;
+            }
+
             return 0;
 
         case PA_SOURCE_MESSAGE_SET_MUTE:
-            s->thread_info.soft_muted = s->muted;
+
+            if (s->thread_info.soft_muted != s->muted) {
+                s->thread_info.soft_muted = s->muted;
+            }
+
+            if (s->flags & PA_SOURCE_DEFERRED_VOLUME && s->set_mute)
+                s->set_mute(s);
+
             return 0;
 
         case PA_SOURCE_MESSAGE_GET_MUTE:
+
+            if (s->flags & PA_SOURCE_DEFERRED_VOLUME && s->get_mute)
+                s->get_mute(s);
+
             return 0;
 
         case PA_SOURCE_MESSAGE_SET_STATE: {
@@ -1103,7 +2272,6 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_
                         o->suspend_within_thread(o, s->thread_info.state == PA_SOURCE_SUSPENDED);
             }
 
-
             return 0;
         }
 
@@ -1124,6 +2292,9 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_
             pa_usec_t *usec = userdata;
             *usec = pa_source_get_requested_latency_within_thread(s);
 
+            /* Yes, that's right, the IO thread will see -1 when no
+             * explicit requested latency is configured, the main
+             * thread will see max_latency */
             if (*usec == (pa_usec_t) -1)
                 *usec = s->thread_info.max_latency;
 
@@ -1177,6 +2348,31 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_
             /* Implementors need to overwrite this implementation! */
             return -1;
 
+        case PA_SOURCE_MESSAGE_SET_PORT:
+
+            pa_assert(userdata);
+            if (s->set_port) {
+                struct source_message_set_port *msg_data = userdata;
+                msg_data->ret = s->set_port(s, msg_data->port);
+            }
+            return 0;
+
+        case PA_SOURCE_MESSAGE_UPDATE_VOLUME_AND_MUTE:
+            /* This message is sent from IO-thread and handled in main thread. */
+            pa_assert_ctl_context();
+
+            /* Make sure we're not messing with main thread when no longer linked */
+            if (!PA_SOURCE_IS_LINKED(s->state))
+                return 0;
+
+            pa_source_get_volume(s, TRUE);
+            pa_source_get_mute(s, TRUE);
+            return 0;
+
+        case PA_SOURCE_MESSAGE_SET_LATENCY_OFFSET:
+            s->thread_info.latency_offset = offset;
+            return 0;
+
         case PA_SOURCE_MESSAGE_MAX:
             ;
     }
@@ -1186,8 +2382,8 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_
 
 /* Called from main thread */
 int pa_source_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause) {
-    uint32_t idx;
     pa_source *source;
+    uint32_t idx;
     int ret = 0;
 
     pa_core_assert_ref(c);
@@ -1394,22 +2590,22 @@ void pa_source_set_latency_range(pa_source *s, pa_usec_t min_latency, pa_usec_t
 
 /* Called from main thread */
 void pa_source_get_latency_range(pa_source *s, pa_usec_t *min_latency, pa_usec_t *max_latency) {
-   pa_source_assert_ref(s);
-   pa_assert_ctl_context();
-   pa_assert(min_latency);
-   pa_assert(max_latency);
+    pa_source_assert_ref(s);
+    pa_assert_ctl_context();
+    pa_assert(min_latency);
+    pa_assert(max_latency);
 
-   if (PA_SOURCE_IS_LINKED(s->state)) {
-       pa_usec_t r[2] = { 0, 0 };
+    if (PA_SOURCE_IS_LINKED(s->state)) {
+        pa_usec_t r[2] = { 0, 0 };
 
-       pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_LATENCY_RANGE, r, 0, NULL) == 0);
+        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_LATENCY_RANGE, r, 0, NULL) == 0);
 
-       *min_latency = r[0];
-       *max_latency = r[1];
-   } else {
-       *min_latency = s->thread_info.min_latency;
-       *max_latency = s->thread_info.max_latency;
-   }
+        *min_latency = r[0];
+        *max_latency = r[1];
+    } else {
+        *min_latency = s->thread_info.min_latency;
+        *max_latency = s->thread_info.max_latency;
+    }
 }
 
 /* Called from IO thread, and from main thread before pa_source_put() is called */
@@ -1493,6 +2689,8 @@ void pa_source_set_fixed_latency_within_thread(pa_source *s, pa_usec_t latency)
 
     if (s->flags & PA_SOURCE_DYNAMIC_LATENCY) {
         pa_assert(latency == 0);
+        s->thread_info.fixed_latency = 0;
+
         return;
     }
 
@@ -1517,6 +2715,18 @@ void pa_source_set_fixed_latency_within_thread(pa_source *s, pa_usec_t latency)
 }
 
 /* Called from main thread */
+void pa_source_set_latency_offset(pa_source *s, int64_t offset) {
+    pa_source_assert_ref(s);
+
+    s->latency_offset = offset;
+
+    if (PA_SOURCE_IS_LINKED(s->state))
+        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_LATENCY_OFFSET, NULL, offset, NULL) == 0);
+    else
+        s->thread_info.latency_offset = offset;
+}
+
+/* Called from main thread */
 size_t pa_source_get_max_rewind(pa_source *s) {
     size_t r;
     pa_assert_ctl_context();
@@ -1533,8 +2743,9 @@ size_t pa_source_get_max_rewind(pa_source *s) {
 /* Called from main context */
 int pa_source_set_port(pa_source *s, const char *name, pa_bool_t save) {
     pa_device_port *port;
+    int ret;
 
-    pa_assert(s);
+    pa_source_assert_ref(s);
     pa_assert_ctl_context();
 
     if (!s->set_port) {
@@ -1542,7 +2753,7 @@ int pa_source_set_port(pa_source *s, const char *name, pa_bool_t save) {
         return -PA_ERR_NOTIMPLEMENTED;
     }
 
-    if (!s->ports)
+    if (!name)
         return -PA_ERR_NOENTITY;
 
     if (!(port = pa_hashmap_get(s->ports, name)))
@@ -1553,7 +2764,15 @@ int pa_source_set_port(pa_source *s, const char *name, pa_bool_t save) {
         return 0;
     }
 
-    if ((s->set_port(s, port)) < 0)
+    if (s->flags & PA_SOURCE_DEFERRED_VOLUME) {
+        struct source_message_set_port msg = { .port = port, .ret = 0 };
+        pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
+        ret = msg.ret;
+    }
+    else
+        ret = s->set_port(s, port);
+
+    if (ret < 0)
         return -PA_ERR_NOENTITY;
 
     pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
@@ -1563,5 +2782,236 @@ int pa_source_set_port(pa_source *s, const char *name, pa_bool_t save) {
     s->active_port = port;
     s->save_port = save;
 
+    pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PORT_CHANGED], s);
+
     return 0;
 }
+
+PA_STATIC_FLIST_DECLARE(pa_source_volume_change, 0, pa_xfree);
+
+/* Called from the IO thread. */
+static pa_source_volume_change *pa_source_volume_change_new(pa_source *s) {
+    pa_source_volume_change *c;
+    if (!(c = pa_flist_pop(PA_STATIC_FLIST_GET(pa_source_volume_change))))
+        c = pa_xnew(pa_source_volume_change, 1);
+
+    PA_LLIST_INIT(pa_source_volume_change, c);
+    c->at = 0;
+    pa_cvolume_reset(&c->hw_volume, s->sample_spec.channels);
+    return c;
+}
+
+/* Called from the IO thread. */
+static void pa_source_volume_change_free(pa_source_volume_change *c) {
+    pa_assert(c);
+    if (pa_flist_push(PA_STATIC_FLIST_GET(pa_source_volume_change), c) < 0)
+        pa_xfree(c);
+}
+
+/* Called from the IO thread. */
+void pa_source_volume_change_push(pa_source *s) {
+    pa_source_volume_change *c = NULL;
+    pa_source_volume_change *nc = NULL;
+    uint32_t safety_margin = s->thread_info.volume_change_safety_margin;
+
+    const char *direction = NULL;
+
+    pa_assert(s);
+    nc = pa_source_volume_change_new(s);
+
+    /* NOTE: There is already more different volumes in pa_source that I can remember.
+     *       Adding one more volume for HW would get us rid of this, but I am trying
+     *       to survive with the ones we already have. */
+    pa_sw_cvolume_divide(&nc->hw_volume, &s->real_volume, &s->soft_volume);
+
+    if (!s->thread_info.volume_changes && pa_cvolume_equal(&nc->hw_volume, &s->thread_info.current_hw_volume)) {
+        pa_log_debug("Volume not changing");
+        pa_source_volume_change_free(nc);
+        return;
+    }
+
+    nc->at = pa_source_get_latency_within_thread(s);
+    nc->at += pa_rtclock_now() + s->thread_info.volume_change_extra_delay;
+
+    if (s->thread_info.volume_changes_tail) {
+        for (c = s->thread_info.volume_changes_tail; c; c = c->prev) {
+            /* If volume is going up let's do it a bit late. If it is going
+             * down let's do it a bit early. */
+            if (pa_cvolume_avg(&nc->hw_volume) > pa_cvolume_avg(&c->hw_volume)) {
+                if (nc->at + safety_margin > c->at) {
+                    nc->at += safety_margin;
+                    direction = "up";
+                    break;
+                }
+            }
+            else if (nc->at - safety_margin > c->at) {
+                    nc->at -= safety_margin;
+                    direction = "down";
+                    break;
+            }
+        }
+    }
+
+    if (c == NULL) {
+        if (pa_cvolume_avg(&nc->hw_volume) > pa_cvolume_avg(&s->thread_info.current_hw_volume)) {
+            nc->at += safety_margin;
+            direction = "up";
+        } else {
+            nc->at -= safety_margin;
+            direction = "down";
+        }
+        PA_LLIST_PREPEND(pa_source_volume_change, s->thread_info.volume_changes, nc);
+    }
+    else {
+        PA_LLIST_INSERT_AFTER(pa_source_volume_change, s->thread_info.volume_changes, c, nc);
+    }
+
+    pa_log_debug("Volume going %s to %d at %llu", direction, pa_cvolume_avg(&nc->hw_volume), (long long unsigned) nc->at);
+
+    /* We can ignore volume events that came earlier but should happen later than this. */
+    PA_LLIST_FOREACH(c, nc->next) {
+        pa_log_debug("Volume change to %d at %llu was dropped", pa_cvolume_avg(&c->hw_volume), (long long unsigned) c->at);
+        pa_source_volume_change_free(c);
+    }
+    nc->next = NULL;
+    s->thread_info.volume_changes_tail = nc;
+}
+
+/* Called from the IO thread. */
+static void pa_source_volume_change_flush(pa_source *s) {
+    pa_source_volume_change *c = s->thread_info.volume_changes;
+    pa_assert(s);
+    s->thread_info.volume_changes = NULL;
+    s->thread_info.volume_changes_tail = NULL;
+    while (c) {
+        pa_source_volume_change *next = c->next;
+        pa_source_volume_change_free(c);
+        c = next;
+    }
+}
+
+/* Called from the IO thread. */
+pa_bool_t pa_source_volume_change_apply(pa_source *s, pa_usec_t *usec_to_next) {
+    pa_usec_t now;
+    pa_bool_t ret = FALSE;
+
+    pa_assert(s);
+
+    if (!s->thread_info.volume_changes || !PA_SOURCE_IS_LINKED(s->state)) {
+        if (usec_to_next)
+            *usec_to_next = 0;
+        return ret;
+    }
+
+    pa_assert(s->write_volume);
+
+    now = pa_rtclock_now();
+
+    while (s->thread_info.volume_changes && now >= s->thread_info.volume_changes->at) {
+        pa_source_volume_change *c = s->thread_info.volume_changes;
+        PA_LLIST_REMOVE(pa_source_volume_change, s->thread_info.volume_changes, c);
+        pa_log_debug("Volume change to %d at %llu was written %llu usec late",
+                     pa_cvolume_avg(&c->hw_volume), (long long unsigned) c->at, (long long unsigned) (now - c->at));
+        ret = TRUE;
+        s->thread_info.current_hw_volume = c->hw_volume;
+        pa_source_volume_change_free(c);
+    }
+
+    if (ret)
+        s->write_volume(s);
+
+    if (s->thread_info.volume_changes) {
+        if (usec_to_next)
+            *usec_to_next = s->thread_info.volume_changes->at - now;
+        if (pa_log_ratelimit(PA_LOG_DEBUG))
+            pa_log_debug("Next volume change in %lld usec", (long long) (s->thread_info.volume_changes->at - now));
+    }
+    else {
+        if (usec_to_next)
+            *usec_to_next = 0;
+        s->thread_info.volume_changes_tail = NULL;
+    }
+    return ret;
+}
+
+
+/* Called from the main thread */
+/* Gets the list of formats supported by the source. The members and idxset must
+ * be freed by the caller. */
+pa_idxset* pa_source_get_formats(pa_source *s) {
+    pa_idxset *ret;
+
+    pa_assert(s);
+
+    if (s->get_formats) {
+        /* Source supports format query, all is good */
+        ret = s->get_formats(s);
+    } else {
+        /* Source doesn't support format query, so assume it does PCM */
+        pa_format_info *f = pa_format_info_new();
+        f->encoding = PA_ENCODING_PCM;
+
+        ret = pa_idxset_new(NULL, NULL);
+        pa_idxset_put(ret, f, NULL);
+    }
+
+    return ret;
+}
+
+/* Called from the main thread */
+/* Checks if the source can accept this format */
+pa_bool_t pa_source_check_format(pa_source *s, pa_format_info *f)
+{
+    pa_idxset *formats = NULL;
+    pa_bool_t ret = FALSE;
+
+    pa_assert(s);
+    pa_assert(f);
+
+    formats = pa_source_get_formats(s);
+
+    if (formats) {
+        pa_format_info *finfo_device;
+        uint32_t i;
+
+        PA_IDXSET_FOREACH(finfo_device, formats, i) {
+            if (pa_format_info_is_compatible(finfo_device, f)) {
+                ret = TRUE;
+                break;
+            }
+        }
+
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
+    }
+
+    return ret;
+}
+
+/* Called from the main thread */
+/* Calculates the intersection between formats supported by the source and
+ * in_formats, and returns these, in the order of the source's formats. */
+pa_idxset* pa_source_check_formats(pa_source *s, pa_idxset *in_formats) {
+    pa_idxset *out_formats = pa_idxset_new(NULL, NULL), *source_formats = NULL;
+    pa_format_info *f_source, *f_in;
+    uint32_t i, j;
+
+    pa_assert(s);
+
+    if (!in_formats || pa_idxset_isempty(in_formats))
+        goto done;
+
+    source_formats = pa_source_get_formats(s);
+
+    PA_IDXSET_FOREACH(f_source, source_formats, i) {
+        PA_IDXSET_FOREACH(f_in, in_formats, j) {
+            if (pa_format_info_is_compatible(f_source, f_in))
+                pa_idxset_put(out_formats, pa_format_info_copy(f_in), NULL);
+        }
+    }
+
+done:
+    if (source_formats)
+        pa_idxset_free(source_formats, (pa_free_cb_t) pa_format_info_free);
+
+    return out_formats;
+}
index e3e56bc..022fb7b 100644 (file)
 ***/
 
 typedef struct pa_source pa_source;
+typedef struct pa_source_volume_change pa_source_volume_change;
 
 #include <inttypes.h>
 
+#include <pulse/def.h>
+#include <pulse/format.h>
 #include <pulse/sample.h>
 #include <pulse/channelmap.h>
 #include <pulse/volume.h>
 
 #include <pulsecore/core.h>
 #include <pulsecore/idxset.h>
-#include <pulsecore/memblock.h>
 #include <pulsecore/memchunk.h>
 #include <pulsecore/sink.h>
 #include <pulsecore/module.h>
 #include <pulsecore/asyncmsgq.h>
 #include <pulsecore/msgobject.h>
 #include <pulsecore/rtpoll.h>
-#include <pulsecore/source-output.h>
 #include <pulsecore/card.h>
+#include <pulsecore/device-port.h>
 #include <pulsecore/queue.h>
 #include <pulsecore/thread-mq.h>
+#include <pulsecore/source-output.h>
 
 #define PA_MAX_OUTPUTS_PER_SOURCE 32
 
@@ -52,6 +55,9 @@ static inline pa_bool_t PA_SOURCE_IS_LINKED(pa_source_state_t x) {
     return x == PA_SOURCE_RUNNING || x == PA_SOURCE_IDLE || x == PA_SOURCE_SUSPENDED;
 }
 
+/* A generic definition for void callback functions */
+typedef void(*pa_source_cb_t)(pa_source *s);
+
 struct pa_source {
     pa_msgobject parent;
 
@@ -71,30 +77,44 @@ struct pa_source {
 
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
+    uint32_t default_sample_rate;
+    uint32_t alternate_sample_rate;
 
     pa_idxset *outputs;
     unsigned n_corked;
     pa_sink *monitor_of;                     /* may be NULL */
+    pa_source_output *output_from_master;    /* non-NULL only for filter sources */
 
     pa_volume_t base_volume; /* shall be constant */
     unsigned n_volume_steps; /* shall be constant */
 
-    pa_cvolume volume, soft_volume;
+    /* Also see http://pulseaudio.org/wiki/InternalVolumes */
+    pa_cvolume reference_volume; /* The volume exported and taken as reference base for relative source output volumes */
+    pa_cvolume real_volume;      /* The volume that the hardware is configured to  */
+    pa_cvolume soft_volume;      /* The internal software volume we apply to all PCM data while it passes through */
+
     pa_bool_t muted:1;
 
     pa_bool_t refresh_volume:1;
     pa_bool_t refresh_muted:1;
-
     pa_bool_t save_port:1;
     pa_bool_t save_volume:1;
     pa_bool_t save_muted:1;
 
+    /* Saved volume state while we're in passthrough mode */
+    pa_cvolume saved_volume;
+    pa_bool_t saved_save_volume:1;
+
     pa_asyncmsgq *asyncmsgq;
 
     pa_memchunk silence;
 
     pa_hashmap *ports;
     pa_device_port *active_port;
+    pa_atomic_t mixer_dirty;
+
+    /* The latency offset is inherited from the currently active port */
+    int64_t latency_offset;
 
     unsigned priority;
 
@@ -103,35 +123,71 @@ struct pa_source {
      * inhibited */
     int (*set_state)(pa_source*source, pa_source_state_t state); /* may be NULL */
 
-    /* Callled when the volume is queried. Called from main loop
+    /* Called when the volume is queried. Called from main loop
      * context. If this is NULL a PA_SOURCE_MESSAGE_GET_VOLUME message
      * will be sent to the IO thread instead. If refresh_volume is
-     * FALSE neither this function is called nor a message is sent. */
-    void (*get_volume)(pa_source *s);         /* dito */
+     * FALSE neither this function is called nor a message is sent.
+     *
+     * You must use the function pa_source_set_get_volume_callback() to
+     * set this callback. */
+    pa_source_cb_t get_volume; /* may be NULL */
 
     /* Called when the volume shall be changed. Called from main loop
      * context. If this is NULL a PA_SOURCE_MESSAGE_SET_VOLUME message
-     * will be sent to the IO thread instead. */
-    void (*set_volume)(pa_source *s);         /* dito */
+     * will be sent to the IO thread instead.
+     *
+     * You must use the function pa_source_set_set_volume_callback() to
+     * set this callback. */
+    pa_source_cb_t set_volume; /* may be NULL */
+
+    /* Source drivers that set PA_SOURCE_DEFERRED_VOLUME must provide this
+     * callback. This callback is not used with source that do not set
+     * PA_SOURCE_DEFERRED_VOLUME. This is called from the IO thread when a
+     * pending hardware volume change has to be written to the
+     * hardware. The requested volume is passed to the callback
+     * implementation in s->thread_info.current_hw_volume.
+     *
+     * The call is done inside pa_source_volume_change_apply(), which is
+     * not called automatically - it is the driver's responsibility to
+     * schedule that function to be called at the right times in the
+     * IO thread.
+     *
+     * You must use the function pa_source_set_write_volume_callback() to
+     * set this callback. */
+    pa_source_cb_t write_volume; /* may be NULL */
 
     /* Called when the mute setting is queried. Called from main loop
      * context. If this is NULL a PA_SOURCE_MESSAGE_GET_MUTE message
      * will be sent to the IO thread instead. If refresh_mute is
-     * FALSE neither this function is called nor a message is sent.*/
-    void (*get_mute)(pa_source *s);           /* dito */
+     * FALSE neither this function is called nor a message is sent.
+     *
+     * You must use the function pa_source_set_get_mute_callback() to
+     * set this callback. */
+    pa_source_cb_t get_mute; /* may be NULL */
 
     /* Called when the mute setting shall be changed. Called from main
      * loop context. If this is NULL a PA_SOURCE_MESSAGE_SET_MUTE
-     * message will be sent to the IO thread instead. */
-    void (*set_mute)(pa_source *s);           /* dito */
+     * message will be sent to the IO thread instead.
+     *
+     * You must use the function pa_source_set_set_mute_callback() to
+     * set this callback. */
+    pa_source_cb_t set_mute; /* may be NULL */
 
     /* Called when a the requested latency is changed. Called from IO
      * thread context. */
-    void (*update_requested_latency)(pa_source *s); /* dito */
+    pa_source_cb_t update_requested_latency; /* may be NULL */
+
+    /* Called whenever the port shall be changed. Called from IO
+     * thread if deferred volumes are enabled, and main thread otherwise. */
+    int (*set_port)(pa_source *s, pa_device_port *port); /*ditto */
+
+    /* Called to get the list of formats supported by the source, sorted
+     * in descending order of preference. */
+    pa_idxset* (*get_formats)(pa_source *s); /* ditto */
 
-    /* Called whenever the port shall be changed. Called from main
-     * thread. */
-    int (*set_port)(pa_source *s, pa_device_port *port); /*dito */
+    /* Called whenever the sampling frequency shall be changed. Called from
+     * main thread. */
+    pa_bool_t (*update_rate)(pa_source *s, uint32_t rate);
 
     /* Contains copies of the above data so that the real-time worker
      * thread can work without access locking */
@@ -155,7 +211,29 @@ struct pa_source {
         pa_usec_t max_latency; /* An upper limit for the latencies */
 
         pa_usec_t fixed_latency; /* for sources with PA_SOURCE_DYNAMIC_LATENCY this is 0 */
- } thread_info;
+
+        /* This latency offset is a direct copy from s->latency_offset */
+        int64_t latency_offset;
+
+        /* Delayed volume change events are queued here. The events
+         * are stored in expiration order. The one expiring next is in
+         * the head of the list. */
+        PA_LLIST_HEAD(pa_source_volume_change, volume_changes);
+        pa_source_volume_change *volume_changes_tail;
+        /* This value is updated in pa_source_volume_change_apply() and
+         * used only by sources with PA_SOURCE_DEFERRED_VOLUME. */
+        pa_cvolume current_hw_volume;
+
+        /* The amount of usec volume up events are delayed and volume
+         * down events are made earlier. */
+        uint32_t volume_change_safety_margin;
+        /* Usec delay added to all volume change events, may be negative. */
+        int32_t volume_change_extra_delay;
+} thread_info;
+
+#ifdef __TIZEN__
+    FILE *dump_fp;
+#endif
 
     void *userdata;
 };
@@ -167,7 +245,10 @@ typedef enum pa_source_message {
     PA_SOURCE_MESSAGE_ADD_OUTPUT,
     PA_SOURCE_MESSAGE_REMOVE_OUTPUT,
     PA_SOURCE_MESSAGE_GET_VOLUME,
+    PA_SOURCE_MESSAGE_SET_SHARED_VOLUME,
+    PA_SOURCE_MESSAGE_SET_VOLUME_SYNCED,
     PA_SOURCE_MESSAGE_SET_VOLUME,
+    PA_SOURCE_MESSAGE_SYNC_VOLUMES,
     PA_SOURCE_MESSAGE_GET_MUTE,
     PA_SOURCE_MESSAGE_SET_MUTE,
     PA_SOURCE_MESSAGE_GET_LATENCY,
@@ -181,10 +262,15 @@ typedef enum pa_source_message {
     PA_SOURCE_MESSAGE_GET_FIXED_LATENCY,
     PA_SOURCE_MESSAGE_GET_MAX_REWIND,
     PA_SOURCE_MESSAGE_SET_MAX_REWIND,
+    PA_SOURCE_MESSAGE_SET_PORT,
+    PA_SOURCE_MESSAGE_UPDATE_VOLUME_AND_MUTE,
+    PA_SOURCE_MESSAGE_SET_LATENCY_OFFSET,
     PA_SOURCE_MESSAGE_MAX
 } pa_source_message_t;
 
 typedef struct pa_source_new_data {
+    pa_suspend_cause_t suspend_cause;
+
     char *name;
     pa_proplist *proplist;
 
@@ -197,6 +283,7 @@ typedef struct pa_source_new_data {
 
     pa_sample_spec sample_spec;
     pa_channel_map channel_map;
+    uint32_t alternate_sample_rate;
     pa_cvolume volume;
     pa_bool_t muted:1;
 
@@ -204,6 +291,7 @@ typedef struct pa_source_new_data {
     pa_bool_t muted_is_set:1;
     pa_bool_t sample_spec_is_set:1;
     pa_bool_t channel_map_is_set:1;
+    pa_bool_t alternate_sample_rate_is_set:1;
 
     pa_bool_t namereg_fail:1;
 
@@ -216,6 +304,7 @@ pa_source_new_data* pa_source_new_data_init(pa_source_new_data *data);
 void pa_source_new_data_set_name(pa_source_new_data *data, const char *name);
 void pa_source_new_data_set_sample_spec(pa_source_new_data *data, const pa_sample_spec *spec);
 void pa_source_new_data_set_channel_map(pa_source_new_data *data, const pa_channel_map *map);
+void pa_source_new_data_set_alternate_sample_rate(pa_source_new_data *data, const uint32_t alternate_sample_rate);
 void pa_source_new_data_set_volume(pa_source_new_data *data, const pa_cvolume *volume);
 void pa_source_new_data_set_muted(pa_source_new_data *data, pa_bool_t mute);
 void pa_source_new_data_set_port(pa_source_new_data *data, const char *port);
@@ -228,6 +317,13 @@ pa_source* pa_source_new(
         pa_source_new_data *data,
         pa_source_flags_t flags);
 
+void pa_source_set_get_volume_callback(pa_source *s, pa_source_cb_t cb);
+void pa_source_set_set_volume_callback(pa_source *s, pa_source_cb_t cb);
+void pa_source_set_write_volume_callback(pa_source *s, pa_source_cb_t cb);
+void pa_source_set_get_mute_callback(pa_source *s, pa_source_cb_t cb);
+void pa_source_set_set_mute_callback(pa_source *s, pa_source_cb_t cb);
+void pa_source_enable_decibel_volume(pa_source *s, pa_bool_t enable);
+
 void pa_source_put(pa_source *s);
 void pa_source_unlink(pa_source *s);
 
@@ -252,6 +348,8 @@ void pa_source_update_flags(pa_source *s, pa_source_flags_t mask, pa_source_flag
 
 /*** May be called by everyone, from main context */
 
+void pa_source_set_latency_offset(pa_source *s, int64_t offset);
+
 /* The returned value is supposed to be in the time domain of the sound card! */
 pa_usec_t pa_source_get_latency(pa_source *s);
 pa_usec_t pa_source_get_requested_latency(pa_source *s);
@@ -264,7 +362,20 @@ int pa_source_update_status(pa_source*s);
 int pa_source_suspend(pa_source *s, pa_bool_t suspend, pa_suspend_cause_t cause);
 int pa_source_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause);
 
-void pa_source_set_volume(pa_source *source, const pa_cvolume *volume, pa_bool_t save);
+/* Use this instead of checking s->flags & PA_SOURCE_FLAT_VOLUME directly. */
+pa_bool_t pa_source_flat_volume_enabled(pa_source *s);
+
+/* Get the master source when sharing volumes */
+pa_source *pa_source_get_master(pa_source *s);
+
+/* Is the source in passthrough mode? (that is, is this a monitor source for a sink
+ * that has a passthrough sink input connected to it. */
+pa_bool_t pa_source_is_passthrough(pa_source *s);
+/* These should be called when a source enters/leaves passthrough mode */
+void pa_source_enter_passthrough(pa_source *s);
+void pa_source_leave_passthrough(pa_source *s);
+
+void pa_source_set_volume(pa_source *source, const pa_cvolume *volume, pa_bool_t sendmsg, pa_bool_t save);
 const pa_cvolume *pa_source_get_volume(pa_source *source, pa_bool_t force_refresh);
 
 void pa_source_set_mute(pa_source *source, pa_bool_t mute, pa_bool_t save);
@@ -273,6 +384,9 @@ pa_bool_t pa_source_get_mute(pa_source *source, pa_bool_t force_refresh);
 pa_bool_t pa_source_update_proplist(pa_source *s, pa_update_mode_t mode, pa_proplist *p);
 
 int pa_source_set_port(pa_source *s, const char *name, pa_bool_t save);
+void pa_source_set_mixer_dirty(pa_source *s, pa_bool_t is_dirty);
+
+pa_bool_t pa_source_update_rate(pa_source *s, uint32_t rate, pa_bool_t passthrough);
 
 unsigned pa_source_linked_by(pa_source *s); /* Number of connected streams */
 unsigned pa_source_used_by(pa_source *s); /* Number of connected streams that are not corked */
@@ -284,6 +398,10 @@ pa_queue *pa_source_move_all_start(pa_source *s, pa_queue *q);
 void pa_source_move_all_finish(pa_source *s, pa_queue *q, pa_bool_t save);
 void pa_source_move_all_fail(pa_queue *q);
 
+pa_idxset* pa_source_get_formats(pa_source *s);
+pa_bool_t pa_source_check_format(pa_source *s, pa_format_info *f);
+pa_idxset* pa_source_check_formats(pa_source *s, pa_idxset *in_formats);
+
 /*** To be called exclusively by the source driver, from IO context */
 
 void pa_source_post(pa_source*s, const pa_memchunk *chunk);
@@ -302,6 +420,10 @@ void pa_source_set_max_rewind_within_thread(pa_source *s, size_t max_rewind);
 void pa_source_set_latency_range_within_thread(pa_source *s, pa_usec_t min_latency, pa_usec_t max_latency);
 void pa_source_set_fixed_latency_within_thread(pa_source *s, pa_usec_t latency);
 
+void pa_source_update_volume_and_mute(pa_source *s);
+
+pa_bool_t pa_source_volume_change_apply(pa_source *s, pa_usec_t *usec_to_next);
+
 /*** To be called exclusively by source output drivers, from IO context */
 
 void pa_source_invalidate_requested_latency(pa_source *s, pa_bool_t dynamic);
index 4a70aea..7f55d4e 100644 (file)
 
 #include <pulsecore/core-util.h>
 #include <pulsecore/core-error.h>
+#include <pulsecore/pipe.h>
 
 #include "start-child.h"
 
 int pa_start_child_for_read(const char *name, const char *argv1, pid_t *pid) {
+#ifdef HAVE_FORK
     pid_t child;
     int pipe_fds[2] = { -1, -1 };
 
@@ -107,6 +109,7 @@ int pa_start_child_for_read(const char *name, const char *argv1, pid_t *pid) {
 
 fail:
     pa_close_pipe(pipe_fds);
+#endif /* HAVE_FORK */
 
     return -1;
 }
index 4fc82de..f131d5c 100644 (file)
@@ -146,7 +146,7 @@ void pa_strbuf_putsn(pa_strbuf *sb, const char *t, size_t l) {
     pa_assert(t);
 
     if (!l)
-       return;
+        return;
 
     c = pa_xmalloc(PA_ALIGN(sizeof(struct chunk)) + l);
     c->length = l;
index 0f4ca86..4c06fee 100644 (file)
@@ -49,7 +49,7 @@ pa_strlist* pa_strlist_prepend(pa_strlist *l, const char *s) {
     memcpy(ITEM_TO_TEXT(n), s, size + 1);
     n->next = l;
 
-    return  n;
+    return n;
 }
 
 char *pa_strlist_tostring(pa_strlist *l) {
@@ -74,7 +74,7 @@ pa_strlist* pa_strlist_remove(pa_strlist *l, const char *s) {
     pa_assert(s);
 
     while (l) {
-        if (!strcmp(ITEM_TO_TEXT(l), s)) {
+        if (pa_streq(ITEM_TO_TEXT(l), s)) {
             pa_strlist *n = l->next;
 
             if (!prev) {
index e57203c..0434bde 100644 (file)
@@ -30,7 +30,7 @@ pa_strlist* pa_strlist_prepend(pa_strlist *l, const char *s);
 /* Remove the specified string from the list, return the new linked list head */
 pa_strlist* pa_strlist_remove(pa_strlist *l, const char *s);
 
-/* Make a whitespace separated string of all server stringes. Returned memory has to be freed with pa_xfree() */
+/* Make a whitespace separated string of all server strings. Returned memory has to be freed with pa_xfree() */
 char *pa_strlist_tostring(pa_strlist *l);
 
 /* Free the entire list */
diff --git a/src/pulsecore/svolume.orc b/src/pulsecore/svolume.orc
new file mode 100644 (file)
index 0000000..0edbefb
--- /dev/null
@@ -0,0 +1,84 @@
+#  This file is part of PulseAudio.
+#
+#  Copyright 2010 Lennart Poettering
+#  Copyright 2010 Wim Taymans <wim.taymans@collabora.co.uk>
+#  Copyright 2010 Arun Raghavan <arun.raghavan@collabora.co.uk>
+#
+#  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, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+#  USA.
+
+# S16NE 1- and 2-channel volume scaling work as follows:
+#
+#     params: samples s (signed 16-bit), volume v (signed 32-bit < 2^31)
+#
+#                  32           16                 0 (type of operation)
+#         sample =               |      sample     | (signed)
+#              s = |      0      |      sample     | (unsigned)
+#
+#     if (sample < 0)
+#          signc = |      0      |      0xffff     | (unsigned)
+#     else
+#          signc = |      0      |        0        | (unsigned)
+#
+#     if (sample < 0)
+#             ml = |      0      | -((s*vl) >> 16) | (unsigned)
+#     else
+#             ml = |      0      |   (s*vl) >> 16  | (unsigned)
+#
+#             vh =               |      v >> 16    | (signed, but sign bit is always zero
+#                                                     since PA_VOLUME_MAX is 0x0fffffff)
+#             mh = |         (s * vh) >> 16        | (signed)
+#             ml = |           ml + mh             | (signed)
+#         sample =               |    (ml >> 16)   | (signed, saturated)
+
+.function pa_volume_s16ne_orc_1ch
+.dest 2 samples int16_t
+.param 4 v int32_t
+.temp 2 vh
+.temp 4 s
+.temp 4 mh
+.temp 4 ml
+.temp 4 signc
+
+convuwl s, samples
+x2 cmpgtsw signc, 0, s
+x2 andw signc, signc, v
+x2 mulhuw ml, s, v
+subl ml, ml, signc
+convhlw vh, v
+mulswl mh, samples, vh
+addl ml, ml, mh
+convssslw samples, ml
+
+.function pa_volume_s16ne_orc_2ch
+.dest 4 samples int16_t
+.longparam 8 vols
+.temp 8 v
+.temp 4 vh
+.temp 8 s
+.temp 8 mh
+.temp 8 ml
+.temp 8 signc
+
+loadpq v, vols
+x2 convuwl s, samples
+x4 cmpgtsw signc, 0, s
+x4 andw signc, signc, v
+x4 mulhuw ml, s, v
+x2 subl ml, ml, signc
+x2 convhlw vh, v
+x2 mulswl mh, samples, vh
+x2 addl ml, ml, mh
+x2 convssslw samples, ml
index 5bd1448..f325d77 100644 (file)
 #include <config.h>
 #endif
 
-#include <pulse/timeval.h>
 #include <pulsecore/random.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/g711.h>
-#include <pulsecore/core-util.h>
+#include <pulsecore/endianmacros.h>
 
 #include "cpu-arm.h"
 
 #include "sample-util.h"
-#include "endianmacros.h"
 
-#if defined (__arm__)
+#if defined (__arm__) && defined (HAVE_ARMV6)
 
 #define MOD_INC() \
     " subs  r0, r6, %2              \n\t" \
+    " itt cs                        \n\t" \
     " addcs r0, %1                  \n\t" \
     " movcs r6, r0                  \n\t"
 
-static void
-pa_volume_s16ne_arm (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
-    int32_t *ve;
+static pa_do_volume_func_t _volume_ref;
 
-    channels = PA_MAX (4U, channels);
-    ve = volumes + channels;
+static void pa_volume_s16ne_arm(int16_t *samples, const int32_t *volumes, unsigned channels, unsigned length) {
+    /* Channels must be at least 4, and always a multiple of the original number.
+     * This is also the max amount we overread the volume array, which should
+     * have enough padding. */
+    const int32_t *ve = volumes + (channels == 3 ? 6 : PA_MAX (4U, channels));
+    unsigned rem = PA_ALIGN((size_t) samples) - (size_t) samples;
+
+    /* Make sure we're word-aligned, else performance _really_ sucks */
+    if (rem) {
+        _volume_ref(samples, volumes, channels, rem < length ? rem : length);
+
+        if (rem < length) {
+            length -= rem;
+            samples += rem / sizeof(*samples);
+        } else
+            return; /* we're done */
+    }
 
     __asm__ __volatile__ (
-        " mov r6, %1                      \n\t"
+        " mov r6, %4                      \n\t" /* r6 = volumes + rem */
         " mov %3, %3, LSR #1              \n\t" /* length /= sizeof (int16_t) */
-        " tst %3, #1                      \n\t" /* check for odd samples */
-        " beq  2f                         \n\t"
+
+        " cmp %3, #4                      \n\t" /* check for 4+ samples */
+        " blt 2f                          \n\t"
+
+        /* See final case for how the multiplication works */
 
         "1:                               \n\t"
-        " ldr  r0, [r6], #4               \n\t" /* odd samples volumes */
-        " ldrh r2, [%0]                   \n\t"
+        " ldrd r2, [r6], #8               \n\t" /* 4 samples at a time */
+        " ldrd r4, [r6], #8               \n\t"
+        " ldrd r0, [%0]                   \n\t"
 
-        " smulwb r0, r0, r2               \n\t"
-        " ssat r0, #16, r0                \n\t"
+#ifdef WORDS_BIGENDIAN
+        " smulwt r2, r2, r0               \n\t"
+        " smulwb r3, r3, r0               \n\t"
+        " smulwt r4, r4, r1               \n\t"
+        " smulwb r5, r5, r1               \n\t"
+#else
+        " smulwb r2, r2, r0               \n\t"
+        " smulwt r3, r3, r0               \n\t"
+        " smulwb r4, r4, r1               \n\t"
+        " smulwt r5, r5, r1               \n\t"
+#endif
 
-        " strh r0, [%0], #2               \n\t"
+        " ssat r2, #16, r2                \n\t"
+        " ssat r3, #16, r3                \n\t"
+        " ssat r4, #16, r4                \n\t"
+        " ssat r5, #16, r5                \n\t"
+
+#ifdef WORDS_BIGENDIAN
+        " pkhbt r0, r3, r2, LSL #16       \n\t"
+        " pkhbt r1, r5, r4, LSL #16       \n\t"
+#else
+        " pkhbt r0, r2, r3, LSL #16       \n\t"
+        " pkhbt r1, r4, r5, LSL #16       \n\t"
+#endif
+        " strd  r0, [%0], #8              \n\t"
 
         MOD_INC()
 
+        " subs %3, %3, #4                 \n\t"
+        " cmp %3, #4                      \n\t"
+        " bge 1b                          \n\t"
+
         "2:                               \n\t"
-        " mov %3, %3, LSR #1              \n\t"
-        " tst %3, #1                      \n\t" /* check for odd samples */
-        " beq  4f                         \n\t"
+        " cmp %3, #2                      \n\t"
+        " blt 3f                          \n\t"
 
-        "3:                               \n\t"
-        " ldrd r2, [r6], #8               \n\t" /* 2 samples at a time */
+        " ldrd r2, [r6], #8               \n\t" /* 2  samples at a time */
         " ldr  r0, [%0]                   \n\t"
 
+#ifdef WORDS_BIGENDIAN
         " smulwt r2, r2, r0               \n\t"
         " smulwb r3, r3, r0               \n\t"
+#else
+        " smulwb r2, r2, r0               \n\t"
+        " smulwt r3, r3, r0               \n\t"
+#endif
 
         " ssat r2, #16, r2                \n\t"
         " ssat r3, #16, r3                \n\t"
 
+#ifdef WORDS_BIGENDIAN
         " pkhbt r0, r3, r2, LSL #16       \n\t"
+#else
+        " pkhbt r0, r2, r3, LSL #16       \n\t"
+#endif
         " str  r0, [%0], #4               \n\t"
 
         MOD_INC()
 
-        "4:                               \n\t"
-        " movs %3, %3, LSR #1             \n\t"
-        " beq  6f                         \n\t"
+        " subs %3, %3, #2                 \n\t"
 
-        "5:                               \n\t"
-        " ldrd r2, [r6], #8               \n\t" /* 4 samples at a time */
-        " ldrd r4, [r6], #8               \n\t"
-        " ldrd r0, [%0]                   \n\t"
+        "3:                               \n\t" /* check for odd # of samples */
+        " cmp %3, #1                      \n\t"
+        " bne 4f                          \n\t"
 
-        " smulwt r2, r2, r0               \n\t"
-        " smulwb r3, r3, r0               \n\t"
-        " smulwt r4, r4, r1               \n\t"
-        " smulwb r5, r5, r1               \n\t"
+        " ldr  r0, [r6], #4               \n\t" /* r0 = volume */
+        " ldrh r2, [%0]                   \n\t" /* r2 = sample */
 
-        " ssat r2, #16, r2                \n\t"
-        " ssat r3, #16, r3                \n\t"
-        " ssat r4, #16, r4                \n\t"
-        " ssat r5, #16, r5                \n\t"
-
-        " pkhbt r0, r3, r2, LSL #16       \n\t"
-        " pkhbt r1, r5, r4, LSL #16       \n\t"
-        " strd  r0, [%0], #8              \n\t"
+        " smulwb r0, r0, r2               \n\t" /* r0 = (r0 * r2) >> 16 */
+        " ssat r0, #16, r0                \n\t" /* r0 = PA_CLAMP(r0, 0x7FFF) */
 
-        MOD_INC()
+        " strh r0, [%0], #2               \n\t" /* sample = r0 */
 
-        " subs %3, %3, #1                 \n\t"
-        " bne 5b                          \n\t"
-        "6:                               \n\t"
+        "4:                               \n\t"
 
         : "+r" (samples), "+r" (volumes), "+r" (ve), "+r" (length)
-        :
+        : "r" (volumes + ((rem / sizeof(*samples)) % channels))
         : "r6", "r5", "r4", "r3", "r2", "r1", "r0", "cc"
     );
 }
 
-#undef RUN_TEST
-
-#ifdef RUN_TEST
-#define CHANNELS 2
-#define SAMPLES 1023
-#define TIMES 1000
-#define PADDING 16
-
-static void run_test (void) {
-    int16_t samples[SAMPLES];
-    int16_t samples_ref[SAMPLES];
-    int16_t samples_orig[SAMPLES];
-    int32_t volumes[CHANNELS + PADDING];
-    int i, j, padding;
-    pa_do_volume_func_t func;
-    pa_usec_t start, stop;
-
-    func = pa_get_volume_func (PA_SAMPLE_S16NE);
-
-    printf ("checking ARM %zd\n", sizeof (samples));
-
-    pa_random (samples, sizeof (samples));
-    memcpy (samples_ref, samples, sizeof (samples));
-    memcpy (samples_orig, samples, sizeof (samples));
-
-    for (i = 0; i < CHANNELS; i++)
-        volumes[i] = rand() >> 1;
-    for (padding = 0; padding < PADDING; padding++, i++)
-        volumes[i] = volumes[padding];
-
-    func (samples_ref, volumes, CHANNELS, sizeof (samples));
-    pa_volume_s16ne_arm (samples, volumes, CHANNELS, sizeof (samples));
-    for (i = 0; i < SAMPLES; i++) {
-        if (samples[i] != samples_ref[i]) {
-            printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i],
-                  samples_orig[i], volumes[i % CHANNELS]);
-        }
-    }
+#endif /* defined (__arm__) && defined (HAVE_ARMV6) */
 
-    start = pa_rtclock_now();
-    for (j = 0; j < TIMES; j++) {
-        memcpy (samples, samples_orig, sizeof (samples));
-        pa_volume_s16ne_arm (samples, volumes, CHANNELS, sizeof (samples));
-    }
-    stop = pa_rtclock_now();
-    pa_log_info("ARM: %llu usec.", (long long unsigned int) (stop - start));
+void pa_volume_func_init_arm(pa_cpu_arm_flag_t flags) {
+#if defined (__arm__) && defined (HAVE_ARMV6)
+    pa_log_info("Initialising ARM optimized volume functions.");
 
-    start = pa_rtclock_now();
-    for (j = 0; j < TIMES; j++) {
-        memcpy (samples_ref, samples_orig, sizeof (samples));
-        func (samples_ref, volumes, CHANNELS, sizeof (samples));
-    }
-    stop = pa_rtclock_now();
-    pa_log_info("ref: %llu usec.", (long long unsigned int) (stop - start));
-}
-#endif
-
-#endif /* defined (__arm__) */
-
-
-void pa_volume_func_init_arm (pa_cpu_arm_flag_t flags) {
-#if defined (__arm__)
-    pa_log_info("Initialising ARM optimized functions.");
-
-#ifdef RUN_TEST
-    run_test ();
-#endif
+    if (!_volume_ref)
+        _volume_ref = pa_get_volume_func(PA_SAMPLE_S16NE);
 
-    pa_set_volume_func (PA_SAMPLE_S16NE,     (pa_do_volume_func_t) pa_volume_s16ne_arm);
-#endif /* defined (__arm__) */
+    pa_set_volume_func(PA_SAMPLE_S16NE, (pa_do_volume_func_t) pa_volume_s16ne_arm);
+#endif /* defined (__arm__) && defined (HAVE_ARMV6) */
 }
index 5fc052b..43b953c 100644 (file)
 #include <config.h>
 #endif
 
-
 #include <pulsecore/macro.h>
 #include <pulsecore/g711.h>
-#include <pulsecore/core-util.h>
+#include <pulsecore/endianmacros.h>
 
 #include "sample-util.h"
-#include "endianmacros.h"
 
-static void
-pa_volume_u8_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
+static void pa_volume_u8_c(uint8_t *samples, const int32_t *volumes, unsigned channels, unsigned length) {
     unsigned channel;
 
     for (channel = 0; length; length--) {
-        int32_t t, hi, lo;
-
-        hi = volumes[channel] >> 16;
-        lo = volumes[channel] & 0xFFFF;
+        int32_t t = pa_mult_s16_volume(*samples - 0x80, volumes[channel]);
 
-        t = (int32_t) *samples - 0x80;
-        t = ((t * lo) >> 16) + (t * hi);
         t = PA_CLAMP_UNLIKELY(t, -0x80, 0x7F);
         *samples++ = (uint8_t) (t + 0x80);
 
@@ -53,19 +44,12 @@ pa_volume_u8_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned
     }
 }
 
-static void
-pa_volume_alaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
+static void pa_volume_alaw_c(uint8_t *samples, const int32_t *volumes, unsigned channels, unsigned length) {
     unsigned channel;
 
     for (channel = 0; length; length--) {
-        int32_t t, hi, lo;
+        int32_t t = pa_mult_s16_volume(st_alaw2linear16(*samples), volumes[channel]);
 
-        hi = volumes[channel] >> 16;
-        lo = volumes[channel] & 0xFFFF;
-
-        t = (int32_t) st_alaw2linear16(*samples);
-        t = ((t * lo) >> 16) + (t * hi);
         t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
         *samples++ = (uint8_t) st_13linear2alaw((int16_t) t >> 3);
 
@@ -74,19 +58,12 @@ pa_volume_alaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigne
     }
 }
 
-static void
-pa_volume_ulaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
+static void pa_volume_ulaw_c(uint8_t *samples, const int32_t *volumes, unsigned channels, unsigned length) {
     unsigned channel;
 
     for (channel = 0; length; length--) {
-        int32_t t, hi, lo;
-
-        hi = volumes[channel] >> 16;
-        lo = volumes[channel] & 0xFFFF;
+        int32_t t = pa_mult_s16_volume(st_ulaw2linear16(*samples), volumes[channel]);
 
-        t = (int32_t) st_ulaw2linear16(*samples);
-        t = ((t * lo) >> 16) + (t * hi);
         t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
         *samples++ = (uint8_t) st_14linear2ulaw((int16_t) t >> 2);
 
@@ -95,27 +72,14 @@ pa_volume_ulaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigne
     }
 }
 
-static void
-pa_volume_s16ne_c (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
+static void pa_volume_s16ne_c(int16_t *samples, const int32_t *volumes, unsigned channels, unsigned length) {
     unsigned channel;
 
-    length /= sizeof (int16_t);
+    length /= sizeof(int16_t);
 
     for (channel = 0; length; length--) {
-        int32_t t, hi, lo;
+        int32_t t = pa_mult_s16_volume(*samples, volumes[channel]);
 
-        /* Multiplying the 32bit volume factor with the 16bit
-         * sample might result in an 48bit value. We want to
-         * do without 64 bit integers and hence do the
-         * multiplication independantly for the HI and LO part
-         * of the volume. */
-
-        hi = volumes[channel] >> 16;
-        lo = volumes[channel] & 0xFFFF;
-
-        t = (int32_t)(*samples);
-        t = ((t * lo) >> 16) + (t * hi);
         t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
         *samples++ = (int16_t) t;
 
@@ -124,21 +88,14 @@ pa_volume_s16ne_c (int16_t *samples, int32_t *volumes, unsigned channels, unsign
     }
 }
 
-static void
-pa_volume_s16re_c (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
+static void pa_volume_s16re_c(int16_t *samples, const int32_t *volumes, unsigned channels, unsigned length) {
     unsigned channel;
 
-    length /= sizeof (int16_t);
+    length /= sizeof(int16_t);
 
     for (channel = 0; length; length--) {
-        int32_t t, hi, lo;
-
-        hi = volumes[channel] >> 16;
-        lo = volumes[channel] & 0xFFFF;
+        int32_t t = pa_mult_s16_volume(PA_INT16_SWAP(*samples), volumes[channel]);
 
-        t = (int32_t) PA_INT16_SWAP(*samples);
-        t = ((t * lo) >> 16) + (t * hi);
         t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
         *samples++ = PA_INT16_SWAP((int16_t) t);
 
@@ -147,12 +104,10 @@ pa_volume_s16re_c (int16_t *samples, int32_t *volumes, unsigned channels, unsign
     }
 }
 
-static void
-pa_volume_float32ne_c (float *samples, float *volumes, unsigned channels, unsigned length)
-{
+static void pa_volume_float32ne_c(float *samples, const float *volumes, unsigned channels, unsigned length) {
     unsigned channel;
 
-    length /= sizeof (float);
+    length /= sizeof(float);
 
     for (channel = 0; length; length--) {
         *samples++ *= volumes[channel];
@@ -162,12 +117,10 @@ pa_volume_float32ne_c (float *samples, float *volumes, unsigned channels, unsign
     }
 }
 
-static void
-pa_volume_float32re_c (float *samples, float *volumes, unsigned channels, unsigned length)
-{
+static void pa_volume_float32re_c(float *samples, float *volumes, unsigned channels, unsigned length) {
     unsigned channel;
 
-    length /= sizeof (float);
+    length /= sizeof(float);
 
     for (channel = 0; length; length--) {
         float t;
@@ -181,12 +134,10 @@ pa_volume_float32re_c (float *samples, float *volumes, unsigned channels, unsign
     }
 }
 
-static void
-pa_volume_s32ne_c (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
+static void pa_volume_s32ne_c(int32_t *samples, const int32_t *volumes, unsigned channels, unsigned length) {
     unsigned channel;
 
-    length /= sizeof (int32_t);
+    length /= sizeof(int32_t);
 
     for (channel = 0; length; length--) {
         int64_t t;
@@ -201,12 +152,10 @@ pa_volume_s32ne_c (int32_t *samples, int32_t *volumes, unsigned channels, unsign
     }
 }
 
-static void
-pa_volume_s32re_c (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
+static void pa_volume_s32re_c(int32_t *samples, const int32_t *volumes, unsigned channels, unsigned length) {
     unsigned channel;
 
-    length /= sizeof (int32_t);
+    length /= sizeof(int32_t);
 
     for (channel = 0; length; length--) {
         int64_t t;
@@ -221,9 +170,7 @@ pa_volume_s32re_c (int32_t *samples, int32_t *volumes, unsigned channels, unsign
     }
 }
 
-static void
-pa_volume_s24ne_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
+static void pa_volume_s24ne_c(uint8_t *samples, const int32_t *volumes, unsigned channels, unsigned length) {
     unsigned channel;
     uint8_t *e;
 
@@ -242,9 +189,7 @@ pa_volume_s24ne_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsign
     }
 }
 
-static void
-pa_volume_s24re_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
+static void pa_volume_s24re_c(uint8_t *samples, const int32_t *volumes, unsigned channels, unsigned length) {
     unsigned channel;
     uint8_t *e;
 
@@ -263,12 +208,10 @@ pa_volume_s24re_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsign
     }
 }
 
-static void
-pa_volume_s24_32ne_c (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
+static void pa_volume_s24_32ne_c(uint32_t *samples, const int32_t *volumes, unsigned channels, unsigned length) {
     unsigned channel;
 
-    length /= sizeof (uint32_t);
+    length /= sizeof(uint32_t);
 
     for (channel = 0; length; length--) {
         int64_t t;
@@ -283,12 +226,10 @@ pa_volume_s24_32ne_c (uint32_t *samples, int32_t *volumes, unsigned channels, un
     }
 }
 
-static void
-pa_volume_s24_32re_c (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
+static void pa_volume_s24_32re_c(uint32_t *samples, const int32_t *volumes, unsigned channels, unsigned length) {
     unsigned channel;
 
-    length /= sizeof (uint32_t);
+    length /= sizeof(uint32_t);
 
     for (channel = 0; length; length--) {
         int64_t t;
@@ -303,8 +244,7 @@ pa_volume_s24_32re_c (uint32_t *samples, int32_t *volumes, unsigned channels, un
     }
 }
 
-static pa_do_volume_func_t do_volume_table[] =
-{
+static pa_do_volume_func_t do_volume_table[] = {
     [PA_SAMPLE_U8]        = (pa_do_volume_func_t) pa_volume_u8_c,
     [PA_SAMPLE_ALAW]      = (pa_do_volume_func_t) pa_volume_alaw_c,
     [PA_SAMPLE_ULAW]      = (pa_do_volume_func_t) pa_volume_ulaw_c,
index 46923ed..d68a105 100644 (file)
 #include <config.h>
 #endif
 
-#include <pulse/timeval.h>
+#include <pulse/rtclock.h>
+
 #include <pulsecore/random.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/g711.h>
-#include <pulsecore/core-util.h>
+#include <pulsecore/endianmacros.h>
 
 #include "cpu-x86.h"
 
 #include "sample-util.h"
-#include "endianmacros.h"
 
 #if defined (__i386__) || defined (__amd64__)
 /* in s: 2 int16_t samples
@@ -41,7 +40,7 @@
  * out s: contains scaled and clamped int16_t samples.
  *
  * We calculate the high 32 bits of a 32x16 multiply which we then
- * clamp to 16 bits. The calulcation is:
+ * clamp to 16 bits. The calculation is:
  *
  *  vl = (v & 0xffff)
  *  vh = (v >> 16)
       " por %%mm4, "#s1"             \n\t" /* .. |  l  h |  */ \
       " por %%mm5, "#s2"             \n\t"
 
-static void
-pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
+static void pa_volume_s16ne_mmx(int16_t *samples, const int32_t *volumes, unsigned channels, unsigned length) {
     pa_reg_x86 channel, temp;
 
-    /* the max number of samples we process at a time, this is also the max amount
-     * we overread the volume array, which should have enough padding. */
-    channels = PA_MAX (4U, channels);
+    /* Channels must be at least 4, and always a multiple of the original number.
+     * This is also the max amount we overread the volume array, which should
+     * have enough padding. */
+    channels = channels == 3 ? 6 : PA_MAX (4U, channels);
 
     __asm__ __volatile__ (
         " xor %3, %3                    \n\t"
@@ -109,7 +107,7 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
         " test $1, %2                   \n\t" /* check for odd samples */
         " je 2f                         \n\t"
 
-        " movd (%1, %3, 4), %%mm0       \n\t" /* |  v0h  |  v0l  | */
+        " movd (%q1, %3, 4), %%mm0      \n\t" /* |  v0h  |  v0l  | */
         " movw (%0), %w4                \n\t" /*     ..  |  p0   | */
         " movd %4, %%mm1                \n\t"
         VOLUME_32x16 (%%mm1, %%mm0)
@@ -124,7 +122,7 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
         " je 4f                         \n\t"
 
         "3:                             \n\t" /* do samples in groups of 2 */
-        " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
+        " movq (%q1, %3, 4), %%mm0      \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
         " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */
         VOLUME_32x16 (%%mm1, %%mm0)
         " movd %%mm0, (%0)              \n\t" /*              .. | p1*v1 | p0*v0 | */
@@ -137,8 +135,8 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
         " je 6f                         \n\t"
 
         "5:                             \n\t" /* do samples in groups of 4 */
-        " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
-        " movq 8(%1, %3, 4), %%mm2      \n\t" /* |  v3h  |  v3l  |  v2h  |  v2l  | */
+        " movq (%q1, %3, 4), %%mm0      \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
+        " movq 8(%q1, %3, 4), %%mm2     \n\t" /* |  v3h  |  v3l  |  v2h  |  v2l  | */
         " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */
         " movd 4(%0), %%mm3             \n\t" /*              .. |   p3  |  p2   | */
         VOLUME_32x16 (%%mm1, %%mm0)
@@ -153,20 +151,23 @@ pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
         "6:                             \n\t"
         " emms                          \n\t"
 
-        : "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((pa_reg_x86)channel), "=&r" (temp)
-        : "rm" ((pa_reg_x86)channels)
+        : "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
+#if defined (__i386__)
+        : "m" (channels)
+#else
+        : "r" ((pa_reg_x86)channels)
+#endif
         : "cc"
     );
 }
 
-static void
-pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
+static void pa_volume_s16re_mmx(int16_t *samples, const int32_t *volumes, unsigned channels, unsigned length) {
     pa_reg_x86 channel, temp;
 
-    /* the max number of samples we process at a time, this is also the max amount
-     * we overread the volume array, which should have enough padding. */
-    channels = PA_MAX (4U, channels);
+    /* Channels must be at least 4, and always a multiple of the original number.
+     * This is also the max amount we overread the volume array, which should
+     * have enough padding. */
+    channels = channels == 3 ? 6 : PA_MAX (4U, channels);
 
     __asm__ __volatile__ (
         " xor %3, %3                    \n\t"
@@ -179,7 +180,7 @@ pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
         " test $1, %2                   \n\t" /* check for odd samples */
         " je 2f                         \n\t"
 
-        " movd (%1, %3, 4), %%mm0       \n\t" /* |  v0h  |  v0l  | */
+        " movd (%q1, %3, 4), %%mm0      \n\t" /* |  v0h  |  v0l  | */
         " movw (%0), %w4                \n\t" /*     ..  |  p0   | */
         " rorw $8, %w4                  \n\t"
         " movd %4, %%mm1                \n\t"
@@ -196,7 +197,7 @@ pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
         " je 4f                         \n\t"
 
         "3:                             \n\t" /* do samples in groups of 2 */
-        " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
+        " movq (%q1, %3, 4), %%mm0      \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
         " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */
         SWAP_16 (%%mm1)
         VOLUME_32x16 (%%mm1, %%mm0)
@@ -211,8 +212,8 @@ pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
         " je 6f                         \n\t"
 
         "5:                             \n\t" /* do samples in groups of 4 */
-        " movq (%1, %3, 4), %%mm0       \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
-        " movq 8(%1, %3, 4), %%mm2      \n\t" /* |  v3h  |  v3l  |  v2h  |  v2l  | */
+        " movq (%q1, %3, 4), %%mm0      \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
+        " movq 8(%q1, %3, 4), %%mm2     \n\t" /* |  v3h  |  v3l  |  v2h  |  v2l  | */
         " movd (%0), %%mm1              \n\t" /*              .. |   p1  |  p0   | */
         " movd 4(%0), %%mm3             \n\t" /*              .. |   p3  |  p2   | */
         SWAP_16_2 (%%mm1, %%mm3)
@@ -229,87 +230,25 @@ pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsi
         "6:                             \n\t"
         " emms                          \n\t"
 
-        : "+r" (samples), "+r" (volumes), "+r" (length), "=D" ((pa_reg_x86)channel), "=&r" (temp)
-        : "rm" ((pa_reg_x86)channels)
+        : "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
+#if defined (__i386__)
+        : "m" (channels)
+#else
+        : "r" ((pa_reg_x86)channels)
+#endif
         : "cc"
     );
 }
 
-#undef RUN_TEST
-
-#ifdef RUN_TEST
-#define CHANNELS 2
-#define SAMPLES 1021
-#define TIMES 1000
-#define PADDING 16
-
-static void run_test (void) {
-    int16_t samples[SAMPLES];
-    int16_t samples_ref[SAMPLES];
-    int16_t samples_orig[SAMPLES];
-    int32_t volumes[CHANNELS + PADDING];
-    int i, j, padding;
-    pa_do_volume_func_t func;
-    pa_usec_t start, stop;
-
-    func = pa_get_volume_func (PA_SAMPLE_S16NE);
-
-    printf ("checking MMX %zd\n", sizeof (samples));
-
-    pa_random (samples, sizeof (samples));
-    /* for (i = 0; i < SAMPLES; i++)
-       samples[i] = -1; */
-    memcpy (samples_ref, samples, sizeof (samples));
-    memcpy (samples_orig, samples, sizeof (samples));
-
-    for (i = 0; i < CHANNELS; i++)
-        volumes[i] = rand() >> 1;
-        /* volumes[i] = 0x0000ffff; */
-    for (padding = 0; padding < PADDING; padding++, i++)
-        volumes[i] = volumes[padding];
-
-    func (samples_ref, volumes, CHANNELS, sizeof (samples));
-    pa_volume_s16ne_mmx (samples, volumes, CHANNELS, sizeof (samples));
-    for (i = 0; i < SAMPLES; i++) {
-        if (samples[i] != samples_ref[i]) {
-            printf ("%d: %04x != %04x (%04x * %08x)\n", i, samples[i], samples_ref[i],
-                  samples_orig[i], volumes[i % CHANNELS]);
-        }
-    }
-
-    start = pa_rtclock_now();
-    for (j = 0; j < TIMES; j++) {
-        memcpy (samples, samples_orig, sizeof (samples));
-        pa_volume_s16ne_mmx (samples, volumes, CHANNELS, sizeof (samples));
-    }
-    stop = pa_rtclock_now();
-    pa_log_info("MMX: %llu usec.", (long long unsigned int)(stop - start));
-
-    start = pa_rtclock_now();
-    for (j = 0; j < TIMES; j++) {
-        memcpy (samples_ref, samples_orig, sizeof (samples));
-        func (samples_ref, volumes, CHANNELS, sizeof (samples));
-    }
-    stop = pa_rtclock_now();
-    pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start));
-}
-#endif
-
 #endif /* defined (__i386__) || defined (__amd64__) */
 
-
-void pa_volume_func_init_mmx (pa_cpu_x86_flag_t flags) {
+void pa_volume_func_init_mmx(pa_cpu_x86_flag_t flags) {
 #if defined (__i386__) || defined (__amd64__)
+    if ((flags & PA_CPU_X86_MMX) && (flags & PA_CPU_X86_CMOV)) {
+        pa_log_info("Initialising MMX optimized volume functions.");
 
-#ifdef RUN_TEST
-    run_test ();
-#endif
-
-    if (flags & PA_CPU_X86_MMX) {
-        pa_log_info("Initialising MMX optimized functions.");
-
-        pa_set_volume_func (PA_SAMPLE_S16NE, (pa_do_volume_func_t) pa_volume_s16ne_mmx);
-        pa_set_volume_func (PA_SAMPLE_S16RE, (pa_do_volume_func_t) pa_volume_s16re_mmx);
+        pa_set_volume_func(PA_SAMPLE_S16NE, (pa_do_volume_func_t) pa_volume_s16ne_mmx);
+        pa_set_volume_func(PA_SAMPLE_S16RE, (pa_do_volume_func_t) pa_volume_s16re_mmx);
     }
 #endif /* defined (__i386__) || defined (__amd64__) */
 }
diff --git a/src/pulsecore/svolume_orc.c b/src/pulsecore/svolume_orc.c
new file mode 100644 (file)
index 0000000..37e6bf8
--- /dev/null
@@ -0,0 +1,53 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2004-2006 Lennart Poettering
+  Copyright 2009 Wim Taymans <wim.taymans@collabora.co.uk>
+  Copyright 2010 Arun Raghavan <arun.raghavan@collabora.co.uk>
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "cpu-orc.h"
+#include <pulse/rtclock.h>
+#include <pulsecore/sample-util.h>
+#include <pulsecore/random.h>
+#include <pulsecore/svolume-orc-gen.h>
+
+pa_do_volume_func_t fallback;
+
+static void
+pa_volume_s16ne_orc(int16_t *samples, const int32_t *volumes, unsigned channels, unsigned length)
+{
+    if (channels == 2) {
+        int64_t v = (int64_t)volumes[1] << 32 | volumes[0];
+        pa_volume_s16ne_orc_2ch (samples, v, ((length / (sizeof(int16_t))) / 2));
+    } else if (channels == 1)
+        pa_volume_s16ne_orc_1ch (samples, volumes[0], length / (sizeof(int16_t)));
+    else
+        fallback(samples, volumes, channels, length);
+}
+
+void pa_volume_func_init_orc(void) {
+    pa_log_info("Initialising ORC optimized volume functions.");
+
+    fallback = pa_get_volume_func(PA_SAMPLE_S16NE);
+    pa_set_volume_func(PA_SAMPLE_S16NE, (pa_do_volume_func_t) pa_volume_s16ne_orc);
+}
index 1cc4e0a..daa87ca 100644 (file)
 #include <config.h>
 #endif
 
-#include <pulse/timeval.h>
+#include <pulse/rtclock.h>
+
 #include <pulsecore/random.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/g711.h>
-#include <pulsecore/core-util.h>
+#include <pulsecore/endianmacros.h>
 
 #include "cpu-x86.h"
 
 #include "sample-util.h"
-#include "endianmacros.h"
 
 #if defined (__i386__) || defined (__amd64__)
 
       " por %%xmm4, "#s1"            \n\t" /* .. |  l  h |  */ \
       " por %%xmm5, "#s2"            \n\t"
 
-static void
-pa_volume_s16ne_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
+
+static int channel_overread_table[8] = {8,8,8,12,8,10,12,14};
+
+static void pa_volume_s16ne_sse2(int16_t *samples, const int32_t *volumes, unsigned channels, unsigned length) {
     pa_reg_x86 channel, temp;
 
-    /* the max number of samples we process at a time, this is also the max amount
-     * we overread the volume array, which should have enough padding. */
-    channels = PA_MAX (8U, channels);
+    /* Channels must be at least 8 and always a multiple of the original number.
+     * This is also the max amount we overread the volume array, which should
+     * have enough padding. */
+    if (channels < 8)
+        channels = channel_overread_table[channels];
 
     __asm__ __volatile__ (
         " xor %3, %3                    \n\t"
@@ -90,7 +92,7 @@ pa_volume_s16ne_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, uns
         " test $1, %2                   \n\t" /* check for odd samples */
         " je 2f                         \n\t"
 
-        " movd (%1, %3, 4), %%xmm0      \n\t" /* |  v0h  |  v0l  | */
+        " movd (%q1, %3, 4), %%xmm0     \n\t" /* |  v0h  |  v0l  | */
         " movw (%0), %w4                \n\t" /*     ..  |   p0  | */
         " movd %4, %%xmm1               \n\t"
         VOLUME_32x16 (%%xmm1, %%xmm0)
@@ -105,7 +107,7 @@ pa_volume_s16ne_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, uns
         " je 4f                         \n\t"
 
         "3:                             \n\t" /* do samples in groups of 2 */
-        " movq (%1, %3, 4), %%xmm0      \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
+        " movq (%q1, %3, 4), %%xmm0     \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
         " movd (%0), %%xmm1             \n\t" /*              .. |   p1  |  p0   | */
         VOLUME_32x16 (%%xmm1, %%xmm0)
         " movd %%xmm0, (%0)             \n\t" /*              .. | p1*v1 | p0*v0 | */
@@ -121,7 +123,7 @@ pa_volume_s16ne_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, uns
          * that the array is 16 bytes aligned, we probably have to do the odd values
          * after this then. */
         "5:                             \n\t" /* do samples in groups of 4 */
-        " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
+        " movdqu (%q1, %3, 4), %%xmm0   \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
         " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */
         VOLUME_32x16 (%%xmm1, %%xmm0)
         " movq %%xmm0, (%0)             \n\t" /*              .. | p3*v3 .. p0*v0 | */
@@ -134,8 +136,8 @@ pa_volume_s16ne_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, uns
         " je 8f                         \n\t"
 
         "7:                             \n\t" /* do samples in groups of 8 */
-        " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
-        " movdqu 16(%1, %3, 4), %%xmm2  \n\t" /* |  v7h  |  v7l  ..  v4h  |  v4l  | */
+        " movdqu (%q1, %3, 4), %%xmm0   \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
+        " movdqu 16(%q1, %3, 4), %%xmm2 \n\t" /* |  v7h  |  v7l  ..  v4h  |  v4l  | */
         " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */
         " movq 8(%0), %%xmm3            \n\t" /*              .. |   p7  ..  p4   | */
         VOLUME_32x16 (%%xmm1, %%xmm0)
@@ -149,19 +151,23 @@ pa_volume_s16ne_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, uns
         "8:                             \n\t"
 
         : "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
-        : "rm" ((pa_reg_x86)channels)
+#if defined (__i386__)
+        : "m" (channels)
+#else
+        : "r" ((pa_reg_x86)channels)
+#endif
         : "cc"
     );
 }
 
-static void
-pa_volume_s16re_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)
-{
+static void pa_volume_s16re_sse2(int16_t *samples, const int32_t *volumes, unsigned channels, unsigned length) {
     pa_reg_x86 channel, temp;
 
-    /* the max number of samples we process at a time, this is also the max amount
-     * we overread the volume array, which should have enough padding. */
-    channels = PA_MAX (8U, channels);
+    /* Channels must be at least 8 and always a multiple of the original number.
+     * This is also the max amount we overread the volume array, which should
+     * have enough padding. */
+    if (channels < 8)
+        channels = channel_overread_table[channels];
 
     __asm__ __volatile__ (
         " xor %3, %3                    \n\t"
@@ -170,7 +176,7 @@ pa_volume_s16re_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, uns
         " test $1, %2                   \n\t" /* check for odd samples */
         " je 2f                         \n\t"
 
-        " movd (%1, %3, 4), %%xmm0      \n\t" /* |  v0h  |  v0l  | */
+        " movd (%q1, %3, 4), %%xmm0     \n\t" /* |  v0h  |  v0l  | */
         " movw (%0), %w4                \n\t" /*     ..  |   p0  | */
         " rorw $8, %w4                  \n\t"
         " movd %4, %%xmm1               \n\t"
@@ -187,7 +193,7 @@ pa_volume_s16re_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, uns
         " je 4f                         \n\t"
 
         "3:                             \n\t" /* do samples in groups of 2 */
-        " movq (%1, %3, 4), %%xmm0      \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
+        " movq (%q1, %3, 4), %%xmm0     \n\t" /* |  v1h  |  v1l  |  v0h  |  v0l  | */
         " movd (%0), %%xmm1             \n\t" /*              .. |   p1  |  p0   | */
         SWAP_16 (%%xmm1)
         VOLUME_32x16 (%%xmm1, %%xmm0)
@@ -205,7 +211,7 @@ pa_volume_s16re_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, uns
          * that the array is 16 bytes aligned, we probably have to do the odd values
          * after this then. */
         "5:                             \n\t" /* do samples in groups of 4 */
-        " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
+        " movdqu (%q1, %3, 4), %%xmm0   \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
         " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */
         SWAP_16 (%%xmm1)
         VOLUME_32x16 (%%xmm1, %%xmm0)
@@ -220,8 +226,8 @@ pa_volume_s16re_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, uns
         " je 8f                         \n\t"
 
         "7:                             \n\t" /* do samples in groups of 8 */
-        " movdqu (%1, %3, 4), %%xmm0    \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
-        " movdqu 16(%1, %3, 4), %%xmm2  \n\t" /* |  v7h  |  v7l  ..  v4h  |  v4l  | */
+        " movdqu (%q1, %3, 4), %%xmm0   \n\t" /* |  v3h  |  v3l  ..  v0h  |  v0l  | */
+        " movdqu 16(%q1, %3, 4), %%xmm2 \n\t" /* |  v7h  |  v7l  ..  v4h  |  v4l  | */
         " movq (%0), %%xmm1             \n\t" /*              .. |   p3  ..  p0   | */
         " movq 8(%0), %%xmm3            \n\t" /*              .. |   p7  ..  p4   | */
         SWAP_16_2 (%%xmm1, %%xmm3)
@@ -237,81 +243,24 @@ pa_volume_s16re_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, uns
         "8:                             \n\t"
 
         : "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
-        : "rm" ((pa_reg_x86)channels)
+#if defined (__i386__)
+        : "m" (channels)
+#else
+        : "r" ((pa_reg_x86)channels)
+#endif
         : "cc"
     );
 }
 
-#undef RUN_TEST
-
-#ifdef RUN_TEST
-#define CHANNELS 2
-#define SAMPLES 1021
-#define TIMES 1000
-#define PADDING 16
-
-static void run_test (void) {
-    int16_t samples[SAMPLES];
-    int16_t samples_ref[SAMPLES];
-    int16_t samples_orig[SAMPLES];
-    int32_t volumes[CHANNELS + PADDING];
-    int i, j, padding;
-    pa_do_volume_func_t func;
-    pa_usec_t start, stop;
-
-    func = pa_get_volume_func (PA_SAMPLE_S16NE);
-
-    printf ("checking SSE %zd\n", sizeof (samples));
-
-    pa_random (samples, sizeof (samples));
-    memcpy (samples_ref, samples, sizeof (samples));
-    memcpy (samples_orig, samples, sizeof (samples));
-
-    for (i = 0; i < CHANNELS; i++)
-        volumes[i] = rand() >> 1;
-    for (padding = 0; padding < PADDING; padding++, i++)
-        volumes[i] = volumes[padding];
-
-    func (samples_ref, volumes, CHANNELS, sizeof (samples));
-    pa_volume_s16ne_sse (samples, volumes, CHANNELS, sizeof (samples));
-    for (i = 0; i < SAMPLES; i++) {
-        if (samples[i] != samples_ref[i]) {
-            printf ("%d: %04x != %04x (%04x * %04x)\n", i, samples[i], samples_ref[i],
-                      samples_orig[i], volumes[i % CHANNELS]);
-        }
-    }
-
-    start = pa_rtclock_now();
-    for (j = 0; j < TIMES; j++) {
-        memcpy (samples, samples_orig, sizeof (samples));
-        pa_volume_s16ne_sse (samples, volumes, CHANNELS, sizeof (samples));
-    }
-    stop = pa_rtclock_now();
-    pa_log_info("SSE: %llu usec.", (long long unsigned int)(stop - start));
-
-    start = pa_rtclock_now();
-    for (j = 0; j < TIMES; j++) {
-        memcpy (samples_ref, samples_orig, sizeof (samples));
-        func (samples_ref, volumes, CHANNELS, sizeof (samples));
-    }
-    stop = pa_rtclock_now();
-    pa_log_info("ref: %llu usec.", (long long unsigned int)(stop - start));
-}
-#endif
 #endif /* defined (__i386__) || defined (__amd64__) */
 
-void pa_volume_func_init_sse (pa_cpu_x86_flag_t flags) {
+void pa_volume_func_init_sse(pa_cpu_x86_flag_t flags) {
 #if defined (__i386__) || defined (__amd64__)
-
-#ifdef RUN_TEST
-    run_test ();
-#endif
-
     if (flags & PA_CPU_X86_SSE2) {
-        pa_log_info("Initialising SSE2 optimized functions.");
+        pa_log_info("Initialising SSE2 optimized volume functions.");
 
-        pa_set_volume_func (PA_SAMPLE_S16NE, (pa_do_volume_func_t) pa_volume_s16ne_sse2);
-        pa_set_volume_func (PA_SAMPLE_S16RE, (pa_do_volume_func_t) pa_volume_s16re_sse2);
+        pa_set_volume_func(PA_SAMPLE_S16NE, (pa_do_volume_func_t) pa_volume_s16ne_sse2);
+        pa_set_volume_func(PA_SAMPLE_S16RE, (pa_do_volume_func_t) pa_volume_s16re_sse2);
     }
 #endif /* defined (__i386__) || defined (__amd64__) */
 }
diff --git a/src/pulsecore/tags b/src/pulsecore/tags
deleted file mode 100644 (file)
index f197f04..0000000
+++ /dev/null
@@ -1,4579 +0,0 @@
-!_TAG_FILE_FORMAT      2       /extended format; --format=1 will not append ;" to lines/
-!_TAG_FILE_SORTED      1       /0=unsorted, 1=sorted, 2=foldcase/
-!_TAG_PROGRAM_AUTHOR   Darren Hiebert  /dhiebert@users.sourceforge.net/
-!_TAG_PROGRAM_NAME     Exuberant Ctags //
-!_TAG_PROGRAM_URL      http://ctags.sourceforge.net    /official site/
-!_TAG_PROGRAM_VERSION  5.8     //
-ABSOLUTE_MAX_LATENCY   sink.c  52;"    d       file:
-ABSOLUTE_MAX_LATENCY   source.c        46;"    d       file:
-ABSOLUTE_MIN_LATENCY   sink.c  51;"    d       file:
-ABSOLUTE_MIN_LATENCY   source.c        45;"    d       file:
-ASYNCQ_SIZE    asyncq.c        41;"    d       file:
-AUTH_TIMEOUT   protocol-esound.c       67;"    d       file:
-AUTH_TIMEOUT   protocol-native.c       65;"    d       file:
-AUTOSPAWN_LOCK lock-autospawn.c        51;"    d       file:
-AVCODEC_H      ffmpeg/avcodec.h        22;"    d
-AVResampleContext      ffmpeg/resample2.c      /^typedef struct AVResampleContext{$/;" s       file:
-AVResampleContext      ffmpeg/resample2.c      /^}AVResampleContext;$/;"       t       typeref:struct:AVResampleContext        file:
-AvahiTimeout   avahi-wrap.c    /^struct AvahiTimeout {$/;"     s       file:
-AvahiWatch     avahi-wrap.c    /^struct AvahiWatch {$/;"       s       file:
-BIAS   g711.c  160;"   d       file:
-BUFFER_LIMIT   ioline.c        41;"    d       file:
-BY_DATA        idxset.c        59;"    d       file:
-BY_HASH        hashmap.c       55;"    d       file:
-BY_INDEX       idxset.c        60;"    d       file:
-CHANNELS       svolume_arm.c   128;"   d       file:
-CHANNELS       svolume_mmx.c   241;"   d       file:
-CHANNELS       svolume_sse.c   248;"   d       file:
-CHECK_VALIDITY protocol-esound.c       331;"   d       file:
-CHECK_VALIDITY protocol-native.c       1820;"  d       file:
-CHUNK_TO_TEXT  strbuf.c        43;"    d       file:
-CLIP   g711.c  161;"   d       file:
-COMMENTS       conf-parser.c   40;"    d       file:
-CONNECTION     protocol-esound.c       124;"   d       file:
-CONNECTION     protocol-simple.c       73;"    d       file:
-CONNECTION_MESSAGE_POST_DATA   protocol-esound.c       /^    CONNECTION_MESSAGE_POST_DATA,$/;" e       enum:__anon14   file:
-CONNECTION_MESSAGE_POST_DATA   protocol-simple.c       /^    CONNECTION_MESSAGE_POST_DATA,         \/* data from source output to main loop *\/$/;"    e       enum:__anon10   file:
-CONNECTION_MESSAGE_RELEASE     protocol-native.c       /^    CONNECTION_MESSAGE_RELEASE,$/;"   e       enum:__anon47   file:
-CONNECTION_MESSAGE_REQUEST_DATA        protocol-esound.c       /^    CONNECTION_MESSAGE_REQUEST_DATA,$/;"      e       enum:__anon14   file:
-CONNECTION_MESSAGE_REQUEST_DATA        protocol-simple.c       /^    CONNECTION_MESSAGE_REQUEST_DATA,      \/* data requested from sink input from the main loop *\/$/;"       e       enum:__anon10   file:
-CONNECTION_MESSAGE_REVOKE      protocol-native.c       /^    CONNECTION_MESSAGE_REVOKE$/;"     e       enum:__anon47   file:
-CONNECTION_MESSAGE_UNLINK_CONNECTION   protocol-esound.c       /^    CONNECTION_MESSAGE_UNLINK_CONNECTION$/;"  e       enum:__anon14   file:
-CONNECTION_MESSAGE_UNLINK_CONNECTION   protocol-simple.c       /^    CONNECTION_MESSAGE_UNLINK_CONNECTION    \/* Please drop a aconnection now *\/$/;" e       enum:__anon10   file:
-CONNECT_TIMEOUT        socket-client.c 72;"    d       file:
-CONVERT_BUFFER_LENGTH  sink-input.c    45;"    d       file:
-COUNTER        aupdate.c       36;"    d       file:
-DEFAULT_COOKIE_FILE    protocol-esound.c       69;"    d       file:
-DEFAULT_FIXED_LATENCY  sink.c  53;"    d       file:
-DEFAULT_FIXED_LATENCY  source.c        47;"    d       file:
-DEFAULT_FRAGSIZE_MSEC  protocol-native.c       73;"    d       file:
-DEFAULT_PROCESS_MSEC   protocol-native.c       72;"    d       file:
-DEFAULT_SINK_LATENCY   protocol-esound.c       77;"    d       file:
-DEFAULT_SINK_LATENCY   protocol-simple.c       96;"    d       file:
-DEFAULT_SOURCE_LATENCY protocol-esound.c       78;"    d       file:
-DEFAULT_SOURCE_LATENCY protocol-http.c 75;"    d       file:
-DEFAULT_SOURCE_LATENCY protocol-simple.c       97;"    d       file:
-DEFAULT_TLENGTH_MSEC   protocol-native.c       71;"    d       file:
-DllMain        dllmain.c       /^BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {$/;"    f
-EAFNOSUPPORT   winsock.h       12;"    d
-ECONNABORTED   winsock.h       9;"     d
-ECONNREFUSED   winsock.h       14;"    d
-ECONNRESET     winsock.h       8;"     d
-EHOSTUNREACH   winsock.h       15;"    d
-EINPROGRESS    winsock.h       11;"    d
-ENETRESET      winsock.h       10;"    d
-ENV_LOG_BACKTRACE      log.c   62;"    d       file:
-ENV_LOG_BACKTRACE_SKIP log.c   63;"    d       file:
-ENV_LOG_COLORS log.c   57;"    d       file:
-ENV_LOG_LEVEL  log.c   56;"    d       file:
-ENV_LOG_PRINT_FILE     log.c   59;"    d       file:
-ENV_LOG_PRINT_LEVEL    log.c   61;"    d       file:
-ENV_LOG_PRINT_META     log.c   60;"    d       file:
-ENV_LOG_PRINT_TIME     log.c   58;"    d       file:
-ENV_LOG_SYSLOG log.c   55;"    d       file:
-ESD_ADPCM      esound.h        123;"   d
-ESD_BITS16     esound.h        112;"   d
-ESD_BITS8      esound.h        111;"   d
-ESD_BUF_SIZE   esound.h        33;"    d
-ESD_CACHING_SAMPLE     esound.h        /^    ESD_CACHING_SAMPLE,         \/* midway through caching a sample *\/$/;"   e       enum:esd_client_state
-ESD_CLIENT_STATE_MAX   esound.h        /^    ESD_CLIENT_STATE_MAX        \/* place holder *\/$/;"      e       enum:esd_client_state
-ESD_DEFAULT_PORT       esound.h        41;"    d
-ESD_DEFAULT_RATE       esound.h        44;"    d
-ESD_ENDIAN_KEY esound.h        50;"    d
-ESD_KEY_LEN    esound.h        38;"    d
-ESD_LOOP       esound.h        133;"   d
-ESD_MASK_BITS  esound.h        110;"   d
-ESD_MASK_CHAN  esound.h        115;"   d
-ESD_MASK_FUNC  esound.h        126;"   d
-ESD_MASK_MODE  esound.h        120;"   d
-ESD_MAX_WRITE_SIZE     esound.h        35;"    d
-ESD_MONITOR    esound.h        129;"   d
-ESD_MONO       esound.h        116;"   d
-ESD_NAME_MAX   esound.h        47;"    d
-ESD_NEEDS_REQDATA      esound.h        /^    ESD_NEEDS_REQDATA,          \/* more data needed to complere request *\/$/;"      e       enum:esd_client_state
-ESD_NEXT_REQUEST       esound.h        /^    ESD_NEXT_REQUEST,           \/* proceed to next request *\/$/;"   e       enum:esd_client_state
-ESD_PLAY       esound.h        127;"   d
-ESD_PROTO_ALL_INFO     esound.h        /^    ESD_PROTO_ALL_INFO,     \/* get all info (server info, players, samples) *\/$/;"  e       enum:esd_proto
-ESD_PROTO_CONNECT      esound.h        /^    ESD_PROTO_CONNECT,      \/* implied on inital client connection *\/$/;"   e       enum:esd_proto
-ESD_PROTO_LATENCY      esound.h        /^    ESD_PROTO_LATENCY,      \/* retrieve latency between write()'s and output *\/$/;" e       enum:esd_proto
-ESD_PROTO_LOCK esound.h        /^    ESD_PROTO_LOCK,         \/* disable "foreign" client connections *\/$/;"  e       enum:esd_proto
-ESD_PROTO_MAX  esound.h        /^    ESD_PROTO_MAX           \/* for bounds checking *\/$/;"   e       enum:esd_proto
-ESD_PROTO_RESUME       esound.h        /^    ESD_PROTO_RESUME,       \/* reclaim \/dev\/dsp and play sounds again *\/$/;"      e       enum:esd_proto
-ESD_PROTO_SAMPLE_CACHE esound.h        /^    ESD_PROTO_SAMPLE_CACHE, \/* cache a sample in the server *\/$/;"  e       enum:esd_proto
-ESD_PROTO_SAMPLE_FREE  esound.h        /^    ESD_PROTO_SAMPLE_FREE,  \/* release a sample in the server *\/$/;"        e       enum:esd_proto
-ESD_PROTO_SAMPLE_GETID esound.h        /^    ESD_PROTO_SAMPLE_GETID, \/* get the ID for an already-cached sample *\/$/;"       e       enum:esd_proto
-ESD_PROTO_SAMPLE_KILL  esound.h        /^    ESD_PROTO_SAMPLE_KILL,  \/* stop the looping sample immed. *\/$/;"        e       enum:esd_proto
-ESD_PROTO_SAMPLE_LOOP  esound.h        /^    ESD_PROTO_SAMPLE_LOOP,  \/* loop a cached sample, til eoloop *\/$/;"      e       enum:esd_proto
-ESD_PROTO_SAMPLE_PAN   esound.h        /^    ESD_PROTO_SAMPLE_PAN,   \/* set default sample panning *\/$/;"    e       enum:esd_proto
-ESD_PROTO_SAMPLE_PLAY  esound.h        /^    ESD_PROTO_SAMPLE_PLAY,  \/* play a cached sample *\/$/;"  e       enum:esd_proto
-ESD_PROTO_SAMPLE_STOP  esound.h        /^    ESD_PROTO_SAMPLE_STOP,  \/* stop a looping sample when done *\/$/;"       e       enum:esd_proto
-ESD_PROTO_SERVER_INFO  esound.h        /^    ESD_PROTO_SERVER_INFO,  \/* get server info (ver, sample rate, format) *\/$/;"    e       enum:esd_proto
-ESD_PROTO_STANDBY      esound.h        /^    ESD_PROTO_STANDBY,      \/* release \/dev\/dsp and ignore all data *\/$/;"        e       enum:esd_proto
-ESD_PROTO_STANDBY_MODE esound.h        /^    ESD_PROTO_STANDBY_MODE, \/* see if server is in standby, autostandby, etc *\/$/;" e       enum:esd_proto
-ESD_PROTO_STREAM_FILT  esound.h        /^    ESD_PROTO_STREAM_FILT,  \/* filter mixed buffer output as a stream *\/$/;"        e       enum:esd_proto
-ESD_PROTO_STREAM_MON   esound.h        /^    ESD_PROTO_STREAM_MON,   \/* send mixed buffer output as a stream *\/$/;"  e       enum:esd_proto
-ESD_PROTO_STREAM_PAN   esound.h        /^    ESD_PROTO_STREAM_PAN,   \/* set stream panning *\/$/;"    e       enum:esd_proto
-ESD_PROTO_STREAM_PLAY  esound.h        /^    ESD_PROTO_STREAM_PLAY,  \/* play all following data as a stream *\/$/;"   e       enum:esd_proto
-ESD_PROTO_STREAM_REC   esound.h        /^    ESD_PROTO_STREAM_REC,   \/* record data from card as a stream *\/$/;"     e       enum:esd_proto
-ESD_PROTO_SUBSCRIBE    esound.h        /^    ESD_PROTO_SUBSCRIBE,    \/* track new and removed players and samples *\/$/;"     e       enum:esd_proto
-ESD_PROTO_UNLOCK       esound.h        /^    ESD_PROTO_UNLOCK,       \/* enable "foreign" client connections *\/$/;"   e       enum:esd_proto
-ESD_PROTO_UNSUBSCRIBE  esound.h        /^    ESD_PROTO_UNSUBSCRIBE,  \/* stop tracking updates *\/$/;" e       enum:esd_proto
-ESD_RECORD     esound.h        130;"   d
-ESD_SAMPLE     esound.h        122;"   d
-ESD_STEREO     esound.h        117;"   d
-ESD_STOP       esound.h        132;"   d
-ESD_STREAM     esound.h        121;"   d
-ESD_STREAMING_DATA     esound.h        /^    ESD_STREAMING_DATA,         \/* data from here on is streamed data *\/$/;"        e       enum:esd_client_state
-ESD_SWAP_ENDIAN_KEY    esound.h        206;"   d
-ESD_UNIX_SOCKET_DIR    esound.h        29;"    d
-ESD_UNIX_SOCKET_NAME   esound.h        30;"    d
-ESD_VOLUME_BASE        esound.h        52;"    d
-ESHUTDOWN      winsock.h       7;"     d
-ESM_ERROR      esound.h        /^    ESM_ERROR, ESM_ON_STANDBY, ESM_ON_AUTOSTANDBY, ESM_RUNNING$/;"    e       enum:esd_standby_mode
-ESM_ON_AUTOSTANDBY     esound.h        /^    ESM_ERROR, ESM_ON_STANDBY, ESM_ON_AUTOSTANDBY, ESM_RUNNING$/;"    e       enum:esd_standby_mode
-ESM_ON_STANDBY esound.h        /^    ESM_ERROR, ESM_ON_STANDBY, ESM_ON_AUTOSTANDBY, ESM_RUNNING$/;"    e       enum:esd_standby_mode
-ESM_RUNNING    esound.h        /^    ESM_ERROR, ESM_ON_STANDBY, ESM_ON_AUTOSTANDBY, ESM_RUNNING$/;"    e       enum:esd_standby_mode
-ETIMEDOUT      winsock.h       13;"    d
-EWOULDBLOCK    winsock.h       16;"    d
-EXTRA_FRAMES   resampler.c     46;"    d       file:
-FALSE  macro.h 185;"   d
-FELEM  ffmpeg/resample2.c      34;"    d       file:
-FELEM  ffmpeg/resample2.c      43;"    d       file:
-FELEM  ffmpeg/resample2.c      52;"    d       file:
-FELEM2 ffmpeg/resample2.c      35;"    d       file:
-FELEM2 ffmpeg/resample2.c      44;"    d       file:
-FELEM2 ffmpeg/resample2.c      53;"    d       file:
-FELEML ffmpeg/resample2.c      36;"    d       file:
-FELEML ffmpeg/resample2.c      45;"    d       file:
-FELEML ffmpeg/resample2.c      54;"    d       file:
-FELEM_MAX      ffmpeg/resample2.c      37;"    d       file:
-FELEM_MAX      ffmpeg/resample2.c      46;"    d       file:
-FELEM_MIN      ffmpeg/resample2.c      38;"    d       file:
-FELEM_MIN      ffmpeg/resample2.c      47;"    d       file:
-FFABS  ffmpeg/avcodec.h        62;"    d
-FFMAX  ffmpeg/avcodec.h        65;"    d
-FFMIN  ffmpeg/avcodec.h        66;"    d
-FFSIGN ffmpeg/avcodec.h        63;"    d
-FILE_STREAM    sound-file-stream.c     68;"    d       file:
-FILE_STREAM_MESSAGE_UNLINK     sound-file-stream.c     /^    FILE_STREAM_MESSAGE_UNLINK$/;"    e       enum:__anon17   file:
-FILTER_SHIFT   ffmpeg/resample2.c      32;"    d       file:
-FILTER_SHIFT   ffmpeg/resample2.c      41;"    d       file:
-FILTER_SHIFT   ffmpeg/resample2.c      50;"    d       file:
-FLIST_SIZE     flist.c 68;"    d       file:
-FRAME_SIZE_MAX_ALLOW   pstream.c       84;"    d       file:
-HANDLE_SINGLE_dq       remap_mmx.c     68;"    d       file:
-HANDLE_SINGLE_dq       remap_sse.c     68;"    d       file:
-HANDLE_SINGLE_wd       remap_mmx.c     75;"    d       file:
-HANDLE_SINGLE_wd       remap_sse.c     75;"    d       file:
-HAVE_CREDS     creds.h 43;"    d
-HAVE_CREDS     creds.h 51;"    d
-HAVE_VECTOR    vector.h        28;"    d
-HISTORY_MAX    time-smoother.c 35;"    d       file:
-HTML_FOOTER    protocol-http.c 70;"    d       file:
-HTML_HEADER    protocol-http.c 60;"    d       file:
-IFSTATE_FALSE  cli-command.c   /^    IFSTATE_FALSE = 0,$/;"    e       enum:__anon30   file:
-IFSTATE_NONE   cli-command.c   /^    IFSTATE_NONE = -1,$/;"    e       enum:__anon30   file:
-IFSTATE_TRUE   cli-command.c   /^    IFSTATE_TRUE = 1,$/;"     e       enum:__anon30   file:
-INCREASE_BY    dynarray.c      35;"    d       file:
-INT16_FROM     sconv-s16be.c   28;"    d       file:
-INT16_FROM     sconv-s16le.c   40;"    d       file:
-INT16_TO       sconv-s16be.c   29;"    d       file:
-INT16_TO       sconv-s16le.c   47;"    d       file:
-INT32_FROM     sconv-s16be.c   33;"    d       file:
-INT32_FROM     sconv-s16le.c   54;"    d       file:
-INT32_TO       sconv-s16be.c   34;"    d       file:
-INT32_TO       sconv-s16le.c   61;"    d       file:
-ITEM_TO_TEXT   strlist.c       40;"    d       file:
-LOAD_SAMPLES   remap_mmx.c     36;"    d       file:
-LOAD_SAMPLES   remap_sse.c     36;"    d       file:
-LOG_FUNC       log.h   120;"   d
-MADV_REMOVE    shm.c   60;"    d       file:
-MAKE_GDBM_FILE database-gdbm.c 35;"    d       file:
-MAKE_TDB_CONTEXT       database-tdb.c  40;"    d       file:
-MAP_ANONYMOUS  memtrap.c       31;"    d       file:
-MAP_ANONYMOUS  shm.c   44;"    d       file:
-MAX_BUFFER     cpu-arm.c       39;"    d       file:
-MAX_CACHE_SAMPLE_SIZE  protocol-esound.c       75;"    d       file:
-MAX_CONNECTIONS        protocol-cli.c  38;"    d       file:
-MAX_CONNECTIONS        protocol-esound.c       64;"    d       file:
-MAX_CONNECTIONS        protocol-http.c 48;"    d       file:
-MAX_CONNECTIONS        protocol-native.c       68;"    d       file:
-MAX_CONNECTIONS        protocol-simple.c       50;"    d       file:
-MAX_MEMBLOCKQ_LENGTH   protocol-native.c       70;"    d       file:
-MAX_MIX_CHANNELS       sink.c  49;"    d       file:
-MAX_SHM_SIZE   shm.c   64;"    d       file:
-MAX_TAG_SIZE   tagstruct.c     43;"    d       file:
-MEMBLOCKQ_MAXLENGTH    sink-input.c    44;"    d       file:
-MEMBLOCKQ_MAXLENGTH    sound-file-stream.c     48;"    d       file:
-MEMBLOCKQ_MAXLENGTH    source-output.c 42;"    d       file:
-MEMBLOCKQ_STREAM       play-memblockq.c        51;"    d       file:
-MEMBLOCKQ_STREAM_MESSAGE_UNLINK        play-memblockq.c        /^    MEMBLOCKQ_STREAM_MESSAGE_UNLINK,$/;"      e       enum:__anon1    file:
-META_ELSE      cli-command.c   70;"    d       file:
-META_ENDIF     cli-command.c   71;"    d       file:
-META_FAIL      cli-command.c   67;"    d       file:
-META_IFEXISTS  cli-command.c   69;"    d       file:
-META_INCLUDE   cli-command.c   66;"    d       file:
-META_NOFAIL    cli-command.c   68;"    d       file:
-MIME_CSS       protocol-http.c 58;"    d       file:
-MIME_HTML      protocol-http.c 56;"    d       file:
-MIME_TEXT      protocol-http.c 57;"    d       file:
-MIX_BUFFER_LENGTH      sink.c  50;"    d       file:
-MOD_ADD        svolume_mmx.c   72;"    d       file:
-MOD_ADD        svolume_sse.c   53;"    d       file:
-MOD_INC        svolume_arm.c   40;"    d       file:
-MONO_TO_STEREO remap_mmx.c     83;"    d       file:
-MONO_TO_STEREO remap_sse.c     83;"    d       file:
-MSB    aupdate.c       34;"    d       file:
-MSG_NOSIGNAL   core-util.c     126;"   d       file:
-NBUCKETS       hashmap.c       37;"    d       file:
-NBUCKETS       idxset.c        38;"    d       file:
-NSEGS  g711.c  48;"    d       file:
-N_EXTRA_SCAN   flist.c 69;"    d       file:
-ON_FRONT       resampler.c     /^    ON_FRONT,$/;"     e       enum:__anon42   file:
-ON_OTHER       resampler.c     /^    ON_OTHER$/;"      e       enum:__anon42   file:
-ON_REAR        resampler.c     /^    ON_REAR,$/;"      e       enum:__anon42   file:
-ON_SIDE        resampler.c     /^    ON_SIDE,$/;"      e       enum:__anon42   file:
-OUTPUT_STREAM  protocol-native.c       108;"   d       file:
-O_BINARY       authkey.c       70;"    d       file:
-O_NOCTTY       authkey.c       74;"    d       file:
-PADDING        svolume_arm.c   131;"   d       file:
-PADDING        svolume_mmx.c   244;"   d       file:
-PADDING        svolume_sse.c   251;"   d       file:
-PA_ALIGN       macro.h /^static inline size_t PA_ALIGN(size_t l) {$/;" f
-PA_ALIGN_PTR   macro.h /^static inline void* PA_ALIGN_PTR(const void *p) {$/;" f
-PA_ASYNCQ_CELLS        asyncq.c        72;"    d       file:
-PA_ATOMIC_INIT atomic.h        120;"   d
-PA_ATOMIC_INIT atomic.h        193;"   d
-PA_ATOMIC_INIT atomic.h        269;"   d
-PA_ATOMIC_INIT atomic.h        415;"   d
-PA_ATOMIC_INIT atomic.h        498;"   d
-PA_ATOMIC_INIT atomic.h        53;"    d
-PA_ATOMIC_PTR_INIT     atomic.h        166;"   d
-PA_ATOMIC_PTR_INIT     atomic.h        239;"   d
-PA_ATOMIC_PTR_INIT     atomic.h        355;"   d
-PA_ATOMIC_PTR_INIT     atomic.h        468;"   d
-PA_ATOMIC_PTR_INIT     atomic.h        532;"   d
-PA_ATOMIC_PTR_INIT     atomic.h        94;"    d
-PA_BITSET_ELEMENTS     bitset.h        28;"    d
-PA_BITSET_SIZE bitset.h        29;"    d
-PA_CARD_PROFILE_DATA   card.h  48;"    d
-PA_CHANNEL_POSITION_MASK_ALL   sample-util.h   151;"   d
-PA_CHANNEL_POSITION_MASK_CENTER        sample-util.h   112;"   d
-PA_CHANNEL_POSITION_MASK_FRONT sample-util.h   119;"   d
-PA_CHANNEL_POSITION_MASK_LEFT  sample-util.h   96;"    d
-PA_CHANNEL_POSITION_MASK_REAR  sample-util.h   129;"   d
-PA_CHANNEL_POSITION_MASK_RIGHT sample-util.h   104;"   d
-PA_CHANNEL_POSITION_MASK_SIDE_OR_TOP_CENTER    sample-util.h   137;"   d
-PA_CHANNEL_POSITION_MASK_TOP   sample-util.h   142;"   d
-PA_CLAMP       macro.h 117;"   d
-PA_CLAMP       macro.h 125;"   d
-PA_CLAMP_UNLIKELY      macro.h 129;"   d
-PA_CLAMP_UNLIKELY      macro.h 137;"   d
-PA_CLIP_SUB    macro.h 167;"   d
-PA_CLIP_SUB    macro.h 174;"   d
-PA_COMMAND_ADD_AUTOLOAD___OBSOLETE     native-common.h /^    PA_COMMAND_ADD_AUTOLOAD___OBSOLETE,$/;"   e       enum:__anon29
-PA_COMMAND_AUTH        native-common.h /^    PA_COMMAND_AUTH,$/;"      e       enum:__anon29
-PA_COMMAND_CLIENT_EVENT        native-common.h /^    PA_COMMAND_CLIENT_EVENT,$/;"      e       enum:__anon29
-PA_COMMAND_CORK_PLAYBACK_STREAM        native-common.h /^    PA_COMMAND_CORK_PLAYBACK_STREAM,$/;"      e       enum:__anon29
-PA_COMMAND_CORK_RECORD_STREAM  native-common.h /^    PA_COMMAND_CORK_RECORD_STREAM,$/;"        e       enum:__anon29
-PA_COMMAND_CREATE_PLAYBACK_STREAM      native-common.h /^    PA_COMMAND_CREATE_PLAYBACK_STREAM,        \/* Payload changed in v9, v12 (0.9.0, 0.9.8) *\/$/;"   e       enum:__anon29
-PA_COMMAND_CREATE_RECORD_STREAM        native-common.h /^    PA_COMMAND_CREATE_RECORD_STREAM,          \/* Payload changed in v9, v12 (0.9.0, 0.9.8) *\/$/;"   e       enum:__anon29
-PA_COMMAND_CREATE_UPLOAD_STREAM        native-common.h /^    PA_COMMAND_CREATE_UPLOAD_STREAM,$/;"      e       enum:__anon29
-PA_COMMAND_DELETE_PLAYBACK_STREAM      native-common.h /^    PA_COMMAND_DELETE_PLAYBACK_STREAM,$/;"    e       enum:__anon29
-PA_COMMAND_DELETE_RECORD_STREAM        native-common.h /^    PA_COMMAND_DELETE_RECORD_STREAM,$/;"      e       enum:__anon29
-PA_COMMAND_DELETE_UPLOAD_STREAM        native-common.h /^    PA_COMMAND_DELETE_UPLOAD_STREAM,$/;"      e       enum:__anon29
-PA_COMMAND_DRAIN_PLAYBACK_STREAM       native-common.h /^    PA_COMMAND_DRAIN_PLAYBACK_STREAM,$/;"     e       enum:__anon29
-PA_COMMAND_ERROR       native-common.h /^    PA_COMMAND_ERROR,$/;"     e       enum:__anon29
-PA_COMMAND_EXIT        native-common.h /^    PA_COMMAND_EXIT,$/;"      e       enum:__anon29
-PA_COMMAND_EXTENSION   native-common.h /^    PA_COMMAND_EXTENSION,$/;" e       enum:__anon29
-PA_COMMAND_FINISH_UPLOAD_STREAM        native-common.h /^    PA_COMMAND_FINISH_UPLOAD_STREAM,$/;"      e       enum:__anon29
-PA_COMMAND_FLUSH_PLAYBACK_STREAM       native-common.h /^    PA_COMMAND_FLUSH_PLAYBACK_STREAM,$/;"     e       enum:__anon29
-PA_COMMAND_FLUSH_RECORD_STREAM native-common.h /^    PA_COMMAND_FLUSH_RECORD_STREAM,$/;"       e       enum:__anon29
-PA_COMMAND_GET_AUTOLOAD_INFO_LIST___OBSOLETE   native-common.h /^    PA_COMMAND_GET_AUTOLOAD_INFO_LIST___OBSOLETE,$/;" e       enum:__anon29
-PA_COMMAND_GET_AUTOLOAD_INFO___OBSOLETE        native-common.h /^    PA_COMMAND_GET_AUTOLOAD_INFO___OBSOLETE,$/;"      e       enum:__anon29
-PA_COMMAND_GET_CARD_INFO       native-common.h /^    PA_COMMAND_GET_CARD_INFO,$/;"     e       enum:__anon29
-PA_COMMAND_GET_CARD_INFO_LIST  native-common.h /^    PA_COMMAND_GET_CARD_INFO_LIST,$/;"        e       enum:__anon29
-PA_COMMAND_GET_CLIENT_INFO     native-common.h /^    PA_COMMAND_GET_CLIENT_INFO,$/;"   e       enum:__anon29
-PA_COMMAND_GET_CLIENT_INFO_LIST        native-common.h /^    PA_COMMAND_GET_CLIENT_INFO_LIST,$/;"      e       enum:__anon29
-PA_COMMAND_GET_MODULE_INFO     native-common.h /^    PA_COMMAND_GET_MODULE_INFO,$/;"   e       enum:__anon29
-PA_COMMAND_GET_MODULE_INFO_LIST        native-common.h /^    PA_COMMAND_GET_MODULE_INFO_LIST,$/;"      e       enum:__anon29
-PA_COMMAND_GET_PLAYBACK_LATENCY        native-common.h /^    PA_COMMAND_GET_PLAYBACK_LATENCY,$/;"      e       enum:__anon29
-PA_COMMAND_GET_RECORD_LATENCY  native-common.h /^    PA_COMMAND_GET_RECORD_LATENCY,$/;"        e       enum:__anon29
-PA_COMMAND_GET_SAMPLE_INFO     native-common.h /^    PA_COMMAND_GET_SAMPLE_INFO,$/;"   e       enum:__anon29
-PA_COMMAND_GET_SAMPLE_INFO_LIST        native-common.h /^    PA_COMMAND_GET_SAMPLE_INFO_LIST,$/;"      e       enum:__anon29
-PA_COMMAND_GET_SERVER_INFO     native-common.h /^    PA_COMMAND_GET_SERVER_INFO,$/;"   e       enum:__anon29
-PA_COMMAND_GET_SINK_INFO       native-common.h /^    PA_COMMAND_GET_SINK_INFO,$/;"     e       enum:__anon29
-PA_COMMAND_GET_SINK_INFO_LIST  native-common.h /^    PA_COMMAND_GET_SINK_INFO_LIST,$/;"        e       enum:__anon29
-PA_COMMAND_GET_SINK_INPUT_INFO native-common.h /^    PA_COMMAND_GET_SINK_INPUT_INFO,          \/* Payload changed in v11 (0.9.7) *\/$/;"       e       enum:__anon29
-PA_COMMAND_GET_SINK_INPUT_INFO_LIST    native-common.h /^    PA_COMMAND_GET_SINK_INPUT_INFO_LIST,     \/* Payload changed in v11 (0.9.7) *\/$/;"       e       enum:__anon29
-PA_COMMAND_GET_SOURCE_INFO     native-common.h /^    PA_COMMAND_GET_SOURCE_INFO,$/;"   e       enum:__anon29
-PA_COMMAND_GET_SOURCE_INFO_LIST        native-common.h /^    PA_COMMAND_GET_SOURCE_INFO_LIST,$/;"      e       enum:__anon29
-PA_COMMAND_GET_SOURCE_OUTPUT_INFO      native-common.h /^    PA_COMMAND_GET_SOURCE_OUTPUT_INFO,$/;"    e       enum:__anon29
-PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST native-common.h /^    PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST,$/;"       e       enum:__anon29
-PA_COMMAND_KILL_CLIENT native-common.h /^    PA_COMMAND_KILL_CLIENT,$/;"       e       enum:__anon29
-PA_COMMAND_KILL_SINK_INPUT     native-common.h /^    PA_COMMAND_KILL_SINK_INPUT,$/;"   e       enum:__anon29
-PA_COMMAND_KILL_SOURCE_OUTPUT  native-common.h /^    PA_COMMAND_KILL_SOURCE_OUTPUT,$/;"        e       enum:__anon29
-PA_COMMAND_LOAD_MODULE native-common.h /^    PA_COMMAND_LOAD_MODULE,$/;"       e       enum:__anon29
-PA_COMMAND_LOOKUP_SINK native-common.h /^    PA_COMMAND_LOOKUP_SINK,$/;"       e       enum:__anon29
-PA_COMMAND_LOOKUP_SOURCE       native-common.h /^    PA_COMMAND_LOOKUP_SOURCE,$/;"     e       enum:__anon29
-PA_COMMAND_MAX native-common.h /^    PA_COMMAND_MAX$/;"        e       enum:__anon29
-PA_COMMAND_MOVE_SINK_INPUT     native-common.h /^    PA_COMMAND_MOVE_SINK_INPUT,$/;"   e       enum:__anon29
-PA_COMMAND_MOVE_SOURCE_OUTPUT  native-common.h /^    PA_COMMAND_MOVE_SOURCE_OUTPUT,$/;"        e       enum:__anon29
-PA_COMMAND_OVERFLOW    native-common.h /^    PA_COMMAND_OVERFLOW,$/;"  e       enum:__anon29
-PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED        native-common.h /^    PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED,$/;"      e       enum:__anon29
-PA_COMMAND_PLAYBACK_STREAM_EVENT       native-common.h /^    PA_COMMAND_PLAYBACK_STREAM_EVENT,$/;"     e       enum:__anon29
-PA_COMMAND_PLAYBACK_STREAM_KILLED      native-common.h /^    PA_COMMAND_PLAYBACK_STREAM_KILLED,$/;"    e       enum:__anon29
-PA_COMMAND_PLAYBACK_STREAM_MOVED       native-common.h /^    PA_COMMAND_PLAYBACK_STREAM_MOVED,$/;"     e       enum:__anon29
-PA_COMMAND_PLAYBACK_STREAM_SUSPENDED   native-common.h /^    PA_COMMAND_PLAYBACK_STREAM_SUSPENDED,$/;" e       enum:__anon29
-PA_COMMAND_PLAY_SAMPLE native-common.h /^    PA_COMMAND_PLAY_SAMPLE,$/;"       e       enum:__anon29
-PA_COMMAND_PREBUF_PLAYBACK_STREAM      native-common.h /^    PA_COMMAND_PREBUF_PLAYBACK_STREAM,$/;"    e       enum:__anon29
-PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED  native-common.h /^    PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED,$/;"        e       enum:__anon29
-PA_COMMAND_RECORD_STREAM_EVENT native-common.h /^    PA_COMMAND_RECORD_STREAM_EVENT,$/;"       e       enum:__anon29
-PA_COMMAND_RECORD_STREAM_KILLED        native-common.h /^    PA_COMMAND_RECORD_STREAM_KILLED,$/;"      e       enum:__anon29
-PA_COMMAND_RECORD_STREAM_MOVED native-common.h /^    PA_COMMAND_RECORD_STREAM_MOVED,$/;"       e       enum:__anon29
-PA_COMMAND_RECORD_STREAM_SUSPENDED     native-common.h /^    PA_COMMAND_RECORD_STREAM_SUSPENDED,$/;"   e       enum:__anon29
-PA_COMMAND_REMOVE_AUTOLOAD___OBSOLETE  native-common.h /^    PA_COMMAND_REMOVE_AUTOLOAD___OBSOLETE,$/;"        e       enum:__anon29
-PA_COMMAND_REMOVE_CLIENT_PROPLIST      native-common.h /^    PA_COMMAND_REMOVE_CLIENT_PROPLIST,$/;"    e       enum:__anon29
-PA_COMMAND_REMOVE_PLAYBACK_STREAM_PROPLIST     native-common.h /^    PA_COMMAND_REMOVE_PLAYBACK_STREAM_PROPLIST,$/;"   e       enum:__anon29
-PA_COMMAND_REMOVE_RECORD_STREAM_PROPLIST       native-common.h /^    PA_COMMAND_REMOVE_RECORD_STREAM_PROPLIST,$/;"     e       enum:__anon29
-PA_COMMAND_REMOVE_SAMPLE       native-common.h /^    PA_COMMAND_REMOVE_SAMPLE,$/;"     e       enum:__anon29
-PA_COMMAND_REPLY       native-common.h /^    PA_COMMAND_REPLY,$/;"     e       enum:__anon29
-PA_COMMAND_REQUEST     native-common.h /^    PA_COMMAND_REQUEST,$/;"   e       enum:__anon29
-PA_COMMAND_SET_CARD_PROFILE    native-common.h /^    PA_COMMAND_SET_CARD_PROFILE,$/;"  e       enum:__anon29
-PA_COMMAND_SET_CLIENT_NAME     native-common.h /^    PA_COMMAND_SET_CLIENT_NAME,$/;"   e       enum:__anon29
-PA_COMMAND_SET_DEFAULT_SINK    native-common.h /^    PA_COMMAND_SET_DEFAULT_SINK,$/;"  e       enum:__anon29
-PA_COMMAND_SET_DEFAULT_SOURCE  native-common.h /^    PA_COMMAND_SET_DEFAULT_SOURCE,$/;"        e       enum:__anon29
-PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR     native-common.h /^    PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR,$/;"   e       enum:__anon29
-PA_COMMAND_SET_PLAYBACK_STREAM_NAME    native-common.h /^    PA_COMMAND_SET_PLAYBACK_STREAM_NAME,$/;"  e       enum:__anon29
-PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR       native-common.h /^    PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR,$/;"     e       enum:__anon29
-PA_COMMAND_SET_RECORD_STREAM_NAME      native-common.h /^    PA_COMMAND_SET_RECORD_STREAM_NAME,$/;"    e       enum:__anon29
-PA_COMMAND_SET_SINK_INPUT_MUTE native-common.h /^    PA_COMMAND_SET_SINK_INPUT_MUTE,$/;"       e       enum:__anon29
-PA_COMMAND_SET_SINK_INPUT_VOLUME       native-common.h /^    PA_COMMAND_SET_SINK_INPUT_VOLUME,$/;"     e       enum:__anon29
-PA_COMMAND_SET_SINK_MUTE       native-common.h /^    PA_COMMAND_SET_SINK_MUTE,$/;"     e       enum:__anon29
-PA_COMMAND_SET_SINK_PORT       native-common.h /^    PA_COMMAND_SET_SINK_PORT,$/;"     e       enum:__anon29
-PA_COMMAND_SET_SINK_VOLUME     native-common.h /^    PA_COMMAND_SET_SINK_VOLUME,$/;"   e       enum:__anon29
-PA_COMMAND_SET_SOURCE_MUTE     native-common.h /^    PA_COMMAND_SET_SOURCE_MUTE,$/;"   e       enum:__anon29
-PA_COMMAND_SET_SOURCE_PORT     native-common.h /^    PA_COMMAND_SET_SOURCE_PORT,$/;"   e       enum:__anon29
-PA_COMMAND_SET_SOURCE_VOLUME   native-common.h /^    PA_COMMAND_SET_SOURCE_VOLUME,$/;" e       enum:__anon29
-PA_COMMAND_STARTED     native-common.h /^    PA_COMMAND_STARTED,$/;"   e       enum:__anon29
-PA_COMMAND_STAT        native-common.h /^    PA_COMMAND_STAT,$/;"      e       enum:__anon29
-PA_COMMAND_SUBSCRIBE   native-common.h /^    PA_COMMAND_SUBSCRIBE,$/;" e       enum:__anon29
-PA_COMMAND_SUBSCRIBE_EVENT     native-common.h /^    PA_COMMAND_SUBSCRIBE_EVENT,$/;"   e       enum:__anon29
-PA_COMMAND_SUSPEND_SINK        native-common.h /^    PA_COMMAND_SUSPEND_SINK,$/;"      e       enum:__anon29
-PA_COMMAND_SUSPEND_SOURCE      native-common.h /^    PA_COMMAND_SUSPEND_SOURCE,$/;"    e       enum:__anon29
-PA_COMMAND_TIMEOUT     native-common.h /^    PA_COMMAND_TIMEOUT, \/* pseudo command *\/$/;"    e       enum:__anon29
-PA_COMMAND_TRIGGER_PLAYBACK_STREAM     native-common.h /^    PA_COMMAND_TRIGGER_PLAYBACK_STREAM,$/;"   e       enum:__anon29
-PA_COMMAND_UNDERFLOW   native-common.h /^    PA_COMMAND_UNDERFLOW,$/;" e       enum:__anon29
-PA_COMMAND_UNLOAD_MODULE       native-common.h /^    PA_COMMAND_UNLOAD_MODULE,$/;"     e       enum:__anon29
-PA_COMMAND_UPDATE_CLIENT_PROPLIST      native-common.h /^    PA_COMMAND_UPDATE_CLIENT_PROPLIST,$/;"    e       enum:__anon29
-PA_COMMAND_UPDATE_PLAYBACK_STREAM_PROPLIST     native-common.h /^    PA_COMMAND_UPDATE_PLAYBACK_STREAM_PROPLIST,$/;"   e       enum:__anon29
-PA_COMMAND_UPDATE_PLAYBACK_STREAM_SAMPLE_RATE  native-common.h /^    PA_COMMAND_UPDATE_PLAYBACK_STREAM_SAMPLE_RATE,$/;"        e       enum:__anon29
-PA_COMMAND_UPDATE_RECORD_STREAM_PROPLIST       native-common.h /^    PA_COMMAND_UPDATE_RECORD_STREAM_PROPLIST,$/;"     e       enum:__anon29
-PA_COMMAND_UPDATE_RECORD_STREAM_SAMPLE_RATE    native-common.h /^    PA_COMMAND_UPDATE_RECORD_STREAM_SAMPLE_RATE,$/;"  e       enum:__anon29
-PA_CORE        core.h  169;"   d
-PA_CORE_HOOK_CARD_NEW  core.h  /^    PA_CORE_HOOK_CARD_NEW,$/;"        e       enum:pa_core_hook
-PA_CORE_HOOK_CARD_PUT  core.h  /^    PA_CORE_HOOK_CARD_PUT,$/;"        e       enum:pa_core_hook
-PA_CORE_HOOK_CARD_UNLINK       core.h  /^    PA_CORE_HOOK_CARD_UNLINK,$/;"     e       enum:pa_core_hook
-PA_CORE_HOOK_CLIENT_NEW        core.h  /^    PA_CORE_HOOK_CLIENT_NEW,$/;"      e       enum:pa_core_hook
-PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED   core.h  /^    PA_CORE_HOOK_CLIENT_PROPLIST_CHANGED,$/;" e       enum:pa_core_hook
-PA_CORE_HOOK_CLIENT_PUT        core.h  /^    PA_CORE_HOOK_CLIENT_PUT,$/;"      e       enum:pa_core_hook
-PA_CORE_HOOK_CLIENT_SEND_EVENT core.h  /^    PA_CORE_HOOK_CLIENT_SEND_EVENT,$/;"       e       enum:pa_core_hook
-PA_CORE_HOOK_CLIENT_UNLINK     core.h  /^    PA_CORE_HOOK_CLIENT_UNLINK,$/;"   e       enum:pa_core_hook
-PA_CORE_HOOK_MAX       core.h  /^    PA_CORE_HOOK_MAX$/;"      e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_FIXATE       core.h  /^    PA_CORE_HOOK_SINK_FIXATE,$/;"     e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_INPUT_FIXATE core.h  /^    PA_CORE_HOOK_SINK_INPUT_FIXATE,$/;"       e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL      core.h  /^    PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL,$/;"    e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH    core.h  /^    PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH,$/;"  e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_INPUT_MOVE_START     core.h  /^    PA_CORE_HOOK_SINK_INPUT_MOVE_START,$/;"   e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_INPUT_NEW    core.h  /^    PA_CORE_HOOK_SINK_INPUT_NEW,$/;"  e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED       core.h  /^    PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED,$/;"     e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_INPUT_PUT    core.h  /^    PA_CORE_HOOK_SINK_INPUT_PUT,$/;"  e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_INPUT_SEND_EVENT     core.h  /^    PA_CORE_HOOK_SINK_INPUT_SEND_EVENT,$/;"   e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED  core.h  /^    PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED,$/;"        e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_INPUT_UNLINK core.h  /^    PA_CORE_HOOK_SINK_INPUT_UNLINK,$/;"       e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_INPUT_UNLINK_POST    core.h  /^    PA_CORE_HOOK_SINK_INPUT_UNLINK_POST,$/;"  e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_NEW  core.h  /^    PA_CORE_HOOK_SINK_NEW,$/;"        e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_PROPLIST_CHANGED     core.h  /^    PA_CORE_HOOK_SINK_PROPLIST_CHANGED,$/;"   e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_PUT  core.h  /^    PA_CORE_HOOK_SINK_PUT,$/;"        e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_STATE_CHANGED        core.h  /^    PA_CORE_HOOK_SINK_STATE_CHANGED,$/;"      e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_UNLINK       core.h  /^    PA_CORE_HOOK_SINK_UNLINK,$/;"     e       enum:pa_core_hook
-PA_CORE_HOOK_SINK_UNLINK_POST  core.h  /^    PA_CORE_HOOK_SINK_UNLINK_POST,$/;"        e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_FIXATE     core.h  /^    PA_CORE_HOOK_SOURCE_FIXATE,$/;"   e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_NEW        core.h  /^    PA_CORE_HOOK_SOURCE_NEW,$/;"      e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_OUTPUT_FIXATE      core.h  /^    PA_CORE_HOOK_SOURCE_OUTPUT_FIXATE,$/;"    e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FAIL   core.h  /^    PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FAIL,$/;" e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FINISH core.h  /^    PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FINISH,$/;"       e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_START  core.h  /^    PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_START,$/;"        e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_OUTPUT_NEW core.h  /^    PA_CORE_HOOK_SOURCE_OUTPUT_NEW,$/;"       e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_OUTPUT_PROPLIST_CHANGED    core.h  /^    PA_CORE_HOOK_SOURCE_OUTPUT_PROPLIST_CHANGED,$/;"  e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_OUTPUT_PUT core.h  /^    PA_CORE_HOOK_SOURCE_OUTPUT_PUT,$/;"       e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_OUTPUT_SEND_EVENT  core.h  /^    PA_CORE_HOOK_SOURCE_OUTPUT_SEND_EVENT,$/;"        e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_OUTPUT_STATE_CHANGED       core.h  /^    PA_CORE_HOOK_SOURCE_OUTPUT_STATE_CHANGED,$/;"     e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK      core.h  /^    PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK,$/;"    e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK_POST core.h  /^    PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK_POST,$/;"       e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_PROPLIST_CHANGED   core.h  /^    PA_CORE_HOOK_SOURCE_PROPLIST_CHANGED,$/;" e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_PUT        core.h  /^    PA_CORE_HOOK_SOURCE_PUT,$/;"      e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_STATE_CHANGED      core.h  /^    PA_CORE_HOOK_SOURCE_STATE_CHANGED,$/;"    e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_UNLINK     core.h  /^    PA_CORE_HOOK_SOURCE_UNLINK,$/;"   e       enum:pa_core_hook
-PA_CORE_HOOK_SOURCE_UNLINK_POST        core.h  /^    PA_CORE_HOOK_SOURCE_UNLINK_POST,$/;"      e       enum:pa_core_hook
-PA_CORE_MESSAGE_MAX    core.h  /^    PA_CORE_MESSAGE_MAX$/;"   e       enum:__anon49
-PA_CORE_MESSAGE_UNLOAD_MODULE  core.h  /^    PA_CORE_MESSAGE_UNLOAD_MODULE,$/;"        e       enum:__anon49
-PA_CORE_RUNNING        core.h  /^    PA_CORE_RUNNING,$/;"      e       enum:pa_core_state
-PA_CORE_SHUTDOWN       core.h  /^    PA_CORE_SHUTDOWN$/;"      e       enum:pa_core_state
-PA_CORE_STARTUP        core.h  /^    PA_CORE_STARTUP,$/;"      e       enum:pa_core_state
-PA_CPU_ARM_EDSP        cpu-arm.h       /^    PA_CPU_ARM_EDSP     = (1 << 3),$/;"       e       enum:pa_cpu_arm_flag
-PA_CPU_ARM_NEON        cpu-arm.h       /^    PA_CPU_ARM_NEON     = (1 << 4),$/;"       e       enum:pa_cpu_arm_flag
-PA_CPU_ARM_V6  cpu-arm.h       /^    PA_CPU_ARM_V6       = (1 << 0),$/;"       e       enum:pa_cpu_arm_flag
-PA_CPU_ARM_V7  cpu-arm.h       /^    PA_CPU_ARM_V7       = (1 << 1),$/;"       e       enum:pa_cpu_arm_flag
-PA_CPU_ARM_VFP cpu-arm.h       /^    PA_CPU_ARM_VFP      = (1 << 2),$/;"       e       enum:pa_cpu_arm_flag
-PA_CPU_ARM_VFPV3       cpu-arm.h       /^    PA_CPU_ARM_VFPV3    = (1 << 5)$/;"        e       enum:pa_cpu_arm_flag
-PA_CPU_X86_3DNOW       cpu-x86.h       /^    PA_CPU_X86_3DNOW     = (1 << 8),$/;"      e       enum:pa_cpu_x86_flag
-PA_CPU_X86_3DNOWEXT    cpu-x86.h       /^    PA_CPU_X86_3DNOWEXT  = (1 << 9)$/;"       e       enum:pa_cpu_x86_flag
-PA_CPU_X86_MMX cpu-x86.h       /^    PA_CPU_X86_MMX       = (1 << 0),$/;"      e       enum:pa_cpu_x86_flag
-PA_CPU_X86_MMXEXT      cpu-x86.h       /^    PA_CPU_X86_MMXEXT    = (1 << 1),$/;"      e       enum:pa_cpu_x86_flag
-PA_CPU_X86_SSE cpu-x86.h       /^    PA_CPU_X86_SSE       = (1 << 2),$/;"      e       enum:pa_cpu_x86_flag
-PA_CPU_X86_SSE2        cpu-x86.h       /^    PA_CPU_X86_SSE2      = (1 << 3),$/;"      e       enum:pa_cpu_x86_flag
-PA_CPU_X86_SSE3        cpu-x86.h       /^    PA_CPU_X86_SSE3      = (1 << 4),$/;"      e       enum:pa_cpu_x86_flag
-PA_CPU_X86_SSE4_1      cpu-x86.h       /^    PA_CPU_X86_SSE4_1    = (1 << 6),$/;"      e       enum:pa_cpu_x86_flag
-PA_CPU_X86_SSE4_2      cpu-x86.h       /^    PA_CPU_X86_SSE4_2    = (1 << 7),$/;"      e       enum:pa_cpu_x86_flag
-PA_CPU_X86_SSSE3       cpu-x86.h       /^    PA_CPU_X86_SSSE3     = (1 << 5),$/;"      e       enum:pa_cpu_x86_flag
-PA_DEBUG_TRAP  macro.h 299;"   d
-PA_DEBUG_TRAP  macro.h 301;"   d
-PA_DECLARE_ALIGNED     macro.h 84;"    d
-PA_DECLARE_ALIGNED     macro.h 86;"    d
-PA_DECLARE_CLASS_COMMON        object.h        73;"    d
-PA_DECLARE_PUBLIC_CLASS        object.h        96;"    d
-PA_DEFINE_PRIVATE_CLASS        object.h        110;"   d
-PA_DEFINE_PUBLIC_CLASS object.h        101;"   d
-PA_DEFINE_RATELIMIT    ratelimit.h     35;"    d
-PA_DEVICE_PORT_DATA    sink.h  63;"    d
-PA_ELEMENTSOF  macro.h 81;"    d
-PA_ENVELOPE_POINTS_MAX envelope.h      30;"    d
-PA_FLAG_SEEKMASK       pstream.c       60;"    d       file:
-PA_FLAG_SHMDATA        pstream.c       56;"    d       file:
-PA_FLAG_SHMMASK        pstream.c       59;"    d       file:
-PA_FLAG_SHMRELEASE     pstream.c       57;"    d       file:
-PA_FLAG_SHMREVOKE      pstream.c       58;"    d       file:
-PA_FLIST_CELLS flist.c 87;"    d       file:
-PA_FLOAT32_SWAP        endianmacros.h  /^static inline float PA_FLOAT32_SWAP(float x) {$/;"    f
-PA_FLOAT32_TO_BE       endianmacros.h  119;"   d
-PA_FLOAT32_TO_BE       endianmacros.h  152;"   d
-PA_FLOAT32_TO_LE       endianmacros.h  118;"   d
-PA_FLOAT32_TO_LE       endianmacros.h  151;"   d
-PA_FLOAT_VECTOR_MAKE   vector.h        54;"    d
-PA_FLOAT_VECTOR_SIZE   vector.h        49;"    d
-PA_GCC_PACKED  shm.c   /^} PA_GCC_PACKED;$/;"  v       typeref:struct:shm_marker
-PA_HASHMAP_FOREACH     hashmap.h       76;"    d
-PA_HASHMAP_FOREACH_BACKWARDS   hashmap.h       80;"    d
-PA_HOOK_CANCEL hook-list.h     /^    PA_HOOK_CANCEL = -1$/;"   e       enum:pa_hook_result
-PA_HOOK_EARLY  hook-list.h     /^    PA_HOOK_EARLY = -100,$/;" e       enum:pa_hook_priority
-PA_HOOK_LATE   hook-list.h     /^    PA_HOOK_LATE = 100$/;"    e       enum:pa_hook_priority
-PA_HOOK_NORMAL hook-list.h     /^    PA_HOOK_NORMAL = 0,$/;"   e       enum:pa_hook_priority
-PA_HOOK_OK     hook-list.h     /^    PA_HOOK_OK = 0,$/;"       e       enum:pa_hook_result
-PA_HOOK_STOP   hook-list.h     /^    PA_HOOK_STOP = 1,$/;"     e       enum:pa_hook_result
-PA_HRTIMER_THRESHOLD_USEC      core-rtclock.h  39;"    d
-PA_IDXSET_FOREACH      idxset.h        110;"   d
-PA_IDXSET_INVALID      idxset.h        36;"    d
-PA_INIT_RATELIMIT      ratelimit.h     44;"    d
-PA_INT16_FROM_BE       endianmacros.h  128;"   d
-PA_INT16_FROM_BE       endianmacros.h  95;"    d
-PA_INT16_FROM_LE       endianmacros.h  127;"   d
-PA_INT16_FROM_LE       endianmacros.h  94;"    d
-PA_INT16_SWAP  endianmacros.h  37;"    d
-PA_INT16_SWAP  endianmacros.h  42;"    d
-PA_INT16_TO_BE endianmacros.h  131;"   d
-PA_INT16_TO_BE endianmacros.h  98;"    d
-PA_INT16_TO_LE endianmacros.h  130;"   d
-PA_INT16_TO_LE endianmacros.h  97;"    d
-PA_INT16_VECTOR_MAKE   vector.h        52;"    d
-PA_INT16_VECTOR_SIZE   vector.h        47;"    d
-PA_INT32_FROM_BE       endianmacros.h  107;"   d
-PA_INT32_FROM_BE       endianmacros.h  140;"   d
-PA_INT32_FROM_LE       endianmacros.h  106;"   d
-PA_INT32_FROM_LE       endianmacros.h  139;"   d
-PA_INT32_SWAP  endianmacros.h  39;"    d
-PA_INT32_SWAP  endianmacros.h  44;"    d
-PA_INT32_TO_BE endianmacros.h  110;"   d
-PA_INT32_TO_BE endianmacros.h  143;"   d
-PA_INT32_TO_LE endianmacros.h  109;"   d
-PA_INT32_TO_LE endianmacros.h  142;"   d
-PA_INT32_TO_PTR        macro.h 275;"   d
-PA_INT32_VECTOR_MAKE   vector.h        53;"    d
-PA_INT32_VECTOR_SIZE   vector.h        48;"    d
-PA_INT_TO_PTR  macro.h 272;"   d
-PA_INT_TYPE_MAX        macro.h 309;"   d
-PA_INT_TYPE_MIN        macro.h 314;"   d
-PA_INT_TYPE_SIGNED     macro.h 307;"   d
-PA_LIKELY      macro.h 42;"    d
-PA_LIKELY      macro.h 45;"    d
-PA_LLIST_FIELDS        llist.h 35;"    d
-PA_LLIST_FIND_HEAD     llist.h 80;"    d
-PA_LLIST_FOREACH       llist.h 107;"   d
-PA_LLIST_FOREACH_SAFE  llist.h 110;"   d
-PA_LLIST_HEAD  llist.h 31;"    d
-PA_LLIST_HEAD_INIT     llist.h 39;"    d
-PA_LLIST_INIT  llist.h 45;"    d
-PA_LLIST_INSERT_AFTER  llist.h 90;"    d
-PA_LLIST_PREPEND       llist.h 53;"    d
-PA_LLIST_REMOVE        llist.h 64;"    d
-PA_LOG_COLORS  log.h   /^    PA_LOG_COLORS      = 0x01, \/* Show colorful output *\/$/;"       e       enum:pa_log_flags
-PA_LOG_DEBUG   log.h   /^    PA_LOG_DEBUG  = 4,    \/* debug message *\/$/;"   e       enum:pa_log_level
-PA_LOG_ERROR   log.h   /^    PA_LOG_ERROR  = 0,    \/* Error messages *\/$/;"  e       enum:pa_log_level
-PA_LOG_INFO    log.h   /^    PA_LOG_INFO   = 3,    \/* Info messages *\/$/;"   e       enum:pa_log_level
-PA_LOG_LEVEL_MAX       log.h   /^    PA_LOG_LEVEL_MAX$/;"      e       enum:pa_log_level
-PA_LOG_NOTICE  log.h   /^    PA_LOG_NOTICE = 2,    \/* Notice messages *\/$/;" e       enum:pa_log_level
-PA_LOG_NULL    log.h   /^    PA_LOG_NULL,    \/* to \/dev\/null *\/$/;"        e       enum:pa_log_target
-PA_LOG_PRINT_FILE      log.h   /^    PA_LOG_PRINT_FILE  = 0x04, \/* Show source file *\/$/;"   e       enum:pa_log_flags
-PA_LOG_PRINT_LEVEL     log.h   /^    PA_LOG_PRINT_LEVEL = 0x10, \/* Show log level prefix *\/$/;"      e       enum:pa_log_flags
-PA_LOG_PRINT_META      log.h   /^    PA_LOG_PRINT_META  = 0x08, \/* Show extended locaton information *\/$/;"  e       enum:pa_log_flags
-PA_LOG_PRINT_TIME      log.h   /^    PA_LOG_PRINT_TIME  = 0x02, \/* Show time *\/$/;"  e       enum:pa_log_flags
-PA_LOG_RESET   log.h   /^    PA_LOG_RESET$/;"  e       enum:pa_log_merge
-PA_LOG_SET     log.h   /^    PA_LOG_SET,$/;"   e       enum:pa_log_merge
-PA_LOG_STDERR  log.h   /^    PA_LOG_STDERR,  \/* default *\/$/;"       e       enum:pa_log_target
-PA_LOG_SYSLOG  log.h   /^    PA_LOG_SYSLOG,$/;"        e       enum:pa_log_target
-PA_LOG_TARGET_MAX      log.h   /^    PA_LOG_TARGET_MAX$/;"     e       enum:pa_log_target
-PA_LOG_UNSET   log.h   /^    PA_LOG_UNSET,$/;" e       enum:pa_log_merge
-PA_LOG_WARN    log.h   /^    PA_LOG_WARN   = 1,    \/* Warning messages *\/$/;"        e       enum:pa_log_level
-PA_MAX macro.h 102;"   d
-PA_MAX macro.h 95;"    d
-PA_MAX_INPUTS_PER_SINK sink.h  47;"    d
-PA_MAX_OUTPUTS_PER_SOURCE      source.h        48;"    d
-PA_MAYBE_FLOAT32_SWAP  endianmacros.h  91;"    d
-PA_MAYBE_INT16_SWAP    endianmacros.h  85;"    d
-PA_MAYBE_INT32_SWAP    endianmacros.h  88;"    d
-PA_MAYBE_UINT16_SWAP   endianmacros.h  86;"    d
-PA_MAYBE_UINT32_SWAP   endianmacros.h  89;"    d
-PA_MEMBLOCK_APPENDED   memblock.h      /^    PA_MEMBLOCK_APPENDED,         \/* the data is appended to the memory block *\/$/;"        e       enum:pa_memblock_type
-PA_MEMBLOCK_FIXED      memblock.h      /^    PA_MEMBLOCK_FIXED,            \/* data is a pointer to fixed memory that needs not to be freed *\/$/;"    e       enum:pa_memblock_type
-PA_MEMBLOCK_IMPORTED   memblock.h      /^    PA_MEMBLOCK_IMPORTED,         \/* Memory is imported from another process via shm *\/$/;" e       enum:pa_memblock_type
-PA_MEMBLOCK_POOL       memblock.h      /^    PA_MEMBLOCK_POOL,             \/* Memory is part of the memory pool *\/$/;"       e       enum:pa_memblock_type
-PA_MEMBLOCK_POOL_EXTERNAL      memblock.h      /^    PA_MEMBLOCK_POOL_EXTERNAL,    \/* Data memory is part of the memory pool but the pa_memblock structure itself not *\/$/;" e       enum:pa_memblock_type
-PA_MEMBLOCK_TYPE_MAX   memblock.h      /^    PA_MEMBLOCK_TYPE_MAX$/;"  e       enum:pa_memblock_type
-PA_MEMBLOCK_USER       memblock.h      /^    PA_MEMBLOCK_USER,             \/* User supplied memory, to be freed with free_cb *\/$/;"  e       enum:pa_memblock_type
-PA_MEMEXPORT_SLOTS_MAX memblock.c      59;"    d       file:
-PA_MEMIMPORT_SEGMENTS_MAX      memblock.c      62;"    d       file:
-PA_MEMIMPORT_SLOTS_MAX memblock.c      61;"    d       file:
-PA_MEMPOOL_SLOTS_MAX   memblock.c      56;"    d       file:
-PA_MEMPOOL_SLOT_SIZE   memblock.c      57;"    d       file:
-PA_MESSAGE_SHUTDOWN    asyncmsgq.h     /^    PA_MESSAGE_SHUTDOWN = -1\/* A generic message to inform the handler of this queue to quit *\/$/;" e       enum:__anon25
-PA_MIN macro.h 106;"   d
-PA_MIN macro.h 113;"   d
-PA_MODULE_AUTHOR       module.h        65;"    d
-PA_MODULE_DEPRECATED   module.h        81;"    d
-PA_MODULE_DESCRIPTION  module.h        69;"    d
-PA_MODULE_LOAD_ONCE    module.h        85;"    d
-PA_MODULE_USAGE        module.h        73;"    d
-PA_MODULE_VERSION      module.h        77;"    d
-PA_MSGOBJECT   msgobject.h     46;"    d
-PA_NAMEREG_CARD        namereg.h       /^    PA_NAMEREG_CARD$/;"       e       enum:pa_namereg_type
-PA_NAMEREG_SAMPLE      namereg.h       /^    PA_NAMEREG_SAMPLE,$/;"    e       enum:pa_namereg_type
-PA_NAMEREG_SINK        namereg.h       /^    PA_NAMEREG_SINK,$/;"      e       enum:pa_namereg_type
-PA_NAMEREG_SOURCE      namereg.h       /^    PA_NAMEREG_SOURCE,$/;"    e       enum:pa_namereg_type
-PA_NAME_MAX    namereg.h       28;"    d
-PA_NATIVE_CONNECTION   protocol-native.c       175;"   d       file:
-PA_NATIVE_COOKIE_FILE  native-common.h 176;"   d
-PA_NATIVE_COOKIE_LENGTH        native-common.h 175;"   d
-PA_NATIVE_COOKIE_PROPERTY_NAME native-common.h 180;"   d
-PA_NATIVE_DEFAULT_PORT native-common.h 178;"   d
-PA_NATIVE_DEFAULT_UNIX_SOCKET  native-common.h 183;"   d
-PA_NATIVE_HOOK_CONNECTION_PUT  protocol-native.h       /^    PA_NATIVE_HOOK_CONNECTION_PUT,$/;"        e       enum:pa_native_hook
-PA_NATIVE_HOOK_CONNECTION_UNLINK       protocol-native.h       /^    PA_NATIVE_HOOK_CONNECTION_UNLINK,$/;"     e       enum:pa_native_hook
-PA_NATIVE_HOOK_MAX     protocol-native.h       /^    PA_NATIVE_HOOK_MAX$/;"    e       enum:pa_native_hook
-PA_NATIVE_HOOK_SERVERS_CHANGED protocol-native.h       /^    PA_NATIVE_HOOK_SERVERS_CHANGED,$/;"       e       enum:pa_native_hook
-PA_NATIVE_SERVER_PROPERTY_NAME native-common.h 181;"   d
-PA_OBJECT      object.h        71;"    d
-PA_ONCE_BEGIN  once.h  44;"    d
-PA_ONCE_END    once.h  49;"    d
-PA_ONCE_INIT   once.h  33;"    d
-PA_PACKET_APPENDED     packet.h        /^    enum { PA_PACKET_APPENDED, PA_PACKET_DYNAMIC } type;$/;"  e       enum:pa_packet::__anon26
-PA_PACKET_DYNAMIC      packet.h        /^    enum { PA_PACKET_APPENDED, PA_PACKET_DYNAMIC } type;$/;"  e       enum:pa_packet::__anon26
-PA_PAGE_ALIGN  macro.h /^static inline size_t PA_PAGE_ALIGN(size_t l) {$/;"    f
-PA_PAGE_ALIGN_PTR      macro.h /^static inline void* PA_PAGE_ALIGN_PTR(const void *p) {$/;"    f
-PA_PAGE_SIZE   macro.h 51;"    d
-PA_PAGE_SIZE   macro.h 53;"    d
-PA_PAGE_SIZE   macro.h 55;"    d
-PA_PAGE_SIZE   macro.h 58;"    d
-PA_PARSED_ADDRESS_TCP4 parseaddr.h     /^    PA_PARSED_ADDRESS_TCP4,$/;"       e       enum:pa_parsed_address_type
-PA_PARSED_ADDRESS_TCP6 parseaddr.h     /^    PA_PARSED_ADDRESS_TCP6,$/;"       e       enum:pa_parsed_address_type
-PA_PARSED_ADDRESS_TCP_AUTO     parseaddr.h     /^    PA_PARSED_ADDRESS_TCP_AUTO$/;"    e       enum:pa_parsed_address_type
-PA_PARSED_ADDRESS_UNIX parseaddr.h     /^    PA_PARSED_ADDRESS_UNIX,$/;"       e       enum:pa_parsed_address_type
-PA_PATH_SEP    macro.h 278;"   d
-PA_PATH_SEP    macro.h 281;"   d
-PA_PATH_SEP_CHAR       macro.h 279;"   d
-PA_PATH_SEP_CHAR       macro.h 282;"   d
-PA_PRETTY_FUNCTION     macro.h 193;"   d
-PA_PRETTY_FUNCTION     macro.h 195;"   d
-PA_PSTREAM_DESCRIPTOR_CHANNEL  pstream.c       /^    PA_PSTREAM_DESCRIPTOR_CHANNEL,$/;"        e       enum:__anon31   file:
-PA_PSTREAM_DESCRIPTOR_FLAGS    pstream.c       /^    PA_PSTREAM_DESCRIPTOR_FLAGS,$/;"  e       enum:__anon31   file:
-PA_PSTREAM_DESCRIPTOR_LENGTH   pstream.c       /^    PA_PSTREAM_DESCRIPTOR_LENGTH,$/;" e       enum:__anon31   file:
-PA_PSTREAM_DESCRIPTOR_MAX      pstream.c       /^    PA_PSTREAM_DESCRIPTOR_MAX$/;"     e       enum:__anon31   file:
-PA_PSTREAM_DESCRIPTOR_OFFSET_HI        pstream.c       /^    PA_PSTREAM_DESCRIPTOR_OFFSET_HI,$/;"      e       enum:__anon31   file:
-PA_PSTREAM_DESCRIPTOR_OFFSET_LO        pstream.c       /^    PA_PSTREAM_DESCRIPTOR_OFFSET_LO,$/;"      e       enum:__anon31   file:
-PA_PSTREAM_DESCRIPTOR_SIZE     pstream.c       83;"    d       file:
-PA_PSTREAM_ITEM_MEMBLOCK       pstream.c       /^        PA_PSTREAM_ITEM_MEMBLOCK,$/;" e       enum:item_info::__anon33        file:
-PA_PSTREAM_ITEM_PACKET pstream.c       /^        PA_PSTREAM_ITEM_PACKET,$/;"   e       enum:item_info::__anon33        file:
-PA_PSTREAM_ITEM_SHMRELEASE     pstream.c       /^        PA_PSTREAM_ITEM_SHMRELEASE,$/;"       e       enum:item_info::__anon33        file:
-PA_PSTREAM_ITEM_SHMREVOKE      pstream.c       /^        PA_PSTREAM_ITEM_SHMREVOKE$/;" e       enum:item_info::__anon33        file:
-PA_PSTREAM_SHM_BLOCKID pstream.c       /^    PA_PSTREAM_SHM_BLOCKID,$/;"       e       enum:__anon32   file:
-PA_PSTREAM_SHM_INDEX   pstream.c       /^    PA_PSTREAM_SHM_INDEX,$/;" e       enum:__anon32   file:
-PA_PSTREAM_SHM_LENGTH  pstream.c       /^    PA_PSTREAM_SHM_LENGTH,$/;"        e       enum:__anon32   file:
-PA_PSTREAM_SHM_MAX     pstream.c       /^    PA_PSTREAM_SHM_MAX$/;"    e       enum:__anon32   file:
-PA_PSTREAM_SHM_SHMID   pstream.c       /^    PA_PSTREAM_SHM_SHMID,$/;" e       enum:__anon32   file:
-PA_PTR_TO_INT  macro.h 271;"   d
-PA_PTR_TO_INT32        macro.h 274;"   d
-PA_PTR_TO_UINT macro.h 265;"   d
-PA_PTR_TO_UINT32       macro.h 268;"   d
-PA_READ24BE    endianmacros.h  /^static inline uint32_t PA_READ24BE(const uint8_t *p) {$/;"    f
-PA_READ24LE    endianmacros.h  /^static inline uint32_t PA_READ24LE(const uint8_t *p) {$/;"    f
-PA_READ24NE    endianmacros.h  121;"   d
-PA_READ24NE    endianmacros.h  154;"   d
-PA_READ24RE    endianmacros.h  124;"   d
-PA_READ24RE    endianmacros.h  157;"   d
-PA_REFCNT_DEC  refcnt.h        48;"    d
-PA_REFCNT_DEC  refcnt.h        69;"    d
-PA_REFCNT_DECLARE      asyncmsgq.c     /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_asyncmsgq     file:
-PA_REFCNT_DECLARE      auth-cookie.c   /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_auth_cookie   file:
-PA_REFCNT_DECLARE      dbus-shared.c   /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_dbus_connection       file:
-PA_REFCNT_DECLARE      ioline.c        /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_ioline        file:
-PA_REFCNT_DECLARE      memblock.c      /^    PA_REFCNT_DECLARE; \/* the reference counter *\/$/;"      m       struct:pa_memblock      file:
-PA_REFCNT_DECLARE      object.h        /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_object
-PA_REFCNT_DECLARE      packet.h        /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_packet
-PA_REFCNT_DECLARE      pdispatch.c     /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_pdispatch     file:
-PA_REFCNT_DECLARE      protocol-cli.c  /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_cli_protocol  file:
-PA_REFCNT_DECLARE      protocol-esound.c       /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_esound_protocol       file:
-PA_REFCNT_DECLARE      protocol-esound.h       /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_esound_options
-PA_REFCNT_DECLARE      protocol-http.c /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_http_protocol file:
-PA_REFCNT_DECLARE      protocol-native.c       /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_native_protocol       file:
-PA_REFCNT_DECLARE      protocol-native.h       /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_native_options
-PA_REFCNT_DECLARE      protocol-simple.c       /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_simple_protocol       file:
-PA_REFCNT_DECLARE      protocol-simple.h       /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_simple_options
-PA_REFCNT_DECLARE      pstream.c       /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_pstream       file:
-PA_REFCNT_DECLARE      refcnt.h        31;"    d
-PA_REFCNT_DECLARE      socket-client.c /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_socket_client file:
-PA_REFCNT_DECLARE      socket-server.c /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_socket_server file:
-PA_REFCNT_DECLARE      x11wrap.c       /^    PA_REFCNT_DECLARE;$/;"    m       struct:pa_x11_wrapper   file:
-PA_REFCNT_INC  refcnt.h        45;"    d
-PA_REFCNT_INC  refcnt.h        63;"    d
-PA_REFCNT_INIT refcnt.h        42;"    d
-PA_REFCNT_INIT refcnt.h        57;"    d
-PA_REFCNT_INIT_ZERO    refcnt.h        37;"    d
-PA_REFCNT_VALUE        refcnt.h        34;"    d
-PA_REG_D       cpu-x86.h       50;"    d
-PA_REG_D       cpu-x86.h       58;"    d
-PA_REG_S       cpu-x86.h       51;"    d
-PA_REG_S       cpu-x86.h       59;"    d
-PA_REG_a       cpu-x86.h       46;"    d
-PA_REG_a       cpu-x86.h       54;"    d
-PA_REG_b       cpu-x86.h       47;"    d
-PA_REG_b       cpu-x86.h       55;"    d
-PA_REG_c       cpu-x86.h       48;"    d
-PA_REG_c       cpu-x86.h       56;"    d
-PA_REG_d       cpu-x86.h       49;"    d
-PA_REG_d       cpu-x86.h       57;"    d
-PA_RESAMPLER_AUTO      resampler.h     /^    PA_RESAMPLER_AUTO, \/* automatic select based on sample format *\/$/;"    e       enum:pa_resample_method
-PA_RESAMPLER_COPY      resampler.h     /^    PA_RESAMPLER_COPY,$/;"    e       enum:pa_resample_method
-PA_RESAMPLER_FFMPEG    resampler.h     /^    PA_RESAMPLER_FFMPEG,$/;"  e       enum:pa_resample_method
-PA_RESAMPLER_INVALID   resampler.h     /^    PA_RESAMPLER_INVALID                 = -1,$/;"    e       enum:pa_resample_method
-PA_RESAMPLER_MAX       resampler.h     /^    PA_RESAMPLER_MAX$/;"      e       enum:pa_resample_method
-PA_RESAMPLER_NO_LFE    resampler.h     /^    PA_RESAMPLER_NO_LFE        = 0x0008U$/;"  e       enum:pa_resample_flags
-PA_RESAMPLER_NO_REMAP  resampler.h     /^    PA_RESAMPLER_NO_REMAP      = 0x0002U,  \/* implies NO_REMIX *\/$/;"       e       enum:pa_resample_flags
-PA_RESAMPLER_NO_REMIX  resampler.h     /^    PA_RESAMPLER_NO_REMIX      = 0x0004U,$/;" e       enum:pa_resample_flags
-PA_RESAMPLER_PEAKS     resampler.h     /^    PA_RESAMPLER_PEAKS,$/;"   e       enum:pa_resample_method
-PA_RESAMPLER_SPEEX_FIXED_BASE  resampler.h     /^    PA_RESAMPLER_SPEEX_FIXED_BASE,$/;"        e       enum:pa_resample_method
-PA_RESAMPLER_SPEEX_FIXED_MAX   resampler.h     /^    PA_RESAMPLER_SPEEX_FIXED_MAX = PA_RESAMPLER_SPEEX_FIXED_BASE + 10,$/;"    e       enum:pa_resample_method
-PA_RESAMPLER_SPEEX_FLOAT_BASE  resampler.h     /^    PA_RESAMPLER_SPEEX_FLOAT_BASE,$/;"        e       enum:pa_resample_method
-PA_RESAMPLER_SPEEX_FLOAT_MAX   resampler.h     /^    PA_RESAMPLER_SPEEX_FLOAT_MAX = PA_RESAMPLER_SPEEX_FLOAT_BASE + 10,$/;"    e       enum:pa_resample_method
-PA_RESAMPLER_SRC_LINEAR        resampler.h     /^    PA_RESAMPLER_SRC_LINEAR              = 4, \/* = SRC_LINEAR *\/$/;"        e       enum:pa_resample_method
-PA_RESAMPLER_SRC_SINC_BEST_QUALITY     resampler.h     /^    PA_RESAMPLER_SRC_SINC_BEST_QUALITY   = 0, \/* = SRC_SINC_BEST_QUALITY *\/$/;"     e       enum:pa_resample_method
-PA_RESAMPLER_SRC_SINC_FASTEST  resampler.h     /^    PA_RESAMPLER_SRC_SINC_FASTEST        = 2, \/* = SRC_SINC_FASTEST *\/$/;"  e       enum:pa_resample_method
-PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY   resampler.h     /^    PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY = 1, \/* = SRC_SINC_MEDIUM_QUALITY *\/$/;"   e       enum:pa_resample_method
-PA_RESAMPLER_SRC_ZERO_ORDER_HOLD       resampler.h     /^    PA_RESAMPLER_SRC_ZERO_ORDER_HOLD     = 3, \/* = SRC_ZERO_ORDER_HOLD *\/$/;"       e       enum:pa_resample_method
-PA_RESAMPLER_TRIVIAL   resampler.h     /^    PA_RESAMPLER_TRIVIAL,$/;" e       enum:pa_resample_method
-PA_RESAMPLER_VARIABLE_RATE     resampler.h     /^    PA_RESAMPLER_VARIABLE_RATE = 0x0001U,$/;" e       enum:pa_resample_flags
-PA_ROUND_DOWN  macro.h 156;"   d
-PA_ROUND_DOWN  macro.h 163;"   d
-PA_ROUND_UP    macro.h 145;"   d
-PA_ROUND_UP    macro.h 152;"   d
-PA_RTPOLL_EARLY        rtpoll.h        /^    PA_RTPOLL_EARLY  = -100,          \/* For veeery important stuff, like handling control messages *\/$/;"  e       enum:pa_rtpoll_priority
-PA_RTPOLL_LATE rtpoll.h        /^    PA_RTPOLL_LATE   = +100,          \/* For housekeeping *\/$/;"    e       enum:pa_rtpoll_priority
-PA_RTPOLL_NEVER        rtpoll.h        /^    PA_RTPOLL_NEVER  = INT_MAX,       \/* For stuff that doesn't register any callbacks, but only fds to listen on *\/$/;"    e       enum:pa_rtpoll_priority
-PA_RTPOLL_NORMAL       rtpoll.h        /^    PA_RTPOLL_NORMAL = 0,             \/* For normal stuff *\/$/;"    e       enum:pa_rtpoll_priority
-PA_SCACHE_ENTRY_SIZE_MAX       core-scache.h   30;"    d
-PA_SILENCE_MAX sample-util.c   44;"    d       file:
-PA_SINK        sink.h  197;"   d
-PA_SINK_INPUT  sink-input.h    241;"   d
-PA_SINK_INPUT_CORKED   sink-input.h    /^    PA_SINK_INPUT_CORKED,       \/*< The stream was corked on user request *\/$/;"    e       enum:pa_sink_input_state
-PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND        sink-input.h    /^    PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND = 256,$/;"        e       enum:pa_sink_input_flags
-PA_SINK_INPUT_DONT_MOVE        sink-input.h    /^    PA_SINK_INPUT_DONT_MOVE = 2,$/;"  e       enum:pa_sink_input_flags
-PA_SINK_INPUT_DRAINED  sink-input.h    /^    PA_SINK_INPUT_DRAINED,      \/*< The stream stopped playing because there was no data to play *\/$/;"     e       enum:pa_sink_input_state
-PA_SINK_INPUT_FIX_CHANNELS     sink-input.h    /^    PA_SINK_INPUT_FIX_CHANNELS = 128,$/;"     e       enum:pa_sink_input_flags
-PA_SINK_INPUT_FIX_FORMAT       sink-input.h    /^    PA_SINK_INPUT_FIX_FORMAT = 32,$/;"        e       enum:pa_sink_input_flags
-PA_SINK_INPUT_FIX_RATE sink-input.h    /^    PA_SINK_INPUT_FIX_RATE = 64,$/;"  e       enum:pa_sink_input_flags
-PA_SINK_INPUT_INIT     sink-input.h    /^    PA_SINK_INPUT_INIT,         \/*< The stream is not active yet, because pa_sink_put() has not been called yet *\/$/;"      e       enum:pa_sink_input_state
-PA_SINK_INPUT_IS_LINKED        sink-input.h    /^static inline pa_bool_t PA_SINK_INPUT_IS_LINKED(pa_sink_input_state_t x) {$/;"        f
-PA_SINK_INPUT_KILL_ON_SUSPEND  sink-input.h    /^    PA_SINK_INPUT_KILL_ON_SUSPEND = 1024$/;"  e       enum:pa_sink_input_flags
-PA_SINK_INPUT_MESSAGE_GET_LATENCY      sink-input.h    /^    PA_SINK_INPUT_MESSAGE_GET_LATENCY,$/;"    e       enum:__anon28
-PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY    sink-input.h    /^    PA_SINK_INPUT_MESSAGE_GET_REQUESTED_LATENCY,$/;"  e       enum:__anon28
-PA_SINK_INPUT_MESSAGE_MAX      sink-input.h    /^    PA_SINK_INPUT_MESSAGE_MAX$/;"     e       enum:__anon28
-PA_SINK_INPUT_MESSAGE_SET_RATE sink-input.h    /^    PA_SINK_INPUT_MESSAGE_SET_RATE,$/;"       e       enum:__anon28
-PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY    sink-input.h    /^    PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY,$/;"  e       enum:__anon28
-PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE    sink-input.h    /^    PA_SINK_INPUT_MESSAGE_SET_SOFT_MUTE,$/;"  e       enum:__anon28
-PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME  sink-input.h    /^    PA_SINK_INPUT_MESSAGE_SET_SOFT_VOLUME,$/;"        e       enum:__anon28
-PA_SINK_INPUT_MESSAGE_SET_STATE        sink-input.h    /^    PA_SINK_INPUT_MESSAGE_SET_STATE,$/;"      e       enum:__anon28
-PA_SINK_INPUT_NO_CREATE_ON_SUSPEND     sink-input.h    /^    PA_SINK_INPUT_NO_CREATE_ON_SUSPEND = 512,$/;"     e       enum:pa_sink_input_flags
-PA_SINK_INPUT_NO_REMAP sink-input.h    /^    PA_SINK_INPUT_NO_REMAP = 8,$/;"   e       enum:pa_sink_input_flags
-PA_SINK_INPUT_NO_REMIX sink-input.h    /^    PA_SINK_INPUT_NO_REMIX = 16,$/;"  e       enum:pa_sink_input_flags
-PA_SINK_INPUT_RUNNING  sink-input.h    /^    PA_SINK_INPUT_RUNNING,      \/*< The stream is alive and kicking *\/$/;"  e       enum:pa_sink_input_state
-PA_SINK_INPUT_START_CORKED     sink-input.h    /^    PA_SINK_INPUT_START_CORKED = 4,$/;"       e       enum:pa_sink_input_flags
-PA_SINK_INPUT_UNLINKED sink-input.h    /^    PA_SINK_INPUT_UNLINKED      \/*< The stream is dead *\/$/;"       e       enum:pa_sink_input_state
-PA_SINK_INPUT_VARIABLE_RATE    sink-input.h    /^    PA_SINK_INPUT_VARIABLE_RATE = 1,$/;"      e       enum:pa_sink_input_flags
-PA_SINK_IS_LINKED      sink.h  /^static inline pa_bool_t PA_SINK_IS_LINKED(pa_sink_state_t x) {$/;"    f
-PA_SINK_MESSAGE_ADD_INPUT      sink.h  /^    PA_SINK_MESSAGE_ADD_INPUT,$/;"    e       enum:pa_sink_message
-PA_SINK_MESSAGE_ATTACH sink.h  /^    PA_SINK_MESSAGE_ATTACH,$/;"       e       enum:pa_sink_message
-PA_SINK_MESSAGE_DETACH sink.h  /^    PA_SINK_MESSAGE_DETACH,$/;"       e       enum:pa_sink_message
-PA_SINK_MESSAGE_FINISH_MOVE    sink.h  /^    PA_SINK_MESSAGE_FINISH_MOVE,$/;"  e       enum:pa_sink_message
-PA_SINK_MESSAGE_GET_FIXED_LATENCY      sink.h  /^    PA_SINK_MESSAGE_GET_FIXED_LATENCY,$/;"    e       enum:pa_sink_message
-PA_SINK_MESSAGE_GET_LATENCY    sink.h  /^    PA_SINK_MESSAGE_GET_LATENCY,$/;"  e       enum:pa_sink_message
-PA_SINK_MESSAGE_GET_LATENCY_RANGE      sink.h  /^    PA_SINK_MESSAGE_GET_LATENCY_RANGE,$/;"    e       enum:pa_sink_message
-PA_SINK_MESSAGE_GET_MAX_REQUEST        sink.h  /^    PA_SINK_MESSAGE_GET_MAX_REQUEST,$/;"      e       enum:pa_sink_message
-PA_SINK_MESSAGE_GET_MAX_REWIND sink.h  /^    PA_SINK_MESSAGE_GET_MAX_REWIND,$/;"       e       enum:pa_sink_message
-PA_SINK_MESSAGE_GET_MUTE       sink.h  /^    PA_SINK_MESSAGE_GET_MUTE,$/;"     e       enum:pa_sink_message
-PA_SINK_MESSAGE_GET_REQUESTED_LATENCY  sink.h  /^    PA_SINK_MESSAGE_GET_REQUESTED_LATENCY,$/;"        e       enum:pa_sink_message
-PA_SINK_MESSAGE_GET_VOLUME     sink.h  /^    PA_SINK_MESSAGE_GET_VOLUME,$/;"   e       enum:pa_sink_message
-PA_SINK_MESSAGE_MAX    sink.h  /^    PA_SINK_MESSAGE_MAX$/;"   e       enum:pa_sink_message
-PA_SINK_MESSAGE_REMOVE_INPUT   sink.h  /^    PA_SINK_MESSAGE_REMOVE_INPUT,$/;" e       enum:pa_sink_message
-PA_SINK_MESSAGE_SET_FIXED_LATENCY      sink.h  /^    PA_SINK_MESSAGE_SET_FIXED_LATENCY,$/;"    e       enum:pa_sink_message
-PA_SINK_MESSAGE_SET_LATENCY_RANGE      sink.h  /^    PA_SINK_MESSAGE_SET_LATENCY_RANGE,$/;"    e       enum:pa_sink_message
-PA_SINK_MESSAGE_SET_MAX_REQUEST        sink.h  /^    PA_SINK_MESSAGE_SET_MAX_REQUEST,$/;"      e       enum:pa_sink_message
-PA_SINK_MESSAGE_SET_MAX_REWIND sink.h  /^    PA_SINK_MESSAGE_SET_MAX_REWIND,$/;"       e       enum:pa_sink_message
-PA_SINK_MESSAGE_SET_MUTE       sink.h  /^    PA_SINK_MESSAGE_SET_MUTE,$/;"     e       enum:pa_sink_message
-PA_SINK_MESSAGE_SET_STATE      sink.h  /^    PA_SINK_MESSAGE_SET_STATE,$/;"    e       enum:pa_sink_message
-PA_SINK_MESSAGE_SET_VOLUME     sink.h  /^    PA_SINK_MESSAGE_SET_VOLUME,$/;"   e       enum:pa_sink_message
-PA_SINK_MESSAGE_START_MOVE     sink.h  /^    PA_SINK_MESSAGE_START_MOVE,$/;"   e       enum:pa_sink_message
-PA_SINK_MESSAGE_SYNC_VOLUMES   sink.h  /^    PA_SINK_MESSAGE_SYNC_VOLUMES,$/;" e       enum:pa_sink_message
-PA_SOURCE      source.h        164;"   d
-PA_SOURCE_IS_LINKED    source.h        /^static inline pa_bool_t PA_SOURCE_IS_LINKED(pa_source_state_t x) {$/;"        f
-PA_SOURCE_MESSAGE_ADD_OUTPUT   source.h        /^    PA_SOURCE_MESSAGE_ADD_OUTPUT,$/;" e       enum:pa_source_message
-PA_SOURCE_MESSAGE_ATTACH       source.h        /^    PA_SOURCE_MESSAGE_ATTACH,$/;"     e       enum:pa_source_message
-PA_SOURCE_MESSAGE_DETACH       source.h        /^    PA_SOURCE_MESSAGE_DETACH,$/;"     e       enum:pa_source_message
-PA_SOURCE_MESSAGE_GET_FIXED_LATENCY    source.h        /^    PA_SOURCE_MESSAGE_GET_FIXED_LATENCY,$/;"  e       enum:pa_source_message
-PA_SOURCE_MESSAGE_GET_LATENCY  source.h        /^    PA_SOURCE_MESSAGE_GET_LATENCY,$/;"        e       enum:pa_source_message
-PA_SOURCE_MESSAGE_GET_LATENCY_RANGE    source.h        /^    PA_SOURCE_MESSAGE_GET_LATENCY_RANGE,$/;"  e       enum:pa_source_message
-PA_SOURCE_MESSAGE_GET_MAX_REWIND       source.h        /^    PA_SOURCE_MESSAGE_GET_MAX_REWIND,$/;"     e       enum:pa_source_message
-PA_SOURCE_MESSAGE_GET_MUTE     source.h        /^    PA_SOURCE_MESSAGE_GET_MUTE,$/;"   e       enum:pa_source_message
-PA_SOURCE_MESSAGE_GET_REQUESTED_LATENCY        source.h        /^    PA_SOURCE_MESSAGE_GET_REQUESTED_LATENCY,$/;"      e       enum:pa_source_message
-PA_SOURCE_MESSAGE_GET_VOLUME   source.h        /^    PA_SOURCE_MESSAGE_GET_VOLUME,$/;" e       enum:pa_source_message
-PA_SOURCE_MESSAGE_MAX  source.h        /^    PA_SOURCE_MESSAGE_MAX$/;" e       enum:pa_source_message
-PA_SOURCE_MESSAGE_REMOVE_OUTPUT        source.h        /^    PA_SOURCE_MESSAGE_REMOVE_OUTPUT,$/;"      e       enum:pa_source_message
-PA_SOURCE_MESSAGE_SET_FIXED_LATENCY    source.h        /^    PA_SOURCE_MESSAGE_SET_FIXED_LATENCY,$/;"  e       enum:pa_source_message
-PA_SOURCE_MESSAGE_SET_LATENCY_RANGE    source.h        /^    PA_SOURCE_MESSAGE_SET_LATENCY_RANGE,$/;"  e       enum:pa_source_message
-PA_SOURCE_MESSAGE_SET_MAX_REWIND       source.h        /^    PA_SOURCE_MESSAGE_SET_MAX_REWIND,$/;"     e       enum:pa_source_message
-PA_SOURCE_MESSAGE_SET_MUTE     source.h        /^    PA_SOURCE_MESSAGE_SET_MUTE,$/;"   e       enum:pa_source_message
-PA_SOURCE_MESSAGE_SET_STATE    source.h        /^    PA_SOURCE_MESSAGE_SET_STATE,$/;"  e       enum:pa_source_message
-PA_SOURCE_MESSAGE_SET_VOLUME   source.h        /^    PA_SOURCE_MESSAGE_SET_VOLUME,$/;" e       enum:pa_source_message
-PA_SOURCE_OUTPUT       source-output.h 186;"   d
-PA_SOURCE_OUTPUT_CORKED        source-output.h /^    PA_SOURCE_OUTPUT_CORKED,$/;"      e       enum:pa_source_output_state
-PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND     source-output.h /^    PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND = 256,$/;"     e       enum:pa_source_output_flags
-PA_SOURCE_OUTPUT_DONT_MOVE     source-output.h /^    PA_SOURCE_OUTPUT_DONT_MOVE = 2,$/;"       e       enum:pa_source_output_flags
-PA_SOURCE_OUTPUT_FIX_CHANNELS  source-output.h /^    PA_SOURCE_OUTPUT_FIX_CHANNELS = 128,$/;"  e       enum:pa_source_output_flags
-PA_SOURCE_OUTPUT_FIX_FORMAT    source-output.h /^    PA_SOURCE_OUTPUT_FIX_FORMAT = 32,$/;"     e       enum:pa_source_output_flags
-PA_SOURCE_OUTPUT_FIX_RATE      source-output.h /^    PA_SOURCE_OUTPUT_FIX_RATE = 64,$/;"       e       enum:pa_source_output_flags
-PA_SOURCE_OUTPUT_INIT  source-output.h /^    PA_SOURCE_OUTPUT_INIT,$/;"        e       enum:pa_source_output_state
-PA_SOURCE_OUTPUT_IS_LINKED     source-output.h /^static inline pa_bool_t PA_SOURCE_OUTPUT_IS_LINKED(pa_source_output_state_t x) {$/;"  f
-PA_SOURCE_OUTPUT_KILL_ON_SUSPEND       source-output.h /^    PA_SOURCE_OUTPUT_KILL_ON_SUSPEND = 1024$/;"       e       enum:pa_source_output_flags
-PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY   source-output.h /^    PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY,$/;" e       enum:__anon16
-PA_SOURCE_OUTPUT_MESSAGE_GET_REQUESTED_LATENCY source-output.h /^    PA_SOURCE_OUTPUT_MESSAGE_GET_REQUESTED_LATENCY,$/;"       e       enum:__anon16
-PA_SOURCE_OUTPUT_MESSAGE_MAX   source-output.h /^    PA_SOURCE_OUTPUT_MESSAGE_MAX$/;"  e       enum:__anon16
-PA_SOURCE_OUTPUT_MESSAGE_SET_RATE      source-output.h /^    PA_SOURCE_OUTPUT_MESSAGE_SET_RATE,$/;"    e       enum:__anon16
-PA_SOURCE_OUTPUT_MESSAGE_SET_REQUESTED_LATENCY source-output.h /^    PA_SOURCE_OUTPUT_MESSAGE_SET_REQUESTED_LATENCY,$/;"       e       enum:__anon16
-PA_SOURCE_OUTPUT_MESSAGE_SET_STATE     source-output.h /^    PA_SOURCE_OUTPUT_MESSAGE_SET_STATE,$/;"   e       enum:__anon16
-PA_SOURCE_OUTPUT_NO_CREATE_ON_SUSPEND  source-output.h /^    PA_SOURCE_OUTPUT_NO_CREATE_ON_SUSPEND = 512,$/;"  e       enum:pa_source_output_flags
-PA_SOURCE_OUTPUT_NO_REMAP      source-output.h /^    PA_SOURCE_OUTPUT_NO_REMAP = 8,$/;"        e       enum:pa_source_output_flags
-PA_SOURCE_OUTPUT_NO_REMIX      source-output.h /^    PA_SOURCE_OUTPUT_NO_REMIX = 16,$/;"       e       enum:pa_source_output_flags
-PA_SOURCE_OUTPUT_RUNNING       source-output.h /^    PA_SOURCE_OUTPUT_RUNNING,$/;"     e       enum:pa_source_output_state
-PA_SOURCE_OUTPUT_START_CORKED  source-output.h /^    PA_SOURCE_OUTPUT_START_CORKED = 4,$/;"    e       enum:pa_source_output_flags
-PA_SOURCE_OUTPUT_UNLINKED      source-output.h /^    PA_SOURCE_OUTPUT_UNLINKED$/;"     e       enum:pa_source_output_state
-PA_SOURCE_OUTPUT_VARIABLE_RATE source-output.h /^    PA_SOURCE_OUTPUT_VARIABLE_RATE = 1,$/;"   e       enum:pa_source_output_flags
-PA_STATIC_FLIST_DECLARE        flist.h 46;"    d
-PA_STATIC_FLIST_GET    flist.h 67;"    d
-PA_STATIC_MUTEX_INIT   mutex.h 55;"    d
-PA_STATIC_SEMAPHORE_INIT       semaphore.h     43;"    d
-PA_STATIC_TLS_DECLARE  thread.h        55;"    d
-PA_STATIC_TLS_DECLARE_NO_FREE  thread.h        107;"   d
-PA_STATIC_TLS_DECLARE_NO_FREE  thread.h        95;"    d
-PA_STATIC_TLS_GET      thread.h        110;"   d
-PA_STATIC_TLS_SET      thread.h        111;"   d
-PA_SUSPEND_ALL core.h  /^    PA_SUSPEND_ALL = 0xFFFF      \/* Magic cause that can be used to resume forcibly *\/$/;"  e       enum:pa_suspend_cause
-PA_SUSPEND_APPLICATION core.h  /^    PA_SUSPEND_APPLICATION = 2,  \/* Used by the device reservation logic *\/$/;"     e       enum:pa_suspend_cause
-PA_SUSPEND_IDLE        core.h  /^    PA_SUSPEND_IDLE = 4,         \/* Used by module-suspend-on-idle *\/$/;"   e       enum:pa_suspend_cause
-PA_SUSPEND_SESSION     core.h  /^    PA_SUSPEND_SESSION = 8,      \/* Used by module-hal for mark inactive sessions *\/$/;"    e       enum:pa_suspend_cause
-PA_SUSPEND_USER        core.h  /^    PA_SUSPEND_USER = 1,         \/* Exposed to the user via some protocol *\/$/;"    e       enum:pa_suspend_cause
-PA_SYMBOL_AUTHOR       modinfo.c       37;"    d       file:
-PA_SYMBOL_DEPRECATED   modinfo.c       41;"    d       file:
-PA_SYMBOL_DESCRIPTION  modinfo.c       38;"    d       file:
-PA_SYMBOL_DONE module.c        48;"    d       file:
-PA_SYMBOL_GET_DEPRECATE        module.c        51;"    d       file:
-PA_SYMBOL_GET_N_USED   module.c        50;"    d       file:
-PA_SYMBOL_INIT module.c        47;"    d       file:
-PA_SYMBOL_LOAD_ONCE    modinfo.c       42;"    d       file:
-PA_SYMBOL_LOAD_ONCE    module.c        49;"    d       file:
-PA_SYMBOL_USAGE        modinfo.c       39;"    d       file:
-PA_SYMBOL_VERSION      modinfo.c       40;"    d       file:
-PA_TAG_ARBITRARY       tagstruct.h     /^    PA_TAG_ARBITRARY = 'x',$/;"       e       enum:__anon3
-PA_TAG_BOOLEAN tagstruct.h     /^    PA_TAG_BOOLEAN = PA_TAG_BOOLEAN_TRUE,$/;" e       enum:__anon3
-PA_TAG_BOOLEAN_FALSE   tagstruct.h     /^    PA_TAG_BOOLEAN_FALSE = '0',$/;"   e       enum:__anon3
-PA_TAG_BOOLEAN_TRUE    tagstruct.h     /^    PA_TAG_BOOLEAN_TRUE = '1',$/;"    e       enum:__anon3
-PA_TAG_CHANNEL_MAP     tagstruct.h     /^    PA_TAG_CHANNEL_MAP = 'm',$/;"     e       enum:__anon3
-PA_TAG_CVOLUME tagstruct.h     /^    PA_TAG_CVOLUME = 'v',$/;" e       enum:__anon3
-PA_TAG_INVALID tagstruct.h     /^    PA_TAG_INVALID = 0,$/;"   e       enum:__anon3
-PA_TAG_PROPLIST        tagstruct.h     /^    PA_TAG_PROPLIST = 'P',$/;"        e       enum:__anon3
-PA_TAG_S64     tagstruct.h     /^    PA_TAG_S64 = 'r',$/;"     e       enum:__anon3
-PA_TAG_SAMPLE_SPEC     tagstruct.h     /^    PA_TAG_SAMPLE_SPEC = 'a',$/;"     e       enum:__anon3
-PA_TAG_STRING  tagstruct.h     /^    PA_TAG_STRING = 't',$/;"  e       enum:__anon3
-PA_TAG_STRING_NULL     tagstruct.h     /^    PA_TAG_STRING_NULL = 'N',$/;"     e       enum:__anon3
-PA_TAG_TIMEVAL tagstruct.h     /^    PA_TAG_TIMEVAL = 'T',$/;" e       enum:__anon3
-PA_TAG_U32     tagstruct.h     /^    PA_TAG_U32 = 'L',$/;"     e       enum:__anon3
-PA_TAG_U64     tagstruct.h     /^    PA_TAG_U64 = 'R',$/;"     e       enum:__anon3
-PA_TAG_U8      tagstruct.h     /^    PA_TAG_U8 = 'B',$/;"      e       enum:__anon3
-PA_TAG_USEC    tagstruct.h     /^    PA_TAG_USEC = 'U'  \/* 64bit unsigned *\/,$/;"    e       enum:__anon3
-PA_TAG_VOLUME  tagstruct.h     /^    PA_TAG_VOLUME = 'V'$/;"   e       enum:__anon3
-PA_TIMEVAL_RTCLOCK     core-rtclock.h  42;"    d
-PA_UINT16_FROM_BE      endianmacros.h  101;"   d
-PA_UINT16_FROM_BE      endianmacros.h  134;"   d
-PA_UINT16_FROM_LE      endianmacros.h  100;"   d
-PA_UINT16_FROM_LE      endianmacros.h  133;"   d
-PA_UINT16_SWAP endianmacros.h  38;"    d
-PA_UINT16_SWAP endianmacros.h  43;"    d
-PA_UINT16_TO_BE        endianmacros.h  104;"   d
-PA_UINT16_TO_BE        endianmacros.h  137;"   d
-PA_UINT16_TO_LE        endianmacros.h  103;"   d
-PA_UINT16_TO_LE        endianmacros.h  136;"   d
-PA_UINT32_FROM_BE      endianmacros.h  113;"   d
-PA_UINT32_FROM_BE      endianmacros.h  146;"   d
-PA_UINT32_FROM_LE      endianmacros.h  112;"   d
-PA_UINT32_FROM_LE      endianmacros.h  145;"   d
-PA_UINT32_SWAP endianmacros.h  40;"    d
-PA_UINT32_SWAP endianmacros.h  45;"    d
-PA_UINT32_TO_BE        endianmacros.h  116;"   d
-PA_UINT32_TO_BE        endianmacros.h  149;"   d
-PA_UINT32_TO_LE        endianmacros.h  115;"   d
-PA_UINT32_TO_LE        endianmacros.h  148;"   d
-PA_UINT32_TO_PTR       macro.h 269;"   d
-PA_UINT8_VECTOR_MAKE   vector.h        51;"    d
-PA_UINT8_VECTOR_SIZE   vector.h        46;"    d
-PA_UINT_TO_PTR macro.h 266;"   d
-PA_UNLIKELY    macro.h 43;"    d
-PA_UNLIKELY    macro.h 46;"    d
-PA_WARN_REFERENCE      macro.h 287;"   d
-PA_WARN_REFERENCE      macro.h 294;"   d
-PA_WRITE24BE   endianmacros.h  /^static inline void PA_WRITE24BE(uint8_t *p, uint32_t u) {$/;" f
-PA_WRITE24LE   endianmacros.h  /^static inline void PA_WRITE24LE(uint8_t *p, uint32_t u) {$/;" f
-PA_WRITE24NE   endianmacros.h  122;"   d
-PA_WRITE24NE   endianmacros.h  155;"   d
-PA_WRITE24RE   endianmacros.h  125;"   d
-PA_WRITE24RE   endianmacros.h  158;"   d
-PLAYBACK_BUFFER_FRAGMENTS      protocol-esound.c       72;"    d       file:
-PLAYBACK_BUFFER_FRAGMENTS      protocol-simple.c       94;"    d       file:
-PLAYBACK_BUFFER_SECONDS        protocol-esound.c       71;"    d       file:
-PLAYBACK_BUFFER_SECONDS        protocol-simple.c       93;"    d       file:
-PLAYBACK_STREAM        protocol-native.c       139;"   d       file:
-PLAYBACK_STREAM_MESSAGE_DRAIN_ACK      protocol-native.c       /^    PLAYBACK_STREAM_MESSAGE_DRAIN_ACK,$/;"    e       enum:__anon45   file:
-PLAYBACK_STREAM_MESSAGE_OVERFLOW       protocol-native.c       /^    PLAYBACK_STREAM_MESSAGE_OVERFLOW,$/;"     e       enum:__anon45   file:
-PLAYBACK_STREAM_MESSAGE_REQUEST_DATA   protocol-native.c       /^    PLAYBACK_STREAM_MESSAGE_REQUEST_DATA,      \/* data requested from sink input from the main loop *\/$/;"  e       enum:__anon45   file:
-PLAYBACK_STREAM_MESSAGE_STARTED        protocol-native.c       /^    PLAYBACK_STREAM_MESSAGE_STARTED,$/;"      e       enum:__anon45   file:
-PLAYBACK_STREAM_MESSAGE_UNDERFLOW      protocol-native.c       /^    PLAYBACK_STREAM_MESSAGE_UNDERFLOW,$/;"    e       enum:__anon45   file:
-PLAYBACK_STREAM_MESSAGE_UPDATE_TLENGTH protocol-native.c       /^    PLAYBACK_STREAM_MESSAGE_UPDATE_TLENGTH$/;"        e       enum:__anon45   file:
-POLLERR        poll.h  37;"    d
-POLLHUP        poll.h  38;"    d
-POLLIN poll.h  30;"    d
-POLLNVAL       poll.h  39;"    d
-POLLOUT        poll.h  32;"    d
-POLLPRI        poll.h  31;"    d
-PROMPT cli.c   49;"    d       file:
-PULSE_ROOTENV  core-util.c     133;"   d       file:
-QUANT_MASK     g711.c  47;"    d       file:
-READ24 sconv-s16be.c   38;"    d       file:
-READ24 sconv-s16le.c   68;"    d       file:
-READ_SIZE      ioline.c        42;"    d       file:
-RECORD_BUFFER_SECONDS  protocol-esound.c       73;"    d       file:
-RECORD_BUFFER_SECONDS  protocol-http.c 74;"    d       file:
-RECORD_BUFFER_SECONDS  protocol-simple.c       95;"    d       file:
-RECORD_STREAM  protocol-native.c       101;"   d       file:
-RECORD_STREAM_MESSAGE_POST_DATA        protocol-native.c       /^    RECORD_STREAM_MESSAGE_POST_DATA         \/* data from source output to main loop *\/$/;"  e       enum:__anon46   file:
-REDUCE time-smoother.c 126;"   d       file:
-REDUCE_INC     time-smoother.c 131;"   d       file:
-RLIMIT_NICE    core-util.h     48;"    d
-RLIMIT_RTPRIO  core-util.h     51;"    d
-RLIMIT_RTTIME  core-util.h     54;"    d
-RTKIT_OBJECT_PATH      rtkit.h 42;"    d
-RTKIT_SERVICE_NAME     rtkit.h 41;"    d
-RUN_TEST       sconv_sse.c     167;"   d       file:
-RUN_TEST       svolume_arm.c   125;"   d       file:
-RUN_TEST       svolume_mmx.c   238;"   d       file:
-RUN_TEST       svolume_sse.c   245;"   d       file:
-SAMPLES        sconv_sse.c     170;"   d       file:
-SAMPLES        svolume_arm.c   129;"   d       file:
-SAMPLES        svolume_mmx.c   242;"   d       file:
-SAMPLES        svolume_sse.c   249;"   d       file:
-SCACHE_PREFIX  protocol-esound.c       80;"    d       file:
-SCHED_RESET_ON_FORK    core-util.c     56;"    d       file:
-SEG_MASK       g711.c  50;"    d       file:
-SEG_SHIFT      g711.c  49;"    d       file:
-SHM_MARKER     shm.c   75;"    d       file:
-SHM_MARKER_SIZE        shm.c   91;"    d       file:
-SHM_PATH       shm.c   70;"    d       file:
-SHM_PATH       shm.c   72;"    d       file:
-SIGN_BIT       g711.c  46;"    d       file:
-SINK_INPUT_MESSAGE_DISABLE_PREBUF      protocol-esound.c       /^    SINK_INPUT_MESSAGE_DISABLE_PREBUF$/;"     e       enum:__anon13   file:
-SINK_INPUT_MESSAGE_DISABLE_PREBUF      protocol-simple.c       /^    SINK_INPUT_MESSAGE_DISABLE_PREBUF \/* disabled prebuf, get playback started. *\/$/;"      e       enum:__anon9    file:
-SINK_INPUT_MESSAGE_DRAIN       protocol-native.c       /^    SINK_INPUT_MESSAGE_DRAIN, \/* disabled prebuf, get playback started. *\/$/;"      e       enum:__anon44   file:
-SINK_INPUT_MESSAGE_FLUSH       protocol-native.c       /^    SINK_INPUT_MESSAGE_FLUSH,$/;"     e       enum:__anon44   file:
-SINK_INPUT_MESSAGE_POST_DATA   protocol-esound.c       /^    SINK_INPUT_MESSAGE_POST_DATA = PA_SINK_INPUT_MESSAGE_MAX, \/* data from main loop to sink input *\/$/;"   e       enum:__anon13   file:
-SINK_INPUT_MESSAGE_POST_DATA   protocol-native.c       /^    SINK_INPUT_MESSAGE_POST_DATA = PA_SINK_INPUT_MESSAGE_MAX, \/* data from main loop to sink input *\/$/;"   e       enum:__anon44   file:
-SINK_INPUT_MESSAGE_POST_DATA   protocol-simple.c       /^    SINK_INPUT_MESSAGE_POST_DATA = PA_SINK_INPUT_MESSAGE_MAX, \/* data from main loop to sink input *\/$/;"   e       enum:__anon9    file:
-SINK_INPUT_MESSAGE_PREBUF_FORCE        protocol-native.c       /^    SINK_INPUT_MESSAGE_PREBUF_FORCE,$/;"      e       enum:__anon44   file:
-SINK_INPUT_MESSAGE_SEEK        protocol-native.c       /^    SINK_INPUT_MESSAGE_SEEK,$/;"      e       enum:__anon44   file:
-SINK_INPUT_MESSAGE_TRIGGER     protocol-native.c       /^    SINK_INPUT_MESSAGE_TRIGGER,$/;"   e       enum:__anon44   file:
-SINK_INPUT_MESSAGE_UPDATE_BUFFER_ATTR  protocol-native.c       /^    SINK_INPUT_MESSAGE_UPDATE_BUFFER_ATTR$/;" e       enum:__anon44   file:
-SINK_INPUT_MESSAGE_UPDATE_LATENCY      protocol-native.c       /^    SINK_INPUT_MESSAGE_UPDATE_LATENCY,$/;"    e       enum:__anon44   file:
-SOCKET_SERVER_GENERIC  socket-server.c /^    enum { SOCKET_SERVER_GENERIC, SOCKET_SERVER_IPV4, SOCKET_SERVER_UNIX, SOCKET_SERVER_IPV6 } type;$/;"      e       enum:pa_socket_server::__anon48 file:
-SOCKET_SERVER_IPV4     socket-server.c /^    enum { SOCKET_SERVER_GENERIC, SOCKET_SERVER_IPV4, SOCKET_SERVER_UNIX, SOCKET_SERVER_IPV6 } type;$/;"      e       enum:pa_socket_server::__anon48 file:
-SOCKET_SERVER_IPV6     socket-server.c /^    enum { SOCKET_SERVER_GENERIC, SOCKET_SERVER_IPV4, SOCKET_SERVER_UNIX, SOCKET_SERVER_IPV6 } type;$/;"      e       enum:pa_socket_server::__anon48 file:
-SOCKET_SERVER_UNIX     socket-server.c /^    enum { SOCKET_SERVER_GENERIC, SOCKET_SERVER_IPV4, SOCKET_SERVER_UNIX, SOCKET_SERVER_IPV6 } type;$/;"      e       enum:pa_socket_server::__anon48 file:
-SOURCE_OUTPUT_MESSAGE_POST_DATA        protocol-http.c /^    SOURCE_OUTPUT_MESSAGE_POST_DATA = PA_SOURCE_OUTPUT_MESSAGE_MAX$/;"        e       enum:__anon18   file:
-SOURCE_OUTPUT_MESSAGE_UPDATE_LATENCY   protocol-native.c       /^    SOURCE_OUTPUT_MESSAGE_UPDATE_LATENCY = PA_SOURCE_OUTPUT_MESSAGE_MAX$/;"   e       enum:__anon43   file:
-STATE_DATA     protocol-http.c /^    STATE_DATA$/;"    e       enum:state      file:
-STATE_FAILED   lock-autospawn.c        /^    STATE_FAILED$/;"  e       enum:__anon50   file:
-STATE_IDLE     lock-autospawn.c        /^    STATE_IDLE,$/;"   e       enum:__anon50   file:
-STATE_MIME_HEADER      protocol-http.c /^    STATE_MIME_HEADER,$/;"    e       enum:state      file:
-STATE_OWNING   lock-autospawn.c        /^    STATE_OWNING,$/;" e       enum:__anon50   file:
-STATE_READ0    envelope.c      /^    STATE_READ0,$/;"  e       enum:envelope_state     file:
-STATE_READ1    envelope.c      /^    STATE_READ1,$/;"  e       enum:envelope_state     file:
-STATE_REQUEST_LINE     protocol-http.c /^    STATE_REQUEST_LINE,$/;"   e       enum:state      file:
-STATE_TAKEN    lock-autospawn.c        /^    STATE_TAKEN,$/;"  e       enum:__anon50   file:
-STATE_VALID0   envelope.c      /^    STATE_VALID0,$/;" e       enum:envelope_state     file:
-STATE_VALID1   envelope.c      /^    STATE_VALID1,$/;" e       enum:envelope_state     file:
-STATE_WAIT0    envelope.c      /^    STATE_WAIT0,$/;"  e       enum:envelope_state     file:
-STATE_WAIT1    envelope.c      /^    STATE_WAIT1,$/;"  e       enum:envelope_state     file:
-STATE_WRITE0   envelope.c      /^    STATE_WRITE0,$/;" e       enum:envelope_state     file:
-STATE_WRITE1   envelope.c      /^    STATE_WRITE1$/;"  e       enum:envelope_state     file:
-STORE_SAMPLES  remap_mmx.c     56;"    d       file:
-STORE_SAMPLES  remap_sse.c     56;"    d       file:
-SUN_LEN        socket-server.c 41;"    d       file:
-SWAP_16        svolume_mmx.c   79;"    d       file:
-SWAP_16        svolume_sse.c   60;"    d       file:
-SWAP_16_2      svolume_mmx.c   86;"    d       file:
-SWAP_16_2      svolume_sse.c   67;"    d       file:
-SWAP_WORDS     sconv-s16be.c   77;"    d       file:
-SWAP_WORDS     sconv-s16be.c   79;"    d       file:
-SWAP_WORDS     sconv-s16le.c   76;"    d       file:
-SWAP_WORDS     sconv-s16le.c   78;"    d       file:
-TIMER_SLACK_NS core-rtclock.c  98;"    d       file:
-TIMES  sconv_sse.c     171;"   d       file:
-TIMES  svolume_arm.c   130;"   d       file:
-TIMES  svolume_mmx.c   243;"   d       file:
-TIMES  svolume_sse.c   250;"   d       file:
-TRUE   macro.h 189;"   d
-UINT16_FROM    sconv-s16be.c   30;"    d       file:
-UINT16_FROM    sconv-s16le.c   43;"    d       file:
-UINT16_TO      sconv-s16be.c   31;"    d       file:
-UINT16_TO      sconv-s16le.c   50;"    d       file:
-UINT32_FROM    sconv-s16be.c   35;"    d       file:
-UINT32_FROM    sconv-s16le.c   57;"    d       file:
-UINT32_TO      sconv-s16be.c   36;"    d       file:
-UINT32_TO      sconv-s16le.c   64;"    d       file:
-UNLOAD_POLL_TIME       core-scache.c   66;"    d       file:
-UNPACK_SAMPLES remap_mmx.c     46;"    d       file:
-UNPACK_SAMPLES remap_sse.c     46;"    d       file:
-UPLOAD_STREAM  protocol-native.c       156;"   d       file:
-URL_CSS        protocol-http.c 51;"    d       file:
-URL_LISTEN     protocol-http.c 53;"    d       file:
-URL_LISTEN_SOURCE      protocol-http.c 54;"    d       file:
-URL_ROOT       protocol-http.c 50;"    d       file:
-URL_STATUS     protocol-http.c 52;"    d       file:
-VOLUME_32x16   svolume_mmx.c   55;"    d       file:
-VOLUME_32x16   svolume_sse.c   40;"    d       file:
-VOLUME_PADDING sample-util.c   106;"   d       file:
-WHICH  aupdate.c       35;"    d       file:
-WHITESPACE     conf-parser.c   39;"    d       file:
-WHITESPACE     core-util.c     834;"   d       file:
-WINDOW_TYPE    ffmpeg/resample2.c      39;"    d       file:
-WINDOW_TYPE    ffmpeg/resample2.c      48;"    d       file:
-WINDOW_TYPE    ffmpeg/resample2.c      55;"    d       file:
-WRITE24        sconv-s16be.c   39;"    d       file:
-WRITE24        sconv-s16le.c   71;"    d       file:
-_GNU_SOURCE    rtkit.c 34;"    d       file:
-_Y     asyncq.c        49;"    d       file:
-_Y     asyncq.c        51;"    d       file:
-_Y     flist.c 75;"    d       file:
-_Y     flist.c 77;"    d       file:
-__kernel_cmpxchg       atomic.h        405;"   d
-__kernel_cmpxchg_t     atomic.h        /^typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr);$/;"      t
-__kernel_cmpxchg_u     atomic.h        409;"   d
-__kernel_cmpxchg_u_t   atomic.h        /^typedef int (__kernel_cmpxchg_u_t)(unsigned long oldval, unsigned long newval, volatile unsigned long *ptr);$/;"      t
-__kernel_dmb   atomic.h        395;"   d
-__kernel_dmb_t atomic.h        /^typedef void (__kernel_dmb_t)(void);$/;"      t
-_gettid        rtkit.c /^static pid_t _gettid(void) {$/;"      f       file:
-_reserved1     shm.c   /^    uint64_t _reserved1;$/;"  m       struct:shm_marker       file:
-_reserved2     shm.c   /^    uint64_t _reserved2;$/;"  m       struct:shm_marker       file:
-_reserved3     shm.c   /^    uint64_t _reserved3;$/;"  m       struct:shm_marker       file:
-_reserved4     shm.c   /^    uint64_t _reserved4;$/;"  m       struct:shm_marker       file:
-_st_13linear2alaw      g711.c  /^uint8_t _st_13linear2alaw[0x2000] = {$/;"     v
-_st_14linear2ulaw      g711.c  /^uint8_t _st_14linear2ulaw[0x4000] = {$/;"     v
-_st_alaw2linear16      g711.c  /^int16_t _st_alaw2linear16[256] = {$/;"        v
-_st_ulaw2linear16      g711.c  /^int16_t _st_ulaw2linear16[256] = {$/;"        v
-a      time-smoother.c /^    double a, b, c;$/;"       m       struct:pa_smoother      file:
-abc_valid      time-smoother.c /^    pa_bool_t abc_valid:1;$/;"        m       struct:pa_smoother      file:
-accumulated_size       memblock.h      /^    pa_atomic_t accumulated_size;$/;" m       struct:pa_mempool_stat
-acl_entry      ipacl.c /^struct acl_entry {$/;"        s       file:
-active_port    sink.h  /^    char *active_port;$/;"    m       struct:pa_sink_new_data
-active_port    sink.h  /^    pa_device_port *active_port;$/;"  m       struct:pa_sink
-active_port    source.h        /^    char *active_port;$/;"    m       struct:pa_source_new_data
-active_port    source.h        /^    pa_device_port *active_port;$/;"  m       struct:pa_source
-active_profile card.h  /^    char *active_profile;$/;" m       struct:pa_card_new_data
-active_profile card.h  /^    pa_card_profile *active_profile;$/;"      m       struct:pa_card
-actual_resample_method sink-input.h    /^    pa_resample_method_t requested_resample_method, actual_resample_method;$/;"       m       struct:pa_sink_input
-actual_resample_method source-output.h /^    pa_resample_method_t requested_resample_method, actual_resample_method;$/;"       m       struct:pa_source_output
-add_file       core-scache.c   /^static void add_file(pa_core *c, const char *pathname) {$/;"  f       file:
-add_glib_properties    proplist-util.c /^static void add_glib_properties(pa_proplist *p) {$/;" f       file:
-add_gtk_properties     proplist-util.c /^static void add_gtk_properties(pa_proplist *p) {$/;"  f       file:
-add_key_value  modargs.c       /^static int add_key_value(pa_hashmap *map, char *key, char *value, const char* const valid_keys[]) {$/;"       f       file:
-add_timeout    dbus-util.c     /^static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) {$/;"        f       file:
-add_to_history time-smoother.c /^static void add_to_history(pa_smoother *s, pa_usec_t x, pa_usec_t y) {$/;"    f       file:
-add_watch      dbus-util.c     /^static dbus_bool_t add_watch(DBusWatch *watch, void *data) {$/;"      f       file:
-address_ipv4   ipacl.c /^    struct in_addr address_ipv4;$/;"  m       struct:acl_entry        typeref:struct:acl_entry::in_addr       file:
-address_ipv6   ipacl.c /^    struct in6_addr address_ipv6;$/;" m       struct:acl_entry        typeref:struct:acl_entry::in6_addr      file:
-adjust_latency protocol-native.c       /^    pa_bool_t adjust_latency:1;$/;"   m       struct:playback_stream  file:
-adjust_latency protocol-native.c       /^    pa_bool_t adjust_latency:1;$/;"   m       struct:record_stream    file:
-adjust_time    time-smoother.c /^    pa_usec_t adjust_time, history_time;$/;"  m       struct:pa_smoother      file:
-after_cb       rtpoll.c        /^    void (*after_cb)(pa_rtpoll_item *i);$/;"  m       struct:pa_rtpoll_item   file:
-alaw_from_float32ne    sconv.c /^static void alaw_from_float32ne(unsigned n, const float *a, uint8_t *b) {$/;" f       file:
-alaw_from_s16ne        sconv.c /^static void alaw_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) {$/;"   f       file:
-alaw_to_float32ne      sconv.c /^static void alaw_to_float32ne(unsigned n, const uint8_t *a, float *b) {$/;"   f       file:
-alaw_to_s16ne  sconv.c /^static void alaw_to_s16ne(unsigned n, const int8_t *a, int16_t *b) {$/;"      f       file:
-allocate_aupdate       memtrap.c       /^static void allocate_aupdate(void) {$/;"      f       file:
-allocated      tagstruct.c     /^    size_t length, allocated;$/;"     m       struct:pa_tagstruct     file:
-allocated_size memblock.h      /^    pa_atomic_t allocated_size;$/;"   m       struct:pa_mempool_stat
-api    avahi-wrap.c    /^    AvahiPoll api;$/;"        m       struct:__anon19 file:
-append strbuf.c        /^static void append(pa_strbuf *sb, struct chunk *c) {$/;"      f       file:
-args   cli-command.c   /^    unsigned args;$/;"        m       struct:command  file:
-argument       module.h        /^    char *name, *argument;$/;"        m       struct:pa_module
-asyncmsgq      sink.h  /^    pa_asyncmsgq *asyncmsgq;$/;"      m       struct:pa_sink
-asyncmsgq      source.h        /^    pa_asyncmsgq *asyncmsgq;$/;"      m       struct:pa_source
-asyncmsgq_free asyncmsgq.c     /^static void asyncmsgq_free(pa_asyncmsgq *a) {$/;"     f       file:
-asyncmsgq_item asyncmsgq.c     /^struct asyncmsgq_item {$/;"   s       file:
-asyncmsgq_read_after   rtpoll.c        /^static void asyncmsgq_read_after(pa_rtpoll_item *i) {$/;"     f       file:
-asyncmsgq_read_before  rtpoll.c        /^static int asyncmsgq_read_before(pa_rtpoll_item *i) {$/;"     f       file:
-asyncmsgq_read_cb      thread-mq.c     /^static void asyncmsgq_read_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) {$/;"  f       file:
-asyncmsgq_read_work    rtpoll.c        /^static int asyncmsgq_read_work(pa_rtpoll_item *i) {$/;"       f       file:
-asyncmsgq_write_after  rtpoll.c        /^static void asyncmsgq_write_after(pa_rtpoll_item *i) {$/;"    f       file:
-asyncmsgq_write_before rtpoll.c        /^static int asyncmsgq_write_before(pa_rtpoll_item *i) {$/;"    f       file:
-asyncmsgq_write_cb     thread-mq.c     /^static void asyncmsgq_write_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) {$/;" f       file:
-asyncns        socket-client.c /^    asyncns_t *asyncns;$/;"   m       struct:pa_socket_client file:
-asyncns_cb     socket-client.c /^static void asyncns_cb(pa_mainloop_api*m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {$/;"        f       file:
-asyncns_io_event       socket-client.c /^    pa_io_event *asyncns_io_event;$/;"        m       struct:pa_socket_client file:
-asyncns_query  socket-client.c /^    asyncns_query_t * asyncns_query;$/;"      m       struct:pa_socket_client file:
-asyncq asyncmsgq.c     /^    pa_asyncq *asyncq;$/;"    m       struct:pa_asyncmsgq     file:
-attach sink-input.h    /^    void (*attach) (pa_sink_input *i);           \/* may be NULL *\/$/;"      m       struct:pa_sink_input
-attach source-output.h /^    void (*attach) (pa_source_output *o);           \/* may be NULL *\/$/;"   m       struct:pa_source_output
-attached       sink-input.h    /^        pa_bool_t attached:1; \/* True only between ->attach() and ->detach() calls *\/$/;"   m       struct:pa_sink_input::__anon27
-attached       source-output.h /^        pa_bool_t attached:1; \/* True only between ->attach() and ->detach() calls *\/$/;"   m       struct:pa_source_output::__anon15
-aupdate        memtrap.c       /^static pa_aupdate *aupdate;$/;"       v       file:
-auth_anonymous protocol-esound.h       /^    pa_bool_t auth_anonymous;$/;"     m       struct:pa_esound_options
-auth_anonymous protocol-native.h       /^    pa_bool_t auth_anonymous;$/;"     m       struct:pa_native_options
-auth_cookie    protocol-esound.h       /^    pa_auth_cookie *auth_cookie;$/;"  m       struct:pa_esound_options
-auth_cookie    protocol-native.h       /^    pa_auth_cookie *auth_cookie;$/;"  m       struct:pa_native_options
-auth_group     protocol-native.h       /^    char *auth_group;$/;"     m       struct:pa_native_options
-auth_ip_acl    protocol-esound.h       /^    pa_ip_acl *auth_ip_acl;$/;"       m       struct:pa_esound_options
-auth_ip_acl    protocol-native.h       /^    pa_ip_acl *auth_ip_acl;$/;"       m       struct:pa_native_options
-auth_timeout   protocol-esound.c       /^static void auth_timeout(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata) {$/;" f       file:
-auth_timeout   protocol-native.c       /^static void auth_timeout(pa_mainloop_api*m, pa_time_event *e, const struct timeval *t, void *userdata) {$/;"  f       file:
-auth_timeout_event     protocol-esound.c       /^    pa_time_event *auth_timeout_event;$/;"    m       struct:connection       file:
-auth_timeout_event     protocol-native.c       /^    pa_time_event *auth_timeout_event;$/;"    m       struct:pa_native_connection     file:
-author modinfo.h       /^    char *author;$/;" m       struct:pa_modinfo
-authorized     protocol-esound.c       /^    pa_bool_t authorized, swap_byte_order;$/;"        m       struct:connection       file:
-authorized     protocol-native.c       /^    pa_bool_t authorized:1;$/;"       m       struct:pa_native_connection     file:
-av_build_filter        ffmpeg/resample2.c      /^void av_build_filter(FELEM *filter, double factor, int tap_count, int phase_count, int scale, int type){$/;"  f
-av_clip        ffmpeg/avcodec.h        /^static inline int av_clip(int a, int amin, int amax)$/;"      f
-av_free        ffmpeg/avcodec.h        42;"    d
-av_freep       ffmpeg/avcodec.h        /^static inline void av_freep(void *k) {$/;"    f
-av_log ffmpeg/avcodec.h        60;"    d
-av_malloc      ffmpeg/avcodec.h        40;"    d
-av_mallocz     ffmpeg/avcodec.h        39;"    d
-av_realloc     ffmpeg/avcodec.h        41;"    d
-av_resample    ffmpeg/resample2.c      /^int av_resample(AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx){$/;" f
-av_resample_close      ffmpeg/resample2.c      /^void av_resample_close(AVResampleContext *c){$/;"     f
-av_resample_compensate ffmpeg/resample2.c      /^void av_resample_compensate(AVResampleContext *c, int sample_delta, int compensation_distance){$/;"   f
-av_resample_init       ffmpeg/resample2.c      /^AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff){$/;"      f
-avahi_poll     avahi-wrap.c    /^    pa_avahi_poll *avahi_poll;$/;"    m       struct:AvahiTimeout     file:
-avahi_poll     avahi-wrap.c    /^    pa_avahi_poll *avahi_poll;$/;"    m       struct:AvahiWatch       file:
-avg_gradient   time-smoother.c /^static double avg_gradient(pa_smoother *s, pa_usec_t x) {$/;" f       file:
-awake  rtpoll.c        /^    pa_usec_t slept, awake;$/;"       m       struct:pa_rtpoll        file:
-b      time-smoother.c /^    double a, b, c;$/;"       m       struct:pa_smoother      file:
-back   queue.c /^    struct queue_entry *front, *back;$/;"     m       struct:pa_queue typeref:struct:pa_queue::       file:
-bad    memtrap.c       /^    pa_atomic_t bad;$/;"      m       struct:pa_memtrap       file:
-base   mcalign.c       /^    size_t base;$/;"  m       struct:pa_mcalign       file:
-base   memblockq.c     /^    size_t maxlength, tlength, base, prebuf, minreq, maxrewind;$/;"   m       struct:pa_memblockq     file:
-base_volume    sink.h  /^    pa_volume_t base_volume; \/* shall be constant *\/$/;"    m       struct:pa_sink
-base_volume    source.h        /^    pa_volume_t base_volume; \/* shall be constant *\/$/;"    m       struct:pa_source
-before_cb      rtpoll.c        /^    int (*before_cb)(pa_rtpoll_item *i);$/;"  m       struct:pa_rtpoll_item   file:
-begin  ratelimit.h     /^    pa_usec_t begin;$/;"      m       struct:pa_ratelimit
-bessel ffmpeg/resample2.c      /^static double bessel(double x){$/;"   f       file:
-bits   ipacl.c /^    int bits;$/;"     m       struct:acl_entry        file:
-block  memblock.c      /^    pa_memblock *block;$/;"   m       struct:memexport_slot   file:
-block_id       pstream.c       /^    uint32_t block_id;$/;"    m       struct:item_info        file:
-block_size     memblock.c      /^    size_t block_size;$/;"    m       struct:pa_mempool       file:
-blocks memblock.c      /^    pa_hashmap *blocks;$/;"   m       struct:pa_memimport     file:
-blocks memblockq.c     /^    struct list_item *blocks, *blocks_tail;$/;"       m       struct:pa_memblockq     typeref:struct:pa_memblockq::list_item  file:
-blocks sample-util.h   /^    pa_memblock* blocks[PA_SAMPLE_MAX];$/;"   m       struct:pa_silence_cache
-blocks_tail    memblockq.c     /^    struct list_item *blocks, *blocks_tail;$/;"       m       struct:pa_memblockq     typeref:struct:pa_memblockq::   file:
-bucket_next    hashmap.c       /^    struct hashmap_entry *bucket_next, *bucket_previous;$/;"  m       struct:hashmap_entry    typeref:struct:hashmap_entry::hashmap_entry     file:
-bucket_previous        hashmap.c       /^    struct hashmap_entry *bucket_next, *bucket_previous;$/;"  m       struct:hashmap_entry    typeref:struct:hashmap_entry::  file:
-buf    resampler.c     /^        pa_memchunk buf[PA_CHANNELS_MAX];$/;" m       struct:pa_resampler::__anon41   file:
-buf1   resampler.c     /^    pa_memchunk buf1, buf2, buf3, buf4;$/;"   m       struct:pa_resampler     file:
-buf1_samples   resampler.c     /^    unsigned buf1_samples, buf2_samples, buf3_samples, buf4_samples;$/;"      m       struct:pa_resampler     file:
-buf2   resampler.c     /^    pa_memchunk buf1, buf2, buf3, buf4;$/;"   m       struct:pa_resampler     file:
-buf2_samples   resampler.c     /^    unsigned buf1_samples, buf2_samples, buf3_samples, buf4_samples;$/;"      m       struct:pa_resampler     file:
-buf3   resampler.c     /^    pa_memchunk buf1, buf2, buf3, buf4;$/;"   m       struct:pa_resampler     file:
-buf3_samples   resampler.c     /^    unsigned buf1_samples, buf2_samples, buf3_samples, buf4_samples;$/;"      m       struct:pa_resampler     file:
-buf4   resampler.c     /^    pa_memchunk buf1, buf2, buf3, buf4;$/;"   m       struct:pa_resampler     file:
-buf4_samples   resampler.c     /^    unsigned buf1_samples, buf2_samples, buf3_samples, buf4_samples;$/;"      m       struct:pa_resampler     file:
-buffer_attr    protocol-native.c       /^    pa_buffer_attr buffer_attr;$/;"   m       struct:playback_stream  file:
-buffer_attr    protocol-native.c       /^    pa_buffer_attr buffer_attr;$/;"   m       struct:record_stream    file:
-burst  ratelimit.h     /^    unsigned burst;$/;"       m       struct:pa_ratelimit
-c      dbus-util.c     /^    pa_dbus_wrap_connection *c;$/;"   m       struct:timeout_data     file:
-c      time-smoother.c /^    double a, b, c;$/;"       m       struct:pa_smoother      file:
-c_locale       core-util.c     /^static locale_t c_locale = NULL;$/;"  v       file:
-c_locale_destroy       core-util.c     /^static void c_locale_destroy(void) {$/;"      f       file:
-cached_dx      envelope.c      /^        size_t cached_dx;$/;" m       struct:pa_envelope::__anon23    file:
-cached_dy_dx   envelope.c      /^        float cached_dy_dx;$/;"       m       struct:pa_envelope::__anon23    file:
-cached_dy_i    envelope.c      /^        int32_t cached_dy_i;$/;"      m       struct:pa_envelope::__anon23    file:
-cached_valid   envelope.c      /^        pa_bool_t cached_valid;$/;"   m       struct:pa_envelope::__anon23    file:
-calc_abc       time-smoother.c /^static void calc_abc(pa_smoother *s) {$/;"    f       file:
-calc_linear_float_stream_volumes       sample-util.c   /^static void calc_linear_float_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec) {$/;"    f       file:
-calc_linear_float_volume       sample-util.c   /^static void calc_linear_float_volume(float linear[], const pa_cvolume *volume) {$/;"  f       file:
-calc_linear_integer_stream_volumes     sample-util.c   /^static void calc_linear_integer_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec) {$/;"  f       file:
-calc_linear_integer_volume     sample-util.c   /^static void calc_linear_integer_volume(int32_t linear[], const pa_cvolume *volume) {$/;"      f       file:
-calc_map_table resampler.c     /^static void calc_map_table(pa_resampler *r) {$/;"     f       file:
-calc_sine      sample-util.c   /^static void calc_sine(float *f, size_t l, double freq) {$/;"  f       file:
-calc_volume_table      sample-util.c   /^static const pa_calc_volume_func_t calc_volume_table[] = {$/;"        v       file:
-call_data      dbus-util.h     /^    void *call_data;$/;"      m       struct:pa_dbus_pending
-callback       avahi-wrap.c    /^    AvahiTimeoutCallback callback;$/;"        m       struct:AvahiTimeout     file:
-callback       avahi-wrap.c    /^    AvahiWatchCallback callback;$/;"  m       struct:AvahiWatch       file:
-callback       core-subscribe.c        /^    pa_subscription_cb_t callback;$/;"        m       struct:pa_subscription  file:
-callback       hook-list.h     /^    pa_hook_cb_t callback;$/;"        m       struct:pa_hook_slot
-callback       iochannel.c     /^    pa_iochannel_cb_t callback;$/;"   m       struct:pa_iochannel     file:
-callback       iochannel.c     /^static void callback(pa_mainloop_api* m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {$/;" f       file:
-callback       ioline.c        /^    pa_ioline_cb_t callback;$/;"      m       struct:pa_ioline        file:
-callback       pdispatch.c     /^    pa_pdispatch_cb_t callback;$/;"   m       struct:reply_info       file:
-callback       socket-client.c /^    pa_socket_client_cb_t callback;$/;"       m       struct:pa_socket_client file:
-callback       socket-server.c /^static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {$/;"  f       file:
-callback_table pdispatch.c     /^    const pa_pdispatch_cb_t *callback_table;$/;"      m       struct:pa_pdispatch     file:
-can_push       memblockq.c     /^static pa_bool_t can_push(pa_memblockq *bq, size_t l) {$/;"   f       file:
-card   sink.h  /^    pa_card *card;                          \/* may be NULL *\/$/;"   m       struct:pa_sink
-card   sink.h  /^    pa_card *card;$/;"        m       struct:pa_sink_new_data
-card   source.h        /^    pa_card *card;                            \/* may be NULL *\/$/;" m       struct:pa_source
-card   source.h        /^    pa_card *card;$/;"        m       struct:pa_source_new_data
-card_fill_tagstruct    protocol-native.c       /^static void card_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_card *card) {$/;"        f       file:
-cards  core.h  /^    pa_idxset *clients, *cards, *sinks, *sources, *sink_inputs, *source_outputs, *modules, *scache;$/;"       m       struct:pa_core
-channel        pstream.c       /^    uint32_t channel;$/;"     m       struct:item_info        file:
-channel_map    core-scache.h   /^    pa_channel_map channel_map;$/;"   m       struct:pa_scache_entry
-channel_map    protocol-native.c       /^    pa_channel_map channel_map;$/;"   m       struct:upload_stream    file:
-channel_map    protocol-simple.h       /^    pa_channel_map channel_map;$/;"   m       struct:pa_simple_options
-channel_map    sink-input.h    /^    pa_channel_map channel_map;$/;"   m       struct:pa_sink_input
-channel_map    sink-input.h    /^    pa_channel_map channel_map;$/;"   m       struct:pa_sink_input_new_data
-channel_map    sink.h  /^    pa_channel_map channel_map;$/;"   m       struct:pa_sink
-channel_map    sink.h  /^    pa_channel_map channel_map;$/;"   m       struct:pa_sink_new_data
-channel_map    source-output.h /^    pa_channel_map channel_map;$/;"   m       struct:pa_source_output
-channel_map    source-output.h /^    pa_channel_map channel_map;$/;"   m       struct:pa_source_output_new_data
-channel_map    source.h        /^    pa_channel_map channel_map;$/;"   m       struct:pa_source
-channel_map    source.h        /^    pa_channel_map channel_map;$/;"   m       struct:pa_source_new_data
-channel_map_is_set     sink-input.h    /^    pa_bool_t channel_map_is_set:1;$/;"       m       struct:pa_sink_input_new_data
-channel_map_is_set     sink.h  /^    pa_bool_t channel_map_is_set:1;$/;"       m       struct:pa_sink_new_data
-channel_map_is_set     source-output.h /^    pa_bool_t channel_map_is_set:1;$/;"       m       struct:pa_source_output_new_data
-channel_map_is_set     source.h        /^    pa_bool_t channel_map_is_set:1;$/;"       m       struct:pa_source_new_data
-check_type     object.h        /^    pa_bool_t (*check_type)(const char *type_name);$/;"       m       struct:pa_object
-chunk  memblockq.c     /^    pa_memchunk chunk;$/;"    m       struct:list_item        file:
-chunk  pstream.c       /^    pa_memchunk chunk;$/;"    m       struct:item_info        file:
-chunk  sample-util.h   /^    pa_memchunk chunk;$/;"    m       struct:pa_mix_info
-chunk  strbuf.c        /^struct chunk {$/;"    s       file:
-cli_eof_cb     protocol-cli.c  /^static void cli_eof_cb(pa_cli*c, void*userdata) {$/;" f       file:
-cli_protocol_new       protocol-cli.c  /^static pa_cli_protocol* cli_protocol_new(pa_core *c) {$/;"    f       file:
-cli_unlink     protocol-cli.c  /^static void cli_unlink(pa_cli_protocol *p, pa_cli *c) {$/;"   f       file:
-client cli.c   /^    pa_client *client;$/;"    m       struct:pa_cli   file:
-client client.h        /^    pa_client *client;$/;"    m       struct:pa_client_send_event_hook_data
-client protocol-esound.c       /^    pa_client *client;$/;"    m       struct:connection       file:
-client protocol-http.c /^    pa_client *client;$/;"    m       struct:connection       file:
-client protocol-native.c       /^    pa_client *client;$/;"    m       struct:pa_native_connection     file:
-client protocol-simple.c       /^    pa_client *client;$/;"    m       struct:connection       file:
-client sink-input.h    /^    pa_client *client;                  \/* may be NULL *\/$/;"       m       struct:pa_sink_input
-client sink-input.h    /^    pa_client *client;$/;"    m       struct:pa_sink_input_new_data
-client source-output.h /^    pa_client *client;                    \/* may be NULL *\/$/;"     m       struct:pa_source_output
-client source-output.h /^    pa_client *client;$/;"    m       struct:pa_source_output_new_data
-client_fill_tagstruct  protocol-native.c       /^static void client_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_client *client) {$/;"  f       file:
-client_kill    cli.c   /^static void client_kill(pa_client *client) {$/;"      f       file:
-client_kill_cb protocol-esound.c       /^static void client_kill_cb(pa_client *c) {$/;"        f       file:
-client_kill_cb protocol-http.c /^static void client_kill_cb(pa_client *client) {$/;"   f       file:
-client_kill_cb protocol-native.c       /^static void client_kill_cb(pa_client *c) {$/;"        f       file:
-client_kill_cb protocol-simple.c       /^static void client_kill_cb(pa_client *client) {$/;"   f       file:
-client_send_event_cb   protocol-native.c       /^static void client_send_event_cb(pa_client *client, const char*event, pa_proplist *pl) {$/;"  f       file:
-clients        core.h  /^    pa_idxset *clients, *cards, *sinks, *sources, *sink_inputs, *source_outputs, *modules, *scache;$/;"       m       struct:pa_core
-code   asyncmsgq.c     /^    int code;$/;"     m       struct:asyncmsgq_item   file:
-command        cli-command.c   /^struct command {$/;"  s       file:
-command_auth   protocol-native.c       /^static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"     f       file:
-command_cork_playback_stream   protocol-native.c       /^static void command_cork_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"     f       file:
-command_cork_record_stream     protocol-native.c       /^static void command_cork_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"       f       file:
-command_create_playback_stream protocol-native.c       /^static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"   f       file:
-command_create_record_stream   protocol-native.c       /^static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"     f       file:
-command_create_upload_stream   protocol-native.c       /^static void command_create_upload_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"     f       file:
-command_delete_stream  protocol-native.c       /^static void command_delete_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"    f       file:
-command_drain_playback_stream  protocol-native.c       /^static void command_drain_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"    f       file:
-command_exit   protocol-native.c       /^static void command_exit(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"     f       file:
-command_extension      protocol-native.c       /^static void command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"        f       file:
-command_finish_upload_stream   protocol-native.c       /^static void command_finish_upload_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"     f       file:
-command_flush_record_stream    protocol-native.c       /^static void command_flush_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"      f       file:
-command_get_info       protocol-native.c       /^static void command_get_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;" f       file:
-command_get_info_list  protocol-native.c       /^static void command_get_info_list(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"    f       file:
-command_get_playback_latency   protocol-native.c       /^static void command_get_playback_latency(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"     f       file:
-command_get_record_latency     protocol-native.c       /^static void command_get_record_latency(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"       f       file:
-command_get_server_info        protocol-native.c       /^static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"  f       file:
-command_kill   protocol-native.c       /^static void command_kill(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"     f       file:
-command_load_module    protocol-native.c       /^static void command_load_module(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"      f       file:
-command_lookup protocol-native.c       /^static void command_lookup(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"   f       file:
-command_move_stream    protocol-native.c       /^static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"      f       file:
-command_names  pdispatch.c     /^static const char *command_names[PA_COMMAND_MAX] = {$/;"      v       file:
-command_play_sample    protocol-native.c       /^static void command_play_sample(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"      f       file:
-command_remove_proplist        protocol-native.c       /^static void command_remove_proplist(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"  f       file:
-command_remove_sample  protocol-native.c       /^static void command_remove_sample(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"    f       file:
-command_set_card_profile       protocol-native.c       /^static void command_set_card_profile(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;" f       file:
-command_set_client_name        protocol-native.c       /^static void command_set_client_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"  f       file:
-command_set_default_sink_or_source     protocol-native.c       /^static void command_set_default_sink_or_source(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"       f       file:
-command_set_mute       protocol-native.c       /^static void command_set_mute($/;"     f       file:
-command_set_sink_or_source_port        protocol-native.c       /^static void command_set_sink_or_source_port(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"  f       file:
-command_set_stream_buffer_attr protocol-native.c       /^static void command_set_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"   f       file:
-command_set_stream_name        protocol-native.c       /^static void command_set_stream_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"  f       file:
-command_set_volume     protocol-native.c       /^static void command_set_volume($/;"   f       file:
-command_stat   protocol-native.c       /^static void command_stat(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"     f       file:
-command_subscribe      protocol-native.c       /^static void command_subscribe(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"        f       file:
-command_suspend        protocol-native.c       /^static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"  f       file:
-command_table  protocol-native.c       /^static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {$/;"  v       file:
-command_trigger_or_flush_or_prebuf_playback_stream     protocol-native.c       /^static void command_trigger_or_flush_or_prebuf_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"       f       file:
-command_unload_module  protocol-native.c       /^static void command_unload_module(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"    f       file:
-command_update_proplist        protocol-native.c       /^static void command_update_proplist(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"  f       file:
-command_update_stream_sample_rate      protocol-native.c       /^static void command_update_stream_sample_rate(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {$/;"        f       file:
-commands       cli-command.c   /^static const struct command commands[] = {$/;"        v       typeref:struct:command  file:
-compare_func   database-simple.c       /^static int compare_func(const void *a, const void *b) {$/;"   f       file:
-compare_func   hashmap.c       /^    pa_compare_func_t compare_func;$/;"       m       struct:pa_hashmap       file:
-compare_func   idxset.c        /^    pa_compare_func_t compare_func;$/;"       m       struct:pa_idxset        file:
-compare_func   prioq.c /^    pa_compare_func_t compare_func;$/;"       m       struct:pa_prioq file:
-compensation_distance  ffmpeg/resample2.c      /^    int compensation_distance;$/;"    m       struct:AVResampleContext        file:
-compute_real_ratios    sink.c  /^static void compute_real_ratios(pa_sink *s) {$/;"     f       file:
-compute_real_volume    sink.c  /^static void compute_real_volume(pa_sink *s) {$/;"     f       file:
-compute_reference_ratios       sink.c  /^static void compute_reference_ratios(pa_sink *s) {$/;"        f       file:
-cond   mutex-posix.c   /^    pthread_cond_t cond;$/;"  m       struct:pa_cond  file:
-configured_sink_latency        protocol-native.c       /^    pa_usec_t configured_sink_latency;$/;"    m       struct:playback_stream  file:
-configured_source_latency      protocol-native.c       /^    pa_usec_t configured_source_latency;$/;"  m       struct:record_stream    file:
-connect_defer_cb       socket-client.c /^static void connect_defer_cb(pa_mainloop_api *m, pa_defer_event *e, void *userdata) {$/;"     f       file:
-connect_io_cb  socket-client.c /^static void connect_io_cb(pa_mainloop_api*m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {$/;"     f       file:
-connection     dbus-shared.c   /^    pa_dbus_wrap_connection *connection;$/;"  m       struct:pa_dbus_connection       file:
-connection     dbus-util.c     /^    DBusConnection *connection;$/;"   m       struct:pa_dbus_wrap_connection  file:
-connection     dbus-util.h     /^    DBusConnection *connection;$/;"   m       struct:pa_dbus_pending
-connection     protocol-esound.c       /^typedef struct connection {$/;"       s       file:
-connection     protocol-esound.c       /^} connection;$/;"     t       typeref:struct:connection       file:
-connection     protocol-http.c /^struct connection {$/;"       s       file:
-connection     protocol-native.c       /^    pa_native_connection *connection;$/;"     m       struct:playback_stream  file:
-connection     protocol-native.c       /^    pa_native_connection *connection;$/;"     m       struct:record_stream    file:
-connection     protocol-native.c       /^    pa_native_connection *connection;$/;"     m       struct:upload_stream    file:
-connection     protocol-simple.c       /^typedef struct connection {$/;"       s       file:
-connection     protocol-simple.c       /^} connection;$/;"     t       typeref:struct:connection       file:
-connection_free        protocol-esound.c       /^static void connection_free(pa_object *obj) {$/;"     f       file:
-connection_free        protocol-simple.c       /^static void connection_free(pa_object *o) {$/;"       f       file:
-connection_process_msg protocol-esound.c       /^static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) {$/;" f       file:
-connection_process_msg protocol-simple.c       /^static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) {$/;" f       file:
-connection_unlink      protocol-esound.c       /^static void connection_unlink(connection *c) {$/;"    f       file:
-connection_unlink      protocol-http.c /^static void connection_unlink(struct connection *c) {$/;"     f       file:
-connection_unlink      protocol-simple.c       /^static void connection_unlink(connection *c) {$/;"    f       file:
-connection_write       protocol-esound.c       /^static void connection_write(connection *c, const void *data, size_t length) {$/;"    f       file:
-connection_write_prepare       protocol-esound.c       /^static void connection_write_prepare(connection *c, size_t length) {$/;"      f       file:
-connections    protocol-cli.c  /^    pa_idxset *connections;$/;"       m       struct:pa_cli_protocol  file:
-connections    protocol-esound.c       /^    pa_idxset *connections;$/;"       m       struct:pa_esound_protocol       file:
-connections    protocol-http.c /^    pa_idxset *connections;$/;"       m       struct:pa_http_protocol file:
-connections    protocol-native.c       /^    pa_idxset *connections;$/;"       m       struct:pa_native_protocol       file:
-connections    protocol-simple.c       /^    pa_idxset *connections;$/;"       m       struct:pa_simple_protocol       file:
-context_data   dbus-util.h     /^    void *context_data;$/;"   m       struct:pa_dbus_pending
-convert_from_work_format       resampler.c     /^static pa_memchunk *convert_from_work_format(pa_resampler *r, pa_memchunk *input) {$/;"       f       file:
-convert_to_work_format resampler.c     /^static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input) {$/;" f       file:
-cookie core.h  /^    uint32_t cookie;$/;"      m       struct:pa_core
-copy_init      resampler.c     /^static int copy_init(pa_resampler *r) {$/;"   f       file:
-core   auth-cookie.c   /^    pa_core *core;$/;"        m       struct:pa_auth_cookie   file:
-core   card.h  /^    pa_core *core;$/;"        m       struct:pa_card
-core   cli.c   /^    pa_core *core;$/;"        m       struct:pa_cli   file:
-core   client.h        /^    pa_core *core;$/;"        m       struct:pa_client
-core   core-scache.h   /^    pa_core *core;$/;"        m       struct:pa_scache_entry
-core   core-subscribe.c        /^    pa_core *core;$/;"        m       struct:pa_subscription  file:
-core   core-subscribe.c        /^    pa_core *core;$/;"        m       struct:pa_subscription_event    file:
-core   dbus-shared.c   /^    pa_core *core;$/;"        m       struct:pa_dbus_connection       file:
-core   module.h        /^    pa_core *core;$/;"        m       struct:pa_module
-core   play-memblockq.c        /^    pa_core *core;$/;"        m       struct:memblockq_stream file:
-core   protocol-cli.c  /^    pa_core *core;$/;"        m       struct:pa_cli_protocol  file:
-core   protocol-esound.c       /^    pa_core *core;$/;"        m       struct:pa_esound_protocol       file:
-core   protocol-http.c /^    pa_core *core;$/;"        m       struct:pa_http_protocol file:
-core   protocol-native.c       /^    pa_core *core;$/;"        m       struct:pa_native_protocol       file:
-core   protocol-simple.c       /^    pa_core *core;$/;"        m       struct:pa_simple_protocol       file:
-core   sink-input.h    /^    pa_core *core;$/;"        m       struct:pa_sink_input
-core   sink.h  /^    pa_core *core;$/;"        m       struct:pa_sink
-core   sound-file-stream.c     /^    pa_core *core;$/;"        m       struct:file_stream      file:
-core   source-output.h /^    pa_core *core;$/;"        m       struct:pa_source_output
-core   source.h        /^    pa_core *core;$/;"        m       struct:pa_source
-core   x11wrap.c       /^    pa_core *core;$/;"        m       struct:pa_x11_wrapper   file:
-core_free      core.c  /^static void core_free(pa_object *o) {$/;"     f       file:
-core_process_msg       core.c  /^static int core_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {$/;"      f       file:
-create_mutex   lock-autospawn.c        /^static void create_mutex(void) {$/;"  f       file:
-creds  pdispatch.c     /^    const pa_creds *creds;$/;"        m       struct:pa_pdispatch     file:
-creds  pstream.c       /^    pa_creds creds;$/;"       m       struct:item_info        file:
-current        asyncmsgq.c     /^    struct asyncmsgq_item *current;$/;"       m       struct:pa_asyncmsgq     typeref:struct:pa_asyncmsgq::asyncmsgq_item     file:
-current        mcalign.c       /^    pa_memchunk leftover, current;$/;"        m       struct:pa_mcalign       file:
-current        pstream.c       /^        struct item_info* current;$/;"        m       struct:pa_pstream::__anon34     typeref:struct:pa_pstream::__anon34::item_info  file:
-current_event  avahi-wrap.c    /^    AvahiWatchEvent current_event;$/;"        m       struct:AvahiWatch       file:
-current_index  idxset.c        /^    uint32_t current_index;$/;"       m       struct:pa_idxset        file:
-current_memblock       protocol-esound.c       /^        pa_memblock *current_memblock;$/;"    m       struct:connection::__anon11     file:
-current_memblock       protocol-simple.c       /^        pa_memblock *current_memblock;$/;"    m       struct:connection::__anon8      file:
-current_monitor_latency        protocol-native.c       /^    pa_usec_t current_monitor_latency;$/;"    m       struct:record_stream    file:
-current_read   memblockq.c     /^    struct list_item *current_read, *current_write;$/;"       m       struct:pa_memblockq     typeref:struct:pa_memblockq::list_item  file:
-current_sink_latency   protocol-native.c       /^    pa_usec_t current_sink_latency;$/;"       m       struct:playback_stream  file:
-current_source_latency protocol-native.c       /^    pa_usec_t current_source_latency;$/;"     m       struct:record_stream    file:
-current_write  memblockq.c     /^    struct list_item *current_read, *current_write;$/;"       m       struct:pa_memblockq     typeref:struct:pa_memblockq::   file:
-data   asyncq.c        /^    void *data;$/;"   m       struct:localq   file:
-data   client.h        /^    pa_proplist *data;$/;"    m       struct:pa_client_send_event_hook_data
-data   conf-parser.h   /^    void *data; \/* Where to store the variable's data *\/$/;"        m       struct:pa_config_item
-data   database-simple.c       /^    pa_datum data;$/;"        m       struct:entry    file:
-data   database.h      /^    void *data;$/;"   m       struct:pa_datum
-data   dynarray.c      /^    void **data;$/;"  m       struct:pa_dynarray      file:
-data   fdsem.c /^    pa_fdsem_data *data;$/;"  m       struct:pa_fdsem file:
-data   hook-list.h     /^    void *data;$/;"   m       struct:pa_hook
-data   hook-list.h     /^    void *data;$/;"   m       struct:pa_hook_slot
-data   idxset.c        /^    void *data;$/;"   m       struct:idxset_entry     file:
-data   memblock.c      /^    pa_atomic_ptr_t data;$/;" m       struct:pa_memblock      file:
-data   namereg.c       /^    void *data;$/;"   m       struct:namereg_entry    file:
-data   packet.h        /^    uint8_t *data;$/;"        m       struct:pa_packet
-data   pstream.c       /^        void *data;$/;"       m       struct:pa_pstream::__anon34     file:
-data   pstream.c       /^        void *data;$/;"       m       struct:pa_pstream::__anon35     file:
-data   queue.c /^    void *data;$/;"   m       struct:queue_entry      file:
-data   shared.c        /^    void *data;  \/* Points to memory maintained by the caller *\/$/;"        m       struct:pa_shared        file:
-data   sink-input.h    /^    pa_proplist *data;$/;"    m       struct:pa_sink_input_send_event_hook_data
-data   source-output.h /^    pa_proplist *data;$/;"    m       struct:pa_source_output_send_event_hook_data
-data   tagstruct.c     /^    uint8_t *data;$/;"        m       struct:pa_tagstruct     file:
-data   thread-win32.c  /^    void *data;$/;"   m       struct:pa_tls_monitor   file:
-data_length    protocol-esound.c       /^    size_t data_length;$/;"   m       struct:proto_handler    file:
-data_next      idxset.c        /^    struct idxset_entry *data_next, *data_previous;$/;"       m       struct:idxset_entry     typeref:struct:idxset_entry::idxset_entry       file:
-data_previous  idxset.c        /^    struct idxset_entry *data_next, *data_previous;$/;"       m       struct:idxset_entry     typeref:struct:idxset_entry::   file:
-data_scan      idxset.c        /^static struct idxset_entry* data_scan(pa_idxset *s, unsigned hash, const void *p) {$/;"       f       file:
-datum_from_gdbm        database-gdbm.c /^static inline pa_datum* datum_from_gdbm(pa_datum *to, const datum *from) {$/;"        f       file:
-datum_from_tdb database-tdb.c  /^static inline pa_datum* datum_from_tdb(pa_datum *to, const TDB_DATA *from) {$/;"      f       file:
-datum_to_gdbm  database-gdbm.c /^static inline datum* datum_to_gdbm(datum *to, const pa_datum *from) {$/;"     f       file:
-datum_to_tdb   database-tdb.c  /^static inline TDB_DATA* datum_to_tdb(TDB_DATA *to, const pa_datum *from) {$/;"        f       file:
-dbus_connection_new    dbus-shared.c   /^static pa_dbus_connection* dbus_connection_new(pa_core *c, pa_dbus_wrap_connection *conn, const char *name) {$/;"     f       file:
-de     time-smoother.c /^    double de;            \/* Gradient we estimated for point e *\/$/;"       m       struct:pa_smoother      file:
-dead   core-subscribe.c        /^    pa_bool_t dead;$/;"       m       struct:pa_subscription  file:
-dead   hook-list.h     /^    pa_bool_t dead;$/;"       m       struct:pa_hook_slot
-dead   ioline.c        /^    pa_bool_t dead:1;$/;"     m       struct:pa_ioline        file:
-dead   protocol-esound.c       /^    pa_bool_t dead;$/;"       m       struct:connection       file:
-dead   protocol-simple.c       /^    pa_bool_t dead;$/;"       m       struct:connection       file:
-dead   pstream.c       /^    pa_bool_t dead;$/;"       m       struct:pa_pstream       file:
-dead   rtpoll.c        /^    pa_bool_t dead;$/;"       m       struct:pa_rtpoll_item   file:
-def    envelope.c      /^    const pa_envelope_def *def;$/;"   m       struct:pa_envelope_item file:
-default_channel_map    core.h  /^    pa_channel_map default_channel_map;$/;"   m       struct:pa_core
-default_fragment_size_msec     core.h  /^    unsigned default_n_fragments, default_fragment_size_msec;$/;"     m       struct:pa_core
-default_n_fragments    core.h  /^    unsigned default_n_fragments, default_fragment_size_msec;$/;"     m       struct:pa_core
-default_sample_spec    core.h  /^    pa_sample_spec default_sample_spec;$/;"   m       struct:pa_core
-default_sink   core.h  /^    pa_sink *default_sink;$/;"        m       struct:pa_core
-default_sink   protocol-esound.h       /^    char *default_sink, *default_source;$/;"  m       struct:pa_esound_options
-default_sink   protocol-simple.h       /^    char *default_sink, *default_source;$/;"  m       struct:pa_simple_options
-default_source core.h  /^    pa_source *default_source;$/;"    m       struct:pa_core
-default_source protocol-esound.h       /^    char *default_sink, *default_source;$/;"  m       struct:pa_esound_options
-default_source protocol-simple.h       /^    char *default_sink, *default_source;$/;"  m       struct:pa_simple_options
-defer_callback ioline.c        /^static void defer_callback(pa_mainloop_api*m, pa_defer_event*e, void *userdata) {$/;" f       file:
-defer_callback protocol-esound.c       /^static void defer_callback(pa_mainloop_api*a, pa_defer_event *e, void *userdata) {$/;"        f       file:
-defer_callback pstream.c       /^static void defer_callback(pa_mainloop_api *m, pa_defer_event *e, void*userdata) {$/;"        f       file:
-defer_cb       core-subscribe.c        /^static void defer_cb(pa_mainloop_api *m, pa_defer_event *de, void *userdata) {$/;"    f       file:
-defer_cb       module.c        /^static void defer_cb(pa_mainloop_api*api, pa_defer_event *e, void *userdata) {$/;"    f       file:
-defer_close    ioline.c        /^    pa_bool_t defer_close:1;$/;"      m       struct:pa_ioline        file:
-defer_event    ioline.c        /^    pa_defer_event *defer_event;$/;"  m       struct:pa_ioline        file:
-defer_event    protocol-esound.c       /^    pa_defer_event *defer_event;$/;"  m       struct:connection       file:
-defer_event    pstream.c       /^    pa_defer_event *defer_event;$/;"  m       struct:pa_pstream       file:
-defer_event    socket-client.c /^    pa_defer_event *defer_event;$/;"  m       struct:pa_socket_client file:
-defer_event    x11wrap.c       /^    pa_defer_event* defer_event;$/;"  m       struct:pa_x11_wrapper   file:
-defer_event    x11wrap.c       /^static void defer_event(pa_mainloop_api *m, pa_defer_event *e, void *userdata) {$/;"  f       file:
-defer_kill     cli.c   /^    int defer_kill;$/;"       m       struct:pa_cli   file:
-delay_memblockq        source-output.h /^        pa_memblockq *delay_memblockq;$/;"    m       struct:pa_source_output::__anon15
-deprecated     modinfo.h       /^    char *deprecated;$/;"     m       struct:pa_modinfo
-description    card.h  /^    char *description;$/;"    m       struct:pa_card_profile
-description    modinfo.h       /^    char *description;$/;"    m       struct:pa_modinfo
-description    protocol-esound.c       /^    const char *description;$/;"      m       struct:proto_handler    file:
-description    sink.h  /^    char *description;$/;"    m       struct:pa_device_port
-descriptor     pstream.c       /^        pa_pstream_descriptor descriptor;$/;" m       struct:pa_pstream::__anon34     file:
-descriptor     pstream.c       /^        pa_pstream_descriptor descriptor;$/;" m       struct:pa_pstream::__anon35     file:
-destroy_mutex  lock-autospawn.c        /^static void destroy_mutex(void) {$/;" f       file:
-detach sink-input.h    /^    void (*detach) (pa_sink_input *i);           \/* may be NULL *\/$/;"      m       struct:pa_sink_input
-detach source-output.h /^    void (*detach) (pa_source_output *o);           \/* may be NULL *\/$/;"   m       struct:pa_source_output
-devices        random.c        /^static const char * const devices[] = { "\/dev\/urandom", "\/dev\/random", NULL };$/;"        v       file:
-die_callback   pstream.c       /^    pa_pstream_notify_cb_t die_callback;$/;"  m       struct:pa_pstream       file:
-die_callback_userdata  pstream.c       /^    void *die_callback_userdata;$/;"  m       struct:pa_pstream       file:
-direct_on_input        source-output.h /^        pa_sink_input *direct_on_input;       \/* may be NULL *\/$/;" m       struct:pa_source_output::__anon15
-direct_on_input        source-output.h /^    pa_sink_input *direct_on_input;       \/* may be NULL *\/$/;"     m       struct:pa_source_output
-direct_on_input        source-output.h /^    pa_sink_input *direct_on_input;$/;"       m       struct:pa_source_output_new_data
-direct_outputs sink-input.h    /^        pa_hashmap *direct_outputs;$/;"       m       struct:pa_sink_input::__anon27
-direct_outputs sink-input.h    /^    pa_idxset *direct_outputs;$/;"    m       struct:pa_sink_input
-disable_lfe_remixing   core.h  /^    pa_bool_t disable_lfe_remixing:1;$/;"     m       struct:pa_core
-disable_remixing       core.h  /^    pa_bool_t disable_remixing:1;$/;" m       struct:pa_core
-disallow_exit  core.h  /^    pa_bool_t disallow_exit:1;$/;"    m       struct:pa_core
-disallow_module_loading        core.h  /^    pa_bool_t disallow_module_loading:1;$/;"  m       struct:pa_core
-dispatch_cb    dbus-util.c     /^static void dispatch_cb(pa_mainloop_api *ea, pa_defer_event *ev, void *userdata) {$/;"        f       file:
-dispatch_event dbus-util.c     /^    pa_defer_event* dispatch_event;$/;"       m       struct:pa_dbus_wrap_connection  file:
-dispatch_status        dbus-util.c     /^static void dispatch_status(DBusConnection *conn, DBusDispatchStatus status, void *userdata) {$/;"    f       file:
-display        x11wrap.c       /^    Display *display;$/;"     m       struct:pa_x11_wrapper   file:
-display_io_event       x11wrap.c       /^static void display_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {$/;" f       file:
-dl     module.h        /^    lt_dlhandle dl;$/;"       m       struct:pa_module
-do_call        socket-client.c /^static void do_call(pa_socket_client *c) {$/;"        f       file:
-do_connect     socket-client.c /^static int do_connect(pa_socket_client *c, const struct sockaddr *sa, socklen_t len) {$/;"    f       file:
-do_read        ioline.c        /^static int do_read(pa_ioline *l) {$/;"        f       file:
-do_read        protocol-esound.c       /^static int do_read(connection *c) {$/;"       f       file:
-do_read        protocol-simple.c       /^static int do_read(connection *c) {$/;"       f       file:
-do_read        pstream.c       /^static int do_read(pa_pstream *p) {$/;"       f       file:
-do_remap       remap.h /^    pa_do_remap_func_t do_remap;$/;"  m       struct:pa_remap
-do_something   pstream.c       /^static void do_something(pa_pstream *p) {$/;" f       file:
-do_unlink      shm.h   /^    pa_bool_t do_unlink:1;$/;"        m       struct:pa_shm
-do_volume_table        svolume_c.c     /^static pa_do_volume_func_t do_volume_table[] =$/;"    v       file:
-do_work        ioline.c        /^static void do_work(pa_ioline *l) {$/;"       f       file:
-do_work        protocol-esound.c       /^static void do_work(connection *c) {$/;"      f       file:
-do_work        protocol-http.c /^static void do_work(struct connection *c) {$/;"       f       file:
-do_work        protocol-simple.c       /^static void do_work(connection *c) {$/;"      f       file:
-do_write       ioline.c        /^static int do_write(pa_ioline *l) {$/;"       f       file:
-do_write       protocol-esound.c       /^static int do_write(connection *c) {$/;"      f       file:
-do_write       protocol-http.c /^static int do_write(struct connection *c) {$/;"       f       file:
-do_write       protocol-simple.c       /^static int do_write(connection *c) {$/;"      f       file:
-do_write       pstream.c       /^static int do_write(pa_pstream *p) {$/;"      f       file:
-done   module.h        /^    void (*done)(pa_module*m);$/;"    m       struct:pa_module
-done   once.h  /^    pa_atomic_t ref, done;$/;"        m       struct:pa_once
-dont_rewind_render     sink-input.h    /^        pa_bool_t rewrite_flush:1, dont_rewind_render:1;$/;"  m       struct:pa_sink_input::__anon27
-dp     time-smoother.c /^    double dp;            \/* Gradient we want at point p *\/$/;"     m       struct:pa_smoother      file:
-drain_callback ioline.c        /^    pa_ioline_drain_cb_t drain_callback;$/;"  m       struct:pa_ioline        file:
-drain_callback pdispatch.c     /^    pa_pdispatch_drain_cb_t drain_callback;$/;"       m       struct:pa_pdispatch     file:
-drain_callback pstream.c       /^    pa_pstream_notify_cb_t drain_callback;$/;"        m       struct:pa_pstream       file:
-drain_callback_userdata        pstream.c       /^    void *drain_callback_userdata;$/;"        m       struct:pa_pstream       file:
-drain_request  protocol-native.c       /^    pa_bool_t drain_request:1;$/;"    m       struct:playback_stream  file:
-drain_tag      protocol-native.c       /^    uint32_t drain_tag;$/;"   m       struct:playback_stream  file:
-drain_userdata ioline.c        /^    void *drain_userdata;$/;" m       struct:pa_ioline        file:
-drain_userdata pdispatch.c     /^    void *drain_userdata;$/;" m       struct:pa_pdispatch     file:
-drained        sink-input.h    /^        pa_atomic_t drained;$/;"      m       struct:pa_sink_input::__anon27
-driver card.h  /^    char *driver;$/;" m       struct:pa_card
-driver card.h  /^    const char *driver;$/;"   m       struct:pa_card_new_data
-driver client.h        /^    char *driver;$/;" m       struct:pa_client
-driver client.h        /^    const char *driver;$/;"   m       struct:pa_client_new_data
-driver sink-input.h    /^    char *driver;                       \/* may be NULL *\/$/;"       m       struct:pa_sink_input
-driver sink-input.h    /^    const char *driver;$/;"   m       struct:pa_sink_input_new_data
-driver sink.h  /^    char *driver;                           \/* may be NULL *\/$/;"   m       struct:pa_sink
-driver sink.h  /^    const char *driver;$/;"   m       struct:pa_sink_new_data
-driver source-output.h /^    char *driver;                         \/* may be NULL *\/$/;"     m       struct:pa_source_output
-driver source-output.h /^    const char *driver;$/;"   m       struct:pa_source_output_new_data
-driver source.h        /^    char *driver;                             \/* may be NULL *\/$/;" m       struct:pa_source
-driver source.h        /^    const char *driver;$/;"   m       struct:pa_source_new_data
-drop_backlog   memblockq.c     /^static void drop_backlog(pa_memblockq *bq) {$/;"      f       file:
-drop_block     memblockq.c     /^static void drop_block(pa_memblockq *bq, struct list_item *q) {$/;"   f       file:
-drop_initial   protocol-native.c       /^    size_t drop_initial;$/;"  m       struct:record_stream    file:
-drop_old       time-smoother.c /^static void drop_old(pa_smoother *s, pa_usec_t x) {$/;"       f       file:
-dst_incr       ffmpeg/resample2.c      /^    int dst_incr;$/;" m       struct:AVResampleContext        file:
-dump_event     core-subscribe.c        /^static void dump_event(const char * prefix, pa_subscription_event*e) {$/;"    f       file:
-dynamic        tagstruct.c     /^    pa_bool_t dynamic;$/;"    m       struct:pa_tagstruct     file:
-early_requests protocol-native.c       /^    pa_bool_t early_requests:1;$/;"   m       struct:playback_stream  file:
-early_requests protocol-native.c       /^    pa_bool_t early_requests:1;$/;"   m       struct:record_stream    file:
-efd    fdsem.c /^    int efd;$/;"      m       struct:pa_fdsem file:
-empty_pipe     lock-autospawn.c        /^static void empty_pipe(void) {$/;"    f       file:
-enable_mainloop_sources        iochannel.c     /^static void enable_mainloop_sources(pa_iochannel *io) {$/;"   f       file:
-entry  database-simple.c       /^typedef struct entry {$/;"    s       file:
-entry  database-simple.c       /^} entry;$/;"  t       typeref:struct:entry    file:
-entry  modargs.c       /^struct entry {$/;"    s       file:
-envelope_begin_read    envelope.c      /^static void envelope_begin_read(pa_envelope *e, int *v) {$/;" f       file:
-envelope_begin_write   envelope.c      /^static void envelope_begin_write(pa_envelope *e, int *v) {$/;"        f       file:
-envelope_commit_read   envelope.c      /^static void envelope_commit_read(pa_envelope *e, int v) {$/;" f       file:
-envelope_commit_write  envelope.c      /^static pa_bool_t envelope_commit_write(pa_envelope *e, int v) {$/;"   f       file:
-envelope_merge envelope.c      /^static void envelope_merge(pa_envelope *e, int v) {$/;"       f       file:
-envelope_state envelope.c      /^enum envelope_state {$/;"     g       file:
-environ        proplist-util.c 32;"    d       file:
-eof_callback   cli.c   /^    pa_cli_eof_cb_t eof_callback;$/;" m       struct:pa_cli   file:
-escape_html    protocol-http.c /^static char *escape_html(const char *t) {$/;" f       file:
-esd_client_state       esound.h        /^enum esd_client_state {$/;"   g
-esd_client_state_t     esound.h        /^typedef int esd_client_state_t;$/;"   t
-esd_format_t   esound.h        /^typedef int esd_format_t;$/;" t
-esd_info       esound.h        /^typedef struct esd_info {$/;" s
-esd_info_t     esound.h        /^} esd_info_t;$/;"     t       typeref:struct:esd_info
-esd_player_info        esound.h        /^typedef struct esd_player_info {$/;"  s
-esd_player_info_t      esound.h        /^} esd_player_info_t;$/;"      t       typeref:struct:esd_player_info
-esd_proto      esound.h        /^enum esd_proto {$/;"  g
-esd_proto_all_info     protocol-esound.c       /^static int esd_proto_all_info(connection *c, esd_proto_t request, const void *data, size_t length) {$/;"      f       file:
-esd_proto_connect      protocol-esound.c       /^static int esd_proto_connect(connection *c, esd_proto_t request, const void *data, size_t length) {$/;"       f       file:
-esd_proto_get_latency  protocol-esound.c       /^static int esd_proto_get_latency(connection *c, esd_proto_t request, const void *data, size_t length) {$/;"   f       file:
-esd_proto_handler_info_t       protocol-esound.c       /^} esd_proto_handler_info_t;$/;"       t       typeref:struct:proto_handler    file:
-esd_proto_sample_cache protocol-esound.c       /^static int esd_proto_sample_cache(connection *c, esd_proto_t request, const void *data, size_t length) {$/;"  f       file:
-esd_proto_sample_free_or_play  protocol-esound.c       /^static int esd_proto_sample_free_or_play(connection *c, esd_proto_t request, const void *data, size_t length) {$/;"   f       file:
-esd_proto_sample_get_id        protocol-esound.c       /^static int esd_proto_sample_get_id(connection *c, esd_proto_t request, const void *data, size_t length) {$/;" f       file:
-esd_proto_sample_pan   protocol-esound.c       /^static int esd_proto_sample_pan(connection *c, esd_proto_t request, const void *data, size_t length) {$/;"    f       file:
-esd_proto_server_info  protocol-esound.c       /^static int esd_proto_server_info(connection *c, esd_proto_t request, const void *data, size_t length) {$/;"   f       file:
-esd_proto_standby_mode protocol-esound.c       /^static int esd_proto_standby_mode(connection *c, esd_proto_t request, const void *data, size_t length) {$/;"  f       file:
-esd_proto_standby_or_resume    protocol-esound.c       /^static int esd_proto_standby_or_resume(connection *c, esd_proto_t request, const void *data, size_t length) {$/;"     f       file:
-esd_proto_stream_pan   protocol-esound.c       /^static int esd_proto_stream_pan(connection *c, esd_proto_t request, const void *data, size_t length) {$/;"    f       file:
-esd_proto_stream_play  protocol-esound.c       /^static int esd_proto_stream_play(connection *c, esd_proto_t request, const void *data, size_t length) {$/;"   f       file:
-esd_proto_stream_record        protocol-esound.c       /^static int esd_proto_stream_record(connection *c, esd_proto_t request, const void *data, size_t length) {$/;" f       file:
-esd_proto_t    esound.h        /^typedef int esd_proto_t;$/;"  t
-esd_sample_info        esound.h        /^typedef struct esd_sample_info {$/;"  s
-esd_sample_info_t      esound.h        /^} esd_sample_info_t;$/;"      t       typeref:struct:esd_sample_info
-esd_server_info        esound.h        /^typedef struct esd_server_info {$/;"  s
-esd_server_info_t      esound.h        /^} esd_server_info_t;$/;"      t       typeref:struct:esd_server_info
-esd_standby_mode       esound.h        /^enum esd_standby_mode {$/;"   g
-esd_standby_mode_t     esound.h        /^typedef int esd_standby_mode_t;$/;"   t
-esound_protocol_new    protocol-esound.c       /^static pa_esound_protocol* esound_protocol_new(pa_core *c) {$/;"      f       file:
-estimate       time-smoother.c /^static void estimate(pa_smoother *s, pa_usec_t x, pa_usec_t *y, double *deriv) {$/;"  f       file:
-event  client.h        /^    const char *event;$/;"    m       struct:pa_client_send_event_hook_data
-event  sink-input.h    /^    const char *event;$/;"    m       struct:pa_sink_input_send_event_hook_data
-event  source-output.h /^    const char *event;$/;"    m       struct:pa_source_output_send_event_hook_data
-event_cb       x11wrap.c       /^    pa_x11_event_cb_t event_cb;$/;"   m       struct:pa_x11_client    file:
-events poll.h  /^    short int events;           \/* Types of events poller cares about.  *\/$/;"      m       struct:pollfd
-ex     time-smoother.c /^    pa_usec_t ex, ey;     \/* Point e, which we estimated before and need to smooth to *\/$/;"        m       struct:pa_smoother      file:
-exit_callback  core.c  /^static void exit_callback(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata) {$/;"        f       file:
-exit_event     core.h  /^    pa_time_event *exit_event;$/;"    m       struct:pa_core
-exit_idle_time core.h  /^    int exit_idle_time, scache_idle_time;$/;" m       struct:pa_core
-expand_buffer_trashcontents    usergroup.c     /^static int expand_buffer_trashcontents(void **bufptr, size_t *buflenptr) {$/;"        f       file:
-export pstream.c       /^    pa_memexport *export;$/;" m       struct:pa_pstream       file:
-exported_size  memblock.h      /^    pa_atomic_t exported_size;$/;"    m       struct:pa_mempool_stat
-extend tagstruct.c     /^static void extend(pa_tagstruct*t, size_t l) {$/;"    f       file:
-extensions     protocol-native.c       /^    pa_hashmap *extensions;$/;"       m       struct:pa_native_protocol       file:
-ey     time-smoother.c /^    pa_usec_t ex, ey;     \/* Point e, which we estimated before and need to smooth to *\/$/;"        m       struct:pa_smoother      file:
-f      envelope.c      /^            float *f;$/;"     m       union:pa_envelope::__anon23::__anon24   file:
-f      envelope.c      /^        float f;$/;"  m       union:pa_envelope_item::__anon22        file:
-f      envelope.h      /^        float f[PA_ENVELOPE_POINTS_MAX];$/;"  m       struct:pa_envelope_def::__anon21
-f      sample-util.c   /^  float f;$/;"        m       union:__anon7   file:
-f      sample-util.h   /^        float f;$/;"  m       union:pa_mix_info::__anon20
-f      vector.h        /^    float f[PA_FLOAT_VECTOR_SIZE];$/;"        m       union:pa_float_vector
-fail   cli.c   /^    pa_bool_t fail, kill_requested;$/;"       m       struct:pa_cli   file:
-failure        ioline.c        /^static void failure(pa_ioline *l, pa_bool_t process_leftover) {$/;"   f       file:
-family ipacl.c /^    int family;$/;"   m       struct:acl_entry        file:
-fd     poll.h  /^    int fd;                     \/* File descriptor to poll.  *\/$/;" m       struct:pollfd
-fd     socket-client.c /^    int fd;$/;"       m       struct:pa_socket_client file:
-fd     socket-server.c /^    int fd;$/;"       m       struct:pa_socket_server file:
-fd     x11wrap.c       /^    int fd;$/;"       m       struct:pa_x11_internal  file:
-fds    fdsem.c /^    int fds[2];$/;"   m       struct:pa_fdsem file:
-fdsem_after    rtpoll.c        /^static void fdsem_after(pa_rtpoll_item *i) {$/;"      f       file:
-fdsem_before   rtpoll.c        /^static int fdsem_before(pa_rtpoll_item *i) {$/;"      f       file:
-ffmpeg resampler.c     /^    } ffmpeg;$/;"     m       struct:pa_resampler     typeref:struct:pa_resampler::__anon41   file:
-ffmpeg_free    resampler.c     /^static void ffmpeg_free(pa_resampler *r) {$/;"        f       file:
-ffmpeg_init    resampler.c     /^static int ffmpeg_init(pa_resampler *r) {$/;" f       file:
-ffmpeg_resample        resampler.c     /^static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {$/;"       f       file:
-file_stream    sound-file-stream.c     /^typedef struct file_stream {$/;"      s       file:
-file_stream    sound-file-stream.c     /^} file_stream;$/;"    t       typeref:struct:file_stream      file:
-file_stream_free       sound-file-stream.c     /^static void file_stream_free(pa_object *o) {$/;"      f       file:
-file_stream_process_msg        sound-file-stream.c     /^static int file_stream_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) {$/;"        f       file:
-file_stream_unlink     sound-file-stream.c     /^static void file_stream_unlink(file_stream *u) {$/;"  f       file:
-filename       core-scache.h   /^    char *filename;$/;"       m       struct:pa_scache_entry
-filename       database-simple.c       /^    char *filename;$/;"       m       struct:simple_data      file:
-filename       socket-server.c /^    char *filename;$/;"       m       struct:pa_socket_server file:
-fill_data      database-simple.c       /^static int fill_data(simple_data *db, FILE *f) {$/;"  f       file:
-fill_mix_info  sink.c  /^static unsigned fill_mix_info(pa_sink *s, size_t *length, pa_mix_info *info, unsigned maxinfo) {$/;"  f       file:
-filter_bank    ffmpeg/resample2.c      /^    FELEM *filter_bank;$/;"   m       struct:AVResampleContext        file:
-filter_length  ffmpeg/resample2.c      /^    int filter_length;$/;"    m       struct:AVResampleContext        file:
-fix_current_read       memblockq.c     /^static void fix_current_read(pa_memblockq *bq) {$/;"  f       file:
-fix_current_write      memblockq.c     /^static void fix_current_write(pa_memblockq *bq) {$/;" f       file:
-fix_playback_buffer_attr       protocol-native.c       /^static void fix_playback_buffer_attr(playback_stream *s) {$/;"        f       file:
-fix_record_buffer_attr_post    protocol-native.c       /^static void fix_record_buffer_attr_post(record_stream *s) {$/;"       f       file:
-fix_record_buffer_attr_pre     protocol-native.c       /^static void fix_record_buffer_attr_pre(record_stream *s) {$/;"        f       file:
-fixed_latency  sink.h  /^        pa_usec_t fixed_latency; \/* for sinks with PA_SINK_DYNAMIC_LATENCY this is 0 *\/$/;" m       struct:pa_sink::__anon36
-fixed_latency  source.h        /^        pa_usec_t fixed_latency; \/* for sources with PA_SOURCE_DYNAMIC_LATENCY this is 0 *\/$/;"     m       struct:pa_source::__anon2
-fixup_sample_spec      protocol-native.c       /^static void fixup_sample_spec(pa_native_connection *c, pa_sample_spec *fixed, const pa_sample_spec *original) {$/;"   f       file:
-flags  log.c   /^static pa_log_flags_t flags = 0, flags_override = 0;$/;"      v       file:
-flags  resampler.c     /^    pa_resample_flags_t flags;$/;"    m       struct:pa_resampler     file:
-flags  sink-input.h    /^    pa_sink_input_flags_t flags;$/;"  m       struct:pa_sink_input
-flags  sink-input.h    /^    pa_sink_input_flags_t flags;$/;"  m       struct:pa_sink_input_new_data
-flags  sink.h  /^    pa_sink_flags_t flags;$/;"        m       struct:pa_sink
-flags  source-output.h /^    pa_source_output_flags_t flags;$/;"       m       struct:pa_source_output
-flags  source-output.h /^    pa_source_output_flags_t flags;$/;"       m       struct:pa_source_output_new_data
-flags  source.h        /^    pa_source_flags_t flags;$/;"      m       struct:pa_source
-flags_override log.c   /^static pa_log_flags_t flags = 0, flags_override = 0;$/;"      v       file:
-flat_volumes   core.h  /^    pa_bool_t flat_volumes:1;$/;"     m       struct:pa_core
-float32ne_to_float32ne sconv.c /^static void float32ne_to_float32ne(unsigned n, const float *a, float *b) {$/;"        f       file:
-float32re_to_float32ne sconv.c /^static void float32re_to_float32ne(unsigned n, const float *a, float *b) {$/;"        f       file:
-flush  fdsem.c /^static void flush(pa_fdsem *f) {$/;"  f       file:
-flush_postq    asyncq.c        /^static pa_bool_t flush_postq(pa_asyncq *l, pa_bool_t wait_op) {$/;"   f       file:
-fooauthcookiehfoo      auth-cookie.h   2;"     d
-fooauthkeyhfoo authkey.h       2;"     d
-fooavahiwrapperhfoo    avahi-wrap.h    2;"     d
-fooclicommandhfoo      cli-command.h   2;"     d
-fooclihfoo     cli.h   2;"     d
-fooclitexthfoo cli-text.h      2;"     d
-fooconfparserhfoo      conf-parser.h   2;"     d
-foocoreerrorhfoo       core-error.h    2;"     d
-foocorehfoo    core.h  2;"     d
-foocorescachehfoo      core-scache.h   2;"     d
-foocoresubscribehfoo   core-subscribe.h        2;"     d
-foocoreutilhfoo        core-util.h     2;"     d
-foocpuarmhfoo  cpu-arm.h       2;"     d
-foocpux86hfoo  cpu-x86.h       2;"     d
-foocredshfoo   creds.h 2;"     d
-foodbussharedhfoo      dbus-shared.h   2;"     d
-foodbusutilhfoo        dbus-util.h     2;"     d
-fooendianmacroshfoo    endianmacros.h  2;"     d
-fooesoundhfoo  esound.h        2;"     d
-foog711hfoo    g711.h  2;"     d
-foohooklistfoo hook-list.h     2;"     d
-fooinet_ntophfoo       inet_ntop.h     2;"     d
-fooinet_ptonhfoo       inet_pton.h     2;"     d
-fooiochannelhfoo       iochannel.h     2;"     d
-fooiolinehfoo  ioline.h        2;"     d
-foollistfoo    llist.h 2;"     d
-foologhfoo     log.h   2;"     d
-foomcalignhfoo mcalign.h       2;"     d
-foomemblockqhfoo       memblockq.h     2;"     d
-foomemchunkhfoo        memchunk.h      2;"     d
-foomodargshfoo modargs.h       2;"     d
-foomodinfohfoo modinfo.h       2;"     d
-foomodulehfoo  module.h        2;"     d
-foonamereghfoo namereg.h       2;"     d
-foonativecommonhfoo    native-common.h 2;"     d
-foopackethfoo  packet.h        2;"     d
-foopdispatchhfoo       pdispatch.h     2;"     d
-foopidhfoo     pid.h   2;"     d
-foopipehfoo    pipe.h  2;"     d
-fooplaychunkhfoo       play-memchunk.h 2;"     d
-fooplaymemblockqhfoo   play-memblockq.h        2;"     d
-fooproplistutilutilhfoo        proplist-util.h 2;"     d
-fooprotocolclihfoo     protocol-cli.h  2;"     d
-fooprotocolesoundhfoo  protocol-esound.h       2;"     d
-fooprotocolhttphfoo    protocol-http.h 2;"     d
-fooprotocolnativehfoo  protocol-native.h       2;"     d
-fooprotocolsimplehfoo  protocol-simple.h       2;"     d
-foopstreamhfoo pstream.h       2;"     d
-foopstreamutilhfoo     pstream-util.h  2;"     d
-foopulseasyncmsgqhfoo  asyncmsgq.h     2;"     d
-foopulseasyncqhfoo     asyncq.h        2;"     d
-foopulseatomichfoo     atomic.h        2;"     d
-foopulsecardhfoo       card.h  2;"     d
-foopulseclienthfoo     client.h        2;"     d
-foopulsecoreaupdatehfoo        aupdate.h       2;"     d
-foopulsecorebitsethfoo bitset.h        2;"     d
-foopulsecoredatabasehfoo       database.h      2;"     d
-foopulsecoredynarrayhfoo       dynarray.h      2;"     d
-foopulsecorehashmaphfoo        hashmap.h       2;"     d
-foopulsecoreidxsethfoo idxset.h        2;"     d
-foopulsecoreipaclhfoo  ipacl.h 2;"     d
-foopulsecoreltdlhelperhfoo     ltdl-helper.h   2;"     d
-foopulsecorememtraphfoo        memtrap.h       2;"     d
-foopulsecoremimetypehfoo       mime-type.h     2;"     d
-foopulsecoreparseaddrhfoo      parseaddr.h     2;"     d
-foopulsecoreprioqhfoo  prioq.h 2;"     d
-foopulsecorequeuehfoo  queue.h 2;"     d
-foopulsecoreratelimithfoo      ratelimit.h     2;"     d
-foopulsecoresndfileutilhfoo    sndfile-util.h  2;"     d
-foopulseenvelopehfoo   envelope.h      2;"     d
-foopulsefdsemhfoo      fdsem.h 2;"     d
-foopulseflisthfoo      flist.h 2;"     d
-foopulselockautospawnhfoo      lock-autospawn.h        2;"     d
-foopulsemacrohfoo      macro.h 2;"     d
-foopulsememblockhfoo   memblock.h      2;"     d
-foopulsemsgobjecthfoo  msgobject.h     2;"     d
-foopulsemutexhfoo      mutex.h 2;"     d
-foopulseobjecthfoo     object.h        2;"     d
-foopulseoncehfoo       once.h  2;"     d
-foopulserefcnthfoo     refcnt.h        2;"     d
-foopulsertclockhfoo    core-rtclock.h  2;"     d
-foopulsertpollhfoo     rtpoll.h        2;"     d
-foopulsesemaphorehfoo  semaphore.h     2;"     d
-foopulseshmhfoo        shm.h   2;"     d
-foopulsesinkhfoo       sink.h  2;"     d
-foopulsesinkinputhfoo  sink-input.h    2;"     d
-foopulsesourcehfoo     source.h        2;"     d
-foopulsesourceoutputhfoo       source-output.h 2;"     d
-foopulsestartchildhfoo start-child.h   2;"     d
-foopulsethreadhfoo     thread.h        2;"     d
-foopulsethreadmqhfoo   thread-mq.h     2;"     d
-foopulsetimesmootherhfoo       time-smoother.h 2;"     d
-foorandomhfoo  random.h        2;"     d
-fooremapfoo    remap.h 2;"     d
-fooresamplerhfoo       resampler.h     2;"     d
-foortkithfoo   rtkit.h 4;"     d
-foosampleutilhfoo      sample-util.h   2;"     d
-foosconv_s16befoo      sconv-s16be.h   2;"     d
-foosconv_s16lefoo      sconv-s16le.h   2;"     d
-foosconvhfoo   sconv.h 2;"     d
-foosharedshfoo shared.h        2;"     d
-foosiomanhfoo  sioman.h        2;"     d
-foosocketclienthfoo    socket-client.h 2;"     d
-foosocketserverhfoo    socket-server.h 2;"     d
-foosocketutilhfoo      socket-util.h   2;"     d
-foosoundfilestreamhfoo sound-file-stream.h     2;"     d
-foostrbufhfoo  strbuf.h        2;"     d
-foostrlisthfoo strlist.h       2;"     d
-footagstructhfoo       tagstruct.h     2;"     d
-footokenizerhfoo       tokenizer.h     2;"     d
-foousergrouphfoo       usergroup.h     2;"     d
-foowinsockhfoo winsock.h       2;"     d
-foox11prophfoo x11prop.h       2;"     d
-foox11wraphfoo x11wrap.h       2;"     d
-format esound.h        /^    esd_format_t format;        \/* magic int with the format info *\/$/;"    m       struct:esd_player_info
-format esound.h        /^    esd_format_t format;        \/* magic int with the format info *\/$/;"    m       struct:esd_sample_info
-format esound.h        /^    esd_format_t format;        \/* magic int with the format info *\/$/;"    m       struct:esd_server_info
-format remap.h /^    pa_sample_format_t *format;$/;"   m       struct:pa_remap
-format_esd2native      protocol-esound.c       /^static void format_esd2native(int format, pa_bool_t swap_bytes, pa_sample_spec *ss) {$/;"     f       file:
-format_native2esd      protocol-esound.c       /^static int format_native2esd(pa_sample_spec *ss) {$/;"        f       file:
-frac   ffmpeg/resample2.c      /^    int frac;$/;"     m       struct:AVResampleContext        file:
-free   object.h        /^    void (*free)(pa_object *o);$/;"   m       struct:pa_object
-free_cb        asyncmsgq.c     /^    pa_free_cb_t free_cb;$/;" m       struct:asyncmsgq_item   file:
-free_cb        memblock.c      /^            pa_free_cb_t free_cb;$/;" m       struct:pa_memblock::__anon4::__anon5    file:
-free_cb        pdispatch.c     /^    pa_free_cb_t free_cb;$/;" m       struct:reply_info       file:
-free_entry     core-scache.c   /^static void free_entry(pa_scache_entry *e) {$/;"      f       file:
-free_entry     database-simple.c       /^static void free_entry(entry *e) {$/;"        f       file:
-free_event     core-subscribe.c        /^static void free_event(pa_subscription_event *s) {$/;"        f       file:
-free_events    socket-client.c /^static void free_events(pa_socket_client *c) {$/;"    f       file:
-free_func      modargs.c       /^static void free_func(void *p, void*userdata) {$/;"   f       file:
-free_func      thread-win32.c  /^    pa_free_cb_t free_func;$/;"       m       struct:pa_tls   file:
-free_func      thread-win32.c  /^    pa_free_cb_t free_func;$/;"       m       struct:pa_tls_monitor   file:
-free_slots     memblock.c      /^    pa_flist *free_slots;$/;" m       struct:pa_mempool       file:
-free_subscription      core-subscribe.c        /^static void free_subscription(pa_subscription *s) {$/;"       f       file:
-from_float32ne_table   sconv.c /^static pa_convert_func_t from_float32ne_table[] = {$/;"       v       file:
-from_s16ne_table       sconv.c /^static pa_convert_func_t from_s16ne_table[] = {$/;"   v       file:
-from_work_format_func  resampler.c     /^    pa_convert_func_t from_work_format_func;$/;"      m       struct:pa_resampler     file:
-front  queue.c /^    struct queue_entry *front, *back;$/;"     m       struct:pa_queue typeref:struct:pa_queue::queue_entry    file:
-front_rear_side        resampler.c     /^static int front_rear_side(pa_channel_position_t p) {$/;"     f       file:
-g_get_application_name proplist-util.c /^static G_CONST_RETURN gchar* _g_get_application_name(void) PA_GCC_WEAKREF(g_get_application_name);$/;"        v
-generate       authkey.c       /^static int generate(int fd, void *ret_data, size_t length) {$/;"      f       file:
-get_backtrace  log.c   /^static char* get_backtrace(unsigned show_nframes) {$/;"       f       file:
-get_cpuid      cpu-x86.c       /^get_cpuid (uint32_t op, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d)$/;"       f       file:
-get_cpuinfo    cpu-arm.c       /^static char *get_cpuinfo(void) {$/;"  f       file:
-get_cpuinfo_line       cpu-arm.c       /^get_cpuinfo_line (char *cpuinfo, const char *tag) {$/;"       f       file:
-get_latency    sink-input.h    /^    pa_usec_t (*get_latency) (pa_sink_input *i); \/* may be NULL *\/$/;"      m       struct:pa_sink_input
-get_latency    source-output.h /^    pa_usec_t (*get_latency) (pa_source_output *o); \/* may be NULL *\/$/;"   m       struct:pa_source_output
-get_mute       sink.h  /^    void (*get_mute)(pa_sink *s);               \/* dito *\/$/;"      m       struct:pa_sink
-get_mute       source.h        /^    void (*get_mute)(pa_source *s);           \/* dito *\/$/;"        m       struct:pa_source
-get_n_used     module.h        /^    int (*get_n_used)(pa_module *m);$/;"      m       struct:pa_module
-get_path       core-util.c     /^static char *get_path(const char *fn, pa_bool_t prependmid, pa_bool_t rt) {$/;"       f       file:
-get_pulse_home core-util.c     /^static char *get_pulse_home(void) {$/;"       f       file:
-get_volume     sink.h  /^    void (*get_volume)(pa_sink *s);             \/* may be NULL *\/$/;"       m       struct:pa_sink
-get_volume     source.h        /^    void (*get_volume)(pa_source *s);         \/* dito *\/$/;"        m       struct:pa_source
-get_watch_flags        dbus-util.c     /^static pa_io_event_flags_t get_watch_flags(DBusWatch *watch) {$/;"    f       file:
-gid    creds.h /^    gid_t gid;$/;"    m       struct:pa_creds
-gtk_window_get_default_icon_name       proplist-util.c /^static G_CONST_RETURN gchar* _gtk_window_get_default_icon_name(void) PA_GCC_WEAKREF(gtk_window_get_default_icon_name);$/;"    v
-handle_css     protocol-http.c /^static void handle_css(struct connection *c) {$/;"    f       file:
-handle_io_event        dbus-util.c     /^static void handle_io_event(pa_mainloop_api *ea, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {$/;"    f       file:
-handle_listen  protocol-http.c /^static void handle_listen(struct connection *c) {$/;" f       file:
-handle_listen_prefix   protocol-http.c /^static void handle_listen_prefix(struct connection *c, const char *source_name) {$/;" f       file:
-handle_root    protocol-http.c /^static void handle_root(struct connection *c) {$/;"   f       file:
-handle_seek    protocol-native.c       /^static void handle_seek(playback_stream *s, int64_t indexw) {$/;"     f       file:
-handle_status  protocol-http.c /^static void handle_status(struct connection *c) {$/;" f       file:
-handle_time_event      dbus-util.c     /^static void handle_time_event(pa_mainloop_api *ea, pa_time_event* e, const struct timeval *t, void *userdata) {$/;"   f       file:
-handle_url     protocol-http.c /^static void handle_url(struct connection *c) {$/;"    f       file:
-has_whined     random.c        /^static pa_bool_t has_whined = TRUE;$/;"       v       file:
-hash_func      database-simple.c       /^static unsigned hash_func(const void *p) {$/;"        f       file:
-hash_func      hashmap.c       /^    pa_hash_func_t hash_func;$/;"     m       struct:pa_hashmap       file:
-hash_func      idxset.c        /^    pa_hash_func_t hash_func;$/;"     m       struct:pa_idxset        file:
-hash_scan      hashmap.c       /^static struct hashmap_entry *hash_scan(pa_hashmap *h, unsigned hash, const void *key) {$/;"   f       file:
-hashmap_entry  hashmap.c       /^struct hashmap_entry {$/;"    s       file:
-head   strbuf.c        /^    struct chunk *head, *tail;$/;"    m       struct:pa_strbuf        typeref:struct:pa_strbuf::chunk file:
-help   cli-command.c   /^    const char *help;$/;"     m       struct:command  file:
-hexc   core-util.c     /^static int hexc(char c) {$/;" f       file:
-history_idx    time-smoother.c /^    unsigned history_idx, n_history;$/;"      m       struct:pa_smoother      file:
-history_time   time-smoother.c /^    pa_usec_t adjust_time, history_time;$/;"  m       struct:pa_smoother      file:
-history_x      time-smoother.c /^    pa_usec_t history_x[HISTORY_MAX], history_y[HISTORY_MAX];$/;"     m       struct:pa_smoother      file:
-history_y      time-smoother.c /^    pa_usec_t history_x[HISTORY_MAX], history_y[HISTORY_MAX];$/;"     m       struct:pa_smoother      file:
-hook   hook-list.h     /^    pa_hook *hook;$/;"        m       struct:pa_hook_slot
-hooks  core.h  /^    pa_hook hooks[PA_CORE_HOOK_MAX];$/;"      m       struct:pa_core
-hooks  protocol-native.c       /^    pa_hook hooks[PA_NATIVE_HOOK_MAX];$/;"    m       struct:pa_native_protocol       file:
-html_print_field       protocol-http.c /^static void html_print_field(pa_ioline *line, const char *left, const char *right) {$/;"      f       file:
-html_response  protocol-http.c /^static void html_response($/;"        f       file:
-http_protocol_new      protocol-http.c /^static pa_http_protocol* http_protocol_new(pa_core *c) {$/;"  f       file:
-http_response  protocol-http.c /^static void http_response($/;"        f       file:
-hungup iochannel.c     /^    pa_bool_t hungup;$/;"     m       struct:pa_iochannel     file:
-i      envelope.c      /^            int32_t *i;$/;"   m       union:pa_envelope::__anon23::__anon24   file:
-i      envelope.c      /^        int32_t i;$/;"        m       union:pa_envelope_item::__anon22        file:
-i      envelope.h      /^        int32_t i[PA_ENVELOPE_POINTS_MAX];$/;"        m       struct:pa_envelope_def::__anon21
-i      sample-util.c   /^  uint32_t i;$/;"     m       union:__anon7   file:
-i      sample-util.h   /^        int32_t i;$/;"        m       union:pa_mix_info::__anon20
-i      vector.h        /^    int16_t i[PA_INT16_VECTOR_SIZE];$/;"      m       union:pa_int16_vector
-i      vector.h        /^    int32_t i[PA_INT32_VECTOR_SIZE];$/;"      m       union:pa_int32_vector
-i_cm   resampler.c     /^    pa_channel_map i_cm, o_cm;$/;"    m       struct:pa_resampler     file:
-i_counter      resampler.c     /^        unsigned i_counter;$/;"       m       struct:pa_resampler::__anon37   file:
-i_counter      resampler.c     /^        unsigned i_counter;$/;"       m       struct:pa_resampler::__anon38   file:
-i_fz   resampler.c     /^    size_t i_fz, o_fz, w_sz;$/;"      m       struct:pa_resampler     file:
-i_ss   remap.h /^    pa_sample_spec *i_ss, *o_ss;$/;"  m       struct:pa_remap
-i_ss   resampler.c     /^    pa_sample_spec i_ss, o_ss;$/;"    m       struct:pa_resampler     file:
-id     memblock.c      /^            uint32_t id;$/;"  m       struct:pa_memblock::__anon4::__anon6    file:
-id     shm.h   /^    unsigned id;$/;"  m       struct:pa_shm
-id     thread-posix.c  /^    pthread_t id;$/;" m       struct:pa_thread        file:
-ideal_dst_incr ffmpeg/resample2.c      /^    int ideal_dst_incr;$/;"   m       struct:AVResampleContext        file:
-ident  log.c   /^static char *ident = NULL; \/* in local charset format *\/$/;"        v       file:
-ident_destructor       log.c   /^static void ident_destructor(void) {$/;"      f       file:
-idx    idxset.c        /^    uint32_t idx;$/;" m       struct:idxset_entry     file:
-idx    prioq.c /^    unsigned idx;$/;" m       struct:pa_prioq_item    file:
-idxset_entry   idxset.c        /^struct idxset_entry {$/;"     s       file:
-ifd    iochannel.c     /^    int ifd, ofd;$/;" m       struct:pa_iochannel     file:
-ifd_type       iochannel.c     /^    int ifd_type, ofd_type;$/;"       m       struct:pa_iochannel     file:
-impl_free      resampler.c     /^    void (*impl_free)(pa_resampler *r);$/;"   m       struct:pa_resampler     file:
-impl_resample  resampler.c     /^    void (*impl_resample)(pa_resampler *r, const pa_memchunk *in, unsigned in_samples, pa_memchunk *out, unsigned *out_samples);$/;"  m       struct:pa_resampler     file:
-impl_reset     resampler.c     /^    void (*impl_reset)(pa_resampler *r);$/;"  m       struct:pa_resampler     file:
-impl_update_rates      resampler.c     /^    void (*impl_update_rates)(pa_resampler *r);$/;"   m       struct:pa_resampler     file:
-import memblock.c      /^    pa_memimport *import;$/;" m       struct:pa_memimport_segment     file:
-import pstream.c       /^    pa_memimport *import;$/;" m       struct:pa_pstream       file:
-imported       memblock.c      /^        } imported;$/;"       m       union:pa_memblock::__anon4      typeref:struct:pa_memblock::__anon4::__anon6    file:
-imported_size  memblock.h      /^    pa_atomic_t imported_size;$/;"    m       struct:pa_mempool_stat
-in_pipe        fdsem.h /^    pa_atomic_t in_pipe;$/;"  m       struct:pa_fdsem_data
-in_prebuf      memblockq.c     /^    pa_bool_t in_prebuf;$/;"  m       struct:pa_memblockq     file:
-in_string      conf-parser.c   /^static int in_string(char c, const char *s) {$/;"     f       file:
-index  card.h  /^    uint32_t index;$/;"       m       struct:pa_card
-index  client.h        /^    uint32_t index;$/;"       m       struct:pa_client
-index  core-scache.h   /^    uint32_t index;$/;"       m       struct:pa_scache_entry
-index  core-subscribe.c        /^    uint32_t index;$/;"       m       struct:pa_subscription_event    file:
-index  ffmpeg/resample2.c      /^    int index;$/;"    m       struct:AVResampleContext        file:
-index  memblockq.c     /^    int64_t index;$/;"        m       struct:list_item        file:
-index  memchunk.h      /^    size_t index, length;$/;" m       struct:pa_memchunk
-index  module.h        /^    uint32_t index;$/;"       m       struct:pa_module
-index  protocol-esound.c       /^    uint32_t index;$/;"       m       struct:connection       file:
-index  protocol-native.c       /^    uint32_t index;$/;"       m       struct:playback_stream  file:
-index  protocol-native.c       /^    uint32_t index;$/;"       m       struct:record_stream    file:
-index  protocol-native.c       /^    uint32_t index;$/;"       m       struct:upload_stream    file:
-index  pstream.c       /^        size_t index;$/;"     m       struct:pa_pstream::__anon34     file:
-index  pstream.c       /^        size_t index;$/;"     m       struct:pa_pstream::__anon35     file:
-index  sink-input.h    /^    uint32_t index;$/;"       m       struct:pa_sink_input
-index  sink.h  /^    uint32_t index;$/;"       m       struct:pa_sink
-index  source-output.h /^    uint32_t index;$/;"       m       struct:pa_source_output
-index  source.h        /^    uint32_t index;$/;"       m       struct:pa_source
-index  thread-win32.c  /^    DWORD index;$/;"  m       struct:pa_tls   file:
-index_next     idxset.c        /^    struct idxset_entry *index_next, *index_previous;$/;"     m       struct:idxset_entry     typeref:struct:idxset_entry::idxset_entry       file:
-index_previous idxset.c        /^    struct idxset_entry *index_next, *index_previous;$/;"     m       struct:idxset_entry     typeref:struct:idxset_entry::   file:
-index_scan     idxset.c        /^static struct idxset_entry* index_scan(pa_idxset *s, unsigned hash, uint32_t idx) {$/;"       f       file:
-inet_ntop      inet_ntop.c     /^const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) {$/;"        f
-inet_pton      inet_pton.c     /^int inet_pton(int af, const char *src, void *dst) {$/;"       f
-init   module.h        /^    int (*init)(pa_module*m);$/;"     m       struct:pa_module
-init_defaults  log.c   /^static void init_defaults(void) {$/;" f       file:
-init_remap_c   remap.c /^static void init_remap_c (pa_remap_t *m) {$/;"        f       file:
-init_remap_mmx remap_mmx.c     /^static void init_remap_mmx (pa_remap_t *m) {$/;"      f       file:
-init_remap_sse2        remap_sse.c     /^static void init_remap_sse2 (pa_remap_t *m) {$/;"     f       file:
-init_table     resampler.c     /^static int (* const init_table[])(pa_resampler*r) = {$/;"     v       file:
-input_event    iochannel.c     /^    pa_io_event* input_event, *output_event;$/;"      m       struct:pa_iochannel     file:
-input_memblockq        protocol-esound.c       /^    pa_memblockq *input_memblockq, *output_memblockq;$/;"     m       struct:connection       file:
-input_memblockq        protocol-simple.c       /^    pa_memblockq *input_memblockq, *output_memblockq;$/;"     m       struct:connection       file:
-inputs sink.h  /^        pa_hashmap *inputs;$/;"       m       struct:pa_sink::__anon36
-inputs sink.h  /^    pa_idxset *inputs;$/;"    m       struct:pa_sink
-inputs_drop    sink.c  /^static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned n, pa_memchunk *result) {$/;" f       file:
-inq    thread-mq.h     /^    pa_asyncmsgq *inq, *outq;$/;"     m       struct:pa_thread_mq
-internal_io_event      x11wrap.c       /^static void internal_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {$/;"        f       file:
-internal_thread_func   thread-posix.c  /^static void* internal_thread_func(void *userdata) {$/;"       f       file:
-internal_thread_func   thread-win32.c  /^static DWORD WINAPI internal_thread_func(LPVOID param) {$/;"  f       file:
-interval       ratelimit.h     /^    pa_usec_t interval;$/;"   m       struct:pa_ratelimit
-io     ioline.c        /^    pa_iochannel *io;$/;"     m       struct:pa_ioline        file:
-io     protocol-esound.c       /^    pa_iochannel *io;$/;"     m       struct:connection       file:
-io     protocol-http.c /^    pa_iochannel *io;$/;"     m       struct:connection       file:
-io     protocol-simple.c       /^    pa_iochannel *io;$/;"     m       struct:connection       file:
-io     pstream.c       /^    pa_iochannel *io;$/;"     m       struct:pa_pstream       file:
-io_callback    ioline.c        /^static void io_callback(pa_iochannel*io, void *userdata) {$/;"        f       file:
-io_callback    protocol-esound.c       /^static void io_callback(pa_iochannel*io, void *userdata) {$/;"        f       file:
-io_callback    protocol-http.c /^static void io_callback(pa_iochannel*io, void *userdata) {$/;"        f       file:
-io_callback    protocol-simple.c       /^static void io_callback(pa_iochannel*io, void *userdata) {$/;"        f       file:
-io_callback    pstream.c       /^static void io_callback(pa_iochannel*io, void *userdata) {$/;"        f       file:
-io_event       avahi-wrap.c    /^    pa_io_event *io_event;$/;"        m       struct:AvahiWatch       file:
-io_event       socket-client.c /^    pa_io_event *io_event;$/;"        m       struct:pa_socket_client file:
-io_event       socket-server.c /^    pa_io_event *io_event;$/;"        m       struct:pa_socket_server file:
-io_event       x11wrap.c       /^    pa_io_event* io_event;$/;"        m       struct:pa_x11_internal  file:
-io_event       x11wrap.c       /^    pa_io_event* io_event;$/;"        m       struct:pa_x11_wrapper   file:
-ioline_free    ioline.c        /^static void ioline_free(pa_ioline *l) {$/;"   f       file:
-is_float       envelope.c      /^    pa_bool_t is_float;$/;"   m       struct:pa_envelope      file:
-is_group       core-util.c     /^static int is_group(gid_t gid, const char *name) {$/;"        f       file:
-is_local       protocol-native.c       /^    pa_bool_t is_local:1;$/;" m       struct:pa_native_connection     file:
-is_silence     memblock.c      /^    pa_bool_t is_silence:1;$/;"       m       struct:pa_memblock      file:
-is_underrun    protocol-native.c       /^    pa_bool_t is_underrun:1;$/;"      m       struct:playback_stream  file:
-is_valid_char  namereg.c       /^static pa_bool_t is_valid_char(char c) {$/;"  f       file:
-item_free      pstream.c       /^static void item_free(void *item, void *q) {$/;"      f       file:
-item_get_float envelope.c      /^static float item_get_float(pa_envelope_item *i, pa_usec_t x) {$/;"   f       file:
-item_get_int   envelope.c      /^static int32_t item_get_int(pa_envelope_item *i, pa_usec_t x) {$/;"   f       file:
-item_info      pstream.c       /^struct item_info {$/;"        s       file:
-items  prioq.c /^    pa_prioq_item **items;$/;"        m       struct:pa_prioq file:
-iterate_list_head      hashmap.c       /^    struct hashmap_entry *iterate_list_head, *iterate_list_tail;$/;"  m       struct:pa_hashmap       typeref:struct:pa_hashmap::hashmap_entry        file:
-iterate_list_head      idxset.c        /^    struct idxset_entry *iterate_list_head, *iterate_list_tail;$/;"   m       struct:pa_idxset        typeref:struct:pa_idxset::idxset_entry  file:
-iterate_list_tail      hashmap.c       /^    struct hashmap_entry *iterate_list_head, *iterate_list_tail;$/;"  m       struct:pa_hashmap       typeref:struct:pa_hashmap::     file:
-iterate_list_tail      idxset.c        /^    struct idxset_entry *iterate_list_head, *iterate_list_tail;$/;"   m       struct:pa_idxset        typeref:struct:pa_idxset::      file:
-iterate_next   hashmap.c       /^    struct hashmap_entry *iterate_next, *iterate_previous;$/;"        m       struct:hashmap_entry    typeref:struct:hashmap_entry::hashmap_entry     file:
-iterate_next   idxset.c        /^    struct idxset_entry *iterate_next, *iterate_previous;$/;" m       struct:idxset_entry     typeref:struct:idxset_entry::idxset_entry       file:
-iterate_previous       hashmap.c       /^    struct hashmap_entry *iterate_next, *iterate_previous;$/;"        m       struct:hashmap_entry    typeref:struct:hashmap_entry::  file:
-iterate_previous       idxset.c        /^    struct idxset_entry *iterate_next, *iterate_previous;$/;" m       struct:idxset_entry     typeref:struct:idxset_entry::   file:
-j      envelope.c      /^    unsigned j;$/;"   m       struct:pa_envelope_item file:
-joined thread-posix.c  /^    pa_bool_t joined;$/;"     m       struct:pa_thread        file:
-key    database-simple.c       /^    pa_datum key;$/;" m       struct:entry    file:
-key    hashmap.c       /^    const void *key;$/;"      m       struct:hashmap_entry    file:
-key    modargs.c       /^    char *key, *value;$/;"    m       struct:entry    file:
-key    thread-posix.c  /^    pthread_key_t key;$/;"    m       struct:pa_tls   file:
-kill   client.h        /^    void (*kill)(pa_client *c);$/;"   m       struct:pa_client
-kill   sink-input.h    /^    void (*kill) (pa_sink_input *i);             \/* may NOT be NULL *\/$/;"  m       struct:pa_sink_input
-kill   source-output.h /^    void (*kill)(pa_source_output* o);              \/* may NOT be NULL *\/$/;"       m       struct:pa_source_output
-kill_cb        x11wrap.c       /^    pa_x11_kill_cb_t kill_cb;$/;"     m       struct:pa_x11_client    file:
-kill_requested cli.c   /^    pa_bool_t fail, kill_requested;$/;"       m       struct:pa_cli   file:
-last_line      cli.c   /^    char *last_line;$/;"      m       struct:pa_cli   file:
-last_localq    asyncq.c        /^    struct localq *last_localq;$/;"   m       struct:pa_asyncq        typeref:struct:pa_asyncq::localq        file:
-last_used_time core-scache.h   /^    time_t last_used_time;$/;"        m       struct:pa_scache_entry
-last_x time-smoother.c /^    pa_usec_t last_y, last_x;$/;"     m       struct:pa_smoother      file:
-last_y time-smoother.c /^    pa_usec_t last_y, last_x;$/;"     m       struct:pa_smoother      file:
-lazy   core-scache.h   /^    pa_bool_t lazy;$/;"       m       struct:pa_scache_entry
-left_vol_scale esound.h        /^    int left_vol_scale;         \/* volume scaling *\/$/;"    m       struct:esd_player_info
-left_vol_scale esound.h        /^    int left_vol_scale;         \/* volume scaling *\/$/;"    m       struct:esd_sample_info
-leftover       mcalign.c       /^    pa_memchunk leftover, current;$/;"        m       struct:pa_mcalign       file:
-length esound.h        /^    int length;                 \/* total buffer length *\/$/;"       m       struct:esd_sample_info
-length flist.c /^    pa_atomic_t length;$/;"   m       struct:pa_flist file:
-length memblock.c      /^    size_t length;$/;"        m       struct:pa_memblock      file:
-length memchunk.h      /^    size_t index, length;$/;" m       struct:pa_memchunk
-length packet.h        /^    size_t length;$/;"        m       struct:pa_packet
-length protocol-native.c       /^    size_t length;$/;"        m       struct:upload_stream    file:
-length queue.c /^    unsigned length;$/;"      m       struct:pa_queue file:
-length strbuf.c        /^    size_t length;$/;"        m       struct:chunk    file:
-length strbuf.c        /^    size_t length;$/;"        m       struct:pa_strbuf        file:
-length tagstruct.c     /^    size_t length, allocated;$/;"     m       struct:pa_tagstruct     file:
-level_to_char  log.c   /^static const char level_to_char[] = {$/;"     v       file:
-level_to_syslog        log.c   /^static const int level_to_syslog[] = {$/;"    v       file:
-libsamplerate_free     resampler.c     /^static void libsamplerate_free(pa_resampler *r) {$/;" f       file:
-libsamplerate_init     resampler.c     /^static int libsamplerate_init(pa_resampler *r) {$/;"  f       file:
-libsamplerate_resample resampler.c     /^static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {$/;"        f       file:
-libsamplerate_reset    resampler.c     /^static void libsamplerate_reset(pa_resampler *r) {$/;"        f       file:
-libsamplerate_update_rates     resampler.c     /^static void libsamplerate_update_rates(pa_resampler *r) {$/;" f       file:
-line   cli.c   /^    pa_ioline *line;$/;"      m       struct:pa_cli   file:
-line   protocol-http.c /^    pa_ioline *line;$/;"      m       struct:connection       file:
-line_callback  cli.c   /^static void line_callback(pa_ioline *line, const char *s, void *userdata) {$/;"       f       file:
-line_callback  protocol-http.c /^static void line_callback(pa_ioline *line, const char *s, void *userdata) {$/;"       f       file:
-line_drain_callback    protocol-http.c /^static void line_drain_callback(pa_ioline *l, void *userdata) {$/;"   f       file:
-linear ffmpeg/resample2.c      /^    int linear;$/;"   m       struct:AVResampleContext        file:
-linear sample-util.h   /^    } linear[PA_CHANNELS_MAX];$/;"    m       struct:pa_mix_info      typeref:union:pa_mix_info::__anon20
-linear_get_float       envelope.c      /^static float linear_get_float(pa_envelope *e, int v) {$/;"    f       file:
-linear_get_int envelope.c      /^static int32_t linear_get_int(pa_envelope *e, int v) {$/;"    f       file:
-linear_interpolate_float       envelope.c      /^static float linear_interpolate_float(pa_usec_t x1, float _y1, pa_usec_t x2, float y2, pa_usec_t x3) {$/;"    f       file:
-linear_interpolate_int envelope.c      /^static int32_t linear_interpolate_int(pa_usec_t x1, int32_t _y1, pa_usec_t x2, int32_t y2, pa_usec_t x3) {$/;"        f       file:
-linebreak      cli-command.c   /^static const char linebreak[] = "\\n\\r";$/;" v       file:
-list_item      memblockq.c     /^struct list_item {$/;"        s       file:
-load   authkey.c       /^static int load(const char *fn, void *data, size_t length) {$/;"      f       file:
-load_once      modinfo.h       /^    pa_bool_t load_once;$/;"  m       struct:pa_modinfo
-load_once      module.h        /^    pa_bool_t load_once:1;$/;"        m       struct:pa_module
-local  socket-client.c /^    pa_bool_t local;$/;"      m       struct:pa_socket_client file:
-localq asyncq.c        /^struct localq {$/;"   s       file:
-lock_fd        lock-autospawn.c        /^static int lock_fd = -1;$/;"  v       file:
-lock_fd_mutex  lock-autospawn.c        /^static pa_mutex *lock_fd_mutex = NULL;$/;"    v       file:
-lrintf ffmpeg/avcodec.h        79;"    d
-lvalue conf-parser.h   /^    const char *lvalue; \/* name of the variable *\/$/;"      m       struct:pa_config_item
-m      vector.h        /^    __m128 m;$/;"     m       union:pa_float_vector
-m      vector.h        /^    __m128i m;$/;"    m       union:pa_int16_vector
-m      vector.h        /^    __m128i m;$/;"    m       union:pa_int32_vector
-m      vector.h        /^    __m128i m;$/;"    m       union:pa_uint8_vector
-mainloop       avahi-wrap.c    /^    pa_mainloop_api *mainloop;$/;"    m       struct:__anon19 file:
-mainloop       core.h  /^    pa_mainloop_api *mainloop;$/;"    m       struct:pa_core
-mainloop       dbus-util.c     /^    pa_mainloop_api *mainloop;$/;"    m       struct:pa_dbus_wrap_connection  file:
-mainloop       iochannel.c     /^    pa_mainloop_api* mainloop;$/;"    m       struct:pa_iochannel     file:
-mainloop       ioline.c        /^    pa_mainloop_api *mainloop;$/;"    m       struct:pa_ioline        file:
-mainloop       pdispatch.c     /^    pa_mainloop_api *mainloop;$/;"    m       struct:pa_pdispatch     file:
-mainloop       pstream.c       /^    pa_mainloop_api *mainloop;$/;"    m       struct:pa_pstream       file:
-mainloop       socket-client.c /^    pa_mainloop_api *mainloop;$/;"    m       struct:pa_socket_client file:
-mainloop       socket-server.c /^    pa_mainloop_api *mainloop;$/;"    m       struct:pa_socket_server file:
-mainloop       thread-mq.h     /^    pa_mainloop_api *mainloop;$/;"    m       struct:pa_thread_mq
-make_random_dir        core-util.c     /^static char* make_random_dir(mode_t m) {$/;"  f       file:
-make_random_dir_and_link       core-util.c     /^static int make_random_dir_and_link(mode_t m, const char *k) {$/;"    f       file:
-map    database-simple.c       /^    pa_hashmap *map;$/;"      m       struct:simple_data      file:
-map_required   resampler.c     /^    pa_bool_t map_required;$/;"       m       struct:pa_resampler     file:
-map_table_f    remap.h /^    float map_table_f[PA_CHANNELS_MAX][PA_CHANNELS_MAX];$/;"  m       struct:pa_remap
-map_table_i    remap.h /^    int32_t map_table_i[PA_CHANNELS_MAX][PA_CHANNELS_MAX];$/;"        m       struct:pa_remap
-marker shm.c   /^    pa_atomic_t marker; \/* 0xbeefcafe *\/$/;"        m       struct:shm_marker       file:
-mask   core-subscribe.c        /^    pa_subscription_mask_t mask;$/;"  m       struct:pa_subscription  file:
-max_f  resampler.c     /^        float max_f[PA_CHANNELS_MAX];$/;"     m       struct:pa_resampler::__anon38   file:
-max_i  resampler.c     /^        int16_t max_i[PA_CHANNELS_MAX];$/;"   m       struct:pa_resampler::__anon38   file:
-max_latency    sink.h  /^        pa_usec_t max_latency; \/* An upper limit for the latencies *\/$/;"   m       struct:pa_sink::__anon36
-max_latency    source.h        /^        pa_usec_t max_latency; \/* An upper limit for the latencies *\/$/;"   m       struct:pa_source::__anon2
-max_request    sink.h  /^        size_t max_request;$/;"       m       struct:pa_sink::__anon36
-max_rewind     sink.h  /^        size_t max_rewind;$/;"        m       struct:pa_sink::__anon36
-max_rewind     source.h        /^        size_t max_rewind;$/;"        m       struct:pa_source::__anon2
-max_sink_channels      card.h  /^    unsigned max_sink_channels;$/;"   m       struct:pa_card_profile
-max_source_channels    card.h  /^    unsigned max_source_channels;$/;" m       struct:pa_card_profile
-maximum_level  log.c   /^static pa_log_level_t maximum_level = PA_LOG_ERROR, maximum_level_override = PA_LOG_ERROR;$/;"        v       file:
-maximum_level_override log.c   /^static pa_log_level_t maximum_level = PA_LOG_ERROR, maximum_level_override = PA_LOG_ERROR;$/;"        v       file:
-maxlength      memblockq.c     /^    size_t maxlength, tlength, base, prebuf, minreq, maxrewind;$/;"   m       struct:pa_memblockq     file:
-maxrewind      memblockq.c     /^    size_t maxlength, tlength, base, prebuf, minreq, maxrewind;$/;"   m       struct:pa_memblockq     file:
-may_move_to    sink-input.h    /^    pa_bool_t (*may_move_to) (pa_sink_input *i, pa_sink *s); \/* may be NULL *\/$/;"  m       struct:pa_sink_input
-may_move_to    source-output.h /^    pa_bool_t (*may_move_to) (pa_source_output *o, pa_source *s); \/* may be NULL *\/$/;"     m       struct:pa_source_output
-mcalign        memblockq.c     /^    pa_mcalign *mcalign;$/;"  m       struct:pa_memblockq     file:
-memblock       memchunk.h      /^    pa_memblock *memblock;$/;"        m       struct:pa_memchunk
-memblock       pstream.c       /^        pa_memblock *memblock;$/;"    m       struct:pa_pstream::__anon35     file:
-memblock_free  memblock.c      /^static void memblock_free(pa_memblock *b) {$/;"       f       file:
-memblock_index protocol-esound.c       /^        size_t memblock_index;$/;"    m       struct:connection::__anon11     file:
-memblock_index protocol-simple.c       /^        size_t memblock_index;$/;"    m       struct:connection::__anon8      file:
-memblock_make_local    memblock.c      /^static void memblock_make_local(pa_memblock *b) {$/;" f       file:
-memblock_new_appended  memblock.c      /^static pa_memblock *memblock_new_appended(pa_mempool *p, size_t length) {$/;" f       file:
-memblock_replace_import        memblock.c      /^static void memblock_replace_import(pa_memblock *b) {$/;"     f       file:
-memblock_shared_copy   memblock.c      /^static pa_memblock *memblock_shared_copy(pa_mempool *p, pa_memblock *b) {$/;" f       file:
-memblock_wait  memblock.c      /^static void memblock_wait(pa_memblock *b) {$/;"       f       file:
-memblockq      play-memblockq.c        /^    pa_memblockq *memblockq;$/;"      m       struct:memblockq_stream file:
-memblockq      protocol-native.c       /^    pa_memblockq *memblockq;$/;"      m       struct:playback_stream  file:
-memblockq      protocol-native.c       /^    pa_memblockq *memblockq;$/;"      m       struct:record_stream    file:
-memblockq      sound-file-stream.c     /^    pa_memblockq *memblockq;$/;"      m       struct:file_stream      file:
-memblockq_stream       play-memblockq.c        /^typedef struct memblockq_stream {$/;" s       file:
-memblockq_stream       play-memblockq.c        /^} memblockq_stream;$/;"       t       typeref:struct:memblockq_stream file:
-memblockq_stream_free  play-memblockq.c        /^static void memblockq_stream_free(pa_object *o) {$/;" f       file:
-memblockq_stream_process_msg   play-memblockq.c        /^static int memblockq_stream_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) {$/;"   f       file:
-memblockq_stream_unlink        play-memblockq.c        /^static void memblockq_stream_unlink(memblockq_stream *u) {$/;"        f       file:
-memchunk       asyncmsgq.c     /^    pa_memchunk memchunk;$/;" m       struct:asyncmsgq_item   file:
-memchunk       core-scache.h   /^    pa_memchunk memchunk;$/;" m       struct:pa_scache_entry
-memchunk       protocol-esound.c       /^        pa_memchunk memchunk;$/;"     m       struct:connection::__anon12     file:
-memchunk       protocol-native.c       /^    pa_memchunk memchunk;$/;" m       struct:upload_stream    file:
-memchunk       pstream.c       /^        pa_memchunk memchunk;$/;"     m       struct:pa_pstream::__anon34     file:
-memexport_revoke_blocks        memblock.c      /^static void memexport_revoke_blocks(pa_memexport *e, pa_memimport *i) {$/;"   f       file:
-memexport_revoke_cb    pstream.c       /^static void memexport_revoke_cb(pa_memexport *e, uint32_t block_id, void *userdata) {$/;"     f       file:
-memexport_slot memblock.c      /^struct memexport_slot {$/;"   s       file:
-memimport_release_cb   pstream.c       /^static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userdata) {$/;"    f       file:
-memory memblock.c      /^    pa_shm memory;$/;"        m       struct:pa_memimport_segment     file:
-memory memblock.c      /^    pa_shm memory;$/;"        m       struct:pa_mempool       file:
-mempool        core.h  /^    pa_mempool *mempool;$/;"  m       struct:pa_core
-mempool        pstream.c       /^    pa_mempool *mempool;$/;"  m       struct:pa_pstream       file:
-mempool        resampler.c     /^    pa_mempool *mempool;$/;"  m       struct:pa_resampler     file:
-mempool_allocate_slot  memblock.c      /^static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) {$/;"        f       file:
-mempool_slot_by_ptr    memblock.c      /^static struct mempool_slot* mempool_slot_by_ptr(pa_mempool *p, void *ptr) {$/;"       f       file:
-mempool_slot_data      memblock.c      /^static inline void* mempool_slot_data(struct mempool_slot *slot) {$/;"        f       file:
-mempool_slot_idx       memblock.c      /^static unsigned mempool_slot_idx(pa_mempool *p, void *ptr) {$/;"      f       file:
-memtrap_link   memtrap.c       /^static void memtrap_link(pa_memtrap *m, unsigned j) {$/;"     f       file:
-memtrap_unlink memtrap.c       /^static void memtrap_unlink(pa_memtrap *m, unsigned j) {$/;"   f       file:
-memtraps       memtrap.c       /^static pa_memtrap *memtraps[2] = { NULL, NULL };$/;"  v       file:
-message        dbus-util.h     /^    DBusMessage *message;$/;" m       struct:pa_dbus_pending
-method resampler.c     /^    pa_resample_method_t method;$/;"  m       struct:pa_resampler     file:
-min_history    time-smoother.c /^    unsigned min_history;$/;" m       struct:pa_smoother      file:
-min_latency    sink.h  /^        pa_usec_t min_latency; \/* we won't go below this latency *\/$/;"     m       struct:pa_sink::__anon36
-min_latency    source.h        /^        pa_usec_t min_latency; \/* we won't go below this latency *\/$/;"     m       struct:pa_source::__anon2
-minreq memblockq.c     /^    size_t maxlength, tlength, base, prebuf, minreq, maxrewind;$/;"   m       struct:pa_memblockq     file:
-missing        memblockq.c     /^    int64_t missing;$/;"      m       struct:pa_memblockq     file:
-missing        protocol-esound.c       /^        pa_atomic_t missing;$/;"      m       struct:connection::__anon11     file:
-missing        protocol-native.c       /^    pa_atomic_t missing;$/;"  m       struct:playback_stream  file:
-missing        protocol-simple.c       /^        pa_atomic_t missing;$/;"      m       struct:connection::__anon8      file:
-module card.h  /^    pa_module *module;$/;"    m       struct:pa_card
-module card.h  /^    pa_module *module;$/;"    m       struct:pa_card_new_data
-module client.h        /^    pa_module *module;$/;"    m       struct:pa_client
-module client.h        /^    pa_module *module;$/;"    m       struct:pa_client_new_data
-module protocol-esound.h       /^    pa_module *module;$/;"    m       struct:pa_esound_options
-module protocol-http.c /^    pa_module *module;$/;"    m       struct:connection       file:
-module protocol-native.h       /^    pa_module *module;$/;"    m       struct:pa_native_options
-module protocol-simple.h       /^    pa_module *module;$/;"    m       struct:pa_simple_options
-module sink-input.h    /^    pa_module *module;                  \/* may be NULL *\/$/;"       m       struct:pa_sink_input
-module sink-input.h    /^    pa_module *module;$/;"    m       struct:pa_sink_input_new_data
-module sink.h  /^    pa_module *module;                      \/* may be NULL *\/$/;"   m       struct:pa_sink
-module sink.h  /^    pa_module *module;$/;"    m       struct:pa_sink_new_data
-module source-output.h /^    pa_module *module;                    \/* may be NULL *\/$/;"     m       struct:pa_source_output
-module source-output.h /^    pa_module *module;$/;"    m       struct:pa_source_output_new_data
-module source.h        /^    pa_module *module;                        \/* may be NULL *\/$/;" m       struct:pa_source
-module source.h        /^    pa_module *module;$/;"    m       struct:pa_source_new_data
-module_defer_unload_event      core.h  /^    pa_defer_event *module_defer_unload_event;$/;"    m       struct:pa_core
-module_fill_tagstruct  protocol-native.c       /^static void module_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_module *module) {$/;"  f       file:
-modules        core.h  /^    pa_idxset *clients, *cards, *sinks, *sources, *sink_inputs, *source_outputs, *modules, *scache;$/;"       m       struct:pa_core
-monitor_of     source.h        /^    pa_sink *monitor_of;                     \/* may be NULL *\/$/;"  m       struct:pa_source
-monitor_source sink.h  /^    pa_source *monitor_source;$/;"    m       struct:pa_sink
-monitor_thread_func    thread-win32.c  /^static DWORD WINAPI monitor_thread_func(LPVOID param) {$/;"   f       file:
-monitor_tls    thread-win32.c  /^static pa_tls *monitor_tls;$/;"       v       file:
-monotonic      time-smoother.c /^    pa_bool_t monotonic:1;$/;"        m       struct:pa_smoother      file:
-moving sink-input.h    /^    void (*moving) (pa_sink_input *i, pa_sink *dest);   \/* may be NULL *\/$/;"       m       struct:pa_sink_input
-moving source-output.h /^    void (*moving) (pa_source_output *o, pa_source *dest);   \/* may be NULL *\/$/;"  m       struct:pa_source_output
-mute_changed   sink-input.h    /^    void (*mute_changed)(pa_sink_input *i); \/* may be NULL *\/$/;"   m       struct:pa_sink_input
-muted  sink-input.h    /^        pa_bool_t muted:1;$/;"        m       struct:pa_sink_input::__anon27
-muted  sink-input.h    /^    pa_bool_t muted:1;$/;"    m       struct:pa_sink_input
-muted  sink-input.h    /^    pa_bool_t muted:1;$/;"    m       struct:pa_sink_input_new_data
-muted  sink.h  /^    pa_bool_t muted :1;$/;"   m       struct:pa_sink_new_data
-muted  sink.h  /^    pa_bool_t muted:1;$/;"    m       struct:pa_sink
-muted  source.h        /^    pa_bool_t muted:1;$/;"    m       struct:pa_source
-muted  source.h        /^    pa_bool_t muted:1;$/;"    m       struct:pa_source_new_data
-muted_is_set   sink-input.h    /^    pa_bool_t muted_is_set:1;$/;"     m       struct:pa_sink_input_new_data
-muted_is_set   sink.h  /^    pa_bool_t muted_is_set:1;$/;"     m       struct:pa_sink_new_data
-muted_is_set   source.h        /^    pa_bool_t muted_is_set:1;$/;"     m       struct:pa_source_new_data
-mutex  asyncmsgq.c     /^    pa_mutex *mutex; \/* only for the writer side *\/$/;"     m       struct:pa_asyncmsgq     file:
-mutex  lock-autospawn.c        /^static pa_mutex *mutex;$/;"   v       file:
-mutex  memblock.c      /^    pa_mutex *mutex;$/;"      m       struct:pa_memexport     file:
-mutex  memblock.c      /^    pa_mutex *mutex;$/;"      m       struct:pa_memimport     file:
-mutex  memblock.c      /^    pa_mutex *mutex;$/;"      m       struct:pa_mempool       file:
-mutex  memtrap.c       /^static pa_static_mutex mutex = PA_STATIC_MUTEX_INIT; \/* only required to serialize access to the write side *\/$/;"  v       file:
-mutex  mutex-posix.c   /^    pthread_mutex_t mutex;$/;"        m       struct:pa_mutex file:
-mutex  mutex-win32.c   /^    CRITICAL_SECTION mutex;$/;"       m       struct:pa_mutex file:
-mutex  once.h  /^    pa_atomic_ptr_t mutex;$/;"        m       struct:pa_once
-mutex  ratelimit.c     /^static pa_static_mutex mutex = PA_STATIC_MUTEX_INIT;$/;"      v       file:
-n_accumulated  memblock.h      /^    pa_atomic_t n_accumulated;$/;"    m       struct:pa_mempool_stat
-n_accumulated_by_type  memblock.h      /^    pa_atomic_t n_accumulated_by_type[PA_MEMBLOCK_TYPE_MAX];$/;"      m       struct:pa_mempool_stat
-n_acquired     memblock.c      /^    pa_atomic_t n_acquired;$/;"       m       struct:pa_memblock      file:
-n_allocated    dynarray.c      /^    unsigned n_allocated, n_entries;$/;"      m       struct:pa_dynarray      file:
-n_allocated    envelope.c      /^        unsigned n_points, n_allocated, n_current;$/;"        m       struct:pa_envelope::__anon23    file:
-n_allocated    memblock.h      /^    pa_atomic_t n_allocated;$/;"      m       struct:pa_mempool_stat
-n_allocated    prioq.c /^    unsigned n_allocated;$/;" m       struct:pa_prioq file:
-n_allocated_by_type    memblock.h      /^    pa_atomic_t n_allocated_by_type[PA_MEMBLOCK_TYPE_MAX];$/;"        m       struct:pa_mempool_stat
-n_blocks       memblock.c      /^    unsigned n_blocks;$/;"    m       struct:pa_memimport_segment     file:
-n_blocks       memblock.c      /^    unsigned n_blocks;$/;"    m       struct:pa_mempool       file:
-n_blocks       memblockq.c     /^    unsigned n_blocks;$/;"    m       struct:pa_memblockq     file:
-n_commands     pdispatch.c     /^    unsigned n_commands;$/;"  m       struct:pa_pdispatch     file:
-n_corked       sink.h  /^    unsigned n_corked;$/;"    m       struct:pa_sink
-n_corked       source.h        /^    unsigned n_corked;$/;"    m       struct:pa_source
-n_current      envelope.c      /^        unsigned n_points, n_allocated, n_current;$/;"        m       struct:pa_envelope::__anon23    file:
-n_dead hook-list.h     /^    int n_firing, n_dead;$/;" m       struct:pa_hook
-n_entries      dynarray.c      /^    unsigned n_allocated, n_entries;$/;"      m       struct:pa_dynarray      file:
-n_entries      hashmap.c       /^    unsigned n_entries;$/;"   m       struct:pa_hashmap       file:
-n_entries      idxset.c        /^    unsigned n_entries;$/;"   m       struct:pa_idxset        file:
-n_exported     memblock.h      /^    pa_atomic_t n_exported;$/;"       m       struct:pa_mempool_stat
-n_firing       hook-list.h     /^    int n_firing, n_dead;$/;" m       struct:pa_hook
-n_history      time-smoother.c /^    unsigned history_idx, n_history;$/;"      m       struct:pa_smoother      file:
-n_imported     memblock.h      /^    pa_atomic_t n_imported;$/;"       m       struct:pa_mempool_stat
-n_init memblock.c      /^    pa_atomic_t n_init;$/;"   m       struct:pa_mempool       file:
-n_init memblock.c      /^    unsigned n_init;$/;"      m       struct:pa_memexport     file:
-n_items        prioq.c /^    unsigned n_items;$/;"     m       struct:pa_prioq file:
-n_missed       ratelimit.h     /^    unsigned n_printed, n_missed;$/;" m       struct:pa_ratelimit
-n_player       protocol-esound.c       /^    unsigned n_player;$/;"    m       struct:pa_esound_protocol       file:
-n_points       envelope.c      /^        unsigned n_points, n_allocated, n_current;$/;"        m       struct:pa_envelope::__anon23    file:
-n_points       envelope.h      /^    unsigned n_points;$/;"    m       struct:pa_envelope_def
-n_pollfd       rtpoll.c        /^    unsigned n_pollfd;$/;"    m       struct:pa_rtpoll_item   file:
-n_pollfd_alloc rtpoll.c        /^    unsigned n_pollfd_alloc, n_pollfd_used;$/;"       m       struct:pa_rtpoll        file:
-n_pollfd_used  rtpoll.c        /^    unsigned n_pollfd_alloc, n_pollfd_used;$/;"       m       struct:pa_rtpoll        file:
-n_pool_full    memblock.h      /^    pa_atomic_t n_pool_full;$/;"      m       struct:pa_mempool_stat
-n_printed      ratelimit.h     /^    unsigned n_printed, n_missed;$/;" m       struct:pa_ratelimit
-n_ref  lock-autospawn.c        /^static unsigned n_ref = 0;$/;"        v       file:
-n_sinks        card.h  /^    unsigned n_sinks;$/;"     m       struct:pa_card_profile
-n_sources      card.h  /^    unsigned n_sources;$/;"   m       struct:pa_card_profile
-n_too_large_for_pool   memblock.h      /^    pa_atomic_t n_too_large_for_pool;$/;"     m       struct:pa_mempool_stat
-n_volume_steps sink.h  /^    unsigned n_volume_steps; \/* shall be constant *\/$/;"    m       struct:pa_sink
-n_volume_steps source.h        /^    unsigned n_volume_steps; \/* shall be constant *\/$/;"    m       struct:pa_source
-name   auth-cookie.c   /^    char *name;$/;"   m       struct:pa_auth_cookie   file:
-name   card.h  /^    char *name;$/;"   m       struct:pa_card
-name   card.h  /^    char *name;$/;"   m       struct:pa_card_new_data
-name   card.h  /^    char *name;$/;"   m       struct:pa_card_profile
-name   cli-command.c   /^    const char *name;$/;"     m       struct:command  file:
-name   core-scache.h   /^    char *name;$/;"   m       struct:pa_scache_entry
-name   esound.h        /^    char name[ ESD_NAME_MAX ];  \/* name of stream for remote control *\/$/;" m       struct:esd_player_info
-name   esound.h        /^    char name[ ESD_NAME_MAX ];  \/* name of stream for remote control *\/$/;" m       struct:esd_sample_info
-name   module.h        /^    char *name, *argument;$/;"        m       struct:pa_module
-name   namereg.c       /^    char *name;$/;"   m       struct:namereg_entry    file:
-name   protocol-esound.c       /^        char *name;$/;"       m       struct:connection::__anon12     file:
-name   protocol-native.c       /^    char *name;$/;"   m       struct:upload_stream    file:
-name   shared.c        /^    char *name;  \/* Points to memory allocated by the shared property system *\/$/;" m       struct:pa_shared        file:
-name   sink.h  /^    char *name;$/;"   m       struct:pa_device_port
-name   sink.h  /^    char *name;$/;"   m       struct:pa_sink
-name   sink.h  /^    char *name;$/;"   m       struct:pa_sink_new_data
-name   source.h        /^    char *name;$/;"   m       struct:pa_source
-name   source.h        /^    char *name;$/;"   m       struct:pa_source_new_data
-namereg        core.h  /^    pa_hashmap *namereg, *shared;$/;" m       struct:pa_core
-namereg_entry  namereg.c       /^struct namereg_entry {$/;"    s       file:
-namereg_fail   card.h  /^    pa_bool_t namereg_fail:1;$/;"     m       struct:pa_card_new_data
-namereg_fail   sink.h  /^    pa_bool_t namereg_fail:1;$/;"     m       struct:pa_sink_new_data
-namereg_fail   source.h        /^    pa_bool_t namereg_fail:1;$/;"     m       struct:pa_source_new_data
-native_connection_free protocol-native.c       /^static void native_connection_free(pa_object *o) {$/;"        f       file:
-native_connection_process_msg  protocol-native.c       /^static int native_connection_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) {$/;"  f       file:
-native_connection_send_memblock        protocol-native.c       /^static void native_connection_send_memblock(pa_native_connection *c) {$/;"    f       file:
-native_connection_unlink       protocol-native.c       /^static void native_connection_unlink(pa_native_connection *c) {$/;"   f       file:
-native_protocol_new    protocol-native.c       /^static pa_native_protocol* native_protocol_new(pa_core *c) {$/;"      f       file:
-new_entry      database-simple.c       /^static entry* new_entry(const pa_datum *key, const pa_datum *data) {$/;"      f       file:
-next   esound.h        /^    struct esd_player_info *next; \/* point to next entry in list *\/$/;"     m       struct:esd_player_info  typeref:struct:esd_player_info::esd_player_info
-next   esound.h        /^    struct esd_sample_info *next; \/* point to next entry in list *\/$/;"     m       struct:esd_sample_info  typeref:struct:esd_sample_info::esd_sample_info
-next   memblockq.c     /^    struct list_item *next, *prev;$/;"        m       struct:list_item        typeref:struct:list_item::list_item     file:
-next   memtrap.c       /^    pa_memtrap *next[2], *prev[2];$/;"        m       struct:pa_memtrap       file:
-next   queue.c /^    struct queue_entry *next;$/;"     m       struct:queue_entry      typeref:struct:queue_entry::queue_entry file:
-next   strbuf.c        /^    struct chunk *next;$/;"   m       struct:chunk    typeref:struct:chunk::chunk     file:
-next   strlist.c       /^    pa_strlist *next;$/;"     m       struct:pa_strlist       file:
-next_assignment        conf-parser.c   /^static int next_assignment($/;"       f       file:
-next_elapse    rtpoll.c        /^    struct timeval next_elapse;$/;"   m       struct:pa_rtpoll        typeref:struct:pa_rtpoll::timeval       file:
-nfds_t poll.h  /^typedef unsigned long int nfds_t;$/;" t
-no_close       iochannel.c     /^    pa_bool_t no_close;$/;"   m       struct:pa_iochannel     file:
-normalize_path authkey.c       /^static char *normalize_path(const char *fn) {$/;"     f       file:
-o_cm   resampler.c     /^    pa_channel_map i_cm, o_cm;$/;"    m       struct:pa_resampler     file:
-o_counter      resampler.c     /^        unsigned o_counter;$/;"       m       struct:pa_resampler::__anon37   file:
-o_counter      resampler.c     /^        unsigned o_counter;$/;"       m       struct:pa_resampler::__anon38   file:
-o_fz   resampler.c     /^    size_t i_fz, o_fz, w_sz;$/;"      m       struct:pa_resampler     file:
-o_ss   remap.h /^    pa_sample_spec *i_ss, *o_ss;$/;"  m       struct:pa_remap
-o_ss   resampler.c     /^    pa_sample_spec i_ss, o_ss;$/;"    m       struct:pa_resampler     file:
-object asyncmsgq.c     /^    pa_msgobject *object;$/;" m       struct:asyncmsgq_item   file:
-ofd    iochannel.c     /^    int ifd, ofd;$/;" m       struct:pa_iochannel     file:
-ofd_type       iochannel.c     /^    int ifd_type, ofd_type;$/;"       m       struct:pa_iochannel     file:
-offset asyncmsgq.c     /^    int64_t offset;$/;"       m       struct:asyncmsgq_item   file:
-offset pstream.c       /^    int64_t offset;$/;"       m       struct:item_info        file:
-on_center      resampler.c     /^static pa_bool_t on_center(pa_channel_position_t p) {$/;"     f       file:
-on_connection  socket-server.c /^    pa_socket_server_on_connection_cb_t on_connection;$/;"    m       struct:pa_socket_server file:
-on_front       resampler.c     /^static pa_bool_t on_front(pa_channel_position_t p) {$/;"      f       file:
-on_left        resampler.c     /^static pa_bool_t on_left(pa_channel_position_t p) {$/;"       f       file:
-on_lfe resampler.c     /^static pa_bool_t on_lfe(pa_channel_position_t p) {$/;"        f       file:
-on_rear        resampler.c     /^static pa_bool_t on_rear(pa_channel_position_t p) {$/;"       f       file:
-on_right       resampler.c     /^static pa_bool_t on_right(pa_channel_position_t p) {$/;"      f       file:
-on_side        resampler.c     /^static pa_bool_t on_side(pa_channel_position_t p) {$/;"       f       file:
-on_the_fly     protocol-native.c       /^    pa_atomic_t on_the_fly;$/;"       m       struct:record_stream    file:
-on_the_fly_snapshot    protocol-native.c       /^    size_t on_the_fly_snapshot;$/;"   m       struct:record_stream    file:
-open_pid_file  pid.c   /^static int open_pid_file(const char *fn, int mode) {$/;"      f       file:
-options        protocol-esound.c       /^    pa_esound_options *options;$/;"   m       struct:connection       file:
-options        protocol-native.c       /^    pa_native_options *options;$/;"   m       struct:pa_native_connection     file:
-options        protocol-simple.c       /^    pa_simple_options *options;$/;"   m       struct:connection       file:
-original_name  protocol-esound.c       /^    char *original_name;$/;"  m       struct:connection       file:
-output_event   iochannel.c     /^    pa_io_event* input_event, *output_event;$/;"      m       struct:pa_iochannel     file:
-output_memblockq       protocol-esound.c       /^    pa_memblockq *input_memblockq, *output_memblockq;$/;"     m       struct:connection       file:
-output_memblockq       protocol-http.c /^    pa_memblockq *output_memblockq;$/;"       m       struct:connection       file:
-output_memblockq       protocol-simple.c       /^    pa_memblockq *input_memblockq, *output_memblockq;$/;"     m       struct:connection       file:
-output_stream  protocol-native.c       /^typedef struct output_stream {$/;"    s       file:
-output_stream  protocol-native.c       /^} output_stream;$/;"  t       typeref:struct:output_stream    file:
-output_streams protocol-native.c       /^    pa_idxset *record_streams, *output_streams;$/;"   m       struct:pa_native_connection     file:
-outputs        source.h        /^        pa_hashmap *outputs;$/;"      m       struct:pa_source::__anon2
-outputs        source.h        /^    pa_idxset *outputs;$/;"   m       struct:pa_source
-outq   thread-mq.h     /^    pa_asyncmsgq *inq, *outq;$/;"     m       struct:pa_thread_mq
-pa_assert      macro.h 235;"   d
-pa_assert      macro.h 238;"   d
-pa_assert      macro.h 241;"   d
-pa_assert_cc   macro.h 256;"   d
-pa_assert_ctl_context  thread-mq.h     49;"    d
-pa_assert_fp   macro.h 236;"   d
-pa_assert_fp   macro.h 239;"   d
-pa_assert_fp   macro.h 242;"   d
-pa_assert_io_context   thread-mq.h     53;"    d
-pa_assert_not_reached  macro.h 246;"   d
-pa_assert_not_reached  macro.h 248;"   d
-pa_assert_se   macro.h 218;"   d
-pa_asyncmsgq   asyncmsgq.c     /^struct pa_asyncmsgq {$/;"     s       file:
-pa_asyncmsgq   asyncmsgq.h     /^typedef struct pa_asyncmsgq pa_asyncmsgq;$/;" t       typeref:struct:pa_asyncmsgq
-pa_asyncmsgq_dispatch  asyncmsgq.c     /^int pa_asyncmsgq_dispatch(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *memchunk) {$/;"        f
-pa_asyncmsgq_dispatching       asyncmsgq.c     /^pa_bool_t pa_asyncmsgq_dispatching(pa_asyncmsgq *a) {$/;"     f
-pa_asyncmsgq_done      asyncmsgq.c     /^void pa_asyncmsgq_done(pa_asyncmsgq *a, int ret) {$/;"        f
-pa_asyncmsgq_flush     asyncmsgq.c     /^void pa_asyncmsgq_flush(pa_asyncmsgq *a, pa_bool_t run) {$/;" f
-pa_asyncmsgq_get       asyncmsgq.c     /^int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **userdata, int64_t *offset, pa_memchunk *chunk, pa_bool_t wait_op) {$/;"        f
-pa_asyncmsgq_new       asyncmsgq.c     /^pa_asyncmsgq *pa_asyncmsgq_new(unsigned size) {$/;"   f
-pa_asyncmsgq_post      asyncmsgq.c     /^void pa_asyncmsgq_post(pa_asyncmsgq *a, pa_msgobject *object, int code, const void *userdata, int64_t offset, const pa_memchunk *chunk, pa_free_cb_t free_cb) {$/;"   f
-pa_asyncmsgq_process_one       asyncmsgq.c     /^int pa_asyncmsgq_process_one(pa_asyncmsgq *a) {$/;"   f
-pa_asyncmsgq_read_after_poll   asyncmsgq.c     /^void pa_asyncmsgq_read_after_poll(pa_asyncmsgq *a) {$/;"      f
-pa_asyncmsgq_read_before_poll  asyncmsgq.c     /^int pa_asyncmsgq_read_before_poll(pa_asyncmsgq *a) {$/;"      f
-pa_asyncmsgq_read_fd   asyncmsgq.c     /^int pa_asyncmsgq_read_fd(pa_asyncmsgq *a) {$/;"       f
-pa_asyncmsgq_ref       asyncmsgq.c     /^pa_asyncmsgq* pa_asyncmsgq_ref(pa_asyncmsgq *q) {$/;" f
-pa_asyncmsgq_send      asyncmsgq.c     /^int pa_asyncmsgq_send(pa_asyncmsgq *a, pa_msgobject *object, int code, const void *userdata, int64_t offset, const pa_memchunk *chunk) {$/;"  f
-pa_asyncmsgq_unref     asyncmsgq.c     /^void pa_asyncmsgq_unref(pa_asyncmsgq* q) {$/;"        f
-pa_asyncmsgq_wait_for  asyncmsgq.c     /^int pa_asyncmsgq_wait_for(pa_asyncmsgq *a, int code) {$/;"    f
-pa_asyncmsgq_write_after_poll  asyncmsgq.c     /^void pa_asyncmsgq_write_after_poll(pa_asyncmsgq *a) {$/;"     f
-pa_asyncmsgq_write_before_poll asyncmsgq.c     /^void pa_asyncmsgq_write_before_poll(pa_asyncmsgq *a) {$/;"    f
-pa_asyncmsgq_write_fd  asyncmsgq.c     /^int pa_asyncmsgq_write_fd(pa_asyncmsgq *a) {$/;"      f
-pa_asyncq      asyncq.c        /^struct pa_asyncq {$/;"        s       file:
-pa_asyncq      asyncq.h        /^typedef struct pa_asyncq pa_asyncq;$/;"       t       typeref:struct:pa_asyncq
-pa_asyncq_free asyncq.c        /^void pa_asyncq_free(pa_asyncq *l, pa_free_cb_t free_cb) {$/;" f
-pa_asyncq_new  asyncq.c        /^pa_asyncq *pa_asyncq_new(unsigned size) {$/;" f
-pa_asyncq_pop  asyncq.c        /^void* pa_asyncq_pop(pa_asyncq*l, pa_bool_t wait_op) {$/;"     f
-pa_asyncq_post asyncq.c        /^void pa_asyncq_post(pa_asyncq*l, void *p) {$/;"       f
-pa_asyncq_push asyncq.c        /^int pa_asyncq_push(pa_asyncq*l, void *p, pa_bool_t wait_op) {$/;"     f
-pa_asyncq_read_after_poll      asyncq.c        /^void pa_asyncq_read_after_poll(pa_asyncq *l) {$/;"    f
-pa_asyncq_read_before_poll     asyncq.c        /^int pa_asyncq_read_before_poll(pa_asyncq *l) {$/;"    f
-pa_asyncq_read_fd      asyncq.c        /^int pa_asyncq_read_fd(pa_asyncq *q) {$/;"     f
-pa_asyncq_write_after_poll     asyncq.c        /^void pa_asyncq_write_after_poll(pa_asyncq *l) {$/;"   f
-pa_asyncq_write_before_poll    asyncq.c        /^void pa_asyncq_write_before_poll(pa_asyncq *l) {$/;"  f
-pa_asyncq_write_fd     asyncq.c        /^int pa_asyncq_write_fd(pa_asyncq *q) {$/;"    f
-pa_atod        core-util.c     /^int pa_atod(const char *s, double *ret_d) {$/;"       f
-pa_atoi        core-util.c     /^int pa_atoi(const char *s, int32_t *ret_i) {$/;"      f
-pa_atomic      atomic.h        /^typedef struct pa_atomic {$/;"        s
-pa_atomic_add  atomic.h        /^static inline int pa_atomic_add(pa_atomic_t *a, int i) {$/;"  f
-pa_atomic_cmpxchg      atomic.h        /^static inline pa_bool_t pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) {$/;" f
-pa_atomic_dec  atomic.h        /^static inline int pa_atomic_dec(pa_atomic_t *a) {$/;" f
-pa_atomic_inc  atomic.h        /^static inline int pa_atomic_inc(pa_atomic_t *a) {$/;" f
-pa_atomic_load atomic.h        /^static inline int pa_atomic_load(const pa_atomic_t *a) {$/;"  f
-pa_atomic_ptr  atomic.h        /^typedef struct pa_atomic_ptr {$/;"    s
-pa_atomic_ptr_cmpxchg  atomic.h        /^static inline pa_bool_t pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* new_p) {$/;"     f
-pa_atomic_ptr_load     atomic.h        /^static inline void* pa_atomic_ptr_load(const pa_atomic_ptr_t *a) {$/;"        f
-pa_atomic_ptr_store    atomic.h        /^static inline void pa_atomic_ptr_store(pa_atomic_ptr_t *a, void *p) {$/;"     f
-pa_atomic_ptr_t        atomic.h        /^} pa_atomic_ptr_t;$/;"        t       typeref:struct:pa_atomic_ptr
-pa_atomic_store        atomic.h        /^static inline void pa_atomic_store(pa_atomic_t *a, int i) {$/;"       f
-pa_atomic_sub  atomic.h        /^static inline int pa_atomic_sub(pa_atomic_t *a, int i) {$/;"  f
-pa_atomic_t    atomic.h        /^} pa_atomic_t;$/;"    t       typeref:struct:pa_atomic
-pa_atou        core-util.c     /^int pa_atou(const char *s, uint32_t *ret_u) {$/;"     f
-pa_aupdate     aupdate.c       /^struct pa_aupdate {$/;"       s       file:
-pa_aupdate     aupdate.h       /^typedef struct pa_aupdate pa_aupdate;$/;"     t       typeref:struct:pa_aupdate
-pa_aupdate_free        aupdate.c       /^void pa_aupdate_free(pa_aupdate *a) {$/;"     f
-pa_aupdate_new aupdate.c       /^pa_aupdate *pa_aupdate_new(void) {$/;"        f
-pa_aupdate_read_begin  aupdate.c       /^unsigned pa_aupdate_read_begin(pa_aupdate *a) {$/;"   f
-pa_aupdate_read_end    aupdate.c       /^void pa_aupdate_read_end(pa_aupdate *a) {$/;" f
-pa_aupdate_write_begin aupdate.c       /^unsigned pa_aupdate_write_begin(pa_aupdate *a) {$/;"  f
-pa_aupdate_write_end   aupdate.c       /^void pa_aupdate_write_end(pa_aupdate *a) {$/;"        f
-pa_aupdate_write_swap  aupdate.c       /^unsigned pa_aupdate_write_swap(pa_aupdate *a) {$/;"   f
-pa_auth_cookie auth-cookie.c   /^struct pa_auth_cookie {$/;"   s       file:
-pa_auth_cookie auth-cookie.h   /^typedef struct pa_auth_cookie pa_auth_cookie;$/;"     t       typeref:struct:pa_auth_cookie
-pa_auth_cookie_get     auth-cookie.c   /^pa_auth_cookie* pa_auth_cookie_get(pa_core *core, const char *cn, size_t size) {$/;"  f
-pa_auth_cookie_read    auth-cookie.c   /^const uint8_t* pa_auth_cookie_read(pa_auth_cookie *c, size_t size) {$/;"      f
-pa_auth_cookie_ref     auth-cookie.c   /^pa_auth_cookie* pa_auth_cookie_ref(pa_auth_cookie *c) {$/;"   f
-pa_auth_cookie_unref   auth-cookie.c   /^void pa_auth_cookie_unref(pa_auth_cookie *c) {$/;"    f
-pa_authkey_load        authkey.c       /^int pa_authkey_load(const char *path, void *data, size_t length) {$/;"        f
-pa_authkey_load_auto   authkey.c       /^int pa_authkey_load_auto(const char *fn, void *data, size_t length) {$/;"     f
-pa_authkey_save        authkey.c       /^int pa_authkey_save(const char *fn, const void *data, size_t length) {$/;"    f
-pa_autospawn_lock_acquire      lock-autospawn.c        /^int pa_autospawn_lock_acquire(pa_bool_t block) {$/;"  f
-pa_autospawn_lock_done lock-autospawn.c        /^void pa_autospawn_lock_done(pa_bool_t after_fork) {$/;"       f
-pa_autospawn_lock_init lock-autospawn.c        /^int pa_autospawn_lock_init(void) {$/;"        f
-pa_autospawn_lock_release      lock-autospawn.c        /^void pa_autospawn_lock_release(void) {$/;"    f
-pa_avahi_poll  avahi-wrap.c    /^} pa_avahi_poll;$/;"  t       typeref:struct:__anon19 file:
-pa_avahi_poll_free     avahi-wrap.c    /^void pa_avahi_poll_free(AvahiPoll *api) {$/;" f
-pa_avahi_poll_new      avahi-wrap.c    /^AvahiPoll* pa_avahi_poll_new(pa_mainloop_api *m) {$/;"        f
-pa_bitset_equals       bitset.c        /^pa_bool_t pa_bitset_equals(const pa_bitset_t *b, unsigned n, ...) {$/;"       f
-pa_bitset_get  bitset.c        /^pa_bool_t pa_bitset_get(const pa_bitset_t *b, unsigned k) {$/;"       f
-pa_bitset_set  bitset.c        /^void pa_bitset_set(pa_bitset_t *b, unsigned k, pa_bool_t v) {$/;"     f
-pa_bitset_t    bitset.h        /^typedef uint32_t pa_bitset_t;$/;"     t
-pa_bool_t      macro.h /^typedef _Bool pa_bool_t;$/;"  t
-pa_bool_t      macro.h /^typedef int pa_bool_t;$/;"    t
-pa_bytes_to_usec_round_up      sample-util.c   /^pa_usec_t pa_bytes_to_usec_round_up(uint64_t length, const pa_sample_spec *spec) {$/;"        f
-pa_calc_volume_func_t  sample-util.c   /^typedef void (*pa_calc_volume_func_t) (void *volumes, const pa_cvolume *volume);$/;"  t       file:
-pa_card        card.h  /^struct pa_card {$/;"  s
-pa_card        card.h  /^typedef struct pa_card pa_card;$/;"   t       typeref:struct:pa_card
-pa_card_free   card.c  /^void pa_card_free(pa_card *c) {$/;"   f
-pa_card_list_to_string cli-text.c      /^char *pa_card_list_to_string(pa_core *c) {$/;"        f
-pa_card_new    card.c  /^pa_card *pa_card_new(pa_core *core, pa_card_new_data *data) {$/;"     f
-pa_card_new_data       card.h  /^typedef struct pa_card_new_data {$/;" s
-pa_card_new_data       card.h  /^} pa_card_new_data;$/;"       t       typeref:struct:pa_card_new_data
-pa_card_new_data_done  card.c  /^void pa_card_new_data_done(pa_card_new_data *data) {$/;"      f
-pa_card_new_data_init  card.c  /^pa_card_new_data* pa_card_new_data_init(pa_card_new_data *data) {$/;" f
-pa_card_new_data_set_name      card.c  /^void pa_card_new_data_set_name(pa_card_new_data *data, const char *name) {$/;"        f
-pa_card_new_data_set_profile   card.c  /^void pa_card_new_data_set_profile(pa_card_new_data *data, const char *profile) {$/;"  f
-pa_card_profile        card.h  /^typedef struct pa_card_profile {$/;"  s
-pa_card_profile        card.h  /^} pa_card_profile;$/;"        t       typeref:struct:pa_card_profile
-pa_card_profile_free   card.c  /^void pa_card_profile_free(pa_card_profile *c) {$/;"   f
-pa_card_profile_new    card.c  /^pa_card_profile *pa_card_profile_new(const char *name, const char *description, size_t extra) {$/;"   f
-pa_card_set_profile    card.c  /^int pa_card_set_profile(pa_card *c, const char *name, pa_bool_t save) {$/;"   f
-pa_card_suspend        card.c  /^int pa_card_suspend(pa_card *c, pa_bool_t suspend, pa_suspend_cause_t cause) {$/;"    f
-pa_check_in_group      core-util.c     /^int pa_check_in_group(gid_t g) {$/;"  f
-pa_check_signal_is_blocked     core-util.c     /^void pa_check_signal_is_blocked(int sig) {$/;"        f
-pa_cli cli.c   /^struct pa_cli {$/;"   s       file:
-pa_cli cli.h   /^typedef struct pa_cli pa_cli;$/;"     t       typeref:struct:pa_cli
-pa_cli_command_card_profile    cli-command.c   /^static int pa_cli_command_card_profile(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"    f       file:
-pa_cli_command_cards   cli-command.c   /^static int pa_cli_command_cards(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"   f       file:
-pa_cli_command_clients cli-command.c   /^static int pa_cli_command_clients(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;" f       file:
-pa_cli_command_describe        cli-command.c   /^static int pa_cli_command_describe(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"        f       file:
-pa_cli_command_dump    cli-command.c   /^static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"    f       file:
-pa_cli_command_execute cli-command.c   /^int pa_cli_command_execute(pa_core *c, const char *s, pa_strbuf *buf, pa_bool_t *fail) {$/;"  f
-pa_cli_command_execute_file    cli-command.c   /^int pa_cli_command_execute_file(pa_core *c, const char *fn, pa_strbuf *buf, pa_bool_t *fail) {$/;"    f
-pa_cli_command_execute_file_stream     cli-command.c   /^int pa_cli_command_execute_file_stream(pa_core *c, FILE *f, pa_strbuf *buf, pa_bool_t *fail) {$/;"    f
-pa_cli_command_execute_line    cli-command.c   /^int pa_cli_command_execute_line(pa_core *c, const char *s, pa_strbuf *buf, pa_bool_t *fail) {$/;"     f
-pa_cli_command_execute_line_stateful   cli-command.c   /^int pa_cli_command_execute_line_stateful(pa_core *c, const char *s, pa_strbuf *buf, pa_bool_t *fail, int *ifstate) {$/;"      f
-pa_cli_command_exit    cli-command.c   /^static int pa_cli_command_exit(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"    f       file:
-pa_cli_command_help    cli-command.c   /^static int pa_cli_command_help(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"    f       file:
-pa_cli_command_info    cli-command.c   /^static int pa_cli_command_info(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"    f       file:
-pa_cli_command_kill_client     cli-command.c   /^static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"     f       file:
-pa_cli_command_kill_sink_input cli-command.c   /^static int pa_cli_command_kill_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;" f       file:
-pa_cli_command_kill_source_output      cli-command.c   /^static int pa_cli_command_kill_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"      f       file:
-pa_cli_command_list_shared_props       cli-command.c   /^static int pa_cli_command_list_shared_props(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"       f       file:
-pa_cli_command_load    cli-command.c   /^static int pa_cli_command_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"    f       file:
-pa_cli_command_log_backtrace   cli-command.c   /^static int pa_cli_command_log_backtrace(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"   f       file:
-pa_cli_command_log_level       cli-command.c   /^static int pa_cli_command_log_level(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"       f       file:
-pa_cli_command_log_meta        cli-command.c   /^static int pa_cli_command_log_meta(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"        f       file:
-pa_cli_command_log_time        cli-command.c   /^static int pa_cli_command_log_time(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"        f       file:
-pa_cli_command_modules cli-command.c   /^static int pa_cli_command_modules(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;" f       file:
-pa_cli_command_move_sink_input cli-command.c   /^static int pa_cli_command_move_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;" f       file:
-pa_cli_command_move_source_output      cli-command.c   /^static int pa_cli_command_move_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"      f       file:
-pa_cli_command_play_file       cli-command.c   /^static int pa_cli_command_play_file(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"       f       file:
-pa_cli_command_scache_list     cli-command.c   /^static int pa_cli_command_scache_list(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"     f       file:
-pa_cli_command_scache_load     cli-command.c   /^static int pa_cli_command_scache_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"     f       file:
-pa_cli_command_scache_load_dir cli-command.c   /^static int pa_cli_command_scache_load_dir(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;" f       file:
-pa_cli_command_scache_play     cli-command.c   /^static int pa_cli_command_scache_play(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"     f       file:
-pa_cli_command_scache_remove   cli-command.c   /^static int pa_cli_command_scache_remove(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"   f       file:
-pa_cli_command_sink_default    cli-command.c   /^static int pa_cli_command_sink_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"    f       file:
-pa_cli_command_sink_input_mute cli-command.c   /^static int pa_cli_command_sink_input_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;" f       file:
-pa_cli_command_sink_input_volume       cli-command.c   /^static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"       f       file:
-pa_cli_command_sink_inputs     cli-command.c   /^static int pa_cli_command_sink_inputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"     f       file:
-pa_cli_command_sink_mute       cli-command.c   /^static int pa_cli_command_sink_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"       f       file:
-pa_cli_command_sink_port       cli-command.c   /^static int pa_cli_command_sink_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"       f       file:
-pa_cli_command_sink_volume     cli-command.c   /^static int pa_cli_command_sink_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"     f       file:
-pa_cli_command_sinks   cli-command.c   /^static int pa_cli_command_sinks(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"   f       file:
-pa_cli_command_source_default  cli-command.c   /^static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"  f       file:
-pa_cli_command_source_mute     cli-command.c   /^static int pa_cli_command_source_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"     f       file:
-pa_cli_command_source_outputs  cli-command.c   /^static int pa_cli_command_source_outputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"  f       file:
-pa_cli_command_source_port     cli-command.c   /^static int pa_cli_command_source_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"     f       file:
-pa_cli_command_source_volume   cli-command.c   /^static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"   f       file:
-pa_cli_command_sources cli-command.c   /^static int pa_cli_command_sources(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;" f       file:
-pa_cli_command_stat    cli-command.c   /^static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"    f       file:
-pa_cli_command_suspend cli-command.c   /^static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;" f       file:
-pa_cli_command_suspend_sink    cli-command.c   /^static int pa_cli_command_suspend_sink(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"    f       file:
-pa_cli_command_suspend_source  cli-command.c   /^static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"  f       file:
-pa_cli_command_unload  cli-command.c   /^static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"  f       file:
-pa_cli_command_update_sink_input_proplist      cli-command.c   /^static int pa_cli_command_update_sink_input_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"      f       file:
-pa_cli_command_update_sink_proplist    cli-command.c   /^static int pa_cli_command_update_sink_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"    f       file:
-pa_cli_command_update_source_output_proplist   cli-command.c   /^static int pa_cli_command_update_source_output_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"   f       file:
-pa_cli_command_update_source_proplist  cli-command.c   /^static int pa_cli_command_update_source_proplist(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"  f       file:
-pa_cli_command_vacuum  cli-command.c   /^static int pa_cli_command_vacuum(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {$/;"  f       file:
-pa_cli_eof_cb_t        cli.h   /^typedef void (*pa_cli_eof_cb_t)(pa_cli *c, void *userdata);$/;"       t
-pa_cli_free    cli.c   /^void pa_cli_free(pa_cli *c) {$/;"     f
-pa_cli_get_module      cli.c   /^pa_module *pa_cli_get_module(pa_cli *c) {$/;" f
-pa_cli_new     cli.c   /^pa_cli* pa_cli_new(pa_core *core, pa_iochannel *io, pa_module *m) {$/;"       f
-pa_cli_protocol        protocol-cli.c  /^struct pa_cli_protocol {$/;"  s       file:
-pa_cli_protocol        protocol-cli.h  /^typedef struct pa_cli_protocol pa_cli_protocol;$/;"   t       typeref:struct:pa_cli_protocol
-pa_cli_protocol_connect        protocol-cli.c  /^void pa_cli_protocol_connect(pa_cli_protocol *p, pa_iochannel *io, pa_module *m) {$/;"        f
-pa_cli_protocol_disconnect     protocol-cli.c  /^void pa_cli_protocol_disconnect(pa_cli_protocol *p, pa_module *m) {$/;"       f
-pa_cli_protocol_get    protocol-cli.c  /^pa_cli_protocol* pa_cli_protocol_get(pa_core *c) {$/;"        f
-pa_cli_protocol_ref    protocol-cli.c  /^pa_cli_protocol* pa_cli_protocol_ref(pa_cli_protocol *p) {$/;"        f
-pa_cli_protocol_unref  protocol-cli.c  /^void pa_cli_protocol_unref(pa_cli_protocol *p) {$/;"  f
-pa_cli_set_eof_callback        cli.c   /^void pa_cli_set_eof_callback(pa_cli *c, pa_cli_eof_cb_t cb, void *userdata) {$/;"     f
-pa_client      client.h        /^struct pa_client {$/;"        s
-pa_client      client.h        /^typedef struct pa_client pa_client;$/;"       t       typeref:struct:pa_client
-pa_client_free client.c        /^void pa_client_free(pa_client *c) {$/;"       f
-pa_client_kill client.c        /^void pa_client_kill(pa_client *c) {$/;"       f
-pa_client_list_to_string       cli-text.c      /^char *pa_client_list_to_string(pa_core *c) {$/;"      f
-pa_client_new  client.c        /^pa_client *pa_client_new(pa_core *core, pa_client_new_data *data) {$/;"       f
-pa_client_new_data     client.h        /^typedef struct pa_client_new_data {$/;"       s
-pa_client_new_data     client.h        /^} pa_client_new_data;$/;"     t       typeref:struct:pa_client_new_data
-pa_client_new_data_done        client.c        /^void pa_client_new_data_done(pa_client_new_data *data) {$/;"  f
-pa_client_new_data_init        client.c        /^pa_client_new_data* pa_client_new_data_init(pa_client_new_data *data) {$/;"   f
-pa_client_send_event   client.c        /^void pa_client_send_event(pa_client *c, const char *event, pa_proplist *data) {$/;"   f
-pa_client_send_event_hook_data client.h        /^typedef struct pa_client_send_event_hook_data {$/;"   s
-pa_client_send_event_hook_data client.h        /^} pa_client_send_event_hook_data;$/;" t       typeref:struct:pa_client_send_event_hook_data
-pa_client_set_name     client.c        /^void pa_client_set_name(pa_client *c, const char *name) {$/;" f
-pa_client_update_proplist      client.c        /^void pa_client_update_proplist(pa_client *c, pa_update_mode_t mode, pa_proplist *p) {$/;"     f
-pa_close       core-util.c     /^int pa_close(int fd) {$/;"    f
-pa_close_all   core-util.c     /^int pa_close_all(int except_fd, ...) {$/;"    f
-pa_close_allv  core-util.c     /^int pa_close_allv(const int except_fds[]) {$/;"       f
-pa_close_pipe  core-util.c     /^void pa_close_pipe(int fds[2]) {$/;"  f
-pa_compare_func_t      idxset.h        /^typedef int (*pa_compare_func_t)(const void *a, const void *b);$/;"   t
-pa_cond        mutex-posix.c   /^struct pa_cond {$/;"  s       file:
-pa_cond        mutex-win32.c   /^struct pa_cond {$/;"  s       file:
-pa_cond        mutex.h /^typedef struct pa_cond pa_cond;$/;"   t       typeref:struct:pa_cond
-pa_cond_free   mutex-posix.c   /^void pa_cond_free(pa_cond *c) {$/;"   f
-pa_cond_free   mutex-win32.c   /^void pa_cond_free(pa_cond *c) {$/;"   f
-pa_cond_new    mutex-posix.c   /^pa_cond *pa_cond_new(void) {$/;"      f
-pa_cond_new    mutex-win32.c   /^pa_cond *pa_cond_new(void) {$/;"      f
-pa_cond_signal mutex-posix.c   /^void pa_cond_signal(pa_cond *c, int broadcast) {$/;"  f
-pa_cond_signal mutex-win32.c   /^void pa_cond_signal(pa_cond *c, int broadcast) {$/;"  f
-pa_cond_wait   mutex-posix.c   /^int pa_cond_wait(pa_cond *c, pa_mutex *m) {$/;"       f
-pa_cond_wait   mutex-win32.c   /^int pa_cond_wait(pa_cond *c, pa_mutex *m) {$/;"       f
-pa_config_item conf-parser.h   /^typedef struct pa_config_item {$/;"   s
-pa_config_item conf-parser.h   /^} pa_config_item;$/;" t       typeref:struct:pa_config_item
-pa_config_parse        conf-parser.c   /^int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void *userdata) {$/;"     f
-pa_config_parse_bool   conf-parser.c   /^int pa_config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {$/;"  f
-pa_config_parse_int    conf-parser.c   /^int pa_config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {$/;"   f
-pa_config_parse_not_bool       conf-parser.c   /^int pa_config_parse_not_bool($/;"     f
-pa_config_parse_size   conf-parser.c   /^int pa_config_parse_size(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {$/;"  f
-pa_config_parse_string conf-parser.c   /^int pa_config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {$/;"        f
-pa_config_parse_unsigned       conf-parser.c   /^int pa_config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {$/;"      f
-pa_config_parser_cb_t  conf-parser.h   /^typedef int (*pa_config_parser_cb_t)(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);$/;"       t
-pa_convert_func_init_sse       sconv_sse.c     /^void pa_convert_func_init_sse (pa_cpu_x86_flag_t flags) {$/;" f
-pa_convert_func_t      sconv.h /^typedef void (*pa_convert_func_t)(unsigned n, const void *a, void *b);$/;"    t
-pa_convert_size        sample-util.c   /^size_t pa_convert_size(size_t size, const pa_sample_spec *from, const pa_sample_spec *to) {$/;"       f
-pa_core        core.h  /^PA_DECLARE_PUBLIC_CLASS(pa_core);$/;" v
-pa_core        core.h  /^struct pa_core {$/;"  s
-pa_core        core.h  /^typedef struct pa_core pa_core;$/;"   t       typeref:struct:pa_core
-pa_core_check_idle     core.c  /^void pa_core_check_idle(pa_core *c) {$/;"     f
-pa_core_exit   core.c  /^int pa_core_exit(pa_core *c, pa_bool_t force, int retval) {$/;"       f
-pa_core_hook   core.h  /^typedef enum pa_core_hook {$/;"       g
-pa_core_hook_t core.h  /^} pa_core_hook_t;$/;" t       typeref:enum:pa_core_hook
-pa_core_maybe_vacuum   core.c  /^void pa_core_maybe_vacuum(pa_core *c) {$/;"   f
-pa_core_new    core.c  /^pa_core* pa_core_new(pa_mainloop_api *m, pa_bool_t shared, size_t shm_size) {$/;"     f
-pa_core_rttime_new     core.c  /^pa_time_event* pa_core_rttime_new(pa_core *c, pa_usec_t usec, pa_time_event_cb_t cb, void *userdata) {$/;"    f
-pa_core_rttime_restart core.c  /^void pa_core_rttime_restart(pa_core *c, pa_time_event *e, pa_usec_t usec) {$/;"       f
-pa_core_state  core.h  /^typedef enum pa_core_state {$/;"      g
-pa_core_state_t        core.h  /^} pa_core_state_t;$/;"        t       typeref:enum:pa_core_state
-pa_cpu_arm_flag        cpu-arm.h       /^typedef enum pa_cpu_arm_flag {$/;"    g
-pa_cpu_arm_flag_t      cpu-arm.h       /^} pa_cpu_arm_flag_t;$/;"      t       typeref:enum:pa_cpu_arm_flag
-pa_cpu_init_arm        cpu-arm.c       /^void pa_cpu_init_arm (void) {$/;"     f
-pa_cpu_init_x86        cpu-x86.c       /^void pa_cpu_init_x86 (void) {$/;"     f
-pa_cpu_x86_flag        cpu-x86.h       /^typedef enum pa_cpu_x86_flag {$/;"    g
-pa_cpu_x86_flag_t      cpu-x86.h       /^} pa_cpu_x86_flag_t;$/;"      t       typeref:enum:pa_cpu_x86_flag
-pa_creds       creds.h /^struct pa_creds {$/;" s
-pa_creds       creds.h /^typedef struct pa_creds pa_creds;$/;" t       typeref:struct:pa_creds
-pa_cstrerror   core-error.c    /^const char* pa_cstrerror(int errnum) {$/;"    f
-pa_database    database.h      /^typedef struct pa_database pa_database;$/;"   t       typeref:struct:pa_database
-pa_database_clear      database-gdbm.c /^int pa_database_clear(pa_database *db) {$/;"  f
-pa_database_clear      database-simple.c       /^int pa_database_clear(pa_database *database) {$/;"    f
-pa_database_clear      database-tdb.c  /^int pa_database_clear(pa_database *db) {$/;"  f
-pa_database_close      database-gdbm.c /^void pa_database_close(pa_database *db) {$/;" f
-pa_database_close      database-simple.c       /^void pa_database_close(pa_database *database) {$/;"   f
-pa_database_close      database-tdb.c  /^void pa_database_close(pa_database *db) {$/;" f
-pa_database_first      database-gdbm.c /^pa_datum* pa_database_first(pa_database *db, pa_datum *key, pa_datum *data) {$/;"     f
-pa_database_first      database-simple.c       /^pa_datum* pa_database_first(pa_database *database, pa_datum *key, pa_datum *data) {$/;"       f
-pa_database_first      database-tdb.c  /^pa_datum* pa_database_first(pa_database *db, pa_datum *key, pa_datum *data) {$/;"     f
-pa_database_get        database-gdbm.c /^pa_datum* pa_database_get(pa_database *db, const pa_datum *key, pa_datum* data) {$/;" f
-pa_database_get        database-simple.c       /^pa_datum* pa_database_get(pa_database *database, const pa_datum *key, pa_datum* data) {$/;"   f
-pa_database_get        database-tdb.c  /^pa_datum* pa_database_get(pa_database *db, const pa_datum *key, pa_datum* data) {$/;" f
-pa_database_next       database-gdbm.c /^pa_datum* pa_database_next(pa_database *db, const pa_datum *key, pa_datum *next, pa_datum *data) {$/;"        f
-pa_database_next       database-simple.c       /^pa_datum* pa_database_next(pa_database *database, const pa_datum *key, pa_datum *next, pa_datum *data) {$/;"  f
-pa_database_next       database-tdb.c  /^pa_datum* pa_database_next(pa_database *db, const pa_datum *key, pa_datum *next, pa_datum *data) {$/;"        f
-pa_database_open       database-gdbm.c /^pa_database* pa_database_open(const char *fn, pa_bool_t for_write) {$/;"      f
-pa_database_open       database-simple.c       /^pa_database* pa_database_open(const char *fn, pa_bool_t for_write) {$/;"      f
-pa_database_open       database-tdb.c  /^pa_database* pa_database_open(const char *fn, pa_bool_t for_write) {$/;"      f
-pa_database_set        database-gdbm.c /^int pa_database_set(pa_database *db, const pa_datum *key, const pa_datum* data, pa_bool_t overwrite) {$/;"    f
-pa_database_set        database-simple.c       /^int pa_database_set(pa_database *database, const pa_datum *key, const pa_datum* data, pa_bool_t overwrite) {$/;"      f
-pa_database_set        database-tdb.c  /^int pa_database_set(pa_database *db, const pa_datum *key, const pa_datum* data, pa_bool_t overwrite) {$/;"    f
-pa_database_size       database-gdbm.c /^signed pa_database_size(pa_database *db) {$/;"        f
-pa_database_size       database-simple.c       /^signed pa_database_size(pa_database *database) {$/;"  f
-pa_database_size       database-tdb.c  /^signed pa_database_size(pa_database *db) {$/;"        f
-pa_database_sync       database-gdbm.c /^int pa_database_sync(pa_database *db) {$/;"   f
-pa_database_sync       database-simple.c       /^int pa_database_sync(pa_database *database) {$/;"     f
-pa_database_sync       database-tdb.c  /^int pa_database_sync(pa_database *db) {$/;"   f
-pa_database_unset      database-gdbm.c /^int pa_database_unset(pa_database *db, const pa_datum *key) {$/;"     f
-pa_database_unset      database-simple.c       /^int pa_database_unset(pa_database *database, const pa_datum *key) {$/;"       f
-pa_database_unset      database-tdb.c  /^int pa_database_unset(pa_database *db, const pa_datum *key) {$/;"     f
-pa_datum       database.h      /^typedef struct pa_datum {$/;" s
-pa_datum       database.h      /^} pa_datum;$/;"       t       typeref:struct:pa_datum
-pa_datum_free  database-gdbm.c /^void pa_datum_free(pa_datum *d) {$/;" f
-pa_datum_free  database-simple.c       /^void pa_datum_free(pa_datum *d) {$/;" f
-pa_datum_free  database-tdb.c  /^void pa_datum_free(pa_datum *d) {$/;" f
-pa_dbus_add_matches    dbus-util.c     /^int pa_dbus_add_matches(DBusConnection *c, DBusError *error, ...) {$/;"       f
-pa_dbus_bus_get        dbus-shared.c   /^pa_dbus_connection* pa_dbus_bus_get(pa_core *c, DBusBusType type, DBusError *error) {$/;"     f
-pa_dbus_connection     dbus-shared.c   /^struct pa_dbus_connection {$/;"       s       file:
-pa_dbus_connection     dbus-shared.h   /^typedef struct pa_dbus_connection pa_dbus_connection;$/;"     t       typeref:struct:pa_dbus_connection
-pa_dbus_connection_get dbus-shared.c   /^DBusConnection* pa_dbus_connection_get(pa_dbus_connection *c){$/;"    f
-pa_dbus_connection_ref dbus-shared.c   /^pa_dbus_connection* pa_dbus_connection_ref(pa_dbus_connection *c) {$/;"       f
-pa_dbus_connection_unref       dbus-shared.c   /^void pa_dbus_connection_unref(pa_dbus_connection *c) {$/;"    f
-pa_dbus_free_pending_list      dbus-util.c     /^void pa_dbus_free_pending_list(pa_dbus_pending **p) {$/;"     f
-pa_dbus_pending        dbus-util.h     /^struct pa_dbus_pending {$/;"  s
-pa_dbus_pending        dbus-util.h     /^typedef struct pa_dbus_pending pa_dbus_pending;$/;"   t       typeref:struct:pa_dbus_pending
-pa_dbus_pending_free   dbus-util.c     /^void pa_dbus_pending_free(pa_dbus_pending *p) {$/;"   f
-pa_dbus_pending_new    dbus-util.c     /^pa_dbus_pending *pa_dbus_pending_new($/;"     f
-pa_dbus_remove_matches dbus-util.c     /^void pa_dbus_remove_matches(DBusConnection *c, ...) {$/;"     f
-pa_dbus_sync_pending_list      dbus-util.c     /^void pa_dbus_sync_pending_list(pa_dbus_pending **p) {$/;"     f
-pa_dbus_wrap_connection        dbus-util.c     /^struct pa_dbus_wrap_connection {$/;"  s       file:
-pa_dbus_wrap_connection        dbus-util.h     /^typedef struct pa_dbus_wrap_connection pa_dbus_wrap_connection;$/;"   t       typeref:struct:pa_dbus_wrap_connection
-pa_dbus_wrap_connection_free   dbus-util.c     /^void pa_dbus_wrap_connection_free(pa_dbus_wrap_connection* c) {$/;"   f
-pa_dbus_wrap_connection_get    dbus-util.c     /^DBusConnection* pa_dbus_wrap_connection_get(pa_dbus_wrap_connection *c) {$/;" f
-pa_dbus_wrap_connection_new    dbus-util.c     /^pa_dbus_wrap_connection* pa_dbus_wrap_connection_new(pa_mainloop_api *m, pa_bool_t use_rtclock, DBusBusType type, DBusError *error) {$/;"     f
-pa_deinterleave        sample-util.c   /^void pa_deinterleave(const void *src, void *dst[], unsigned channels, size_t ss, unsigned n) {$/;"    f
-pa_device_init_description     sink.c  /^pa_bool_t pa_device_init_description(pa_proplist *p) {$/;"    f
-pa_device_init_icon    sink.c  /^pa_bool_t pa_device_init_icon(pa_proplist *p, pa_bool_t is_sink) {$/;"        f
-pa_device_init_intended_roles  sink.c  /^pa_bool_t pa_device_init_intended_roles(pa_proplist *p) {$/;" f
-pa_device_init_priority        sink.c  /^unsigned pa_device_init_priority(pa_proplist *p) {$/;"        f
-pa_device_port sink.h  /^struct pa_device_port {$/;"   s
-pa_device_port sink.h  /^typedef struct pa_device_port pa_device_port;$/;"     t       typeref:struct:pa_device_port
-pa_device_port_free    sink.c  /^void pa_device_port_free(pa_device_port *p) {$/;"     f
-pa_device_port_new     sink.c  /^pa_device_port *pa_device_port_new(const char *name, const char *description, size_t extra) {$/;"     f
-pa_disable_sigpipe     core-util.c     /^void pa_disable_sigpipe(void) {$/;"   f
-pa_do_remap_func_t     remap.h /^typedef void (*pa_do_remap_func_t) (pa_remap_t *m, void *d, const void *s, unsigned n);$/;"   t
-pa_do_volume_func_t    sample-util.h   /^typedef void (*pa_do_volume_func_t) (void *samples, void *volumes, unsigned channels, unsigned length);$/;"   t
-pa_dynarray    dynarray.c      /^struct pa_dynarray {$/;"      s       file:
-pa_dynarray    dynarray.h      /^typedef struct pa_dynarray pa_dynarray;$/;"   t       typeref:struct:pa_dynarray
-pa_dynarray_append     dynarray.c      /^unsigned pa_dynarray_append(pa_dynarray*a, void *p) {$/;"     f
-pa_dynarray_free       dynarray.c      /^void pa_dynarray_free(pa_dynarray* a, pa_free2_cb_t free_func, void *userdata) {$/;"  f
-pa_dynarray_get        dynarray.c      /^void *pa_dynarray_get(pa_dynarray*a, unsigned i) {$/;"        f
-pa_dynarray_new        dynarray.c      /^pa_dynarray* pa_dynarray_new(void) {$/;"      f
-pa_dynarray_put        dynarray.c      /^void pa_dynarray_put(pa_dynarray*a, unsigned i, void *p) {$/;"        f
-pa_dynarray_size       dynarray.c      /^unsigned pa_dynarray_size(pa_dynarray*a) {$/;"        f
-pa_endswith    core-util.c     /^pa_bool_t pa_endswith(const char *s, const char *sfx) {$/;"   f
-pa_envelope    envelope.c      /^struct pa_envelope {$/;"      s       file:
-pa_envelope    envelope.h      /^typedef struct pa_envelope pa_envelope;$/;"   t       typeref:struct:pa_envelope
-pa_envelope_add        envelope.c      /^pa_envelope_item *pa_envelope_add(pa_envelope *e, const pa_envelope_def *def) {$/;"   f
-pa_envelope_apply      envelope.c      /^void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) {$/;"      f
-pa_envelope_def        envelope.h      /^typedef struct pa_envelope_def {$/;"  s
-pa_envelope_def        envelope.h      /^} pa_envelope_def;$/;"        t       typeref:struct:pa_envelope_def
-pa_envelope_free       envelope.c      /^void pa_envelope_free(pa_envelope *e) {$/;"   f
-pa_envelope_item       envelope.c      /^struct pa_envelope_item {$/;" s       file:
-pa_envelope_item       envelope.h      /^typedef struct pa_envelope_item pa_envelope_item;$/;" t       typeref:struct:pa_envelope_item
-pa_envelope_new        envelope.c      /^pa_envelope *pa_envelope_new(const pa_sample_spec *ss) {$/;"  f
-pa_envelope_remove     envelope.c      /^void pa_envelope_remove(pa_envelope *e, pa_envelope_item *i) {$/;"    f
-pa_envelope_replace    envelope.c      /^pa_envelope_item *pa_envelope_replace(pa_envelope *e, pa_envelope_item *i, const pa_envelope_def *def) {$/;"  f
-pa_envelope_rewind     envelope.c      /^void pa_envelope_rewind(pa_envelope *e, size_t n_bytes) {$/;" f
-pa_esound_options      protocol-esound.h       /^typedef struct pa_esound_options {$/;"        s
-pa_esound_options      protocol-esound.h       /^} pa_esound_options;$/;"      t       typeref:struct:pa_esound_options
-pa_esound_options_new  protocol-esound.c       /^pa_esound_options* pa_esound_options_new(void) {$/;"  f
-pa_esound_options_parse        protocol-esound.c       /^int pa_esound_options_parse(pa_esound_options *o, pa_core *c, pa_modargs *ma) {$/;"   f
-pa_esound_options_ref  protocol-esound.c       /^pa_esound_options* pa_esound_options_ref(pa_esound_options *o) {$/;"  f
-pa_esound_options_unref        protocol-esound.c       /^void pa_esound_options_unref(pa_esound_options *o) {$/;"      f
-pa_esound_protocol     protocol-esound.c       /^struct pa_esound_protocol {$/;"       s       file:
-pa_esound_protocol     protocol-esound.h       /^typedef struct pa_esound_protocol pa_esound_protocol;$/;"     t       typeref:struct:pa_esound_protocol
-pa_esound_protocol_connect     protocol-esound.c       /^void pa_esound_protocol_connect(pa_esound_protocol *p, pa_iochannel *io, pa_esound_options *o) {$/;"  f
-pa_esound_protocol_disconnect  protocol-esound.c       /^void pa_esound_protocol_disconnect(pa_esound_protocol *p, pa_module *m) {$/;" f
-pa_esound_protocol_get protocol-esound.c       /^pa_esound_protocol* pa_esound_protocol_get(pa_core *c) {$/;"  f
-pa_esound_protocol_ref protocol-esound.c       /^pa_esound_protocol* pa_esound_protocol_ref(pa_esound_protocol *p) {$/;"       f
-pa_esound_protocol_unref       protocol-esound.c       /^void pa_esound_protocol_unref(pa_esound_protocol *p) {$/;"    f
-pa_fdsem       fdsem.c /^struct pa_fdsem {$/;" s       file:
-pa_fdsem       fdsem.h /^typedef struct pa_fdsem pa_fdsem;$/;" t       typeref:struct:pa_fdsem
-pa_fdsem_after_poll    fdsem.c /^int pa_fdsem_after_poll(pa_fdsem *f) {$/;"    f
-pa_fdsem_before_poll   fdsem.c /^int pa_fdsem_before_poll(pa_fdsem *f) {$/;"   f
-pa_fdsem_data  fdsem.h /^typedef struct pa_fdsem_data {$/;"    s
-pa_fdsem_data  fdsem.h /^} pa_fdsem_data;$/;"  t       typeref:struct:pa_fdsem_data
-pa_fdsem_free  fdsem.c /^void pa_fdsem_free(pa_fdsem *f) {$/;" f
-pa_fdsem_get   fdsem.c /^int pa_fdsem_get(pa_fdsem *f) {$/;"   f
-pa_fdsem_new   fdsem.c /^pa_fdsem *pa_fdsem_new(void) {$/;"    f
-pa_fdsem_new_shm       fdsem.c /^pa_fdsem *pa_fdsem_new_shm(pa_fdsem_data *data, int* event_fd) {$/;"  f
-pa_fdsem_open_shm      fdsem.c /^pa_fdsem *pa_fdsem_open_shm(pa_fdsem_data *data, int event_fd) {$/;"  f
-pa_fdsem_post  fdsem.c /^void pa_fdsem_post(pa_fdsem *f) {$/;" f
-pa_fdsem_try   fdsem.c /^int pa_fdsem_try(pa_fdsem *f) {$/;"   f
-pa_fdsem_wait  fdsem.c /^void pa_fdsem_wait(pa_fdsem *f) {$/;" f
-pa_find_config_file    core-util.c     /^char *pa_find_config_file(const char *global, const char *local, const char *env) {$/;"       f
-pa_flist       flist.c /^struct pa_flist {$/;" s       file:
-pa_flist       flist.h /^typedef struct pa_flist pa_flist;$/;" t       typeref:struct:pa_flist
-pa_flist_free  flist.c /^void pa_flist_free(pa_flist *l, pa_free_cb_t free_cb) {$/;"   f
-pa_flist_new   flist.c /^pa_flist *pa_flist_new(unsigned size) {$/;"   f
-pa_flist_pop   flist.c /^void* pa_flist_pop(pa_flist*l) {$/;"  f
-pa_flist_push  flist.c /^int pa_flist_push(pa_flist*l, void *p) {$/;"  f
-pa_float_vector        vector.h        /^typedef union pa_float_vector {$/;"   u
-pa_float_vector_t      vector.h        /^} pa_float_vector_t;$/;"      t       typeref:union:pa_float_vector
-pa_frame_align sample-util.c   /^size_t pa_frame_align(size_t l, const pa_sample_spec *ss) {$/;"       f
-pa_frame_aligned       sample-util.c   /^pa_bool_t pa_frame_aligned(size_t l, const pa_sample_spec *ss) {$/;"  f
-pa_free2_cb_t  idxset.h        /^typedef void (*pa_free2_cb_t)(void *p, void *userdata);$/;"   t
-pa_full_status_string  cli-text.c      /^char *pa_full_status_string(pa_core *c) {$/;" f
-pa_gcd core-util.c     /^unsigned pa_gcd(unsigned a, unsigned b) {$/;" f
-pa_get_binary_name_malloc      core-util.c     /^char *pa_get_binary_name_malloc(void) {$/;"   f
-pa_get_convert_from_float32ne_function sconv.c /^pa_convert_func_t pa_get_convert_from_float32ne_function(pa_sample_format_t f) {$/;"  f
-pa_get_convert_from_s16ne_function     sconv.c /^pa_convert_func_t pa_get_convert_from_s16ne_function(pa_sample_format_t f) {$/;"      f
-pa_get_convert_to_float32ne_function   sconv.c /^pa_convert_func_t pa_get_convert_to_float32ne_function(pa_sample_format_t f) {$/;"    f
-pa_get_convert_to_s16ne_function       sconv.c /^pa_convert_func_t pa_get_convert_to_s16ne_function(pa_sample_format_t f) {$/;"        f
-pa_get_gid_of_group    core-util.c     /^gid_t pa_get_gid_of_group(const char *name) {$/;"     f
-pa_get_home_dir_malloc core-util.c     /^char *pa_get_home_dir_malloc(void) {$/;"      f
-pa_get_host_name_malloc        core-util.c     /^char *pa_get_host_name_malloc(void) {$/;"     f
-pa_get_init_remap_func remap.c /^pa_init_remap_func_t pa_get_init_remap_func(void) {$/;"       f
-pa_get_runtime_dir     core-util.c     /^char *pa_get_runtime_dir(void) {$/;"  f
-pa_get_state_dir       core-util.c     /^char *pa_get_state_dir(void) {$/;"    f
-pa_get_temp_dir        core-util.c     /^const char *pa_get_temp_dir(void) {$/;"       f
-pa_get_user_name_malloc        core-util.c     /^char *pa_get_user_name_malloc(void) {$/;"     f
-pa_get_volume_func     svolume_c.c     /^pa_do_volume_func_t pa_get_volume_func(pa_sample_format_t f) {$/;"    f
-pa_getcwd      core-util.c     /^char *pa_getcwd(void) {$/;"   f
-pa_getgrgid_free       usergroup.c     /^void pa_getgrgid_free(struct group *grp) {$/;"        f
-pa_getgrgid_malloc     usergroup.c     /^struct group *pa_getgrgid_malloc(gid_t gid) {$/;"     f
-pa_getgrnam_free       usergroup.c     /^void pa_getgrnam_free(struct group *group) {$/;"      f
-pa_getgrnam_malloc     usergroup.c     /^struct group *pa_getgrnam_malloc(const char *name) {$/;"      f
-pa_getpwnam_free       usergroup.c     /^void pa_getpwnam_free(struct passwd *passwd) {$/;"    f
-pa_getpwnam_malloc     usergroup.c     /^struct passwd *pa_getpwnam_malloc(const char *name) {$/;"     f
-pa_getpwuid_free       usergroup.c     /^void pa_getpwuid_free(struct passwd *passwd) {$/;"    f
-pa_getpwuid_malloc     usergroup.c     /^struct passwd *pa_getpwuid_malloc(uid_t uid) {$/;"    f
-pa_hash_func_t idxset.h        /^typedef unsigned (*pa_hash_func_t)(const void *p);$/;"        t
-pa_hashmap     hashmap.c       /^struct pa_hashmap {$/;"       s       file:
-pa_hashmap     hashmap.h       /^typedef struct pa_hashmap pa_hashmap;$/;"     t       typeref:struct:pa_hashmap
-pa_hashmap_first       hashmap.c       /^void* pa_hashmap_first(pa_hashmap *h) {$/;"   f
-pa_hashmap_free        hashmap.c       /^void pa_hashmap_free(pa_hashmap*h, pa_free2_cb_t free_cb, void *userdata) {$/;"       f
-pa_hashmap_get hashmap.c       /^void* pa_hashmap_get(pa_hashmap *h, const void *key) {$/;"    f
-pa_hashmap_isempty     hashmap.c       /^pa_bool_t pa_hashmap_isempty(pa_hashmap *h) {$/;"     f
-pa_hashmap_iterate     hashmap.c       /^void *pa_hashmap_iterate(pa_hashmap *h, void **state, const void **key) {$/;" f
-pa_hashmap_iterate_backwards   hashmap.c       /^void *pa_hashmap_iterate_backwards(pa_hashmap *h, void **state, const void **key) {$/;"       f
-pa_hashmap_last        hashmap.c       /^void* pa_hashmap_last(pa_hashmap *h) {$/;"    f
-pa_hashmap_new hashmap.c       /^pa_hashmap *pa_hashmap_new(pa_hash_func_t hash_func, pa_compare_func_t compare_func) {$/;"    f
-pa_hashmap_put hashmap.c       /^int pa_hashmap_put(pa_hashmap *h, const void *key, void *value) {$/;" f
-pa_hashmap_remove      hashmap.c       /^void* pa_hashmap_remove(pa_hashmap *h, const void *key) {$/;" f
-pa_hashmap_size        hashmap.c       /^unsigned pa_hashmap_size(pa_hashmap *h) {$/;" f
-pa_hashmap_steal_first hashmap.c       /^void* pa_hashmap_steal_first(pa_hashmap *h) {$/;"     f
-pa_hexstr      core-util.c     /^char *pa_hexstr(const uint8_t* d, size_t dlength, char *s, size_t slength) {$/;"      f
-pa_hook        hook-list.h     /^struct pa_hook {$/;"  s
-pa_hook        hook-list.h     /^typedef struct pa_hook pa_hook;$/;"   t       typeref:struct:pa_hook
-pa_hook_cb_t   hook-list.h     /^typedef pa_hook_result_t (*pa_hook_cb_t)($/;" t
-pa_hook_connect        hook-list.c     /^pa_hook_slot* pa_hook_connect(pa_hook *hook, pa_hook_priority_t prio, pa_hook_cb_t cb, void *data) {$/;"      f
-pa_hook_done   hook-list.c     /^void pa_hook_done(pa_hook *hook) {$/;"        f
-pa_hook_fire   hook-list.c     /^pa_hook_result_t pa_hook_fire(pa_hook *hook, void *data) {$/;"        f
-pa_hook_init   hook-list.c     /^void pa_hook_init(pa_hook *hook, void *data) {$/;"    f
-pa_hook_is_firing      hook-list.c     /^pa_bool_t pa_hook_is_firing(pa_hook *hook) {$/;"      f
-pa_hook_priority       hook-list.h     /^typedef enum pa_hook_priority {$/;"   g
-pa_hook_priority_t     hook-list.h     /^} pa_hook_priority_t;$/;"     t       typeref:enum:pa_hook_priority
-pa_hook_result hook-list.h     /^typedef enum pa_hook_result {$/;"     g
-pa_hook_result_t       hook-list.h     /^} pa_hook_result_t;$/;"       t       typeref:enum:pa_hook_result
-pa_hook_slot   hook-list.h     /^struct pa_hook_slot {$/;"     s
-pa_hook_slot   hook-list.h     /^typedef struct pa_hook_slot pa_hook_slot;$/;" t       typeref:struct:pa_hook_slot
-pa_hook_slot_free      hook-list.c     /^void pa_hook_slot_free(pa_hook_slot *slot) {$/;"      f
-pa_http_protocol       protocol-http.c /^struct pa_http_protocol {$/;" s       file:
-pa_http_protocol       protocol-http.h /^typedef struct pa_http_protocol pa_http_protocol;$/;" t       typeref:struct:pa_http_protocol
-pa_http_protocol_add_server_string     protocol-http.c /^void pa_http_protocol_add_server_string(pa_http_protocol *p, const char *name) {$/;"  f
-pa_http_protocol_connect       protocol-http.c /^void pa_http_protocol_connect(pa_http_protocol *p, pa_iochannel *io, pa_module *m) {$/;"      f
-pa_http_protocol_disconnect    protocol-http.c /^void pa_http_protocol_disconnect(pa_http_protocol *p, pa_module *m) {$/;"     f
-pa_http_protocol_get   protocol-http.c /^pa_http_protocol* pa_http_protocol_get(pa_core *c) {$/;"      f
-pa_http_protocol_ref   protocol-http.c /^pa_http_protocol* pa_http_protocol_ref(pa_http_protocol *p) {$/;"     f
-pa_http_protocol_remove_server_string  protocol-http.c /^void pa_http_protocol_remove_server_string(pa_http_protocol *p, const char *name) {$/;"       f
-pa_http_protocol_servers       protocol-http.c /^pa_strlist *pa_http_protocol_servers(pa_http_protocol *p) {$/;"       f
-pa_http_protocol_unref protocol-http.c /^void pa_http_protocol_unref(pa_http_protocol *p) {$/;"        f
-pa_idxset      idxset.c        /^struct pa_idxset {$/;"        s       file:
-pa_idxset      idxset.h        /^typedef struct pa_idxset pa_idxset;$/;"       t       typeref:struct:pa_idxset
-pa_idxset_copy idxset.c        /^pa_idxset *pa_idxset_copy(pa_idxset *s) {$/;" f
-pa_idxset_first        idxset.c        /^void* pa_idxset_first(pa_idxset *s, uint32_t *idx) {$/;"      f
-pa_idxset_free idxset.c        /^void pa_idxset_free(pa_idxset *s, pa_free2_cb_t free_cb, void *userdata) {$/;"        f
-pa_idxset_get_by_data  idxset.c        /^void* pa_idxset_get_by_data(pa_idxset*s, const void *p, uint32_t *idx) {$/;"  f
-pa_idxset_get_by_index idxset.c        /^void* pa_idxset_get_by_index(pa_idxset*s, uint32_t idx) {$/;" f
-pa_idxset_isempty      idxset.c        /^pa_bool_t pa_idxset_isempty(pa_idxset *s) {$/;"       f
-pa_idxset_iterate      idxset.c        /^void *pa_idxset_iterate(pa_idxset *s, void **state, uint32_t *idx) {$/;"      f
-pa_idxset_new  idxset.c        /^pa_idxset* pa_idxset_new(pa_hash_func_t hash_func, pa_compare_func_t compare_func) {$/;"      f
-pa_idxset_next idxset.c        /^void *pa_idxset_next(pa_idxset *s, uint32_t *idx) {$/;"       f
-pa_idxset_put  idxset.c        /^int pa_idxset_put(pa_idxset*s, void *p, uint32_t *idx) {$/;"  f
-pa_idxset_remove_by_data       idxset.c        /^void* pa_idxset_remove_by_data(pa_idxset*s, const void *data, uint32_t *idx) {$/;"    f
-pa_idxset_remove_by_index      idxset.c        /^void* pa_idxset_remove_by_index(pa_idxset*s, uint32_t idx) {$/;"      f
-pa_idxset_rrobin       idxset.c        /^void* pa_idxset_rrobin(pa_idxset *s, uint32_t *idx) {$/;"     f
-pa_idxset_size idxset.c        /^unsigned pa_idxset_size(pa_idxset*s) {$/;"    f
-pa_idxset_steal_first  idxset.c        /^void* pa_idxset_steal_first(pa_idxset *s, uint32_t *idx) {$/;"        f
-pa_idxset_string_compare_func  idxset.c        /^int pa_idxset_string_compare_func(const void *a, const void *b) {$/;" f
-pa_idxset_string_hash_func     idxset.c        /^unsigned pa_idxset_string_hash_func(const void *p) {$/;"      f
-pa_idxset_trivial_compare_func idxset.c        /^int pa_idxset_trivial_compare_func(const void *a, const void *b) {$/;"        f
-pa_idxset_trivial_hash_func    idxset.c        /^unsigned pa_idxset_trivial_hash_func(const void *p) {$/;"     f
-pa_in_system_mode      core-util.c     /^pa_bool_t pa_in_system_mode(void) {$/;"       f
-pa_in_valgrind core-util.c     /^pa_bool_t pa_in_valgrind(void) {$/;"  f
-pa_in_valgrind core-util.h     /^static inline pa_bool_t pa_in_valgrind(void) {$/;"    f
-pa_init_proplist       proplist-util.c /^void pa_init_proplist(pa_proplist *p) {$/;"   f
-pa_init_remap  remap.c /^void pa_init_remap (pa_remap_t *m) {$/;"      f
-pa_init_remap_func_t   remap.h /^typedef void (*pa_init_remap_func_t) (pa_remap_t *m);$/;"     t
-pa_int16_vector        vector.h        /^typedef union pa_int16_vector {$/;"   u
-pa_int16_vector_t      vector.h        /^} pa_int16_vector_t;$/;"      t       typeref:union:pa_int16_vector
-pa_int32_vector        vector.h        /^typedef union pa_int32_vector {$/;"   u
-pa_int32_vector_t      vector.h        /^} pa_int32_vector_t;$/;"      t       typeref:union:pa_int32_vector
-pa_interleave  sample-util.c   /^void pa_interleave(const void *src[], unsigned channels, void *dst, size_t ss, unsigned n) {$/;"      f
-pa_iochannel   iochannel.c     /^struct pa_iochannel {$/;"     s       file:
-pa_iochannel   iochannel.h     /^typedef struct pa_iochannel pa_iochannel;$/;" t       typeref:struct:pa_iochannel
-pa_iochannel_cb_t      iochannel.h     /^typedef void (*pa_iochannel_cb_t)(pa_iochannel*io, void *userdata);$/;"       t
-pa_iochannel_creds_enable      iochannel.c     /^int pa_iochannel_creds_enable(pa_iochannel *io) {$/;" f
-pa_iochannel_creds_supported   iochannel.c     /^pa_bool_t pa_iochannel_creds_supported(pa_iochannel *io) {$/;"        f
-pa_iochannel_free      iochannel.c     /^void pa_iochannel_free(pa_iochannel*io) {$/;" f
-pa_iochannel_get_mainloop_api  iochannel.c     /^pa_mainloop_api* pa_iochannel_get_mainloop_api(pa_iochannel *io) {$/;"        f
-pa_iochannel_get_recv_fd       iochannel.c     /^int pa_iochannel_get_recv_fd(pa_iochannel *io) {$/;"  f
-pa_iochannel_get_send_fd       iochannel.c     /^int pa_iochannel_get_send_fd(pa_iochannel *io) {$/;"  f
-pa_iochannel_is_hungup iochannel.c     /^pa_bool_t pa_iochannel_is_hungup(pa_iochannel*io) {$/;"       f
-pa_iochannel_is_readable       iochannel.c     /^pa_bool_t pa_iochannel_is_readable(pa_iochannel*io) {$/;"     f
-pa_iochannel_is_writable       iochannel.c     /^pa_bool_t pa_iochannel_is_writable(pa_iochannel*io) {$/;"     f
-pa_iochannel_new       iochannel.c     /^pa_iochannel* pa_iochannel_new(pa_mainloop_api*m, int ifd, int ofd) {$/;"     f
-pa_iochannel_read      iochannel.c     /^ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l) {$/;" f
-pa_iochannel_read_with_creds   iochannel.c     /^ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, pa_creds *creds, pa_bool_t *creds_valid) {$/;"     f
-pa_iochannel_set_callback      iochannel.c     /^void pa_iochannel_set_callback(pa_iochannel*io, pa_iochannel_cb_t _callback, void *userdata) {$/;"    f
-pa_iochannel_set_noclose       iochannel.c     /^void pa_iochannel_set_noclose(pa_iochannel*io, pa_bool_t b) {$/;"     f
-pa_iochannel_socket_is_local   iochannel.c     /^pa_bool_t pa_iochannel_socket_is_local(pa_iochannel *io) {$/;"        f
-pa_iochannel_socket_peer_to_string     iochannel.c     /^void pa_iochannel_socket_peer_to_string(pa_iochannel*io, char*s, size_t l) {$/;"      f
-pa_iochannel_socket_set_rcvbuf iochannel.c     /^int pa_iochannel_socket_set_rcvbuf(pa_iochannel *io, size_t l) {$/;"  f
-pa_iochannel_socket_set_sndbuf iochannel.c     /^int pa_iochannel_socket_set_sndbuf(pa_iochannel *io, size_t l) {$/;"  f
-pa_iochannel_write     iochannel.c     /^ssize_t pa_iochannel_write(pa_iochannel*io, const void*data, size_t l) {$/;"  f
-pa_iochannel_write_with_creds  iochannel.c     /^ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l, const pa_creds *ucred) {$/;"        f
-pa_ioline      ioline.c        /^struct pa_ioline {$/;"        s       file:
-pa_ioline      ioline.h        /^typedef struct pa_ioline pa_ioline;$/;"       t       typeref:struct:pa_ioline
-pa_ioline_cb_t ioline.h        /^typedef void (*pa_ioline_cb_t)(pa_ioline*io, const char *s, void *userdata);$/;"      t
-pa_ioline_close        ioline.c        /^void pa_ioline_close(pa_ioline *l) {$/;"      f
-pa_ioline_defer_close  ioline.c        /^void pa_ioline_defer_close(pa_ioline *l) {$/;"        f
-pa_ioline_detach_iochannel     ioline.c        /^pa_iochannel* pa_ioline_detach_iochannel(pa_ioline *l) {$/;"  f
-pa_ioline_drain_cb_t   ioline.h        /^typedef void (*pa_ioline_drain_cb_t)(pa_ioline *io, void *userdata);$/;"      t
-pa_ioline_is_drained   ioline.c        /^pa_bool_t pa_ioline_is_drained(pa_ioline *l) {$/;"    f
-pa_ioline_new  ioline.c        /^pa_ioline* pa_ioline_new(pa_iochannel *io) {$/;"      f
-pa_ioline_printf       ioline.c        /^void pa_ioline_printf(pa_ioline *l, const char *format, ...) {$/;"    f
-pa_ioline_puts ioline.c        /^void pa_ioline_puts(pa_ioline *l, const char *c) {$/;"        f
-pa_ioline_ref  ioline.c        /^pa_ioline* pa_ioline_ref(pa_ioline *l) {$/;"  f
-pa_ioline_set_callback ioline.c        /^void pa_ioline_set_callback(pa_ioline*l, pa_ioline_cb_t callback, void *userdata) {$/;"       f
-pa_ioline_set_drain_callback   ioline.c        /^void pa_ioline_set_drain_callback(pa_ioline*l, pa_ioline_drain_cb_t callback, void *userdata) {$/;"   f
-pa_ioline_unref        ioline.c        /^void pa_ioline_unref(pa_ioline *l) {$/;"      f
-pa_ip_acl      ipacl.c /^struct pa_ip_acl {$/;"        s       file:
-pa_ip_acl      ipacl.h /^typedef struct pa_ip_acl pa_ip_acl;$/;"       t       typeref:struct:pa_ip_acl
-pa_ip_acl_check        ipacl.c /^int pa_ip_acl_check(pa_ip_acl *acl, int fd) {$/;"     f
-pa_ip_acl_free ipacl.c /^void pa_ip_acl_free(pa_ip_acl *acl) {$/;"     f
-pa_ip_acl_new  ipacl.c /^pa_ip_acl* pa_ip_acl_new(const char *s) {$/;" f
-pa_is_ip_address       parseaddr.c     /^pa_bool_t pa_is_ip_address(const char *a) {$/;"       f
-pa_is_path_absolute    core-util.c     /^pa_bool_t pa_is_path_absolute(const char *fn) {$/;"   f
-pa_is_power_of_two     core-util.h     /^static inline int pa_is_power_of_two(unsigned n) {$/;"        f
-pa_load_sym    ltdl-helper.c   /^pa_void_func_t pa_load_sym(lt_dlhandle handle, const char *module, const char *symbol) {$/;"  f
-pa_lock_fd     core-util.c     /^int pa_lock_fd(int fd, int b) {$/;"   f
-pa_lock_lockfile       core-util.c     /^int pa_lock_lockfile(const char *fn) {$/;"    f
-pa_log log.h   136;"   d
-pa_log_debug   log.h   111;"   d
-pa_log_error   log.h   115;"   d
-pa_log_flags   log.h   /^typedef enum pa_log_flags {$/;"       g
-pa_log_flags_t log.h   /^} pa_log_flags_t;$/;" t       typeref:enum:pa_log_flags
-pa_log_info    log.h   112;"   d
-pa_log_level   log.c   /^void pa_log_level(pa_log_level_t level, const char *format, ...) {$/;"        f
-pa_log_level   log.h   /^typedef enum pa_log_level {$/;"       g
-pa_log_level_meta      log.c   /^void pa_log_level_meta($/;"   f
-pa_log_level_t log.h   /^} pa_log_level_t;$/;" t       typeref:enum:pa_log_level
-pa_log_levelv  log.c   /^void pa_log_levelv(pa_log_level_t level, const char *format, va_list ap) {$/;"        f
-pa_log_levelv_meta     log.c   /^void pa_log_levelv_meta($/;"  f
-pa_log_merge   log.h   /^typedef enum pa_log_merge {$/;"       g
-pa_log_merge_t log.h   /^} pa_log_merge_t;$/;" t       typeref:enum:pa_log_merge
-pa_log_notice  log.h   113;"   d
-pa_log_ratelimit       log.c   /^pa_bool_t pa_log_ratelimit(void) {$/;"        f
-pa_log_set_flags       log.c   /^void pa_log_set_flags(pa_log_flags_t _flags, pa_log_merge_t merge) {$/;"      f
-pa_log_set_ident       log.c   /^void pa_log_set_ident(const char *p) {$/;"    f
-pa_log_set_level       log.c   /^void pa_log_set_level(pa_log_level_t l) {$/;" f
-pa_log_set_show_backtrace      log.c   /^void pa_log_set_show_backtrace(unsigned nlevels) {$/;"        f
-pa_log_set_skip_backtrace      log.c   /^void pa_log_set_skip_backtrace(unsigned nlevels) {$/;"        f
-pa_log_set_target      log.c   /^void pa_log_set_target(pa_log_target_t t) {$/;"       f
-pa_log_target  log.h   /^typedef enum pa_log_target {$/;"      g
-pa_log_target_t        log.h   /^} pa_log_target_t;$/;"        t       typeref:enum:pa_log_target
-pa_log_warn    log.h   114;"   d
-pa_logl        log.h   116;"   d
-pa_loop_read   core-util.c     /^ssize_t pa_loop_read(int fd, void*data, size_t size, int *type) {$/;" f
-pa_loop_write  core-util.c     /^ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type) {$/;"  f
-pa_machine_id  core-util.c     /^char *pa_machine_id(void) {$/;"       f
-pa_make_fd_cloexec     core-util.c     /^void pa_make_fd_cloexec(int fd) {$/;" f
-pa_make_fd_nonblock    core-util.c     /^void pa_make_fd_nonblock(int fd) {$/;"        f
-pa_make_path_absolute  core-util.c     /^char *pa_make_path_absolute(const char *p) {$/;"      f
-pa_make_power_of_two   core-util.h     /^static inline unsigned pa_make_power_of_two(unsigned n) {$/;" f
-pa_make_realtime       core-util.c     /^int pa_make_realtime(int rtprio) {$/;"        f
-pa_make_secure_dir     core-util.c     /^int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) {$/;" f
-pa_make_secure_parent_dir      core-util.c     /^int pa_make_secure_parent_dir(const char *fn, mode_t m, uid_t uid, gid_t gid) {$/;"   f
-pa_make_socket_low_delay       socket-util.c   /^void pa_make_socket_low_delay(int fd) {$/;"   f
-pa_make_tcp_socket_low_delay   socket-util.c   /^void pa_make_tcp_socket_low_delay(int fd) {$/;"       f
-pa_make_udp_socket_low_delay   socket-util.c   /^void pa_make_udp_socket_low_delay(int fd) {$/;"       f
-pa_match       core-util.c     /^int pa_match(const char *expr, const char *v) {$/;"   f
-pa_maybe_prefix_path   core-util.c     /^char* pa_maybe_prefix_path(const char *path, const char *prefix) {$/;"        f
-pa_mcalign     mcalign.c       /^struct pa_mcalign {$/;"       s       file:
-pa_mcalign     mcalign.h       /^typedef struct pa_mcalign pa_mcalign;$/;"     t       typeref:struct:pa_mcalign
-pa_mcalign_csize       mcalign.c       /^size_t pa_mcalign_csize(pa_mcalign *m, size_t l) {$/;"        f
-pa_mcalign_flush       mcalign.c       /^void pa_mcalign_flush(pa_mcalign *m) {$/;"    f
-pa_mcalign_free        mcalign.c       /^void pa_mcalign_free(pa_mcalign *m) {$/;"     f
-pa_mcalign_new mcalign.c       /^pa_mcalign *pa_mcalign_new(size_t base) {$/;" f
-pa_mcalign_pop mcalign.c       /^int pa_mcalign_pop(pa_mcalign *m, pa_memchunk *c) {$/;"       f
-pa_mcalign_push        mcalign.c       /^void pa_mcalign_push(pa_mcalign *m, const pa_memchunk *c) {$/;"       f
-pa_memblock    memblock.c      /^struct pa_memblock {$/;"      s       file:
-pa_memblock    memblock.h      /^typedef struct pa_memblock pa_memblock;$/;"   t       typeref:struct:pa_memblock
-pa_memblock_acquire    memblock.c      /^void* pa_memblock_acquire(pa_memblock *b) {$/;"       f
-pa_memblock_get_length memblock.c      /^size_t pa_memblock_get_length(pa_memblock *b) {$/;"   f
-pa_memblock_get_pool   memblock.c      /^pa_mempool* pa_memblock_get_pool(pa_memblock *b) {$/;"        f
-pa_memblock_is_read_only       memblock.c      /^pa_bool_t pa_memblock_is_read_only(pa_memblock *b) {$/;"      f
-pa_memblock_is_silence memblock.c      /^pa_bool_t pa_memblock_is_silence(pa_memblock *b) {$/;"        f
-pa_memblock_new        memblock.c      /^pa_memblock *pa_memblock_new(pa_mempool *p, size_t length) {$/;"      f
-pa_memblock_new_fixed  memblock.c      /^pa_memblock *pa_memblock_new_fixed(pa_mempool *p, void *d, size_t length, pa_bool_t read_only) {$/;"  f
-pa_memblock_new_malloced       memblock.h      91;"    d
-pa_memblock_new_pool   memblock.c      /^pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) {$/;" f
-pa_memblock_new_user   memblock.c      /^pa_memblock *pa_memblock_new_user(pa_mempool *p, void *d, size_t length, pa_free_cb_t free_cb, pa_bool_t read_only) {$/;"     f
-pa_memblock_ref        memblock.c      /^pa_memblock* pa_memblock_ref(pa_memblock*b) {$/;"     f
-pa_memblock_ref_is_one memblock.c      /^pa_bool_t pa_memblock_ref_is_one(pa_memblock *b) {$/;"        f
-pa_memblock_release    memblock.c      /^void pa_memblock_release(pa_memblock *b) {$/;"        f
-pa_memblock_set_is_silence     memblock.c      /^void pa_memblock_set_is_silence(pa_memblock *b, pa_bool_t v) {$/;"    f
-pa_memblock_type       memblock.h      /^typedef enum pa_memblock_type {$/;"   g
-pa_memblock_type_t     memblock.h      /^} pa_memblock_type_t;$/;"     t       typeref:enum:pa_memblock_type
-pa_memblock_unref      memblock.c      /^void pa_memblock_unref(pa_memblock*b) {$/;"   f
-pa_memblock_unref_fixed        memblock.c      /^void pa_memblock_unref_fixed(pa_memblock *b) {$/;"    f
-pa_memblock_will_need  memblock.c      /^pa_memblock *pa_memblock_will_need(pa_memblock *b) {$/;"      f
-pa_memblockq   memblockq.c     /^struct pa_memblockq {$/;"     s       file:
-pa_memblockq   memblockq.h     /^typedef struct pa_memblockq pa_memblockq;$/;" t       typeref:struct:pa_memblockq
-pa_memblockq_apply_attr        memblockq.c     /^void pa_memblockq_apply_attr(pa_memblockq *bq, const pa_buffer_attr *a) {$/;" f
-pa_memblockq_drop      memblockq.c     /^void pa_memblockq_drop(pa_memblockq *bq, size_t length) {$/;" f
-pa_memblockq_flush_read        memblockq.c     /^void pa_memblockq_flush_read(pa_memblockq *bq) {$/;"  f
-pa_memblockq_flush_write       memblockq.c     /^void pa_memblockq_flush_write(pa_memblockq *bq) {$/;" f
-pa_memblockq_free      memblockq.c     /^void pa_memblockq_free(pa_memblockq* bq) {$/;"        f
-pa_memblockq_get_attr  memblockq.c     /^void pa_memblockq_get_attr(pa_memblockq *bq, pa_buffer_attr *a) {$/;" f
-pa_memblockq_get_base  memblockq.c     /^size_t pa_memblockq_get_base(pa_memblockq *bq) {$/;"  f
-pa_memblockq_get_length        memblockq.c     /^size_t pa_memblockq_get_length(pa_memblockq *bq) {$/;"        f
-pa_memblockq_get_maxlength     memblockq.c     /^size_t pa_memblockq_get_maxlength(pa_memblockq *bq) {$/;"     f
-pa_memblockq_get_maxrewind     memblockq.c     /^size_t pa_memblockq_get_maxrewind(pa_memblockq *bq) {$/;"     f
-pa_memblockq_get_minreq        memblockq.c     /^size_t pa_memblockq_get_minreq(pa_memblockq *bq) {$/;"        f
-pa_memblockq_get_nblocks       memblockq.c     /^unsigned pa_memblockq_get_nblocks(pa_memblockq *bq) {$/;"     f
-pa_memblockq_get_prebuf        memblockq.c     /^size_t pa_memblockq_get_prebuf(pa_memblockq *bq) {$/;"        f
-pa_memblockq_get_read_index    memblockq.c     /^int64_t pa_memblockq_get_read_index(pa_memblockq *bq) {$/;"   f
-pa_memblockq_get_tlength       memblockq.c     /^size_t pa_memblockq_get_tlength(pa_memblockq *bq) {$/;"       f
-pa_memblockq_get_write_index   memblockq.c     /^int64_t pa_memblockq_get_write_index(pa_memblockq *bq) {$/;"  f
-pa_memblockq_is_empty  memblockq.c     /^pa_bool_t pa_memblockq_is_empty(pa_memblockq *bq) {$/;"       f
-pa_memblockq_is_readable       memblockq.c     /^pa_bool_t pa_memblockq_is_readable(pa_memblockq *bq) {$/;"    f
-pa_memblockq_missing   memblockq.c     /^size_t pa_memblockq_missing(pa_memblockq *bq) {$/;"   f
-pa_memblockq_new       memblockq.c     /^pa_memblockq* pa_memblockq_new($/;"   f
-pa_memblockq_peek      memblockq.c     /^int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) {$/;"     f
-pa_memblockq_pop_missing       memblockq.c     /^size_t pa_memblockq_pop_missing(pa_memblockq *bq) {$/;"       f
-pa_memblockq_prebuf_active     memblockq.c     /^pa_bool_t pa_memblockq_prebuf_active(pa_memblockq *bq) {$/;"  f
-pa_memblockq_prebuf_disable    memblockq.c     /^void pa_memblockq_prebuf_disable(pa_memblockq *bq) {$/;"      f
-pa_memblockq_prebuf_force      memblockq.c     /^void pa_memblockq_prebuf_force(pa_memblockq *bq) {$/;"        f
-pa_memblockq_push      memblockq.c     /^int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {$/;"      f
-pa_memblockq_push_align        memblockq.c     /^int pa_memblockq_push_align(pa_memblockq* bq, const pa_memchunk *chunk) {$/;" f
-pa_memblockq_rewind    memblockq.c     /^void pa_memblockq_rewind(pa_memblockq *bq, size_t length) {$/;"       f
-pa_memblockq_seek      memblockq.c     /^void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek, pa_bool_t account) {$/;"        f
-pa_memblockq_set_maxlength     memblockq.c     /^void pa_memblockq_set_maxlength(pa_memblockq *bq, size_t maxlength) {$/;"     f
-pa_memblockq_set_maxrewind     memblockq.c     /^void pa_memblockq_set_maxrewind(pa_memblockq *bq, size_t maxrewind) {$/;"     f
-pa_memblockq_set_minreq        memblockq.c     /^void pa_memblockq_set_minreq(pa_memblockq *bq, size_t minreq) {$/;"   f
-pa_memblockq_set_prebuf        memblockq.c     /^void pa_memblockq_set_prebuf(pa_memblockq *bq, size_t prebuf) {$/;"   f
-pa_memblockq_set_silence       memblockq.c     /^void pa_memblockq_set_silence(pa_memblockq *bq, pa_memchunk *silence) {$/;"   f
-pa_memblockq_set_tlength       memblockq.c     /^void pa_memblockq_set_tlength(pa_memblockq *bq, size_t tlength) {$/;" f
-pa_memblockq_silence   memblockq.c     /^void pa_memblockq_silence(pa_memblockq *bq) {$/;"     f
-pa_memblockq_sink_input_new    play-memblockq.c        /^pa_sink_input* pa_memblockq_sink_input_new($/;"       f
-pa_memblockq_sink_input_set_queue      play-memblockq.c        /^void pa_memblockq_sink_input_set_queue(pa_sink_input *i, pa_memblockq *q) {$/;"       f
-pa_memblockq_splice    memblockq.c     /^int pa_memblockq_splice(pa_memblockq *bq, pa_memblockq *source) {$/;" f
-pa_memblockq_willneed  memblockq.c     /^void pa_memblockq_willneed(pa_memblockq *bq) {$/;"    f
-pa_memchunk    memchunk.h      /^typedef struct pa_memchunk {$/;"      s
-pa_memchunk    memchunk.h      /^} pa_memchunk;$/;"    t       typeref:struct:pa_memchunk
-pa_memchunk_dump_to_file       sample-util.c   /^void pa_memchunk_dump_to_file(pa_memchunk *c, const char *fn) {$/;"   f
-pa_memchunk_make_writable      memchunk.c      /^pa_memchunk* pa_memchunk_make_writable(pa_memchunk *c, size_t min) {$/;"      f
-pa_memchunk_memcpy     memchunk.c      /^pa_memchunk* pa_memchunk_memcpy(pa_memchunk *dst, pa_memchunk *src) {$/;"     f
-pa_memchunk_reset      memchunk.c      /^pa_memchunk* pa_memchunk_reset(pa_memchunk *c) {$/;"  f
-pa_memchunk_sine       sample-util.c   /^void pa_memchunk_sine(pa_memchunk *c, pa_mempool *pool, unsigned rate, unsigned freq) {$/;"   f
-pa_memchunk_will_need  memchunk.c      /^pa_memchunk *pa_memchunk_will_need(const pa_memchunk *c) {$/;"        f
-pa_memexport   memblock.c      /^struct pa_memexport {$/;"     s       file:
-pa_memexport   memblock.h      /^typedef struct pa_memexport pa_memexport;$/;" t       typeref:struct:pa_memexport
-pa_memexport_free      memblock.c      /^void pa_memexport_free(pa_memexport *e) {$/;" f
-pa_memexport_new       memblock.c      /^pa_memexport* pa_memexport_new(pa_mempool *p, pa_memexport_revoke_cb_t cb, void *userdata) {$/;"      f
-pa_memexport_process_release   memblock.c      /^int pa_memexport_process_release(pa_memexport *e, uint32_t id) {$/;"  f
-pa_memexport_put       memblock.c      /^int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32_t *shm_id, size_t *offset, size_t * size) {$/;"      f
-pa_memexport_revoke_cb_t       memblock.h      /^typedef void (*pa_memexport_revoke_cb_t)(pa_memexport *e, uint32_t block_id, void *userdata);$/;"     t
-pa_memimport   memblock.c      /^struct pa_memimport {$/;"     s       file:
-pa_memimport   memblock.h      /^typedef struct pa_memimport pa_memimport;$/;" t       typeref:struct:pa_memimport
-pa_memimport_free      memblock.c      /^void pa_memimport_free(pa_memimport *i) {$/;" f
-pa_memimport_get       memblock.c      /^pa_memblock* pa_memimport_get(pa_memimport *i, uint32_t block_id, uint32_t shm_id, size_t offset, size_t size) {$/;"  f
-pa_memimport_new       memblock.c      /^pa_memimport* pa_memimport_new(pa_mempool *p, pa_memimport_release_cb_t cb, void *userdata) {$/;"     f
-pa_memimport_process_revoke    memblock.c      /^int pa_memimport_process_revoke(pa_memimport *i, uint32_t id) {$/;"   f
-pa_memimport_release_cb_t      memblock.h      /^typedef void (*pa_memimport_release_cb_t)(pa_memimport *i, uint32_t block_id, void *userdata);$/;"    t
-pa_memimport_segment   memblock.c      /^struct pa_memimport_segment {$/;"     s       file:
-pa_memimport_segment   memblock.h      /^typedef struct pa_memimport_segment pa_memimport_segment;$/;" t       typeref:struct:pa_memimport_segment
-pa_memory_barrier      atomic.h        /^static inline void pa_memory_barrier(void) {$/;"      f
-pa_mempool     memblock.c      /^struct pa_mempool {$/;"       s       file:
-pa_mempool     memblock.h      /^typedef struct pa_mempool pa_mempool;$/;"     t       typeref:struct:pa_mempool
-pa_mempool_block_size_max      memblock.c      /^size_t pa_mempool_block_size_max(pa_mempool *p) {$/;" f
-pa_mempool_free        memblock.c      /^void pa_mempool_free(pa_mempool *p) {$/;"     f
-pa_mempool_get_shm_id  memblock.c      /^int pa_mempool_get_shm_id(pa_mempool *p, uint32_t *id) {$/;"  f
-pa_mempool_get_stat    memblock.c      /^const pa_mempool_stat* pa_mempool_get_stat(pa_mempool *p) {$/;"       f
-pa_mempool_is_shared   memblock.c      /^pa_bool_t pa_mempool_is_shared(pa_mempool *p) {$/;"   f
-pa_mempool_new memblock.c      /^pa_mempool* pa_mempool_new(pa_bool_t shared, size_t size) {$/;"       f
-pa_mempool_stat        memblock.h      /^struct pa_mempool_stat {$/;"  s
-pa_mempool_stat        memblock.h      /^typedef struct pa_mempool_stat pa_mempool_stat;$/;"   t       typeref:struct:pa_mempool_stat
-pa_mempool_vacuum      memblock.c      /^void pa_mempool_vacuum(pa_mempool *p) {$/;"   f
-pa_memtrap     memtrap.c       /^struct pa_memtrap {$/;"       s       file:
-pa_memtrap     memtrap.h       /^typedef struct pa_memtrap pa_memtrap;$/;"     t       typeref:struct:pa_memtrap
-pa_memtrap_add memtrap.c       /^pa_memtrap* pa_memtrap_add(const void *start, size_t size) {$/;"      f
-pa_memtrap_install     memtrap.c       /^void pa_memtrap_install(void) {$/;"   f
-pa_memtrap_is_good     memtrap.c       /^pa_bool_t pa_memtrap_is_good(pa_memtrap *m) {$/;"     f
-pa_memtrap_remove      memtrap.c       /^void pa_memtrap_remove(pa_memtrap *m) {$/;"   f
-pa_memtrap_update      memtrap.c       /^pa_memtrap *pa_memtrap_update(pa_memtrap *m, const void *start, size_t size) {$/;"    f
-pa_memzero     macro.h 304;"   d
-pa_mix sample-util.c   /^size_t pa_mix($/;"    f
-pa_mix_info    sample-util.h   /^typedef struct pa_mix_info {$/;"      s
-pa_mix_info    sample-util.h   /^} pa_mix_info;$/;"    t       typeref:struct:pa_mix_info
-pa_modargs     modargs.h       /^typedef struct pa_modargs pa_modargs;$/;"     t       typeref:struct:pa_modargs
-pa_modargs_free        modargs.c       /^void pa_modargs_free(pa_modargs*ma) {$/;"     f
-pa_modargs_get_channel_map     modargs.c       /^int pa_modargs_get_channel_map(pa_modargs *ma, const char *name, pa_channel_map *rmap) {$/;"  f
-pa_modargs_get_proplist        modargs.c       /^int pa_modargs_get_proplist(pa_modargs *ma, const char *name, pa_proplist *p, pa_update_mode_t m) {$/;"       f
-pa_modargs_get_sample_spec     modargs.c       /^int pa_modargs_get_sample_spec(pa_modargs *ma, pa_sample_spec *rss) {$/;"     f
-pa_modargs_get_sample_spec_and_channel_map     modargs.c       /^int pa_modargs_get_sample_spec_and_channel_map($/;"   f
-pa_modargs_get_value   modargs.c       /^const char *pa_modargs_get_value(pa_modargs *ma, const char *key, const char *def) {$/;"      f
-pa_modargs_get_value_boolean   modargs.c       /^int pa_modargs_get_value_boolean(pa_modargs *ma, const char *key, pa_bool_t *value) {$/;"     f
-pa_modargs_get_value_s32       modargs.c       /^int pa_modargs_get_value_s32(pa_modargs *ma, const char *key, int32_t *value) {$/;"   f
-pa_modargs_get_value_u32       modargs.c       /^int pa_modargs_get_value_u32(pa_modargs *ma, const char *key, uint32_t *value) {$/;"  f
-pa_modargs_new modargs.c       /^pa_modargs *pa_modargs_new(const char *args, const char* const* valid_keys) {$/;"     f
-pa_modinfo     modinfo.h       /^typedef struct pa_modinfo {$/;"       s
-pa_modinfo     modinfo.h       /^} pa_modinfo;$/;"     t       typeref:struct:pa_modinfo
-pa_modinfo_free        modinfo.c       /^void pa_modinfo_free(pa_modinfo *i) {$/;"     f
-pa_modinfo_get_by_handle       modinfo.c       /^pa_modinfo *pa_modinfo_get_by_handle(lt_dlhandle dl, const char *module_name) {$/;"   f
-pa_modinfo_get_by_name modinfo.c       /^pa_modinfo *pa_modinfo_get_by_name(const char *name) {$/;"    f
-pa_module      module.h        /^struct pa_module {$/;"        s
-pa_module      module.h        /^typedef struct pa_module pa_module;$/;"       t       typeref:struct:pa_module
-pa_module_free module.c        /^static void pa_module_free(pa_module *m) {$/;"        f       file:
-pa_module_get_n_used   module.c        /^int pa_module_get_n_used(pa_module*m) {$/;"   f
-pa_module_list_to_string       cli-text.c      /^char *pa_module_list_to_string(pa_core *c) {$/;"      f
-pa_module_load module.c        /^pa_module* pa_module_load(pa_core *c, const char *name, const char *argument) {$/;"   f
-pa_module_unload       module.c        /^void pa_module_unload(pa_core *c, pa_module *m, pa_bool_t force) {$/;"        f
-pa_module_unload_all   module.c        /^void pa_module_unload_all(pa_core *c) {$/;"   f
-pa_module_unload_by_index      module.c        /^void pa_module_unload_by_index(pa_core *c, uint32_t idx, pa_bool_t force) {$/;"       f
-pa_module_unload_request       module.c        /^void pa_module_unload_request(pa_module *m, pa_bool_t force) {$/;"    f
-pa_module_unload_request_by_index      module.c        /^void pa_module_unload_request_by_index(pa_core *c, uint32_t idx, pa_bool_t force) {$/;"       f
-pa_msgobject   msgobject.h     /^PA_DECLARE_PUBLIC_CLASS(pa_msgobject);$/;"    v
-pa_msgobject   msgobject.h     /^struct pa_msgobject {$/;"     s
-pa_msgobject   msgobject.h     /^typedef struct pa_msgobject pa_msgobject;$/;" t       typeref:struct:pa_msgobject
-pa_msgobject_free      msgobject.h     44;"    d
-pa_msgobject_new       msgobject.h     43;"    d
-pa_msgobject_new_internal      msgobject.c     /^pa_msgobject *pa_msgobject_new_internal(size_t size, const char *type_id, pa_bool_t (*check_type)(const char *type_name)) {$/;"       f
-pa_mutex       mutex-posix.c   /^struct pa_mutex {$/;" s       file:
-pa_mutex       mutex-win32.c   /^struct pa_mutex {$/;" s       file:
-pa_mutex       mutex.h /^typedef struct pa_mutex pa_mutex;$/;" t       typeref:struct:pa_mutex
-pa_mutex_free  mutex-posix.c   /^void pa_mutex_free(pa_mutex *m) {$/;" f
-pa_mutex_free  mutex-win32.c   /^void pa_mutex_free(pa_mutex *m) {$/;" f
-pa_mutex_lock  mutex-posix.c   /^void pa_mutex_lock(pa_mutex *m) {$/;" f
-pa_mutex_lock  mutex-win32.c   /^void pa_mutex_lock(pa_mutex *m) {$/;" f
-pa_mutex_new   mutex-posix.c   /^pa_mutex* pa_mutex_new(pa_bool_t recursive, pa_bool_t inherit_priority) {$/;" f
-pa_mutex_new   mutex-win32.c   /^pa_mutex* pa_mutex_new(pa_bool_t recursive, pa_bool_t inherit_priority) {$/;" f
-pa_mutex_try_lock      mutex-posix.c   /^pa_bool_t pa_mutex_try_lock(pa_mutex *m) {$/;"        f
-pa_mutex_unlock        mutex-posix.c   /^void pa_mutex_unlock(pa_mutex *m) {$/;"       f
-pa_mutex_unlock        mutex-win32.c   /^void pa_mutex_unlock(pa_mutex *m) {$/;"       f
-pa_namereg_get namereg.c       /^void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type) {$/;"      f
-pa_namereg_get_default_sink    namereg.c       /^pa_sink *pa_namereg_get_default_sink(pa_core *c) {$/;"        f
-pa_namereg_get_default_source  namereg.c       /^pa_source *pa_namereg_get_default_source(pa_core *c) {$/;"    f
-pa_namereg_is_valid_name       namereg.c       /^pa_bool_t pa_namereg_is_valid_name(const char *name) {$/;"    f
-pa_namereg_is_valid_name_or_wildcard   namereg.c       /^pa_bool_t pa_namereg_is_valid_name_or_wildcard(const char *name, pa_namereg_type_t type) {$/;"        f
-pa_namereg_make_valid_name     namereg.c       /^char* pa_namereg_make_valid_name(const char *name) {$/;"      f
-pa_namereg_register    namereg.c       /^const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t type, void *data, pa_bool_t fail) {$/;"       f
-pa_namereg_set_default_sink    namereg.c       /^pa_sink* pa_namereg_set_default_sink(pa_core*c, pa_sink *s) {$/;"     f
-pa_namereg_set_default_source  namereg.c       /^pa_source* pa_namereg_set_default_source(pa_core*c, pa_source *s) {$/;"       f
-pa_namereg_type        namereg.h       /^typedef enum pa_namereg_type {$/;"    g
-pa_namereg_type_t      namereg.h       /^} pa_namereg_type_t;$/;"      t       typeref:enum:pa_namereg_type
-pa_namereg_unregister  namereg.c       /^void pa_namereg_unregister(pa_core *c, const char *name) {$/;"        f
-pa_native_connection   protocol-native.c       /^struct pa_native_connection {$/;"     s       file:
-pa_native_connection   protocol-native.h       /^typedef struct pa_native_connection pa_native_connection;$/;" t       typeref:struct:pa_native_connection
-pa_native_connection_get_client        protocol-native.c       /^pa_client* pa_native_connection_get_client(pa_native_connection *c) {$/;"     f
-pa_native_connection_get_pstream       protocol-native.c       /^pa_pstream* pa_native_connection_get_pstream(pa_native_connection *c) {$/;"   f
-pa_native_hook protocol-native.h       /^typedef enum pa_native_hook {$/;"     g
-pa_native_hook_t       protocol-native.h       /^} pa_native_hook_t;$/;"       t       typeref:enum:pa_native_hook
-pa_native_options      protocol-native.h       /^typedef struct pa_native_options {$/;"        s
-pa_native_options      protocol-native.h       /^} pa_native_options;$/;"      t       typeref:struct:pa_native_options
-pa_native_options_new  protocol-native.c       /^pa_native_options* pa_native_options_new(void) {$/;"  f
-pa_native_options_parse        protocol-native.c       /^int pa_native_options_parse(pa_native_options *o, pa_core *c, pa_modargs *ma) {$/;"   f
-pa_native_options_ref  protocol-native.c       /^pa_native_options* pa_native_options_ref(pa_native_options *o) {$/;"  f
-pa_native_options_unref        protocol-native.c       /^void pa_native_options_unref(pa_native_options *o) {$/;"      f
-pa_native_protocol     protocol-native.c       /^struct pa_native_protocol {$/;"       s       file:
-pa_native_protocol     protocol-native.h       /^typedef struct pa_native_protocol pa_native_protocol;$/;"     t       typeref:struct:pa_native_protocol
-pa_native_protocol_add_server_string   protocol-native.c       /^void pa_native_protocol_add_server_string(pa_native_protocol *p, const char *name) {$/;"      f
-pa_native_protocol_connect     protocol-native.c       /^void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_native_options *o) {$/;"  f
-pa_native_protocol_disconnect  protocol-native.c       /^void pa_native_protocol_disconnect(pa_native_protocol *p, pa_module *m) {$/;" f
-pa_native_protocol_ext_cb_t    protocol-native.h       /^typedef int (*pa_native_protocol_ext_cb_t)($/;"       t
-pa_native_protocol_get protocol-native.c       /^pa_native_protocol* pa_native_protocol_get(pa_core *c) {$/;"  f
-pa_native_protocol_hooks       protocol-native.c       /^pa_hook *pa_native_protocol_hooks(pa_native_protocol *p) {$/;"        f
-pa_native_protocol_install_ext protocol-native.c       /^int pa_native_protocol_install_ext(pa_native_protocol *p, pa_module *m, pa_native_protocol_ext_cb_t cb) {$/;" f
-pa_native_protocol_ref protocol-native.c       /^pa_native_protocol* pa_native_protocol_ref(pa_native_protocol *p) {$/;"       f
-pa_native_protocol_remove_ext  protocol-native.c       /^void pa_native_protocol_remove_ext(pa_native_protocol *p, pa_module *m) {$/;" f
-pa_native_protocol_remove_server_string        protocol-native.c       /^void pa_native_protocol_remove_server_string(pa_native_protocol *p, const char *name) {$/;"   f
-pa_native_protocol_servers     protocol-native.c       /^pa_strlist *pa_native_protocol_servers(pa_native_protocol *p) {$/;"   f
-pa_native_protocol_unref       protocol-native.c       /^void pa_native_protocol_unref(pa_native_protocol *p) {$/;"    f
-pa_ncpus       core-util.c     /^unsigned pa_ncpus(void) {$/;" f
-pa_nop macro.h 227;"   d
-pa_object      object.h        /^struct pa_object {$/;"        s
-pa_object      object.h        /^typedef struct pa_object pa_object;$/;"       t       typeref:struct:pa_object
-pa_object_assert_ref   object.h        69;"    d
-pa_object_cast object.h        /^static inline pa_object* pa_object_cast(void *o) {$/;"        f
-pa_object_check_type   object.c        /^pa_bool_t pa_object_check_type(const char *type_id) {$/;"     f
-pa_object_free object.h        45;"    d
-pa_object_isinstance   object.h        /^static inline pa_bool_t pa_object_isinstance(void *o) {$/;"   f
-pa_object_new  object.h        43;"    d
-pa_object_new_internal object.c        /^pa_object *pa_object_new_internal(size_t size, const char *type_id, pa_bool_t (*check_type)(const char *type_id)) {$/;"       f
-pa_object_ref  object.c        /^pa_object *pa_object_ref(pa_object *o) {$/;"  f
-pa_object_refcnt       object.h        /^static inline int pa_object_refcnt(pa_object *o) {$/;"        f
-pa_object_type_id      object.c        /^const char pa_object_type_id[] = "pa_object";$/;"     v
-pa_object_unref        object.c        /^void pa_object_unref(pa_object *o) {$/;"      f
-pa_once        once.h  /^typedef struct pa_once {$/;"  s
-pa_once        once.h  /^} pa_once;$/;"        t       typeref:struct:pa_once
-pa_once_begin  once.c  /^pa_bool_t pa_once_begin(pa_once *control) {$/;"       f
-pa_once_end    once.c  /^void pa_once_end(pa_once *control) {$/;"      f
-pa_once_func_t once.h  /^typedef void (*pa_once_func_t) (void);$/;"    t
-pa_open_config_file    core-util.c     /^FILE *pa_open_config_file(const char *global, const char *local, const char *env, char **result) {$/;"        f
-pa_own_uid_in_group    core-util.c     /^int pa_own_uid_in_group(const char *name, gid_t *gid) {$/;"   f
-pa_packet      packet.h        /^typedef struct pa_packet {$/;"        s
-pa_packet      packet.h        /^} pa_packet;$/;"      t       typeref:struct:pa_packet
-pa_packet_new  packet.c        /^pa_packet* pa_packet_new(size_t length) {$/;" f
-pa_packet_new_dynamic  packet.c        /^pa_packet* pa_packet_new_dynamic(void* data, size_t length) {$/;"     f
-pa_packet_ref  packet.c        /^pa_packet* pa_packet_ref(pa_packet *p) {$/;"  f
-pa_packet_unref        packet.c        /^void pa_packet_unref(pa_packet *p) {$/;"      f
-pa_parent_dir  core-util.c     /^char *pa_parent_dir(const char *fn) {$/;"     f
-pa_parse_address       parseaddr.c     /^int pa_parse_address(const char *name, pa_parsed_address *ret_p) {$/;"        f
-pa_parse_boolean       core-util.c     /^int pa_parse_boolean(const char *v) {$/;"     f
-pa_parse_resample_method       resampler.c     /^pa_resample_method_t pa_parse_resample_method(const char *string) {$/;"       f
-pa_parsed_address      parseaddr.h     /^typedef struct pa_parsed_address {$/;"        s
-pa_parsed_address      parseaddr.h     /^} pa_parsed_address;$/;"      t       typeref:struct:pa_parsed_address
-pa_parsed_address_type parseaddr.h     /^typedef enum pa_parsed_address_type {$/;"     g
-pa_parsed_address_type_t       parseaddr.h     /^} pa_parsed_address_type_t;$/;"       t       typeref:enum:pa_parsed_address_type
-pa_parsehex    core-util.c     /^size_t pa_parsehex(const char *p, uint8_t *d, size_t dlength) {$/;"   f
-pa_pdispatch   pdispatch.c     /^struct pa_pdispatch {$/;"     s       file:
-pa_pdispatch   pdispatch.h     /^typedef struct pa_pdispatch pa_pdispatch;$/;" t       typeref:struct:pa_pdispatch
-pa_pdispatch_cb_t      pdispatch.h     /^typedef void (*pa_pdispatch_cb_t)(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);$/;"     t
-pa_pdispatch_creds     pdispatch.c     /^const pa_creds * pa_pdispatch_creds(pa_pdispatch *pd) {$/;"   f
-pa_pdispatch_drain_cb_t        pdispatch.h     /^typedef void (*pa_pdispatch_drain_cb_t)(pa_pdispatch *pd, void *userdata);$/;"        t
-pa_pdispatch_is_pending        pdispatch.c     /^int pa_pdispatch_is_pending(pa_pdispatch *pd) {$/;"   f
-pa_pdispatch_new       pdispatch.c     /^pa_pdispatch* pa_pdispatch_new(pa_mainloop_api *mainloop, pa_bool_t use_rtclock, const pa_pdispatch_cb_t *table, unsigned entries) {$/;"      f
-pa_pdispatch_ref       pdispatch.c     /^pa_pdispatch* pa_pdispatch_ref(pa_pdispatch *pd) {$/;"        f
-pa_pdispatch_register_reply    pdispatch.c     /^void pa_pdispatch_register_reply(pa_pdispatch *pd, uint32_t tag, int timeout, pa_pdispatch_cb_t cb, void *userdata, pa_free_cb_t free_cb) {$/;"       f
-pa_pdispatch_run       pdispatch.c     /^int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, const pa_creds *creds, void *userdata) {$/;" f
-pa_pdispatch_set_drain_callback        pdispatch.c     /^void pa_pdispatch_set_drain_callback(pa_pdispatch *pd, pa_pdispatch_drain_cb_t cb, void *userdata) {$/;"      f
-pa_pdispatch_unref     pdispatch.c     /^void pa_pdispatch_unref(pa_pdispatch *pd) {$/;"       f
-pa_pdispatch_unregister_reply  pdispatch.c     /^void pa_pdispatch_unregister_reply(pa_pdispatch *pd, void *userdata) {$/;"    f
-pa_pid_file_check_running      pid.c   /^int pa_pid_file_check_running(pid_t *pid, const char *procname) {$/;" f
-pa_pid_file_create     pid.c   /^int pa_pid_file_create(const char *procname) {$/;"    f
-pa_pid_file_kill       pid.c   /^int pa_pid_file_kill(int sig, pid_t *pid, const char *exe_name) {$/;" f
-pa_pid_file_kill       pid.c   /^int pa_pid_file_kill(int sig, pid_t *pid, const char *procname) {$/;" f
-pa_pid_file_remove     pid.c   /^int pa_pid_file_remove(void) {$/;"    f
-pa_pipe_buf    core-util.c     /^size_t pa_pipe_buf(int fd) {$/;"      f
-pa_play_file   sound-file-stream.c     /^int pa_play_file($/;" f
-pa_play_memblockq      play-memblockq.c        /^int pa_play_memblockq($/;"    f
-pa_play_memchunk       play-memchunk.c /^int pa_play_memchunk($/;"     f
-pa_prioq       prioq.c /^struct pa_prioq {$/;" s       file:
-pa_prioq       prioq.h /^typedef struct pa_prioq pa_prioq;$/;" t       typeref:struct:pa_prioq
-pa_prioq_free  prioq.c /^void pa_prioq_free(pa_prioq *q, pa_free2_cb_t free_cb, void *userdata) {$/;"  f
-pa_prioq_isempty       prioq.c /^pa_bool_t pa_prioq_isempty(pa_prioq *q) {$/;" f
-pa_prioq_item  prioq.c /^struct pa_prioq_item {$/;"    s       file:
-pa_prioq_item  prioq.h /^typedef struct pa_prioq_item pa_prioq_item;$/;"       t       typeref:struct:pa_prioq_item
-pa_prioq_new   prioq.c /^pa_prioq *pa_prioq_new(pa_compare_func_t compare_func) {$/;"  f
-pa_prioq_peek  prioq.c /^void* pa_prioq_peek(pa_prioq *q) {$/;"        f
-pa_prioq_pop   prioq.c /^void* pa_prioq_pop(pa_prioq *q){$/;"  f
-pa_prioq_put   prioq.c /^pa_prioq_item* pa_prioq_put(pa_prioq *q, void *p) {$/;"       f
-pa_prioq_remove        prioq.c /^void* pa_prioq_remove(pa_prioq *q, pa_prioq_item *i) {$/;"    f
-pa_prioq_reshuffle     prioq.c /^void pa_prioq_reshuffle(pa_prioq *q, pa_prioq_item *i) {$/;"  f
-pa_prioq_size  prioq.c /^unsigned pa_prioq_size(pa_prioq *q) {$/;"     f
-pa_pstream     pstream.c       /^struct pa_pstream {$/;"       s       file:
-pa_pstream     pstream.h       /^typedef struct pa_pstream pa_pstream;$/;"     t       typeref:struct:pa_pstream
-pa_pstream_block_id_cb_t       pstream.h       /^typedef void (*pa_pstream_block_id_cb_t)(pa_pstream *p, uint32_t block_id, void *userdata);$/;"       t
-pa_pstream_descriptor  pstream.c       /^typedef uint32_t pa_pstream_descriptor[PA_PSTREAM_DESCRIPTOR_MAX];$/;"        t       file:
-pa_pstream_enable_shm  pstream.c       /^void pa_pstream_enable_shm(pa_pstream *p, pa_bool_t enable) {$/;"     f
-pa_pstream_get_shm     pstream.c       /^pa_bool_t pa_pstream_get_shm(pa_pstream *p) {$/;"     f
-pa_pstream_is_pending  pstream.c       /^pa_bool_t pa_pstream_is_pending(pa_pstream *p) {$/;"  f
-pa_pstream_memblock_cb_t       pstream.h       /^typedef void (*pa_pstream_memblock_cb_t)(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata);$/;" t
-pa_pstream_new pstream.c       /^pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *pool) {$/;"      f
-pa_pstream_notify_cb_t pstream.h       /^typedef void (*pa_pstream_notify_cb_t)(pa_pstream *p, void *userdata);$/;"    t
-pa_pstream_packet_cb_t pstream.h       /^typedef void (*pa_pstream_packet_cb_t)(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata);$/;"  t
-pa_pstream_ref pstream.c       /^pa_pstream* pa_pstream_ref(pa_pstream*p) {$/;"        f
-pa_pstream_send_error  pstream-util.c  /^void pa_pstream_send_error(pa_pstream *p, uint32_t tag, uint32_t error) {$/;" f
-pa_pstream_send_memblock       pstream.c       /^void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa_seek_mode_t seek_mode, const pa_memchunk *chunk) {$/;"       f
-pa_pstream_send_packet pstream.c       /^void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_creds *creds) {$/;"     f
-pa_pstream_send_release        pstream.c       /^void pa_pstream_send_release(pa_pstream *p, uint32_t block_id) {$/;"  f
-pa_pstream_send_revoke pstream.c       /^void pa_pstream_send_revoke(pa_pstream *p, uint32_t block_id) {$/;"   f
-pa_pstream_send_simple_ack     pstream-util.c  /^void pa_pstream_send_simple_ack(pa_pstream *p, uint32_t tag) {$/;"    f
-pa_pstream_send_tagstruct      pstream-util.h  33;"    d
-pa_pstream_send_tagstruct_with_creds   pstream-util.c  /^void pa_pstream_send_tagstruct_with_creds(pa_pstream *p, pa_tagstruct *t, const pa_creds *creds) {$/;"        f
-pa_pstream_set_die_callback    pstream.c       /^void pa_pstream_set_die_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata) {$/;"      f
-pa_pstream_set_drain_callback  pstream.c       /^void pa_pstream_set_drain_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata) {$/;"    f
-pa_pstream_set_recieve_memblock_callback       pstream.c       /^void pa_pstream_set_recieve_memblock_callback(pa_pstream *p, pa_pstream_memblock_cb_t cb, void *userdata) {$/;"       f
-pa_pstream_set_recieve_packet_callback pstream.c       /^void pa_pstream_set_recieve_packet_callback(pa_pstream *p, pa_pstream_packet_cb_t cb, void *userdata) {$/;"   f
-pa_pstream_set_release_callback        pstream.c       /^void pa_pstream_set_release_callback(pa_pstream *p, pa_pstream_block_id_cb_t cb, void *userdata) {$/;"        f
-pa_pstream_set_revoke_callback pstream.c       /^void pa_pstream_set_revoke_callback(pa_pstream *p, pa_pstream_block_id_cb_t cb, void *userdata) {$/;" f
-pa_pstream_unlink      pstream.c       /^void pa_pstream_unlink(pa_pstream *p) {$/;"   f
-pa_pstream_unref       pstream.c       /^void pa_pstream_unref(pa_pstream*p) {$/;"     f
-pa_queue       queue.c /^struct pa_queue {$/;" s       file:
-pa_queue       queue.h /^typedef struct pa_queue pa_queue;$/;" t       typeref:struct:pa_queue
-pa_queue_free  queue.c /^void pa_queue_free(pa_queue* q, pa_free2_cb_t free_func, void *userdata) {$/;"        f
-pa_queue_isempty       queue.c /^int pa_queue_isempty(pa_queue *q) {$/;"       f
-pa_queue_new   queue.c /^pa_queue* pa_queue_new(void) {$/;"    f
-pa_queue_pop   queue.c /^void* pa_queue_pop(pa_queue *q) {$/;" f
-pa_queue_push  queue.c /^void pa_queue_push(pa_queue *q, void *p) {$/;"        f
-pa_raise_priority      core-util.c     /^int pa_raise_priority(int nice_level) {$/;"   f
-pa_random      random.c        /^void pa_random(void *ret_data, size_t length) {$/;"   f
-pa_random_seed random.c        /^void pa_random_seed(void) {$/;"       f
-pa_ratelimit   ratelimit.h     /^typedef struct pa_ratelimit {$/;"     s
-pa_ratelimit   ratelimit.h     /^} pa_ratelimit;$/;"   t       typeref:struct:pa_ratelimit
-pa_ratelimit_test      ratelimit.c     /^pa_bool_t pa_ratelimit_test(pa_ratelimit *r) {$/;"    f
-pa_read        core-util.c     /^ssize_t pa_read(int fd, void *buf, size_t count, int *type) {$/;"     f
-pa_read_line_from_file core-util.c     /^char *pa_read_line_from_file(const char *fn) {$/;"    f
-pa_readlink    core-util.c     /^char *pa_readlink(const char *p) {$/;"        f
-pa_realpath    core-util.c     /^char *pa_realpath(const char *path) {$/;"     f
-pa_reduce      core-util.c     /^void pa_reduce(unsigned *num, unsigned *den) {$/;"    f
-pa_reg_x86     cpu-x86.h       /^typedef int32_t pa_reg_x86;$/;"       t
-pa_reg_x86     cpu-x86.h       /^typedef int64_t pa_reg_x86;$/;"       t
-pa_remap       remap.h /^struct pa_remap {$/;" s
-pa_remap_func_init_mmx remap_mmx.c     /^void pa_remap_func_init_mmx (pa_cpu_x86_flag_t flags) {$/;"   f
-pa_remap_func_init_sse remap_sse.c     /^void pa_remap_func_init_sse (pa_cpu_x86_flag_t flags) {$/;"   f
-pa_remap_t     remap.h /^typedef struct pa_remap pa_remap_t;$/;"       t       typeref:struct:pa_remap
-pa_replace     core-util.c     /^char *pa_replace(const char*s, const char*a, const char *b) {$/;"     f
-pa_resample_flags      resampler.h     /^typedef enum pa_resample_flags {$/;"  g
-pa_resample_flags_t    resampler.h     /^} pa_resample_flags_t;$/;"    t       typeref:enum:pa_resample_flags
-pa_resample_method     resampler.h     /^typedef enum pa_resample_method {$/;" g
-pa_resample_method_supported   resampler.c     /^int pa_resample_method_supported(pa_resample_method_t m) {$/;"        f
-pa_resample_method_t   resampler.h     /^} pa_resample_method_t;$/;"   t       typeref:enum:pa_resample_method
-pa_resample_method_to_string   resampler.c     /^const char *pa_resample_method_to_string(pa_resample_method_t m) {$/;"        f
-pa_resampler   resampler.c     /^struct pa_resampler {$/;"     s       file:
-pa_resampler   resampler.h     /^typedef struct pa_resampler pa_resampler;$/;" t       typeref:struct:pa_resampler
-pa_resampler_free      resampler.c     /^void pa_resampler_free(pa_resampler *r) {$/;" f
-pa_resampler_get_method        resampler.c     /^pa_resample_method_t pa_resampler_get_method(pa_resampler *r) {$/;"   f
-pa_resampler_input_channel_map resampler.c     /^const pa_channel_map* pa_resampler_input_channel_map(pa_resampler *r) {$/;"   f
-pa_resampler_input_sample_spec resampler.c     /^const pa_sample_spec* pa_resampler_input_sample_spec(pa_resampler *r) {$/;"   f
-pa_resampler_max_block_size    resampler.c     /^size_t pa_resampler_max_block_size(pa_resampler *r) {$/;"     f
-pa_resampler_new       resampler.c     /^pa_resampler* pa_resampler_new($/;"   f
-pa_resampler_output_channel_map        resampler.c     /^const pa_channel_map* pa_resampler_output_channel_map(pa_resampler *r) {$/;"  f
-pa_resampler_output_sample_spec        resampler.c     /^const pa_sample_spec* pa_resampler_output_sample_spec(pa_resampler *r) {$/;"  f
-pa_resampler_request   resampler.c     /^size_t pa_resampler_request(pa_resampler *r, size_t out_length) {$/;" f
-pa_resampler_reset     resampler.c     /^void pa_resampler_reset(pa_resampler *r) {$/;"        f
-pa_resampler_result    resampler.c     /^size_t pa_resampler_result(pa_resampler *r, size_t in_length) {$/;"   f
-pa_resampler_run       resampler.c     /^void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) {$/;" f
-pa_resampler_set_input_rate    resampler.c     /^void pa_resampler_set_input_rate(pa_resampler *r, uint32_t rate) {$/;"        f
-pa_resampler_set_output_rate   resampler.c     /^void pa_resampler_set_output_rate(pa_resampler *r, uint32_t rate) {$/;"       f
-pa_reset_personality   core-util.c     /^void pa_reset_personality(void) {$/;" f
-pa_reset_priority      core-util.c     /^void pa_reset_priority(void) {$/;"    f
-pa_reset_sigs  core-util.c     /^int pa_reset_sigs(int except, ...) {$/;"      f
-pa_reset_sigsv core-util.c     /^int pa_reset_sigsv(const int except[]) {$/;"  f
-pa_return_if_fail      macro.h 198;"   d
-pa_return_null_if_fail macro.h 214;"   d
-pa_return_val_if_fail  macro.h 206;"   d
-pa_rtclock_age core-rtclock.c  /^pa_usec_t pa_rtclock_age(const struct timeval *tv) {$/;"      f
-pa_rtclock_from_wallclock      core-rtclock.c  /^struct timeval* pa_rtclock_from_wallclock(struct timeval *tv) {$/;"   f
-pa_rtclock_get core-rtclock.c  /^struct timeval *pa_rtclock_get(struct timeval *tv) {$/;"      f
-pa_rtclock_hrtimer     core-rtclock.c  /^pa_bool_t pa_rtclock_hrtimer(void) {$/;"      f
-pa_rtclock_hrtimer_enable      core-rtclock.c  /^void pa_rtclock_hrtimer_enable(void) {$/;"    f
-pa_rtpoll      rtpoll.c        /^struct pa_rtpoll {$/;"        s       file:
-pa_rtpoll      rtpoll.h        /^typedef struct pa_rtpoll pa_rtpoll;$/;"       t       typeref:struct:pa_rtpoll
-pa_rtpoll_free rtpoll.c        /^void pa_rtpoll_free(pa_rtpoll *p) {$/;"       f
-pa_rtpoll_item rtpoll.c        /^struct pa_rtpoll_item {$/;"   s       file:
-pa_rtpoll_item rtpoll.h        /^typedef struct pa_rtpoll_item pa_rtpoll_item;$/;"     t       typeref:struct:pa_rtpoll_item
-pa_rtpoll_item_free    rtpoll.c        /^void pa_rtpoll_item_free(pa_rtpoll_item *i) {$/;"     f
-pa_rtpoll_item_get_pollfd      rtpoll.c        /^struct pollfd *pa_rtpoll_item_get_pollfd(pa_rtpoll_item *i, unsigned *n_fds) {$/;"    f
-pa_rtpoll_item_get_userdata    rtpoll.c        /^void* pa_rtpoll_item_get_userdata(pa_rtpoll_item *i) {$/;"    f
-pa_rtpoll_item_new     rtpoll.c        /^pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, pa_rtpoll_priority_t prio, unsigned n_fds) {$/;"     f
-pa_rtpoll_item_new_asyncmsgq_read      rtpoll.c        /^pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq_read(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_asyncmsgq *q) {$/;"     f
-pa_rtpoll_item_new_asyncmsgq_write     rtpoll.c        /^pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq_write(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_asyncmsgq *q) {$/;"    f
-pa_rtpoll_item_new_fdsem       rtpoll.c        /^pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_fdsem *f) {$/;"  f
-pa_rtpoll_item_set_after_callback      rtpoll.c        /^void pa_rtpoll_item_set_after_callback(pa_rtpoll_item *i, void (*after_cb)(pa_rtpoll_item *i)) {$/;"  f
-pa_rtpoll_item_set_before_callback     rtpoll.c        /^void pa_rtpoll_item_set_before_callback(pa_rtpoll_item *i, int (*before_cb)(pa_rtpoll_item *i)) {$/;" f
-pa_rtpoll_item_set_userdata    rtpoll.c        /^void pa_rtpoll_item_set_userdata(pa_rtpoll_item *i, void *userdata) {$/;"     f
-pa_rtpoll_item_set_work_callback       rtpoll.c        /^void pa_rtpoll_item_set_work_callback(pa_rtpoll_item *i, int (*work_cb)(pa_rtpoll_item *i)) {$/;"     f
-pa_rtpoll_new  rtpoll.c        /^pa_rtpoll *pa_rtpoll_new(void) {$/;"  f
-pa_rtpoll_priority     rtpoll.h        /^typedef enum pa_rtpoll_priority {$/;" g
-pa_rtpoll_priority_t   rtpoll.h        /^} pa_rtpoll_priority_t;$/;"   t       typeref:enum:pa_rtpoll_priority
-pa_rtpoll_quit rtpoll.c        /^void pa_rtpoll_quit(pa_rtpoll *p) {$/;"       f
-pa_rtpoll_run  rtpoll.c        /^int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait_op) {$/;"      f
-pa_rtpoll_set_timer_absolute   rtpoll.c        /^void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, pa_usec_t usec) {$/;" f
-pa_rtpoll_set_timer_disabled   rtpoll.c        /^void pa_rtpoll_set_timer_disabled(pa_rtpoll *p) {$/;" f
-pa_rtpoll_set_timer_relative   rtpoll.c        /^void pa_rtpoll_set_timer_relative(pa_rtpoll *p, pa_usec_t usec) {$/;" f
-pa_rtpoll_timer_elapsed        rtpoll.c        /^pa_bool_t pa_rtpoll_timer_elapsed(pa_rtpoll *p) {$/;" f
-pa_run_from_build_tree core-util.c     /^pa_bool_t pa_run_from_build_tree(void) {$/;"  f
-pa_run_once    once.c  /^void pa_run_once(pa_once *control, pa_once_func_t func) {$/;" f
-pa_running_in_vm       core-util.c     /^pa_bool_t pa_running_in_vm(void) {$/;"        f
-pa_runtime_path        core-util.c     /^char *pa_runtime_path(const char *fn) {$/;"   f
-pa_sample_clamp        sample-util.c   /^void pa_sample_clamp(pa_sample_format_t format, void *dst, size_t dstr, const void *src, size_t sstr, unsigned n) {$/;"       f
-pa_sample_spec_is_mime mime-type.c     /^pa_bool_t pa_sample_spec_is_mime(const pa_sample_spec *ss, const pa_channel_map *cm) {$/;"    f
-pa_sample_spec_mimefy  mime-type.c     /^void pa_sample_spec_mimefy(pa_sample_spec *ss, pa_channel_map *cm) {$/;"      f
-pa_sample_spec_to_mime_type    mime-type.c     /^char *pa_sample_spec_to_mime_type(const pa_sample_spec *ss, const pa_channel_map *cm) {$/;"   f
-pa_sample_spec_to_mime_type_mimefy     mime-type.c     /^char *pa_sample_spec_to_mime_type_mimefy(const pa_sample_spec *_ss, const pa_channel_map *_cm) {$/;"  f
-pa_scache_add_directory_lazy   core-scache.c   /^int pa_scache_add_directory_lazy(pa_core *c, const char *pathname) {$/;"      f
-pa_scache_add_file     core-scache.c   /^int pa_scache_add_file(pa_core *c, const char *name, const char *filename, uint32_t *idx) {$/;"       f
-pa_scache_add_file_lazy        core-scache.c   /^int pa_scache_add_file_lazy(pa_core *c, const char *name, const char *filename, uint32_t *idx) {$/;"  f
-pa_scache_add_item     core-scache.c   /^int pa_scache_add_item($/;"   f
-pa_scache_entry        core-scache.h   /^typedef struct pa_scache_entry {$/;"  s
-pa_scache_entry        core-scache.h   /^} pa_scache_entry;$/;"        t       typeref:struct:pa_scache_entry
-pa_scache_free_all     core-scache.c   /^void pa_scache_free_all(pa_core *c) {$/;"     f
-pa_scache_get_id_by_name       core-scache.c   /^uint32_t pa_scache_get_id_by_name(pa_core *c, const char *name) {$/;" f
-pa_scache_get_name_by_id       core-scache.c   /^const char *pa_scache_get_name_by_id(pa_core *c, uint32_t id) {$/;"   f
-pa_scache_list_to_string       cli-text.c      /^char *pa_scache_list_to_string(pa_core *c) {$/;"      f
-pa_scache_play_item    core-scache.c   /^int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t volume, pa_proplist *p, uint32_t *sink_input_idx) {$/;"      f
-pa_scache_play_item_by_name    core-scache.c   /^int pa_scache_play_item_by_name(pa_core *c, const char *name, const char*sink_name, pa_volume_t volume, pa_proplist *p, uint32_t *sink_input_idx) {$/;"       f
-pa_scache_remove_item  core-scache.c   /^int pa_scache_remove_item(pa_core *c, const char *name) {$/;" f
-pa_scache_total_size   core-scache.c   /^size_t pa_scache_total_size(pa_core *c) {$/;" f
-pa_scache_unload_unused        core-scache.c   /^void pa_scache_unload_unused(pa_core *c) {$/;"        f
-pa_sconv_float32be_from_s16ne  sconv-s16be.h   64;"    d
-pa_sconv_float32be_from_s16ne  sconv-s16le.h   64;"    d
-pa_sconv_float32be_to_s16ne    sconv-s16be.h   63;"    d
-pa_sconv_float32be_to_s16ne    sconv-s16le.h   63;"    d
-pa_sconv_float32le_from_s16ne  sconv-s16be.h   66;"    d
-pa_sconv_float32le_from_s16ne  sconv-s16le.h   66;"    d
-pa_sconv_float32le_to_s16ne    sconv-s16be.h   65;"    d
-pa_sconv_float32le_to_s16ne    sconv-s16le.h   65;"    d
-pa_sconv_s16le_from_f32ne_sse  sconv_sse.c     /^static void pa_sconv_s16le_from_f32ne_sse(unsigned n, const float *a, int16_t *b) {$/;"       f       file:
-pa_sconv_s16le_from_f32ne_sse2 sconv_sse.c     /^static void pa_sconv_s16le_from_f32ne_sse2(unsigned n, const float *a, int16_t *b) {$/;"      f       file:
-pa_sconv_s16le_from_float32ne  sconv-s16be.c   42;"    d       file:
-pa_sconv_s16le_from_float32ne  sconv-s16le.c   /^void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) {$/;"      f
-pa_sconv_s16le_from_float32re  sconv-s16be.c   44;"    d       file:
-pa_sconv_s16le_from_float32re  sconv-s16le.c   /^void pa_sconv_s16le_from_float32re(unsigned n, const float *a, int16_t *b) {$/;"      f
-pa_sconv_s16le_to_float32ne    sconv-s16be.c   41;"    d       file:
-pa_sconv_s16le_to_float32ne    sconv-s16le.c   /^void pa_sconv_s16le_to_float32ne(unsigned n, const int16_t *a, float *b) {$/;"        f
-pa_sconv_s16le_to_float32re    sconv-s16be.c   43;"    d       file:
-pa_sconv_s16le_to_float32re    sconv-s16le.c   /^void pa_sconv_s16le_to_float32re(unsigned n, const int16_t *a, float *b) {$/;"        f
-pa_sconv_s24_32le_from_float32ne       sconv-s16be.c   57;"    d       file:
-pa_sconv_s24_32le_from_float32ne       sconv-s16le.c   /^void pa_sconv_s24_32le_from_float32ne(unsigned n, const float *a, uint32_t *b) {$/;"  f
-pa_sconv_s24_32le_from_float32re       sconv-s16be.c   59;"    d       file:
-pa_sconv_s24_32le_from_float32re       sconv-s16le.c   /^void pa_sconv_s24_32le_from_float32re(unsigned n, const float *a, uint32_t *b) {$/;"  f
-pa_sconv_s24_32le_from_s16ne   sconv-s16be.c   72;"    d       file:
-pa_sconv_s24_32le_from_s16ne   sconv-s16le.c   /^void pa_sconv_s24_32le_from_s16ne(unsigned n, const int16_t *a, uint32_t *b) {$/;"    f
-pa_sconv_s24_32le_from_s16re   sconv-s16be.c   74;"    d       file:
-pa_sconv_s24_32le_from_s16re   sconv-s16le.c   /^void pa_sconv_s24_32le_from_s16re(unsigned n, const int16_t *a, uint32_t *b) {$/;"    f
-pa_sconv_s24_32le_to_float32ne sconv-s16be.c   56;"    d       file:
-pa_sconv_s24_32le_to_float32ne sconv-s16le.c   /^void pa_sconv_s24_32le_to_float32ne(unsigned n, const uint32_t *a, float *b) {$/;"    f
-pa_sconv_s24_32le_to_float32re sconv-s16be.c   58;"    d       file:
-pa_sconv_s24_32le_to_float32re sconv-s16le.c   /^void pa_sconv_s24_32le_to_float32re(unsigned n, const uint32_t *a, float *b) {$/;"    f
-pa_sconv_s24_32le_to_s16ne     sconv-s16be.c   71;"    d       file:
-pa_sconv_s24_32le_to_s16ne     sconv-s16le.c   /^void pa_sconv_s24_32le_to_s16ne(unsigned n, const uint32_t *a, int16_t *b) {$/;"      f
-pa_sconv_s24_32le_to_s16re     sconv-s16be.c   73;"    d       file:
-pa_sconv_s24_32le_to_s16re     sconv-s16le.c   /^void pa_sconv_s24_32le_to_s16re(unsigned n, const uint32_t *a, int16_t *b) {$/;"      f
-pa_sconv_s24le_from_float32ne  sconv-s16be.c   52;"    d       file:
-pa_sconv_s24le_from_float32ne  sconv-s16le.c   /^void pa_sconv_s24le_from_float32ne(unsigned n, const float *a, uint8_t *b) {$/;"      f
-pa_sconv_s24le_from_float32re  sconv-s16be.c   54;"    d       file:
-pa_sconv_s24le_from_float32re  sconv-s16le.c   /^void pa_sconv_s24le_from_float32re(unsigned n, const float *a, uint8_t *b) {$/;"      f
-pa_sconv_s24le_from_s16ne      sconv-s16be.c   67;"    d       file:
-pa_sconv_s24le_from_s16ne      sconv-s16le.c   /^void pa_sconv_s24le_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) {$/;"        f
-pa_sconv_s24le_from_s16re      sconv-s16be.c   69;"    d       file:
-pa_sconv_s24le_from_s16re      sconv-s16le.c   /^void pa_sconv_s24le_from_s16re(unsigned n, const int16_t *a, uint8_t *b) {$/;"        f
-pa_sconv_s24le_to_float32ne    sconv-s16be.c   51;"    d       file:
-pa_sconv_s24le_to_float32ne    sconv-s16le.c   /^void pa_sconv_s24le_to_float32ne(unsigned n, const uint8_t *a, float *b) {$/;"        f
-pa_sconv_s24le_to_float32re    sconv-s16be.c   53;"    d       file:
-pa_sconv_s24le_to_float32re    sconv-s16le.c   /^void pa_sconv_s24le_to_float32re(unsigned n, const uint8_t *a, float *b) {$/;"        f
-pa_sconv_s24le_to_s16ne        sconv-s16be.c   66;"    d       file:
-pa_sconv_s24le_to_s16ne        sconv-s16le.c   /^void pa_sconv_s24le_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) {$/;"  f
-pa_sconv_s24le_to_s16re        sconv-s16be.c   68;"    d       file:
-pa_sconv_s24le_to_s16re        sconv-s16le.c   /^void pa_sconv_s24le_to_s16re(unsigned n, const uint8_t *a, int16_t *b) {$/;"  f
-pa_sconv_s32le_from_float32ne  sconv-s16be.c   47;"    d       file:
-pa_sconv_s32le_from_float32ne  sconv-s16le.c   /^void pa_sconv_s32le_from_float32ne(unsigned n, const float *a, int32_t *b) {$/;"      f
-pa_sconv_s32le_from_float32re  sconv-s16be.c   49;"    d       file:
-pa_sconv_s32le_from_float32re  sconv-s16le.c   /^void pa_sconv_s32le_from_float32re(unsigned n, const float *a, int32_t *b) {$/;"      f
-pa_sconv_s32le_from_s16ne      sconv-s16be.c   62;"    d       file:
-pa_sconv_s32le_from_s16ne      sconv-s16le.c   /^void pa_sconv_s32le_from_s16ne(unsigned n, const int16_t *a, int32_t *b) {$/;"        f
-pa_sconv_s32le_from_s16re      sconv-s16be.c   64;"    d       file:
-pa_sconv_s32le_from_s16re      sconv-s16le.c   /^void pa_sconv_s32le_from_s16re(unsigned n, const int16_t *a, int32_t *b) {$/;"        f
-pa_sconv_s32le_to_float32ne    sconv-s16be.c   46;"    d       file:
-pa_sconv_s32le_to_float32ne    sconv-s16le.c   /^void pa_sconv_s32le_to_float32ne(unsigned n, const int32_t *a, float *b) {$/;"        f
-pa_sconv_s32le_to_float32re    sconv-s16be.c   48;"    d       file:
-pa_sconv_s32le_to_float32re    sconv-s16le.c   /^void pa_sconv_s32le_to_float32re(unsigned n, const int32_t *a, float *b) {$/;"        f
-pa_sconv_s32le_to_s16ne        sconv-s16be.c   61;"    d       file:
-pa_sconv_s32le_to_s16ne        sconv-s16le.c   /^void pa_sconv_s32le_to_s16ne(unsigned n, const int32_t*a, int16_t *b) {$/;"   f
-pa_sconv_s32le_to_s16re        sconv-s16be.c   63;"    d       file:
-pa_sconv_s32le_to_s16re        sconv-s16le.c   /^void pa_sconv_s32le_to_s16re(unsigned n, const int32_t*a, int16_t *b) {$/;"   f
-pa_semaphore   semaphore-posix.c       /^struct pa_semaphore {$/;"     s       file:
-pa_semaphore   semaphore-win32.c       /^struct pa_semaphore$/;"       s       file:
-pa_semaphore   semaphore.h     /^typedef struct pa_semaphore pa_semaphore;$/;" t       typeref:struct:pa_semaphore
-pa_semaphore_free      semaphore-posix.c       /^void pa_semaphore_free(pa_semaphore *s) {$/;" f
-pa_semaphore_free      semaphore-win32.c       /^void pa_semaphore_free(pa_semaphore *s) {$/;" f
-pa_semaphore_new       semaphore-posix.c       /^pa_semaphore* pa_semaphore_new(unsigned value) {$/;"  f
-pa_semaphore_new       semaphore-win32.c       /^pa_semaphore* pa_semaphore_new(unsigned value) {$/;"  f
-pa_semaphore_post      semaphore-posix.c       /^void pa_semaphore_post(pa_semaphore *s) {$/;" f
-pa_semaphore_post      semaphore-win32.c       /^void pa_semaphore_post(pa_semaphore *s) {$/;" f
-pa_semaphore_wait      semaphore-posix.c       /^void pa_semaphore_wait(pa_semaphore *s) {$/;" f
-pa_semaphore_wait      semaphore-win32.c       /^void pa_semaphore_wait(pa_semaphore *s) {$/;" f
-pa_session_id  core-util.c     /^char *pa_session_id(void) {$/;"       f
-pa_set_convert_from_float32ne_function sconv.c /^void pa_set_convert_from_float32ne_function(pa_sample_format_t f, pa_convert_func_t func) {$/;"       f
-pa_set_convert_from_s16ne_function     sconv.c /^void pa_set_convert_from_s16ne_function(pa_sample_format_t f, pa_convert_func_t func) {$/;"   f
-pa_set_convert_to_float32ne_function   sconv.c /^void pa_set_convert_to_float32ne_function(pa_sample_format_t f, pa_convert_func_t func) {$/;" f
-pa_set_convert_to_s16ne_function       sconv.c /^void pa_set_convert_to_s16ne_function(pa_sample_format_t f, pa_convert_func_t func) {$/;"     f
-pa_set_env     core-util.c     /^void pa_set_env(const char *key, const char *value) {$/;"     f
-pa_set_env_and_record  core-util.c     /^void pa_set_env_and_record(const char *key, const char *value) {$/;"  f
-pa_set_init_remap_func remap.c /^void pa_set_init_remap_func(pa_init_remap_func_t func) {$/;"  f
-pa_set_root    core-util.c     /^int pa_set_root(HANDLE handle) {$/;"  f
-pa_set_volume_func     svolume_c.c     /^void pa_set_volume_func(pa_sample_format_t f, pa_do_volume_func_t func) {$/;" f
-pa_shared      shared.c        /^typedef struct pa_shared {$/;"        s       file:
-pa_shared      shared.c        /^} pa_shared;$/;"      t       typeref:struct:pa_shared        file:
-pa_shared_dump shared.c        /^void pa_shared_dump(pa_core *c, pa_strbuf *s) {$/;"   f
-pa_shared_get  shared.c        /^void* pa_shared_get(pa_core *c, const char *name) {$/;"       f
-pa_shared_remove       shared.c        /^int pa_shared_remove(pa_core *c, const char *name) {$/;"      f
-pa_shared_replace      shared.c        /^int pa_shared_replace(pa_core *c, const char *name, void *data) {$/;" f
-pa_shared_set  shared.c        /^int pa_shared_set(pa_core *c, const char *name, void *data) {$/;"     f
-pa_shm shm.h   /^typedef struct pa_shm {$/;"   s
-pa_shm shm.h   /^} pa_shm;$/;" t       typeref:struct:pa_shm
-pa_shm_attach_ro       shm.c   /^int pa_shm_attach_ro(pa_shm *m, unsigned id) {$/;"    f
-pa_shm_cleanup shm.c   /^int pa_shm_cleanup(void) {$/;"        f
-pa_shm_create_rw       shm.c   /^int pa_shm_create_rw(pa_shm *m, size_t size, pa_bool_t shared, mode_t mode) {$/;"     f
-pa_shm_free    shm.c   /^void pa_shm_free(pa_shm *m) {$/;"     f
-pa_shm_punch   shm.c   /^void pa_shm_punch(pa_shm *m, size_t offset, size_t size) {$/;"        f
-pa_sig2str     core-util.c     /^const char *pa_sig2str(int sig) {$/;" f
-pa_silence_cache       sample-util.h   /^typedef struct pa_silence_cache {$/;" s
-pa_silence_cache       sample-util.h   /^} pa_silence_cache;$/;"       t       typeref:struct:pa_silence_cache
-pa_silence_cache_done  sample-util.c   /^void pa_silence_cache_done(pa_silence_cache *cache) {$/;"     f
-pa_silence_cache_init  sample-util.c   /^void pa_silence_cache_init(pa_silence_cache *cache) {$/;"     f
-pa_silence_memblock    sample-util.c   /^pa_memblock *pa_silence_memblock(pa_memblock* b, const pa_sample_spec *spec) {$/;"    f
-pa_silence_memchunk    sample-util.c   /^pa_memchunk* pa_silence_memchunk(pa_memchunk *c, const pa_sample_spec *spec) {$/;"    f
-pa_silence_memchunk_get        sample-util.c   /^pa_memchunk* pa_silence_memchunk_get(pa_silence_cache *cache, pa_mempool *pool, pa_memchunk* ret, const pa_sample_spec *spec, size_t length) {$/;"    f
-pa_silence_memory      sample-util.c   /^void* pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) {$/;"     f
-pa_simple_options      protocol-simple.h       /^typedef struct pa_simple_options {$/;"        s
-pa_simple_options      protocol-simple.h       /^} pa_simple_options;$/;"      t       typeref:struct:pa_simple_options
-pa_simple_options_new  protocol-simple.c       /^pa_simple_options* pa_simple_options_new(void) {$/;"  f
-pa_simple_options_parse        protocol-simple.c       /^int pa_simple_options_parse(pa_simple_options *o, pa_core *c, pa_modargs *ma) {$/;"   f
-pa_simple_options_ref  protocol-simple.c       /^pa_simple_options* pa_simple_options_ref(pa_simple_options *o) {$/;"  f
-pa_simple_options_unref        protocol-simple.c       /^void pa_simple_options_unref(pa_simple_options *o) {$/;"      f
-pa_simple_protocol     protocol-simple.c       /^struct pa_simple_protocol {$/;"       s       file:
-pa_simple_protocol     protocol-simple.h       /^typedef struct pa_simple_protocol pa_simple_protocol;$/;"     t       typeref:struct:pa_simple_protocol
-pa_simple_protocol_connect     protocol-simple.c       /^void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simple_options *o) {$/;"  f
-pa_simple_protocol_disconnect  protocol-simple.c       /^void pa_simple_protocol_disconnect(pa_simple_protocol *p, pa_module *m) {$/;" f
-pa_simple_protocol_get protocol-simple.c       /^pa_simple_protocol* pa_simple_protocol_get(pa_core *c) {$/;"  f
-pa_simple_protocol_ref protocol-simple.c       /^pa_simple_protocol* pa_simple_protocol_ref(pa_simple_protocol *p) {$/;"       f
-pa_simple_protocol_unref       protocol-simple.c       /^void pa_simple_protocol_unref(pa_simple_protocol *p) {$/;"    f
-pa_sink        sink.h  /^PA_DECLARE_PUBLIC_CLASS(pa_sink);$/;" v
-pa_sink        sink.h  /^struct pa_sink {$/;"  s
-pa_sink        sink.h  /^typedef struct pa_sink pa_sink;$/;"   t       typeref:struct:pa_sink
-pa_sink_assert_io_context      sink.h  366;"   d
-pa_sink_attach sink.c  /^void pa_sink_attach(pa_sink *s) {$/;" f
-pa_sink_attach_within_thread   sink.c  /^void pa_sink_attach_within_thread(pa_sink *s) {$/;"   f
-pa_sink_check_suspend  sink.c  /^unsigned pa_sink_check_suspend(pa_sink *s) {$/;"      f
-pa_sink_detach sink.c  /^void pa_sink_detach(pa_sink *s) {$/;" f
-pa_sink_detach_within_thread   sink.c  /^void pa_sink_detach_within_thread(pa_sink *s) {$/;"   f
-pa_sink_get_fixed_latency      sink.c  /^pa_usec_t pa_sink_get_fixed_latency(pa_sink *s) {$/;" f
-pa_sink_get_latency    sink.c  /^pa_usec_t pa_sink_get_latency(pa_sink *s) {$/;"       f
-pa_sink_get_latency_range      sink.c  /^void pa_sink_get_latency_range(pa_sink *s, pa_usec_t *min_latency, pa_usec_t *max_latency) {$/;"      f
-pa_sink_get_latency_within_thread      sink.c  /^pa_usec_t pa_sink_get_latency_within_thread(pa_sink *s) {$/;" f
-pa_sink_get_max_request        sink.c  /^size_t pa_sink_get_max_request(pa_sink *s) {$/;"      f
-pa_sink_get_max_rewind sink.c  /^size_t pa_sink_get_max_rewind(pa_sink *s) {$/;"       f
-pa_sink_get_mute       sink.c  /^pa_bool_t pa_sink_get_mute(pa_sink *s, pa_bool_t force_refresh) {$/;" f
-pa_sink_get_requested_latency  sink.c  /^pa_usec_t pa_sink_get_requested_latency(pa_sink *s) {$/;"     f
-pa_sink_get_requested_latency_within_thread    sink.c  /^pa_usec_t pa_sink_get_requested_latency_within_thread(pa_sink *s) {$/;"       f
-pa_sink_get_state      sink.h  323;"   d
-pa_sink_get_volume     sink.c  /^const pa_cvolume *pa_sink_get_volume(pa_sink *s, pa_bool_t force_refresh) {$/;"       f
-pa_sink_input  sink-input.h    /^PA_DECLARE_PUBLIC_CLASS(pa_sink_input);$/;"   v
-pa_sink_input  sink-input.h    /^struct pa_sink_input {$/;"    s
-pa_sink_input  sink-input.h    /^typedef struct pa_sink_input pa_sink_input;$/;"       t       typeref:struct:pa_sink_input
-pa_sink_input_assert_io_context        sink-input.h    384;"   d
-pa_sink_input_cork     sink-input.c    /^void pa_sink_input_cork(pa_sink_input *i, pa_bool_t b) {$/;"  f
-pa_sink_input_drop     sink-input.c    /^void pa_sink_input_drop(pa_sink_input *i, size_t nbytes \/* in sink sample spec *\/) {$/;"    f
-pa_sink_input_fail_move        sink-input.c    /^void pa_sink_input_fail_move(pa_sink_input *i) {$/;"  f
-pa_sink_input_finish_move      sink-input.c    /^int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {$/;"  f
-pa_sink_input_flags    sink-input.h    /^typedef enum pa_sink_input_flags {$/;"        g
-pa_sink_input_flags_t  sink-input.h    /^} pa_sink_input_flags_t;$/;"  t       typeref:enum:pa_sink_input_flags
-pa_sink_input_get_latency      sink-input.c    /^pa_usec_t pa_sink_input_get_latency(pa_sink_input *i, pa_usec_t *sink_latency) {$/;"  f
-pa_sink_input_get_max_request  sink-input.c    /^size_t pa_sink_input_get_max_request(pa_sink_input *i) {$/;"  f
-pa_sink_input_get_max_rewind   sink-input.c    /^size_t pa_sink_input_get_max_rewind(pa_sink_input *i) {$/;"   f
-pa_sink_input_get_mute sink-input.c    /^pa_bool_t pa_sink_input_get_mute(pa_sink_input *i) {$/;"      f
-pa_sink_input_get_requested_latency    sink-input.c    /^pa_usec_t pa_sink_input_get_requested_latency(pa_sink_input *i) {$/;" f
-pa_sink_input_get_resample_method      sink-input.c    /^pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) {$/;"        f
-pa_sink_input_get_silence      sink-input.c    /^pa_memchunk* pa_sink_input_get_silence(pa_sink_input *i, pa_memchunk *ret) {$/;"      f
-pa_sink_input_get_state        sink-input.c    /^pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i) {$/;" f
-pa_sink_input_get_volume       sink-input.c    /^pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i, pa_cvolume *volume, pa_bool_t absolute) {$/;"  f
-pa_sink_input_kill     sink-input.c    /^void pa_sink_input_kill(pa_sink_input*i) {$/;"        f
-pa_sink_input_list_to_string   cli-text.c      /^char *pa_sink_input_list_to_string(pa_core *c) {$/;"  f
-pa_sink_input_may_move sink-input.c    /^pa_bool_t pa_sink_input_may_move(pa_sink_input *i) {$/;"      f
-pa_sink_input_may_move_to      sink-input.c    /^pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {$/;"    f
-pa_sink_input_move_to  sink-input.c    /^int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {$/;"      f
-pa_sink_input_new      sink-input.c    /^int pa_sink_input_new($/;"    f
-pa_sink_input_new_data sink-input.h    /^typedef struct pa_sink_input_new_data {$/;"   s
-pa_sink_input_new_data sink-input.h    /^} pa_sink_input_new_data;$/;" t       typeref:struct:pa_sink_input_new_data
-pa_sink_input_new_data_apply_volume_factor     sink-input.c    /^void pa_sink_input_new_data_apply_volume_factor(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {$/;"  f
-pa_sink_input_new_data_apply_volume_factor_sink        sink-input.c    /^void pa_sink_input_new_data_apply_volume_factor_sink(pa_sink_input_new_data *data, const pa_cvolume *volume_factor) {$/;"     f
-pa_sink_input_new_data_done    sink-input.c    /^void pa_sink_input_new_data_done(pa_sink_input_new_data *data) {$/;"  f
-pa_sink_input_new_data_init    sink-input.c    /^pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data) {$/;"       f
-pa_sink_input_new_data_set_channel_map sink-input.c    /^void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map) {$/;"    f
-pa_sink_input_new_data_set_muted       sink-input.c    /^void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute) {$/;"     f
-pa_sink_input_new_data_set_sample_spec sink-input.c    /^void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec) {$/;"   f
-pa_sink_input_new_data_set_volume      sink-input.c    /^void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) {$/;"  f
-pa_sink_input_peek     sink-input.c    /^void pa_sink_input_peek(pa_sink_input *i, size_t slength \/* in sink frames *\/, pa_memchunk *chunk, pa_cvolume *volume) {$/;"        f
-pa_sink_input_process_msg      sink-input.c    /^int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {$/;"    f
-pa_sink_input_process_rewind   sink-input.c    /^void pa_sink_input_process_rewind(pa_sink_input *i, size_t nbytes \/* in sink sample spec *\/) {$/;"  f
-pa_sink_input_put      sink-input.c    /^void pa_sink_input_put(pa_sink_input *i) {$/;"        f
-pa_sink_input_request_rewind   sink-input.c    /^void pa_sink_input_request_rewind($/;"        f
-pa_sink_input_safe_to_remove   sink-input.c    /^pa_bool_t pa_sink_input_safe_to_remove(pa_sink_input *i) {$/;"        f
-pa_sink_input_send_event       sink-input.c    /^void pa_sink_input_send_event(pa_sink_input *i, const char *event, pa_proplist *data) {$/;"   f
-pa_sink_input_send_event_hook_data     sink-input.h    /^typedef struct pa_sink_input_send_event_hook_data {$/;"       s
-pa_sink_input_send_event_hook_data     sink-input.h    /^} pa_sink_input_send_event_hook_data;$/;"     t       typeref:struct:pa_sink_input_send_event_hook_data
-pa_sink_input_set_mute sink-input.c    /^void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute, pa_bool_t save) {$/;"   f
-pa_sink_input_set_name sink-input.c    /^void pa_sink_input_set_name(pa_sink_input *i, const char *name) {$/;" f
-pa_sink_input_set_rate sink-input.c    /^int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) {$/;"     f
-pa_sink_input_set_requested_latency    sink-input.c    /^pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec) {$/;" f
-pa_sink_input_set_requested_latency_within_thread      sink-input.c    /^pa_usec_t pa_sink_input_set_requested_latency_within_thread(pa_sink_input *i, pa_usec_t usec) {$/;"   f
-pa_sink_input_set_state_within_thread  sink-input.c    /^void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state_t state) {$/;"       f
-pa_sink_input_set_volume       sink-input.c    /^void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume, pa_bool_t save, pa_bool_t absolute) {$/;"   f
-pa_sink_input_start_move       sink-input.c    /^int pa_sink_input_start_move(pa_sink_input *i) {$/;"  f
-pa_sink_input_state    sink-input.h    /^typedef enum pa_sink_input_state {$/;"        g
-pa_sink_input_state_t  sink-input.h    /^} pa_sink_input_state_t;$/;"  t       typeref:enum:pa_sink_input_state
-pa_sink_input_unlink   sink-input.c    /^void pa_sink_input_unlink(pa_sink_input *i) {$/;"     f
-pa_sink_input_update_max_request       sink-input.c    /^void pa_sink_input_update_max_request(pa_sink_input *i, size_t nbytes  \/* in the sink's sample spec *\/) {$/;"       f
-pa_sink_input_update_max_rewind        sink-input.c    /^void pa_sink_input_update_max_rewind(pa_sink_input *i, size_t nbytes  \/* in the sink's sample spec *\/) {$/;"        f
-pa_sink_input_update_proplist  sink-input.c    /^void pa_sink_input_update_proplist(pa_sink_input *i, pa_update_mode_t mode, pa_proplist *p) {$/;"     f
-pa_sink_invalidate_requested_latency   sink.c  /^void pa_sink_invalidate_requested_latency(pa_sink *s, pa_bool_t dynamic) {$/;"        f
-pa_sink_linked_by      sink.c  /^unsigned pa_sink_linked_by(pa_sink *s) {$/;"  f
-pa_sink_list_to_string cli-text.c      /^char *pa_sink_list_to_string(pa_core *c) {$/;"        f
-pa_sink_message        sink.h  /^typedef enum pa_sink_message {$/;"    g
-pa_sink_message_t      sink.h  /^} pa_sink_message_t;$/;"      t       typeref:enum:pa_sink_message
-pa_sink_move_all_fail  sink.c  /^void pa_sink_move_all_fail(pa_queue *q) {$/;" f
-pa_sink_move_all_finish        sink.c  /^void pa_sink_move_all_finish(pa_sink *s, pa_queue *q, pa_bool_t save) {$/;"   f
-pa_sink_move_all_start sink.c  /^pa_queue *pa_sink_move_all_start(pa_sink *s, pa_queue *q) {$/;"       f
-pa_sink_mute_changed   sink.c  /^void pa_sink_mute_changed(pa_sink *s, pa_bool_t new_muted) {$/;"      f
-pa_sink_new    sink.c  /^pa_sink* pa_sink_new($/;"     f
-pa_sink_new_data       sink.h  /^typedef struct pa_sink_new_data {$/;" s
-pa_sink_new_data       sink.h  /^} pa_sink_new_data;$/;"       t       typeref:struct:pa_sink_new_data
-pa_sink_new_data_done  sink.c  /^void pa_sink_new_data_done(pa_sink_new_data *data) {$/;"      f
-pa_sink_new_data_init  sink.c  /^pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data) {$/;" f
-pa_sink_new_data_set_channel_map       sink.c  /^void pa_sink_new_data_set_channel_map(pa_sink_new_data *data, const pa_channel_map *map) {$/;"        f
-pa_sink_new_data_set_muted     sink.c  /^void pa_sink_new_data_set_muted(pa_sink_new_data *data, pa_bool_t mute) {$/;" f
-pa_sink_new_data_set_name      sink.c  /^void pa_sink_new_data_set_name(pa_sink_new_data *data, const char *name) {$/;"        f
-pa_sink_new_data_set_port      sink.c  /^void pa_sink_new_data_set_port(pa_sink_new_data *data, const char *port) {$/;"        f
-pa_sink_new_data_set_sample_spec       sink.c  /^void pa_sink_new_data_set_sample_spec(pa_sink_new_data *data, const pa_sample_spec *spec) {$/;"       f
-pa_sink_new_data_set_volume    sink.c  /^void pa_sink_new_data_set_volume(pa_sink_new_data *data, const pa_cvolume *volume) {$/;"      f
-pa_sink_process_msg    sink.c  /^int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {$/;"  f
-pa_sink_process_rewind sink.c  /^void pa_sink_process_rewind(pa_sink *s, size_t nbytes) {$/;"  f
-pa_sink_put    sink.c  /^void pa_sink_put(pa_sink* s) {$/;"    f
-pa_sink_render sink.c  /^void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {$/;"      f
-pa_sink_render_full    sink.c  /^void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) {$/;"        f
-pa_sink_render_into    sink.c  /^void pa_sink_render_into(pa_sink*s, pa_memchunk *target) {$/;"        f
-pa_sink_render_into_full       sink.c  /^void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) {$/;"  f
-pa_sink_request_rewind sink.c  /^void pa_sink_request_rewind(pa_sink*s, size_t nbytes) {$/;"   f
-pa_sink_set_asyncmsgq  sink.c  /^void pa_sink_set_asyncmsgq(pa_sink *s, pa_asyncmsgq *q) {$/;" f
-pa_sink_set_description        sink.c  /^void pa_sink_set_description(pa_sink *s, const char *description) {$/;"       f
-pa_sink_set_fixed_latency      sink.c  /^void pa_sink_set_fixed_latency(pa_sink *s, pa_usec_t latency) {$/;"   f
-pa_sink_set_fixed_latency_within_thread        sink.c  /^void pa_sink_set_fixed_latency_within_thread(pa_sink *s, pa_usec_t latency) {$/;"     f
-pa_sink_set_latency_range      sink.c  /^void pa_sink_set_latency_range(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency) {$/;"        f
-pa_sink_set_latency_range_within_thread        sink.c  /^void pa_sink_set_latency_range_within_thread(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency) {$/;"  f
-pa_sink_set_max_request        sink.c  /^void pa_sink_set_max_request(pa_sink *s, size_t max_request) {$/;"    f
-pa_sink_set_max_request_within_thread  sink.c  /^void pa_sink_set_max_request_within_thread(pa_sink *s, size_t max_request) {$/;"      f
-pa_sink_set_max_rewind sink.c  /^void pa_sink_set_max_rewind(pa_sink *s, size_t max_rewind) {$/;"      f
-pa_sink_set_max_rewind_within_thread   sink.c  /^void pa_sink_set_max_rewind_within_thread(pa_sink *s, size_t max_rewind) {$/;"        f
-pa_sink_set_mute       sink.c  /^void pa_sink_set_mute(pa_sink *s, pa_bool_t mute, pa_bool_t save) {$/;"       f
-pa_sink_set_port       sink.c  /^int pa_sink_set_port(pa_sink *s, const char *name, pa_bool_t save) {$/;"      f
-pa_sink_set_rtpoll     sink.c  /^void pa_sink_set_rtpoll(pa_sink *s, pa_rtpoll *p) {$/;"       f
-pa_sink_set_soft_volume        sink.c  /^void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume) {$/;"      f
-pa_sink_set_volume     sink.c  /^void pa_sink_set_volume($/;"  f
-pa_sink_suspend        sink.c  /^int pa_sink_suspend(pa_sink *s, pa_bool_t suspend, pa_suspend_cause_t cause) {$/;"    f
-pa_sink_suspend_all    sink.c  /^int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause) {$/;"        f
-pa_sink_unlink sink.c  /^void pa_sink_unlink(pa_sink* s) {$/;" f
-pa_sink_update_flags   sink.c  /^void pa_sink_update_flags(pa_sink *s, pa_sink_flags_t mask, pa_sink_flags_t value) {$/;"      f
-pa_sink_update_proplist        sink.c  /^pa_bool_t pa_sink_update_proplist(pa_sink *s, pa_update_mode_t mode, pa_proplist *p) {$/;"    f
-pa_sink_update_status  sink.c  /^int pa_sink_update_status(pa_sink*s) {$/;"    f
-pa_sink_used_by        sink.c  /^unsigned pa_sink_used_by(pa_sink *s) {$/;"    f
-pa_sink_volume_changed sink.c  /^void pa_sink_volume_changed(pa_sink *s, const pa_cvolume *new_real_volume) {$/;"      f
-pa_smoother    time-smoother.c /^struct pa_smoother {$/;"      s       file:
-pa_smoother    time-smoother.h /^typedef struct pa_smoother pa_smoother;$/;"   t       typeref:struct:pa_smoother
-pa_smoother_fix_now    time-smoother.c /^void pa_smoother_fix_now(pa_smoother *s) {$/;"        f
-pa_smoother_free       time-smoother.c /^void pa_smoother_free(pa_smoother* s) {$/;"   f
-pa_smoother_get        time-smoother.c /^pa_usec_t pa_smoother_get(pa_smoother *s, pa_usec_t x) {$/;"  f
-pa_smoother_new        time-smoother.c /^pa_smoother* pa_smoother_new($/;"     f
-pa_smoother_pause      time-smoother.c /^void pa_smoother_pause(pa_smoother *s, pa_usec_t x) {$/;"     f
-pa_smoother_put        time-smoother.c /^void pa_smoother_put(pa_smoother *s, pa_usec_t x, pa_usec_t y) {$/;"  f
-pa_smoother_reset      time-smoother.c /^void pa_smoother_reset(pa_smoother *s, pa_usec_t time_offset, pa_bool_t paused) {$/;" f
-pa_smoother_resume     time-smoother.c /^void pa_smoother_resume(pa_smoother *s, pa_usec_t x, pa_bool_t fix_now) {$/;" f
-pa_smoother_set_time_offset    time-smoother.c /^void pa_smoother_set_time_offset(pa_smoother *s, pa_usec_t offset) {$/;"      f
-pa_smoother_translate  time-smoother.c /^pa_usec_t pa_smoother_translate(pa_smoother *s, pa_usec_t x, pa_usec_t y_delay) {$/;" f
-pa_sndfile_dump_formats        sndfile-util.c  /^void pa_sndfile_dump_formats(void) {$/;"      f
-pa_sndfile_format_from_string  sndfile-util.c  /^int pa_sndfile_format_from_string(const char *name) {$/;"     f
-pa_sndfile_init_proplist       sndfile-util.c  /^void pa_sndfile_init_proplist(SNDFILE *sf, pa_proplist *p) {$/;"      f
-pa_sndfile_read_channel_map    sndfile-util.c  /^int pa_sndfile_read_channel_map(SNDFILE *sf, pa_channel_map *cm) {$/;"        f
-pa_sndfile_read_sample_spec    sndfile-util.c  /^int pa_sndfile_read_sample_spec(SNDFILE *sf, pa_sample_spec *ss) {$/;"        f
-pa_sndfile_readf_function      sndfile-util.c  /^pa_sndfile_readf_t pa_sndfile_readf_function(const pa_sample_spec *ss) {$/;"  f
-pa_sndfile_readf_t     sndfile-util.h  /^typedef sf_count_t (*pa_sndfile_readf_t)(SNDFILE *sndfile, void *ptr, sf_count_t frames);$/;" t
-pa_sndfile_write_channel_map   sndfile-util.c  /^int pa_sndfile_write_channel_map(SNDFILE *sf, pa_channel_map *cm) {$/;"       f
-pa_sndfile_write_sample_spec   sndfile-util.c  /^int pa_sndfile_write_sample_spec(SF_INFO *sfi, pa_sample_spec *ss) {$/;"      f
-pa_sndfile_writef_function     sndfile-util.c  /^pa_sndfile_writef_t pa_sndfile_writef_function(const pa_sample_spec *ss) {$/;"        f
-pa_sndfile_writef_t    sndfile-util.h  /^typedef sf_count_t (*pa_sndfile_writef_t)(SNDFILE *sndfile, const void *ptr, sf_count_t frames);$/;"  t
-pa_snprintf    core-util.c     /^size_t pa_snprintf(char *str, size_t size, const char *format, ...) {$/;"     f
-pa_socket_address_is_local     socket-util.c   /^pa_bool_t pa_socket_address_is_local(const struct sockaddr *sa) {$/;" f
-pa_socket_client       socket-client.c /^struct pa_socket_client {$/;" s       file:
-pa_socket_client       socket-client.h /^typedef struct pa_socket_client pa_socket_client;$/;" t       typeref:struct:pa_socket_client
-pa_socket_client_cb_t  socket-client.h /^typedef void (*pa_socket_client_cb_t)(pa_socket_client *c, pa_iochannel*io, void *userdata);$/;"      t
-pa_socket_client_is_local      socket-client.c /^pa_bool_t pa_socket_client_is_local(pa_socket_client *c) {$/;"        f
-pa_socket_client_new_ipv4      socket-client.c /^pa_socket_client* pa_socket_client_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port) {$/;"        f
-pa_socket_client_new_ipv6      socket-client.c /^pa_socket_client* pa_socket_client_new_ipv6(pa_mainloop_api *m, uint8_t address[16], uint16_t port) {$/;"     f
-pa_socket_client_new_sockaddr  socket-client.c /^pa_socket_client* pa_socket_client_new_sockaddr(pa_mainloop_api *m, const struct sockaddr *sa, size_t salen) {$/;"    f
-pa_socket_client_new_string    socket-client.c /^pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, pa_bool_t use_rtclock, const char*name, uint16_t default_port) {$/;"        f
-pa_socket_client_new_unix      socket-client.c /^pa_socket_client* pa_socket_client_new_unix(pa_mainloop_api *m, const char *filename) {$/;"   f
-pa_socket_client_ref   socket-client.c /^pa_socket_client* pa_socket_client_ref(pa_socket_client *c) {$/;"     f
-pa_socket_client_set_callback  socket-client.c /^void pa_socket_client_set_callback(pa_socket_client *c, pa_socket_client_cb_t on_connection, void *userdata) {$/;"    f
-pa_socket_client_unref socket-client.c /^void pa_socket_client_unref(pa_socket_client *c) {$/;"        f
-pa_socket_is_local     socket-util.c   /^pa_bool_t pa_socket_is_local(int fd) {$/;"    f
-pa_socket_peer_to_string       socket-util.c   /^void pa_socket_peer_to_string(int fd, char *c, size_t l) {$/;"        f
-pa_socket_server       socket-server.c /^struct pa_socket_server {$/;" s       file:
-pa_socket_server       socket-server.h /^typedef struct pa_socket_server pa_socket_server;$/;" t       typeref:struct:pa_socket_server
-pa_socket_server_get_address   socket-server.c /^char *pa_socket_server_get_address(pa_socket_server *s, char *c, size_t l) {$/;"      f
-pa_socket_server_new   socket-server.c /^pa_socket_server* pa_socket_server_new(pa_mainloop_api *m, int fd) {$/;"      f
-pa_socket_server_new_ipv4      socket-server.c /^pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port, const char *tcpwrap_service) {$/;"   f
-pa_socket_server_new_ipv4_any  socket-server.c /^pa_socket_server* pa_socket_server_new_ipv4_any(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) {$/;" f
-pa_socket_server_new_ipv4_loopback     socket-server.c /^pa_socket_server* pa_socket_server_new_ipv4_loopback(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) {$/;"    f
-pa_socket_server_new_ipv4_string       socket-server.c /^pa_socket_server* pa_socket_server_new_ipv4_string(pa_mainloop_api *m, const char *name, uint16_t port, const char *tcpwrap_service) {$/;"    f
-pa_socket_server_new_ipv6      socket-server.c /^pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t address[16], uint16_t port, const char *tcpwrap_service) {$/;"  f
-pa_socket_server_new_ipv6_any  socket-server.c /^pa_socket_server* pa_socket_server_new_ipv6_any(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) {$/;" f
-pa_socket_server_new_ipv6_loopback     socket-server.c /^pa_socket_server* pa_socket_server_new_ipv6_loopback(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) {$/;"    f
-pa_socket_server_new_ipv6_string       socket-server.c /^pa_socket_server* pa_socket_server_new_ipv6_string(pa_mainloop_api *m, const char *name, uint16_t port, const char *tcpwrap_service) {$/;"    f
-pa_socket_server_new_unix      socket-server.c /^pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *filename) {$/;"   f
-pa_socket_server_on_connection_cb_t    socket-server.h /^typedef void (*pa_socket_server_on_connection_cb_t)(pa_socket_server*s, pa_iochannel *io, void *userdata);$/;"        t
-pa_socket_server_ref   socket-server.c /^pa_socket_server* pa_socket_server_ref(pa_socket_server *s) {$/;"     f
-pa_socket_server_set_callback  socket-server.c /^void pa_socket_server_set_callback(pa_socket_server*s, pa_socket_server_on_connection_cb_t on_connection, void *userdata) {$/;"       f
-pa_socket_server_unref socket-server.c /^void pa_socket_server_unref(pa_socket_server *s) {$/;"        f
-pa_socket_set_rcvbuf   socket-util.c   /^int pa_socket_set_rcvbuf(int fd, size_t l) {$/;"      f
-pa_socket_set_sndbuf   socket-util.c   /^int pa_socket_set_sndbuf(int fd, size_t l) {$/;"      f
-pa_sound_file_load     sound-file.c    /^int pa_sound_file_load($/;"   f
-pa_sound_file_too_big_to_cache sound-file.c    /^int pa_sound_file_too_big_to_cache(const char *fname) {$/;"   f
-pa_source      source.h        /^PA_DECLARE_PUBLIC_CLASS(pa_source);$/;"       v
-pa_source      source.h        /^struct pa_source {$/;"        s
-pa_source      source.h        /^typedef struct pa_source pa_source;$/;"       t       typeref:struct:pa_source
-pa_source_assert_io_context    source.h        310;"   d
-pa_source_attach       source.c        /^void pa_source_attach(pa_source *s) {$/;"     f
-pa_source_attach_within_thread source.c        /^void pa_source_attach_within_thread(pa_source *s) {$/;"       f
-pa_source_check_suspend        source.c        /^unsigned pa_source_check_suspend(pa_source *s) {$/;"  f
-pa_source_detach       source.c        /^void pa_source_detach(pa_source *s) {$/;"     f
-pa_source_detach_within_thread source.c        /^void pa_source_detach_within_thread(pa_source *s) {$/;"       f
-pa_source_get_fixed_latency    source.c        /^pa_usec_t pa_source_get_fixed_latency(pa_source *s) {$/;"     f
-pa_source_get_latency  source.c        /^pa_usec_t pa_source_get_latency(pa_source *s) {$/;"   f
-pa_source_get_latency_range    source.c        /^void pa_source_get_latency_range(pa_source *s, pa_usec_t *min_latency, pa_usec_t *max_latency) {$/;"  f
-pa_source_get_latency_within_thread    source.c        /^pa_usec_t pa_source_get_latency_within_thread(pa_source *s) {$/;"     f
-pa_source_get_max_rewind       source.c        /^size_t pa_source_get_max_rewind(pa_source *s) {$/;"   f
-pa_source_get_mute     source.c        /^pa_bool_t pa_source_get_mute(pa_source *s, pa_bool_t force_refresh) {$/;"     f
-pa_source_get_requested_latency        source.c        /^pa_usec_t pa_source_get_requested_latency(pa_source *s) {$/;" f
-pa_source_get_requested_latency_within_thread  source.c        /^pa_usec_t pa_source_get_requested_latency_within_thread(pa_source *s) {$/;"   f
-pa_source_get_state    source.h        280;"   d
-pa_source_get_volume   source.c        /^const pa_cvolume *pa_source_get_volume(pa_source *s, pa_bool_t force_refresh) {$/;"   f
-pa_source_invalidate_requested_latency source.c        /^void pa_source_invalidate_requested_latency(pa_source *s, pa_bool_t dynamic) {$/;"    f
-pa_source_linked_by    source.c        /^unsigned pa_source_linked_by(pa_source *s) {$/;"      f
-pa_source_list_to_string       cli-text.c      /^char *pa_source_list_to_string(pa_core *c) {$/;"      f
-pa_source_message      source.h        /^typedef enum pa_source_message {$/;"  g
-pa_source_message_t    source.h        /^} pa_source_message_t;$/;"    t       typeref:enum:pa_source_message
-pa_source_move_all_fail        source.c        /^void pa_source_move_all_fail(pa_queue *q) {$/;"       f
-pa_source_move_all_finish      source.c        /^void pa_source_move_all_finish(pa_source *s, pa_queue *q, pa_bool_t save) {$/;"       f
-pa_source_move_all_start       source.c        /^pa_queue *pa_source_move_all_start(pa_source *s, pa_queue *q) {$/;"   f
-pa_source_mute_changed source.c        /^void pa_source_mute_changed(pa_source *s, pa_bool_t new_muted) {$/;"  f
-pa_source_new  source.c        /^pa_source* pa_source_new($/;" f
-pa_source_new_data     source.h        /^typedef struct pa_source_new_data {$/;"       s
-pa_source_new_data     source.h        /^} pa_source_new_data;$/;"     t       typeref:struct:pa_source_new_data
-pa_source_new_data_done        source.c        /^void pa_source_new_data_done(pa_source_new_data *data) {$/;"  f
-pa_source_new_data_init        source.c        /^pa_source_new_data* pa_source_new_data_init(pa_source_new_data *data) {$/;"   f
-pa_source_new_data_set_channel_map     source.c        /^void pa_source_new_data_set_channel_map(pa_source_new_data *data, const pa_channel_map *map) {$/;"    f
-pa_source_new_data_set_muted   source.c        /^void pa_source_new_data_set_muted(pa_source_new_data *data, pa_bool_t mute) {$/;"     f
-pa_source_new_data_set_name    source.c        /^void pa_source_new_data_set_name(pa_source_new_data *data, const char *name) {$/;"    f
-pa_source_new_data_set_port    source.c        /^void pa_source_new_data_set_port(pa_source_new_data *data, const char *port) {$/;"    f
-pa_source_new_data_set_sample_spec     source.c        /^void pa_source_new_data_set_sample_spec(pa_source_new_data *data, const pa_sample_spec *spec) {$/;"   f
-pa_source_new_data_set_volume  source.c        /^void pa_source_new_data_set_volume(pa_source_new_data *data, const pa_cvolume *volume) {$/;"  f
-pa_source_output       source-output.h /^PA_DECLARE_PUBLIC_CLASS(pa_source_output);$/;"        v
-pa_source_output       source-output.h /^struct pa_source_output {$/;" s
-pa_source_output       source-output.h /^typedef struct pa_source_output pa_source_output;$/;" t       typeref:struct:pa_source_output
-pa_source_output_assert_io_context     source-output.h 291;"   d
-pa_source_output_cork  source-output.c /^void pa_source_output_cork(pa_source_output *o, pa_bool_t b) {$/;"    f
-pa_source_output_fail_move     source-output.c /^void pa_source_output_fail_move(pa_source_output *o) {$/;"    f
-pa_source_output_finish_move   source-output.c /^int pa_source_output_finish_move(pa_source_output *o, pa_source *dest, pa_bool_t save) {$/;"  f
-pa_source_output_flags source-output.h /^typedef enum pa_source_output_flags {$/;"     g
-pa_source_output_flags_t       source-output.h /^} pa_source_output_flags_t;$/;"       t       typeref:enum:pa_source_output_flags
-pa_source_output_get_latency   source-output.c /^pa_usec_t pa_source_output_get_latency(pa_source_output *o, pa_usec_t *source_latency) {$/;"  f
-pa_source_output_get_max_rewind        source-output.c /^size_t pa_source_output_get_max_rewind(pa_source_output *o) {$/;"     f
-pa_source_output_get_requested_latency source-output.c /^pa_usec_t pa_source_output_get_requested_latency(pa_source_output *o) {$/;"   f
-pa_source_output_get_resample_method   source-output.c /^pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o) {$/;"  f
-pa_source_output_get_state     source-output.h 275;"   d
-pa_source_output_kill  source-output.c /^void pa_source_output_kill(pa_source_output*o) {$/;"  f
-pa_source_output_list_to_string        cli-text.c      /^char *pa_source_output_list_to_string(pa_core *c) {$/;"       f
-pa_source_output_may_move      source-output.c /^pa_bool_t pa_source_output_may_move(pa_source_output *o) {$/;"        f
-pa_source_output_may_move_to   source-output.c /^pa_bool_t pa_source_output_may_move_to(pa_source_output *o, pa_source *dest) {$/;"    f
-pa_source_output_move_to       source-output.c /^int pa_source_output_move_to(pa_source_output *o, pa_source *dest, pa_bool_t save) {$/;"      f
-pa_source_output_new   source-output.c /^int pa_source_output_new($/;" f
-pa_source_output_new_data      source-output.h /^typedef struct pa_source_output_new_data {$/;"        s
-pa_source_output_new_data      source-output.h /^} pa_source_output_new_data;$/;"      t       typeref:struct:pa_source_output_new_data
-pa_source_output_new_data_done source-output.c /^void pa_source_output_new_data_done(pa_source_output_new_data *data) {$/;"    f
-pa_source_output_new_data_init source-output.c /^pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data) {$/;"      f
-pa_source_output_new_data_set_channel_map      source-output.c /^void pa_source_output_new_data_set_channel_map(pa_source_output_new_data *data, const pa_channel_map *map) {$/;"      f
-pa_source_output_new_data_set_sample_spec      source-output.c /^void pa_source_output_new_data_set_sample_spec(pa_source_output_new_data *data, const pa_sample_spec *spec) {$/;"     f
-pa_source_output_process_msg   source-output.c /^int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int64_t offset, pa_memchunk* chunk) {$/;"        f
-pa_source_output_process_rewind        source-output.c /^void pa_source_output_process_rewind(pa_source_output *o, size_t nbytes \/* in source sample spec *\/) {$/;"  f
-pa_source_output_push  source-output.c /^void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) {$/;"       f
-pa_source_output_put   source-output.c /^void pa_source_output_put(pa_source_output *o) {$/;"  f
-pa_source_output_send_event    source-output.c /^void pa_source_output_send_event(pa_source_output *o, const char *event, pa_proplist *data) {$/;"     f
-pa_source_output_send_event_hook_data  source-output.h /^typedef struct pa_source_output_send_event_hook_data {$/;"    s
-pa_source_output_send_event_hook_data  source-output.h /^} pa_source_output_send_event_hook_data;$/;"  t       typeref:struct:pa_source_output_send_event_hook_data
-pa_source_output_set_name      source-output.c /^void pa_source_output_set_name(pa_source_output *o, const char *name) {$/;"   f
-pa_source_output_set_rate      source-output.c /^int pa_source_output_set_rate(pa_source_output *o, uint32_t rate) {$/;"       f
-pa_source_output_set_requested_latency source-output.c /^pa_usec_t pa_source_output_set_requested_latency(pa_source_output *o, pa_usec_t usec) {$/;"   f
-pa_source_output_set_requested_latency_within_thread   source-output.c /^pa_usec_t pa_source_output_set_requested_latency_within_thread(pa_source_output *o, pa_usec_t usec) {$/;"     f
-pa_source_output_set_state_within_thread       source-output.c /^void pa_source_output_set_state_within_thread(pa_source_output *o, pa_source_output_state_t state) {$/;"      f
-pa_source_output_start_move    source-output.c /^int pa_source_output_start_move(pa_source_output *o) {$/;"    f
-pa_source_output_state source-output.h /^typedef enum pa_source_output_state {$/;"     g
-pa_source_output_state_t       source-output.h /^} pa_source_output_state_t;$/;"       t       typeref:enum:pa_source_output_state
-pa_source_output_unlink        source-output.c /^void pa_source_output_unlink(pa_source_output*o) {$/;"        f
-pa_source_output_update_max_rewind     source-output.c /^void pa_source_output_update_max_rewind(pa_source_output *o, size_t nbytes  \/* in the source's sample spec *\/) {$/;"        f
-pa_source_output_update_proplist       source-output.c /^void pa_source_output_update_proplist(pa_source_output *o, pa_update_mode_t mode, pa_proplist *p) {$/;"       f
-pa_source_post source.c        /^void pa_source_post(pa_source*s, const pa_memchunk *chunk) {$/;"      f
-pa_source_post_direct  source.c        /^void pa_source_post_direct(pa_source*s, pa_source_output *o, const pa_memchunk *chunk) {$/;"  f
-pa_source_process_msg  source.c        /^int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {$/;"   f
-pa_source_process_rewind       source.c        /^void pa_source_process_rewind(pa_source *s, size_t nbytes) {$/;"      f
-pa_source_put  source.c        /^void pa_source_put(pa_source *s) {$/;"        f
-pa_source_set_asyncmsgq        source.c        /^void pa_source_set_asyncmsgq(pa_source *s, pa_asyncmsgq *q) {$/;"     f
-pa_source_set_description      source.c        /^void pa_source_set_description(pa_source *s, const char *description) {$/;"   f
-pa_source_set_fixed_latency    source.c        /^void pa_source_set_fixed_latency(pa_source *s, pa_usec_t latency) {$/;"       f
-pa_source_set_fixed_latency_within_thread      source.c        /^void pa_source_set_fixed_latency_within_thread(pa_source *s, pa_usec_t latency) {$/;" f
-pa_source_set_latency_range    source.c        /^void pa_source_set_latency_range(pa_source *s, pa_usec_t min_latency, pa_usec_t max_latency) {$/;"    f
-pa_source_set_latency_range_within_thread      source.c        /^void pa_source_set_latency_range_within_thread(pa_source *s, pa_usec_t min_latency, pa_usec_t max_latency) {$/;"      f
-pa_source_set_max_rewind       source.c        /^void pa_source_set_max_rewind(pa_source *s, size_t max_rewind) {$/;"  f
-pa_source_set_max_rewind_within_thread source.c        /^void pa_source_set_max_rewind_within_thread(pa_source *s, size_t max_rewind) {$/;"    f
-pa_source_set_mute     source.c        /^void pa_source_set_mute(pa_source *s, pa_bool_t mute, pa_bool_t save) {$/;"   f
-pa_source_set_port     source.c        /^int pa_source_set_port(pa_source *s, const char *name, pa_bool_t save) {$/;"  f
-pa_source_set_rtpoll   source.c        /^void pa_source_set_rtpoll(pa_source *s, pa_rtpoll *p) {$/;"   f
-pa_source_set_soft_volume      source.c        /^void pa_source_set_soft_volume(pa_source *s, const pa_cvolume *volume) {$/;"  f
-pa_source_set_volume   source.c        /^void pa_source_set_volume($/;"        f
-pa_source_suspend      source.c        /^int pa_source_suspend(pa_source *s, pa_bool_t suspend, pa_suspend_cause_t cause) {$/;"        f
-pa_source_suspend_all  source.c        /^int pa_source_suspend_all(pa_core *c, pa_bool_t suspend, pa_suspend_cause_t cause) {$/;"      f
-pa_source_sync_suspend source.c        /^int pa_source_sync_suspend(pa_source *s) {$/;"        f
-pa_source_unlink       source.c        /^void pa_source_unlink(pa_source *s) {$/;"     f
-pa_source_update_flags source.c        /^void pa_source_update_flags(pa_source *s, pa_source_flags_t mask, pa_source_flags_t value) {$/;"      f
-pa_source_update_proplist      source.c        /^pa_bool_t pa_source_update_proplist(pa_source *s, pa_update_mode_t mode, pa_proplist *p) {$/;"        f
-pa_source_update_status        source.c        /^int pa_source_update_status(pa_source*s) {$/;"        f
-pa_source_used_by      source.c        /^unsigned pa_source_used_by(pa_source *s) {$/;"        f
-pa_source_volume_changed       source.c        /^void pa_source_volume_changed(pa_source *s, const pa_cvolume *new_volume) {$/;"       f
-pa_split       core-util.c     /^char *pa_split(const char *c, const char *delimiter, const char**state) {$/;" f
-pa_split_spaces        core-util.c     /^char *pa_split_spaces(const char *c, const char **state) {$/;"        f
-pa_split_spaces_strv   core-util.c     /^char **pa_split_spaces_strv(const char *s) {$/;"      f
-pa_sprintf_malloc      core-util.c     /^char *pa_sprintf_malloc(const char *format, ...) {$/;"        f
-pa_start_child_for_read        start-child.c   /^int pa_start_child_for_read(const char *name, const char *argv1, pid_t *pid) {$/;"    f
-pa_startswith  core-util.c     /^pa_bool_t pa_startswith(const char *s, const char *pfx) {$/;" f
-pa_state_path  core-util.c     /^char *pa_state_path(const char *fn, pa_bool_t appendmid) {$/;"        f
-pa_static_mutex        mutex.h /^typedef struct pa_static_mutex {$/;"  s
-pa_static_mutex        mutex.h /^} pa_static_mutex;$/;"        t       typeref:struct:pa_static_mutex
-pa_static_mutex_get    mutex-posix.c   /^pa_mutex* pa_static_mutex_get(pa_static_mutex *s, pa_bool_t recursive, pa_bool_t inherit_priority) {$/;"      f
-pa_static_semaphore    semaphore.h     /^typedef struct pa_static_semaphore {$/;"      s
-pa_static_semaphore    semaphore.h     /^} pa_static_semaphore;$/;"    t       typeref:struct:pa_static_semaphore
-pa_static_semaphore_get        semaphore-posix.c       /^pa_semaphore* pa_static_semaphore_get(pa_static_semaphore *s, unsigned value) {$/;"   f
-pa_stdio_acquire       sioman.c        /^int pa_stdio_acquire(void) {$/;"      f
-pa_stdio_release       sioman.c        /^void pa_stdio_release(void) {$/;"     f
-pa_strbuf      strbuf.c        /^struct pa_strbuf {$/;"        s       file:
-pa_strbuf      strbuf.h        /^typedef struct pa_strbuf pa_strbuf;$/;"       t       typeref:struct:pa_strbuf
-pa_strbuf_free strbuf.c        /^void pa_strbuf_free(pa_strbuf *sb) {$/;"      f
-pa_strbuf_isempty      strbuf.c        /^pa_bool_t pa_strbuf_isempty(pa_strbuf *sb) {$/;"      f
-pa_strbuf_new  strbuf.c        /^pa_strbuf *pa_strbuf_new(void) {$/;"  f
-pa_strbuf_printf       strbuf.c        /^size_t pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) {$/;" f
-pa_strbuf_putc strbuf.c        /^void pa_strbuf_putc(pa_strbuf *sb, char c) {$/;"      f
-pa_strbuf_puts strbuf.c        /^void pa_strbuf_puts(pa_strbuf *sb, const char *t) {$/;"       f
-pa_strbuf_putsn        strbuf.c        /^void pa_strbuf_putsn(pa_strbuf *sb, const char *t, size_t l) {$/;"    f
-pa_strbuf_tostring     strbuf.c        /^char *pa_strbuf_tostring(pa_strbuf *sb) {$/;" f
-pa_strbuf_tostring_free        strbuf.c        /^char *pa_strbuf_tostring_free(pa_strbuf *sb) {$/;"    f
-pa_strempty    core-util.h     /^static inline const char *pa_strempty(const char *x) {$/;"    f
-pa_streq       core-util.h     203;"   d
-pa_strip_nl    core-util.c     /^char* pa_strip_nl(char *s) {$/;"      f
-pa_strlcpy     core-util.c     /^char *pa_strlcpy(char *b, const char *s, size_t l) {$/;"      f
-pa_strlist     strlist.c       /^struct pa_strlist {$/;"       s       file:
-pa_strlist     strlist.h       /^typedef struct pa_strlist pa_strlist;$/;"     t       typeref:struct:pa_strlist
-pa_strlist_data        strlist.c       /^const char *pa_strlist_data(pa_strlist *s) {$/;"      f
-pa_strlist_free        strlist.c       /^void pa_strlist_free(pa_strlist *l) {$/;"     f
-pa_strlist_next        strlist.c       /^pa_strlist *pa_strlist_next(pa_strlist *s) {$/;"      f
-pa_strlist_parse       strlist.c       /^pa_strlist* pa_strlist_parse(const char *s) {$/;"     f
-pa_strlist_pop strlist.c       /^pa_strlist* pa_strlist_pop(pa_strlist *l, char **s) {$/;"     f
-pa_strlist_prepend     strlist.c       /^pa_strlist* pa_strlist_prepend(pa_strlist *l, const char *s) {$/;"    f
-pa_strlist_remove      strlist.c       /^pa_strlist* pa_strlist_remove(pa_strlist *l, const char *s) {$/;"     f
-pa_strlist_reverse     strlist.c       /^pa_strlist *pa_strlist_reverse(pa_strlist *l) {$/;"   f
-pa_strlist_tostring    strlist.c       /^char *pa_strlist_tostring(pa_strlist *l) {$/;"        f
-pa_strna       core-util.h     /^static inline const char *pa_strna(const char *x) {$/;"       f
-pa_strnull     core-util.h     /^static inline const char *pa_strnull(const char *x) {$/;"     f
-pa_subscription        core-subscribe.c        /^struct pa_subscription {$/;"  s       file:
-pa_subscription        core-subscribe.h        /^typedef struct pa_subscription pa_subscription;$/;"   t       typeref:struct:pa_subscription
-pa_subscription_cb_t   core-subscribe.h        /^typedef void (*pa_subscription_cb_t)(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata);$/;"   t
-pa_subscription_event  core-subscribe.c        /^struct pa_subscription_event {$/;"    s       file:
-pa_subscription_event  core-subscribe.h        /^typedef struct pa_subscription_event pa_subscription_event;$/;"       t       typeref:struct:pa_subscription_event
-pa_subscription_free   core-subscribe.c        /^void pa_subscription_free(pa_subscription*s) {$/;"    f
-pa_subscription_free_all       core-subscribe.c        /^void pa_subscription_free_all(pa_core *c) {$/;"       f
-pa_subscription_new    core-subscribe.c        /^pa_subscription* pa_subscription_new(pa_core *c, pa_subscription_mask_t m, pa_subscription_cb_t callback, void *userdata) {$/;"       f
-pa_subscription_post   core-subscribe.c        /^void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t idx) {$/;"     f
-pa_suspend_cause       core.h  /^typedef enum pa_suspend_cause {$/;"   g
-pa_suspend_cause_t     core.h  /^} pa_suspend_cause_t;$/;"     t       typeref:enum:pa_suspend_cause
-pa_tagstruct   tagstruct.c     /^struct pa_tagstruct {$/;"     s       file:
-pa_tagstruct   tagstruct.h     /^typedef struct pa_tagstruct pa_tagstruct;$/;" t       typeref:struct:pa_tagstruct
-pa_tagstruct_data      tagstruct.c     /^const uint8_t* pa_tagstruct_data(pa_tagstruct*t, size_t *l) {$/;"     f
-pa_tagstruct_eof       tagstruct.c     /^int pa_tagstruct_eof(pa_tagstruct*t) {$/;"    f
-pa_tagstruct_free      tagstruct.c     /^void pa_tagstruct_free(pa_tagstruct*t) {$/;"  f
-pa_tagstruct_free_data tagstruct.c     /^uint8_t* pa_tagstruct_free_data(pa_tagstruct*t, size_t *l) {$/;"      f
-pa_tagstruct_get       tagstruct.c     /^int pa_tagstruct_get(pa_tagstruct *t, ...) {$/;"      f
-pa_tagstruct_get_arbitrary     tagstruct.c     /^int pa_tagstruct_get_arbitrary(pa_tagstruct *t, const void **p, size_t length) {$/;"  f
-pa_tagstruct_get_boolean       tagstruct.c     /^int pa_tagstruct_get_boolean(pa_tagstruct*t, pa_bool_t *b) {$/;"      f
-pa_tagstruct_get_channel_map   tagstruct.c     /^int pa_tagstruct_get_channel_map(pa_tagstruct *t, pa_channel_map *map) {$/;"  f
-pa_tagstruct_get_cvolume       tagstruct.c     /^int pa_tagstruct_get_cvolume(pa_tagstruct *t, pa_cvolume *cvolume) {$/;"      f
-pa_tagstruct_get_proplist      tagstruct.c     /^int pa_tagstruct_get_proplist(pa_tagstruct *t, pa_proplist *p) {$/;"  f
-pa_tagstruct_get_sample_spec   tagstruct.c     /^int pa_tagstruct_get_sample_spec(pa_tagstruct *t, pa_sample_spec *ss) {$/;"   f
-pa_tagstruct_get_timeval       tagstruct.c     /^int pa_tagstruct_get_timeval(pa_tagstruct*t, struct timeval *tv) {$/;"        f
-pa_tagstruct_get_usec  tagstruct.c     /^int pa_tagstruct_get_usec(pa_tagstruct*t, pa_usec_t *u) {$/;" f
-pa_tagstruct_get_volume        tagstruct.c     /^int pa_tagstruct_get_volume(pa_tagstruct*t, pa_volume_t *vol) {$/;"   f
-pa_tagstruct_gets      tagstruct.c     /^int pa_tagstruct_gets(pa_tagstruct*t, const char **s) {$/;"   f
-pa_tagstruct_gets64    tagstruct.c     /^int pa_tagstruct_gets64(pa_tagstruct*t, int64_t *u) {$/;"     f
-pa_tagstruct_getu32    tagstruct.c     /^int pa_tagstruct_getu32(pa_tagstruct*t, uint32_t *i) {$/;"    f
-pa_tagstruct_getu64    tagstruct.c     /^int pa_tagstruct_getu64(pa_tagstruct*t, uint64_t *u) {$/;"    f
-pa_tagstruct_getu8     tagstruct.c     /^int pa_tagstruct_getu8(pa_tagstruct*t, uint8_t *c) {$/;"      f
-pa_tagstruct_new       tagstruct.c     /^pa_tagstruct *pa_tagstruct_new(const uint8_t* data, size_t length) {$/;"      f
-pa_tagstruct_put       tagstruct.c     /^void pa_tagstruct_put(pa_tagstruct *t, ...) {$/;"     f
-pa_tagstruct_put_arbitrary     tagstruct.c     /^void pa_tagstruct_put_arbitrary(pa_tagstruct *t, const void *p, size_t length) {$/;"  f
-pa_tagstruct_put_boolean       tagstruct.c     /^void pa_tagstruct_put_boolean(pa_tagstruct*t, pa_bool_t b) {$/;"      f
-pa_tagstruct_put_channel_map   tagstruct.c     /^void pa_tagstruct_put_channel_map(pa_tagstruct *t, const pa_channel_map *map) {$/;"   f
-pa_tagstruct_put_cvolume       tagstruct.c     /^void pa_tagstruct_put_cvolume(pa_tagstruct *t, const pa_cvolume *cvolume) {$/;"       f
-pa_tagstruct_put_proplist      tagstruct.c     /^void pa_tagstruct_put_proplist(pa_tagstruct *t, pa_proplist *p) {$/;" f
-pa_tagstruct_put_sample_spec   tagstruct.c     /^void pa_tagstruct_put_sample_spec(pa_tagstruct *t, const pa_sample_spec *ss) {$/;"    f
-pa_tagstruct_put_timeval       tagstruct.c     /^void pa_tagstruct_put_timeval(pa_tagstruct*t, const struct timeval *tv) {$/;" f
-pa_tagstruct_put_usec  tagstruct.c     /^void pa_tagstruct_put_usec(pa_tagstruct*t, pa_usec_t u) {$/;" f
-pa_tagstruct_put_volume        tagstruct.c     /^void pa_tagstruct_put_volume(pa_tagstruct *t, pa_volume_t vol) {$/;"  f
-pa_tagstruct_puts      tagstruct.c     /^void pa_tagstruct_puts(pa_tagstruct*t, const char *s) {$/;"   f
-pa_tagstruct_puts64    tagstruct.c     /^void pa_tagstruct_puts64(pa_tagstruct*t, int64_t u) {$/;"     f
-pa_tagstruct_putu32    tagstruct.c     /^void pa_tagstruct_putu32(pa_tagstruct*t, uint32_t i) {$/;"    f
-pa_tagstruct_putu64    tagstruct.c     /^void pa_tagstruct_putu64(pa_tagstruct*t, uint64_t u) {$/;"    f
-pa_tagstruct_putu8     tagstruct.c     /^void pa_tagstruct_putu8(pa_tagstruct*t, uint8_t c) {$/;"      f
-pa_thread      thread-posix.c  /^struct pa_thread {$/;"        s       file:
-pa_thread      thread-win32.c  /^struct pa_thread {$/;"        s       file:
-pa_thread      thread.h        /^typedef struct pa_thread pa_thread;$/;"       t       typeref:struct:pa_thread
-pa_thread_free thread-posix.c  /^void pa_thread_free(pa_thread *t) {$/;"       f
-pa_thread_free thread-win32.c  /^void pa_thread_free(pa_thread *t) {$/;"       f
-pa_thread_func_t       thread.h        /^typedef void (*pa_thread_func_t) (void *userdata);$/;"        t
-pa_thread_get_data     thread-posix.c  /^void* pa_thread_get_data(pa_thread *t) {$/;"  f
-pa_thread_is_running   thread-posix.c  /^int pa_thread_is_running(pa_thread *t) {$/;"  f
-pa_thread_is_running   thread-win32.c  /^int pa_thread_is_running(pa_thread *t) {$/;"  f
-pa_thread_join thread-posix.c  /^int pa_thread_join(pa_thread *t) {$/;"        f
-pa_thread_join thread-win32.c  /^int pa_thread_join(pa_thread *t) {$/;"        f
-pa_thread_mq   thread-mq.h     /^typedef struct pa_thread_mq {$/;"     s
-pa_thread_mq   thread-mq.h     /^} pa_thread_mq;$/;"   t       typeref:struct:pa_thread_mq
-pa_thread_mq_done      thread-mq.c     /^void pa_thread_mq_done(pa_thread_mq *q) {$/;" f
-pa_thread_mq_get       thread-mq.c     /^pa_thread_mq *pa_thread_mq_get(void) {$/;"    f
-pa_thread_mq_init      thread-mq.c     /^void pa_thread_mq_init(pa_thread_mq *q, pa_mainloop_api *mainloop, pa_rtpoll *rtpoll) {$/;"   f
-pa_thread_mq_install   thread-mq.c     /^void pa_thread_mq_install(pa_thread_mq *q) {$/;"      f
-pa_thread_new  thread-posix.c  /^pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) {$/;"  f
-pa_thread_new  thread-win32.c  /^pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) {$/;"  f
-pa_thread_self thread-posix.c  /^pa_thread* pa_thread_self(void) {$/;" f
-pa_thread_self thread-win32.c  /^pa_thread* pa_thread_self(void) {$/;" f
-pa_thread_set_data     thread-posix.c  /^void pa_thread_set_data(pa_thread *t, void *userdata) {$/;"   f
-pa_thread_yield        thread-posix.c  /^void pa_thread_yield(void) {$/;"      f
-pa_thread_yield        thread-win32.c  /^void pa_thread_yield(void) {$/;"      f
-pa_timespec_load       core-rtclock.c  /^pa_usec_t pa_timespec_load(const struct timespec *ts) {$/;"   f
-pa_timespec_store      core-rtclock.c  /^struct timespec* pa_timespec_store(struct timespec *ts, pa_usec_t v) {$/;"    f
-pa_timeval_rtstore     core-rtclock.c  /^struct timeval* pa_timeval_rtstore(struct timeval *tv, pa_usec_t v, pa_bool_t rtclock) {$/;"  f
-pa_tls thread-posix.c  /^struct pa_tls {$/;"   s       file:
-pa_tls thread-win32.c  /^struct pa_tls {$/;"   s       file:
-pa_tls thread.h        /^typedef struct pa_tls pa_tls;$/;"     t       typeref:struct:pa_tls
-pa_tls_free    thread-posix.c  /^void pa_tls_free(pa_tls *t) {$/;"     f
-pa_tls_free    thread-win32.c  /^void pa_tls_free(pa_tls *t) {$/;"     f
-pa_tls_get     thread-posix.c  /^void *pa_tls_get(pa_tls *t) {$/;"     f
-pa_tls_get     thread-win32.c  /^void *pa_tls_get(pa_tls *t) {$/;"     f
-pa_tls_monitor thread-win32.c  /^struct pa_tls_monitor {$/;"   s       file:
-pa_tls_new     thread-posix.c  /^pa_tls* pa_tls_new(pa_free_cb_t free_cb) {$/;"        f
-pa_tls_new     thread-win32.c  /^pa_tls* pa_tls_new(pa_free_cb_t free_cb) {$/;"        f
-pa_tls_set     thread-posix.c  /^void *pa_tls_set(pa_tls *t, void *userdata) {$/;"     f
-pa_tls_set     thread-win32.c  /^void *pa_tls_set(pa_tls *t, void *userdata) {$/;"     f
-pa_tokenizer   tokenizer.h     /^typedef struct pa_tokenizer pa_tokenizer;$/;" t       typeref:struct:pa_tokenizer
-pa_tokenizer_free      tokenizer.c     /^void pa_tokenizer_free(pa_tokenizer *t) {$/;" f
-pa_tokenizer_get       tokenizer.c     /^const char *pa_tokenizer_get(pa_tokenizer *t, unsigned i) {$/;"       f
-pa_tokenizer_new       tokenizer.c     /^pa_tokenizer* pa_tokenizer_new(const char *s, unsigned args) {$/;"    f
-pa_truncate_utf8       core-util.c     /^char *pa_truncate_utf8(char *c, size_t l) {$/;"       f
-pa_uid_in_group        core-util.c     /^int pa_uid_in_group(uid_t uid, const char *name) {$/;"        f
-pa_uint8_vector        vector.h        /^typedef union pa_uint8_vector {$/;"   u
-pa_uint8_vector_t      vector.h        /^} pa_uint8_vector_t;$/;"      t       typeref:union:pa_uint8_vector
-pa_ulog2       core-util.h     /^static inline unsigned pa_ulog2(unsigned n) {$/;"     f
-pa_uname_string        core-util.c     /^char *pa_uname_string(void) {$/;"     f
-pa_unblock_sigs        core-util.c     /^int pa_unblock_sigs(int except, ...) {$/;"    f
-pa_unblock_sigsv       core-util.c     /^int pa_unblock_sigsv(const int except[]) {$/;"        f
-pa_unescape    core-util.c     /^char *pa_unescape(char *p) {$/;"      f
-pa_unix_socket_is_stale        socket-util.c   /^int pa_unix_socket_is_stale(const char *fn) {$/;"     f
-pa_unix_socket_remove_stale    socket-util.c   /^int pa_unix_socket_remove_stale(const char *fn) {$/;" f
-pa_unlock_lockfile     core-util.c     /^int pa_unlock_lockfile(const char *fn, int fd) {$/;"  f
-pa_unset_env_recorded  core-util.c     /^void pa_unset_env_recorded(void) {$/;"        f
-pa_usec_to_bytes_round_up      sample-util.c   /^size_t pa_usec_to_bytes_round_up(pa_usec_t t, const pa_sample_spec *spec) {$/;"       f
-pa_v16qi       vector.h        /^typedef uint8_t pa_v16qi __attribute__ ((vector_size (PA_UINT8_VECTOR_SIZE * sizeof(uint8_t))));$/;"  t
-pa_v4sf        vector.h        /^typedef float pa_v4sf __attribute__ ((vector_size (PA_FLOAT_VECTOR_SIZE * sizeof(float))));$/;"       t
-pa_v4si        vector.h        /^typedef int32_t pa_v4si __attribute__ ((vector_size (PA_INT32_VECTOR_SIZE * sizeof(int32_t))));$/;"   t
-pa_v8hi        vector.h        /^typedef int16_t pa_v8hi __attribute__ ((vector_size (PA_INT16_VECTOR_SIZE * sizeof(int16_t))));$/;"   t
-pa_void_func_t ltdl-helper.h   /^typedef void (*pa_void_func_t)(void);$/;"     t
-pa_volume_alaw_c       svolume_c.c     /^pa_volume_alaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)$/;" f       file:
-pa_volume_float32ne_c  svolume_c.c     /^pa_volume_float32ne_c (float *samples, float *volumes, unsigned channels, unsigned length)$/;"        f       file:
-pa_volume_float32re_c  svolume_c.c     /^pa_volume_float32re_c (float *samples, float *volumes, unsigned channels, unsigned length)$/;"        f       file:
-pa_volume_func_init_arm        svolume_arm.c   /^void pa_volume_func_init_arm (pa_cpu_arm_flag_t flags) {$/;"  f
-pa_volume_func_init_mmx        svolume_mmx.c   /^void pa_volume_func_init_mmx (pa_cpu_x86_flag_t flags) {$/;"  f
-pa_volume_func_init_sse        svolume_sse.c   /^void pa_volume_func_init_sse (pa_cpu_x86_flag_t flags) {$/;"  f
-pa_volume_memchunk     sample-util.c   /^void pa_volume_memchunk($/;"  f
-pa_volume_s16ne_arm    svolume_arm.c   /^pa_volume_s16ne_arm (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)$/;"      f       file:
-pa_volume_s16ne_c      svolume_c.c     /^pa_volume_s16ne_c (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)$/;"        f       file:
-pa_volume_s16ne_mmx    svolume_mmx.c   /^pa_volume_s16ne_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)$/;"      f       file:
-pa_volume_s16ne_sse2   svolume_sse.c   /^pa_volume_s16ne_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)$/;"     f       file:
-pa_volume_s16re_c      svolume_c.c     /^pa_volume_s16re_c (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)$/;"        f       file:
-pa_volume_s16re_mmx    svolume_mmx.c   /^pa_volume_s16re_mmx (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)$/;"      f       file:
-pa_volume_s16re_sse2   svolume_sse.c   /^pa_volume_s16re_sse2 (int16_t *samples, int32_t *volumes, unsigned channels, unsigned length)$/;"     f       file:
-pa_volume_s24_32ne_c   svolume_c.c     /^pa_volume_s24_32ne_c (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)$/;"    f       file:
-pa_volume_s24_32re_c   svolume_c.c     /^pa_volume_s24_32re_c (uint32_t *samples, int32_t *volumes, unsigned channels, unsigned length)$/;"    f       file:
-pa_volume_s24ne_c      svolume_c.c     /^pa_volume_s24ne_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)$/;"        f       file:
-pa_volume_s24re_c      svolume_c.c     /^pa_volume_s24re_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)$/;"        f       file:
-pa_volume_s32ne_c      svolume_c.c     /^pa_volume_s32ne_c (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)$/;"        f       file:
-pa_volume_s32re_c      svolume_c.c     /^pa_volume_s32re_c (int32_t *samples, int32_t *volumes, unsigned channels, unsigned length)$/;"        f       file:
-pa_volume_u8_c svolume_c.c     /^pa_volume_u8_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)$/;"   f       file:
-pa_volume_ulaw_c       svolume_c.c     /^pa_volume_ulaw_c (uint8_t *samples, int32_t *volumes, unsigned channels, unsigned length)$/;" f       file:
-pa_vsnprintf   core-util.c     /^size_t pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) {$/;"     f
-pa_vsprintf_malloc     core-util.c     /^char *pa_vsprintf_malloc(const char *format, va_list ap) {$/;"        f
-pa_will_need   core-util.c     /^void *pa_will_need(const void *p, size_t l) {$/;"     f
-pa_write       core-util.c     /^ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {$/;"      f
-pa_x11_client  x11wrap.c       /^struct pa_x11_client {$/;"    s       file:
-pa_x11_client  x11wrap.h       /^typedef struct pa_x11_client pa_x11_client;$/;"       t       typeref:struct:pa_x11_client
-pa_x11_client_free     x11wrap.c       /^void pa_x11_client_free(pa_x11_client *c) {$/;"       f
-pa_x11_client_new      x11wrap.c       /^pa_x11_client* pa_x11_client_new(pa_x11_wrapper *w, pa_x11_event_cb_t event_cb, pa_x11_kill_cb_t kill_cb, void *userdata) {$/;"       f
-pa_x11_del_prop        x11prop.c       /^void pa_x11_del_prop(Display *d, const char *name) {$/;"      f
-pa_x11_event_cb_t      x11wrap.h       /^typedef int (*pa_x11_event_cb_t)(pa_x11_wrapper *w, XEvent *e, void *userdata);$/;"   t
-pa_x11_get_prop        x11prop.c       /^char* pa_x11_get_prop(Display *d, const char *name, char *p, size_t l) {$/;"  f
-pa_x11_internal        x11wrap.c       /^struct pa_x11_internal {$/;"  s       file:
-pa_x11_internal        x11wrap.c       /^typedef struct pa_x11_internal pa_x11_internal;$/;"   t       typeref:struct:pa_x11_internal  file:
-pa_x11_kill_cb_t       x11wrap.h       /^typedef void (*pa_x11_kill_cb_t)(pa_x11_wrapper *w, void *userdata);$/;"      t
-pa_x11_set_prop        x11prop.c       /^void pa_x11_set_prop(Display *d, const char *name, const char *data) {$/;"    f
-pa_x11_wrapper x11wrap.c       /^struct pa_x11_wrapper {$/;"   s       file:
-pa_x11_wrapper x11wrap.h       /^typedef struct pa_x11_wrapper pa_x11_wrapper;$/;"     t       typeref:struct:pa_x11_wrapper
-pa_x11_wrapper_get     x11wrap.c       /^pa_x11_wrapper* pa_x11_wrapper_get(pa_core *c, const char *name) {$/;"        f
-pa_x11_wrapper_get_display     x11wrap.c       /^Display *pa_x11_wrapper_get_display(pa_x11_wrapper *w) {$/;"  f
-pa_x11_wrapper_kill    x11wrap.c       /^void pa_x11_wrapper_kill(pa_x11_wrapper *w) {$/;"     f
-pa_x11_wrapper_ref     x11wrap.c       /^pa_x11_wrapper* pa_x11_wrapper_ref(pa_x11_wrapper *w) {$/;"   f
-pa_x11_wrapper_unref   x11wrap.c       /^void pa_x11_wrapper_unref(pa_x11_wrapper* w) {$/;"    f
-pa_xfreev      core-util.c     /^void pa_xfreev(void**a) {$/;" f
-pa_xstrfreev   core-util.h     /^static inline void pa_xstrfreev(char **a) {$/;"       f
-pa_yes_no      core-util.h     /^static inline const char *pa_yes_no(pa_bool_t b) {$/;"        f
-pa_zero        macro.h 305;"   d
-packet pstream.c       /^        pa_packet *packet;$/;"        m       struct:pa_pstream::__anon35     file:
-packet pstream.c       /^    pa_packet *packet;$/;"    m       struct:item_info        file:
-parent core.h  /^    pa_msgobject parent;$/;"  m       struct:pa_core
-parent msgobject.h     /^    pa_object parent;$/;"     m       struct:pa_msgobject
-parent play-memblockq.c        /^    pa_msgobject parent;$/;"  m       struct:memblockq_stream file:
-parent protocol-esound.c       /^    pa_msgobject parent;$/;"  m       struct:connection       file:
-parent protocol-native.c       /^    output_stream parent;$/;" m       struct:playback_stream  file:
-parent protocol-native.c       /^    output_stream parent;$/;" m       struct:upload_stream    file:
-parent protocol-native.c       /^    pa_msgobject parent;$/;"  m       struct:output_stream    file:
-parent protocol-native.c       /^    pa_msgobject parent;$/;"  m       struct:pa_native_connection     file:
-parent protocol-native.c       /^    pa_msgobject parent;$/;"  m       struct:record_stream    file:
-parent protocol-simple.c       /^    pa_msgobject parent;$/;"  m       struct:connection       file:
-parent sink-input.h    /^    pa_msgobject parent;$/;"  m       struct:pa_sink_input
-parent sink.h  /^    pa_msgobject parent;$/;"  m       struct:pa_sink
-parent sound-file-stream.c     /^    pa_msgobject parent;$/;"  m       struct:file_stream      file:
-parent source-output.h /^    pa_msgobject parent;$/;"  m       struct:pa_source_output
-parent source.h        /^    pa_msgobject parent;$/;"  m       struct:pa_source
-parse  conf-parser.h   /^    pa_config_parser_cb_t parse; \/* Function that is called to parse the variable's value *\/$/;"    m       struct:pa_config_item
-parse  tokenizer.c     /^static void parse(pa_dynarray*a, const char *s, unsigned args) {$/;"  f       file:
-parse_host     parseaddr.c     /^static char *parse_host(const char *s, uint16_t *ret_port) {$/;"      f       file:
-parse_index    cli-command.c   /^static uint32_t parse_index(const char *n) {$/;"      f       file:
-parse_line     conf-parser.c   /^static int parse_line(const char *filename, unsigned line, char **section, const pa_config_item *t, char *l, void *userdata) {$/;"    f       file:
-path_or_host   parseaddr.h     /^    char *path_or_host;$/;"   m       struct:pa_parsed_address
-pause_time     time-smoother.c /^    pa_usec_t pause_time;$/;" m       struct:pa_smoother      file:
-paused time-smoother.c /^    pa_bool_t paused:1;$/;"   m       struct:pa_smoother      file:
-pdispatch      pdispatch.c     /^    pa_pdispatch *pdispatch;$/;"      m       struct:reply_info       file:
-pdispatch      protocol-native.c       /^    pa_pdispatch *pdispatch;$/;"      m       struct:pa_native_connection     file:
-pdispatch_free pdispatch.c     /^static void pdispatch_free(pa_pdispatch *pd) {$/;"    f       file:
-peaks  resampler.c     /^    } peaks;$/;"      m       struct:pa_resampler     typeref:struct:pa_resampler::__anon38   file:
-peaks_init     resampler.c     /^static int peaks_init(pa_resampler*r) {$/;"   f       file:
-peaks_resample resampler.c     /^static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {$/;"        f       file:
-peaks_update_rates_or_reset    resampler.c     /^static void peaks_update_rates_or_reset(pa_resampler *r) {$/;"        f       file:
-pending        dbus-util.h     /^    DBusPendingCall *pending;$/;"     m       struct:pa_dbus_pending
-per_type       memblock.c      /^    } per_type;$/;"   m       struct:pa_memblock      typeref:union:pa_memblock::__anon4      file:
-phase_mask     ffmpeg/resample2.c      /^    int phase_mask;$/;"       m       struct:AVResampleContext        file:
-phase_shift    ffmpeg/resample2.c      /^    int phase_shift;$/;"      m       struct:AVResampleContext        file:
-pid    shm.c   /^    pa_atomic_t pid;$/;"      m       struct:shm_marker       file:
-ping   lock-autospawn.c        /^static void ping(void) {$/;"  f       file:
-pipe   pipe.c  /^int pipe(int filedes[2]) {$/;"        f
-pipe_fd        lock-autospawn.c        /^static int pipe_fd[2] = { -1, -1 };$/;"       v       file:
-playback       protocol-esound.c       /^    } playback;$/;"   m       struct:connection       typeref:struct:connection::__anon11     file:
-playback       protocol-simple.c       /^    } playback;$/;"   m       struct:connection       typeref:struct:connection::__anon8      file:
-playback       protocol-simple.h       /^    pa_bool_t playback:1;$/;" m       struct:pa_simple_options
-playback_stream        protocol-native.c       /^typedef struct playback_stream {$/;"  s       file:
-playback_stream        protocol-native.c       /^} playback_stream;$/;"        t       typeref:struct:playback_stream  file:
-playback_stream_free   protocol-native.c       /^static void playback_stream_free(pa_object* o) {$/;"  f       file:
-playback_stream_new    protocol-native.c       /^static playback_stream* playback_stream_new($/;"      f       file:
-playback_stream_process_msg    protocol-native.c       /^static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) {$/;"    f       file:
-playback_stream_request_bytes  protocol-native.c       /^static void playback_stream_request_bytes(playback_stream *s) {$/;"   f       file:
-playback_stream_send_killed    protocol-native.c       /^static void playback_stream_send_killed(playback_stream *p) {$/;"     f       file:
-playback_stream_unlink protocol-native.c       /^static void playback_stream_unlink(playback_stream *s) {$/;"  f       file:
-player_list    esound.h        /^    esd_player_info_t *player_list;$/;"       m       struct:esd_info
-playing_for    protocol-native.c       /^    uint64_t playing_for, underrun_for;$/;"   m       struct:playback_stream  file:
-playing_for    sink-input.h    /^        uint64_t underrun_for, playing_for;$/;"       m       struct:pa_sink_input::__anon27
-please_signal  memblock.c      /^    pa_atomic_t please_signal;$/;"    m       struct:pa_memblock      file:
-points envelope.c      /^    } points[2];$/;"  m       struct:pa_envelope      typeref:struct:pa_envelope::__anon23    file:
-points_x       envelope.h      /^    pa_usec_t points_x[PA_ENVELOPE_POINTS_MAX];$/;"   m       struct:pa_envelope_def
-points_y       envelope.h      /^    } points_y;$/;"   m       struct:pa_envelope_def  typeref:struct:pa_envelope_def::__anon21
-poll   poll.c  /^int poll (struct pollfd *fds, unsigned long int nfds, int timeout) {$/;"      f
-pollfd poll.h  /^struct pollfd$/;"     s
-pollfd rtpoll.c        /^    struct pollfd *pollfd, *pollfd2;$/;"      m       struct:pa_rtpoll        typeref:struct:pa_rtpoll::pollfd        file:
-pollfd rtpoll.c        /^    struct pollfd *pollfd;$/;"        m       struct:pa_rtpoll_item   typeref:struct:pa_rtpoll_item::pollfd   file:
-pollfd2        rtpoll.c        /^    struct pollfd *pollfd, *pollfd2;$/;"      m       struct:pa_rtpoll        typeref:struct:pa_rtpoll::      file:
-pool   memblock.c      /^    pa_mempool *pool;$/;"     m       struct:pa_memblock      file:
-pool   memblock.c      /^    pa_mempool *pool;$/;"     m       struct:pa_memexport     file:
-pool   memblock.c      /^    pa_mempool *pool;$/;"     m       struct:pa_memimport     file:
-pop    sink-input.h    /^    int (*pop) (pa_sink_input *i, size_t request_nbytes, pa_memchunk *chunk); \/* may NOT be NULL *\/$/;"     m       struct:pa_sink_input
-port   parseaddr.h     /^    uint16_t port;$/;"        m       struct:pa_parsed_address
-ports  sink.h  /^    pa_hashmap *ports;$/;"    m       struct:pa_sink
-ports  sink.h  /^    pa_hashmap *ports;$/;"    m       struct:pa_sink_new_data
-ports  source.h        /^    pa_hashmap *ports;$/;"    m       struct:pa_source
-ports  source.h        /^    pa_hashmap *ports;$/;"    m       struct:pa_source_new_data
-prebuf memblockq.c     /^    size_t maxlength, tlength, base, prebuf, minreq, maxrewind;$/;"   m       struct:pa_memblockq     file:
-prepare_next_write_item        pstream.c       /^static void prepare_next_write_item(pa_pstream *p) {$/;"      f       file:
-prev   memblockq.c     /^    struct list_item *next, *prev;$/;"        m       struct:list_item        typeref:struct:list_item::      file:
-prev   memtrap.c       /^    pa_memtrap *next[2], *prev[2];$/;"        m       struct:pa_memtrap       file:
-priority       card.h  /^    unsigned priority;$/;"    m       struct:pa_card_profile
-priority       hook-list.h     /^    pa_hook_priority_t priority;$/;"  m       struct:pa_hook_slot
-priority       rtpoll.c        /^    pa_rtpoll_priority_t priority;$/;"        m       struct:pa_rtpoll_item   file:
-priority       sink.h  /^    unsigned priority;$/;"    m       struct:pa_device_port
-priority       sink.h  /^    unsigned priority;$/;"    m       struct:pa_sink
-priority       source.h        /^    unsigned priority;$/;"    m       struct:pa_source
-proc   cli-command.c   /^    int (*proc) (pa_core *c, pa_tokenizer*t, pa_strbuf *buf, pa_bool_t *fail);$/;"    m       struct:command  file:
-proc   protocol-esound.c       /^    int (*proc)(connection *c, esd_proto_t request, const void *data, size_t length);$/;"     m       struct:proto_handler    file:
-proc_name_ours pid.c   /^static int proc_name_ours(pid_t pid, const char *procname) {$/;"      f       file:
-process_msg    msgobject.h     /^    int (*process_msg)(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk);$/;"    m       struct:pa_msgobject
-process_rewind sink-input.h    /^    void (*process_rewind) (pa_sink_input *i, size_t nbytes);     \/* may NOT be NULL *\/$/;" m       struct:pa_sink_input
-process_rewind source-output.h /^    void (*process_rewind)(pa_source_output *o, size_t nbytes); \/* may be NULL *\/$/;"       m       struct:pa_source_output
-profiles       card.h  /^    pa_hashmap *profiles;$/;" m       struct:pa_card
-profiles       card.h  /^    pa_hashmap *profiles;$/;" m       struct:pa_card_new_data
-propagate_real_volume  sink.c  /^static void propagate_real_volume(pa_sink *s, const pa_cvolume *old_real_volume) {$/;"        f       file:
-propagate_reference_volume     sink.c  /^static void propagate_reference_volume(pa_sink *s) {$/;"      f       file:
-property_name  dbus-shared.c   /^    const char *property_name;$/;"    m       struct:pa_dbus_connection       file:
-property_name  x11wrap.c       /^    char *property_name;$/;"  m       struct:pa_x11_wrapper   file:
-proplist       card.h  /^    pa_proplist *proplist;$/;"        m       struct:pa_card
-proplist       card.h  /^    pa_proplist *proplist;$/;"        m       struct:pa_card_new_data
-proplist       client.h        /^    pa_proplist *proplist;$/;"        m       struct:pa_client
-proplist       client.h        /^    pa_proplist *proplist;$/;"        m       struct:pa_client_new_data
-proplist       core-scache.h   /^    pa_proplist *proplist;$/;"        m       struct:pa_scache_entry
-proplist       module.h        /^    pa_proplist *proplist;$/;"        m       struct:pa_module
-proplist       protocol-native.c       /^    pa_proplist *proplist;$/;"        m       struct:upload_stream    file:
-proplist       sink-input.h    /^    pa_proplist *proplist;$/;"        m       struct:pa_sink_input
-proplist       sink-input.h    /^    pa_proplist *proplist;$/;"        m       struct:pa_sink_input_new_data
-proplist       sink.h  /^    pa_proplist *proplist;$/;"        m       struct:pa_sink
-proplist       sink.h  /^    pa_proplist *proplist;$/;"        m       struct:pa_sink_new_data
-proplist       source-output.h /^    pa_proplist *proplist;$/;"        m       struct:pa_source_output
-proplist       source-output.h /^    pa_proplist *proplist;$/;"        m       struct:pa_source_output_new_data
-proplist       source.h        /^    pa_proplist *proplist;$/;"        m       struct:pa_source
-proplist       source.h        /^    pa_proplist *proplist;$/;"        m       struct:pa_source_new_data
-proto_handler  protocol-esound.c       /^typedef struct proto_handler {$/;"    s       file:
-proto_map      protocol-esound.c       /^static struct proto_handler proto_map[ESD_PROTO_MAX] = {$/;"  v       typeref:struct:proto_handler    file:
-protocol       protocol-esound.c       /^    pa_esound_protocol *protocol;$/;" m       struct:connection       file:
-protocol       protocol-http.c /^    pa_http_protocol *protocol;$/;"   m       struct:connection       file:
-protocol       protocol-native.c       /^    pa_native_protocol *protocol;$/;" m       struct:pa_native_connection     file:
-protocol       protocol-simple.c       /^    pa_simple_protocol *protocol;$/;" m       struct:connection       file:
-protocol_error protocol-native.c       /^static void protocol_error(pa_native_connection *c) {$/;"     f       file:
-pstream        protocol-native.c       /^    pa_pstream *pstream;$/;"  m       struct:pa_native_connection     file:
-pstream_die_callback   protocol-native.c       /^static void pstream_die_callback(pa_pstream *p, void *userdata) {$/;" f       file:
-pstream_drain_callback protocol-native.c       /^static void pstream_drain_callback(pa_pstream *p, void *userdata) {$/;"       f       file:
-pstream_free   pstream.c       /^static void pstream_free(pa_pstream *p) {$/;" f       file:
-pstream_memblock_callback      protocol-native.c       /^static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata) {$/;"   f       file:
-pstream_packet_callback        protocol-native.c       /^static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) {$/;"    f       file:
-pstream_release_callback       protocol-native.c       /^static void pstream_release_callback(pa_pstream *p, uint32_t block_id, void *userdata) {$/;"  f       file:
-pstream_revoke_callback        protocol-native.c       /^static void pstream_revoke_callback(pa_pstream *p, uint32_t block_id, void *userdata) {$/;"   f       file:
-ptr    mutex.h /^    pa_atomic_ptr_t ptr;$/;"  m       struct:pa_static_mutex
-ptr    sample-util.h   /^    void *ptr;$/;"    m       struct:pa_mix_info
-ptr    semaphore.h     /^    pa_atomic_ptr_t ptr;$/;"  m       struct:pa_static_semaphore
-ptr    shm.h   /^    void *ptr;$/;"    m       struct:pa_shm
-push   asyncq.c        /^static int push(pa_asyncq*l, void *p, pa_bool_t wait_op) {$/;"        f       file:
-push   source-output.h /^    void (*push)(pa_source_output *o, const pa_memchunk *chunk); \/* may NOT be NULL *\/$/;"  m       struct:pa_source_output
-px     time-smoother.c /^    pa_usec_t px, py;     \/* Point p, where we want to reach stability *\/$/;"       m       struct:pa_smoother      file:
-py     time-smoother.c /^    pa_usec_t px, py;     \/* Point p, where we want to reach stability *\/$/;"       m       struct:pa_smoother      file:
-queue_entry    queue.c /^struct queue_entry {$/;"      s       file:
-quit   rtpoll.c        /^    pa_bool_t quit:1;$/;"     m       struct:pa_rtpoll        file:
-random_proper  random.c        /^static int random_proper(void *ret_data, size_t length) {$/;" f       file:
-rate   esound.h        /^    int rate;                   \/* sample rate *\/$/;"       m       struct:esd_player_info
-rate   esound.h        /^    int rate;                   \/* sample rate *\/$/;"       m       struct:esd_sample_info
-rate   esound.h        /^    int rate;                   \/* sample rate *\/$/;"       m       struct:esd_server_info
-rbuf   ioline.c        /^    char *rbuf;$/;"   m       struct:pa_ioline        file:
-rbuf_index     ioline.c        /^    size_t rbuf_length, rbuf_index, rbuf_valid_length;$/;"    m       struct:pa_ioline        file:
-rbuf_length    ioline.c        /^    size_t rbuf_length, rbuf_index, rbuf_valid_length;$/;"    m       struct:pa_ioline        file:
-rbuf_valid_length      ioline.c        /^    size_t rbuf_length, rbuf_index, rbuf_valid_length;$/;"    m       struct:pa_ioline        file:
-read   pstream.c       /^    } read;$/;"       m       struct:pa_pstream       typeref:struct:pa_pstream::__anon35     file:
-read_creds     pstream.c       /^    pa_creds read_creds, write_creds;$/;"     m       struct:pa_pstream       file:
-read_creds_valid       pstream.c       /^    pa_bool_t read_creds_valid, send_creds_now;$/;"   m       struct:pa_pstream       file:
-read_data      database-simple.c       /^static int read_data(FILE *f, void **data, ssize_t *length) {$/;"     f       file:
-read_data      protocol-esound.c       /^    void *read_data;$/;"      m       struct:connection       file:
-read_data_alloc        protocol-esound.c       /^    size_t read_data_alloc, read_data_length;$/;"     m       struct:connection       file:
-read_data_length       protocol-esound.c       /^    size_t read_data_alloc, read_data_length;$/;"     m       struct:connection       file:
-read_event     thread-mq.h     /^    pa_io_event *read_event, *write_event;$/;"        m       struct:pa_thread_mq
-read_fdsem     asyncq.c        /^    pa_fdsem *read_fdsem, *write_fdsem;$/;"   m       struct:pa_asyncq        file:
-read_idx       asyncq.c        /^    unsigned read_idx;$/;"    m       struct:pa_asyncq        file:
-read_idx       flist.c /^    pa_atomic_t read_idx;$/;" m       struct:pa_flist file:
-read_index     memblockq.c     /^    int64_t read_index, write_index;$/;"      m       struct:pa_memblockq     file:
-read_index     protocol-native.c       /^    int64_t read_index, write_index;$/;"      m       struct:playback_stream  file:
-read_lock      aupdate.c       /^    pa_atomic_t read_lock;$/;"        m       struct:pa_aupdate       file:
-read_only      database-simple.c       /^    pa_bool_t read_only;$/;"  m       struct:simple_data      file:
-read_only      memblock.c      /^    pa_bool_t read_only:1;$/;"        m       struct:pa_memblock      file:
-read_pid       pid.c   /^static pid_t read_pid(const char *fn, int fd) {$/;"   f       file:
-read_uint      database-simple.c       /^static int read_uint(FILE *f, uint32_t *res) {$/;"    f       file:
-readable       iochannel.c     /^    pa_bool_t readable;$/;"   m       struct:pa_iochannel     file:
-readf_function sound-file-stream.c     /^    sf_count_t (*readf_function)(SNDFILE *sndfile, void *ptr, sf_count_t frames);$/;" m       struct:file_stream      file:
-real_ratio     sink-input.h    /^    pa_cvolume real_ratio;         \/* The ratio of the stream's volume to the sink's real volume *\/$/;"     m       struct:pa_sink_input
-real_volume    sink.h  /^    pa_cvolume real_volume;      \/* The volume that the hardware is configured to  *\/$/;"   m       struct:pa_sink
-realtime_priority      core.h  /^    int realtime_priority;$/;"        m       struct:pa_core
-realtime_scheduling    core.h  /^    pa_bool_t realtime_scheduling:1;$/;"      m       struct:pa_core
-rebuild_needed rtpoll.c        /^    pa_bool_t rebuild_needed:1;$/;"   m       struct:pa_rtpoll        file:
-recieve_memblock_callback      pstream.c       /^    pa_pstream_memblock_cb_t recieve_memblock_callback;$/;"   m       struct:pa_pstream       file:
-recieve_memblock_callback_userdata     pstream.c       /^    void *recieve_memblock_callback_userdata;$/;"     m       struct:pa_pstream       file:
-recieve_packet_callback        pstream.c       /^    pa_pstream_packet_cb_t recieve_packet_callback;$/;"       m       struct:pa_pstream       file:
-recieve_packet_callback_userdata       pstream.c       /^    void *recieve_packet_callback_userdata;$/;"       m       struct:pa_pstream       file:
-record protocol-simple.h       /^    pa_bool_t record:1;$/;"   m       struct:pa_simple_options
-record_stream  protocol-native.c       /^typedef struct record_stream {$/;"    s       file:
-record_stream  protocol-native.c       /^} record_stream;$/;"  t       typeref:struct:record_stream    file:
-record_stream_free     protocol-native.c       /^static void record_stream_free(pa_object *o) {$/;"    f       file:
-record_stream_new      protocol-native.c       /^static record_stream* record_stream_new($/;"  f       file:
-record_stream_process_msg      protocol-native.c       /^static int record_stream_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) {$/;"      f       file:
-record_stream_send_killed      protocol-native.c       /^static void record_stream_send_killed(record_stream *r) {$/;" f       file:
-record_stream_unlink   protocol-native.c       /^static void record_stream_unlink(record_stream *s) {$/;"      f       file:
-record_streams protocol-native.c       /^    pa_idxset *record_streams, *output_streams;$/;"   m       struct:pa_native_connection     file:
-recorded_env   core-util.c     /^static pa_strlist *recorded_env = NULL;$/;"   v       file:
-reduce asyncq.c        /^static unsigned reduce(pa_asyncq *l, unsigned value) {$/;"    f       file:
-reduce flist.c /^static unsigned reduce(pa_flist *l, unsigned value) {$/;"     f       file:
-ref    lock-autospawn.c        /^static int ref(void) {$/;"    f       file:
-ref    once.h  /^    pa_atomic_t ref, done;$/;"        m       struct:pa_once
-reference_ratio        sink-input.h    /^    pa_cvolume reference_ratio;    \/* The ratio of the stream's volume to the sink's reference volume *\/$/;"        m       struct:pa_sink_input
-reference_volume       sink.h  /^    pa_cvolume reference_volume; \/* The volume exported and taken as reference base for relative sink input volumes *\/$/;"  m       struct:pa_sink
-refresh_muted  sink.h  /^    pa_bool_t refresh_muted:1;$/;"    m       struct:pa_sink
-refresh_muted  source.h        /^    pa_bool_t refresh_muted:1;$/;"    m       struct:pa_source
-refresh_volume sink.h  /^    pa_bool_t refresh_volume:1;$/;"   m       struct:pa_sink
-refresh_volume source.h        /^    pa_bool_t refresh_volume:1;$/;"   m       struct:pa_source
-release_callback       pstream.c       /^    pa_pstream_block_id_cb_t release_callback;$/;"    m       struct:pa_pstream       file:
-release_callback_userdata      pstream.c       /^    void *release_callback_userdata;$/;"      m       struct:pa_pstream       file:
-release_cb     memblock.c      /^    pa_memimport_release_cb_t release_cb;$/;" m       struct:pa_memimport     file:
-remap  resampler.c     /^    pa_remap_t remap;$/;"     m       struct:pa_resampler     file:
-remap_channels resampler.c     /^static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {$/;" f       file:
-remap_channels_matrix_c        remap.c /^static void remap_channels_matrix_c (pa_remap_t *m, void *dst, const void *src, unsigned n) {$/;"     f       file:
-remap_func     remap.c /^static pa_init_remap_func_t remap_func = init_remap_c;$/;"    v       file:
-remap_mono_to_stereo_c remap.c /^static void remap_mono_to_stereo_c (pa_remap_t *m, void *dst, const void *src, unsigned n) {$/;"      f       file:
-remap_mono_to_stereo_mmx       remap_mmx.c     /^static void remap_mono_to_stereo_mmx (pa_remap_t *m, void *dst, const void *src, unsigned n) {$/;"    f       file:
-remap_mono_to_stereo_sse2      remap_sse.c     /^static void remap_mono_to_stereo_sse2 (pa_remap_t *m, void *dst, const void *src, unsigned n) {$/;"   f       file:
-remove_entry   hashmap.c       /^static void remove_entry(pa_hashmap *h, struct hashmap_entry *e) {$/;"        f       file:
-remove_entry   idxset.c        /^static void remove_entry(pa_idxset *s, struct idxset_entry *e) {$/;"  f       file:
-remove_timeout dbus-util.c     /^static void remove_timeout(DBusTimeout *timeout, void *data) {$/;"    f       file:
-remove_watch   dbus-util.c     /^static void remove_watch(DBusWatch *watch, void *data) {$/;"  f       file:
-render_memblockq       sink-input.h    /^        pa_memblockq *render_memblockq;$/;"   m       struct:pa_sink_input::__anon27
-render_memblockq_length        protocol-native.c       /^    size_t render_memblockq_length;$/;"       m       struct:playback_stream  file:
-reply_info     pdispatch.c     /^struct reply_info {$/;"       s       file:
-reply_info_free        pdispatch.c     /^static void reply_info_free(struct reply_info *r) {$/;"       f       file:
-reply_new      protocol-native.c       /^static pa_tagstruct *reply_new(uint32_t tag) {$/;"    f       file:
-request        protocol-esound.c       /^    esd_proto_t request;$/;"  m       struct:connection       file:
-request_rewind sink.h  /^    void (*request_rewind)(pa_sink *s);        \/* dito *\/$/;"       m       struct:pa_sink
-requested      memblockq.c     /^    size_t requested;$/;"     m       struct:pa_memblockq     file:
-requested_latency      sink.h  /^        pa_usec_t requested_latency;$/;"      m       struct:pa_sink::__anon36
-requested_latency      source.h        /^        pa_usec_t requested_latency;$/;"      m       struct:pa_source::__anon2
-requested_latency_valid        sink.h  /^        pa_bool_t requested_latency_valid:1;$/;"      m       struct:pa_sink::__anon36
-requested_latency_valid        source.h        /^        pa_bool_t requested_latency_valid:1;$/;"      m       struct:pa_source::__anon2
-requested_resample_method      sink-input.h    /^    pa_resample_method_t requested_resample_method, actual_resample_method;$/;"       m       struct:pa_sink_input
-requested_resample_method      source-output.h /^    pa_resample_method_t requested_resample_method, actual_resample_method;$/;"       m       struct:pa_source_output
-requested_sink_latency sink-input.h    /^        pa_usec_t requested_sink_latency;$/;" m       struct:pa_sink_input::__anon27
-requested_source_latency       source-output.h /^        pa_usec_t requested_source_latency;$/;"       m       struct:pa_source_output::__anon15
-resample       resampler.c     /^static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) {$/;"       f       file:
-resample_method        core.h  /^    pa_resample_method_t resample_method;$/;" m       struct:pa_core
-resample_method        sink-input.h    /^    pa_resample_method_t resample_method;$/;" m       struct:pa_sink_input_new_data
-resample_method        source-output.h /^    pa_resample_method_t resample_method;$/;" m       struct:pa_source_output_new_data
-resample_methods       resampler.c     /^static const char * const resample_methods[] = {$/;"  v       file:
-resampler      sink-input.h    /^        pa_resampler *resampler;                     \/* may be NULL *\/$/;"  m       struct:pa_sink_input::__anon27
-resampler      source-output.h /^        pa_resampler* resampler;              \/* may be NULL *\/$/;" m       struct:pa_source_output::__anon15
-reset_all_revents      rtpoll.c        /^static void reset_all_revents(pa_rtpoll *p) {$/;"     f       file:
-reset_callbacks        sink-input.c    /^static void reset_callbacks(pa_sink_input *i) {$/;"   f       file:
-reset_callbacks        sink.c  /^static void reset_callbacks(pa_sink *s) {$/;" f       file:
-reset_callbacks        source-output.c /^static void reset_callbacks(pa_source_output *o) {$/;"        f       file:
-reset_callbacks        source.c        /^static void reset_callbacks(pa_source *s) {$/;"       f       file:
-reset_revents  rtpoll.c        /^static void reset_revents(pa_rtpoll_item *i) {$/;"    f       file:
-ret    asyncmsgq.c     /^    int ret;$/;"      m       struct:asyncmsgq_item   file:
-revents        poll.h  /^    short int revents;          \/* Types of events that actually occurred.  *\/$/;"  m       struct:pollfd
-revoke_callback        pstream.c       /^    pa_pstream_block_id_cb_t revoke_callback;$/;"     m       struct:pa_pstream       file:
-revoke_callback_userdata       pstream.c       /^    void *revoke_callback_userdata;$/;"       m       struct:pa_pstream       file:
-revoke_cb      memblock.c      /^    pa_memexport_revoke_cb_t revoke_cb;$/;"   m       struct:pa_memexport     file:
-rewind_nbytes  sink.h  /^        size_t rewind_nbytes;$/;"     m       struct:pa_sink::__anon36
-rewind_requested       sink.h  /^        pa_bool_t rewind_requested;$/;"       m       struct:pa_sink::__anon36
-rewrite_flush  sink-input.h    /^        pa_bool_t rewrite_flush:1, dont_rewind_render:1;$/;"  m       struct:pa_sink_input::__anon27
-rewrite_nbytes sink-input.h    /^        size_t rewrite_nbytes;$/;"    m       struct:pa_sink_input::__anon27
-right_vol_scale        esound.h        /^    int right_vol_scale;$/;"  m       struct:esd_player_info
-right_vol_scale        esound.h        /^    int right_vol_scale;$/;"  m       struct:esd_sample_info
-rindex tagstruct.c     /^    size_t rindex;$/;"        m       struct:pa_tagstruct     file:
-rrobin_index   protocol-native.c       /^    uint32_t rrobin_index;$/;"        m       struct:pa_native_connection     file:
-rtkit_make_high_priority       rtkit.c /^int rtkit_make_high_priority(DBusConnection *connection, pid_t thread, int nice_level) {$/;"  f
-rtkit_make_realtime    rtkit.c /^int rtkit_make_realtime(DBusConnection *connection, pid_t thread, int priority) {$/;" f
-rtpoll rtpoll.c        /^    pa_rtpoll *rtpoll;$/;"    m       struct:pa_rtpoll_item   file:
-rtpoll sink.h  /^        pa_rtpoll *rtpoll;$/;"        m       struct:pa_sink::__anon36
-rtpoll source.h        /^        pa_rtpoll *rtpoll;$/;"        m       struct:pa_source::__anon2
-rtpoll_item_destroy    rtpoll.c        /^static void rtpoll_item_destroy(pa_rtpoll_item *i) {$/;"      f       file:
-rtpoll_rebuild rtpoll.c        /^static void rtpoll_rebuild(pa_rtpoll *p) {$/;"        f       file:
-run_action     pdispatch.c     /^static void run_action(pa_pdispatch *pd, struct reply_info *r, uint32_t command, pa_tagstruct *ts) {$/;"      f       file:
-run_test       sconv_sse.c     /^static void run_test (void) {$/;"     f       file:
-run_test       svolume_arm.c   /^static void run_test (void) {$/;"     f       file:
-run_test       svolume_mmx.c   /^static void run_test (void) {$/;"     f       file:
-run_test       svolume_sse.c   /^static void run_test (void) {$/;"     f       file:
-running        rtpoll.c        /^    pa_bool_t running:1;$/;"  m       struct:pa_rtpoll        file:
-running        thread-posix.c  /^    pa_atomic_t running;$/;"  m       struct:pa_thread        file:
-running_as_daemon      core.h  /^    pa_bool_t running_as_daemon:1;$/;"        m       struct:pa_core
-ry     time-smoother.c /^    pa_usec_t ry;         \/* The original y value for ex *\/$/;"     m       struct:pa_smoother      file:
-s16ne_to_s16ne sconv.c /^static void s16ne_to_s16ne(unsigned n, const int16_t *a, int16_t *b) {$/;"    f       file:
-s16re_to_s16ne sconv.c /^static void s16re_to_s16ne(unsigned n, const int16_t *a, int16_t *b) {$/;"    f       file:
-sample_id      esound.h        /^    int sample_id;              \/* either a stream fd or sample id *\/$/;"   m       struct:esd_sample_info
-sample_list    esound.h        /^    esd_sample_info_t *sample_list;$/;"       m       struct:esd_info
-sample_spec    core-scache.h   /^    pa_sample_spec sample_spec;$/;"   m       struct:pa_scache_entry
-sample_spec    envelope.c      /^    pa_sample_spec sample_spec;$/;"   m       struct:pa_envelope      file:
-sample_spec    protocol-esound.c       /^        pa_sample_spec sample_spec;$/;"       m       struct:connection::__anon12     file:
-sample_spec    protocol-native.c       /^    pa_sample_spec sample_spec;$/;"   m       struct:upload_stream    file:
-sample_spec    protocol-simple.h       /^    pa_sample_spec sample_spec;$/;"   m       struct:pa_simple_options
-sample_spec    sink-input.h    /^        pa_sample_spec sample_spec;$/;"       m       struct:pa_sink_input::__anon27
-sample_spec    sink-input.h    /^    pa_sample_spec sample_spec;$/;"   m       struct:pa_sink_input
-sample_spec    sink-input.h    /^    pa_sample_spec sample_spec;$/;"   m       struct:pa_sink_input_new_data
-sample_spec    sink.h  /^    pa_sample_spec sample_spec;$/;"   m       struct:pa_sink
-sample_spec    sink.h  /^    pa_sample_spec sample_spec;$/;"   m       struct:pa_sink_new_data
-sample_spec    source-output.h /^        pa_sample_spec sample_spec;$/;"       m       struct:pa_source_output::__anon15
-sample_spec    source-output.h /^    pa_sample_spec sample_spec;$/;"   m       struct:pa_source_output
-sample_spec    source-output.h /^    pa_sample_spec sample_spec;$/;"   m       struct:pa_source_output_new_data
-sample_spec    source.h        /^    pa_sample_spec sample_spec;$/;"   m       struct:pa_source
-sample_spec    source.h        /^    pa_sample_spec sample_spec;$/;"   m       struct:pa_source_new_data
-sample_spec_is_set     sink-input.h    /^    pa_bool_t sample_spec_is_set:1;$/;"       m       struct:pa_sink_input_new_data
-sample_spec_is_set     sink.h  /^    pa_bool_t sample_spec_is_set:1;$/;"       m       struct:pa_sink_new_data
-sample_spec_is_set     source-output.h /^    pa_bool_t sample_spec_is_set:1;$/;"       m       struct:pa_source_output_new_data
-sample_spec_is_set     source.h        /^    pa_bool_t sample_spec_is_set:1;$/;"       m       struct:pa_source_new_data
-save_muted     sink-input.h    /^    pa_bool_t save_sink:1, save_volume:1, save_muted:1;$/;"   m       struct:pa_sink_input
-save_muted     sink-input.h    /^    pa_bool_t save_sink:1, save_volume:1, save_muted:1;$/;"   m       struct:pa_sink_input_new_data
-save_muted     sink.h  /^    pa_bool_t save_muted:1;$/;"       m       struct:pa_sink
-save_muted     sink.h  /^    pa_bool_t save_muted:1;$/;"       m       struct:pa_sink_new_data
-save_muted     source.h        /^    pa_bool_t save_muted:1;$/;"       m       struct:pa_source
-save_muted     source.h        /^    pa_bool_t save_muted:1;$/;"       m       struct:pa_source_new_data
-save_port      sink.h  /^    pa_bool_t save_port:1;$/;"        m       struct:pa_sink
-save_port      sink.h  /^    pa_bool_t save_port:1;$/;"        m       struct:pa_sink_new_data
-save_port      source.h        /^    pa_bool_t save_port:1;$/;"        m       struct:pa_source
-save_port      source.h        /^    pa_bool_t save_port:1;$/;"        m       struct:pa_source_new_data
-save_profile   card.h  /^    pa_bool_t save_profile:1;$/;"     m       struct:pa_card
-save_profile   card.h  /^    pa_bool_t save_profile:1;$/;"     m       struct:pa_card_new_data
-save_sink      sink-input.h    /^    pa_bool_t save_sink:1, save_volume:1, save_muted:1;$/;"   m       struct:pa_sink_input
-save_sink      sink-input.h    /^    pa_bool_t save_sink:1, save_volume:1, save_muted:1;$/;"   m       struct:pa_sink_input_new_data
-save_source    source-output.h /^    pa_bool_t save_source:1;$/;"      m       struct:pa_source_output
-save_source    source-output.h /^    pa_bool_t save_source:1;$/;"      m       struct:pa_source_output_new_data
-save_volume    sink-input.h    /^    pa_bool_t save_sink:1, save_volume:1, save_muted:1;$/;"   m       struct:pa_sink_input
-save_volume    sink-input.h    /^    pa_bool_t save_sink:1, save_volume:1, save_muted:1;$/;"   m       struct:pa_sink_input_new_data
-save_volume    sink.h  /^    pa_bool_t save_volume:1;$/;"      m       struct:pa_sink
-save_volume    sink.h  /^    pa_bool_t save_volume:1;$/;"      m       struct:pa_sink_new_data
-save_volume    source.h        /^    pa_bool_t save_volume:1;$/;"      m       struct:pa_source
-save_volume    source.h        /^    pa_bool_t save_volume:1;$/;"      m       struct:pa_source_new_data
-scache core.h  /^    pa_idxset *clients, *cards, *sinks, *sources, *sink_inputs, *source_outputs, *modules, *scache;$/;"       m       struct:pa_core
-scache protocol-esound.c       /^    } scache;$/;"     m       struct:connection       typeref:struct:connection::__anon12     file:
-scache_add_item        core-scache.c   /^static pa_scache_entry* scache_add_item(pa_core *c, const char *name) {$/;"   f       file:
-scache_auto_unload_event       core.h  /^    pa_time_event *scache_auto_unload_event;$/;"      m       struct:pa_core
-scache_fill_tagstruct  protocol-native.c       /^static void scache_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_scache_entry *e) {$/;" f       file:
-scache_idle_time       core.h  /^    int exit_idle_time, scache_idle_time;$/;" m       struct:pa_core
-scan_for_dead  rtpoll.c        /^    pa_bool_t scan_for_dead:1;$/;"    m       struct:pa_rtpoll        file:
-scan_for_lines ioline.c        /^static void scan_for_lines(pa_ioline *l, size_t skip) {$/;"   f       file:
-sched_event    core-subscribe.c        /^static void sched_event(pa_core *c) {$/;"     f       file:
-search g711.c  /^static int16_t search($/;"    f       file:
-section        conf-parser.h   /^    const char *section;$/;"  m       struct:pa_config_item
-seek_mode      pstream.c       /^    pa_seek_mode_t seek_mode;$/;"     m       struct:item_info        file:
-seg_aend       g711.c  /^static int16_t seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,$/;"     v       file:
-seg_uend       g711.c  /^static int16_t seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,$/;"    v       file:
-segment        memblock.c      /^            pa_memimport_segment *segment;$/;"        m       struct:pa_memblock::__anon4::__anon6    file:
-segment_attach memblock.c      /^static pa_memimport_segment* segment_attach(pa_memimport *i, uint32_t shm_id) {$/;"   f       file:
-segment_detach memblock.c      /^static void segment_detach(pa_memimport_segment *seg) {$/;"   f       file:
-segment_name   shm.c   /^static char *segment_name(char *fn, size_t l, unsigned id) {$/;"      f       file:
-segments       memblock.c      /^    pa_hashmap *segments;$/;" m       struct:pa_memimport     file:
-sem    semaphore-posix.c       /^    sem_t sem;$/;"    m       struct:pa_semaphore     file:
-sema   semaphore-win32.c       /^    HANDLE sema;$/;"  m       struct:pa_semaphore     file:
-semaphore      asyncmsgq.c     /^    pa_semaphore *semaphore;$/;"      m       struct:asyncmsgq_item   file:
-semaphore      aupdate.c       /^    pa_semaphore *semaphore;$/;"      m       struct:pa_aupdate       file:
-semaphore      envelope.c      /^    pa_semaphore *semaphore;$/;"      m       struct:pa_envelope      file:
-semaphore      memblock.c      /^    pa_semaphore *semaphore;$/;"      m       struct:pa_mempool       file:
-send_creds_now pstream.c       /^    pa_bool_t read_creds_valid, send_creds_now;$/;"   m       struct:pa_pstream       file:
-send_event     client.h        /^    void (*send_event)(pa_client *c, const char *name, pa_proplist *data);$/;"        m       struct:pa_client
-send_event     sink-input.h    /^    void (*send_event)(pa_sink_input *i, const char *event, pa_proplist* data); \/* may be NULL *\/$/;"       m       struct:pa_sink_input
-send_event     source-output.h /^    void (*send_event)(pa_source_output *o, const char *event, pa_proplist* data);$/;"        m       struct:pa_source_output
-send_queue     pstream.c       /^    pa_queue *send_queue;$/;" m       struct:pa_pstream       file:
-server esound.h        /^    esd_server_info_t *server;  \/* the server that contains this sample *\/$/;"      m       struct:esd_sample_info
-server esound.h        /^    esd_server_info_t *server;  \/* the server that contains this stream *\/$/;"      m       struct:esd_player_info
-server esound.h        /^    esd_server_info_t *server;$/;"    m       struct:esd_info
-servers        protocol-http.c /^    pa_strlist *servers;$/;"  m       struct:pa_http_protocol file:
-servers        protocol-native.c       /^    pa_strlist *servers;$/;"  m       struct:pa_native_protocol       file:
-set_block      pipe.c  /^static int set_block(int fd, int blocking) {$/;"      f       file:
-set_mute       sink.h  /^    void (*set_mute)(pa_sink *s);               \/* dito *\/$/;"      m       struct:pa_sink
-set_mute       source.h        /^    void (*set_mute)(pa_source *s);           \/* dito *\/$/;"        m       struct:pa_source
-set_nice       core-util.c     /^static int set_nice(int nice_level) {$/;"     f       file:
-set_port       sink.h  /^    int (*set_port)(pa_sink *s, pa_device_port *port); \/* dito *\/$/;"       m       struct:pa_sink
-set_port       source.h        /^    int (*set_port)(pa_source *s, pa_device_port *port); \/*dito *\/$/;"      m       struct:pa_source
-set_profile    card.h  /^    int (*set_profile)(pa_card *c, pa_card_profile *profile);$/;"     m       struct:pa_card
-set_real_ratio sink-input.c    /^static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v) {$/;"       f       file:
-set_scheduler  core-util.c     /^static int set_scheduler(int rtprio) {$/;"    f       file:
-set_state      sink.h  /^    int (*set_state)(pa_sink *s, pa_sink_state_t state); \/* may be NULL *\/$/;"      m       struct:pa_sink
-set_state      source.h        /^    int (*set_state)(pa_source*source, pa_source_state_t state); \/* may be NULL *\/$/;"      m       struct:pa_source
-set_volume     sink.h  /^    void (*set_volume)(pa_sink *s);             \/* dito *\/$/;"      m       struct:pa_sink
-set_volume     source.h        /^    void (*set_volume)(pa_source *s);         \/* dito *\/$/;"        m       struct:pa_source
-shared core.h  /^    pa_hashmap *namereg, *shared;$/;" m       struct:pa_core
-shared shm.h   /^    pa_bool_t shared:1;$/;"   m       struct:pa_shm
-shared_free    shared.c        /^static void shared_free(pa_shared *p) {$/;"   f       file:
-shared_new     shared.c        /^static pa_shared* shared_new(const char *name, void *data) {$/;"      f       file:
-shm_info       pstream.c       /^        uint32_t shm_info[PA_PSTREAM_SHM_MAX];$/;"    m       struct:pa_pstream::__anon34     file:
-shm_info       pstream.c       /^        uint32_t shm_info[PA_PSTREAM_SHM_MAX];$/;"    m       struct:pa_pstream::__anon35     file:
-shm_marker     shm.c   /^struct shm_marker {$/;"       s       file:
-show_backtrace log.c   /^static unsigned show_backtrace = 0, show_backtrace_override = 0, skip_backtrace = 0;$/;"      v       file:
-show_backtrace_override        log.c   /^static unsigned show_backtrace = 0, show_backtrace_override = 0, skip_backtrace = 0;$/;"      v       file:
-shuffle_down   prioq.c /^static void shuffle_down(pa_prioq *q, unsigned idx) {$/;"     f       file:
-shuffle_up     prioq.c /^static void shuffle_up(pa_prioq *q, pa_prioq_item *i) {$/;"   f       file:
-signal_handler memtrap.c       /^static void signal_handler(int sig, siginfo_t* si, void *data) {$/;"  f       file:
-signalled      fdsem.h /^    pa_atomic_t signalled;$/;"        m       struct:pa_fdsem_data
-sigsafe_error  memtrap.c       /^static void sigsafe_error(const char *s) {$/;"        f       file:
-silence        memblockq.c     /^    pa_memchunk silence;$/;"  m       struct:pa_memblockq     file:
-silence        sink.h  /^    pa_memchunk silence;$/;"  m       struct:pa_sink
-silence        source.h        /^    pa_memchunk silence;$/;"  m       struct:pa_source
-silence_byte   sample-util.c   /^static uint8_t silence_byte(pa_sample_format_t format) {$/;"  f       file:
-silence_cache  core.h  /^    pa_silence_cache silence_cache;$/;"       m       struct:pa_core
-silence_memblock_new   sample-util.c   /^static pa_memblock *silence_memblock_new(pa_mempool *pool, uint8_t c) {$/;"   f       file:
-simple_data    database-simple.c       /^typedef struct simple_data {$/;"      s       file:
-simple_data    database-simple.c       /^} simple_data;$/;"    t       typeref:struct:simple_data      file:
-simple_protocol_new    protocol-simple.c       /^static pa_simple_protocol* simple_protocol_new(pa_core *c) {$/;"      f       file:
-sink   sink-input.h    /^    pa_sink *sink; \/* NULL while we are being moved *\/$/;"  m       struct:pa_sink_input
-sink   sink-input.h    /^    pa_sink *sink;$/;"        m       struct:pa_sink_input_new_data
-sink_fill_tagstruct    protocol-native.c       /^static void sink_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_sink *sink) {$/;"        f       file:
-sink_free      sink.c  /^static void sink_free(pa_object *o) {$/;"     f       file:
-sink_input     play-memblockq.c        /^    pa_sink_input *sink_input;$/;"    m       struct:memblockq_stream file:
-sink_input     protocol-esound.c       /^    pa_sink_input *sink_input;$/;"    m       struct:connection       file:
-sink_input     protocol-native.c       /^    pa_sink_input *sink_input;$/;"    m       struct:playback_stream  file:
-sink_input     protocol-simple.c       /^    pa_sink_input *sink_input;$/;"    m       struct:connection       file:
-sink_input     sink-input.h    /^    pa_sink_input *sink_input;$/;"    m       struct:pa_sink_input_send_event_hook_data
-sink_input     sound-file-stream.c     /^    pa_sink_input *sink_input;$/;"    m       struct:file_stream      file:
-sink_input_fill_tagstruct      protocol-native.c       /^static void sink_input_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_sink_input *s) {$/;"       f       file:
-sink_input_free        sink-input.c    /^static void sink_input_free(pa_object *o) {$/;"       f       file:
-sink_input_kill_cb     play-memblockq.c        /^static void sink_input_kill_cb(pa_sink_input *i) {$/;"        f       file:
-sink_input_kill_cb     protocol-esound.c       /^static void sink_input_kill_cb(pa_sink_input *i) {$/;"        f       file:
-sink_input_kill_cb     protocol-native.c       /^static void sink_input_kill_cb(pa_sink_input *i) {$/;"        f       file:
-sink_input_kill_cb     protocol-simple.c       /^static void sink_input_kill_cb(pa_sink_input *i) {$/;"        f       file:
-sink_input_kill_cb     sound-file-stream.c     /^static void sink_input_kill_cb(pa_sink_input *i) {$/;"        f       file:
-sink_input_moving_cb   protocol-native.c       /^static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {$/;"       f       file:
-sink_input_pop_cb      play-memblockq.c        /^static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {$/;"       f       file:
-sink_input_pop_cb      protocol-esound.c       /^static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) {$/;"       f       file:
-sink_input_pop_cb      protocol-native.c       /^static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk) {$/;"       f       file:
-sink_input_pop_cb      protocol-simple.c       /^static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) {$/;"       f       file:
-sink_input_pop_cb      sound-file-stream.c     /^static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) {$/;"       f       file:
-sink_input_process_msg protocol-esound.c       /^static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {$/;"        f       file:
-sink_input_process_msg protocol-native.c       /^static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {$/;"        f       file:
-sink_input_process_msg protocol-simple.c       /^static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {$/;"        f       file:
-sink_input_process_rewind_cb   play-memblockq.c        /^static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {$/;"       f       file:
-sink_input_process_rewind_cb   protocol-esound.c       /^static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {$/;"       f       file:
-sink_input_process_rewind_cb   protocol-native.c       /^static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {$/;"       f       file:
-sink_input_process_rewind_cb   protocol-simple.c       /^static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {$/;"       f       file:
-sink_input_process_rewind_cb   sound-file-stream.c     /^static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) {$/;"       f       file:
-sink_input_send_event_cb       protocol-native.c       /^static void sink_input_send_event_cb(pa_sink_input *i, const char *event, pa_proplist *pl) {$/;"      f       file:
-sink_input_set_state   sink-input.c    /^static void sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) {$/;" f       file:
-sink_input_state_change_cb     play-memblockq.c        /^static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t state) {$/;"   f       file:
-sink_input_state_change_cb     sound-file-stream.c     /^static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t state) {$/;"   f       file:
-sink_input_suspend_cb  protocol-native.c       /^static void sink_input_suspend_cb(pa_sink_input *i, pa_bool_t suspend) {$/;"  f       file:
-sink_input_update_max_request_cb       protocol-native.c       /^static void sink_input_update_max_request_cb(pa_sink_input *i, size_t nbytes) {$/;"   f       file:
-sink_input_update_max_rewind_cb        play-memblockq.c        /^static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {$/;"    f       file:
-sink_input_update_max_rewind_cb        protocol-esound.c       /^static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {$/;"    f       file:
-sink_input_update_max_rewind_cb        protocol-native.c       /^static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {$/;"    f       file:
-sink_input_update_max_rewind_cb        protocol-simple.c       /^static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {$/;"    f       file:
-sink_input_update_max_rewind_cb        sound-file-stream.c     /^static void sink_input_update_max_rewind_cb(pa_sink_input *i, size_t nbytes) {$/;"    f       file:
-sink_inputs    client.h        /^    pa_idxset *sink_inputs;$/;"       m       struct:pa_client
-sink_inputs    core.h  /^    pa_idxset *clients, *cards, *sinks, *sources, *sink_inputs, *source_outputs, *modules, *scache;$/;"       m       struct:pa_core
-sink_set_state sink.c  /^static int sink_set_state(pa_sink *s, pa_sink_state_t state) {$/;"    f       file:
-sink_state_to_string   cli-text.c      /^static const char *sink_state_to_string(pa_sink_state_t state) {$/;"  f       file:
-sinks  card.h  /^    pa_idxset *sinks;$/;"     m       struct:pa_card
-sinks  core.h  /^    pa_idxset *clients, *cards, *sinks, *sources, *sink_inputs, *source_outputs, *modules, *scache;$/;"       m       struct:pa_core
-size   asyncq.c        /^    unsigned size;$/;"        m       struct:pa_asyncq        file:
-size   auth-cookie.c   /^    size_t size;$/;"  m       struct:pa_auth_cookie   file:
-size   database.h      /^    size_t size;$/;"  m       struct:pa_datum
-size   flist.c /^    unsigned size;$/;"        m       struct:pa_flist file:
-size   memtrap.c       /^    size_t size;$/;"  m       struct:pa_memtrap       file:
-size   shm.h   /^    size_t size;$/;"  m       struct:pa_shm
-skip_backtrace log.c   /^static unsigned show_backtrace = 0, show_backtrace_override = 0, skip_backtrace = 0;$/;"      v       file:
-slept  rtpoll.c        /^    pa_usec_t slept, awake;$/;"       m       struct:pa_rtpoll        file:
-slot_free      hook-list.c     /^static void slot_free(pa_hook *hook, pa_hook_slot *slot) {$/;"        f       file:
-slots  memblock.c      /^    struct memexport_slot slots[PA_MEMEXPORT_SLOTS_MAX];$/;"  m       struct:pa_memexport     typeref:struct:pa_memexport::memexport_slot     file:
-smoothing      time-smoother.c /^    pa_bool_t smoothing:1; \/* If FALSE we skip the polonyomial interpolation step *\/$/;"    m       struct:pa_smoother      file:
-sndfile        sound-file-stream.c     /^    SNDFILE *sndfile;$/;"     m       struct:file_stream      file:
-sockaddr_prepare       socket-client.c /^static int sockaddr_prepare(pa_socket_client *c, const struct sockaddr *sa, size_t salen) {$/;"       f       file:
-socket_client_free     socket-client.c /^static void socket_client_free(pa_socket_client *c) {$/;"     f       file:
-socket_client_new      socket-client.c /^static pa_socket_client* socket_client_new(pa_mainloop_api *m) {$/;"  f       file:
-socket_server_free     socket-server.c /^static void socket_server_free(pa_socket_server*s) {$/;"      f       file:
-soft_muted     sink.h  /^        pa_bool_t soft_muted:1;$/;"   m       struct:pa_sink::__anon36
-soft_muted     source.h        /^        pa_bool_t soft_muted:1;$/;"   m       struct:pa_source::__anon2
-soft_volume    sink-input.h    /^        pa_cvolume soft_volume;$/;"   m       struct:pa_sink_input::__anon27
-soft_volume    sink-input.h    /^    pa_cvolume soft_volume;        \/* The internal software volume we apply to all PCM data while it passes through. Usually calculated as real_ratio * volume_factor *\/$/;"        m       struct:pa_sink_input
-soft_volume    sink.h  /^        pa_cvolume soft_volume;$/;"   m       struct:pa_sink::__anon36
-soft_volume    sink.h  /^    pa_cvolume soft_volume;      \/* The internal software volume we apply to all PCM data while it passes through *\/$/;"    m       struct:pa_sink
-soft_volume    source.h        /^        pa_cvolume soft_volume;$/;"   m       struct:pa_source::__anon2
-soft_volume    source.h        /^    pa_cvolume volume, soft_volume;$/;"       m       struct:pa_source
-soundfilehfoo  sound-file.h    2;"     d
-source source-output.h /^    pa_source *source; \/* NULL while being moved *\/$/;"     m       struct:pa_source_output
-source source-output.h /^    pa_source *source;$/;"    m       struct:pa_source_output_new_data
-source_fill_tagstruct  protocol-native.c       /^static void source_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_source *source) {$/;"  f       file:
-source_free    source.c        /^static void source_free(pa_object *o) {$/;"   f       file:
-source_id      esound.h        /^    int source_id;              \/* either a stream fd or sample id *\/$/;"   m       struct:esd_player_info
-source_output  protocol-esound.c       /^    pa_source_output *source_output;$/;"      m       struct:connection       file:
-source_output  protocol-http.c /^    pa_source_output *source_output;$/;"      m       struct:connection       file:
-source_output  protocol-native.c       /^    pa_source_output *source_output;$/;"      m       struct:record_stream    file:
-source_output  protocol-simple.c       /^    pa_source_output *source_output;$/;"      m       struct:connection       file:
-source_output  source-output.h /^    pa_source_output *source_output;$/;"      m       struct:pa_source_output_send_event_hook_data
-source_output_fill_tagstruct   protocol-native.c       /^static void source_output_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_source_output *s) {$/;" f       file:
-source_output_free     source-output.c /^static void source_output_free(pa_object* mo) {$/;"   f       file:
-source_output_get_latency_cb   protocol-esound.c       /^static pa_usec_t source_output_get_latency_cb(pa_source_output *o) {$/;"      f       file:
-source_output_get_latency_cb   protocol-http.c /^static pa_usec_t source_output_get_latency_cb(pa_source_output *o) {$/;"      f       file:
-source_output_get_latency_cb   protocol-native.c       /^static pa_usec_t source_output_get_latency_cb(pa_source_output *o) {$/;"      f       file:
-source_output_get_latency_cb   protocol-simple.c       /^static pa_usec_t source_output_get_latency_cb(pa_source_output *o) {$/;"      f       file:
-source_output_kill_cb  protocol-esound.c       /^static void source_output_kill_cb(pa_source_output *o) {$/;"  f       file:
-source_output_kill_cb  protocol-http.c /^static void source_output_kill_cb(pa_source_output *o) {$/;"  f       file:
-source_output_kill_cb  protocol-native.c       /^static void source_output_kill_cb(pa_source_output *o) {$/;"  f       file:
-source_output_kill_cb  protocol-simple.c       /^static void source_output_kill_cb(pa_source_output *o) {$/;"  f       file:
-source_output_moving_cb        protocol-native.c       /^static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {$/;"       f       file:
-source_output_process_msg      protocol-http.c /^static int source_output_process_msg(pa_msgobject *m, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {$/;"     f       file:
-source_output_process_msg      protocol-native.c       /^static int source_output_process_msg(pa_msgobject *_o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {$/;"    f       file:
-source_output_push_cb  protocol-esound.c       /^static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) {$/;"        f       file:
-source_output_push_cb  protocol-http.c /^static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) {$/;"        f       file:
-source_output_push_cb  protocol-native.c       /^static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) {$/;"        f       file:
-source_output_push_cb  protocol-simple.c       /^static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) {$/;"        f       file:
-source_output_send_event_cb    protocol-native.c       /^static void source_output_send_event_cb(pa_source_output *o, const char *event, pa_proplist *pl) {$/;"        f       file:
-source_output_set_state        source-output.c /^static void source_output_set_state(pa_source_output *o, pa_source_output_state_t state) {$/;"        f       file:
-source_output_suspend_cb       protocol-native.c       /^static void source_output_suspend_cb(pa_source_output *o, pa_bool_t suspend) {$/;"    f       file:
-source_outputs client.h        /^    pa_idxset *source_outputs;$/;"    m       struct:pa_client
-source_outputs core.h  /^    pa_idxset *clients, *cards, *sinks, *sources, *sink_inputs, *source_outputs, *modules, *scache;$/;"       m       struct:pa_core
-source_set_state       source.c        /^static int source_set_state(pa_source *s, pa_source_state_t state) {$/;"      f       file:
-source_state_to_string cli-text.c      /^static const char *source_state_to_string(pa_source_state_t state) {$/;"      f       file:
-sources        card.h  /^    pa_idxset *sources;$/;"   m       struct:pa_card
-sources        core.h  /^    pa_idxset *clients, *cards, *sinks, *sources, *sink_inputs, *source_outputs, *modules, *scache;$/;"       m       struct:pa_core
-speex  resampler.c     /^    } speex;$/;"      m       struct:pa_resampler     typeref:struct:pa_resampler::__anon40   file:
-speex_free     resampler.c     /^static void speex_free(pa_resampler *r) {$/;" f       file:
-speex_init     resampler.c     /^static int speex_init(pa_resampler *r) {$/;"  f       file:
-speex_resample_float   resampler.c     /^static void speex_resample_float(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {$/;"  f       file:
-speex_resample_int     resampler.c     /^static void speex_resample_int(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {$/;"    f       file:
-speex_reset    resampler.c     /^static void speex_reset(pa_resampler *r) {$/;"        f       file:
-speex_update_rates     resampler.c     /^static void speex_update_rates(pa_resampler *r) {$/;" f       file:
-src    resampler.c     /^    } src;$/;"        m       struct:pa_resampler     typeref:struct:pa_resampler::__anon39   file:
-src_incr       ffmpeg/resample2.c      /^    int src_incr;$/;" m       struct:AVResampleContext        file:
-st_13linear2alaw       g711.c  /^unsigned char st_13linear2alaw($/;"   f
-st_13linear2alaw       g711.h  23;"    d
-st_14linear2ulaw       g711.c  /^unsigned char st_14linear2ulaw($/;"   f
-st_14linear2ulaw       g711.h  33;"    d
-st_alaw2linear16       g711.c  /^int16_t st_alaw2linear16($/;" f
-st_alaw2linear16       g711.h  24;"    d
-st_ulaw2linear16       g711.c  /^int16_t st_ulaw2linear16($/;" f
-st_ulaw2linear16       g711.h  34;"    d
-start  memtrap.c       /^    void *start;$/;"  m       struct:pa_memtrap       file:
-start_thread   lock-autospawn.c        /^static int start_thread(void) {$/;"   f       file:
-start_timeout  socket-client.c /^static void start_timeout(pa_socket_client *c, pa_bool_t use_rtclock) {$/;"   f       file:
-start_x        envelope.c      /^    pa_usec_t start_x;$/;"    m       struct:pa_envelope_item file:
-start_y        envelope.c      /^    } start_y;$/;"    m       struct:pa_envelope_item typeref:union:pa_envelope_item::__anon22        file:
-starting_getgr_buflen  usergroup.c     /^static size_t starting_getgr_buflen(void) {$/;"       f       file:
-starting_getpw_buflen  usergroup.c     /^static size_t starting_getpw_buflen(void) {$/;"       f       file:
-stat   memblock.c      /^    pa_mempool_stat stat;$/;" m       struct:pa_mempool       file:
-stat_add       memblock.c      /^static void stat_add(pa_memblock*b) {$/;"     f       file:
-stat_remove    memblock.c      /^static void stat_remove(pa_memblock *b) {$/;" f       file:
-state  core.h  /^    pa_core_state_t state;$/;"        m       struct:pa_core
-state  envelope.c      /^    pa_atomic_t state;$/;"    m       struct:pa_envelope      file:
-state  lock-autospawn.c        /^} state = STATE_IDLE;$/;"     v       typeref:enum:__anon50   file:
-state  protocol-esound.c       /^    esd_client_state_t state;$/;"     m       struct:connection       file:
-state  protocol-http.c /^    enum state state;$/;"     m       struct:connection       typeref:enum:connection::state  file:
-state  protocol-http.c /^enum state {$/;"      g       file:
-state  resampler.c     /^        SRC_STATE *state;$/;" m       struct:pa_resampler::__anon39   file:
-state  resampler.c     /^        SpeexResamplerState* state;$/;"       m       struct:pa_resampler::__anon40   file:
-state  resampler.c     /^        struct AVResampleContext *state;$/;"  m       struct:pa_resampler::__anon41   typeref:struct:pa_resampler::__anon41::AVResampleContext        file:
-state  sink-input.h    /^        pa_sink_input_state_t state;$/;"      m       struct:pa_sink_input::__anon27
-state  sink-input.h    /^    pa_sink_input_state_t state;$/;"  m       struct:pa_sink_input
-state  sink.h  /^        pa_sink_state_t state;$/;"    m       struct:pa_sink::__anon36
-state  sink.h  /^    pa_sink_state_t state;$/;"        m       struct:pa_sink
-state  source-output.h /^        pa_source_output_state_t state;$/;"   m       struct:pa_source_output::__anon15
-state  source-output.h /^    pa_source_output_state_t state;$/;"       m       struct:pa_source_output
-state  source.h        /^        pa_source_state_t state;$/;"  m       struct:pa_source::__anon2
-state  source.h        /^    pa_source_state_t state;$/;"      m       struct:pa_source
-state_change   sink-input.h    /^    void (*state_change) (pa_sink_input *i, pa_sink_input_state_t state); \/* may be NULL *\/$/;"     m       struct:pa_sink_input
-state_change   source-output.h /^    void (*state_change) (pa_source_output *o, pa_source_output_state_t state); \/* may be NULL *\/$/;"       m       struct:pa_source_output
-stdio_inuse    sioman.c        /^static pa_atomic_t stdio_inuse = PA_ATOMIC_INIT(0);$/;"       v       file:
-strip  conf-parser.c   /^static char *strip(char *s) {$/;"     f       file:
-subscription   protocol-native.c       /^    pa_subscription *subscription;$/;"        m       struct:pa_native_connection     file:
-subscription_cb        protocol-native.c       /^static void subscription_cb(pa_core *core, pa_subscription_event_type_t e, uint32_t idx, void *userdata) {$/;"        f       file:
-subscription_defer_event       core.h  /^    pa_defer_event *subscription_defer_event;$/;"     m       struct:pa_core
-subscription_event_last        core.h  /^    pa_subscription_event *subscription_event_last;$/;"       m       struct:pa_core
-suseconds_t    winsock.h       /^typedef long suseconds_t;$/;" t
-suspend        sink-input.h    /^    void (*suspend) (pa_sink_input *i, pa_bool_t b);   \/* may be NULL *\/$/;"        m       struct:pa_sink_input
-suspend        source-output.h /^    void (*suspend) (pa_source_output *o, pa_bool_t b);   \/* may be NULL *\/$/;"     m       struct:pa_source_output
-suspend_cause  sink.h  /^    pa_suspend_cause_t suspend_cause;$/;"     m       struct:pa_sink
-suspend_cause  source.h        /^    pa_suspend_cause_t suspend_cause;$/;"     m       struct:pa_source
-suspend_within_thread  sink-input.h    /^    void (*suspend_within_thread) (pa_sink_input *i, pa_bool_t b);   \/* may be NULL *\/$/;"  m       struct:pa_sink_input
-suspend_within_thread  source-output.h /^    void (*suspend_within_thread) (pa_source_output *o, pa_bool_t b);   \/* may be NULL *\/$/;"       m       struct:pa_source_output
-swap   prioq.c /^static void swap(pa_prioq *q, unsigned j, unsigned k) {$/;"   f       file:
-swap_byte_order        protocol-esound.c       /^    pa_bool_t authorized, swap_byte_order;$/;"        m       struct:connection       file:
-swapped        aupdate.c       /^    pa_bool_t swapped;$/;"    m       struct:pa_aupdate       file:
-sync_base      sink-input.h    /^    pa_sink_input *sync_base;$/;"     m       struct:pa_sink_input_new_data
-sync_input_volumes_within_thread       sink.c  /^static void sync_input_volumes_within_thread(pa_sink *s) {$/;"        f       file:
-sync_next      sink-input.h    /^        pa_sink_input *sync_prev, *sync_next;$/;"     m       struct:pa_sink_input::__anon27
-sync_next      sink-input.h    /^    pa_sink_input *sync_prev, *sync_next;$/;" m       struct:pa_sink_input
-sync_prev      sink-input.h    /^        pa_sink_input *sync_prev, *sync_next;$/;"     m       struct:pa_sink_input::__anon27
-sync_prev      sink-input.h    /^    pa_sink_input *sync_prev, *sync_next;$/;" m       struct:pa_sink_input
-syncid protocol-native.c       /^    uint32_t syncid;$/;"      m       struct:playback_stream  file:
-tag    pdispatch.c     /^    uint32_t tag;$/;" m       struct:reply_info       file:
-tail   strbuf.c        /^    struct chunk *head, *tail;$/;"    m       struct:pa_strbuf        typeref:struct:pa_strbuf::      file:
-target log.c   /^static pa_log_target_t target = PA_LOG_STDERR, target_override;$/;"   v       file:
-target_override        log.c   /^static pa_log_target_t target = PA_LOG_STDERR, target_override;$/;"   v       file:
-target_override_set    log.c   /^static pa_bool_t target_override_set = FALSE;$/;"     v       file:
-tcpwrap_service        socket-server.c /^    char *tcpwrap_service;$/;"        m       struct:pa_socket_server file:
-thread lock-autospawn.c        /^static pa_thread *thread = NULL;$/;"  v       file:
-thread thread-win32.c  /^    HANDLE thread;$/;"        m       struct:pa_thread        file:
-thread thread-win32.c  /^    HANDLE thread;$/;"        m       struct:pa_tls_monitor   file:
-thread_free_cb thread-posix.c  /^static void thread_free_cb(void *p) {$/;"     f       file:
-thread_func    lock-autospawn.c        /^static void thread_func(void *u) {$/;"        f       file:
-thread_func    thread-posix.c  /^    pa_thread_func_t thread_func;$/;" m       struct:pa_thread        file:
-thread_func    thread-win32.c  /^    pa_thread_func_t thread_func;$/;" m       struct:pa_thread        file:
-thread_info    sink-input.h    /^    } thread_info;$/;"        m       struct:pa_sink_input    typeref:struct:pa_sink_input::__anon27
-thread_info    sink.h  /^    } thread_info;$/;"        m       struct:pa_sink  typeref:struct:pa_sink::__anon36
-thread_info    source-output.h /^    } thread_info;$/;"        m       struct:pa_source_output typeref:struct:pa_source_output::__anon15
-thread_info    source.h        /^ } thread_info;$/;"   m       struct:pa_source        typeref:struct:pa_source::__anon2
-thread_mq      thread-mq.c     /^PA_STATIC_TLS_DECLARE_NO_FREE(thread_mq);$/;" v
-thread_tls     thread-win32.c  /^static pa_tls *thread_tls;$/;"        v       file:
-thread_tls_once        thread-win32.c  /^static pa_once thread_tls_once = PA_ONCE_INIT;$/;"    v       file:
-thread_tls_once_func   thread-win32.c  /^static void thread_tls_once_func(void) {$/;"  f       file:
-time_event     avahi-wrap.c    /^    pa_time_event *time_event;$/;"    m       struct:AvahiTimeout     file:
-time_event     pdispatch.c     /^    pa_time_event *time_event;$/;"    m       struct:reply_info       file:
-time_event_destroy_cb  dbus-util.c     /^static void time_event_destroy_cb(pa_mainloop_api *a, pa_time_event *e, void *userdata) {$/;" f       file:
-time_offset    time-smoother.c /^    pa_usec_t time_offset;$/;"        m       struct:pa_smoother      file:
-timeout        dbus-util.c     /^    DBusTimeout *timeout;$/;" m       struct:timeout_data     file:
-timeout_callback       avahi-wrap.c    /^static void timeout_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {$/;"      f       file:
-timeout_callback       core-scache.c   /^static void timeout_callback(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata) {$/;"     f       file:
-timeout_callback       pdispatch.c     /^static void timeout_callback(pa_mainloop_api*m, pa_time_event*e, const struct timeval *t, void *userdata) {$/;"       f       file:
-timeout_cb     socket-client.c /^static void timeout_cb(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata) {$/;"   f       file:
-timeout_data   dbus-util.c     /^struct timeout_data {$/;"     s       file:
-timeout_event  socket-client.c /^    pa_time_event *timeout_event;$/;" m       struct:pa_socket_client file:
-timeout_free   avahi-wrap.c    /^static void timeout_free(AvahiTimeout *t) {$/;"       f       file:
-timeout_new    avahi-wrap.c    /^static AvahiTimeout* timeout_new(const AvahiPoll *api, const struct timeval *tv, AvahiTimeoutCallback callback, void *userdata) {$/;" f       file:
-timeout_update avahi-wrap.c    /^static void timeout_update(AvahiTimeout *t, const struct timeval *tv) {$/;"   f       file:
-timer_elapsed  rtpoll.c        /^    pa_bool_t timer_elapsed:1;$/;"    m       struct:pa_rtpoll        file:
-timer_enabled  rtpoll.c        /^    pa_bool_t timer_enabled:1;$/;"    m       struct:pa_rtpoll        file:
-timestamp      rtpoll.c        /^    pa_usec_t timestamp;$/;"  m       struct:pa_rtpoll        file:
-tlength        memblockq.c     /^    size_t maxlength, tlength, base, prebuf, minreq, maxrewind;$/;"   m       struct:pa_memblockq     file:
-tmp_filename   database-simple.c       /^    char *tmp_filename;$/;"   m       struct:simple_data      file:
-to_float32ne_table     sconv.c /^static pa_convert_func_t to_float32ne_table[] = {$/;" v       file:
-to_s16ne_table sconv.c /^static pa_convert_func_t to_s16ne_table[] = {$/;"     v       file:
-to_work_format_func    resampler.c     /^    pa_convert_func_t to_work_format_func;$/;"        m       struct:pa_resampler     file:
-toggle_timeout dbus-util.c     /^static void toggle_timeout(DBusTimeout *timeout, void *data) {$/;"    f       file:
-toggle_watch   dbus-util.c     /^static void toggle_watch(DBusWatch *watch, void *data) {$/;"  f       file:
-token_free     tokenizer.c     /^static void token_free(void *p, void *userdata) {$/;" f       file:
-translate_error        rtkit.c /^static int translate_error(const char *name) {$/;"    f       file:
-translate_io_flags     avahi-wrap.c    /^static pa_io_event_flags_t translate_io_flags(AvahiWatchEvent e) {$/;"        f       file:
-translate_io_flags_back        avahi-wrap.c    /^static AvahiWatchEvent translate_io_flags_back(pa_io_event_flags_t e) {$/;"   f       file:
-trap   memblock.c      /^    pa_memtrap *trap;$/;"     m       struct:pa_memimport_segment     file:
-trivial        resampler.c     /^    } trivial;$/;"    m       struct:pa_resampler     typeref:struct:pa_resampler::__anon37   file:
-trivial_init   resampler.c     /^static int trivial_init(pa_resampler*r) {$/;" f       file:
-trivial_resample       resampler.c     /^static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {$/;"      f       file:
-trivial_update_rates_or_reset  resampler.c     /^static void trivial_update_rates_or_reset(pa_resampler *r) {$/;"      f       file:
-type   core-subscribe.c        /^    pa_subscription_event_type_t type;$/;"    m       struct:pa_subscription_event    file:
-type   memblock.c      /^    pa_memblock_type_t type;$/;"      m       struct:pa_memblock      file:
-type   namereg.c       /^    pa_namereg_type_t type;$/;"       m       struct:namereg_entry    file:
-type   packet.h        /^    enum { PA_PACKET_APPENDED, PA_PACKET_DYNAMIC } type;$/;"  m       struct:pa_packet        typeref:enum:pa_packet::__anon26
-type   parseaddr.h     /^    pa_parsed_address_type_t type;$/;"        m       struct:pa_parsed_address
-type   pstream.c       /^    } type;$/;"       m       struct:item_info        typeref:enum:item_info::__anon33        file:
-type   socket-server.c /^    enum { SOCKET_SERVER_GENERIC, SOCKET_SERVER_IPV4, SOCKET_SERVER_UNIX, SOCKET_SERVER_IPV6 } type;$/;"      m       struct:pa_socket_server typeref:enum:pa_socket_server::__anon48 file:
-type_id        object.h        /^    const char *type_id;$/;"  m       struct:pa_object
-u      vector.h        /^    uint8_t u[PA_UINT8_VECTOR_SIZE];$/;"      m       union:pa_uint8_vector
-u8_from_float32ne      sconv.c /^static void u8_from_float32ne(unsigned n, const float *a, uint8_t *b) {$/;"   f       file:
-u8_from_s16ne  sconv.c /^static void u8_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) {$/;"     f       file:
-u8_to_float32ne        sconv.c /^static void u8_to_float32ne(unsigned n, const uint8_t *a, float *b) {$/;"     f       file:
-u8_to_s16ne    sconv.c /^static void u8_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) {$/;"       f       file:
-uid    creds.h /^    uid_t uid;$/;"    m       struct:pa_creds
-ulaw_from_float32ne    sconv.c /^static void ulaw_from_float32ne(unsigned n, const float *a, uint8_t *b) {$/;" f       file:
-ulaw_from_s16ne        sconv.c /^static void ulaw_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) {$/;"   f       file:
-ulaw_to_float32ne      sconv.c /^static void ulaw_to_float32ne(unsigned n, const uint8_t *a, float *b) {$/;"   f       file:
-ulaw_to_s16ne  sconv.c /^static void ulaw_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) {$/;"     f       file:
-underrun       protocol-esound.c       /^        pa_bool_t underrun;$/;"       m       struct:connection::__anon11     file:
-underrun       protocol-simple.c       /^        pa_bool_t underrun;$/;"       m       struct:connection::__anon8      file:
-underrun_for   protocol-native.c       /^    uint64_t playing_for, underrun_for;$/;"   m       struct:playback_stream  file:
-underrun_for   sink-input.h    /^        uint64_t underrun_for, playing_for;$/;"       m       struct:pa_sink_input::__anon27
-unload_requested       module.h        /^    pa_bool_t unload_requested:1;$/;" m       struct:pa_module
-unref  lock-autospawn.c        /^static void unref(pa_bool_t after_fork) {$/;" f       file:
-update_max_request     sink-input.h    /^    void (*update_max_request) (pa_sink_input *i, size_t nbytes); \/* may be NULL *\/$/;"     m       struct:pa_sink_input
-update_max_rewind      sink-input.h    /^    void (*update_max_rewind) (pa_sink_input *i, size_t nbytes); \/* may be NULL *\/$/;"      m       struct:pa_sink_input
-update_max_rewind      source-output.h /^    void (*update_max_rewind) (pa_source_output *o, size_t nbytes); \/* may be NULL *\/$/;"   m       struct:pa_source_output
-update_n_corked        sink-input.c    /^static void update_n_corked(pa_sink_input *i, pa_sink_input_state_t state) {$/;"      f       file:
-update_n_corked        source-output.c /^static void update_n_corked(pa_source_output *o, pa_source_output_state_t state) {$/;"        f       file:
-update_prebuf  memblockq.c     /^static pa_bool_t update_prebuf(pa_memblockq *bq) {$/;"        f       file:
-update_requested_latency       sink.h  /^    void (*update_requested_latency)(pa_sink *s); \/* dito *\/$/;"    m       struct:pa_sink
-update_requested_latency       source.h        /^    void (*update_requested_latency)(pa_source *s); \/* dito *\/$/;"  m       struct:pa_source
-update_sink_fixed_latency      sink-input.h    /^    void (*update_sink_fixed_latency) (pa_sink_input *i); \/* may be NULL *\/$/;"     m       struct:pa_sink_input
-update_sink_latency_range      sink-input.h    /^    void (*update_sink_latency_range) (pa_sink_input *i); \/* may be NULL *\/$/;"     m       struct:pa_sink_input
-update_sink_requested_latency  sink-input.h    /^    void (*update_sink_requested_latency) (pa_sink_input *i); \/* may be NULL *\/$/;" m       struct:pa_sink_input
-update_source_fixed_latency    source-output.h /^    void (*update_source_fixed_latency) (pa_source_output *i); \/* may be NULL *\/$/;"        m       struct:pa_source_output
-update_source_latency_range    source-output.h /^    void (*update_source_latency_range) (pa_source_output *o); \/* may be NULL *\/$/;"        m       struct:pa_source_output
-update_source_requested_latency        source-output.h /^    void (*update_source_requested_latency) (pa_source_output *o); \/* may be NULL *\/$/;"    m       struct:pa_source_output
-upload_stream  protocol-native.c       /^typedef struct upload_stream {$/;"    s       file:
-upload_stream  protocol-native.c       /^} upload_stream;$/;"  t       typeref:struct:upload_stream    file:
-upload_stream_free     protocol-native.c       /^static void upload_stream_free(pa_object *o) {$/;"    f       file:
-upload_stream_new      protocol-native.c       /^static upload_stream* upload_stream_new($/;"  f       file:
-upload_stream_unlink   protocol-native.c       /^static void upload_stream_unlink(upload_stream *s) {$/;"      f       file:
-url    protocol-http.c /^    char *url;$/;"    m       struct:connection       file:
-usage  modinfo.h       /^    char *usage;$/;"  m       struct:pa_modinfo
-use_rtclock    dbus-util.c     /^    pa_bool_t use_rtclock:1;$/;"      m       struct:pa_dbus_wrap_connection  file:
-use_rtclock    pdispatch.c     /^    pa_bool_t use_rtclock;$/;"        m       struct:pa_pdispatch     file:
-use_shm        pstream.c       /^    pa_bool_t use_shm;$/;"    m       struct:pa_pstream       file:
-user   memblock.c      /^        } user;$/;"   m       union:pa_memblock::__anon4      typeref:struct:pa_memblock::__anon4::__anon5    file:
-userdata       asyncmsgq.c     /^    void *userdata;$/;"       m       struct:asyncmsgq_item   file:
-userdata       avahi-wrap.c    /^    void *userdata;$/;"       m       struct:AvahiTimeout     file:
-userdata       avahi-wrap.c    /^    void *userdata;$/;"       m       struct:AvahiWatch       file:
-userdata       card.h  /^    void *userdata;$/;"       m       struct:pa_card
-userdata       cli.c   /^    void *userdata;$/;"       m       struct:pa_cli   file:
-userdata       client.h        /^    void *userdata;$/;"       m       struct:pa_client
-userdata       core-subscribe.c        /^    void *userdata;$/;"       m       struct:pa_subscription  file:
-userdata       iochannel.c     /^    void*userdata;$/;"        m       struct:pa_iochannel     file:
-userdata       ioline.c        /^    void *userdata;$/;"       m       struct:pa_ioline        file:
-userdata       memblock.c      /^    void *userdata;$/;"       m       struct:pa_memexport     file:
-userdata       memblock.c      /^    void *userdata;$/;"       m       struct:pa_memimport     file:
-userdata       module.h        /^    void *userdata;$/;"       m       struct:pa_module
-userdata       pdispatch.c     /^    void *userdata;$/;"       m       struct:reply_info       file:
-userdata       rtpoll.c        /^    void *userdata;$/;"       m       struct:pa_rtpoll_item   file:
-userdata       sample-util.h   /^    void *userdata;$/;"       m       struct:pa_mix_info
-userdata       sink-input.h    /^    void *userdata;$/;"       m       struct:pa_sink_input
-userdata       sink.h  /^    void *userdata;$/;"       m       struct:pa_sink
-userdata       socket-client.c /^    void *userdata;$/;"       m       struct:pa_socket_client file:
-userdata       socket-server.c /^    void *userdata;$/;"       m       struct:pa_socket_server file:
-userdata       source-output.h /^    void *userdata;$/;"       m       struct:pa_source_output
-userdata       source.h        /^    void *userdata;$/;"       m       struct:pa_source
-userdata       thread-posix.c  /^    void *userdata;$/;"       m       struct:pa_thread        file:
-userdata       thread-win32.c  /^    void *userdata;$/;"       m       struct:pa_thread        file:
-userdata       x11wrap.c       /^    void *userdata;$/;"       m       struct:pa_x11_client    file:
-v      vector.h        /^    pa_v16qi v;$/;"   m       union:pa_uint8_vector
-v      vector.h        /^    pa_v4sf v;$/;"    m       union:pa_float_vector
-v      vector.h        /^    pa_v4si v;$/;"    m       union:pa_int32_vector
-v      vector.h        /^    pa_v8hi v;$/;"    m       union:pa_int16_vector
-value  atomic.h        /^    volatile AO_t value;$/;"  m       struct:pa_atomic
-value  atomic.h        /^    volatile AO_t value;$/;"  m       struct:pa_atomic_ptr
-value  atomic.h        /^    volatile int value;$/;"   m       struct:pa_atomic
-value  atomic.h        /^    volatile unsigned int value;$/;"  m       struct:pa_atomic
-value  atomic.h        /^    volatile unsigned long value;$/;" m       struct:pa_atomic_ptr
-value  atomic.h        /^    volatile void *value;$/;" m       struct:pa_atomic_ptr
-value  hashmap.c       /^    void *value;$/;"  m       struct:hashmap_entry    file:
-value  modargs.c       /^    char *key, *value;$/;"    m       struct:entry    file:
-value  prioq.c /^    void *value;$/;"  m       struct:pa_prioq_item    file:
-version        esound.h        /^    int version;                \/* server version encoded as an int *\/$/;"  m       struct:esd_server_info
-version        modinfo.h       /^    char *version;$/;"        m       struct:pa_modinfo
-version        protocol-native.c       /^    uint32_t version;$/;"     m       struct:pa_native_connection     file:
-volume core-scache.h   /^    pa_cvolume volume;$/;"    m       struct:pa_scache_entry
-volume sample-util.h   /^    pa_cvolume volume;$/;"    m       struct:pa_mix_info
-volume sink-input.h    /^    pa_cvolume volume, volume_factor, volume_factor_sink;$/;" m       struct:pa_sink_input_new_data
-volume sink-input.h    /^    pa_cvolume volume;             \/* The volume clients are informed about *\/$/;"  m       struct:pa_sink_input
-volume sink.h  /^    pa_cvolume volume;$/;"    m       struct:pa_sink_new_data
-volume source.h        /^    pa_cvolume volume, soft_volume;$/;"       m       struct:pa_source
-volume source.h        /^    pa_cvolume volume;$/;"    m       struct:pa_source_new_data
-volume_changed sink-input.h    /^    void (*volume_changed)(pa_sink_input *i); \/* may be NULL *\/$/;" m       struct:pa_sink_input
-volume_factor  sink-input.h    /^    pa_cvolume volume, volume_factor, volume_factor_sink;$/;" m       struct:pa_sink_input_new_data
-volume_factor  sink-input.h    /^    pa_cvolume volume_factor;      \/* An internally used volume factor that can be used by modules to apply effects and suchlike without having that visible to the outside *\/$/;"  m       struct:pa_sink_input
-volume_factor_is_set   sink-input.h    /^    pa_bool_t volume_is_set:1, volume_factor_is_set:1, volume_factor_sink_is_set:1;$/;"       m       struct:pa_sink_input_new_data
-volume_factor_sink     sink-input.h    /^    pa_cvolume volume, volume_factor, volume_factor_sink;$/;" m       struct:pa_sink_input_new_data
-volume_factor_sink     sink-input.h    /^    pa_cvolume volume_factor_sink; \/* A second volume factor in format of the sink this stream is connected to *\/$/;"       m       struct:pa_sink_input
-volume_factor_sink_is_set      sink-input.h    /^    pa_bool_t volume_is_set:1, volume_factor_is_set:1, volume_factor_sink_is_set:1;$/;"       m       struct:pa_sink_input_new_data
-volume_is_absolute     sink-input.h    /^    pa_bool_t volume_is_absolute:1;$/;"       m       struct:pa_sink_input_new_data
-volume_is_set  core-scache.h   /^    pa_bool_t volume_is_set;$/;"      m       struct:pa_scache_entry
-volume_is_set  sink-input.h    /^    pa_bool_t volume_is_set:1, volume_factor_is_set:1, volume_factor_sink_is_set:1;$/;"       m       struct:pa_sink_input_new_data
-volume_is_set  sink.h  /^    pa_bool_t volume_is_set:1;$/;"    m       struct:pa_sink_new_data
-volume_is_set  source.h        /^    pa_bool_t volume_is_set:1;$/;"    m       struct:pa_source_new_data
-volume_val     sample-util.c   /^} volume_val;$/;"     t       typeref:union:__anon7   file:
-w_sz   resampler.c     /^    size_t i_fz, o_fz, w_sz;$/;"      m       struct:pa_resampler     file:
-wait_events    mutex-win32.c   /^    pa_hashmap *wait_events;$/;"      m       struct:pa_cond  file:
-wait_for_ping  lock-autospawn.c        /^static void wait_for_ping(void) {$/;" f       file:
-waiting        fdsem.h /^    pa_atomic_t waiting;$/;"  m       struct:pa_fdsem_data
-waiting_for_post       asyncq.c        /^    pa_bool_t waiting_for_post;$/;"   m       struct:pa_asyncq        file:
-wakeup_main    dbus-util.c     /^static void wakeup_main(void *userdata) {$/;" f       file:
-wallclock_from_rtclock core-rtclock.c  /^static struct timeval* wallclock_from_rtclock(struct timeval *tv) {$/;"       f       file:
-watch_callback avahi-wrap.c    /^static void watch_callback(pa_mainloop_api*a, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) {$/;"       f       file:
-watch_free     avahi-wrap.c    /^static void watch_free(AvahiWatch *w) {$/;"   f       file:
-watch_get_events       avahi-wrap.c    /^static AvahiWatchEvent watch_get_events(AvahiWatch *w) {$/;"  f       file:
-watch_new      avahi-wrap.c    /^static AvahiWatch* watch_new(const AvahiPoll *api, int fd, AvahiWatchEvent event, AvahiWatchCallback callback, void *userdata) {$/;"  f       file:
-watch_update   avahi-wrap.c    /^static void watch_update(AvahiWatch *w, AvahiWatchEvent event) {$/;"  f       file:
-wbuf   ioline.c        /^    char *wbuf;$/;"   m       struct:pa_ioline        file:
-wbuf_index     ioline.c        /^    size_t wbuf_length, wbuf_index, wbuf_valid_length;$/;"    m       struct:pa_ioline        file:
-wbuf_length    ioline.c        /^    size_t wbuf_length, wbuf_index, wbuf_valid_length;$/;"    m       struct:pa_ioline        file:
-wbuf_valid_length      ioline.c        /^    size_t wbuf_length, wbuf_index, wbuf_valid_length;$/;"    m       struct:pa_ioline        file:
-whitespace     cli-command.c   /^static const char whitespace[] = " \\t\\n\\r";$/;"    v       file:
-with_creds     pstream.c       /^    pa_bool_t with_creds;$/;" m       struct:item_info        file:
-work   x11wrap.c       /^static void work(pa_x11_wrapper *w) {$/;"     f       file:
-work_cb        rtpoll.c        /^    int (*work_cb)(pa_rtpoll_item *i);$/;"    m       struct:pa_rtpoll_item   file:
-work_format    resampler.c     /^    pa_sample_format_t work_format;$/;"       m       struct:pa_resampler     file:
-wrapper        x11wrap.c       /^    pa_x11_wrapper *wrapper;$/;"      m       struct:pa_x11_client    file:
-wrapper        x11wrap.c       /^    pa_x11_wrapper *wrapper;$/;"      m       struct:pa_x11_internal  file:
-writable       iochannel.c     /^    pa_bool_t writable;$/;"   m       struct:pa_iochannel     file:
-write  pstream.c       /^    } write;$/;"      m       struct:pa_pstream       typeref:struct:pa_pstream::__anon34     file:
-write_creds    pstream.c       /^    pa_creds read_creds, write_creds;$/;"     m       struct:pa_pstream       file:
-write_data     database-simple.c       /^static int write_data(FILE *f, void *data, const size_t length) {$/;" f       file:
-write_data     protocol-esound.c       /^    void *write_data;$/;"     m       struct:connection       file:
-write_data_alloc       protocol-esound.c       /^    size_t write_data_alloc, write_data_index, write_data_length;$/;" m       struct:connection       file:
-write_data_index       protocol-esound.c       /^    size_t write_data_alloc, write_data_index, write_data_length;$/;" m       struct:connection       file:
-write_data_length      protocol-esound.c       /^    size_t write_data_alloc, write_data_index, write_data_length;$/;" m       struct:connection       file:
-write_entry    database-simple.c       /^static int write_entry(FILE *f, const entry *e) {$/;" f       file:
-write_event    thread-mq.h     /^    pa_io_event *read_event, *write_event;$/;"        m       struct:pa_thread_mq
-write_fdsem    asyncq.c        /^    pa_fdsem *read_fdsem, *write_fdsem;$/;"   m       struct:pa_asyncq        file:
-write_idx      asyncq.c        /^    unsigned write_idx;$/;"   m       struct:pa_asyncq        file:
-write_idx      flist.c /^    pa_atomic_t write_idx;$/;"        m       struct:pa_flist file:
-write_index    memblockq.c     /^    int64_t read_index, write_index;$/;"      m       struct:pa_memblockq     file:
-write_index    protocol-native.c       /^    int64_t read_index, write_index;$/;"      m       struct:playback_stream  file:
-write_lock     aupdate.c       /^    pa_mutex *write_lock;$/;" m       struct:pa_aupdate       file:
-write_uint     database-simple.c       /^static int write_uint(FILE *f, const uint32_t num) {$/;"      f       file:
-x      envelope.c      /^        size_t *x;$/;"        m       struct:pa_envelope::__anon23    file:
-x      envelope.c      /^    size_t x;$/;"     m       struct:pa_envelope      file:
-x11_internal_add       x11wrap.c       /^static pa_x11_internal* x11_internal_add(pa_x11_wrapper *w, int fd) {$/;"     f       file:
-x11_internal_remove    x11wrap.c       /^static void x11_internal_remove(pa_x11_wrapper *w, pa_x11_internal *i) {$/;"  f       file:
-x11_watch      x11wrap.c       /^static void x11_watch(Display *display, XPointer userdata, int fd, Bool opening, XPointer *watch_data) {$/;"  f       file:
-x11_wrapper_free       x11wrap.c       /^static void x11_wrapper_free(pa_x11_wrapper*w) {$/;"  f       file:
-x11_wrapper_new        x11wrap.c       /^static pa_x11_wrapper* x11_wrapper_new(pa_core *c, const char *name, const char *t) {$/;"     f       file:
-y      envelope.c      /^        } y;$/;"      m       struct:pa_envelope::__anon23    typeref:union:pa_envelope::__anon23::__anon24   file:
index 330b759..762947a 100644 (file)
@@ -35,7 +35,7 @@
 
 #include <pulse/xmalloc.h>
 
-#include <pulsecore/winsock.h>
+#include <pulsecore/socket.h>
 #include <pulsecore/macro.h>
 
 #include "tagstruct.h"
@@ -228,6 +228,7 @@ void pa_tagstruct_put_channel_map(pa_tagstruct *t, const pa_channel_map *map) {
     unsigned i;
 
     pa_assert(t);
+    pa_assert(map);
     extend(t, 2 + (size_t) map->channels);
 
     t->data[t->length++] = PA_TAG_CHANNEL_MAP;
@@ -242,6 +243,7 @@ void pa_tagstruct_put_cvolume(pa_tagstruct *t, const pa_cvolume *cvolume) {
     pa_volume_t vol;
 
     pa_assert(t);
+    pa_assert(cvolume);
     extend(t, 2 + cvolume->channels * sizeof(pa_volume_t));
 
     t->data[t->length++] = PA_TAG_CVOLUME;
@@ -291,6 +293,17 @@ void pa_tagstruct_put_proplist(pa_tagstruct *t, pa_proplist *p) {
     pa_tagstruct_puts(t, NULL);
 }
 
+void pa_tagstruct_put_format_info(pa_tagstruct *t, pa_format_info *f) {
+    pa_assert(t);
+    pa_assert(f);
+
+    extend(t, 1);
+
+    t->data[t->length++] = PA_TAG_FORMAT_INFO;
+    pa_tagstruct_putu8(t, (uint8_t) f->encoding);
+    pa_tagstruct_put_proplist(t, f->plist);
+}
+
 int pa_tagstruct_gets(pa_tagstruct*t, const char **s) {
     int error = 0;
     size_t n;
@@ -589,7 +602,6 @@ int pa_tagstruct_get_proplist(pa_tagstruct *t, pa_proplist *p) {
     size_t saved_rindex;
 
     pa_assert(t);
-    pa_assert(p);
 
     if (t->rindex+1 > t->length)
         return -1;
@@ -611,6 +623,9 @@ int pa_tagstruct_get_proplist(pa_tagstruct *t, pa_proplist *p) {
         if (!k)
             break;
 
+        if (!pa_proplist_key_valid(k))
+            goto fail;
+
         if (pa_tagstruct_getu32(t, &length) < 0)
             goto fail;
 
@@ -620,8 +635,8 @@ int pa_tagstruct_get_proplist(pa_tagstruct *t, pa_proplist *p) {
         if (pa_tagstruct_get_arbitrary(t, &d, length) < 0)
             goto fail;
 
-        if (pa_proplist_set(p, k, d, length) < 0)
-            goto fail;
+        if (p)
+            pa_assert_se(pa_proplist_set(p, k, d, length) >= 0);
     }
 
     return 0;
@@ -631,6 +646,37 @@ fail:
     return -1;
 }
 
+int pa_tagstruct_get_format_info(pa_tagstruct *t, pa_format_info *f) {
+    size_t saved_rindex;
+    uint8_t encoding;
+
+    pa_assert(t);
+    pa_assert(f);
+
+    if (t->rindex+1 > t->length)
+        return -1;
+
+    if (t->data[t->rindex] != PA_TAG_FORMAT_INFO)
+        return -1;
+
+    saved_rindex = t->rindex;
+    t->rindex++;
+
+    if (pa_tagstruct_getu8(t, &encoding) < 0)
+        goto fail;
+
+    f->encoding = encoding;
+
+    if (pa_tagstruct_get_proplist(t, f->plist) < 0)
+        goto fail;
+
+    return 0;
+
+fail:
+    t->rindex = saved_rindex;
+    return -1;
+}
+
 void pa_tagstruct_put(pa_tagstruct *t, ...) {
     va_list va;
     pa_assert(t);
index 1a99e92..5f729bc 100644 (file)
 #include <inttypes.h>
 #include <sys/types.h>
 #include <sys/time.h>
-#include <time.h>
 
 #include <pulse/sample.h>
+#include <pulse/format.h>
 #include <pulse/channelmap.h>
 #include <pulse/volume.h>
 #include <pulse/proplist.h>
-#include <pulse/gccmacro.h>
 
 #include <pulsecore/macro.h>
 
@@ -59,7 +58,8 @@ enum {
     PA_TAG_CHANNEL_MAP = 'm',
     PA_TAG_CVOLUME = 'v',
     PA_TAG_PROPLIST = 'P',
-    PA_TAG_VOLUME = 'V'
+    PA_TAG_VOLUME = 'V',
+    PA_TAG_FORMAT_INFO = 'f',
 };
 
 pa_tagstruct *pa_tagstruct_new(const uint8_t* data, size_t length);
@@ -85,6 +85,7 @@ void pa_tagstruct_put_channel_map(pa_tagstruct *t, const pa_channel_map *map);
 void pa_tagstruct_put_cvolume(pa_tagstruct *t, const pa_cvolume *cvolume);
 void pa_tagstruct_put_proplist(pa_tagstruct *t, pa_proplist *p);
 void pa_tagstruct_put_volume(pa_tagstruct *t, pa_volume_t volume);
+void pa_tagstruct_put_format_info(pa_tagstruct *t, pa_format_info *f);
 
 int pa_tagstruct_get(pa_tagstruct *t, ...);
 
@@ -102,5 +103,6 @@ int pa_tagstruct_get_channel_map(pa_tagstruct *t, pa_channel_map *map);
 int pa_tagstruct_get_cvolume(pa_tagstruct *t, pa_cvolume *v);
 int pa_tagstruct_get_proplist(pa_tagstruct *t, pa_proplist *p);
 int pa_tagstruct_get_volume(pa_tagstruct *t, pa_volume_t *v);
+int pa_tagstruct_get_format_info(pa_tagstruct *t, pa_format_info *f);
 
 #endif
index 73997a7..b492793 100644 (file)
 #include <unistd.h>
 #include <errno.h>
 
-#include <pulse/xmalloc.h>
-
-#include <pulsecore/atomic.h>
-#include <pulsecore/once.h>
-#include <pulsecore/log.h>
 #include <pulsecore/thread.h>
 #include <pulsecore/semaphore.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/core-util.h>
-#include <pulsecore/flist.h>
 
 #include "thread-mq.h"
 
@@ -49,7 +42,7 @@ static void asyncmsgq_read_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io
     pa_assert(events == PA_IO_EVENT_INPUT);
 
     pa_asyncmsgq_ref(aq = q->outq);
-    pa_asyncmsgq_write_after_poll(aq);
+    pa_asyncmsgq_read_after_poll(aq);
 
     for (;;) {
         pa_msgobject *object;
index 96839d2..a1f4b3f 100644 (file)
@@ -27,7 +27,7 @@
 #include <pulsecore/rtpoll.h>
 
 /* Two way communication between a thread and a mainloop. Before the
- * thread is started a pa_pthread_mq should be initialized and than
+ * thread is started a pa_thread_mq should be initialized and than
  * attached to the thread using pa_thread_mq_install(). */
 
 typedef struct pa_thread_mq {
index fdab270..3f4ae5c 100644 (file)
 #include <sched.h>
 #include <errno.h>
 
+#ifdef __linux__
+#include <sys/prctl.h>
+#endif
+
 #include <pulse/xmalloc.h>
-#include <pulsecore/mutex.h>
-#include <pulsecore/once.h>
 #include <pulsecore/atomic.h>
 #include <pulsecore/macro.h>
 
@@ -42,6 +44,7 @@ struct pa_thread {
     void *userdata;
     pa_atomic_t running;
     pa_bool_t joined;
+    char *name;
 };
 
 struct pa_tls {
@@ -53,9 +56,11 @@ static void thread_free_cb(void *p) {
 
     pa_assert(t);
 
-    if (!t->thread_func)
+    if (!t->thread_func) {
         /* This is a foreign thread, we need to free the struct */
+        pa_xfree(t->name);
         pa_xfree(t);
+    }
 }
 
 PA_STATIC_TLS_DECLARE(current_thread, thread_free_cb);
@@ -64,6 +69,12 @@ static void* internal_thread_func(void *userdata) {
     pa_thread *t = userdata;
     pa_assert(t);
 
+#ifdef __linux__
+    prctl(PR_SET_NAME, t->name);
+#elif defined(HAVE_PTHREAD_SETNAME_NP) && defined(OS_IS_DARWIN)
+    pthread_setname_np(t->name);
+#endif
+
     t->id = pthread_self();
 
     PA_STATIC_TLS_SET(current_thread, t);
@@ -75,16 +86,15 @@ static void* internal_thread_func(void *userdata) {
     return NULL;
 }
 
-pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) {
+pa_thread* pa_thread_new(const char *name, pa_thread_func_t thread_func, void *userdata) {
     pa_thread *t;
 
     pa_assert(thread_func);
 
-    t = pa_xnew(pa_thread, 1);
+    t = pa_xnew0(pa_thread, 1);
+    t->name = pa_xstrdup(name);
     t->thread_func = thread_func;
     t->userdata = userdata;
-    t->joined = FALSE;
-    pa_atomic_store(&t->running, 0);
 
     if (pthread_create(&t->id, NULL, internal_thread_func, t) < 0) {
         pa_xfree(t);
@@ -112,6 +122,8 @@ void pa_thread_free(pa_thread *t) {
     pa_assert(t);
 
     pa_thread_join(t);
+
+    pa_xfree(t->name);
     pa_xfree(t);
 }
 
@@ -135,10 +147,8 @@ pa_thread* pa_thread_self(void) {
     /* This is a foreign thread, let's create a pthread structure to
      * make sure that we can always return a sensible pointer */
 
-    t = pa_xnew(pa_thread, 1);
+    t = pa_xnew0(pa_thread, 1);
     t->id = pthread_self();
-    t->thread_func = NULL;
-    t->userdata = NULL;
     t->joined = TRUE;
     pa_atomic_store(&t->running, 2);
 
@@ -159,6 +169,43 @@ void pa_thread_set_data(pa_thread *t, void *userdata) {
     t->userdata = userdata;
 }
 
+void pa_thread_set_name(pa_thread *t, const char *name) {
+    pa_assert(t);
+
+    pa_xfree(t->name);
+    t->name = pa_xstrdup(name);
+
+#ifdef __linux__
+    prctl(PR_SET_NAME, name);
+#elif defined(HAVE_PTHREAD_SETNAME_NP) && defined(OS_IS_DARWIN)
+    pthread_setname_np(name);
+#endif
+}
+
+const char *pa_thread_get_name(pa_thread *t) {
+    pa_assert(t);
+
+#ifdef __linux__
+    if (!t->name) {
+        t->name = pa_xmalloc(17);
+
+        if (prctl(PR_GET_NAME, t->name) >= 0)
+            t->name[16] = 0;
+        else {
+            pa_xfree(t->name);
+            t->name = NULL;
+        }
+    }
+#elif defined(HAVE_PTHREAD_GETNAME_NP) && defined(OS_IS_DARWIN)
+    if (!t->name) {
+        t->name = pa_xmalloc0(17);
+        pthread_getname_np(t->id, t->name, 16);
+    }
+#endif
+
+    return t->name;
+}
+
 void pa_thread_yield(void) {
 #ifdef HAVE_PTHREAD_YIELD
     pthread_yield();
index 0a1baa5..89c8c46 100644 (file)
@@ -28,7 +28,6 @@
 #include <windows.h>
 
 #include <pulse/xmalloc.h>
-#include <pulsecore/log.h>
 #include <pulsecore/once.h>
 
 #include "thread.h"
@@ -71,8 +70,9 @@ static DWORD WINAPI internal_thread_func(LPVOID param) {
     return 0;
 }
 
-pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) {
+pa_thread* pa_thread_new(const char *name, pa_thread_func_t thread_func, void *userdata) {
     pa_thread *t;
+    DWORD thread_id;
 
     assert(thread_func);
 
@@ -80,7 +80,7 @@ pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) {
     t->thread_func = thread_func;
     t->userdata = userdata;
 
-    t->thread = CreateThread(NULL, 0, internal_thread_func, t, 0, NULL);
+    t->thread = CreateThread(NULL, 0, internal_thread_func, t, 0, &thread_id);
 
     if (!t->thread) {
         pa_xfree(t);
@@ -123,6 +123,27 @@ pa_thread* pa_thread_self(void) {
     return pa_tls_get(thread_tls);
 }
 
+void* pa_thread_get_data(pa_thread *t) {
+    pa_assert(t);
+
+    return t->userdata;
+}
+
+void pa_thread_set_data(pa_thread *t, void *userdata) {
+    pa_assert(t);
+
+    t->userdata = userdata;
+}
+
+void pa_thread_set_name(pa_thread *t, const char *name) {
+    /* Not implemented */
+}
+
+const char *pa_thread_get_name(pa_thread *t) {
+    /* Not implemented */
+    return NULL;
+}
+
 void pa_thread_yield(void) {
     Sleep(0);
 }
index 25eace6..9cabb89 100644 (file)
@@ -24,6 +24,8 @@
 ***/
 
 #include <pulse/def.h>
+#include <pulse/gccmacro.h>
+
 #include <pulsecore/once.h>
 #include <pulsecore/core-util.h>
 
@@ -35,7 +37,7 @@ typedef struct pa_thread pa_thread;
 
 typedef void (*pa_thread_func_t) (void *userdata);
 
-pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata);
+pa_thread* pa_thread_new(const char *name, pa_thread_func_t thread_func, void *userdata);
 void pa_thread_free(pa_thread *t);
 int pa_thread_join(pa_thread *t);
 int pa_thread_is_running(pa_thread *t);
@@ -45,6 +47,9 @@ void pa_thread_yield(void);
 void* pa_thread_get_data(pa_thread *t);
 void pa_thread_set_data(pa_thread *t, void *userdata);
 
+const char *pa_thread_get_name(pa_thread *t);
+void pa_thread_set_name(pa_thread *t, const char *name);
+
 typedef struct pa_tls pa_tls;
 
 pa_tls* pa_tls_new(pa_free_cb_t free_cb);
@@ -55,7 +60,7 @@ void *pa_tls_set(pa_tls *t, void *userdata);
 #define PA_STATIC_TLS_DECLARE(name, free_cb)                            \
     static struct {                                                     \
         pa_once once;                                                   \
-        pa_tls *tls;                                                    \
+        pa_tls *volatile tls;                                           \
     } name##_tls = {                                                    \
         .once = PA_ONCE_INIT,                                           \
         .tls = NULL                                                     \
@@ -89,7 +94,7 @@ void *pa_tls_set(pa_tls *t, void *userdata);
     }                                                                   \
     struct __stupid_useless_struct_to_allow_trailing_semicolon
 
-#ifdef SUPPORT_TLS___THREAD
+#if defined(SUPPORT_TLS___THREAD) && !defined(OS_IS_WIN32)
 /* An optimized version of the above that requires no dynamic
  * allocation if the compiler supports __thread */
 #define PA_STATIC_TLS_DECLARE_NO_FREE(name)                             \
index d6c3787..7a61a75 100644 (file)
@@ -24,6 +24,7 @@
 #endif
 
 #include <stdio.h>
+#include <math.h>
 
 #include <pulse/sample.h>
 #include <pulse/xmalloc.h>
@@ -38,7 +39,7 @@
  * Implementation of a time smoothing algorithm to synchronize remote
  * clocks to a local one. Evens out noise, adjusts to clock skew and
  * allows cheap estimations of the remote time while clock updates may
- * be seldom and recieved in non-equidistant intervals.
+ * be seldom and received in non-equidistant intervals.
  *
  * Basically, we estimate the gradient of received clock samples in a
  * certain history window (of size 'history_time') with linear
@@ -47,7 +48,7 @@
  * towards that point with a 3rd order polynomial interpolation with
  * fitting derivatives. (more or less a b-spline)
  *
- * The larger 'history_time' is chosen the better we will surpress
+ * The larger 'history_time' is chosen the better we will suppress
  * noise -- but we'll adjust to clock skew slower..
  *
  * The larger 'adjust_time' is chosen the smoother our estimation
@@ -82,7 +83,7 @@ struct pa_smoother {
 
     pa_bool_t monotonic:1;
     pa_bool_t paused:1;
-    pa_bool_t smoothing:1; /* If FALSE we skip the polonyomial interpolation step */
+    pa_bool_t smoothing:1; /* If FALSE we skip the polynomial interpolation step */
 
     pa_usec_t pause_time;
 
@@ -196,6 +197,13 @@ static double avg_gradient(pa_smoother *s, pa_usec_t x) {
     int64_t ax = 0, ay = 0, k, t;
     double r;
 
+    /* FIXME: Optimization: Jason Newton suggested that instead of
+     * going through the history on each iteration we could calculated
+     * avg_gradient() as we go.
+     *
+     * Second idea: it might make sense to weight history entries:
+     * more recent entries should matter more than old ones. */
+
     /* Too few measurements, assume gradient of 1 */
     if (s->n_history < s->min_history)
         return 1;
@@ -256,7 +264,7 @@ static void calc_abc(pa_smoother *s) {
 
     pa_assert(ex < px);
 
-    /* To increase the dynamic range and symplify calculation, we
+    /* To increase the dynamic range and simplify calculation, we
      * move these values to the origin */
     kx = (int64_t) px - (int64_t) ex;
     ky = (int64_t) py - (int64_t) ey;
@@ -313,10 +321,8 @@ static void estimate(pa_smoother *s, pa_usec_t x, pa_usec_t *y, double *deriv) {
 
         calc_abc(s);
 
-        tx = (double) x;
-
         /* Move to origin */
-        tx -= (double) s->ex;
+        tx = (double) (x - s->ex);
 
         /* Horner scheme */
         ty = (tx * (s->c + tx * (s->b + tx * s->a)));
@@ -380,7 +386,7 @@ void pa_smoother_put(pa_smoother *s, pa_usec_t x, pa_usec_t y) {
     s->abc_valid = FALSE;
 
 #ifdef DEBUG_DATA
-    pa_log_debug("%p, put(%llu | %llu) = %llu", s, (unsigned long long)  (x + s->time_offset), (unsigned long long) x, (unsigned long long) y);
+    pa_log_debug("%p, put(%llu | %llu) = %llu", s, (unsigned long long) (x + s->time_offset), (unsigned long long) x, (unsigned long long) y);
 #endif
 }
 
@@ -436,7 +442,7 @@ void pa_smoother_pause(pa_smoother *s, pa_usec_t x) {
         return;
 
 #ifdef DEBUG_DATA
-    pa_log_debug("pause(%llu)", (unsigned long long)  x);
+    pa_log_debug("pause(%llu)", (unsigned long long) x);
 #endif
 
     s->paused = TRUE;
index 1eb466d..cb682d6 100644 (file)
 #include <stdlib.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/gccmacro.h>
 
 #include <pulsecore/dynarray.h>
 #include <pulsecore/macro.h>
 
 #include "tokenizer.h"
 
-static void token_free(void *p, void *userdata) {
-    pa_xfree(p);
-}
-
 static void parse(pa_dynarray*a, const char *s, unsigned args) {
     int infty = 0;
     const char delimiter[] = " \t\n\r";
@@ -77,7 +72,7 @@ void pa_tokenizer_free(pa_tokenizer *t) {
     pa_dynarray *a = (pa_dynarray*) t;
 
     pa_assert(a);
-    pa_dynarray_free(a, token_free, NULL);
+    pa_dynarray_free(a, pa_xfree);
 }
 
 const char *pa_tokenizer_get(pa_tokenizer *t, unsigned i) {
index 71b13bc..c244865 100644 (file)
@@ -142,9 +142,7 @@ struct group *pa_getgrgid_malloc(gid_t gid) {
     getgr_buflen = buflen - sizeof(struct group);
     getgr_buf = (char *)buf + sizeof(struct group);
 
-    while ((err = getgrgid_r(gid, (struct group *)buf, getgr_buf,
-                    getgr_buflen, &result)) == ERANGE)
-    {
+    while ((err = getgrgid_r(gid, (struct group *)buf, getgr_buf, getgr_buflen, &result)) == ERANGE) {
         if (expand_buffer_trashcontents(&buf, &buflen))
             break;
 
@@ -203,9 +201,7 @@ struct group *pa_getgrnam_malloc(const char *name) {
     getgr_buflen = buflen - sizeof(struct group);
     getgr_buf = (char *)buf + sizeof(struct group);
 
-    while ((err = getgrnam_r(name, (struct group *)buf, getgr_buf,
-                    getgr_buflen, &result)) == ERANGE)
-    {
+    while ((err = getgrnam_r(name, (struct group *)buf, getgr_buf, getgr_buflen, &result)) == ERANGE) {
         if (expand_buffer_trashcontents(&buf, &buflen))
             break;
 
@@ -268,9 +264,7 @@ struct passwd *pa_getpwnam_malloc(const char *name) {
     getpw_buflen = buflen - sizeof(struct passwd);
     getpw_buf = (char *)buf + sizeof(struct passwd);
 
-    while ((err = getpwnam_r(name, (struct passwd *)buf, getpw_buf,
-                    getpw_buflen, &result)) == ERANGE)
-    {
+    while ((err = getpwnam_r(name, (struct passwd *)buf, getpw_buf, getpw_buflen, &result)) == ERANGE) {
         if (expand_buffer_trashcontents(&buf, &buflen))
             break;
 
@@ -329,9 +323,7 @@ struct passwd *pa_getpwuid_malloc(uid_t uid) {
     getpw_buflen = buflen - sizeof(struct passwd);
     getpw_buf = (char *)buf + sizeof(struct passwd);
 
-    while ((err = getpwuid_r(uid, (struct passwd *)buf, getpw_buf,
-                    getpw_buflen, &result)) == ERANGE)
-    {
+    while ((err = getpwuid_r(uid, (struct passwd *)buf, getpw_buf, getpw_buflen, &result)) == ERANGE) {
         if (expand_buffer_trashcontents(&buf, &buflen))
             break;
 
diff --git a/src/pulsecore/vector.h b/src/pulsecore/vector.h
deleted file mode 100644 (file)
index 9de3b8c..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2004-2006 Lennart Poettering
-  Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
-
-  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, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#include <inttypes.h>
-
-/* First, define HAVE_VECTOR if we have the gcc vector extensions at all */
-#if defined(__SSE2__)
-    /* || defined(__ALTIVEC__)*/
-#define HAVE_VECTOR
-
-
-/* This is supposed to be portable to different SIMD instruction
- * sets. We define vector types for different base types: uint8_t,
- * int16_t, int32_t, float. The vector type is a union. The fields .i,
- * .u, .f are arrays for accessing the separate elements of a
- * vector. .v is a gcc vector type of the right format. .m is the
- * vector in the type the SIMD extenstion specific intrinsics API
- * expects. PA_xxx_VECTOR_SIZE is the size of the
- * entries. PA_xxxx_VECTOR_MAKE constructs a gcc vector variable with
- * the same value in all elements. */
-
-#ifdef __SSE2__
-
-#include <xmmintrin.h>
-#include <emmintrin.h>
-
-#define PA_UINT8_VECTOR_SIZE 16
-#define PA_INT16_VECTOR_SIZE 8
-#define PA_INT32_VECTOR_SIZE 4
-#define PA_FLOAT_VECTOR_SIZE 4
-
-#define PA_UINT8_VECTOR_MAKE(x) (pa_v16qi) { x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x }
-#define PA_INT16_VECTOR_MAKE(x) (pa_v8hi) { x, x, x, x, x, x, x, x }
-#define PA_INT32_VECTOR_MAKE(x) (pa_v4si) { x, x, x, x }
-#define PA_FLOAT_VECTOR_MAKE(x) (pa_v4fi) { x, x, x, x }
-
-#endif
-
-/* uint8_t vector */
-typedef uint8_t pa_v16qi __attribute__ ((vector_size (PA_UINT8_VECTOR_SIZE * sizeof(uint8_t))));
-typedef union pa_uint8_vector {
-    uint8_t u[PA_UINT8_VECTOR_SIZE];
-    pa_v16qi v;
-#ifdef __SSE2__
-    __m128i m;
-#endif
-} pa_uint8_vector_t;
-
-/* int16_t vector*/
-typedef int16_t pa_v8hi __attribute__ ((vector_size (PA_INT16_VECTOR_SIZE * sizeof(int16_t))));
-typedef union pa_int16_vector {
-    int16_t i[PA_INT16_VECTOR_SIZE];
-    pa_v8hi v;
-#ifdef __SSE2__
-    __m128i m;
-#endif
-} pa_int16_vector_t;
-
-/* int32_t vector */
-typedef int32_t pa_v4si __attribute__ ((vector_size (PA_INT32_VECTOR_SIZE * sizeof(int32_t))));
-typedef union pa_int32_vector {
-    int32_t i[PA_INT32_VECTOR_SIZE];
-    pa_v4si v;
-#ifdef __SSE2__
-    __m128i m;
-#endif
-} pa_int32_vector_t;
-
-/* float vector */
-typedef float pa_v4sf __attribute__ ((vector_size (PA_FLOAT_VECTOR_SIZE * sizeof(float))));
-typedef union pa_float_vector {
-    float f[PA_FLOAT_VECTOR_SIZE];
-    pa_v4sf v;
-#ifdef __SSE2__
-    __m128 m;
-#endif
-} pa_float_vector_t;
-
-#endif
index 873a76e..baf5b01 100644 (file)
 
 #include <string.h>
 
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-
 #include "x11prop.h"
 
-void pa_x11_set_prop(Display *d, const char *name, const char *data) {
-    Atom a = XInternAtom(d, name, False);
-    XChangeProperty(d, RootWindow(d, 0), a, XA_STRING, 8, PropModeReplace, (const unsigned char*) data, (int) (strlen(data)+1));
+#include <pulsecore/macro.h>
+
+#include <xcb/xproto.h>
+
+#define PA_XCB_FORMAT 8
+
+static xcb_screen_t *screen_of_display(xcb_connection_t *xcb, int screen) {
+    const xcb_setup_t *s;
+    xcb_screen_iterator_t iter;
+
+    if ((s = xcb_get_setup(xcb))) {
+        iter = xcb_setup_roots_iterator(s);
+        for (; iter.rem; --screen, xcb_screen_next(&iter))
+            if (0 == screen)
+                return iter.data;
+    }
+    return NULL;
 }
 
-void pa_x11_del_prop(Display *d, const char *name) {
-    Atom a = XInternAtom(d, name, False);
-    XDeleteProperty(d, RootWindow(d, 0), a);
+void pa_x11_set_prop(xcb_connection_t *xcb, int screen, const char *name, const char *data) {
+    xcb_screen_t *xs;
+    xcb_intern_atom_reply_t *reply;
+
+    pa_assert(xcb);
+    pa_assert(name);
+    pa_assert(data);
+
+    if ((xs = screen_of_display(xcb, screen))) {
+        reply = xcb_intern_atom_reply(xcb,
+                                      xcb_intern_atom(xcb, 0, strlen(name), name),
+                                      NULL);
+
+        if (reply) {
+            xcb_change_property(xcb, XCB_PROP_MODE_REPLACE, xs->root, reply->atom,
+                                XCB_ATOM_STRING, PA_XCB_FORMAT,
+                                (int) strlen(data), (const void*) data);
+
+            free(reply);
+        }
+    }
 }
 
-char* pa_x11_get_prop(Display *d, const char *name, char *p, size_t l) {
-    Atom actual_type;
-    int actual_format;
-    unsigned long nitems;
-    unsigned long nbytes_after;
-    unsigned char *prop = NULL;
+void pa_x11_del_prop(xcb_connection_t *xcb, int screen, const char *name) {
+    xcb_screen_t *xs;
+    xcb_intern_atom_reply_t *reply;
+
+    pa_assert(xcb);
+    pa_assert(name);
+
+    if ((xs = screen_of_display(xcb, screen))) {
+        reply = xcb_intern_atom_reply(xcb,
+                                      xcb_intern_atom(xcb, 0, strlen(name), name),
+                                      NULL);
+
+        if (reply) {
+            xcb_delete_property(xcb, xs->root, reply->atom);
+            free(reply);
+        }
+    }
+}
+
+char* pa_x11_get_prop(xcb_connection_t *xcb, int screen, const char *name, char *p, size_t l) {
     char *ret = NULL;
+    int len;
+    xcb_get_property_cookie_t req;
+    xcb_get_property_reply_t* prop = NULL;
+    xcb_screen_t *xs;
+    xcb_intern_atom_reply_t *reply;
+
+    pa_assert(xcb);
+    pa_assert(name);
+    pa_assert(p);
+
+
+    xs = screen_of_display(xcb, screen);
+    /*
+     * Also try and get the settings from the first screen.
+     * This allows for e.g. a Media Center to run on screen 1 (e.g. HDMI) and have
+     * different defaults (e.g. prefer the HDMI sink) than the primary screen 0
+     * which uses the Internal Audio sink.
+     */
+    if (!xs && 0 != screen)
+        xs = screen_of_display(xcb, 0);
+
+    if (xs) {
+        reply = xcb_intern_atom_reply(xcb,
+                                      xcb_intern_atom(xcb, 0, strlen(name), name),
+                                      NULL);
+
+        if (!reply)
+            goto finish;
+
+        req = xcb_get_property(xcb, 0, xs->root, reply->atom, XCB_ATOM_STRING, 0, (uint32_t)(l-1));
+        free(reply);
+        prop = xcb_get_property_reply(xcb, req, NULL);
+
+        if (!prop)
+            goto finish;
 
-    Atom a = XInternAtom(d, name, False);
-    if (XGetWindowProperty(d, RootWindow(d, 0), a, 0, (long) ((l+2)/4), False, XA_STRING, &actual_type, &actual_format, &nitems, &nbytes_after, &prop) != Success)
-        goto finish;
+        if (PA_XCB_FORMAT != prop->format)
+            goto finish;
 
-    if (actual_type != XA_STRING)
-        goto finish;
+        len = xcb_get_property_value_length(prop);
+        if (len < 1 || len >= (int)l)
+            goto finish;
 
-    memcpy(p, prop, nitems);
-    p[nitems] = 0;
+        memcpy(p, xcb_get_property_value(prop), len);
+        p[len] = 0;
 
-    ret = p;
+        ret = p;
+    }
 
 finish:
 
     if (prop)
-        XFree(prop);
+        free(prop);
 
     return ret;
 }
index dc67526..5a12114 100644 (file)
@@ -5,6 +5,7 @@
   This file is part of PulseAudio.
 
   Copyright 2004-2006 Lennart Poettering
+  Copyright 2010 Colin Guthrie
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
 
 #include <sys/types.h>
 
-#include <X11/Xlib.h>
+#include <xcb/xcb.h>
 
-void pa_x11_set_prop(Display *d, const char *name, const char *data);
-void pa_x11_del_prop(Display *d, const char *name);
-char* pa_x11_get_prop(Display *d, const char *name, char *p, size_t l);
+void pa_x11_set_prop(xcb_connection_t *xcb, int screen, const char *name, const char *data);
+void pa_x11_del_prop(xcb_connection_t *xcb, int screen, const char *name);
+char* pa_x11_get_prop(xcb_connection_t *xcb, int screen, const char *name, char *p, size_t l);
 
 #endif
index 1960a12..454507a 100644 (file)
@@ -259,6 +259,10 @@ Display *pa_x11_wrapper_get_display(pa_x11_wrapper *w) {
     return w->display;
 }
 
+xcb_connection_t *pa_x11_wrapper_get_xcb_connection(pa_x11_wrapper *w) {
+    return XGetXCBConnection(pa_x11_wrapper_get_display(w));
+}
+
 void pa_x11_wrapper_kill(pa_x11_wrapper *w) {
     pa_x11_client *c, *n;
 
index b57541f..e632ecc 100644 (file)
@@ -23,6 +23,7 @@
 ***/
 
 #include <X11/Xlib.h>
+#include <X11/Xlib-xcb.h>
 
 #include <pulsecore/core.h>
 
@@ -34,7 +35,7 @@ typedef int (*pa_x11_event_cb_t)(pa_x11_wrapper *w, XEvent *e, void *userdata);
 typedef void (*pa_x11_kill_cb_t)(pa_x11_wrapper *w, void *userdata);
 
 /* Return the X11 wrapper for this core. In case no wrapper was
-    existant before, allocate a new one */
+    existent before, allocate a new one */
 pa_x11_wrapper* pa_x11_wrapper_get(pa_core *c, const char *name);
 
 /* Increase the wrapper's reference count by one */
@@ -46,6 +47,9 @@ void pa_x11_wrapper_unref(pa_x11_wrapper* w);
 /* Return the X11 display object for this connection */
 Display *pa_x11_wrapper_get_display(pa_x11_wrapper *w);
 
+/* Return the XCB connection object for this connection */
+xcb_connection_t *pa_x11_wrapper_get_xcb_connection(pa_x11_wrapper *w);
+
 /* Kill the connection to the X11 display */
 void pa_x11_wrapper_kill(pa_x11_wrapper *w);
 
diff --git a/src/tests/alsa-mixer-path-test.c b/src/tests/alsa-mixer-path-test.c
new file mode 100644 (file)
index 0000000..f2bc4cb
--- /dev/null
@@ -0,0 +1,111 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <check.h>
+#include <dirent.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#include <pulse/pulseaudio.h>
+#include <pulsecore/log.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/strlist.h>
+#include <modules/alsa/alsa-mixer.h>
+
+/* This function was copied from alsa-mixer.c */
+static const char *get_default_paths_dir(void) {
+    if (pa_run_from_build_tree())
+        return PA_SRCDIR "/modules/alsa/mixer/paths/";
+    else
+        return PA_ALSA_PATHS_DIR;
+}
+
+static pa_strlist *load_makefile() {
+    FILE *f;
+    bool lookforfiles = false;
+    char buf[2048];
+    pa_strlist *result = NULL;
+    const char *Makefile = PA_BUILDDIR "/Makefile";
+
+    f = pa_fopen_cloexec(Makefile, "r");
+    fail_unless(f != NULL); /* Consider skipping this test instead of failing if Makefile not found? */
+    while (!feof(f)) {
+        if (!fgets(buf, sizeof(buf), f)) {
+            fail_unless(feof(f));
+            break;
+        }
+        if (strstr(buf, "dist_alsapaths_DATA = \\") != NULL) {
+           lookforfiles = true;
+           continue;
+        }
+        if (!lookforfiles)
+           continue;
+        if (!strstr(buf, "\\"))
+           lookforfiles = false;
+        else
+           strstr(buf, "\\")[0] = '\0';
+        pa_strip(buf);
+        pa_log_debug("Shipping file '%s'", pa_path_get_filename(buf));
+        result = pa_strlist_prepend(result, pa_path_get_filename(buf));
+    }
+    fclose(f);
+    return result;
+}
+
+
+START_TEST (mixer_path_test) {
+    DIR *dir;
+    struct dirent *ent;
+    pa_strlist *ship = load_makefile();
+    const char *pathsdir = get_default_paths_dir();
+    pa_log_debug("Analyzing directory: '%s'", pathsdir);
+
+    dir = opendir(pathsdir);
+    fail_unless(dir != NULL);
+    while ((ent = readdir(dir)) != NULL) {
+        pa_alsa_path *path;
+        if (pa_streq(ent->d_name, ".") || pa_streq(ent->d_name, ".."))
+            continue;
+        pa_log_debug("Analyzing file: '%s'", ent->d_name);
+
+        /* Can the file be parsed? */
+        path = pa_alsa_path_new(pathsdir, ent->d_name, PA_ALSA_DIRECTION_ANY);
+        fail_unless(path != NULL);
+
+        /* Is the file shipped? */
+        if (ship) {
+            pa_strlist *n;
+            bool found = false;
+            for (n = ship; n; n = pa_strlist_next(n))
+                found |= pa_streq(ent->d_name, pa_strlist_data(n));
+            fail_unless(found);
+        }
+    }
+    closedir(dir);
+    pa_strlist_free(ship);
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_DEBUG);
+
+    s = suite_create("Alsa-mixer-path");
+    tc = tcase_create("alsa-mixer-path");
+    tcase_add_test(tc, mixer_path_test);
+    tcase_set_timeout(tc, 30);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
index 233bbe6..3c82fdc 100644 (file)
@@ -1,6 +1,12 @@
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
 #include <assert.h>
 #include <inttypes.h>
 #include <time.h>
+#include <unistd.h>
+#include <pthread.h>
 
 #include <alsa/asoundlib.h>
 
@@ -12,7 +18,7 @@ static uint64_t timespec_us(const struct timespec *ts) {
 
 int main(int argc, char *argv[]) {
     const char *dev;
-    int r;
+    int r, cap, count = 0;
     snd_pcm_hw_params_t *hwparams;
     snd_pcm_sw_params_t *swparams;
     snd_pcm_status_t *status;
@@ -22,11 +28,20 @@ int main(int argc, char *argv[]) {
     snd_pcm_uframes_t boundary, buffer_size = 44100/10; /* 100s */
     int dir = 1;
     struct timespec start, last_timestamp = { 0, 0 };
-    uint64_t start_us;
+    uint64_t start_us, last_us = 0;
     snd_pcm_sframes_t last_avail = 0, last_delay = 0;
     struct pollfd *pollfds;
     int n_pollfd;
     int64_t sample_count = 0;
+    struct sched_param sp;
+
+    r = -1;
+#ifdef _POSIX_PRIORITY_SCHEDULING
+    sp.sched_priority = 5;
+    r = pthread_setschedparam(pthread_self(), SCHED_RR, &sp);
+#endif
+    if (r)
+        printf("Could not get RT prio. :(\n");
 
     snd_pcm_hw_params_alloca(&hwparams);
     snd_pcm_sw_params_alloca(&swparams);
@@ -38,8 +53,12 @@ int main(int argc, char *argv[]) {
     start_us = timespec_us(&start);
 
     dev = argc > 1 ? argv[1] : "front:AudioPCI";
+    cap = argc > 2 ? atoi(argv[2]) : 0;
 
-    r = snd_pcm_open(&pcm, dev, SND_PCM_STREAM_PLAYBACK, 0);
+    if (cap == 0)
+      r = snd_pcm_open(&pcm, dev, SND_PCM_STREAM_PLAYBACK, 0);
+    else
+      r = snd_pcm_open(&pcm, dev, SND_PCM_STREAM_CAPTURE, 0);
     assert(r == 0);
 
     r = snd_pcm_hw_params_any(pcm, hwparams);
@@ -78,7 +97,10 @@ int main(int argc, char *argv[]) {
     r = snd_pcm_sw_params_current(pcm, swparams);
     assert(r == 0);
 
-    r = snd_pcm_sw_params_set_avail_min(pcm, swparams, 1);
+    if (cap == 0)
+      r = snd_pcm_sw_params_set_avail_min(pcm, swparams, 1);
+    else
+      r = snd_pcm_sw_params_set_avail_min(pcm, swparams, 0);
     assert(r == 0);
 
     r = snd_pcm_sw_params_set_period_event(pcm, swparams, 0);
@@ -117,13 +139,21 @@ int main(int argc, char *argv[]) {
     r = snd_pcm_poll_descriptors(pcm, pollfds, n_pollfd);
     assert(r == n_pollfd);
 
+    printf("Starting. Buffer size is %u frames\n", (unsigned int) buffer_size);
+
+    if (cap) {
+      r = snd_pcm_start(pcm);
+      assert(r == 0);
+    }
+
     for (;;) {
         snd_pcm_sframes_t avail, delay;
         struct timespec now, timestamp;
         unsigned short revents;
-        int written = 0;
+        int handled = 0;
         uint64_t now_us, timestamp_us;
         snd_pcm_state_t state;
+        unsigned long long pos;
 
         r = poll(pollfds, n_pollfd, 0);
         assert(r >= 0);
@@ -131,7 +161,10 @@ int main(int argc, char *argv[]) {
         r = snd_pcm_poll_descriptors_revents(pcm, pollfds, n_pollfd, &revents);
         assert(r == 0);
 
-        assert((revents & ~POLLOUT) == 0);
+        if (cap == 0)
+          assert((revents & ~POLLOUT) == 0);
+        else
+          assert((revents & ~POLLIN) == 0);
 
         avail = snd_pcm_avail(pcm);
         assert(avail >= 0);
@@ -152,18 +185,22 @@ int main(int argc, char *argv[]) {
 
         assert(!revents || avail > 0);
 
-        if (avail) {
+        if ((!cap && avail) || (cap && (unsigned)avail >= buffer_size)) {
             snd_pcm_sframes_t sframes;
-            static const uint16_t samples[2] = { 0, 0 };
+            static const uint16_t psamples[2] = { 0, 0 };
+            uint16_t csamples[2];
 
-            sframes = snd_pcm_writei(pcm, samples, 1);
+            if (cap == 0)
+              sframes = snd_pcm_writei(pcm, psamples, 1);
+            else
+              sframes = snd_pcm_readi(pcm, csamples, 1);
             assert(sframes == 1);
 
-            written = 1;
+            handled = 1;
             sample_count++;
         }
 
-        if (!written &&
+        if (!handled &&
             memcmp(&timestamp, &last_timestamp, sizeof(timestamp)) == 0 &&
             avail == last_avail &&
             delay == last_delay) {
@@ -174,23 +211,35 @@ int main(int argc, char *argv[]) {
         now_us = timespec_us(&now);
         timestamp_us = timespec_us(&timestamp);
 
-        printf("%llu\t%llu\t%llu\t%li\t%li\t%i\t%i\t%i\n",
+        if (cap == 0)
+            pos = (unsigned long long) ((sample_count - handled - delay) * 1000000LU / 44100);
+        else
+            pos = (unsigned long long) ((sample_count - handled + delay) * 1000000LU / 44100);
+
+        if (count++ % 50 == 0)
+            printf("Elapsed\tCPU\tALSA\tPos\tSamples\tavail\tdelay\trevents\thandled\tstate\n");
+
+        printf("%llu\t%llu\t%llu\t%llu\t%llu\t%li\t%li\t%i\t%i\t%i\n",
+               (unsigned long long) (now_us - last_us),
                (unsigned long long) (now_us - start_us),
                (unsigned long long) (timestamp_us ? timestamp_us - start_us : 0),
-               (unsigned long long) ((sample_count - 1 - delay) * 1000000LU / 44100),
+               pos,
+               (unsigned long long) sample_count,
                (signed long) avail,
                (signed long) delay,
                revents,
-               written,
+               handled,
                state);
 
-        /** When this assert is hit, most likely something bad
-         * happened, i.e. the avail jumped suddenly. */
-        assert((unsigned) avail <= buffer_size);
+        if (cap == 0)
+          /** When this assert is hit, most likely something bad
+           * happened, i.e. the avail jumped suddenly. */
+          assert((unsigned) avail <= buffer_size);
 
         last_avail = avail;
         last_delay = delay;
         last_timestamp = timestamp;
+        last_us = now_us;
     }
 
     return 0;
index 40c74f7..3bba753 100644 (file)
 #include <stdlib.h>
 #include <unistd.h>
 
-#include <pulse/util.h>
-#include <pulse/xmalloc.h>
+#include <check.h>
+
 #include <pulsecore/asyncmsgq.h>
 #include <pulsecore/thread.h>
 #include <pulsecore/log.h>
-#include <pulsecore/core-util.h>
 #include <pulsecore/macro.h>
 
 enum {
@@ -52,19 +51,19 @@ static void the_thread(void *_q) {
         switch (code) {
 
             case OPERATION_A:
-                printf("Operation A\n");
+                pa_log_info("Operation A");
                 break;
 
             case OPERATION_B:
-                printf("Operation B\n");
+                pa_log_info("Operation B");
                 break;
 
             case OPERATION_C:
-                printf("Operation C\n");
+                pa_log_info("Operation C");
                 break;
 
             case QUIT:
-                printf("quit\n");
+                pa_log_info("quit");
                 quit = 1;
                 break;
         }
@@ -74,35 +73,55 @@ static void the_thread(void *_q) {
     } while (!quit);
 }
 
-int main(int argc, char *argv[]) {
+START_TEST (asyncmsgq_test) {
     pa_asyncmsgq *q;
     pa_thread *t;
 
-    pa_assert_se(q = pa_asyncmsgq_new(0));
+    q = pa_asyncmsgq_new(0);
+    fail_unless(q != NULL);
 
-    pa_assert_se(t = pa_thread_new(the_thread, q));
+    t = pa_thread_new("test", the_thread, q);
+    fail_unless(t != NULL);
 
-    printf("Operation A post\n");
+    pa_log_info("Operation A post");
     pa_asyncmsgq_post(q, NULL, OPERATION_A, NULL, 0, NULL, NULL);
 
     pa_thread_yield();
 
-    printf("Operation B post\n");
+    pa_log_info("Operation B post");
     pa_asyncmsgq_post(q, NULL, OPERATION_B, NULL, 0, NULL, NULL);
 
     pa_thread_yield();
 
-    printf("Operation C send\n");
+    pa_log_info("Operation C send");
     pa_asyncmsgq_send(q, NULL, OPERATION_C, NULL, 0, NULL);
 
     pa_thread_yield();
 
-    printf("Quit post\n");
+    pa_log_info("Quit post");
     pa_asyncmsgq_post(q, NULL, QUIT, NULL, 0, NULL, NULL);
 
     pa_thread_free(t);
 
     pa_asyncmsgq_unref(q);
+}
+END_TEST
 
-    return 0;
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Async Message Queue");
+    tc = tcase_create("asyncmsgq");
+    tcase_add_test(tc, asyncmsgq_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index a617e1a..7abfb89 100644 (file)
 #include <stdlib.h>
 #include <unistd.h>
 
+#include <check.h>
+
 #include <pulse/util.h>
-#include <pulse/xmalloc.h>
 #include <pulsecore/asyncq.h>
 #include <pulsecore/thread.h>
 #include <pulsecore/log.h>
-#include <pulsecore/core-util.h>
 #include <pulsecore/macro.h>
 
 static void producer(void *_q) {
@@ -38,12 +38,12 @@ static void producer(void *_q) {
     int i;
 
     for (i = 0; i < 1000; i++) {
-        printf("pushing %i\n", i);
+        pa_log_debug("pushing %i", i);
         pa_asyncq_push(q, PA_UINT_TO_PTR(i+1), 1);
     }
 
     pa_asyncq_push(q, PA_UINT_TO_PTR(-1), TRUE);
-    printf("pushed end\n");
+    pa_log_debug("pushed end");
 }
 
 static void consumer(void *_q) {
@@ -51,7 +51,7 @@ static void consumer(void *_q) {
     void *p;
     int i;
 
-    sleep(1);
+    pa_msleep(1000);
 
     for (i = 0;; i++) {
         p = pa_asyncq_pop(q, TRUE);
@@ -59,27 +59,51 @@ static void consumer(void *_q) {
         if (p == PA_UINT_TO_PTR(-1))
             break;
 
-        pa_assert(p == PA_UINT_TO_PTR(i+1));
+        fail_unless(p == PA_UINT_TO_PTR(i+1));
 
-        printf("popped %i\n", i);
+        pa_log_debug("popped %i", i);
     }
 
-    printf("popped end\n");
+    pa_log_debug("popped end");
 }
 
-int main(int argc, char *argv[]) {
+START_TEST (asyncq_test) {
     pa_asyncq *q;
     pa_thread *t1, *t2;
 
-    pa_assert_se(q = pa_asyncq_new(0));
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_DEBUG);
+
+    q = pa_asyncq_new(0);
+    fail_unless(q != NULL);
 
-    pa_assert_se(t1 = pa_thread_new(producer, q));
-    pa_assert_se(t2 = pa_thread_new(consumer, q));
+    t1 = pa_thread_new("producer", producer, q);
+    fail_unless(t1 != NULL);
+    t2 = pa_thread_new("consumer", consumer, q);
+    fail_unless(t2 != NULL);
 
     pa_thread_free(t1);
     pa_thread_free(t2);
 
     pa_asyncq_free(q, NULL);
+}
+END_TEST
 
-    return 0;
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Async Queue");
+    tc = tcase_create("asyncq");
+    tcase_add_test(tc, asyncq_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index 6cf58fb..eb0187c 100644 (file)
@@ -2,13 +2,15 @@
 #include <config.h>
 #endif
 
+#include <stdlib.h>
 #include <stdio.h>
 #include <assert.h>
 
+#include <check.h>
+
 #include <pulse/channelmap.h>
-#include <pulse/gccmacro.h>
 
-int main(int argc, char *argv[]) {
+START_TEST (channelmap_test) {
     char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
     pa_channel_map map, map2;
 
@@ -30,9 +32,27 @@ int main(int argc, char *argv[]) {
 
     pa_channel_map_parse(&map2, cm);
 
-    assert(pa_channel_map_equal(&map, &map2));
+    fail_unless(pa_channel_map_equal(&map, &map2));
 
     pa_channel_map_parse(&map2, "left,test");
+}
+END_TEST
 
-    return 0;
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Channel Map");
+    tc = tcase_create("channelmap");
+    tcase_add_test(tc, channelmap_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
diff --git a/src/tests/connect-stress.c b/src/tests/connect-stress.c
new file mode 100644 (file)
index 0000000..0cf072d
--- /dev/null
@@ -0,0 +1,230 @@
+/***
+  This file is part of PulseAudio.
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <check.h>
+
+#include <pulse/pulseaudio.h>
+#include <pulse/mainloop.h>
+
+#include <pulsecore/sink.h>
+
+/* Set the number of streams such that it allows two simultaneous instances of
+ * connect-stress to be run and not go above the max limit for streams-per-sink.
+ * This leaves enough room for a couple other streams from regular system usage,
+ * which makes a non-error abort less likely (although still easily possible of
+ * playing >=3 streams outside of the test - including internal loopback, rtp,
+ * combine, remap streams etc.) */
+#define NSTREAMS ((PA_MAX_INPUTS_PER_SINK/2) - 1)
+#define NTESTS 1000
+#define SAMPLE_HZ 44100
+
+static pa_context *context = NULL;
+static pa_stream *streams[NSTREAMS];
+static pa_threaded_mainloop *mainloop = NULL;
+static char *bname;
+
+static const pa_sample_spec sample_spec = {
+    .format = PA_SAMPLE_FLOAT32,
+    .rate = SAMPLE_HZ,
+    .channels = 1
+};
+
+static void context_state_callback(pa_context *c, void *userdata);
+
+static void connect(const char *name, int *try) {
+    int ret;
+    pa_mainloop_api *api;
+
+    /* Set up a new main loop */
+    mainloop = pa_threaded_mainloop_new();
+    fail_unless(mainloop != NULL);
+
+    api = pa_threaded_mainloop_get_api(mainloop);
+    context = pa_context_new(api, name);
+    fail_unless(context != NULL);
+
+    pa_context_set_state_callback(context, context_state_callback, try);
+
+    /* Connect the context */
+    if (pa_context_connect(context, NULL, 0, NULL) < 0) {
+        fprintf(stderr, "pa_context_connect() failed.\n");
+        fail();
+    }
+
+    ret = pa_threaded_mainloop_start(mainloop);
+    fail_unless(ret == 0);
+}
+
+static void disconnect(void) {
+    int i;
+
+    fail_unless(mainloop != NULL);
+    fail_unless(context != NULL);
+
+    pa_threaded_mainloop_lock(mainloop);
+
+    for (i = 0; i < NSTREAMS; i++)
+        if (streams[i]) {
+            pa_stream_disconnect(streams[i]);
+            pa_stream_unref(streams[i]);
+            streams[i] = NULL;
+        }
+
+    pa_context_disconnect(context);
+    context = NULL;
+
+    pa_threaded_mainloop_unlock(mainloop);
+    pa_threaded_mainloop_stop(mainloop);
+    pa_threaded_mainloop_free(mainloop);
+    mainloop = NULL;
+}
+
+static const pa_buffer_attr buffer_attr = {
+    .maxlength = SAMPLE_HZ * sizeof(float) * NSTREAMS,
+    .tlength = (uint32_t) -1,
+    .prebuf = 0, /* Setting prebuf to 0 guarantees us the streams will run synchronously, no matter what */
+    .minreq = (uint32_t) -1,
+    .fragsize = 0
+};
+
+static void stream_write_callback(pa_stream *stream, size_t nbytes, void *userdata) {
+    char silence[8192];
+
+    memset(silence, 0, sizeof(silence));
+
+    while (nbytes) {
+        int n = PA_MIN(sizeof(silence), nbytes);
+        pa_stream_write(stream, silence, n, NULL, 0, 0);
+        nbytes -= n;
+    }
+}
+
+static void stream_state_callback(pa_stream *s, void *userdata) {
+    fail_unless(s != NULL);
+
+    switch (pa_stream_get_state(s)) {
+        case PA_STREAM_UNCONNECTED:
+        case PA_STREAM_CREATING:
+        case PA_STREAM_TERMINATED:
+        case PA_STREAM_READY:
+            break;
+
+        default:
+        case PA_STREAM_FAILED:
+            fprintf(stderr, "Stream error: %s\n", pa_strerror(pa_context_errno(pa_stream_get_context(s))));
+            fail();
+    }
+}
+
+static void context_state_callback(pa_context *c, void *userdata) {
+    int *try;
+
+    fail_unless(c != NULL);
+    fail_unless(userdata != NULL);
+
+    try = (int*)userdata;
+
+    switch (pa_context_get_state(c)) {
+        case PA_CONTEXT_CONNECTING:
+        case PA_CONTEXT_AUTHORIZING:
+        case PA_CONTEXT_SETTING_NAME:
+            break;
+
+        case PA_CONTEXT_READY: {
+
+            int i;
+            fprintf(stderr, "Connection (%d of %d) established.\n", (*try)+1, NTESTS);
+
+            for (i = 0; i < NSTREAMS; i++) {
+                char name[64];
+
+                snprintf(name, sizeof(name), "stream #%i", i);
+                streams[i] = pa_stream_new(c, name, &sample_spec, NULL);
+                fail_unless(streams[i] != NULL);
+                pa_stream_set_state_callback(streams[i], stream_state_callback, NULL);
+                pa_stream_set_write_callback(streams[i], stream_write_callback, NULL);
+                pa_stream_connect_playback(streams[i], NULL, &buffer_attr, 0, NULL, NULL);
+            }
+
+            break;
+        }
+
+        case PA_CONTEXT_TERMINATED:
+            fprintf(stderr, "Connection terminated.\n");
+            pa_context_unref(context);
+            context = NULL;
+            break;
+
+        case PA_CONTEXT_FAILED:
+        default:
+            fprintf(stderr, "Context error: %s\n", pa_strerror(pa_context_errno(c)));
+            fail();
+    }
+}
+
+START_TEST (connect_stress_test) {
+    int i;
+
+    for (i = 0; i < NSTREAMS; i++)
+        streams[i] = NULL;
+
+    for (i = 0; i < NTESTS; i++) {
+        connect(bname, &i);
+        usleep(rand() % 500000);
+        disconnect();
+        usleep(rand() % 500000);
+    }
+
+    fprintf(stderr, "Done.\n");
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    bname = argv[0];
+
+    s = suite_create("Connect Stress");
+    tc = tcase_create("connectstress");
+    tcase_add_test(tc, connect_stress_test);
+    tcase_set_timeout(tc, 20 * 60);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/src/tests/cpu-test.c b/src/tests/cpu-test.c
new file mode 100644 (file)
index 0000000..aa4527a
--- /dev/null
@@ -0,0 +1,914 @@
+/***
+  This file is part of PulseAudio.
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <check.h>
+#include <unistd.h>
+#include <math.h>
+
+#include <pulse/rtclock.h>
+#include <pulsecore/cpu-x86.h>
+#include <pulsecore/cpu-orc.h>
+#include <pulsecore/random.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/endianmacros.h>
+#include <pulsecore/sconv.h>
+#include <pulsecore/remap.h>
+#include <pulsecore/sample-util.h>
+#include <pulsecore/mix.h>
+
+#define PA_CPU_TEST_RUN_START(l, t1, t2)                        \
+{                                                               \
+    int _j, _k;                                                 \
+    int _times = (t1), _times2 = (t2);                          \
+    pa_usec_t _start, _stop;                                    \
+    pa_usec_t _min = INT_MAX, _max = 0;                         \
+    double _s1 = 0, _s2 = 0;                                    \
+    const char *_label = (l);                                   \
+                                                                \
+    for (_k = 0; _k < _times2; _k++) {                          \
+        _start = pa_rtclock_now();                              \
+        for (_j = 0; _j < _times; _j++)
+
+#define PA_CPU_TEST_RUN_STOP                                    \
+        _stop = pa_rtclock_now();                               \
+                                                                \
+        if (_min > (_stop - _start)) _min = _stop - _start;     \
+        if (_max < (_stop - _start)) _max = _stop - _start;     \
+        _s1 += _stop - _start;                                  \
+        _s2 += (_stop - _start) * (_stop - _start);             \
+    }                                                           \
+    pa_log_debug("%s: %llu usec (avg: %g, min = %llu, max = %llu, stddev = %g).", _label, \
+            (long long unsigned int)_s1,                        \
+            ((double)_s1 / _times2),                            \
+            (long long unsigned int)_min,                       \
+            (long long unsigned int)_max,                       \
+            sqrt(_times2 * _s2 - _s1 * _s1) / _times2);         \
+}
+
+/* Common defines for svolume tests */
+#define SAMPLES 1028
+#define TIMES 1000
+#define TIMES2 100
+#define PADDING 16
+
+static void run_volume_test(
+        pa_do_volume_func_t func,
+        pa_do_volume_func_t orig_func,
+        int align,
+        int channels,
+        pa_bool_t correct,
+        pa_bool_t perf) {
+
+    PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES]) = { 0 };
+    PA_DECLARE_ALIGNED(8, int16_t, s_ref[SAMPLES]) = { 0 };
+    PA_DECLARE_ALIGNED(8, int16_t, s_orig[SAMPLES]) = { 0 };
+    int32_t volumes[channels + PADDING];
+    int16_t *samples, *samples_ref, *samples_orig;
+    int i, padding, nsamples, size;
+
+    /* Force sample alignment as requested */
+    samples = s + (8 - align);
+    samples_ref = s_ref + (8 - align);
+    samples_orig = s_orig + (8 - align);
+    nsamples = SAMPLES - (8 - align);
+    if (nsamples % channels)
+        nsamples -= nsamples % channels;
+    size = nsamples * sizeof(int16_t);
+
+    pa_random(samples, size);
+    memcpy(samples_ref, samples, size);
+    memcpy(samples_orig, samples, size);
+
+    for (i = 0; i < channels; i++)
+        volumes[i] = PA_CLAMP_VOLUME((pa_volume_t)(rand() >> 15));
+    for (padding = 0; padding < PADDING; padding++, i++)
+        volumes[i] = volumes[padding];
+
+    if (correct) {
+        orig_func(samples_ref, volumes, channels, size);
+        func(samples, volumes, channels, size);
+
+        for (i = 0; i < nsamples; i++) {
+            if (samples[i] != samples_ref[i]) {
+                pa_log_debug("Correctness test failed: align=%d, channels=%d", align, channels);
+                pa_log_debug("%d: %04hx != %04hx (%04hx * %08x)\n", i, samples[i], samples_ref[i],
+                        samples_orig[i], volumes[i % channels]);
+                fail();
+            }
+        }
+    }
+
+    if (perf) {
+        pa_log_debug("Testing svolume %dch performance with %d sample alignment", channels, align);
+
+        PA_CPU_TEST_RUN_START("func", TIMES, TIMES2) {
+            memcpy(samples, samples_orig, size);
+            func(samples, volumes, channels, size);
+        } PA_CPU_TEST_RUN_STOP
+
+        PA_CPU_TEST_RUN_START("orig", TIMES, TIMES2) {
+            memcpy(samples_ref, samples_orig, size);
+            orig_func(samples_ref, volumes, channels, size);
+        } PA_CPU_TEST_RUN_STOP
+
+        fail_unless(memcmp(samples_ref, samples, size) == 0);
+    }
+}
+
+#if defined (__i386__) || defined (__amd64__)
+START_TEST (svolume_mmx_test) {
+    pa_do_volume_func_t orig_func, mmx_func;
+    pa_cpu_x86_flag_t flags = 0;
+    int i, j;
+
+    pa_cpu_get_x86_flags(&flags);
+
+    if (!((flags & PA_CPU_X86_MMX) && (flags & PA_CPU_X86_CMOV))) {
+        pa_log_info("MMX/CMOV not supported. Skipping");
+        return;
+    }
+
+    orig_func = pa_get_volume_func(PA_SAMPLE_S16NE);
+    pa_volume_func_init_mmx(flags);
+    mmx_func = pa_get_volume_func(PA_SAMPLE_S16NE);
+
+    pa_log_debug("Checking MMX svolume");
+    for (i = 1; i <= 3; i++) {
+        for (j = 0; j < 7; j++)
+            run_volume_test(mmx_func, orig_func, j, i, TRUE, FALSE);
+    }
+    run_volume_test(mmx_func, orig_func, 7, 1, TRUE, TRUE);
+    run_volume_test(mmx_func, orig_func, 7, 2, TRUE, TRUE);
+    run_volume_test(mmx_func, orig_func, 7, 3, TRUE, TRUE);
+}
+END_TEST
+
+START_TEST (svolume_sse_test) {
+    pa_do_volume_func_t orig_func, sse_func;
+    pa_cpu_x86_flag_t flags = 0;
+    int i, j;
+
+    pa_cpu_get_x86_flags(&flags);
+
+    if (!(flags & PA_CPU_X86_SSE2)) {
+        pa_log_info("SSE2 not supported. Skipping");
+        return;
+    }
+
+    orig_func = pa_get_volume_func(PA_SAMPLE_S16NE);
+    pa_volume_func_init_sse(flags);
+    sse_func = pa_get_volume_func(PA_SAMPLE_S16NE);
+
+    pa_log_debug("Checking SSE2 svolume");
+    for (i = 1; i <= 3; i++) {
+        for (j = 0; j < 7; j++)
+            run_volume_test(sse_func, orig_func, j, i, TRUE, FALSE);
+    }
+    run_volume_test(sse_func, orig_func, 7, 1, TRUE, TRUE);
+    run_volume_test(sse_func, orig_func, 7, 2, TRUE, TRUE);
+    run_volume_test(sse_func, orig_func, 7, 3, TRUE, TRUE);
+}
+END_TEST
+#endif /* defined (__i386__) || defined (__amd64__) */
+
+#if defined (__arm__) && defined (__linux__)
+START_TEST (svolume_arm_test) {
+    pa_do_volume_func_t orig_func, arm_func;
+    pa_cpu_arm_flag_t flags = 0;
+    int i, j;
+
+    pa_cpu_get_arm_flags(&flags);
+
+    if (!(flags & PA_CPU_ARM_V6)) {
+        pa_log_info("ARMv6 instructions not supported. Skipping");
+        return;
+    }
+
+    orig_func = pa_get_volume_func(PA_SAMPLE_S16NE);
+    pa_volume_func_init_arm(flags);
+    arm_func = pa_get_volume_func(PA_SAMPLE_S16NE);
+
+    pa_log_debug("Checking ARM svolume");
+    for (i = 1; i <= 3; i++) {
+        for (j = 0; j < 7; j++)
+            run_volume_test(arm_func, orig_func, j, i, TRUE, FALSE);
+    }
+    run_volume_test(arm_func, orig_func, 7, 1, TRUE, TRUE);
+    run_volume_test(arm_func, orig_func, 7, 2, TRUE, TRUE);
+    run_volume_test(arm_func, orig_func, 7, 3, TRUE, TRUE);
+}
+END_TEST
+#endif /* defined (__arm__) && defined (__linux__) */
+
+START_TEST (svolume_orc_test) {
+    pa_do_volume_func_t orig_func, orc_func;
+    pa_cpu_info cpu_info;
+    int i, j;
+
+#if defined (__i386__) || defined (__amd64__)
+    pa_zero(cpu_info);
+    cpu_info.cpu_type = PA_CPU_X86;
+    pa_cpu_get_x86_flags(&cpu_info.flags.x86);
+#endif
+
+    orig_func = pa_get_volume_func(PA_SAMPLE_S16NE);
+
+    if (!pa_cpu_init_orc(cpu_info)) {
+        pa_log_info("Orc not supported. Skipping");
+        return;
+    }
+
+    orc_func = pa_get_volume_func(PA_SAMPLE_S16NE);
+
+    pa_log_debug("Checking Orc svolume");
+    for (i = 1; i <= 2; i++) {
+        for (j = 0; j < 7; j++)
+            run_volume_test(orc_func, orig_func, j, i, TRUE, FALSE);
+    }
+    run_volume_test(orc_func, orig_func, 7, 1, TRUE, TRUE);
+    run_volume_test(orc_func, orig_func, 7, 2, TRUE, TRUE);
+}
+END_TEST
+
+#undef SAMPLES
+#undef TIMES
+#undef TIMES2
+#undef PADDING
+/* End svolume tests */
+
+/* Start conversion tests */
+#define SAMPLES 1028
+#define TIMES 1000
+#define TIMES2 100
+
+static void run_conv_test_float_to_s16(
+        pa_convert_func_t func,
+        pa_convert_func_t orig_func,
+        int align,
+        pa_bool_t correct,
+        pa_bool_t perf) {
+
+    PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES]) = { 0 };
+    PA_DECLARE_ALIGNED(8, int16_t, s_ref[SAMPLES]) = { 0 };
+    PA_DECLARE_ALIGNED(8, float, f[SAMPLES]);
+    int16_t *samples, *samples_ref;
+    float *floats;
+    int i, nsamples;
+
+    /* Force sample alignment as requested */
+    samples = s + (8 - align);
+    samples_ref = s_ref + (8 - align);
+    floats = f + (8 - align);
+    nsamples = SAMPLES - (8 - align);
+
+    for (i = 0; i < nsamples; i++) {
+        floats[i] = 2.1f * (rand()/(float) RAND_MAX - 0.5f);
+    }
+
+    if (correct) {
+        orig_func(nsamples, floats, samples_ref);
+        func(nsamples, floats, samples);
+
+        for (i = 0; i < nsamples; i++) {
+            if (abs(samples[i] - samples_ref[i]) > 1) {
+                pa_log_debug("Correctness test failed: align=%d", align);
+                pa_log_debug("%d: %04hx != %04hx (%.24f)\n", i, samples[i], samples_ref[i], floats[i]);
+                fail();
+            }
+        }
+    }
+
+    if (perf) {
+        pa_log_debug("Testing sconv performance with %d sample alignment", align);
+
+        PA_CPU_TEST_RUN_START("func", TIMES, TIMES2) {
+            func(nsamples, floats, samples);
+        } PA_CPU_TEST_RUN_STOP
+
+        PA_CPU_TEST_RUN_START("orig", TIMES, TIMES2) {
+            orig_func(nsamples, floats, samples_ref);
+        } PA_CPU_TEST_RUN_STOP
+    }
+}
+
+/* This test is currently only run under NEON */
+#if defined (__arm__) && defined (__linux__)
+#ifdef HAVE_NEON
+static void run_conv_test_s16_to_float(
+        pa_convert_func_t func,
+        pa_convert_func_t orig_func,
+        int align,
+        pa_bool_t correct,
+        pa_bool_t perf) {
+
+    PA_DECLARE_ALIGNED(8, float, f[SAMPLES]) = { 0 };
+    PA_DECLARE_ALIGNED(8, float, f_ref[SAMPLES]) = { 0 };
+    PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES]);
+    float *floats, *floats_ref;
+    int16_t *samples;
+    int i, nsamples;
+
+    /* Force sample alignment as requested */
+    floats = f + (8 - align);
+    floats_ref = f_ref + (8 - align);
+    samples = s + (8 - align);
+    nsamples = SAMPLES - (8 - align);
+
+    pa_random(samples, nsamples * sizeof(int16_t));
+
+    if (correct) {
+        orig_func(nsamples, samples, floats_ref);
+        func(nsamples, samples, floats);
+
+        for (i = 0; i < nsamples; i++) {
+            if (fabsf(floats[i] - floats_ref[i]) > 0.0001) {
+                pa_log_debug("Correctness test failed: align=%d", align);
+                pa_log_debug("%d: %.24f != %.24f (%d)\n", i, floats[i], floats_ref[i], samples[i]);
+                fail();
+            }
+        }
+    }
+
+    if (perf) {
+        pa_log_debug("Testing sconv performance with %d sample alignment", align);
+
+        PA_CPU_TEST_RUN_START("func", TIMES, TIMES2) {
+            func(nsamples, samples, floats);
+        } PA_CPU_TEST_RUN_STOP
+
+        PA_CPU_TEST_RUN_START("orig", TIMES, TIMES2) {
+            orig_func(nsamples, samples, floats_ref);
+        } PA_CPU_TEST_RUN_STOP
+    }
+}
+#endif /* HAVE_NEON */
+#endif /* defined (__arm__) && defined (__linux__) */
+
+#if defined (__i386__) || defined (__amd64__)
+START_TEST (sconv_sse2_test) {
+    pa_cpu_x86_flag_t flags = 0;
+    pa_convert_func_t orig_func, sse2_func;
+
+    pa_cpu_get_x86_flags(&flags);
+
+    if (!(flags & PA_CPU_X86_SSE2)) {
+        pa_log_info("SSE2 not supported. Skipping");
+        return;
+    }
+
+    orig_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE);
+    pa_convert_func_init_sse(PA_CPU_X86_SSE2);
+    sse2_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE);
+
+    pa_log_debug("Checking SSE2 sconv (float -> s16)");
+    run_conv_test_float_to_s16(sse2_func, orig_func, 0, TRUE, FALSE);
+    run_conv_test_float_to_s16(sse2_func, orig_func, 1, TRUE, FALSE);
+    run_conv_test_float_to_s16(sse2_func, orig_func, 2, TRUE, FALSE);
+    run_conv_test_float_to_s16(sse2_func, orig_func, 3, TRUE, FALSE);
+    run_conv_test_float_to_s16(sse2_func, orig_func, 4, TRUE, FALSE);
+    run_conv_test_float_to_s16(sse2_func, orig_func, 5, TRUE, FALSE);
+    run_conv_test_float_to_s16(sse2_func, orig_func, 6, TRUE, FALSE);
+    run_conv_test_float_to_s16(sse2_func, orig_func, 7, TRUE, TRUE);
+}
+END_TEST
+
+START_TEST (sconv_sse_test) {
+    pa_cpu_x86_flag_t flags = 0;
+    pa_convert_func_t orig_func, sse_func;
+
+    pa_cpu_get_x86_flags(&flags);
+
+    if (!(flags & PA_CPU_X86_SSE)) {
+        pa_log_info("SSE not supported. Skipping");
+        return;
+    }
+
+    orig_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE);
+    pa_convert_func_init_sse(PA_CPU_X86_SSE);
+    sse_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE);
+
+    pa_log_debug("Checking SSE sconv (float -> s16)");
+    run_conv_test_float_to_s16(sse_func, orig_func, 0, TRUE, FALSE);
+    run_conv_test_float_to_s16(sse_func, orig_func, 1, TRUE, FALSE);
+    run_conv_test_float_to_s16(sse_func, orig_func, 2, TRUE, FALSE);
+    run_conv_test_float_to_s16(sse_func, orig_func, 3, TRUE, FALSE);
+    run_conv_test_float_to_s16(sse_func, orig_func, 4, TRUE, FALSE);
+    run_conv_test_float_to_s16(sse_func, orig_func, 5, TRUE, FALSE);
+    run_conv_test_float_to_s16(sse_func, orig_func, 6, TRUE, FALSE);
+    run_conv_test_float_to_s16(sse_func, orig_func, 7, TRUE, TRUE);
+}
+END_TEST
+#endif /* defined (__i386__) || defined (__amd64__) */
+
+#if defined (__arm__) && defined (__linux__)
+#ifdef HAVE_NEON
+START_TEST (sconv_neon_test) {
+    pa_cpu_arm_flag_t flags = 0;
+    pa_convert_func_t orig_from_func, neon_from_func;
+    pa_convert_func_t orig_to_func, neon_to_func;
+
+    pa_cpu_get_arm_flags(&flags);
+
+    if (!(flags & PA_CPU_ARM_NEON)) {
+        pa_log_info("NEON not supported. Skipping");
+        return;
+    }
+
+    orig_from_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE);
+    orig_to_func = pa_get_convert_to_float32ne_function(PA_SAMPLE_S16LE);
+    pa_convert_func_init_neon(flags);
+    neon_from_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE);
+    neon_to_func = pa_get_convert_to_float32ne_function(PA_SAMPLE_S16LE);
+
+    pa_log_debug("Checking NEON sconv (float -> s16)");
+    run_conv_test_float_to_s16(neon_from_func, orig_from_func, 0, TRUE, FALSE);
+    run_conv_test_float_to_s16(neon_from_func, orig_from_func, 1, TRUE, FALSE);
+    run_conv_test_float_to_s16(neon_from_func, orig_from_func, 2, TRUE, FALSE);
+    run_conv_test_float_to_s16(neon_from_func, orig_from_func, 3, TRUE, FALSE);
+    run_conv_test_float_to_s16(neon_from_func, orig_from_func, 4, TRUE, FALSE);
+    run_conv_test_float_to_s16(neon_from_func, orig_from_func, 5, TRUE, FALSE);
+    run_conv_test_float_to_s16(neon_from_func, orig_from_func, 6, TRUE, FALSE);
+    run_conv_test_float_to_s16(neon_from_func, orig_from_func, 7, TRUE, TRUE);
+
+    pa_log_debug("Checking NEON sconv (s16 -> float)");
+    run_conv_test_s16_to_float(neon_to_func, orig_to_func, 0, TRUE, FALSE);
+    run_conv_test_s16_to_float(neon_to_func, orig_to_func, 1, TRUE, FALSE);
+    run_conv_test_s16_to_float(neon_to_func, orig_to_func, 2, TRUE, FALSE);
+    run_conv_test_s16_to_float(neon_to_func, orig_to_func, 3, TRUE, FALSE);
+    run_conv_test_s16_to_float(neon_to_func, orig_to_func, 4, TRUE, FALSE);
+    run_conv_test_s16_to_float(neon_to_func, orig_to_func, 5, TRUE, FALSE);
+    run_conv_test_s16_to_float(neon_to_func, orig_to_func, 6, TRUE, FALSE);
+    run_conv_test_s16_to_float(neon_to_func, orig_to_func, 7, TRUE, TRUE);
+}
+END_TEST
+#endif /* HAVE_NEON */
+#endif /* defined (__arm__) && defined (__linux__) */
+
+#undef SAMPLES
+#undef TIMES
+/* End conversion tests */
+
+/* Start remap tests */
+#define SAMPLES 1028
+#define TIMES 1000
+#define TIMES2 100
+
+static void run_remap_test_mono_stereo_float(
+        pa_remap_t *remap,
+        pa_do_remap_func_t func,
+        pa_do_remap_func_t orig_func,
+        int align,
+        pa_bool_t correct,
+        pa_bool_t perf) {
+
+    PA_DECLARE_ALIGNED(8, float, s_ref[SAMPLES*2]) = { 0 };
+    PA_DECLARE_ALIGNED(8, float, s[SAMPLES*2]) = { 0 };
+    PA_DECLARE_ALIGNED(8, float, m[SAMPLES]);
+    float *stereo, *stereo_ref;
+    float *mono;
+    int i, nsamples;
+
+    /* Force sample alignment as requested */
+    stereo = s + (8 - align);
+    stereo_ref = s_ref + (8 - align);
+    mono = m + (8 - align);
+    nsamples = SAMPLES - (8 - align);
+
+    for (i = 0; i < nsamples; i++)
+        mono[i] = 2.1f * (rand()/(float) RAND_MAX - 0.5f);
+
+    if (correct) {
+        orig_func(remap, stereo_ref, mono, nsamples);
+        func(remap, stereo, mono, nsamples);
+
+        for (i = 0; i < nsamples * 2; i++) {
+            if (fabsf(stereo[i] - stereo_ref[i]) > 0.0001) {
+                pa_log_debug("Correctness test failed: align=%d", align);
+                pa_log_debug("%d: %.24f != %.24f (%.24f)\n", i, stereo[i], stereo_ref[i], mono[i]);
+                fail();
+            }
+        }
+    }
+
+    if (perf) {
+        pa_log_debug("Testing remap performance with %d sample alignment", align);
+
+        PA_CPU_TEST_RUN_START("func", TIMES, TIMES2) {
+            func(remap, stereo, mono, nsamples);
+        } PA_CPU_TEST_RUN_STOP
+
+        PA_CPU_TEST_RUN_START("orig", TIMES, TIMES2) {
+            orig_func(remap, stereo_ref, mono, nsamples);
+        } PA_CPU_TEST_RUN_STOP
+    }
+}
+
+static void run_remap_test_mono_stereo_s16(
+        pa_remap_t *remap,
+        pa_do_remap_func_t func,
+        pa_do_remap_func_t orig_func,
+        int align,
+        pa_bool_t correct,
+        pa_bool_t perf) {
+
+    PA_DECLARE_ALIGNED(8, int16_t, s_ref[SAMPLES*2]) = { 0 };
+    PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES*2]) = { 0 };
+    PA_DECLARE_ALIGNED(8, int16_t, m[SAMPLES]);
+    int16_t *stereo, *stereo_ref;
+    int16_t *mono;
+    int i, nsamples;
+
+    /* Force sample alignment as requested */
+    stereo = s + (8 - align);
+    stereo_ref = s_ref + (8 - align);
+    mono = m + (8 - align);
+    nsamples = SAMPLES - (8 - align);
+
+    pa_random(mono, nsamples * sizeof(int16_t));
+
+    if (correct) {
+        orig_func(remap, stereo_ref, mono, nsamples);
+        func(remap, stereo, mono, nsamples);
+
+        for (i = 0; i < nsamples * 2; i++) {
+            if (abs(stereo[i] - stereo_ref[i]) > 1) {
+                pa_log_debug("Correctness test failed: align=%d", align);
+                pa_log_debug("%d: %d != %d (%d)\n", i, stereo[i], stereo_ref[i], mono[i]);
+                fail();
+            }
+        }
+    }
+
+    if (perf) {
+        pa_log_debug("Testing remap performance with %d sample alignment", align);
+
+        PA_CPU_TEST_RUN_START("func", TIMES, TIMES2) {
+            func(remap, stereo, mono, nsamples);
+        } PA_CPU_TEST_RUN_STOP
+
+        PA_CPU_TEST_RUN_START("orig", TIMES, TIMES2) {
+            orig_func(remap, stereo_ref, mono, nsamples);
+        } PA_CPU_TEST_RUN_STOP
+    }
+}
+
+static void remap_test_mono_stereo_float(
+        pa_init_remap_func_t init_func,
+        pa_init_remap_func_t orig_init_func) {
+
+    pa_sample_format_t sf;
+    pa_remap_t remap;
+    pa_sample_spec iss, oss;
+    pa_do_remap_func_t orig_func, func;
+
+    iss.format = oss.format = sf = PA_SAMPLE_FLOAT32NE;
+    iss.channels = 1;
+    oss.channels = 2;
+    remap.format = &sf;
+    remap.i_ss = &iss;
+    remap.o_ss = &oss;
+    remap.map_table_f[0][0] = 1.0;
+    remap.map_table_f[1][0] = 1.0;
+    remap.map_table_i[0][0] = 0x10000;
+    remap.map_table_i[1][0] = 0x10000;
+    orig_init_func(&remap);
+    orig_func = remap.do_remap;
+    if (!orig_func) {
+        pa_log_warn("No reference remapping function, abort test");
+        return;
+    }
+
+    init_func(&remap);
+    func = remap.do_remap;
+    if (!func || func == orig_func) {
+        pa_log_warn("No remapping function, abort test");
+        return;
+    }
+
+    run_remap_test_mono_stereo_float(&remap, func, orig_func, 0, TRUE, FALSE);
+    run_remap_test_mono_stereo_float(&remap, func, orig_func, 1, TRUE, FALSE);
+    run_remap_test_mono_stereo_float(&remap, func, orig_func, 2, TRUE, FALSE);
+    run_remap_test_mono_stereo_float(&remap, func, orig_func, 3, TRUE, TRUE);
+}
+
+static void remap_test_mono_stereo_s16(
+        pa_init_remap_func_t init_func,
+        pa_init_remap_func_t orig_init_func) {
+
+    pa_sample_format_t sf;
+    pa_remap_t remap;
+    pa_sample_spec iss, oss;
+    pa_do_remap_func_t orig_func, func;
+
+    iss.format = oss.format = sf = PA_SAMPLE_S16NE;
+    iss.channels = 1;
+    oss.channels = 2;
+    remap.format = &sf;
+    remap.i_ss = &iss;
+    remap.o_ss = &oss;
+    remap.map_table_f[0][0] = 1.0;
+    remap.map_table_f[1][0] = 1.0;
+    remap.map_table_i[0][0] = 0x10000;
+    remap.map_table_i[1][0] = 0x10000;
+    orig_init_func(&remap);
+    orig_func = remap.do_remap;
+    if (!orig_func) {
+        pa_log_warn("No reference remapping function, abort test");
+        return;
+    }
+
+    init_func(&remap);
+    func = remap.do_remap;
+    if (!func || func == orig_func) {
+        pa_log_warn("No remapping function, abort test");
+        return;
+    }
+
+    run_remap_test_mono_stereo_s16(&remap, func, orig_func, 0, TRUE, FALSE);
+    run_remap_test_mono_stereo_s16(&remap, func, orig_func, 1, TRUE, FALSE);
+    run_remap_test_mono_stereo_s16(&remap, func, orig_func, 2, TRUE, FALSE);
+    run_remap_test_mono_stereo_s16(&remap, func, orig_func, 3, TRUE, TRUE);
+}
+
+#if defined (__i386__) || defined (__amd64__)
+START_TEST (remap_mmx_test) {
+    pa_cpu_x86_flag_t flags = 0;
+    pa_init_remap_func_t init_func, orig_init_func;
+
+    pa_cpu_get_x86_flags(&flags);
+    if (!(flags & PA_CPU_X86_MMX)) {
+        pa_log_info("MMX not supported. Skipping");
+        return;
+    }
+
+    pa_log_debug("Checking MMX remap (float, mono->stereo)");
+    orig_init_func = pa_get_init_remap_func();
+    pa_remap_func_init_mmx(flags);
+    init_func = pa_get_init_remap_func();
+    remap_test_mono_stereo_float(init_func, orig_init_func);
+
+    pa_log_debug("Checking MMX remap (s16, mono->stereo)");
+    remap_test_mono_stereo_s16(init_func, orig_init_func);
+}
+END_TEST
+
+START_TEST (remap_sse2_test) {
+    pa_cpu_x86_flag_t flags = 0;
+    pa_init_remap_func_t init_func, orig_init_func;
+
+    pa_cpu_get_x86_flags(&flags);
+    if (!(flags & PA_CPU_X86_SSE2)) {
+        pa_log_info("SSE2 not supported. Skipping");
+        return;
+    }
+
+    pa_log_debug("Checking SSE2 remap (float, mono->stereo)");
+    orig_init_func = pa_get_init_remap_func();
+    pa_remap_func_init_sse(flags);
+    init_func = pa_get_init_remap_func();
+    remap_test_mono_stereo_float(init_func, orig_init_func);
+
+    pa_log_debug("Checking SSE2 remap (s16, mono->stereo)");
+    remap_test_mono_stereo_s16(init_func, orig_init_func);
+}
+END_TEST
+#endif /* defined (__i386__) || defined (__amd64__) */
+
+#undef SAMPLES
+#undef TIMES
+#undef TIMES2
+/* End remap tests */
+
+/* Start mix tests */
+
+/* Only ARM NEON has mix tests, so disable the related functions for other
+ * architectures for now to avoid compiler warnings about unused functions. */
+#if defined (__arm__) && defined (__linux__)
+#ifdef HAVE_NEON
+
+#define SAMPLES 1028
+#define TIMES 1000
+#define TIMES2 100
+
+static void acquire_mix_streams(pa_mix_info streams[], unsigned nstreams) {
+    unsigned i;
+
+    for (i = 0; i < nstreams; i++)
+        streams[i].ptr = pa_memblock_acquire_chunk(&streams[i].chunk);
+}
+
+static void release_mix_streams(pa_mix_info streams[], unsigned nstreams) {
+    unsigned i;
+
+    for (i = 0; i < nstreams; i++)
+        pa_memblock_release(streams[i].chunk.memblock);
+}
+
+static void run_mix_test(
+        pa_do_mix_func_t func,
+        pa_do_mix_func_t orig_func,
+        int align,
+        int channels,
+        pa_bool_t correct,
+        pa_bool_t perf) {
+
+    PA_DECLARE_ALIGNED(8, int16_t, in0[SAMPLES * 4]) = { 0 };
+    PA_DECLARE_ALIGNED(8, int16_t, in1[SAMPLES * 4]) = { 0 };
+    PA_DECLARE_ALIGNED(8, int16_t, out[SAMPLES * 4]) = { 0 };
+    PA_DECLARE_ALIGNED(8, int16_t, out_ref[SAMPLES * 4]) = { 0 };
+    int16_t *samples0, *samples1;
+    int16_t *samples, *samples_ref;
+    int nsamples;
+    pa_mempool *pool;
+    pa_memchunk c0, c1;
+    pa_mix_info m[2];
+    int i;
+
+    pa_assert(channels == 1 || channels == 2 || channels == 4);
+
+    /* Force sample alignment as requested */
+    samples0 = in0 + (8 - align);
+    samples1 = in1 + (8 - align);
+    samples = out + (8 - align);
+    samples_ref = out_ref + (8 - align);
+    nsamples = channels * (SAMPLES - (8 - align));
+
+    fail_unless((pool = pa_mempool_new(FALSE, 0)) != NULL, NULL);
+
+    pa_random(samples0, nsamples * sizeof(int16_t));
+    c0.memblock = pa_memblock_new_fixed(pool, samples0, nsamples * sizeof(int16_t), FALSE);
+    c0.length = pa_memblock_get_length(c0.memblock);
+    c0.index = 0;
+
+    pa_random(samples1, nsamples * sizeof(int16_t));
+    c1.memblock = pa_memblock_new_fixed(pool, samples1, nsamples * sizeof(int16_t), FALSE);
+    c1.length = pa_memblock_get_length(c1.memblock);
+    c1.index = 0;
+
+    m[0].chunk = c0;
+    m[0].volume.channels = channels;
+    for (i = 0; i < channels; i++) {
+        m[0].volume.values[i] = PA_VOLUME_NORM;
+        m[0].linear[i].i = 0x5555;
+    }
+
+    m[1].chunk = c1;
+    m[1].volume.channels = channels;
+    for (i = 0; i < channels; i++) {
+        m[1].volume.values[i] = PA_VOLUME_NORM;
+        m[1].linear[i].i = 0x6789;
+    }
+
+    if (correct) {
+        acquire_mix_streams(m, 2);
+        orig_func(m, 2, channels, samples_ref, nsamples * sizeof(int16_t));
+        release_mix_streams(m, 2);
+
+        acquire_mix_streams(m, 2);
+        func(m, 2, channels, samples, nsamples * sizeof(int16_t));
+        release_mix_streams(m, 2);
+
+        for (i = 0; i < nsamples; i++) {
+            if (samples[i] != samples_ref[i]) {
+                pa_log_debug("Correctness test failed: align=%d, channels=%d", align, channels);
+                pa_log_debug("%d: %hd != %04hd (%hd + %hd)\n",
+                    i,
+                    samples[i], samples_ref[i],
+                    samples0[i], samples1[i]);
+                fail();
+            }
+        }
+    }
+
+    if (perf) {
+        pa_log_debug("Testing %d-channel mixing performance with %d sample alignment", channels, align);
+
+        PA_CPU_TEST_RUN_START("func", TIMES, TIMES2) {
+            acquire_mix_streams(m, 2);
+            func(m, 2, channels, samples, nsamples * sizeof(int16_t));
+            release_mix_streams(m, 2);
+        } PA_CPU_TEST_RUN_STOP
+
+        PA_CPU_TEST_RUN_START("orig", TIMES, TIMES2) {
+            acquire_mix_streams(m, 2);
+            orig_func(m, 2, channels, samples_ref, nsamples * sizeof(int16_t));
+            release_mix_streams(m, 2);
+        } PA_CPU_TEST_RUN_STOP
+    }
+
+    pa_memblock_unref(c0.memblock);
+    pa_memblock_unref(c1.memblock);
+
+    pa_mempool_free(pool);
+}
+#endif /* HAVE_NEON */
+#endif /* defined (__arm__) && defined (__linux__) */
+
+#if defined (__arm__) && defined (__linux__)
+#ifdef HAVE_NEON
+START_TEST (mix_neon_test) {
+    pa_do_mix_func_t orig_func, neon_func;
+    pa_cpu_arm_flag_t flags = 0;
+
+    pa_cpu_get_arm_flags(&flags);
+
+    if (!(flags & PA_CPU_ARM_NEON)) {
+        pa_log_info("NEON not supported. Skipping");
+        return;
+    }
+
+    orig_func = pa_get_mix_func(PA_SAMPLE_S16NE);
+    pa_mix_func_init_neon(flags);
+    neon_func = pa_get_mix_func(PA_SAMPLE_S16NE);
+
+    pa_log_debug("Checking NEON mix");
+    run_mix_test(neon_func, orig_func, 7, 2, TRUE, TRUE);
+}
+END_TEST
+#endif /* HAVE_NEON */
+#endif /* defined (__arm__) && defined (__linux__) */
+/* End mix tests */
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_DEBUG);
+
+    s = suite_create("CPU");
+
+    /* Volume tests */
+    tc = tcase_create("svolume");
+#if defined (__i386__) || defined (__amd64__)
+    tcase_add_test(tc, svolume_mmx_test);
+    tcase_add_test(tc, svolume_sse_test);
+#endif
+#if defined (__arm__) && defined (__linux__)
+    tcase_add_test(tc, svolume_arm_test);
+#endif
+    tcase_add_test(tc, svolume_orc_test);
+    tcase_set_timeout(tc, 120);
+    suite_add_tcase(s, tc);
+
+    /* Conversion tests */
+    tc = tcase_create("sconv");
+#if defined (__i386__) || defined (__amd64__)
+    tcase_add_test(tc, sconv_sse2_test);
+    tcase_add_test(tc, sconv_sse_test);
+#endif
+#if defined (__arm__) && defined (__linux__)
+#if HAVE_NEON
+    tcase_add_test(tc, sconv_neon_test);
+#endif
+#endif
+    tcase_set_timeout(tc, 120);
+    suite_add_tcase(s, tc);
+
+    /* Remap tests */
+    tc = tcase_create("remap");
+#if defined (__i386__) || defined (__amd64__)
+    tcase_add_test(tc, remap_mmx_test);
+    tcase_add_test(tc, remap_sse2_test);
+#endif
+    tcase_set_timeout(tc, 120);
+    suite_add_tcase(s, tc);
+    /* Mix tests */
+    tc = tcase_create("mix");
+#if defined (__arm__) && defined (__linux__)
+#if HAVE_NEON
+    tcase_add_test(tc, mix_neon_test);
+#endif
+#endif
+    tcase_set_timeout(tc, 120);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
index 9d0f4ee..8988c1a 100644 (file)
 #endif
 
 #include <assert.h>
-#include <sys/time.h>
+#include <time.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <signal.h>
 
+#include <check.h>
+
 #include <pulse/mainloop.h>
-#include <pulse/gccmacro.h>
 
 #ifdef TEST2
 #include <pulse/mainloop-signal.h>
 #endif
 
-#include "../daemon/cpulimit.h"
+#include <daemon/cpulimit.h>
 
 /* A simple example for testing the cpulimit subsystem */
 
@@ -49,17 +50,18 @@ static void func(pa_mainloop_api *m, pa_signal_event *e, int sig, void *userdata
     if ((now - start) >= 30) {
         m->quit(m, 1);
         fprintf(stderr, "Test failed\n");
+        fail();
     } else
         raise(SIGUSR1);
 }
 
 #endif
 
-int main(int argc, char *argv[]) {
+START_TEST (cpulimit_test) {
     pa_mainloop *m;
 
     m = pa_mainloop_new();
-    assert(m);
+    fail_unless(m != NULL);
 
     pa_cpu_limit_init(pa_mainloop_get_api(m));
 
@@ -78,6 +80,7 @@ int main(int argc, char *argv[]) {
 
         if ((now - start) >= 30) {
             fprintf(stderr, "Test failed\n");
+            fail();
             break;
         }
     }
@@ -86,6 +89,24 @@ int main(int argc, char *argv[]) {
     pa_cpu_limit_done();
 
     pa_mainloop_free(m);
+}
+END_TEST
 
-    return 0;
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("CPU Limit");
+    tc = tcase_create("cpulimit");
+    tcase_add_test(tc, cpulimit_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
diff --git a/src/tests/envelope-test.c b/src/tests/envelope-test.c
deleted file mode 100644 (file)
index 9382040..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  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, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <pulse/sample.h>
-#include <pulse/volume.h>
-#include <pulse/timeval.h>
-
-#include <pulsecore/envelope.h>
-#include <pulsecore/macro.h>
-#include <pulsecore/endianmacros.h>
-#include <pulsecore/memblock.h>
-#include <pulsecore/sample-util.h>
-
-const pa_envelope_def ramp_down = {
-    .n_points = 2,
-    .points_x = { 100*PA_USEC_PER_MSEC, 300*PA_USEC_PER_MSEC },
-    .points_y = {
-        .f = { 1.0f, 0.2f },
-        .i = { 0x10000, 0x10000/5 }
-    }
-};
-
-const pa_envelope_def ramp_up = {
-    .n_points = 2,
-    .points_x = { 100*PA_USEC_PER_MSEC, 300*PA_USEC_PER_MSEC },
-    .points_y = {
-        .f = { 0.2f, 1.0f },
-        .i = { 0x10000/5, 0x10000 }
-    }
-};
-
-const pa_envelope_def ramp_down2 = {
-    .n_points = 2,
-    .points_x = { 50*PA_USEC_PER_MSEC, 900*PA_USEC_PER_MSEC },
-    .points_y = {
-        .f = { 0.8f, 0.7f },
-        .i = { 0x10000*4/5, 0x10000*7/10 }
-    }
-};
-
-const pa_envelope_def ramp_up2 = {
-    .n_points = 2,
-    .points_x = { 50*PA_USEC_PER_MSEC, 900*PA_USEC_PER_MSEC },
-    .points_y = {
-        .f = { 0.7f, 0.9f },
-        .i = { 0x10000*7/10, 0x10000*9/10 }
-    }
-};
-
-static void dump_block(const pa_sample_spec *ss, const pa_memchunk *chunk) {
-    void *d;
-    unsigned i;
-
-    static unsigned j = 0;
-
-    d = pa_memblock_acquire(chunk->memblock);
-
-    switch (ss->format) {
-
-        case PA_SAMPLE_U8:
-        case PA_SAMPLE_ULAW:
-        case PA_SAMPLE_ALAW: {
-            uint8_t *u = d;
-
-            for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
-                printf("0x%02x ", *(u++));
-
-            break;
-        }
-
-        case PA_SAMPLE_S16NE:
-        case PA_SAMPLE_S16RE: {
-            int16_t *u = d;
-
-            for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
-                printf("%i\t%i\n", j++, *(u++));
-
-            break;
-        }
-
-        case PA_SAMPLE_S32NE:
-        case PA_SAMPLE_S32RE: {
-            int32_t *u = d;
-
-            for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
-                printf("%i\t%i\n", j++, *(u++));
-
-            break;
-        }
-
-        case PA_SAMPLE_FLOAT32NE:
-        case PA_SAMPLE_FLOAT32RE: {
-            float *u = d;
-
-            for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
-                printf("%i\t%1.3g\n", j++, PA_MAYBE_FLOAT32_SWAP(ss->format == PA_SAMPLE_FLOAT32RE, *u));
-                u++;
-            }
-
-            break;
-        }
-
-        default:
-            pa_assert_not_reached();
-    }
-
-    printf("\n");
-
-    pa_memblock_release(chunk->memblock);
-}
-
-static pa_memblock * generate_block(pa_mempool *pool, const pa_sample_spec *ss) {
-    pa_memblock *block;
-    void *d;
-    unsigned n_samples;
-
-    block = pa_memblock_new(pool, pa_bytes_per_second(ss));
-    n_samples = (unsigned) (pa_memblock_get_length(block) / pa_sample_size(ss));
-
-    d = pa_memblock_acquire(block);
-
-    switch (ss->format) {
-
-        case PA_SAMPLE_S16NE:
-        case PA_SAMPLE_S16RE: {
-            int16_t *i;
-
-            for (i = d; n_samples > 0; n_samples--, i++)
-                *i = 0x7FFF;
-
-            break;
-        }
-
-        case PA_SAMPLE_S32NE:
-        case PA_SAMPLE_S32RE: {
-            int32_t *i;
-
-            for (i = d; n_samples > 0; n_samples--, i++)
-                *i = 0x7FFFFFFF;
-
-            break;
-        }
-
-        case PA_SAMPLE_FLOAT32RE:
-        case PA_SAMPLE_FLOAT32NE: {
-            float *f;
-
-            for (f = d; n_samples > 0; n_samples--, f++)
-                *f = PA_MAYBE_FLOAT32_SWAP(ss->format == PA_SAMPLE_FLOAT32RE, 1.0f);
-
-            break;
-        }
-
-        default:
-            pa_assert_not_reached();
-    }
-
-    pa_memblock_release(block);
-    return block;
-}
-
-int main(int argc, char *argv[]) {
-    pa_mempool *pool;
-    pa_memblock *block;
-    pa_memchunk chunk;
-    pa_envelope *envelope;
-    pa_envelope_item *item1, *item2;
-
-    const pa_sample_spec ss = {
-        .format = PA_SAMPLE_S16NE,
-        .channels = 1,
-        .rate = 200
-    };
-
-    const pa_cvolume v = {
-        .channels = 1,
-        .values = { PA_VOLUME_NORM, PA_VOLUME_NORM/2 }
-    };
-
-    pa_log_set_level(PA_LOG_DEBUG);
-
-    pa_assert_se(pool = pa_mempool_new(FALSE, 0));
-    pa_assert_se(envelope = pa_envelope_new(&ss));
-
-    block = generate_block(pool, &ss);
-
-    chunk.memblock = pa_memblock_ref(block);
-    chunk.length = pa_memblock_get_length(block);
-    chunk.index = 0;
-
-    pa_volume_memchunk(&chunk, &ss, &v);
-
-    item1 = pa_envelope_add(envelope, &ramp_down);
-    item2 = pa_envelope_add(envelope, &ramp_down2);
-    pa_envelope_apply(envelope, &chunk);
-    dump_block(&ss, &chunk);
-
-    pa_memblock_unref(chunk.memblock);
-
-    chunk.memblock = pa_memblock_ref(block);
-    chunk.length = pa_memblock_get_length(block);
-    chunk.index = 0;
-
-    item1 = pa_envelope_replace(envelope, item1, &ramp_up);
-    item2 = pa_envelope_replace(envelope, item2, &ramp_up2);
-    pa_envelope_apply(envelope, &chunk);
-    dump_block(&ss, &chunk);
-
-    pa_memblock_unref(chunk.memblock);
-
-    pa_envelope_remove(envelope, item1);
-    pa_envelope_remove(envelope, item2);
-    pa_envelope_free(envelope);
-
-    pa_memblock_unref(block);
-
-    pa_mempool_free(pool);
-
-    return 0;
-}
diff --git a/src/tests/extended-test.c b/src/tests/extended-test.c
new file mode 100644 (file)
index 0000000..ce8a6b0
--- /dev/null
@@ -0,0 +1,222 @@
+/***
+  This file is part of PulseAudio.
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <signal.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <check.h>
+
+#include <pulse/pulseaudio.h>
+#include <pulse/mainloop.h>
+
+#define NSTREAMS 4
+#define SINE_HZ 440
+#define SAMPLE_HZ 8000
+
+static pa_context *context = NULL;
+static pa_stream *streams[NSTREAMS];
+static pa_mainloop_api *mainloop_api = NULL;
+static const char *bname;
+
+static float data[SAMPLE_HZ]; /* one second space */
+
+static int n_streams_ready = 0;
+
+static const pa_buffer_attr buffer_attr = {
+    .maxlength = SAMPLE_HZ*sizeof(float)*NSTREAMS, /* exactly space for the entire play time */
+    .tlength = (uint32_t) -1,
+    .prebuf = 0, /* Setting prebuf to 0 guarantees us the streams will run synchronously, no matter what */
+    .minreq = (uint32_t) -1,
+    .fragsize = 0
+};
+
+static void nop_free_cb(void *p) {}
+
+static void underflow_cb(struct pa_stream *s, void *userdata) {
+    int i = (int) (long) userdata;
+
+    fprintf(stderr, "Stream %i finished\n", i);
+
+    if (++n_streams_ready >= 2*NSTREAMS) {
+        fprintf(stderr, "We're done\n");
+        mainloop_api->quit(mainloop_api, 0);
+    }
+}
+
+/* This routine is called whenever the stream state changes */
+static void stream_state_callback(pa_stream *s, void *userdata) {
+    fail_unless(s != NULL);
+
+    switch (pa_stream_get_state(s)) {
+        case PA_STREAM_UNCONNECTED:
+        case PA_STREAM_CREATING:
+        case PA_STREAM_TERMINATED:
+            break;
+
+        case PA_STREAM_READY: {
+
+            int r, i = (int) (long) userdata;
+
+            fprintf(stderr, "Writing data to stream %i.\n", i);
+
+            r = pa_stream_write(s, data, sizeof(data), nop_free_cb, (int64_t) sizeof(data) * (int64_t) i, PA_SEEK_ABSOLUTE);
+            fail_unless(r == 0);
+
+            /* Be notified when this stream is drained */
+            pa_stream_set_underflow_callback(s, underflow_cb, userdata);
+
+            /* All streams have been set up, let's go! */
+            if (++n_streams_ready >= NSTREAMS) {
+                fprintf(stderr, "Uncorking\n");
+                pa_operation_unref(pa_stream_cork(s, 0, NULL, NULL));
+            }
+
+            break;
+        }
+
+        default:
+        case PA_STREAM_FAILED:
+            fprintf(stderr, "Stream error: %s\n", pa_strerror(pa_context_errno(pa_stream_get_context(s))));
+            fail();
+    }
+}
+
+/* This is called whenever the context status changes */
+static void context_state_callback(pa_context *c, void *userdata) {
+    fail_unless(c != NULL);
+
+    switch (pa_context_get_state(c)) {
+        case PA_CONTEXT_CONNECTING:
+        case PA_CONTEXT_AUTHORIZING:
+        case PA_CONTEXT_SETTING_NAME:
+            break;
+
+        case PA_CONTEXT_READY: {
+
+            int i;
+            fprintf(stderr, "Connection established.\n");
+
+            for (i = 0; i < NSTREAMS; i++) {
+                char name[64];
+                pa_format_info *formats[1];
+
+                formats[0] = pa_format_info_new();
+                formats[0]->encoding = PA_ENCODING_PCM;
+                pa_format_info_set_sample_format(formats[0], PA_SAMPLE_FLOAT32);
+                pa_format_info_set_rate(formats[0], SAMPLE_HZ);
+                pa_format_info_set_channels(formats[0], 1);
+
+                fprintf(stderr, "Creating stream %i\n", i);
+
+                snprintf(name, sizeof(name), "stream #%i", i);
+
+                streams[i] = pa_stream_new_extended(c, name, formats, 1, NULL);
+                fail_unless(streams[i] != NULL);
+                pa_stream_set_state_callback(streams[i], stream_state_callback, (void*) (long) i);
+                pa_stream_connect_playback(streams[i], NULL, &buffer_attr, PA_STREAM_START_CORKED, NULL, i == 0 ? NULL : streams[0]);
+
+                pa_format_info_free(formats[0]);
+            }
+
+            break;
+        }
+
+        case PA_CONTEXT_TERMINATED:
+            mainloop_api->quit(mainloop_api, 0);
+            break;
+
+        case PA_CONTEXT_FAILED:
+        default:
+            fprintf(stderr, "Context error: %s\n", pa_strerror(pa_context_errno(c)));
+            fail();
+    }
+}
+
+START_TEST (extended_test) {
+    pa_mainloop* m = NULL;
+    int i, ret = 1;
+
+    for (i = 0; i < SAMPLE_HZ; i++)
+        data[i] = (float) sin(((double) i/SAMPLE_HZ)*2*M_PI*SINE_HZ)/2;
+
+    for (i = 0; i < NSTREAMS; i++)
+        streams[i] = NULL;
+
+    /* Set up a new main loop */
+    m = pa_mainloop_new();
+    fail_unless(m != NULL);
+
+    mainloop_api = pa_mainloop_get_api(m);
+
+    context = pa_context_new(mainloop_api, bname);
+    fail_unless(context != NULL);
+
+    pa_context_set_state_callback(context, context_state_callback, NULL);
+
+    /* Connect the context */
+    if (pa_context_connect(context, NULL, 0, NULL) < 0) {
+        fprintf(stderr, "pa_context_connect() failed.\n");
+        goto quit;
+    }
+
+    if (pa_mainloop_run(m, &ret) < 0)
+        fprintf(stderr, "pa_mainloop_run() failed.\n");
+
+quit:
+    pa_context_unref(context);
+
+    for (i = 0; i < NSTREAMS; i++)
+        if (streams[i])
+            pa_stream_unref(streams[i]);
+
+    pa_mainloop_free(m);
+
+    fail_unless(ret == 0);
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    bname = argv[0];
+
+    s = suite_create("Extended");
+    tc = tcase_create("extended");
+    tcase_add_test(tc, extended_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
index 64c0add..6915204 100644 (file)
@@ -87,7 +87,7 @@ int main(int argc, char* argv[]) {
     flist = pa_flist_new(0);
 
     for (i = 0; i < THREADS_MAX; i++) {
-        threads[i] = pa_thread_new(thread_func, pa_sprintf_malloc("Thread #%i", i+1));
+        threads[i] = pa_thread_new("test", thread_func, pa_sprintf_malloc("Thread #%i", i+1));
         assert(threads[i]);
     }
 
diff --git a/src/tests/format-test.c b/src/tests/format-test.c
new file mode 100644 (file)
index 0000000..5e7d587
--- /dev/null
@@ -0,0 +1,171 @@
+/***
+  This file is part of PulseAudio.
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <check.h>
+
+#include <pulsecore/macro.h>
+#include <pulsecore/core-util.h>
+#include <pulse/format.h>
+#include <pulse/xmalloc.h>
+
+#define INIT(f) f = pa_format_info_new()
+#define DEINIT(f) pa_format_info_free(f);
+#define REINIT(f) { DEINIT(f); INIT(f); }
+
+START_TEST (format_test) {
+    pa_format_info *f1 = NULL, *f2 = NULL;
+    int rates1[] = { 32000, 44100, 48000 }, i, temp_int1 = -1, temp_int2 = -1, *temp_int_array;
+    const char *strings[] = { "thing1", "thing2", "thing3" };
+    char *temp_str, **temp_str_array;
+
+    /* 1. Simple fixed format int check */
+    INIT(f1); INIT(f2);
+    f1->encoding = PA_ENCODING_AC3_IEC61937;
+    pa_format_info_set_prop_int(f1, PA_PROP_FORMAT_RATE, 32000);
+    f2->encoding = PA_ENCODING_AC3_IEC61937;
+    pa_format_info_set_prop_int(f2, PA_PROP_FORMAT_RATE, 44100);
+    fail_unless(!pa_format_info_is_compatible(f1, f2));
+
+    /* 2. Check int array membership - positive */
+    REINIT(f1); REINIT(f2);
+    f1->encoding = PA_ENCODING_AC3_IEC61937;
+    pa_format_info_set_prop_int_array(f1, PA_PROP_FORMAT_RATE, rates1, PA_ELEMENTSOF(rates1));
+    f2->encoding = PA_ENCODING_AC3_IEC61937;
+    pa_format_info_set_prop_int(f2, PA_PROP_FORMAT_RATE, 44100);
+    fail_unless(pa_format_info_is_compatible(f1, f2));
+    fail_unless(pa_format_info_is_compatible(f2, f1));
+
+    /* 3. Check int array membership - negative */
+    REINIT(f2);
+    f2->encoding = PA_ENCODING_AC3_IEC61937;
+    pa_format_info_set_prop_int(f2, PA_PROP_FORMAT_RATE, 96000);
+    fail_unless(!pa_format_info_is_compatible(f1, f2));
+    fail_unless(!pa_format_info_is_compatible(f2, f1));
+
+    /* 4. Check int range - positive */
+    REINIT(f1); REINIT(f2);
+    f1->encoding = PA_ENCODING_AC3_IEC61937;
+    pa_format_info_set_prop_int_range(f1, PA_PROP_FORMAT_RATE, 32000, 48000);
+    f2->encoding = PA_ENCODING_AC3_IEC61937;
+    pa_format_info_set_prop_int(f2, PA_PROP_FORMAT_RATE, 44100);
+    fail_unless(pa_format_info_is_compatible(f1, f2));
+    fail_unless(pa_format_info_is_compatible(f2, f1));
+
+    /* 5. Check int range - negative */
+    REINIT(f2);
+    f2->encoding = PA_ENCODING_AC3_IEC61937;
+    pa_format_info_set_prop_int(f2, PA_PROP_FORMAT_RATE, 96000);
+    fail_unless(!pa_format_info_is_compatible(f1, f2));
+    fail_unless(!pa_format_info_is_compatible(f2, f1));
+
+    /* 6. Simple fixed format string check */
+    REINIT(f1); REINIT(f2);
+    f1->encoding = PA_ENCODING_AC3_IEC61937;
+    pa_format_info_set_prop_string(f1, "format.test_string", "thing1");
+    f2->encoding = PA_ENCODING_AC3_IEC61937;
+    pa_format_info_set_prop_string(f2, "format.test_string", "notthing1");
+    fail_unless(!pa_format_info_is_compatible(f1, f2));
+
+    /* 7. Check string array membership - positive */
+    REINIT(f1); REINIT(f2);
+    f1->encoding = PA_ENCODING_AC3_IEC61937;
+    pa_format_info_set_prop_string_array(f1, "format.test_string", strings, PA_ELEMENTSOF(strings));
+    f2->encoding = PA_ENCODING_AC3_IEC61937;
+    pa_format_info_set_prop_string(f2, "format.test_string", "thing3");
+    fail_unless(pa_format_info_is_compatible(f1, f2));
+    fail_unless(pa_format_info_is_compatible(f2, f1));
+
+    /* 8. Check string array membership - negative */
+    REINIT(f2);
+    f2->encoding = PA_ENCODING_AC3_IEC61937;
+    pa_format_info_set_prop_string(f2, "format.test_string", "thing5");
+    fail_unless(!pa_format_info_is_compatible(f1, f2));
+    fail_unless(!pa_format_info_is_compatible(f2, f1));
+
+    /* 9. Verify setting/getting an int */
+    REINIT(f1);
+    pa_format_info_set_prop_int(f1, "format.test_string", 42);
+    fail_unless(pa_format_info_get_prop_type(f1, "format.test_string") == PA_PROP_TYPE_INT);
+    fail_unless(pa_format_info_get_prop_int(f1, "format.test_string", &temp_int1) == 0);
+    fail_unless(temp_int1 == 42);
+
+    /* 10. Verify setting/getting an int range */
+    REINIT(f1);
+    pa_format_info_set_prop_int_range(f1, "format.test_string", 0, 100);
+    pa_assert(pa_format_info_get_prop_type(f1, "format.test_string") == PA_PROP_TYPE_INT_RANGE);
+    pa_assert(pa_format_info_get_prop_int_range(f1, "format.test_string", &temp_int1, &temp_int2) == 0);
+    pa_assert(temp_int1 == 0 && temp_int2 == 100);
+
+    /* 11. Verify setting/getting an int array */
+    REINIT(f1);
+    pa_format_info_set_prop_int_array(f1, "format.test_string", rates1, PA_ELEMENTSOF(rates1));
+    fail_unless(pa_format_info_get_prop_type(f1, "format.test_string") == PA_PROP_TYPE_INT_ARRAY);
+    fail_unless(pa_format_info_get_prop_int_array(f1, "format.test_string", &temp_int_array, &temp_int1) == 0);
+    fail_unless(temp_int1 == PA_ELEMENTSOF(rates1));
+    for (i = 0; i < temp_int1; i++)
+        fail_unless(temp_int_array[i] == rates1[i]);
+    pa_xfree(temp_int_array);
+
+    /* 12. Verify setting/getting a string */
+    REINIT(f1);
+    pa_format_info_set_prop_string(f1, "format.test_string", "foo");
+    fail_unless(pa_format_info_get_prop_type(f1, "format.test_string") == PA_PROP_TYPE_STRING);
+    fail_unless(pa_format_info_get_prop_string(f1, "format.test_string", &temp_str) == 0);
+    fail_unless(pa_streq(temp_str, "foo"));
+    pa_xfree(temp_str);
+
+    /* 13. Verify setting/getting an int array */
+    REINIT(f1);
+    pa_format_info_set_prop_string_array(f1, "format.test_string", strings, PA_ELEMENTSOF(strings));
+    fail_unless(pa_format_info_get_prop_type(f1, "format.test_string") == PA_PROP_TYPE_STRING_ARRAY);
+    fail_unless(pa_format_info_get_prop_string_array(f1, "format.test_string", &temp_str_array, &temp_int1) == 0);
+    fail_unless(temp_int1 == PA_ELEMENTSOF(strings));
+    for (i = 0; i < temp_int1; i++)
+        fail_unless(pa_streq(temp_str_array[i], strings[i]));
+    pa_format_info_free_string_array(temp_str_array, temp_int1);
+
+    DEINIT(f1);
+    DEINIT(f2);
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Format");
+    tc = tcase_create("format");
+    tcase_add_test(tc, format_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
index e49f2ef..5d781c9 100644 (file)
 #include <config.h>
 #endif
 
-#include <limits.h>
 #include <stdio.h>
 #include <string.h>
 
+#include <check.h>
+
 #include <pulse/util.h>
 #include <pulse/xmalloc.h>
 
-int main(int argc, char *argv[]) {
+#include <pulsecore/log.h>
+
+START_TEST (getbinaryname_test) {
     char *exename;
     size_t allocated = 128;
 
@@ -36,20 +39,38 @@ int main(int argc, char *argv[]) {
         exename = pa_xmalloc(allocated);
 
         if (!pa_get_binary_name(exename, allocated)) {
-            printf("failed to read binary name\n");
+            pa_log_error("failed to read binary name");
             pa_xfree(exename);
-            break;
+            fail();
         }
 
         if (strlen(exename) < allocated - 1) {
-            printf("%s\n", exename);
+            pa_log("%s", exename);
             pa_xfree(exename);
-            break;
+            return;
         }
 
         pa_xfree(exename);
         allocated *= 2;
     }
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Binary Name");
+    tc = tcase_create("getbinaryname");
+    tcase_add_test(tc, getbinaryname_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
 
-    return 0;
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index 452e477..aec2a5d 100644 (file)
@@ -2,20 +2,26 @@
 #include <config.h>
 #endif
 
+#include <check.h>
+
 #include <pulsecore/hook-list.h>
 #include <pulsecore/log.h>
 
 static pa_hook_result_t func1(const char *hook_data, const char *call_data, const char *slot_data) {
     pa_log("(func1) hook=%s call=%s slot=%s", hook_data, call_data, slot_data);
+    /* succeed when it runs to here */
+    fail_unless(1);
     return PA_HOOK_OK;
 }
 
 static pa_hook_result_t func2(const char *hook_data, const char *call_data, const char *slot_data) {
     pa_log("(func2) hook=%s call=%s slot=%s", hook_data, call_data, slot_data);
+    /* succeed when it runs to here */
+    fail_unless(1);
     return PA_HOOK_OK;
 }
 
-int main(int argc, char *argv[]) {
+START_TEST (hooklist_test) {
     pa_hook hook;
     pa_hook_slot *slot;
 
@@ -32,6 +38,24 @@ int main(int argc, char *argv[]) {
     pa_hook_fire(&hook, (void*) "call2");
 
     pa_hook_done(&hook);
+}
+END_TEST
 
-    return 0;
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Hook List");
+    tc = tcase_create("hooklist");
+    tcase_add_test(tc, hooklist_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index 007555c..6303c5e 100644 (file)
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
-#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <getopt.h>
-#include <math.h>
+
+#include <check.h>
 
 #include <pulse/pulseaudio.h>
 #include <pulse/mainloop.h>
 
+#include <pulsecore/log.h>
+#include <pulsecore/macro.h>
 #include <pulsecore/thread.h>
 
 #define INTERPOLATE
@@ -44,6 +45,7 @@ static pa_stream *stream = NULL;
 static pa_mainloop_api *mainloop_api = NULL;
 static pa_bool_t playback = TRUE;
 static pa_usec_t latency = 0;
+static const char *bname = NULL;
 
 static void stream_write_cb(pa_stream *p, size_t nbytes, void *userdata) {
     /* Just some silence */
@@ -51,14 +53,14 @@ static void stream_write_cb(pa_stream *p, size_t nbytes, void *userdata) {
     for (;;) {
         void *data;
 
-        pa_assert_se((nbytes = pa_stream_writable_size(p)) != (size_t) -1);
+        fail_unless((nbytes = pa_stream_writable_size(p)) != (size_t) -1);
 
         if (nbytes <= 0)
             break;
 
-        pa_assert_se(pa_stream_begin_write(p, &data, &nbytes) == 0);
+        fail_unless(pa_stream_begin_write(p, &data, &nbytes) == 0);
         pa_memzero(data, nbytes);
-        pa_assert_se(pa_stream_write(p, data, nbytes, NULL, 0, PA_SEEK_RELATIVE) == 0);
+        fail_unless(pa_stream_write(p, data, nbytes, NULL, 0, PA_SEEK_RELATIVE) == 0);
     }
 }
 
@@ -73,8 +75,8 @@ static void stream_read_cb(pa_stream *p, size_t nbytes, void *userdata) {
         if (nbytes <= 0)
             break;
 
-        pa_assert_se(pa_stream_peek(p, &data, &nbytes) == 0);
-        pa_assert_se(pa_stream_drop(p) == 0);
+        fail_unless(pa_stream_peek(p, &data, &nbytes) == 0);
+        fail_unless(pa_stream_drop(p) == 0);
     }
 }
 
@@ -89,7 +91,7 @@ static void stream_latency_cb(pa_stream *p, void *userdata) {
 
 /* This is called whenever the context status changes */
 static void context_state_callback(pa_context *c, void *userdata) {
-    assert(c);
+    fail_unless(c != NULL);
 
     switch (pa_context_get_state(c)) {
         case PA_CONTEXT_CONNECTING:
@@ -120,9 +122,10 @@ static void context_state_callback(pa_context *c, void *userdata) {
             if (latency > 0)
                 flags |= PA_STREAM_ADJUST_LATENCY;
 
-            fprintf(stderr, "Connection established.\n");
+            pa_log("Connection established");
 
-            pa_assert_se(stream = pa_stream_new(c, "interpol-test", &ss, NULL));
+            stream = pa_stream_new(c, "interpol-test", &ss, NULL);
+            fail_unless(stream != NULL);
 
             if (playback) {
                 pa_assert_se(pa_stream_connect_playback(stream, NULL, &attr, flags, NULL, NULL) == 0);
@@ -142,12 +145,12 @@ static void context_state_callback(pa_context *c, void *userdata) {
 
         case PA_CONTEXT_FAILED:
         default:
-            fprintf(stderr, "Context error: %s\n", pa_strerror(pa_context_errno(c)));
-            abort();
+            pa_log_error("Context error: %s", pa_strerror(pa_context_errno(c)));
+            fail();
     }
 }
 
-int main(int argc, char *argv[]) {
+START_TEST (interpol_test) {
     pa_threaded_mainloop* m = NULL;
     int k;
     struct timeval start, last_info = { 0, 0 };
@@ -156,26 +159,21 @@ int main(int argc, char *argv[]) {
     pa_bool_t corked = FALSE;
 #endif
 
-    pa_log_set_level(PA_LOG_DEBUG);
-
-    playback = argc <= 1 || !pa_streq(argv[1], "-r");
-
-    latency =
-        (argc >= 2 && !pa_streq(argv[1], "-r")) ? atoi(argv[1]) :
-        (argc >= 3 ? atoi(argv[2]) : 0);
-
     /* Set up a new main loop */
-    pa_assert_se(m = pa_threaded_mainloop_new());
-    pa_assert_se(mainloop_api = pa_threaded_mainloop_get_api(m));
-    pa_assert_se(context = pa_context_new(mainloop_api, argv[0]));
+    m = pa_threaded_mainloop_new();
+    fail_unless(m != NULL);
+    mainloop_api = pa_threaded_mainloop_get_api(m);
+    fail_unless(mainloop_api != NULL);
+    context = pa_context_new(mainloop_api, bname);
+    fail_unless(context != NULL);
 
     pa_context_set_state_callback(context, context_state_callback, NULL);
 
-    pa_assert_se(pa_context_connect(context, NULL, 0, NULL) >= 0);
+    fail_unless(pa_context_connect(context, NULL, 0, NULL) >= 0);
 
     pa_gettimeofday(&start);
 
-    pa_assert_se(pa_threaded_mainloop_start(m) >= 0);
+    fail_unless(pa_threaded_mainloop_start(m) >= 0);
 
 /* #ifdef CORK */
     for (k = 0; k < 20000; k++)
@@ -216,7 +214,7 @@ int main(int argc, char *argv[]) {
             pa_bool_t cork_now;
 #endif
             rtc = pa_timeval_diff(&now, &start);
-            printf("%i\t%llu\t%llu\t%llu\t%llu\t%lli\t%u\t%u\t%llu\t%llu\n", k,
+            pa_log_info("%i\t%llu\t%llu\t%llu\t%llu\t%lli\t%u\t%u\t%llu\t%llu\n", k,
                    (unsigned long long) rtc,
                    (unsigned long long) t,
                    (unsigned long long) (rtc-old_rtc),
@@ -247,7 +245,6 @@ int main(int argc, char *argv[]) {
         }
 
         /* Spin loop, ugly but normal usleep() is just too badly grained */
-
         tv = now;
         while (pa_timeval_diff(pa_gettimeofday(&now), &tv) < 1000)
             pa_thread_yield();
@@ -268,6 +265,32 @@ int main(int argc, char *argv[]) {
 
     if (m)
         pa_threaded_mainloop_free(m);
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_DEBUG);
+
+    bname = argv[0];
+    playback = argc <= 1 || !pa_streq(argv[1], "-r");
+    latency = (argc >= 2 && !pa_streq(argv[1], "-r")) ? atoi(argv[1]) : (argc >= 3 ? atoi(argv[2]) : 0);
+
+    s = suite_create("Interpol");
+    tc = tcase_create("interpol");
+    tcase_add_test(tc, interpol_test);
+    tcase_set_timeout(tc, 5 * 60);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
 
-    return 0;
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index 57b7068..4ce3490 100644 (file)
@@ -5,12 +5,10 @@
 #include <sys/types.h>
 #include <stdio.h>
 #include <unistd.h>
-#include <assert.h>
 #include <string.h>
 
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
+#include <check.h>
+
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
 #ifdef HAVE_NETINET_IP_H
 #include <netinet/ip.h>
 #endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-#include "../pulsecore/winsock.h"
-#include "../pulsecore/macro.h"
 
+#include <pulsecore/log.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/socket.h>
 #include <pulsecore/ipacl.h>
+#include <pulsecore/arpa-inet.h>
 
-int main(int argc, char *argv[]) {
+static void do_ip_acl_check(const char *s, int fd, int expected) {
+    pa_ip_acl *acl;
+    int result;
+
+    acl = pa_ip_acl_new(s);
+    fail_unless(acl != NULL);
+    result = pa_ip_acl_check(acl, fd);
+    pa_ip_acl_free(acl);
+
+    pa_log_info("%-20s result=%u (should be %u)", s, result, expected);
+    fail_unless(result == expected);
+}
+
+START_TEST (ipacl_test) {
     struct sockaddr_in sa;
 #ifdef HAVE_IPV6
     struct sockaddr_in6 sa6;
 #endif
     int fd;
     int r;
-    pa_ip_acl *acl;
 
     fd = socket(PF_INET, SOCK_STREAM, 0);
-    assert(fd >= 0);
+    fail_unless(fd >= 0);
 
     sa.sin_family = AF_INET;
     sa.sin_port = htons(22);
     sa.sin_addr.s_addr = inet_addr("127.0.0.1");
 
     r = connect(fd, (struct sockaddr*) &sa, sizeof(sa));
-    assert(r >= 0);
-
-    acl = pa_ip_acl_new("127.0.0.1");
-    assert(acl);
-    printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
-    pa_ip_acl_free(acl);
-
-    acl = pa_ip_acl_new("127.0.0.2/0");
-    assert(acl);
-    printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
-    pa_ip_acl_free(acl);
-
-    acl = pa_ip_acl_new("127.0.0.1/32");
-    assert(acl);
-    printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
-    pa_ip_acl_free(acl);
-
-    acl = pa_ip_acl_new("127.0.0.1/7");
-    assert(acl);
-    printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
-    pa_ip_acl_free(acl);
+    fail_unless(r >= 0);
 
-    acl = pa_ip_acl_new("127.0.0.2");
-    assert(acl);
-    printf("result=%u (should be 0)\n", pa_ip_acl_check(acl, fd));
-    pa_ip_acl_free(acl);
-
-    acl = pa_ip_acl_new("127.0.0.0/8;0.0.0.0/32");
-    assert(acl);
-    printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
-    pa_ip_acl_free(acl);
-
-    acl = pa_ip_acl_new("128.0.0.2/9");
-    assert(acl);
-    printf("result=%u (should be 0)\n", pa_ip_acl_check(acl, fd));
-    pa_ip_acl_free(acl);
-
-    acl = pa_ip_acl_new("::1/9");
-    assert(acl);
-    printf("result=%u (should be 0)\n", pa_ip_acl_check(acl, fd));
-    pa_ip_acl_free(acl);
+    do_ip_acl_check("127.0.0.1", fd, 1);
+    do_ip_acl_check("127.0.0.2/0", fd, 1);
+    do_ip_acl_check("127.0.0.1/32", fd, 1);
+    do_ip_acl_check("127.0.0.1/7", fd, 1);
+    do_ip_acl_check("127.0.0.2", fd, 0);
+    do_ip_acl_check("127.0.0.0/8;0.0.0.0/32", fd, 1);
+    do_ip_acl_check("128.0.0.2/9", fd, 0);
+    do_ip_acl_check("::1/9", fd, 0);
 
     close(fd);
 
 #ifdef HAVE_IPV6
     if ( (fd = socket(PF_INET6, SOCK_STREAM, 0)) < 0 ) {
-      printf("Unable to open IPv6 socket, IPv6 tests ignored");
-      return 0;
+      pa_log_error("Unable to open IPv6 socket, IPv6 tests ignored");
+      return;
     }
 
     memset(&sa6, 0, sizeof(sa6));
     sa6.sin6_family = AF_INET6;
     sa6.sin6_port = htons(22);
-    pa_assert_se(inet_pton(AF_INET6, "::1", &sa6.sin6_addr) == 1);
+    fail_unless(inet_pton(AF_INET6, "::1", &sa6.sin6_addr) == 1);
 
     r = connect(fd, (struct sockaddr*) &sa6, sizeof(sa6));
-    assert(r >= 0);
+    fail_unless(r >= 0);
 
-    acl = pa_ip_acl_new("::1");
-    assert(acl);
-    printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
-    pa_ip_acl_free(acl);
-
-    acl = pa_ip_acl_new("::1/9");
-    assert(acl);
-    printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
-    pa_ip_acl_free(acl);
+    do_ip_acl_check("::1", fd, 1);
+    do_ip_acl_check("::1/9", fd, 1);
+    do_ip_acl_check("::/0", fd, 1);
+    do_ip_acl_check("::2/128", fd, 0);
+    do_ip_acl_check("::2/127", fd, 0);
+    do_ip_acl_check("::2/126", fd, 1);
 
-    acl = pa_ip_acl_new("::/0");
-    assert(acl);
-    printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
-    pa_ip_acl_free(acl);
+    close(fd);
+#endif
+}
+END_TEST
 
-    acl = pa_ip_acl_new("::2/128");
-    assert(acl);
-    printf("result=%u (should be 0)\n", pa_ip_acl_check(acl, fd));
-    pa_ip_acl_free(acl);
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
 
-    acl = pa_ip_acl_new("::2/127");
-    assert(acl);
-    printf("result=%u (should be 0)\n", pa_ip_acl_check(acl, fd));
-    pa_ip_acl_free(acl);
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_DEBUG);
 
-    acl = pa_ip_acl_new("::2/126");
-    assert(acl);
-    printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
-    pa_ip_acl_free(acl);
+    s = suite_create("IP ACL");
+    tc = tcase_create("ipacl");
+    tcase_add_test(tc, ipacl_test);
+    suite_add_tcase(s, tc);
 
-    close(fd);
-#endif
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
 
-    return 0;
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index c754e23..1aa3bca 100644 (file)
 #include <config.h>
 #endif
 
-#include <sys/poll.h>
+#include <check.h>
+
 #include <string.h>
 
+#include <pulsecore/poll.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/thread.h>
 #include <pulsecore/lock-autospawn.h>
 #include <pulse/util.h>
 
 static void thread_func(void*k) {
-    pa_assert_se(pa_autospawn_lock_init() >= 0);
+    fail_unless(pa_autospawn_lock_init() >= 0);
 
     pa_log("%i, Trying to acquire lock.", PA_PTR_TO_INT(k));
 
-    pa_assert_se(pa_autospawn_lock_acquire(TRUE) > 0);
+    fail_unless(pa_autospawn_lock_acquire(TRUE) > 0);
 
     pa_log("%i, Got the lock!, Sleeping for 5s", PA_PTR_TO_INT(k));
 
@@ -52,7 +54,7 @@ static void thread_func(void*k) {
 static void thread_func2(void *k) {
     int fd;
 
-    pa_assert_se((fd = pa_autospawn_lock_init()) >= 0);
+    fail_unless((fd = pa_autospawn_lock_init()) >= 0);
 
     pa_log("%i, Trying to acquire lock.", PA_PTR_TO_INT(k));
 
@@ -63,13 +65,13 @@ static void thread_func2(void *k) {
         if ((j = pa_autospawn_lock_acquire(FALSE)) > 0)
             break;
 
-        pa_assert(j == 0);
+        fail_unless(j == 0);
 
         memset(&pollfd, 0, sizeof(pollfd));
         pollfd.fd = fd;
         pollfd.events = POLLIN;
 
-        pa_assert_se(poll(&pollfd, 1, -1) == 1);
+        fail_unless(pa_poll(&pollfd, 1, -1) == 1);
 
         pa_log("%i, woke up", PA_PTR_TO_INT(k));
     }
@@ -85,13 +87,13 @@ static void thread_func2(void *k) {
     pa_autospawn_lock_done(FALSE);
 }
 
-int main(int argc, char**argv) {
+START_TEST (lockautospawn_test) {
     pa_thread *a, *b, *c, *d;
 
-    pa_assert_se((a = pa_thread_new(thread_func, PA_INT_TO_PTR(1))));
-    pa_assert_se((b = pa_thread_new(thread_func2, PA_INT_TO_PTR(2))));
-    pa_assert_se((c = pa_thread_new(thread_func2, PA_INT_TO_PTR(3))));
-    pa_assert_se((d = pa_thread_new(thread_func, PA_INT_TO_PTR(4))));
+    pa_assert_se((a = pa_thread_new("test1", thread_func, PA_INT_TO_PTR(1))));
+    pa_assert_se((b = pa_thread_new("test2", thread_func2, PA_INT_TO_PTR(2))));
+    pa_assert_se((c = pa_thread_new("test3", thread_func2, PA_INT_TO_PTR(3))));
+    pa_assert_se((d = pa_thread_new("test4", thread_func, PA_INT_TO_PTR(4))));
 
     pa_thread_join(a);
     pa_thread_join(b);
@@ -102,8 +104,28 @@ int main(int argc, char**argv) {
     pa_thread_free(b);
     pa_thread_free(c);
     pa_thread_free(d);
-
-    pa_log("End");
-
-    return 0;
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Lock Auto Spawn");
+    tc = tcase_create("lockautospawn");
+    tcase_add_test(tc, lockautospawn_test);
+    /* the default timeout is too small,
+     * set it to a reasonable large one.
+     */
+    tcase_set_timeout(tc, 60 * 60);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index 3ec6d11..3b062f8 100644 (file)
 #include <unistd.h>
 #include <sys/time.h>
 #include <assert.h>
+#include <check.h>
 
 #include <pulse/rtclock.h>
 #include <pulse/timeval.h>
-#include <pulse/gccmacro.h>
 
 #include <pulsecore/core-util.h>
 #include <pulsecore/core-rtclock.h>
@@ -48,7 +48,7 @@ static pa_defer_event *de;
 
 static void iocb(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
     unsigned char c;
-    (void) read(fd, &c, sizeof(c));
+    pa_assert_se(read(fd, &c, sizeof(c)) >= 0);
     fprintf(stderr, "IO EVENT: %c\n", c < 32 ? '.' : c);
     a->defer_enable(de, 1);
 }
@@ -68,7 +68,7 @@ static void tcb(pa_mainloop_api*a, pa_time_event *e, const struct timeval *tv, v
 #endif
 }
 
-int main(int argc, char *argv[]) {
+START_TEST (mainloop_test) {
     pa_mainloop_api *a;
     pa_io_event *ioe;
     pa_time_event *te;
@@ -78,28 +78,28 @@ int main(int argc, char *argv[]) {
     pa_glib_mainloop *g;
 
     glib_main_loop = g_main_loop_new(NULL, FALSE);
-    assert(glib_main_loop);
+    fail_if(!glib_main_loop);
 
     g = pa_glib_mainloop_new(NULL);
-    assert(g);
+    fail_if(!g);
 
     a = pa_glib_mainloop_get_api(g);
-    assert(a);
+    fail_if(!a);
 #else /* GLIB_MAIN_LOOP */
     pa_mainloop *m;
 
     m = pa_mainloop_new();
-    assert(m);
+    fail_if(!m);
 
     a = pa_mainloop_get_api(m);
-    assert(a);
+    fail_if(!a);
 #endif /* GLIB_MAIN_LOOP */
 
     ioe = a->io_new(a, 0, PA_IO_EVENT_INPUT, iocb, NULL);
-    assert(ioe);
+    fail_if(!ioe);
 
     de = a->defer_new(a, dcb, NULL);
-    assert(de);
+    fail_if(!de);
 
     te = a->time_new(a, pa_timeval_rtstore(&tv, pa_rtclock_now() + 2 * PA_USEC_PER_SEC, TRUE), tcb, NULL);
 
@@ -119,6 +119,24 @@ int main(int argc, char *argv[]) {
 #else
     pa_mainloop_free(m);
 #endif
+}
+END_TEST
 
-    return 0;
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("MainLoop");
+    tc = tcase_create("mainloop");
+    tcase_add_test(tc, mainloop_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index 92e3e14..75a71dd 100644 (file)
@@ -29,8 +29,6 @@
 #include <stdlib.h>
 #include <time.h>
 
-#include <pulse/gccmacro.h>
-
 #include <pulsecore/core-util.h>
 #include <pulsecore/mcalign.h>
 
index 9cf6c78..a48daf7 100644 (file)
 #include <stdio.h>
 #include <unistd.h>
 
+#include <check.h>
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/log.h>
 #include <pulsecore/memblock.h>
 #include <pulsecore/macro.h>
-#include <pulse/xmalloc.h>
 
 static void release_cb(pa_memimport *i, uint32_t block_id, void *userdata) {
-    printf("%s: Imported block %u is released.\n", (char*) userdata, block_id);
+    pa_log("%s: Imported block %u is released.", (char*) userdata, block_id);
 }
 
 static void revoke_cb(pa_memexport *e, uint32_t block_id, void *userdata) {
-    printf("%s: Exported block %u is revoked.\n", (char*) userdata, block_id);
+    pa_log("%s: Exported block %u is revoked.", (char*) userdata, block_id);
 }
 
 static void print_stats(pa_mempool *p, const char *text) {
     const pa_mempool_stat*s = pa_mempool_get_stat(p);
 
-    printf("%s = {\n"
-           "n_allocated = %u\n"
-           "n_accumulated = %u\n"
-           "n_imported = %u\n"
-           "n_exported = %u\n"
-           "allocated_size = %u\n"
-           "accumulated_size = %u\n"
-           "imported_size = %u\n"
-           "exported_size = %u\n"
-           "n_too_large_for_pool = %u\n"
-           "n_pool_full = %u\n"
-           "}\n",
+    pa_log_debug("%s = {\n"
+                 "\tn_allocated = %u\n"
+                 "\tn_accumulated = %u\n"
+                 "\tn_imported = %u\n"
+                 "\tn_exported = %u\n"
+                 "\tallocated_size = %u\n"
+                 "\taccumulated_size = %u\n"
+                 "\timported_size = %u\n"
+                 "\texported_size = %u\n"
+                 "\tn_too_large_for_pool = %u\n"
+                 "\tn_pool_full = %u\n"
+                 "}",
            text,
            (unsigned) pa_atomic_load(&s->n_allocated),
            (unsigned) pa_atomic_load(&s->n_accumulated),
@@ -64,7 +68,7 @@ static void print_stats(pa_mempool *p, const char *text) {
            (unsigned) pa_atomic_load(&s->n_pool_full));
 }
 
-int main(int argc, char *argv[]) {
+START_TEST (memblock_test) {
     pa_mempool *pool_a, *pool_b, *pool_c;
     unsigned id_a, id_b, id_c;
     pa_memexport *export_a, *export_b;
@@ -79,15 +83,16 @@ int main(int argc, char *argv[]) {
     const char txt[] = "This is a test!";
 
     pool_a = pa_mempool_new(TRUE, 0);
+    fail_unless(pool_a != NULL);
     pool_b = pa_mempool_new(TRUE, 0);
+    fail_unless(pool_b != NULL);
     pool_c = pa_mempool_new(TRUE, 0);
+    fail_unless(pool_c != NULL);
 
     pa_mempool_get_shm_id(pool_a, &id_a);
     pa_mempool_get_shm_id(pool_b, &id_b);
     pa_mempool_get_shm_id(pool_c, &id_c);
 
-    pa_assert(pool_a && pool_b && pool_c);
-
     blocks[0] = pa_memblock_new_fixed(pool_a, (void*) txt, sizeof(txt), 1);
 
     blocks[1] = pa_memblock_new(pool_a, sizeof(txt));
@@ -104,40 +109,40 @@ int main(int argc, char *argv[]) {
     blocks[4] = NULL;
 
     for (i = 0; blocks[i]; i++) {
-        printf("Memory block %u\n", i);
+        pa_log("Memory block %u", i);
 
         mb_a = blocks[i];
-        pa_assert(mb_a);
+        fail_unless(mb_a != NULL);
 
         export_a = pa_memexport_new(pool_a, revoke_cb, (void*) "A");
+        fail_unless(export_a != NULL);
         export_b = pa_memexport_new(pool_b, revoke_cb, (void*) "B");
-
-        pa_assert(export_a && export_b);
+        fail_unless(export_b != NULL);
 
         import_b = pa_memimport_new(pool_b, release_cb, (void*) "B");
+        fail_unless(import_b != NULL);
         import_c = pa_memimport_new(pool_c, release_cb, (void*) "C");
-
-        pa_assert(import_b && import_c);
+        fail_unless(import_b != NULL);
 
         r = pa_memexport_put(export_a, mb_a, &id, &shm_id, &offset, &size);
-        pa_assert(r >= 0);
-        pa_assert(shm_id == id_a);
+        fail_unless(r >= 0);
+        fail_unless(shm_id == id_a);
 
-        printf("A: Memory block exported as %u\n", id);
+        pa_log("A: Memory block exported as %u", id);
 
         mb_b = pa_memimport_get(import_b, id, shm_id, offset, size);
-        pa_assert(mb_b);
+        fail_unless(mb_b != NULL);
         r = pa_memexport_put(export_b, mb_b, &id, &shm_id, &offset, &size);
-        pa_assert(r >= 0);
-        pa_assert(shm_id == id_a || shm_id == id_b);
+        fail_unless(r >= 0);
+        fail_unless(shm_id == id_a || shm_id == id_b);
         pa_memblock_unref(mb_b);
 
-        printf("B: Memory block exported as %u\n", id);
+        pa_log("B: Memory block exported as %u", id);
 
         mb_c = pa_memimport_get(import_c, id, shm_id, offset, size);
-        pa_assert(mb_c);
+        fail_unless(mb_c != NULL);
         x = pa_memblock_acquire(mb_c);
-        printf("1 data=%s\n", x);
+        pa_log_debug("1 data=%s", x);
         pa_memblock_release(mb_c);
 
         print_stats(pool_a, "A");
@@ -146,7 +151,7 @@ int main(int argc, char *argv[]) {
 
         pa_memexport_free(export_b);
         x = pa_memblock_acquire(mb_c);
-        printf("2 data=%s\n", x);
+        pa_log_debug("2 data=%s", x);
         pa_memblock_release(mb_c);
         pa_memblock_unref(mb_c);
 
@@ -158,17 +163,38 @@ int main(int argc, char *argv[]) {
         pa_memexport_free(export_a);
     }
 
-    printf("vaccuuming...\n");
+    pa_log("vacuuming...");
 
     pa_mempool_vacuum(pool_a);
     pa_mempool_vacuum(pool_b);
     pa_mempool_vacuum(pool_c);
 
-    printf("vaccuuming done...\n");
+    pa_log("vacuuming done...");
 
     pa_mempool_free(pool_a);
     pa_mempool_free(pool_b);
     pa_mempool_free(pool_c);
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_DEBUG);
+
+    s = suite_create("Memblock");
+    tc = tcase_create("memblock");
+    tcase_add_test(tc, memblock_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
 
-    return 0;
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index e401bb6..11ac905 100644 (file)
 #endif
 
 #include <stdlib.h>
-#include <assert.h>
 #include <stdio.h>
 #include <signal.h>
 
+#include <check.h>
+
 #include <pulsecore/memblockq.h>
 #include <pulsecore/log.h>
-
-static void dump_chunk(const pa_memchunk *chunk) {
+#include <pulsecore/macro.h>
+#include <pulsecore/strbuf.h>
+#include <pulsecore/core-util.h>
+
+#include <pulse/xmalloc.h>
+
+static const char *fixed[] = {
+    "1122444411441144__22__11______3333______________________________",
+    "__________________3333__________________________________________"
+};
+static const char *manual[] = {
+    "1122444411441144__22__11______3333______________________________",
+    "__________________3333______________________________"
+};
+
+static void dump_chunk(const pa_memchunk *chunk, pa_strbuf *buf) {
     size_t n;
     void *q;
     char *e;
 
-    pa_assert(chunk);
+    fail_unless(chunk != NULL);
 
     q = pa_memblock_acquire(chunk->memblock);
-    for (e = (char*) q + chunk->index, n = 0; n < chunk->length; n++, e++)
-        printf("%c", *e);
+    for (e = (char*) q + chunk->index, n = 0; n < chunk->length; n++, e++) {
+        fprintf(stderr, "%c", *e);
+        pa_strbuf_putc(buf, *e);
+    }
     pa_memblock_release(chunk->memblock);
 }
 
-static void dump(pa_memblockq *bq) {
+static void dump(pa_memblockq *bq, int n) {
     pa_memchunk out;
+    pa_strbuf *buf;
+    char *str;
 
     pa_assert(bq);
 
     /* First let's dump this as fixed block */
-    printf("FIXED >");
+    fprintf(stderr, "FIXED >");
     pa_memblockq_peek_fixed_size(bq, 64, &out);
-    dump_chunk(&out);
+    buf = pa_strbuf_new();
+    dump_chunk(&out, buf);
     pa_memblock_unref(out.memblock);
-    printf("<\n");
+    str = pa_strbuf_tostring_free(buf);
+    fail_unless(pa_streq(str, fixed[n]));
+    pa_xfree(str);
+    fprintf(stderr, "<\n");
 
     /* Then let's dump the queue manually */
-    printf("MANUAL>");
+    fprintf(stderr, "MANUAL>");
 
+    buf = pa_strbuf_new();
     for (;;) {
         if (pa_memblockq_peek(bq, &out) < 0)
             break;
 
-        dump_chunk(&out);
+        dump_chunk(&out, buf);
         pa_memblock_unref(out.memblock);
         pa_memblockq_drop(bq, out.length);
     }
-
-    printf("<\n");
+    str = pa_strbuf_tostring_free(buf);
+    fail_unless(pa_streq(str, manual[n]));
+    pa_xfree(str);
+    fprintf(stderr, "<\n");
 }
 
-int main(int argc, char *argv[]) {
+START_TEST (memblockq_test) {
     int ret;
 
     pa_mempool *p;
     pa_memblockq *bq;
     pa_memchunk chunk1, chunk2, chunk3, chunk4;
     pa_memchunk silence;
+    pa_sample_spec ss = {
+        .format = PA_SAMPLE_S16LE,
+        .rate = 48000,
+        .channels = 1
+    };
 
     pa_log_set_level(PA_LOG_DEBUG);
 
     p = pa_mempool_new(FALSE, 0);
 
-    silence.memblock = pa_memblock_new_fixed(p, (char*)  "__", 2, 1);
-    assert(silence.memblock);
+    silence.memblock = pa_memblock_new_fixed(p, (char*) "__", 2, 1);
+    fail_unless(silence.memblock != NULL);
+
     silence.index = 0;
     silence.length = pa_memblock_get_length(silence.memblock);
 
-    bq = pa_memblockq_new(0, 200, 10, 2, 4, 4, 40, &silence);
-    assert(bq);
+    bq = pa_memblockq_new("test memblockq", 0, 200, 10, &ss, 4, 4, 40, &silence);
+    fail_unless(bq != NULL);
 
     chunk1.memblock = pa_memblock_new_fixed(p, (char*) "11", 2, 1);
+    fail_unless(chunk1.memblock != NULL);
+
     chunk1.index = 0;
     chunk1.length = 2;
-    assert(chunk1.memblock);
 
     chunk2.memblock = pa_memblock_new_fixed(p, (char*) "XX22", 4, 1);
+    fail_unless(chunk2.memblock != NULL);
+
     chunk2.index = 2;
     chunk2.length = 2;
-    assert(chunk2.memblock);
 
     chunk3.memblock = pa_memblock_new_fixed(p, (char*) "3333", 4, 1);
+    fail_unless(chunk3.memblock != NULL);
+
     chunk3.index = 0;
     chunk3.length = 4;
-    assert(chunk3.memblock);
 
     chunk4.memblock = pa_memblock_new_fixed(p, (char*) "44444444", 8, 1);
+    fail_unless(chunk4.memblock != NULL);
+
     chunk4.index = 0;
     chunk4.length = 8;
-    assert(chunk4.memblock);
 
     ret = pa_memblockq_push(bq, &chunk1);
-    assert(ret == 0);
+    fail_unless(ret == 0);
 
     ret = pa_memblockq_push(bq, &chunk2);
-    assert(ret == 0);
+    fail_unless(ret == 0);
 
     ret = pa_memblockq_push(bq, &chunk3);
-    assert(ret == 0);
+    fail_unless(ret == 0);
 
     ret = pa_memblockq_push(bq, &chunk4);
-    assert(ret == 0);
+    fail_unless(ret == 0);
 
     pa_memblockq_seek(bq, -6, 0, TRUE);
     ret = pa_memblockq_push(bq, &chunk3);
-    assert(ret == 0);
+    fail_unless(ret == 0);
 
     pa_memblockq_seek(bq, -2, 0, TRUE);
     ret = pa_memblockq_push(bq, &chunk1);
-    assert(ret == 0);
+    fail_unless(ret == 0);
 
     pa_memblockq_seek(bq, -10, 0, TRUE);
     ret = pa_memblockq_push(bq, &chunk4);
-    assert(ret == 0);
+    fail_unless(ret == 0);
 
     pa_memblockq_seek(bq, 10, 0, TRUE);
 
     ret = pa_memblockq_push(bq, &chunk1);
-    assert(ret == 0);
+    fail_unless(ret == 0);
 
     pa_memblockq_seek(bq, -6, 0, TRUE);
     ret = pa_memblockq_push(bq, &chunk2);
-    assert(ret == 0);
+    fail_unless(ret == 0);
 
     /* Test splitting */
     pa_memblockq_seek(bq, -12, 0, TRUE);
     ret = pa_memblockq_push(bq, &chunk1);
-    assert(ret == 0);
+    fail_unless(ret == 0);
 
     pa_memblockq_seek(bq, 20, 0, TRUE);
 
     /* Test merging */
     ret = pa_memblockq_push(bq, &chunk3);
-    assert(ret == 0);
+    fail_unless(ret == 0);
     pa_memblockq_seek(bq, -2, 0, TRUE);
 
     chunk3.index += 2;
     chunk3.length -= 2;
     ret = pa_memblockq_push(bq, &chunk3);
-    assert(ret == 0);
+    fail_unless(ret == 0);
 
     pa_memblockq_seek(bq, 30, PA_SEEK_RELATIVE, TRUE);
 
-    dump(bq);
+    dump(bq, 0);
 
     pa_memblockq_rewind(bq, 52);
 
-    dump(bq);
+    dump(bq, 1);
 
     pa_memblockq_free(bq);
     pa_memblock_unref(silence.memblock);
@@ -175,6 +211,24 @@ int main(int argc, char *argv[]) {
     pa_memblock_unref(chunk4.memblock);
 
     pa_mempool_free(p);
+}
+END_TEST
 
-    return 0;
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Memblock Queue");
+    tc = tcase_create("memblockq");
+    tcase_add_test(tc, memblockq_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
diff --git a/src/tests/mix-special-test.c b/src/tests/mix-special-test.c
new file mode 100644 (file)
index 0000000..df86ccb
--- /dev/null
@@ -0,0 +1,354 @@
+/***
+  This file is part of PulseAudio.
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <check.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <pulse/rtclock.h>
+#include <pulsecore/random.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/mix.h>
+#include <pulsecore/sample-util.h>
+
+#define PA_CPU_TEST_RUN_START(l, t1, t2)                        \
+{                                                               \
+    int _j, _k;                                                 \
+    int _times = (t1), _times2 = (t2);                          \
+    pa_usec_t _start, _stop;                                    \
+    pa_usec_t _min = INT_MAX, _max = 0;                         \
+    double _s1 = 0, _s2 = 0;                                    \
+    const char *_label = (l);                                   \
+                                                                \
+    for (_k = 0; _k < _times2; _k++) {                          \
+        _start = pa_rtclock_now();                              \
+        for (_j = 0; _j < _times; _j++)
+
+#define PA_CPU_TEST_RUN_STOP                                    \
+        _stop = pa_rtclock_now();                               \
+                                                                \
+        if (_min > (_stop - _start)) _min = _stop - _start;     \
+        if (_max < (_stop - _start)) _max = _stop - _start;     \
+        _s1 += _stop - _start;                                  \
+        _s2 += (_stop - _start) * (_stop - _start);             \
+    }                                                           \
+    pa_log_debug("%s: %llu usec (avg: %g, min = %llu, max = %llu, stddev = %g).", _label, \
+            (long long unsigned int)_s1,                        \
+            ((double)_s1 / _times2),                            \
+            (long long unsigned int)_min,                       \
+            (long long unsigned int)_max,                       \
+            sqrt(_times2 * _s2 - _s1 * _s1) / _times2);         \
+}
+
+static void acquire_mix_streams(pa_mix_info streams[], unsigned nstreams) {
+    unsigned i;
+
+    for (i = 0; i < nstreams; i++)
+        streams[i].ptr = pa_memblock_acquire_chunk(&streams[i].chunk);
+}
+
+static void release_mix_streams(pa_mix_info streams[], unsigned nstreams) {
+    unsigned i;
+
+    for (i = 0; i < nstreams; i++)
+        pa_memblock_release(streams[i].chunk.memblock);
+}
+
+/* special case: mix 2 s16ne streams, 1 channel each */
+static void pa_mix2_ch1_s16ne(pa_mix_info streams[], int16_t *data, unsigned length) {
+    const int16_t *ptr0 = streams[0].ptr;
+    const int16_t *ptr1 = streams[1].ptr;
+
+    const int32_t cv0 = streams[0].linear[0].i;
+    const int32_t cv1 = streams[1].linear[0].i;
+
+    length /= sizeof(int16_t);
+
+    for (; length > 0; length--) {
+        int32_t sum;
+
+        sum = pa_mult_s16_volume(*ptr0++, cv0);
+        sum += pa_mult_s16_volume(*ptr1++, cv1);
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
+        *data++ = sum;
+    }
+}
+
+/* special case: mix 2 s16ne streams, 2 channels each */
+static void pa_mix2_ch2_s16ne(pa_mix_info streams[], int16_t *data, unsigned length) {
+    const int16_t *ptr0 = streams[0].ptr;
+    const int16_t *ptr1 = streams[1].ptr;
+
+    length /= sizeof(int16_t) * 2;
+
+    for (; length > 0; length--) {
+        int32_t sum;
+
+        sum = pa_mult_s16_volume(*ptr0++, streams[0].linear[0].i);
+        sum += pa_mult_s16_volume(*ptr1++, streams[1].linear[0].i);
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
+        *data++ = sum;
+
+        sum = pa_mult_s16_volume(*ptr0++, streams[0].linear[1].i);
+        sum += pa_mult_s16_volume(*ptr1++, streams[1].linear[1].i);
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
+        *data++ = sum;
+    }
+}
+
+/* special case: mix 2 s16ne streams */
+static void pa_mix2_s16ne(pa_mix_info streams[], unsigned channels, int16_t *data, unsigned length) {
+    const int16_t *ptr0 = streams[0].ptr;
+    const int16_t *ptr1 = streams[1].ptr;
+    unsigned channel = 0;
+
+    length /= sizeof(int16_t);
+
+    for (; length > 0; length--) {
+        int32_t sum;
+
+        sum = pa_mult_s16_volume(*ptr0++, streams[0].linear[channel].i);
+        sum += pa_mult_s16_volume(*ptr1++, streams[1].linear[channel].i);
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
+        *data++ = sum;
+
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
+}
+
+/* special case: mix s16ne streams, 2 channels each */
+static void pa_mix_ch2_s16ne(pa_mix_info streams[], unsigned nstreams, int16_t *data, unsigned length) {
+
+    length /= sizeof(int16_t) * 2;
+
+    for (; length > 0; length--) {
+        int32_t sum0 = 0, sum1 = 0;
+        unsigned i;
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            int32_t cv0 = m->linear[0].i;
+            int32_t cv1 = m->linear[1].i;
+
+            sum0 += pa_mult_s16_volume(*((int16_t*) m->ptr), cv0);
+            m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
+
+            sum1 += pa_mult_s16_volume(*((int16_t*) m->ptr), cv1);
+            m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
+        }
+
+        *data++ = PA_CLAMP_UNLIKELY(sum0, -0x8000, 0x7FFF);
+        *data++ = PA_CLAMP_UNLIKELY(sum1, -0x8000, 0x7FFF);
+    }
+}
+
+static void pa_mix_generic_s16ne(pa_mix_info streams[], unsigned nstreams, unsigned channels, int16_t *data, unsigned length) {
+    unsigned channel = 0;
+
+    length /= sizeof(int16_t);
+
+    for (; length > 0; length--) {
+        int32_t sum = 0;
+        unsigned i;
+
+        for (i = 0; i < nstreams; i++) {
+            pa_mix_info *m = streams + i;
+            int32_t cv = m->linear[channel].i;
+
+            if (PA_LIKELY(cv > 0))
+                sum += pa_mult_s16_volume(*((int16_t*) m->ptr), cv);
+            m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
+        }
+
+        sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
+        *data++ = sum;
+
+        if (PA_UNLIKELY(++channel >= channels))
+            channel = 0;
+    }
+}
+
+
+#define SAMPLES 1028
+#define TIMES 1000
+#define TIMES2 100
+
+START_TEST (mix_special_1ch_test) {
+    int16_t samples0[SAMPLES];
+    int16_t samples1[SAMPLES];
+    int16_t out[SAMPLES];
+    int16_t out_ref[SAMPLES];
+    pa_mempool *pool;
+    pa_memchunk c0, c1;
+    pa_mix_info m[2];
+    unsigned nsamples = SAMPLES;
+
+    fail_unless((pool = pa_mempool_new(FALSE, 0)) != NULL, NULL);
+
+    pa_random(samples0, nsamples * sizeof(int16_t));
+    c0.memblock = pa_memblock_new_fixed(pool, samples0, nsamples * sizeof(int16_t), FALSE);
+    c0.length = pa_memblock_get_length(c0.memblock);
+    c0.index = 0;
+
+    pa_random(samples1, nsamples * sizeof(int16_t));
+    c1.memblock = pa_memblock_new_fixed(pool, samples1, nsamples * sizeof(int16_t), FALSE);
+    c1.length = pa_memblock_get_length(c1.memblock);
+    c1.index = 0;
+
+    m[0].chunk = c0;
+    m[0].volume.channels = 1;
+    m[0].volume.values[0] = PA_VOLUME_NORM;
+    m[0].linear[0].i = 0x5555;
+
+    m[1].chunk = c1;
+    m[1].volume.channels = 1;
+    m[1].volume.values[0] = PA_VOLUME_NORM;
+    m[1].linear[0].i = 0x6789;
+
+    PA_CPU_TEST_RUN_START("mix s16 generic 1 channel", TIMES, TIMES2) {
+        acquire_mix_streams(m, 2);
+        pa_mix_generic_s16ne(m, 2, 1, out_ref, nsamples * sizeof(int16_t));
+        release_mix_streams(m, 2);
+    } PA_CPU_TEST_RUN_STOP
+
+    PA_CPU_TEST_RUN_START("mix s16 2 streams 1 channel", TIMES, TIMES2) {
+        acquire_mix_streams(m, 2);
+        pa_mix2_ch1_s16ne(m, out, nsamples * sizeof(int16_t));
+        release_mix_streams(m, 2);
+    } PA_CPU_TEST_RUN_STOP
+
+    fail_unless(memcmp(out, out_ref, nsamples * sizeof(int16_t)) == 0);
+
+    pa_memblock_unref(c0.memblock);
+    pa_memblock_unref(c1.memblock);
+
+    pa_mempool_free(pool);
+}
+END_TEST
+
+START_TEST (mix_special_2ch_test) {
+    int16_t samples0[SAMPLES*2];
+    int16_t samples1[SAMPLES*2];
+    int16_t out[SAMPLES*2];
+    int16_t out_ref[SAMPLES*2];
+    int i;
+    pa_mempool *pool;
+    pa_memchunk c0, c1;
+    pa_mix_info m[2];
+    unsigned nsamples = SAMPLES * 2;
+
+    fail_unless((pool = pa_mempool_new(FALSE, 0)) != NULL, NULL);
+
+    pa_random(samples0, nsamples * sizeof(int16_t));
+    c0.memblock = pa_memblock_new_fixed(pool, samples0, nsamples * sizeof(int16_t), FALSE);
+    c0.length = pa_memblock_get_length(c0.memblock);
+    c0.index = 0;
+
+    pa_random(samples1, nsamples * sizeof(int16_t));
+    c1.memblock = pa_memblock_new_fixed(pool, samples1, nsamples * sizeof(int16_t), FALSE);
+    c1.length = pa_memblock_get_length(c1.memblock);
+    c1.index = 0;
+
+    m[0].chunk = c0;
+    m[0].volume.channels = 2;
+    for (i = 0; i < m[0].volume.channels; i++) {
+        m[0].volume.values[i] = PA_VOLUME_NORM;
+        m[0].linear[i].i = 0x5555;
+    }
+
+    m[1].chunk = c1;
+    m[1].volume.channels = 2;
+    for (i = 0; i < m[1].volume.channels; i++) {
+        m[1].volume.values[i] = PA_VOLUME_NORM;
+        m[1].linear[i].i = 0x6789;
+    }
+
+    PA_CPU_TEST_RUN_START("mix s16 generic 2 channels", TIMES, TIMES2) {
+        acquire_mix_streams(m, 2);
+        pa_mix_generic_s16ne(m, 2, 2, out_ref, nsamples * sizeof(int16_t));
+        release_mix_streams(m, 2);
+    } PA_CPU_TEST_RUN_STOP
+
+    PA_CPU_TEST_RUN_START("mix s16 2 channels", TIMES, TIMES2) {
+        acquire_mix_streams(m, 2);
+        pa_mix_ch2_s16ne(m, 2, out, nsamples * sizeof(int16_t));
+        release_mix_streams(m, 2);
+    } PA_CPU_TEST_RUN_STOP
+
+    fail_unless(memcmp(out, out_ref, nsamples * sizeof(int16_t)) == 0);
+
+    PA_CPU_TEST_RUN_START("mix s16 2 streams", TIMES, TIMES2) {
+        acquire_mix_streams(m, 2);
+        pa_mix2_s16ne(m, 2, out, nsamples * sizeof(int16_t));
+        release_mix_streams(m, 2);
+    } PA_CPU_TEST_RUN_STOP
+
+    fail_unless(memcmp(out, out_ref, nsamples * sizeof(int16_t)) == 0);
+
+    PA_CPU_TEST_RUN_START("mix s16 2 streams 2 channels", TIMES, TIMES2) {
+        acquire_mix_streams(m, 2);
+        pa_mix2_ch2_s16ne(m, out, nsamples * sizeof(int16_t));
+        release_mix_streams(m, 2);
+    } PA_CPU_TEST_RUN_STOP
+
+    fail_unless(memcmp(out, out_ref, nsamples * sizeof(int16_t)) == 0);
+
+    pa_memblock_unref(c0.memblock);
+    pa_memblock_unref(c1.memblock);
+
+    pa_mempool_free(pool);
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_DEBUG);
+
+    s = suite_create("Mix-special");
+    tc = tcase_create("mix-special 1ch");
+    tcase_add_test(tc, mix_special_1ch_test);
+    tcase_set_timeout(tc, 120);
+    suite_add_tcase(s, tc);
+    tc = tcase_create("mix-special 2ch");
+    tcase_add_test(tc, mix_special_2ch_test);
+    tcase_set_timeout(tc, 120);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
index 457c4ac..4980dd0 100644 (file)
 #endif
 
 #include <stdio.h>
+#include <math.h>
+
+#include <check.h>
 
 #include <pulse/sample.h>
 #include <pulse/volume.h>
 
-#include <pulsecore/resampler.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/endianmacros.h>
 #include <pulsecore/memblock.h>
 #include <pulsecore/sample-util.h>
-
-static float swap_float(float a) {
-    uint32_t *b = (uint32_t*) &a;
-    *b = PA_UINT32_SWAP(*b);
-    return a;
-}
-
-static void dump_block(const pa_sample_spec *ss, const pa_memchunk *chunk) {
+#include <pulsecore/mix.h>
+
+
+/* PA_SAMPLE_U8 */
+static const uint8_t u8_result[3][10] = {
+{ 0x00, 0xff, 0x7f, 0x80, 0x9f, 0x3f, 0x01, 0xf0, 0x20, 0x21 },
+{ 0x0c, 0xf2, 0x7f, 0x80, 0x9b, 0x45, 0x0d, 0xe4, 0x29, 0x2a },
+{ 0x00, 0xff, 0x7e, 0x80, 0xba, 0x04, 0x00, 0xff, 0x00, 0x00 },
+};
+
+/* PA_SAMPLE_ALAW */
+static const uint8_t alaw_result[3][10] = {
+{ 0x00, 0xff, 0x7f, 0x80, 0x9f, 0x3f, 0x01, 0xf0, 0x20, 0x21 },
+{ 0x06, 0xf2, 0x72, 0x86, 0x92, 0x32, 0x07, 0xf6, 0x26, 0x27 },
+{ 0x31, 0xec, 0x6d, 0xb1, 0x8c, 0x2d, 0x36, 0xe1, 0x2a, 0x2a },
+};
+
+/* PA_SAMPLE_ULAW */
+static const uint8_t ulaw_result[3][10] = {
+{ 0x00, 0xff, 0x7f, 0x80, 0x9f, 0x3f, 0x01, 0xf0, 0x20, 0x21 },
+{ 0x03, 0xff, 0xff, 0x83, 0xa2, 0x42, 0x04, 0xf2, 0x23, 0x24 },
+{ 0x00, 0xff, 0xff, 0x80, 0x91, 0x31, 0x00, 0xe9, 0x12, 0x13 },
+};
+
+/* PA_SAMPLE_S16LE */
+static const uint16_t s16le_result[3][10] = {
+{ 0x0000, 0xffff, 0x7fff, 0x8000, 0x9fff, 0x3fff, 0x0001, 0xf000, 0x0020, 0x0021 },
+{ 0x0000, 0xffff, 0x7332, 0x8ccd, 0xa998, 0x3998, 0x0000, 0xf199, 0x001c, 0x001d },
+{ 0x0000, 0xfffe, 0x7fff, 0x8000, 0x8000, 0x7997, 0x0001, 0xe199, 0x003c, 0x003e },
+};
+
+/* PA_SAMPLE_S16BE */
+static const uint16_t s16be_result[3][10] = {
+{ 0x0000, 0xffff, 0x7fff, 0x8000, 0x9fff, 0x3fff, 0x0001, 0xf000, 0x0020, 0x0021 },
+{ 0x0000, 0xffff, 0x8bff, 0x7300, 0xa8ff, 0x52ff, 0xe600, 0xd700, 0xcc1c, 0xb31d },
+{ 0x0000, 0xfeff, 0x0aff, 0xf300, 0x47ff, 0x91fe, 0xe601, 0xc701, 0xcc3c, 0xb33e },
+};
+
+/* PA_SAMPLE_FLOAT32LE */
+static const float float32le_result[3][10] = {
+{ 0.000000, -1.000000, 1.000000, 4711.000000, 0.222000, 0.330000, -0.300000, 99.000000, -0.555000, -0.123000 },
+{ 0.000000, -0.899987, 0.899987, 4239.837402, 0.199797, 0.296996, -0.269996, 89.098679, -0.499493, -0.110698 },
+{ 0.000000, -1.899987, 1.899987, 8950.837891, 0.421797, 0.626996, -0.569996, 188.098679, -1.054493, -0.233698 },
+};
+
+/* PA_SAMPLE_FLOAT32BE */
+static const float float32be_result[3][10] = {
+{ 0.000000, -1.000000, 1.000000, 4711.000000, 0.222000, 0.330000, -0.300000, 99.000000, -0.555000, -0.123000 },
+{ 0.000000, -0.899987, 0.899987, 4239.837402, 0.199797, 0.296996, -0.269996, 89.098679, -0.499493, -0.110698 },
+{ 0.000000, -1.899987, 1.899987, 8950.837891, 0.421797, 0.626996, -0.569996, 188.098679, -1.054493, -0.233698 },
+};
+
+/* PA_SAMPLE_S32LE */
+static const uint32_t s32le_result[3][10] = {
+{ 0x00000001, 0xffff0002, 0x7fff0003, 0x80000004, 0x9fff0005, 0x3fff0006, 0x00010007, 0xf0000008, 0x00200009, 0x0021000a },
+{ 0x00000000, 0xffff199b, 0x7332199c, 0x8ccd0003, 0xa998d99e, 0x3998999f, 0x0000e66c, 0xf199a007, 0x001cccc8, 0x001db32e },
+{ 0x00000001, 0xfffe199d, 0x7fffffff, 0x80000000, 0x80000000, 0x799799a5, 0x0001e673, 0xe199a00f, 0x003cccd1, 0x003eb338 },
+};
+
+/* PA_SAMPLE_S32BE */
+static const uint32_t s32be_result[3][10] = {
+{ 0x00000001, 0xffff0002, 0x7fff0003, 0x80000004, 0x9fff0005, 0x3fff0006, 0x00010007, 0xf0000008, 0x00200009, 0x0021000a },
+{ 0x0066e600, 0x65b2cd01, 0xf117b402, 0x73989903, 0x0ee48004, 0xb8496705, 0xe6ca4c06, 0xd7303307, 0xccb21908, 0xb3190009 },
+{ 0x0066e601, 0x64b2ce03, 0x7017b505, 0xf3989907, 0xade38109, 0xf748680b, 0xe6cb4c0d, 0xc731330f, 0xccd21911, 0xb33a0013 },
+};
+
+/* PA_SAMPLE_S24LE */
+static const uint8_t s24le_result[3][30] = {
+{ 0x00, 0x00, 0x01, 0xff, 0xff, 0x02, 0x7f, 0xff, 0x03, 0x80, 0x00, 0x04, 0x9f, 0xff, 0x05, 0x3f, 0xff, 0x06, 0x01, 0x00, 0x07, 0xf0, 0x00, 0x08, 0x20, 0x00, 0x09, 0x21, 0x00, 0x0a },
+{ 0x66, 0xe6, 0x00, 0x31, 0xb3, 0x02, 0x23, 0x99, 0x03, 0x0b, 0x9a, 0x03, 0x0c, 0x66, 0x05, 0x1c, 0x4c, 0x06, 0xca, 0x4c, 0x06, 0x07, 0x34, 0x07, 0xb2, 0x19, 0x08, 0x19, 0x00, 0x09 },
+{ 0x66, 0xe6, 0x01, 0x30, 0xb3, 0x05, 0xa2, 0x98, 0x07, 0x8b, 0x9a, 0x07, 0xab, 0x65, 0x0b, 0x5b, 0x4b, 0x0d, 0xcb, 0x4c, 0x0d, 0xf7, 0x34, 0x0f, 0xd2, 0x19, 0x11, 0x3a, 0x00, 0x13 },
+};
+
+/* PA_SAMPLE_S24BE */
+static const uint8_t s24be_result[3][30] = {
+{ 0x00, 0x00, 0x01, 0xff, 0xff, 0x02, 0x7f, 0xff, 0x03, 0x80, 0x00, 0x04, 0x9f, 0xff, 0x05, 0x3f, 0xff, 0x06, 0x01, 0x00, 0x07,
+    0xf0, 0x00, 0x08, 0x20, 0x00, 0x09, 0x21, 0x00, 0x0a },
+{ 0x00, 0x00, 0x00, 0xff, 0xff, 0x1b, 0x73, 0x32, 0x1c, 0x8c, 0xcd, 0x03, 0xa9, 0x98, 0xde, 0x39, 0x98, 0x9f, 0x00, 0xe6, 0x6c,
+    0xf1, 0x99, 0xa7, 0x1c, 0xcc, 0xc8, 0x1d, 0xb3, 0x2e },
+{ 0x00, 0x00, 0x01, 0xff, 0xfe, 0x1d, 0x7f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x79, 0x97, 0xa5, 0x01, 0xe6, 0x73,
+    0xe1, 0x99, 0xaf, 0x3c, 0xcc, 0xd1, 0x3e, 0xb3, 0x38 },
+};
+
+/* PA_SAMPLE_S24_32LE */
+static const uint32_t s24_32le_result[3][10] = {
+{ 0x00000001, 0xffff0002, 0x7fff0003, 0x80000004, 0x9fff0005, 0x3fff0006, 0x00010007, 0xf0000008, 0x00200009, 0x0021000a },
+{ 0x00000000, 0x00ff199b, 0x00ff199c, 0x00000003, 0x00ff199e, 0x00ff199f, 0x0000e66c, 0x00000007, 0x001cccc8, 0x001db32e },
+{ 0x00000001, 0x00fe199d, 0x00fe199f, 0x00000007, 0x00fe19a3, 0x00fe19a5, 0x0001e673, 0x0000000f, 0x003cccd1, 0x003eb338 },
+};
+
+/* PA_SAMPLE_S24_32BE */
+static const uint32_t s24_32be_result[3][10] = {
+{ 0x00000001, 0xffff0002, 0x7fff0003, 0x80000004, 0x9fff0005, 0x3fff0006, 0x00010007, 0xf0000008, 0x00200009, 0x0021000a },
+{ 0x00000000, 0x65e60000, 0xf1e50000, 0x73000000, 0x0ee60000, 0xb8e50000, 0xe6000000, 0xd7000000, 0xcc1c0000, 0xb31d0000 },
+{ 0x00000000, 0xe5010200, 0x00036400, 0x0470e500, 0xf3000000, 0xe5010500, 0x0006ad00, 0x07f7e400, 0xe6010000, 0x00000800 },
+};
+
+static void compare_block(const pa_sample_spec *ss, const pa_memchunk *chunk, int iter) {
     void *d;
     unsigned i;
 
     d = pa_memblock_acquire(chunk->memblock);
 
     switch (ss->format) {
+        case PA_SAMPLE_U8: {
+            const uint8_t *v = u8_result[iter];
+            uint8_t *u = d;
+
+            for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
+                fail_unless(*u == *v, NULL);
+                ++u;
+                ++v;
+            }
+            break;
+        }
 
-        case PA_SAMPLE_U8:
-        case PA_SAMPLE_ULAW:
         case PA_SAMPLE_ALAW: {
+            const uint8_t *v = alaw_result[iter];
             uint8_t *u = d;
 
-            for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
-                printf("0x%02x ", *(u++));
+            for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
+                fail_unless(*u == *v, NULL);
+                ++u;
+                ++v;
+            }
+            break;
+        }
 
+        case PA_SAMPLE_ULAW: {
+            const uint8_t *v = ulaw_result[iter];
+            uint8_t *u = d;
+
+            for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
+                fail_unless(*u == *v, NULL);
+                ++u;
+                ++v;
+            }
             break;
         }
 
-        case PA_SAMPLE_S16NE:
-        case PA_SAMPLE_S16RE: {
+        case PA_SAMPLE_S16LE: {
+            const uint16_t *v = s16le_result[iter];
             uint16_t *u = d;
 
-            for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
-                printf("0x%04x ", *(u++));
+            for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
+                fail_unless(*u == *v, NULL);
+                ++u;
+                ++v;
+            }
+            break;
+        }
+
+        case PA_SAMPLE_S16BE: {
+            const uint16_t *v = s16be_result[iter];
+            uint16_t *u = d;
 
+            for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
+                fail_unless(*u == *v, NULL);
+                ++u;
+                ++v;
+            }
             break;
         }
 
-        case PA_SAMPLE_S24_32NE:
-        case PA_SAMPLE_S24_32RE:
-        case PA_SAMPLE_S32NE:
-        case PA_SAMPLE_S32RE: {
+        case PA_SAMPLE_FLOAT32LE: {
+            const float *v = float32le_result[iter];
+            float *u = d;
+
+            for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
+                float uu = ss->format == PA_SAMPLE_FLOAT32NE ? *u : PA_FLOAT32_SWAP(*u);
+                fail_unless(fabs(uu - *v) <= 1e-6, NULL);
+                ++u;
+                ++v;
+            }
+            break;
+        }
+
+        case PA_SAMPLE_FLOAT32BE: {
+            const float *v = float32be_result[iter];
+            float *u = d;
+
+            for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
+                float uu = ss->format == PA_SAMPLE_FLOAT32NE ? *u : PA_FLOAT32_SWAP(*u);
+                fail_unless(fabs(uu - *v) <= 1e-6, NULL);
+                ++u;
+                ++v;
+            }
+            break;
+        }
+
+        case PA_SAMPLE_S32LE: {
+            const uint32_t *v = s32le_result[iter];
             uint32_t *u = d;
 
-            for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
-                printf("0x%08x ", *(u++));
+            for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
+                fail_unless(*u == *v, NULL);
+                ++u;
+                ++v;
+            }
+            break;
+        }
+
+        case PA_SAMPLE_S32BE: {
+            const uint32_t *v = s32be_result[iter];
+            uint32_t *u = d;
 
+            for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
+                fail_unless(*u == *v, NULL);
+                ++u;
+                ++v;
+            }
             break;
         }
 
-        case PA_SAMPLE_S24NE:
-        case PA_SAMPLE_S24RE: {
-            uint8_t *u = d;
+        case PA_SAMPLE_S24_32LE: {
+            const uint32_t *v = s24_32le_result[iter];
+            uint32_t *u = d;
 
             for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
-                printf("0x%02x%02x%02xx ", *u, *(u+1), *(u+2));
-                u += 3;
+                fail_unless(*u == *v, NULL);
+                ++u;
+                ++v;
             }
+            break;
+        }
+
+        case PA_SAMPLE_S24_32BE: {
+            const uint32_t *v = s24_32be_result[iter];
+            uint32_t *u = d;
 
+            for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
+                fail_unless(*u == *v, NULL);
+                ++u;
+                ++v;
+            }
             break;
         }
 
-        case PA_SAMPLE_FLOAT32NE:
-        case PA_SAMPLE_FLOAT32RE: {
-            float *u = d;
+        case PA_SAMPLE_S24LE: {
+            const uint8_t *v = s24le_result[iter];
+            uint8_t *u = d;
 
             for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
-                printf("%1.5f ",  ss->format == PA_SAMPLE_FLOAT32NE ? *u : swap_float(*u));
-                u++;
+                fail_unless(*u == *v, NULL);
+                fail_unless(*(u+1) == *(v+1), NULL);
+                fail_unless(*(u+2) == *(v+2), NULL);
+
+                u += 3;
+                v += 3;
             }
+            break;
+        }
 
+        case PA_SAMPLE_S24BE: {
+            const uint8_t *v = s24be_result[iter];
+            uint8_t *u = d;
+
+            for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
+                fail_unless(*u == *v, NULL);
+                fail_unless(*(u+1) == *(v+1), NULL);
+                fail_unless(*(u+2) == *(v+2), NULL);
+
+                u += 3;
+                v += 3;
+            }
             break;
         }
 
@@ -107,8 +305,6 @@ static void dump_block(const pa_sample_spec *ss, const pa_memchunk *chunk) {
             pa_assert_not_reached();
     }
 
-    printf("\n");
-
     pa_memblock_release(chunk->memblock);
 }
 
@@ -188,7 +384,7 @@ static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) {
 
             if (ss->format == PA_SAMPLE_FLOAT32RE) {
                 for (i = 0; i < 10; i++)
-                    u[i] = swap_float(float_samples[i]);
+                    u[i] = PA_FLOAT32_SWAP(float_samples[i]);
             } else
               memcpy(d, float_samples, sizeof(float_samples));
 
@@ -204,14 +400,15 @@ static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) {
     return r;
 }
 
-int main(int argc, char *argv[]) {
+START_TEST (mix_test) {
     pa_mempool *pool;
     pa_sample_spec a;
     pa_cvolume v;
 
-    pa_log_set_level(PA_LOG_DEBUG);
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_DEBUG);
 
-    pa_assert_se(pool = pa_mempool_new(FALSE, 0));
+    fail_unless((pool = pa_mempool_new(FALSE, 0)) != NULL, NULL);
 
     a.channels = 1;
     a.rate = 44100;
@@ -224,14 +421,14 @@ int main(int argc, char *argv[]) {
         pa_mix_info m[2];
         void *ptr;
 
-        printf("=== mixing: %s\n", pa_sample_format_to_string(a.format));
+        pa_log_debug("=== mixing: %s\n", pa_sample_format_to_string(a.format));
 
         /* Generate block */
         i.memblock = generate_block(pool, &a);
         i.length = pa_memblock_get_length(i.memblock);
         i.index = 0;
 
-        dump_block(&a, &i);
+        compare_block(&a, &i, 0);
 
         /* Make a copy */
         j = i;
@@ -241,7 +438,7 @@ int main(int argc, char *argv[]) {
         /* Adjust volume of the copy */
         pa_volume_memchunk(&j, &a, &v);
 
-        dump_block(&a, &j);
+        compare_block(&a, &j, 1);
 
         m[0].chunk = i;
         m[0].volume.values[0] = PA_VOLUME_NORM;
@@ -254,11 +451,11 @@ int main(int argc, char *argv[]) {
         k.length = i.length;
         k.index = 0;
 
-        ptr = (uint8_t*) pa_memblock_acquire(k.memblock) + k.index;
+        ptr = pa_memblock_acquire_chunk(&k);
         pa_mix(m, 2, ptr, k.length, &a, NULL, FALSE);
         pa_memblock_release(k.memblock);
 
-        dump_block(&a, &k);
+        compare_block(&a, &k, 2);
 
         pa_memblock_unref(i.memblock);
         pa_memblock_unref(j.memblock);
@@ -266,6 +463,24 @@ int main(int argc, char *argv[]) {
     }
 
     pa_mempool_free(pool);
+}
+END_TEST
 
-    return 0;
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Mix");
+    tc = tcase_create("mix");
+    tcase_add_test(tc, mix_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
diff --git a/src/tests/mult-s16-test.c b/src/tests/mult-s16-test.c
new file mode 100644 (file)
index 0000000..15ed8f2
--- /dev/null
@@ -0,0 +1,145 @@
+/***
+  This file is part of PulseAudio.
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <check.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <pulse/rtclock.h>
+#include <pulsecore/random.h>
+#include <pulsecore/macro.h>
+
+#define PA_CPU_TEST_RUN_START(l, t1, t2)                        \
+{                                                               \
+    int _j, _k;                                                 \
+    int _times = (t1), _times2 = (t2);                          \
+    pa_usec_t _start, _stop;                                    \
+    pa_usec_t _min = INT_MAX, _max = 0;                         \
+    double _s1 = 0, _s2 = 0;                                    \
+    const char *_label = (l);                                   \
+                                                                \
+    for (_k = 0; _k < _times2; _k++) {                          \
+        _start = pa_rtclock_now();                              \
+        for (_j = 0; _j < _times; _j++)
+
+#define PA_CPU_TEST_RUN_STOP                                    \
+        _stop = pa_rtclock_now();                               \
+                                                                \
+        if (_min > (_stop - _start)) _min = _stop - _start;     \
+        if (_max < (_stop - _start)) _max = _stop - _start;     \
+        _s1 += _stop - _start;                                  \
+        _s2 += (_stop - _start) * (_stop - _start);             \
+    }                                                           \
+    pa_log_debug("%s: %llu usec (avg: %g, min = %llu, max = %llu, stddev = %g).", _label, \
+            (long long unsigned int)_s1,                        \
+            ((double)_s1 / _times2),                            \
+            (long long unsigned int)_min,                       \
+            (long long unsigned int)_max,                       \
+            sqrt(_times2 * _s2 - _s1 * _s1) / _times2);         \
+}
+
+static inline int32_t pa_mult_s16_volume_32(int16_t v, int32_t cv) {
+    /* Multiplying the 32 bit volume factor with the
+     * 16 bit sample might result in an 48 bit value. We
+     * want to do without 64 bit integers and hence do
+     * the multiplication independently for the HI and
+     * LO part of the volume. */
+    int32_t hi = cv >> 16;
+    int32_t lo = cv & 0xFFFF;
+    return ((v * lo) >> 16) + (v * hi);
+}
+
+static inline int32_t pa_mult_s16_volume_64(int16_t v, int32_t cv) {
+    /* Multiply with 64 bit integers on 64 bit platforms */
+    return (v * (int64_t) cv) >> 16;
+}
+
+#define SAMPLES 1028
+#define TIMES 10000
+#define TIMES2 100
+
+START_TEST (mult_s16_test) {
+    int16_t samples[SAMPLES];
+    int32_t volumes[SAMPLES];
+    int32_t sum1 = 0, sum2 = 0;
+    int i;
+
+    pa_random(samples, sizeof(samples));
+    pa_random(volumes, sizeof(volumes));
+
+    for (i = 0; i < SAMPLES; i++) {
+        int32_t a = pa_mult_s16_volume_32(samples[i], volumes[i]);
+        int32_t b = pa_mult_s16_volume_64(samples[i], volumes[i]);
+
+        if (a != b) {
+            pa_log_debug("%d: %d != %d", i, a, b);
+            fail();
+        }
+    }
+
+    PA_CPU_TEST_RUN_START("32 bit mult", TIMES, TIMES2) {
+        for (i = 0; i < SAMPLES; i++) {
+            sum1 += pa_mult_s16_volume_32(samples[i], volumes[i]);
+        }
+    } PA_CPU_TEST_RUN_STOP
+
+    PA_CPU_TEST_RUN_START("64 bit mult", TIMES, TIMES2) {
+        for (i = 0; i < SAMPLES; i++)
+            sum2 += pa_mult_s16_volume_64(samples[i], volumes[i]);
+    } PA_CPU_TEST_RUN_STOP
+
+    fail_unless(sum1 == sum2);
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_DEBUG);
+
+#if __WORDSIZE == 64 || ((ULONG_MAX) > (UINT_MAX))
+    pa_log_debug("This seems to be 64-bit code.");
+#elif  __WORDSIZE == 32
+    pa_log_debug("This seems to be 32-bit code.");
+#else
+    pa_log_debug("Don't know if this is 32- or 64-bit code.");
+#endif
+
+    s = suite_create("Mult-s16");
+    tc = tcase_create("mult-s16");
+    tcase_add_test(tc, mult_s16_test);
+    tcase_set_timeout(tc, 120);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/src/tests/once-test.c b/src/tests/once-test.c
new file mode 100644 (file)
index 0000000..b39a0e3
--- /dev/null
@@ -0,0 +1,138 @@
+/***
+  This file is part of PulseAudio.
+
+  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, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_PTHREAD
+#include <pthread.h>
+#endif
+
+#include <check.h>
+
+#include <pulsecore/thread.h>
+#include <pulsecore/once.h>
+#include <pulsecore/log.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/atomic.h>
+#include <pulse/xmalloc.h>
+
+static pa_once once = PA_ONCE_INIT;
+static volatile unsigned n_run = 0;
+static const char * volatile ran_by = NULL;
+#ifdef HAVE_PTHREAD
+static pthread_barrier_t barrier;
+#endif
+static unsigned n_cpu;
+
+#define N_ITERATIONS 500
+#define N_THREADS 100
+
+static void once_func(void) {
+    n_run++;
+    ran_by = (const char*) pa_thread_get_data(pa_thread_self());
+}
+
+static void thread_func(void *data) {
+#ifdef HAVE_PTHREAD
+    int r;
+
+#ifdef HAVE_PTHREAD_SETAFFINITY_NP
+    static pa_atomic_t i_cpu = PA_ATOMIC_INIT(0);
+    cpu_set_t mask;
+
+    CPU_ZERO(&mask);
+    CPU_SET((size_t) (pa_atomic_inc(&i_cpu) % n_cpu), &mask);
+    fail_unless(pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) == 0);
+#endif
+
+    pa_log_debug("started up: %s", (char *) data);
+
+    r = pthread_barrier_wait(&barrier);
+    fail_unless(r == 0 || r == PTHREAD_BARRIER_SERIAL_THREAD);
+#endif /* HAVE_PTHREAD */
+
+    pa_run_once(&once, once_func);
+}
+
+START_TEST (once_test) {
+    unsigned n, i;
+
+    n_cpu = pa_ncpus();
+
+    for (n = 0; n < N_ITERATIONS; n++) {
+        pa_thread* threads[N_THREADS];
+
+#ifdef HAVE_PTHREAD
+        fail_unless(pthread_barrier_init(&barrier, NULL, N_THREADS) == 0);
+#endif
+
+        /* Yes, kinda ugly */
+        pa_zero(once);
+
+        for (i = 0; i < N_THREADS; i++)
+            threads[i] = pa_thread_new("once", thread_func, pa_sprintf_malloc("Thread #%i", i+1));
+
+        for (i = 0; i < N_THREADS; i++)
+            pa_thread_join(threads[i]);
+
+        fail_unless(n_run == 1);
+        pa_log_info("ran by %s", ran_by);
+
+        for (i = 0; i < N_THREADS; i++) {
+            pa_xfree(pa_thread_get_data(threads[i]));
+            pa_thread_free(threads[i]);
+        }
+
+        n_run = 0;
+        ran_by = NULL;
+
+#ifdef HAVE_PTHREAD
+        fail_unless(pthread_barrier_destroy(&barrier) == 0);
+#endif
+    }
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_DEBUG);
+
+    s = suite_create("Once");
+    tc = tcase_create("once");
+    tcase_add_test(tc, once_test);
+    /* the default timeout is too small,
+     * set it to a reasonable large one.
+     */
+    tcase_set_timeout(tc, 60 * 60);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
index d4224e1..7d119c4 100644 (file)
@@ -29,7 +29,6 @@
 
 #include <pulse/simple.h>
 #include <pulse/error.h>
-#include <pulse/gccmacro.h>
 
 #define BUFSIZE 1024
 
index 9f19ff4..dfa43f0 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <pulse/simple.h>
 #include <pulse/error.h>
-#include <pulse/gccmacro.h>
 
 #define BUFSIZE 1024
 
diff --git a/src/tests/prioq-test.c b/src/tests/prioq-test.c
deleted file mode 100644 (file)
index 120b512..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <pulsecore/prioq.h>
-#include <pulsecore/macro.h>
-
-#define N 1024
-
-int main(int argc, char *argv[]) {
-    pa_prioq *q;
-    unsigned i;
-
-    srand(0);
-
-    q = pa_prioq_new(pa_idxset_trivial_compare_func);
-
-    /* Fill in 1024 */
-    for (i = 0; i < N; i++)
-        pa_prioq_put(q, PA_UINT_TO_PTR((unsigned) rand()));
-
-    /* Remove half of it again */
-    for (i = 0; i < N/2; i++){
-        unsigned u = PA_PTR_TO_UINT(pa_prioq_pop(q));
-        pa_log("%16u", u);
-    }
-
-    pa_log("Refilling");
-
-    /* Fill in another 1024 */
-    for (i = 0; i < N; i++)
-        pa_prioq_put(q, PA_UINT_TO_PTR((unsigned) rand()));
-
-
-    /* Remove everything */
-    while (!pa_prioq_isempty(q)) {
-        unsigned u = PA_PTR_TO_UINT(pa_prioq_pop(q));
-        pa_log("%16u", u);
-    }
-
-    pa_prioq_free(q, NULL, NULL);
-
-    return 0;
-}
index 27a0d3f..6aac03c 100644 (file)
 
 #include <stdio.h>
 
+#include <check.h>
+
 #include <pulse/proplist.h>
 #include <pulse/xmalloc.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/modargs.h>
 
-int main(int argc, char*argv[]) {
+START_TEST (proplist_test) {
     pa_modargs *ma;
     pa_proplist *a, *b, *c, *d;
     char *s, *t, *u, *v;
@@ -37,27 +39,27 @@ int main(int argc, char*argv[]) {
     const char *x[] = { "foo", NULL };
 
     a = pa_proplist_new();
-    pa_assert_se(pa_proplist_sets(a, PA_PROP_MEDIA_TITLE, "Brandenburgische Konzerte") == 0);
-    pa_assert_se(pa_proplist_sets(a, PA_PROP_MEDIA_ARTIST, "Johann Sebastian Bach") == 0);
+    fail_unless(pa_proplist_sets(a, PA_PROP_MEDIA_TITLE, "Brandenburgische Konzerte") == 0);
+    fail_unless(pa_proplist_sets(a, PA_PROP_MEDIA_ARTIST, "Johann Sebastian Bach") == 0);
 
     b = pa_proplist_new();
-    pa_assert_se(pa_proplist_sets(b, PA_PROP_MEDIA_TITLE, "Goldbergvariationen") == 0);
-    pa_assert_se(pa_proplist_set(b, PA_PROP_MEDIA_ICON, "\0\1\2\3\4\5\6\7", 8) == 0);
+    fail_unless(pa_proplist_sets(b, PA_PROP_MEDIA_TITLE, "Goldbergvariationen") == 0);
+    fail_unless(pa_proplist_set(b, PA_PROP_MEDIA_ICON, "\0\1\2\3\4\5\6\7", 8) == 0);
 
     pa_proplist_update(a, PA_UPDATE_MERGE, b);
 
-    pa_assert_se(!pa_proplist_gets(a, PA_PROP_MEDIA_ICON));
+    fail_unless(!pa_proplist_gets(a, PA_PROP_MEDIA_ICON));
 
-    printf("%s\n", pa_strnull(pa_proplist_gets(a, PA_PROP_MEDIA_TITLE)));
-    pa_assert_se(pa_proplist_unset(b, PA_PROP_MEDIA_TITLE) == 0);
+    pa_log_debug("%s", pa_strnull(pa_proplist_gets(a, PA_PROP_MEDIA_TITLE)));
+    fail_unless(pa_proplist_unset(b, PA_PROP_MEDIA_TITLE) == 0);
 
     s = pa_proplist_to_string(a);
     t = pa_proplist_to_string(b);
-    printf("---\n%s---\n%s", s, t);
+    pa_log_debug("---\n%s---\n%s", s, t);
 
     c = pa_proplist_from_string(s);
     u = pa_proplist_to_string(c);
-    pa_assert_se(pa_streq(s, u));
+    fail_unless(pa_streq(s, u));
 
     pa_xfree(s);
     pa_xfree(t);
@@ -69,28 +71,51 @@ int main(int argc, char*argv[]) {
 
     text = "  eins = zwei drei = \"\\\"vier\\\"\" fuenf=sechs sieben ='\\a\\c\\h\\t\\'\\\"' neun= hex:0123456789abCDef ";
 
-    printf("%s\n", text);
+    pa_log_debug("%s", text);
     d = pa_proplist_from_string(text);
     v = pa_proplist_to_string(d);
     pa_proplist_free(d);
-    printf("%s\n", v);
+    pa_log_debug("%s", v);
     d = pa_proplist_from_string(v);
     pa_xfree(v);
     v = pa_proplist_to_string(d);
     pa_proplist_free(d);
-    printf("%s\n", v);
+    pa_log_debug("%s", v);
     pa_xfree(v);
 
-    pa_assert_se(ma = pa_modargs_new("foo='foobar=waldo foo2=\"lj\\\\\"dhflh\" foo3=\\'kjlskj\\\\\\'\\''", x));
-    pa_assert_se(a = pa_proplist_new());
+    ma = pa_modargs_new("foo='foobar=waldo foo2=\"lj\\\"dhflh\" foo3=\"kjlskj\\'\"'", x);
+    fail_unless(ma != NULL);
+    a = pa_proplist_new();
+    fail_unless(a != NULL);
 
-    pa_assert_se(pa_modargs_get_proplist(ma, "foo", a, PA_UPDATE_REPLACE) >= 0);
+    fail_unless(pa_modargs_get_proplist(ma, "foo", a, PA_UPDATE_REPLACE) >= 0);
 
-    printf("%s\n", v = pa_proplist_to_string(a));
+    pa_log_debug("%s", v = pa_proplist_to_string(a));
     pa_xfree(v);
 
     pa_proplist_free(a);
     pa_modargs_free(ma);
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_DEBUG);
+
+    s = suite_create("Property List");
+    tc = tcase_create("propertylist");
+    tcase_add_test(tc, proplist_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
 
-    return 0;
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index 7ee2693..814645e 100644 (file)
 #include <stdlib.h>
 #include <unistd.h>
 
-#include <pulse/util.h>
-#include <pulse/xmalloc.h>
+#include <check.h>
+
 #include <pulsecore/queue.h>
 #include <pulsecore/log.h>
-#include <pulsecore/core-util.h>
 #include <pulsecore/macro.h>
 
-int main(int argc, char *argv[]) {
+START_TEST (queue_test) {
     pa_queue *q;
 
-    pa_assert_se(q = pa_queue_new());
+    q = pa_queue_new();
+    fail_unless(q != NULL);
 
-    pa_assert(pa_queue_isempty(q));
+    fail_unless(pa_queue_isempty(q));
 
     pa_queue_push(q, (void*) "eins");
     pa_log("%s\n", (char*) pa_queue_pop(q));
 
-    pa_assert(pa_queue_isempty(q));
+    fail_unless(pa_queue_isempty(q));
 
     pa_queue_push(q, (void*) "zwei");
     pa_queue_push(q, (void*) "drei");
@@ -56,12 +56,30 @@ int main(int argc, char *argv[]) {
     pa_log("%s\n", (char*) pa_queue_pop(q));
     pa_log("%s\n", (char*) pa_queue_pop(q));
 
-    pa_assert(pa_queue_isempty(q));
+    fail_unless(pa_queue_isempty(q));
 
     pa_queue_push(q, (void*) "sechs");
     pa_queue_push(q, (void*) "sieben");
 
-    pa_queue_free(q, NULL, NULL);
+    pa_queue_free(q, NULL);
+}
+END_TEST
 
-    return 0;
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Queue");
+    tc = tcase_create("queue");
+    tcase_add_test(tc, queue_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index 4990bf9..19f5582 100644 (file)
 #include <stdio.h>
 
 #include <pulse/sample.h>
-#include <pulse/volume.h>
 
 #include <pulsecore/resampler.h>
 #include <pulsecore/macro.h>
-#include <pulsecore/endianmacros.h>
 #include <pulsecore/memblock.h>
-#include <pulsecore/sample-util.h>
 
 int main(int argc, char *argv[]) {
 
index 82198b5..e07a3d6 100644 (file)
 #endif
 
 #include <stdio.h>
+#include <getopt.h>
+#include <locale.h>
 
+#include <pulse/pulseaudio.h>
+
+#include <pulse/rtclock.h>
 #include <pulse/sample.h>
 #include <pulse/volume.h>
 
+#include <pulsecore/i18n.h>
+#include <pulsecore/log.h>
 #include <pulsecore/resampler.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/endianmacros.h>
 #include <pulsecore/memblock.h>
 #include <pulsecore/sample-util.h>
+#include <pulsecore/core-util.h>
 
-static void dump_block(const pa_sample_spec *ss, const pa_memchunk *chunk) {
+static void dump_block(const char *label, const pa_sample_spec *ss, const pa_memchunk *chunk) {
     void *d;
     unsigned i;
 
+    if (getenv("MAKE_CHECK"))
+        return;
+    printf("%s:  \t", label);
+
     d = pa_memblock_acquire(chunk->memblock);
 
     switch (ss->format) {
@@ -241,33 +253,206 @@ static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) {
     return r;
 }
 
+static void help(const char *argv0) {
+    printf(_("%s [options]\n\n"
+             "-h, --help                            Show this help\n"
+             "-v, --verbose                         Print debug messages\n"
+             "      --from-rate=SAMPLERATE          From sample rate in Hz (defaults to 44100)\n"
+             "      --from-format=SAMPLEFORMAT      From sample type (defaults to s16le)\n"
+             "      --from-channels=CHANNELS        From number of channels (defaults to 1)\n"
+             "      --to-rate=SAMPLERATE            To sample rate in Hz (defaults to 44100)\n"
+             "      --to-format=SAMPLEFORMAT        To sample type (defaults to s16le)\n"
+             "      --to-channels=CHANNELS          To number of channels (defaults to 1)\n"
+             "      --resample-method=METHOD        Resample method (defaults to auto)\n"
+             "      --seconds=SECONDS               From stream duration (defaults to 60)\n"
+             "\n"
+             "If the formats are not specified, the test performs all formats combinations,\n"
+             "back and forth.\n"
+             "\n"
+             "Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, alaw,\n"
+             "s24le, s24be, s24-32le, s24-32be, s32le, s32be (defaults to s16ne)\n"
+             "\n"
+             "See --dump-resample-methods for possible values of resample methods.\n"),
+             argv0);
+}
+
+enum {
+    ARG_VERSION = 256,
+    ARG_FROM_SAMPLERATE,
+    ARG_FROM_SAMPLEFORMAT,
+    ARG_FROM_CHANNELS,
+    ARG_TO_SAMPLERATE,
+    ARG_TO_SAMPLEFORMAT,
+    ARG_TO_CHANNELS,
+    ARG_SECONDS,
+    ARG_RESAMPLE_METHOD,
+    ARG_DUMP_RESAMPLE_METHODS
+};
+
+static void dump_resample_methods(void) {
+    int i;
+
+    for (i = 0; i < PA_RESAMPLER_MAX; i++)
+        if (pa_resample_method_supported(i))
+            printf("%s\n", pa_resample_method_to_string(i));
+
+}
+
 int main(int argc, char *argv[]) {
-    pa_mempool *pool;
+    pa_mempool *pool = NULL;
     pa_sample_spec a, b;
-    pa_cvolume v;
+    int ret = 1, c;
+    pa_bool_t all_formats = TRUE;
+    pa_resample_method_t method;
+    int seconds;
+
+    static const struct option long_options[] = {
+        {"help",                  0, NULL, 'h'},
+        {"verbose",               0, NULL, 'v'},
+        {"version",               0, NULL, ARG_VERSION},
+        {"from-rate",             1, NULL, ARG_FROM_SAMPLERATE},
+        {"from-format",           1, NULL, ARG_FROM_SAMPLEFORMAT},
+        {"from-channels",         1, NULL, ARG_FROM_CHANNELS},
+        {"to-rate",               1, NULL, ARG_TO_SAMPLERATE},
+        {"to-format",             1, NULL, ARG_TO_SAMPLEFORMAT},
+        {"to-channels",           1, NULL, ARG_TO_CHANNELS},
+        {"seconds",               1, NULL, ARG_SECONDS},
+        {"resample-method",       1, NULL, ARG_RESAMPLE_METHOD},
+        {"dump-resample-methods", 0, NULL, ARG_DUMP_RESAMPLE_METHODS},
+        {NULL,                    0, NULL, 0}
+    };
+
+    setlocale(LC_ALL, "");
+#ifdef ENABLE_NLS
+    bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);
+#endif
 
-    pa_log_set_level(PA_LOG_DEBUG);
+    pa_log_set_level(PA_LOG_WARN);
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_INFO);
 
     pa_assert_se(pool = pa_mempool_new(FALSE, 0));
 
     a.channels = b.channels = 1;
     a.rate = b.rate = 44100;
+    a.format = b.format = PA_SAMPLE_S16LE;
+
+    method = PA_RESAMPLER_AUTO;
+    seconds = 60;
+
+    while ((c = getopt_long(argc, argv, "hv", long_options, NULL)) != -1) {
+
+        switch (c) {
+            case 'h' :
+                help(argv[0]);
+                ret = 0;
+                goto quit;
+
+            case 'v':
+                pa_log_set_level(PA_LOG_DEBUG);
+                break;
+
+            case ARG_VERSION:
+                printf(_("%s %s\n"), argv[0], PACKAGE_VERSION);
+                ret = 0;
+                goto quit;
+
+            case ARG_DUMP_RESAMPLE_METHODS:
+                dump_resample_methods();
+                ret = 0;
+                goto quit;
+
+            case ARG_FROM_CHANNELS:
+                a.channels = (uint8_t) atoi(optarg);
+                break;
+
+            case ARG_FROM_SAMPLEFORMAT:
+                a.format = pa_parse_sample_format(optarg);
+                all_formats = FALSE;
+                break;
+
+            case ARG_FROM_SAMPLERATE:
+                a.rate = (uint32_t) atoi(optarg);
+                break;
+
+            case ARG_TO_CHANNELS:
+                b.channels = (uint8_t) atoi(optarg);
+                break;
+
+            case ARG_TO_SAMPLEFORMAT:
+                b.format = pa_parse_sample_format(optarg);
+                all_formats = FALSE;
+                break;
+
+            case ARG_TO_SAMPLERATE:
+                b.rate = (uint32_t) atoi(optarg);
+                break;
+
+            case ARG_SECONDS:
+                seconds = atoi(optarg);
+                break;
+
+            case ARG_RESAMPLE_METHOD:
+                if (*optarg == '\0' || pa_streq(optarg, "help")) {
+                    dump_resample_methods();
+                    ret = 0;
+                    goto quit;
+                }
+                method = pa_parse_resample_method(optarg);
+                break;
+
+            default:
+                goto quit;
+        }
+    }
+
+    ret = 0;
+    pa_assert_se(pool = pa_mempool_new(FALSE, 0));
+
+    if (!all_formats) {
 
-    v.channels = a.channels;
-    v.values[0] = pa_sw_volume_from_linear(0.5);
+        pa_resampler *resampler;
+        pa_memchunk i, j;
+        pa_usec_t ts;
+
+        pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS);
+        pa_log_debug(_("=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"), seconds,
+                   a.rate, a.channels, pa_sample_format_to_string(a.format),
+                   b.rate, b.channels, pa_sample_format_to_string(b.format));
+
+        ts = pa_rtclock_now();
+        pa_assert_se(resampler = pa_resampler_new(pool, &a, NULL, &b, NULL, method, 0));
+        pa_log_info("init: %llu", (long long unsigned)(pa_rtclock_now() - ts));
+
+        i.memblock = pa_memblock_new(pool, pa_usec_to_bytes(1*PA_USEC_PER_SEC, &a));
+
+        ts = pa_rtclock_now();
+        i.length = pa_memblock_get_length(i.memblock);
+        i.index = 0;
+        while (seconds--) {
+            pa_resampler_run(resampler, &i, &j);
+            pa_memblock_unref(j.memblock);
+        }
+        pa_log_info("resampling: %llu", (long long unsigned)(pa_rtclock_now() - ts));
+        pa_memblock_unref(i.memblock);
+
+        pa_resampler_free(resampler);
+
+        goto quit;
+    }
 
     for (a.format = 0; a.format < PA_SAMPLE_MAX; a.format ++) {
         for (b.format = 0; b.format < PA_SAMPLE_MAX; b.format ++) {
             pa_resampler *forth, *back;
             pa_memchunk i, j, k;
 
-            printf("=== %s -> %s -> %s -> /2\n",
-                   pa_sample_format_to_string(a.format),
-                   pa_sample_format_to_string(b.format),
-                   pa_sample_format_to_string(a.format));
+            pa_log_debug("=== %s -> %s -> %s -> /2",
+                       pa_sample_format_to_string(a.format),
+                       pa_sample_format_to_string(b.format),
+                       pa_sample_format_to_string(a.format));
 
-            pa_assert_se(forth = pa_resampler_new(pool, &a, NULL, &b, NULL, PA_RESAMPLER_AUTO, 0));
-            pa_assert_se(back = pa_resampler_new(pool, &b, NULL, &a, NULL, PA_RESAMPLER_AUTO, 0));
+            pa_assert_se(forth = pa_resampler_new(pool, &a, NULL, &b, NULL, method, 0));
+            pa_assert_se(back = pa_resampler_new(pool, &b, NULL, &a, NULL, method, 0));
 
             i.memblock = generate_block(pool, &a);
             i.length = pa_memblock_get_length(i.memblock);
@@ -275,28 +460,22 @@ int main(int argc, char *argv[]) {
             pa_resampler_run(forth, &i, &j);
             pa_resampler_run(back, &j, &k);
 
-            printf("before:  ");
-            dump_block(&a, &i);
-            printf("after :  ");
-            dump_block(&b, &j);
-            printf("reverse: ");
-            dump_block(&a, &k);
+            dump_block("before", &a, &i);
+            dump_block("after", &b, &j);
+            dump_block("reverse", &a, &k);
 
+            pa_memblock_unref(i.memblock);
             pa_memblock_unref(j.memblock);
             pa_memblock_unref(k.memblock);
 
-            pa_volume_memchunk(&i, &a, &v);
-            printf("volume:  ");
-            dump_block(&a, &i);
-
-            pa_memblock_unref(i.memblock);
-
             pa_resampler_free(forth);
             pa_resampler_free(back);
         }
     }
 
-    pa_mempool_free(pool);
+ quit:
+    if (pool)
+        pa_mempool_free(pool);
 
-    return 0;
+    return ret;
 }
index 1706cdf..2ac34f0 100644 (file)
 #include <config.h>
 #endif
 
+#include <check.h>
 #include <signal.h>
-#include <poll.h>
 
+#include <pulsecore/poll.h>
 #include <pulsecore/log.h>
 #include <pulsecore/rtpoll.h>
 
@@ -41,7 +42,7 @@ static int worker(pa_rtpoll_item *w) {
     return 0;
 }
 
-int main(int argc, char *argv[]) {
+START_TEST (rtpoll_test) {
     pa_rtpoll *p;
     pa_rtpoll_item *i, *w;
     struct pollfd *pollfd;
@@ -80,6 +81,28 @@ int main(int argc, char *argv[]) {
     pa_rtpoll_item_free(w);
 
     pa_rtpoll_free(p);
+}
+END_TEST
 
-    return 0;
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("RT Poll");
+    tc = tcase_create("rtpoll");
+    tcase_add_test(tc, rtpoll_test);
+    /* the default timeout is too small,
+     * set it to a reasonable large one.
+     */
+    tcase_set_timeout(tc, 60 * 60);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index c93fee9..739683d 100644 (file)
 #include <stdlib.h>
 #include <unistd.h>
 #include <time.h>
-#include <sched.h>
 #include <inttypes.h>
-#include <string.h>
+
+#ifdef HAVE_PTHREAD
 #include <pthread.h>
+#endif
 
+#include <pulse/util.h>
 #include <pulse/timeval.h>
 #include <pulse/gccmacro.h>
 
 #include <pulsecore/log.h>
 #include <pulsecore/macro.h>
+#include <pulsecore/thread.h>
 #include <pulsecore/core-util.h>
+#include <pulsecore/core-rtclock.h>
 
 static int msec_lower, msec_upper;
 
-static void* work(void *p) PA_GCC_NORETURN;
+static void work(void *p) PA_GCC_NORETURN;
 
-static void* work(void *p) {
-#ifdef HAVE_PTHREAD_SETAFFINITY_NP
-    cpu_set_t mask;
-#endif
-    struct sched_param param;
+static void work(void *p) {
 
     pa_log_notice("CPU%i: Created thread.", PA_PTR_TO_UINT(p));
 
-    memset(&param, 0, sizeof(param));
-    param.sched_priority = 12;
-    pa_assert_se(pthread_setschedparam(pthread_self(), SCHED_FIFO, &param) == 0);
+    pa_make_realtime(12);
 
 #ifdef HAVE_PTHREAD_SETAFFINITY_NP
+{
+    cpu_set_t mask;
+
     CPU_ZERO(&mask);
     CPU_SET((size_t) PA_PTR_TO_UINT(p), &mask);
     pa_assert_se(pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) == 0);
+}
 #endif
 
     for (;;) {
-        struct timespec now, end;
-        uint64_t nsec;
+        struct timeval now, end;
+        uint64_t usec;
 
         pa_log_notice("CPU%i: Sleeping for 1s", PA_PTR_TO_UINT(p));
-        sleep(1);
-
-#ifdef CLOCK_REALTIME
-        pa_assert_se(clock_gettime(CLOCK_REALTIME, &end) == 0);
-#endif
-
-        nsec =
-            (uint64_t) ((((double) rand())*(double)(msec_upper-msec_lower)*PA_NSEC_PER_MSEC)/RAND_MAX) +
-            (uint64_t) ((uint64_t) msec_lower*PA_NSEC_PER_MSEC);
+        pa_msleep(1000);
 
-        pa_log_notice("CPU%i: Freezing for %ims", PA_PTR_TO_UINT(p), (int) (nsec/PA_NSEC_PER_MSEC));
+        usec =
+            (uint64_t) ((((double) rand())*(double)(msec_upper-msec_lower)*PA_USEC_PER_MSEC)/RAND_MAX) +
+            (uint64_t) ((uint64_t) msec_lower*PA_USEC_PER_MSEC);
 
-        end.tv_sec += (time_t) (nsec / PA_NSEC_PER_SEC);
-        end.tv_nsec += (long int) (nsec % PA_NSEC_PER_SEC);
+        pa_log_notice("CPU%i: Freezing for %ims", PA_PTR_TO_UINT(p), (int) (usec/PA_USEC_PER_MSEC));
 
-        while ((pa_usec_t) end.tv_nsec > PA_NSEC_PER_SEC) {
-            end.tv_sec++;
-            end.tv_nsec -= (long int) PA_NSEC_PER_SEC;
-        }
+        pa_rtclock_get(&end);
+        pa_timeval_add(&end, usec);
 
         do {
-#ifdef CLOCK_REALTIME
-            pa_assert_se(clock_gettime(CLOCK_REALTIME, &now) == 0);
-#endif
-        } while (now.tv_sec < end.tv_sec ||
-                 (now.tv_sec == end.tv_sec && now.tv_nsec < end.tv_nsec));
+            pa_rtclock_get(&now);
+        } while (pa_timeval_cmp(&now, &end) < 0);
     }
 }
 
 int main(int argc, char*argv[]) {
     unsigned n;
 
-    pa_log_set_level(PA_LOG_DEBUG);
+    pa_log_set_level(PA_LOG_INFO);
 
     srand((unsigned) time(NULL));
 
@@ -115,11 +105,10 @@ int main(int argc, char*argv[]) {
     pa_assert(msec_upper > 0);
     pa_assert(msec_upper >= msec_lower);
 
-    pa_log_notice("Creating random latencies in the range of %ims to  %ims.", msec_lower, msec_upper);
+    pa_log_notice("Creating random latencies in the range of %ims to %ims.", msec_lower, msec_upper);
 
     for (n = 1; n < pa_ncpus(); n++) {
-        pthread_t t;
-        pa_assert_se(pthread_create(&t, NULL, work, PA_UINT_TO_PTR(n)) == 0);
+        pa_assert_se(pa_thread_new("rtstutter", work, PA_UINT_TO_PTR(n)));
     }
 
     work(PA_INT_TO_PTR(0));
index 0cd929c..72cd224 100644 (file)
 #include <config.h>
 #endif
 
+#include <check.h>
+
 #include <signal.h>
 #include <stdio.h>
 
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
 
-int main(int argc, char *argv[]) {
+static const char *names[] = {
+    "SIG-1",
+    "SIG0",
+    "SIGHUP",
+    "SIGINT",
+    "SIGQUIT",
+    "SIGULL",
+    "SIGTRAP",
+    "SIGABRT",
+    "SIGBUS",
+    "SIGFPE",
+    "SIGKILL",
+    "SIGUSR1",
+    "SIGSEGV",
+    "SIGUSR2",
+    "SIGPIPE",
+    "SIGALRM",
+    "SIGTERM",
+    "SIGSTKFLT",
+    "SIGCHLD",
+    "SIGCONT",
+    "SIGSTOP",
+    "SIGTSTP",
+    "SIGTTIN",
+    "SIGTTOU",
+    "SIGURG",
+    "SIGXCPU",
+    "SIGXFSZ",
+    "SIGVTALRM",
+    "SIGPROF",
+    "SIGWINCH",
+    "SIGIO",
+    "SIGPWR",
+    "SIGSYS",
+    "SIG32",
+    "SIG33",
+    "SIGRTMIN+0",
+    "SIGRTMIN+1",
+    "SIGRTMIN+2",
+    "SIGRTMIN+3",
+    "SIGRTMIN+4",
+    "SIGRTMIN+5",
+    "SIGRTMIN+6",
+    "SIGRTMIN+7",
+    "SIGRTMIN+8",
+    "SIGRTMIN+9",
+    "SIGRTMIN+10",
+    "SIGRTMIN+11",
+    "SIGRTMIN+12",
+    "SIGRTMIN+13",
+    "SIGRTMIN+14",
+    "SIGRTMIN+15",
+    "SIGRTMIN+16",
+    "SIGRTMIN+17",
+    "SIGRTMIN+18",
+    "SIGRTMIN+19",
+    "SIGRTMIN+20",
+    "SIGRTMIN+21",
+    "SIGRTMIN+22",
+    "SIGRTMIN+23",
+    "SIGRTMIN+24",
+    "SIGRTMIN+25",
+    "SIGRTMIN+26",
+    "SIGRTMIN+27",
+    "SIGRTMIN+28",
+    "SIGRTMIN+29",
+    "SIGRTMIN+30",
+    "SIG65"
+};
+
+START_TEST (sig2str_test) {
     int sig;
 
-    for (sig = -1; sig <= NSIG; sig++)
+    for (sig = -1; sig <= NSIG; sig++) {
         printf("%i = %s\n", sig, pa_sig2str(sig));
+        fail_unless(pa_streq(pa_sig2str(sig), names[sig+1]));
+    }
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Signal String");
+    tc = tcase_create("sig2str");
+    tcase_add_test(tc, sig2str_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
 
-    return 0;
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index 4b9ca84..e5815e5 100644 (file)
 #include <fcntl.h>
 #include <sys/mman.h>
 
+#include <check.h>
+
 #include <pulsecore/memtrap.h>
 #include <pulsecore/core-util.h>
 
-int main(int argc, char *argv[]) {
+START_TEST (sigbus_test) {
     void *p;
     int fd;
     pa_memtrap *m;
@@ -38,10 +40,10 @@ int main(int argc, char *argv[]) {
     pa_memtrap_install();
 
     /* Create the memory map */
-    pa_assert_se((fd = open("sigbus-test-map", O_RDWR|O_TRUNC|O_CREAT, 0660)) >= 0);
-    pa_assert_se(unlink("sigbus-test-map") == 0);
-    pa_assert_se(ftruncate(fd, PA_PAGE_SIZE) >= 0);
-    pa_assert_se((p = mmap(NULL, PA_PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) != MAP_FAILED);
+    fail_unless((fd = open("sigbus-test-map", O_RDWR|O_TRUNC|O_CREAT, 0660)) >= 0);
+    fail_unless(unlink("sigbus-test-map") == 0);
+    fail_unless(ftruncate(fd, PA_PAGE_SIZE) >= 0);
+    fail_unless((p = mmap(NULL, PA_PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) != MAP_FAILED);
 
     /* Register memory map */
     m = pa_memtrap_add(p, PA_PAGE_SIZE);
@@ -54,7 +56,7 @@ int main(int argc, char *argv[]) {
     pa_log("And memtrap says it is good: %s", pa_yes_no(pa_memtrap_is_good(m)));
 
     /* Invalidate mapping */
-    pa_assert_se(ftruncate(fd, 0) >= 0);
+    fail_unless(ftruncate(fd, 0) >= 0);
 
     /* Use memory map */
     pa_snprintf(p, PA_PAGE_SIZE, "This is a test that should fail but get caught.");
@@ -65,6 +67,24 @@ int main(int argc, char *argv[]) {
 
     pa_memtrap_remove(m);
     munmap(p, PA_PAGE_SIZE);
+}
+END_TEST
 
-    return 0;
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Sig Bus");
+    tc = tcase_create("sigbus");
+    tcase_add_test(tc, sigbus_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index 2cc9f58..eac824e 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 
-#include <pulsecore/time-smoother.h>
+#include <check.h>
+
 #include <pulse/timeval.h>
 
-int main(int argc, char*argv[]) {
+#include <pulsecore/log.h>
+#include <pulsecore/time-smoother.h>
+
+START_TEST (smoother_test) {
     pa_usec_t x;
     unsigned u = 0;
     pa_smoother *s;
@@ -45,7 +49,8 @@ int main(int argc, char*argv[]) {
 
     srand(0);
 
-    pa_log_set_level(PA_LOG_DEBUG);
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_DEBUG);
 
     for (m = 0, u = 0; u < PA_ELEMENTSOF(msec); u+= 2) {
 
@@ -67,16 +72,35 @@ int main(int argc, char*argv[]) {
 
         while (u < PA_ELEMENTSOF(msec) && (pa_usec_t) msec[u]*PA_USEC_PER_MSEC < x) {
             pa_smoother_put(s, (pa_usec_t) msec[u] * PA_USEC_PER_MSEC, (pa_usec_t) msec[u+1] * PA_USEC_PER_MSEC);
-            printf("%i\t\t%i\n", msec[u],  msec[u+1]);
+            pa_log_debug("%i\t\t%i", msec[u],  msec[u+1]);
             u += 2;
 
-            pa_smoother_resume(s, (pa_usec_t) msec[u] * PA_USEC_PER_MSEC, TRUE);
+            if (u < PA_ELEMENTSOF(msec))
+                pa_smoother_resume(s, (pa_usec_t) msec[u] * PA_USEC_PER_MSEC, TRUE);
         }
 
-        printf("%llu\t%llu\n", (unsigned long long) (x/PA_USEC_PER_MSEC), (unsigned long long) (pa_smoother_get(s, x)/PA_USEC_PER_MSEC));
+        pa_log_debug("%llu\t%llu", (unsigned long long) (x/PA_USEC_PER_MSEC), (unsigned long long) (pa_smoother_get(s, x)/PA_USEC_PER_MSEC));
     }
 
     pa_smoother_free(s);
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Smoother");
+    tc = tcase_create("smoother");
+    tcase_add_test(tc, smoother_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
 
-    return 0;
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index 10f370c..6a4f4bb 100644 (file)
@@ -1,11 +1,16 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdio.h>
+#include <check.h>
 
 #include <pulse/xmalloc.h>
-#include <pulse/gccmacro.h>
 
 #include <pulsecore/strlist.h>
+#include <pulsecore/core-util.h>
 
-int main(int argc, char* argv[]) {
+START_TEST (strlist_test) {
     char *t, *u;
     pa_strlist *l = NULL;
 
@@ -19,25 +24,47 @@ int main(int argc, char* argv[]) {
     pa_strlist_free(l);
 
     fprintf(stderr, "1: %s\n", t);
+    fail_unless(pa_streq(t, "a b c d e"));
 
     l = pa_strlist_parse(t);
     pa_xfree(t);
 
     t = pa_strlist_tostring(l);
     fprintf(stderr, "2: %s\n", t);
+    fail_unless(pa_streq(t, "a b c d e"));
     pa_xfree(t);
 
     l = pa_strlist_pop(l, &u);
     fprintf(stderr, "3: %s\n", u);
+    fail_unless(pa_streq(u, "a"));
     pa_xfree(u);
 
     l = pa_strlist_remove(l, "c");
 
     t = pa_strlist_tostring(l);
     fprintf(stderr, "4: %s\n", t);
+    fail_unless(pa_streq(t, "b d e"));
     pa_xfree(t);
 
     pa_strlist_free(l);
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("StrList");
+    tc = tcase_create("strlist");
+    tcase_add_test(tc, strlist_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
 
-    return 0;
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index bb64a91..0a758d1 100644 (file)
 #endif
 
 #include <signal.h>
-#include <string.h>
 #include <errno.h>
 #include <unistd.h>
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <getopt.h>
 #include <math.h>
 
+#include <check.h>
+
 #include <pulse/pulseaudio.h>
 #include <pulse/mainloop.h>
 
@@ -41,6 +41,7 @@
 static pa_context *context = NULL;
 static pa_stream *streams[NSTREAMS];
 static pa_mainloop_api *mainloop_api = NULL;
+static const char *bname = NULL;
 
 static float data[SAMPLE_HZ]; /* one second space */
 
@@ -55,7 +56,7 @@ static const pa_sample_spec sample_spec = {
 static const pa_buffer_attr buffer_attr = {
     .maxlength = SAMPLE_HZ*sizeof(float)*NSTREAMS, /* exactly space for the entire play time */
     .tlength = (uint32_t) -1,
-    .prebuf = 0, /* Setting prebuf to 0 guarantees us the the streams will run synchronously, no matter what */
+    .prebuf = 0, /* Setting prebuf to 0 guarantees us the streams will run synchronously, no matter what */
     .minreq = (uint32_t) -1,
     .fragsize = 0
 };
@@ -75,7 +76,7 @@ static void underflow_cb(struct pa_stream *s, void *userdata) {
 
 /* This routine is called whenever the stream state changes */
 static void stream_state_callback(pa_stream *s, void *userdata) {
-    assert(s);
+    fail_unless(s != NULL);
 
     switch (pa_stream_get_state(s)) {
         case PA_STREAM_UNCONNECTED:
@@ -90,7 +91,7 @@ static void stream_state_callback(pa_stream *s, void *userdata) {
             fprintf(stderr, "Writing data to stream %i.\n", i);
 
             r = pa_stream_write(s, data, sizeof(data), nop_free_cb, (int64_t) sizeof(data) * (int64_t) i, PA_SEEK_ABSOLUTE);
-            assert(r == 0);
+            fail_unless(r == 0);
 
             /* Be notified when this stream is drained */
             pa_stream_set_underflow_callback(s, underflow_cb, userdata);
@@ -107,13 +108,13 @@ static void stream_state_callback(pa_stream *s, void *userdata) {
         default:
         case PA_STREAM_FAILED:
             fprintf(stderr, "Stream error: %s\n", pa_strerror(pa_context_errno(pa_stream_get_context(s))));
-            abort();
+            fail();
     }
 }
 
 /* This is called whenever the context status changes */
 static void context_state_callback(pa_context *c, void *userdata) {
-    assert(c);
+    fail_unless(c != NULL);
 
     switch (pa_context_get_state(c)) {
         case PA_CONTEXT_CONNECTING:
@@ -134,7 +135,7 @@ static void context_state_callback(pa_context *c, void *userdata) {
                 snprintf(name, sizeof(name), "stream #%i", i);
 
                 streams[i] = pa_stream_new(c, name, &sample_spec, NULL);
-                assert(streams[i]);
+                fail_unless(streams[i] != NULL);
                 pa_stream_set_state_callback(streams[i], stream_state_callback, (void*) (long) i);
                 pa_stream_connect_playback(streams[i], NULL, &buffer_attr, PA_STREAM_START_CORKED, NULL, i == 0 ? NULL : streams[0]);
             }
@@ -149,11 +150,11 @@ static void context_state_callback(pa_context *c, void *userdata) {
         case PA_CONTEXT_FAILED:
         default:
             fprintf(stderr, "Context error: %s\n", pa_strerror(pa_context_errno(c)));
-            abort();
+            fail();
     }
 }
 
-int main(int argc, char *argv[]) {
+START_TEST (sync_playback_test) {
     pa_mainloop* m = NULL;
     int i, ret = 0;
 
@@ -165,12 +166,12 @@ int main(int argc, char *argv[]) {
 
     /* Set up a new main loop */
     m = pa_mainloop_new();
-    assert(m);
+    fail_unless(m != NULL);
 
     mainloop_api = pa_mainloop_get_api(m);
 
-    context = pa_context_new(mainloop_api, argv[0]);
-    assert(context);
+    context = pa_context_new(mainloop_api, bname);
+    fail_unless(context != NULL);
 
     pa_context_set_state_callback(context, context_state_callback, NULL);
 
@@ -192,5 +193,28 @@ quit:
 
     pa_mainloop_free(m);
 
-    return ret;
+    fail_unless(ret == 0);
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    bname = argv[0];
+
+    s = suite_create("Sync Playback");
+    tc = tcase_create("syncplayback");
+    tcase_add_test(tc, sync_playback_test);
+    tcase_set_timeout(tc, 5 * 60);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index 4696fb0..d2f6152 100644 (file)
 #include <unistd.h>
 #include <stdio.h>
 
+#include <check.h>
+
 #include <pulse/rtclock.h>
 #include <pulse/timeval.h>
 #include <pulse/util.h>
 #include <pulse/thread-mainloop.h>
-#include <pulse/gccmacro.h>
 
 #include <pulsecore/macro.h>
 #include <pulsecore/core-rtclock.h>
@@ -41,19 +42,21 @@ static void tcb(pa_mainloop_api *a, pa_time_event *e, const struct timeval *tv,
     fprintf(stderr, "TIME EVENT END\n");
 }
 
-int main(int argc, char *argv[]) {
+START_TEST (thread_mainloop_test) {
     pa_mainloop_api *a;
     pa_threaded_mainloop *m;
     struct timeval tv;
 
-    pa_assert_se(m = pa_threaded_mainloop_new());
-    pa_assert_se(a = pa_threaded_mainloop_get_api(m));
+    m = pa_threaded_mainloop_new();
+    fail_unless(m != NULL);
+    a = pa_threaded_mainloop_get_api(m);
+    fail_unless(m != NULL);
 
-    pa_assert_se(pa_threaded_mainloop_start(m) >= 0);
+    fail_unless(pa_threaded_mainloop_start(m) >= 0);
 
     pa_threaded_mainloop_lock(m);
 
-    pa_assert_se(!pa_threaded_mainloop_in_thread(m));
+    fail_unless(!pa_threaded_mainloop_in_thread(m));
 
     a->time_new(a, pa_timeval_rtstore(&tv, pa_rtclock_now() + 5 * PA_USEC_PER_SEC, TRUE), tcb, m);
 
@@ -68,10 +71,31 @@ int main(int argc, char *argv[]) {
     fprintf(stderr, "waiting 5s (sleep)\n");
     pa_msleep(5000);
 
-    fprintf(stderr, "shutting down\n");
-
     pa_threaded_mainloop_stop(m);
 
     pa_threaded_mainloop_free(m);
-    return 0;
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Thread MainLoop");
+    tc = tcase_create("threadmainloop");
+    tcase_add_test(tc, thread_mainloop_test);
+    /* the default timeout is too small,
+     * set it to a reasonable large one.
+     */
+    tcase_set_timeout(tc, 60 * 60);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index 2c07b1c..de4813c 100644 (file)
 #include <config.h>
 #endif
 
+#include <check.h>
+
+#include <pulse/xmalloc.h>
 #include <pulsecore/thread.h>
+#include <pulsecore/macro.h>
 #include <pulsecore/mutex.h>
 #include <pulsecore/once.h>
 #include <pulsecore/log.h>
 #include <pulsecore/core-util.h>
-#include <pulse/xmalloc.h>
 
 static pa_mutex *mutex = NULL;
 static pa_cond *cond1 = NULL, *cond2 = NULL;
@@ -45,14 +48,14 @@ static pa_once once = PA_ONCE_INIT;
 static void thread_func(void *data) {
     pa_tls_set(tls, data);
 
-    pa_log("thread_func() for %s starting...", (char*) pa_tls_get(tls));
+    pa_log_info("thread_func() for %s starting...", (char*) pa_tls_get(tls));
 
     pa_mutex_lock(mutex);
 
     for (;;) {
         int k, n;
 
-        pa_log("%s waiting ...", (char*) pa_tls_get(tls));
+        pa_log_info("%s waiting ...", (char*) pa_tls_get(tls));
 
         for (;;) {
 
@@ -74,7 +77,7 @@ static void thread_func(void *data) {
 
         pa_cond_signal(cond2, 0);
 
-        pa_log("%s got number %i", (char*) pa_tls_get(tls), k);
+        pa_log_info("%s got number %i", (char*) pa_tls_get(tls), k);
 
         /* Spin! */
         for (n = 0; n < k; n++)
@@ -87,14 +90,15 @@ quit:
 
     pa_mutex_unlock(mutex);
 
-    pa_log("thread_func() for %s done...", (char*) pa_tls_get(tls));
+    pa_log_info("thread_func() for %s done...", (char*) pa_tls_get(tls));
 }
 
-int main(int argc, char *argv[]) {
+START_TEST (thread_test) {
     int i, k;
     pa_thread* t[THREADS_MAX];
 
-    assert(pa_thread_is_running(pa_thread_self()));
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_DEBUG);
 
     mutex = pa_mutex_new(FALSE, FALSE);
     cond1 = pa_cond_new();
@@ -102,8 +106,8 @@ int main(int argc, char *argv[]) {
     tls = pa_tls_new(pa_xfree);
 
     for (i = 0; i < THREADS_MAX; i++) {
-        t[i] = pa_thread_new(thread_func, pa_sprintf_malloc("Thread #%i", i+1));
-        assert(t[i]);
+        t[i] = pa_thread_new("test", thread_func, pa_sprintf_malloc("Thread #%i", i+1));
+        fail_unless(t[i] != 0);
     }
 
     pa_mutex_lock(mutex);
@@ -111,12 +115,11 @@ int main(int argc, char *argv[]) {
     pa_log("loop-init");
 
     for (k = 0; k < 100; k++) {
-        assert(magic_number == 0);
-
+        pa_assert(magic_number == 0);
 
         magic_number = (int) rand() % 0x10000;
 
-        pa_log("iteration %i (%i)", k, magic_number);
+        pa_log_info("iteration %i (%i)", k, magic_number);
 
         pa_cond_signal(cond1, 0);
 
@@ -137,6 +140,24 @@ int main(int argc, char *argv[]) {
     pa_cond_free(cond1);
     pa_cond_free(cond2);
     pa_tls_free(tls);
+}
+END_TEST
 
-    return 0;
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Thread");
+    tc = tcase_create("thread");
+    tcase_add_test(tc, thread_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index a48b016..13ee48c 100644 (file)
 #include <grp.h>
 #include <errno.h>
 
+#include <check.h>
+
 #include <pulsecore/usergroup.h>
+#include <pulsecore/core-util.h>
 
 static int load_reference_structs(struct group **gr, struct passwd **pw) {
     setpwent();
@@ -46,29 +49,25 @@ static int load_reference_structs(struct group **gr, struct passwd **pw) {
 static int compare_group(const struct group *a, const struct group *b) {
     char **amem, **bmem;
 
-    if (strcmp(a->gr_name, b->gr_name)) {
-        fprintf(stderr, "Group name mismatch: [%s] [%s]\n",
-                a->gr_name, b->gr_name);
+    if (!pa_streq(a->gr_name, b->gr_name)) {
+        fprintf(stderr, "Group name mismatch: [%s] [%s]\n", a->gr_name, b->gr_name);
         return 1;
     }
 
-    if (strcmp(a->gr_passwd, b->gr_passwd)) {
-        fprintf(stderr, "Group password mismatch: [%s] [%s]\n",
-                a->gr_passwd, b->gr_passwd);
+    if (!pa_streq(a->gr_passwd, b->gr_passwd)) {
+        fprintf(stderr, "Group password mismatch: [%s] [%s]\n", a->gr_passwd, b->gr_passwd);
         return 1;
     }
 
     if (a->gr_gid != b->gr_gid) {
-        fprintf(stderr, "Gid mismatch: [%lu] [%lu]\n",
-                (unsigned long) a->gr_gid, (unsigned long) b->gr_gid);
+        fprintf(stderr, "Gid mismatch: [%lu] [%lu]\n", (unsigned long) a->gr_gid, (unsigned long) b->gr_gid);
         return 1;
     }
 
     /* XXX: Assuming the group ordering is identical. */
     for (amem = a->gr_mem, bmem = b->gr_mem; *amem && *bmem; ++amem, ++bmem) {
-        if (strcmp(*amem, *bmem)) {
-            fprintf(stderr, "Group member mismatch: [%s] [%s]\n",
-                    *amem, *bmem);
+        if (!pa_streq(*amem, *bmem)) {
+            fprintf(stderr, "Group member mismatch: [%s] [%s]\n", *amem, *bmem);
             return 1;
         }
     }
@@ -82,39 +81,37 @@ static int compare_group(const struct group *a, const struct group *b) {
 }
 
 static int compare_passwd(const struct passwd *a, const struct passwd *b) {
-    if (strcmp(a->pw_name, b->pw_name)) {
+    if (!pa_streq(a->pw_name, b->pw_name)) {
         fprintf(stderr, "pw_name mismatch: [%s] [%s]\n", a->pw_name, b->pw_name);
         return 1;
     }
 
-    if (strcmp(a->pw_passwd, b->pw_passwd)) {
+    if (!pa_streq(a->pw_passwd, b->pw_passwd)) {
         fprintf(stderr, "pw_passwd mismatch: [%s] [%s]\n", a->pw_passwd, b->pw_passwd);
         return 1;
     }
 
     if (a->pw_uid != b->pw_uid) {
-        fprintf(stderr, "pw_uid mismatch: [%lu] [%lu]\n",
-               (unsigned long) a->pw_uid, (unsigned long) b->pw_uid);
+        fprintf(stderr, "pw_uid mismatch: [%lu] [%lu]\n", (unsigned long) a->pw_uid, (unsigned long) b->pw_uid);
         return 1;
     }
 
     if (a->pw_gid != b->pw_gid) {
-        fprintf(stderr, "pw_gid mismatch: [%lu] [%lu]\n",
-               (unsigned long) a->pw_gid, (unsigned long) b->pw_gid);
+        fprintf(stderr, "pw_gid mismatch: [%lu] [%lu]\n", (unsigned long) a->pw_gid, (unsigned long) b->pw_gid);
         return 1;
     }
 
-    if (strcmp(a->pw_gecos, b->pw_gecos)) {
+    if (!pa_streq(a->pw_gecos, b->pw_gecos)) {
         fprintf(stderr, "pw_gecos mismatch: [%s] [%s]\n", a->pw_gecos, b->pw_gecos);
         return 1;
     }
 
-    if (strcmp(a->pw_dir, b->pw_dir)) {
+    if (!pa_streq(a->pw_dir, b->pw_dir)) {
         fprintf(stderr, "pw_dir mismatch: [%s] [%s]\n", a->pw_dir, b->pw_dir);
         return 1;
     }
 
-    if (strcmp(a->pw_shell, b->pw_shell)) {
+    if (!pa_streq(a->pw_shell, b->pw_shell)) {
         fprintf(stderr, "pw_shell mismatch: [%s] [%s]\n", a->pw_shell, b->pw_shell);
         return 1;
     }
@@ -122,40 +119,51 @@ static int compare_passwd(const struct passwd *a, const struct passwd *b) {
     return 0;
 }
 
-int main(int argc, char *argv[]) {
+START_TEST (usergroup_test) {
     struct group *gr;
     struct passwd *pw;
-    int err;
     struct group *reference_group = NULL;
     struct passwd *reference_passwd = NULL;
 
-    err = load_reference_structs(&reference_group, &reference_passwd);
-    if (err)
-        return 77;
+    fail_if(load_reference_structs(&reference_group, &reference_passwd));
 
     errno = 0;
     gr = pa_getgrgid_malloc(reference_group->gr_gid);
-    if (compare_group(reference_group, gr))
-        return 1;
+    fail_if(compare_group(reference_group, gr));
     pa_getgrgid_free(gr);
 
     errno = 0;
     gr = pa_getgrnam_malloc(reference_group->gr_name);
-    if (compare_group(reference_group, gr))
-        return 1;
+    fail_if(compare_group(reference_group, gr));
     pa_getgrnam_free(gr);
 
     errno = 0;
     pw = pa_getpwuid_malloc(reference_passwd->pw_uid);
-    if (compare_passwd(reference_passwd, pw))
-        return 1;
+    fail_if(compare_passwd(reference_passwd, pw));
     pa_getpwuid_free(pw);
 
     errno = 0;
     pw = pa_getpwnam_malloc(reference_passwd->pw_name);
-    if (compare_passwd(reference_passwd, pw))
-        return 1;
+    fail_if(compare_passwd(reference_passwd, pw));
     pa_getpwnam_free(pw);
+}
+END_TEST
 
-    return 0;
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Usergroup");
+    tc = tcase_create("usergroup");
+    tcase_add_test(tc, usergroup_test);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index f1708ad..22a58c0 100644 (file)
@@ -1,24 +1,72 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdio.h>
 #include <assert.h>
+#include <check.h>
 
 #include <pulse/utf8.h>
 #include <pulse/xmalloc.h>
+#include <pulsecore/core-util.h>
 
-int main(int argc, char *argv[]) {
+START_TEST (utf8_valid) {
+    fail_unless(pa_utf8_valid("hallo") != NULL);
+    fail_unless(pa_utf8_valid("hallo\n") != NULL);
+    fail_unless(pa_utf8_valid("hüpfburg\n") == NULL);
+    fail_unless(pa_utf8_valid("hallo\n") != NULL);
+    fail_unless(pa_utf8_valid("hüpfburg\n") != NULL);
+}
+END_TEST
+
+START_TEST (utf8_filter) {
     char *c;
 
-    assert(pa_utf8_valid("hallo"));
-    assert(pa_utf8_valid("hallo\n"));
-    assert(!pa_utf8_valid("hüpfburg\n"));
-    assert(pa_utf8_valid("hallo\n"));
-    assert(pa_utf8_valid("hüpfburg\n"));
+    {
+        char res1[] = { 0x68, 0x5f, 0x70, 0x66, 0x62, 0x75, 0x72, 0x67, '\0' };
+        c = pa_utf8_filter("hüpfburg");
+        pa_log_debug("%s %s\n", res1, c);
+        fail_unless(pa_streq(c, res1));
+        pa_xfree(c);
+    }
+
+    {
+        char res2[] = { 0x68, 0xc3, 0xbc, 0x70, 0x66, 0x62, 0x75, 0x72, 0x67, '\0' };
+        c = pa_utf8_filter("hüpfburg");
+        fail_unless(pa_streq(c, res2));
+        pa_log_debug("%s %s\n", res2, c);
+        pa_xfree(c);
+    }
+
+    {
+        char res3[] = { 0x5f, 0x78, 0x6b, 0x6e, 0x5f, 0x72, 0x7a, 0x6d, 0x5f, 0x72, 0x7a, 0x65, 0x6c, 0x74, 0x5f, 0x72, 0x73, 0x7a, 0xdf, 0xb3, 0x5f, 0x64, 0x73, 0x6a, 0x6b, 0x66, 0x68, '\0' };
+        c = pa_utf8_filter("üxknärzmörzeltörszß³§dsjkfh");
+        pa_log_debug("%s %s\n", res3, c);
+        fail_unless(pa_streq(c, res3));
+        pa_xfree(c);
+    }
+}
+END_TEST
+
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_DEBUG);
+
+    s = suite_create("UTF8");
+    tc = tcase_create("utf8");
+    tcase_add_test(tc, utf8_valid);
+    tcase_add_test(tc, utf8_filter);
+    suite_add_tcase(s, tc);
 
-    printf("LATIN1: %s\n", c = pa_utf8_filter("hüpfburg"));
-    pa_xfree(c);
-    printf("UTF8: %sx\n", c = pa_utf8_filter("hüpfburg"));
-    pa_xfree(c);
-    printf("LATIN1: %sx\n", c = pa_utf8_filter("üxknärzmörzeltörszß³§dsjkfh"));
-    pa_xfree(c);
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
 
-    return 0;
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
diff --git a/src/tests/vector-test.c b/src/tests/vector-test.c
deleted file mode 100644 (file)
index 7494348..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2009 Lennart Poettering
-
-  PulseAudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as
-  published by the Free Software Foundation; either version 2.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, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <pulsecore/vector.h>
-#include <pulsecore/log.h>
-
-int main(int argc, char *argv[]) {
-
-#ifdef __SSE2__
-    pa_int16_vector_t input, zero;
-    pa_int32_vector_t unpacked1, unpacked2;
-    pa_int32_vector_t volume1, volume2, volume1_hi, volume1_lo, volume2_hi, volume2_lo, reduce, mask;
-    pa_int16_vector_t output;
-
-    unsigned u;
-
-    zero.v = PA_INT16_VECTOR_MAKE(0);
-    reduce.v = PA_INT32_VECTOR_MAKE(0x10000);
-    volume1.v = volume2.v = PA_INT32_VECTOR_MAKE(0x10000*2+7);
-    mask.v = PA_INT32_VECTOR_MAKE(0xFFFF);
-
-    volume1_lo.m = _mm_and_si128(volume1.m, mask.m);
-    volume2_lo.m = _mm_and_si128(volume2.m, mask.m);
-    volume1_hi.m = _mm_srli_epi32(volume1.m, 16);
-    volume2_hi.m = _mm_srli_epi32(volume2.m, 16);
-
-    input.v = PA_INT16_VECTOR_MAKE(32000);
-
-    for (u = 0; u < PA_INT16_VECTOR_SIZE; u++)
-        pa_log("input=%i\n", input.i[u]);
-
-    unpacked1.m = _mm_unpackhi_epi16(zero.m, input.m);
-    unpacked2.m = _mm_unpacklo_epi16(zero.m, input.m);
-
-    for (u = 0; u < PA_INT32_VECTOR_SIZE; u++)
-        pa_log("unpacked1=%i\n", unpacked1.i[u]);
-
-    unpacked1.v /= reduce.v;
-    unpacked2.v /= reduce.v;
-
-    for (u = 0; u < PA_INT32_VECTOR_SIZE; u++)
-        pa_log("unpacked1=%i\n", unpacked1.i[u]);
-
-    for (u = 0; u < PA_INT32_VECTOR_SIZE; u++)
-        pa_log("volume1=%i\n", volume1.i[u]);
-
-    unpacked1.v = (unpacked1.v * volume1_lo.v) / reduce.v + unpacked1.v * volume1_hi.v;
-    unpacked2.v = (unpacked2.v * volume2_lo.v) / reduce.v + unpacked2.v * volume2_hi.v;
-
-    for (u = 0; u < PA_INT32_VECTOR_SIZE; u++)
-        pa_log("unpacked1=%i\n", unpacked1.i[u]);
-
-    output.m = _mm_packs_epi32(unpacked1.m, unpacked2.m);
-
-    for (u = 0; u < PA_INT16_VECTOR_SIZE; u++)
-        pa_log("output=%i\n", output.i[u]);
-
-#endif
-
-    return 0;
-}
similarity index 66%
rename from src/tests/voltest.c
rename to src/tests/volume-test.c
index 551f7ec..d8d2149 100644 (file)
 #endif
 
 #include <stdio.h>
+#include <math.h>
+
+#include <check.h>
 
 #include <pulse/volume.h>
-#include <pulse/gccmacro.h>
 
+#include <pulsecore/log.h>
 #include <pulsecore/macro.h>
 
-int main(int argc, char *argv[]) {
+START_TEST (volume_test) {
     pa_volume_t v;
     pa_cvolume cv;
     float b;
@@ -36,15 +39,18 @@ int main(int argc, char *argv[]) {
     pa_volume_t md = 0;
     unsigned mdn = 0;
 
-    printf("Attenuation of sample 1 against 32767: %g dB\n", 20.0*log10(1.0/32767.0));
-    printf("Smallest possible attenutation > 0 applied to 32767: %li\n", lrint(32767.0*pa_sw_volume_to_linear(1)));
+    if (!getenv("MAKE_CHECK"))
+        pa_log_set_level(PA_LOG_DEBUG);
+
+    pa_log("Attenuation of sample 1 against 32767: %g dB", 20.0*log10(1.0/32767.0));
+    pa_log("Smallest possible attenuation > 0 applied to 32767: %li", lrint(32767.0*pa_sw_volume_to_linear(1)));
 
     for (v = PA_VOLUME_MUTED; v <= PA_VOLUME_NORM*2; v += 256) {
 
         double dB = pa_sw_volume_to_dB(v);
         double f = pa_sw_volume_to_linear(v);
 
-        printf("Volume: %3i; percent: %i%%; decibel %0.2f; linear = %0.2f; volume(decibel): %3i; volume(linear): %3i\n",
+        pa_log_debug("Volume: %3i; percent: %i%%; decibel %0.2f; linear = %0.2f; volume(decibel): %3i; volume(linear): %3i",
                v, (v*100)/PA_VOLUME_NORM, dB, f, pa_sw_volume_from_dB(dB), pa_sw_volume_from_linear(f));
     }
 
@@ -53,11 +59,7 @@ int main(int argc, char *argv[]) {
 
         pa_cvolume_set(&cv, 2, v);
 
-        printf("Volume: %3i [%s] [%s]\n",
-               v,
-               pa_cvolume_snprint(s, sizeof(s), &cv),
-               pa_sw_cvolume_snprint_dB(t, sizeof(t), &cv));
-
+        pa_log_debug("Volume: %3i [%s] [%s]", v, pa_cvolume_snprint(s, sizeof(s), &cv), pa_sw_cvolume_snprint_dB(t, sizeof(t), &cv));
     }
 
     map.channels = cv.channels = 2;
@@ -68,7 +70,7 @@ int main(int argc, char *argv[]) {
         for (cv.values[1] = PA_VOLUME_MUTED; cv.values[1] <= PA_VOLUME_NORM*2; cv.values[1] += 4096) {
             char s[PA_CVOLUME_SNPRINT_MAX];
 
-            printf("Volume: [%s]; balance: %2.1f\n", pa_cvolume_snprint(s, sizeof(s), &cv), pa_cvolume_get_balance(&cv, &map));
+            pa_log_debug("Volume: [%s]; balance: %2.1f", pa_cvolume_snprint(s, sizeof(s), &cv), pa_cvolume_get_balance(&cv, &map));
         }
 
     for (cv.values[0] = PA_VOLUME_MUTED+4096; cv.values[0] <= PA_VOLUME_NORM*2; cv.values[0] += 4096)
@@ -78,13 +80,13 @@ int main(int argc, char *argv[]) {
                 pa_cvolume r;
                 float k;
 
-                printf("Before: volume: [%s]; balance: %2.1f\n", pa_cvolume_snprint(s, sizeof(s), &cv), pa_cvolume_get_balance(&cv, &map));
+                pa_log_debug("Before: volume: [%s]; balance: %2.1f", pa_cvolume_snprint(s, sizeof(s), &cv), pa_cvolume_get_balance(&cv, &map));
 
                 r = cv;
                 pa_cvolume_set_balance(&r, &map,b);
 
                 k = pa_cvolume_get_balance(&r, &map);
-                printf("After: volume: [%s]; balance: %2.1f (intended: %2.1f) %s\n", pa_cvolume_snprint(s, sizeof(s), &r), k, b, k < b-.05 || k > b+.5 ? "MISMATCH" : "");
+                pa_log_debug("After: volume: [%s]; balance: %2.1f (intended: %2.1f) %s", pa_cvolume_snprint(s, sizeof(s), &r), k, b, k < b-.05 || k > b+.5 ? "MISMATCH" : "");
             }
 
     for (v = PA_VOLUME_MUTED; v <= PA_VOLUME_NORM*2; v += 51) {
@@ -95,8 +97,8 @@ int main(int argc, char *argv[]) {
         pa_volume_t r = pa_sw_volume_from_dB(db);
         pa_volume_t w;
 
-        pa_assert(k == v);
-        pa_assert(r == v);
+        fail_unless(k == v);
+        fail_unless(r == v);
 
         for (w = PA_VOLUME_MUTED; w < PA_VOLUME_NORM*2; w += 37) {
 
@@ -125,10 +127,29 @@ int main(int argc, char *argv[]) {
         }
     }
 
-    printf("max deviation: %lu n=%lu\n", (unsigned long) md, (unsigned long) mdn);
+    pa_log("max deviation: %lu n=%lu", (unsigned long) md, (unsigned long) mdn);
 
-    pa_assert(md <= 1);
-    pa_assert(mdn <= 251);
+    fail_unless(md <= 1);
+    fail_unless(mdn <= 251);
+}
+END_TEST
 
-    return 0;
+int main(int argc, char *argv[]) {
+    int failed = 0;
+    Suite *s;
+    TCase *tc;
+    SRunner *sr;
+
+    s = suite_create("Volume");
+    tc = tcase_create("volume");
+    tcase_add_test(tc, volume_test);
+    tcase_set_timeout(tc, 120);
+    suite_add_tcase(s, tc);
+
+    sr = srunner_create(s);
+    srunner_run_all(sr, CK_NORMAL);
+    failed = srunner_ntests_failed(sr);
+    srunner_free(sr);
+
+    return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 }
diff --git a/src/utils/pabrowse.c b/src/utils/pabrowse.c
deleted file mode 100644 (file)
index a349e41..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2004-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, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-  USA.
-***/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <assert.h>
-#include <signal.h>
-
-#include <pulse/browser.h>
-#include <pulse/pulseaudio.h>
-#include <pulse/rtclock.h>
-
-#include <pulsecore/core-util.h>
-
-static void exit_signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void *userdata) {
-    fprintf(stderr, "Got signal, exiting\n");
-    m->quit(m, 0);
-}
-
-static void dump_server(const pa_browse_info *i) {
-    char t[16];
-
-    if (i->cookie)
-        snprintf(t, sizeof(t), "0x%08x", *i->cookie);
-
-    printf("server: %s\n"
-           "server-version: %s\n"
-           "user-name: %s\n"
-           "fqdn: %s\n"
-           "cookie: %s\n",
-           i->server,
-           i->server_version ? i->server_version : "n/a",
-           i->user_name ? i->user_name : "n/a",
-           i->fqdn ? i->fqdn : "n/a",
-           i->cookie ? t : "n/a");
-}
-
-static void dump_device(const pa_browse_info *i) {
-    char ss[PA_SAMPLE_SPEC_SNPRINT_MAX];
-
-    if (i->sample_spec)
-        pa_sample_spec_snprint(ss, sizeof(ss), i->sample_spec);
-
-    printf("device: %s\n"
-           "description: %s\n"
-           "sample spec: %s\n",
-           i->device,
-           i->description ? i->description : "n/a",
-           i->sample_spec ? ss : "n/a");
-
-}
-
-static void browser_callback(pa_browser *b, pa_browse_opcode_t c, const pa_browse_info *i, void *userdata) {
-    assert(b && i);
-
-    switch (c) {
-
-        case PA_BROWSE_NEW_SERVER:
-            printf("\n=> new server <%s>\n", i->name);
-            dump_server(i);
-            break;
-
-        case PA_BROWSE_NEW_SINK:
-            printf("\n=> new sink <%s>\n", i->name);
-            dump_server(i);
-            dump_device(i);
-            break;
-
-        case PA_BROWSE_NEW_SOURCE:
-            printf("\n=> new source <%s>\n", i->name);
-            dump_server(i);
-            dump_device(i);
-            break;
-
-        case PA_BROWSE_REMOVE_SERVER:
-            printf("\n=> removed server <%s>\n", i->name);
-            break;
-
-        case PA_BROWSE_REMOVE_SINK:
-            printf("\n=> removed sink <%s>\n", i->name);
-            break;
-
-        case PA_BROWSE_REMOVE_SOURCE:
-            printf("\n=> removed source <%s>\n", i->name);
-            break;
-
-        default:
-            ;
-    }
-}
-
-static void error_callback(pa_browser *b, const char *s, void *userdata) {
-    pa_mainloop_api*m = userdata;
-
-    fprintf(stderr, "Failure: %s\n", s);
-    m->quit(m, 1);
-}
-
-int main(int argc, char *argv[]) {
-    pa_mainloop *mainloop = NULL;
-    pa_browser *browser = NULL;
-    int ret = 1, r;
-    const char *s;
-
-    if (!(mainloop = pa_mainloop_new()))
-        goto finish;
-
-    r = pa_signal_init(pa_mainloop_get_api(mainloop));
-    assert(r == 0);
-    pa_signal_new(SIGINT, exit_signal_callback, NULL);
-    pa_signal_new(SIGTERM, exit_signal_callback, NULL);
-    pa_disable_sigpipe();
-
-    if (!(browser = pa_browser_new_full(pa_mainloop_get_api(mainloop), PA_BROWSE_FOR_SERVERS|PA_BROWSE_FOR_SINKS|PA_BROWSE_FOR_SOURCES, &s))) {
-        fprintf(stderr, "pa_browse_new_full(): %s\n", s);
-        goto finish;
-    }
-
-    pa_browser_set_callback(browser, browser_callback, NULL);
-    pa_browser_set_error_callback(browser, error_callback, pa_mainloop_get_api(mainloop));
-
-    ret = 0;
-    pa_mainloop_run(mainloop, &ret);
-
-finish:
-
-    if (browser)
-        pa_browser_unref(browser);
-
-    if (mainloop) {
-        pa_signal_done();
-        pa_mainloop_free(mainloop);
-    }
-
-    return ret;
-}
index 5f29ba3..aa24bd3 100644 (file)
 
 #include <sndfile.h>
 
-#include <pulse/i18n.h>
 #include <pulse/pulseaudio.h>
 #include <pulse/rtclock.h>
 
-#include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
+#include <pulsecore/i18n.h>
 #include <pulsecore/log.h>
+#include <pulsecore/macro.h>
 #include <pulsecore/sndfile-util.h>
+#include <pulsecore/sample-util.h>
 
 #define TIME_EVENT_USEC 50000
 
@@ -59,6 +60,9 @@ static pa_mainloop_api *mainloop_api = NULL;
 static void *buffer = NULL;
 static size_t buffer_length = 0, buffer_index = 0;
 
+static void *silence_buffer = NULL;
+static size_t silence_buffer_length = 0;
+
 static pa_io_event* stdio_event = NULL;
 
 static pa_proplist *proplist = NULL;
@@ -86,10 +90,13 @@ static sf_count_t (*writef_function)(SNDFILE *_sndfile, const void *ptr, sf_coun
 static pa_stream_flags_t flags = 0;
 
 static size_t latency = 0, process_time = 0;
+static int32_t latency_msec = 0, process_time_msec = 0;
 
 static pa_bool_t raw = TRUE;
 static int file_format = -1;
 
+static uint32_t cork_requests = 0;
+
 /* A shortcut for terminating the application */
 static void quit(int ret) {
     pa_assert(mainloop_api);
@@ -103,6 +110,7 @@ static void context_drain_complete(pa_context*c, void *userdata) {
 
 /* Stream draining complete */
 static void stream_drain_complete(pa_stream*s, int success, void *userdata) {
+    pa_operation *o = NULL;
 
     if (!success) {
         pa_log(_("Failed to drain stream: %s"), pa_strerror(pa_context_errno(context)));
@@ -116,9 +124,10 @@ static void stream_drain_complete(pa_stream*s, int success, void *userdata) {
     pa_stream_unref(stream);
     stream = NULL;
 
-    if (!pa_context_drain(context, context_drain_complete, NULL))
+    if (!(o = pa_context_drain(context, context_drain_complete, NULL)))
         pa_context_disconnect(context);
     else {
+        pa_operation_unref(o);
         if (verbose)
             pa_log(_("Draining connection to server."));
     }
@@ -193,28 +202,41 @@ static void stream_write_callback(pa_stream *s, size_t length, void *userdata) {
 
         pa_assert(sndfile);
 
-        if (pa_stream_begin_write(s, &data, &length) < 0) {
-            pa_log(_("pa_stream_begin_write() failed: %s"), pa_strerror(pa_context_errno(context)));
-            quit(1);
-            return;
-        }
+        for (;;) {
+            size_t data_length = length;
 
-        if (readf_function) {
-            size_t k = pa_frame_size(&sample_spec);
+            if (pa_stream_begin_write(s, &data, &data_length) < 0) {
+                pa_log(_("pa_stream_begin_write() failed: %s"), pa_strerror(pa_context_errno(context)));
+                quit(1);
+                return;
+            }
+
+            if (readf_function) {
+                size_t k = pa_frame_size(&sample_spec);
 
-            if ((bytes = readf_function(sndfile, data, (sf_count_t) (length/k))) > 0)
-                bytes *= (sf_count_t) k;
+                if ((bytes = readf_function(sndfile, data, (sf_count_t) (data_length/k))) > 0)
+                    bytes *= (sf_count_t) k;
 
-        } else
-            bytes = sf_read_raw(sndfile, data, (sf_count_t) length);
+            } else
+                bytes = sf_read_raw(sndfile, data, (sf_count_t) data_length);
 
-        if (bytes > 0)
-            pa_stream_write(s, data, (size_t) bytes, NULL, 0, PA_SEEK_RELATIVE);
-        else
-            pa_stream_cancel_write(s);
+            if (bytes > 0)
+                pa_stream_write(s, data, (size_t) bytes, NULL, 0, PA_SEEK_RELATIVE);
+            else
+                pa_stream_cancel_write(s);
 
-        if (bytes < (sf_count_t) length)
-            start_drain();
+            /* EOF? */
+            if (bytes < (sf_count_t) data_length) {
+                start_drain();
+                break;
+            }
+
+            /* Request fulfilled */
+            if ((size_t) bytes >= length)
+                break;
+
+            length -= bytes;
+        }
     }
 }
 
@@ -239,18 +261,18 @@ static void stream_read_callback(pa_stream *s, size_t length, void *userdata) {
                 return;
             }
 
-            pa_assert(data);
             pa_assert(length > 0);
 
-            if (buffer) {
+            /* If there is a hole in the stream, we generate silence, except
+             * if it's a passthrough stream in which case we skip the hole. */
+            if (data || !(flags & PA_STREAM_PASSTHROUGH)) {
                 buffer = pa_xrealloc(buffer, buffer_length + length);
-                memcpy((uint8_t*) buffer + buffer_length, data, length);
+                if (data)
+                    memcpy((uint8_t *) buffer + buffer_length, data, length);
+                else
+                    pa_silence_memory((uint8_t *) buffer + buffer_length, length, &sample_spec);
+
                 buffer_length += length;
-            } else {
-                buffer = pa_xmalloc(length);
-                memcpy(buffer, data, length);
-                buffer_length = length;
-                buffer_index = 0;
             }
 
             pa_stream_drop(s);
@@ -269,17 +291,27 @@ static void stream_read_callback(pa_stream *s, size_t length, void *userdata) {
                 return;
             }
 
-            pa_assert(data);
             pa_assert(length > 0);
 
+            if (!data && (flags & PA_STREAM_PASSTHROUGH)) {
+                pa_stream_drop(s);
+                continue;
+            }
+
+            if (!data && length > silence_buffer_length) {
+                silence_buffer = pa_xrealloc(silence_buffer, length);
+                pa_silence_memory((uint8_t *) silence_buffer + silence_buffer_length, length - silence_buffer_length, &sample_spec);
+                silence_buffer_length = length;
+            }
+
             if (writef_function) {
                 size_t k = pa_frame_size(&sample_spec);
 
-                if ((bytes = writef_function(sndfile, data, (sf_count_t) (length/k))) > 0)
+                if ((bytes = writef_function(sndfile, data ? data : silence_buffer, (sf_count_t) (length/k))) > 0)
                     bytes *= (sf_count_t) k;
 
             } else
-                bytes = sf_write_raw(sndfile, data, (sf_count_t) length);
+                bytes = sf_write_raw(sndfile, data ? data : silence_buffer, (sf_count_t) length);
 
             if (bytes < (sf_count_t) length)
                 quit(1);
@@ -392,6 +424,24 @@ static void stream_event_callback(pa_stream *s, const char *name, pa_proplist *p
 
     t = pa_proplist_to_string_sep(pl, ", ");
     pa_log("Got event '%s', properties '%s'", name, t);
+
+    if (pa_streq(name, PA_STREAM_EVENT_REQUEST_CORK)) {
+        if (cork_requests == 0) {
+            pa_log(_("Cork request stack is empty: corking stream"));
+            pa_operation_unref(pa_stream_cork(s, 1, NULL, NULL));
+        }
+        cork_requests++;
+    } else if (pa_streq(name, PA_STREAM_EVENT_REQUEST_UNCORK)) {
+        if (cork_requests == 1) {
+            pa_log(_("Cork request stack is empty: uncorking stream"));
+            pa_operation_unref(pa_stream_cork(s, 0, NULL, NULL));
+        }
+        if (cork_requests == 0)
+            pa_log(_("Warning: Received more uncork requests than cork requests!"));
+        else
+            cork_requests--;
+    }
+
     pa_xfree(t);
 }
 
@@ -434,25 +484,31 @@ static void context_state_callback(pa_context *c, void *userdata) {
             buffer_attr.maxlength = (uint32_t) -1;
             buffer_attr.prebuf = (uint32_t) -1;
 
-            if (latency > 0) {
+            if (latency_msec > 0) {
+                buffer_attr.fragsize = buffer_attr.tlength = pa_usec_to_bytes(latency_msec * PA_USEC_PER_MSEC, &sample_spec);
+                flags |= PA_STREAM_ADJUST_LATENCY;
+            } else if (latency > 0) {
                 buffer_attr.fragsize = buffer_attr.tlength = (uint32_t) latency;
-                buffer_attr.minreq = (uint32_t) process_time;
                 flags |= PA_STREAM_ADJUST_LATENCY;
-            } else {
-                buffer_attr.tlength = (uint32_t) -1;
+            } else
+                buffer_attr.fragsize = buffer_attr.tlength = (uint32_t) -1;
+
+            if (process_time_msec > 0) {
+                buffer_attr.minreq = pa_usec_to_bytes(process_time_msec * PA_USEC_PER_MSEC, &sample_spec);
+            } else if (process_time > 0)
+                buffer_attr.minreq = (uint32_t) process_time;
+            else
                 buffer_attr.minreq = (uint32_t) -1;
-                buffer_attr.fragsize = (uint32_t) -1;
-            }
 
             if (mode == PLAYBACK) {
                 pa_cvolume cv;
-                if (pa_stream_connect_playback(stream, device, latency > 0 ? &buffer_attr : NULL, flags, volume_is_set ? pa_cvolume_set(&cv, sample_spec.channels, volume) : NULL, NULL) < 0) {
+                if (pa_stream_connect_playback(stream, device, &buffer_attr, flags, volume_is_set ? pa_cvolume_set(&cv, sample_spec.channels, volume) : NULL, NULL) < 0) {
                     pa_log(_("pa_stream_connect_playback() failed: %s"), pa_strerror(pa_context_errno(c)));
                     goto fail;
                 }
 
             } else {
-                if (pa_stream_connect_record(stream, device, latency > 0 ? &buffer_attr : NULL, flags) < 0) {
+                if (pa_stream_connect_record(stream, device, &buffer_attr, flags) < 0) {
                     pa_log(_("pa_stream_connect_record() failed: %s"), pa_strerror(pa_context_errno(c)));
                     goto fail;
                 }
@@ -497,7 +553,7 @@ static void stdin_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_even
 
     buffer = pa_xmalloc(l);
 
-    if ((r = read(fd, buffer, l)) <= 0) {
+    if ((r = pa_read(fd, buffer, l, userdata)) <= 0) {
         if (r == 0) {
             if (verbose)
                 pa_log(_("Got EOF."));
@@ -536,7 +592,7 @@ static void stdout_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_eve
 
     pa_assert(buffer_length);
 
-    if ((r = write(fd, (uint8_t*) buffer+buffer_index, buffer_length)) <= 0) {
+    if ((r = pa_write(fd, (uint8_t*) buffer+buffer_index, buffer_length, userdata)) <= 0) {
         pa_log(_("write() failed: %s"), strerror(errno));
         quit(1);
 
@@ -555,7 +611,7 @@ static void stdout_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_eve
     }
 }
 
-/* UNIX signal to quit recieved */
+/* UNIX signal to quit received */
 static void exit_signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void *userdata) {
     if (verbose)
         pa_log(_("Got signal, exiting."));
@@ -583,6 +639,7 @@ static void stream_update_timing_callback(pa_stream *s, int success, void *userd
     fprintf(stderr, "        \r");
 }
 
+#ifdef SIGUSR1
 /* Someone requested that the latency is shown */
 static void sigusr1_signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void *userdata) {
 
@@ -591,6 +648,7 @@ static void sigusr1_signal_callback(pa_mainloop_api*m, pa_signal_event *e, int s
 
     pa_operation_unref(pa_stream_update_timing_info(stream, stream_update_timing_callback, NULL));
 }
+#endif
 
 static void time_event_callback(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata) {
     if (stream && pa_stream_get_state(stream) == PA_STREAM_READY) {
@@ -634,9 +692,12 @@ static void help(const char *argv0) {
              "      --no-remap                        Map channels by index instead of name.\n"
              "      --latency=BYTES                   Request the specified latency in bytes.\n"
              "      --process-time=BYTES              Request the specified process time per request in bytes.\n"
+             "      --latency-msec=MSEC               Request the specified latency in msec.\n"
+             "      --process-time-msec=MSEC          Request the specified process time per request in msec.\n"
              "      --property=PROPERTY=VALUE         Set the specified property to the specified value.\n"
              "      --raw                             Record/play raw PCM data.\n"
-             "      --file-format=FFORMAT             Record/play formatted PCM data.\n"
+             "      --passthrough                     passthrough data \n"
+             "      --file-format[=FFORMAT]           Record/play formatted PCM data.\n"
              "      --list-file-formats               List available file formats.\n")
            , argv0);
 }
@@ -657,9 +718,12 @@ enum {
     ARG_LATENCY,
     ARG_PROCESS_TIME,
     ARG_RAW,
+    ARG_PASSTHROUGH,
     ARG_PROPERTY,
     ARG_FILE_FORMAT,
-    ARG_LIST_FILE_FORMATS
+    ARG_LIST_FILE_FORMATS,
+    ARG_LATENCY_MSEC,
+    ARG_PROCESS_TIME_MSEC
 };
 
 int main(int argc, char *argv[]) {
@@ -668,6 +732,8 @@ int main(int argc, char *argv[]) {
     char *bn, *server = NULL;
     pa_time_event *time_event = NULL;
     const char *filename = NULL;
+    /* type for pa_read/_write. passed as userdata to the callbacks */
+    unsigned long type = 0;
 
     static const struct option long_options[] = {
         {"record",       0, NULL, 'r'},
@@ -693,13 +759,18 @@ int main(int argc, char *argv[]) {
         {"process-time", 1, NULL, ARG_PROCESS_TIME},
         {"property",     1, NULL, ARG_PROPERTY},
         {"raw",          0, NULL, ARG_RAW},
+        {"passthrough",  0, NULL, ARG_PASSTHROUGH},
         {"file-format",  2, NULL, ARG_FILE_FORMAT},
         {"list-file-formats", 0, NULL, ARG_LIST_FILE_FORMATS},
+        {"latency-msec", 1, NULL, ARG_LATENCY_MSEC},
+        {"process-time-msec", 1, NULL, ARG_PROCESS_TIME_MSEC},
         {NULL,           0, NULL, 0}
     };
 
     setlocale(LC_ALL, "");
+#ifdef ENABLE_NLS
     bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);
+#endif
 
     bn = pa_path_get_filename(argv[0]);
 
@@ -712,7 +783,7 @@ int main(int argc, char *argv[]) {
     } else if (strstr(bn, "cat")) {
         mode = PLAYBACK;
         raw = TRUE;
-    } if (strstr(bn, "rec") || strstr(bn, "mon")) {
+    } else if (strstr(bn, "rec") || strstr(bn, "mon")) {
         mode = RECORD;
         raw = TRUE;
     }
@@ -854,6 +925,20 @@ int main(int argc, char *argv[]) {
                 }
                 break;
 
+            case ARG_LATENCY_MSEC:
+                if (((latency_msec = (int32_t) atoi(optarg))) <= 0) {
+                    pa_log(_("Invalid latency specification '%s'"), optarg);
+                    goto quit;
+                }
+                break;
+
+            case ARG_PROCESS_TIME_MSEC:
+                if (((process_time_msec = (int32_t) atoi(optarg))) <= 0) {
+                    pa_log(_("Invalid process time specification '%s'"), optarg);
+                    goto quit;
+                }
+                break;
+
             case ARG_PROPERTY: {
                 char *t;
 
@@ -873,9 +958,11 @@ int main(int argc, char *argv[]) {
                 raw = TRUE;
                 break;
 
-            case ARG_FILE_FORMAT:
-                raw = FALSE;
+            case ARG_PASSTHROUGH:
+                flags |= PA_STREAM_PASSTHROUGH;
+                break;
 
+            case ARG_FILE_FORMAT:
                 if (optarg) {
                     if ((file_format = pa_sndfile_format_from_string(optarg)) < 0) {
                         pa_log(_("Unknown file format %s."), optarg);
@@ -906,7 +993,7 @@ int main(int argc, char *argv[]) {
 
         filename = argv[optind];
 
-        if ((fd = open(argv[optind], mode == PLAYBACK ? O_RDONLY : O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0) {
+        if ((fd = pa_open_cloexec(argv[optind], mode == PLAYBACK ? O_RDONLY : O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0) {
             pa_log(_("open(): %s"), strerror(errno));
             goto quit;
         }
@@ -934,13 +1021,19 @@ int main(int argc, char *argv[]) {
                 goto quit;
             }
 
-            /* Transparently upgrade classic .wav to wavex for multichannel audio */
             if (file_format <= 0) {
-                if ((sample_spec.channels == 2 && (!channel_map_set || (channel_map.map[0] == PA_CHANNEL_POSITION_LEFT &&
-                                                                        channel_map.map[1] == PA_CHANNEL_POSITION_RIGHT))) ||
-                    (sample_spec.channels == 1 && (!channel_map_set || (channel_map.map[0] == PA_CHANNEL_POSITION_MONO))))
+                char *extension;
+                if (filename && (extension = strrchr(filename, '.')))
+                    file_format = pa_sndfile_format_from_string(extension+1);
+                if (file_format <= 0)
                     file_format = SF_FORMAT_WAV;
-                else
+                /* Transparently upgrade classic .wav to wavex for multichannel audio */
+                if (file_format == SF_FORMAT_WAV &&
+                    (sample_spec.channels > 2 ||
+                    (channel_map_set &&
+                    !(sample_spec.channels == 1 && channel_map.map[0] == PA_CHANNEL_POSITION_MONO) &&
+                    !(sample_spec.channels == 2 && channel_map.map[0] == PA_CHANNEL_POSITION_LEFT
+                                                && channel_map.map[1] == PA_CHANNEL_POSITION_RIGHT))))
                     file_format = SF_FORMAT_WAVEX;
             }
 
@@ -1028,6 +1121,11 @@ int main(int argc, char *argv[]) {
         if ((t = filename) ||
             (t = pa_proplist_gets(proplist, PA_PROP_APPLICATION_NAME)))
             pa_proplist_sets(proplist, PA_PROP_MEDIA_NAME, t);
+
+        if (!pa_proplist_contains(proplist, PA_PROP_MEDIA_NAME)) {
+            pa_log(_("Failed to set media name."));
+            goto quit;
+        }
     }
 
     /* Set up a new main loop */
@@ -1047,10 +1145,14 @@ int main(int argc, char *argv[]) {
     pa_disable_sigpipe();
 
     if (raw) {
+#ifdef OS_IS_WIN32
+        /* need to turn on binary mode for stdio io. Windows, meh */
+        setmode(mode == PLAYBACK ? STDIN_FILENO : STDOUT_FILENO, O_BINARY);
+#endif
         if (!(stdio_event = mainloop_api->io_new(mainloop_api,
                                                  mode == PLAYBACK ? STDIN_FILENO : STDOUT_FILENO,
                                                  mode == PLAYBACK ? PA_IO_EVENT_INPUT : PA_IO_EVENT_OUTPUT,
-                                                 mode == PLAYBACK ? stdin_callback : stdout_callback, NULL))) {
+                                                 mode == PLAYBACK ? stdin_callback : stdout_callback, &type))) {
             pa_log(_("io_new() failed."));
             goto quit;
         }
@@ -1105,6 +1207,7 @@ quit:
         pa_mainloop_free(m);
     }
 
+    pa_xfree(silence_buffer);
     pa_xfree(buffer);
 
     pa_xfree(server);
index 5ef57e3..dc477aa 100644 (file)
 
 #include <assert.h>
 #include <signal.h>
-#include <sys/poll.h>
 #include <sys/socket.h>
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
 #include <sys/un.h>
+#include <getopt.h>
 #include <locale.h>
 
-#include <pulse/error.h>
 #include <pulse/util.h>
 #include <pulse/xmalloc.h>
-#include <pulse/i18n.h>
 
+#include <pulsecore/i18n.h>
+#include <pulsecore/poll.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/pid.h>
 
-int main(int argc, char*argv[]) {
+static void help(const char *argv0) {
+    printf("%s %s\n",    argv0, "exit");
+    printf("%s %s\n",    argv0, "help");
+    printf("%s %s\n",    argv0, "list-(modules|sinks|sources|clients|cards|samples)");
+    printf("%s %s\n",    argv0, "list-(sink-inputs|source-outputs)");
+    printf("%s %s\n",    argv0, "stat");
+    printf("%s %s\n",    argv0, "info");
+    printf("%s %s %s\n", argv0, "load-module", _("NAME [ARGS ...]"));
+    printf("%s %s %s\n", argv0, "unload-module", _("NAME|#N"));
+    printf("%s %s %s\n", argv0, "describe-module", _("NAME"));
+    printf("%s %s %s\n", argv0, "set-(sink|source)-volume", _("NAME|#N VOLUME"));
+    printf("%s %s %s\n", argv0, "set-(sink-input|source-output)-volume", _("#N VOLUME"));
+    printf("%s %s %s\n", argv0, "set-(sink|source)-mute", _("NAME|#N 1|0"));
+    printf("%s %s %s\n", argv0, "set-(sink-input|source-output)-mute", _("#N 1|0"));
+    printf("%s %s %s\n", argv0, "update-(sink|source)-proplist", _("NAME|#N KEY=VALUE"));
+    printf("%s %s %s\n", argv0, "update-(sink-input|source-output)-proplist", _("#N KEY=VALUE"));
+    printf("%s %s %s\n", argv0, "set-default(sink|source)", _("NAME|#N"));
+    printf("%s %s %s\n", argv0, "kill-(client|sink-input|source-output)", _("#N"));
+    printf("%s %s %s\n", argv0, "play-sample", _("NAME SINK|#N"));
+    printf("%s %s %s\n", argv0, "remove-sample", _("NAME"));
+    printf("%s %s %s\n", argv0, "load-sample", _("NAME FILENAME"));
+    printf("%s %s %s\n", argv0, "load-sample-lazy", _("NAME FILENAME"));
+    printf("%s %s %s\n", argv0, "load-sample-dir-lazy", _("PATHNAME"));
+    printf("%s %s %s\n", argv0, "play-file", _("FILENAME SINK|#N"));
+    printf("%s %s\n",    argv0, "dump");
+    printf("%s %s %s\n", argv0, "move-(sink-input|source-output)", _("#N SINK|SOURCE"));
+    printf("%s %s %s\n", argv0, "suspend-(sink|source)", _("NAME|#N 1|0"));
+    printf("%s %s %s\n", argv0, "suspend", _("1|0"));
+    printf("%s %s %s\n", argv0, "set-card-profile", _("CARD PROFILE"));
+    printf("%s %s %s\n", argv0, "set-(sink|source)-port", _("NAME|#N PORT"));
+    printf("%s %s %s\n", argv0, "set-port-latency-offset", _("CARD-NAME|CARD-#N PORT OFFSET"));
+    printf("%s %s %s\n", argv0, "set-log-target", _("TARGET"));
+    printf("%s %s %s\n", argv0, "set-log-level", _("NUMERIC LEVEL"));
+    printf("%s %s %s\n", argv0, "set-log-meta", _("1|0"));
+    printf("%s %s %s\n", argv0, "set-log-time", _("1|0"));
+    printf("%s %s %s\n", argv0, "set-log-backtrace", _("FRAMES"));
+
+    printf(_("\n"
+         "  -h, --help                            Show this help\n"
+         "      --version                         Show version\n"
+         "When no command is given pacmd starts in the interactive mode\n" ));
+}
 
-    enum {
-        WATCH_STDIN,
-        WATCH_STDOUT,
-        WATCH_SOCKET,
-        N_WATCH
-    };
+enum {
+    ARG_VERSION = 256
+};
 
-    pid_t pid ;
+int main(int argc, char*argv[]) {
+    pid_t pid;
     int fd = -1;
     int ret = 1, i;
     struct sockaddr_un sa;
-    char ibuf[PIPE_BUF], obuf[PIPE_BUF];
-    size_t ibuf_index, ibuf_length, obuf_index, obuf_length;
+    char *ibuf = NULL;
+    char *obuf = NULL;
+    size_t buf_size, ibuf_size, ibuf_index, ibuf_length, obuf_size, obuf_index, obuf_length;
     char *cli;
     pa_bool_t ibuf_eof, obuf_eof, ibuf_closed, obuf_closed;
-    struct pollfd pollfd[N_WATCH];
+    struct pollfd pollfd[3];
+    struct pollfd *watch_socket, *watch_stdin, *watch_stdout;
+
+    int stdin_type = 0, stdout_type = 0, fd_type = 0;
+
+    char *bn = NULL;
+    int c;
+
+    static const struct option long_options[] = {
+        {"version",     0, NULL, ARG_VERSION},
+        {"help",        0, NULL, 'h'},
+        {NULL,          0, NULL, 0}
+    };
 
     setlocale(LC_ALL, "");
+#ifdef ENABLE_NLS
     bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);
+#endif
+
+    bn = pa_path_get_filename(argv[0]);
+
+    while ((c = getopt_long(argc, argv, "h", long_options, NULL)) != -1) {
+        switch (c) {
+            case 'h' :
+                help(bn);
+                ret = 0;
+                goto quit;
+            case ARG_VERSION:
+                printf(_("pacmd %s\n"
+                         "Compiled with libpulse %s\n"
+                         "Linked with libpulse %s\n"),
+                       PACKAGE_VERSION,
+                       pa_get_headers_version(),
+                       pa_get_library_version());
+                ret = 0;
+                goto quit;
+            default:
+                goto quit;
+        }
+    }
 
     if (pa_pid_file_check_running(&pid, "pulseaudio") < 0) {
         pa_log(_("No PulseAudio daemon running, or not running as session daemon."));
-        goto fail;
+        goto quit;
     }
 
-    if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
+    if ((fd = pa_socket_cloexec(PF_UNIX, SOCK_STREAM, 0)) < 0) {
         pa_log(_("socket(PF_UNIX, SOCK_STREAM, 0): %s"), strerror(errno));
-        goto fail;
+        goto quit;
     }
 
     pa_zero(sa);
     sa.sun_family = AF_UNIX;
 
     if (!(cli = pa_runtime_path("cli")))
-        goto fail;
+        goto quit;
 
     pa_strlcpy(sa.sun_path, cli, sizeof(sa.sun_path));
     pa_xfree(cli);
@@ -89,15 +165,16 @@ int main(int argc, char*argv[]) {
 
         if ((r = connect(fd, (struct sockaddr*) &sa, sizeof(sa))) < 0 && (errno != ECONNREFUSED && errno != ENOENT)) {
             pa_log(_("connect(): %s"), strerror(errno));
-            goto fail;
+            goto quit;
         }
 
+
         if (r >= 0)
             break;
 
         if (pa_pid_file_kill(SIGUSR2, NULL, "pulseaudio") < 0) {
             pa_log(_("Failed to kill PulseAudio daemon."));
-            goto fail;
+            goto quit;
         }
 
         pa_msleep(300);
@@ -105,9 +182,14 @@ int main(int argc, char*argv[]) {
 
     if (i >= 5) {
         pa_log(_("Daemon not responding."));
-        goto fail;
+        goto quit;
     }
 
+    buf_size = pa_pipe_buf(fd);
+    ibuf_size = PA_MIN(buf_size, pa_pipe_buf(STDIN_FILENO));
+    ibuf = pa_xmalloc(ibuf_size);
+    obuf_size = PA_MIN(buf_size, pa_pipe_buf(STDOUT_FILENO));
+    obuf = pa_xmalloc(obuf_size);
     ibuf_index = ibuf_length = obuf_index = obuf_length = 0;
     ibuf_eof = obuf_eof = ibuf_closed = obuf_closed = FALSE;
 
@@ -115,11 +197,11 @@ int main(int argc, char*argv[]) {
         for (i = 1; i < argc; i++) {
             size_t k;
 
-            k = PA_MIN(sizeof(ibuf) - ibuf_length, strlen(argv[i]));
+            k = PA_MIN(ibuf_size - ibuf_length, strlen(argv[i]));
             memcpy(ibuf + ibuf_length, argv[i], k);
             ibuf_length += k;
 
-            if (ibuf_length < sizeof(ibuf)) {
+            if (ibuf_length < ibuf_size) {
                 ibuf[ibuf_length] = i < argc-1 ? ' ' : '\n';
                 ibuf_length++;
             }
@@ -128,124 +210,146 @@ int main(int argc, char*argv[]) {
         ibuf_eof = TRUE;
     }
 
-    pa_zero(pollfd);
-
-    pollfd[WATCH_STDIN].fd = STDIN_FILENO;
-    pollfd[WATCH_STDOUT].fd = STDOUT_FILENO;
-    pollfd[WATCH_SOCKET].fd = fd;
-
     for (;;) {
+        struct pollfd *p;
+
         if (ibuf_eof &&
             obuf_eof &&
             ibuf_length <= 0 &&
             obuf_length <= 0)
             break;
 
-        pollfd[WATCH_STDIN].events = pollfd[WATCH_STDOUT].events = pollfd[WATCH_SOCKET].events = 0;
+        if (ibuf_length <= 0 && ibuf_eof && !ibuf_closed) {
+            shutdown(fd, SHUT_WR);
+            ibuf_closed = TRUE;
+        }
+
+        if (obuf_length <= 0 && obuf_eof && !obuf_closed) {
+            shutdown(fd, SHUT_RD);
+            obuf_closed = TRUE;
+        }
+
+        pa_zero(pollfd);
 
-        if (obuf_length > 0)
-            pollfd[WATCH_STDOUT].events |= POLLOUT;
-        else if (!obuf_eof)
-            pollfd[WATCH_SOCKET].events |= POLLIN;
+        p = pollfd;
 
-        if (ibuf_length > 0)
-            pollfd[WATCH_SOCKET].events |= POLLOUT;
-        else if (!ibuf_eof)
-            pollfd[WATCH_STDIN].events |= POLLIN;
+        if (ibuf_length > 0 || (!obuf_eof && obuf_length <= 0)) {
+            watch_socket = p++;
+            watch_socket->fd = fd;
+            watch_socket->events =
+                (ibuf_length > 0 ? POLLOUT : 0) |
+                (!obuf_eof && obuf_length <= 0 ? POLLIN : 0);
+        } else
+            watch_socket = NULL;
 
-        if (poll(pollfd, N_WATCH, -1) < 0) {
+        if (!ibuf_eof && ibuf_length <= 0) {
+            watch_stdin = p++;
+            watch_stdin->fd = STDIN_FILENO;
+            watch_stdin->events = POLLIN;
+        } else
+            watch_stdin = NULL;
+
+        if (obuf_length > 0) {
+            watch_stdout = p++;
+            watch_stdout->fd = STDOUT_FILENO;
+            watch_stdout->events = POLLOUT;
+        } else
+            watch_stdout = NULL;
+
+        if (pa_poll(pollfd, p-pollfd, -1) < 0) {
 
             if (errno == EINTR)
                 continue;
 
             pa_log(_("poll(): %s"), strerror(errno));
-            goto fail;
+            goto quit;
         }
 
-        if (pollfd[WATCH_STDIN].revents & POLLIN) {
-            ssize_t r;
-            pa_assert(!ibuf_length);
-
-            if ((r = pa_read(STDIN_FILENO, ibuf, sizeof(ibuf), NULL)) <= 0) {
-                if (r < 0) {
-                    pa_log(_("read(): %s"), strerror(errno));
-                    goto fail;
+        if (watch_stdin) {
+            if (watch_stdin->revents & POLLIN) {
+                ssize_t r;
+                pa_assert(ibuf_length <= 0);
+
+                if ((r = pa_read(STDIN_FILENO, ibuf, ibuf_size, &stdin_type)) <= 0) {
+                    if (r < 0) {
+                        pa_log(_("read(): %s"), strerror(errno));
+                        goto quit;
+                    }
+
+                    ibuf_eof = TRUE;
+                } else {
+                    ibuf_length = (size_t) r;
+                    ibuf_index = 0;
                 }
-
+            } else if (watch_stdin->revents & POLLHUP)
                 ibuf_eof = TRUE;
-            } else {
-                ibuf_length = (size_t) r;
-                ibuf_index = 0;
-            }
         }
 
-        if (pollfd[WATCH_SOCKET].revents & POLLIN) {
-            ssize_t r;
-            pa_assert(!obuf_length);
-
-            if ((r = pa_read(fd, obuf, sizeof(obuf), NULL)) <= 0) {
-                if (r < 0) {
-                    pa_log(_("read(): %s"), strerror(errno));
-                    goto fail;
+        if (watch_socket) {
+            if (watch_socket->revents & POLLIN) {
+                ssize_t r;
+                pa_assert(obuf_length <= 0);
+
+                if ((r = pa_read(fd, obuf, obuf_size, &fd_type)) <= 0) {
+                    if (r < 0) {
+                        pa_log(_("read(): %s"), strerror(errno));
+                        goto quit;
+                    }
+
+                    obuf_eof = TRUE;
+                } else {
+                    obuf_length = (size_t) r;
+                    obuf_index = 0;
                 }
-
+            } else if (watch_socket->revents & POLLHUP)
                 obuf_eof = TRUE;
-            } else {
-                obuf_length = (size_t) r;
-                obuf_index = 0;
-            }
         }
 
-        if (pollfd[WATCH_STDOUT].revents & POLLHUP) {
-            obuf_eof = TRUE;
-            obuf_length = 0;
-        } else if (pollfd[WATCH_STDOUT].revents & POLLOUT) {
-            ssize_t r;
-            pa_assert(obuf_length);
+        if (watch_stdout) {
+            if (watch_stdout->revents & POLLHUP) {
+                obuf_eof = TRUE;
+                obuf_length = 0;
+            } else if (watch_stdout->revents & POLLOUT) {
+                ssize_t r;
+                pa_assert(obuf_length > 0);
+
+                if ((r = pa_write(STDOUT_FILENO, obuf + obuf_index, obuf_length, &stdout_type)) < 0) {
+                    pa_log(_("write(): %s"), strerror(errno));
+                    goto quit;
+                }
 
-            if ((r = pa_write(STDOUT_FILENO, obuf + obuf_index, obuf_length, NULL)) < 0) {
-                pa_log(_("write(): %s"), strerror(errno));
-                goto fail;
+                obuf_length -= (size_t) r;
+                obuf_index += obuf_index;
             }
-
-            obuf_length -= (size_t) r;
-            obuf_index += obuf_index;
         }
 
-        if (pollfd[WATCH_SOCKET].revents & POLLHUP) {
-            ibuf_eof = TRUE;
-            ibuf_length = 0;
-        } if (pollfd[WATCH_SOCKET].revents & POLLOUT) {
-            ssize_t r;
-            pa_assert(ibuf_length);
+        if (watch_socket) {
+            if (watch_socket->revents & POLLHUP) {
+                ibuf_eof = TRUE;
+                ibuf_length = 0;
+            } if (watch_socket->revents & POLLOUT) {
+                ssize_t r;
+                pa_assert(ibuf_length > 0);
+
+                if ((r = pa_write(fd, ibuf + ibuf_index, ibuf_length, &fd_type)) < 0) {
+                    pa_log(_("write(): %s"), strerror(errno));
+                    goto quit;
+                }
 
-            if ((r = pa_write(fd, ibuf + ibuf_index, ibuf_length, NULL)) < 0) {
-                pa_log(_("write(): %s"), strerror(errno));
-                goto fail;
+                ibuf_length -= (size_t) r;
+                ibuf_index += obuf_index;
             }
-
-            ibuf_length -= (size_t) r;
-            ibuf_index += obuf_index;
-        }
-
-        if (ibuf_length <= 0 && ibuf_eof && !ibuf_closed) {
-            pa_close(STDIN_FILENO);
-            shutdown(fd, SHUT_WR);
-            ibuf_closed = TRUE;
-        }
-
-        if (obuf_length <= 0 && obuf_eof && !obuf_closed) {
-            shutdown(fd, SHUT_RD);
-            pa_close(STDOUT_FILENO);
-            obuf_closed = TRUE;
         }
     }
 
     ret = 0;
 
-fail:
+quit:
     if (fd >= 0)
         pa_close(fd);
 
+    pa_xfree(obuf);
+    pa_xfree(ibuf);
+
     return ret;
 }
index 141ab5b..0fb62cb 100644 (file)
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <limits.h>
 #include <getopt.h>
 #include <locale.h>
+#include <ctype.h>
 
 #include <sndfile.h>
 
-#include <pulse/i18n.h>
 #include <pulse/pulseaudio.h>
+#include <pulse/ext-device-restore.h>
 
+#include <pulsecore/i18n.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/log.h>
 #include <pulsecore/sndfile-util.h>
 
-#define BUFSIZE (16*1024)
-
 static pa_context *context = NULL;
 static pa_mainloop_api *mainloop_api = NULL;
 
 static char
+    *list_type = NULL,
     *sample_name = NULL,
     *sink_name = NULL,
     *source_name = NULL,
@@ -57,16 +57,34 @@ static char
     *module_args = NULL,
     *card_name = NULL,
     *profile_name = NULL,
-    *port_name = NULL;
+    *port_name = NULL,
+    *formats = NULL;
 
 static uint32_t
     sink_input_idx = PA_INVALID_INDEX,
-    source_output_idx = PA_INVALID_INDEX;
+    source_output_idx = PA_INVALID_INDEX,
+    sink_idx = PA_INVALID_INDEX;
 
+static pa_bool_t short_list_format = FALSE;
 static uint32_t module_index;
+static int32_t latency_offset;
 static pa_bool_t suspend;
-static pa_bool_t mute;
 static pa_volume_t volume;
+static enum volume_flags {
+    VOL_UINT     = 0,
+    VOL_PERCENT  = 1,
+    VOL_LINEAR   = 2,
+    VOL_DECIBEL  = 3,
+    VOL_ABSOLUTE = 0 << 4,
+    VOL_RELATIVE = 1 << 4,
+} volume_flags;
+
+static enum mute_flags {
+    INVALID_MUTE = -1,
+    UNMUTE = 0,
+    MUTE = 1,
+    TOGGLE_MUTE = 2
+} mute = INVALID_MUTE;
 
 static pa_proplist *proplist = NULL;
 
@@ -83,6 +101,7 @@ static enum {
     NONE,
     EXIT,
     STAT,
+    INFO,
     UPLOAD_SAMPLE,
     PLAY_SAMPLE,
     REMOVE_SAMPLE,
@@ -95,13 +114,20 @@ static enum {
     SUSPEND_SOURCE,
     SET_CARD_PROFILE,
     SET_SINK_PORT,
+    SET_DEFAULT_SINK,
     SET_SOURCE_PORT,
+    SET_DEFAULT_SOURCE,
     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_SINK_INPUT_MUTE,
+    SET_SOURCE_OUTPUT_MUTE,
+    SET_SINK_FORMATS,
+    SET_PORT_LATENCY_OFFSET,
+    SUBSCRIBE
 } action = NONE;
 
 static void quit(int ret) {
@@ -158,10 +184,23 @@ static void get_server_info_callback(pa_context *c, const pa_server_info *i, voi
         return;
     }
 
+    printf(_("Server String: %s\n"
+             "Library Protocol Version: %u\n"
+             "Server Protocol Version: %u\n"
+             "Is Local: %s\n"
+             "Client Index: %u\n"
+             "Tile Size: %zu\n"),
+             pa_context_get_server(c),
+             pa_context_get_protocol_version(c),
+             pa_context_get_server_protocol_version(c),
+             pa_yes_no(pa_context_is_local(c)),
+             pa_context_get_index(c),
+             pa_context_get_tile_size(c, NULL));
+
     pa_sample_spec_snprint(ss, sizeof(ss), &i->sample_spec);
     pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map);
 
-    printf(_("User name: %s\n"
+    printf(_("User Name: %s\n"
              "Host Name: %s\n"
              "Server Name: %s\n"
              "Server Version: %s\n"
@@ -169,7 +208,7 @@ static void get_server_info_callback(pa_context *c, const pa_server_info *i, voi
              "Default Channel Map: %s\n"
              "Default Sink: %s\n"
              "Default Source: %s\n"
-             "Cookie: %08x\n"),
+             "Cookie: %04x:%04x\n"),
            i->user_name,
            i->host_name,
            i->server_name,
@@ -178,11 +217,21 @@ static void get_server_info_callback(pa_context *c, const pa_server_info *i, voi
            cm,
            i->default_sink_name,
            i->default_source_name,
-           i->cookie);
+           i->cookie >> 16,
+           i->cookie & 0xFFFFU);
 
     complete_action();
 }
 
+static const char* get_available_str_ynonly(int available)
+{
+    switch (available) {
+        case PA_PORT_AVAILABLE_YES: return ", available";
+        case PA_PORT_AVAILABLE_NO: return ", not available";
+    }
+    return "";
+}
+
 static void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_last, void *userdata) {
 
     static const char *state_table[] = {
@@ -198,7 +247,8 @@ static void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_
         cvdb[PA_SW_CVOLUME_SNPRINT_DB_MAX],
         v[PA_VOLUME_SNPRINT_MAX],
         vdb[PA_SW_VOLUME_SNPRINT_DB_MAX],
-        cm[PA_CHANNEL_MAP_SNPRINT_MAX];
+        cm[PA_CHANNEL_MAP_SNPRINT_MAX],
+        f[PA_FORMAT_INFO_SNPRINT_MAX];
     char *pl;
 
     if (is_last < 0) {
@@ -214,10 +264,20 @@ static void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_
 
     pa_assert(i);
 
-    if (nl)
+    if (nl && !short_list_format)
         printf("\n");
     nl = TRUE;
 
+    if (short_list_format) {
+        printf("%u\t%s\t%s\t%s\t%s\n",
+               i->index,
+               i->name,
+               pa_strnull(i->driver),
+               pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec),
+               state_table[1+i->state]);
+        return;
+    }
+
     printf(_("Sink #%u\n"
              "\tState: %s\n"
              "\tName: %s\n"
@@ -232,7 +292,7 @@ static void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_
              "\tBase Volume: %s%s%s\n"
              "\tMonitor Source: %s\n"
              "\tLatency: %0.0f usec, configured %0.0f usec\n"
-             "\tFlags: %s%s%s%s%s%s\n"
+             "\tFlags: %s%s%s%s%s%s%s\n"
              "\tProperties:\n\t\t%s\n"),
            i->index,
            state_table[1+i->state],
@@ -258,6 +318,7 @@ static void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_
            i->flags & PA_SINK_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "",
            i->flags & PA_SINK_DECIBEL_VOLUME ? "DECIBEL_VOLUME " : "",
            i->flags & PA_SINK_LATENCY ? "LATENCY " : "",
+           i->flags & PA_SINK_SET_FORMATS ? "SET_FORMATS " : "",
            pl = pa_proplist_to_string_sep(i->proplist, "\n\t\t"));
 
     pa_xfree(pl);
@@ -267,12 +328,21 @@ static void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_
 
         printf(_("\tPorts:\n"));
         for (p = i->ports; *p; p++)
-            printf("\t\t%s: %s (priority. %u)\n", (*p)->name, (*p)->description, (*p)->priority);
+            printf("\t\t%s: %s (priority: %u%s)\n", (*p)->name, (*p)->description,
+                    (*p)->priority, get_available_str_ynonly((*p)->available));
     }
 
     if (i->active_port)
         printf(_("\tActive Port: %s\n"),
                i->active_port->name);
+
+    if (i->formats) {
+        uint8_t j;
+
+        printf(_("\tFormats:\n"));
+        for (j = 0; j < i->n_formats; j++)
+            printf("\t\t%s\n", pa_format_info_snprint(f, sizeof(f), i->formats[j]));
+    }
 }
 
 static void get_source_info_callback(pa_context *c, const pa_source_info *i, int is_last, void *userdata) {
@@ -290,7 +360,8 @@ static void get_source_info_callback(pa_context *c, const pa_source_info *i, int
         cvdb[PA_SW_CVOLUME_SNPRINT_DB_MAX],
         v[PA_VOLUME_SNPRINT_MAX],
         vdb[PA_SW_VOLUME_SNPRINT_DB_MAX],
-        cm[PA_CHANNEL_MAP_SNPRINT_MAX];
+        cm[PA_CHANNEL_MAP_SNPRINT_MAX],
+        f[PA_FORMAT_INFO_SNPRINT_MAX];
     char *pl;
 
     if (is_last < 0) {
@@ -306,10 +377,20 @@ static void get_source_info_callback(pa_context *c, const pa_source_info *i, int
 
     pa_assert(i);
 
-    if (nl)
+    if (nl && !short_list_format)
         printf("\n");
     nl = TRUE;
 
+    if (short_list_format) {
+        printf("%u\t%s\t%s\t%s\t%s\n",
+               i->index,
+               i->name,
+               pa_strnull(i->driver),
+               pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec),
+               state_table[1+i->state]);
+        return;
+    }
+
     printf(_("Source #%u\n"
              "\tState: %s\n"
              "\tName: %s\n"
@@ -359,12 +440,21 @@ static void get_source_info_callback(pa_context *c, const pa_source_info *i, int
 
         printf(_("\tPorts:\n"));
         for (p = i->ports; *p; p++)
-            printf("\t\t%s: %s (priority. %u)\n", (*p)->name, (*p)->description, (*p)->priority);
+            printf("\t\t%s: %s (priority: %u%s)\n", (*p)->name, (*p)->description,
+                    (*p)->priority, get_available_str_ynonly((*p)->available));
     }
 
     if (i->active_port)
         printf(_("\tActive Port: %s\n"),
                i->active_port->name);
+
+    if (i->formats) {
+        uint8_t j;
+
+        printf(_("\tFormats:\n"));
+        for (j = 0; j < i->n_formats; j++)
+            printf("\t\t%s\n", pa_format_info_snprint(f, sizeof(f), i->formats[j]));
+    }
 }
 
 static void get_module_info_callback(pa_context *c, const pa_module_info *i, int is_last, void *userdata) {
@@ -384,12 +474,17 @@ static void get_module_info_callback(pa_context *c, const pa_module_info *i, int
 
     pa_assert(i);
 
-    if (nl)
+    if (nl && !short_list_format)
         printf("\n");
     nl = TRUE;
 
     pa_snprintf(t, sizeof(t), "%u", i->n_used);
 
+    if (short_list_format) {
+        printf("%u\t%s\t%s\t\n", i->index, i->name, i->argument ? i->argument : "");
+        return;
+    }
+
     printf(_("Module #%u\n"
              "\tName: %s\n"
              "\tArgument: %s\n"
@@ -421,12 +516,20 @@ static void get_client_info_callback(pa_context *c, const pa_client_info *i, int
 
     pa_assert(i);
 
-    if (nl)
+    if (nl && !short_list_format)
         printf("\n");
     nl = TRUE;
 
     pa_snprintf(t, sizeof(t), "%u", i->owner_module);
 
+    if (short_list_format) {
+        printf("%u\t%s\t%s\n",
+               i->index,
+               pa_strnull(i->driver),
+               pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_PROCESS_BINARY)));
+        return;
+    }
+
     printf(_("Client #%u\n"
              "\tDriver: %s\n"
              "\tOwner Module: %s\n"
@@ -456,12 +559,17 @@ static void get_card_info_callback(pa_context *c, const pa_card_info *i, int is_
 
     pa_assert(i);
 
-    if (nl)
+    if (nl && !short_list_format)
         printf("\n");
     nl = TRUE;
 
     pa_snprintf(t, sizeof(t), "%u", i->owner_module);
 
+    if (short_list_format) {
+        printf("%u\t%s\t%s\n", i->index, i->name, pa_strnull(i->driver));
+        return;
+    }
+
     printf(_("Card #%u\n"
              "\tName: %s\n"
              "\tDriver: %s\n"
@@ -473,6 +581,8 @@ static void get_card_info_callback(pa_context *c, const pa_card_info *i, int is_
            i->owner_module != PA_INVALID_INDEX ? t : _("n/a"),
            pl = pa_proplist_to_string_sep(i->proplist, "\n\t\t"));
 
+    pa_xfree(pl);
+
     if (i->profiles) {
         pa_card_profile_info *p;
 
@@ -485,11 +595,36 @@ static void get_card_info_callback(pa_context *c, const pa_card_info *i, int is_
         printf(_("\tActive Profile: %s\n"),
                i->active_profile->name);
 
-    pa_xfree(pl);
+    if (i->ports) {
+        pa_card_port_info **p;
+
+        printf(_("\tPorts:\n"));
+        for (p = i->ports; *p; p++) {
+            pa_card_profile_info **pr = (*p)->profiles;
+            printf("\t\t%s: %s (priority: %u, latency offset: %" PRId64 " usec%s)\n", (*p)->name,
+                (*p)->description, (*p)->priority, (*p)->latency_offset,
+                get_available_str_ynonly((*p)->available));
+
+            if (!pa_proplist_isempty((*p)->proplist)) {
+                printf(_("\t\t\tProperties:\n\t\t\t\t%s\n"), pl = pa_proplist_to_string_sep((*p)->proplist, "\n\t\t\t\t"));
+                pa_xfree(pl);
+            }
+
+            if (pr) {
+                printf(_("\t\t\tPart of profile(s): %s"), pa_strnull((*pr)->name));
+                pr++;
+                while (*pr) {
+                    printf(", %s", pa_strnull((*pr)->name));
+                    pr++;
+                }
+                printf("\n");
+            }
+        }
+    }
 }
 
 static void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info *i, int is_last, void *userdata) {
-    char t[32], k[32], s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cvdb[PA_SW_CVOLUME_SNPRINT_DB_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
+    char t[32], k[32], s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cvdb[PA_SW_CVOLUME_SNPRINT_DB_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX], f[PA_FORMAT_INFO_SNPRINT_MAX];
     char *pl;
 
     if (is_last < 0) {
@@ -505,13 +640,23 @@ static void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info
 
     pa_assert(i);
 
-    if (nl)
+    if (nl && !short_list_format)
         printf("\n");
     nl = TRUE;
 
     pa_snprintf(t, sizeof(t), "%u", i->owner_module);
     pa_snprintf(k, sizeof(k), "%u", i->client);
 
+    if (short_list_format) {
+        printf("%u\t%u\t%s\t%s\t%s\n",
+               i->index,
+               i->sink,
+               i->client != PA_INVALID_INDEX ? k : "-",
+               pa_strnull(i->driver),
+               pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec));
+        return;
+    }
+
     printf(_("Sink Input #%u\n"
              "\tDriver: %s\n"
              "\tOwner Module: %s\n"
@@ -519,6 +664,8 @@ static void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info
              "\tSink: %u\n"
              "\tSample Specification: %s\n"
              "\tChannel Map: %s\n"
+             "\tFormat: %s\n"
+             "\tCorked: %s\n"
              "\tMute: %s\n"
              "\tVolume: %s\n"
              "\t        %s\n"
@@ -534,6 +681,8 @@ static void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info
            i->sink,
            pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec),
            pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
+           pa_format_info_snprint(f, sizeof(f), i->format),
+           pa_yes_no(i->corked),
            pa_yes_no(i->mute),
            pa_cvolume_snprint(cv, sizeof(cv), &i->volume),
            pa_sw_cvolume_snprint_dB(cvdb, sizeof(cvdb), &i->volume),
@@ -547,7 +696,7 @@ static void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info
 }
 
 static void get_source_output_info_callback(pa_context *c, const pa_source_output_info *i, int is_last, void *userdata) {
-    char t[32], k[32], s[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
+    char t[32], k[32], s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cvdb[PA_SW_CVOLUME_SNPRINT_DB_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX], f[PA_FORMAT_INFO_SNPRINT_MAX];
     char *pl;
 
     if (is_last < 0) {
@@ -563,7 +712,7 @@ static void get_source_output_info_callback(pa_context *c, const pa_source_outpu
 
     pa_assert(i);
 
-    if (nl)
+    if (nl && !short_list_format)
         printf("\n");
     nl = TRUE;
 
@@ -571,6 +720,16 @@ static void get_source_output_info_callback(pa_context *c, const pa_source_outpu
     pa_snprintf(t, sizeof(t), "%u", i->owner_module);
     pa_snprintf(k, sizeof(k), "%u", i->client);
 
+    if (short_list_format) {
+        printf("%u\t%u\t%s\t%s\t%s\n",
+               i->index,
+               i->source,
+               i->client != PA_INVALID_INDEX ? k : "-",
+               pa_strnull(i->driver),
+               pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec));
+        return;
+    }
+
     printf(_("Source Output #%u\n"
              "\tDriver: %s\n"
              "\tOwner Module: %s\n"
@@ -578,6 +737,12 @@ static void get_source_output_info_callback(pa_context *c, const pa_source_outpu
              "\tSource: %u\n"
              "\tSample Specification: %s\n"
              "\tChannel Map: %s\n"
+             "\tFormat: %s\n"
+             "\tCorked: %s\n"
+             "\tMute: %s\n"
+             "\tVolume: %s\n"
+             "\t        %s\n"
+             "\t        balance %0.2f\n"
              "\tBuffer Latency: %0.0f usec\n"
              "\tSource Latency: %0.0f usec\n"
              "\tResample method: %s\n"
@@ -589,6 +754,12 @@ static void get_source_output_info_callback(pa_context *c, const pa_source_outpu
            i->source,
            pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec),
            pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
+           pa_format_info_snprint(f, sizeof(f), i->format),
+           pa_yes_no(i->corked),
+           pa_yes_no(i->mute),
+           pa_cvolume_snprint(cv, sizeof(cv), &i->volume),
+           pa_sw_cvolume_snprint_dB(cvdb, sizeof(cvdb), &i->volume),
+           pa_cvolume_get_balance(&i->volume, &i->channel_map),
            (double) i->buffer_usec,
            (double) i->source_usec,
            i->resample_method ? i->resample_method : _("n/a"),
@@ -614,12 +785,21 @@ static void get_sample_info_callback(pa_context *c, const pa_sample_info *i, int
 
     pa_assert(i);
 
-    if (nl)
+    if (nl && !short_list_format)
         printf("\n");
     nl = TRUE;
 
     pa_bytes_snprint(t, sizeof(t), i->bytes);
 
+    if (short_list_format) {
+        printf("%u\t%s\t%s\t%0.3f\n",
+               i->index,
+               i->name,
+               pa_sample_spec_valid(&i->sample_spec) ? pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec) : "-",
+               (double) i->duration/1000000.0);
+        return;
+    }
+
     printf(_("Sample #%u\n"
              "\tName: %s\n"
              "\tSample Specification: %s\n"
@@ -670,6 +850,220 @@ static void index_callback(pa_context *c, uint32_t idx, void *userdata) {
     complete_action();
 }
 
+static void volume_relative_adjust(pa_cvolume *cv) {
+    pa_assert((volume_flags & VOL_RELATIVE) == VOL_RELATIVE);
+
+    /* Relative volume change is additive in case of UINT or PERCENT
+     * and multiplicative for LINEAR or DECIBEL */
+    if ((volume_flags & 0x0F) == VOL_UINT || (volume_flags & 0x0F) == VOL_PERCENT) {
+        pa_volume_t v = pa_cvolume_avg(cv);
+        v = v + volume < PA_VOLUME_NORM ? PA_VOLUME_MUTED : v + volume - PA_VOLUME_NORM;
+        pa_cvolume_set(cv, 1, v);
+    }
+    if ((volume_flags & 0x0F) == VOL_LINEAR || (volume_flags & 0x0F) == VOL_DECIBEL) {
+        pa_sw_cvolume_multiply_scalar(cv, cv, volume);
+    }
+}
+
+static void unload_module_by_name_callback(pa_context *c, const pa_module_info *i, int is_last, void *userdata) {
+    static pa_bool_t unloaded = FALSE;
+
+    if (is_last < 0) {
+        pa_log(_("Failed to get module information: %s"), pa_strerror(pa_context_errno(c)));
+        quit(1);
+        return;
+    }
+
+    if (is_last) {
+        if (unloaded == FALSE)
+            pa_log(_("Failed to unload module: Module %s not loaded"), module_name);
+        complete_action();
+        return;
+    }
+
+    pa_assert(i);
+
+    if (pa_streq(module_name, i->name)) {
+        unloaded = TRUE;
+        actions++;
+        pa_operation_unref(pa_context_unload_module(c, i->index, simple_callback, NULL));
+    }
+}
+
+static void get_sink_volume_callback(pa_context *c, const pa_sink_info *i, int is_last, void *userdata) {
+    pa_cvolume cv;
+
+    if (is_last < 0) {
+        pa_log(_("Failed to get sink information: %s"), pa_strerror(pa_context_errno(c)));
+        quit(1);
+        return;
+    }
+
+    if (is_last)
+        return;
+
+    pa_assert(i);
+
+    cv = i->volume;
+    volume_relative_adjust(&cv);
+    pa_operation_unref(pa_context_set_sink_volume_by_name(c, sink_name, &cv, simple_callback, NULL));
+}
+
+static void get_source_volume_callback(pa_context *c, const pa_source_info *i, int is_last, void *userdata) {
+    pa_cvolume cv;
+
+    if (is_last < 0) {
+        pa_log(_("Failed to get source information: %s"), pa_strerror(pa_context_errno(c)));
+        quit(1);
+        return;
+    }
+
+    if (is_last)
+        return;
+
+    pa_assert(i);
+
+    cv = i->volume;
+    volume_relative_adjust(&cv);
+    pa_operation_unref(pa_context_set_source_volume_by_name(c, source_name, &cv, simple_callback, NULL));
+}
+
+static void get_sink_input_volume_callback(pa_context *c, const pa_sink_input_info *i, int is_last, void *userdata) {
+    pa_cvolume cv;
+
+    if (is_last < 0) {
+        pa_log(_("Failed to get sink input information: %s"), pa_strerror(pa_context_errno(c)));
+        quit(1);
+        return;
+    }
+
+    if (is_last)
+        return;
+
+    pa_assert(i);
+
+    cv = i->volume;
+    volume_relative_adjust(&cv);
+    pa_operation_unref(pa_context_set_sink_input_volume(c, sink_input_idx, &cv, simple_callback, NULL));
+}
+
+static void get_source_output_volume_callback(pa_context *c, const pa_source_output_info *o, int is_last, void *userdata) {
+    pa_cvolume cv;
+
+    if (is_last < 0) {
+        pa_log(_("Failed to get source output information: %s"), pa_strerror(pa_context_errno(c)));
+        quit(1);
+        return;
+    }
+
+    if (is_last)
+        return;
+
+    pa_assert(o);
+
+    cv = o->volume;
+    volume_relative_adjust(&cv);
+    pa_operation_unref(pa_context_set_source_output_volume(c, source_output_idx, &cv, simple_callback, NULL));
+}
+
+static void sink_toggle_mute_callback(pa_context *c, const pa_sink_info *i, int is_last, void *userdata) {
+    if (is_last < 0) {
+        pa_log(_("Failed to get sink information: %s"), pa_strerror(pa_context_errno(c)));
+        quit(1);
+        return;
+    }
+
+    if (is_last)
+        return;
+
+    pa_assert(i);
+
+    pa_operation_unref(pa_context_set_sink_mute_by_name(c, i->name, !i->mute, simple_callback, NULL));
+}
+
+static void source_toggle_mute_callback(pa_context *c, const pa_source_info *o, int is_last, void *userdata) {
+    if (is_last < 0) {
+        pa_log(_("Failed to get source information: %s"), pa_strerror(pa_context_errno(c)));
+        quit(1);
+        return;
+    }
+
+    if (is_last)
+        return;
+
+    pa_assert(o);
+
+    pa_operation_unref(pa_context_set_source_mute_by_name(c, o->name, !o->mute, simple_callback, NULL));
+}
+
+static void sink_input_toggle_mute_callback(pa_context *c, const pa_sink_input_info *i, int is_last, void *userdata) {
+    if (is_last < 0) {
+        pa_log(_("Failed to get sink input information: %s"), pa_strerror(pa_context_errno(c)));
+        quit(1);
+        return;
+    }
+
+    if (is_last)
+        return;
+
+    pa_assert(i);
+
+    pa_operation_unref(pa_context_set_sink_input_mute(c, i->index, !i->mute, simple_callback, NULL));
+}
+
+static void source_output_toggle_mute_callback(pa_context *c, const pa_source_output_info *o, int is_last, void *userdata) {
+    if (is_last < 0) {
+        pa_log(_("Failed to get source output information: %s"), pa_strerror(pa_context_errno(c)));
+        quit(1);
+        return;
+    }
+
+    if (is_last)
+        return;
+
+    pa_assert(o);
+
+    pa_operation_unref(pa_context_set_source_output_mute(c, o->index, !o->mute, simple_callback, NULL));
+}
+
+/* PA_MAX_FORMATS is defined in internal.h so we just define a sane value here */
+#define MAX_FORMATS 256
+
+static void set_sink_formats(pa_context *c, uint32_t sink, const char *str) {
+    pa_format_info *f_arr[MAX_FORMATS];
+    char *format = NULL;
+    const char *state = NULL;
+    int i = 0;
+
+    while ((format = pa_split(str, ";", &state))) {
+        pa_format_info *f = pa_format_info_from_string(pa_strip(format));
+
+        if (!f) {
+            pa_log(_("Failed to set format: invalid format string %s"), format);
+            goto error;
+        }
+
+        f_arr[i++] = f;
+        pa_xfree(format);
+    }
+
+    pa_operation_unref(pa_ext_device_restore_save_formats(c, PA_DEVICE_TYPE_SINK, sink, i, f_arr, simple_callback, NULL));
+
+done:
+    if (format)
+        pa_xfree(format);
+    while(i--)
+        pa_format_info_free(f_arr[i]);
+
+    return;
+
+error:
+    while(i--)
+        pa_format_info_free(f_arr[i]);
+    quit(1);
+    goto done;
+}
+
 static void stream_state_callback(pa_stream *s, void *userdata) {
     pa_assert(s);
 
@@ -710,12 +1104,73 @@ static void stream_write_callback(pa_stream *s, size_t length, void *userdata) {
 
     sample_length -= length;
 
-    if (sample_length  <= 0) {
+    if (sample_length <= 0) {
         pa_stream_set_write_callback(sample_stream, NULL, NULL);
         pa_stream_finish_upload(sample_stream);
     }
 }
 
+static const char *subscription_event_type_to_string(pa_subscription_event_type_t t) {
+
+    switch (t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) {
+
+    case PA_SUBSCRIPTION_EVENT_NEW:
+        return _("new");
+
+    case PA_SUBSCRIPTION_EVENT_CHANGE:
+        return _("change");
+
+    case PA_SUBSCRIPTION_EVENT_REMOVE:
+        return _("remove");
+    }
+
+    return _("unknown");
+}
+
+static const char *subscription_event_facility_to_string(pa_subscription_event_type_t t) {
+
+    switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) {
+
+    case PA_SUBSCRIPTION_EVENT_SINK:
+        return _("sink");
+
+    case PA_SUBSCRIPTION_EVENT_SOURCE:
+        return _("source");
+
+    case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
+        return _("sink-input");
+
+    case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT:
+        return _("source-output");
+
+    case PA_SUBSCRIPTION_EVENT_MODULE:
+        return _("module");
+
+    case PA_SUBSCRIPTION_EVENT_CLIENT:
+        return _("client");
+
+    case PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE:
+        return _("sample-cache");
+
+    case PA_SUBSCRIPTION_EVENT_SERVER:
+        return _("server");
+
+    case PA_SUBSCRIPTION_EVENT_CARD:
+        return _("server");
+    }
+
+    return _("unknown");
+}
+
+static void context_subscribe_callback(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
+    pa_assert(c);
+
+    printf(_("Event '%s' on %s #%u\n"),
+           subscription_event_type_to_string(t),
+           subscription_event_facility_to_string(t),
+           idx);
+}
+
 static void context_state_callback(pa_context *c, void *userdata) {
     pa_assert(c);
     switch (pa_context_get_state(c)) {
@@ -727,8 +1182,12 @@ static void context_state_callback(pa_context *c, void *userdata) {
         case PA_CONTEXT_READY:
             switch (action) {
                 case STAT:
-                    actions = 2;
                     pa_operation_unref(pa_context_stat(c, stat_callback, NULL));
+                    if (short_list_format)
+                        break;
+                    actions++;
+
+                case INFO:
                     pa_operation_unref(pa_context_get_server_info(c, get_server_info_callback, NULL));
                     break;
 
@@ -754,15 +1213,36 @@ static void context_state_callback(pa_context *c, void *userdata) {
                     break;
 
                 case LIST:
-                    actions = 8;
-                    pa_operation_unref(pa_context_get_module_info_list(c, get_module_info_callback, NULL));
-                    pa_operation_unref(pa_context_get_sink_info_list(c, get_sink_info_callback, NULL));
-                    pa_operation_unref(pa_context_get_source_info_list(c, get_source_info_callback, NULL));
-                    pa_operation_unref(pa_context_get_sink_input_info_list(c, get_sink_input_info_callback, NULL));
-                    pa_operation_unref(pa_context_get_source_output_info_list(c, get_source_output_info_callback, NULL));
-                    pa_operation_unref(pa_context_get_client_info_list(c, get_client_info_callback, NULL));
-                    pa_operation_unref(pa_context_get_sample_info_list(c, get_sample_info_callback, NULL));
-                    pa_operation_unref(pa_context_get_card_info_list(c, get_card_info_callback, NULL));
+                    if (list_type) {
+                        if (pa_streq(list_type, "modules"))
+                            pa_operation_unref(pa_context_get_module_info_list(c, get_module_info_callback, NULL));
+                        else if (pa_streq(list_type, "sinks"))
+                            pa_operation_unref(pa_context_get_sink_info_list(c, get_sink_info_callback, NULL));
+                        else if (pa_streq(list_type, "sources"))
+                            pa_operation_unref(pa_context_get_source_info_list(c, get_source_info_callback, NULL));
+                        else if (pa_streq(list_type, "sink-inputs"))
+                            pa_operation_unref(pa_context_get_sink_input_info_list(c, get_sink_input_info_callback, NULL));
+                        else if (pa_streq(list_type, "source-outputs"))
+                            pa_operation_unref(pa_context_get_source_output_info_list(c, get_source_output_info_callback, NULL));
+                        else if (pa_streq(list_type, "clients"))
+                            pa_operation_unref(pa_context_get_client_info_list(c, get_client_info_callback, NULL));
+                        else if (pa_streq(list_type, "samples"))
+                            pa_operation_unref(pa_context_get_sample_info_list(c, get_sample_info_callback, NULL));
+                        else if (pa_streq(list_type, "cards"))
+                            pa_operation_unref(pa_context_get_card_info_list(c, get_card_info_callback, NULL));
+                        else
+                            pa_assert_not_reached();
+                    } else {
+                        actions = 8;
+                        pa_operation_unref(pa_context_get_module_info_list(c, get_module_info_callback, NULL));
+                        pa_operation_unref(pa_context_get_sink_info_list(c, get_sink_info_callback, NULL));
+                        pa_operation_unref(pa_context_get_source_info_list(c, get_source_info_callback, NULL));
+                        pa_operation_unref(pa_context_get_sink_input_info_list(c, get_sink_input_info_callback, NULL));
+                        pa_operation_unref(pa_context_get_source_output_info_list(c, get_source_output_info_callback, NULL));
+                        pa_operation_unref(pa_context_get_client_info_list(c, get_client_info_callback, NULL));
+                        pa_operation_unref(pa_context_get_sample_info_list(c, get_sample_info_callback, NULL));
+                        pa_operation_unref(pa_context_get_card_info_list(c, get_card_info_callback, NULL));
+                    }
                     break;
 
                 case MOVE_SINK_INPUT:
@@ -778,7 +1258,10 @@ static void context_state_callback(pa_context *c, void *userdata) {
                     break;
 
                 case UNLOAD_MODULE:
-                    pa_operation_unref(pa_context_unload_module(c, module_index, simple_callback, NULL));
+                    if (module_name)
+                        pa_operation_unref(pa_context_get_module_info_list(c, unload_module_by_name_callback, NULL));
+                    else
+                        pa_operation_unref(pa_context_unload_module(c, module_index, simple_callback, NULL));
                     break;
 
                 case SUSPEND_SINK:
@@ -803,45 +1286,111 @@ static void context_state_callback(pa_context *c, void *userdata) {
                     pa_operation_unref(pa_context_set_sink_port_by_name(c, sink_name, port_name, simple_callback, NULL));
                     break;
 
+                case SET_DEFAULT_SINK:
+                    pa_operation_unref(pa_context_set_default_sink(c, sink_name, simple_callback, NULL));
+                    break;
+
                 case SET_SOURCE_PORT:
                     pa_operation_unref(pa_context_set_source_port_by_name(c, source_name, port_name, simple_callback, NULL));
                     break;
 
+                case SET_DEFAULT_SOURCE:
+                    pa_operation_unref(pa_context_set_default_source(c, source_name, simple_callback, NULL));
+                    break;
+
                 case SET_SINK_MUTE:
-                    pa_operation_unref(pa_context_set_sink_mute_by_name(c, sink_name, mute, simple_callback, NULL));
+                    if (mute == TOGGLE_MUTE)
+                        pa_operation_unref(pa_context_get_sink_info_by_name(c, sink_name, sink_toggle_mute_callback, NULL));
+                    else
+                        pa_operation_unref(pa_context_set_sink_mute_by_name(c, sink_name, mute, simple_callback, NULL));
                     break;
 
                 case SET_SOURCE_MUTE:
-                    pa_operation_unref(pa_context_set_source_mute_by_name(c, source_name, mute, simple_callback, NULL));
+                    if (mute == TOGGLE_MUTE)
+                        pa_operation_unref(pa_context_get_source_info_by_name(c, source_name, source_toggle_mute_callback, NULL));
+                    else
+                        pa_operation_unref(pa_context_set_source_mute_by_name(c, source_name, mute, simple_callback, NULL));
                     break;
 
                 case SET_SINK_INPUT_MUTE:
-                    pa_operation_unref(pa_context_set_sink_input_mute(c, sink_input_idx, mute, simple_callback, NULL));
+                    if (mute == TOGGLE_MUTE)
+                        pa_operation_unref(pa_context_get_sink_input_info(c, sink_input_idx, sink_input_toggle_mute_callback, NULL));
+                    else
+                        pa_operation_unref(pa_context_set_sink_input_mute(c, sink_input_idx, mute, simple_callback, NULL));
                     break;
 
-                case SET_SINK_VOLUME: {
-                    pa_cvolume v;
+                case SET_SOURCE_OUTPUT_MUTE:
+                    if (mute == TOGGLE_MUTE)
+                        pa_operation_unref(pa_context_get_source_output_info(c, source_output_idx, source_output_toggle_mute_callback, NULL));
+                    else
+                        pa_operation_unref(pa_context_set_source_output_mute(c, source_output_idx, mute, simple_callback, NULL));
+                    break;
 
-                    pa_cvolume_set(&v, 1, volume);
-                    pa_operation_unref(pa_context_set_sink_volume_by_name(c, sink_name, &v, simple_callback, NULL));
+                case SET_SINK_VOLUME:
+                    if ((volume_flags & VOL_RELATIVE) == VOL_RELATIVE) {
+                        pa_operation_unref(pa_context_get_sink_info_by_name(c, sink_name, get_sink_volume_callback, NULL));
+                    } else {
+                        pa_cvolume v;
+                        pa_cvolume_set(&v, 1, volume);
+                        pa_operation_unref(pa_context_set_sink_volume_by_name(c, sink_name, &v, simple_callback, NULL));
+                    }
+                    break;
+
+                case SET_SOURCE_VOLUME:
+                    if ((volume_flags & VOL_RELATIVE) == VOL_RELATIVE) {
+                        pa_operation_unref(pa_context_get_source_info_by_name(c, source_name, get_source_volume_callback, NULL));
+                    } else {
+                        pa_cvolume v;
+                        pa_cvolume_set(&v, 1, volume);
+                        pa_operation_unref(pa_context_set_source_volume_by_name(c, source_name, &v, simple_callback, NULL));
+                    }
                     break;
-                }
 
-                case SET_SOURCE_VOLUME: {
-                    pa_cvolume v;
+                case SET_SINK_INPUT_VOLUME:
+                    if ((volume_flags & VOL_RELATIVE) == VOL_RELATIVE) {
+                        pa_operation_unref(pa_context_get_sink_input_info(c, sink_input_idx, get_sink_input_volume_callback, NULL));
+                    } else {
+                        pa_cvolume v;
+                        pa_cvolume_set(&v, 1, volume);
+                        pa_operation_unref(pa_context_set_sink_input_volume(c, sink_input_idx, &v, simple_callback, NULL));
+                    }
+                    break;
 
-                    pa_cvolume_set(&v, 1, volume);
-                    pa_operation_unref(pa_context_set_source_volume_by_name(c, source_name, &v, simple_callback, NULL));
+                case SET_SOURCE_OUTPUT_VOLUME:
+                    if ((volume_flags & VOL_RELATIVE) == VOL_RELATIVE) {
+                        pa_operation_unref(pa_context_get_source_output_info(c, source_output_idx, get_source_output_volume_callback, NULL));
+                    } else {
+                        pa_cvolume v;
+                        pa_cvolume_set(&v, 1, volume);
+                        pa_operation_unref(pa_context_set_source_output_volume(c, source_output_idx, &v, simple_callback, NULL));
+                    }
                     break;
-                }
 
-                case SET_SINK_INPUT_VOLUME: {
-                    pa_cvolume v;
+                case SET_SINK_FORMATS:
+                    set_sink_formats(c, sink_idx, formats);
+                    break;
 
-                    pa_cvolume_set(&v, 1, volume);
-                    pa_operation_unref(pa_context_set_sink_input_volume(c, sink_input_idx, &v, simple_callback, NULL));
+                case SET_PORT_LATENCY_OFFSET:
+                    pa_operation_unref(pa_context_set_port_latency_offset(c, card_name, port_name, latency_offset, simple_callback, NULL));
+                    break;
+
+                case SUBSCRIBE:
+                    pa_context_set_subscribe_callback(c, context_subscribe_callback, NULL);
+
+                    pa_operation_unref(pa_context_subscribe(
+                                              c,
+                                              PA_SUBSCRIPTION_MASK_SINK|
+                                              PA_SUBSCRIPTION_MASK_SOURCE|
+                                              PA_SUBSCRIPTION_MASK_SINK_INPUT|
+                                              PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT|
+                                              PA_SUBSCRIPTION_MASK_MODULE|
+                                              PA_SUBSCRIPTION_MASK_CLIENT|
+                                              PA_SUBSCRIPTION_MASK_SAMPLE_CACHE|
+                                              PA_SUBSCRIPTION_MASK_SERVER|
+                                              PA_SUBSCRIPTION_MASK_CARD,
+                                              NULL,
+                                              NULL));
                     break;
-                }
 
                 default:
                     pa_assert_not_reached();
@@ -864,38 +1413,111 @@ static void exit_signal_callback(pa_mainloop_api *m, pa_signal_event *e, int sig
     quit(0);
 }
 
+static int parse_volume(const char *vol_spec, pa_volume_t *vol, enum volume_flags *vol_flags) {
+    double v;
+    char *vs;
+
+    pa_assert(vol_spec);
+    pa_assert(vol);
+    pa_assert(vol_flags);
+
+    vs = pa_xstrdup(vol_spec);
+
+    *vol_flags = (pa_startswith(vs, "+") || pa_startswith(vs, "-")) ? VOL_RELATIVE : VOL_ABSOLUTE;
+    if (strchr(vs, '.'))
+        *vol_flags |= VOL_LINEAR;
+    if (pa_endswith(vs, "%")) {
+        *vol_flags |= VOL_PERCENT;
+        vs[strlen(vs)-1] = 0;
+    }
+    if (pa_endswith(vs, "db") || pa_endswith(vs, "dB")) {
+        *vol_flags |= VOL_DECIBEL;
+        vs[strlen(vs)-2] = 0;
+    }
+
+    if (pa_atod(vs, &v) < 0) {
+        pa_log(_("Invalid volume specification"));
+        pa_xfree(vs);
+        return -1;
+    }
+
+    pa_xfree(vs);
+
+    if ((*vol_flags & VOL_RELATIVE) == VOL_RELATIVE) {
+        if ((*vol_flags & 0x0F) == VOL_UINT)
+            v += (double) PA_VOLUME_NORM;
+        if ((*vol_flags & 0x0F) == VOL_PERCENT)
+            v += 100.0;
+        if ((*vol_flags & 0x0F) == VOL_LINEAR)
+            v += 1.0;
+    }
+    if ((*vol_flags & 0x0F) == VOL_PERCENT)
+        v = v * (double) PA_VOLUME_NORM / 100;
+    if ((*vol_flags & 0x0F) == VOL_LINEAR)
+        v = pa_sw_volume_from_linear(v);
+    if ((*vol_flags & 0x0F) == VOL_DECIBEL)
+        v = pa_sw_volume_from_dB(v);
+
+    if (!PA_VOLUME_IS_VALID((pa_volume_t) v)) {
+        pa_log(_("Volume outside permissible range.\n"));
+        return -1;
+    }
+
+    *vol = (pa_volume_t) v;
+
+    return 0;
+}
+
+static enum mute_flags parse_mute(const char *mute_text) {
+    int b;
+
+    pa_assert(mute_text);
+
+    if (pa_streq("toggle", mute_text))
+        return TOGGLE_MUTE;
+
+    b = pa_parse_boolean(mute_text);
+    switch (b) {
+        case 0:
+            return UNMUTE;
+        case 1:
+            return MUTE;
+        default:
+            return INVALID_MUTE;
+    }
+}
+
 static void help(const char *argv0) {
 
-    printf(_("%s [options] stat\n"
-             "%s [options] list\n"
-             "%s [options] exit\n"
-             "%s [options] upload-sample FILENAME [NAME]\n"
-             "%s [options] play-sample NAME [SINK]\n"
-             "%s [options] remove-sample NAME\n"
-             "%s [options] move-sink-input SINKINPUT SINK\n"
-             "%s [options] move-source-output SOURCEOUTPUT SOURCE\n"
-             "%s [options] load-module NAME [ARGS ...]\n"
-             "%s [options] unload-module MODULE\n"
-             "%s [options] suspend-sink SINK 1|0\n"
-             "%s [options] suspend-source SOURCE 1|0\n"
-             "%s [options] set-card-profile CARD PROFILE\n"
-             "%s [options] set-sink-port SINK PORT\n"
-             "%s [options] set-source-port SOURCE PORT\n"
-             "%s [options] set-sink-volume SINK VOLUME\n"
-             "%s [options] set-source-volume SOURCE VOLUME\n"
-             "%s [options] set-sink-input-volume SINKINPUT VOLUME\n"
-             "%s [options] set-sink-mute SINK 1|0\n"
-             "%s [options] set-source-mute SOURCE 1|0\n"
-             "%s [options] set-sink-input-mute SINKINPUT 1|0\n\n"
+    printf("%s %s %s\n",    argv0, _("[options]"), "stat [short]");
+    printf("%s %s %s\n",    argv0, _("[options]"), "info");
+    printf("%s %s %s %s\n", argv0, _("[options]"), "list [short]", _("[TYPE]"));
+    printf("%s %s %s\n",    argv0, _("[options]"), "exit");
+    printf("%s %s %s %s\n", argv0, _("[options]"), "upload-sample", _("FILENAME [NAME]"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "play-sample ", _("NAME [SINK]"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "remove-sample ", _("NAME"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "load-module ", _("NAME [ARGS ...]"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "unload-module ", _("NAME|#N"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "move-(sink-input|source-output)", _("#N SINK|SOURCE"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "suspend-(sink|source)", _("NAME|#N 1|0"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "set-card-profile ", _("CARD PROFILE"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "set-default-(sink|source)", _("NAME"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "set-(sink|source)-port", _("NAME|#N PORT"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "set-(sink|source)-volume", _("NAME|#N VOLUME"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "set-(sink-input|source-output)-volume", _("#N VOLUME"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "set-(sink|source)-mute", _("NAME|#N 1|0|toggle"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "set-(sink-input|source-output)-mute", _("#N 1|0|toggle"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "set-sink-formats", _("#N FORMATS"));
+    printf("%s %s %s %s\n", argv0, _("[options]"), "set-port-latency-offset", _("CARD-NAME|CARD-#N PORT OFFSET"));
+    printf("%s %s %s\n",    argv0, _("[options]"), "subscribe");
+    printf(_("\nThe special names @DEFAULT_SINK@, @DEFAULT_SOURCE@ and @DEFAULT_MONITOR@\n"
+             "can be used to specify the default sink, source and monitor.\n"));
+
+    printf(_("\n"
              "  -h, --help                            Show this help\n"
              "      --version                         Show version\n\n"
              "  -s, --server=SERVER                   The name of the server to connect to\n"
-             "  -n, --client-name=NAME                How to call this client on the server\n"),
-           argv0, argv0, argv0, argv0, argv0,
-           argv0, argv0, argv0, argv0, argv0,
-           argv0, argv0, argv0, argv0, argv0,
-           argv0, argv0, argv0, argv0, argv0,
-           argv0);
+             "  -n, --client-name=NAME                How to call this client on the server\n"));
 }
 
 enum {
@@ -903,7 +1525,7 @@ enum {
 };
 
 int main(int argc, char *argv[]) {
-    pa_mainloopm = NULL;
+    pa_mainloop *m = NULL;
     int ret = 1, c;
     char *server = NULL, *bn;
 
@@ -916,7 +1538,9 @@ int main(int argc, char *argv[]) {
     };
 
     setlocale(LC_ALL, "");
+#ifdef ENABLE_NLS
     bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);
+#endif
 
     bn = pa_path_get_filename(argv[0]);
 
@@ -965,13 +1589,36 @@ int main(int argc, char *argv[]) {
     }
 
     if (optind < argc) {
-        if (pa_streq(argv[optind], "stat"))
+        if (pa_streq(argv[optind], "stat")) {
             action = STAT;
+            short_list_format = FALSE;
+            if (optind+1 < argc && pa_streq(argv[optind+1], "short"))
+                short_list_format = TRUE;
+
+        } else if (pa_streq(argv[optind], "info"))
+            action = INFO;
+
         else if (pa_streq(argv[optind], "exit"))
             action = EXIT;
-        else if (pa_streq(argv[optind], "list"))
+
+        else if (pa_streq(argv[optind], "list")) {
             action = LIST;
-        else if (pa_streq(argv[optind], "upload-sample")) {
+
+            for (int i = optind+1; i < argc; i++){
+                if (pa_streq(argv[i], "modules") || pa_streq(argv[i], "clients") ||
+                    pa_streq(argv[i], "sinks")   || pa_streq(argv[i], "sink-inputs") ||
+                    pa_streq(argv[i], "sources") || pa_streq(argv[i], "source-outputs") ||
+                    pa_streq(argv[i], "samples") || pa_streq(argv[i], "cards")) {
+                    list_type = pa_xstrdup(argv[i]);
+                } else if (pa_streq(argv[i], "short")) {
+                    short_list_format = TRUE;
+                } else {
+                    pa_log(_("Specify nothing, or one of: %s"), "modules, sinks, sources, sink-inputs, source-outputs, clients, samples, cards");
+                    goto quit;
+                }
+            }
+
+        } else if (pa_streq(argv[optind], "upload-sample")) {
             struct SF_INFO sfi;
             action = UPLOAD_SAMPLE;
 
@@ -1001,7 +1648,7 @@ int main(int argc, char *argv[]) {
 
             if (pa_sndfile_read_channel_map(sndfile, &channel_map) < 0) {
                 if (sample_spec.channels > 2)
-                     pa_log(_("Warning: Failed to determine sample specification from file."));
+                    pa_log(_("Warning: Failed to determine sample specification from file."));
                 pa_channel_map_init_extend(&channel_map, sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
             }
 
@@ -1077,13 +1724,16 @@ int main(int argc, char *argv[]) {
             action = UNLOAD_MODULE;
 
             if (argc != optind+2) {
-                pa_log(_("You have to specify a module index"));
+                pa_log(_("You have to specify a module index or name"));
                 goto quit;
             }
 
-            module_index = (uint32_t) atoi(argv[optind+1]);
+            if (pa_atou(argv[optind + 1], &module_index) < 0)
+                module_name = argv[optind + 1];
 
         } else if (pa_streq(argv[optind], "suspend-sink")) {
+            int b;
+
             action = SUSPEND_SINK;
 
             if (argc > optind+3 || optind+1 >= argc) {
@@ -1091,12 +1741,19 @@ int main(int argc, char *argv[]) {
                 goto quit;
             }
 
-            suspend = pa_parse_boolean(argv[argc-1]);
+            if ((b = pa_parse_boolean(argv[argc-1])) < 0) {
+                pa_log(_("Invalid suspend specification."));
+                goto quit;
+            }
+
+            suspend = !!b;
 
             if (argc > optind+2)
                 sink_name = pa_xstrdup(argv[optind+1]);
 
         } else if (pa_streq(argv[optind], "suspend-source")) {
+            int b;
+
             action = SUSPEND_SOURCE;
 
             if (argc > optind+3 || optind+1 >= argc) {
@@ -1104,7 +1761,12 @@ int main(int argc, char *argv[]) {
                 goto quit;
             }
 
-            suspend = pa_parse_boolean(argv[argc-1]);
+            if ((b = pa_parse_boolean(argv[argc-1])) < 0) {
+                pa_log(_("Invalid suspend specification."));
+                goto quit;
+            }
+
+            suspend = !!b;
 
             if (argc > optind+2)
                 source_name = pa_xstrdup(argv[optind+1]);
@@ -1130,6 +1792,16 @@ int main(int argc, char *argv[]) {
             sink_name = pa_xstrdup(argv[optind+1]);
             port_name = pa_xstrdup(argv[optind+2]);
 
+        } else if (pa_streq(argv[optind], "set-default-sink")) {
+            action = SET_DEFAULT_SINK;
+
+            if (argc != optind+2) {
+                pa_log(_("You have to specify a sink name"));
+                goto quit;
+            }
+
+            sink_name = pa_xstrdup(argv[optind+1]);
+
         } else if (pa_streq(argv[optind], "set-source-port")) {
             action = SET_SOURCE_PORT;
 
@@ -1141,8 +1813,17 @@ int main(int argc, char *argv[]) {
             source_name = pa_xstrdup(argv[optind+1]);
             port_name = pa_xstrdup(argv[optind+2]);
 
+        } else if (pa_streq(argv[optind], "set-default-source")) {
+            action = SET_DEFAULT_SOURCE;
+
+            if (argc != optind+2) {
+                pa_log(_("You have to specify a source name"));
+                goto quit;
+            }
+
+            source_name = pa_xstrdup(argv[optind+1]);
+
         } else if (pa_streq(argv[optind], "set-sink-volume")) {
-            uint32_t v;
             action = SET_SINK_VOLUME;
 
             if (argc != optind+3) {
@@ -1150,16 +1831,12 @@ int main(int argc, char *argv[]) {
                 goto quit;
             }
 
-            if (pa_atou(argv[optind+2], &v) < 0) {
-                pa_log(_("Invalid volume specification"));
-                goto quit;
-            }
-
             sink_name = pa_xstrdup(argv[optind+1]);
-            volume = (pa_volume_t) v;
+
+            if (parse_volume(argv[optind+2], &volume, &volume_flags) < 0)
+                goto quit;
 
         } else if (pa_streq(argv[optind], "set-source-volume")) {
-            uint32_t v;
             action = SET_SOURCE_VOLUME;
 
             if (argc != optind+3) {
@@ -1167,16 +1844,12 @@ int main(int argc, char *argv[]) {
                 goto quit;
             }
 
-            if (pa_atou(argv[optind+2], &v) < 0) {
-                pa_log(_("Invalid volume specification"));
-                goto quit;
-            }
-
             source_name = pa_xstrdup(argv[optind+1]);
-            volume = (pa_volume_t) v;
+
+            if (parse_volume(argv[optind+2], &volume, &volume_flags) < 0)
+                goto quit;
 
         } else if (pa_streq(argv[optind], "set-sink-input-volume")) {
-            uint32_t v;
             action = SET_SINK_INPUT_VOLUME;
 
             if (argc != optind+3) {
@@ -1189,15 +1862,26 @@ int main(int argc, char *argv[]) {
                 goto quit;
             }
 
-            if (pa_atou(argv[optind+2], &v) < 0) {
-                pa_log(_("Invalid volume specification"));
+            if (parse_volume(argv[optind+2], &volume, &volume_flags) < 0)
+                goto quit;
+
+        } else if (pa_streq(argv[optind], "set-source-output-volume")) {
+            action = SET_SOURCE_OUTPUT_VOLUME;
+
+            if (argc != optind+3) {
+                pa_log(_("You have to specify a source output index and a volume"));
                 goto quit;
             }
 
-            volume = (pa_volume_t) v;
+            if (pa_atou(argv[optind+1], &source_output_idx) < 0) {
+                pa_log(_("Invalid source output index"));
+                goto quit;
+            }
+
+            if (parse_volume(argv[optind+2], &volume, &volume_flags) < 0)
+                goto quit;
 
         } else if (pa_streq(argv[optind], "set-sink-mute")) {
-            int b;
             action = SET_SINK_MUTE;
 
             if (argc != optind+3) {
@@ -1205,16 +1889,14 @@ int main(int argc, char *argv[]) {
                 goto quit;
             }
 
-            if ((b = pa_parse_boolean(argv[optind+2])) < 0) {
-                pa_log(_("Invalid volume specification"));
+            if ((mute = parse_mute(argv[optind+2])) == INVALID_MUTE) {
+                pa_log(_("Invalid mute specification"));
                 goto quit;
             }
 
             sink_name = pa_xstrdup(argv[optind+1]);
-            mute = b;
 
         } else if (pa_streq(argv[optind], "set-source-mute")) {
-            int b;
             action = SET_SOURCE_MUTE;
 
             if (argc != optind+3) {
@@ -1222,16 +1904,14 @@ int main(int argc, char *argv[]) {
                 goto quit;
             }
 
-            if ((b = pa_parse_boolean(argv[optind+2])) < 0) {
-                pa_log(_("Invalid volume specification"));
+            if ((mute = parse_mute(argv[optind+2])) == INVALID_MUTE) {
+                pa_log(_("Invalid mute specification"));
                 goto quit;
             }
 
             source_name = pa_xstrdup(argv[optind+1]);
-            mute = b;
 
         } else if (pa_streq(argv[optind], "set-sink-input-mute")) {
-            int b;
             action = SET_SINK_INPUT_MUTE;
 
             if (argc != optind+3) {
@@ -1244,12 +1924,59 @@ int main(int argc, char *argv[]) {
                 goto quit;
             }
 
-            if ((b = pa_parse_boolean(argv[optind+2])) < 0) {
-                pa_log(_("Invalid volume specification"));
+            if ((mute = parse_mute(argv[optind+2])) == INVALID_MUTE) {
+                pa_log(_("Invalid mute specification"));
+                goto quit;
+            }
+
+        } else if (pa_streq(argv[optind], "set-source-output-mute")) {
+            action = SET_SOURCE_OUTPUT_MUTE;
+
+            if (argc != optind+3) {
+                pa_log(_("You have to specify a source output index and a mute boolean"));
                 goto quit;
             }
 
-            mute = b;
+            if (pa_atou(argv[optind+1], &source_output_idx) < 0) {
+                pa_log(_("Invalid source output index specification"));
+                goto quit;
+            }
+
+            if ((mute = parse_mute(argv[optind+2])) == INVALID_MUTE) {
+                pa_log(_("Invalid mute specification"));
+                goto quit;
+            }
+
+        } else if (pa_streq(argv[optind], "subscribe"))
+
+            action = SUBSCRIBE;
+
+        else if (pa_streq(argv[optind], "set-sink-formats")) {
+            int32_t tmp;
+
+            if (argc != optind+3 || pa_atoi(argv[optind+1], &tmp) < 0) {
+                pa_log(_("You have to specify a sink index and a semicolon-separated list of supported formats"));
+                goto quit;
+            }
+
+            sink_idx = tmp;
+            action = SET_SINK_FORMATS;
+            formats = pa_xstrdup(argv[optind+2]);
+
+        } else if (pa_streq(argv[optind], "set-port-latency-offset")) {
+            action = SET_PORT_LATENCY_OFFSET;
+
+            if (argc != optind+4) {
+                pa_log(_("You have to specify a card name/index, a port name and a latency offset"));
+                goto quit;
+            }
+
+            card_name = pa_xstrdup(argv[optind+1]);
+            port_name = pa_xstrdup(argv[optind+2]);
+            if (pa_atoi(argv[optind + 3], &latency_offset) < 0) {
+                pa_log(_("Could not parse latency offset"));
+                goto quit;
+            }
 
         } else if (pa_streq(argv[optind], "help")) {
             help(bn);
@@ -1304,12 +2031,15 @@ quit:
     }
 
     pa_xfree(server);
+    pa_xfree(list_type);
     pa_xfree(sample_name);
     pa_xfree(sink_name);
     pa_xfree(source_name);
     pa_xfree(module_args);
     pa_xfree(card_name);
     pa_xfree(profile_name);
+    pa_xfree(port_name);
+    pa_xfree(formats);
 
     if (sndfile)
         sf_close(sndfile);
index 2ed0a03..858cec8 100644 (file)
@@ -118,6 +118,7 @@ static PA_LLIST_HEAD(fd_info, fd_infos) = NULL;
 static int (*_ioctl)(int, int, void*) = NULL;
 static int (*_close)(int) = NULL;
 static int (*_open)(const char *, int, mode_t) = NULL;
+static int (*___open_2)(const char *, int) = NULL;
 static FILE* (*_fopen)(const char *path, const char *mode) = NULL;
 static int (*_stat)(const char *, struct stat *) = NULL;
 #ifdef _STAT_VER
@@ -125,6 +126,7 @@ static int (*___xstat)(int, const char *, struct stat *) = NULL;
 #endif
 #ifdef HAVE_OPEN64
 static int (*_open64)(const char *, int, mode_t) = NULL;
+static int (*___open64_2)(const char *, int) = NULL;
 static FILE* (*_fopen64)(const char *path, const char *mode) = NULL;
 static int (*_stat64)(const char *, struct stat64 *) = NULL;
 #ifdef _STAT_VER
@@ -157,6 +159,14 @@ do { \
     pthread_mutex_unlock(&func_mutex); \
 } while(0)
 
+#define LOAD___OPEN_2_FUNC() \
+do { \
+    pthread_mutex_lock(&func_mutex); \
+    if (!___open_2) \
+        ___open_2 = (int (*)(const char *, int)) dlsym_fn(RTLD_NEXT, "__open_2"); \
+    pthread_mutex_unlock(&func_mutex); \
+} while(0)
+
 #define LOAD_OPEN64_FUNC() \
 do { \
     pthread_mutex_lock(&func_mutex); \
@@ -165,6 +175,14 @@ do { \
     pthread_mutex_unlock(&func_mutex); \
 } while(0)
 
+#define LOAD___OPEN64_2_FUNC() \
+do { \
+    pthread_mutex_lock(&func_mutex); \
+    if (!___open64_2) \
+        ___open64_2 = (int (*)(const char *, int)) dlsym_fn(RTLD_NEXT, "__open64_2"); \
+    pthread_mutex_unlock(&func_mutex); \
+} while(0)
+
 #define LOAD_CLOSE_FUNC() \
 do { \
     pthread_mutex_lock(&func_mutex); \
@@ -264,7 +282,7 @@ static void debug(int level, const char *format, ...) PA_GCC_PRINTF_ATTR(2,3);
 
 #define DEBUG_LEVEL_ALWAYS                0
 #define DEBUG_LEVEL_NORMAL                1
-#define DEBUG_LEVEL_VERBOSE                2
+#define DEBUG_LEVEL_VERBOSE               2
 
 static void debug(int level, const char *format, ...) {
     va_list ap;
@@ -904,9 +922,22 @@ static int fd_info_copy_data(fd_info *i, int force) {
                 return -1;
             }
 
-            if (!data)
+            if (len <= 0)
                 break;
 
+            if (!data) {
+                /* Maybe we should generate silence here, but I'm lazy and
+                 * I'll just skip any holes in the stream. */
+                if (pa_stream_drop(i->rec_stream) < 0) {
+                    debug(DEBUG_LEVEL_NORMAL, __FILE__": pa_stream_drop(): %s\n", pa_strerror(pa_context_errno(i->context)));
+                    return -1;
+                }
+
+                assert(n >= len);
+                n -= len;
+                continue;
+            }
+
             buf = (const char*)data + i->rec_offset;
 
             if ((r = write(i->thread_fd, buf, len - i->rec_offset)) <= 0) {
@@ -1204,7 +1235,7 @@ fail:
 static void sink_info_cb(pa_context *context, const pa_sink_info *si, int eol, void *userdata) {
     fd_info *i = userdata;
 
-    if (!si || eol < 0) {
+    if (eol < 0) {
         i->operation_success = 0;
         pa_threaded_mainloop_signal(i->mainloop, 0);
         return;
@@ -1226,7 +1257,7 @@ static void sink_info_cb(pa_context *context, const pa_sink_info *si, int eol, v
 static void source_info_cb(pa_context *context, const pa_source_info *si, int eol, void *userdata) {
     fd_info *i = userdata;
 
-    if (!si || eol < 0) {
+    if (eol < 0) {
         i->operation_success = 0;
         pa_threaded_mainloop_signal(i->mainloop, 0);
         return;
@@ -1426,6 +1457,7 @@ static int sndstat_open(int flags, int *_errno) {
 
     unlink(fn);
     pa_xfree(fn);
+    fn = NULL;
 
     if (write(fd, sndstat, sizeof(sndstat) -1) != sizeof(sndstat)-1) {
         *_errno = errno;
@@ -1458,11 +1490,11 @@ static int real_open(const char *filename, int flags, mode_t mode) {
         return _open(filename, flags, mode);
     }
 
-    if (filename && dsp_cloak_enable() && (strcmp(filename, "/dev/dsp") == 0 || strcmp(filename, "/dev/adsp") == 0))
+    if (filename && dsp_cloak_enable() && (pa_streq(filename, "/dev/dsp") || pa_streq(filename, "/dev/adsp") || pa_streq(filename, "/dev/audio")))
         r = dsp_open(flags, &_errno);
-    else if (filename && mixer_cloak_enable() && strcmp(filename, "/dev/mixer") == 0)
+    else if (filename && mixer_cloak_enable() && pa_streq(filename, "/dev/mixer"))
         r = mixer_open(flags, &_errno);
-    else if (filename && sndstat_cloak_enable() && strcmp(filename, "/dev/sndstat") == 0)
+    else if (filename && sndstat_cloak_enable() && pa_streq(filename, "/dev/sndstat"))
         r = sndstat_open(flags, &_errno);
     else {
         function_exit();
@@ -1494,6 +1526,27 @@ int open(const char *filename, int flags, ...) {
     return real_open(filename, flags, mode);
 }
 
+static pa_bool_t is_audio_device_node(const char *path) {
+    return
+        pa_streq(path, "/dev/dsp") ||
+        pa_streq(path, "/dev/adsp") ||
+        pa_streq(path, "/dev/audio") ||
+        pa_streq(path, "/dev/sndstat") ||
+        pa_streq(path, "/dev/mixer");
+}
+
+int __open_2(const char *filename, int flags) {
+    debug(DEBUG_LEVEL_VERBOSE, __FILE__": __open_2(%s)\n", filename?filename:"NULL");
+
+    if ((flags & O_CREAT) ||
+        !filename ||
+        !is_audio_device_node(filename)) {
+        LOAD___OPEN_2_FUNC();
+        return ___open_2(filename, flags);
+    }
+    return real_open(filename, flags, 0);
+}
+
 static int mixer_ioctl(fd_info *i, unsigned long request, void*argp, int *_errno) {
     int ret = -1;
 
@@ -1557,7 +1610,7 @@ static int mixer_ioctl(fd_info *i, unsigned long request, void*argp, int *_errno
 
             *(int*) argp =
                 ((v->values[0]*100/PA_VOLUME_NORM)) |
-                ((v->values[v->channels > 1 ? 1 : 0]*100/PA_VOLUME_NORM)  << 8);
+                ((v->values[v->channels > 1 ? 1 : 0]*100/PA_VOLUME_NORM) << 8);
 
             pa_threaded_mainloop_unlock(i->mainloop);
 
@@ -2038,7 +2091,7 @@ static int dsp_ioctl(fd_info *i, unsigned long request, void*argp, int *_errno)
         case SNDCTL_DSP_GETCAPS:
             debug(DEBUG_LEVEL_NORMAL, __FILE__": SNDCTL_DSP_CAPS\n");
 
-            *(int*)  argp = DSP_CAP_DUPLEX | DSP_CAP_TRIGGER
+            *(int*) argp = DSP_CAP_DUPLEX | DSP_CAP_TRIGGER
 #ifdef DSP_CAP_MULTI
               | DSP_CAP_MULTI
 #endif
@@ -2302,7 +2355,7 @@ static int dsp_ioctl(fd_info *i, unsigned long request, void*argp, int *_errno)
             break;
 
         default:
-            /* Mixer ioctls are valid on /dev/dsp aswell */
+            /* Mixer ioctls are valid on /dev/dsp as well */
             return mixer_ioctl(i, request, argp, _errno);
 
 inval:
@@ -2388,10 +2441,7 @@ int access(const char *pathname, int mode) {
     debug(DEBUG_LEVEL_VERBOSE, __FILE__": access(%s)\n", pathname?pathname:"NULL");
 
     if (!pathname ||
-        (strcmp(pathname, "/dev/dsp") != 0 &&
-         strcmp(pathname, "/dev/adsp") != 0 &&
-         strcmp(pathname, "/dev/sndstat") != 0 &&
-         strcmp(pathname, "/dev/mixer") != 0 )) {
+        !is_audio_device_node(pathname)) {
         LOAD_ACCESS_FUNC();
         return _access(pathname, mode);
     }
@@ -2417,10 +2467,7 @@ int stat(const char *pathname, struct stat *buf) {
 
     if (!pathname ||
         !buf ||
-        ( strcmp(pathname, "/dev/dsp") != 0 &&
-          strcmp(pathname, "/dev/adsp") != 0 &&
-          strcmp(pathname, "/dev/sndstat") != 0 &&
-          strcmp(pathname, "/dev/mixer") != 0 )) {
+        !is_audio_device_node(pathname)) {
         debug(DEBUG_LEVEL_VERBOSE, __FILE__": stat(%s)\n", pathname?pathname:"NULL");
         LOAD_STAT_FUNC();
         return _stat(pathname, buf);
@@ -2474,10 +2521,7 @@ int stat64(const char *pathname, struct stat64 *buf) {
 
     if (!pathname ||
         !buf ||
-        ( strcmp(pathname, "/dev/dsp") != 0 &&
-          strcmp(pathname, "/dev/adsp") != 0 &&
-          strcmp(pathname, "/dev/sndstat") != 0 &&
-          strcmp(pathname, "/dev/mixer") != 0 )) {
+        !is_audio_device_node(pathname)) {
         LOAD_STAT64_FUNC();
         return _stat64(pathname, buf);
     }
@@ -2519,10 +2563,7 @@ int open64(const char *filename, int flags, ...) {
     }
 
     if (!filename ||
-        ( strcmp(filename, "/dev/dsp") != 0 &&
-          strcmp(filename, "/dev/adsp") != 0 &&
-          strcmp(filename, "/dev/sndstat") != 0 &&
-          strcmp(filename, "/dev/mixer") != 0 )) {
+        !is_audio_device_node(filename)) {
         LOAD_OPEN64_FUNC();
         return _open64(filename, flags, mode);
     }
@@ -2530,6 +2571,19 @@ int open64(const char *filename, int flags, ...) {
     return real_open(filename, flags, mode);
 }
 
+int __open64_2(const char *filename, int flags) {
+    debug(DEBUG_LEVEL_VERBOSE, __FILE__": __open64_2(%s)\n", filename?filename:"NULL");
+
+    if ((flags & O_CREAT) ||
+        !filename ||
+        !is_audio_device_node(filename)) {
+        LOAD___OPEN64_2_FUNC();
+        return ___open64_2(filename, flags);
+    }
+
+    return real_open(filename, flags, 0);
+}
+
 #endif
 
 #ifdef _STAT_VER
@@ -2539,10 +2593,7 @@ int __xstat(int ver, const char *pathname, struct stat *buf) {
 
     if (!pathname ||
         !buf ||
-        ( strcmp(pathname, "/dev/dsp") != 0 &&
-          strcmp(pathname, "/dev/adsp") != 0 &&
-          strcmp(pathname, "/dev/sndstat") != 0 &&
-          strcmp(pathname, "/dev/mixer") != 0 )) {
+        !is_audio_device_node(pathname)) {
         LOAD_XSTAT_FUNC();
         return ___xstat(ver, pathname, buf);
     }
@@ -2562,10 +2613,7 @@ int __xstat64(int ver, const char *pathname, struct stat64 *buf) {
 
     if (!pathname ||
         !buf ||
-        ( strcmp(pathname, "/dev/dsp") != 0 &&
-          strcmp(pathname, "/dev/adsp") != 0 &&
-          strcmp(pathname, "/dev/sndstat") != 0 &&
-          strcmp(pathname, "/dev/mixer") != 0 )) {
+        !is_audio_device_node(pathname)) {
         LOAD_XSTAT64_FUNC();
         return ___xstat64(ver, pathname, buf);
     }
@@ -2591,10 +2639,7 @@ FILE* fopen(const char *filename, const char *mode) {
 
     if (!filename ||
         !mode ||
-        ( strcmp(filename, "/dev/dsp") != 0 &&
-          strcmp(filename, "/dev/adsp") != 0 &&
-          strcmp(filename, "/dev/sndstat") != 0 &&
-          strcmp(filename, "/dev/mixer") != 0 )) {
+        !is_audio_device_node(filename)) {
         LOAD_FOPEN_FUNC();
         return _fopen(filename, mode);
     }
@@ -2634,10 +2679,7 @@ FILE *fopen64(const char *filename, const char *mode) {
 
     if (!filename ||
         !mode ||
-        ( strcmp(filename, "/dev/dsp") != 0 &&
-          strcmp(filename, "/dev/adsp") != 0 &&
-          strcmp(filename, "/dev/sndstat") != 0 &&
-          strcmp(filename, "/dev/mixer") != 0 )) {
+        !is_audio_device_node(filename)) {
         LOAD_FOPEN64_FUNC();
         return _fopen64(filename, mode);
     }
old mode 100755 (executable)
new mode 100644 (file)
similarity index 95%
rename from src/utils/padsp
rename to src/utils/padsp.in
index 4fe175c..4ecce8c
@@ -76,9 +76,9 @@ done
 shift $(( $OPTIND - 1 ))
 
 if [ x"$LD_PRELOAD" = x ] ; then
-   LD_PRELOAD="libpulsedsp.so"
+   LD_PRELOAD="@pkglibdir@/libpulsedsp.so"
 else
-   LD_PRELOAD="$LD_PRELOAD libpulsedsp.so"
+   LD_PRELOAD="$LD_PRELOAD @pkglibdir@/libpulsedsp.so"
 fi
 
 export LD_PRELOAD
index c327ee4..5825191 100644 (file)
@@ -33,7 +33,6 @@
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <limits.h>
 #include <getopt.h>
 #include <locale.h>
 
 #include <sys/prctl.h>
 #endif
 
-#include <pulse/i18n.h>
 #include <pulse/pulseaudio.h>
-#include <pulsecore/macro.h>
 
-#define BUFSIZE 1024
+#include <pulsecore/i18n.h>
+#include <pulsecore/macro.h>
 
 static pa_context *context = NULL;
 static pa_mainloop_api *mainloop_api = NULL;
@@ -233,7 +231,9 @@ int main(int argc, char *argv[]) {
     };
 
     setlocale(LC_ALL, "");
+#ifdef ENABLE_NLS
     bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);
+#endif
 
     bn = pa_path_get_filename(argv[0]);
 
@@ -292,7 +292,11 @@ int main(int argc, char *argv[]) {
     }
 
     pa_context_set_state_callback(context, context_state_callback, NULL);
-    pa_context_connect(context, server, PA_CONTEXT_NOAUTOSPAWN, NULL);
+
+    if (pa_context_connect(context, server, PA_CONTEXT_NOAUTOSPAWN, NULL) < 0) {
+        fprintf(stderr, "pa_context_connect() failed: %s\n", pa_strerror(pa_context_errno(context)));
+        goto quit;
+    }
 
     if (pa_mainloop_run(m, &ret) < 0) {
         fprintf(stderr, _("pa_mainloop_run() failed.\n"));
index a9eb329..16cf866 100644 (file)
 
 #include <stdio.h>
 #include <getopt.h>
-#include <string.h>
 #include <assert.h>
 #include <locale.h>
 
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
+#include <xcb/xcb.h>
 
 #include <pulse/util.h>
-#include <pulse/i18n.h>
+#include <pulse/client-conf.h>
 
 #include <pulsecore/core-util.h>
+#include <pulsecore/i18n.h>
 #include <pulsecore/log.h>
 #include <pulsecore/authkey.h>
 #include <pulsecore/native-common.h>
 #include <pulsecore/x11prop.h>
 
-#include "../pulse/client-conf.h"
 
 int main(int argc, char *argv[]) {
     const char *dname = NULL, *sink = NULL, *source = NULL, *server = NULL, *cookie_file = PA_NATIVE_COOKIE_FILE;
-    int c, ret = 1;
-    Display *d = NULL;
+    int c, ret = 1, screen = 0;
+    xcb_connection_t *xcb = NULL;
     enum { DUMP, EXPORT, IMPORT, REMOVE } mode = DUMP;
 
     setlocale(LC_ALL, "");
+#ifdef ENABLE_NLS
     bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);
+#endif
 
     while ((c = getopt(argc, argv, "deiD:S:O:I:c:hr")) != -1) {
         switch (c) {
@@ -96,21 +96,26 @@ int main(int argc, char *argv[]) {
         }
     }
 
-    if (!(d = XOpenDisplay(dname))) {
-        pa_log(_("XOpenDisplay() failed"));
+    if (!(xcb = xcb_connect(dname, &screen))) {
+        pa_log(_("xcb_connect() failed"));
+        goto finish;
+    }
+
+    if (xcb_connection_has_error(xcb)) {
+        pa_log(_("xcb_connection_has_error() returned true"));
         goto finish;
     }
 
     switch (mode) {
         case DUMP: {
             char t[1024];
-            if (pa_x11_get_prop(d, "PULSE_SERVER", t, sizeof(t)))
+            if (pa_x11_get_prop(xcb, screen, "PULSE_SERVER", t, sizeof(t)))
                 printf(_("Server: %s\n"), t);
-            if (pa_x11_get_prop(d, "PULSE_SOURCE", t, sizeof(t)))
+            if (pa_x11_get_prop(xcb, screen, "PULSE_SOURCE", t, sizeof(t)))
                 printf(_("Source: %s\n"), t);
-            if (pa_x11_get_prop(d, "PULSE_SINK", t, sizeof(t)))
+            if (pa_x11_get_prop(xcb, screen, "PULSE_SINK", t, sizeof(t)))
                 printf(_("Sink: %s\n"), t);
-            if (pa_x11_get_prop(d, "PULSE_COOKIE", t, sizeof(t)))
+            if (pa_x11_get_prop(xcb, screen, "PULSE_COOKIE", t, sizeof(t)))
                 printf(_("Cookie: %s\n"), t);
 
             break;
@@ -118,14 +123,14 @@ int main(int argc, char *argv[]) {
 
         case IMPORT: {
             char t[1024];
-            if (pa_x11_get_prop(d, "PULSE_SERVER", t, sizeof(t)))
+            if (pa_x11_get_prop(xcb, screen, "PULSE_SERVER", t, sizeof(t)))
                 printf("PULSE_SERVER='%s'\nexport PULSE_SERVER\n", t);
-            if (pa_x11_get_prop(d, "PULSE_SOURCE", t, sizeof(t)))
+            if (pa_x11_get_prop(xcb, screen, "PULSE_SOURCE", t, sizeof(t)))
                 printf("PULSE_SOURCE='%s'\nexport PULSE_SOURCE\n", t);
-            if (pa_x11_get_prop(d, "PULSE_SINK", t, sizeof(t)))
+            if (pa_x11_get_prop(xcb, screen, "PULSE_SINK", t, sizeof(t)))
                 printf("PULSE_SINK='%s'\nexport PULSE_SINK\n", t);
 
-            if (pa_x11_get_prop(d, "PULSE_COOKIE", t, sizeof(t))) {
+            if (pa_x11_get_prop(xcb, screen, "PULSE_COOKIE", t, sizeof(t))) {
                 uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
                 size_t l;
                 if ((l = pa_parsehex(t, cookie, sizeof(cookie))) != sizeof(cookie)) {
@@ -158,16 +163,16 @@ int main(int argc, char *argv[]) {
                 goto finish;
             }
 
-            pa_x11_del_prop(d, "PULSE_SERVER");
-            pa_x11_del_prop(d, "PULSE_SINK");
-            pa_x11_del_prop(d, "PULSE_SOURCE");
-            pa_x11_del_prop(d, "PULSE_ID");
-            pa_x11_del_prop(d, "PULSE_COOKIE");
+            pa_x11_del_prop(xcb, screen, "PULSE_SERVER");
+            pa_x11_del_prop(xcb, screen, "PULSE_SINK");
+            pa_x11_del_prop(xcb, screen, "PULSE_SOURCE");
+            pa_x11_del_prop(xcb, screen, "PULSE_ID");
+            pa_x11_del_prop(xcb, screen, "PULSE_COOKIE");
 
             if (server)
-                pa_x11_set_prop(d, "PULSE_SERVER", server);
+                pa_x11_set_prop(xcb, screen, "PULSE_SERVER", server);
             else if (conf->default_server)
-                pa_x11_set_prop(d, "PULSE_SERVER", conf->default_server);
+                pa_x11_set_prop(xcb, screen, "PULSE_SERVER", conf->default_server);
             else {
                 char hn[256];
                 if (!pa_get_fqdn(hn, sizeof(hn))) {
@@ -175,36 +180,37 @@ int main(int argc, char *argv[]) {
                     goto finish;
                 }
 
-                pa_x11_set_prop(d, "PULSE_SERVER", hn);
+                pa_x11_set_prop(xcb, screen, "PULSE_SERVER", hn);
             }
 
             if (sink)
-                pa_x11_set_prop(d, "PULSE_SINK", sink);
+                pa_x11_set_prop(xcb, screen, "PULSE_SINK", sink);
             else if (conf->default_sink)
-                pa_x11_set_prop(d, "PULSE_SINK", conf->default_sink);
+                pa_x11_set_prop(xcb, screen, "PULSE_SINK", conf->default_sink);
 
             if (source)
-                pa_x11_set_prop(d, "PULSE_SOURCE", source);
+                pa_x11_set_prop(xcb, screen, "PULSE_SOURCE", source);
             if (conf->default_source)
-                pa_x11_set_prop(d, "PULSE_SOURCE", conf->default_source);
+                pa_x11_set_prop(xcb, screen, "PULSE_SOURCE", conf->default_source);
 
             pa_client_conf_free(conf);
 
-            if (pa_authkey_load_auto(cookie_file, cookie, sizeof(cookie)) < 0) {
+            if (pa_authkey_load_auto(cookie_file, TRUE, cookie, sizeof(cookie)) < 0) {
                 fprintf(stderr, _("Failed to load cookie data\n"));
                 goto finish;
             }
 
-            pa_x11_set_prop(d, "PULSE_COOKIE", pa_hexstr(cookie, sizeof(cookie), hx, sizeof(hx)));
+            pa_x11_set_prop(xcb, screen, "PULSE_COOKIE", pa_hexstr(cookie, sizeof(cookie), hx, sizeof(hx)));
             break;
         }
 
         case REMOVE:
-            pa_x11_del_prop(d, "PULSE_SERVER");
-            pa_x11_del_prop(d, "PULSE_SINK");
-            pa_x11_del_prop(d, "PULSE_SOURCE");
-            pa_x11_del_prop(d, "PULSE_ID");
-            pa_x11_del_prop(d, "PULSE_COOKIE");
+            pa_x11_del_prop(xcb, screen, "PULSE_SERVER");
+            pa_x11_del_prop(xcb, screen, "PULSE_SINK");
+            pa_x11_del_prop(xcb, screen, "PULSE_SOURCE");
+            pa_x11_del_prop(xcb, screen, "PULSE_ID");
+            pa_x11_del_prop(xcb, screen, "PULSE_COOKIE");
+            pa_x11_del_prop(xcb, screen, "PULSE_SESSION_ID");
             break;
 
         default:
@@ -216,9 +222,9 @@ int main(int argc, char *argv[]) {
 
 finish:
 
-    if (d) {
-        XSync(d, False);
-        XCloseDisplay(d);
+    if (xcb) {
+        xcb_flush(xcb);
+        xcb_disconnect(xcb);
     }
 
     return ret;
diff --git a/src/utils/qpaeq b/src/utils/qpaeq
new file mode 100755 (executable)
index 0000000..4b00e3a
--- /dev/null
@@ -0,0 +1,575 @@
+#!/usr/bin/env python
+#    qpaeq is a equalizer interface for pulseaudio's equalizer sinks
+#    Copyright (C) 2009  Jason Newton <nevion@gmail.com
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program 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 Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+import os,math,sys
+try:
+    import PyQt4,sip
+    from PyQt4 import QtGui,QtCore
+    import dbus.mainloop.qt
+    import dbus
+except ImportError as e:
+    sys.stderr.write('There was an error importing needed libraries\n'
+                     'Make sure you have qt4 and dbus-python installed\n'
+                     'The error that occured was:\n'
+                     '\t%s\n' % (str(e)))
+    sys.exit(-1)
+
+from functools import partial
+
+import signal
+signal.signal(signal.SIGINT, signal.SIG_DFL)
+SYNC_TIMEOUT = 4*1000
+
+CORE_PATH = "/org/pulseaudio/core1"
+CORE_IFACE = "org.PulseAudio.Core1"
+def connect():
+    try:
+        if 'PULSE_DBUS_SERVER' in os.environ:
+            address = os.environ['PULSE_DBUS_SERVER']
+        else:
+            bus = dbus.SessionBus() # Should be UserBus, but D-Bus doesn't implement that yet.
+            server_lookup = bus.get_object('org.PulseAudio1', '/org/pulseaudio/server_lookup1')
+            address = server_lookup.Get('org.PulseAudio.ServerLookup1', 'Address', dbus_interface='org.freedesktop.DBus.Properties')
+        return dbus.connection.Connection(address)
+    except Exception as e:
+        sys.stderr.write('There was an error connecting to pulseaudio, '
+                         'please make sure you have the pulseaudio dbus '
+                         'module loaded, exiting...\n')
+        sys.exit(-1)
+
+
+#TODO: signals: sink Filter changed, sink reconfigured (window size) (sink iface)
+#TODO: manager signals: new sink, removed sink, new profile, removed profile
+#TODO: add support for changing of window_size 1000-fft_size (adv option)
+#TODO: reconnect support loop 1 second trying to reconnect
+#TODO: just resample the filters for profiles when loading to different sizes
+#TODO: add preamp
+prop_iface='org.freedesktop.DBus.Properties'
+eq_iface='org.PulseAudio.Ext.Equalizing1.Equalizer'
+device_iface='org.PulseAudio.Core1.Device'
+class QPaeq(QtGui.QWidget):
+    manager_path='/org/pulseaudio/equalizing1'
+    manager_iface='org.PulseAudio.Ext.Equalizing1.Manager'
+    core_iface='org.PulseAudio.Core1'
+    core_path='/org/pulseaudio/core1'
+    module_name='module-equalizer-sink'
+
+    def __init__(self):
+        QtGui.QWidget.__init__(self)
+        self.setWindowTitle('qpaeq')
+        self.slider_widget=None
+        self.sink_name=None
+        self.filter_state=None
+
+        self.create_layout()
+
+        self.set_connection()
+        self.connect_to_sink(self.sinks[0])
+        self.set_callbacks()
+        self.setMinimumSize(self.sizeHint())
+
+    def create_layout(self):
+        self.main_layout=QtGui.QVBoxLayout()
+        self.setLayout(self.main_layout)
+        toprow_layout=QtGui.QHBoxLayout()
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        #sizePolicy.setHeightForWidth(self.profile_box.sizePolicy().hasHeightForWidth())
+
+        toprow_layout.addWidget(QtGui.QLabel('Sink'))
+        self.sink_box = QtGui.QComboBox()
+        self.sink_box.setSizePolicy(sizePolicy)
+        self.sink_box.setDuplicatesEnabled(False)
+        self.sink_box.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically)
+        #self.sink_box.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
+        toprow_layout.addWidget(self.sink_box)
+
+        toprow_layout.addWidget(QtGui.QLabel('Channel'))
+        self.channel_box = QtGui.QComboBox()
+        self.channel_box.setSizePolicy(sizePolicy)
+        toprow_layout.addWidget(self.channel_box)
+
+        toprow_layout.addWidget(QtGui.QLabel('Preset'))
+        self.profile_box = QtGui.QComboBox()
+        self.profile_box.setSizePolicy(sizePolicy)
+        self.profile_box.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically)
+        #self.profile_box.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
+        toprow_layout.addWidget(self.profile_box)
+
+        large_icon_size=self.style().pixelMetric(QtGui.QStyle.PM_LargeIconSize)
+        large_icon_size=QtCore.QSize(large_icon_size,large_icon_size)
+        save_profile=QtGui.QToolButton()
+        save_profile.setIcon(self.style().standardIcon(QtGui.QStyle.SP_DriveFDIcon))
+        save_profile.setIconSize(large_icon_size)
+        save_profile.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
+        save_profile.clicked.connect(self.save_profile)
+        remove_profile=QtGui.QToolButton()
+        remove_profile.setIcon(self.style().standardIcon(QtGui.QStyle.SP_TrashIcon))
+        remove_profile.setIconSize(large_icon_size)
+        remove_profile.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
+        remove_profile.clicked.connect(self.remove_profile)
+        toprow_layout.addWidget(save_profile)
+        toprow_layout.addWidget(remove_profile)
+
+        reset_button = QtGui.QPushButton('Reset')
+        reset_button.clicked.connect(self.reset)
+        toprow_layout.addStretch()
+        toprow_layout.addWidget(reset_button)
+        self.layout().addLayout(toprow_layout)
+
+        self.profile_box.activated.connect(self.load_profile)
+        self.channel_box.activated.connect(self.select_channel)
+    def connect_to_sink(self,name):
+        #TODO: clear slots for profile buttons
+
+        #flush any pending saves for other sinks
+        if self.filter_state is not None:
+            self.filter_state.flush_state()
+        sink=self.connection.get_object(object_path=name)
+        self.sink_props=dbus.Interface(sink,dbus_interface=prop_iface)
+        self.sink=dbus.Interface(sink,dbus_interface=eq_iface)
+        self.filter_state=FilterState(sink)
+        #sample_rate,filter_rate,channels,channel)
+
+        self.channel_box.clear()
+        self.channel_box.addItem('All',self.filter_state.channels)
+        for i in range(self.filter_state.channels):
+            self.channel_box.addItem('%d' %(i+1,),i)
+        self.setMinimumSize(self.sizeHint())
+
+        self.set_slider_widget(SliderArray(self.filter_state))
+
+        self.sink_name=name
+        #set the signal listener for this sink
+        core=self._get_core()
+        #temporary hack until signal filtering works properly
+        core.ListenForSignal('',[dbus.ObjectPath(self.sink_name),dbus.ObjectPath(self.manager_path)])
+        #for x in ['FilterChanged']:
+        #    core.ListenForSignal("%s.%s" %(self.eq_iface,x),[dbus.ObjectPath(self.sink_name)])
+        #core.ListenForSignal(self.eq_iface,[dbus.ObjectPath(self.sink_name)])
+        self.sink.connect_to_signal('FilterChanged',self.read_filter)
+
+    def set_slider_widget(self,widget):
+        layout=self.layout()
+        if self.slider_widget is not None:
+            i=layout.indexOf(self.slider_widget)
+            layout.removeWidget(self.slider_widget)
+            self.slider_widget.deleteLater()
+            layout.insertWidget(i,self.slider_widget)
+        else:
+            layout.addWidget(widget)
+        self.slider_widget=widget
+        self.read_filter()
+    def _get_core(self):
+        core_obj=self.connection.get_object(object_path=self.core_path)
+        core=dbus.Interface(core_obj,dbus_interface=self.core_iface)
+        return core
+    def sink_added(self,sink):
+        #TODO: preserve selected sink
+        self.update_sinks()
+    def sink_removed(self,sink):
+        #TODO: preserve selected sink, try connecting to backup otherwise
+        if sink==self.sink_name:
+            #connect to new sink?
+            pass
+        self.update_sinks()
+    def save_profile(self):
+        #popup dialog box for name
+        current=self.profile_box.currentIndex()
+        profile,ok=QtGui.QInputDialog.getItem(self,'Preset Name','Preset',self.profiles,current)
+        if not ok or profile=='':
+            return
+        if profile in self.profiles:
+            mbox=QtGui.QMessageBox(self)
+            mbox.setText('%s preset already exists'%(profile,))
+            mbox.setInformativeText('Do you want to save over it?')
+            mbox.setStandardButtons(mbox.Save|mbox.Discard|mbox.Cancel)
+            mbox.setDefaultButton(mbox.Save)
+            ret=mbox.exec_()
+            if ret!=mbox.Save:
+                return
+        self.sink.SaveProfile(self.filter_state.channel,dbus.String(profile))
+        if self.filter_state.channel==self.filter_state.channels:
+            for x in range(1,self.filter_state.channels):
+                self.sink.LoadProfile(x,dbus.String(profile))
+    def remove_profile(self):
+        #find active profile name, remove it
+        profile=self.profile_box.currentText()
+        manager=dbus.Interface(self.manager_obj,dbus_interface=self.manager_iface)
+        manager.RemoveProfile(dbus.String(profile))
+    def load_profile(self,x):
+        profile=self.profile_box.itemText(x)
+        self.filter_state.load_profile(profile)
+    def select_channel(self,x):
+        self.filter_state.channel = self.channel_box.itemData(x).toPyObject()
+        self._set_profile_name()
+        self.filter_state.readback()
+
+    #TODO: add back in preamp!
+    #print(frequencies)
+    #main_layout.addLayout(self.create_slider(partial(self.update_coefficient,0),
+    #    'Preamp')[0]
+    #)
+    def set_connection(self):
+        self.connection=connect()
+
+        self.manager_obj=self.connection.get_object(object_path=self.manager_path)
+        manager_props=dbus.Interface(self.manager_obj,dbus_interface=prop_iface)
+        try:
+            self.sinks=manager_props.Get(self.manager_iface,'EqualizedSinks')
+        except dbus.exceptions.DBusException:
+            # probably module not yet loaded, try to load it:
+            try:
+                core=self.connection.get_object(object_path=self.core_path)
+                core.LoadModule(self.module_name,{},dbus_interface=self.core_iface)
+                # yup, we don't need to re-create manager_obj and manager_props,
+                # these are late-bound
+                self.sinks=manager_props.Get(self.manager_iface,'EqualizedSinks')
+            except dbus.exceptions.DBusException:
+                sys.stderr.write('It seems that running pulseaudio does not support '
+                                 'equalizer features and loading %s module failed.\n'
+                                 'Exiting...\n' % self.module_name)
+                sys.exit(-1)
+
+    def set_callbacks(self):
+        manager=dbus.Interface(self.manager_obj,dbus_interface=self.manager_iface)
+        manager.connect_to_signal('ProfilesChanged',self.update_profiles)
+        manager.connect_to_signal('SinkAdded',self.sink_added)
+        manager.connect_to_signal('SinkRemoved',self.sink_removed)
+        #self._get_core().ListenForSignal(self.manager_iface,[])
+        #self._get_core().ListenForSignal(self.manager_iface,[dbus.ObjectPath(self.manager_path)])
+        #core=self._get_core()
+        #for x in ['ProfilesChanged','SinkAdded','SinkRemoved']:
+        #    core.ListenForSignal("%s.%s" %(self.manager_iface,x),[dbus.ObjectPath(self.manager_path)])
+        self.update_profiles()
+        self.update_sinks()
+    def update_profiles(self):
+        #print('update profiles called!')
+        manager_props=dbus.Interface(self.manager_obj,dbus_interface=prop_iface)
+        self.profiles=manager_props.Get(self.manager_iface,'Profiles')
+        self.profile_box.blockSignals(True)
+        self.profile_box.clear()
+        self.profile_box.addItems(self.profiles)
+        self.profile_box.blockSignals(False)
+        self._set_profile_name()
+    def update_sinks(self):
+        self.sink_box.blockSignals(True)
+        self.sink_box.clear()
+        for x in self.sinks:
+            sink=self.connection.get_object(object_path=x)
+            sink_props=dbus.Interface(sink,dbus_interface=prop_iface)
+            simple_name=sink_props.Get(device_iface,'Name')
+            self.sink_box.addItem(simple_name,x)
+        self.sink_box.blockSignals(False)
+        self.sink_box.setMinimumSize(self.sink_box.sizeHint())
+    def read_filter(self):
+        #print(self.filter_frequencies)
+        self.filter_state.readback()
+    def reset(self):
+        coefs=dbus.Array([1/math.sqrt(2.0)]*(self.filter_state.filter_rate//2+1))
+        preamp=1.0
+        self.filter_state.set_filter(preamp,coefs)
+    def _set_profile_name(self):
+        self.profile_box.blockSignals(True)
+        profile_name=self.sink.BaseProfile(self.filter_state.channel)
+        if profile_name is not None:
+            i=self.profile_box.findText(profile_name)
+            if i>=0:
+                self.profile_box.setCurrentIndex(i)
+        self.profile_box.blockSignals(False)
+
+
+class SliderArray(QtGui.QWidget):
+    def __init__(self,filter_state,parent=None):
+        super(SliderArray,self).__init__(parent)
+        #self.setStyleSheet('padding: 0px; border-width: 0px; margin: 0px;')
+        #self.setStyleSheet('font-size: 7pt; font-family: monospace;'+outline%('blue'))
+        self.filter_state=filter_state
+        self.setLayout(QtGui.QHBoxLayout())
+        self.sub_array=None
+        self.set_sub_array(SliderArraySub(self.filter_state))
+        self.inhibit_resize=0
+    def set_sub_array(self,widget):
+        if self.sub_array is not None:
+            self.layout().removeWidget(self.sub_array)
+            self.sub_array.disconnect_signals()
+            self.sub_array.deleteLater()
+        self.sub_array=widget
+        self.layout().addWidget(self.sub_array)
+        self.sub_array.connect_signals()
+        self.filter_state.readback()
+    def resizeEvent(self,event):
+        super(SliderArray,self).resizeEvent(event)
+        if self.inhibit_resize==0:
+            self.inhibit_resize+=1
+            #self.add_sliders_to_fit()
+            t=QtCore.QTimer(self)
+            t.setSingleShot(True)
+            t.setInterval(0)
+            t.timeout.connect(partial(self.add_sliders_to_fit,event))
+            t.start()
+    def add_sliders_to_fit(self,event):
+        if event.oldSize().width()>0 and event.size().width()>0:
+            i=len(self.filter_state.frequencies)*int(round(float(event.size().width())/event.oldSize().width()))
+        else:
+            i=len(self.filter_state.frequencies)
+
+        t_w=self.size().width()
+        def evaluate(filter_state, target, variable):
+            base_freqs=self.filter_state.freq_proper(self.filter_state.DEFAULT_FREQUENCIES)
+            filter_state._set_frequency_values(subdivide(base_freqs,variable))
+            new_widget=SliderArraySub(filter_state)
+            w=new_widget.sizeHint().width()
+            return w-target
+        def searcher(initial,evaluator):
+            i=initial
+            def d(e): return 1 if e>=0 else -1
+            error=evaluator(i)
+            old_direction=d(error)
+            i-=old_direction
+            while True:
+                error=evaluator(i)
+                direction=d(error)
+                if direction!=old_direction:
+                    k=i-1
+                    #while direction<0 and error!=0:
+                    #    k-=1
+                    #    error=evaluator(i)
+                    #    direction=d(error)
+                    return k, evaluator(k)
+                i-=direction
+                old_direction=direction
+        searcher(i,partial(evaluate,self.filter_state,t_w))
+        self.set_sub_array(SliderArraySub(self.filter_state))
+        self.inhibit_resize-=1
+
+class SliderArraySub(QtGui.QWidget):
+    def __init__(self,filter_state,parent=None):
+        super(SliderArraySub,self).__init__(parent)
+        self.filter_state=filter_state
+        self.setLayout(QtGui.QGridLayout())
+        self.slider=[None]*len(self.filter_state.frequencies)
+        self.label=[None]*len(self.slider)
+        #self.setStyleSheet('padding: 0px; border-width: 0px; margin: 0px;')
+        #self.setStyleSheet('font-size: 7pt; font-family: monospace;'+outline%('blue'))
+        qt=QtCore.Qt
+        #self.layout().setHorizontalSpacing(1)
+        def add_slider(slider,label, c):
+            self.layout().addWidget(slider,0,c,qt.AlignHCenter)
+            self.layout().addWidget(label,1,c,qt.AlignHCenter)
+            self.layout().setColumnMinimumWidth(c,max(label.sizeHint().width(),slider.sizeHint().width()))
+        def create_slider(slider_label):
+            slider=QtGui.QSlider(QtCore.Qt.Vertical,self)
+            label=SliderLabel(slider_label,filter_state,self)
+            slider.setRange(-1000,2000)
+            slider.setSingleStep(1)
+            return (slider,label)
+        self.preamp_slider,self.preamp_label=create_slider('Preamp')
+        add_slider(self.preamp_slider,self.preamp_label,0)
+        for i,hz in enumerate(self.filter_state.frequencies):
+            slider,label=create_slider(self.hz2label(hz))
+            self.slider[i]=slider
+            #slider.setStyleSheet('font-size: 7pt; font-family: monospace;'+outline%('red',))
+            self.label[i]=label
+            c=i+1
+            add_slider(slider,label,i+1)
+    def hz2label(self, hz):
+        if hz==0:
+            label_text='DC'
+        elif hz==self.filter_state.sample_rate//2:
+            label_text='Coda'
+        else:
+            label_text=hz2str(hz)
+        return label_text
+
+    def connect_signals(self):
+        def connect(writer,reader,slider,label):
+            slider.valueChanged.connect(writer)
+            self.filter_state.readFilter.connect(reader)
+            label_cb=partial(slider.setValue,0)
+            label.clicked.connect(label_cb)
+            return label_cb
+
+        self.preamp_writer_cb=self.write_preamp
+        self.preamp_reader_cb=self.sync_preamp
+        self.preamp_label_cb=connect(self.preamp_writer_cb,
+                self.preamp_reader_cb,
+                self.preamp_slider,
+                self.preamp_label)
+        self.writer_callbacks=[None]*len(self.slider)
+        self.reader_callbacks=[None]*len(self.slider)
+        self.label_callbacks=[None]*len(self.label)
+        for i in range(len(self.slider)):
+            self.writer_callbacks[i]=partial(self.write_coefficient,i)
+            self.reader_callbacks[i]=partial(self.sync_coefficient,i)
+            self.label_callbacks[i]=connect(self.writer_callbacks[i],
+                    self.reader_callbacks[i],
+                    self.slider[i],
+                    self.label[i])
+    def disconnect_signals(self):
+        def disconnect(writer,reader,label_cb,slider,label):
+            slider.valueChanged.disconnect(writer)
+            self.filter_state.readFilter.disconnect(reader)
+            label.clicked.disconnect(label_cb)
+        disconnect(self.preamp_writer_cb, self.preamp_reader_cb,
+                self.preamp_label_cb, self.preamp_slider, self.preamp_label)
+        for i in range(len(self.slider)):
+            disconnect(self.writer_callbacks[i],
+                    self.reader_callbacks[i],
+                    self.label_callbacks[i],
+                    self.slider[i],
+                    self.label[i])
+
+    def write_preamp(self, v):
+        self.filter_state.preamp=self.slider2coef(v)
+        self.filter_state.seed()
+    def sync_preamp(self):
+        self.preamp_slider.blockSignals(True)
+        self.preamp_slider.setValue(self.coef2slider(self.filter_state.preamp))
+        self.preamp_slider.blockSignals(False)
+
+
+    def write_coefficient(self,i,v):
+        self.filter_state.coefficients[i]=self.slider2coef(v)/math.sqrt(2.0)
+        self.filter_state.seed()
+    def sync_coefficient(self,i):
+        slider=self.slider[i]
+        slider.blockSignals(True)
+        slider.setValue(self.coef2slider(math.sqrt(2.0)*self.filter_state.coefficients[i]))
+        slider.blockSignals(False)
+    @staticmethod
+    def slider2coef(x):
+        return (1.0+(x/1000.0))
+    @staticmethod
+    def coef2slider(x):
+        return int((x-1.0)*1000)
+outline='border-width: 1px; border-style: solid; border-color: %s;'
+
+class SliderLabel(QtGui.QLabel):
+    clicked=QtCore.pyqtSignal()
+    def __init__(self,label_text,filter_state,parent=None):
+        super(SliderLabel,self).__init__(parent)
+        self.setStyleSheet('font-size: 7pt; font-family: monospace;')
+        self.setText(label_text)
+        self.setMinimumSize(self.sizeHint())
+    def mouseDoubleClickEvent(self, event):
+        self.clicked.emit()
+        super(SliderLabel,self).mouseDoubleClickEvent(event)
+
+#until there are server side state savings, do it in the client but try and avoid
+#simulaneous broadcasting situations
+class FilterState(QtCore.QObject):
+    #DEFAULT_FREQUENCIES=map(float,[25,50,75,100,150,200,300,400,500,800,1e3,1.5e3,3e3,5e3,7e3,10e3,15e3,20e3])
+    DEFAULT_FREQUENCIES=[31.75,63.5,125,250,500,1e3,2e3,4e3,8e3,16e3]
+    readFilter=QtCore.pyqtSignal()
+    def __init__(self,sink):
+        super(FilterState,self).__init__()
+        self.sink_props=dbus.Interface(sink,dbus_interface=prop_iface)
+        self.sink=dbus.Interface(sink,dbus_interface=eq_iface)
+        self.sample_rate=self.get_eq_attr('SampleRate')
+        self.filter_rate=self.get_eq_attr('FilterSampleRate')
+        self.channels=self.get_eq_attr('NChannels')
+        self.channel=self.channels
+        self.set_frequency_values(self.DEFAULT_FREQUENCIES)
+        self.sync_timer=QtCore.QTimer()
+        self.sync_timer.setSingleShot(True)
+        self.sync_timer.timeout.connect(self.save_state)
+
+    def get_eq_attr(self,attr):
+        return self.sink_props.Get(eq_iface,attr)
+    def freq_proper(self,xs):
+        return [0]+xs+[self.sample_rate//2]
+    def _set_frequency_values(self,freqs):
+        self.frequencies=freqs
+        #print('base',self.frequencies)
+        self.filter_frequencies=[int(round(x)) for x in self.translate_rates(self.filter_rate,self.sample_rate,
+                    self.frequencies)]
+        self.coefficients=[0.0]*len(self.frequencies)
+        self.preamp=1.0
+    def set_frequency_values(self,freqs):
+        self._set_frequency_values(self.freq_proper(freqs))
+    @staticmethod
+    def translate_rates(dst,src,rates):
+        return list([x*dst/src for x in rates])
+    def seed(self):
+        self.sink.SeedFilter(self.channel,self.filter_frequencies,self.coefficients,self.preamp)
+        self.sync_timer.start(SYNC_TIMEOUT)
+    def readback(self):
+        coefs,preamp=self.sink.FilterAtPoints(self.channel,self.filter_frequencies)
+        self.coefficients=coefs
+        self.preamp=preamp
+        self.readFilter.emit()
+    def set_filter(self,preamp,coefs):
+        self.sink.SetFilter(self.channel,dbus.Array(coefs),self.preamp)
+        self.sync_timer.start(SYNC_TIMEOUT)
+    def save_state(self):
+        print('saving state')
+        self.sink.SaveState()
+    def load_profile(self,profile):
+        self.sink.LoadProfile(self.channel,dbus.String(profile))
+        self.sync_timer.start(SYNC_TIMEOUT)
+    def flush_state(self):
+        if self.sync_timer.isActive():
+            self.sync_timer.stop()
+            self.save_state()
+
+
+def safe_log(k,b):
+    i=0
+    while k//b!=0:
+        i+=1
+        k=k//b
+    return i
+def hz2str(hz):
+    p=safe_log(hz,10.0)
+    if p<3:
+        return '%dHz' %(hz,)
+    elif hz%1000==0:
+        return '%dKHz' %(hz/(10.0**3),)
+    else:
+        return '%.1fKHz' %(hz/(10.0**3),)
+
+def subdivide(xs, t_points):
+    while len(xs)<t_points:
+        m=[0]*(2*len(xs)-1)
+        m[0:len(m):2]=xs
+        for i in range(1,len(m),2):
+            m[i]=(m[i-1]+m[i+1])//2
+        xs=m
+    p_drop=len(xs)-t_points
+    p_drop_left=p_drop//2
+    p_drop_right=p_drop-p_drop_left
+    #print('xs',xs)
+    #print('dropping %d, %d left, %d right' %(p_drop,p_drop_left,p_drop_right))
+    c=len(xs)//2
+    left=xs[0:p_drop_left*2:2]+xs[p_drop_left*2:c]
+    right=list(reversed(xs[c:]))
+    right=right[0:p_drop_right*2:2]+right[p_drop_right*2:]
+    right=list(reversed(right))
+    return left+right
+
+def main():
+    dbus.mainloop.qt.DBusQtMainLoop(set_as_default=True)
+    app=QtGui.QApplication(sys.argv)
+    qpaeq_main=QPaeq()
+    qpaeq_main.show()
+    sys.exit(app.exec_())
+
+if __name__=='__main__':
+    main()
diff --git a/todo b/todo
index da993a2..653bedc 100644 (file)
--- a/todo
+++ b/todo
@@ -13,9 +13,12 @@ I18N:
 
 Cleanups:
 - drop dependency of libpulse on libX11, instead use an external mini binary
+
+Network:
 - module-tunnel: improve latency calculation
-- use software volume when hardware doesn't support all channels (alsa done)
-- using POSIX monotonous clocks wherever possible instead of gettimeofday()
+- module-tunnel: more reliable audio streaming over wifi
+- Compressed network streams for tunnels/rtp streams. (Might be a good GSoC project)
+  This builds on passthrough support. A good candidate codec would be CELT.
 
 Test:
 - autoload
@@ -27,19 +30,14 @@ Auth/Crypto:
 - sasl auth 
 
 Features:
-- chroot()
 - use scatter/gather io for sockets
-- CODECs to reduce bandwidth usage (plug-in based)
-- multiline configuration statements
-- paplay needs to set a channel map. our default is only correct for AIFF.
-  (we need help from libsndfile for this)
 - examine if it is possible to mimic esd's handling of half duplex cards
   (switch to capture when a recording client connects and drop playback during
   that time)
-- Support for device selection in waveout driver
 - add an API to libpulse for allocating memory from the pa_context memory pool
-- better ".include" command in configuration files. should have glob support.
-- recursive .if
+- configuration file syntax:
+  - multiline configuration statements
+  - recursive .if
 
 Long term:
 - pass meta info for hearing impaired
diff --git a/vala/libpulse-mainloop-glib.deps b/vala/libpulse-mainloop-glib.deps
new file mode 100644 (file)
index 0000000..69bebf3
--- /dev/null
@@ -0,0 +1 @@
+libpulse
diff --git a/vala/libpulse-mainloop-glib.vapi b/vala/libpulse-mainloop-glib.vapi
new file mode 100644 (file)
index 0000000..a54cb45
--- /dev/null
@@ -0,0 +1,13 @@
+using GLib;
+
+namespace PulseAudio {
+        [Compact]
+        [CCode (cheader_filename="pulse/glib-mainloop.h", cname="pa_glib_mainloop", cprefix="pa_glib_mainloop_", free_function="pa_glib_mainloop_free")]
+        public class GLibMainLoop {
+
+                [CCode (cname="pa_glib_mainloop_new")]
+                public GLibMainLoop(MainContext? c = null);
+
+                public unowned MainLoopApi get_api();
+        }
+}
diff --git a/vala/libpulse.deps b/vala/libpulse.deps
new file mode 100644 (file)
index 0000000..b3188f7
--- /dev/null
@@ -0,0 +1 @@
+posix
index 9e05b14..59375e1 100644 (file)
@@ -46,13 +46,13 @@ namespace PulseAudio {
         [CCode (cname="PA_CHECK_VERSION")]
         public bool CHECK_VERSION(int major, int minor, int micro);
 
-        [CCode (cname="INVALID_INDEX")]
+        [CCode (cname="PA_INVALID_INDEX")]
         public const uint32 INVALID_INDEX;
 
-        [CCode (cname="pa_free_cb_t")]
+        [CCode (cname="pa_free_cb_t", has_target=false)]
         public delegate void FreeCb(void *p);
 
-        [CCode (cname="pa_sample_format_t", cprefix="PA_SAMPLE_")]
+        [CCode (cname="pa_sample_format_t", cprefix="PA_SAMPLE_", has_type_id=false)]
         public enum SampleFormat {
                 U8,
                 ALAW,
@@ -105,7 +105,7 @@ namespace PulseAudio {
         public struct usec : uint64 {
         }
 
-        [CCode (cname="pa_sample_spec")]
+        [CCode (cname="pa_sample_spec", has_type_id=false)]
         public struct SampleSpec {
                 public SampleFormat format;
                 public uint32 rate;
@@ -168,7 +168,7 @@ namespace PulseAudio {
                 return (string) buffer;
         }
 
-        [CCode (cname="pa_volume_t")]
+        [CCode (cname="pa_volume_t", has_type_id=false)]
         public struct Volume : uint32 {
 
                 [CCode (cname="PA_SW_VOLUME_SNPRINT_DB_MAX")]
@@ -237,13 +237,14 @@ namespace PulseAudio {
         [CCode (cname="PA_CHANNELS_MAX")]
         public const int CHANNELS_MAX;
 
-        [CCode (cname="PA_CHANNELS_MAX")]
+        [CCode (cname="PA_RATE_MAX")]
         public const int RATE_MAX;
 
-        [CCode (cname="pa_cvolume")]
+        [CCode (cname="pa_cvolume", has_type_id=false)]
         public struct CVolume {
                 public uint8 channels;
-                public Volume values[];
+                // TODO: Replace array length with CHANNELS_MAX once vala's bug #647788 is fixed
+                public Volume values[32];
 
                 [CCode (cname="PA_SW_CVOLUME_SNPRINT_DB_MAX")]
                 public static const size_t SW_SNPRINT_DB_MAX;
@@ -373,10 +374,11 @@ namespace PulseAudio {
                 public unowned CVolume? dec(Volume minus = 1);
         }
 
-        [CCode (cname="pa_channel_map")]
+        [CCode (cname="pa_channel_map", has_type_id=false)]
         public struct ChannelMap {
                 public uint8 channels;
-                public ChannelPosition map[];
+                // TODO: Replace array length with CHANNELS_MAX once vala's bug #647788 is fixed
+                public ChannelPosition map[32];
 
                 [CCode (cname="PA_CHANNEL_MAP_SNPRINT_MAX")]
                 public static const size_t SNPRINT_MAX;
@@ -446,11 +448,11 @@ namespace PulseAudio {
                 public ChannelPositionMask mask();
         }
 
-        [CCode (cname="pa_channel_position_mask_t")]
+        [CCode (cname="pa_channel_position_mask_t", has_type_id=false)]
         public struct ChannelPositionMask : uint64 {
         }
 
-        [CCode (cname="pa_channel_position_t", cprefix="PA_CHANNEL_POSITION_")]
+        [CCode (cname="pa_channel_position_t", cprefix="PA_CHANNEL_POSITION_", has_type_id=false)]
         public enum ChannelPosition {
                 INVALID,
                 MONO,
@@ -513,7 +515,7 @@ namespace PulseAudio {
                 public static ChannelPosition from_string(string s);
         }
 
-        [CCode (cname="pa_channel_map_def_t", cprefix="PA_CHANNEL_MAP_")]
+        [CCode (cname="pa_channel_map_def_t", cprefix="PA_CHANNEL_MAP_", has_type_id=false)]
         public enum ChannelMapDef {
                 AIFF,
                 WAVEEX,
@@ -525,7 +527,7 @@ namespace PulseAudio {
         }
 
         [Compact]
-        [CCode (cname="pa_proplist", cprefix="pa_proplist_", free_function="pa_proplist_free")]
+        [CCode (cname="pa_proplist", cprefix="pa_proplist_", free_function="pa_proplist_free", has_type_id=false)]
         public class Proplist {
 
                 [CCode (cname="PA_PROP_MEDIA_NAME")]
@@ -686,7 +688,7 @@ namespace PulseAudio {
                 public bool is_empty();
         }
 
-        [CCode (cname="pa_update_mode_t", cprefix="PA_UPDATE_")]
+        [CCode (cname="pa_update_mode_t", cprefix="PA_UPDATE_", has_type_id=false)]
         public enum UpdateMode {
                 SET,
                 MERGE,
@@ -696,7 +698,7 @@ namespace PulseAudio {
         [CCode (cname="PA_OK")]
         public const int OK;
 
-        [CCode (cname="int", cprefix="PA_ERR_")]
+        [CCode (cname="int", cprefix="PA_ERR_", has_type_id=false)]
         public enum Error {
                 ACCESS,
                 COMMAND,
@@ -731,14 +733,14 @@ namespace PulseAudio {
 
         public delegate void VoidFunc();
 
-        [CCode (cname="pa_spawn_api")]
+        [CCode (cname="pa_spawn_api", has_type_id=false)]
         public struct SpawnApi {
                 VoidFunc? prefork;
                 VoidFunc? postfork;
                 VoidFunc? atfork;
         }
 
-        [CCode (cname="pa_io_event_flags_t", cprefix="PA_IO_EVENT_")]
+        [CCode (cname="pa_io_event_flags_t", cprefix="PA_IO_EVENT_", has_type_id=false)]
         public enum IoEventFlags {
                 NULL,
                 INPUT,
@@ -748,22 +750,22 @@ namespace PulseAudio {
         }
 
         [Compact]
-        [CCode (cname="pa_io_event", unref_function="", ref_function="")]
+        [CCode (cname="pa_io_event", unref_function="", ref_function="", has_type_id=false)]
         public struct IoEvent {
         }
 
         [Compact]
-        [CCode (cname="pa_time_event", unref_function="", ref_function="")]
+        [CCode (cname="pa_time_event", unref_function="", ref_function="", has_type_id=false)]
         public struct TimeEvent {
         }
 
         [Compact]
-        [CCode (cname="pa_defer_event", unref_function="", ref_function="")]
+        [CCode (cname="pa_defer_event", unref_function="", ref_function="", has_type_id=false)]
         public struct DeferEvent {
         }
 
         [Compact]
-        [CCode (cname="pa_signal_event", cprefix="pa_signal_", free_function="pa_signal_free")]
+        [CCode (cname="pa_signal_event", cprefix="pa_signal_", free_function="pa_signal_free", has_type_id=false)]
         public struct SignalEvent {
 
                 [CCode (cname="pa_signal_new")]
@@ -773,7 +775,7 @@ namespace PulseAudio {
         }
 
         [Compact]
-        [CCode (cname="pa_mainloop_api", unref_function="", ref_function="")]
+        [CCode (cname="pa_mainloop_api", unref_function="", ref_function="", has_type_id=false)]
         public class MainLoopApi {
                 public void* userdata;
 
@@ -841,7 +843,7 @@ namespace PulseAudio {
         public delegate int PollFunc(pollfd[] ufds, int timeout);
 
         [Compact]
-        [CCode (cname="pa_mainloop", cprefix="pa_mainloop_", free_function="pa_mainloop_free")]
+        [CCode (cname="pa_mainloop", cprefix="pa_mainloop_", free_function="pa_mainloop_free", has_type_id=false)]
         public class MainLoop {
 
                 [CCode (cname="pa_mainloop_new")]
@@ -854,7 +856,7 @@ namespace PulseAudio {
                 public int iterate(bool block = true, out int retval = null);
                 public int run(out int retval = null);
                 public unowned MainLoopApi get_api();
-                public void quit(int r);
+                public void quit(int retval);
                 public void wakeup();
                 public void set_poll_func(PollFunc poll_func);
         }
@@ -879,20 +881,10 @@ namespace PulseAudio {
         }
 
         [Compact]
-        [CCode (cname="pa_glib_mainloop", cprefix="pa_glib_mainloop_", free_function="pa_glib_mainloop_free")]
-        public class GLibMainLoop {
-
-                [CCode (cname="pa_glib_mainloop_new")]
-                public GLibMainLoop();
-
-                public unowned MainLoopApi get_api();
-        }
-
-        [Compact]
-        [CCode (cname="pa_operation", cprefix="pa_operation_", unref_function="pa_operation_unref", ref_function="pa_operation_ref")]
+        [CCode (cname="pa_operation", cprefix="pa_operation_", unref_function="pa_operation_unref", ref_function="pa_operation_ref", has_type_id=false)]
         public class Operation {
 
-                [CCode (cname="pa_operation_state_t", cprefix="PA_OPERATION_")]
+                [CCode (cname="pa_operation_state_t", cprefix="PA_OPERATION_", has_type_id=false)]
                 public enum State {
                         RUNNING,
                         DONE,
@@ -904,16 +896,16 @@ namespace PulseAudio {
         }
 
         [Compact]
-        [CCode (cname="pa_context", cprefix="pa_context_", unref_function="pa_context_unref", ref_function="pa_context_ref")]
+        [CCode (cname="pa_context", cprefix="pa_context_", unref_function="pa_context_unref", ref_function="pa_context_ref", has_type_id=false)]
         public class Context {
 
-                [CCode (cname="pa_context_flags_t", cprefix="PA_CONTEXT_")]
+                [CCode (cname="pa_context_flags_t", cprefix="PA_CONTEXT_", has_type_id=false)]
                 public enum Flags {
                         NOAUTOSPAWN,
                         NOFAIL
                 }
 
-                [CCode (cname="pa_context_state_t", cprefix="PA_CONTEXT_")]
+                [CCode (cname="pa_context_state_t", cprefix="PA_CONTEXT_", has_type_id=false)]
                 public enum State {
                         UNCONNECTED,
                         CONNECTING,
@@ -923,11 +915,11 @@ namespace PulseAudio {
                         FAILED,
                         TERMINATED;
 
-                        [CCode (cname="PA_CONTEXT_IS_GOOD")]
+                        [CCode (cname="PA_CONTEXT_IS_GOOD", has_type_id=false)]
                         public bool IS_GOOD();
                 }
 
-                [CCode (cname="pa_subscription_mask_t", cprefix="PA_SUBSCRIPTION_MASK_")]
+                [CCode (cname="pa_subscription_mask_t", cprefix="PA_SUBSCRIPTION_MASK_", has_type_id=false)]
                 public enum SubscriptionMask {
                         NULL,
                         SINK,
@@ -945,7 +937,7 @@ namespace PulseAudio {
                         public bool match_flags(SubscriptionEventType t);
                 }
 
-                [CCode (cname="pa_subscription_event_type_t", cprefix="PA_SUBSCRIPTION_EVENT_")]
+                [CCode (cname="pa_subscription_event_type_t", cprefix="PA_SUBSCRIPTION_EVENT_", has_type_id=false)]
                 public enum SubscriptionEventType {
                         SINK,
                         SOURCE,
@@ -1024,7 +1016,7 @@ namespace PulseAudio {
                 public Operation? suspend_sink_by_index(uint32 idx, bool suspend, SuccessCb? cb = null);
 
                 public Operation? set_sink_port_by_name(string name, string port, SuccessCb? cb = null);
-                public Operation? set_sink_port_by_index(string idx, string port, SuccessCb? cb = null);
+                public Operation? set_sink_port_by_index(uint32 idx, string port, SuccessCb? cb = null);
 
                 public Operation? get_source_info_by_name(string name, SourceInfoCb cb);
                 public Operation? get_source_info_by_index(uint32 idx, SourceInfoCb cb);
@@ -1039,7 +1031,7 @@ namespace PulseAudio {
                 public Operation? suspend_source_by_index(uint32 idx, bool suspend, SuccessCb? cb = null);
 
                 public Operation? set_source_port_by_name(string name, string port, SuccessCb? cb = null);
-                public Operation? set_source_port_by_index(string idx, string port, SuccessCb? cb = null);
+                public Operation? set_source_port_by_index(uint32 idx, string port, SuccessCb? cb = null);
 
                 public Operation? get_server_info(ServerInfoCb cb);
 
@@ -1093,10 +1085,10 @@ namespace PulseAudio {
         }
 
         [Compact]
-        [CCode (cname="pa_stream", cprefix="pa_stream_", unref_function="pa_stream_unref", ref_function="pa_stream_ref")]
+        [CCode (cname="pa_stream", cprefix="pa_stream_", unref_function="pa_stream_unref", ref_function="pa_stream_ref", has_type_id=false)]
         public class Stream {
 
-                [CCode (cname="pa_stream_flags_t", cprefix="PA_STREAM_")]
+                [CCode (cname="pa_stream_flags_t", cprefix="PA_STREAM_", has_type_id=false)]
                 public enum Flags {
                         START_CORKED,
                         INTERPOLATE_TIMING,
@@ -1118,7 +1110,7 @@ namespace PulseAudio {
                         FAIL_ON_SUSPEND
                 }
 
-                [CCode (cname="pa_stream_state_t", cprefix="PA_STREAM_")]
+                [CCode (cname="pa_stream_state_t", cprefix="PA_STREAM_", has_type_id=false)]
                 public enum State {
                         UNCONNECTED,
                         CREATING,
@@ -1130,7 +1122,7 @@ namespace PulseAudio {
                         public bool IS_GOOD();
                 }
 
-                [CCode (cname="pa_stream_direction_t", cprefix="PA_STREAM_")]
+                [CCode (cname="pa_stream_direction_t", cprefix="PA_STREAM_", has_type_id=false)]
                 public enum Direction {
                         NODIRECTION,
                         PLAYBACK,
@@ -1138,7 +1130,7 @@ namespace PulseAudio {
                         UPLOAD
                 }
 
-                [CCode (cname="pa_seek_mode_t", cprefix="PA_SEEK_")]
+                [CCode (cname="pa_seek_mode_t", cprefix="PA_SEEK_", has_type_id=false)]
                 public enum SeekMode {
                         RELATIVE,
                         ABSOLUTE,
@@ -1146,7 +1138,7 @@ namespace PulseAudio {
                         RELATIVE_END
                 }
 
-                [CCode (cname="pa_buffer_attr")]
+                [CCode (cname="pa_buffer_attr", has_type_id=false)]
                 public struct BufferAttr {
                         uint32 maxlength;
                         uint32 tlength;
@@ -1155,7 +1147,7 @@ namespace PulseAudio {
                         uint32 fragsize;
                 }
 
-                [CCode (cname="pa_timing_info")]
+                [CCode (cname="pa_timing_info", has_type_id=false)]
                 public struct TimingInfo {
                         timeval timestamp;
                         int synchronized_clocks;
@@ -1194,8 +1186,8 @@ namespace PulseAudio {
                 public int is_suspended();
                 public int is_corked();
 
-                public int connect_playback(string dev, BufferAttr? a = null, Flags flags = 0, CVolume? volume = null, Stream? sync_stream = null);
-                public int connect_record(string dev, BufferAttr? a = null, Flags flags = 0);
+                public int connect_playback(string? dev = null, BufferAttr? a = null, Flags flags = 0, CVolume? volume = null, Stream? sync_stream = null);
+                public int connect_record(string? dev = null, BufferAttr? a = null, Flags flags = 0);
                 public int connect_upload(size_t length);
                 public int disconnect();
                 public int finish_upload();
@@ -1248,14 +1240,14 @@ namespace PulseAudio {
                 public uint32 get_monitor_stream();
         }
 
-        [CCode (cname="pa_sink_port_info")]
+        [CCode (cname="pa_sink_port_info", has_type_id=false)]
         public struct SinkPortInfo {
                 public string name;
                 public string description;
                 public uint32 priority;
         }
 
-        [CCode (cname="pa_sink_info")]
+        [CCode (cname="pa_sink_info", has_type_id=false)]
         public struct SinkInfo {
                 public string name;
                 public uint32 index;
@@ -1281,14 +1273,14 @@ namespace PulseAudio {
                 public SinkPortInfo* active_port;
         }
 
-        [CCode (cname="pa_source_port_info")]
+        [CCode (cname="pa_source_port_info", has_type_id=false)]
         public struct SourcePortInfo {
                 public string name;
                 public string description;
                 public uint32 priority;
         }
 
-        [CCode (cname="pa_source_info")]
+        [CCode (cname="pa_source_info", has_type_id=false)]
         public struct SourceInfo {
                 public string name;
                 public uint32 index;
@@ -1314,7 +1306,7 @@ namespace PulseAudio {
                 public SourcePortInfo* active_port;
         }
 
-        [CCode (cname="pa_server_info")]
+        [CCode (cname="pa_server_info", has_type_id=false)]
         public struct ServerInfo {
                 public string user_name;
                 public string host_name;
@@ -1326,7 +1318,7 @@ namespace PulseAudio {
                 public ChannelMap channel_map;
         }
 
-        [CCode (cname="pa_module_info")]
+        [CCode (cname="pa_module_info", has_type_id=false)]
         public struct ModuleInfo {
                 public uint32 index;
                 public string name;
@@ -1335,7 +1327,7 @@ namespace PulseAudio {
                 public Proplist proplist;
         }
 
-        [CCode (cname="pa_client_info")]
+        [CCode (cname="pa_client_info", has_type_id=false)]
         public struct ClientInfo {
                 public uint32 index;
                 public string name;
@@ -1344,7 +1336,7 @@ namespace PulseAudio {
                 public Proplist proplist;
         }
 
-        [CCode (cname="pa_card_profile_info")]
+        [CCode (cname="pa_card_profile_info", has_type_id=false)]
         public struct CardProfileInfo {
                 public string name;
                 public string description;
@@ -1353,19 +1345,19 @@ namespace PulseAudio {
                 public uint32 priority;
         }
 
-        [CCode (cname="pa_card_info")]
+        [CCode (cname="pa_card_info", has_type_id=false)]
         public struct CardInfo {
                 public uint32 index;
                 public string name;
                 public uint32 owner_module;
                 public string driver;
                 public uint32 n_profiles;
-                public CardProfileInfo profiles[];
+                public CardProfileInfo[] profiles;
                 public CardProfileInfo *active_profile;
                 public Proplist proplist;
         }
 
-        [CCode (cname="pa_sink_input_info")]
+        [CCode (cname="pa_sink_input_info", has_type_id=false)]
         public struct SinkInputInfo {
                 public uint32 index;
                 public string name;
@@ -1383,7 +1375,7 @@ namespace PulseAudio {
                 public Proplist proplist;
         }
 
-        [CCode (cname="pa_source_output_info")]
+        [CCode (cname="pa_source_output_info", has_type_id=false)]
         public struct SourceOutputInfo {
                 public uint32 index;
                 public string name;
@@ -1399,7 +1391,7 @@ namespace PulseAudio {
                 public Proplist proplist;
         }
 
-        [CCode (cname="pa_stat_info")]
+        [CCode (cname="pa_stat_info", has_type_id=false)]
         public struct StatInfo {
                 public uint32 memblock_total;
                 public uint32 memblock_total_size;
@@ -1408,7 +1400,7 @@ namespace PulseAudio {
                 public uint32 scache_size;
         }
 
-        [CCode (cname="pa_sample_info")]
+        [CCode (cname="pa_sample_info", has_type_id=false)]
         public struct SampleInfo {
                 public uint32 index;
                 public string name;
@@ -1422,7 +1414,7 @@ namespace PulseAudio {
                 public Proplist proplist;
         }
 
-        [CCode (cname="pa_sink_flags_t", cprefix="PA_SINK_")]
+        [CCode (cname="pa_sink_flags_t", cprefix="PA_SINK_", has_type_id=false)]
         public enum SinkFlags {
                 HW_VOLUME_CTRL,
                 LATENCY,
@@ -1434,7 +1426,7 @@ namespace PulseAudio {
                 DYNAMIC_LATENCY
         }
 
-        [CCode (cname="pa_source_flags_t", cprefix="PA_SOURCE_")]
+        [CCode (cname="pa_source_flags_t", cprefix="PA_SOURCE_", has_type_id=false)]
         public enum SourceFlags {
                 HW_VOLUME_CTRL,
                 LATENCY,
@@ -1445,7 +1437,7 @@ namespace PulseAudio {
                 DYNAMIC_LATENCY
         }
 
-        [CCode (cname="pa_sink_state_t", cprefix="PA_SINK_")]
+        [CCode (cname="pa_sink_state_t", cprefix="PA_SINK_", has_type_id=false)]
         public enum SinkState {
                 INVALID_STATE,
                 RUNNING,
@@ -1456,7 +1448,7 @@ namespace PulseAudio {
                 public bool IS_OPENED();
         }
 
-        [CCode (cname="pa_source_state_t", cprefix="PA_SOURCE_")]
+        [CCode (cname="pa_source_state_t", cprefix="PA_SOURCE_", has_type_id=false)]
         public enum SourceState {
                 INVALID_STATE,
                 RUNNING,